diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 218ff0fdc..524062f34 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -92,12 +92,20 @@ android:name=".activity.Welcome" > - - - + + + + + + + + + + @@ -154,6 +162,15 @@ + + + + + clazz) { - Intent i = new Intent(context, clazz); - i.setAction(Intent.ACTION_MAIN); - i.addCategory(Intent.CATEGORY_LAUNCHER); - i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); - i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - return i; - } - /** * Legacy URI parser. Used in one of three different scenarios: * 1. Backup / Restore of account diff --git a/src/com/android/email/NotificationController.java b/src/com/android/email/NotificationController.java index 4695afe12..bc7cb4350 100644 --- a/src/com/android/email/NotificationController.java +++ b/src/com/android/email/NotificationController.java @@ -18,6 +18,7 @@ package com.android.email; import com.android.email.activity.ContactStatusLoader; import com.android.email.activity.Welcome; +import com.android.email.activity.setup.AccountSecurity; import com.android.email.activity.setup.AccountSettingsXL; import com.android.emailcommon.mail.Address; import com.android.emailcommon.provider.EmailContent; @@ -43,15 +44,15 @@ import java.util.concurrent.atomic.AtomicInteger; /** * Class that manages notifications. - * - * TODO Gather all notification related code here */ public class NotificationController { - public static final int NOTIFICATION_ID_SECURITY_NEEDED = 1; - public static final int NOTIFICATION_ID_EXCHANGE_CALENDAR_ADDED = 2; - public static final int NOTIFICATION_ID_ATTACHMENT_WARNING = 3; - public static final int NOTIFICATION_ID_PASSWORD_EXPIRING = 4; - public static final int NOTIFICATION_ID_PASSWORD_EXPIRED = 5; + private static final int NOTIFICATION_ID_SECURITY_NEEDED = 1; + + // ID reserved for CalendarSyncEnabler + private static final int PLACEHOLDER_NOTIFICATION_ID_EXCHANGE_CALENDAR_ADDED = 2; + private static final int NOTIFICATION_ID_ATTACHMENT_WARNING = 3; + private static final int NOTIFICATION_ID_PASSWORD_EXPIRING = 4; + private static final int NOTIFICATION_ID_PASSWORD_EXPIRED = 5; private static final int NOTIFICATION_ID_BASE_NEW_MESSAGES = 0x10000000; private static final int NOTIFICATION_ID_BASE_LOGIN_WARNING = 0x20000000; @@ -93,13 +94,12 @@ public class NotificationController { * @param intent The intent to launch from the notification * @param notificationId The notification id */ - public void postAccountNotification(Account account, String ticker, String contentTitle, + private void showAccountNotification(Account account, String ticker, String contentTitle, String contentText, Intent intent, int notificationId) { // Pending Intent PendingIntent pending = null; if (intent != null) { - intent = rewriteForPendingIntent(intent); pending = PendingIntent.getActivity(mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); } @@ -137,7 +137,7 @@ public class NotificationController { * Generic notification canceler. * @param notificationId The notification id */ - public void cancelNotification(int notificationId) { + private void cancelNotification(int notificationId) { mNotificationManager.cancel(notificationId); } @@ -203,26 +203,6 @@ public class NotificationController { private static final AtomicInteger sSequenceNumber = new AtomicInteger(); - /** - * Rewrite an intent so that it'll always look unique to {@link PendingIntent}. - * - * TODO This should be removed. Instead, use URIs which is unique to each account to open - * activities. - */ - private static Intent rewriteForPendingIntent(Intent original) { - if (original.getComponent() == null) { - return original; // Doesn't have a component set -- can't set a URI. - } - Uri.Builder builder = new Uri.Builder(); - builder.scheme("content"); - builder.authority("email-dummy"); - builder.appendEncodedPath(Integer.toString(sSequenceNumber.incrementAndGet())); - - // If a componentName is set, the data part won't be used to resolve an intent. - original.setData(builder.build()); - return original; - } - /** * Create a notification * @@ -249,7 +229,7 @@ public class NotificationController { // Intent to open inbox PendingIntent contentIntent = PendingIntent.getActivity(mContext, 0, - rewriteForPendingIntent(Welcome.createOpenAccountInboxIntent(mContext, accountId)), + Welcome.createOpenAccountInboxIntent(mContext, accountId), 0); Notification.Builder builder = new Notification.Builder(mContext) @@ -332,7 +312,7 @@ public class NotificationController { public void showDownloadForwardFailedNotification(Attachment attachment) { final Account account = Account.restoreAccountWithId(mContext, attachment.mAccountKey); if (account == null) return; - postAccountNotification(account, + showAccountNotification(account, mContext.getString(R.string.forward_download_failed_ticker), mContext.getString(R.string.forward_download_failed_title), attachment.mFileName, @@ -354,7 +334,7 @@ public class NotificationController { public void showLoginFailedNotification(long accountId) { final Account account = Account.restoreAccountWithId(mContext, accountId); if (account == null) return; - postAccountNotification(account, + showAccountNotification(account, mContext.getString(R.string.login_failed_ticker, account.mDisplayName), mContext.getString(R.string.login_failed_title), account.getDisplayName(), @@ -366,4 +346,69 @@ public class NotificationController { public void cancelLoginFailedNotification(long accountId) { mNotificationManager.cancel(getLoginFailedNotificationId(accountId)); } + + /** + * Show "password expiring" notification. + * + * Note all accounts share the same notification ID. + */ + public void showPasswordExpiringNotification(long accountId) { + Account account = Account.restoreAccountWithId(mContext, accountId); + if (account == null) return; + Intent intent = AccountSecurity.actionDevicePasswordExpirationIntent(mContext, + accountId, false); + String ticker = mContext.getString( + R.string.password_expire_warning_ticker_fmt, account.getDisplayName()); + String contentTitle = mContext.getString( + R.string.password_expire_warning_content_title); + String contentText = account.getDisplayName(); + showAccountNotification(account, ticker, contentTitle, contentText, intent, + NOTIFICATION_ID_PASSWORD_EXPIRING); + } + + /** + * Show "password expired" notification. + * + * Note all accounts share the same notification ID. + */ + public void showPasswordExpiredNotification(long accountId) { + Account account = Account.restoreAccountWithId(mContext, accountId); + if (account == null) return; + Intent intent = AccountSecurity.actionDevicePasswordExpirationIntent(mContext, + accountId, true); + String ticker = mContext.getString(R.string.password_expired_ticker); + String contentTitle = mContext.getString(R.string.password_expired_content_title); + String contentText = account.getDisplayName(); + showAccountNotification(account, ticker, contentTitle, + contentText, intent, NOTIFICATION_ID_PASSWORD_EXPIRED); + } + + /** + * Cancel both "password expired/expiring" notifications. + */ + public void cancelPasswordExpirationNotifications() { + cancelNotification(NOTIFICATION_ID_PASSWORD_EXPIRING); + cancelNotification(NOTIFICATION_ID_PASSWORD_EXPIRED); + } + + /** + * Show "security needed" notification. + */ + public void showSecurityNeededNotification(Account account) { + String tickerText = mContext.getString(R.string.security_notification_ticker_fmt, + account.getDisplayName()); + String contentTitle = mContext.getString(R.string.security_notification_content_title); + String contentText = account.getDisplayName(); + Intent intent = AccountSecurity.actionUpdateSecurityIntent(mContext, account.mId, true); + showAccountNotification( + account, tickerText, contentTitle, contentText, intent, + NOTIFICATION_ID_SECURITY_NEEDED); + } + + /** + * Cancel "security needed" notification. + */ + public void cancelSecurityNeededNotification() { + cancelNotification(NOTIFICATION_ID_SECURITY_NEEDED); + } } diff --git a/src/com/android/email/SecurityPolicy.java b/src/com/android/email/SecurityPolicy.java index 2362faa9d..557156b7e 100644 --- a/src/com/android/email/SecurityPolicy.java +++ b/src/com/android/email/SecurityPolicy.java @@ -502,14 +502,7 @@ public class SecurityPolicy { setAccountHoldFlag(mContext, account, true); // Put up a notification - String tickerText = mContext.getString(R.string.security_notification_ticker_fmt, - account.getDisplayName()); - String contentTitle = mContext.getString(R.string.security_notification_content_title); - String contentText = account.getDisplayName(); - Intent intent = AccountSecurity.actionUpdateSecurityIntent(mContext, accountId, true); - NotificationController.getInstance(mContext).postAccountNotification( - account, tickerText, contentTitle, contentText, intent, - NotificationController.NOTIFICATION_ID_SECURITY_NEEDED); + NotificationController.getInstance(mContext).showSecurityNeededNotification(account); } /** @@ -517,8 +510,7 @@ public class SecurityPolicy { * cleared now. */ public void clearNotification(long accountId) { - NotificationController.getInstance(mContext).cancelNotification( - NotificationController.NOTIFICATION_ID_SECURITY_NEEDED); + NotificationController.getInstance(mContext).cancelSecurityNeededNotification(); } /** @@ -617,34 +609,14 @@ public class SecurityPolicy { if (!expired) { // 4. If warning, simply put up a generic notification and report that it came from // the shortest-expiring account. - Account account = Account.restoreAccountWithId(context, nextExpiringAccountId); - if (account == null) return; - Intent intent = AccountSecurity.actionDevicePasswordExpirationIntent(context, - nextExpiringAccountId, false); - String ticker = context.getString( - R.string.password_expire_warning_ticker_fmt, account.getDisplayName()); - String contentTitle = context.getString( - R.string.password_expire_warning_content_title); - String contentText = account.getDisplayName(); - NotificationController nc = NotificationController.getInstance(mContext); - nc.postAccountNotification(account, ticker, contentTitle, contentText, intent, - NotificationController.NOTIFICATION_ID_PASSWORD_EXPIRING); + NotificationController.getInstance(mContext).showPasswordExpiringNotification( + nextExpiringAccountId); } else { // 5. Actually expired - find all accounts that expire passwords, and wipe them boolean wiped = wipeExpiredAccounts(context, Controller.getInstance(context)); if (wiped) { - // Post notification - Account account = Account.restoreAccountWithId(context, nextExpiringAccountId); - if (account == null) return; - Intent intent = AccountSecurity.actionDevicePasswordExpirationIntent(context, - nextExpiringAccountId, true); - String ticker = context.getString(R.string.password_expired_ticker); - String contentTitle = context.getString(R.string.password_expired_content_title); - String contentText = account.getDisplayName(); - NotificationController nc = NotificationController.getInstance(mContext); - nc.postAccountNotification(account, ticker, contentTitle, - contentText, intent, - NotificationController.NOTIFICATION_ID_PASSWORD_EXPIRED); + NotificationController.getInstance(mContext).showPasswordExpiredNotification( + nextExpiringAccountId); } } } @@ -732,9 +704,7 @@ public class SecurityPolicy { // Clear security holds (if any) Account.clearSecurityHoldOnAllAccounts(context); // Cancel any active notifications (if any are posted) - NotificationController nc = NotificationController.getInstance(context); - nc.cancelNotification(NotificationController.NOTIFICATION_ID_PASSWORD_EXPIRING); - nc.cancelNotification(NotificationController.NOTIFICATION_ID_PASSWORD_EXPIRED); + NotificationController.getInstance(context).cancelPasswordExpirationNotifications(); break; case DEVICE_ADMIN_MESSAGE_PASSWORD_EXPIRING: instance.onPasswordExpiring(instance.mContext); diff --git a/src/com/android/email/activity/IntentUtilities.java b/src/com/android/email/activity/IntentUtilities.java new file mode 100644 index 000000000..218e018c6 --- /dev/null +++ b/src/com/android/email/activity/IntentUtilities.java @@ -0,0 +1,142 @@ +/* + * 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 android.app.Activity; +import android.content.Context; +import android.content.Intent; +import android.net.Uri; +import android.text.TextUtils; + +public final class IntentUtilities { + // Format for activity URIs: content://ui.email.android.com/... + private static final String ACTIVITY_INTENT_SCHEME = "content"; + private static final String ACTIVITY_INTENT_HOST = "ui.email.android.com"; + + 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 IntentUtilities() { + } + + /** + * @return a URI builder for "content://ui.email.android.com/..." + */ + public static Uri.Builder createActivityIntentUrlBuilder(String path) { + final Uri.Builder b = new Uri.Builder(); + b.scheme(ACTIVITY_INTENT_SCHEME); + b.authority(ACTIVITY_INTENT_HOST); + b.path(path); + return b; + } + + /** + * Add the account ID parameter. + */ + public static void setAccountId(Uri.Builder b, long accountId) { + if (accountId != -1) { + b.appendQueryParameter(ACCOUNT_ID_PARAM, Long.toString(accountId)); + } + } + + /** + * Add the mailbox ID parameter. + */ + public static void setMailboxId(Uri.Builder b, long mailboxId) { + if (mailboxId != -1) { + b.appendQueryParameter(MAILBOX_ID_PARAM, Long.toString(mailboxId)); + } + } + + /** + * Add the message ID parameter. + */ + public static void setMessageId(Uri.Builder b, long messageId) { + if (messageId != -1) { + b.appendQueryParameter(MESSAGE_ID_PARAM, Long.toString(messageId)); + } + } + + /** + * Retrieve the account ID. + */ + public static long getAccountIdFromIntent(Intent intent) { + return getLongFromIntent(intent, ACCOUNT_ID_PARAM); + } + + /** + * Retrieve the mailbox ID. + */ + public static long getMailboxIdFromIntent(Intent intent) { + return getLongFromIntent(intent, MAILBOX_ID_PARAM); + } + + /** + * Retrieve the message ID. + */ + public static long getMessageIdFromIntent(Intent intent) { + return getLongFromIntent(intent, MESSAGE_ID_PARAM); + } + + private static long getLongFromIntent(Intent intent, String paramName) { + long value = -1; + if (intent.getData() != null) { + value = getLongParamFromUri(intent.getData(), paramName, -1); + } + return value; + } + + private static long getLongParamFromUri(Uri uri, String paramName, long defaultValue) { + final String value = uri.getQueryParameter(paramName); + if (!TextUtils.isEmpty(value)) { + try { + return Long.parseLong(value); + } catch (NumberFormatException e) { + // return default + } + } + return defaultValue; + } + + /** + * Create an {@link Intent} to launch an activity as the main entry point. Existing activities + * will all be closed. + */ + public static Intent createRestartAppIntent(Context context, Class clazz) { + Intent i = new Intent(context, clazz); + prepareRestartAppIntent(i); + return i; + } + + /** + * Create an {@link Intent} to launch an activity as the main entry point. Existing activities + * will all be closed. + */ + public static Intent createRestartAppIntent(Uri data) { + Intent i = new Intent(Intent.ACTION_MAIN, data); + prepareRestartAppIntent(i); + return i; + } + + private static void prepareRestartAppIntent(Intent i) { + i.setAction(Intent.ACTION_MAIN); + i.addCategory(Intent.CATEGORY_LAUNCHER); + i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + } +} diff --git a/src/com/android/email/activity/MessageListXL.java b/src/com/android/email/activity/MessageListXL.java index 45b60fd6f..bb2ad7db5 100644 --- a/src/com/android/email/activity/MessageListXL.java +++ b/src/com/android/email/activity/MessageListXL.java @@ -31,7 +31,6 @@ import com.android.emailcommon.mail.MessagingException; import com.android.emailcommon.provider.EmailContent.Account; import com.android.emailcommon.provider.EmailContent.Mailbox; import com.android.emailcommon.utility.EmailAsyncTask; -import com.android.emailcommon.utility.Utility; import android.app.ActionBar; import android.app.Activity; @@ -103,7 +102,7 @@ public class MessageListXL extends Activity implements * @param accountId If -1, default account will be used. */ public static void actionOpenAccount(Activity fromActivity, long accountId) { - Intent i = Utility.createRestartAppIntent(fromActivity, MessageListXL.class); + Intent i = IntentUtilities.createRestartAppIntent(fromActivity, MessageListXL.class); if (accountId != -1) { i.putExtra(EXTRA_ACCOUNT_ID, accountId); } @@ -121,7 +120,7 @@ public class MessageListXL extends Activity implements if (accountId == -1 || mailboxId == -1) { throw new InvalidParameterException(); } - Intent i = Utility.createRestartAppIntent(fromActivity, MessageListXL.class); + Intent i = IntentUtilities.createRestartAppIntent(fromActivity, MessageListXL.class); i.putExtra(EXTRA_ACCOUNT_ID, accountId); i.putExtra(EXTRA_MAILBOX_ID, mailboxId); fromActivity.startActivity(i); @@ -140,7 +139,7 @@ public class MessageListXL extends Activity implements if (accountId == -1 || mailboxId == -1 || messageId == -1) { throw new InvalidParameterException(); } - Intent i = Utility.createRestartAppIntent(fromActivity, MessageListXL.class); + Intent i = IntentUtilities.createRestartAppIntent(fromActivity, MessageListXL.class); i.putExtra(EXTRA_ACCOUNT_ID, accountId); i.putExtra(EXTRA_MAILBOX_ID, mailboxId); i.putExtra(EXTRA_MESSAGE_ID, messageId); diff --git a/src/com/android/email/activity/Welcome.java b/src/com/android/email/activity/Welcome.java index 22c575dc3..2a4de4c60 100644 --- a/src/com/android/email/activity/Welcome.java +++ b/src/com/android/email/activity/Welcome.java @@ -24,15 +24,14 @@ import com.android.email.service.MailService; import com.android.emailcommon.provider.EmailContent; import com.android.emailcommon.provider.EmailContent.Account; import com.android.emailcommon.provider.EmailContent.Mailbox; -import com.android.emailcommon.utility.Utility; import android.app.Activity; import android.content.Context; import android.content.Intent; import android.content.res.Configuration; +import android.net.Uri; import android.os.AsyncTask; import android.os.Bundle; -import android.os.Handler; /** * The Welcome activity initializes the application and decides what Activity @@ -47,38 +46,32 @@ public class Welcome extends Activity { * Commands for testing... * Open 1 pane adb shell am start -a android.intent.action.MAIN \ - -n com.google.android.email/com.android.email.activity.Welcome \ + -d '"content://ui.email.android.com/view/mailbox"' \ -e DEBUG_PANE_MODE 1 * Open 2 pane adb shell am start -a android.intent.action.MAIN \ - -n com.google.android.email/com.android.email.activity.Welcome \ + -d '"content://ui.email.android.com/view/mailbox"' \ -e DEBUG_PANE_MODE 2 - * Open an account (ID=2) in 2 pane + * Open an account (ID=1) in 2 pane adb shell am start -a android.intent.action.MAIN \ - -n com.google.android.email/com.android.email.activity.Welcome \ - -e DEBUG_PANE_MODE 2 --el ACCOUNT_ID 2 + -d '"content://ui.email.android.com/view/mailbox?ACCOUNT_ID=1"' \ + -e DEBUG_PANE_MODE 2 * Open a message (account id=1, mailbox id=2, message id=3) adb shell am start -a android.intent.action.MAIN \ - -n com.google.android.email/com.android.email.activity.Welcome \ + -d '"content://ui.email.android.com/view/mailbox?ACCOUNT_ID=1&MAILBOX_ID=2&MESSAGE_ID=3"' \ -e DEBUG_PANE_MODE 2 \ - --el ACCOUNT_ID 1 \ - --el MAILBOX_ID 2 \ - --el MESSAGE_ID 3 */ - private static final String EXTRA_ACCOUNT_ID = "ACCOUNT_ID"; - private static final String EXTRA_MAILBOX_ID = "MAILBOX_ID"; - private static final String EXTRA_MESSAGE_ID = "MESSAGE_ID"; /** * Extra for debugging. Set 1 to force one-pane. Set 2 to force two-pane. */ private static final String EXTRA_DEBUG_PANE_MODE = "DEBUG_PANE_MODE"; - private Handler mHandler = new Handler(); + private static final String VIEW_MAILBOX_INTENT_URL_PATH = "/view/mailbox"; /** * @return true if the two-pane activity should be used on the current configuration. @@ -94,7 +87,7 @@ public class Welcome extends Activity { * which will drop any other activities on the stack (e.g. AccountFolderList or MessageList). */ public static void actionStart(Activity fromActivity) { - Intent i = Utility.createRestartAppIntent(fromActivity, Welcome.class); + Intent i = IntentUtilities.createRestartAppIntent(fromActivity, Welcome.class); fromActivity.startActivity(i); } @@ -103,11 +96,10 @@ public class Welcome extends Activity { * specified account will be automatically be opened when the activity starts. */ public static Intent createOpenAccountInboxIntent(Context context, long accountId) { - Intent i = Utility.createRestartAppIntent(context, Welcome.class); - if (accountId != -1) { - i.putExtra(EXTRA_ACCOUNT_ID, accountId); - } - return i; + final Uri.Builder b = IntentUtilities.createActivityIntentUrlBuilder( + VIEW_MAILBOX_INTENT_URL_PATH); + IntentUtilities.setAccountId(b, accountId); + return IntentUtilities.createRestartAppIntent(b.build()); } /** @@ -115,13 +107,12 @@ public class Welcome extends Activity { */ public static Intent createOpenMessageIntent(Context context, long accountId, long mailboxId, long messageId) { - Intent i = Utility.createRestartAppIntent(context, Welcome.class); - if (accountId != -1) { - i.putExtra(EXTRA_ACCOUNT_ID, accountId); - i.putExtra(EXTRA_MAILBOX_ID, mailboxId); - i.putExtra(EXTRA_MESSAGE_ID, messageId); - } - return i; + final Uri.Builder b = IntentUtilities.createActivityIntentUrlBuilder( + VIEW_MAILBOX_INTENT_URL_PATH); + IntentUtilities.setAccountId(b, accountId); + IntentUtilities.setMailboxId(b, mailboxId); + IntentUtilities.setMessageId(b, messageId); + return IntentUtilities.createRestartAppIntent(b.build()); } /** @@ -170,9 +161,10 @@ public class Welcome extends Activity { // TODO More completely separate ExchangeService from Email app ExchangeUtils.startExchangeService(this); - final long accountId = getIntent().getLongExtra(EXTRA_ACCOUNT_ID, -1); - final long mailboxId = getIntent().getLongExtra(EXTRA_MAILBOX_ID, -1); - final long messageId = getIntent().getLongExtra(EXTRA_MESSAGE_ID, -1); + 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).execute(); } diff --git a/src/com/android/email/activity/setup/AccountSettingsXL.java b/src/com/android/email/activity/setup/AccountSettingsXL.java index 9ccfcd626..22b015282 100644 --- a/src/com/android/email/activity/setup/AccountSettingsXL.java +++ b/src/com/android/email/activity/setup/AccountSettingsXL.java @@ -20,6 +20,7 @@ import com.android.email.Controller; import com.android.email.NotificationController; import com.android.email.R; import com.android.email.activity.ActivityHelper; +import com.android.email.activity.IntentUtilities; import com.android.email.mail.Sender; import com.android.email.mail.Store; import com.android.emailcommon.Logging; @@ -39,6 +40,7 @@ import android.content.DialogInterface; import android.content.Intent; import android.content.res.Resources; import android.database.Cursor; +import android.net.Uri; import android.os.AsyncTask; import android.os.Bundle; import android.preference.PreferenceActivity; @@ -66,8 +68,13 @@ import java.util.List; * dealing with accounts being added/deleted and triggering the header reload. */ public class AccountSettingsXL extends PreferenceActivity { + /* + * Intent to open account settings for account=1 + adb shell am start -a android.intent.action.EDIT \ + -d '"content://ui.email.android.com/settings?ACCOUNT_ID=1"' + */ + // Intent extras for our internal activity launch - /* package */ static final String EXTRA_ACCOUNT_ID = "AccountSettingsXL.account_id"; private static final String EXTRA_ENABLE_DEBUG = "AccountSettingsXL.enable_debug"; private static final String EXTRA_LOGIN_WARNING_FOR_ACCOUNT = "AccountSettingsXL.for_account"; @@ -116,9 +123,7 @@ public class AccountSettingsXL extends PreferenceActivity { * Display (and edit) settings for a specific account, or -1 for any/all accounts */ public static void actionSettings(Activity fromActivity, long accountId) { - Intent i = new Intent(fromActivity, AccountSettingsXL.class); - i.putExtra(EXTRA_ACCOUNT_ID, accountId); - fromActivity.startActivity(i); + fromActivity.startActivity(createAccountSettingsIntent(fromActivity, accountId, null)); } /** @@ -128,9 +133,12 @@ public class AccountSettingsXL extends PreferenceActivity { */ public static Intent createAccountSettingsIntent(Context context, long accountId, String loginWarningAccountName) { - Intent i = new Intent(context, AccountSettingsXL.class); - i.putExtra(EXTRA_ACCOUNT_ID, accountId); - i.putExtra(EXTRA_LOGIN_WARNING_FOR_ACCOUNT, loginWarningAccountName); + final Uri.Builder b = IntentUtilities.createActivityIntentUrlBuilder("settings"); + IntentUtilities.setAccountId(b, accountId); + Intent i = new Intent(Intent.ACTION_EDIT, b.build()); + if (loginWarningAccountName != null) { + i.putExtra(EXTRA_LOGIN_WARNING_FOR_ACCOUNT, loginWarningAccountName); + } return i; } @@ -160,7 +168,7 @@ public class AccountSettingsXL extends PreferenceActivity { (GetAccountIdFromAccountTask) new GetAccountIdFromAccountTask().execute(i); } else { // Otherwise, we're called from within the Email app and look for our extras - mRequestedAccountId = i.getLongExtra(EXTRA_ACCOUNT_ID, -1); + mRequestedAccountId = IntentUtilities.getAccountIdFromIntent(i); String loginWarningAccount = i.getStringExtra(EXTRA_LOGIN_WARNING_FOR_ACCOUNT); if (loginWarningAccount != null) { // Show dialog (first time only - don't re-show on a rotation) diff --git a/tests/src/com/android/email/activity/IntentUtilitiesTests.java b/tests/src/com/android/email/activity/IntentUtilitiesTests.java new file mode 100644 index 000000000..7d0ca546d --- /dev/null +++ b/tests/src/com/android/email/activity/IntentUtilitiesTests.java @@ -0,0 +1,85 @@ +/* + * 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.activity.IntentUtilities; + +import android.content.Intent; +import android.net.Uri; +import android.test.AndroidTestCase; + +public class IntentUtilitiesTests extends AndroidTestCase { + public void testSimple() { + final Uri.Builder b = IntentUtilities.createActivityIntentUrlBuilder("/abc"); + IntentUtilities.setAccountId(b, 10); + IntentUtilities.setMailboxId(b, 20); + IntentUtilities.setMessageId(b, 30); + + final Uri u = b.build(); + assertEquals("content", u.getScheme()); + assertEquals("ui.email.android.com", u.getAuthority()); + assertEquals("/abc", u.getPath()); + + final Intent i = new Intent(Intent.ACTION_MAIN, u); + assertEquals(10, IntentUtilities.getAccountIdFromIntent(i)); + assertEquals(20, IntentUtilities.getMailboxIdFromIntent(i)); + assertEquals(30, IntentUtilities.getMessageIdFromIntent(i)); + } + + public void testGetIdFromIntent() { + Intent i; + + // No URL in intent + i = new Intent(getContext(), getClass()); + assertEquals(-1, IntentUtilities.getAccountIdFromIntent(i)); + assertEquals(-1, IntentUtilities.getMailboxIdFromIntent(i)); + assertEquals(-1, IntentUtilities.getMessageIdFromIntent(i)); + + // No param + checkGetIdFromIntent("content://s/", -1); + + // No value + checkGetIdFromIntent("content://s/?ID=", -1); + + // Value not integer + checkGetIdFromIntent("content://s/?ID=x", -1); + + // Negative value + checkGetIdFromIntent("content://s/?ID=-100", -100); + + // Normal value + checkGetIdFromIntent("content://s/?ID=200", 200); + + // With all 3 params + i = new Intent(Intent.ACTION_VIEW, Uri.parse( + "content://s/?ACCOUNT_ID=5&MAILBOX_ID=6&MESSAGE_ID=7")); + assertEquals(5, IntentUtilities.getAccountIdFromIntent(i)); + assertEquals(6, IntentUtilities.getMailboxIdFromIntent(i)); + assertEquals(7, IntentUtilities.getMessageIdFromIntent(i)); + } + + public void checkGetIdFromIntent(String uri, long expected) { + Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse(uri.replace("ID", "ACCOUNT_ID"))); + assertEquals(expected, IntentUtilities.getAccountIdFromIntent(i)); + + i = new Intent(Intent.ACTION_VIEW, Uri.parse(uri.replace("ID", "MAILBOX_ID"))); + assertEquals(expected, IntentUtilities.getMailboxIdFromIntent(i)); + + i = new Intent(Intent.ACTION_VIEW, Uri.parse(uri.replace("ID", "MESSAGE_ID"))); + assertEquals(expected, IntentUtilities.getMessageIdFromIntent(i)); + } +} diff --git a/tests/src/com/android/email/activity/setup/AccountSettingsXLTests.java b/tests/src/com/android/email/activity/setup/AccountSettingsXLTests.java index e75a1ece9..446e93b63 100644 --- a/tests/src/com/android/email/activity/setup/AccountSettingsXLTests.java +++ b/tests/src/com/android/email/activity/setup/AccountSettingsXLTests.java @@ -16,6 +16,7 @@ package com.android.email.activity.setup; +import com.android.email.activity.IntentUtilities; import com.android.email.mail.Store; import com.android.emailcommon.provider.EmailContent.Account; import com.android.emailcommon.utility.Utility; @@ -169,9 +170,7 @@ public class AccountSettingsXLTests extends ActivityInstrumentationTestCase2