OSDN Git Service

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