From c5c44eed77b851e71803b972fb76fd91d5338fef Mon Sep 17 00:00:00 2001 From: Ben Komalo Date: Thu, 20 Oct 2011 14:08:20 -0700 Subject: [PATCH] Fix account creation issues. This is a theoretically dangerous issue that has surfaced only as a monkey bug so far. The issue is that callers that create an Intent set some global state, expecting that state to still be valid when the Intent is handled. However, if the process was killed before the Intent could be handled, or if that global singleton was not saved properly, that state was lost and SetupData was never initialized properly. Bug: 5337276 Change-Id: I6bd08a0dec13f54c7ba8d536ebdc87e6c559c483 --- .../activity/setup/AccountSetupBasics.java | 46 +++++++++++++------ .../email/activity/setup/SetupData.java | 1 + 2 files changed, 32 insertions(+), 15 deletions(-) diff --git a/src/com/android/email/activity/setup/AccountSetupBasics.java b/src/com/android/email/activity/setup/AccountSetupBasics.java index a54949243..cc48a7a7b 100644 --- a/src/com/android/email/activity/setup/AccountSetupBasics.java +++ b/src/com/android/email/activity/setup/AccountSetupBasics.java @@ -97,17 +97,18 @@ public class AccountSetupBasics extends AccountSetupActivity * Direct access for forcing account creation * For use by continuous automated test system (e.g. in conjunction with monkey tests) */ - private final String ACTION_CREATE_ACCOUNT = "com.android.email.CREATE_ACCOUNT"; - private final String EXTRA_CREATE_ACCOUNT_EMAIL = "EMAIL"; - private final String EXTRA_CREATE_ACCOUNT_USER = "USER"; - private final String EXTRA_CREATE_ACCOUNT_INCOMING = "INCOMING"; - private final String EXTRA_CREATE_ACCOUNT_OUTGOING = "OUTGOING"; - private final Boolean DEBUG_ALLOW_NON_TEST_HARNESS_CREATION = false; + private static final String ACTION_CREATE_ACCOUNT = "com.android.email.CREATE_ACCOUNT"; + private static final String EXTRA_FLOW_MODE = "FLOW_MODE"; + private static final String EXTRA_CREATE_ACCOUNT_EMAIL = "EMAIL"; + private static final String EXTRA_CREATE_ACCOUNT_USER = "USER"; + private static final String EXTRA_CREATE_ACCOUNT_INCOMING = "INCOMING"; + private static final String EXTRA_CREATE_ACCOUNT_OUTGOING = "OUTGOING"; + private static final Boolean DEBUG_ALLOW_NON_TEST_HARNESS_CREATION = false; - private final static String STATE_KEY_PROVIDER = "AccountSetupBasics.provider"; + private static final String STATE_KEY_PROVIDER = "AccountSetupBasics.provider"; // NOTE: If you change this value, confirm that the new interval exists in arrays.xml - private final static int DEFAULT_ACCOUNT_CHECK_INTERVAL = 15; + private static final int DEFAULT_ACCOUNT_CHECK_INTERVAL = 15; // Support for UI private TextView mWelcomeView; @@ -126,8 +127,9 @@ public class AccountSetupBasics extends AccountSetupActivity FutureTask mOwnerLookupTask; public static void actionNewAccount(Activity fromActivity) { - SetupData.init(SetupData.FLOW_MODE_NORMAL); - fromActivity.startActivity(new Intent(fromActivity, AccountSetupBasics.class)); + Intent i = new Intent(fromActivity, AccountSetupBasics.class); + i.putExtra(EXTRA_FLOW_MODE, SetupData.FLOW_MODE_NORMAL); + fromActivity.startActivity(i); } /** @@ -135,8 +137,9 @@ public class AccountSetupBasics extends AccountSetupActivity * for exchange accounts. */ public static Intent actionSetupExchangeIntent(Context context) { - SetupData.init(SetupData.FLOW_MODE_ACCOUNT_MANAGER_EAS); - return new Intent(context, AccountSetupBasics.class); + Intent i = new Intent(context, AccountSetupBasics.class); + i.putExtra(EXTRA_FLOW_MODE, SetupData.FLOW_MODE_ACCOUNT_MANAGER_EAS); + return i; } /** @@ -144,11 +147,16 @@ public class AccountSetupBasics extends AccountSetupActivity * for pop/imap accounts. */ public static Intent actionSetupPopImapIntent(Context context) { - SetupData.init(SetupData.FLOW_MODE_ACCOUNT_MANAGER_POP_IMAP); - return new Intent(context, AccountSetupBasics.class); + Intent i = new Intent(context, AccountSetupBasics.class); + i.putExtra(EXTRA_FLOW_MODE, SetupData.FLOW_MODE_ACCOUNT_MANAGER_POP_IMAP); + return i; } public static void actionAccountCreateFinishedAccountFlow(Activity fromActivity) { + // TODO: handle this case - modifying state on SetupData when instantiating an Intent + // is not safe, since it's not guaranteed that an Activity will run with the Intent, and + // information can get lost. + Intent i= new Intent(fromActivity, AccountSetupBasics.class); // If we're in the "account flow" (from AccountManager), we want to return to the caller // (in the settings app) @@ -183,7 +191,15 @@ public class AccountSetupBasics extends AccountSetupActivity SetupData.init(SetupData.FLOW_MODE_FORCE_CREATE); } - int flowMode = SetupData.getFlowMode(); + int flowMode = getIntent().getIntExtra(EXTRA_FLOW_MODE, SetupData.FLOW_MODE_UNSPECIFIED); + if (flowMode != SetupData.FLOW_MODE_UNSPECIFIED) { + SetupData.init(flowMode); + } else { + // TODO: get rid of this case. It's not safe to rely on this global static state. It + // should be specified in the Intent always. + flowMode = SetupData.getFlowMode(); + } + if (flowMode == SetupData.FLOW_MODE_RETURN_TO_CALLER) { // Return to the caller who initiated account creation finish(); diff --git a/src/com/android/email/activity/setup/SetupData.java b/src/com/android/email/activity/setup/SetupData.java index 460688432..dcc907dad 100644 --- a/src/com/android/email/activity/setup/SetupData.java +++ b/src/com/android/email/activity/setup/SetupData.java @@ -30,6 +30,7 @@ public class SetupData implements Parcelable { // NORMAL is the standard entry from the Email app; EAS and POP_IMAP are used when entering via // Settings -> Accounts + public static final int FLOW_MODE_UNSPECIFIED = -1; public static final int FLOW_MODE_NORMAL = 0; public static final int FLOW_MODE_ACCOUNT_MANAGER_EAS = 1; public static final int FLOW_MODE_ACCOUNT_MANAGER_POP_IMAP = 2;