2 * Copyright (C) 2014 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package com.android.settings;
19 import android.app.ActivityManager;
20 import android.app.Fragment;
21 import android.app.FragmentManager;
22 import android.app.FragmentTransaction;
23 import android.content.ActivityNotFoundException;
24 import android.app.ActionBar;
25 import android.content.BroadcastReceiver;
26 import android.content.ComponentName;
27 import android.content.Context;
28 import android.content.Intent;
29 import android.content.IntentFilter;
30 import android.content.SharedPreferences;
31 import android.content.pm.ActivityInfo;
32 import android.content.pm.PackageManager;
33 import android.content.pm.ResolveInfo;
34 import android.content.pm.PackageManager.NameNotFoundException;
35 import android.content.res.Configuration;
36 import android.nfc.NfcAdapter;
37 import android.os.AsyncTask;
38 import android.os.Bundle;
39 import android.os.UserHandle;
40 import android.os.UserManager;
41 import android.support.v14.preference.PreferenceFragment;
42 import android.support.v7.preference.Preference;
43 import android.support.v7.preference.PreferenceManager;
44 import android.text.TextUtils;
45 import android.transition.TransitionManager;
46 import android.util.Log;
47 import android.view.Menu;
48 import android.view.MenuInflater;
49 import android.view.MenuItem;
50 import android.view.View;
51 import android.view.View.OnClickListener;
52 import android.view.ViewGroup;
53 import android.widget.Button;
54 import android.widget.SearchView;
56 import com.android.internal.util.ArrayUtils;
57 import com.android.settings.Settings.WifiSettingsActivity;
58 import com.android.settings.accessibility.AccessibilitySettings;
59 import com.android.settings.accessibility.AccessibilitySettingsForSetupWizard;
60 import com.android.settings.accessibility.CaptionPropertiesFragment;
61 import com.android.settings.accounts.AccountSettings;
62 import com.android.settings.accounts.AccountSyncSettings;
63 import com.android.settings.accounts.ChooseAccountActivity;
64 import com.android.settings.accounts.ManagedProfileSettings;
65 import com.android.settings.applications.AdvancedAppSettings;
66 import com.android.settings.applications.DrawOverlayDetails;
67 import com.android.settings.applications.InstalledAppDetails;
68 import com.android.settings.applications.ManageApplications;
69 import com.android.settings.applications.ManageAssist;
70 import com.android.settings.applications.ManageDomainUrls;
71 import com.android.settings.applications.NotificationApps;
72 import com.android.settings.applications.ProcessStatsSummary;
73 import com.android.settings.applications.ProcessStatsUi;
74 import com.android.settings.applications.UsageAccessDetails;
75 import com.android.settings.applications.VrListenerSettings;
76 import com.android.settings.applications.WriteSettingsDetails;
77 import com.android.settings.bluetooth.BluetoothSettings;
78 import com.android.settings.dashboard.DashboardContainerFragment;
79 import com.android.settings.dashboard.SearchResultsSummary;
80 import com.android.settings.datausage.DataUsageSummary;
81 import com.android.settings.deletionhelper.AutomaticStorageManagerSettings;
82 import com.android.settings.deviceinfo.ImeiInformation;
83 import com.android.settings.deviceinfo.PrivateVolumeForget;
84 import com.android.settings.deviceinfo.PrivateVolumeSettings;
85 import com.android.settings.deviceinfo.PublicVolumeSettings;
86 import com.android.settings.deviceinfo.SimStatus;
87 import com.android.settings.deviceinfo.Status;
88 import com.android.settings.deviceinfo.StorageSettings;
89 import com.android.settings.display.NightDisplaySettings;
90 import com.android.settings.fuelgauge.BatterySaverSettings;
91 import com.android.settings.fuelgauge.PowerUsageDetail;
92 import com.android.settings.fuelgauge.PowerUsageSummary;
93 import com.android.settings.gestures.GestureSettings;
94 import com.android.settings.inputmethod.AvailableVirtualKeyboardFragment;
95 import com.android.settings.inputmethod.InputMethodAndLanguageSettings;
96 import com.android.settings.inputmethod.KeyboardLayoutPickerFragment;
97 import com.android.settings.inputmethod.KeyboardLayoutPickerFragment2;
98 import com.android.settings.inputmethod.PhysicalKeyboardFragment;
99 import com.android.settings.inputmethod.SpellCheckersSettings;
100 import com.android.settings.inputmethod.UserDictionaryList;
101 import com.android.settings.localepicker.LocaleListEditor;
102 import com.android.settings.location.LocationSettings;
103 import com.android.settings.nfc.AndroidBeam;
104 import com.android.settings.nfc.PaymentSettings;
105 import com.android.settings.notification.AppNotificationSettings;
106 import com.android.settings.notification.ConfigureNotificationSettings;
107 import com.android.settings.notification.NotificationAccessSettings;
108 import com.android.settings.notification.NotificationStation;
109 import com.android.settings.notification.OtherSoundSettings;
110 import com.android.settings.notification.SoundSettings;
111 import com.android.settings.notification.ZenAccessSettings;
112 import com.android.settings.notification.ZenModeAutomationSettings;
113 import com.android.settings.notification.ZenModeEventRuleSettings;
114 import com.android.settings.notification.ZenModePrioritySettings;
115 import com.android.settings.notification.ZenModeScheduleRuleSettings;
116 import com.android.settings.notification.ZenModeSettings;
117 import com.android.settings.notification.ZenModeVisualInterruptionSettings;
118 import com.android.settings.print.PrintJobSettingsFragment;
119 import com.android.settings.print.PrintSettingsFragment;
120 import com.android.settings.qstile.DevelopmentTiles;
121 import com.android.settings.search.DynamicIndexableContentMonitor;
122 import com.android.settings.search.Index;
123 import com.android.settings.sim.SimSettings;
124 import com.android.settings.tts.TextToSpeechSettings;
125 import com.android.settings.users.UserSettings;
126 import com.android.settings.vpn2.VpnSettings;
127 import com.android.settings.wfd.WifiDisplaySettings;
128 import com.android.settings.widget.SwitchBar;
129 import com.android.settings.wifi.AdvancedWifiSettings;
130 import com.android.settings.wifi.SavedAccessPointsWifiSettings;
131 import com.android.settings.wifi.WifiAPITest;
132 import com.android.settings.wifi.WifiInfo;
133 import com.android.settings.wifi.WifiSettings;
134 import com.android.settings.wifi.p2p.WifiP2pSettings;
135 import com.android.settingslib.drawer.DashboardCategory;
136 import com.android.settingslib.drawer.SettingsDrawerActivity;
137 import com.android.settingslib.drawer.Tile;
139 import java.net.URISyntaxException;
140 import java.util.ArrayList;
141 import java.util.List;
142 import java.util.Set;
144 public class SettingsActivity extends SettingsDrawerActivity
145 implements PreferenceManager.OnPreferenceTreeClickListener,
146 PreferenceFragment.OnPreferenceStartFragmentCallback,
147 ButtonBarHandler, FragmentManager.OnBackStackChangedListener,
148 SearchView.OnQueryTextListener, SearchView.OnCloseListener,
149 MenuItem.OnActionExpandListener {
151 private static final String LOG_TAG = "Settings";
153 private static final int LOADER_ID_INDEXABLE_CONTENT_MONITOR = 1;
155 // Constants for state save/restore
156 private static final String SAVE_KEY_CATEGORIES = ":settings:categories";
157 private static final String SAVE_KEY_SEARCH_MENU_EXPANDED = ":settings:search_menu_expanded";
158 private static final String SAVE_KEY_SEARCH_QUERY = ":settings:search_query";
159 private static final String SAVE_KEY_SHOW_HOME_AS_UP = ":settings:show_home_as_up";
160 private static final String SAVE_KEY_SHOW_SEARCH = ":settings:show_search";
161 private static final String SAVE_KEY_HOME_ACTIVITIES_COUNT = ":settings:home_activities_count";
164 * When starting this activity, the invoking Intent can contain this extra
165 * string to specify which fragment should be initially displayed.
166 * <p/>Starting from Key Lime Pie, when this argument is passed in, the activity
167 * will call isValidFragment() to confirm that the fragment class name is valid for this
170 public static final String EXTRA_SHOW_FRAGMENT = ":settings:show_fragment";
173 * When starting this activity and using {@link #EXTRA_SHOW_FRAGMENT},
174 * this extra can also be specified to supply a Bundle of arguments to pass
175 * to that fragment when it is instantiated during the initial creation
178 public static final String EXTRA_SHOW_FRAGMENT_ARGUMENTS = ":settings:show_fragment_args";
181 * Fragment "key" argument passed thru {@link #EXTRA_SHOW_FRAGMENT_ARGUMENTS}
183 public static final String EXTRA_FRAGMENT_ARG_KEY = ":settings:fragment_args_key";
185 public static final String BACK_STACK_PREFS = ":settings:prefs";
187 // extras that allow any preference activity to be launched as part of a wizard
189 // show Back and Next buttons? takes boolean parameter
190 // Back will then return RESULT_CANCELED and Next RESULT_OK
191 protected static final String EXTRA_PREFS_SHOW_BUTTON_BAR = "extra_prefs_show_button_bar";
193 // add a Skip button?
194 private static final String EXTRA_PREFS_SHOW_SKIP = "extra_prefs_show_skip";
196 // specify custom text for the Back or Next buttons, or cause a button to not appear
197 // at all by setting it to null
198 protected static final String EXTRA_PREFS_SET_NEXT_TEXT = "extra_prefs_set_next_text";
199 protected static final String EXTRA_PREFS_SET_BACK_TEXT = "extra_prefs_set_back_text";
202 * When starting this activity and using {@link #EXTRA_SHOW_FRAGMENT},
203 * those extra can also be specify to supply the title or title res id to be shown for
206 public static final String EXTRA_SHOW_FRAGMENT_TITLE = ":settings:show_fragment_title";
208 * The package name used to resolve the title resource id.
210 public static final String EXTRA_SHOW_FRAGMENT_TITLE_RES_PACKAGE_NAME =
211 ":settings:show_fragment_title_res_package_name";
212 public static final String EXTRA_SHOW_FRAGMENT_TITLE_RESID =
213 ":settings:show_fragment_title_resid";
214 public static final String EXTRA_SHOW_FRAGMENT_AS_SHORTCUT =
215 ":settings:show_fragment_as_shortcut";
217 public static final String EXTRA_SHOW_FRAGMENT_AS_SUBSETTING =
218 ":settings:show_fragment_as_subsetting";
220 public static final String EXTRA_HIDE_DRAWER = ":settings:hide_drawer";
222 public static final String EXTRA_LAUNCH_ACTIVITY_ACTION = ":settings:launch_activity_action";
224 public static final String META_DATA_KEY_FRAGMENT_CLASS =
225 "com.android.settings.FRAGMENT_CLASS";
227 public static final String META_DATA_KEY_LAUNCH_ACTIVITY_ACTION =
228 "com.android.settings.ACTIVITY_ACTION";
230 private static final String EXTRA_UI_OPTIONS = "settings:ui_options";
232 private static final String EMPTY_QUERY = "";
234 private static final int REQUEST_SUGGESTION = 42;
236 private static final String ACTION_TIMER_SWITCH = "qualcomm.intent.action.TIMER_SWITCH";
238 private String mFragmentClass;
239 private String mActivityAction;
241 private CharSequence mInitialTitle;
242 private int mInitialTitleResId;
244 // Show only these settings for restricted users
245 private String[] SETTINGS_FOR_RESTRICTED = {
247 WifiSettingsActivity.class.getName(),
248 Settings.BluetoothSettingsActivity.class.getName(),
249 Settings.DataUsageSummaryActivity.class.getName(),
250 Settings.RoamingSettingsActivity.class.getName(),
251 Settings.SimSettingsActivity.class.getName(),
252 Settings.WirelessSettingsActivity.class.getName(),
254 Settings.HomeSettingsActivity.class.getName(),
255 Settings.SoundSettingsActivity.class.getName(),
256 Settings.DisplaySettingsActivity.class.getName(),
257 Settings.StorageSettingsActivity.class.getName(),
258 Settings.ManageApplicationsActivity.class.getName(),
259 Settings.AppsCompatibilityActivity.class.getName(),
260 Settings.PowerUsageSummaryActivity.class.getName(),
261 Settings.GestureSettingsActivity.class.getName(),
263 Settings.LocationSettingsActivity.class.getName(),
264 Settings.SecuritySettingsActivity.class.getName(),
265 Settings.InputMethodAndLanguageSettingsActivity.class.getName(),
266 Settings.UserSettingsActivity.class.getName(),
267 Settings.AccountSettingsActivity.class.getName(),
269 Settings.DateTimeSettingsActivity.class.getName(),
270 Settings.DeviceInfoSettingsActivity.class.getName(),
271 Settings.AccessibilitySettingsActivity.class.getName(),
272 Settings.PrintSettingsActivity.class.getName(),
273 Settings.PaymentSettingsActivity.class.getName(),
274 Settings.TimerSwitchSettingsActivity.class.getName(),
277 private static final String[] ENTRY_FRAGMENTS = {
278 WirelessSettings.class.getName(),
279 WifiSettings.class.getName(),
280 AdvancedWifiSettings.class.getName(),
281 SavedAccessPointsWifiSettings.class.getName(),
282 BluetoothSettings.class.getName(),
283 SimSettings.class.getName(),
284 TetherSettings.class.getName(),
285 WifiP2pSettings.class.getName(),
286 VpnSettings.class.getName(),
287 DateTimeSettings.class.getName(),
288 LocaleListEditor.class.getName(),
289 InputMethodAndLanguageSettings.class.getName(),
290 AvailableVirtualKeyboardFragment.class.getName(),
291 SpellCheckersSettings.class.getName(),
292 UserDictionaryList.class.getName(),
293 UserDictionarySettings.class.getName(),
294 HomeSettings.class.getName(),
295 DisplaySettings.class.getName(),
296 DeviceInfoSettings.class.getName(),
297 ManageApplications.class.getName(),
298 AppsCompatibility.class.getName(),
299 NotificationApps.class.getName(),
300 ManageAssist.class.getName(),
301 ProcessStatsUi.class.getName(),
302 NotificationStation.class.getName(),
303 LocationSettings.class.getName(),
304 SecuritySettings.class.getName(),
305 UsageAccessDetails.class.getName(),
306 PrivacySettings.class.getName(),
307 DeviceAdminSettings.class.getName(),
308 AccessibilitySettings.class.getName(),
309 AccessibilitySettingsForSetupWizard.class.getName(),
310 CaptionPropertiesFragment.class.getName(),
311 com.android.settings.accessibility.ToggleDaltonizerPreferenceFragment.class.getName(),
312 TextToSpeechSettings.class.getName(),
313 StorageSettings.class.getName(),
314 PrivateVolumeForget.class.getName(),
315 PrivateVolumeSettings.class.getName(),
316 PublicVolumeSettings.class.getName(),
317 DevelopmentSettings.class.getName(),
318 AndroidBeam.class.getName(),
319 WifiDisplaySettings.class.getName(),
320 PowerUsageSummary.class.getName(),
321 AccountSyncSettings.class.getName(),
322 AccountSettings.class.getName(),
323 GestureSettings.class.getName(),
324 CryptKeeperSettings.class.getName(),
325 DataUsageSummary.class.getName(),
326 DreamSettings.class.getName(),
327 UserSettings.class.getName(),
328 NotificationAccessSettings.class.getName(),
329 ZenAccessSettings.class.getName(),
330 PrintSettingsFragment.class.getName(),
331 PrintJobSettingsFragment.class.getName(),
332 TrustedCredentialsSettings.class.getName(),
333 PaymentSettings.class.getName(),
334 KeyboardLayoutPickerFragment.class.getName(),
335 KeyboardLayoutPickerFragment2.class.getName(),
336 PhysicalKeyboardFragment.class.getName(),
337 ZenModeSettings.class.getName(),
338 SoundSettings.class.getName(),
339 ConfigureNotificationSettings.class.getName(),
340 ChooseLockPassword.ChooseLockPasswordFragment.class.getName(),
341 ChooseLockPattern.ChooseLockPatternFragment.class.getName(),
342 InstalledAppDetails.class.getName(),
343 BatterySaverSettings.class.getName(),
344 AppNotificationSettings.class.getName(),
345 OtherSoundSettings.class.getName(),
346 ApnSettings.class.getName(),
347 ApnEditor.class.getName(),
348 WifiCallingSettings.class.getName(),
349 ZenModePrioritySettings.class.getName(),
350 ZenModeAutomationSettings.class.getName(),
351 ZenModeScheduleRuleSettings.class.getName(),
352 ZenModeEventRuleSettings.class.getName(),
353 ZenModeVisualInterruptionSettings.class.getName(),
354 ProcessStatsUi.class.getName(),
355 PowerUsageDetail.class.getName(),
356 ProcessStatsSummary.class.getName(),
357 DrawOverlayDetails.class.getName(),
358 WriteSettingsDetails.class.getName(),
359 AdvancedAppSettings.class.getName(),
360 WallpaperTypeSettings.class.getName(),
361 VrListenerSettings.class.getName(),
362 ManagedProfileSettings.class.getName(),
363 ChooseAccountActivity.class.getName(),
364 IccLockSettings.class.getName(),
365 ImeiInformation.class.getName(),
366 SimStatus.class.getName(),
367 Status.class.getName(),
368 TestingSettings.class.getName(),
369 WifiAPITest.class.getName(),
370 WifiInfo.class.getName(),
371 MasterClear.class.getName(),
372 NightDisplaySettings.class.getName(),
373 ManageDomainUrls.class.getName(),
374 AutomaticStorageManagerSettings.class.getName()
378 private static final String[] LIKE_SHORTCUT_INTENT_ACTION_ARRAY = {
379 "android.settings.APPLICATION_DETAILS_SETTINGS"
382 private SharedPreferences mDevelopmentPreferences;
383 private SharedPreferences.OnSharedPreferenceChangeListener mDevelopmentPreferencesListener;
385 private boolean mBatteryPresent = true;
386 private BroadcastReceiver mBatteryInfoReceiver = new BroadcastReceiver() {
388 public void onReceive(Context context, Intent intent) {
389 String action = intent.getAction();
390 if (Intent.ACTION_BATTERY_CHANGED.equals(action)) {
391 boolean batteryPresent = Utils.isBatteryPresent(intent);
393 if (mBatteryPresent != batteryPresent) {
394 mBatteryPresent = batteryPresent;
401 private final BroadcastReceiver mUserAddRemoveReceiver = new BroadcastReceiver() {
403 public void onReceive(Context context, Intent intent) {
404 String action = intent.getAction();
405 if (action.equals(Intent.ACTION_USER_ADDED)
406 || action.equals(Intent.ACTION_USER_REMOVED)) {
407 Index.getInstance(getApplicationContext()).update();
412 private final DynamicIndexableContentMonitor mDynamicIndexableContentMonitor =
413 new DynamicIndexableContentMonitor();
415 private ActionBar mActionBar;
416 private SwitchBar mSwitchBar;
418 private Button mNextButton;
420 private boolean mDisplayHomeAsUpEnabled;
421 private boolean mDisplaySearch;
423 private boolean mIsShowingDashboard;
424 private boolean mIsShortcut;
426 private ViewGroup mContent;
428 private SearchView mSearchView;
429 private MenuItem mSearchMenuItem;
430 private boolean mSearchMenuItemExpanded = false;
431 private SearchResultsSummary mSearchResultsFragment;
432 private String mSearchQuery;
435 private ArrayList<DashboardCategory> mCategories = new ArrayList<DashboardCategory>();
437 private static final String MSG_DATA_FORCE_REFRESH = "msg_data_force_refresh";
439 private boolean mNeedToRevertToInitialFragment = false;
441 private Intent mResultIntentData;
442 private ComponentName mCurrentSuggestion;
444 public SwitchBar getSwitchBar() {
449 public boolean onPreferenceStartFragment(PreferenceFragment caller, Preference pref) {
450 startPreferencePanel(pref.getFragment(), pref.getExtras(), -1, pref.getTitle(),
456 public boolean onPreferenceTreeClick(Preference preference) {
461 public void onConfigurationChanged(Configuration newConfig) {
462 super.onConfigurationChanged(newConfig);
463 Index.getInstance(this).update();
467 public boolean onCreateOptionsMenu(Menu menu) {
468 if (!mDisplaySearch) {
472 MenuInflater inflater = getMenuInflater();
473 inflater.inflate(R.menu.options_menu, menu);
475 // Cache the search query (can be overriden by the OnQueryTextListener)
476 final String query = mSearchQuery;
478 mSearchMenuItem = menu.findItem(R.id.search);
479 mSearchView = (SearchView) mSearchMenuItem.getActionView();
481 if (mSearchMenuItem == null || mSearchView == null) {
485 if (mSearchResultsFragment != null) {
486 mSearchResultsFragment.setSearchView(mSearchView);
489 mSearchMenuItem.setOnActionExpandListener(this);
490 mSearchView.setOnQueryTextListener(this);
491 mSearchView.setOnCloseListener(this);
493 if (mSearchMenuItemExpanded) {
494 mSearchMenuItem.expandActionView();
496 mSearchView.setQuery(query, true /* submit */);
502 public SharedPreferences getSharedPreferences(String name, int mode) {
503 if (name.equals(getPackageName() + "_preferences")) {
504 return new SharedPreferencesLogger(this, getMetricsTag());
506 return super.getSharedPreferences(name, mode);
509 private String getMetricsTag() {
510 String tag = getClass().getName();
511 if (getIntent() != null && getIntent().hasExtra(EXTRA_SHOW_FRAGMENT)) {
512 tag = getIntent().getStringExtra(EXTRA_SHOW_FRAGMENT);
514 if (tag.startsWith("com.android.settings.")) {
515 tag = tag.replace("com.android.settings.", "");
520 private static boolean isShortCutIntent(final Intent intent) {
521 Set<String> categories = intent.getCategories();
522 return (categories != null) && categories.contains("com.android.settings.SHORTCUT");
525 private static boolean isLikeShortCutIntent(final Intent intent) {
526 String action = intent.getAction();
527 if (action == null) {
530 for (int i = 0; i < LIKE_SHORTCUT_INTENT_ACTION_ARRAY.length; i++) {
531 if (LIKE_SHORTCUT_INTENT_ACTION_ARRAY[i].equals(action)) return true;
537 protected void onCreate(Bundle savedState) {
538 super.onCreate(savedState);
539 long startTime = System.currentTimeMillis();
541 // Should happen before any call to getIntent()
544 final Intent intent = getIntent();
545 if (intent.hasExtra(EXTRA_LAUNCH_ACTIVITY_ACTION)) {
546 if (mActivityAction != null) {
548 startActivity(new Intent(mActivityAction));
549 }catch(ActivityNotFoundException e){
550 Log.w(LOG_TAG, "Activity not found for action: " + mActivityAction);
557 if (intent.hasExtra(EXTRA_UI_OPTIONS)) {
558 getWindow().setUiOptions(intent.getIntExtra(EXTRA_UI_OPTIONS, 0));
560 if (intent.getBooleanExtra(EXTRA_HIDE_DRAWER, false)) {
561 setIsDrawerPresent(false);
564 mDevelopmentPreferences = getSharedPreferences(DevelopmentSettings.PREF_FILE,
565 Context.MODE_PRIVATE);
567 // Getting Intent properties can only be done after the super.onCreate(...)
568 final String initialFragmentName = intent.getStringExtra(EXTRA_SHOW_FRAGMENT);
570 mIsShortcut = isShortCutIntent(intent) || isLikeShortCutIntent(intent) ||
571 intent.getBooleanExtra(EXTRA_SHOW_FRAGMENT_AS_SHORTCUT, false);
573 final ComponentName cn = intent.getComponent();
574 final String className = cn.getClassName();
576 mIsShowingDashboard = className.equals(Settings.class.getName())
577 || className.equals(Settings.WirelessSettings.class.getName())
578 || className.equals(Settings.DeviceSettings.class.getName())
579 || className.equals(Settings.PersonalSettings.class.getName())
580 || className.equals(Settings.WirelessSettings.class.getName());
582 // This is a "Sub Settings" when:
583 // - this is a real SubSettings
584 // - or :settings:show_fragment_as_subsetting is passed to the Intent
585 final boolean isSubSettings = this instanceof SubSettings ||
586 intent.getBooleanExtra(EXTRA_SHOW_FRAGMENT_AS_SUBSETTING, false);
588 // If this is a sub settings, then apply the SubSettings Theme for the ActionBar content insets
590 // Check also that we are not a Theme Dialog as we don't want to override them
591 final int themeResId = getThemeResId();
592 if (themeResId != R.style.Theme_DialogWhenLarge &&
593 themeResId != R.style.Theme_SubSettingsDialogWhenLarge) {
594 setTheme(R.style.Theme_SubSettings);
598 setContentView(mIsShowingDashboard ?
599 R.layout.settings_main_dashboard : R.layout.settings_main_prefs);
601 mContent = (ViewGroup) findViewById(R.id.main_content);
603 getFragmentManager().addOnBackStackChangedListener(this);
605 if (mIsShowingDashboard) {
606 // Run the Index update only if we have some space
607 if (!Utils.isLowStorage(this)) {
608 long indexStartTime = System.currentTimeMillis();
609 Index.getInstance(getApplicationContext()).update();
610 if (DEBUG_TIMING) Log.d(LOG_TAG, "Index.update() took "
611 + (System.currentTimeMillis() - indexStartTime) + " ms");
613 Log.w(LOG_TAG, "Cannot update the Indexer as we are running low on storage space!");
617 if (savedState != null) {
618 // We are restarting from a previous saved state; used that to initialize, instead
619 // of starting fresh.
620 mSearchMenuItemExpanded = savedState.getBoolean(SAVE_KEY_SEARCH_MENU_EXPANDED);
621 mSearchQuery = savedState.getString(SAVE_KEY_SEARCH_QUERY);
622 setTitleFromIntent(intent);
624 ArrayList<DashboardCategory> categories =
625 savedState.getParcelableArrayList(SAVE_KEY_CATEGORIES);
626 if (categories != null) {
628 mCategories.addAll(categories);
629 setTitleFromBackStack();
632 mDisplayHomeAsUpEnabled = savedState.getBoolean(SAVE_KEY_SHOW_HOME_AS_UP);
633 mDisplaySearch = savedState.getBoolean(SAVE_KEY_SHOW_SEARCH);
636 if (!mIsShowingDashboard) {
637 mDisplaySearch = false;
638 // UP will be shown only if it is a sub settings
640 mDisplayHomeAsUpEnabled = isSubSettings;
641 } else if (isSubSettings) {
642 mDisplayHomeAsUpEnabled = true;
644 mDisplayHomeAsUpEnabled = false;
646 setTitleFromIntent(intent);
648 Bundle initialArguments = intent.getBundleExtra(EXTRA_SHOW_FRAGMENT_ARGUMENTS);
649 switchToFragment(initialFragmentName, initialArguments, true, false,
650 mInitialTitleResId, mInitialTitle, false);
652 // No UP affordance if we are displaying the main Dashboard
653 mDisplayHomeAsUpEnabled = false;
654 // Show Search affordance (if device is provisioned)
655 mDisplaySearch = Utils.isDeviceProvisioned(this);
656 mInitialTitleResId = R.string.dashboard_title;
658 // add argument to indicate which settings tab should be initially selected
659 final Bundle args = new Bundle();
660 final String extraName = DashboardContainerFragment.EXTRA_SELECT_SETTINGS_TAB;
661 args.putString(extraName, intent.getStringExtra(extraName));
663 switchToFragment(DashboardContainerFragment.class.getName(), args, false, false,
664 mInitialTitleResId, mInitialTitle, false);
668 mActionBar = getActionBar();
669 if (mActionBar != null) {
670 mActionBar.setDisplayHomeAsUpEnabled(mDisplayHomeAsUpEnabled);
671 mActionBar.setHomeButtonEnabled(mDisplayHomeAsUpEnabled);
673 mSwitchBar = (SwitchBar) findViewById(R.id.switch_bar);
674 if (mSwitchBar != null) {
675 mSwitchBar.setMetricsTag(getMetricsTag());
678 // see if we should show Back/Next buttons
679 if (intent.getBooleanExtra(EXTRA_PREFS_SHOW_BUTTON_BAR, false)) {
681 View buttonBar = findViewById(R.id.button_bar);
682 if (buttonBar != null) {
683 buttonBar.setVisibility(View.VISIBLE);
685 Button backButton = (Button)findViewById(R.id.back_button);
686 backButton.setOnClickListener(new OnClickListener() {
687 public void onClick(View v) {
688 setResult(RESULT_CANCELED, getResultIntentData());
692 Button skipButton = (Button)findViewById(R.id.skip_button);
693 skipButton.setOnClickListener(new OnClickListener() {
694 public void onClick(View v) {
695 setResult(RESULT_OK, getResultIntentData());
699 mNextButton = (Button)findViewById(R.id.next_button);
700 mNextButton.setOnClickListener(new OnClickListener() {
701 public void onClick(View v) {
702 setResult(RESULT_OK, getResultIntentData());
707 // set our various button parameters
708 if (intent.hasExtra(EXTRA_PREFS_SET_NEXT_TEXT)) {
709 String buttonText = intent.getStringExtra(EXTRA_PREFS_SET_NEXT_TEXT);
710 if (TextUtils.isEmpty(buttonText)) {
711 mNextButton.setVisibility(View.GONE);
714 mNextButton.setText(buttonText);
717 if (intent.hasExtra(EXTRA_PREFS_SET_BACK_TEXT)) {
718 String buttonText = intent.getStringExtra(EXTRA_PREFS_SET_BACK_TEXT);
719 if (TextUtils.isEmpty(buttonText)) {
720 backButton.setVisibility(View.GONE);
723 backButton.setText(buttonText);
726 if (intent.getBooleanExtra(EXTRA_PREFS_SHOW_SKIP, false)) {
727 skipButton.setVisibility(View.VISIBLE);
732 if (DEBUG_TIMING) Log.d(LOG_TAG, "onCreate took " + (System.currentTimeMillis() - startTime)
736 public void setDisplaySearchMenu(boolean displaySearch) {
737 if (Utils.isDeviceProvisioned(this) && displaySearch != mDisplaySearch) {
738 mDisplaySearch = displaySearch;
739 invalidateOptionsMenu();
743 private void setTitleFromIntent(Intent intent) {
744 final int initialTitleResId = intent.getIntExtra(EXTRA_SHOW_FRAGMENT_TITLE_RESID, -1);
745 if (initialTitleResId > 0) {
746 mInitialTitle = null;
747 mInitialTitleResId = initialTitleResId;
749 final String initialTitleResPackageName = intent.getStringExtra(
750 EXTRA_SHOW_FRAGMENT_TITLE_RES_PACKAGE_NAME);
751 if (initialTitleResPackageName != null) {
753 Context authContext = createPackageContextAsUser(initialTitleResPackageName,
754 0 /* flags */, new UserHandle(UserHandle.myUserId()));
755 mInitialTitle = authContext.getResources().getText(mInitialTitleResId);
756 setTitle(mInitialTitle);
757 mInitialTitleResId = -1;
759 } catch (NameNotFoundException e) {
760 Log.w(LOG_TAG, "Could not find package" + initialTitleResPackageName);
763 setTitle(mInitialTitleResId);
766 mInitialTitleResId = -1;
767 final String initialTitle = intent.getStringExtra(EXTRA_SHOW_FRAGMENT_TITLE);
768 mInitialTitle = (initialTitle != null) ? initialTitle : getTitle();
769 setTitle(mInitialTitle);
774 public void onBackStackChanged() {
775 setTitleFromBackStack();
778 private void setTitleFromBackStack() {
779 final int count = getFragmentManager().getBackStackEntryCount();
782 if (mInitialTitleResId > 0) {
783 setTitle(mInitialTitleResId);
785 setTitle(mInitialTitle);
790 FragmentManager.BackStackEntry bse = getFragmentManager().getBackStackEntryAt(count - 1);
791 setTitleFromBackStackEntry(bse);
794 private void setTitleFromBackStackEntry(FragmentManager.BackStackEntry bse) {
795 final CharSequence title;
796 final int titleRes = bse.getBreadCrumbTitleRes();
798 title = getText(titleRes);
800 title = bse.getBreadCrumbTitle();
808 protected void onSaveInstanceState(Bundle outState) {
809 super.onSaveInstanceState(outState);
811 if (mCategories.size() > 0) {
812 outState.putParcelableArrayList(SAVE_KEY_CATEGORIES, mCategories);
815 outState.putBoolean(SAVE_KEY_SHOW_HOME_AS_UP, mDisplayHomeAsUpEnabled);
816 outState.putBoolean(SAVE_KEY_SHOW_SEARCH, mDisplaySearch);
818 if (mDisplaySearch) {
819 // The option menus are created if the ActionBar is visible and they are also created
820 // asynchronously. If you launch Settings with an Intent action like
821 // android.intent.action.POWER_USAGE_SUMMARY and at the same time your device is locked
822 // thru a LockScreen, onCreateOptionsMenu() is not yet called and references to the search
823 // menu item and search view are null.
824 boolean isExpanded = (mSearchMenuItem != null) && mSearchMenuItem.isActionViewExpanded();
825 outState.putBoolean(SAVE_KEY_SEARCH_MENU_EXPANDED, isExpanded);
827 String query = (mSearchView != null) ? mSearchView.getQuery().toString() : EMPTY_QUERY;
828 outState.putString(SAVE_KEY_SEARCH_QUERY, query);
833 protected void onStart() {
836 if (mNeedToRevertToInitialFragment) {
837 revertToInitialFragment();
840 mDevelopmentPreferencesListener = new SharedPreferences.OnSharedPreferenceChangeListener() {
842 public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
846 mDevelopmentPreferences.registerOnSharedPreferenceChangeListener(
847 mDevelopmentPreferencesListener);
849 registerReceiver(mBatteryInfoReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
850 registerReceiver(mUserAddRemoveReceiver, new IntentFilter(Intent.ACTION_USER_ADDED));
851 registerReceiver(mUserAddRemoveReceiver, new IntentFilter(Intent.ACTION_USER_REMOVED));
853 mDynamicIndexableContentMonitor.register(this, LOADER_ID_INDEXABLE_CONTENT_MONITOR);
855 if(mDisplaySearch && !TextUtils.isEmpty(mSearchQuery)) {
856 onQueryTextSubmit(mSearchQuery);
862 protected void onStop() {
864 unregisterReceiver(mBatteryInfoReceiver);
865 unregisterReceiver(mUserAddRemoveReceiver);
866 mDynamicIndexableContentMonitor.unregister();
870 public void onDestroy() {
872 if (mDevelopmentPreferencesListener != null) {
873 mDevelopmentPreferences.unregisterOnSharedPreferenceChangeListener(
874 mDevelopmentPreferencesListener);
875 mDevelopmentPreferencesListener = null;
879 protected boolean isValidFragment(String fragmentName) {
880 // Almost all fragments are wrapped in this,
881 // except for a few that have their own activities.
882 for (int i = 0; i < ENTRY_FRAGMENTS.length; i++) {
883 if (ENTRY_FRAGMENTS[i].equals(fragmentName)) return true;
889 public Intent getIntent() {
890 Intent superIntent = super.getIntent();
891 String startingFragment = getStartingFragmentClass(superIntent);
892 // This is called from super.onCreate, isMultiPane() is not yet reliable
893 // Do not use onIsHidingHeaders either, which relies itself on this method
894 if (startingFragment != null) {
895 Intent modIntent = new Intent(superIntent);
896 modIntent.putExtra(EXTRA_SHOW_FRAGMENT, startingFragment);
897 Bundle args = superIntent.getExtras();
899 args = new Bundle(args);
903 args.putParcelable("intent", superIntent);
904 modIntent.putExtra(EXTRA_SHOW_FRAGMENT_ARGUMENTS, args);
907 if (mActivityAction != null) {
908 Intent modIntent = new Intent(superIntent);
909 modIntent.putExtra(EXTRA_LAUNCH_ACTIVITY_ACTION, mActivityAction);
917 * Checks if the component name in the intent is different from the Settings class and
918 * returns the class name to load as a fragment.
920 private String getStartingFragmentClass(Intent intent) {
921 if (mFragmentClass != null) return mFragmentClass;
923 String intentClass = intent.getComponent().getClassName();
924 if (intentClass.equals(getClass().getName())) return null;
926 if ("com.android.settings.ManageApplications".equals(intentClass)
927 || "com.android.settings.RunningServices".equals(intentClass)
928 || "com.android.settings.applications.StorageUse".equals(intentClass)) {
929 // Old names of manage apps.
930 intentClass = com.android.settings.applications.ManageApplications.class.getName();
937 * Start a new fragment containing a preference panel. If the preferences
938 * are being displayed in multi-pane mode, the given fragment class will
939 * be instantiated and placed in the appropriate pane. If running in
940 * single-pane mode, a new activity will be launched in which to show the
943 * @param fragmentClass Full name of the class implementing the fragment.
944 * @param args Any desired arguments to supply to the fragment.
945 * @param titleRes Optional resource identifier of the title of this
947 * @param titleText Optional text of the title of this fragment.
948 * @param resultTo Optional fragment that result data should be sent to.
949 * If non-null, resultTo.onActivityResult() will be called when this
950 * preference panel is done. The launched panel must use
951 * {@link #finishPreferencePanel(Fragment, int, Intent)} when done.
952 * @param resultRequestCode If resultTo is non-null, this is the caller's
953 * request code to be received with the result.
955 public void startPreferencePanel(String fragmentClass, Bundle args, int titleRes,
956 CharSequence titleText, Fragment resultTo, int resultRequestCode) {
959 if (titleText != null) {
960 title = titleText.toString();
962 // There not much we can do in that case
966 Utils.startWithFragment(this, fragmentClass, args, resultTo, resultRequestCode,
967 titleRes, title, mIsShortcut);
971 * Start a new fragment in a new activity containing a preference panel for a given user. If the
972 * preferences are being displayed in multi-pane mode, the given fragment class will be
973 * instantiated and placed in the appropriate pane. If running in single-pane mode, a new
974 * activity will be launched in which to show the fragment.
976 * @param fragmentClass Full name of the class implementing the fragment.
977 * @param args Any desired arguments to supply to the fragment.
978 * @param titleRes Optional resource identifier of the title of this fragment.
979 * @param titleText Optional text of the title of this fragment.
980 * @param userHandle The user for which the panel has to be started.
982 public void startPreferencePanelAsUser(String fragmentClass, Bundle args, int titleRes,
983 CharSequence titleText, UserHandle userHandle) {
984 // This is a workaround.
986 // Calling startWithFragmentAsUser() without specifying FLAG_ACTIVITY_NEW_TASK to the intent
987 // starting the fragment could cause a native stack corruption. See b/17523189. However,
988 // adding that flag and start the preference panel with the same UserHandler will make it
989 // impossible to use back button to return to the previous screen. See b/20042570.
991 // We work around this issue by adding FLAG_ACTIVITY_NEW_TASK to the intent, while doing
992 // another check here to call startPreferencePanel() instead of startWithFragmentAsUser()
993 // when we're calling it as the same user.
994 if (userHandle.getIdentifier() == UserHandle.myUserId()) {
995 startPreferencePanel(fragmentClass, args, titleRes, titleText, null, 0);
999 if (titleText != null) {
1000 title = titleText.toString();
1002 // There not much we can do in that case
1006 Utils.startWithFragmentAsUser(this, fragmentClass, args,
1007 titleRes, title, mIsShortcut, userHandle);
1012 * Called by a preference panel fragment to finish itself.
1014 * @param caller The fragment that is asking to be finished.
1015 * @param resultCode Optional result code to send back to the original
1016 * launching fragment.
1017 * @param resultData Optional result data to send back to the original
1018 * launching fragment.
1020 public void finishPreferencePanel(Fragment caller, int resultCode, Intent resultData) {
1021 setResult(resultCode, resultData);
1026 * Start a new fragment.
1028 * @param fragment The fragment to start
1029 * @param push If true, the current fragment will be pushed onto the back stack. If false,
1030 * the current fragment will be replaced.
1032 public void startPreferenceFragment(Fragment fragment, boolean push) {
1033 FragmentTransaction transaction = getFragmentManager().beginTransaction();
1034 transaction.replace(R.id.main_content, fragment);
1036 transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
1037 transaction.addToBackStack(BACK_STACK_PREFS);
1039 transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
1041 transaction.commitAllowingStateLoss();
1045 * Switch to a specific Fragment with taking care of validation, Title and BackStack
1047 private Fragment switchToFragment(String fragmentName, Bundle args, boolean validate,
1048 boolean addToBackStack, int titleResId, CharSequence title, boolean withTransition) {
1049 if (validate && !isValidFragment(fragmentName)) {
1050 throw new IllegalArgumentException("Invalid fragment for this activity: "
1053 Fragment f = Fragment.instantiate(this, fragmentName, args);
1054 FragmentTransaction transaction = getFragmentManager().beginTransaction();
1055 transaction.replace(R.id.main_content, f);
1056 if (withTransition) {
1057 TransitionManager.beginDelayedTransition(mContent);
1059 if (addToBackStack) {
1060 transaction.addToBackStack(SettingsActivity.BACK_STACK_PREFS);
1062 if (titleResId > 0) {
1063 transaction.setBreadCrumbTitle(titleResId);
1064 } else if (title != null) {
1065 transaction.setBreadCrumbTitle(title);
1067 transaction.commitAllowingStateLoss();
1068 getFragmentManager().executePendingTransactions();
1072 private void updateTilesList() {
1073 // Generally the items that are will be changing from these updates will
1074 // not be in the top list of tiles, so run it in the background and the
1075 // SettingsDrawerActivity will pick up on the updates automatically.
1076 AsyncTask.execute(new Runnable() {
1079 doUpdateTilesList();
1084 private void doUpdateTilesList() {
1085 PackageManager pm = getPackageManager();
1086 final UserManager um = UserManager.get(this);
1087 final boolean isAdmin = um.isAdminUser();
1089 String packageName = getPackageName();
1090 setTileEnabled(new ComponentName(packageName, WifiSettingsActivity.class.getName()),
1091 pm.hasSystemFeature(PackageManager.FEATURE_WIFI), isAdmin, pm);
1093 setTileEnabled(new ComponentName(packageName,
1094 Settings.BluetoothSettingsActivity.class.getName()),
1095 pm.hasSystemFeature(PackageManager.FEATURE_BLUETOOTH), isAdmin, pm);
1097 setTileEnabled(new ComponentName(packageName,
1098 Settings.DataUsageSummaryActivity.class.getName()),
1099 Utils.isBandwidthControlEnabled(), isAdmin, pm);
1101 setTileEnabled(new ComponentName(packageName,
1102 Settings.RoamingSettingsActivity.class.getName()),
1103 getResources().getBoolean(R.bool.config_roamingsettings_enabled), isAdmin, pm);
1105 setTileEnabled(new ComponentName(packageName,
1106 Settings.SimSettingsActivity.class.getName()),
1107 Utils.showSimCardTile(this), isAdmin, pm);
1109 setTileEnabled(new ComponentName(packageName,
1110 Settings.PowerUsageSummaryActivity.class.getName()),
1111 mBatteryPresent, isAdmin, pm);
1113 setTileEnabled(new ComponentName(packageName,
1114 Settings.UserSettingsActivity.class.getName()),
1115 UserHandle.MU_ENABLED && UserManager.supportsMultipleUsers()
1116 && !Utils.isMonkeyRunning(), isAdmin, pm);
1118 setTileEnabled(new ComponentName(packageName,
1119 Settings.WirelessSettingsActivity.class.getName()),
1120 !UserManager.isDeviceInDemoMode(this), isAdmin, pm);
1122 setTileEnabled(new ComponentName(packageName,
1123 Settings.DateTimeSettingsActivity.class.getName()),
1124 !UserManager.isDeviceInDemoMode(this), isAdmin, pm);
1125 NfcAdapter adapter = NfcAdapter.getDefaultAdapter(this);
1126 setTileEnabled(new ComponentName(packageName,
1127 Settings.PaymentSettingsActivity.class.getName()),
1128 pm.hasSystemFeature(PackageManager.FEATURE_NFC)
1129 && pm.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION)
1130 && adapter != null && adapter.isEnabled(), isAdmin, pm);
1131 setTileEnabled(new ComponentName(packageName,
1132 Settings.PrintSettingsActivity.class.getName()),
1133 pm.hasSystemFeature(PackageManager.FEATURE_PRINTING), isAdmin, pm);
1135 final boolean showDev = mDevelopmentPreferences.getBoolean(
1136 DevelopmentSettings.PREF_SHOW, android.os.Build.TYPE.equals("eng"))
1137 && !um.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES);
1138 setTileEnabled(new ComponentName(packageName,
1139 Settings.DevelopmentSettingsActivity.class.getName()),
1140 showDev, isAdmin, pm);
1142 // Reveal development-only quick settings tiles
1143 DevelopmentTiles.setTilesEnabled(this, showDev);
1145 // Show scheduled power on and off if support
1146 boolean showTimerSwitch = false;
1147 Intent intent = new Intent(ACTION_TIMER_SWITCH);
1148 List<ResolveInfo> infos = getBaseContext().getPackageManager()
1149 .queryIntentActivities(intent, 0);
1150 if (infos != null && !infos.isEmpty()) {
1151 showTimerSwitch = true;
1153 setTileEnabled(new ComponentName(packageName,
1154 Settings.TimerSwitchSettingsActivity.class.getName()),
1155 showTimerSwitch, isAdmin, pm);
1157 if (UserHandle.MU_ENABLED && !isAdmin) {
1158 // When on restricted users, disable all extra categories (but only the settings ones).
1159 List<DashboardCategory> categories = getDashboardCategories();
1160 for (DashboardCategory category : categories) {
1161 for (Tile tile : category.tiles) {
1162 ComponentName component = tile.intent.getComponent();
1163 if (packageName.equals(component.getPackageName()) && !ArrayUtils.contains(
1164 SETTINGS_FOR_RESTRICTED, component.getClassName())) {
1165 setTileEnabled(component, false, isAdmin, pm);
1171 String backupIntent = getResources().getString(R.string.config_backup_settings_intent);
1172 boolean useDefaultBackup = TextUtils.isEmpty(backupIntent);
1173 setTileEnabled(new ComponentName(packageName,
1174 Settings.PrivacySettingsActivity.class.getName()), useDefaultBackup, isAdmin, pm);
1175 boolean hasBackupActivity = false;
1176 if (!useDefaultBackup) {
1178 intent = Intent.parseUri(backupIntent, 0);
1179 hasBackupActivity = !getPackageManager().queryIntentActivities(intent, 0).isEmpty();
1180 } catch (URISyntaxException e) {
1181 Log.e(LOG_TAG, "Invalid backup intent URI!", e);
1184 setTileEnabled(new ComponentName(packageName,
1185 BackupSettingsActivity.class.getName()), hasBackupActivity,
1186 isAdmin || Utils.isCarrierDemoUser(this), pm);
1190 private void setTileEnabled(ComponentName component, boolean enabled, boolean isAdmin,
1191 PackageManager pm) {
1192 if (UserHandle.MU_ENABLED && !isAdmin && getPackageName().equals(component.getPackageName())
1193 && !ArrayUtils.contains(SETTINGS_FOR_RESTRICTED, component.getClassName())) {
1196 setTileEnabled(component, enabled);
1199 private void getMetaData() {
1201 ActivityInfo ai = getPackageManager().getActivityInfo(getComponentName(),
1202 PackageManager.GET_META_DATA);
1203 if (ai == null || ai.metaData == null) return;
1204 mFragmentClass = ai.metaData.getString(META_DATA_KEY_FRAGMENT_CLASS);
1205 mActivityAction = ai.metaData.getString(META_DATA_KEY_LAUNCH_ACTIVITY_ACTION);
1206 } catch (NameNotFoundException nnfe) {
1208 Log.d(LOG_TAG, "Cannot get Metadata for: " + getComponentName().toString());
1212 // give subclasses access to the Next button
1213 public boolean hasNextButton() {
1214 return mNextButton != null;
1217 public Button getNextButton() {
1222 public boolean shouldUpRecreateTask(Intent targetIntent) {
1223 return super.shouldUpRecreateTask(new Intent(this, SettingsActivity.class));
1227 public boolean onQueryTextSubmit(String query) {
1228 switchToSearchResultsFragmentIfNeeded();
1229 mSearchQuery = query;
1230 return mSearchResultsFragment.onQueryTextSubmit(query);
1234 public boolean onQueryTextChange(String newText) {
1235 mSearchQuery = newText;
1236 if (mSearchResultsFragment == null) {
1239 return mSearchResultsFragment.onQueryTextChange(newText);
1243 public boolean onClose() {
1248 public boolean onOptionsItemSelected(MenuItem item) {
1249 if (super.onOptionsItemSelected(item)) {
1252 if (mDisplayHomeAsUpEnabled && item.getItemId() == android.R.id.home) {
1260 public boolean onMenuItemActionExpand(MenuItem item) {
1261 if (item.getItemId() == mSearchMenuItem.getItemId()) {
1262 switchToSearchResultsFragmentIfNeeded();
1268 public boolean onMenuItemActionCollapse(MenuItem item) {
1269 if (item.getItemId() == mSearchMenuItem.getItemId()) {
1270 if (mSearchMenuItemExpanded) {
1271 revertToInitialFragment();
1278 protected void onTileClicked(Tile tile) {
1279 if (mIsShowingDashboard) {
1280 // If on dashboard, don't finish so the back comes back to here.
1283 super.onTileClicked(tile);
1288 public void onProfileTileOpen() {
1289 if (!mIsShowingDashboard) {
1294 private void switchToSearchResultsFragmentIfNeeded() {
1295 if (mSearchResultsFragment != null) {
1298 Fragment current = getFragmentManager().findFragmentById(R.id.main_content);
1299 if (current != null && current instanceof SearchResultsSummary) {
1300 mSearchResultsFragment = (SearchResultsSummary) current;
1302 setContentHeaderView(null);
1303 mSearchResultsFragment = (SearchResultsSummary) switchToFragment(
1304 SearchResultsSummary.class.getName(), null, false, true,
1305 R.string.search_results_title, null, true);
1307 mSearchResultsFragment.setSearchView(mSearchView);
1308 mSearchMenuItemExpanded = true;
1311 public void needToRevertToInitialFragment() {
1312 mNeedToRevertToInitialFragment = true;
1315 private void revertToInitialFragment() {
1316 mNeedToRevertToInitialFragment = false;
1317 mSearchResultsFragment = null;
1318 mSearchMenuItemExpanded = false;
1319 getFragmentManager().popBackStackImmediate(SettingsActivity.BACK_STACK_PREFS,
1320 FragmentManager.POP_BACK_STACK_INCLUSIVE);
1321 if (mSearchMenuItem != null) {
1322 mSearchMenuItem.collapseActionView();
1326 public Intent getResultIntentData() {
1327 return mResultIntentData;
1330 public void setResultIntentData(Intent resultIntentData) {
1331 mResultIntentData = resultIntentData;
1334 public void startSuggestion(Intent intent) {
1335 if (intent == null || ActivityManager.isUserAMonkey()
1336 || getPackageManager().queryIntentActivities(intent, 0).isEmpty()) {
1339 mCurrentSuggestion = intent.getComponent();
1340 startActivityForResult(intent, REQUEST_SUGGESTION);
1344 protected void onActivityResult(int requestCode, int resultCode, Intent data) {
1345 if (requestCode == REQUEST_SUGGESTION && mCurrentSuggestion != null
1346 && resultCode != RESULT_CANCELED) {
1347 getPackageManager().setComponentEnabledSetting(mCurrentSuggestion,
1348 PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
1350 super.onActivityResult(requestCode, resultCode, data);