diff --git a/emailcommon/src/com/android/emailcommon/provider/EmailContent.java b/emailcommon/src/com/android/emailcommon/provider/EmailContent.java index 384605f1f..c030df751 100644 --- a/emailcommon/src/com/android/emailcommon/provider/EmailContent.java +++ b/emailcommon/src/com/android/emailcommon/provider/EmailContent.java @@ -1077,7 +1077,7 @@ public abstract class EmailContent { public static final String UNREAD_COUNT_SELECTION = MessageColumns.MAILBOX_KEY + " =? and " + MessageColumns.FLAG_READ + "= 0"; - public static final String UUID_SELECTION = AccountColumns.COMPATIBILITY_UUID + " =?"; + private static final String UUID_SELECTION = AccountColumns.COMPATIBILITY_UUID + " =?"; public static final String SECURITY_NONZERO_SELECTION = Account.SECURITY_FLAGS + " IS NOT NULL AND " + Account.SECURITY_FLAGS + "!=0"; @@ -1479,9 +1479,16 @@ public abstract class EmailContent { } // Now id is a UUId. + return getAccountIdFromUuid(context, id); + } + + /** + * @return ID of the account with the given UUID. + */ + public static long getAccountIdFromUuid(Context context, String uuid) { return Utility.getFirstRowLong(context, CONTENT_URI, ID_PROJECTION, - UUID_SELECTION, new String[] {id}, null, 0, Long.valueOf(-1)); + UUID_SELECTION, new String[] {uuid}, null, 0, -1L); } /** diff --git a/src/com/android/email/activity/AccountShortcutPicker.java b/src/com/android/email/activity/AccountShortcutPicker.java index 0145fc91d..1bcf2595e 100644 --- a/src/com/android/email/activity/AccountShortcutPicker.java +++ b/src/com/android/email/activity/AccountShortcutPicker.java @@ -177,7 +177,7 @@ public class AccountShortcutPicker extends ListActivity */ private void setupShortcut(Account account) { // First, set up the shortcut intent. - Intent shortcutIntent = Welcome.createOpenAccountInboxIntent(this, account.mId); + Intent shortcutIntent = Welcome.createAccountShortcutIntent(this, account); // Then, set up the container intent (the response to the caller) Intent intent = new Intent(); diff --git a/src/com/android/email/activity/IntentUtilities.java b/src/com/android/email/activity/IntentUtilities.java index 218e018c6..95a193414 100644 --- a/src/com/android/email/activity/IntentUtilities.java +++ b/src/com/android/email/activity/IntentUtilities.java @@ -16,6 +16,8 @@ package com.android.email.activity; +import com.android.emailcommon.provider.EmailContent.Account; + import android.app.Activity; import android.content.Context; import android.content.Intent; @@ -30,6 +32,7 @@ public final class IntentUtilities { private static final String ACCOUNT_ID_PARAM = "ACCOUNT_ID"; private static final String MAILBOX_ID_PARAM = "MAILBOX_ID"; private static final String MESSAGE_ID_PARAM = "MESSAGE_ID"; + private static final String ACCOUNT_UUID_PARAM = "ACCOUNT_UUID"; private IntentUtilities() { } @@ -72,6 +75,16 @@ public final class IntentUtilities { } } + /** + * Add the account UUID parameter. + */ + public static void setAccountUuid(Uri.Builder b, String mUuid) { + if (TextUtils.isEmpty(mUuid)) { + throw new IllegalArgumentException(); + } + b.appendQueryParameter(ACCOUNT_UUID_PARAM, mUuid); + } + /** * Retrieve the account ID. */ @@ -93,6 +106,18 @@ public final class IntentUtilities { return getLongFromIntent(intent, MESSAGE_ID_PARAM); } + /** + * Retrieve the account UUID, or null if the UUID param is not found. + */ + public static String getAccountUuidFromIntent(Intent intent) { + final Uri uri = intent.getData(); + if (uri == null) { + return null; + } + String uuid = uri.getQueryParameter(ACCOUNT_UUID_PARAM); + return TextUtils.isEmpty(uuid) ? null : uuid; + } + private static long getLongFromIntent(Intent intent, String paramName) { long value = -1; if (intent.getData() != null) { diff --git a/src/com/android/email/activity/Welcome.java b/src/com/android/email/activity/Welcome.java index f019d8ef7..5719e2304 100644 --- a/src/com/android/email/activity/Welcome.java +++ b/src/com/android/email/activity/Welcome.java @@ -32,6 +32,7 @@ import android.content.Intent; import android.content.res.Configuration; import android.net.Uri; import android.os.Bundle; +import android.text.TextUtils; /** * The Welcome activity initializes the application and decides what Activity @@ -124,6 +125,17 @@ public class Welcome extends Activity { fromActivity.startActivity(createOpenAccountInboxIntent(fromActivity, accountId)); } + /** + * Create an {@link Intent} for account shortcuts. The returned intent stores the account's + * UUID rather than the account ID, which will be changed after account restore. + */ + public static Intent createAccountShortcutIntent(Context context, Account account) { + final Uri.Builder b = IntentUtilities.createActivityIntentUrlBuilder( + VIEW_MAILBOX_INTENT_URL_PATH); + IntentUtilities.setAccountUuid(b, account.mCompatibilityUuid); + return IntentUtilities.createRestartAppIntent(b.build()); + } + /** * Parse the {@link #EXTRA_DEBUG_PANE_MODE} extra and return 1 or 2, if it's set to "1" or "2". * Return 0 otherwise. @@ -163,13 +175,7 @@ public class Welcome extends Activity { // TODO More completely separate ExchangeService from Email app ExchangeUtils.startExchangeService(this); - final Intent intent = getIntent(); - final long accountId = IntentUtilities.getAccountIdFromIntent(intent); - final long mailboxId = IntentUtilities.getMailboxIdFromIntent(intent); - final long messageId = IntentUtilities.getMessageIdFromIntent(intent); - final int debugPaneMode = getDebugPaneMode(getIntent()); - new MainActivityLauncher(this, accountId, mailboxId, messageId, debugPaneMode) - .executeParallel(); + new MainActivityLauncher(this, getIntent()).executeParallel(); } @Override @@ -184,21 +190,23 @@ public class Welcome extends Activity { * * if {@code account} is -1, open the default account. */ - private static class MainActivityLauncher extends EmailAsyncTask { + /* package */ static class MainActivityLauncher extends EmailAsyncTask { private final Welcome mFromActivity; private final int mDebugPaneMode; private final long mAccountId; private final long mMailboxId; private final long mMessageId; + private final String mAccountUuid; - public MainActivityLauncher(Welcome fromActivity, long accountId, long mailboxId, - long messageId, int debugPaneMode) { + public MainActivityLauncher(Welcome fromActivity, Intent intent) { super(fromActivity.mTaskTracker); mFromActivity = fromActivity; - mAccountId = accountId; - mMailboxId = mailboxId; - mMessageId = messageId; - mDebugPaneMode = debugPaneMode; + + mAccountId = IntentUtilities.getAccountIdFromIntent(intent); + mMailboxId = IntentUtilities.getMailboxIdFromIntent(intent); + mMessageId = IntentUtilities.getMessageIdFromIntent(intent); + mAccountUuid = IntentUtilities.getAccountUuidFromIntent(intent); + mDebugPaneMode = getDebugPaneMode(intent); } private boolean isMailboxSelected() { @@ -209,6 +217,16 @@ public class Welcome extends Activity { return mMessageId != -1; } + /* package */ static long resolveAccountId(Context context, long accountId, String uuid) { + if (!TextUtils.isEmpty(uuid)) { + accountId = Account.getAccountIdFromUuid(context, uuid); + } + if (accountId == -1 || !Account.isValidId(context, accountId)) { + accountId = EmailContent.Account.getDefaultAccountId(context); + } + return accountId; + } + @Override protected Void doInBackground(Void... params) { // Reconcile POP/IMAP accounts. EAS accounts are taken care of by ExchangeService. @@ -219,10 +237,7 @@ public class Welcome extends Activity { if (numAccount == 0) { AccountSetupBasics.actionNewAccount(mFromActivity); } else { - long accountId = mAccountId; - if (accountId == -1 || !Account.isValidId(mFromActivity, accountId)) { - accountId = EmailContent.Account.getDefaultAccountId(mFromActivity); - } + final long accountId = resolveAccountId(mFromActivity, mAccountId, mAccountUuid); final boolean useTwoPane = (mDebugPaneMode == 2) || (useTwoPane(mFromActivity) && mDebugPaneMode == 0); diff --git a/tests/src/com/android/email/activity/IntentUtilitiesTests.java b/tests/src/com/android/email/activity/IntentUtilitiesTests.java index 7d0ca546d..e68f31d85 100644 --- a/tests/src/com/android/email/activity/IntentUtilitiesTests.java +++ b/tests/src/com/android/email/activity/IntentUtilitiesTests.java @@ -28,6 +28,7 @@ public class IntentUtilitiesTests extends AndroidTestCase { IntentUtilities.setAccountId(b, 10); IntentUtilities.setMailboxId(b, 20); IntentUtilities.setMessageId(b, 30); + IntentUtilities.setAccountUuid(b, "*uuid*"); final Uri u = b.build(); assertEquals("content", u.getScheme()); @@ -38,6 +39,7 @@ public class IntentUtilitiesTests extends AndroidTestCase { assertEquals(10, IntentUtilities.getAccountIdFromIntent(i)); assertEquals(20, IntentUtilities.getMailboxIdFromIntent(i)); assertEquals(30, IntentUtilities.getMessageIdFromIntent(i)); + assertEquals("*uuid*", IntentUtilities.getAccountUuidFromIntent(i)); } public void testGetIdFromIntent() { @@ -82,4 +84,24 @@ public class IntentUtilitiesTests extends AndroidTestCase { i = new Intent(Intent.ACTION_VIEW, Uri.parse(uri.replace("ID", "MESSAGE_ID"))); assertEquals(expected, IntentUtilities.getMessageIdFromIntent(i)); } + + public void testGetAccountUuidFromIntent() { + Intent i; + + // No URL in intent + i = new Intent(getContext(), getClass()); + assertEquals(null, IntentUtilities.getAccountUuidFromIntent(i)); + + // No param + i = new Intent(Intent.ACTION_VIEW, Uri.parse("content://s/")); + assertEquals(null, IntentUtilities.getAccountUuidFromIntent(i)); + + // No value + i = new Intent(Intent.ACTION_VIEW, Uri.parse("content://s/?ACCOUNT_UUID=")); + assertEquals(null, IntentUtilities.getAccountUuidFromIntent(i)); + + // With valid UUID + i = new Intent(Intent.ACTION_VIEW, Uri.parse("content://s/?ACCOUNT_UUID=xyz")); + assertEquals("xyz", IntentUtilities.getAccountUuidFromIntent(i)); + } } diff --git a/tests/src/com/android/email/activity/WelcomeTests.java b/tests/src/com/android/email/activity/WelcomeTests.java new file mode 100644 index 000000000..98144eb80 --- /dev/null +++ b/tests/src/com/android/email/activity/WelcomeTests.java @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.email.activity; + +import com.android.email.DBTestHelper; +import com.android.email.provider.ProviderTestUtils; +import com.android.emailcommon.provider.EmailContent.Account; + +import android.content.Context; +import android.test.AndroidTestCase; + +public class WelcomeTests extends AndroidTestCase { + + private Context mProviderContext; + + @Override + protected void setUp() throws Exception { + super.setUp(); + mProviderContext = DBTestHelper.ProviderContextSetupHelper.getProviderContext( + getContext()); + } + + public void testResolveAccountId() { + final Context c = mProviderContext; + final Account account1 = ProviderTestUtils.setupAccount("account-1", true, c); + final long id1 = account1.mId; + final Account account2 = ProviderTestUtils.setupAccount("account-2", true, c); + final long id2 = account2.mId; + final Account account3 = ProviderTestUtils.setupAccount("account-3", true, c); + final long id3 = account3.mId; + + // Make sure the last one created (account 3) is the default. + assertTrue(Account.getDefaultAccountId(c) == id3); + + // No account specified -- should return the default account. + assertEquals(id3, Welcome.MainActivityLauncher.resolveAccountId(c, -1, null)); + + // Invalid account id -- should return the default account. + assertEquals(id3, Welcome.MainActivityLauncher.resolveAccountId(c, 12345, null)); + + // Valid ID + assertEquals(id1, Welcome.MainActivityLauncher.resolveAccountId(c, id1, null)); + + // Invalid UUID -- should return the default account. + assertEquals(id3, Welcome.MainActivityLauncher.resolveAccountId(c, -1, "xxx")); + + // Valid UUID + assertEquals(id1, Welcome.MainActivityLauncher.resolveAccountId(c, -1, + account1.mCompatibilityUuid)); + } +}