am ba127f57: Improve VpnSettings start-up time.

Merge commit 'ba127f57ae143a0c7fad5a46b327c04eb2254737'

* commit 'ba127f57ae143a0c7fad5a46b327c04eb2254737':
  Improve VpnSettings start-up time.
This commit is contained in:
Hung-ying Tyan
2009-07-19 21:14:28 -07:00
committed by Android Git Automerger
3 changed files with 101 additions and 95 deletions

View File

@@ -127,6 +127,7 @@
</activity> </activity>
<activity android:name=".vpn.VpnSettings" <activity android:name=".vpn.VpnSettings"
android:configChanges="orientation|keyboardHidden"
android:launchMode="singleTask"> android:launchMode="singleTask">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
@@ -136,8 +137,12 @@
</intent-filter> </intent-filter>
</activity> </activity>
<activity android:name=".vpn.VpnTypeSelection"></activity> <activity android:name=".vpn.VpnTypeSelection"
<activity android:name=".vpn.VpnEditor"></activity> android:configChanges="orientation|keyboardHidden">
</activity>
<activity android:name=".vpn.VpnEditor"
android:configChanges="orientation|keyboardHidden">
</activity>
<activity android:name="DateTimeSettings" android:label="@string/date_and_time" <activity android:name="DateTimeSettings" android:label="@string/date_and_time"
> >
@@ -270,6 +275,7 @@
</activity> </activity>
<activity android:name="SecuritySettings" android:label="@string/security_settings_title" <activity android:name="SecuritySettings" android:label="@string/security_settings_title"
android:configChanges="orientation|keyboardHidden"
android:clearTaskOnLaunch="true" android:clearTaskOnLaunch="true"
> >
<intent-filter> <intent-filter>

View File

@@ -26,6 +26,7 @@ import android.net.vpn.IVpnService;
import android.net.vpn.VpnManager; import android.net.vpn.VpnManager;
import android.net.vpn.VpnProfile; import android.net.vpn.VpnProfile;
import android.net.vpn.VpnState; import android.net.vpn.VpnState;
import android.os.ConditionVariable;
import android.os.IBinder; import android.os.IBinder;
import android.os.RemoteException; import android.os.RemoteException;
import android.text.TextUtils; import android.text.TextUtils;
@@ -42,7 +43,6 @@ import java.io.IOException;
*/ */
public class AuthenticationActor implements VpnProfileActor { public class AuthenticationActor implements VpnProfileActor {
private static final String TAG = AuthenticationActor.class.getName(); private static final String TAG = AuthenticationActor.class.getName();
private static final int ONE_SECOND = 1000; // ms
private Context mContext; private Context mContext;
private VpnProfile mProfile; private VpnProfile mProfile;
@@ -175,27 +175,31 @@ public class AuthenticationActor implements VpnProfileActor {
//@Override //@Override
public void checkStatus() { public void checkStatus() {
final ConditionVariable cv = new ConditionVariable();
cv.close();
ServiceConnection c = new ServiceConnection() { ServiceConnection c = new ServiceConnection() {
public synchronized void onServiceConnected(ComponentName className, public synchronized void onServiceConnected(ComponentName className,
IBinder service) { IBinder service) {
cv.open();
try { try {
IVpnService.Stub.asInterface(service).checkStatus(mProfile); IVpnService.Stub.asInterface(service).checkStatus(mProfile);
} catch (RemoteException e) { } catch (RemoteException e) {
Log.e(TAG, "checkStatus()", e); Log.e(TAG, "checkStatus()", e);
broadcastConnectivity(VpnState.IDLE); broadcastConnectivity(VpnState.IDLE);
} finally { } finally {
notify(); mContext.unbindService(this);
} }
} }
public void onServiceDisconnected(ComponentName className) { public void onServiceDisconnected(ComponentName className) {
// do nothing cv.open();
broadcastConnectivity(VpnState.IDLE);
mContext.unbindService(this);
} }
}; };
if (bindService(c)) { if (bindService(c)) {
// wait for a second, let status propagate // wait for a second, let status propagate
wait(c, ONE_SECOND); if (!cv.block(1000)) broadcastConnectivity(VpnState.IDLE);
mContext.unbindService(c);
} }
} }
@@ -211,14 +215,6 @@ public class AuthenticationActor implements VpnProfileActor {
mVpnManager.broadcastConnectivity(mProfile.getName(), s, errorCode); mVpnManager.broadcastConnectivity(mProfile.getName(), s, errorCode);
} }
private void wait(Object o, int ms) {
synchronized (o) {
try {
o.wait(ms);
} catch (Exception e) {}
}
}
private void setSavedUsername(String name) throws IOException { private void setSavedUsername(String name) throws IOException {
if (!name.equals(mProfile.getSavedUsername())) { if (!name.equals(mProfile.getSavedUsername())) {
mProfile.setSavedUsername(name); mProfile.setSavedUsername(name);

View File

@@ -21,10 +21,13 @@ import com.android.settings.SecuritySettings;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.app.Dialog; import android.app.Dialog;
import android.content.ComponentName;
import android.content.BroadcastReceiver; import android.content.BroadcastReceiver;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.content.ServiceConnection;
import android.net.vpn.IVpnService;
import android.net.vpn.L2tpIpsecPskProfile; import android.net.vpn.L2tpIpsecPskProfile;
import android.net.vpn.L2tpProfile; import android.net.vpn.L2tpProfile;
import android.net.vpn.VpnManager; import android.net.vpn.VpnManager;
@@ -33,8 +36,10 @@ import android.net.vpn.VpnState;
import android.net.vpn.VpnType; import android.net.vpn.VpnType;
import android.os.Bundle; import android.os.Bundle;
import android.os.ConditionVariable; import android.os.ConditionVariable;
import android.os.IBinder;
import android.os.Parcel; import android.os.Parcel;
import android.os.Parcelable; import android.os.Parcelable;
import android.os.RemoteException;
import android.preference.Preference; import android.preference.Preference;
import android.preference.PreferenceActivity; import android.preference.PreferenceActivity;
import android.preference.PreferenceCategory; import android.preference.PreferenceCategory;
@@ -86,8 +91,6 @@ public class VpnSettings extends PreferenceActivity implements
private static final String PROFILES_ROOT = VpnManager.PROFILES_PATH + "/"; private static final String PROFILES_ROOT = VpnManager.PROFILES_PATH + "/";
private static final String PROFILE_OBJ_FILE = ".pobj"; private static final String PROFILE_OBJ_FILE = ".pobj";
private static final String STATE_ACTIVE_ACTOR = "active_actor";
private static final int REQUEST_ADD_OR_EDIT_PROFILE = 1; private static final int REQUEST_ADD_OR_EDIT_PROFILE = 1;
private static final int REQUEST_SELECT_VPN_TYPE = 2; private static final int REQUEST_SELECT_VPN_TYPE = 2;
@@ -113,8 +116,6 @@ public class VpnSettings extends PreferenceActivity implements
private Map<String, VpnPreference> mVpnPreferenceMap; private Map<String, VpnPreference> mVpnPreferenceMap;
private List<VpnProfile> mVpnProfileList; private List<VpnProfile> mVpnProfileList;
private int mIndexOfEditedProfile = -1;
// profile engaged in a connection // profile engaged in a connection
private VpnProfile mActiveProfile; private VpnProfile mActiveProfile;
@@ -159,28 +160,13 @@ public class VpnSettings extends PreferenceActivity implements
// listen to vpn connectivity event // listen to vpn connectivity event
mVpnManager.registerConnectivityReceiver(mConnectivityReceiver); mVpnManager.registerConnectivityReceiver(mConnectivityReceiver);
String profileName = (savedInstanceState == null)
? null
: savedInstanceState.getString(STATE_ACTIVE_ACTOR);
retrieveVpnListFromStorage(); retrieveVpnListFromStorage();
if (!TextUtils.isEmpty(profileName)) { checkVpnConnectionStatusInBackground();
mActiveProfile = mVpnPreferenceMap.get(profileName).mProfile;
mConnectingActor = getActor(mActiveProfile);
} else {
checkVpnConnectionStatusInBackground();
}
}
@Override
public void onPause() {
super.onPause();
mStatusChecker.onPause();
} }
@Override @Override
public void onResume() { public void onResume() {
super.onResume(); super.onResume();
mStatusChecker.onResume();
if ((mUnlockAction != null) && isKeystoreUnlocked()) { if ((mUnlockAction != null) && isKeystoreUnlocked()) {
Runnable action = mUnlockAction; Runnable action = mUnlockAction;
@@ -189,15 +175,6 @@ public class VpnSettings extends PreferenceActivity implements
} }
} }
@Override
protected synchronized void onSaveInstanceState(Bundle outState) {
if (mConnectingActor == null) return;
Log.d(TAG, " ~~~~~ save connecting actor");
outState.putString(STATE_ACTIVE_ACTOR,
mConnectingActor.getProfile().getName());
}
@Override @Override
protected void onDestroy() { protected void onDestroy() {
super.onDestroy(); super.onDestroy();
@@ -278,8 +255,6 @@ public class VpnSettings extends PreferenceActivity implements
public void onClick(DialogInterface dialog, int w) { public void onClick(DialogInterface dialog, int w) {
VpnProfile p = mConnectingActor.getProfile(); VpnProfile p = mConnectingActor.getProfile();
onIdle(); onIdle();
mIndexOfEditedProfile =
mVpnProfileList.indexOf(p);
startVpnEditor(p); startVpnEditor(p);
} }
}) })
@@ -325,7 +300,6 @@ public class VpnSettings extends PreferenceActivity implements
return true; return true;
case CONTEXT_MENU_EDIT_ID: case CONTEXT_MENU_EDIT_ID:
mIndexOfEditedProfile = position;
startVpnEditor(p); startVpnEditor(p);
return true; return true;
@@ -340,9 +314,6 @@ public class VpnSettings extends PreferenceActivity implements
@Override @Override
protected void onActivityResult(final int requestCode, final int resultCode, protected void onActivityResult(final int requestCode, final int resultCode,
final Intent data) { final Intent data) {
final int index = mIndexOfEditedProfile;
mIndexOfEditedProfile = -1;
if ((resultCode == RESULT_CANCELED) || (data == null)) { if ((resultCode == RESULT_CANCELED) || (data == null)) {
Log.d(TAG, "no result returned by editor"); Log.d(TAG, "no result returned by editor");
return; return;
@@ -358,6 +329,7 @@ public class VpnSettings extends PreferenceActivity implements
return; return;
} }
int index = getProfileIndexFromId(p.getId());
if (checkDuplicateName(p, index)) { if (checkDuplicateName(p, index)) {
final VpnProfile profile = p; final VpnProfile profile = p;
Util.showErrorMessage(this, String.format( Util.showErrorMessage(this, String.format(
@@ -374,7 +346,6 @@ public class VpnSettings extends PreferenceActivity implements
if (needKeystoreToSave(p)) { if (needKeystoreToSave(p)) {
Runnable action = new Runnable() { Runnable action = new Runnable() {
public void run() { public void run() {
mIndexOfEditedProfile = index;
onActivityResult(requestCode, resultCode, data); onActivityResult(requestCode, resultCode, data);
} }
}; };
@@ -382,7 +353,7 @@ public class VpnSettings extends PreferenceActivity implements
} }
try { try {
if ((index < 0) || (index >= mVpnProfileList.size())) { if (index < 0) {
addProfile(p); addProfile(p);
Util.showShortToastMessage(this, String.format( Util.showShortToastMessage(this, String.format(
getString(R.string.vpn_profile_added), p.getName())); getString(R.string.vpn_profile_added), p.getName()));
@@ -440,6 +411,18 @@ public class VpnSettings extends PreferenceActivity implements
} }
} }
private int getProfileIndexFromId(String id) {
int index = 0;
for (VpnProfile p : mVpnProfileList) {
if (p.getId().equals(id)) {
return index;
} else {
index++;
}
}
return -1;
}
// Replaces the profile at index in mVpnProfileList with p. // Replaces the profile at index in mVpnProfileList with p.
// Returns true if p's name is a duplicate. // Returns true if p's name is a duplicate.
private boolean checkDuplicateName(VpnProfile p, int index) { private boolean checkDuplicateName(VpnProfile p, int index) {
@@ -517,11 +500,16 @@ public class VpnSettings extends PreferenceActivity implements
disableProfilePreferencesIfOneActive(); disableProfilePreferencesIfOneActive();
} }
private VpnPreference addPreferenceFor(VpnProfile p) {
return addPreferenceFor(p, true);
}
// Adds a preference in mVpnListContainer // Adds a preference in mVpnListContainer
private void addPreferenceFor(VpnProfile p) { private VpnPreference addPreferenceFor(
VpnProfile p, boolean addToContainer) {
VpnPreference pref = new VpnPreference(this, p); VpnPreference pref = new VpnPreference(this, p);
mVpnPreferenceMap.put(p.getName(), pref); mVpnPreferenceMap.put(p.getName(), pref);
mVpnListContainer.addPreference(pref); if (addToContainer) mVpnListContainer.addPreference(pref);
pref.setOnPreferenceClickListener( pref.setOnPreferenceClickListener(
new Preference.OnPreferenceClickListener() { new Preference.OnPreferenceClickListener() {
@@ -530,6 +518,7 @@ public class VpnSettings extends PreferenceActivity implements
return true; return true;
} }
}); });
return pref;
} }
// index: index to mVpnProfileList // index: index to mVpnProfileList
@@ -790,12 +779,18 @@ public class VpnSettings extends PreferenceActivity implements
return false; return false;
} }
}); });
for (VpnProfile p : mVpnProfileList) addPreferenceFor(p); for (VpnProfile p : mVpnProfileList) {
Preference pref = addPreferenceFor(p, false);
}
disableProfilePreferencesIfOneActive(); disableProfilePreferencesIfOneActive();
} }
private void checkVpnConnectionStatusInBackground() { private void checkVpnConnectionStatusInBackground() {
mStatusChecker.check(mVpnProfileList); new Thread(new Runnable() {
public void run() {
mStatusChecker.check(mVpnProfileList);
}
}).start();
} }
// A sanity check. Returns true if the profile directory name and profile ID // A sanity check. Returns true if the profile directory name and profile ID
@@ -931,49 +926,58 @@ public class VpnSettings extends PreferenceActivity implements
// managing status check in a background thread // managing status check in a background thread
private class StatusChecker { private class StatusChecker {
private Set<VpnProfile> mQueue = new HashSet<VpnProfile>(); private List<VpnProfile> mList;
private boolean mPaused = true;
private ConditionVariable mThreadCv = new ConditionVariable();
void onPause() { synchronized void check(final List<VpnProfile> list) {
mPaused = true; final ConditionVariable cv = new ConditionVariable();
mThreadCv.block(); // until the checking thread is over cv.close();
} mVpnManager.startVpnService();
ServiceConnection c = new ServiceConnection() {
public synchronized void onServiceConnected(
ComponentName className, IBinder binder) {
cv.open();
synchronized void onResume() { IVpnService service = IVpnService.Stub.asInterface(binder);
start(); for (VpnProfile p : list) {
} try {
service.checkStatus(p);
synchronized void check(List<VpnProfile> list) { } catch (Throwable e) {
boolean started = !mQueue.isEmpty(); Log.e(TAG, " --- checkStatus(): " + p.getName(), e);
for (VpnProfile p : list) { changeState(p, VpnState.IDLE);
if (!mQueue.contains(p)) mQueue.add(p); }
}
if (!started) start();
}
private synchronized VpnProfile next() {
if (mPaused || mQueue.isEmpty()) return null;
Iterator<VpnProfile> i = mQueue.iterator();
VpnProfile p = i.next();
i.remove();
return p;
}
private synchronized void start() {
if (!mPaused) return;
mPaused = false;
mThreadCv.close();
new Thread(new Runnable() {
public void run() {
while (true) {
VpnProfile p = next();
if (p == null) break;
getActor(p).checkStatus();
} }
mThreadCv.open(); VpnSettings.this.unbindService(this);
showPreferences();
} }
}).start();
public void onServiceDisconnected(ComponentName className) {
cv.open();
setDefaultState(list);
VpnSettings.this.unbindService(this);
showPreferences();
}
};
if (mVpnManager.bindVpnService(c)) {
if (!cv.block(1000)) {
Log.d(TAG, "checkStatus() bindService failed");
setDefaultState(list);
}
} else {
setDefaultState(list);
}
}
private void showPreferences() {
for (VpnProfile p : mVpnProfileList) {
VpnPreference pref = mVpnPreferenceMap.get(p.getName());
mVpnListContainer.addPreference(pref);
}
}
private void setDefaultState(List<VpnProfile> list) {
for (VpnProfile p : list) changeState(p, VpnState.IDLE);
showPreferences();
} }
} }
} }