diff --git a/AndroidManifest.xml b/AndroidManifest.xml index f6fc64c30..4bfdd45b4 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -135,22 +135,14 @@ > - - - - diff --git a/src/com/android/email/activity/setup/AccountSettings.java b/src/com/android/email/activity/setup/AccountSettings.java deleted file mode 100644 index 264a16d51..000000000 --- a/src/com/android/email/activity/setup/AccountSettings.java +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Copyright (C) 2008 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.setup; - -import com.android.email.Email; -import com.android.email.R; -import com.android.email.activity.Welcome; -import com.android.email.mail.Sender; -import com.android.email.mail.Store; -import com.android.email.provider.EmailContent.Account; -import com.android.email.provider.EmailContent.AccountColumns; - -import android.app.Activity; -import android.app.Fragment; -import android.content.Intent; -import android.database.Cursor; -import android.os.Bundle; -import android.util.Log; - -/** - * TODO: At this point this is used only to support the Account Manager, and needs to be removed. - */ -public class AccountSettings extends Activity - implements AccountSettingsFragment.Callback, AccountSettingsFragment.OnAttachListener { - // NOTE: This string must match the one in res/xml/account_preferences.xml - private static final String ACTION_ACCOUNT_MANAGER_ENTRY = - "com.android.email.activity.setup.ACCOUNT_MANAGER_ENTRY"; - // NOTE: This constant should eventually be defined in android.accounts.Constants, but for - // now we define it here - private static final String ACCOUNT_MANAGER_EXTRA_ACCOUNT = "account"; - private static final String EXTRA_ACCOUNT_ID = "account_id"; - - // UI values - /* package */ AccountSettingsFragment mFragment; - - // Account data values - private long mAccountId = -1; - - /** - * Display (and edit) settings for a specific account - */ - public static void actionSettings(Activity fromActivity, long accountId) { - Intent i = new Intent(fromActivity, AccountSettings.class); - i.putExtra(EXTRA_ACCOUNT_ID, accountId); - fromActivity.startActivity(i); - } - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - Intent i = getIntent(); - if (ACTION_ACCOUNT_MANAGER_ENTRY.equals(i.getAction())) { - // This case occurs if we're changing account settings from Settings -> Accounts - setAccountIdFromAccountManagerIntent(); - } else { - // Otherwise, we're called from within the Email app and look for our extra - mAccountId = i.getLongExtra(EXTRA_ACCOUNT_ID, -1); - } - - // If there's no accountId, we're done - if (mAccountId == -1) { - finish(); - return; - } - - // Now set up the UI and the fragment - setContentView(R.layout.account_settings); - mFragment = (AccountSettingsFragment) - getFragmentManager().findFragmentById(R.id.settings_fragment); - mFragment.setCallback(this); - mFragment.startLoadingAccount(mAccountId); - } - - private void setAccountIdFromAccountManagerIntent() { - // First, get the AccountManager account that we've been ask to handle - android.accounts.Account acct = - (android.accounts.Account)getIntent() - .getParcelableExtra(ACCOUNT_MANAGER_EXTRA_ACCOUNT); - // Find a HostAuth using eas and whose login is the name of the AccountManager account - Cursor c = getContentResolver().query(Account.CONTENT_URI, - new String[] {AccountColumns.ID}, AccountColumns.EMAIL_ADDRESS + "=?", - new String[] {acct.name}, null); - try { - if (c.moveToFirst()) { - mAccountId = c.getLong(0); - } - } finally { - c.close(); - } - } - - @Override - public void onResume() { - super.onResume(); - - // Exit immediately if the accounts list has changed (e.g. externally deleted) - if (Email.getNotifyUiAccountsChanged()) { - Welcome.actionStart(this); - finish(); - return; - } - } - - /** - * Implements AccountSettingsFragment.Callback - */ - @Override - public void onIncomingSettings(Account account) { - try { - Store store = Store.getInstance(account.getStoreUri(this), getApplication(), null); - if (store != null) { - Class setting = store.getSettingActivityClass(); - if (setting != null) { - java.lang.reflect.Method m = setting.getMethod("actionEditIncomingSettings", - Activity.class, int.class, Account.class); - m.invoke(null, this, SetupData.FLOW_MODE_EDIT, account); - } - } - } catch (Exception e) { - Log.d(Email.LOG_TAG, "Error while trying to invoke store settings.", e); - } - } - - /** - * Implements AccountSettingsFragment.Callback - */ - @Override - public void onOutgoingSettings(Account account) { - try { - Sender sender = Sender.getInstance(getApplication(), account.getSenderUri(this)); - if (sender != null) { - Class setting = sender.getSettingActivityClass(); - if (setting != null) { - java.lang.reflect.Method m = setting.getMethod("actionEditOutgoingSettings", - Activity.class, int.class, Account.class); - m.invoke(null, this, SetupData.FLOW_MODE_EDIT, account); - } - } - } catch (Exception e) { - Log.d(Email.LOG_TAG, "Error while trying to invoke sender settings.", e); - } - } - - /** - * Implements AccountSettingsFragment.Callback - */ - @Override - public void abandonEdit() { - finish(); - } - - /** - * Implements AccountSettingsFragment.Callback - */ - @Override - public void deleteAccount(Account account) { - // STOPSHIP - this is not implemented because this entire activity is deprecated - // If you need to delete an account, use the AccountSettingsXL, which will eventually - // become the only settings activity. - } - - /** - * Implements AccountSettingsFragment.OnAttachListener - * Does nothing (this activity sets up the fragment in onCreate via its layout) - */ - @Override - public void onAttach(Fragment f) { - } -} diff --git a/src/com/android/email/activity/setup/AccountSettingsXL.java b/src/com/android/email/activity/setup/AccountSettingsXL.java index d8a4f046e..ab3c510b5 100644 --- a/src/com/android/email/activity/setup/AccountSettingsXL.java +++ b/src/com/android/email/activity/setup/AccountSettingsXL.java @@ -24,6 +24,7 @@ import com.android.email.mail.Sender; import com.android.email.mail.Store; import com.android.email.provider.EmailContent; import com.android.email.provider.EmailContent.Account; +import com.android.email.provider.EmailContent.AccountColumns; import com.android.email.service.MailService; import android.app.Activity; @@ -46,8 +47,6 @@ import java.util.List; /** * Handles account preferences using multi-pane arrangement when possible. * - * TODO: Go directly to specific account when requested - post runnable after onBuildHeaders - * TODO: Incorporate entry point & other stuff to support launch from AccountManager * TODO: In Account settings in Phone UI, change title * TODO: Rework all remaining calls to DB from UI thread * TODO: Delete account - on single-pane view (phone UX) the account list doesn't update properly @@ -58,9 +57,17 @@ import java.util.List; public class AccountSettingsXL extends PreferenceActivity implements AccountSettingsFragment.OnAttachListener, OnClickListener { - private static final String EXTRA_ACCOUNT_ID = "AccountSettingsXL.account_id"; + // 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"; + // Intent extras for launch directly from system account manager + // NOTE: This string must match the one in res/xml/account_preferences.xml + private static final String ACTION_ACCOUNT_MANAGER_ENTRY = + "com.android.email.activity.setup.ACCOUNT_MANAGER_ENTRY"; + // NOTE: This constant should eventually be defined in android.accounts.Constants + private static final String EXTRA_ACCOUNT_MANAGER_ACCOUNT = "account"; + // Key codes used to open a debug settings fragment. private static final int[] SECRET_KEY_CODES = { KeyEvent.KEYCODE_D, KeyEvent.KEYCODE_E, KeyEvent.KEYCODE_B, KeyEvent.KEYCODE_U, @@ -68,22 +75,26 @@ public class AccountSettingsXL extends PreferenceActivity }; private int mSecretKeyCodeIndex = 0; - /** - * When the user taps "Email Preferences" 10 times in a row, we'll enable the debug settings. - */ + // Support for account-by-name lookup + private static final String SELECTION_ACCOUNT_EMAIL_ADDRESS = + AccountColumns.EMAIL_ADDRESS + "=?"; + + // When the user taps "Email Preferences" 10 times in a row, we'll enable the debug settings. private int mNumGeneralHeaderClicked = 0; private long mRequestedAccountId; + private Header mRequestedAccountHeader; private ExtendedHeader[] mAccountListHeaders; private Header mAppPreferencesHeader; private int mCurrentHeaderPosition; - private Fragment mCurrentFragment; + /* package */ Fragment mCurrentFragment; private long mDeletingAccountId = -1; private boolean mShowDebugMenu; private Button mAddAccountButton; // Async Tasks private LoadAccountListTask mLoadAccountListTask; + private GetAccountIdFromAccountTask mGetAccountIdFromAccountTask; // Specific callbacks used by settings fragments private AccountSettingsFragmentCallback mAccountSettingsFragmentCallback @@ -113,7 +124,14 @@ public class AccountSettingsXL extends PreferenceActivity super.onCreate(savedInstanceState); Intent i = getIntent(); - mRequestedAccountId = i.getLongExtra(EXTRA_ACCOUNT_ID, -1); + if (ACTION_ACCOUNT_MANAGER_ENTRY.equals(i.getAction())) { + // This case occurs if we're changing account settings from Settings -> Accounts + mGetAccountIdFromAccountTask = + (GetAccountIdFromAccountTask) new GetAccountIdFromAccountTask().execute(i); + } else { + // Otherwise, we're called from within the Email app and look for our extra + mRequestedAccountId = i.getLongExtra(EXTRA_ACCOUNT_ID, -1); + } mShowDebugMenu = i.getBooleanExtra(EXTRA_ENABLE_DEBUG, false); // Add Account as header list footer @@ -139,6 +157,8 @@ public class AccountSettingsXL extends PreferenceActivity super.onDestroy(); Utility.cancelTaskInterrupt(mLoadAccountListTask); mLoadAccountListTask = null; + Utility.cancelTaskInterrupt(mGetAccountIdFromAccountTask); + mGetAccountIdFromAccountTask = null; } /** @@ -165,6 +185,17 @@ public class AccountSettingsXL extends PreferenceActivity } } + /** + * If the caller requested a specific account to be edited, switch to it. This is a one-shot, + * so the user is free to edit another account as well. + */ + @Override + public Header onGetNewHeader() { + Header result = mRequestedAccountHeader; + mRequestedAccountHeader = null; + return result; + } + private void enableDebugMenu() { mShowDebugMenu = true; invalidateHeaders(); @@ -206,22 +237,32 @@ public class AccountSettingsXL extends PreferenceActivity /** * Write the current header (accounts) array into the one provided by the PreferenceActivity. * Skip any headers that match mDeletingAccountId (this is a quick-hide algorithm while a - * background thread works on deleting the account). + * background thread works on deleting the account). Also sets mRequestedAccountHeader if + * we find the requested account (by id). */ @Override public void onBuildHeaders(List
target) { + // Assume the account is unspecified + mRequestedAccountHeader = null; + // Always add app preferences as first header target.clear(); target.add(getAppPreferencesHeader()); + // Then add zero or more account headers as necessary if (mAccountListHeaders != null) { int headerCount = mAccountListHeaders.length; for (int index = 0; index < headerCount; index++) { - if (mAccountListHeaders[index].accountId != mDeletingAccountId) { - target.add(mAccountListHeaders[index]); + ExtendedHeader header = mAccountListHeaders[index]; + if (header.accountId != mDeletingAccountId) { + target.add(header); + if (header.accountId == mRequestedAccountId) { + mRequestedAccountHeader = header; + } } } } + // finally, if debug header is enabled, show it if (mShowDebugMenu) { // setup lightweight header for debugging @@ -259,7 +300,7 @@ public class AccountSettingsXL extends PreferenceActivity * for quick scans, etc. */ private class ExtendedHeader extends Header { - public long accountId; + public final long accountId; public ExtendedHeader(long _accountId, String _title, String _summary) { title = _title; @@ -453,6 +494,32 @@ public class AccountSettingsXL extends PreferenceActivity } } + /** + * This AsyncTask looks up an account based on its email address (which is what we get from + * the Account Manager). When the account id is determined, we refresh the header list, + * which will select the preferences for that account. + */ + private class GetAccountIdFromAccountTask extends AsyncTask { + + @Override + protected Long doInBackground(Intent... params) { + Intent intent = params[0]; + android.accounts.Account acct = + (android.accounts.Account) intent.getParcelableExtra(EXTRA_ACCOUNT_MANAGER_ACCOUNT); + return Utility.getFirstRowLong(AccountSettingsXL.this, Account.CONTENT_URI, + Account.ID_PROJECTION, SELECTION_ACCOUNT_EMAIL_ADDRESS, new String[] {acct.name}, + null, Account.ID_PROJECTION_COLUMN, -1L); + } + + @Override + protected void onPostExecute(Long accountId) { + if (accountId != -1 && !isCancelled()) { + mRequestedAccountId = accountId; + AccountSettingsXL.this.invalidateHeaders(); + } + } + } + /** * Placeholder for app-wide preferences * STOPSHIP - make this real diff --git a/tests/src/com/android/email/activity/setup/AccountSettingsTests.java b/tests/src/com/android/email/activity/setup/AccountSettingsXLTests.java similarity index 79% rename from tests/src/com/android/email/activity/setup/AccountSettingsTests.java rename to tests/src/com/android/email/activity/setup/AccountSettingsXLTests.java index 3404d01f7..fd8abd63d 100644 --- a/tests/src/com/android/email/activity/setup/AccountSettingsTests.java +++ b/tests/src/com/android/email/activity/setup/AccountSettingsXLTests.java @@ -24,29 +24,30 @@ import android.content.Context; import android.content.Intent; import android.net.Uri; import android.preference.ListPreference; +import android.preference.PreferenceFragment; import android.test.ActivityInstrumentationTestCase2; import android.test.suitebuilder.annotation.MediumTest; /** - * Tests of basic UI logic in the AccountSettings screen. + * Tests of basic UI logic in the Account Settings fragment. + * + * TODO: This should use a local provider for the test "accounts", and not touch user data + * + * To execute: runtest -c com.android.email.activity.setup.AccountSettingsXLTests email */ @MediumTest -public class AccountSettingsTests extends ActivityInstrumentationTestCase2 { - - // Borrowed from AccountSettings - private static final String EXTRA_ACCOUNT_ID = "account_id"; +public class AccountSettingsXLTests extends ActivityInstrumentationTestCase2 { private long mAccountId; private Account mAccount; private Context mContext; - private AccountSettings mActivity; private ListPreference mCheckFrequency; private static final String PREFERENCE_FREQUENCY = "account_check_frequency"; - public AccountSettingsTests() { - super(AccountSettings.class); + public AccountSettingsXLTests() { + super(AccountSettingsXL.class); } /** @@ -76,7 +77,7 @@ public class AccountSettingsTests extends ActivityInstrumentationTestCase2