blob: 9f8686049dbb129d7f9178890eed1422ab08915b [file] [log] [blame]
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -08001/*
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
17package com.android.settings;
18
Matthew Fritze7ac78f22016-10-03 13:26:07 -070019import android.app.ActivityManager;
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -080020import android.app.Fragment;
21import android.app.FragmentManager;
22import android.app.FragmentTransaction;
Matthew Fritze7ac78f22016-10-03 13:26:07 -070023import android.app.ActionBar;
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -080024import android.content.BroadcastReceiver;
Fabrice Di Megliod25314d2014-03-21 19:24:43 -070025import android.content.ComponentName;
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -080026import android.content.Context;
27import android.content.Intent;
28import android.content.IntentFilter;
29import android.content.SharedPreferences;
30import android.content.pm.ActivityInfo;
31import android.content.pm.PackageManager;
32import android.content.pm.PackageManager.NameNotFoundException;
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -080033import android.content.res.Configuration;
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -080034import android.nfc.NfcAdapter;
Jason Monkfd2c7222015-12-02 15:38:38 -050035import android.os.AsyncTask;
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -080036import android.os.Bundle;
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -080037import android.os.UserHandle;
38import android.os.UserManager;
Jason Monk39b46742015-09-10 15:52:51 -040039import android.support.v14.preference.PreferenceFragment;
40import android.support.v7.preference.Preference;
41import android.support.v7.preference.PreferenceManager;
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -080042import android.text.TextUtils;
Fabrice Di Meglio59a40552014-05-23 16:46:50 -070043import android.transition.TransitionManager;
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -080044import android.util.Log;
Fabrice Di Megliod25314d2014-03-21 19:24:43 -070045import android.view.Menu;
46import android.view.MenuInflater;
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -080047import android.view.MenuItem;
48import android.view.View;
49import android.view.View.OnClickListener;
Fabrice Di Meglio59a40552014-05-23 16:46:50 -070050import android.view.ViewGroup;
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -080051import android.widget.Button;
Fabrice Di Megliod25314d2014-03-21 19:24:43 -070052import android.widget.SearchView;
Fan Zhang28691572016-03-23 15:31:08 -070053
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -080054import com.android.internal.util.ArrayUtils;
Jason Monk4da79e02015-09-10 10:54:36 -040055import com.android.settings.Settings.WifiSettingsActivity;
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -080056import com.android.settings.accessibility.AccessibilitySettings;
Anna Galuszab1795f52016-01-08 14:37:16 -080057import com.android.settings.accessibility.AccessibilitySettingsForSetupWizard;
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -080058import com.android.settings.accessibility.CaptionPropertiesFragment;
Fan Zhanga96a2d82016-09-27 17:51:11 -070059import com.android.settings.accessibility.ToggleDaltonizerPreferenceFragment;
Alexandra Gherghina6d839872014-07-22 12:04:58 +000060import com.android.settings.accounts.AccountSettings;
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -080061import com.android.settings.accounts.AccountSyncSettings;
Jason Monkb7e43802016-06-06 16:01:58 -040062import com.android.settings.accounts.ChooseAccountActivity;
Tony Mak64f6d982016-05-03 18:55:41 +010063import com.android.settings.accounts.ManagedProfileSettings;
Jason Monk91e2f892016-02-23 15:31:09 -050064import com.android.settings.applications.AdvancedAppSettings;
Billy Laufee78562015-07-27 12:57:07 +010065import com.android.settings.applications.DrawOverlayDetails;
Fabrice Di Megliod25314d2014-03-21 19:24:43 -070066import com.android.settings.applications.InstalledAppDetails;
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -080067import com.android.settings.applications.ManageApplications;
Xiyuan Xia86a55402015-06-02 14:55:32 -070068import com.android.settings.applications.ManageAssist;
Todd Kennedy2ef1aa52016-09-06 14:02:38 -070069import com.android.settings.applications.ManageDomainUrls;
Jason Monka2d47fc2016-03-03 10:49:44 -050070import com.android.settings.applications.NotificationApps;
Jason Monk2cdafc62015-06-12 12:32:50 -040071import com.android.settings.applications.ProcessStatsSummary;
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -080072import com.android.settings.applications.ProcessStatsUi;
Jason Monkd8da51c2015-04-17 14:34:12 -040073import com.android.settings.applications.UsageAccessDetails;
Ruben Brunkc461d5c2016-04-07 21:45:41 -070074import com.android.settings.applications.VrListenerSettings;
Fan Zhangece8ff62016-06-30 13:20:12 -070075import com.android.settings.applications.WriteSettingsDetails;
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -080076import com.android.settings.bluetooth.BluetoothSettings;
Fan Zhang5f79ae92016-08-18 16:04:19 -070077import com.android.settings.core.instrumentation.SharedPreferencesLogger;
Fan Zhang28691572016-03-23 15:31:08 -070078import com.android.settings.dashboard.DashboardContainerFragment;
Fan Zhanga96a2d82016-09-27 17:51:11 -070079import com.android.settings.dashboard.DashboardFeatureProvider;
80import com.android.settings.dashboard.DashboardSummary;
Fabrice Di Megliod25314d2014-03-21 19:24:43 -070081import com.android.settings.dashboard.SearchResultsSummary;
Fan Zhanga96a2d82016-09-27 17:51:11 -070082import com.android.settings.dashboard.SupportFragment;
Jason Monkb37e2882016-01-11 14:27:20 -050083import com.android.settings.datausage.DataUsageSummary;
Daniel Nishi39818892016-09-20 16:40:49 -070084import com.android.settings.deletionhelper.AutomaticStorageManagerSettings;
Jason Monkb7e43802016-06-06 16:01:58 -040085import com.android.settings.deviceinfo.ImeiInformation;
Jeff Sharkeya16257d2015-04-28 13:41:01 -070086import com.android.settings.deviceinfo.PrivateVolumeForget;
Jeff Sharkeye77f0682015-04-29 11:24:57 -070087import com.android.settings.deviceinfo.PrivateVolumeSettings;
Jeff Sharkey42833b22015-04-11 21:27:33 -070088import com.android.settings.deviceinfo.PublicVolumeSettings;
Jason Monkb7e43802016-06-06 16:01:58 -040089import com.android.settings.deviceinfo.SimStatus;
90import com.android.settings.deviceinfo.Status;
Fan Zhangbb6d2602016-10-04 13:21:06 -070091import com.android.settings.deviceinfo.StorageDashboardFragment;
Jeff Sharkey42833b22015-04-11 21:27:33 -070092import com.android.settings.deviceinfo.StorageSettings;
Justin Klaasseneae3d9f2016-07-21 19:25:17 -070093import com.android.settings.display.NightDisplaySettings;
John Spurlockc7f8e8c2014-06-04 19:11:22 -040094import com.android.settings.fuelgauge.BatterySaverSettings;
Jason Monk1eb54eb2015-04-29 12:46:42 -040095import com.android.settings.fuelgauge.PowerUsageDetail;
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -080096import com.android.settings.fuelgauge.PowerUsageSummary;
Doris Ling91365232016-05-23 17:06:26 -070097import com.android.settings.gestures.GestureSettings;
Abodunrinwa Toki976bb3f2016-01-20 18:43:20 +000098import com.android.settings.inputmethod.AvailableVirtualKeyboardFragment;
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -080099import com.android.settings.inputmethod.InputMethodAndLanguageSettings;
100import com.android.settings.inputmethod.KeyboardLayoutPickerFragment;
Abodunrinwa Toki5f0b59b2016-01-25 23:02:23 +0000101import com.android.settings.inputmethod.KeyboardLayoutPickerFragment2;
Abodunrinwa Tokib28b2cc2016-03-22 16:29:38 +0000102import com.android.settings.inputmethod.PhysicalKeyboardFragment;
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -0800103import com.android.settings.inputmethod.SpellCheckersSettings;
104import com.android.settings.inputmethod.UserDictionaryList;
Mihai Nitad7d48fd2016-01-12 08:55:05 -0800105import com.android.settings.localepicker.LocaleListEditor;
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -0800106import com.android.settings.location.LocationSettings;
107import com.android.settings.nfc.AndroidBeam;
108import com.android.settings.nfc.PaymentSettings;
John Spurlock802ddf92014-07-18 11:51:13 -0400109import com.android.settings.notification.AppNotificationSettings;
Julia Reynolds8c0a4232015-11-24 10:08:14 -0500110import com.android.settings.notification.ConfigureNotificationSettings;
John Spurlock4a350512014-04-08 14:08:21 -0400111import com.android.settings.notification.NotificationAccessSettings;
John Spurlock4a350512014-04-08 14:08:21 -0400112import com.android.settings.notification.NotificationStation;
Jason Monk2ebc8a02015-02-13 15:23:19 -0500113import com.android.settings.notification.OtherSoundSettings;
Jason Monkb37e2882016-01-11 14:27:20 -0500114import com.android.settings.notification.SoundSettings;
John Spurlock08531a82015-05-07 17:45:43 -0400115import com.android.settings.notification.ZenAccessSettings;
John Spurlock533a5662015-06-19 10:47:36 -0400116import com.android.settings.notification.ZenModeAutomationSettings;
John Spurlockf57bad72015-04-30 09:26:15 -0400117import com.android.settings.notification.ZenModeEventRuleSettings;
John Spurlockc1df2aa2015-04-13 20:57:06 -0400118import com.android.settings.notification.ZenModePrioritySettings;
John Spurlock45fa1402015-04-09 12:50:04 -0400119import com.android.settings.notification.ZenModeScheduleRuleSettings;
Jason Monk39b46742015-09-10 15:52:51 -0400120import com.android.settings.notification.ZenModeSettings;
Julia Reynolds5555d262015-11-09 10:52:17 -0500121import com.android.settings.notification.ZenModeVisualInterruptionSettings;
Fan Zhanga96a2d82016-09-27 17:51:11 -0700122import com.android.settings.overlay.FeatureFactory;
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -0800123import com.android.settings.print.PrintJobSettingsFragment;
124import com.android.settings.print.PrintSettingsFragment;
Dan Sandler12c4ba42016-03-28 11:13:40 -0400125import com.android.settings.qstile.DevelopmentTiles;
Jason Monk2ebc8a02015-02-13 15:23:19 -0500126import com.android.settings.search.DynamicIndexableContentMonitor;
127import com.android.settings.search.Index;
PauloftheWest38155612014-06-30 10:02:36 -0700128import com.android.settings.sim.SimSettings;
Fan Zhangcc335d92016-09-29 14:37:14 -0700129import com.android.settings.system.SystemDashboardFragment;
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -0800130import com.android.settings.tts.TextToSpeechSettings;
131import com.android.settings.users.UserSettings;
132import com.android.settings.vpn2.VpnSettings;
133import com.android.settings.wfd.WifiDisplaySettings;
Fabrice Di Meglio41937762014-05-13 19:51:59 -0700134import com.android.settings.widget.SwitchBar;
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -0800135import com.android.settings.wifi.AdvancedWifiSettings;
PauloftheWest7837b992014-06-24 07:42:27 -0700136import com.android.settings.wifi.SavedAccessPointsWifiSettings;
Jason Monkb7e43802016-06-06 16:01:58 -0400137import com.android.settings.wifi.WifiAPITest;
138import com.android.settings.wifi.WifiInfo;
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -0800139import com.android.settings.wifi.WifiSettings;
140import com.android.settings.wifi.p2p.WifiP2pSettings;
Jason Monk4da79e02015-09-10 10:54:36 -0400141import com.android.settingslib.drawer.DashboardCategory;
Jason Monk4da79e02015-09-10 10:54:36 -0400142import com.android.settingslib.drawer.SettingsDrawerActivity;
Jason Monk7ea14c52016-01-22 14:28:02 -0500143import com.android.settingslib.drawer.Tile;
Jason Monk2ebc8a02015-02-13 15:23:19 -0500144
Doris Ling26bf0032016-06-15 18:16:09 -0700145import java.net.URISyntaxException;
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -0800146import java.util.ArrayList;
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -0800147import java.util.List;
Fabrice Di Meglio0d643fd2014-06-16 20:11:27 -0700148import java.util.Set;
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -0800149
Jason Monk4da79e02015-09-10 10:54:36 -0400150public class SettingsActivity extends SettingsDrawerActivity
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -0800151 implements PreferenceManager.OnPreferenceTreeClickListener,
152 PreferenceFragment.OnPreferenceStartFragmentCallback,
Alexandra Gherghinacfc7f9d2014-07-04 12:25:38 +0100153 ButtonBarHandler, FragmentManager.OnBackStackChangedListener,
Fabrice Di Megliod25314d2014-03-21 19:24:43 -0700154 SearchView.OnQueryTextListener, SearchView.OnCloseListener,
Alexandra Gherghinacfc7f9d2014-07-04 12:25:38 +0100155 MenuItem.OnActionExpandListener {
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -0800156
157 private static final String LOG_TAG = "Settings";
158
Philip P. Moltmannd9779db2016-02-24 12:11:05 -0800159 private static final int LOADER_ID_INDEXABLE_CONTENT_MONITOR = 1;
160
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -0800161 // Constants for state save/restore
Fabrice Di Meglio769630c2014-04-24 14:48:48 -0700162 private static final String SAVE_KEY_CATEGORIES = ":settings:categories";
Fabrice Di Megliod25314d2014-03-21 19:24:43 -0700163 private static final String SAVE_KEY_SEARCH_MENU_EXPANDED = ":settings:search_menu_expanded";
164 private static final String SAVE_KEY_SEARCH_QUERY = ":settings:search_query";
Fabrice Di Megliob731dd02014-04-03 18:40:38 -0700165 private static final String SAVE_KEY_SHOW_HOME_AS_UP = ":settings:show_home_as_up";
Fabrice Di Meglio3d35ec72014-06-06 12:13:29 -0700166 private static final String SAVE_KEY_SHOW_SEARCH = ":settings:show_search";
Fabrice Di Meglioceb335f2014-07-23 16:25:30 -0700167 private static final String SAVE_KEY_HOME_ACTIVITIES_COUNT = ":settings:home_activities_count";
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -0800168
169 /**
170 * When starting this activity, the invoking Intent can contain this extra
171 * string to specify which fragment should be initially displayed.
172 * <p/>Starting from Key Lime Pie, when this argument is passed in, the activity
173 * will call isValidFragment() to confirm that the fragment class name is valid for this
174 * activity.
175 */
176 public static final String EXTRA_SHOW_FRAGMENT = ":settings:show_fragment";
177
178 /**
179 * When starting this activity and using {@link #EXTRA_SHOW_FRAGMENT},
180 * this extra can also be specified to supply a Bundle of arguments to pass
181 * to that fragment when it is instantiated during the initial creation
182 * of the activity.
183 */
184 public static final String EXTRA_SHOW_FRAGMENT_ARGUMENTS = ":settings:show_fragment_args";
185
186 /**
Fabrice Di Meglioc1457322014-04-04 19:07:50 -0700187 * Fragment "key" argument passed thru {@link #EXTRA_SHOW_FRAGMENT_ARGUMENTS}
188 */
189 public static final String EXTRA_FRAGMENT_ARG_KEY = ":settings:fragment_args_key";
190
Fabrice Di Meglio6f0739a2014-02-03 18:12:25 -0800191 public static final String BACK_STACK_PREFS = ":settings:prefs";
192
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -0800193 // extras that allow any preference activity to be launched as part of a wizard
194
195 // show Back and Next buttons? takes boolean parameter
196 // Back will then return RESULT_CANCELED and Next RESULT_OK
197 protected static final String EXTRA_PREFS_SHOW_BUTTON_BAR = "extra_prefs_show_button_bar";
198
199 // add a Skip button?
200 private static final String EXTRA_PREFS_SHOW_SKIP = "extra_prefs_show_skip";
201
202 // specify custom text for the Back or Next buttons, or cause a button to not appear
203 // at all by setting it to null
204 protected static final String EXTRA_PREFS_SET_NEXT_TEXT = "extra_prefs_set_next_text";
205 protected static final String EXTRA_PREFS_SET_BACK_TEXT = "extra_prefs_set_back_text";
206
207 /**
208 * When starting this activity and using {@link #EXTRA_SHOW_FRAGMENT},
Fabrice Di Meglioa9e77992014-06-09 12:52:24 -0700209 * those extra can also be specify to supply the title or title res id to be shown for
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -0800210 * that fragment.
211 */
Fabrice Di Megliod25314d2014-03-21 19:24:43 -0700212 public static final String EXTRA_SHOW_FRAGMENT_TITLE = ":settings:show_fragment_title";
Alexandra Gherghina62464b82014-08-11 12:40:13 +0100213 /**
214 * The package name used to resolve the title resource id.
215 */
216 public static final String EXTRA_SHOW_FRAGMENT_TITLE_RES_PACKAGE_NAME =
217 ":settings:show_fragment_title_res_package_name";
Fabrice Di Meglio61a1fec2014-08-13 16:22:38 -0700218 public static final String EXTRA_SHOW_FRAGMENT_TITLE_RESID =
219 ":settings:show_fragment_title_resid";
220 public static final String EXTRA_SHOW_FRAGMENT_AS_SHORTCUT =
221 ":settings:show_fragment_as_shortcut";
222
223 public static final String EXTRA_SHOW_FRAGMENT_AS_SUBSETTING =
224 ":settings:show_fragment_as_subsetting";
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -0800225
Udam Saini92779ce2016-03-28 14:29:48 -0700226 public static final String EXTRA_HIDE_DRAWER = ":settings:hide_drawer";
227
Jason Monk30695812015-11-17 09:01:08 -0500228 public static final String META_DATA_KEY_FRAGMENT_CLASS =
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -0800229 "com.android.settings.FRAGMENT_CLASS";
230
231 private static final String EXTRA_UI_OPTIONS = "settings:ui_options";
232
Fabrice Di Megliod6985df2014-04-03 16:43:26 -0700233 private static final String EMPTY_QUERY = "";
234
Jason Monkd4f03ec2016-01-07 16:25:34 -0500235 private static final int REQUEST_SUGGESTION = 42;
236
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -0800237 private String mFragmentClass;
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -0800238
Fabrice Di Meglio8eb3f0f2014-02-27 15:51:46 -0800239 private CharSequence mInitialTitle;
Fabrice Di Meglioa9e77992014-06-09 12:52:24 -0700240 private int mInitialTitleResId;
Fabrice Di Meglio8eb3f0f2014-02-27 15:51:46 -0800241
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -0800242 // Show only these settings for restricted users
Jason Monk4da79e02015-09-10 10:54:36 -0400243 private String[] SETTINGS_FOR_RESTRICTED = {
244 //wireless_section
245 WifiSettingsActivity.class.getName(),
246 Settings.BluetoothSettingsActivity.class.getName(),
247 Settings.DataUsageSummaryActivity.class.getName(),
248 Settings.SimSettingsActivity.class.getName(),
249 Settings.WirelessSettingsActivity.class.getName(),
250 //device_section
251 Settings.HomeSettingsActivity.class.getName(),
Julia Reynolds8c0a4232015-11-24 10:08:14 -0500252 Settings.SoundSettingsActivity.class.getName(),
Jason Monk4da79e02015-09-10 10:54:36 -0400253 Settings.DisplaySettingsActivity.class.getName(),
254 Settings.StorageSettingsActivity.class.getName(),
255 Settings.ManageApplicationsActivity.class.getName(),
256 Settings.PowerUsageSummaryActivity.class.getName(),
Doris Ling91365232016-05-23 17:06:26 -0700257 Settings.GestureSettingsActivity.class.getName(),
Jason Monk4da79e02015-09-10 10:54:36 -0400258 //personal_section
259 Settings.LocationSettingsActivity.class.getName(),
260 Settings.SecuritySettingsActivity.class.getName(),
261 Settings.InputMethodAndLanguageSettingsActivity.class.getName(),
262 Settings.UserSettingsActivity.class.getName(),
263 Settings.AccountSettingsActivity.class.getName(),
264 //system_section
265 Settings.DateTimeSettingsActivity.class.getName(),
266 Settings.DeviceInfoSettingsActivity.class.getName(),
267 Settings.AccessibilitySettingsActivity.class.getName(),
268 Settings.PrintSettingsActivity.class.getName(),
269 Settings.PaymentSettingsActivity.class.getName(),
Fan Zhangcc335d92016-09-29 14:37:14 -0700270
271 // New IA
272 // Home page
273 "com.android.settings.Settings.BatteryDashboardAlias",
274 Settings.SystemDashboardActivity.class.getName(),
275 Settings.SupportDashboardActivity.class.getName(),
276 // Home page > System
277 "com.android.settings.Settings.LanguageAndInputDashboardAlias",
278 "com.android.settings.Settings.DateTimeDashboardAlias",
279 "com.android.settings.Settings.AccessibilityDashboardAlias",
280 "com.android.settings.Settings.AboutDeviceDashboardAlias",
281
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -0800282 };
283
284 private static final String[] ENTRY_FRAGMENTS = {
285 WirelessSettings.class.getName(),
286 WifiSettings.class.getName(),
287 AdvancedWifiSettings.class.getName(),
PauloftheWest7837b992014-06-24 07:42:27 -0700288 SavedAccessPointsWifiSettings.class.getName(),
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -0800289 BluetoothSettings.class.getName(),
PauloftheWest38155612014-06-30 10:02:36 -0700290 SimSettings.class.getName(),
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -0800291 TetherSettings.class.getName(),
292 WifiP2pSettings.class.getName(),
293 VpnSettings.class.getName(),
294 DateTimeSettings.class.getName(),
Mihai Nitad7d48fd2016-01-12 08:55:05 -0800295 LocaleListEditor.class.getName(),
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -0800296 InputMethodAndLanguageSettings.class.getName(),
Abodunrinwa Toki976bb3f2016-01-20 18:43:20 +0000297 AvailableVirtualKeyboardFragment.class.getName(),
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -0800298 SpellCheckersSettings.class.getName(),
299 UserDictionaryList.class.getName(),
300 UserDictionarySettings.class.getName(),
Amith Yamasani3033ce02014-07-14 18:03:15 -0700301 HomeSettings.class.getName(),
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -0800302 DisplaySettings.class.getName(),
303 DeviceInfoSettings.class.getName(),
304 ManageApplications.class.getName(),
Jason Monka2d47fc2016-03-03 10:49:44 -0500305 NotificationApps.class.getName(),
Xiyuan Xia86a55402015-06-02 14:55:32 -0700306 ManageAssist.class.getName(),
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -0800307 ProcessStatsUi.class.getName(),
308 NotificationStation.class.getName(),
309 LocationSettings.class.getName(),
310 SecuritySettings.class.getName(),
Jason Monkd8da51c2015-04-17 14:34:12 -0400311 UsageAccessDetails.class.getName(),
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -0800312 PrivacySettings.class.getName(),
313 DeviceAdminSettings.class.getName(),
314 AccessibilitySettings.class.getName(),
Anna Galuszab1795f52016-01-08 14:37:16 -0800315 AccessibilitySettingsForSetupWizard.class.getName(),
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -0800316 CaptionPropertiesFragment.class.getName(),
Fan Zhanga96a2d82016-09-27 17:51:11 -0700317 ToggleDaltonizerPreferenceFragment.class.getName(),
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -0800318 TextToSpeechSettings.class.getName(),
Jeff Sharkey42833b22015-04-11 21:27:33 -0700319 StorageSettings.class.getName(),
Jeff Sharkeya16257d2015-04-28 13:41:01 -0700320 PrivateVolumeForget.class.getName(),
Jeff Sharkeye77f0682015-04-29 11:24:57 -0700321 PrivateVolumeSettings.class.getName(),
322 PublicVolumeSettings.class.getName(),
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -0800323 DevelopmentSettings.class.getName(),
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -0800324 AndroidBeam.class.getName(),
325 WifiDisplaySettings.class.getName(),
326 PowerUsageSummary.class.getName(),
327 AccountSyncSettings.class.getName(),
Alexandra Gherghina6d839872014-07-22 12:04:58 +0000328 AccountSettings.class.getName(),
Doris Ling91365232016-05-23 17:06:26 -0700329 GestureSettings.class.getName(),
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -0800330 CryptKeeperSettings.class.getName(),
331 DataUsageSummary.class.getName(),
332 DreamSettings.class.getName(),
333 UserSettings.class.getName(),
334 NotificationAccessSettings.class.getName(),
John Spurlock08531a82015-05-07 17:45:43 -0400335 ZenAccessSettings.class.getName(),
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -0800336 PrintSettingsFragment.class.getName(),
337 PrintJobSettingsFragment.class.getName(),
338 TrustedCredentialsSettings.class.getName(),
339 PaymentSettings.class.getName(),
340 KeyboardLayoutPickerFragment.class.getName(),
Abodunrinwa Toki5f0b59b2016-01-25 23:02:23 +0000341 KeyboardLayoutPickerFragment2.class.getName(),
Abodunrinwa Tokib28b2cc2016-03-22 16:29:38 +0000342 PhysicalKeyboardFragment.class.getName(),
Fabrice Di Megliod25314d2014-03-21 19:24:43 -0700343 ZenModeSettings.class.getName(),
Julia Reynolds8c0a4232015-11-24 10:08:14 -0500344 SoundSettings.class.getName(),
345 ConfigureNotificationSettings.class.getName(),
Fabrice Di Megliod25314d2014-03-21 19:24:43 -0700346 ChooseLockPassword.ChooseLockPasswordFragment.class.getName(),
347 ChooseLockPattern.ChooseLockPatternFragment.class.getName(),
John Spurlockc7f8e8c2014-06-04 19:11:22 -0400348 InstalledAppDetails.class.getName(),
349 BatterySaverSettings.class.getName(),
Fabrice Di Megliodcf59dd2014-07-21 11:22:20 -0700350 AppNotificationSettings.class.getName(),
Fabrice Di Meglioe3ff4d82014-07-23 20:03:20 -0700351 OtherSoundSettings.class.getName(),
Narayan Kamath33acb152015-03-16 12:48:05 +0000352 ApnSettings.class.getName(),
Jason Monkb7e43802016-06-06 16:01:58 -0400353 ApnEditor.class.getName(),
John Spurlock45fa1402015-04-09 12:50:04 -0400354 WifiCallingSettings.class.getName(),
John Spurlockc1df2aa2015-04-13 20:57:06 -0400355 ZenModePrioritySettings.class.getName(),
John Spurlock533a5662015-06-19 10:47:36 -0400356 ZenModeAutomationSettings.class.getName(),
John Spurlock45fa1402015-04-09 12:50:04 -0400357 ZenModeScheduleRuleSettings.class.getName(),
John Spurlockf57bad72015-04-30 09:26:15 -0400358 ZenModeEventRuleSettings.class.getName(),
Julia Reynolds5555d262015-11-09 10:52:17 -0500359 ZenModeVisualInterruptionSettings.class.getName(),
Jason Monk2583fc12015-03-25 09:46:30 -0400360 ProcessStatsUi.class.getName(),
Jason Monk1eb54eb2015-04-29 12:46:42 -0400361 PowerUsageDetail.class.getName(),
Jason Monk2cdafc62015-06-12 12:32:50 -0400362 ProcessStatsSummary.class.getName(),
Billy Laufee78562015-07-27 12:57:07 +0100363 DrawOverlayDetails.class.getName(),
364 WriteSettingsDetails.class.getName(),
Jason Monk91e2f892016-02-23 15:31:09 -0500365 AdvancedAppSettings.class.getName(),
Jason Monkb9e5d232016-01-26 17:43:57 -0500366 WallpaperTypeSettings.class.getName(),
Ruben Brunkc461d5c2016-04-07 21:45:41 -0700367 VrListenerSettings.class.getName(),
Tony Mak64f6d982016-05-03 18:55:41 +0100368 ManagedProfileSettings.class.getName(),
Jason Monkb7e43802016-06-06 16:01:58 -0400369 ChooseAccountActivity.class.getName(),
370 IccLockSettings.class.getName(),
371 ImeiInformation.class.getName(),
372 SimStatus.class.getName(),
373 Status.class.getName(),
374 TestingSettings.class.getName(),
375 WifiAPITest.class.getName(),
376 WifiInfo.class.getName(),
Doris Ling7d73a292016-06-21 18:08:22 -0700377 MasterClear.class.getName(),
Justin Klaasseneae3d9f2016-07-21 19:25:17 -0700378 NightDisplaySettings.class.getName(),
Todd Kennedy2ef1aa52016-09-06 14:02:38 -0700379 ManageDomainUrls.class.getName(),
Fan Zhanga96a2d82016-09-27 17:51:11 -0700380 AutomaticStorageManagerSettings.class.getName(),
Fan Zhangcc335d92016-09-29 14:37:14 -0700381 SupportFragment.class.getName(),
Fan Zhangbb6d2602016-10-04 13:21:06 -0700382 StorageDashboardFragment.class.getName(),
Fan Zhangcc335d92016-09-29 14:37:14 -0700383 SystemDashboardFragment.class.getName(),
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -0800384 };
385
Fabrice Di Meglio5a62d942014-07-01 17:18:40 -0700386
387 private static final String[] LIKE_SHORTCUT_INTENT_ACTION_ARRAY = {
388 "android.settings.APPLICATION_DETAILS_SETTINGS"
389 };
390
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -0800391 private SharedPreferences mDevelopmentPreferences;
392 private SharedPreferences.OnSharedPreferenceChangeListener mDevelopmentPreferencesListener;
393
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -0800394 private boolean mBatteryPresent = true;
395 private BroadcastReceiver mBatteryInfoReceiver = new BroadcastReceiver() {
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -0800396 @Override
397 public void onReceive(Context context, Intent intent) {
398 String action = intent.getAction();
399 if (Intent.ACTION_BATTERY_CHANGED.equals(action)) {
400 boolean batteryPresent = Utils.isBatteryPresent(intent);
401
402 if (mBatteryPresent != batteryPresent) {
403 mBatteryPresent = batteryPresent;
Jason Monk4da79e02015-09-10 10:54:36 -0400404 updateTilesList();
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -0800405 }
406 }
407 }
408 };
409
Clara Bayarri6934a042015-10-14 11:07:35 +0100410 private final BroadcastReceiver mUserAddRemoveReceiver = new BroadcastReceiver() {
411 @Override
412 public void onReceive(Context context, Intent intent) {
413 String action = intent.getAction();
414 if (action.equals(Intent.ACTION_USER_ADDED)
415 || action.equals(Intent.ACTION_USER_REMOVED)) {
416 Index.getInstance(getApplicationContext()).update();
417 }
418 }
419 };
420
Svetoslav990159a2014-04-14 17:14:59 -0700421 private final DynamicIndexableContentMonitor mDynamicIndexableContentMonitor =
422 new DynamicIndexableContentMonitor();
Svetoslav853e4712014-04-14 10:10:25 -0700423
Fabrice Di Megliod25314d2014-03-21 19:24:43 -0700424 private ActionBar mActionBar;
Fabrice Di Meglio41937762014-05-13 19:51:59 -0700425 private SwitchBar mSwitchBar;
426
427 private Button mNextButton;
Fabrice Di Meglio3d35ec72014-06-06 12:13:29 -0700428
Fabrice Di Megliob731dd02014-04-03 18:40:38 -0700429 private boolean mDisplayHomeAsUpEnabled;
Fabrice Di Meglio3d35ec72014-06-06 12:13:29 -0700430 private boolean mDisplaySearch;
Fabrice Di Megliod25314d2014-03-21 19:24:43 -0700431
Fabrice Di Meglio35062d62014-05-13 14:39:41 -0700432 private boolean mIsShowingDashboard;
Fabrice Di Meglio0d643fd2014-06-16 20:11:27 -0700433 private boolean mIsShortcut;
Fabrice Di Meglio35062d62014-05-13 14:39:41 -0700434
Fabrice Di Meglio59a40552014-05-23 16:46:50 -0700435 private ViewGroup mContent;
436
Fabrice Di Megliod25314d2014-03-21 19:24:43 -0700437 private SearchView mSearchView;
438 private MenuItem mSearchMenuItem;
439 private boolean mSearchMenuItemExpanded = false;
Fabrice Di Megliod25314d2014-03-21 19:24:43 -0700440 private SearchResultsSummary mSearchResultsFragment;
441 private String mSearchQuery;
442
Fabrice Di Meglio769630c2014-04-24 14:48:48 -0700443 // Categories
444 private ArrayList<DashboardCategory> mCategories = new ArrayList<DashboardCategory>();
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -0800445
Fabrice Di Megliob0a464f2014-07-23 18:15:42 -0700446 private static final String MSG_DATA_FORCE_REFRESH = "msg_data_force_refresh";
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -0800447
Fabrice Di Megliod25314d2014-03-21 19:24:43 -0700448 private boolean mNeedToRevertToInitialFragment = false;
449
Fan Zhanga96a2d82016-09-27 17:51:11 -0700450 private DashboardFeatureProvider mDashboardFeatureProvider;
Jim Miller0698a212014-10-16 19:49:07 -0700451 private Intent mResultIntentData;
Jason Monkd4f03ec2016-01-07 16:25:34 -0500452 private ComponentName mCurrentSuggestion;
Jim Miller0698a212014-10-16 19:49:07 -0700453
Fabrice Di Meglio41937762014-05-13 19:51:59 -0700454 public SwitchBar getSwitchBar() {
455 return mSwitchBar;
456 }
457
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -0800458 @Override
459 public boolean onPreferenceStartFragment(PreferenceFragment caller, Preference pref) {
Sunny Goyal21ef89f2016-05-25 12:41:16 -0700460 startPreferencePanel(pref.getFragment(), pref.getExtras(), -1, pref.getTitle(),
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -0800461 null, 0);
462 return true;
463 }
464
465 @Override
Jason Monk39b46742015-09-10 15:52:51 -0400466 public boolean onPreferenceTreeClick(Preference preference) {
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -0800467 return false;
468 }
469
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -0800470 @Override
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -0800471 public void onConfigurationChanged(Configuration newConfig) {
472 super.onConfigurationChanged(newConfig);
Fabrice Di Meglio6f0739a2014-02-03 18:12:25 -0800473 Index.getInstance(this).update();
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -0800474 }
475
476 @Override
Fabrice Di Megliod25314d2014-03-21 19:24:43 -0700477 protected void onStart() {
478 super.onStart();
479
480 if (mNeedToRevertToInitialFragment) {
481 revertToInitialFragment();
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -0800482 }
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -0800483 }
484
485 @Override
Fabrice Di Megliod25314d2014-03-21 19:24:43 -0700486 public boolean onCreateOptionsMenu(Menu menu) {
Fabrice Di Meglio3d35ec72014-06-06 12:13:29 -0700487 if (!mDisplaySearch) {
488 return false;
489 }
490
Fabrice Di Megliod25314d2014-03-21 19:24:43 -0700491 MenuInflater inflater = getMenuInflater();
492 inflater.inflate(R.menu.options_menu, menu);
493
494 // Cache the search query (can be overriden by the OnQueryTextListener)
495 final String query = mSearchQuery;
496
Fabrice Di Meglio95937822014-03-31 19:46:42 -0700497 mSearchMenuItem = menu.findItem(R.id.search);
498 mSearchView = (SearchView) mSearchMenuItem.getActionView();
Fabrice Di Megliod25314d2014-03-21 19:24:43 -0700499
Fabrice Di Meglio23ae00c2014-04-21 12:43:20 -0700500 if (mSearchMenuItem == null || mSearchView == null) {
501 return false;
502 }
503
Fabrice Di Meglio8c3b0ce2014-05-12 18:54:32 -0700504 if (mSearchResultsFragment != null) {
505 mSearchResultsFragment.setSearchView(mSearchView);
506 }
507
Fabrice Di Meglio95937822014-03-31 19:46:42 -0700508 mSearchMenuItem.setOnActionExpandListener(this);
Fan Zhangb9239182016-08-22 13:59:59 -0700509 mSearchView.setMaxWidth(Integer.MAX_VALUE);
Fabrice Di Megliod25314d2014-03-21 19:24:43 -0700510 mSearchView.setOnQueryTextListener(this);
511 mSearchView.setOnCloseListener(this);
512
Fabrice Di Megliod25314d2014-03-21 19:24:43 -0700513 if (mSearchMenuItemExpanded) {
514 mSearchMenuItem.expandActionView();
515 }
516 mSearchView.setQuery(query, true /* submit */);
517
518 return true;
519 }
520
Jason Monk31c7c322016-01-20 14:41:52 -0500521 @Override
522 public SharedPreferences getSharedPreferences(String name, int mode) {
523 if (name.equals(getPackageName() + "_preferences")) {
Jason Monke4ebcd12016-02-21 09:37:41 -0500524 return new SharedPreferencesLogger(this, getMetricsTag());
Jason Monk31c7c322016-01-20 14:41:52 -0500525 }
526 return super.getSharedPreferences(name, mode);
527 }
528
Jason Monke4ebcd12016-02-21 09:37:41 -0500529 private String getMetricsTag() {
530 String tag = getClass().getName();
531 if (getIntent() != null && getIntent().hasExtra(EXTRA_SHOW_FRAGMENT)) {
532 tag = getIntent().getStringExtra(EXTRA_SHOW_FRAGMENT);
533 }
534 if (tag.startsWith("com.android.settings.")) {
535 tag = tag.replace("com.android.settings.", "");
536 }
537 return tag;
538 }
539
Fabrice Di Meglio0d643fd2014-06-16 20:11:27 -0700540 private static boolean isShortCutIntent(final Intent intent) {
541 Set<String> categories = intent.getCategories();
542 return (categories != null) && categories.contains("com.android.settings.SHORTCUT");
543 }
544
Fabrice Di Meglio5b3c3c02014-06-30 15:18:08 -0700545 private static boolean isLikeShortCutIntent(final Intent intent) {
Fabrice Di Meglio5b7a1002014-06-23 17:54:40 -0700546 String action = intent.getAction();
Fabrice Di Meglio5a62d942014-07-01 17:18:40 -0700547 if (action == null) {
548 return false;
549 }
550 for (int i = 0; i < LIKE_SHORTCUT_INTENT_ACTION_ARRAY.length; i++) {
551 if (LIKE_SHORTCUT_INTENT_ACTION_ARRAY[i].equals(action)) return true;
552 }
553 return false;
Fabrice Di Meglio5b7a1002014-06-23 17:54:40 -0700554 }
555
Fabrice Di Megliod25314d2014-03-21 19:24:43 -0700556 @Override
557 protected void onCreate(Bundle savedState) {
Fabrice Di Meglio0d643fd2014-06-16 20:11:27 -0700558 super.onCreate(savedState);
Jason Monkfd2c7222015-12-02 15:38:38 -0500559 long startTime = System.currentTimeMillis();
Fan Zhanga96a2d82016-09-27 17:51:11 -0700560 mDashboardFeatureProvider =
561 FeatureFactory.getFactory(this).getDashboardFeatureProvider(this);
Fabrice Di Meglio0d643fd2014-06-16 20:11:27 -0700562 // Should happen before any call to getIntent()
563 getMetaData();
564
565 final Intent intent = getIntent();
566 if (intent.hasExtra(EXTRA_UI_OPTIONS)) {
567 getWindow().setUiOptions(intent.getIntExtra(EXTRA_UI_OPTIONS, 0));
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -0800568 }
Udam Saini92779ce2016-03-28 14:29:48 -0700569 if (intent.getBooleanExtra(EXTRA_HIDE_DRAWER, false)) {
570 setIsDrawerPresent(false);
571 }
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -0800572
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -0800573 mDevelopmentPreferences = getSharedPreferences(DevelopmentSettings.PREF_FILE,
574 Context.MODE_PRIVATE);
575
Fabrice Di Meglioda8baba2014-06-10 17:12:51 -0700576 // Getting Intent properties can only be done after the super.onCreate(...)
Fabrice Di Meglio0d643fd2014-06-16 20:11:27 -0700577 final String initialFragmentName = intent.getStringExtra(EXTRA_SHOW_FRAGMENT);
Fabrice Di Meglioda8baba2014-06-10 17:12:51 -0700578
Fabrice Di Meglio5b3c3c02014-06-30 15:18:08 -0700579 mIsShortcut = isShortCutIntent(intent) || isLikeShortCutIntent(intent) ||
Fabrice Di Meglio0d643fd2014-06-16 20:11:27 -0700580 intent.getBooleanExtra(EXTRA_SHOW_FRAGMENT_AS_SHORTCUT, false);
581
Fabrice Di Meglioe817a662014-07-16 19:51:06 -0700582 final ComponentName cn = intent.getComponent();
Fabrice Di Meglio5a62d942014-07-01 17:18:40 -0700583 final String className = cn.getClassName();
Fabrice Di Meglioda8baba2014-06-10 17:12:51 -0700584
Jason Monk4da79e02015-09-10 10:54:36 -0400585 mIsShowingDashboard = className.equals(Settings.class.getName())
586 || className.equals(Settings.WirelessSettings.class.getName())
587 || className.equals(Settings.DeviceSettings.class.getName())
588 || className.equals(Settings.PersonalSettings.class.getName())
589 || className.equals(Settings.WirelessSettings.class.getName());
Fabrice Di Meglio5a62d942014-07-01 17:18:40 -0700590
Fabrice Di Meglio61a1fec2014-08-13 16:22:38 -0700591 // This is a "Sub Settings" when:
592 // - this is a real SubSettings
593 // - or :settings:show_fragment_as_subsetting is passed to the Intent
Jorim Jaggi4dfcb822015-04-29 17:21:32 -0700594 final boolean isSubSettings = this instanceof SubSettings ||
Fabrice Di Meglio61a1fec2014-08-13 16:22:38 -0700595 intent.getBooleanExtra(EXTRA_SHOW_FRAGMENT_AS_SUBSETTING, false);
596
597 // If this is a sub settings, then apply the SubSettings Theme for the ActionBar content insets
598 if (isSubSettings) {
Fabrice Di Meglio712df6c2014-07-18 17:44:37 -0700599 // Check also that we are not a Theme Dialog as we don't want to override them
600 final int themeResId = getThemeResId();
601 if (themeResId != R.style.Theme_DialogWhenLarge &&
602 themeResId != R.style.Theme_SubSettingsDialogWhenLarge) {
603 setTheme(R.style.Theme_SubSettings);
604 }
Fabrice Di Meglioda8baba2014-06-10 17:12:51 -0700605 }
606
Fabrice Di Megliod40dd452014-07-18 15:20:34 -0700607 setContentView(mIsShowingDashboard ?
608 R.layout.settings_main_dashboard : R.layout.settings_main_prefs);
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -0800609
Anna Galusza6b1e9db2016-03-30 17:25:36 -0700610 mContent = (ViewGroup) findViewById(R.id.main_content);
Fabrice Di Meglio59a40552014-05-23 16:46:50 -0700611
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -0800612 getFragmentManager().addOnBackStackChangedListener(this);
613
Fabrice Di Meglio35062d62014-05-13 14:39:41 -0700614 if (mIsShowingDashboard) {
Fabrice Di Megliodff3faa2015-02-27 11:14:11 -0800615 // Run the Index update only if we have some space
616 if (!Utils.isLowStorage(this)) {
Jason Monkfd2c7222015-12-02 15:38:38 -0500617 long indexStartTime = System.currentTimeMillis();
Jason Monk6c9e8842016-04-14 14:34:16 -0400618 Index.getInstance(getApplicationContext()).update();
Jason Monkfd2c7222015-12-02 15:38:38 -0500619 if (DEBUG_TIMING) Log.d(LOG_TAG, "Index.update() took "
620 + (System.currentTimeMillis() - indexStartTime) + " ms");
Fabrice Di Megliodff3faa2015-02-27 11:14:11 -0800621 } else {
622 Log.w(LOG_TAG, "Cannot update the Indexer as we are running low on storage space!");
623 }
Fabrice Di Meglio5cda21b2014-04-21 10:14:28 -0700624 }
625
Fabrice Di Megliod25314d2014-03-21 19:24:43 -0700626 if (savedState != null) {
Fabrice Di Meglio1800a9f2014-04-03 19:31:07 -0700627 // We are restarting from a previous saved state; used that to initialize, instead
628 // of starting fresh.
Fabrice Di Megliod25314d2014-03-21 19:24:43 -0700629 mSearchMenuItemExpanded = savedState.getBoolean(SAVE_KEY_SEARCH_MENU_EXPANDED);
630 mSearchQuery = savedState.getString(SAVE_KEY_SEARCH_QUERY);
Fabrice Di Meglio0d643fd2014-06-16 20:11:27 -0700631 setTitleFromIntent(intent);
Fabrice Di Meglio5529d292014-02-11 19:52:28 -0800632
Fabrice Di Meglio769630c2014-04-24 14:48:48 -0700633 ArrayList<DashboardCategory> categories =
634 savedState.getParcelableArrayList(SAVE_KEY_CATEGORIES);
635 if (categories != null) {
Fabrice Di Meglio5f995722014-05-19 19:51:31 -0700636 mCategories.clear();
Fabrice Di Meglio769630c2014-04-24 14:48:48 -0700637 mCategories.addAll(categories);
Fabrice Di Megliob643cbf2014-03-10 12:18:39 -0700638 setTitleFromBackStack();
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -0800639 }
Fabrice Di Megliob731dd02014-04-03 18:40:38 -0700640
641 mDisplayHomeAsUpEnabled = savedState.getBoolean(SAVE_KEY_SHOW_HOME_AS_UP);
Fabrice Di Meglio3d35ec72014-06-06 12:13:29 -0700642 mDisplaySearch = savedState.getBoolean(SAVE_KEY_SHOW_SEARCH);
Salvador Martinez2368e542016-07-25 18:16:47 -0700643
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -0800644 } else {
Fabrice Di Meglio35062d62014-05-13 14:39:41 -0700645 if (!mIsShowingDashboard) {
Jason Monkea8b1a72015-06-02 16:46:34 -0400646 mDisplaySearch = false;
647 // UP will be shown only if it is a sub settings
Fabrice Di Meglio0d643fd2014-06-16 20:11:27 -0700648 if (mIsShortcut) {
649 mDisplayHomeAsUpEnabled = isSubSettings;
Fabrice Di Meglio5a62d942014-07-01 17:18:40 -0700650 } else if (isSubSettings) {
651 mDisplayHomeAsUpEnabled = true;
Fabrice Di Meglio61a1fec2014-08-13 16:22:38 -0700652 } else {
653 mDisplayHomeAsUpEnabled = false;
Fabrice Di Megliod25314d2014-03-21 19:24:43 -0700654 }
Fabrice Di Meglio0d643fd2014-06-16 20:11:27 -0700655 setTitleFromIntent(intent);
Fabrice Di Meglioc1457322014-04-04 19:07:50 -0700656
Fabrice Di Meglio0d643fd2014-06-16 20:11:27 -0700657 Bundle initialArguments = intent.getBundleExtra(EXTRA_SHOW_FRAGMENT_ARGUMENTS);
Fabrice Di Meglioa9e77992014-06-09 12:52:24 -0700658 switchToFragment(initialFragmentName, initialArguments, true, false,
659 mInitialTitleResId, mInitialTitle, false);
Fabrice Di Meglio10afdb82014-02-11 19:50:56 +0000660 } else {
Fabrice Di Meglio5a62d942014-07-01 17:18:40 -0700661 // No UP affordance if we are displaying the main Dashboard
Fabrice Di Megliob731dd02014-04-03 18:40:38 -0700662 mDisplayHomeAsUpEnabled = false;
Fabrice Di Meglio5a62d942014-07-01 17:18:40 -0700663 // Show Search affordance
664 mDisplaySearch = true;
Fabrice Di Meglioa9e77992014-06-09 12:52:24 -0700665 mInitialTitleResId = R.string.dashboard_title;
Salvador Martinez2368e542016-07-25 18:16:47 -0700666
667 // add argument to indicate which settings tab should be initially selected
668 final Bundle args = new Bundle();
669 final String extraName = DashboardContainerFragment.EXTRA_SELECT_SETTINGS_TAB;
670 args.putString(extraName, intent.getStringExtra(extraName));
Fan Zhanga96a2d82016-09-27 17:51:11 -0700671 if (isDashboardFeatureEnabled()) {
672 switchToFragment(DashboardSummary.class.getName(), args, false, false,
673 mInitialTitleResId, mInitialTitle, false);
674 } else {
675 switchToFragment(DashboardContainerFragment.class.getName(), args, false, false,
676 mInitialTitleResId, mInitialTitle, false);
677 }
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -0800678 }
679 }
680
Fabrice Di Megliod25314d2014-03-21 19:24:43 -0700681 mActionBar = getActionBar();
Fabrice Di Megliod8aec082014-05-20 10:49:50 -0700682 if (mActionBar != null) {
683 mActionBar.setDisplayHomeAsUpEnabled(mDisplayHomeAsUpEnabled);
684 mActionBar.setHomeButtonEnabled(mDisplayHomeAsUpEnabled);
685 }
Fabrice Di Meglio41937762014-05-13 19:51:59 -0700686 mSwitchBar = (SwitchBar) findViewById(R.id.switch_bar);
Jason Monke4ebcd12016-02-21 09:37:41 -0500687 if (mSwitchBar != null) {
688 mSwitchBar.setMetricsTag(getMetricsTag());
689 }
Fabrice Di Meglio41937762014-05-13 19:51:59 -0700690
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -0800691 // see if we should show Back/Next buttons
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -0800692 if (intent.getBooleanExtra(EXTRA_PREFS_SHOW_BUTTON_BAR, false)) {
693
Fabrice Di Megliod2b64f32014-05-20 12:55:15 -0700694 View buttonBar = findViewById(R.id.button_bar);
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -0800695 if (buttonBar != null) {
696 buttonBar.setVisibility(View.VISIBLE);
697
Fabrice Di Megliod2b64f32014-05-20 12:55:15 -0700698 Button backButton = (Button)findViewById(R.id.back_button);
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -0800699 backButton.setOnClickListener(new OnClickListener() {
700 public void onClick(View v) {
Jim Miller0698a212014-10-16 19:49:07 -0700701 setResult(RESULT_CANCELED, getResultIntentData());
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -0800702 finish();
703 }
704 });
Fabrice Di Megliod2b64f32014-05-20 12:55:15 -0700705 Button skipButton = (Button)findViewById(R.id.skip_button);
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -0800706 skipButton.setOnClickListener(new OnClickListener() {
707 public void onClick(View v) {
Jim Miller0698a212014-10-16 19:49:07 -0700708 setResult(RESULT_OK, getResultIntentData());
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -0800709 finish();
710 }
711 });
Fabrice Di Megliod2b64f32014-05-20 12:55:15 -0700712 mNextButton = (Button)findViewById(R.id.next_button);
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -0800713 mNextButton.setOnClickListener(new OnClickListener() {
714 public void onClick(View v) {
Jim Miller0698a212014-10-16 19:49:07 -0700715 setResult(RESULT_OK, getResultIntentData());
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -0800716 finish();
717 }
718 });
719
720 // set our various button parameters
721 if (intent.hasExtra(EXTRA_PREFS_SET_NEXT_TEXT)) {
722 String buttonText = intent.getStringExtra(EXTRA_PREFS_SET_NEXT_TEXT);
723 if (TextUtils.isEmpty(buttonText)) {
724 mNextButton.setVisibility(View.GONE);
725 }
726 else {
727 mNextButton.setText(buttonText);
728 }
729 }
730 if (intent.hasExtra(EXTRA_PREFS_SET_BACK_TEXT)) {
731 String buttonText = intent.getStringExtra(EXTRA_PREFS_SET_BACK_TEXT);
732 if (TextUtils.isEmpty(buttonText)) {
733 backButton.setVisibility(View.GONE);
734 }
735 else {
736 backButton.setText(buttonText);
737 }
738 }
739 if (intent.getBooleanExtra(EXTRA_PREFS_SHOW_SKIP, false)) {
740 skipButton.setVisibility(View.VISIBLE);
741 }
742 }
743 }
Fabrice Di Meglioceb335f2014-07-23 16:25:30 -0700744
Jason Monkfd2c7222015-12-02 15:38:38 -0500745 if (DEBUG_TIMING) Log.d(LOG_TAG, "onCreate took " + (System.currentTimeMillis() - startTime)
746 + " ms");
Fabrice Di Meglioceb335f2014-07-23 16:25:30 -0700747 }
748
Fan Zhangece8ff62016-06-30 13:20:12 -0700749 public void setDisplaySearchMenu(boolean displaySearch) {
750 if (displaySearch != mDisplaySearch) {
751 mDisplaySearch = displaySearch;
752 invalidateOptionsMenu();
753 }
754 }
755
Fabrice Di Meglioa9e77992014-06-09 12:52:24 -0700756 private void setTitleFromIntent(Intent intent) {
757 final int initialTitleResId = intent.getIntExtra(EXTRA_SHOW_FRAGMENT_TITLE_RESID, -1);
758 if (initialTitleResId > 0) {
759 mInitialTitle = null;
760 mInitialTitleResId = initialTitleResId;
Alexandra Gherghina62464b82014-08-11 12:40:13 +0100761
762 final String initialTitleResPackageName = intent.getStringExtra(
763 EXTRA_SHOW_FRAGMENT_TITLE_RES_PACKAGE_NAME);
764 if (initialTitleResPackageName != null) {
765 try {
766 Context authContext = createPackageContextAsUser(initialTitleResPackageName,
767 0 /* flags */, new UserHandle(UserHandle.myUserId()));
768 mInitialTitle = authContext.getResources().getText(mInitialTitleResId);
769 setTitle(mInitialTitle);
770 mInitialTitleResId = -1;
771 return;
772 } catch (NameNotFoundException e) {
773 Log.w(LOG_TAG, "Could not find package" + initialTitleResPackageName);
774 }
775 } else {
776 setTitle(mInitialTitleResId);
777 }
Fabrice Di Meglioa9e77992014-06-09 12:52:24 -0700778 } else {
779 mInitialTitleResId = -1;
780 final String initialTitle = intent.getStringExtra(EXTRA_SHOW_FRAGMENT_TITLE);
781 mInitialTitle = (initialTitle != null) ? initialTitle : getTitle();
782 setTitle(mInitialTitle);
783 }
784 }
785
Fabrice Di Meglioc95be4f2014-03-07 12:57:38 -0800786 @Override
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -0800787 public void onBackStackChanged() {
Fabrice Di Megliod25314d2014-03-21 19:24:43 -0700788 setTitleFromBackStack();
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -0800789 }
790
Fan Zhang28691572016-03-23 15:31:08 -0700791 private void setTitleFromBackStack() {
Fabrice Di Meglio8eb3f0f2014-02-27 15:51:46 -0800792 final int count = getFragmentManager().getBackStackEntryCount();
Fabrice Di Megliob643cbf2014-03-10 12:18:39 -0700793
Fabrice Di Meglio8eb3f0f2014-02-27 15:51:46 -0800794 if (count == 0) {
Fabrice Di Meglioa9e77992014-06-09 12:52:24 -0700795 if (mInitialTitleResId > 0) {
796 setTitle(mInitialTitleResId);
797 } else {
798 setTitle(mInitialTitle);
799 }
Fan Zhang28691572016-03-23 15:31:08 -0700800 return;
Fabrice Di Meglio5529d292014-02-11 19:52:28 -0800801 }
Fabrice Di Megliob643cbf2014-03-10 12:18:39 -0700802
Fabrice Di Meglio8eb3f0f2014-02-27 15:51:46 -0800803 FragmentManager.BackStackEntry bse = getFragmentManager().getBackStackEntryAt(count - 1);
804 setTitleFromBackStackEntry(bse);
805 }
806
807 private void setTitleFromBackStackEntry(FragmentManager.BackStackEntry bse) {
808 final CharSequence title;
809 final int titleRes = bse.getBreadCrumbTitleRes();
810 if (titleRes > 0) {
811 title = getText(titleRes);
812 } else {
813 title = bse.getBreadCrumbTitle();
814 }
815 if (title != null) {
816 setTitle(title);
817 }
Fabrice Di Meglio5529d292014-02-11 19:52:28 -0800818 }
819
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -0800820 @Override
821 protected void onSaveInstanceState(Bundle outState) {
822 super.onSaveInstanceState(outState);
823
Fabrice Di Meglio769630c2014-04-24 14:48:48 -0700824 if (mCategories.size() > 0) {
825 outState.putParcelableArrayList(SAVE_KEY_CATEGORIES, mCategories);
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -0800826 }
Fabrice Di Megliod6985df2014-04-03 16:43:26 -0700827
Fabrice Di Megliob731dd02014-04-03 18:40:38 -0700828 outState.putBoolean(SAVE_KEY_SHOW_HOME_AS_UP, mDisplayHomeAsUpEnabled);
Fabrice Di Meglio3d35ec72014-06-06 12:13:29 -0700829 outState.putBoolean(SAVE_KEY_SHOW_SEARCH, mDisplaySearch);
Fabrice Di Megliob731dd02014-04-03 18:40:38 -0700830
Fabrice Di Meglio3d35ec72014-06-06 12:13:29 -0700831 if (mDisplaySearch) {
832 // The option menus are created if the ActionBar is visible and they are also created
833 // asynchronously. If you launch Settings with an Intent action like
834 // android.intent.action.POWER_USAGE_SUMMARY and at the same time your device is locked
835 // thru a LockScreen, onCreateOptionsMenu() is not yet called and references to the search
836 // menu item and search view are null.
837 boolean isExpanded = (mSearchMenuItem != null) && mSearchMenuItem.isActionViewExpanded();
838 outState.putBoolean(SAVE_KEY_SEARCH_MENU_EXPANDED, isExpanded);
Fabrice Di Megliod6985df2014-04-03 16:43:26 -0700839
Fabrice Di Meglio3d35ec72014-06-06 12:13:29 -0700840 String query = (mSearchView != null) ? mSearchView.getQuery().toString() : EMPTY_QUERY;
841 outState.putString(SAVE_KEY_SEARCH_QUERY, query);
842 }
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -0800843 }
844
845 @Override
Jason Monk39b46742015-09-10 15:52:51 -0400846 protected void onResume() {
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -0800847 super.onResume();
848
849 mDevelopmentPreferencesListener = new SharedPreferences.OnSharedPreferenceChangeListener() {
850 @Override
851 public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
Jason Monk4da79e02015-09-10 10:54:36 -0400852 updateTilesList();
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -0800853 }
854 };
855 mDevelopmentPreferences.registerOnSharedPreferenceChangeListener(
856 mDevelopmentPreferencesListener);
857
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -0800858 registerReceiver(mBatteryInfoReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
Clara Bayarri6934a042015-10-14 11:07:35 +0100859 registerReceiver(mUserAddRemoveReceiver, new IntentFilter(Intent.ACTION_USER_ADDED));
860 registerReceiver(mUserAddRemoveReceiver, new IntentFilter(Intent.ACTION_USER_REMOVED));
Svetoslav853e4712014-04-14 10:10:25 -0700861
Philip P. Moltmannd9779db2016-02-24 12:11:05 -0800862 mDynamicIndexableContentMonitor.register(this, LOADER_ID_INDEXABLE_CONTENT_MONITOR);
Fabrice Di Meglioa3270762014-04-16 16:54:56 -0700863
Fabrice Di Meglio3d35ec72014-06-06 12:13:29 -0700864 if(mDisplaySearch && !TextUtils.isEmpty(mSearchQuery)) {
Fabrice Di Meglioa3270762014-04-16 16:54:56 -0700865 onQueryTextSubmit(mSearchQuery);
866 }
Jason Monk4da79e02015-09-10 10:54:36 -0400867 updateTilesList();
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -0800868 }
869
870 @Override
Jason Monk39b46742015-09-10 15:52:51 -0400871 protected void onPause() {
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -0800872 super.onPause();
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -0800873 unregisterReceiver(mBatteryInfoReceiver);
Clara Bayarri8c9521f2016-01-12 14:10:45 +0000874 unregisterReceiver(mUserAddRemoveReceiver);
Svetoslav990159a2014-04-14 17:14:59 -0700875 mDynamicIndexableContentMonitor.unregister();
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -0800876 }
877
878 @Override
879 public void onDestroy() {
880 super.onDestroy();
Fabrice Di Meglio680b0642014-05-20 15:19:29 -0700881
882 mDevelopmentPreferences.unregisterOnSharedPreferenceChangeListener(
883 mDevelopmentPreferencesListener);
884 mDevelopmentPreferencesListener = null;
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -0800885 }
886
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -0800887 protected boolean isValidFragment(String fragmentName) {
888 // Almost all fragments are wrapped in this,
889 // except for a few that have their own activities.
890 for (int i = 0; i < ENTRY_FRAGMENTS.length; i++) {
891 if (ENTRY_FRAGMENTS[i].equals(fragmentName)) return true;
892 }
893 return false;
894 }
895
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -0800896 @Override
897 public Intent getIntent() {
898 Intent superIntent = super.getIntent();
899 String startingFragment = getStartingFragmentClass(superIntent);
900 // This is called from super.onCreate, isMultiPane() is not yet reliable
901 // Do not use onIsHidingHeaders either, which relies itself on this method
902 if (startingFragment != null) {
903 Intent modIntent = new Intent(superIntent);
904 modIntent.putExtra(EXTRA_SHOW_FRAGMENT, startingFragment);
905 Bundle args = superIntent.getExtras();
906 if (args != null) {
907 args = new Bundle(args);
908 } else {
909 args = new Bundle();
910 }
911 args.putParcelable("intent", superIntent);
Kenny Guyac1e20e2014-06-24 14:34:14 +0100912 modIntent.putExtra(EXTRA_SHOW_FRAGMENT_ARGUMENTS, args);
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -0800913 return modIntent;
914 }
915 return superIntent;
916 }
917
918 /**
919 * Checks if the component name in the intent is different from the Settings class and
920 * returns the class name to load as a fragment.
921 */
922 private String getStartingFragmentClass(Intent intent) {
923 if (mFragmentClass != null) return mFragmentClass;
924
925 String intentClass = intent.getComponent().getClassName();
926 if (intentClass.equals(getClass().getName())) return null;
927
928 if ("com.android.settings.ManageApplications".equals(intentClass)
929 || "com.android.settings.RunningServices".equals(intentClass)
930 || "com.android.settings.applications.StorageUse".equals(intentClass)) {
931 // Old names of manage apps.
932 intentClass = com.android.settings.applications.ManageApplications.class.getName();
933 }
934
935 return intentClass;
936 }
937
938 /**
Fabrice Di Meglio10afdb82014-02-11 19:50:56 +0000939 * Start a new fragment containing a preference panel. If the preferences
940 * are being displayed in multi-pane mode, the given fragment class will
941 * be instantiated and placed in the appropriate pane. If running in
942 * single-pane mode, a new activity will be launched in which to show the
943 * fragment.
944 *
945 * @param fragmentClass Full name of the class implementing the fragment.
946 * @param args Any desired arguments to supply to the fragment.
947 * @param titleRes Optional resource identifier of the title of this
948 * fragment.
949 * @param titleText Optional text of the title of this fragment.
950 * @param resultTo Optional fragment that result data should be sent to.
951 * If non-null, resultTo.onActivityResult() will be called when this
952 * preference panel is done. The launched panel must use
953 * {@link #finishPreferencePanel(Fragment, int, Intent)} when done.
954 * @param resultRequestCode If resultTo is non-null, this is the caller's
Fabrice Di Meglio58146c22014-06-26 16:20:26 -0700955 * request code to be received with the result.
Fabrice Di Meglio10afdb82014-02-11 19:50:56 +0000956 */
957 public void startPreferencePanel(String fragmentClass, Bundle args, int titleRes,
Fabrice Di Megliod25314d2014-03-21 19:24:43 -0700958 CharSequence titleText, Fragment resultTo, int resultRequestCode) {
Fabrice Di Meglioa9e77992014-06-09 12:52:24 -0700959 String title = null;
960 if (titleRes < 0) {
961 if (titleText != null) {
962 title = titleText.toString();
963 } else {
964 // There not much we can do in that case
965 title = "";
966 }
Fabrice Di Meglio911fb2a2014-04-04 17:55:57 -0700967 }
Fabrice Di Meglioa9e77992014-06-09 12:52:24 -0700968 Utils.startWithFragment(this, fragmentClass, args, resultTo, resultRequestCode,
Fabrice Di Meglio0d643fd2014-06-16 20:11:27 -0700969 titleRes, title, mIsShortcut);
Fabrice Di Meglio10afdb82014-02-11 19:50:56 +0000970 }
971
972 /**
Zoltan Szatmary-Ban7a2ccf22014-09-18 10:26:11 +0100973 * Start a new fragment in a new activity containing a preference panel for a given user. If the
974 * preferences are being displayed in multi-pane mode, the given fragment class will be
975 * instantiated and placed in the appropriate pane. If running in single-pane mode, a new
976 * activity will be launched in which to show the fragment.
977 *
978 * @param fragmentClass Full name of the class implementing the fragment.
979 * @param args Any desired arguments to supply to the fragment.
980 * @param titleRes Optional resource identifier of the title of this fragment.
981 * @param titleText Optional text of the title of this fragment.
982 * @param userHandle The user for which the panel has to be started.
983 */
984 public void startPreferencePanelAsUser(String fragmentClass, Bundle args, int titleRes,
985 CharSequence titleText, UserHandle userHandle) {
Lifu Tangd0332852015-04-02 12:05:46 -0700986 // This is a workaround.
987 //
988 // Calling startWithFragmentAsUser() without specifying FLAG_ACTIVITY_NEW_TASK to the intent
989 // starting the fragment could cause a native stack corruption. See b/17523189. However,
990 // adding that flag and start the preference panel with the same UserHandler will make it
991 // impossible to use back button to return to the previous screen. See b/20042570.
992 //
993 // We work around this issue by adding FLAG_ACTIVITY_NEW_TASK to the intent, while doing
994 // another check here to call startPreferencePanel() instead of startWithFragmentAsUser()
995 // when we're calling it as the same user.
996 if (userHandle.getIdentifier() == UserHandle.myUserId()) {
997 startPreferencePanel(fragmentClass, args, titleRes, titleText, null, 0);
998 } else {
999 String title = null;
1000 if (titleRes < 0) {
1001 if (titleText != null) {
1002 title = titleText.toString();
1003 } else {
1004 // There not much we can do in that case
1005 title = "";
1006 }
Zoltan Szatmary-Ban7a2ccf22014-09-18 10:26:11 +01001007 }
Lifu Tangd0332852015-04-02 12:05:46 -07001008 Utils.startWithFragmentAsUser(this, fragmentClass, args,
1009 titleRes, title, mIsShortcut, userHandle);
Zoltan Szatmary-Ban7a2ccf22014-09-18 10:26:11 +01001010 }
Zoltan Szatmary-Ban7a2ccf22014-09-18 10:26:11 +01001011 }
1012
1013 /**
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -08001014 * Called by a preference panel fragment to finish itself.
1015 *
1016 * @param caller The fragment that is asking to be finished.
1017 * @param resultCode Optional result code to send back to the original
1018 * launching fragment.
1019 * @param resultData Optional result data to send back to the original
1020 * launching fragment.
1021 */
1022 public void finishPreferencePanel(Fragment caller, int resultCode, Intent resultData) {
1023 setResult(resultCode, resultData);
Fabrice Di Meglio58146c22014-06-26 16:20:26 -07001024 finish();
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -08001025 }
1026
1027 /**
Fabrice Di Meglio10afdb82014-02-11 19:50:56 +00001028 * Start a new fragment.
1029 *
1030 * @param fragment The fragment to start
1031 * @param push If true, the current fragment will be pushed onto the back stack. If false,
1032 * the current fragment will be replaced.
1033 */
1034 public void startPreferenceFragment(Fragment fragment, boolean push) {
1035 FragmentTransaction transaction = getFragmentManager().beginTransaction();
Anna Galusza6b1e9db2016-03-30 17:25:36 -07001036 transaction.replace(R.id.main_content, fragment);
Fabrice Di Meglio10afdb82014-02-11 19:50:56 +00001037 if (push) {
1038 transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
1039 transaction.addToBackStack(BACK_STACK_PREFS);
1040 } else {
1041 transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
1042 }
1043 transaction.commitAllowingStateLoss();
1044 }
1045
1046 /**
Fabrice Di Megliod25314d2014-03-21 19:24:43 -07001047 * Switch to a specific Fragment with taking care of validation, Title and BackStack
1048 */
1049 private Fragment switchToFragment(String fragmentName, Bundle args, boolean validate,
Fabrice Di Meglioa9e77992014-06-09 12:52:24 -07001050 boolean addToBackStack, int titleResId, CharSequence title, boolean withTransition) {
Fabrice Di Megliod25314d2014-03-21 19:24:43 -07001051 if (validate && !isValidFragment(fragmentName)) {
1052 throw new IllegalArgumentException("Invalid fragment for this activity: "
1053 + fragmentName);
1054 }
1055 Fragment f = Fragment.instantiate(this, fragmentName, args);
1056 FragmentTransaction transaction = getFragmentManager().beginTransaction();
Anna Galusza6b1e9db2016-03-30 17:25:36 -07001057 transaction.replace(R.id.main_content, f);
Fabrice Di Megliod25314d2014-03-21 19:24:43 -07001058 if (withTransition) {
Fabrice Di Meglio59a40552014-05-23 16:46:50 -07001059 TransitionManager.beginDelayedTransition(mContent);
Fabrice Di Megliod25314d2014-03-21 19:24:43 -07001060 }
1061 if (addToBackStack) {
1062 transaction.addToBackStack(SettingsActivity.BACK_STACK_PREFS);
1063 }
Fabrice Di Meglioa9e77992014-06-09 12:52:24 -07001064 if (titleResId > 0) {
1065 transaction.setBreadCrumbTitle(titleResId);
1066 } else if (title != null) {
Fabrice Di Megliod25314d2014-03-21 19:24:43 -07001067 transaction.setBreadCrumbTitle(title);
1068 }
1069 transaction.commitAllowingStateLoss();
Fabrice Di Meglio59a40552014-05-23 16:46:50 -07001070 getFragmentManager().executePendingTransactions();
Fabrice Di Megliod25314d2014-03-21 19:24:43 -07001071 return f;
1072 }
1073
Jason Monk4da79e02015-09-10 10:54:36 -04001074 private void updateTilesList() {
Jason Monkfd2c7222015-12-02 15:38:38 -05001075 // Generally the items that are will be changing from these updates will
1076 // not be in the top list of tiles, so run it in the background and the
1077 // SettingsDrawerActivity will pick up on the updates automatically.
1078 AsyncTask.execute(new Runnable() {
1079 @Override
1080 public void run() {
1081 doUpdateTilesList();
1082 }
1083 });
1084 }
1085
1086 private void doUpdateTilesList() {
Jason Monk4da79e02015-09-10 10:54:36 -04001087 PackageManager pm = getPackageManager();
Xiaohui Chen44879a32015-07-22 13:53:22 -07001088 final UserManager um = UserManager.get(this);
1089 final boolean isAdmin = um.isAdminUser();
Fabrice Di Meglio63bbb8e2014-04-23 16:44:30 -07001090
Jason Monk4da79e02015-09-10 10:54:36 -04001091 String packageName = getPackageName();
1092 setTileEnabled(new ComponentName(packageName, WifiSettingsActivity.class.getName()),
1093 pm.hasSystemFeature(PackageManager.FEATURE_WIFI), isAdmin, pm);
Fabrice Di Meglio63bbb8e2014-04-23 16:44:30 -07001094
Jason Monk4da79e02015-09-10 10:54:36 -04001095 setTileEnabled(new ComponentName(packageName,
1096 Settings.BluetoothSettingsActivity.class.getName()),
1097 pm.hasSystemFeature(PackageManager.FEATURE_BLUETOOTH), isAdmin, pm);
Fabrice Di Meglio63bbb8e2014-04-23 16:44:30 -07001098
Jason Monk4da79e02015-09-10 10:54:36 -04001099 setTileEnabled(new ComponentName(packageName,
1100 Settings.DataUsageSummaryActivity.class.getName()),
1101 Utils.isBandwidthControlEnabled(), isAdmin, pm);
Fabrice Di Meglio63bbb8e2014-04-23 16:44:30 -07001102
Jason Monk4da79e02015-09-10 10:54:36 -04001103 setTileEnabled(new ComponentName(packageName,
1104 Settings.SimSettingsActivity.class.getName()),
1105 Utils.showSimCardTile(this), isAdmin, pm);
Fabrice Di Meglio63bbb8e2014-04-23 16:44:30 -07001106
Jason Monk4da79e02015-09-10 10:54:36 -04001107 setTileEnabled(new ComponentName(packageName,
1108 Settings.PowerUsageSummaryActivity.class.getName()),
1109 mBatteryPresent, isAdmin, pm);
1110
1111 setTileEnabled(new ComponentName(packageName,
Jason Monk4da79e02015-09-10 10:54:36 -04001112 Settings.UserSettingsActivity.class.getName()),
1113 UserHandle.MU_ENABLED && UserManager.supportsMultipleUsers()
1114 && !Utils.isMonkeyRunning(), isAdmin, pm);
1115
Fyodor Kupolovca060e32016-06-24 13:01:11 -07001116 setTileEnabled(new ComponentName(packageName,
1117 Settings.WirelessSettingsActivity.class.getName()),
1118 !UserManager.isDeviceInDemoMode(this), isAdmin, pm);
1119
1120 setTileEnabled(new ComponentName(packageName,
1121 Settings.DateTimeSettingsActivity.class.getName()),
1122 !UserManager.isDeviceInDemoMode(this), isAdmin, pm);
Jason Monk4da79e02015-09-10 10:54:36 -04001123 NfcAdapter adapter = NfcAdapter.getDefaultAdapter(this);
1124 setTileEnabled(new ComponentName(packageName,
1125 Settings.PaymentSettingsActivity.class.getName()),
1126 pm.hasSystemFeature(PackageManager.FEATURE_NFC)
1127 && pm.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION)
1128 && adapter != null && adapter.isEnabled(), isAdmin, pm);
1129
1130 setTileEnabled(new ComponentName(packageName,
1131 Settings.PrintSettingsActivity.class.getName()),
1132 pm.hasSystemFeature(PackageManager.FEATURE_PRINTING), isAdmin, pm);
1133
1134 final boolean showDev = mDevelopmentPreferences.getBoolean(
Dan Sandler12c4ba42016-03-28 11:13:40 -04001135 DevelopmentSettings.PREF_SHOW, android.os.Build.TYPE.equals("eng"))
1136 && !um.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES);
Jason Monk4da79e02015-09-10 10:54:36 -04001137 setTileEnabled(new ComponentName(packageName,
1138 Settings.DevelopmentSettingsActivity.class.getName()),
Dan Sandler12c4ba42016-03-28 11:13:40 -04001139 showDev, isAdmin, pm);
Fan Zhangcc335d92016-09-29 14:37:14 -07001140 setTileEnabled(new ComponentName(packageName,
1141 Settings.DevelopmentSettingsActivity.DASHBOARD_ALIAS),
1142 showDev, isAdmin, pm);
Dan Sandler12c4ba42016-03-28 11:13:40 -04001143
1144 // Reveal development-only quick settings tiles
1145 DevelopmentTiles.setTilesEnabled(this, showDev);
Jason Monk4da79e02015-09-10 10:54:36 -04001146
1147 if (UserHandle.MU_ENABLED && !isAdmin) {
1148 // When on restricted users, disable all extra categories (but only the settings ones).
Fan Zhanga96a2d82016-09-27 17:51:11 -07001149 List<DashboardCategory> categories;
1150 if (isDashboardFeatureEnabled()) {
1151 categories = mDashboardFeatureProvider.getAllCategories();
1152 } else {
1153 categories = getDashboardCategories();
1154 }
1155
Jason Monk4da79e02015-09-10 10:54:36 -04001156 for (DashboardCategory category : categories) {
Jason Monkd4f03ec2016-01-07 16:25:34 -05001157 for (Tile tile : category.tiles) {
Jason Monk4da79e02015-09-10 10:54:36 -04001158 ComponentName component = tile.intent.getComponent();
Jason Monk5862c1e2016-06-07 14:02:33 -04001159 if (packageName.equals(component.getPackageName()) && !ArrayUtils.contains(
Jason Monk4da79e02015-09-10 10:54:36 -04001160 SETTINGS_FOR_RESTRICTED, component.getClassName())) {
1161 setTileEnabled(component, false, isAdmin, pm);
Fabrice Di Meglio63bbb8e2014-04-23 16:44:30 -07001162 }
Fabrice Di Meglio63bbb8e2014-04-23 16:44:30 -07001163 }
Fabrice Di Meglio63bbb8e2014-04-23 16:44:30 -07001164 }
1165 }
Doris Ling26bf0032016-06-15 18:16:09 -07001166
1167 String backupIntent = getResources().getString(R.string.config_backup_settings_intent);
1168 boolean useDefaultBackup = TextUtils.isEmpty(backupIntent);
1169 setTileEnabled(new ComponentName(packageName,
1170 Settings.PrivacySettingsActivity.class.getName()), useDefaultBackup, isAdmin, pm);
1171 boolean hasBackupActivity = false;
1172 if (!useDefaultBackup) {
1173 try {
1174 Intent intent = Intent.parseUri(backupIntent, 0);
1175 hasBackupActivity = !getPackageManager().queryIntentActivities(intent, 0).isEmpty();
1176 } catch (URISyntaxException e) {
1177 Log.e(LOG_TAG, "Invalid backup intent URI!", e);
1178 }
1179 }
1180 setTileEnabled(new ComponentName(packageName,
1181 BackupSettingsActivity.class.getName()), hasBackupActivity, isAdmin, pm);
1182
Jason Monk2ebc8a02015-02-13 15:23:19 -05001183 }
1184
Jason Monk4da79e02015-09-10 10:54:36 -04001185 private void setTileEnabled(ComponentName component, boolean enabled, boolean isAdmin,
1186 PackageManager pm) {
Jason Monk5862c1e2016-06-07 14:02:33 -04001187 if (UserHandle.MU_ENABLED && !isAdmin && getPackageName().equals(component.getPackageName())
Jason Monk4da79e02015-09-10 10:54:36 -04001188 && !ArrayUtils.contains(SETTINGS_FOR_RESTRICTED, component.getClassName())) {
1189 enabled = false;
1190 }
Jason Monk5862c1e2016-06-07 14:02:33 -04001191 setTileEnabled(component, enabled);
Jason Monk2ebc8a02015-02-13 15:23:19 -05001192 }
1193
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -08001194 private void getMetaData() {
1195 try {
1196 ActivityInfo ai = getPackageManager().getActivityInfo(getComponentName(),
1197 PackageManager.GET_META_DATA);
1198 if (ai == null || ai.metaData == null) return;
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -08001199 mFragmentClass = ai.metaData.getString(META_DATA_KEY_FRAGMENT_CLASS);
1200 } catch (NameNotFoundException nnfe) {
1201 // No recovery
1202 Log.d(LOG_TAG, "Cannot get Metadata for: " + getComponentName().toString());
1203 }
1204 }
1205
Fan Zhanga96a2d82016-09-27 17:51:11 -07001206 @Override
1207 protected boolean isDashboardFeatureEnabled() {
1208 if (mDashboardFeatureProvider == null) {
1209 mDashboardFeatureProvider =
1210 FeatureFactory.getFactory(this).getDashboardFeatureProvider(this);
1211 }
1212 return mDashboardFeatureProvider.isEnabled();
1213 }
1214
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -08001215 // give subclasses access to the Next button
1216 public boolean hasNextButton() {
1217 return mNextButton != null;
1218 }
1219
1220 public Button getNextButton() {
1221 return mNextButton;
1222 }
1223
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -08001224 @Override
1225 public boolean shouldUpRecreateTask(Intent targetIntent) {
1226 return super.shouldUpRecreateTask(new Intent(this, SettingsActivity.class));
1227 }
1228
Fabrice Di Megliod25314d2014-03-21 19:24:43 -07001229 @Override
1230 public boolean onQueryTextSubmit(String query) {
1231 switchToSearchResultsFragmentIfNeeded();
1232 mSearchQuery = query;
1233 return mSearchResultsFragment.onQueryTextSubmit(query);
1234 }
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -08001235
Fabrice Di Megliod25314d2014-03-21 19:24:43 -07001236 @Override
1237 public boolean onQueryTextChange(String newText) {
1238 mSearchQuery = newText;
Fabrice Di Meglio7e4855e2014-05-23 16:03:43 -07001239 if (mSearchResultsFragment == null) {
Fabrice Di Meglioa3270762014-04-16 16:54:56 -07001240 return false;
1241 }
1242 return mSearchResultsFragment.onQueryTextChange(newText);
Fabrice Di Megliod25314d2014-03-21 19:24:43 -07001243 }
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -08001244
Fabrice Di Megliod25314d2014-03-21 19:24:43 -07001245 @Override
1246 public boolean onClose() {
1247 return false;
1248 }
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -08001249
Fabrice Di Megliod25314d2014-03-21 19:24:43 -07001250 @Override
1251 public boolean onMenuItemActionExpand(MenuItem item) {
1252 if (item.getItemId() == mSearchMenuItem.getItemId()) {
Fabrice Di Megliobb16fd82014-04-04 14:48:05 -07001253 switchToSearchResultsFragmentIfNeeded();
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -08001254 }
Fabrice Di Megliod25314d2014-03-21 19:24:43 -07001255 return true;
1256 }
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -08001257
Fabrice Di Megliod25314d2014-03-21 19:24:43 -07001258 @Override
1259 public boolean onMenuItemActionCollapse(MenuItem item) {
1260 if (item.getItemId() == mSearchMenuItem.getItemId()) {
Fabrice Di Megliobb16fd82014-04-04 14:48:05 -07001261 if (mSearchMenuItemExpanded) {
Fabrice Di Megliod25314d2014-03-21 19:24:43 -07001262 revertToInitialFragment();
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -08001263 }
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -08001264 }
Fabrice Di Megliod25314d2014-03-21 19:24:43 -07001265 return true;
1266 }
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -08001267
Jason Monk4da79e02015-09-10 10:54:36 -04001268 @Override
Jason Monkd4f03ec2016-01-07 16:25:34 -05001269 protected void onTileClicked(Tile tile) {
Jason Monk4da79e02015-09-10 10:54:36 -04001270 if (mIsShowingDashboard) {
1271 // If on dashboard, don't finish so the back comes back to here.
1272 openTile(tile);
1273 } else {
1274 super.onTileClicked(tile);
1275 }
1276 }
1277
Jason Monkaf001092015-11-04 13:16:18 -05001278 @Override
1279 public void onProfileTileOpen() {
1280 if (!mIsShowingDashboard) {
1281 finish();
1282 }
1283 }
1284
Fabrice Di Megliod25314d2014-03-21 19:24:43 -07001285 private void switchToSearchResultsFragmentIfNeeded() {
Fabrice Di Megliobb16fd82014-04-04 14:48:05 -07001286 if (mSearchResultsFragment != null) {
1287 return;
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -08001288 }
Anna Galusza6b1e9db2016-03-30 17:25:36 -07001289 Fragment current = getFragmentManager().findFragmentById(R.id.main_content);
Fabrice Di Megliobb16fd82014-04-04 14:48:05 -07001290 if (current != null && current instanceof SearchResultsSummary) {
1291 mSearchResultsFragment = (SearchResultsSummary) current;
1292 } else {
Fan Zhang28691572016-03-23 15:31:08 -07001293 setContentHeaderView(null);
Fabrice Di Megliobb16fd82014-04-04 14:48:05 -07001294 mSearchResultsFragment = (SearchResultsSummary) switchToFragment(
Fabrice Di Meglioa9e77992014-06-09 12:52:24 -07001295 SearchResultsSummary.class.getName(), null, false, true,
1296 R.string.search_results_title, null, true);
Fabrice Di Megliobb16fd82014-04-04 14:48:05 -07001297 }
Fabrice Di Megliod297a582014-04-22 17:23:23 -07001298 mSearchResultsFragment.setSearchView(mSearchView);
Fabrice Di Megliobb16fd82014-04-04 14:48:05 -07001299 mSearchMenuItemExpanded = true;
Fabrice Di Megliod25314d2014-03-21 19:24:43 -07001300 }
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -08001301
Fabrice Di Megliod25314d2014-03-21 19:24:43 -07001302 public void needToRevertToInitialFragment() {
1303 mNeedToRevertToInitialFragment = true;
1304 }
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -08001305
Fabrice Di Megliod25314d2014-03-21 19:24:43 -07001306 private void revertToInitialFragment() {
1307 mNeedToRevertToInitialFragment = false;
Fabrice Di Megliod25314d2014-03-21 19:24:43 -07001308 mSearchResultsFragment = null;
Fabrice Di Megliobb16fd82014-04-04 14:48:05 -07001309 mSearchMenuItemExpanded = false;
1310 getFragmentManager().popBackStackImmediate(SettingsActivity.BACK_STACK_PREFS,
1311 FragmentManager.POP_BACK_STACK_INCLUSIVE);
Fabrice Di Meglio23ae00c2014-04-21 12:43:20 -07001312 if (mSearchMenuItem != null) {
1313 mSearchMenuItem.collapseActionView();
1314 }
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -08001315 }
Jim Miller0698a212014-10-16 19:49:07 -07001316
1317 public Intent getResultIntentData() {
1318 return mResultIntentData;
1319 }
1320
1321 public void setResultIntentData(Intent resultIntentData) {
1322 mResultIntentData = resultIntentData;
1323 }
Jason Monkd4f03ec2016-01-07 16:25:34 -05001324
1325 public void startSuggestion(Intent intent) {
Matthew Fritze7ac78f22016-10-03 13:26:07 -07001326 if (intent == null || ActivityManager.isUserAMonkey()) {
Matthew Fritze703dc602016-09-30 12:36:27 -07001327 return;
1328 }
Matthew Fritzef265dbc2016-10-04 13:39:27 -07001329 mCurrentSuggestion = intent.getComponent();
Jason Monkd4f03ec2016-01-07 16:25:34 -05001330 startActivityForResult(intent, REQUEST_SUGGESTION);
1331 }
1332
1333 @Override
1334 protected void onActivityResult(int requestCode, int resultCode, Intent data) {
1335 if (requestCode == REQUEST_SUGGESTION && mCurrentSuggestion != null
1336 && resultCode != RESULT_CANCELED) {
1337 getPackageManager().setComponentEnabledSetting(mCurrentSuggestion,
1338 PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
1339 }
1340 super.onActivityResult(requestCode, resultCode, data);
1341 }
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -08001342}