EmailPreferenceActivity.java revision 8c03e2af9f439c6e0c6abb38b0c371da7ccdb72a
1/* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.email.activity.setup; 18 19import android.app.ActionBar; 20import android.app.Fragment; 21import android.content.Intent; 22import android.net.Uri; 23import android.os.Bundle; 24import android.view.KeyEvent; 25import android.view.Menu; 26import android.view.MenuItem; 27 28import com.android.email.R; 29import com.android.emailcommon.utility.IntentUtilities; 30import com.android.mail.providers.Folder; 31import com.android.mail.providers.UIProvider.EditSettingsExtras; 32import com.android.mail.ui.settings.MailPreferenceActivity; 33import com.android.mail.utils.Utils; 34 35import java.util.List; 36 37/** 38 * Handles account preferences, using multi-pane arrangement when possible. 39 * 40 * This activity uses the following fragments: 41 * AccountSettingsFragment 42 * GeneralPreferences 43 * DebugFragment 44 * 45 */ 46public class AccountSettings extends MailPreferenceActivity { 47 /* 48 * Intent to open account settings for account=1 49 adb shell am start -a android.intent.action.EDIT \ 50 -d '"content://ui.email.android.com/settings?ACCOUNT_ID=1"' 51 */ 52 53 // Intent extras for our internal activity launch 54 private static final String EXTRA_ENABLE_DEBUG = "AccountSettings.enable_debug"; 55 // STOPSHIP: Do not ship with the debug menu allowed. 56 private static final boolean DEBUG_MENU_ALLOWED = false; 57 58 // Intent extras for launch directly from system account manager 59 // NOTE: This string must match the one in res/xml/account_preferences.xml 60 private static String INTENT_ACCOUNT_MANAGER_ENTRY; 61 62 // Key codes used to open a debug settings fragment. 63 private static final int[] SECRET_KEY_CODES = { 64 KeyEvent.KEYCODE_D, KeyEvent.KEYCODE_E, KeyEvent.KEYCODE_B, KeyEvent.KEYCODE_U, 65 KeyEvent.KEYCODE_G 66 }; 67 private int mSecretKeyCodeIndex = 0; 68 69 // When the user taps "Email Preferences" 10 times in a row, we'll enable the debug settings. 70 private int mNumGeneralHeaderClicked = 0; 71 72 private boolean mShowDebugMenu; 73 private Uri mFeedbackUri; 74 private MenuItem mFeedbackMenuItem; 75 76 @Override 77 public Intent getIntent() { 78 final Intent intent = super.getIntent(); 79 final long accountId = IntentUtilities.getAccountIdFromIntent(intent); 80 if (accountId < 0) { 81 return intent; 82 } 83 Intent modIntent = new Intent(intent); 84 modIntent.putExtra(EXTRA_SHOW_FRAGMENT, AccountSettingsFragment.class.getCanonicalName()); 85 modIntent.putExtra( 86 EXTRA_SHOW_FRAGMENT_ARGUMENTS, 87 AccountSettingsFragment.buildArguments( 88 IntentUtilities.getAccountNameFromIntent(intent))); 89 modIntent.putExtra(EXTRA_NO_HEADERS, true); 90 return modIntent; 91 } 92 93 @Override 94 public void onCreate(Bundle savedInstanceState) { 95 super.onCreate(savedInstanceState); 96 97 final Intent i = getIntent(); 98 if (savedInstanceState == null) { 99 // If we are not restarting from a previous instance, we need to 100 // figure out the initial prefs to show. (Otherwise, we want to 101 // continue showing whatever the user last selected.) 102 if (INTENT_ACCOUNT_MANAGER_ENTRY == null) { 103 INTENT_ACCOUNT_MANAGER_ENTRY = getString(R.string.intent_account_manager_entry); 104 } 105 if (INTENT_ACCOUNT_MANAGER_ENTRY.equals(i.getAction())) { 106 // This case occurs if we're changing account settings from Settings -> Accounts. 107 // We get an account object in the intent, but it's not actually useful to us since 108 // it's always just the first account of that type. The user can't specify which 109 // account they wish to view from within the settings UI, so just dump them at the 110 // main screen. 111 // android.accounts.Account acct = i.getParcelableExtra("account"); 112 } else if (i.hasExtra(EditSettingsExtras.EXTRA_FOLDER)) { 113 launchMailboxSettings(i); 114 return; 115 } else { 116 // Otherwise, we're called from within the Email app and look for our extras 117 final long accountId = IntentUtilities.getAccountIdFromIntent(i); 118 if (accountId != -1) { 119 final Bundle args = AccountSettingsFragment.buildArguments(accountId); 120 startPreferencePanel(AccountSettingsFragment.class.getName(), args, 121 0, null, null, 0); 122 } 123 } 124 } 125 mShowDebugMenu = i.getBooleanExtra(EXTRA_ENABLE_DEBUG, false); 126 127 getActionBar().setDisplayOptions( 128 ActionBar.DISPLAY_HOME_AS_UP, ActionBar.DISPLAY_HOME_AS_UP); 129 130 mFeedbackUri = Utils.getValidUri(getString(R.string.email_feedback_uri)); 131 } 132 133 /** 134 * Listen for secret sequence and, if heard, enable debug menu 135 */ 136 @Override 137 public boolean onKeyDown(int keyCode, KeyEvent event) { 138 if (event.getKeyCode() == SECRET_KEY_CODES[mSecretKeyCodeIndex]) { 139 mSecretKeyCodeIndex++; 140 if (mSecretKeyCodeIndex == SECRET_KEY_CODES.length) { 141 mSecretKeyCodeIndex = 0; 142 enableDebugMenu(); 143 } 144 } else { 145 mSecretKeyCodeIndex = 0; 146 } 147 return super.onKeyDown(keyCode, event); 148 } 149 150 @Override 151 public boolean onCreateOptionsMenu(Menu menu) { 152 super.onCreateOptionsMenu(menu); 153 getMenuInflater().inflate(R.menu.settings_menu, menu); 154 155 mFeedbackMenuItem = menu.findItem(R.id.feedback_menu_item); 156 return true; 157 } 158 159 @Override 160 public boolean onPrepareOptionsMenu(Menu menu) { 161 super.onPrepareOptionsMenu(menu); 162 163 if (mFeedbackMenuItem != null) { 164 // We only want to enable the feedback menu item, if there is a valid feedback uri 165 mFeedbackMenuItem.setVisible(!Uri.EMPTY.equals(mFeedbackUri)); 166 } 167 return true; 168 } 169 170 171 @Override 172 public boolean onOptionsItemSelected(MenuItem item) { 173 switch (item.getItemId()) { 174 case android.R.id.home: 175 // The app icon on the action bar is pressed. Just emulate a back press. 176 // TODO: this should navigate to the main screen, even if a sub-setting is open. 177 // But we shouldn't just finish(), as we want to show "discard changes?" dialog 178 // when necessary. 179 onBackPressed(); 180 break; 181 case R.id.feedback_menu_item: 182 Utils.sendFeedback(this, mFeedbackUri, false /* reportingProblem */); 183 break; 184 default: 185 return super.onOptionsItemSelected(item); 186 } 187 return true; 188 } 189 190 @Override 191 public boolean isValidFragment(String fragmentName) { 192 // This activity is not exported, so we can allow any fragment 193 return true; 194 } 195 196 private void launchMailboxSettings(Intent intent) { 197 final Folder folder = intent.getParcelableExtra(EditSettingsExtras.EXTRA_FOLDER); 198 199 // TODO: determine from the account if we should navigate to the mailbox settings. 200 // See bug 6242668 201 202 // Get the mailbox id from the folder 203 final long mailboxId = 204 Long.parseLong(folder.folderUri.fullUri.getPathSegments().get(1)); 205 206 MailboxSettings.start(this, mailboxId); 207 finish(); 208 } 209 210 private void enableDebugMenu() { 211 mShowDebugMenu = true; 212 invalidateHeaders(); 213 } 214 215 private void onAddNewAccount() { 216 final Intent setupIntent = AccountSetupFinal.actionNewAccountIntent(this); 217 startActivity(setupIntent); 218 } 219 220 @Override 221 public void onBuildExtraHeaders(List<Header> target) { 222 super.onBuildExtraHeaders(target); 223 // finally, if debug header is enabled, show it 224 if (DEBUG_MENU_ALLOWED) { 225 if (mShowDebugMenu) { 226 // setup lightweight header for debugging 227 final Header debugHeader = new Header(); 228 debugHeader.title = getText(R.string.debug_title); 229 debugHeader.summary = null; 230 debugHeader.iconRes = 0; 231 debugHeader.fragment = DebugFragment.class.getCanonicalName(); 232 debugHeader.fragmentArguments = null; 233 target.add(debugHeader); 234 } 235 } 236 } 237 238 /** 239 * Called when the user selects an item in the header list. Handles save-data cases as needed 240 * 241 * @param header The header that was selected. 242 * @param position The header's position in the list. 243 */ 244 @Override 245 public void onHeaderClick(Header header, int position) { 246 // Secret keys: Click 10x to enable debug settings 247 if (position == 0) { 248 mNumGeneralHeaderClicked++; 249 if (mNumGeneralHeaderClicked == 10) { 250 enableDebugMenu(); 251 } 252 } else { 253 mNumGeneralHeaderClicked = 0; 254 } 255 256 // Process header click normally 257 super.onHeaderClick(header, position); 258 } 259 260 @Override 261 public void onAttachFragment(Fragment f) { 262 super.onAttachFragment(f); 263 // When we're changing fragments, enable/disable the add account button 264 invalidateOptionsMenu(); 265 } 266} 267