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.ActionBar;
20 import android.app.ActivityManager;
21 import android.app.Fragment;
22 import android.app.FragmentManager;
23 import android.app.FragmentTransaction;
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.accessibility.ToggleDaltonizerPreferenceFragment;
60 import com.android.settings.accounts.AccountSettings;
61 import com.android.settings.accounts.AccountSyncSettings;
62 import com.android.settings.accounts.ChooseAccountActivity;
63 import com.android.settings.accounts.ManagedProfileSettings;
64 import com.android.settings.accounts.UserAndAccountDashboardFragment;
65 import com.android.settings.applications.AdvancedAppSettings;
66 import com.android.settings.applications.AppAndNotificationDashboardFragment;
67 import com.android.settings.applications.DrawOverlayDetails;
68 import com.android.settings.applications.InstalledAppDetails;
69 import com.android.settings.applications.ManageApplications;
70 import com.android.settings.applications.ManageAssist;
71 import com.android.settings.applications.ManageDomainUrls;
72 import com.android.settings.applications.NotificationApps;
73 import com.android.settings.applications.ProcessStatsSummary;
74 import com.android.settings.applications.ProcessStatsUi;
75 import com.android.settings.applications.UsageAccessDetails;
76 import com.android.settings.applications.VrListenerSettings;
77 import com.android.settings.applications.WriteSettingsDetails;
78 import com.android.settings.bluetooth.BluetoothSettings;
79 import com.android.settings.connecteddevice.ConnectedDeviceDashboardFragment;
80 import com.android.settings.core.instrumentation.SharedPreferencesLogger;
81 import com.android.settings.dashboard.DashboardContainerFragment;
82 import com.android.settings.dashboard.DashboardFeatureProvider;
83 import com.android.settings.dashboard.DashboardSummary;
84 import com.android.settings.dashboard.SearchResultsSummary;
85 import com.android.settings.dashboard.SupportFragment;
86 import com.android.settings.datausage.DataUsageSummary;
87 import com.android.settings.deletionhelper.AutomaticStorageManagerSettings;
88 import com.android.settings.deviceinfo.ImeiInformation;
89 import com.android.settings.deviceinfo.PrivateVolumeForget;
90 import com.android.settings.deviceinfo.PrivateVolumeSettings;
91 import com.android.settings.deviceinfo.PublicVolumeSettings;
92 import com.android.settings.deviceinfo.SimStatus;
93 import com.android.settings.deviceinfo.Status;
94 import com.android.settings.deviceinfo.StorageDashboardFragment;
95 import com.android.settings.deviceinfo.StorageSettings;
96 import com.android.settings.display.NightDisplaySettings;
97 import com.android.settings.enterprise.EnterprisePrivacyFeatureProvider;
98 import com.android.settings.enterprise.EnterprisePrivacySettings;
99 import com.android.settings.fuelgauge.BatterySaverSettings;
100 import com.android.settings.fuelgauge.PowerUsageDetail;
101 import com.android.settings.fuelgauge.PowerUsageSummary;
102 import com.android.settings.gestures.DoubleTapPowerSettings;
103 import com.android.settings.gestures.DoubleTapScreenPreferenceController;
104 import com.android.settings.gestures.DoubleTapScreenSettings;
105 import com.android.settings.gestures.DoubleTwistGestureSettings;
106 import com.android.settings.gestures.GestureSettings;
107 import com.android.settings.gestures.PickupGestureSettings;
108 import com.android.settings.gestures.SwipeToNotificationSettings;
109 import com.android.settings.inputmethod.AvailableVirtualKeyboardFragment;
110 import com.android.settings.inputmethod.InputAndGestureSettings;
111 import com.android.settings.inputmethod.InputMethodAndLanguageSettings;
112 import com.android.settings.inputmethod.KeyboardLayoutPickerFragment;
113 import com.android.settings.inputmethod.PhysicalKeyboardFragment;
114 import com.android.settings.inputmethod.SpellCheckersSettings;
115 import com.android.settings.inputmethod.UserDictionaryList;
116 import com.android.settings.language.LanguageAndRegionSettings;
117 import com.android.settings.localepicker.LocaleListEditor;
118 import com.android.settings.location.LocationSettings;
119 import com.android.settings.network.NetworkDashboardFragment;
120 import com.android.settings.nfc.AndroidBeam;
121 import com.android.settings.nfc.PaymentSettings;
122 import com.android.settings.notification.AppNotificationSettings;
123 import com.android.settings.notification.ConfigureNotificationSettings;
124 import com.android.settings.notification.NotificationAccessSettings;
125 import com.android.settings.notification.NotificationStation;
126 import com.android.settings.notification.OtherSoundSettings;
127 import com.android.settings.notification.SoundSettings;
128 import com.android.settings.notification.ZenAccessSettings;
129 import com.android.settings.notification.ZenModeAutomationSettings;
130 import com.android.settings.notification.ZenModeEventRuleSettings;
131 import com.android.settings.notification.ZenModePrioritySettings;
132 import com.android.settings.notification.ZenModeScheduleRuleSettings;
133 import com.android.settings.notification.ZenModeSettings;
134 import com.android.settings.notification.ZenModeVisualInterruptionSettings;
135 import com.android.settings.overlay.FeatureFactory;
136 import com.android.settings.print.PrintJobSettingsFragment;
137 import com.android.settings.print.PrintSettingsFragment;
138 import com.android.settings.qstile.DevelopmentTiles;
139 import com.android.settings.search.DynamicIndexableContentMonitor;
140 import com.android.settings.search.Index;
141 import com.android.settings.sim.SimSettings;
142 import com.android.settings.system.SystemDashboardFragment;
143 import com.android.settings.tts.TextToSpeechSettings;
144 import com.android.settings.users.UserSettings;
145 import com.android.settings.vpn2.VpnSettings;
146 import com.android.settings.wfd.WifiDisplaySettings;
147 import com.android.settings.widget.SwitchBar;
148 import com.android.settings.wifi.AdvancedWifiSettings;
149 import com.android.settings.wifi.SavedAccessPointsWifiSettings;
150 import com.android.settings.wifi.WifiAPITest;
151 import com.android.settings.wifi.WifiInfo;
152 import com.android.settings.wifi.WifiSettings;
153 import com.android.settings.wifi.p2p.WifiP2pSettings;
154 import com.android.settingslib.drawer.DashboardCategory;
155 import com.android.settingslib.drawer.SettingsDrawerActivity;
156 import com.android.settingslib.drawer.Tile;
158 import java.net.URISyntaxException;
159 import java.util.ArrayList;
160 import java.util.List;
161 import java.util.Set;
163 public class SettingsActivity extends SettingsDrawerActivity
164 implements PreferenceManager.OnPreferenceTreeClickListener,
165 PreferenceFragment.OnPreferenceStartFragmentCallback,
166 ButtonBarHandler, FragmentManager.OnBackStackChangedListener,
167 SearchView.OnQueryTextListener, SearchView.OnCloseListener,
168 MenuItem.OnActionExpandListener {
170 private static final String LOG_TAG = "Settings";
172 private static final int LOADER_ID_INDEXABLE_CONTENT_MONITOR = 1;
174 // Constants for state save/restore
175 private static final String SAVE_KEY_CATEGORIES = ":settings:categories";
176 private static final String SAVE_KEY_SEARCH_MENU_EXPANDED = ":settings:search_menu_expanded";
177 private static final String SAVE_KEY_SEARCH_QUERY = ":settings:search_query";
178 private static final String SAVE_KEY_SHOW_HOME_AS_UP = ":settings:show_home_as_up";
179 private static final String SAVE_KEY_SHOW_SEARCH = ":settings:show_search";
182 * When starting this activity, the invoking Intent can contain this extra
183 * string to specify which fragment should be initially displayed.
184 * <p/>Starting from Key Lime Pie, when this argument is passed in, the activity
185 * will call isValidFragment() to confirm that the fragment class name is valid for this
188 public static final String EXTRA_SHOW_FRAGMENT = ":settings:show_fragment";
191 * When starting this activity and using {@link #EXTRA_SHOW_FRAGMENT},
192 * this extra can also be specified to supply a Bundle of arguments to pass
193 * to that fragment when it is instantiated during the initial creation
196 public static final String EXTRA_SHOW_FRAGMENT_ARGUMENTS = ":settings:show_fragment_args";
199 * Fragment "key" argument passed thru {@link #EXTRA_SHOW_FRAGMENT_ARGUMENTS}
201 public static final String EXTRA_FRAGMENT_ARG_KEY = ":settings:fragment_args_key";
203 public static final String BACK_STACK_PREFS = ":settings:prefs";
205 // extras that allow any preference activity to be launched as part of a wizard
207 // show Back and Next buttons? takes boolean parameter
208 // Back will then return RESULT_CANCELED and Next RESULT_OK
209 protected static final String EXTRA_PREFS_SHOW_BUTTON_BAR = "extra_prefs_show_button_bar";
211 // add a Skip button?
212 private static final String EXTRA_PREFS_SHOW_SKIP = "extra_prefs_show_skip";
214 // specify custom text for the Back or Next buttons, or cause a button to not appear
215 // at all by setting it to null
216 protected static final String EXTRA_PREFS_SET_NEXT_TEXT = "extra_prefs_set_next_text";
217 protected static final String EXTRA_PREFS_SET_BACK_TEXT = "extra_prefs_set_back_text";
220 * When starting this activity and using {@link #EXTRA_SHOW_FRAGMENT},
221 * those extra can also be specify to supply the title or title res id to be shown for
224 public static final String EXTRA_SHOW_FRAGMENT_TITLE = ":settings:show_fragment_title";
226 * The package name used to resolve the title resource id.
228 public static final String EXTRA_SHOW_FRAGMENT_TITLE_RES_PACKAGE_NAME =
229 ":settings:show_fragment_title_res_package_name";
230 public static final String EXTRA_SHOW_FRAGMENT_TITLE_RESID =
231 ":settings:show_fragment_title_resid";
232 public static final String EXTRA_SHOW_FRAGMENT_AS_SHORTCUT =
233 ":settings:show_fragment_as_shortcut";
235 public static final String EXTRA_SHOW_FRAGMENT_AS_SUBSETTING =
236 ":settings:show_fragment_as_subsetting";
238 public static final String EXTRA_HIDE_DRAWER = ":settings:hide_drawer";
240 public static final String META_DATA_KEY_FRAGMENT_CLASS =
241 "com.android.settings.FRAGMENT_CLASS";
243 private static final String EXTRA_UI_OPTIONS = "settings:ui_options";
245 private static final String EMPTY_QUERY = "";
247 private static final int REQUEST_SUGGESTION = 42;
249 private String mFragmentClass;
251 private CharSequence mInitialTitle;
252 private int mInitialTitleResId;
254 // Show only these settings for restricted users
255 private String[] SETTINGS_FOR_RESTRICTED = {
257 WifiSettingsActivity.class.getName(),
258 Settings.BluetoothSettingsActivity.class.getName(),
259 Settings.DataUsageSummaryActivity.class.getName(),
260 Settings.SimSettingsActivity.class.getName(),
261 Settings.WirelessSettingsActivity.class.getName(),
263 Settings.HomeSettingsActivity.class.getName(),
264 Settings.SoundSettingsActivity.class.getName(),
265 Settings.DisplaySettingsActivity.class.getName(),
266 Settings.StorageSettingsActivity.class.getName(),
267 Settings.ManageApplicationsActivity.class.getName(),
268 Settings.PowerUsageSummaryActivity.class.getName(),
269 Settings.GestureSettingsActivity.class.getName(),
271 Settings.LocationSettingsActivity.class.getName(),
272 Settings.SecuritySettingsActivity.class.getName(),
273 Settings.InputMethodAndLanguageSettingsActivity.class.getName(),
274 Settings.UserSettingsActivity.class.getName(),
275 Settings.AccountSettingsActivity.class.getName(),
277 Settings.DateTimeSettingsActivity.class.getName(),
278 Settings.DeviceInfoSettingsActivity.class.getName(),
279 Settings.AccessibilitySettingsActivity.class.getName(),
280 Settings.PrintSettingsActivity.class.getName(),
281 Settings.PaymentSettingsActivity.class.getName(),
282 Settings.EnterprisePrivacySettingsActivity.class.getName(),
286 Settings.NetworkDashboardActivity.class.getName(),
287 Settings.ConnectedDeviceDashboardActivity.class.getName(),
288 Settings.AppAndNotificationDashboardActivity.class.getName(),
289 "com.android.settings.Settings.BatteryDashboardAlias",
290 "com.android.settings.Settings.DisplayDashboardAlias",
291 "com.android.settings.Settings.SoundDashboardAlias",
292 "com.android.settings.Settings.SecurityDashboardAlias",
293 Settings.UserAndAccountDashboardActivity.class.getName(),
294 Settings.SystemDashboardActivity.class.getName(),
295 Settings.SupportDashboardActivity.class.getName(),
296 // Home page > Apps & Notifications
297 "com.android.settings.Settings.ManageApplicationsDashboardAlias",
298 "com.android.settings.Settings.PaymentSettingsDashboardAlias",
299 // Home page > Network & Internet
300 "com.android.settings.Settings.WifiDashboardAlias",
301 "com.android.settings.Settings.DataUsageDashboardAlias",
302 // Home page > Security
303 "com.android.settings.Settings.LocationDashboardAlias",
304 // Home page > System
305 Settings.LanguageAndRegionSettingsActivity.class.getName(),
306 Settings.InputAndGestureSettingsActivity.class.getName(),
307 "com.android.settings.Settings.DateTimeDashboardAlias",
308 "com.android.settings.Settings.AccessibilityDashboardAlias",
309 "com.android.settings.Settings.AboutDeviceDashboardAlias",
312 private static final String[] ENTRY_FRAGMENTS = {
313 WirelessSettings.class.getName(),
314 WifiSettings.class.getName(),
315 AdvancedWifiSettings.class.getName(),
316 SavedAccessPointsWifiSettings.class.getName(),
317 BluetoothSettings.class.getName(),
318 SimSettings.class.getName(),
319 TetherSettings.class.getName(),
320 WifiP2pSettings.class.getName(),
321 VpnSettings.class.getName(),
322 DateTimeSettings.class.getName(),
323 LocaleListEditor.class.getName(),
324 InputMethodAndLanguageSettings.class.getName(),
325 AvailableVirtualKeyboardFragment.class.getName(),
326 InputAndGestureSettings.class.getName(),
327 LanguageAndRegionSettings.class.getName(),
328 SpellCheckersSettings.class.getName(),
329 UserDictionaryList.class.getName(),
330 UserDictionarySettings.class.getName(),
331 HomeSettings.class.getName(),
332 DisplaySettings.class.getName(),
333 DeviceInfoSettings.class.getName(),
334 ManageApplications.class.getName(),
335 NotificationApps.class.getName(),
336 ManageAssist.class.getName(),
337 ProcessStatsUi.class.getName(),
338 NotificationStation.class.getName(),
339 LocationSettings.class.getName(),
340 SecuritySettings.class.getName(),
341 UsageAccessDetails.class.getName(),
342 PrivacySettings.class.getName(),
343 DeviceAdminSettings.class.getName(),
344 AccessibilitySettings.class.getName(),
345 AccessibilitySettingsForSetupWizard.class.getName(),
346 CaptionPropertiesFragment.class.getName(),
347 ToggleDaltonizerPreferenceFragment.class.getName(),
348 TextToSpeechSettings.class.getName(),
349 StorageSettings.class.getName(),
350 PrivateVolumeForget.class.getName(),
351 PrivateVolumeSettings.class.getName(),
352 PublicVolumeSettings.class.getName(),
353 DevelopmentSettings.class.getName(),
354 AndroidBeam.class.getName(),
355 WifiDisplaySettings.class.getName(),
356 PowerUsageSummary.class.getName(),
357 AccountSyncSettings.class.getName(),
358 AccountSettings.class.getName(),
359 GestureSettings.class.getName(),
360 SwipeToNotificationSettings.class.getName(),
361 DoubleTapPowerSettings.class.getName(),
362 DoubleTapScreenSettings.class.getName(),
363 PickupGestureSettings.class.getName(),
364 DoubleTwistGestureSettings.class.getName(),
365 CryptKeeperSettings.class.getName(),
366 DataUsageSummary.class.getName(),
367 DreamSettings.class.getName(),
368 UserSettings.class.getName(),
369 NotificationAccessSettings.class.getName(),
370 ZenAccessSettings.class.getName(),
371 PrintSettingsFragment.class.getName(),
372 PrintJobSettingsFragment.class.getName(),
373 TrustedCredentialsSettings.class.getName(),
374 PaymentSettings.class.getName(),
375 KeyboardLayoutPickerFragment.class.getName(),
376 PhysicalKeyboardFragment.class.getName(),
377 ZenModeSettings.class.getName(),
378 SoundSettings.class.getName(),
379 ConfigureNotificationSettings.class.getName(),
380 ChooseLockPassword.ChooseLockPasswordFragment.class.getName(),
381 ChooseLockPattern.ChooseLockPatternFragment.class.getName(),
382 InstalledAppDetails.class.getName(),
383 BatterySaverSettings.class.getName(),
384 AppNotificationSettings.class.getName(),
385 OtherSoundSettings.class.getName(),
386 ApnSettings.class.getName(),
387 ApnEditor.class.getName(),
388 WifiCallingSettings.class.getName(),
389 ZenModePrioritySettings.class.getName(),
390 ZenModeAutomationSettings.class.getName(),
391 ZenModeScheduleRuleSettings.class.getName(),
392 ZenModeEventRuleSettings.class.getName(),
393 ZenModeVisualInterruptionSettings.class.getName(),
394 ProcessStatsUi.class.getName(),
395 PowerUsageDetail.class.getName(),
396 ProcessStatsSummary.class.getName(),
397 DrawOverlayDetails.class.getName(),
398 WriteSettingsDetails.class.getName(),
399 AdvancedAppSettings.class.getName(),
400 WallpaperTypeSettings.class.getName(),
401 VrListenerSettings.class.getName(),
402 ManagedProfileSettings.class.getName(),
403 ChooseAccountActivity.class.getName(),
404 IccLockSettings.class.getName(),
405 ImeiInformation.class.getName(),
406 SimStatus.class.getName(),
407 Status.class.getName(),
408 TestingSettings.class.getName(),
409 WifiAPITest.class.getName(),
410 WifiInfo.class.getName(),
411 MasterClear.class.getName(),
412 NightDisplaySettings.class.getName(),
413 ManageDomainUrls.class.getName(),
414 AutomaticStorageManagerSettings.class.getName(),
415 SupportFragment.class.getName(),
416 StorageDashboardFragment.class.getName(),
417 SystemDashboardFragment.class.getName(),
418 NetworkDashboardFragment.class.getName(),
419 ConnectedDeviceDashboardFragment.class.getName(),
420 AppAndNotificationDashboardFragment.class.getName(),
421 UserAndAccountDashboardFragment.class.getName(),
422 EnterprisePrivacySettings.class.getName(),
426 private static final String[] LIKE_SHORTCUT_INTENT_ACTION_ARRAY = {
427 "android.settings.APPLICATION_DETAILS_SETTINGS"
430 private SharedPreferences mDevelopmentPreferences;
431 private SharedPreferences.OnSharedPreferenceChangeListener mDevelopmentPreferencesListener;
433 private boolean mBatteryPresent = true;
434 private BroadcastReceiver mBatteryInfoReceiver = new BroadcastReceiver() {
436 public void onReceive(Context context, Intent intent) {
437 String action = intent.getAction();
438 if (Intent.ACTION_BATTERY_CHANGED.equals(action)) {
439 boolean batteryPresent = Utils.isBatteryPresent(intent);
441 if (mBatteryPresent != batteryPresent) {
442 mBatteryPresent = batteryPresent;
449 private final BroadcastReceiver mUserAddRemoveReceiver = new BroadcastReceiver() {
451 public void onReceive(Context context, Intent intent) {
452 String action = intent.getAction();
453 if (action.equals(Intent.ACTION_USER_ADDED)
454 || action.equals(Intent.ACTION_USER_REMOVED)) {
455 Index.getInstance(getApplicationContext()).update();
460 private final DynamicIndexableContentMonitor mDynamicIndexableContentMonitor =
461 new DynamicIndexableContentMonitor();
463 private ActionBar mActionBar;
464 private SwitchBar mSwitchBar;
466 private Button mNextButton;
468 private boolean mDisplayHomeAsUpEnabled;
469 private boolean mDisplaySearch;
471 private boolean mIsShowingDashboard;
472 private boolean mIsShortcut;
474 private ViewGroup mContent;
476 private SearchView mSearchView;
477 private MenuItem mSearchMenuItem;
478 private boolean mSearchMenuItemExpanded = false;
479 private SearchResultsSummary mSearchResultsFragment;
480 private String mSearchQuery;
483 private ArrayList<DashboardCategory> mCategories = new ArrayList<DashboardCategory>();
485 private static final String MSG_DATA_FORCE_REFRESH = "msg_data_force_refresh";
487 private boolean mNeedToRevertToInitialFragment = false;
489 private DashboardFeatureProvider mDashboardFeatureProvider;
490 private Intent mResultIntentData;
491 private ComponentName mCurrentSuggestion;
493 public SwitchBar getSwitchBar() {
498 public boolean onPreferenceStartFragment(PreferenceFragment caller, Preference pref) {
499 startPreferencePanel(pref.getFragment(), pref.getExtras(), -1, pref.getTitle(),
505 public boolean onPreferenceTreeClick(Preference preference) {
510 public void onConfigurationChanged(Configuration newConfig) {
511 super.onConfigurationChanged(newConfig);
512 Index.getInstance(this).update();
516 protected void onStart() {
519 if (mNeedToRevertToInitialFragment) {
520 revertToInitialFragment();
525 public boolean onCreateOptionsMenu(Menu menu) {
526 if (!mDisplaySearch) {
530 MenuInflater inflater = getMenuInflater();
531 inflater.inflate(R.menu.options_menu, menu);
533 // Cache the search query (can be overriden by the OnQueryTextListener)
534 final String query = mSearchQuery;
536 mSearchMenuItem = menu.findItem(R.id.search);
537 mSearchView = (SearchView) mSearchMenuItem.getActionView();
539 if (mSearchMenuItem == null || mSearchView == null) {
543 if (mSearchResultsFragment != null) {
544 mSearchResultsFragment.setSearchView(mSearchView);
547 mSearchMenuItem.setOnActionExpandListener(this);
548 mSearchView.setMaxWidth(Integer.MAX_VALUE);
549 mSearchView.setOnQueryTextListener(this);
550 mSearchView.setOnCloseListener(this);
552 if (mSearchMenuItemExpanded) {
553 mSearchMenuItem.expandActionView();
555 mSearchView.setQuery(query, true /* submit */);
561 public SharedPreferences getSharedPreferences(String name, int mode) {
562 if (name.equals(getPackageName() + "_preferences")) {
563 return new SharedPreferencesLogger(this, getMetricsTag());
565 return super.getSharedPreferences(name, mode);
568 private String getMetricsTag() {
569 String tag = getClass().getName();
570 if (getIntent() != null && getIntent().hasExtra(EXTRA_SHOW_FRAGMENT)) {
571 tag = getIntent().getStringExtra(EXTRA_SHOW_FRAGMENT);
573 if (tag.startsWith("com.android.settings.")) {
574 tag = tag.replace("com.android.settings.", "");
579 private static boolean isShortCutIntent(final Intent intent) {
580 Set<String> categories = intent.getCategories();
581 return (categories != null) && categories.contains("com.android.settings.SHORTCUT");
584 private static boolean isLikeShortCutIntent(final Intent intent) {
585 String action = intent.getAction();
586 if (action == null) {
589 for (int i = 0; i < LIKE_SHORTCUT_INTENT_ACTION_ARRAY.length; i++) {
590 if (LIKE_SHORTCUT_INTENT_ACTION_ARRAY[i].equals(action)) return true;
596 protected void onCreate(Bundle savedState) {
597 super.onCreate(savedState);
598 long startTime = System.currentTimeMillis();
599 mDashboardFeatureProvider =
600 FeatureFactory.getFactory(this).getDashboardFeatureProvider(this);
601 // Should happen before any call to getIntent()
604 final Intent intent = getIntent();
605 if (intent.hasExtra(EXTRA_UI_OPTIONS)) {
606 getWindow().setUiOptions(intent.getIntExtra(EXTRA_UI_OPTIONS, 0));
608 if (intent.getBooleanExtra(EXTRA_HIDE_DRAWER, false)) {
609 setIsDrawerPresent(false);
612 mDevelopmentPreferences = getSharedPreferences(DevelopmentSettings.PREF_FILE,
613 Context.MODE_PRIVATE);
615 // Getting Intent properties can only be done after the super.onCreate(...)
616 final String initialFragmentName = intent.getStringExtra(EXTRA_SHOW_FRAGMENT);
618 mIsShortcut = isShortCutIntent(intent) || isLikeShortCutIntent(intent) ||
619 intent.getBooleanExtra(EXTRA_SHOW_FRAGMENT_AS_SHORTCUT, false);
621 final ComponentName cn = intent.getComponent();
622 final String className = cn.getClassName();
624 mIsShowingDashboard = className.equals(Settings.class.getName())
625 || className.equals(Settings.WirelessSettings.class.getName())
626 || className.equals(Settings.DeviceSettings.class.getName())
627 || className.equals(Settings.PersonalSettings.class.getName())
628 || className.equals(Settings.WirelessSettings.class.getName());
630 // This is a "Sub Settings" when:
631 // - this is a real SubSettings
632 // - or :settings:show_fragment_as_subsetting is passed to the Intent
633 final boolean isSubSettings = this instanceof SubSettings ||
634 intent.getBooleanExtra(EXTRA_SHOW_FRAGMENT_AS_SUBSETTING, false);
636 // If this is a sub settings, then apply the SubSettings Theme for the ActionBar content insets
638 // Check also that we are not a Theme Dialog as we don't want to override them
639 final int themeResId = getThemeResId();
640 if (themeResId != R.style.Theme_DialogWhenLarge &&
641 themeResId != R.style.Theme_SubSettingsDialogWhenLarge) {
642 setTheme(R.style.Theme_SubSettings);
646 setContentView(mIsShowingDashboard ?
647 R.layout.settings_main_dashboard : R.layout.settings_main_prefs);
649 mContent = (ViewGroup) findViewById(R.id.main_content);
651 getFragmentManager().addOnBackStackChangedListener(this);
653 if (mIsShowingDashboard) {
654 // Run the Index update only if we have some space
655 if (!Utils.isLowStorage(this)) {
656 long indexStartTime = System.currentTimeMillis();
657 Index.getInstance(getApplicationContext()).update();
658 if (DEBUG_TIMING) Log.d(LOG_TAG, "Index.update() took "
659 + (System.currentTimeMillis() - indexStartTime) + " ms");
661 Log.w(LOG_TAG, "Cannot update the Indexer as we are running low on storage space!");
665 if (savedState != null) {
666 // We are restarting from a previous saved state; used that to initialize, instead
667 // of starting fresh.
668 mSearchMenuItemExpanded = savedState.getBoolean(SAVE_KEY_SEARCH_MENU_EXPANDED);
669 mSearchQuery = savedState.getString(SAVE_KEY_SEARCH_QUERY);
670 setTitleFromIntent(intent);
672 ArrayList<DashboardCategory> categories =
673 savedState.getParcelableArrayList(SAVE_KEY_CATEGORIES);
674 if (categories != null) {
676 mCategories.addAll(categories);
677 setTitleFromBackStack();
680 mDisplayHomeAsUpEnabled = savedState.getBoolean(SAVE_KEY_SHOW_HOME_AS_UP);
681 mDisplaySearch = savedState.getBoolean(SAVE_KEY_SHOW_SEARCH);
684 if (!mIsShowingDashboard) {
685 mDisplaySearch = false;
686 // UP will be shown only if it is a sub settings
688 mDisplayHomeAsUpEnabled = isSubSettings;
689 } else if (isSubSettings) {
690 mDisplayHomeAsUpEnabled = true;
692 mDisplayHomeAsUpEnabled = false;
694 setTitleFromIntent(intent);
696 Bundle initialArguments = intent.getBundleExtra(EXTRA_SHOW_FRAGMENT_ARGUMENTS);
697 switchToFragment(initialFragmentName, initialArguments, true, false,
698 mInitialTitleResId, mInitialTitle, false);
700 // No UP affordance if we are displaying the main Dashboard
701 mDisplayHomeAsUpEnabled = false;
702 // Show Search affordance
703 mDisplaySearch = true;
704 mInitialTitleResId = R.string.dashboard_title;
706 // add argument to indicate which settings tab should be initially selected
707 final Bundle args = new Bundle();
708 final String extraName = DashboardContainerFragment.EXTRA_SELECT_SETTINGS_TAB;
709 args.putString(extraName, intent.getStringExtra(extraName));
710 if (isDashboardFeatureEnabled()) {
711 switchToFragment(DashboardSummary.class.getName(), args, false, false,
712 mInitialTitleResId, mInitialTitle, false);
714 switchToFragment(DashboardContainerFragment.class.getName(), args, false, false,
715 mInitialTitleResId, mInitialTitle, false);
720 mActionBar = getActionBar();
721 if (mActionBar != null) {
722 mActionBar.setDisplayHomeAsUpEnabled(mDisplayHomeAsUpEnabled);
723 mActionBar.setHomeButtonEnabled(mDisplayHomeAsUpEnabled);
725 mSwitchBar = (SwitchBar) findViewById(R.id.switch_bar);
726 if (mSwitchBar != null) {
727 mSwitchBar.setMetricsTag(getMetricsTag());
730 // see if we should show Back/Next buttons
731 if (intent.getBooleanExtra(EXTRA_PREFS_SHOW_BUTTON_BAR, false)) {
733 View buttonBar = findViewById(R.id.button_bar);
734 if (buttonBar != null) {
735 buttonBar.setVisibility(View.VISIBLE);
737 Button backButton = (Button)findViewById(R.id.back_button);
738 backButton.setOnClickListener(new OnClickListener() {
739 public void onClick(View v) {
740 setResult(RESULT_CANCELED, getResultIntentData());
744 Button skipButton = (Button)findViewById(R.id.skip_button);
745 skipButton.setOnClickListener(new OnClickListener() {
746 public void onClick(View v) {
747 setResult(RESULT_OK, getResultIntentData());
751 mNextButton = (Button)findViewById(R.id.next_button);
752 mNextButton.setOnClickListener(new OnClickListener() {
753 public void onClick(View v) {
754 setResult(RESULT_OK, getResultIntentData());
759 // set our various button parameters
760 if (intent.hasExtra(EXTRA_PREFS_SET_NEXT_TEXT)) {
761 String buttonText = intent.getStringExtra(EXTRA_PREFS_SET_NEXT_TEXT);
762 if (TextUtils.isEmpty(buttonText)) {
763 mNextButton.setVisibility(View.GONE);
766 mNextButton.setText(buttonText);
769 if (intent.hasExtra(EXTRA_PREFS_SET_BACK_TEXT)) {
770 String buttonText = intent.getStringExtra(EXTRA_PREFS_SET_BACK_TEXT);
771 if (TextUtils.isEmpty(buttonText)) {
772 backButton.setVisibility(View.GONE);
775 backButton.setText(buttonText);
778 if (intent.getBooleanExtra(EXTRA_PREFS_SHOW_SKIP, false)) {
779 skipButton.setVisibility(View.VISIBLE);
784 if (DEBUG_TIMING) Log.d(LOG_TAG, "onCreate took " + (System.currentTimeMillis() - startTime)
788 public void setDisplaySearchMenu(boolean displaySearch) {
789 if (displaySearch != mDisplaySearch) {
790 mDisplaySearch = displaySearch;
791 invalidateOptionsMenu();
795 private void setTitleFromIntent(Intent intent) {
796 final int initialTitleResId = intent.getIntExtra(EXTRA_SHOW_FRAGMENT_TITLE_RESID, -1);
797 if (initialTitleResId > 0) {
798 mInitialTitle = null;
799 mInitialTitleResId = initialTitleResId;
801 final String initialTitleResPackageName = intent.getStringExtra(
802 EXTRA_SHOW_FRAGMENT_TITLE_RES_PACKAGE_NAME);
803 if (initialTitleResPackageName != null) {
805 Context authContext = createPackageContextAsUser(initialTitleResPackageName,
806 0 /* flags */, new UserHandle(UserHandle.myUserId()));
807 mInitialTitle = authContext.getResources().getText(mInitialTitleResId);
808 setTitle(mInitialTitle);
809 mInitialTitleResId = -1;
811 } catch (NameNotFoundException e) {
812 Log.w(LOG_TAG, "Could not find package" + initialTitleResPackageName);
815 setTitle(mInitialTitleResId);
818 mInitialTitleResId = -1;
819 final String initialTitle = intent.getStringExtra(EXTRA_SHOW_FRAGMENT_TITLE);
820 mInitialTitle = (initialTitle != null) ? initialTitle : getTitle();
821 setTitle(mInitialTitle);
826 public void onBackStackChanged() {
827 setTitleFromBackStack();
830 private void setTitleFromBackStack() {
831 final int count = getFragmentManager().getBackStackEntryCount();
834 if (mInitialTitleResId > 0) {
835 setTitle(mInitialTitleResId);
837 setTitle(mInitialTitle);
842 FragmentManager.BackStackEntry bse = getFragmentManager().getBackStackEntryAt(count - 1);
843 setTitleFromBackStackEntry(bse);
846 private void setTitleFromBackStackEntry(FragmentManager.BackStackEntry bse) {
847 final CharSequence title;
848 final int titleRes = bse.getBreadCrumbTitleRes();
850 title = getText(titleRes);
852 title = bse.getBreadCrumbTitle();
860 protected void onSaveInstanceState(Bundle outState) {
861 super.onSaveInstanceState(outState);
863 if (mCategories.size() > 0) {
864 outState.putParcelableArrayList(SAVE_KEY_CATEGORIES, mCategories);
867 outState.putBoolean(SAVE_KEY_SHOW_HOME_AS_UP, mDisplayHomeAsUpEnabled);
868 outState.putBoolean(SAVE_KEY_SHOW_SEARCH, mDisplaySearch);
870 if (mDisplaySearch) {
871 // The option menus are created if the ActionBar is visible and they are also created
872 // asynchronously. If you launch Settings with an Intent action like
873 // android.intent.action.POWER_USAGE_SUMMARY and at the same time your device is locked
874 // thru a LockScreen, onCreateOptionsMenu() is not yet called and references to the search
875 // menu item and search view are null.
876 boolean isExpanded = (mSearchMenuItem != null) && mSearchMenuItem.isActionViewExpanded();
877 outState.putBoolean(SAVE_KEY_SEARCH_MENU_EXPANDED, isExpanded);
879 String query = (mSearchView != null) ? mSearchView.getQuery().toString() : EMPTY_QUERY;
880 outState.putString(SAVE_KEY_SEARCH_QUERY, query);
885 protected void onResume() {
888 mDevelopmentPreferencesListener = new SharedPreferences.OnSharedPreferenceChangeListener() {
890 public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
894 mDevelopmentPreferences.registerOnSharedPreferenceChangeListener(
895 mDevelopmentPreferencesListener);
897 registerReceiver(mBatteryInfoReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
898 registerReceiver(mUserAddRemoveReceiver, new IntentFilter(Intent.ACTION_USER_ADDED));
899 registerReceiver(mUserAddRemoveReceiver, new IntentFilter(Intent.ACTION_USER_REMOVED));
901 mDynamicIndexableContentMonitor.register(this, LOADER_ID_INDEXABLE_CONTENT_MONITOR);
903 if(mDisplaySearch && !TextUtils.isEmpty(mSearchQuery)) {
904 onQueryTextSubmit(mSearchQuery);
910 protected void onPause() {
912 unregisterReceiver(mBatteryInfoReceiver);
913 unregisterReceiver(mUserAddRemoveReceiver);
914 mDynamicIndexableContentMonitor.unregister();
918 public void onDestroy() {
921 mDevelopmentPreferences.unregisterOnSharedPreferenceChangeListener(
922 mDevelopmentPreferencesListener);
923 mDevelopmentPreferencesListener = null;
926 protected boolean isValidFragment(String fragmentName) {
927 // Almost all fragments are wrapped in this,
928 // except for a few that have their own activities.
929 for (int i = 0; i < ENTRY_FRAGMENTS.length; i++) {
930 if (ENTRY_FRAGMENTS[i].equals(fragmentName)) return true;
936 public Intent getIntent() {
937 Intent superIntent = super.getIntent();
938 String startingFragment = getStartingFragmentClass(superIntent);
939 // This is called from super.onCreate, isMultiPane() is not yet reliable
940 // Do not use onIsHidingHeaders either, which relies itself on this method
941 if (startingFragment != null) {
942 Intent modIntent = new Intent(superIntent);
943 modIntent.putExtra(EXTRA_SHOW_FRAGMENT, startingFragment);
944 Bundle args = superIntent.getExtras();
946 args = new Bundle(args);
950 args.putParcelable("intent", superIntent);
951 modIntent.putExtra(EXTRA_SHOW_FRAGMENT_ARGUMENTS, args);
958 * Checks if the component name in the intent is different from the Settings class and
959 * returns the class name to load as a fragment.
961 private String getStartingFragmentClass(Intent intent) {
962 if (mFragmentClass != null) return mFragmentClass;
964 String intentClass = intent.getComponent().getClassName();
965 if (intentClass.equals(getClass().getName())) return null;
967 if ("com.android.settings.ManageApplications".equals(intentClass)
968 || "com.android.settings.RunningServices".equals(intentClass)
969 || "com.android.settings.applications.StorageUse".equals(intentClass)) {
970 // Old names of manage apps.
971 intentClass = com.android.settings.applications.ManageApplications.class.getName();
978 * Start a new fragment containing a preference panel. If the preferences
979 * are being displayed in multi-pane mode, the given fragment class will
980 * be instantiated and placed in the appropriate pane. If running in
981 * single-pane mode, a new activity will be launched in which to show the
984 * @param fragmentClass Full name of the class implementing the fragment.
985 * @param args Any desired arguments to supply to the fragment.
986 * @param titleRes Optional resource identifier of the title of this
988 * @param titleText Optional text of the title of this fragment.
989 * @param resultTo Optional fragment that result data should be sent to.
990 * If non-null, resultTo.onActivityResult() will be called when this
991 * preference panel is done. The launched panel must use
992 * {@link #finishPreferencePanel(Fragment, int, Intent)} when done.
993 * @param resultRequestCode If resultTo is non-null, this is the caller's
994 * request code to be received with the result.
996 public void startPreferencePanel(String fragmentClass, Bundle args, int titleRes,
997 CharSequence titleText, Fragment resultTo, int resultRequestCode) {
1000 if (titleText != null) {
1001 title = titleText.toString();
1003 // There not much we can do in that case
1007 Utils.startWithFragment(this, fragmentClass, args, resultTo, resultRequestCode,
1008 titleRes, title, mIsShortcut);
1012 * Start a new fragment in a new activity containing a preference panel for a given user. If the
1013 * preferences are being displayed in multi-pane mode, the given fragment class will be
1014 * instantiated and placed in the appropriate pane. If running in single-pane mode, a new
1015 * activity will be launched in which to show the fragment.
1017 * @param fragmentClass Full name of the class implementing the fragment.
1018 * @param args Any desired arguments to supply to the fragment.
1019 * @param titleRes Optional resource identifier of the title of this fragment.
1020 * @param titleText Optional text of the title of this fragment.
1021 * @param userHandle The user for which the panel has to be started.
1023 public void startPreferencePanelAsUser(String fragmentClass, Bundle args, int titleRes,
1024 CharSequence titleText, UserHandle userHandle) {
1025 // This is a workaround.
1027 // Calling startWithFragmentAsUser() without specifying FLAG_ACTIVITY_NEW_TASK to the intent
1028 // starting the fragment could cause a native stack corruption. See b/17523189. However,
1029 // adding that flag and start the preference panel with the same UserHandler will make it
1030 // impossible to use back button to return to the previous screen. See b/20042570.
1032 // We work around this issue by adding FLAG_ACTIVITY_NEW_TASK to the intent, while doing
1033 // another check here to call startPreferencePanel() instead of startWithFragmentAsUser()
1034 // when we're calling it as the same user.
1035 if (userHandle.getIdentifier() == UserHandle.myUserId()) {
1036 startPreferencePanel(fragmentClass, args, titleRes, titleText, null, 0);
1038 String title = null;
1040 if (titleText != null) {
1041 title = titleText.toString();
1043 // There not much we can do in that case
1047 Utils.startWithFragmentAsUser(this, fragmentClass, args,
1048 titleRes, title, mIsShortcut, userHandle);
1053 * Called by a preference panel fragment to finish itself.
1055 * @param caller The fragment that is asking to be finished.
1056 * @param resultCode Optional result code to send back to the original
1057 * launching fragment.
1058 * @param resultData Optional result data to send back to the original
1059 * launching fragment.
1061 public void finishPreferencePanel(Fragment caller, int resultCode, Intent resultData) {
1062 setResult(resultCode, resultData);
1067 * Start a new fragment.
1069 * @param fragment The fragment to start
1070 * @param push If true, the current fragment will be pushed onto the back stack. If false,
1071 * the current fragment will be replaced.
1073 public void startPreferenceFragment(Fragment fragment, boolean push) {
1074 FragmentTransaction transaction = getFragmentManager().beginTransaction();
1075 transaction.replace(R.id.main_content, fragment);
1077 transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
1078 transaction.addToBackStack(BACK_STACK_PREFS);
1080 transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
1082 transaction.commitAllowingStateLoss();
1086 * Switch to a specific Fragment with taking care of validation, Title and BackStack
1088 private Fragment switchToFragment(String fragmentName, Bundle args, boolean validate,
1089 boolean addToBackStack, int titleResId, CharSequence title, boolean withTransition) {
1090 if (validate && !isValidFragment(fragmentName)) {
1091 throw new IllegalArgumentException("Invalid fragment for this activity: "
1094 Fragment f = Fragment.instantiate(this, fragmentName, args);
1095 FragmentTransaction transaction = getFragmentManager().beginTransaction();
1096 transaction.replace(R.id.main_content, f);
1097 if (withTransition) {
1098 TransitionManager.beginDelayedTransition(mContent);
1100 if (addToBackStack) {
1101 transaction.addToBackStack(SettingsActivity.BACK_STACK_PREFS);
1103 if (titleResId > 0) {
1104 transaction.setBreadCrumbTitle(titleResId);
1105 } else if (title != null) {
1106 transaction.setBreadCrumbTitle(title);
1108 transaction.commitAllowingStateLoss();
1109 getFragmentManager().executePendingTransactions();
1113 private void updateTilesList() {
1114 // Generally the items that are will be changing from these updates will
1115 // not be in the top list of tiles, so run it in the background and the
1116 // SettingsDrawerActivity will pick up on the updates automatically.
1117 AsyncTask.execute(new Runnable() {
1120 doUpdateTilesList();
1125 private void doUpdateTilesList() {
1126 PackageManager pm = getPackageManager();
1127 final UserManager um = UserManager.get(this);
1128 final boolean isAdmin = um.isAdminUser();
1130 String packageName = getPackageName();
1131 setTileEnabled(new ComponentName(packageName, WifiSettingsActivity.class.getName()),
1132 pm.hasSystemFeature(PackageManager.FEATURE_WIFI), isAdmin, pm);
1134 setTileEnabled(new ComponentName(packageName,
1135 Settings.BluetoothSettingsActivity.class.getName()),
1136 pm.hasSystemFeature(PackageManager.FEATURE_BLUETOOTH), isAdmin, pm);
1138 setTileEnabled(new ComponentName(packageName,
1139 Settings.DataUsageSummaryActivity.class.getName()),
1140 Utils.isBandwidthControlEnabled(), isAdmin, pm);
1142 setTileEnabled(new ComponentName(packageName,
1143 Settings.SimSettingsActivity.class.getName()),
1144 Utils.showSimCardTile(this), isAdmin, pm);
1146 setTileEnabled(new ComponentName(packageName,
1147 Settings.PowerUsageSummaryActivity.class.getName()),
1148 mBatteryPresent, isAdmin, pm);
1150 setTileEnabled(new ComponentName(packageName,
1151 Settings.UserSettingsActivity.class.getName()),
1152 UserHandle.MU_ENABLED && UserManager.supportsMultipleUsers()
1153 && !Utils.isMonkeyRunning(), isAdmin, pm);
1155 setTileEnabled(new ComponentName(packageName,
1156 Settings.WirelessSettingsActivity.class.getName()),
1157 !UserManager.isDeviceInDemoMode(this), isAdmin, pm);
1159 setTileEnabled(new ComponentName(packageName,
1160 Settings.DateTimeSettingsActivity.class.getName()),
1161 !UserManager.isDeviceInDemoMode(this), isAdmin, pm);
1162 NfcAdapter adapter = NfcAdapter.getDefaultAdapter(this);
1163 setTileEnabled(new ComponentName(packageName,
1164 Settings.PaymentSettingsActivity.class.getName()),
1165 pm.hasSystemFeature(PackageManager.FEATURE_NFC)
1166 && pm.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION)
1167 && adapter != null && adapter.isEnabled(), isAdmin, pm);
1169 setTileEnabled(new ComponentName(packageName,
1170 Settings.PrintSettingsActivity.class.getName()),
1171 pm.hasSystemFeature(PackageManager.FEATURE_PRINTING), isAdmin, pm);
1173 final boolean showDev = mDevelopmentPreferences.getBoolean(
1174 DevelopmentSettings.PREF_SHOW, android.os.Build.TYPE.equals("eng"))
1175 && !um.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES);
1176 setTileEnabled(new ComponentName(packageName,
1177 Settings.DevelopmentSettingsActivity.class.getName()),
1178 showDev, isAdmin, pm);
1179 setTileEnabled(new ComponentName(packageName,
1180 Settings.DevelopmentSettingsActivity.DASHBOARD_ALIAS),
1181 showDev, isAdmin, pm);
1183 // Reveal development-only quick settings tiles
1184 DevelopmentTiles.setTilesEnabled(this, showDev);
1186 if (UserHandle.MU_ENABLED && !isAdmin) {
1187 // When on restricted users, disable all extra categories (but only the settings ones).
1188 List<DashboardCategory> categories;
1189 if (isDashboardFeatureEnabled()) {
1190 categories = mDashboardFeatureProvider.getAllCategories();
1192 categories = getDashboardCategories();
1195 for (DashboardCategory category : categories) {
1196 for (Tile tile : category.tiles) {
1197 ComponentName component = tile.intent.getComponent();
1198 if (packageName.equals(component.getPackageName()) && !ArrayUtils.contains(
1199 SETTINGS_FOR_RESTRICTED, component.getClassName())) {
1200 setTileEnabled(component, false, isAdmin, pm);
1206 String backupIntent = getResources().getString(R.string.config_backup_settings_intent);
1207 boolean useDefaultBackup = TextUtils.isEmpty(backupIntent);
1208 setTileEnabled(new ComponentName(packageName,
1209 Settings.PrivacySettingsActivity.class.getName()), useDefaultBackup, isAdmin, pm);
1210 setTileEnabled(new ComponentName(packageName,
1211 "com.android.settings.PrivacyDashboardAlias"),
1212 useDefaultBackup, isAdmin, pm);
1214 boolean hasBackupActivity = false;
1215 if (!useDefaultBackup) {
1217 Intent intent = Intent.parseUri(backupIntent, 0);
1218 hasBackupActivity = !getPackageManager().queryIntentActivities(intent, 0).isEmpty();
1219 } catch (URISyntaxException e) {
1220 Log.e(LOG_TAG, "Invalid backup intent URI!", e);
1223 setTileEnabled(new ComponentName(packageName,
1224 BackupSettingsActivity.class.getName()), hasBackupActivity, isAdmin, pm);
1226 setTileEnabled(new ComponentName(packageName,
1227 Settings.EnterprisePrivacySettingsActivity.class.getName()),
1228 FeatureFactory.getFactory(this).getEnterprisePrivacyFeatureProvider(this)
1229 .hasDeviceOwner(), isAdmin, pm);
1233 private void setTileEnabled(ComponentName component, boolean enabled, boolean isAdmin,
1234 PackageManager pm) {
1235 if (UserHandle.MU_ENABLED && !isAdmin && getPackageName().equals(component.getPackageName())
1236 && !ArrayUtils.contains(SETTINGS_FOR_RESTRICTED, component.getClassName())) {
1239 setTileEnabled(component, enabled);
1242 private void getMetaData() {
1244 ActivityInfo ai = getPackageManager().getActivityInfo(getComponentName(),
1245 PackageManager.GET_META_DATA);
1246 if (ai == null || ai.metaData == null) return;
1247 mFragmentClass = ai.metaData.getString(META_DATA_KEY_FRAGMENT_CLASS);
1248 } catch (NameNotFoundException nnfe) {
1250 Log.d(LOG_TAG, "Cannot get Metadata for: " + getComponentName().toString());
1255 protected boolean isDashboardFeatureEnabled() {
1256 if (mDashboardFeatureProvider == null) {
1257 mDashboardFeatureProvider =
1258 FeatureFactory.getFactory(this).getDashboardFeatureProvider(this);
1260 return mDashboardFeatureProvider.isEnabled();
1263 // give subclasses access to the Next button
1264 public boolean hasNextButton() {
1265 return mNextButton != null;
1268 public Button getNextButton() {
1273 public boolean shouldUpRecreateTask(Intent targetIntent) {
1274 return super.shouldUpRecreateTask(new Intent(this, SettingsActivity.class));
1278 public boolean onQueryTextSubmit(String query) {
1279 switchToSearchResultsFragmentIfNeeded();
1280 mSearchQuery = query;
1281 return mSearchResultsFragment.onQueryTextSubmit(query);
1285 public boolean onQueryTextChange(String newText) {
1286 mSearchQuery = newText;
1287 if (mSearchResultsFragment == null) {
1290 return mSearchResultsFragment.onQueryTextChange(newText);
1294 public boolean onClose() {
1299 public boolean onMenuItemActionExpand(MenuItem item) {
1300 if (item.getItemId() == mSearchMenuItem.getItemId()) {
1301 switchToSearchResultsFragmentIfNeeded();
1307 public boolean onMenuItemActionCollapse(MenuItem item) {
1308 if (item.getItemId() == mSearchMenuItem.getItemId()) {
1309 if (mSearchMenuItemExpanded) {
1310 revertToInitialFragment();
1317 protected void onTileClicked(Tile tile) {
1318 if (mIsShowingDashboard) {
1319 // If on dashboard, don't finish so the back comes back to here.
1322 super.onTileClicked(tile);
1327 public void onProfileTileOpen() {
1328 if (!mIsShowingDashboard) {
1333 private void switchToSearchResultsFragmentIfNeeded() {
1334 if (mSearchResultsFragment != null) {
1337 Fragment current = getFragmentManager().findFragmentById(R.id.main_content);
1338 if (current != null && current instanceof SearchResultsSummary) {
1339 mSearchResultsFragment = (SearchResultsSummary) current;
1341 setContentHeaderView(null);
1342 mSearchResultsFragment = (SearchResultsSummary) switchToFragment(
1343 SearchResultsSummary.class.getName(), null, false, true,
1344 R.string.search_results_title, null, true);
1346 mSearchResultsFragment.setSearchView(mSearchView);
1347 mSearchMenuItemExpanded = true;
1350 public void needToRevertToInitialFragment() {
1351 mNeedToRevertToInitialFragment = true;
1354 private void revertToInitialFragment() {
1355 mNeedToRevertToInitialFragment = false;
1356 mSearchResultsFragment = null;
1357 mSearchMenuItemExpanded = false;
1358 getFragmentManager().popBackStackImmediate(SettingsActivity.BACK_STACK_PREFS,
1359 FragmentManager.POP_BACK_STACK_INCLUSIVE);
1360 if (mSearchMenuItem != null) {
1361 mSearchMenuItem.collapseActionView();
1365 public Intent getResultIntentData() {
1366 return mResultIntentData;
1369 public void setResultIntentData(Intent resultIntentData) {
1370 mResultIntentData = resultIntentData;
1373 public void startSuggestion(Intent intent) {
1374 if (intent == null || ActivityManager.isUserAMonkey()) {
1377 mCurrentSuggestion = intent.getComponent();
1378 startActivityForResult(intent, REQUEST_SUGGESTION);
1382 protected void onActivityResult(int requestCode, int resultCode, Intent data) {
1383 if (requestCode == REQUEST_SUGGESTION && mCurrentSuggestion != null
1384 && resultCode != RESULT_CANCELED) {
1385 getPackageManager().setComponentEnabledSetting(mCurrentSuggestion,
1386 PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
1388 super.onActivityResult(requestCode, resultCode, data);