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.app.ActionBar;
24 import android.content.BroadcastReceiver;
25 import android.content.ComponentName;
26 import android.content.Context;
27 import android.content.Intent;
28 import android.content.IntentFilter;
29 import android.content.SharedPreferences;
30 import android.content.pm.ActivityInfo;
31 import android.content.pm.PackageManager;
32 import android.content.pm.PackageManager.NameNotFoundException;
33 import android.content.res.Configuration;
34 import android.nfc.NfcAdapter;
35 import android.os.AsyncTask;
36 import android.os.Bundle;
37 import android.os.UserHandle;
38 import android.os.UserManager;
39 import android.support.v14.preference.PreferenceFragment;
40 import android.support.v7.preference.Preference;
41 import android.support.v7.preference.PreferenceManager;
42 import android.text.TextUtils;
43 import android.transition.TransitionManager;
44 import android.util.Log;
45 import android.view.Menu;
46 import android.view.MenuInflater;
47 import android.view.MenuItem;
48 import android.view.View;
49 import android.view.View.OnClickListener;
50 import android.view.ViewGroup;
51 import android.widget.Button;
52 import android.widget.SearchView;
54 import com.android.internal.util.ArrayUtils;
55 import com.android.settings.Settings.WifiSettingsActivity;
56 import com.android.settings.accessibility.AccessibilitySettings;
57 import com.android.settings.accessibility.AccessibilitySettingsForSetupWizard;
58 import com.android.settings.accessibility.CaptionPropertiesFragment;
59 import com.android.settings.accounts.AccountSettings;
60 import com.android.settings.accounts.AccountSyncSettings;
61 import com.android.settings.accounts.ChooseAccountActivity;
62 import com.android.settings.accounts.ManagedProfileSettings;
63 import com.android.settings.applications.AdvancedAppSettings;
64 import com.android.settings.applications.DrawOverlayDetails;
65 import com.android.settings.applications.InstalledAppDetails;
66 import com.android.settings.applications.ManageApplications;
67 import com.android.settings.applications.ManageAssist;
68 import com.android.settings.applications.ManageDomainUrls;
69 import com.android.settings.applications.NotificationApps;
70 import com.android.settings.applications.ProcessStatsSummary;
71 import com.android.settings.applications.ProcessStatsUi;
72 import com.android.settings.applications.UsageAccessDetails;
73 import com.android.settings.applications.VrListenerSettings;
74 import com.android.settings.applications.WriteSettingsDetails;
75 import com.android.settings.bluetooth.BluetoothSettings;
76 import com.android.settings.dashboard.DashboardContainerFragment;
77 import com.android.settings.dashboard.SearchResultsSummary;
78 import com.android.settings.datausage.DataUsageSummary;
79 import com.android.settings.deletionhelper.AutomaticStorageManagerSettings;
80 import com.android.settings.deviceinfo.ImeiInformation;
81 import com.android.settings.deviceinfo.PrivateVolumeForget;
82 import com.android.settings.deviceinfo.PrivateVolumeSettings;
83 import com.android.settings.deviceinfo.PublicVolumeSettings;
84 import com.android.settings.deviceinfo.SimStatus;
85 import com.android.settings.deviceinfo.Status;
86 import com.android.settings.deviceinfo.StorageSettings;
87 import com.android.settings.display.NightDisplaySettings;
88 import com.android.settings.fuelgauge.BatterySaverSettings;
89 import com.android.settings.fuelgauge.PowerUsageDetail;
90 import com.android.settings.fuelgauge.PowerUsageSummary;
91 import com.android.settings.gestures.GestureSettings;
92 import com.android.settings.inputmethod.AvailableVirtualKeyboardFragment;
93 import com.android.settings.inputmethod.InputMethodAndLanguageSettings;
94 import com.android.settings.inputmethod.KeyboardLayoutPickerFragment;
95 import com.android.settings.inputmethod.KeyboardLayoutPickerFragment2;
96 import com.android.settings.inputmethod.PhysicalKeyboardFragment;
97 import com.android.settings.inputmethod.SpellCheckersSettings;
98 import com.android.settings.inputmethod.UserDictionaryList;
99 import com.android.settings.localepicker.LocaleListEditor;
100 import com.android.settings.location.LocationSettings;
101 import com.android.settings.nfc.AndroidBeam;
102 import com.android.settings.nfc.PaymentSettings;
103 import com.android.settings.notification.AppNotificationSettings;
104 import com.android.settings.notification.ConfigureNotificationSettings;
105 import com.android.settings.notification.NotificationAccessSettings;
106 import com.android.settings.notification.NotificationStation;
107 import com.android.settings.notification.OtherSoundSettings;
108 import com.android.settings.notification.SoundSettings;
109 import com.android.settings.notification.ZenAccessSettings;
110 import com.android.settings.notification.ZenModeAutomationSettings;
111 import com.android.settings.notification.ZenModeEventRuleSettings;
112 import com.android.settings.notification.ZenModePrioritySettings;
113 import com.android.settings.notification.ZenModeScheduleRuleSettings;
114 import com.android.settings.notification.ZenModeSettings;
115 import com.android.settings.notification.ZenModeVisualInterruptionSettings;
116 import com.android.settings.print.PrintJobSettingsFragment;
117 import com.android.settings.print.PrintSettingsFragment;
118 import com.android.settings.qstile.DevelopmentTiles;
119 import com.android.settings.search.DynamicIndexableContentMonitor;
120 import com.android.settings.search.Index;
121 import com.android.settings.sim.SimSettings;
122 import com.android.settings.tts.TextToSpeechSettings;
123 import com.android.settings.users.UserSettings;
124 import com.android.settings.vpn2.VpnSettings;
125 import com.android.settings.wfd.WifiDisplaySettings;
126 import com.android.settings.widget.SwitchBar;
127 import com.android.settings.wifi.AdvancedWifiSettings;
128 import com.android.settings.wifi.SavedAccessPointsWifiSettings;
129 import com.android.settings.wifi.WifiAPITest;
130 import com.android.settings.wifi.WifiInfo;
131 import com.android.settings.wifi.WifiSettings;
132 import com.android.settings.wifi.p2p.WifiP2pSettings;
133 import com.android.settingslib.drawer.DashboardCategory;
134 import com.android.settingslib.drawer.SettingsDrawerActivity;
135 import com.android.settingslib.drawer.Tile;
137 import java.net.URISyntaxException;
138 import java.util.ArrayList;
139 import java.util.List;
140 import java.util.Set;
142 public class SettingsActivity extends SettingsDrawerActivity
143 implements PreferenceManager.OnPreferenceTreeClickListener,
144 PreferenceFragment.OnPreferenceStartFragmentCallback,
145 ButtonBarHandler, FragmentManager.OnBackStackChangedListener,
146 SearchView.OnQueryTextListener, SearchView.OnCloseListener,
147 MenuItem.OnActionExpandListener {
149 private static final String LOG_TAG = "Settings";
151 private static final int LOADER_ID_INDEXABLE_CONTENT_MONITOR = 1;
153 // Constants for state save/restore
154 private static final String SAVE_KEY_CATEGORIES = ":settings:categories";
155 private static final String SAVE_KEY_SEARCH_MENU_EXPANDED = ":settings:search_menu_expanded";
156 private static final String SAVE_KEY_SEARCH_QUERY = ":settings:search_query";
157 private static final String SAVE_KEY_SHOW_HOME_AS_UP = ":settings:show_home_as_up";
158 private static final String SAVE_KEY_SHOW_SEARCH = ":settings:show_search";
159 private static final String SAVE_KEY_HOME_ACTIVITIES_COUNT = ":settings:home_activities_count";
162 * When starting this activity, the invoking Intent can contain this extra
163 * string to specify which fragment should be initially displayed.
164 * <p/>Starting from Key Lime Pie, when this argument is passed in, the activity
165 * will call isValidFragment() to confirm that the fragment class name is valid for this
168 public static final String EXTRA_SHOW_FRAGMENT = ":settings:show_fragment";
171 * When starting this activity and using {@link #EXTRA_SHOW_FRAGMENT},
172 * this extra can also be specified to supply a Bundle of arguments to pass
173 * to that fragment when it is instantiated during the initial creation
176 public static final String EXTRA_SHOW_FRAGMENT_ARGUMENTS = ":settings:show_fragment_args";
179 * Fragment "key" argument passed thru {@link #EXTRA_SHOW_FRAGMENT_ARGUMENTS}
181 public static final String EXTRA_FRAGMENT_ARG_KEY = ":settings:fragment_args_key";
183 public static final String BACK_STACK_PREFS = ":settings:prefs";
185 // extras that allow any preference activity to be launched as part of a wizard
187 // show Back and Next buttons? takes boolean parameter
188 // Back will then return RESULT_CANCELED and Next RESULT_OK
189 protected static final String EXTRA_PREFS_SHOW_BUTTON_BAR = "extra_prefs_show_button_bar";
191 // add a Skip button?
192 private static final String EXTRA_PREFS_SHOW_SKIP = "extra_prefs_show_skip";
194 // specify custom text for the Back or Next buttons, or cause a button to not appear
195 // at all by setting it to null
196 protected static final String EXTRA_PREFS_SET_NEXT_TEXT = "extra_prefs_set_next_text";
197 protected static final String EXTRA_PREFS_SET_BACK_TEXT = "extra_prefs_set_back_text";
200 * When starting this activity and using {@link #EXTRA_SHOW_FRAGMENT},
201 * those extra can also be specify to supply the title or title res id to be shown for
204 public static final String EXTRA_SHOW_FRAGMENT_TITLE = ":settings:show_fragment_title";
206 * The package name used to resolve the title resource id.
208 public static final String EXTRA_SHOW_FRAGMENT_TITLE_RES_PACKAGE_NAME =
209 ":settings:show_fragment_title_res_package_name";
210 public static final String EXTRA_SHOW_FRAGMENT_TITLE_RESID =
211 ":settings:show_fragment_title_resid";
212 public static final String EXTRA_SHOW_FRAGMENT_AS_SHORTCUT =
213 ":settings:show_fragment_as_shortcut";
215 public static final String EXTRA_SHOW_FRAGMENT_AS_SUBSETTING =
216 ":settings:show_fragment_as_subsetting";
218 public static final String EXTRA_HIDE_DRAWER = ":settings:hide_drawer";
220 public static final String META_DATA_KEY_FRAGMENT_CLASS =
221 "com.android.settings.FRAGMENT_CLASS";
223 private static final String EXTRA_UI_OPTIONS = "settings:ui_options";
225 private static final String EMPTY_QUERY = "";
227 private static final int REQUEST_SUGGESTION = 42;
229 private String mFragmentClass;
231 private CharSequence mInitialTitle;
232 private int mInitialTitleResId;
234 // Show only these settings for restricted users
235 private String[] SETTINGS_FOR_RESTRICTED = {
237 WifiSettingsActivity.class.getName(),
238 Settings.BluetoothSettingsActivity.class.getName(),
239 Settings.DataUsageSummaryActivity.class.getName(),
240 Settings.SimSettingsActivity.class.getName(),
241 Settings.WirelessSettingsActivity.class.getName(),
243 Settings.HomeSettingsActivity.class.getName(),
244 Settings.SoundSettingsActivity.class.getName(),
245 Settings.DisplaySettingsActivity.class.getName(),
246 Settings.StorageSettingsActivity.class.getName(),
247 Settings.ManageApplicationsActivity.class.getName(),
248 Settings.PowerUsageSummaryActivity.class.getName(),
249 Settings.GestureSettingsActivity.class.getName(),
251 Settings.LocationSettingsActivity.class.getName(),
252 Settings.SecuritySettingsActivity.class.getName(),
253 Settings.InputMethodAndLanguageSettingsActivity.class.getName(),
254 Settings.UserSettingsActivity.class.getName(),
255 Settings.AccountSettingsActivity.class.getName(),
257 Settings.DateTimeSettingsActivity.class.getName(),
258 Settings.DeviceInfoSettingsActivity.class.getName(),
259 Settings.AccessibilitySettingsActivity.class.getName(),
260 Settings.PrintSettingsActivity.class.getName(),
261 Settings.PaymentSettingsActivity.class.getName(),
264 private static final String[] ENTRY_FRAGMENTS = {
265 WirelessSettings.class.getName(),
266 WifiSettings.class.getName(),
267 AdvancedWifiSettings.class.getName(),
268 SavedAccessPointsWifiSettings.class.getName(),
269 BluetoothSettings.class.getName(),
270 SimSettings.class.getName(),
271 TetherSettings.class.getName(),
272 WifiP2pSettings.class.getName(),
273 VpnSettings.class.getName(),
274 DateTimeSettings.class.getName(),
275 LocaleListEditor.class.getName(),
276 InputMethodAndLanguageSettings.class.getName(),
277 AvailableVirtualKeyboardFragment.class.getName(),
278 SpellCheckersSettings.class.getName(),
279 UserDictionaryList.class.getName(),
280 UserDictionarySettings.class.getName(),
281 HomeSettings.class.getName(),
282 DisplaySettings.class.getName(),
283 DeviceInfoSettings.class.getName(),
284 ManageApplications.class.getName(),
285 NotificationApps.class.getName(),
286 ManageAssist.class.getName(),
287 ProcessStatsUi.class.getName(),
288 NotificationStation.class.getName(),
289 LocationSettings.class.getName(),
290 SecuritySettings.class.getName(),
291 UsageAccessDetails.class.getName(),
292 PrivacySettings.class.getName(),
293 DeviceAdminSettings.class.getName(),
294 AccessibilitySettings.class.getName(),
295 AccessibilitySettingsForSetupWizard.class.getName(),
296 CaptionPropertiesFragment.class.getName(),
297 com.android.settings.accessibility.ToggleDaltonizerPreferenceFragment.class.getName(),
298 TextToSpeechSettings.class.getName(),
299 StorageSettings.class.getName(),
300 PrivateVolumeForget.class.getName(),
301 PrivateVolumeSettings.class.getName(),
302 PublicVolumeSettings.class.getName(),
303 DevelopmentSettings.class.getName(),
304 AndroidBeam.class.getName(),
305 WifiDisplaySettings.class.getName(),
306 PowerUsageSummary.class.getName(),
307 AccountSyncSettings.class.getName(),
308 AccountSettings.class.getName(),
309 GestureSettings.class.getName(),
310 CryptKeeperSettings.class.getName(),
311 DataUsageSummary.class.getName(),
312 DreamSettings.class.getName(),
313 UserSettings.class.getName(),
314 NotificationAccessSettings.class.getName(),
315 ZenAccessSettings.class.getName(),
316 PrintSettingsFragment.class.getName(),
317 PrintJobSettingsFragment.class.getName(),
318 TrustedCredentialsSettings.class.getName(),
319 PaymentSettings.class.getName(),
320 KeyboardLayoutPickerFragment.class.getName(),
321 KeyboardLayoutPickerFragment2.class.getName(),
322 PhysicalKeyboardFragment.class.getName(),
323 ZenModeSettings.class.getName(),
324 SoundSettings.class.getName(),
325 ConfigureNotificationSettings.class.getName(),
326 ChooseLockPassword.ChooseLockPasswordFragment.class.getName(),
327 ChooseLockPattern.ChooseLockPatternFragment.class.getName(),
328 InstalledAppDetails.class.getName(),
329 BatterySaverSettings.class.getName(),
330 AppNotificationSettings.class.getName(),
331 OtherSoundSettings.class.getName(),
332 ApnSettings.class.getName(),
333 ApnEditor.class.getName(),
334 WifiCallingSettings.class.getName(),
335 ZenModePrioritySettings.class.getName(),
336 ZenModeAutomationSettings.class.getName(),
337 ZenModeScheduleRuleSettings.class.getName(),
338 ZenModeEventRuleSettings.class.getName(),
339 ZenModeVisualInterruptionSettings.class.getName(),
340 ProcessStatsUi.class.getName(),
341 PowerUsageDetail.class.getName(),
342 ProcessStatsSummary.class.getName(),
343 DrawOverlayDetails.class.getName(),
344 WriteSettingsDetails.class.getName(),
345 AdvancedAppSettings.class.getName(),
346 WallpaperTypeSettings.class.getName(),
347 VrListenerSettings.class.getName(),
348 ManagedProfileSettings.class.getName(),
349 ChooseAccountActivity.class.getName(),
350 IccLockSettings.class.getName(),
351 ImeiInformation.class.getName(),
352 SimStatus.class.getName(),
353 Status.class.getName(),
354 TestingSettings.class.getName(),
355 WifiAPITest.class.getName(),
356 WifiInfo.class.getName(),
357 MasterClear.class.getName(),
358 NightDisplaySettings.class.getName(),
359 ManageDomainUrls.class.getName(),
360 AutomaticStorageManagerSettings.class.getName()
364 private static final String[] LIKE_SHORTCUT_INTENT_ACTION_ARRAY = {
365 "android.settings.APPLICATION_DETAILS_SETTINGS"
368 private SharedPreferences mDevelopmentPreferences;
369 private SharedPreferences.OnSharedPreferenceChangeListener mDevelopmentPreferencesListener;
371 private boolean mBatteryPresent = true;
372 private BroadcastReceiver mBatteryInfoReceiver = new BroadcastReceiver() {
374 public void onReceive(Context context, Intent intent) {
375 String action = intent.getAction();
376 if (Intent.ACTION_BATTERY_CHANGED.equals(action)) {
377 boolean batteryPresent = Utils.isBatteryPresent(intent);
379 if (mBatteryPresent != batteryPresent) {
380 mBatteryPresent = batteryPresent;
387 private final BroadcastReceiver mUserAddRemoveReceiver = new BroadcastReceiver() {
389 public void onReceive(Context context, Intent intent) {
390 String action = intent.getAction();
391 if (action.equals(Intent.ACTION_USER_ADDED)
392 || action.equals(Intent.ACTION_USER_REMOVED)) {
393 Index.getInstance(getApplicationContext()).update();
398 private final DynamicIndexableContentMonitor mDynamicIndexableContentMonitor =
399 new DynamicIndexableContentMonitor();
401 private ActionBar mActionBar;
402 private SwitchBar mSwitchBar;
404 private Button mNextButton;
406 private boolean mDisplayHomeAsUpEnabled;
407 private boolean mDisplaySearch;
409 private boolean mIsShowingDashboard;
410 private boolean mIsShortcut;
412 private ViewGroup mContent;
414 private SearchView mSearchView;
415 private MenuItem mSearchMenuItem;
416 private boolean mSearchMenuItemExpanded = false;
417 private SearchResultsSummary mSearchResultsFragment;
418 private String mSearchQuery;
421 private ArrayList<DashboardCategory> mCategories = new ArrayList<DashboardCategory>();
423 private static final String MSG_DATA_FORCE_REFRESH = "msg_data_force_refresh";
425 private boolean mNeedToRevertToInitialFragment = false;
427 private Intent mResultIntentData;
428 private ComponentName mCurrentSuggestion;
430 public SwitchBar getSwitchBar() {
435 public boolean onPreferenceStartFragment(PreferenceFragment caller, Preference pref) {
436 startPreferencePanel(pref.getFragment(), pref.getExtras(), -1, pref.getTitle(),
442 public boolean onPreferenceTreeClick(Preference preference) {
447 public void onConfigurationChanged(Configuration newConfig) {
448 super.onConfigurationChanged(newConfig);
449 Index.getInstance(this).update();
453 public boolean onCreateOptionsMenu(Menu menu) {
454 if (!mDisplaySearch) {
458 MenuInflater inflater = getMenuInflater();
459 inflater.inflate(R.menu.options_menu, menu);
461 // Cache the search query (can be overriden by the OnQueryTextListener)
462 final String query = mSearchQuery;
464 mSearchMenuItem = menu.findItem(R.id.search);
465 mSearchView = (SearchView) mSearchMenuItem.getActionView();
467 if (mSearchMenuItem == null || mSearchView == null) {
471 if (mSearchResultsFragment != null) {
472 mSearchResultsFragment.setSearchView(mSearchView);
475 mSearchMenuItem.setOnActionExpandListener(this);
476 mSearchView.setOnQueryTextListener(this);
477 mSearchView.setOnCloseListener(this);
479 if (mSearchMenuItemExpanded) {
480 mSearchMenuItem.expandActionView();
482 mSearchView.setQuery(query, true /* submit */);
488 public SharedPreferences getSharedPreferences(String name, int mode) {
489 if (name.equals(getPackageName() + "_preferences")) {
490 return new SharedPreferencesLogger(this, getMetricsTag());
492 return super.getSharedPreferences(name, mode);
495 private String getMetricsTag() {
496 String tag = getClass().getName();
497 if (getIntent() != null && getIntent().hasExtra(EXTRA_SHOW_FRAGMENT)) {
498 tag = getIntent().getStringExtra(EXTRA_SHOW_FRAGMENT);
500 if (tag.startsWith("com.android.settings.")) {
501 tag = tag.replace("com.android.settings.", "");
506 private static boolean isShortCutIntent(final Intent intent) {
507 Set<String> categories = intent.getCategories();
508 return (categories != null) && categories.contains("com.android.settings.SHORTCUT");
511 private static boolean isLikeShortCutIntent(final Intent intent) {
512 String action = intent.getAction();
513 if (action == null) {
516 for (int i = 0; i < LIKE_SHORTCUT_INTENT_ACTION_ARRAY.length; i++) {
517 if (LIKE_SHORTCUT_INTENT_ACTION_ARRAY[i].equals(action)) return true;
523 protected void onCreate(Bundle savedState) {
524 super.onCreate(savedState);
525 long startTime = System.currentTimeMillis();
527 // Should happen before any call to getIntent()
530 final Intent intent = getIntent();
531 if (intent.hasExtra(EXTRA_UI_OPTIONS)) {
532 getWindow().setUiOptions(intent.getIntExtra(EXTRA_UI_OPTIONS, 0));
534 if (intent.getBooleanExtra(EXTRA_HIDE_DRAWER, false)) {
535 setIsDrawerPresent(false);
538 mDevelopmentPreferences = getSharedPreferences(DevelopmentSettings.PREF_FILE,
539 Context.MODE_PRIVATE);
541 // Getting Intent properties can only be done after the super.onCreate(...)
542 final String initialFragmentName = intent.getStringExtra(EXTRA_SHOW_FRAGMENT);
544 mIsShortcut = isShortCutIntent(intent) || isLikeShortCutIntent(intent) ||
545 intent.getBooleanExtra(EXTRA_SHOW_FRAGMENT_AS_SHORTCUT, false);
547 final ComponentName cn = intent.getComponent();
548 final String className = cn.getClassName();
550 mIsShowingDashboard = className.equals(Settings.class.getName())
551 || className.equals(Settings.WirelessSettings.class.getName())
552 || className.equals(Settings.DeviceSettings.class.getName())
553 || className.equals(Settings.PersonalSettings.class.getName())
554 || className.equals(Settings.WirelessSettings.class.getName());
556 // This is a "Sub Settings" when:
557 // - this is a real SubSettings
558 // - or :settings:show_fragment_as_subsetting is passed to the Intent
559 final boolean isSubSettings = this instanceof SubSettings ||
560 intent.getBooleanExtra(EXTRA_SHOW_FRAGMENT_AS_SUBSETTING, false);
562 // If this is a sub settings, then apply the SubSettings Theme for the ActionBar content insets
564 // Check also that we are not a Theme Dialog as we don't want to override them
565 final int themeResId = getThemeResId();
566 if (themeResId != R.style.Theme_DialogWhenLarge &&
567 themeResId != R.style.Theme_SubSettingsDialogWhenLarge) {
568 setTheme(R.style.Theme_SubSettings);
572 setContentView(mIsShowingDashboard ?
573 R.layout.settings_main_dashboard : R.layout.settings_main_prefs);
575 mContent = (ViewGroup) findViewById(R.id.main_content);
577 getFragmentManager().addOnBackStackChangedListener(this);
579 if (mIsShowingDashboard) {
580 // Run the Index update only if we have some space
581 if (!Utils.isLowStorage(this)) {
582 long indexStartTime = System.currentTimeMillis();
583 Index.getInstance(getApplicationContext()).update();
584 if (DEBUG_TIMING) Log.d(LOG_TAG, "Index.update() took "
585 + (System.currentTimeMillis() - indexStartTime) + " ms");
587 Log.w(LOG_TAG, "Cannot update the Indexer as we are running low on storage space!");
591 if (savedState != null) {
592 // We are restarting from a previous saved state; used that to initialize, instead
593 // of starting fresh.
594 mSearchMenuItemExpanded = savedState.getBoolean(SAVE_KEY_SEARCH_MENU_EXPANDED);
595 mSearchQuery = savedState.getString(SAVE_KEY_SEARCH_QUERY);
596 setTitleFromIntent(intent);
598 ArrayList<DashboardCategory> categories =
599 savedState.getParcelableArrayList(SAVE_KEY_CATEGORIES);
600 if (categories != null) {
602 mCategories.addAll(categories);
603 setTitleFromBackStack();
606 mDisplayHomeAsUpEnabled = savedState.getBoolean(SAVE_KEY_SHOW_HOME_AS_UP);
607 mDisplaySearch = savedState.getBoolean(SAVE_KEY_SHOW_SEARCH);
610 if (!mIsShowingDashboard) {
611 mDisplaySearch = false;
612 // UP will be shown only if it is a sub settings
614 mDisplayHomeAsUpEnabled = isSubSettings;
615 } else if (isSubSettings) {
616 mDisplayHomeAsUpEnabled = true;
618 mDisplayHomeAsUpEnabled = false;
620 setTitleFromIntent(intent);
622 Bundle initialArguments = intent.getBundleExtra(EXTRA_SHOW_FRAGMENT_ARGUMENTS);
623 switchToFragment(initialFragmentName, initialArguments, true, false,
624 mInitialTitleResId, mInitialTitle, false);
626 // No UP affordance if we are displaying the main Dashboard
627 mDisplayHomeAsUpEnabled = false;
628 // Show Search affordance
629 mDisplaySearch = true;
630 mInitialTitleResId = R.string.dashboard_title;
632 // add argument to indicate which settings tab should be initially selected
633 final Bundle args = new Bundle();
634 final String extraName = DashboardContainerFragment.EXTRA_SELECT_SETTINGS_TAB;
635 args.putString(extraName, intent.getStringExtra(extraName));
637 switchToFragment(DashboardContainerFragment.class.getName(), args, false, false,
638 mInitialTitleResId, mInitialTitle, false);
642 mActionBar = getActionBar();
643 if (mActionBar != null) {
644 mActionBar.setDisplayHomeAsUpEnabled(mDisplayHomeAsUpEnabled);
645 mActionBar.setHomeButtonEnabled(mDisplayHomeAsUpEnabled);
647 mSwitchBar = (SwitchBar) findViewById(R.id.switch_bar);
648 if (mSwitchBar != null) {
649 mSwitchBar.setMetricsTag(getMetricsTag());
652 // see if we should show Back/Next buttons
653 if (intent.getBooleanExtra(EXTRA_PREFS_SHOW_BUTTON_BAR, false)) {
655 View buttonBar = findViewById(R.id.button_bar);
656 if (buttonBar != null) {
657 buttonBar.setVisibility(View.VISIBLE);
659 Button backButton = (Button)findViewById(R.id.back_button);
660 backButton.setOnClickListener(new OnClickListener() {
661 public void onClick(View v) {
662 setResult(RESULT_CANCELED, getResultIntentData());
666 Button skipButton = (Button)findViewById(R.id.skip_button);
667 skipButton.setOnClickListener(new OnClickListener() {
668 public void onClick(View v) {
669 setResult(RESULT_OK, getResultIntentData());
673 mNextButton = (Button)findViewById(R.id.next_button);
674 mNextButton.setOnClickListener(new OnClickListener() {
675 public void onClick(View v) {
676 setResult(RESULT_OK, getResultIntentData());
681 // set our various button parameters
682 if (intent.hasExtra(EXTRA_PREFS_SET_NEXT_TEXT)) {
683 String buttonText = intent.getStringExtra(EXTRA_PREFS_SET_NEXT_TEXT);
684 if (TextUtils.isEmpty(buttonText)) {
685 mNextButton.setVisibility(View.GONE);
688 mNextButton.setText(buttonText);
691 if (intent.hasExtra(EXTRA_PREFS_SET_BACK_TEXT)) {
692 String buttonText = intent.getStringExtra(EXTRA_PREFS_SET_BACK_TEXT);
693 if (TextUtils.isEmpty(buttonText)) {
694 backButton.setVisibility(View.GONE);
697 backButton.setText(buttonText);
700 if (intent.getBooleanExtra(EXTRA_PREFS_SHOW_SKIP, false)) {
701 skipButton.setVisibility(View.VISIBLE);
706 if (DEBUG_TIMING) Log.d(LOG_TAG, "onCreate took " + (System.currentTimeMillis() - startTime)
710 public void setDisplaySearchMenu(boolean displaySearch) {
711 if (displaySearch != mDisplaySearch) {
712 mDisplaySearch = displaySearch;
713 invalidateOptionsMenu();
717 private void setTitleFromIntent(Intent intent) {
718 final int initialTitleResId = intent.getIntExtra(EXTRA_SHOW_FRAGMENT_TITLE_RESID, -1);
719 if (initialTitleResId > 0) {
720 mInitialTitle = null;
721 mInitialTitleResId = initialTitleResId;
723 final String initialTitleResPackageName = intent.getStringExtra(
724 EXTRA_SHOW_FRAGMENT_TITLE_RES_PACKAGE_NAME);
725 if (initialTitleResPackageName != null) {
727 Context authContext = createPackageContextAsUser(initialTitleResPackageName,
728 0 /* flags */, new UserHandle(UserHandle.myUserId()));
729 mInitialTitle = authContext.getResources().getText(mInitialTitleResId);
730 setTitle(mInitialTitle);
731 mInitialTitleResId = -1;
733 } catch (NameNotFoundException e) {
734 Log.w(LOG_TAG, "Could not find package" + initialTitleResPackageName);
737 setTitle(mInitialTitleResId);
740 mInitialTitleResId = -1;
741 final String initialTitle = intent.getStringExtra(EXTRA_SHOW_FRAGMENT_TITLE);
742 mInitialTitle = (initialTitle != null) ? initialTitle : getTitle();
743 setTitle(mInitialTitle);
748 public void onBackStackChanged() {
749 setTitleFromBackStack();
752 private void setTitleFromBackStack() {
753 final int count = getFragmentManager().getBackStackEntryCount();
756 if (mInitialTitleResId > 0) {
757 setTitle(mInitialTitleResId);
759 setTitle(mInitialTitle);
764 FragmentManager.BackStackEntry bse = getFragmentManager().getBackStackEntryAt(count - 1);
765 setTitleFromBackStackEntry(bse);
768 private void setTitleFromBackStackEntry(FragmentManager.BackStackEntry bse) {
769 final CharSequence title;
770 final int titleRes = bse.getBreadCrumbTitleRes();
772 title = getText(titleRes);
774 title = bse.getBreadCrumbTitle();
782 protected void onSaveInstanceState(Bundle outState) {
783 super.onSaveInstanceState(outState);
785 if (mCategories.size() > 0) {
786 outState.putParcelableArrayList(SAVE_KEY_CATEGORIES, mCategories);
789 outState.putBoolean(SAVE_KEY_SHOW_HOME_AS_UP, mDisplayHomeAsUpEnabled);
790 outState.putBoolean(SAVE_KEY_SHOW_SEARCH, mDisplaySearch);
792 if (mDisplaySearch) {
793 // The option menus are created if the ActionBar is visible and they are also created
794 // asynchronously. If you launch Settings with an Intent action like
795 // android.intent.action.POWER_USAGE_SUMMARY and at the same time your device is locked
796 // thru a LockScreen, onCreateOptionsMenu() is not yet called and references to the search
797 // menu item and search view are null.
798 boolean isExpanded = (mSearchMenuItem != null) && mSearchMenuItem.isActionViewExpanded();
799 outState.putBoolean(SAVE_KEY_SEARCH_MENU_EXPANDED, isExpanded);
801 String query = (mSearchView != null) ? mSearchView.getQuery().toString() : EMPTY_QUERY;
802 outState.putString(SAVE_KEY_SEARCH_QUERY, query);
807 protected void onStart() {
810 if (mNeedToRevertToInitialFragment) {
811 revertToInitialFragment();
814 mDevelopmentPreferencesListener = new SharedPreferences.OnSharedPreferenceChangeListener() {
816 public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
820 mDevelopmentPreferences.registerOnSharedPreferenceChangeListener(
821 mDevelopmentPreferencesListener);
823 registerReceiver(mBatteryInfoReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
824 registerReceiver(mUserAddRemoveReceiver, new IntentFilter(Intent.ACTION_USER_ADDED));
825 registerReceiver(mUserAddRemoveReceiver, new IntentFilter(Intent.ACTION_USER_REMOVED));
827 mDynamicIndexableContentMonitor.register(this, LOADER_ID_INDEXABLE_CONTENT_MONITOR);
829 if(mDisplaySearch && !TextUtils.isEmpty(mSearchQuery)) {
830 onQueryTextSubmit(mSearchQuery);
836 protected void onStop() {
838 unregisterReceiver(mBatteryInfoReceiver);
839 unregisterReceiver(mUserAddRemoveReceiver);
840 mDynamicIndexableContentMonitor.unregister();
844 public void onDestroy() {
847 mDevelopmentPreferences.unregisterOnSharedPreferenceChangeListener(
848 mDevelopmentPreferencesListener);
849 mDevelopmentPreferencesListener = null;
852 protected boolean isValidFragment(String fragmentName) {
853 // Almost all fragments are wrapped in this,
854 // except for a few that have their own activities.
855 for (int i = 0; i < ENTRY_FRAGMENTS.length; i++) {
856 if (ENTRY_FRAGMENTS[i].equals(fragmentName)) return true;
862 public Intent getIntent() {
863 Intent superIntent = super.getIntent();
864 String startingFragment = getStartingFragmentClass(superIntent);
865 // This is called from super.onCreate, isMultiPane() is not yet reliable
866 // Do not use onIsHidingHeaders either, which relies itself on this method
867 if (startingFragment != null) {
868 Intent modIntent = new Intent(superIntent);
869 modIntent.putExtra(EXTRA_SHOW_FRAGMENT, startingFragment);
870 Bundle args = superIntent.getExtras();
872 args = new Bundle(args);
876 args.putParcelable("intent", superIntent);
877 modIntent.putExtra(EXTRA_SHOW_FRAGMENT_ARGUMENTS, args);
884 * Checks if the component name in the intent is different from the Settings class and
885 * returns the class name to load as a fragment.
887 private String getStartingFragmentClass(Intent intent) {
888 if (mFragmentClass != null) return mFragmentClass;
890 String intentClass = intent.getComponent().getClassName();
891 if (intentClass.equals(getClass().getName())) return null;
893 if ("com.android.settings.ManageApplications".equals(intentClass)
894 || "com.android.settings.RunningServices".equals(intentClass)
895 || "com.android.settings.applications.StorageUse".equals(intentClass)) {
896 // Old names of manage apps.
897 intentClass = com.android.settings.applications.ManageApplications.class.getName();
904 * Start a new fragment containing a preference panel. If the preferences
905 * are being displayed in multi-pane mode, the given fragment class will
906 * be instantiated and placed in the appropriate pane. If running in
907 * single-pane mode, a new activity will be launched in which to show the
910 * @param fragmentClass Full name of the class implementing the fragment.
911 * @param args Any desired arguments to supply to the fragment.
912 * @param titleRes Optional resource identifier of the title of this
914 * @param titleText Optional text of the title of this fragment.
915 * @param resultTo Optional fragment that result data should be sent to.
916 * If non-null, resultTo.onActivityResult() will be called when this
917 * preference panel is done. The launched panel must use
918 * {@link #finishPreferencePanel(Fragment, int, Intent)} when done.
919 * @param resultRequestCode If resultTo is non-null, this is the caller's
920 * request code to be received with the result.
922 public void startPreferencePanel(String fragmentClass, Bundle args, int titleRes,
923 CharSequence titleText, Fragment resultTo, int resultRequestCode) {
926 if (titleText != null) {
927 title = titleText.toString();
929 // There not much we can do in that case
933 Utils.startWithFragment(this, fragmentClass, args, resultTo, resultRequestCode,
934 titleRes, title, mIsShortcut);
938 * Start a new fragment in a new activity containing a preference panel for a given user. If the
939 * preferences are being displayed in multi-pane mode, the given fragment class will be
940 * instantiated and placed in the appropriate pane. If running in single-pane mode, a new
941 * activity will be launched in which to show the fragment.
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 fragment.
946 * @param titleText Optional text of the title of this fragment.
947 * @param userHandle The user for which the panel has to be started.
949 public void startPreferencePanelAsUser(String fragmentClass, Bundle args, int titleRes,
950 CharSequence titleText, UserHandle userHandle) {
951 // This is a workaround.
953 // Calling startWithFragmentAsUser() without specifying FLAG_ACTIVITY_NEW_TASK to the intent
954 // starting the fragment could cause a native stack corruption. See b/17523189. However,
955 // adding that flag and start the preference panel with the same UserHandler will make it
956 // impossible to use back button to return to the previous screen. See b/20042570.
958 // We work around this issue by adding FLAG_ACTIVITY_NEW_TASK to the intent, while doing
959 // another check here to call startPreferencePanel() instead of startWithFragmentAsUser()
960 // when we're calling it as the same user.
961 if (userHandle.getIdentifier() == UserHandle.myUserId()) {
962 startPreferencePanel(fragmentClass, args, titleRes, titleText, null, 0);
966 if (titleText != null) {
967 title = titleText.toString();
969 // There not much we can do in that case
973 Utils.startWithFragmentAsUser(this, fragmentClass, args,
974 titleRes, title, mIsShortcut, userHandle);
979 * Called by a preference panel fragment to finish itself.
981 * @param caller The fragment that is asking to be finished.
982 * @param resultCode Optional result code to send back to the original
983 * launching fragment.
984 * @param resultData Optional result data to send back to the original
985 * launching fragment.
987 public void finishPreferencePanel(Fragment caller, int resultCode, Intent resultData) {
988 setResult(resultCode, resultData);
993 * Start a new fragment.
995 * @param fragment The fragment to start
996 * @param push If true, the current fragment will be pushed onto the back stack. If false,
997 * the current fragment will be replaced.
999 public void startPreferenceFragment(Fragment fragment, boolean push) {
1000 FragmentTransaction transaction = getFragmentManager().beginTransaction();
1001 transaction.replace(R.id.main_content, fragment);
1003 transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
1004 transaction.addToBackStack(BACK_STACK_PREFS);
1006 transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
1008 transaction.commitAllowingStateLoss();
1012 * Switch to a specific Fragment with taking care of validation, Title and BackStack
1014 private Fragment switchToFragment(String fragmentName, Bundle args, boolean validate,
1015 boolean addToBackStack, int titleResId, CharSequence title, boolean withTransition) {
1016 if (validate && !isValidFragment(fragmentName)) {
1017 throw new IllegalArgumentException("Invalid fragment for this activity: "
1020 Fragment f = Fragment.instantiate(this, fragmentName, args);
1021 FragmentTransaction transaction = getFragmentManager().beginTransaction();
1022 transaction.replace(R.id.main_content, f);
1023 if (withTransition) {
1024 TransitionManager.beginDelayedTransition(mContent);
1026 if (addToBackStack) {
1027 transaction.addToBackStack(SettingsActivity.BACK_STACK_PREFS);
1029 if (titleResId > 0) {
1030 transaction.setBreadCrumbTitle(titleResId);
1031 } else if (title != null) {
1032 transaction.setBreadCrumbTitle(title);
1034 transaction.commitAllowingStateLoss();
1035 getFragmentManager().executePendingTransactions();
1039 private void updateTilesList() {
1040 // Generally the items that are will be changing from these updates will
1041 // not be in the top list of tiles, so run it in the background and the
1042 // SettingsDrawerActivity will pick up on the updates automatically.
1043 AsyncTask.execute(new Runnable() {
1046 doUpdateTilesList();
1051 private void doUpdateTilesList() {
1052 PackageManager pm = getPackageManager();
1053 final UserManager um = UserManager.get(this);
1054 final boolean isAdmin = um.isAdminUser();
1056 String packageName = getPackageName();
1057 setTileEnabled(new ComponentName(packageName, WifiSettingsActivity.class.getName()),
1058 pm.hasSystemFeature(PackageManager.FEATURE_WIFI), isAdmin, pm);
1060 setTileEnabled(new ComponentName(packageName,
1061 Settings.BluetoothSettingsActivity.class.getName()),
1062 pm.hasSystemFeature(PackageManager.FEATURE_BLUETOOTH), isAdmin, pm);
1064 setTileEnabled(new ComponentName(packageName,
1065 Settings.DataUsageSummaryActivity.class.getName()),
1066 Utils.isBandwidthControlEnabled(), isAdmin, pm);
1068 setTileEnabled(new ComponentName(packageName,
1069 Settings.SimSettingsActivity.class.getName()),
1070 Utils.showSimCardTile(this), isAdmin, pm);
1072 setTileEnabled(new ComponentName(packageName,
1073 Settings.PowerUsageSummaryActivity.class.getName()),
1074 mBatteryPresent, isAdmin, pm);
1076 setTileEnabled(new ComponentName(packageName,
1077 Settings.UserSettingsActivity.class.getName()),
1078 UserHandle.MU_ENABLED && UserManager.supportsMultipleUsers()
1079 && !Utils.isMonkeyRunning(), isAdmin, pm);
1081 setTileEnabled(new ComponentName(packageName,
1082 Settings.WirelessSettingsActivity.class.getName()),
1083 !UserManager.isDeviceInDemoMode(this), isAdmin, pm);
1085 setTileEnabled(new ComponentName(packageName,
1086 Settings.DateTimeSettingsActivity.class.getName()),
1087 !UserManager.isDeviceInDemoMode(this), isAdmin, pm);
1088 NfcAdapter adapter = NfcAdapter.getDefaultAdapter(this);
1089 setTileEnabled(new ComponentName(packageName,
1090 Settings.PaymentSettingsActivity.class.getName()),
1091 pm.hasSystemFeature(PackageManager.FEATURE_NFC)
1092 && pm.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION)
1093 && adapter != null && adapter.isEnabled(), isAdmin, pm);
1095 setTileEnabled(new ComponentName(packageName,
1096 Settings.PrintSettingsActivity.class.getName()),
1097 pm.hasSystemFeature(PackageManager.FEATURE_PRINTING), isAdmin, pm);
1099 final boolean showDev = mDevelopmentPreferences.getBoolean(
1100 DevelopmentSettings.PREF_SHOW, android.os.Build.TYPE.equals("eng"))
1101 && !um.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES);
1102 setTileEnabled(new ComponentName(packageName,
1103 Settings.DevelopmentSettingsActivity.class.getName()),
1104 showDev, isAdmin, pm);
1106 // Reveal development-only quick settings tiles
1107 DevelopmentTiles.setTilesEnabled(this, showDev);
1109 if (UserHandle.MU_ENABLED && !isAdmin) {
1110 // When on restricted users, disable all extra categories (but only the settings ones).
1111 List<DashboardCategory> categories = getDashboardCategories();
1112 for (DashboardCategory category : categories) {
1113 for (Tile tile : category.tiles) {
1114 ComponentName component = tile.intent.getComponent();
1115 if (packageName.equals(component.getPackageName()) && !ArrayUtils.contains(
1116 SETTINGS_FOR_RESTRICTED, component.getClassName())) {
1117 setTileEnabled(component, false, isAdmin, pm);
1123 String backupIntent = getResources().getString(R.string.config_backup_settings_intent);
1124 boolean useDefaultBackup = TextUtils.isEmpty(backupIntent);
1125 setTileEnabled(new ComponentName(packageName,
1126 Settings.PrivacySettingsActivity.class.getName()), useDefaultBackup, isAdmin, pm);
1127 boolean hasBackupActivity = false;
1128 if (!useDefaultBackup) {
1130 Intent intent = Intent.parseUri(backupIntent, 0);
1131 hasBackupActivity = !getPackageManager().queryIntentActivities(intent, 0).isEmpty();
1132 } catch (URISyntaxException e) {
1133 Log.e(LOG_TAG, "Invalid backup intent URI!", e);
1136 setTileEnabled(new ComponentName(packageName,
1137 BackupSettingsActivity.class.getName()), hasBackupActivity,
1138 isAdmin || Utils.isCarrierDemoUser(this), pm);
1142 private void setTileEnabled(ComponentName component, boolean enabled, boolean isAdmin,
1143 PackageManager pm) {
1144 if (UserHandle.MU_ENABLED && !isAdmin && getPackageName().equals(component.getPackageName())
1145 && !ArrayUtils.contains(SETTINGS_FOR_RESTRICTED, component.getClassName())) {
1148 setTileEnabled(component, enabled);
1151 private void getMetaData() {
1153 ActivityInfo ai = getPackageManager().getActivityInfo(getComponentName(),
1154 PackageManager.GET_META_DATA);
1155 if (ai == null || ai.metaData == null) return;
1156 mFragmentClass = ai.metaData.getString(META_DATA_KEY_FRAGMENT_CLASS);
1157 } catch (NameNotFoundException nnfe) {
1159 Log.d(LOG_TAG, "Cannot get Metadata for: " + getComponentName().toString());
1163 // give subclasses access to the Next button
1164 public boolean hasNextButton() {
1165 return mNextButton != null;
1168 public Button getNextButton() {
1173 public boolean shouldUpRecreateTask(Intent targetIntent) {
1174 return super.shouldUpRecreateTask(new Intent(this, SettingsActivity.class));
1178 public boolean onQueryTextSubmit(String query) {
1179 switchToSearchResultsFragmentIfNeeded();
1180 mSearchQuery = query;
1181 return mSearchResultsFragment.onQueryTextSubmit(query);
1185 public boolean onQueryTextChange(String newText) {
1186 mSearchQuery = newText;
1187 if (mSearchResultsFragment == null) {
1190 return mSearchResultsFragment.onQueryTextChange(newText);
1194 public boolean onClose() {
1199 public boolean onMenuItemActionExpand(MenuItem item) {
1200 if (item.getItemId() == mSearchMenuItem.getItemId()) {
1201 switchToSearchResultsFragmentIfNeeded();
1207 public boolean onMenuItemActionCollapse(MenuItem item) {
1208 if (item.getItemId() == mSearchMenuItem.getItemId()) {
1209 if (mSearchMenuItemExpanded) {
1210 revertToInitialFragment();
1217 protected void onTileClicked(Tile tile) {
1218 if (mIsShowingDashboard) {
1219 // If on dashboard, don't finish so the back comes back to here.
1222 super.onTileClicked(tile);
1227 public void onProfileTileOpen() {
1228 if (!mIsShowingDashboard) {
1233 private void switchToSearchResultsFragmentIfNeeded() {
1234 if (mSearchResultsFragment != null) {
1237 Fragment current = getFragmentManager().findFragmentById(R.id.main_content);
1238 if (current != null && current instanceof SearchResultsSummary) {
1239 mSearchResultsFragment = (SearchResultsSummary) current;
1241 setContentHeaderView(null);
1242 mSearchResultsFragment = (SearchResultsSummary) switchToFragment(
1243 SearchResultsSummary.class.getName(), null, false, true,
1244 R.string.search_results_title, null, true);
1246 mSearchResultsFragment.setSearchView(mSearchView);
1247 mSearchMenuItemExpanded = true;
1250 public void needToRevertToInitialFragment() {
1251 mNeedToRevertToInitialFragment = true;
1254 private void revertToInitialFragment() {
1255 mNeedToRevertToInitialFragment = false;
1256 mSearchResultsFragment = null;
1257 mSearchMenuItemExpanded = false;
1258 getFragmentManager().popBackStackImmediate(SettingsActivity.BACK_STACK_PREFS,
1259 FragmentManager.POP_BACK_STACK_INCLUSIVE);
1260 if (mSearchMenuItem != null) {
1261 mSearchMenuItem.collapseActionView();
1265 public Intent getResultIntentData() {
1266 return mResultIntentData;
1269 public void setResultIntentData(Intent resultIntentData) {
1270 mResultIntentData = resultIntentData;
1273 public void startSuggestion(Intent intent) {
1274 if (intent == null || ActivityManager.isUserAMonkey()) {
1277 mCurrentSuggestion = intent.getComponent();
1278 startActivityForResult(intent, REQUEST_SUGGESTION);
1282 protected void onActivityResult(int requestCode, int resultCode, Intent data) {
1283 if (requestCode == REQUEST_SUGGESTION && mCurrentSuggestion != null
1284 && resultCode != RESULT_CANCELED) {
1285 getPackageManager().setComponentEnabledSetting(mCurrentSuggestion,
1286 PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
1288 super.onActivityResult(requestCode, resultCode, data);