diff --git a/res/values/strings.xml b/res/values/strings.xml
index dd7ba1769c4..f7d76a4ecc2 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -1850,6 +1850,8 @@ found in the list of installed applications.
Are you sure you don\'t want to create this profile?
Are you sure you want to discard the changes made to this profile?
Unable to connect to the network. Do you want to try again?
+ Server name cannot be resolved. Do you want to check your server name setting?
+ The username or password you entered is incorrect. Do you want to try again?
Add VPN
@@ -1870,8 +1872,6 @@ found in the list of installed applications.
Connect to network
- nowhere
-
VPN name
a VPN name
diff --git a/src/com/android/settings/SecuritySettings.java b/src/com/android/settings/SecuritySettings.java
index 79a394800e7..b34e8b1d10b 100644
--- a/src/com/android/settings/SecuritySettings.java
+++ b/src/com/android/settings/SecuritySettings.java
@@ -442,8 +442,9 @@ public class SecuritySettings extends PreferenceActivity implements
}
}
- private class CstorHelper implements
- DialogInterface.OnClickListener, DialogInterface.OnDismissListener {
+ private class CstorHelper implements DialogInterface.OnClickListener,
+ DialogInterface.OnDismissListener,
+ DialogInterface.OnCancelListener {
private Keystore mKeystore = Keystore.getInstance();
private View mView;
private int mDialogId;
@@ -523,14 +524,18 @@ public class SecuritySettings extends PreferenceActivity implements
.show();
}
+ public void onCancel(DialogInterface dialog) {
+ if (mCstorAddCredentialHelper != null) {
+ // release the object here so that it doesn't get triggerred in
+ // onDismiss()
+ mCstorAddCredentialHelper = null;
+ finish();
+ }
+ }
+
public void onClick(DialogInterface dialog, int which) {
if (which == DialogInterface.BUTTON_NEGATIVE) {
- if (mCstorAddCredentialHelper != null) {
- // release the object here so that it doesn't get triggerred in
- // onDismiss()
- mCstorAddCredentialHelper = null;
- finish();
- }
+ onCancel(dialog);
return;
}
@@ -797,7 +802,7 @@ public class SecuritySettings extends PreferenceActivity implements
.setTitle(R.string.cstor_access_dialog_title)
.setPositiveButton(android.R.string.ok, this)
.setNegativeButton(android.R.string.cancel, this)
- .setCancelable(false)
+ .setOnCancelListener(this)
.create();
d.setOnDismissListener(this);
return d;
@@ -837,7 +842,7 @@ public class SecuritySettings extends PreferenceActivity implements
.setTitle(R.string.cstor_set_passwd_dialog_title)
.setPositiveButton(android.R.string.ok, this)
.setNegativeButton(android.R.string.cancel, this)
- .setCancelable(false)
+ .setOnCancelListener(this)
.create();
d.setOnDismissListener(this);
return d;
@@ -872,7 +877,7 @@ public class SecuritySettings extends PreferenceActivity implements
.setTitle(R.string.cstor_name_credential_dialog_title)
.setPositiveButton(android.R.string.ok, this)
.setNegativeButton(android.R.string.cancel, this)
- .setCancelable(false)
+ .setOnCancelListener(this)
.create();
d.setOnDismissListener(this);
return d;
diff --git a/src/com/android/settings/vpn/AuthenticationActor.java b/src/com/android/settings/vpn/AuthenticationActor.java
index 537438fa273..2584fbd1d77 100644
--- a/src/com/android/settings/vpn/AuthenticationActor.java
+++ b/src/com/android/settings/vpn/AuthenticationActor.java
@@ -99,14 +99,18 @@ public class AuthenticationActor implements VpnProfileActor {
//@Override
public View createConnectView() {
- return View.inflate(mContext, R.layout.vpn_connect_dialog_view, null);
- }
+ View v = View.inflate(mContext, R.layout.vpn_connect_dialog_view, null);
+ TextView usernameView = (TextView) v.findViewById(R.id.username_value);
+ TextView passwordView = (TextView) v.findViewById(R.id.password_value);
+ CheckBox saveUsername = (CheckBox) v.findViewById(R.id.save_username);
- //@Override
- public void updateConnectView(Dialog d) {
String username = mProfile.getSavedUsername();
- if (username == null) username = "";
- updateConnectView(d, username, "", !TextUtils.isEmpty(username));
+ if (!TextUtils.isEmpty(username)) {
+ usernameView.setText(username);
+ saveUsername.setChecked(true);
+ passwordView.requestFocus();
+ }
+ return v;
}
protected Context getContext() {
@@ -118,22 +122,20 @@ public class AuthenticationActor implements VpnProfileActor {
ServiceConnection c = new ServiceConnection() {
public void onServiceConnected(ComponentName className,
IBinder service) {
- boolean success = false;
try {
- success = IVpnService.Stub.asInterface(service)
+ boolean success = IVpnService.Stub.asInterface(service)
.connect(mProfile, username, password);
- } catch (Throwable e) {
- Log.e(TAG, "connect()", e);
- checkStatus();
- } finally {
- mContext.unbindService(this);
-
if (!success) {
Log.d(TAG, "~~~~~~ connect() failed!");
- broadcastConnectivity(VpnState.IDLE);
} 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);
}
}
@@ -141,7 +143,10 @@ public class AuthenticationActor implements VpnProfileActor {
checkStatus();
}
};
- if (!bindService(c)) broadcastConnectivity(VpnState.IDLE);
+ if (!bindService(c)) {
+ broadcastConnectivity(VpnState.IDLE,
+ VpnManager.VPN_ERROR_CONNECTION_FAILED);
+ }
}
//@Override
@@ -156,7 +161,6 @@ public class AuthenticationActor implements VpnProfileActor {
checkStatus();
} finally {
mContext.unbindService(this);
- broadcastConnectivity(VpnState.IDLE);
}
}
@@ -164,7 +168,9 @@ public class AuthenticationActor implements VpnProfileActor {
checkStatus();
}
};
- bindService(c);
+ if (!bindService(c)) {
+ checkStatus();
+ }
}
//@Override
@@ -174,8 +180,9 @@ public class AuthenticationActor implements VpnProfileActor {
IBinder service) {
try {
IVpnService.Stub.asInterface(service).checkStatus(mProfile);
- } catch (Throwable e) {
+ } catch (RemoteException e) {
Log.e(TAG, "checkStatus()", e);
+ broadcastConnectivity(VpnState.IDLE);
} finally {
notify();
}
@@ -196,21 +203,14 @@ public class AuthenticationActor implements VpnProfileActor {
return mVpnManager.bindVpnService(c);
}
- private void updateConnectView(Dialog d, String username,
- String password, boolean toSaveUsername) {
- TextView usernameView = (TextView) d.findViewById(R.id.username_value);
- TextView passwordView = (TextView) d.findViewById(R.id.password_value);
- CheckBox saveUsername = (CheckBox) d.findViewById(R.id.save_username);
- usernameView.setText(username);
- passwordView.setText(password);
- saveUsername.setChecked(toSaveUsername);
- if (toSaveUsername) passwordView.requestFocus();
- }
-
private void broadcastConnectivity(VpnState s) {
mVpnManager.broadcastConnectivity(mProfile.getName(), s);
}
+ private void broadcastConnectivity(VpnState s, int errorCode) {
+ mVpnManager.broadcastConnectivity(mProfile.getName(), s, errorCode);
+ }
+
private void wait(Object o, int ms) {
synchronized (o) {
try {
diff --git a/src/com/android/settings/vpn/VpnProfileActor.java b/src/com/android/settings/vpn/VpnProfileActor.java
index 1e71e864c6b..da601f8f4aa 100644
--- a/src/com/android/settings/vpn/VpnProfileActor.java
+++ b/src/com/android/settings/vpn/VpnProfileActor.java
@@ -37,12 +37,6 @@ public interface VpnProfileActor {
*/
View createConnectView();
- /**
- * Updates the view in the connect dialog.
- * @param dialog the recycled connect dialog.
- */
- void updateConnectView(Dialog dialog);
-
/**
* Validates the inputs in the dialog.
* @param dialog the connect dialog
diff --git a/src/com/android/settings/vpn/VpnSettings.java b/src/com/android/settings/vpn/VpnSettings.java
index d38b664a289..08dd8dd1cb3 100644
--- a/src/com/android/settings/vpn/VpnSettings.java
+++ b/src/com/android/settings/vpn/VpnSettings.java
@@ -99,7 +99,12 @@ public class VpnSettings extends PreferenceActivity implements
private static final int CONNECT_BUTTON = DialogInterface.BUTTON1;
private static final int OK_BUTTON = DialogInterface.BUTTON1;
- private static final int DIALOG_CONNECT = 0;
+ private static final int DIALOG_CONNECT = 1;
+ private static final int DIALOG_RECONNECT = 2;
+ private static final int DIALOG_AUTH_ERROR = 3;
+ private static final int DIALOG_UNKNOWN_SERVER = 4;
+
+ private static final int NO_ERROR = 0;
private PreferenceScreen mAddVpn;
private PreferenceCategory mVpnListContainer;
@@ -115,7 +120,6 @@ public class VpnSettings extends PreferenceActivity implements
// actor engaged in connecting
private VpnProfileActor mConnectingActor;
- private boolean mStateSaved = false;
// states saved for unlocking keystore
private Runnable mUnlockAction;
@@ -125,7 +129,9 @@ public class VpnSettings extends PreferenceActivity implements
private ConnectivityReceiver mConnectivityReceiver =
new ConnectivityReceiver();
- private boolean mConnectingError;
+ private int mConnectingErrorCode = NO_ERROR;
+
+ private Dialog mShowingDialog;
private StatusChecker mStatusChecker = new StatusChecker();
@@ -156,11 +162,10 @@ public class VpnSettings extends PreferenceActivity implements
String profileName = (savedInstanceState == null)
? null
: savedInstanceState.getString(STATE_ACTIVE_ACTOR);
- mStateSaved = !TextUtils.isEmpty(profileName);
retrieveVpnListFromStorage();
- if (mStateSaved) {
- mConnectingActor =
- getActor(mVpnPreferenceMap.get(profileName).mProfile);
+ if (!TextUtils.isEmpty(profileName)) {
+ mActiveProfile = mVpnPreferenceMap.get(profileName).mProfile;
+ mConnectingActor = getActor(mActiveProfile);
} else {
checkVpnConnectionStatusInBackground();
}
@@ -188,6 +193,7 @@ public class VpnSettings extends PreferenceActivity implements
protected synchronized void onSaveInstanceState(Bundle outState) {
if (mConnectingActor == null) return;
+ Log.d(TAG, " ~~~~~ save connecting actor");
outState.putString(STATE_ACTIVE_ACTOR,
mConnectingActor.getProfile().getName());
}
@@ -197,6 +203,9 @@ public class VpnSettings extends PreferenceActivity implements
super.onDestroy();
unregisterForContextMenu(getListView());
mVpnManager.unregisterConnectivityReceiver(mConnectivityReceiver);
+ if ((mShowingDialog != null) && mShowingDialog.isShowing()) {
+ mShowingDialog.dismiss();
+ }
}
@Override
@@ -205,39 +214,76 @@ public class VpnSettings extends PreferenceActivity implements
case DIALOG_CONNECT:
return createConnectDialog();
+ case DIALOG_RECONNECT:
+ return createReconnectDialogBuilder().create();
+
+ case DIALOG_AUTH_ERROR:
+ return createAuthErrorDialog();
+
+ case DIALOG_UNKNOWN_SERVER:
+ return createUnknownServerDialog();
+
default:
- return null;
+ return super.onCreateDialog(id);
}
}
private Dialog createConnectDialog() {
- if (mConnectingActor == null) {
- Log.e(TAG, "no connecting actor to create the dialog");
- return null;
- }
- String name = (mConnectingActor == null)
- ? getString(R.string.vpn_default_profile_name)
- : mConnectingActor.getProfile().getName();
- Dialog d = new AlertDialog.Builder(this)
+ return new AlertDialog.Builder(this)
.setView(mConnectingActor.createConnectView())
.setTitle(String.format(getString(R.string.vpn_connect_to),
- name))
+ mConnectingActor.getProfile().getName()))
.setPositiveButton(getString(R.string.vpn_connect_button),
this)
.setNegativeButton(getString(android.R.string.cancel),
this)
.create();
- return d;
}
- @Override
- protected void onPrepareDialog (int id, Dialog dialog) {
- if (mStateSaved) {
- mStateSaved = false;
- super.onPrepareDialog(id, dialog);
- } else if (mConnectingActor != null) {
- mConnectingActor.updateConnectView(dialog);
- }
+ private AlertDialog.Builder createReconnectDialogBuilder() {
+ return new AlertDialog.Builder(this)
+ .setTitle(android.R.string.dialog_alert_title)
+ .setIcon(android.R.drawable.ic_dialog_alert)
+ .setMessage(R.string.vpn_confirm_reconnect)
+ .setPositiveButton(R.string.vpn_yes_button,
+ new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int w) {
+ connectOrDisconnect(mConnectingActor.getProfile());
+ }
+ })
+ .setNegativeButton(R.string.vpn_no_button,
+ new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int w) {
+ onIdle();
+ }
+ })
+ .setOnCancelListener(new DialogInterface.OnCancelListener() {
+ public void onCancel(DialogInterface dialog) {
+ onIdle();
+ }
+ });
+ }
+
+ private Dialog createAuthErrorDialog() {
+ return createReconnectDialogBuilder()
+ .setMessage(R.string.vpn_auth_error_dialog_msg)
+ .create();
+ }
+
+ private Dialog createUnknownServerDialog() {
+ return createReconnectDialogBuilder()
+ .setMessage(R.string.vpn_unknown_server_dialog_msg)
+ .setPositiveButton(R.string.vpn_yes_button,
+ new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int w) {
+ VpnProfile p = mConnectingActor.getProfile();
+ onIdle();
+ mIndexOfEditedProfile =
+ mVpnProfileList.indexOf(p);
+ startVpnEditor(p);
+ }
+ })
+ .create();
}
@Override
@@ -252,8 +298,8 @@ public class VpnSettings extends PreferenceActivity implements
menu.setHeaderTitle(p.getName());
boolean isIdle = (state == VpnState.IDLE);
- boolean isNotConnect =
- (isIdle || (state == VpnState.DISCONNECTING));
+ boolean isNotConnect = (isIdle || (state == VpnState.DISCONNECTING)
+ || (state == VpnState.CANCELLED));
menu.add(0, CONTEXT_MENU_CONNECT_ID, 0, R.string.vpn_menu_connect)
.setEnabled(isIdle && (mActiveProfile == null));
menu.add(0, CONTEXT_MENU_DISCONNECT_ID, 0,
@@ -363,17 +409,18 @@ public class VpnSettings extends PreferenceActivity implements
// Called when the buttons on the connect dialog are clicked.
//@Override
public synchronized void onClick(DialogInterface dialog, int which) {
- dismissDialog(DIALOG_CONNECT);
if (which == CONNECT_BUTTON) {
Dialog d = (Dialog) dialog;
String error = mConnectingActor.validateInputs(d);
if (error == null) {
changeState(mConnectingActor.getProfile(), VpnState.CONNECTING);
mConnectingActor.connect(d);
+ removeDialog(DIALOG_CONNECT);
return;
} else {
+ dismissDialog(DIALOG_CONNECT);
// show error dialog
- new AlertDialog.Builder(this)
+ mShowingDialog = new AlertDialog.Builder(this)
.setTitle(android.R.string.dialog_alert_title)
.setIcon(android.R.drawable.ic_dialog_alert)
.setMessage(String.format(getString(
@@ -385,8 +432,11 @@ public class VpnSettings extends PreferenceActivity implements
showDialog(DIALOG_CONNECT);
}
})
- .show();
+ .create();
+ mShowingDialog.show();
}
+ } else {
+ removeDialog(DIALOG_CONNECT);
}
}
@@ -428,13 +478,14 @@ public class VpnSettings extends PreferenceActivity implements
}
}
};
- new AlertDialog.Builder(this)
+ mShowingDialog = new AlertDialog.Builder(this)
.setTitle(android.R.string.dialog_alert_title)
.setIcon(android.R.drawable.ic_dialog_alert)
.setMessage(R.string.vpn_confirm_profile_deletion)
.setPositiveButton(android.R.string.ok, onClickListener)
.setNegativeButton(R.string.vpn_no_button, onClickListener)
- .show();
+ .create();
+ mShowingDialog.show();
}
// Randomly generates an ID for the profile.
@@ -583,8 +634,8 @@ public class VpnSettings extends PreferenceActivity implements
}
mConnectingActor = getActor(p);
+ mActiveProfile = p;
if (mConnectingActor.isConnectDialogNeeded()) {
- removeDialog(DIALOG_CONNECT);
showDialog(DIALOG_CONNECT);
} else {
changeState(p, VpnState.CONNECTING);
@@ -605,8 +656,6 @@ public class VpnSettings extends PreferenceActivity implements
break;
case CONNECTED:
- mConnectingError = false;
- // pass through
case DISCONNECTING:
changeState(p, VpnState.DISCONNECTING);
getActor(p).disconnect();
@@ -625,16 +674,13 @@ public class VpnSettings extends PreferenceActivity implements
switch (state) {
case CONNECTED:
mConnectingActor = null;
- // pass through
- case CONNECTING:
mActiveProfile = p;
disableProfilePreferencesIfOneActive();
break;
+ case CONNECTING:
case DISCONNECTING:
- if (oldState == VpnState.CONNECTING) {
- mConnectingError = true;
- }
+ disableProfilePreferencesIfOneActive();
break;
case CANCELLED:
@@ -642,31 +688,34 @@ public class VpnSettings extends PreferenceActivity implements
break;
case IDLE:
- assert(mActiveProfile != p);
- mActiveProfile = null;
- mConnectingActor = null;
- enableProfilePreferences();
+ assert(mActiveProfile == p);
- if (oldState == VpnState.CONNECTING) mConnectingError = true;
- if (mConnectingError) showReconnectDialog(p);
+ switch (mConnectingErrorCode) {
+ case NO_ERROR:
+ onIdle();
+ break;
+
+ case VpnManager.VPN_ERROR_AUTH:
+ showDialog(DIALOG_AUTH_ERROR);
+ break;
+
+ case VpnManager.VPN_ERROR_UNKNOWN_SERVER:
+ showDialog(DIALOG_UNKNOWN_SERVER);
+ break;
+
+ default:
+ showDialog(DIALOG_RECONNECT);
+ break;
+ }
+ mConnectingErrorCode = NO_ERROR;
break;
}
}
- private void showReconnectDialog(final VpnProfile p) {
- new AlertDialog.Builder(this)
- .setTitle(android.R.string.dialog_alert_title)
- .setIcon(android.R.drawable.ic_dialog_alert)
- .setMessage(R.string.vpn_confirm_reconnect)
- .setPositiveButton(R.string.vpn_yes_button,
- new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int w) {
- dialog.dismiss();
- connectOrDisconnect(p);
- }
- })
- .setNegativeButton(R.string.vpn_no_button, null)
- .show();
+ private void onIdle() {
+ mActiveProfile = null;
+ mConnectingActor = null;
+ enableProfilePreferences();
}
private void disableProfilePreferencesIfOneActive() {
@@ -674,6 +723,7 @@ public class VpnSettings extends PreferenceActivity implements
for (VpnProfile p : mVpnProfileList) {
switch (p.getState()) {
+ case CONNECTING:
case DISCONNECTING:
case IDLE:
mVpnPreferenceMap.get(p.getName()).setEnabled(false);
@@ -856,14 +906,20 @@ public class VpnSettings extends PreferenceActivity implements
VpnState s = (VpnState) intent.getSerializableExtra(
VpnManager.BROADCAST_CONNECTION_STATE);
+
if (s == null) {
Log.e(TAG, "received null connectivity state");
return;
}
+
+ mConnectingErrorCode = intent.getIntExtra(
+ VpnManager.BROADCAST_ERROR_CODE, NO_ERROR);
+
VpnPreference pref = mVpnPreferenceMap.get(profileName);
if (pref != null) {
Log.d(TAG, "received connectivity: " + profileName
- + ": connected? " + s);
+ + ": connected? " + s
+ + " err=" + mConnectingErrorCode);
changeState(pref.mProfile, s);
} else {
Log.e(TAG, "received connectivity: " + profileName