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