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