Home | History | Annotate | Download | only in setup
      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 
     17 package com.android.email.activity.setup;
     18 
     19 import android.app.ActionBar;
     20 import android.app.Fragment;
     21 import android.content.Intent;
     22 import android.net.Uri;
     23 import android.os.Bundle;
     24 import android.support.annotation.NonNull;
     25 import android.view.KeyEvent;
     26 import android.view.Menu;
     27 import android.view.MenuItem;
     28 
     29 import com.android.email.R;
     30 import com.android.emailcommon.utility.IntentUtilities;
     31 import com.android.mail.providers.UIProvider.EditSettingsExtras;
     32 import com.android.mail.ui.settings.MailPreferenceActivity;
     33 import com.android.mail.utils.Utils;
     34 
     35 import 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  */
     46 public class EmailPreferenceActivity 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                 throw new IllegalArgumentException("EXTRA_FOLDER is no longer supported");
    114             } else {
    115                 // Otherwise, we're called from within the Email app and look for our extras
    116                 final long accountId = IntentUtilities.getAccountIdFromIntent(i);
    117                 if (accountId != -1) {
    118                     final Bundle args = AccountSettingsFragment.buildArguments(accountId);
    119                     startPreferencePanel(AccountSettingsFragment.class.getName(), args,
    120                             0, null, null, 0);
    121                 }
    122             }
    123         }
    124         mShowDebugMenu = i.getBooleanExtra(EXTRA_ENABLE_DEBUG, false);
    125 
    126         final ActionBar actionBar = getActionBar();
    127         if (actionBar != null) {
    128             actionBar.setDisplayOptions(
    129                     ActionBar.DISPLAY_HOME_AS_UP, ActionBar.DISPLAY_HOME_AS_UP);
    130         }
    131 
    132         mFeedbackUri = Utils.getValidUri(getString(R.string.email_feedback_uri));
    133     }
    134 
    135     /**
    136      * Listen for secret sequence and, if heard, enable debug menu
    137      */
    138     @Override
    139     public boolean onKeyDown(int keyCode, @NonNull KeyEvent event) {
    140         if (event.getKeyCode() == SECRET_KEY_CODES[mSecretKeyCodeIndex]) {
    141             mSecretKeyCodeIndex++;
    142             if (mSecretKeyCodeIndex == SECRET_KEY_CODES.length) {
    143                 mSecretKeyCodeIndex = 0;
    144                 enableDebugMenu();
    145             }
    146         } else {
    147             mSecretKeyCodeIndex = 0;
    148         }
    149         return super.onKeyDown(keyCode, event);
    150     }
    151 
    152     @Override
    153     public boolean onCreateOptionsMenu(Menu menu) {
    154         super.onCreateOptionsMenu(menu);
    155         getMenuInflater().inflate(R.menu.settings_menu, menu);
    156 
    157         mFeedbackMenuItem = menu.findItem(R.id.feedback_menu_item);
    158         return true;
    159     }
    160 
    161     @Override
    162     public boolean onPrepareOptionsMenu(Menu menu) {
    163         super.onPrepareOptionsMenu(menu);
    164 
    165         if (mFeedbackMenuItem != null) {
    166             // We only want to enable the feedback menu item, if there is a valid feedback uri
    167             mFeedbackMenuItem.setVisible(!Uri.EMPTY.equals(mFeedbackUri));
    168         }
    169         return true;
    170     }
    171 
    172 
    173     @Override
    174     public boolean onOptionsItemSelected(MenuItem item) {
    175         switch (item.getItemId()) {
    176             case android.R.id.home:
    177                 // The app icon on the action bar is pressed.  Just emulate a back press.
    178                 // TODO: this should navigate to the main screen, even if a sub-setting is open.
    179                 // But we shouldn't just finish(), as we want to show "discard changes?" dialog
    180                 // when necessary.
    181                 onBackPressed();
    182                 break;
    183             case R.id.feedback_menu_item:
    184                 Utils.sendFeedback(this, mFeedbackUri, false /* reportingProblem */);
    185                 break;
    186             default:
    187                 return super.onOptionsItemSelected(item);
    188         }
    189         return true;
    190     }
    191 
    192     @Override
    193     public boolean isValidFragment(String fragmentName) {
    194         // This activity is not exported, so we can allow any fragment
    195         return true;
    196     }
    197 
    198     private void enableDebugMenu() {
    199         mShowDebugMenu = true;
    200         invalidateHeaders();
    201     }
    202 
    203     private void onAddNewAccount() {
    204         final Intent setupIntent = AccountSetupFinal.actionNewAccountIntent(this);
    205         startActivity(setupIntent);
    206     }
    207 
    208     @Override
    209     public void onBuildExtraHeaders(List<Header> target) {
    210         super.onBuildExtraHeaders(target);
    211 
    212         loadHeadersFromResource(R.xml.email_extra_preference_headers, target);
    213 
    214         // if debug header is enabled, show it
    215         if (DEBUG_MENU_ALLOWED) {
    216             if (mShowDebugMenu) {
    217                 // setup lightweight header for debugging
    218                 final Header debugHeader = new Header();
    219                 debugHeader.title = getText(R.string.debug_title);
    220                 debugHeader.summary = null;
    221                 debugHeader.iconRes = 0;
    222                 debugHeader.fragment = DebugFragment.class.getCanonicalName();
    223                 debugHeader.fragmentArguments = null;
    224                 target.add(debugHeader);
    225             }
    226         }
    227     }
    228 
    229     /**
    230      * Called when the user selects an item in the header list.  Handles save-data cases as needed
    231      *
    232      * @param header The header that was selected.
    233      * @param position The header's position in the list.
    234      */
    235     @Override
    236     public void onHeaderClick(@NonNull Header header, int position) {
    237         // Secret keys:  Click 10x to enable debug settings
    238         if (position == 0) {
    239             mNumGeneralHeaderClicked++;
    240             if (mNumGeneralHeaderClicked == 10) {
    241                 enableDebugMenu();
    242             }
    243         } else {
    244             mNumGeneralHeaderClicked = 0;
    245         }
    246         if (header.id == R.id.add_account_header) {
    247             onAddNewAccount();
    248             return;
    249         }
    250 
    251         // Process header click normally
    252         super.onHeaderClick(header, position);
    253     }
    254 
    255     @Override
    256     public void onAttachFragment(Fragment f) {
    257         super.onAttachFragment(f);
    258         // When we're changing fragments, enable/disable the add account button
    259         invalidateOptionsMenu();
    260     }
    261 }
    262