SettingsActivity.java revision a2d47fcf59f03d091edaf5895fd3b651e1f499e1
1/*
2 * Copyright (C) 2014 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.settings;
18
19import android.app.ActionBar;
20import android.app.Fragment;
21import android.app.FragmentManager;
22import android.app.FragmentTransaction;
23import android.content.BroadcastReceiver;
24import android.content.ComponentName;
25import android.content.Context;
26import android.content.Intent;
27import android.content.IntentFilter;
28import android.content.SharedPreferences;
29import android.content.pm.ActivityInfo;
30import android.content.pm.PackageManager;
31import android.content.pm.PackageManager.NameNotFoundException;
32import android.content.res.Configuration;
33import android.nfc.NfcAdapter;
34import android.os.AsyncTask;
35import android.os.Bundle;
36import android.os.UserHandle;
37import android.os.UserManager;
38import android.support.v14.preference.PreferenceFragment;
39import android.support.v7.preference.Preference;
40import android.support.v7.preference.PreferenceManager;
41import android.text.TextUtils;
42import android.transition.TransitionManager;
43import android.util.Log;
44import android.view.Menu;
45import android.view.MenuInflater;
46import android.view.MenuItem;
47import android.view.View;
48import android.view.View.OnClickListener;
49import android.view.ViewGroup;
50import android.widget.Button;
51import android.widget.SearchView;
52import com.android.internal.util.ArrayUtils;
53import com.android.settings.Settings.WifiSettingsActivity;
54import com.android.settings.accessibility.AccessibilitySettings;
55import com.android.settings.accessibility.AccessibilitySettingsForSetupWizard;
56import com.android.settings.accessibility.CaptionPropertiesFragment;
57import com.android.settings.accounts.AccountSettings;
58import com.android.settings.accounts.AccountSyncSettings;
59import com.android.settings.applications.AdvancedAppSettings;
60import com.android.settings.applications.DrawOverlayDetails;
61import com.android.settings.applications.InstalledAppDetails;
62import com.android.settings.applications.ManageApplications;
63import com.android.settings.applications.ManageAssist;
64import com.android.settings.applications.NotificationApps;
65import com.android.settings.applications.ProcessStatsSummary;
66import com.android.settings.applications.ProcessStatsUi;
67import com.android.settings.applications.UsageAccessDetails;
68import com.android.settings.applications.WriteSettingsDetails;
69import com.android.settings.bluetooth.BluetoothSettings;
70import com.android.settings.dashboard.DashboardSummary;
71import com.android.settings.dashboard.SearchResultsSummary;
72import com.android.settings.datausage.DataUsageSummary;
73import com.android.settings.deviceinfo.PrivateVolumeForget;
74import com.android.settings.deviceinfo.PrivateVolumeSettings;
75import com.android.settings.deviceinfo.PublicVolumeSettings;
76import com.android.settings.deviceinfo.StorageSettings;
77import com.android.settings.fuelgauge.BatterySaverSettings;
78import com.android.settings.fuelgauge.PowerUsageDetail;
79import com.android.settings.fuelgauge.PowerUsageSummary;
80import com.android.settings.inputmethod.AvailableVirtualKeyboardFragment;
81import com.android.settings.inputmethod.InputMethodAndLanguageSettings;
82import com.android.settings.inputmethod.KeyboardLayoutPickerFragment;
83import com.android.settings.inputmethod.KeyboardLayoutPickerFragment2;
84import com.android.settings.inputmethod.SpellCheckersSettings;
85import com.android.settings.inputmethod.UserDictionaryList;
86import com.android.settings.localepicker.LocaleListEditor;
87import com.android.settings.location.LocationSettings;
88import com.android.settings.nfc.AndroidBeam;
89import com.android.settings.nfc.PaymentSettings;
90import com.android.settings.notification.AppNotificationSettings;
91import com.android.settings.notification.ConfigureNotificationSettings;
92import com.android.settings.notification.NotificationAccessSettings;
93import com.android.settings.notification.NotificationStation;
94import com.android.settings.notification.OtherSoundSettings;
95import com.android.settings.notification.SoundSettings;
96import com.android.settings.notification.ZenAccessSettings;
97import com.android.settings.notification.ZenModeAutomationSettings;
98import com.android.settings.notification.ZenModeEventRuleSettings;
99import com.android.settings.notification.ZenModePrioritySettings;
100import com.android.settings.notification.ZenModeScheduleRuleSettings;
101import com.android.settings.notification.ZenModeSettings;
102import com.android.settings.notification.ZenModeVisualInterruptionSettings;
103import com.android.settings.print.PrintJobSettingsFragment;
104import com.android.settings.print.PrintSettingsFragment;
105import com.android.settings.search.DynamicIndexableContentMonitor;
106import com.android.settings.search.Index;
107import com.android.settings.sim.SimSettings;
108import com.android.settings.tts.TextToSpeechSettings;
109import com.android.settings.users.UserSettings;
110import com.android.settings.vpn2.VpnSettings;
111import com.android.settings.wfd.WifiDisplaySettings;
112import com.android.settings.widget.SwitchBar;
113import com.android.settings.wifi.AdvancedWifiSettings;
114import com.android.settings.wifi.SavedAccessPointsWifiSettings;
115import com.android.settings.wifi.WifiSettings;
116import com.android.settings.wifi.p2p.WifiP2pSettings;
117import com.android.settingslib.drawer.DashboardCategory;
118import com.android.settingslib.drawer.SettingsDrawerActivity;
119import com.android.settingslib.drawer.Tile;
120
121import java.util.ArrayList;
122import java.util.List;
123import java.util.Set;
124
125public class SettingsActivity extends SettingsDrawerActivity
126        implements PreferenceManager.OnPreferenceTreeClickListener,
127        PreferenceFragment.OnPreferenceStartFragmentCallback,
128        ButtonBarHandler, FragmentManager.OnBackStackChangedListener,
129        SearchView.OnQueryTextListener, SearchView.OnCloseListener,
130        MenuItem.OnActionExpandListener {
131
132    private static final String LOG_TAG = "Settings";
133
134    // Constants for state save/restore
135    private static final String SAVE_KEY_CATEGORIES = ":settings:categories";
136    private static final String SAVE_KEY_SEARCH_MENU_EXPANDED = ":settings:search_menu_expanded";
137    private static final String SAVE_KEY_SEARCH_QUERY = ":settings:search_query";
138    private static final String SAVE_KEY_SHOW_HOME_AS_UP = ":settings:show_home_as_up";
139    private static final String SAVE_KEY_SHOW_SEARCH = ":settings:show_search";
140    private static final String SAVE_KEY_HOME_ACTIVITIES_COUNT = ":settings:home_activities_count";
141
142    /**
143     * When starting this activity, the invoking Intent can contain this extra
144     * string to specify which fragment should be initially displayed.
145     * <p/>Starting from Key Lime Pie, when this argument is passed in, the activity
146     * will call isValidFragment() to confirm that the fragment class name is valid for this
147     * activity.
148     */
149    public static final String EXTRA_SHOW_FRAGMENT = ":settings:show_fragment";
150
151    /**
152     * When starting this activity and using {@link #EXTRA_SHOW_FRAGMENT},
153     * this extra can also be specified to supply a Bundle of arguments to pass
154     * to that fragment when it is instantiated during the initial creation
155     * of the activity.
156     */
157    public static final String EXTRA_SHOW_FRAGMENT_ARGUMENTS = ":settings:show_fragment_args";
158
159    /**
160     * Fragment "key" argument passed thru {@link #EXTRA_SHOW_FRAGMENT_ARGUMENTS}
161     */
162    public static final String EXTRA_FRAGMENT_ARG_KEY = ":settings:fragment_args_key";
163
164    public static final String BACK_STACK_PREFS = ":settings:prefs";
165
166    // extras that allow any preference activity to be launched as part of a wizard
167
168    // show Back and Next buttons? takes boolean parameter
169    // Back will then return RESULT_CANCELED and Next RESULT_OK
170    protected static final String EXTRA_PREFS_SHOW_BUTTON_BAR = "extra_prefs_show_button_bar";
171
172    // add a Skip button?
173    private static final String EXTRA_PREFS_SHOW_SKIP = "extra_prefs_show_skip";
174
175    // specify custom text for the Back or Next buttons, or cause a button to not appear
176    // at all by setting it to null
177    protected static final String EXTRA_PREFS_SET_NEXT_TEXT = "extra_prefs_set_next_text";
178    protected static final String EXTRA_PREFS_SET_BACK_TEXT = "extra_prefs_set_back_text";
179
180    /**
181     * When starting this activity and using {@link #EXTRA_SHOW_FRAGMENT},
182     * those extra can also be specify to supply the title or title res id to be shown for
183     * that fragment.
184     */
185    public static final String EXTRA_SHOW_FRAGMENT_TITLE = ":settings:show_fragment_title";
186    /**
187     * The package name used to resolve the title resource id.
188     */
189    public static final String EXTRA_SHOW_FRAGMENT_TITLE_RES_PACKAGE_NAME =
190            ":settings:show_fragment_title_res_package_name";
191    public static final String EXTRA_SHOW_FRAGMENT_TITLE_RESID =
192            ":settings:show_fragment_title_resid";
193    public static final String EXTRA_SHOW_FRAGMENT_AS_SHORTCUT =
194            ":settings:show_fragment_as_shortcut";
195
196    public static final String EXTRA_SHOW_FRAGMENT_AS_SUBSETTING =
197            ":settings:show_fragment_as_subsetting";
198
199    public static final String META_DATA_KEY_FRAGMENT_CLASS =
200        "com.android.settings.FRAGMENT_CLASS";
201
202    private static final String EXTRA_UI_OPTIONS = "settings:ui_options";
203
204    private static final String EMPTY_QUERY = "";
205
206    private static final int REQUEST_SUGGESTION = 42;
207
208    private String mFragmentClass;
209
210    private CharSequence mInitialTitle;
211    private int mInitialTitleResId;
212
213    // Show only these settings for restricted users
214    private String[] SETTINGS_FOR_RESTRICTED = {
215            //wireless_section
216            WifiSettingsActivity.class.getName(),
217            Settings.BluetoothSettingsActivity.class.getName(),
218            Settings.DataUsageSummaryActivity.class.getName(),
219            Settings.SimSettingsActivity.class.getName(),
220            Settings.WirelessSettingsActivity.class.getName(),
221            //device_section
222            Settings.HomeSettingsActivity.class.getName(),
223            Settings.SoundSettingsActivity.class.getName(),
224            Settings.DisplaySettingsActivity.class.getName(),
225            Settings.StorageSettingsActivity.class.getName(),
226            Settings.ManageApplicationsActivity.class.getName(),
227            Settings.PowerUsageSummaryActivity.class.getName(),
228            //personal_section
229            Settings.LocationSettingsActivity.class.getName(),
230            Settings.SecuritySettingsActivity.class.getName(),
231            Settings.InputMethodAndLanguageSettingsActivity.class.getName(),
232            Settings.UserSettingsActivity.class.getName(),
233            Settings.AccountSettingsActivity.class.getName(),
234            //system_section
235            Settings.DateTimeSettingsActivity.class.getName(),
236            Settings.DeviceInfoSettingsActivity.class.getName(),
237            Settings.AccessibilitySettingsActivity.class.getName(),
238            Settings.PrintSettingsActivity.class.getName(),
239            Settings.PaymentSettingsActivity.class.getName(),
240    };
241
242    private static final String[] ENTRY_FRAGMENTS = {
243            WirelessSettings.class.getName(),
244            WifiSettings.class.getName(),
245            AdvancedWifiSettings.class.getName(),
246            SavedAccessPointsWifiSettings.class.getName(),
247            BluetoothSettings.class.getName(),
248            SimSettings.class.getName(),
249            TetherSettings.class.getName(),
250            WifiP2pSettings.class.getName(),
251            VpnSettings.class.getName(),
252            DateTimeSettings.class.getName(),
253            LocaleListEditor.class.getName(),
254            InputMethodAndLanguageSettings.class.getName(),
255            AvailableVirtualKeyboardFragment.class.getName(),
256            SpellCheckersSettings.class.getName(),
257            UserDictionaryList.class.getName(),
258            UserDictionarySettings.class.getName(),
259            HomeSettings.class.getName(),
260            DisplaySettings.class.getName(),
261            DeviceInfoSettings.class.getName(),
262            ManageApplications.class.getName(),
263            NotificationApps.class.getName(),
264            ManageAssist.class.getName(),
265            ProcessStatsUi.class.getName(),
266            NotificationStation.class.getName(),
267            LocationSettings.class.getName(),
268            SecuritySettings.class.getName(),
269            UsageAccessDetails.class.getName(),
270            PrivacySettings.class.getName(),
271            DeviceAdminSettings.class.getName(),
272            AccessibilitySettings.class.getName(),
273            AccessibilitySettingsForSetupWizard.class.getName(),
274            CaptionPropertiesFragment.class.getName(),
275            com.android.settings.accessibility.ToggleDaltonizerPreferenceFragment.class.getName(),
276            TextToSpeechSettings.class.getName(),
277            StorageSettings.class.getName(),
278            PrivateVolumeForget.class.getName(),
279            PrivateVolumeSettings.class.getName(),
280            PublicVolumeSettings.class.getName(),
281            DevelopmentSettings.class.getName(),
282            AndroidBeam.class.getName(),
283            WifiDisplaySettings.class.getName(),
284            PowerUsageSummary.class.getName(),
285            AccountSyncSettings.class.getName(),
286            AccountSettings.class.getName(),
287            CryptKeeperSettings.class.getName(),
288            DataUsageSummary.class.getName(),
289            DreamSettings.class.getName(),
290            UserSettings.class.getName(),
291            NotificationAccessSettings.class.getName(),
292            ZenAccessSettings.class.getName(),
293            PrintSettingsFragment.class.getName(),
294            PrintJobSettingsFragment.class.getName(),
295            TrustedCredentialsSettings.class.getName(),
296            PaymentSettings.class.getName(),
297            KeyboardLayoutPickerFragment.class.getName(),
298            KeyboardLayoutPickerFragment2.class.getName(),
299            ZenModeSettings.class.getName(),
300            SoundSettings.class.getName(),
301            ConfigureNotificationSettings.class.getName(),
302            ChooseLockPassword.ChooseLockPasswordFragment.class.getName(),
303            ChooseLockPattern.ChooseLockPatternFragment.class.getName(),
304            InstalledAppDetails.class.getName(),
305            BatterySaverSettings.class.getName(),
306            AppNotificationSettings.class.getName(),
307            OtherSoundSettings.class.getName(),
308            ApnSettings.class.getName(),
309            WifiCallingSettings.class.getName(),
310            ZenModePrioritySettings.class.getName(),
311            ZenModeAutomationSettings.class.getName(),
312            ZenModeScheduleRuleSettings.class.getName(),
313            ZenModeEventRuleSettings.class.getName(),
314            ZenModeVisualInterruptionSettings.class.getName(),
315            ProcessStatsUi.class.getName(),
316            PowerUsageDetail.class.getName(),
317            ProcessStatsSummary.class.getName(),
318            DrawOverlayDetails.class.getName(),
319            WriteSettingsDetails.class.getName(),
320            AdvancedAppSettings.class.getName(),
321            WallpaperTypeSettings.class.getName(),
322    };
323
324
325    private static final String[] LIKE_SHORTCUT_INTENT_ACTION_ARRAY = {
326            "android.settings.APPLICATION_DETAILS_SETTINGS"
327    };
328
329    private SharedPreferences mDevelopmentPreferences;
330    private SharedPreferences.OnSharedPreferenceChangeListener mDevelopmentPreferencesListener;
331
332    private boolean mBatteryPresent = true;
333    private BroadcastReceiver mBatteryInfoReceiver = new BroadcastReceiver() {
334        @Override
335        public void onReceive(Context context, Intent intent) {
336            String action = intent.getAction();
337            if (Intent.ACTION_BATTERY_CHANGED.equals(action)) {
338                boolean batteryPresent = Utils.isBatteryPresent(intent);
339
340                if (mBatteryPresent != batteryPresent) {
341                    mBatteryPresent = batteryPresent;
342                    updateTilesList();
343                }
344            }
345        }
346    };
347
348    private final BroadcastReceiver mUserAddRemoveReceiver = new BroadcastReceiver() {
349        @Override
350        public void onReceive(Context context, Intent intent) {
351            String action = intent.getAction();
352            if (action.equals(Intent.ACTION_USER_ADDED)
353                    || action.equals(Intent.ACTION_USER_REMOVED)) {
354                Index.getInstance(getApplicationContext()).update();
355            }
356        }
357    };
358
359    private final DynamicIndexableContentMonitor mDynamicIndexableContentMonitor =
360            new DynamicIndexableContentMonitor();
361
362    private ActionBar mActionBar;
363    private SwitchBar mSwitchBar;
364
365    private Button mNextButton;
366
367    private boolean mDisplayHomeAsUpEnabled;
368    private boolean mDisplaySearch;
369
370    private boolean mIsShowingDashboard;
371    private boolean mIsShortcut;
372
373    private ViewGroup mContent;
374
375    private SearchView mSearchView;
376    private MenuItem mSearchMenuItem;
377    private boolean mSearchMenuItemExpanded = false;
378    private SearchResultsSummary mSearchResultsFragment;
379    private String mSearchQuery;
380
381    // Categories
382    private ArrayList<DashboardCategory> mCategories = new ArrayList<DashboardCategory>();
383
384    private static final String MSG_DATA_FORCE_REFRESH = "msg_data_force_refresh";
385
386    private boolean mNeedToRevertToInitialFragment = false;
387
388    private Intent mResultIntentData;
389    private ComponentName mCurrentSuggestion;
390
391    public SwitchBar getSwitchBar() {
392        return mSwitchBar;
393    }
394
395    @Override
396    public boolean onPreferenceStartFragment(PreferenceFragment caller, Preference pref) {
397        // Override the fragment title for Wallpaper settings
398        CharSequence title = pref.getTitle();
399        if (pref.getFragment().equals(WallpaperTypeSettings.class.getName())) {
400            title = getString(R.string.wallpaper_settings_fragment_title);
401        }
402        startPreferencePanel(pref.getFragment(), pref.getExtras(), -1, title,
403                null, 0);
404        return true;
405    }
406
407    @Override
408    public boolean onPreferenceTreeClick(Preference preference) {
409        return false;
410    }
411
412    @Override
413    public void onConfigurationChanged(Configuration newConfig) {
414        super.onConfigurationChanged(newConfig);
415        Index.getInstance(this).update();
416    }
417
418    @Override
419    protected void onStart() {
420        super.onStart();
421
422        if (mNeedToRevertToInitialFragment) {
423            revertToInitialFragment();
424        }
425    }
426
427    @Override
428    public boolean onCreateOptionsMenu(Menu menu) {
429        if (!mDisplaySearch) {
430            return false;
431        }
432
433        MenuInflater inflater = getMenuInflater();
434        inflater.inflate(R.menu.options_menu, menu);
435
436        // Cache the search query (can be overriden by the OnQueryTextListener)
437        final String query = mSearchQuery;
438
439        mSearchMenuItem = menu.findItem(R.id.search);
440        mSearchView = (SearchView) mSearchMenuItem.getActionView();
441
442        if (mSearchMenuItem == null || mSearchView == null) {
443            return false;
444        }
445
446        if (mSearchResultsFragment != null) {
447            mSearchResultsFragment.setSearchView(mSearchView);
448        }
449
450        mSearchMenuItem.setOnActionExpandListener(this);
451        mSearchView.setOnQueryTextListener(this);
452        mSearchView.setOnCloseListener(this);
453
454        if (mSearchMenuItemExpanded) {
455            mSearchMenuItem.expandActionView();
456        }
457        mSearchView.setQuery(query, true /* submit */);
458
459        return true;
460    }
461
462    @Override
463    public SharedPreferences getSharedPreferences(String name, int mode) {
464        if (name.equals(getPackageName() + "_preferences")) {
465            return new SharedPreferencesLogger(this, getMetricsTag());
466        }
467        return super.getSharedPreferences(name, mode);
468    }
469
470    private String getMetricsTag() {
471        String tag = getClass().getName();
472        if (getIntent() != null && getIntent().hasExtra(EXTRA_SHOW_FRAGMENT)) {
473            tag = getIntent().getStringExtra(EXTRA_SHOW_FRAGMENT);
474        }
475        if (tag.startsWith("com.android.settings.")) {
476            tag = tag.replace("com.android.settings.", "");
477        }
478        return tag;
479    }
480
481    private static boolean isShortCutIntent(final Intent intent) {
482        Set<String> categories = intent.getCategories();
483        return (categories != null) && categories.contains("com.android.settings.SHORTCUT");
484    }
485
486    private static boolean isLikeShortCutIntent(final Intent intent) {
487        String action = intent.getAction();
488        if (action == null) {
489            return false;
490        }
491        for (int i = 0; i < LIKE_SHORTCUT_INTENT_ACTION_ARRAY.length; i++) {
492            if (LIKE_SHORTCUT_INTENT_ACTION_ARRAY[i].equals(action)) return true;
493        }
494        return false;
495    }
496
497    @Override
498    protected void onCreate(Bundle savedState) {
499        super.onCreate(savedState);
500        long startTime = System.currentTimeMillis();
501
502        // Should happen before any call to getIntent()
503        getMetaData();
504
505        final Intent intent = getIntent();
506        if (intent.hasExtra(EXTRA_UI_OPTIONS)) {
507            getWindow().setUiOptions(intent.getIntExtra(EXTRA_UI_OPTIONS, 0));
508        }
509
510        mDevelopmentPreferences = getSharedPreferences(DevelopmentSettings.PREF_FILE,
511                Context.MODE_PRIVATE);
512
513        // Getting Intent properties can only be done after the super.onCreate(...)
514        final String initialFragmentName = intent.getStringExtra(EXTRA_SHOW_FRAGMENT);
515
516        mIsShortcut = isShortCutIntent(intent) || isLikeShortCutIntent(intent) ||
517                intent.getBooleanExtra(EXTRA_SHOW_FRAGMENT_AS_SHORTCUT, false);
518
519        final ComponentName cn = intent.getComponent();
520        final String className = cn.getClassName();
521
522        mIsShowingDashboard = className.equals(Settings.class.getName())
523                || className.equals(Settings.WirelessSettings.class.getName())
524                || className.equals(Settings.DeviceSettings.class.getName())
525                || className.equals(Settings.PersonalSettings.class.getName())
526                || className.equals(Settings.WirelessSettings.class.getName());
527
528        // This is a "Sub Settings" when:
529        // - this is a real SubSettings
530        // - or :settings:show_fragment_as_subsetting is passed to the Intent
531        final boolean isSubSettings = this instanceof SubSettings ||
532                intent.getBooleanExtra(EXTRA_SHOW_FRAGMENT_AS_SUBSETTING, false);
533
534        // If this is a sub settings, then apply the SubSettings Theme for the ActionBar content insets
535        if (isSubSettings) {
536            // Check also that we are not a Theme Dialog as we don't want to override them
537            final int themeResId = getThemeResId();
538            if (themeResId != R.style.Theme_DialogWhenLarge &&
539                    themeResId != R.style.Theme_SubSettingsDialogWhenLarge) {
540                setTheme(R.style.Theme_SubSettings);
541            }
542        }
543
544        setContentView(mIsShowingDashboard ?
545                R.layout.settings_main_dashboard : R.layout.settings_main_prefs);
546
547        mContent = (ViewGroup) findViewById(R.id.main_content);
548
549        getFragmentManager().addOnBackStackChangedListener(this);
550
551        if (mIsShowingDashboard) {
552            // Run the Index update only if we have some space
553            if (!Utils.isLowStorage(this)) {
554                long indexStartTime = System.currentTimeMillis();
555                AsyncTask.execute(new Runnable() {
556                    @Override
557                    public void run() {
558                        Index.getInstance(getApplicationContext()).update();
559                    }
560                });
561                if (DEBUG_TIMING) Log.d(LOG_TAG, "Index.update() took "
562                        + (System.currentTimeMillis() - indexStartTime) + " ms");
563            } else {
564                Log.w(LOG_TAG, "Cannot update the Indexer as we are running low on storage space!");
565            }
566        }
567
568        if (savedState != null) {
569            // We are restarting from a previous saved state; used that to initialize, instead
570            // of starting fresh.
571            mSearchMenuItemExpanded = savedState.getBoolean(SAVE_KEY_SEARCH_MENU_EXPANDED);
572            mSearchQuery = savedState.getString(SAVE_KEY_SEARCH_QUERY);
573
574            setTitleFromIntent(intent);
575
576            ArrayList<DashboardCategory> categories =
577                    savedState.getParcelableArrayList(SAVE_KEY_CATEGORIES);
578            if (categories != null) {
579                mCategories.clear();
580                mCategories.addAll(categories);
581                setTitleFromBackStack();
582            }
583
584            mDisplayHomeAsUpEnabled = savedState.getBoolean(SAVE_KEY_SHOW_HOME_AS_UP);
585            mDisplaySearch = savedState.getBoolean(SAVE_KEY_SHOW_SEARCH);
586        } else {
587            if (!mIsShowingDashboard) {
588                mDisplaySearch = false;
589                // UP will be shown only if it is a sub settings
590                if (mIsShortcut) {
591                    mDisplayHomeAsUpEnabled = isSubSettings;
592                } else if (isSubSettings) {
593                    mDisplayHomeAsUpEnabled = true;
594                } else {
595                    mDisplayHomeAsUpEnabled = false;
596                }
597                setTitleFromIntent(intent);
598
599                Bundle initialArguments = intent.getBundleExtra(EXTRA_SHOW_FRAGMENT_ARGUMENTS);
600                switchToFragment(initialFragmentName, initialArguments, true, false,
601                        mInitialTitleResId, mInitialTitle, false);
602            } else {
603                // No UP affordance if we are displaying the main Dashboard
604                mDisplayHomeAsUpEnabled = false;
605                // Show Search affordance
606                mDisplaySearch = true;
607                mInitialTitleResId = R.string.dashboard_title;
608                switchToFragment(DashboardSummary.class.getName(), null, false, false,
609                        mInitialTitleResId, mInitialTitle, false);
610            }
611        }
612
613        mActionBar = getActionBar();
614        if (mActionBar != null) {
615            mActionBar.setDisplayHomeAsUpEnabled(mDisplayHomeAsUpEnabled);
616            mActionBar.setHomeButtonEnabled(mDisplayHomeAsUpEnabled);
617        }
618        mSwitchBar = (SwitchBar) findViewById(R.id.switch_bar);
619        if (mSwitchBar != null) {
620            mSwitchBar.setMetricsTag(getMetricsTag());
621        }
622
623        // see if we should show Back/Next buttons
624        if (intent.getBooleanExtra(EXTRA_PREFS_SHOW_BUTTON_BAR, false)) {
625
626            View buttonBar = findViewById(R.id.button_bar);
627            if (buttonBar != null) {
628                buttonBar.setVisibility(View.VISIBLE);
629
630                Button backButton = (Button)findViewById(R.id.back_button);
631                backButton.setOnClickListener(new OnClickListener() {
632                    public void onClick(View v) {
633                        setResult(RESULT_CANCELED, getResultIntentData());
634                        finish();
635                    }
636                });
637                Button skipButton = (Button)findViewById(R.id.skip_button);
638                skipButton.setOnClickListener(new OnClickListener() {
639                    public void onClick(View v) {
640                        setResult(RESULT_OK, getResultIntentData());
641                        finish();
642                    }
643                });
644                mNextButton = (Button)findViewById(R.id.next_button);
645                mNextButton.setOnClickListener(new OnClickListener() {
646                    public void onClick(View v) {
647                        setResult(RESULT_OK, getResultIntentData());
648                        finish();
649                    }
650                });
651
652                // set our various button parameters
653                if (intent.hasExtra(EXTRA_PREFS_SET_NEXT_TEXT)) {
654                    String buttonText = intent.getStringExtra(EXTRA_PREFS_SET_NEXT_TEXT);
655                    if (TextUtils.isEmpty(buttonText)) {
656                        mNextButton.setVisibility(View.GONE);
657                    }
658                    else {
659                        mNextButton.setText(buttonText);
660                    }
661                }
662                if (intent.hasExtra(EXTRA_PREFS_SET_BACK_TEXT)) {
663                    String buttonText = intent.getStringExtra(EXTRA_PREFS_SET_BACK_TEXT);
664                    if (TextUtils.isEmpty(buttonText)) {
665                        backButton.setVisibility(View.GONE);
666                    }
667                    else {
668                        backButton.setText(buttonText);
669                    }
670                }
671                if (intent.getBooleanExtra(EXTRA_PREFS_SHOW_SKIP, false)) {
672                    skipButton.setVisibility(View.VISIBLE);
673                }
674            }
675        }
676
677        if (DEBUG_TIMING) Log.d(LOG_TAG, "onCreate took " + (System.currentTimeMillis() - startTime)
678                + " ms");
679    }
680
681    private void setTitleFromIntent(Intent intent) {
682        final int initialTitleResId = intent.getIntExtra(EXTRA_SHOW_FRAGMENT_TITLE_RESID, -1);
683        if (initialTitleResId > 0) {
684            mInitialTitle = null;
685            mInitialTitleResId = initialTitleResId;
686
687            final String initialTitleResPackageName = intent.getStringExtra(
688                    EXTRA_SHOW_FRAGMENT_TITLE_RES_PACKAGE_NAME);
689            if (initialTitleResPackageName != null) {
690                try {
691                    Context authContext = createPackageContextAsUser(initialTitleResPackageName,
692                            0 /* flags */, new UserHandle(UserHandle.myUserId()));
693                    mInitialTitle = authContext.getResources().getText(mInitialTitleResId);
694                    setTitle(mInitialTitle);
695                    mInitialTitleResId = -1;
696                    return;
697                } catch (NameNotFoundException e) {
698                    Log.w(LOG_TAG, "Could not find package" + initialTitleResPackageName);
699                }
700            } else {
701                setTitle(mInitialTitleResId);
702            }
703        } else {
704            mInitialTitleResId = -1;
705            final String initialTitle = intent.getStringExtra(EXTRA_SHOW_FRAGMENT_TITLE);
706            mInitialTitle = (initialTitle != null) ? initialTitle : getTitle();
707            setTitle(mInitialTitle);
708        }
709    }
710
711    @Override
712    public void onBackStackChanged() {
713        setTitleFromBackStack();
714    }
715
716    private int setTitleFromBackStack() {
717        final int count = getFragmentManager().getBackStackEntryCount();
718
719        if (count == 0) {
720            if (mInitialTitleResId > 0) {
721                setTitle(mInitialTitleResId);
722            } else {
723                setTitle(mInitialTitle);
724            }
725            return 0;
726        }
727
728        FragmentManager.BackStackEntry bse = getFragmentManager().getBackStackEntryAt(count - 1);
729        setTitleFromBackStackEntry(bse);
730
731        return count;
732    }
733
734    private void setTitleFromBackStackEntry(FragmentManager.BackStackEntry bse) {
735        final CharSequence title;
736        final int titleRes = bse.getBreadCrumbTitleRes();
737        if (titleRes > 0) {
738            title = getText(titleRes);
739        } else {
740            title = bse.getBreadCrumbTitle();
741        }
742        if (title != null) {
743            setTitle(title);
744        }
745    }
746
747    @Override
748    protected void onSaveInstanceState(Bundle outState) {
749        super.onSaveInstanceState(outState);
750
751        if (mCategories.size() > 0) {
752            outState.putParcelableArrayList(SAVE_KEY_CATEGORIES, mCategories);
753        }
754
755        outState.putBoolean(SAVE_KEY_SHOW_HOME_AS_UP, mDisplayHomeAsUpEnabled);
756        outState.putBoolean(SAVE_KEY_SHOW_SEARCH, mDisplaySearch);
757
758        if (mDisplaySearch) {
759            // The option menus are created if the ActionBar is visible and they are also created
760            // asynchronously. If you launch Settings with an Intent action like
761            // android.intent.action.POWER_USAGE_SUMMARY and at the same time your device is locked
762            // thru a LockScreen, onCreateOptionsMenu() is not yet called and references to the search
763            // menu item and search view are null.
764            boolean isExpanded = (mSearchMenuItem != null) && mSearchMenuItem.isActionViewExpanded();
765            outState.putBoolean(SAVE_KEY_SEARCH_MENU_EXPANDED, isExpanded);
766
767            String query = (mSearchView != null) ? mSearchView.getQuery().toString() : EMPTY_QUERY;
768            outState.putString(SAVE_KEY_SEARCH_QUERY, query);
769        }
770    }
771
772    @Override
773    protected void onResume() {
774        super.onResume();
775
776        mDevelopmentPreferencesListener = new SharedPreferences.OnSharedPreferenceChangeListener() {
777            @Override
778            public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
779                updateTilesList();
780            }
781        };
782        mDevelopmentPreferences.registerOnSharedPreferenceChangeListener(
783                mDevelopmentPreferencesListener);
784
785        registerReceiver(mBatteryInfoReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
786        registerReceiver(mUserAddRemoveReceiver, new IntentFilter(Intent.ACTION_USER_ADDED));
787        registerReceiver(mUserAddRemoveReceiver, new IntentFilter(Intent.ACTION_USER_REMOVED));
788
789        mDynamicIndexableContentMonitor.register(this);
790
791        if(mDisplaySearch && !TextUtils.isEmpty(mSearchQuery)) {
792            onQueryTextSubmit(mSearchQuery);
793        }
794        updateTilesList();
795    }
796
797    @Override
798    protected void onPause() {
799        super.onPause();
800        unregisterReceiver(mBatteryInfoReceiver);
801        unregisterReceiver(mUserAddRemoveReceiver);
802        mDynamicIndexableContentMonitor.unregister();
803    }
804
805    @Override
806    public void onDestroy() {
807        super.onDestroy();
808
809        mDevelopmentPreferences.unregisterOnSharedPreferenceChangeListener(
810                mDevelopmentPreferencesListener);
811        mDevelopmentPreferencesListener = null;
812    }
813
814    protected boolean isValidFragment(String fragmentName) {
815        // Almost all fragments are wrapped in this,
816        // except for a few that have their own activities.
817        for (int i = 0; i < ENTRY_FRAGMENTS.length; i++) {
818            if (ENTRY_FRAGMENTS[i].equals(fragmentName)) return true;
819        }
820        return false;
821    }
822
823    @Override
824    public Intent getIntent() {
825        Intent superIntent = super.getIntent();
826        String startingFragment = getStartingFragmentClass(superIntent);
827        // This is called from super.onCreate, isMultiPane() is not yet reliable
828        // Do not use onIsHidingHeaders either, which relies itself on this method
829        if (startingFragment != null) {
830            Intent modIntent = new Intent(superIntent);
831            modIntent.putExtra(EXTRA_SHOW_FRAGMENT, startingFragment);
832            Bundle args = superIntent.getExtras();
833            if (args != null) {
834                args = new Bundle(args);
835            } else {
836                args = new Bundle();
837            }
838            args.putParcelable("intent", superIntent);
839            modIntent.putExtra(EXTRA_SHOW_FRAGMENT_ARGUMENTS, args);
840            return modIntent;
841        }
842        return superIntent;
843    }
844
845    /**
846     * Checks if the component name in the intent is different from the Settings class and
847     * returns the class name to load as a fragment.
848     */
849    private String getStartingFragmentClass(Intent intent) {
850        if (mFragmentClass != null) return mFragmentClass;
851
852        String intentClass = intent.getComponent().getClassName();
853        if (intentClass.equals(getClass().getName())) return null;
854
855        if ("com.android.settings.ManageApplications".equals(intentClass)
856                || "com.android.settings.RunningServices".equals(intentClass)
857                || "com.android.settings.applications.StorageUse".equals(intentClass)) {
858            // Old names of manage apps.
859            intentClass = com.android.settings.applications.ManageApplications.class.getName();
860        }
861
862        return intentClass;
863    }
864
865    /**
866     * Start a new fragment containing a preference panel.  If the preferences
867     * are being displayed in multi-pane mode, the given fragment class will
868     * be instantiated and placed in the appropriate pane.  If running in
869     * single-pane mode, a new activity will be launched in which to show the
870     * fragment.
871     *
872     * @param fragmentClass Full name of the class implementing the fragment.
873     * @param args Any desired arguments to supply to the fragment.
874     * @param titleRes Optional resource identifier of the title of this
875     * fragment.
876     * @param titleText Optional text of the title of this fragment.
877     * @param resultTo Optional fragment that result data should be sent to.
878     * If non-null, resultTo.onActivityResult() will be called when this
879     * preference panel is done.  The launched panel must use
880     * {@link #finishPreferencePanel(Fragment, int, Intent)} when done.
881     * @param resultRequestCode If resultTo is non-null, this is the caller's
882     * request code to be received with the result.
883     */
884    public void startPreferencePanel(String fragmentClass, Bundle args, int titleRes,
885            CharSequence titleText, Fragment resultTo, int resultRequestCode) {
886        String title = null;
887        if (titleRes < 0) {
888            if (titleText != null) {
889                title = titleText.toString();
890            } else {
891                // There not much we can do in that case
892                title = "";
893            }
894        }
895        Utils.startWithFragment(this, fragmentClass, args, resultTo, resultRequestCode,
896                titleRes, title, mIsShortcut);
897    }
898
899    /**
900     * Start a new fragment in a new activity containing a preference panel for a given user. If the
901     * preferences are being displayed in multi-pane mode, the given fragment class will be
902     * instantiated and placed in the appropriate pane. If running in single-pane mode, a new
903     * activity will be launched in which to show the fragment.
904     *
905     * @param fragmentClass Full name of the class implementing the fragment.
906     * @param args Any desired arguments to supply to the fragment.
907     * @param titleRes Optional resource identifier of the title of this fragment.
908     * @param titleText Optional text of the title of this fragment.
909     * @param userHandle The user for which the panel has to be started.
910     */
911    public void startPreferencePanelAsUser(String fragmentClass, Bundle args, int titleRes,
912            CharSequence titleText, UserHandle userHandle) {
913        // This is a workaround.
914        //
915        // Calling startWithFragmentAsUser() without specifying FLAG_ACTIVITY_NEW_TASK to the intent
916        // starting the fragment could cause a native stack corruption. See b/17523189. However,
917        // adding that flag and start the preference panel with the same UserHandler will make it
918        // impossible to use back button to return to the previous screen. See b/20042570.
919        //
920        // We work around this issue by adding FLAG_ACTIVITY_NEW_TASK to the intent, while doing
921        // another check here to call startPreferencePanel() instead of startWithFragmentAsUser()
922        // when we're calling it as the same user.
923        if (userHandle.getIdentifier() == UserHandle.myUserId()) {
924            startPreferencePanel(fragmentClass, args, titleRes, titleText, null, 0);
925        } else {
926            String title = null;
927            if (titleRes < 0) {
928                if (titleText != null) {
929                    title = titleText.toString();
930                } else {
931                    // There not much we can do in that case
932                    title = "";
933                }
934            }
935            Utils.startWithFragmentAsUser(this, fragmentClass, args,
936                    titleRes, title, mIsShortcut, userHandle);
937        }
938    }
939
940    /**
941     * Called by a preference panel fragment to finish itself.
942     *
943     * @param caller The fragment that is asking to be finished.
944     * @param resultCode Optional result code to send back to the original
945     * launching fragment.
946     * @param resultData Optional result data to send back to the original
947     * launching fragment.
948     */
949    public void finishPreferencePanel(Fragment caller, int resultCode, Intent resultData) {
950        setResult(resultCode, resultData);
951        finish();
952    }
953
954    /**
955     * Start a new fragment.
956     *
957     * @param fragment The fragment to start
958     * @param push If true, the current fragment will be pushed onto the back stack.  If false,
959     * the current fragment will be replaced.
960     */
961    public void startPreferenceFragment(Fragment fragment, boolean push) {
962        FragmentTransaction transaction = getFragmentManager().beginTransaction();
963        transaction.replace(R.id.main_content, fragment);
964        if (push) {
965            transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
966            transaction.addToBackStack(BACK_STACK_PREFS);
967        } else {
968            transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
969        }
970        transaction.commitAllowingStateLoss();
971    }
972
973    /**
974     * Switch to a specific Fragment with taking care of validation, Title and BackStack
975     */
976    private Fragment switchToFragment(String fragmentName, Bundle args, boolean validate,
977            boolean addToBackStack, int titleResId, CharSequence title, boolean withTransition) {
978        if (validate && !isValidFragment(fragmentName)) {
979            throw new IllegalArgumentException("Invalid fragment for this activity: "
980                    + fragmentName);
981        }
982        Fragment f = Fragment.instantiate(this, fragmentName, args);
983        FragmentTransaction transaction = getFragmentManager().beginTransaction();
984        transaction.replace(R.id.main_content, f);
985        if (withTransition) {
986            TransitionManager.beginDelayedTransition(mContent);
987        }
988        if (addToBackStack) {
989            transaction.addToBackStack(SettingsActivity.BACK_STACK_PREFS);
990        }
991        if (titleResId > 0) {
992            transaction.setBreadCrumbTitle(titleResId);
993        } else if (title != null) {
994            transaction.setBreadCrumbTitle(title);
995        }
996        transaction.commitAllowingStateLoss();
997        getFragmentManager().executePendingTransactions();
998        return f;
999    }
1000
1001    private void updateTilesList() {
1002        // Generally the items that are will be changing from these updates will
1003        // not be in the top list of tiles, so run it in the background and the
1004        // SettingsDrawerActivity will pick up on the updates automatically.
1005        AsyncTask.execute(new Runnable() {
1006            @Override
1007            public void run() {
1008                doUpdateTilesList();
1009            }
1010        });
1011    }
1012
1013    private void doUpdateTilesList() {
1014        PackageManager pm = getPackageManager();
1015        final UserManager um = UserManager.get(this);
1016        final boolean isAdmin = um.isAdminUser();
1017
1018        String packageName = getPackageName();
1019        setTileEnabled(new ComponentName(packageName, WifiSettingsActivity.class.getName()),
1020                pm.hasSystemFeature(PackageManager.FEATURE_WIFI), isAdmin, pm);
1021
1022        setTileEnabled(new ComponentName(packageName,
1023                Settings.BluetoothSettingsActivity.class.getName()),
1024                pm.hasSystemFeature(PackageManager.FEATURE_BLUETOOTH), isAdmin, pm);
1025
1026        setTileEnabled(new ComponentName(packageName,
1027                Settings.DataUsageSummaryActivity.class.getName()),
1028                Utils.isBandwidthControlEnabled(), isAdmin, pm);
1029
1030        setTileEnabled(new ComponentName(packageName,
1031                Settings.SimSettingsActivity.class.getName()),
1032                Utils.showSimCardTile(this), isAdmin, pm);
1033
1034        setTileEnabled(new ComponentName(packageName,
1035                Settings.PowerUsageSummaryActivity.class.getName()),
1036                mBatteryPresent, isAdmin, pm);
1037
1038        setTileEnabled(new ComponentName(packageName,
1039                Settings.UserSettingsActivity.class.getName()),
1040                UserHandle.MU_ENABLED && UserManager.supportsMultipleUsers()
1041                && !Utils.isMonkeyRunning(), isAdmin, pm);
1042
1043        NfcAdapter adapter = NfcAdapter.getDefaultAdapter(this);
1044        setTileEnabled(new ComponentName(packageName,
1045                        Settings.PaymentSettingsActivity.class.getName()),
1046                pm.hasSystemFeature(PackageManager.FEATURE_NFC)
1047                        && pm.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION)
1048                        && adapter != null && adapter.isEnabled(), isAdmin, pm);
1049
1050        setTileEnabled(new ComponentName(packageName,
1051                Settings.PrintSettingsActivity.class.getName()),
1052                pm.hasSystemFeature(PackageManager.FEATURE_PRINTING), isAdmin, pm);
1053
1054        final boolean showDev = mDevelopmentPreferences.getBoolean(
1055                DevelopmentSettings.PREF_SHOW,
1056                android.os.Build.TYPE.equals("eng"));
1057        setTileEnabled(new ComponentName(packageName,
1058                        Settings.DevelopmentSettingsActivity.class.getName()),
1059                showDev && !um.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES),
1060                isAdmin, pm);
1061
1062        if (UserHandle.MU_ENABLED && !isAdmin) {
1063            // When on restricted users, disable all extra categories (but only the settings ones).
1064            List<DashboardCategory> categories = getDashboardCategories();
1065            for (DashboardCategory category : categories) {
1066                for (Tile tile : category.tiles) {
1067                    ComponentName component = tile.intent.getComponent();
1068                    if (packageName.equals(component)&& !ArrayUtils.contains(
1069                            SETTINGS_FOR_RESTRICTED, component.getClassName())) {
1070                        setTileEnabled(component, false, isAdmin, pm);
1071                    }
1072                }
1073            }
1074        }
1075    }
1076
1077    private void setTileEnabled(ComponentName component, boolean enabled, boolean isAdmin,
1078                                PackageManager pm) {
1079        if (UserHandle.MU_ENABLED && !isAdmin
1080                && !ArrayUtils.contains(SETTINGS_FOR_RESTRICTED, component.getClassName())) {
1081            enabled = false;
1082        }
1083        int state = pm.getComponentEnabledSetting(component);
1084        boolean isEnabled = state == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
1085                || state == PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
1086        if (isEnabled != enabled) {
1087            pm.setComponentEnabledSetting(component, enabled
1088                    ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED
1089                    : PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
1090                    PackageManager.DONT_KILL_APP);
1091        }
1092    }
1093
1094    private void getMetaData() {
1095        try {
1096            ActivityInfo ai = getPackageManager().getActivityInfo(getComponentName(),
1097                    PackageManager.GET_META_DATA);
1098            if (ai == null || ai.metaData == null) return;
1099            mFragmentClass = ai.metaData.getString(META_DATA_KEY_FRAGMENT_CLASS);
1100        } catch (NameNotFoundException nnfe) {
1101            // No recovery
1102            Log.d(LOG_TAG, "Cannot get Metadata for: " + getComponentName().toString());
1103        }
1104    }
1105
1106    // give subclasses access to the Next button
1107    public boolean hasNextButton() {
1108        return mNextButton != null;
1109    }
1110
1111    public Button getNextButton() {
1112        return mNextButton;
1113    }
1114
1115    @Override
1116    public boolean shouldUpRecreateTask(Intent targetIntent) {
1117        return super.shouldUpRecreateTask(new Intent(this, SettingsActivity.class));
1118    }
1119
1120    @Override
1121    public boolean onQueryTextSubmit(String query) {
1122        switchToSearchResultsFragmentIfNeeded();
1123        mSearchQuery = query;
1124        return mSearchResultsFragment.onQueryTextSubmit(query);
1125    }
1126
1127    @Override
1128    public boolean onQueryTextChange(String newText) {
1129        mSearchQuery = newText;
1130        if (mSearchResultsFragment == null) {
1131            return false;
1132        }
1133        return mSearchResultsFragment.onQueryTextChange(newText);
1134    }
1135
1136    @Override
1137    public boolean onClose() {
1138        return false;
1139    }
1140
1141    @Override
1142    public boolean onMenuItemActionExpand(MenuItem item) {
1143        if (item.getItemId() == mSearchMenuItem.getItemId()) {
1144            switchToSearchResultsFragmentIfNeeded();
1145        }
1146        return true;
1147    }
1148
1149    @Override
1150    public boolean onMenuItemActionCollapse(MenuItem item) {
1151        if (item.getItemId() == mSearchMenuItem.getItemId()) {
1152            if (mSearchMenuItemExpanded) {
1153                revertToInitialFragment();
1154            }
1155        }
1156        return true;
1157    }
1158
1159    @Override
1160    protected void onTileClicked(Tile tile) {
1161        if (mIsShowingDashboard) {
1162            // If on dashboard, don't finish so the back comes back to here.
1163            openTile(tile);
1164        } else {
1165            super.onTileClicked(tile);
1166        }
1167    }
1168
1169    @Override
1170    public void onProfileTileOpen() {
1171        if (!mIsShowingDashboard) {
1172            finish();
1173        }
1174    }
1175
1176    private void switchToSearchResultsFragmentIfNeeded() {
1177        if (mSearchResultsFragment != null) {
1178            return;
1179        }
1180        Fragment current = getFragmentManager().findFragmentById(R.id.main_content);
1181        if (current != null && current instanceof SearchResultsSummary) {
1182            mSearchResultsFragment = (SearchResultsSummary) current;
1183        } else {
1184            mSearchResultsFragment = (SearchResultsSummary) switchToFragment(
1185                    SearchResultsSummary.class.getName(), null, false, true,
1186                    R.string.search_results_title, null, true);
1187        }
1188        mSearchResultsFragment.setSearchView(mSearchView);
1189        mSearchMenuItemExpanded = true;
1190    }
1191
1192    public void needToRevertToInitialFragment() {
1193        mNeedToRevertToInitialFragment = true;
1194    }
1195
1196    private void revertToInitialFragment() {
1197        mNeedToRevertToInitialFragment = false;
1198        mSearchResultsFragment = null;
1199        mSearchMenuItemExpanded = false;
1200        getFragmentManager().popBackStackImmediate(SettingsActivity.BACK_STACK_PREFS,
1201                FragmentManager.POP_BACK_STACK_INCLUSIVE);
1202        if (mSearchMenuItem != null) {
1203            mSearchMenuItem.collapseActionView();
1204        }
1205    }
1206
1207    public Intent getResultIntentData() {
1208        return mResultIntentData;
1209    }
1210
1211    public void setResultIntentData(Intent resultIntentData) {
1212        mResultIntentData = resultIntentData;
1213    }
1214
1215    public void startSuggestion(Intent intent) {
1216        mCurrentSuggestion = intent.getComponent();
1217        startActivityForResult(intent, REQUEST_SUGGESTION);
1218    }
1219
1220    @Override
1221    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
1222        if (requestCode == REQUEST_SUGGESTION && mCurrentSuggestion != null
1223                && resultCode != RESULT_CANCELED) {
1224            getPackageManager().setComponentEnabledSetting(mCurrentSuggestion,
1225                    PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
1226        }
1227        super.onActivityResult(requestCode, resultCode, data);
1228    }
1229
1230}
1231