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