Merge "Extract credential storage dialogs to a new activity." into honeycomb
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 5a2ecca..2e293c8 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -3142,5 +3142,7 @@
<string name="enter_password">Enter password to decrypt storage</string>
<!-- This is displayed when the password is entered incorrectly -->
<string name="try_again">Sorry, try again</string>
+ <!-- This error message is displayed when the vpn profile is going to be saved but the vpn service is busy [CHAR LIMIT=NONE] -->
+ <string name="service_busy">Service busy, try again</string>
</resources>
diff --git a/src/com/android/settings/vpn/AuthenticationActor.java b/src/com/android/settings/vpn/AuthenticationActor.java
index 0228934..f8401d6 100644
--- a/src/com/android/settings/vpn/AuthenticationActor.java
+++ b/src/com/android/settings/vpn/AuthenticationActor.java
@@ -19,16 +19,10 @@
import com.android.settings.R;
import android.app.Dialog;
-import android.content.ComponentName;
import android.content.Context;
-import android.content.ServiceConnection;
-import android.net.vpn.IVpnService;
import android.net.vpn.VpnManager;
import android.net.vpn.VpnProfile;
import android.net.vpn.VpnState;
-import android.os.ConditionVariable;
-import android.os.IBinder;
-import android.os.RemoteException;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
@@ -117,102 +111,13 @@
return mContext;
}
- private void connect(final String username, final String password) {
- mVpnManager.startVpnService();
- ServiceConnection c = new ServiceConnection() {
- public void onServiceConnected(ComponentName className,
- IBinder service) {
- try {
- boolean success = IVpnService.Stub.asInterface(service)
- .connect(mProfile, username, password);
- if (!success) {
- Log.d(TAG, "~~~~~~ connect() failed!");
- } else {
- Log.d(TAG, "~~~~~~ connect() succeeded!");
- }
- } catch (Throwable e) {
- Log.e(TAG, "connect()", e);
- broadcastConnectivity(VpnState.IDLE,
- VpnManager.VPN_ERROR_CONNECTION_FAILED);
- } finally {
- mContext.unbindService(this);
- }
- }
-
- public void onServiceDisconnected(ComponentName className) {
- checkStatus();
- }
- };
- if (!bindService(c)) {
- broadcastConnectivity(VpnState.IDLE,
- VpnManager.VPN_ERROR_CONNECTION_FAILED);
- }
+ private void connect(String username, String password) {
+ mVpnManager.connect(mProfile, username, password);
}
//@Override
public void disconnect() {
- ServiceConnection c = new ServiceConnection() {
- public void onServiceConnected(ComponentName className,
- IBinder service) {
- try {
- IVpnService.Stub.asInterface(service).disconnect();
- } catch (RemoteException e) {
- Log.e(TAG, "disconnect()", e);
- checkStatus();
- } finally {
- mContext.unbindService(this);
- }
- }
-
- public void onServiceDisconnected(ComponentName className) {
- checkStatus();
- }
- };
- if (!bindService(c)) {
- checkStatus();
- }
- }
-
- //@Override
- public void checkStatus() {
- final ConditionVariable cv = new ConditionVariable();
- cv.close();
- ServiceConnection c = new ServiceConnection() {
- public synchronized void onServiceConnected(ComponentName className,
- IBinder service) {
- cv.open();
- try {
- IVpnService.Stub.asInterface(service).checkStatus(mProfile);
- } catch (RemoteException e) {
- Log.e(TAG, "checkStatus()", e);
- broadcastConnectivity(VpnState.IDLE);
- } finally {
- mContext.unbindService(this);
- }
- }
-
- public void onServiceDisconnected(ComponentName className) {
- cv.open();
- broadcastConnectivity(VpnState.IDLE);
- mContext.unbindService(this);
- }
- };
- if (bindService(c)) {
- // wait for a second, let status propagate
- if (!cv.block(1000)) broadcastConnectivity(VpnState.IDLE);
- }
- }
-
- private boolean bindService(ServiceConnection c) {
- return mVpnManager.bindVpnService(c);
- }
-
- private void broadcastConnectivity(VpnState s) {
- mVpnManager.broadcastConnectivity(mProfile.getName(), s);
- }
-
- private void broadcastConnectivity(VpnState s, int errorCode) {
- mVpnManager.broadcastConnectivity(mProfile.getName(), s, errorCode);
+ mVpnManager.disconnect();
}
private void setSavedUsername(String name) throws IOException {
diff --git a/src/com/android/settings/vpn/VpnEditor.java b/src/com/android/settings/vpn/VpnEditor.java
index 1b3bdb5..161d34b 100644
--- a/src/com/android/settings/vpn/VpnEditor.java
+++ b/src/com/android/settings/vpn/VpnEditor.java
@@ -28,6 +28,7 @@
import android.net.vpn.L2tpIpsecPskProfile;
import android.net.vpn.L2tpProfile;
import android.net.vpn.PptpProfile;
+import android.net.vpn.VpnManager;
import android.net.vpn.VpnProfile;
import android.os.Bundle;
import android.os.Parcel;
@@ -37,6 +38,7 @@
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
+import android.widget.Toast;
/**
* The activity class for editing a new or existing VPN profile.
@@ -48,6 +50,7 @@
private static final String KEY_PROFILE = "profile";
private static final String KEY_ORIGINAL_PROFILE_NAME = "orig_profile_name";
+ private VpnManager mVpnManager;
private VpnProfileEditor mProfileEditor;
private boolean mAddingProfile;
private byte[] mOriginalProfileData;
@@ -63,6 +66,7 @@
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
+ mVpnManager = new VpnManager(getActivity());
VpnProfile p;
if (savedInstanceState != null) {
@@ -111,8 +115,15 @@
case MENU_SAVE:
Intent resultIntent = validateAndGetResult();
if (resultIntent != null) {
- ((PreferenceActivity) getActivity()).finishPreferencePanel(
- this, Activity.RESULT_OK, resultIntent);
+ PreferenceActivity activity =
+ (PreferenceActivity) getActivity();
+ if (!mVpnManager.isIdle()) {
+ Toast.makeText(activity, R.string.service_busy,
+ Toast.LENGTH_SHORT).show();
+ } else {
+ activity.finishPreferencePanel(this,
+ Activity.RESULT_OK, resultIntent);
+ }
}
return true;
diff --git a/src/com/android/settings/vpn/VpnProfileActor.java b/src/com/android/settings/vpn/VpnProfileActor.java
index da601f8..4c7b014 100644
--- a/src/com/android/settings/vpn/VpnProfileActor.java
+++ b/src/com/android/settings/vpn/VpnProfileActor.java
@@ -54,11 +54,4 @@
* Tears down the connection.
*/
void disconnect();
-
- /**
- * Checks the current status. The result is expected to be broadcast.
- * Use {@link VpnManager#registerConnectivityReceiver()} to register a
- * broadcast receiver and to receives the broadcast events.
- */
- void checkStatus();
}
diff --git a/src/com/android/settings/vpn/VpnSettings.java b/src/com/android/settings/vpn/VpnSettings.java
index 960d37e..bd1cc9e 100644
--- a/src/com/android/settings/vpn/VpnSettings.java
+++ b/src/com/android/settings/vpn/VpnSettings.java
@@ -23,12 +23,9 @@
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.BroadcastReceiver;
-import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
-import android.content.ServiceConnection;
-import android.net.vpn.IVpnService;
import android.net.vpn.L2tpIpsecProfile;
import android.net.vpn.L2tpIpsecPskProfile;
import android.net.vpn.L2tpProfile;
@@ -37,9 +34,6 @@
import android.net.vpn.VpnState;
import android.net.vpn.VpnType;
import android.os.Bundle;
-import android.os.ConditionVariable;
-import android.os.Handler;
-import android.os.IBinder;
import android.preference.Preference;
import android.preference.PreferenceActivity;
import android.preference.PreferenceCategory;
@@ -137,9 +131,7 @@
private int mConnectingErrorCode = NO_ERROR;
- private Dialog mShowingDialog;
-
- private StatusChecker mStatusChecker = new StatusChecker();
+ private Dialog mShowingDialog, mConnectDialog;
@Override
public void onCreate(Bundle savedInstanceState) {
@@ -190,7 +182,6 @@
// for long-press gesture on a profile preference
registerForContextMenu(getListView());
-
retrieveVpnListFromStorage();
restoreInstanceState(savedInstanceState);
}
@@ -216,7 +207,13 @@
mUnlockAction = null;
getActivity().runOnUiThread(action);
}
- checkVpnConnectionStatusInBackground();
+ if (mConnectDialog == null || !mConnectDialog.isShowing()) {
+ checkVpnConnectionStatus();
+ } else {
+ // Dismiss the connect dialog in case there is another instance
+ // trying to operate a vpn connection.
+ if (!mVpnManager.isIdle()) removeConnectDialog();
+ }
}
@Override
@@ -245,7 +242,8 @@
public Dialog onCreateDialog (int id) {
switch (id) {
case DIALOG_CONNECT:
- return createConnectDialog();
+ mConnectDialog = createConnectDialog();
+ return mConnectDialog;
case DIALOG_SECRET_NOT_SET:
return createSecretNotSetDialog();
@@ -261,11 +259,19 @@
}
}
+ private void removeConnectDialog() {
+ if (mConnectDialog != null) {
+ mConnectDialog.dismiss();
+ mConnectDialog = null;
+ checkVpnConnectionStatus();
+ }
+ }
+
private class ConnectDialog extends AlertDialog {
public ConnectDialog(Context context) {
super(context);
setTitle(String.format(getString(R.string.vpn_connect_to),
- mActiveProfile.getName()));
+ mConnectingActor.getProfile().getName()));
setButton(DialogInterface.BUTTON_POSITIVE,
getString(R.string.vpn_connect_button),
VpnSettings.this);
@@ -506,11 +512,11 @@
String error = mConnectingActor.validateInputs(d);
if (error == null) {
mConnectingActor.connect(d);
- removeDialog(DIALOG_CONNECT);
+ removeConnectDialog();
return;
} else {
// dismissDialog(DIALOG_CONNECT);
- removeDialog(DIALOG_CONNECT);
+ removeConnectDialog();
final Activity activity = getActivity();
// show error dialog
@@ -530,8 +536,7 @@
mShowingDialog.show();
}
} else {
- removeDialog(DIALOG_CONNECT);
- changeState(mActiveProfile, VpnState.IDLE);
+ removeConnectDialog();
}
}
@@ -620,14 +625,10 @@
saveProfileToStorage(p);
mVpnProfileList.add(p);
- addPreferenceFor(p);
+ addPreferenceFor(p, true);
disableProfilePreferencesIfOneActive();
}
- private VpnPreference addPreferenceFor(VpnProfile p) {
- return addPreferenceFor(p, true);
- }
-
// Adds a preference in mVpnListContainer
private VpnPreference addPreferenceFor(
VpnProfile p, boolean addToContainer) {
@@ -886,18 +887,23 @@
return p1.getName().compareTo(p2.getName());
}
});
+ // Delay adding preferences to mVpnListContainer until states are
+ // obtained so that the user won't see initial state transition.
for (VpnProfile p : mVpnProfileList) {
Preference pref = addPreferenceFor(p, false);
}
disableProfilePreferencesIfOneActive();
}
- private void checkVpnConnectionStatusInBackground() {
- new Thread(new Runnable() {
- public void run() {
- mStatusChecker.check(mVpnProfileList);
- }
- }).start();
+ private void checkVpnConnectionStatus() {
+ for (VpnProfile p : mVpnProfileList) {
+ changeState(p, mVpnManager.getState(p));
+ }
+ // make preferences appear
+ for (VpnProfile p : mVpnProfileList) {
+ VpnPreference pref = mVpnPreferenceMap.get(p.getName());
+ mVpnListContainer.addPreference(pref);
+ }
}
// A sanity check. Returns true if the profile directory name and profile ID
@@ -1074,61 +1080,4 @@
}
}
}
-
- // managing status check in a background thread
- private class StatusChecker {
- synchronized void check(final List<VpnProfile> list) {
- final ConditionVariable cv = new ConditionVariable();
- cv.close();
- mVpnManager.startVpnService();
- ServiceConnection c = new ServiceConnection() {
- public synchronized void onServiceConnected(
- ComponentName className, IBinder binder) {
- cv.open();
-
- IVpnService service = IVpnService.Stub.asInterface(binder);
- for (VpnProfile p : list) {
- try {
- service.checkStatus(p);
- } catch (Throwable e) {
- Log.e(TAG, " --- checkStatus(): " + p.getName(), e);
- changeState(p, VpnState.IDLE);
- }
- }
- if (getActivity() == null) return;
- getActivity().unbindService(this);
- showPreferences();
- }
-
- public void onServiceDisconnected(ComponentName className) {
- cv.open();
-
- setDefaultState(list);
- if (getActivity() == null) return;
- getActivity().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();
- }
- }
}