Support pre-HC style account shortcuts

Account shortcuts used to point at MessageList directly with a
content://com.android.email.provider/account/ACCOUNT-UUID URI.

Hook these intents and open Welcome instead.

On Eclair and before, we stored an account-ID directly as an extra,
but this style is no longer supported.

Bug 4208879

Change-Id: I9fecb0723743377a6d7c7e84626e8613f2356492
This commit is contained in:
Makoto Onuki 2011-05-16 15:23:15 -07:00
parent 182caacd47
commit 2ed7a86949
6 changed files with 191 additions and 4 deletions

View File

@ -256,6 +256,14 @@
</intent-filter> </intent-filter>
</activity> </activity>
<activity
android:name=".activity.MessageList"
>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
</intent-filter>
</activity>
<receiver <receiver
android:name=".service.AttachmentDownloadService$Watchdog" android:name=".service.AttachmentDownloadService$Watchdog"
android:enabled="true"/> android:enabled="true"/>

View File

@ -943,6 +943,11 @@ save attachment.</string>
<!-- Title of activity/dialog containing shortcut picker (list of accounts) [CHAR_LIMIT=20] --> <!-- Title of activity/dialog containing shortcut picker (list of accounts) [CHAR_LIMIT=20] -->
<string name="account_shortcut_picker_title">Select an account</string> <string name="account_shortcut_picker_title">Select an account</string>
<!-- Toast shown when the selected account no longer exists. This is used when, for example,
a shotcut or a widget is stale and points at a deleted account.
[CHAR_LIMIT=none]-->
<string name="toast_account_not_found">Account not found. It may have been removed.</string>
<!-- Message that appears when adding a Windows Live Hotmail Plus account --> <!-- Message that appears when adding a Windows Live Hotmail Plus account -->
<string name="provider_note_live">Only some \"Plus\" accounts include POP access <string name="provider_note_live">Only some \"Plus\" accounts include POP access
allowing this program to connect. If you are not able to sign in with allowing this program to connect. If you are not able to sign in with

View File

@ -17,6 +17,7 @@
package com.android.email.activity; package com.android.email.activity;
import com.android.email.R; import com.android.email.R;
import com.android.emailcommon.Logging;
import com.android.emailcommon.provider.EmailContent.Account; import com.android.emailcommon.provider.EmailContent.Account;
import com.android.emailcommon.provider.EmailContent.AccountColumns; import com.android.emailcommon.provider.EmailContent.AccountColumns;
@ -28,6 +29,7 @@ import android.content.Loader;
import android.database.Cursor; import android.database.Cursor;
import android.os.Bundle; import android.os.Bundle;
import android.os.Parcelable; import android.os.Parcelable;
import android.util.Log;
import android.view.View; import android.view.View;
import android.view.View.OnClickListener; import android.view.View.OnClickListener;
import android.widget.AdapterView; import android.widget.AdapterView;
@ -37,13 +39,19 @@ import android.widget.SimpleCursorAdapter;
/** /**
* This class implements a launcher shortcut for directly accessing a single account. * This class implements a launcher shortcut for directly accessing a single account.
*
* TODO Handle upgraded shortcuts for the phone UI release. Shortcuts used to launch MessageList
* directly. We need to detect this and redirect to Welcome.
*/ */
public class AccountShortcutPicker extends ListActivity public class AccountShortcutPicker extends ListActivity
implements OnClickListener, OnItemClickListener, LoaderCallbacks<Cursor> { implements OnClickListener, OnItemClickListener, LoaderCallbacks<Cursor> {
/**
* Debug flag -- if true, create pre-honeycomb style shortcuts.
*
* This allows developers to test launching the app from old style shortcuts (which point at
* MessageList rather than Welcome) without actually carrying over shortcuts from previous
* versions.
*/
private static final boolean TEST_CREATE_OLD_STYLE_SHORTCUT = false; // DO NOT SUBMIT WITH TRUE
@SuppressWarnings("hiding") @SuppressWarnings("hiding")
private SimpleCursorAdapter mAdapter; private SimpleCursorAdapter mAdapter;
@ -132,7 +140,13 @@ public class AccountShortcutPicker extends ListActivity
*/ */
private void setupShortcut(Account account) { private void setupShortcut(Account account) {
// First, set up the shortcut intent. // First, set up the shortcut intent.
Intent shortcutIntent = Welcome.createAccountShortcutIntent(this, account); final Intent shortcutIntent;
if (TEST_CREATE_OLD_STYLE_SHORTCUT) {
shortcutIntent = MessageList.createFroyoIntent(this, account);
Log.d(Logging.LOG_TAG, "Created old style intent: " + shortcutIntent);
} else {
shortcutIntent = Welcome.createAccountShortcutIntent(this, account);
}
// Then, set up the container intent (the response to the caller) // Then, set up the container intent (the response to the caller)
Intent intent = new Intent(); Intent intent = new Intent();
@ -140,6 +154,7 @@ public class AccountShortcutPicker extends ListActivity
intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, account.getDisplayName()); intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, account.getDisplayName());
Parcelable iconResource Parcelable iconResource
= Intent.ShortcutIconResource.fromContext(this, R.mipmap.ic_launcher_email); = Intent.ShortcutIconResource.fromContext(this, R.mipmap.ic_launcher_email);
intent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, iconResource); intent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, iconResource);
// Now, return the result to the launcher // Now, return the result to the launcher

View File

@ -0,0 +1,93 @@
/*
* 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.R;
import com.android.emailcommon.provider.EmailContent.Account;
import com.android.emailcommon.utility.EmailAsyncTask;
import com.android.emailcommon.utility.Utility;
import com.google.common.annotations.VisibleForTesting;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
/**
* A dummy activity to support old-style (pre-honeycomb) account shortcuts.
*/
public class MessageList extends Activity {
@VisibleForTesting
static final String EXTRA_ACCOUNT_ID = "com.android.email.activity._ACCOUNT_ID";
private final EmailAsyncTask.Tracker mTaskTracker = new EmailAsyncTask.Tracker();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final Activity me = this;
new EmailAsyncTask<Void, Void, Long>(mTaskTracker) {
@Override
protected Long doInBackground(Void... params) {
return getAccountFromIntent(me, getIntent());
}
@Override
protected void onPostExecute(Long accountId) {
if ((accountId == null) || (accountId == Account.NO_ACCOUNT)) {
// Account deleted?
Utility.showToast(me, R.string.toast_account_not_found);
Welcome.actionStart(me);
} else {
Welcome.actionOpenAccountInbox(me, accountId);
}
finish();
}
}.executeParallel();
}
@Override
protected void onDestroy() {
mTaskTracker.cancellAllInterrupt();
super.onDestroy();
}
@VisibleForTesting
static long getAccountFromIntent(Context context, Intent i) {
final Uri uri = i.getData();
if (uri == null) {
return Account.NO_ACCOUNT;
}
return Account.getAccountIdFromShortcutSafeUri(context, uri);
}
/**
* Create a froyo/gingerbread style account shortcut intent. Used by unit tests and
* test code in {@link AccountShortcutPicker}.
*/
@VisibleForTesting
static Intent createFroyoIntent(Context context, Account account) {
final Intent intent = new Intent(context, MessageList.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.putExtra(EXTRA_ACCOUNT_ID, account.mId);
intent.setData(account.getShortcutSafeUri());
return intent;
}
}

View File

@ -211,6 +211,8 @@ public class Welcome extends Activity {
@VisibleForTesting @VisibleForTesting
static long resolveAccountId(Context context, long accountId, String uuid) { static long resolveAccountId(Context context, long accountId, String uuid) {
// TODO show "account may have been removed" toast when an account is specified but
// can't find it.
if (!TextUtils.isEmpty(uuid)) { if (!TextUtils.isEmpty(uuid)) {
accountId = Account.getAccountIdFromUuid(context, uuid); accountId = Account.getAccountIdFromUuid(context, uuid);
} }

View File

@ -0,0 +1,64 @@
/*
* 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.content.Intent;
import android.test.AndroidTestCase;
public class MessageListTests extends AndroidTestCase {
private Context mMockContext;
public MessageListTests() {
}
@Override
public void setUp() throws Exception {
super.setUp();
// ProviderTestCase2 can't be used. It creates a mock context that doesn't support
// some methods we need here, such as getPackageName.
mMockContext = DBTestHelper.ProviderContextSetupHelper.getProviderContext(
getContext());
}
public void testGetAccountFromIntent() {
final Context c = mMockContext;
final Account a1 = ProviderTestUtils.setupAccount("a1", true, c);
final Account a2 = ProviderTestUtils.setupAccount("a2", true, c);
assertEquals(a1.mId, MessageList.getAccountFromIntent(c,
MessageList.createFroyoIntent(c, a1)));
assertEquals(a2.mId, MessageList.getAccountFromIntent(c,
MessageList.createFroyoIntent(c, a2)));
// Mixed -- UUID in the URI doesn't match the account ID in extra.
// It's a test for shortcuts for restored accounts.
final Intent i = MessageList.createFroyoIntent(c, a2);
i.putExtra(MessageList.EXTRA_ACCOUNT_ID, 12345);
assertEquals(a2.mId, MessageList.getAccountFromIntent(c, i));
// Invalid intent -- no extra, no URI.
assertEquals(Account.NO_ACCOUNT, MessageList.getAccountFromIntent(c,
new Intent(c, MessageList.class)));
}
}