blob: e90b1cd168ba1eb428456ee6f3108cde8983b24a [file] [log] [blame]
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -08001/*
2 * Copyright (C) 2008 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
Amith Yamasani56821db2012-06-05 13:20:45 -070019import android.accounts.Account;
20import android.accounts.AccountManager;
21import android.accounts.OnAccountsUpdateListener;
Jaewan Kima3fe77b2013-06-04 21:17:40 +090022import android.content.BroadcastReceiver;
Amith Yamasanic9fdfa82010-12-14 14:38:16 -080023import android.content.ComponentName;
Gilles Debunnee78c1872011-06-20 15:00:07 -070024import android.content.Context;
Amith Yamasani379d9b02010-09-27 12:03:59 -070025import android.content.Intent;
Jaewan Kima3fe77b2013-06-04 21:17:40 +090026import android.content.IntentFilter;
Amith Yamasani233592b2013-03-01 17:05:23 -080027import android.content.RestrictionEntry;
Dianne Hackborncaefa9b2012-10-10 15:05:42 -070028import android.content.SharedPreferences;
Amith Yamasani5203bdf2010-11-04 09:59:44 -070029import android.content.pm.ActivityInfo;
30import android.content.pm.PackageManager;
31import android.content.pm.PackageManager.NameNotFoundException;
Amith Yamasanid1ab8282012-05-18 09:50:08 -070032import android.graphics.drawable.Drawable;
Dianne Hackbornf4eb85b2010-10-29 16:53:04 -070033import android.os.Bundle;
Jeff Sharkey34e964d2012-04-21 15:41:48 -070034import android.os.INetworkManagementService;
35import android.os.RemoteException;
36import android.os.ServiceManager;
Dianne Hackbornbb06a422012-08-16 11:01:57 -070037import android.os.UserHandle;
Jeff Sharkey44202462012-09-19 13:13:45 -070038import android.os.UserManager;
Amith Yamasania4379d62011-07-22 10:34:58 -070039import android.preference.Preference;
Amith Yamasani02cf71a2010-09-21 15:48:52 -070040import android.preference.PreferenceActivity;
Amith Yamasania4379d62011-07-22 10:34:58 -070041import android.preference.PreferenceFragment;
Gilles Debunnee78c1872011-06-20 15:00:07 -070042import android.text.TextUtils;
Amith Yamasanic9fdfa82010-12-14 14:38:16 -080043import android.util.Log;
Gilles Debunnee78c1872011-06-20 15:00:07 -070044import android.view.LayoutInflater;
Amith Yamasanic9fdfa82010-12-14 14:38:16 -080045import android.view.View;
46import android.view.View.OnClickListener;
Gilles Debunnee78c1872011-06-20 15:00:07 -070047import android.view.ViewGroup;
48import android.widget.ArrayAdapter;
Amith Yamasani9e3a4702011-01-11 09:09:26 -080049import android.widget.Button;
Gilles Debunnee78c1872011-06-20 15:00:07 -070050import android.widget.ImageView;
51import android.widget.ListAdapter;
52import android.widget.Switch;
53import android.widget.TextView;
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -080054
Jeff Sharkeycc0d26b2012-11-27 16:42:27 -080055import com.android.internal.util.ArrayUtils;
Alan Viverette341ff662013-07-18 17:49:33 -070056import com.android.settings.accessibility.ToggleAccessibilityServicePreferenceFragment;
Jeff Sharkeycc0d26b2012-11-27 16:42:27 -080057import com.android.settings.accounts.AccountSyncSettings;
58import com.android.settings.accounts.AuthenticatorHelper;
59import com.android.settings.accounts.ManageAccountsSettings;
60import com.android.settings.bluetooth.BluetoothEnabler;
61import com.android.settings.bluetooth.BluetoothSettings;
Jeff Sharkey0c3634c2013-02-20 12:35:16 -080062import com.android.settings.wfd.WifiDisplaySettings;
Jeff Sharkeycc0d26b2012-11-27 16:42:27 -080063import com.android.settings.wifi.WifiEnabler;
64import com.android.settings.wifi.WifiSettings;
65import com.android.settings.wifi.p2p.WifiP2pSettings;
66
Gilles Debunnee78c1872011-06-20 15:00:07 -070067import java.util.ArrayList;
Amith Yamasanid1ab8282012-05-18 09:50:08 -070068import java.util.Collections;
69import java.util.Comparator;
Amith Yamasani5203bdf2010-11-04 09:59:44 -070070import java.util.HashMap;
Amith Yamasani02cf71a2010-09-21 15:48:52 -070071import java.util.List;
Amith Yamasanid7993472010-08-18 13:59:28 -070072
73/**
74 * Top-level settings activity to handle single pane and double pane UI layout.
75 */
Amith Yamasani56821db2012-06-05 13:20:45 -070076public class Settings extends PreferenceActivity
77 implements ButtonBarHandler, OnAccountsUpdateListener {
Amith Yamasanid7993472010-08-18 13:59:28 -070078
Gilles Debunnee78c1872011-06-20 15:00:07 -070079 private static final String LOG_TAG = "Settings";
Amith Yamasaniea7b28c2012-06-20 13:51:40 -070080
Amith Yamasani5203bdf2010-11-04 09:59:44 -070081 private static final String META_DATA_KEY_HEADER_ID =
Gilles Debunnee78c1872011-06-20 15:00:07 -070082 "com.android.settings.TOP_LEVEL_HEADER_ID";
Amith Yamasani5203bdf2010-11-04 09:59:44 -070083 private static final String META_DATA_KEY_FRAGMENT_CLASS =
Gilles Debunnee78c1872011-06-20 15:00:07 -070084 "com.android.settings.FRAGMENT_CLASS";
Amith Yamasanic9fdfa82010-12-14 14:38:16 -080085 private static final String META_DATA_KEY_PARENT_TITLE =
86 "com.android.settings.PARENT_FRAGMENT_TITLE";
87 private static final String META_DATA_KEY_PARENT_FRAGMENT_CLASS =
88 "com.android.settings.PARENT_FRAGMENT_CLASS";
89
Jeff Sharkeycc0d26b2012-11-27 16:42:27 -080090 private static final String EXTRA_UI_OPTIONS = "settings:ui_options";
Jeff Sharkey9fab0da2011-07-09 17:52:31 -070091
Amith Yamasanic9fdfa82010-12-14 14:38:16 -080092 private static final String SAVE_KEY_CURRENT_HEADER = "com.android.settings.CURRENT_HEADER";
93 private static final String SAVE_KEY_PARENT_HEADER = "com.android.settings.PARENT_HEADER";
Amith Yamasani5203bdf2010-11-04 09:59:44 -070094
95 private String mFragmentClass;
96 private int mTopLevelHeaderId;
Amith Yamasani3965ae62010-11-15 14:45:19 -080097 private Header mFirstHeader;
Amith Yamasanic9fdfa82010-12-14 14:38:16 -080098 private Header mCurrentHeader;
99 private Header mParentHeader;
100 private boolean mInLocalHeaderSwitch;
Amith Yamasani5203bdf2010-11-04 09:59:44 -0700101
Amith Yamasanib810a0d2012-03-25 10:12:26 -0700102 // Show only these settings for restricted users
103 private int[] SETTINGS_FOR_RESTRICTED = {
Amith Yamasani32630392012-08-10 19:31:39 -0700104 R.id.wireless_section,
Amith Yamasanib810a0d2012-03-25 10:12:26 -0700105 R.id.wifi_settings,
106 R.id.bluetooth_settings,
Jeff Sharkey38305fb2012-09-14 16:26:51 -0700107 R.id.data_usage_settings,
Amith Yamasani9627a8e2012-09-23 12:54:14 -0700108 R.id.wireless_settings,
Amith Yamasani32630392012-08-10 19:31:39 -0700109 R.id.device_section,
Amith Yamasanib810a0d2012-03-25 10:12:26 -0700110 R.id.sound_settings,
111 R.id.display_settings,
Jeff Sharkey90c8b202012-08-30 15:20:10 -0700112 R.id.storage_settings,
Dianne Hackborn271c8b02012-08-20 17:24:39 -0700113 R.id.application_settings,
Dianne Hackborn52e56a22012-09-12 17:02:23 -0700114 R.id.battery_settings,
Amith Yamasani32630392012-08-10 19:31:39 -0700115 R.id.personal_section,
Amith Yamasani9627a8e2012-09-23 12:54:14 -0700116 R.id.location_settings,
Amith Yamasani3deeeb72012-04-05 14:44:48 -0700117 R.id.security_settings,
Amith Yamasani9627a8e2012-09-23 12:54:14 -0700118 R.id.language_settings,
Amith Yamasani0ca80fe2013-06-03 16:41:03 -0700119 R.id.restriction_settings,
Amith Yamasanidc6bfa62012-09-06 18:04:06 -0700120 R.id.user_settings,
Amith Yamasanid1ab8282012-05-18 09:50:08 -0700121 R.id.account_settings,
Amith Yamasani32630392012-08-10 19:31:39 -0700122 R.id.account_add,
123 R.id.system_section,
Amith Yamasani9627a8e2012-09-23 12:54:14 -0700124 R.id.date_time_settings,
Jeff Brown9e143f52012-09-19 20:46:07 -0700125 R.id.about_settings,
Svetoslav Ganovd4c7b492013-06-11 21:15:11 -0700126 R.id.accessibility_settings,
127 R.id.print_settings
Amith Yamasanib810a0d2012-03-25 10:12:26 -0700128 };
129
Dianne Hackborncaefa9b2012-10-10 15:05:42 -0700130 private SharedPreferences mDevelopmentPreferences;
131 private SharedPreferences.OnSharedPreferenceChangeListener mDevelopmentPreferencesListener;
132
Amith Yamasani02cf71a2010-09-21 15:48:52 -0700133 // TODO: Update Call Settings based on airplane mode state.
Amith Yamasanib61cf512010-09-12 08:17:50 -0700134
Amith Yamasani5203bdf2010-11-04 09:59:44 -0700135 protected HashMap<Integer, Integer> mHeaderIndexMap = new HashMap<Integer, Integer>();
136
Amith Yamasanid1ab8282012-05-18 09:50:08 -0700137 private AuthenticatorHelper mAuthenticatorHelper;
138 private Header mLastHeader;
Amith Yamasani86708a82012-06-06 20:23:08 -0700139 private boolean mListeningToAccountUpdates;
Amith Yamasanid1ab8282012-05-18 09:50:08 -0700140
Jaewan Kima3fe77b2013-06-04 21:17:40 +0900141 private boolean mBatteryPresent = true;
142 private BroadcastReceiver mBatteryInfoReceiver = new BroadcastReceiver() {
143
144 @Override
145 public void onReceive(Context context, Intent intent) {
146 String action = intent.getAction();
147 if (Intent.ACTION_BATTERY_CHANGED.equals(action)) {
148 boolean batteryPresent = Utils.isBatteryPresent(intent);
149
150 if (mBatteryPresent != batteryPresent) {
151 mBatteryPresent = batteryPresent;
152 invalidateHeaders();
153 }
154 }
155 }
156 };
157
Amith Yamasani5203bdf2010-11-04 09:59:44 -0700158 @Override
159 protected void onCreate(Bundle savedInstanceState) {
Jeff Sharkeycc0d26b2012-11-27 16:42:27 -0800160 if (getIntent().hasExtra(EXTRA_UI_OPTIONS)) {
161 getWindow().setUiOptions(getIntent().getIntExtra(EXTRA_UI_OPTIONS, 0));
Jeff Sharkey54d0af52011-08-11 18:26:57 -0700162 }
Jeff Sharkey9fab0da2011-07-09 17:52:31 -0700163
Amith Yamasanid1ab8282012-05-18 09:50:08 -0700164 mAuthenticatorHelper = new AuthenticatorHelper();
165 mAuthenticatorHelper.updateAuthDescriptions(this);
166 mAuthenticatorHelper.onAccountsUpdated(this, null);
167
Dianne Hackborncaefa9b2012-10-10 15:05:42 -0700168 mDevelopmentPreferences = getSharedPreferences(DevelopmentSettings.PREF_FILE,
169 Context.MODE_PRIVATE);
170
Amith Yamasani5203bdf2010-11-04 09:59:44 -0700171 getMetaData();
Amith Yamasanic9fdfa82010-12-14 14:38:16 -0800172 mInLocalHeaderSwitch = true;
Amith Yamasani5203bdf2010-11-04 09:59:44 -0700173 super.onCreate(savedInstanceState);
Amith Yamasanic9fdfa82010-12-14 14:38:16 -0800174 mInLocalHeaderSwitch = false;
Amith Yamasani5203bdf2010-11-04 09:59:44 -0700175
Gilles Debunne3661b622011-06-27 11:19:16 -0700176 if (!onIsHidingHeaders() && onIsMultiPane()) {
Amith Yamasanid1ab8282012-05-18 09:50:08 -0700177 highlightHeader(mTopLevelHeaderId);
Amith Yamasani72aa19d2010-12-09 06:07:12 -0800178 // Force the title so that it doesn't get overridden by a direct launch of
179 // a specific settings screen.
180 setTitle(R.string.settings_label);
181 }
Amith Yamasanic9fdfa82010-12-14 14:38:16 -0800182
183 // Retrieve any saved state
184 if (savedInstanceState != null) {
185 mCurrentHeader = savedInstanceState.getParcelable(SAVE_KEY_CURRENT_HEADER);
186 mParentHeader = savedInstanceState.getParcelable(SAVE_KEY_PARENT_HEADER);
187 }
188
189 // If the current header was saved, switch to it
190 if (savedInstanceState != null && mCurrentHeader != null) {
191 //switchToHeaderLocal(mCurrentHeader);
192 showBreadCrumbs(mCurrentHeader.title, null);
193 }
194
195 if (mParentHeader != null) {
196 setParentTitle(mParentHeader.title, null, new OnClickListener() {
Maggie Benthall0c5a4012013-03-14 17:41:27 -0400197 @Override
Amith Yamasanic9fdfa82010-12-14 14:38:16 -0800198 public void onClick(View v) {
199 switchToParent(mParentHeader.fragment);
200 }
201 });
202 }
Gilles Debunnedc7101f2011-06-27 12:00:49 -0700203
Amith Yamasani3d384f42012-05-11 15:22:04 -0700204 // Override up navigation for multi-pane, since we handle it in the fragment breadcrumbs
205 if (onIsMultiPane()) {
206 getActionBar().setDisplayHomeAsUpEnabled(false);
207 getActionBar().setHomeButtonEnabled(false);
208 }
Amith Yamasanic9fdfa82010-12-14 14:38:16 -0800209 }
210
211 @Override
212 protected void onSaveInstanceState(Bundle outState) {
213 super.onSaveInstanceState(outState);
214
215 // Save the current fragment, if it is the same as originally launched
216 if (mCurrentHeader != null) {
217 outState.putParcelable(SAVE_KEY_CURRENT_HEADER, mCurrentHeader);
218 }
219 if (mParentHeader != null) {
220 outState.putParcelable(SAVE_KEY_PARENT_HEADER, mParentHeader);
221 }
222 }
223
Gilles Debunnee78c1872011-06-20 15:00:07 -0700224 @Override
225 public void onResume() {
226 super.onResume();
227
Dianne Hackborncaefa9b2012-10-10 15:05:42 -0700228 mDevelopmentPreferencesListener = new SharedPreferences.OnSharedPreferenceChangeListener() {
229 @Override
230 public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
231 invalidateHeaders();
232 }
233 };
234 mDevelopmentPreferences.registerOnSharedPreferenceChangeListener(
235 mDevelopmentPreferencesListener);
236
Gilles Debunnee78c1872011-06-20 15:00:07 -0700237 ListAdapter listAdapter = getListAdapter();
238 if (listAdapter instanceof HeaderAdapter) {
239 ((HeaderAdapter) listAdapter).resume();
240 }
Amith Yamasaniea7b28c2012-06-20 13:51:40 -0700241 invalidateHeaders();
Jaewan Kima3fe77b2013-06-04 21:17:40 +0900242
243 registerReceiver(mBatteryInfoReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
Gilles Debunnee78c1872011-06-20 15:00:07 -0700244 }
245
246 @Override
247 public void onPause() {
248 super.onPause();
249
Jaewan Kima3fe77b2013-06-04 21:17:40 +0900250 unregisterReceiver(mBatteryInfoReceiver);
251
Gilles Debunnee78c1872011-06-20 15:00:07 -0700252 ListAdapter listAdapter = getListAdapter();
253 if (listAdapter instanceof HeaderAdapter) {
254 ((HeaderAdapter) listAdapter).pause();
Amith Yamasani86708a82012-06-06 20:23:08 -0700255 }
Dianne Hackborncaefa9b2012-10-10 15:05:42 -0700256
257 mDevelopmentPreferences.unregisterOnSharedPreferenceChangeListener(
258 mDevelopmentPreferencesListener);
259 mDevelopmentPreferencesListener = null;
Amith Yamasani86708a82012-06-06 20:23:08 -0700260 }
261
262 @Override
263 public void onDestroy() {
264 super.onDestroy();
265 if (mListeningToAccountUpdates) {
Amith Yamasani56821db2012-06-05 13:20:45 -0700266 AccountManager.get(this).removeOnAccountsUpdatedListener(this);
Gilles Debunnee78c1872011-06-20 15:00:07 -0700267 }
268 }
269
Amith Yamasanic9fdfa82010-12-14 14:38:16 -0800270 private void switchToHeaderLocal(Header header) {
271 mInLocalHeaderSwitch = true;
272 switchToHeader(header);
273 mInLocalHeaderSwitch = false;
274 }
275
276 @Override
277 public void switchToHeader(Header header) {
278 if (!mInLocalHeaderSwitch) {
279 mCurrentHeader = null;
280 mParentHeader = null;
281 }
282 super.switchToHeader(header);
283 }
284
285 /**
286 * Switch to parent fragment and store the grand parent's info
Jake Hamby2748fc22011-01-12 15:06:28 -0800287 * @param className name of the activity wrapper for the parent fragment.
Amith Yamasanic9fdfa82010-12-14 14:38:16 -0800288 */
289 private void switchToParent(String className) {
290 final ComponentName cn = new ComponentName(this, className);
291 try {
292 final PackageManager pm = getPackageManager();
293 final ActivityInfo parentInfo = pm.getActivityInfo(cn, PackageManager.GET_META_DATA);
294
295 if (parentInfo != null && parentInfo.metaData != null) {
296 String fragmentClass = parentInfo.metaData.getString(META_DATA_KEY_FRAGMENT_CLASS);
297 CharSequence fragmentTitle = parentInfo.loadLabel(pm);
298 Header parentHeader = new Header();
299 parentHeader.fragment = fragmentClass;
300 parentHeader.title = fragmentTitle;
301 mCurrentHeader = parentHeader;
302
303 switchToHeaderLocal(parentHeader);
Amith Yamasanid1ab8282012-05-18 09:50:08 -0700304 highlightHeader(mTopLevelHeaderId);
Amith Yamasanic9fdfa82010-12-14 14:38:16 -0800305
306 mParentHeader = new Header();
307 mParentHeader.fragment
308 = parentInfo.metaData.getString(META_DATA_KEY_PARENT_FRAGMENT_CLASS);
309 mParentHeader.title = parentInfo.metaData.getString(META_DATA_KEY_PARENT_TITLE);
310 }
311 } catch (NameNotFoundException nnfe) {
Gilles Debunnee78c1872011-06-20 15:00:07 -0700312 Log.w(LOG_TAG, "Could not find parent activity : " + className);
Amith Yamasanic9fdfa82010-12-14 14:38:16 -0800313 }
Amith Yamasani5203bdf2010-11-04 09:59:44 -0700314 }
315
Amith Yamasani3965ae62010-11-15 14:45:19 -0800316 @Override
317 public void onNewIntent(Intent intent) {
318 super.onNewIntent(intent);
319
320 // If it is not launched from history, then reset to top-level
Amith Yamasanief617232012-10-09 16:57:25 -0700321 if ((intent.getFlags() & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) == 0) {
322 if (mFirstHeader != null && !onIsHidingHeaders() && onIsMultiPane()) {
323 switchToHeaderLocal(mFirstHeader);
324 }
325 getListView().setSelectionFromTop(0, 0);
Amith Yamasani3965ae62010-11-15 14:45:19 -0800326 }
327 }
328
Amith Yamasanid1ab8282012-05-18 09:50:08 -0700329 private void highlightHeader(int id) {
330 if (id != 0) {
331 Integer index = mHeaderIndexMap.get(id);
Amith Yamasani5203bdf2010-11-04 09:59:44 -0700332 if (index != null) {
333 getListView().setItemChecked(index, true);
Amith Yamasanief617232012-10-09 16:57:25 -0700334 if (isMultiPane()) {
335 getListView().smoothScrollToPosition(index);
336 }
Amith Yamasani5203bdf2010-11-04 09:59:44 -0700337 }
338 }
339 }
340
Amith Yamasanie0e4fc22010-10-05 11:49:51 -0700341 @Override
342 public Intent getIntent() {
Gilles Debunnee78c1872011-06-20 15:00:07 -0700343 Intent superIntent = super.getIntent();
344 String startingFragment = getStartingFragmentClass(superIntent);
Gilles Debunne3661b622011-06-27 11:19:16 -0700345 // This is called from super.onCreate, isMultiPane() is not yet reliable
346 // Do not use onIsHidingHeaders either, which relies itself on this method
347 if (startingFragment != null && !onIsMultiPane()) {
Gilles Debunnee78c1872011-06-20 15:00:07 -0700348 Intent modIntent = new Intent(superIntent);
Amith Yamasanie0e4fc22010-10-05 11:49:51 -0700349 modIntent.putExtra(EXTRA_SHOW_FRAGMENT, startingFragment);
Gilles Debunnee78c1872011-06-20 15:00:07 -0700350 Bundle args = superIntent.getExtras();
Dianne Hackbornf4eb85b2010-10-29 16:53:04 -0700351 if (args != null) {
352 args = new Bundle(args);
353 } else {
354 args = new Bundle();
355 }
Gilles Debunnee78c1872011-06-20 15:00:07 -0700356 args.putParcelable("intent", superIntent);
357 modIntent.putExtra(EXTRA_SHOW_FRAGMENT_ARGUMENTS, superIntent.getExtras());
Amith Yamasanie0e4fc22010-10-05 11:49:51 -0700358 return modIntent;
359 }
Gilles Debunnee78c1872011-06-20 15:00:07 -0700360 return superIntent;
Amith Yamasanie0e4fc22010-10-05 11:49:51 -0700361 }
362
Amith Yamasani02cf71a2010-09-21 15:48:52 -0700363 /**
Amith Yamasani379d9b02010-09-27 12:03:59 -0700364 * Checks if the component name in the intent is different from the Settings class and
365 * returns the class name to load as a fragment.
366 */
Amith Yamasani5203bdf2010-11-04 09:59:44 -0700367 protected String getStartingFragmentClass(Intent intent) {
368 if (mFragmentClass != null) return mFragmentClass;
369
Dianne Hackbornf4eb85b2010-10-29 16:53:04 -0700370 String intentClass = intent.getComponent().getClassName();
Amith Yamasani379d9b02010-09-27 12:03:59 -0700371 if (intentClass.equals(getClass().getName())) return null;
372
Dianne Hackbornee293792010-11-01 12:32:33 -0700373 if ("com.android.settings.ManageApplications".equals(intentClass)
374 || "com.android.settings.RunningServices".equals(intentClass)
375 || "com.android.settings.applications.StorageUse".equals(intentClass)) {
Gilles Debunnee78c1872011-06-20 15:00:07 -0700376 // Old names of manage apps.
Dianne Hackbornf4eb85b2010-10-29 16:53:04 -0700377 intentClass = com.android.settings.applications.ManageApplications.class.getName();
378 }
379
Amith Yamasani379d9b02010-09-27 12:03:59 -0700380 return intentClass;
381 }
382
383 /**
384 * Override initial header when an activity-alias is causing Settings to be launched
385 * for a specific fragment encoded in the android:name parameter.
386 */
387 @Override
388 public Header onGetInitialHeader() {
389 String fragmentClass = getStartingFragmentClass(super.getIntent());
390 if (fragmentClass != null) {
391 Header header = new Header();
392 header.fragment = fragmentClass;
Amith Yamasanic9fdfa82010-12-14 14:38:16 -0800393 header.title = getTitle();
Amith Yamasanie0e4fc22010-10-05 11:49:51 -0700394 header.fragmentArguments = getIntent().getExtras();
Amith Yamasanic9fdfa82010-12-14 14:38:16 -0800395 mCurrentHeader = header;
Amith Yamasani379d9b02010-09-27 12:03:59 -0700396 return header;
397 }
Gilles Debunnee78c1872011-06-20 15:00:07 -0700398
Gilles Debunneb396c9b2011-06-22 16:07:29 -0700399 return mFirstHeader;
Amith Yamasani379d9b02010-09-27 12:03:59 -0700400 }
401
Dianne Hackbornb7258182011-03-15 16:23:55 -0700402 @Override
Dianne Hackborn48147dc2011-03-18 12:29:41 -0700403 public Intent onBuildStartFragmentIntent(String fragmentName, Bundle args,
404 int titleRes, int shortTitleRes) {
405 Intent intent = super.onBuildStartFragmentIntent(fragmentName, args,
406 titleRes, shortTitleRes);
Jeff Sharkey9fab0da2011-07-09 17:52:31 -0700407
Jeff Sharkeycc0d26b2012-11-27 16:42:27 -0800408 // Some fragments want split ActionBar; these should stay in sync with
409 // uiOptions for fragments also defined as activities in manifest.
410 if (WifiSettings.class.getName().equals(fragmentName) ||
411 WifiP2pSettings.class.getName().equals(fragmentName) ||
Jeff Sharkey0c3634c2013-02-20 12:35:16 -0800412 WifiDisplaySettings.class.getName().equals(fragmentName) ||
Jeff Sharkeycc0d26b2012-11-27 16:42:27 -0800413 BluetoothSettings.class.getName().equals(fragmentName) ||
414 DreamSettings.class.getName().equals(fragmentName) ||
415 ToggleAccessibilityServicePreferenceFragment.class.getName().equals(fragmentName)) {
416 intent.putExtra(EXTRA_UI_OPTIONS, ActivityInfo.UIOPTION_SPLIT_ACTION_BAR_WHEN_NARROW);
Jeff Sharkey9fab0da2011-07-09 17:52:31 -0700417 }
418
Dianne Hackbornb7258182011-03-15 16:23:55 -0700419 intent.setClass(this, SubSettings.class);
420 return intent;
421 }
Amith Yamasaniea7b28c2012-06-20 13:51:40 -0700422
Amith Yamasani379d9b02010-09-27 12:03:59 -0700423 /**
Amith Yamasani02cf71a2010-09-21 15:48:52 -0700424 * Populate the activity with the top-level headers.
425 */
Amith Yamasanid7993472010-08-18 13:59:28 -0700426 @Override
Gilles Debunnee78c1872011-06-20 15:00:07 -0700427 public void onBuildHeaders(List<Header> headers) {
428 loadHeadersFromResource(R.xml.settings_headers, headers);
Gilles Debunnee78c1872011-06-20 15:00:07 -0700429 updateHeaderList(headers);
Amith Yamasani02cf71a2010-09-21 15:48:52 -0700430 }
Amith Yamasanid7993472010-08-18 13:59:28 -0700431
Amith Yamasani02cf71a2010-09-21 15:48:52 -0700432 private void updateHeaderList(List<Header> target) {
Dianne Hackborncaefa9b2012-10-10 15:05:42 -0700433 final boolean showDev = mDevelopmentPreferences.getBoolean(
434 DevelopmentSettings.PREF_SHOW,
435 android.os.Build.TYPE.equals("eng"));
Amith Yamasani02cf71a2010-09-21 15:48:52 -0700436 int i = 0;
Maggie Benthall0c5a4012013-03-14 17:41:27 -0400437
438 final UserManager um = (UserManager) getSystemService(Context.USER_SERVICE);
Dianne Hackborncaefa9b2012-10-10 15:05:42 -0700439 mHeaderIndexMap.clear();
Amith Yamasani02cf71a2010-09-21 15:48:52 -0700440 while (i < target.size()) {
441 Header header = target.get(i);
Amith Yamasani5203bdf2010-11-04 09:59:44 -0700442 // Ids are integers, so downcasting
443 int id = (int) header.id;
Chris Wren2bc32ae2012-09-24 14:23:46 -0400444 if (id == R.id.operator_settings || id == R.id.manufacturer_settings) {
Amith Yamasani02cf71a2010-09-21 15:48:52 -0700445 Utils.updateHeaderToSpecificActivityFromMetaDataOrRemove(this, target, header);
Gilles Debunne2454f492011-06-21 16:16:06 -0700446 } else if (id == R.id.wifi_settings) {
447 // Remove WiFi Settings if WiFi service is not available.
448 if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI)) {
Dianne Hackborncaefa9b2012-10-10 15:05:42 -0700449 target.remove(i);
Gilles Debunne2454f492011-06-21 16:16:06 -0700450 }
Gilles Debunnee78c1872011-06-20 15:00:07 -0700451 } else if (id == R.id.bluetooth_settings) {
452 // Remove Bluetooth Settings if Bluetooth service is not available.
Gilles Debunne2454f492011-06-21 16:16:06 -0700453 if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH)) {
Dianne Hackborncaefa9b2012-10-10 15:05:42 -0700454 target.remove(i);
Gilles Debunnee78c1872011-06-20 15:00:07 -0700455 }
Jeff Sharkey34e964d2012-04-21 15:41:48 -0700456 } else if (id == R.id.data_usage_settings) {
457 // Remove data usage when kernel module not enabled
458 final INetworkManagementService netManager = INetworkManagementService.Stub
459 .asInterface(ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE));
460 try {
461 if (!netManager.isBandwidthControlEnabled()) {
Dianne Hackborncaefa9b2012-10-10 15:05:42 -0700462 target.remove(i);
Jeff Sharkey34e964d2012-04-21 15:41:48 -0700463 }
464 } catch (RemoteException e) {
465 // ignored
466 }
Jaewan Kima3fe77b2013-06-04 21:17:40 +0900467 } else if (id == R.id.battery_settings) {
468 // Remove battery settings when battery is not available. (e.g. TV)
469
470 if (!mBatteryPresent) {
471 target.remove(i);
472 }
Amith Yamasanid1ab8282012-05-18 09:50:08 -0700473 } else if (id == R.id.account_settings) {
474 int headerIndex = i + 1;
475 i = insertAccountsHeaders(target, headerIndex);
Amith Yamasanib810a0d2012-03-25 10:12:26 -0700476 } else if (id == R.id.user_settings) {
Amith Yamasanidc6bfa62012-09-06 18:04:06 -0700477 if (!UserHandle.MU_ENABLED
Jeff Sharkey44202462012-09-19 13:13:45 -0700478 || !UserManager.supportsMultipleUsers()
Amith Yamasanib810a0d2012-03-25 10:12:26 -0700479 || Utils.isMonkeyRunning()) {
Dianne Hackborncaefa9b2012-10-10 15:05:42 -0700480 target.remove(i);
481 }
482 } else if (id == R.id.development_settings) {
483 if (!showDev) {
484 target.remove(i);
Amith Yamasanib810a0d2012-03-25 10:12:26 -0700485 }
Maggie Benthall0c5a4012013-03-14 17:41:27 -0400486 } else if (id == R.id.account_add) {
487 if (um.hasUserRestriction(UserManager.DISALLOW_MODIFY_ACCOUNTS)) {
488 target.remove(i);
489 }
Amith Yamasani0ca80fe2013-06-03 16:41:03 -0700490 } else if (id == R.id.restriction_settings) {
Amith Yamasanid5b1a292013-07-22 16:51:39 -0700491 if (um.isLinkedUser()
492 || um.hasUserRestriction(UserManager.DISALLOW_APP_RESTRICTIONS)) {
Amith Yamasani0ca80fe2013-06-03 16:41:03 -0700493 target.remove(i);
494 }
Amith Yamasanib810a0d2012-03-25 10:12:26 -0700495 }
Dianne Hackborncaefa9b2012-10-10 15:05:42 -0700496
Jaewan Kimbb0e6212013-02-04 15:36:17 +0900497 if (i < target.size() && target.get(i) == header
Amith Yamasanib99f8642012-10-10 21:41:12 -0700498 && UserHandle.MU_ENABLED && UserHandle.myUserId() != 0
Amith Yamasanib810a0d2012-03-25 10:12:26 -0700499 && !ArrayUtils.contains(SETTINGS_FOR_RESTRICTED, id)) {
Dianne Hackborncaefa9b2012-10-10 15:05:42 -0700500 target.remove(i);
Amith Yamasanid7993472010-08-18 13:59:28 -0700501 }
Gilles Debunnee78c1872011-06-20 15:00:07 -0700502
Amith Yamasani5203bdf2010-11-04 09:59:44 -0700503 // Increment if the current one wasn't removed by the Utils code.
Jaewan Kimbb0e6212013-02-04 15:36:17 +0900504 if (i < target.size() && target.get(i) == header) {
Amith Yamasani3965ae62010-11-15 14:45:19 -0800505 // Hold on to the first header, when we need to reset to the top-level
Gilles Debunneb396c9b2011-06-22 16:07:29 -0700506 if (mFirstHeader == null &&
507 HeaderAdapter.getHeaderType(header) != HeaderAdapter.HEADER_TYPE_CATEGORY) {
508 mFirstHeader = header;
509 }
Amith Yamasani5203bdf2010-11-04 09:59:44 -0700510 mHeaderIndexMap.put(id, i);
Amith Yamasani02cf71a2010-09-21 15:48:52 -0700511 i++;
Amith Yamasani5203bdf2010-11-04 09:59:44 -0700512 }
Amith Yamasanid7993472010-08-18 13:59:28 -0700513 }
514 }
515
Amith Yamasanid1ab8282012-05-18 09:50:08 -0700516 private int insertAccountsHeaders(List<Header> target, int headerIndex) {
517 String[] accountTypes = mAuthenticatorHelper.getEnabledAccountTypes();
518 List<Header> accountHeaders = new ArrayList<Header>(accountTypes.length);
519 for (String accountType : accountTypes) {
520 CharSequence label = mAuthenticatorHelper.getLabelForType(this, accountType);
Brian Muramatsuc28af522012-06-28 14:25:14 -0700521 if (label == null) {
522 continue;
523 }
524
Amith Yamasani3882c2e2012-06-07 17:03:20 -0700525 Account[] accounts = AccountManager.get(this).getAccountsByType(accountType);
526 boolean skipToAccount = accounts.length == 1
527 && !mAuthenticatorHelper.hasAccountPreferences(accountType);
Amith Yamasanid1ab8282012-05-18 09:50:08 -0700528 Header accHeader = new Header();
529 accHeader.title = label;
530 if (accHeader.extras == null) {
531 accHeader.extras = new Bundle();
532 }
Amith Yamasani3882c2e2012-06-07 17:03:20 -0700533 if (skipToAccount) {
534 accHeader.breadCrumbTitleRes = R.string.account_sync_settings_title;
535 accHeader.breadCrumbShortTitleRes = R.string.account_sync_settings_title;
536 accHeader.fragment = AccountSyncSettings.class.getName();
537 accHeader.fragmentArguments = new Bundle();
538 // Need this for the icon
539 accHeader.extras.putString(ManageAccountsSettings.KEY_ACCOUNT_TYPE, accountType);
540 accHeader.extras.putParcelable(AccountSyncSettings.ACCOUNT_KEY, accounts[0]);
541 accHeader.fragmentArguments.putParcelable(AccountSyncSettings.ACCOUNT_KEY,
542 accounts[0]);
543 } else {
544 accHeader.breadCrumbTitle = label;
545 accHeader.breadCrumbShortTitle = label;
546 accHeader.fragment = ManageAccountsSettings.class.getName();
547 accHeader.fragmentArguments = new Bundle();
548 accHeader.extras.putString(ManageAccountsSettings.KEY_ACCOUNT_TYPE, accountType);
549 accHeader.fragmentArguments.putString(ManageAccountsSettings.KEY_ACCOUNT_TYPE,
550 accountType);
551 if (!isMultiPane()) {
552 accHeader.fragmentArguments.putString(ManageAccountsSettings.KEY_ACCOUNT_LABEL,
553 label.toString());
554 }
Amith Yamasanid1ab8282012-05-18 09:50:08 -0700555 }
556 accountHeaders.add(accHeader);
557 }
558
559 // Sort by label
560 Collections.sort(accountHeaders, new Comparator<Header>() {
561 @Override
562 public int compare(Header h1, Header h2) {
563 return h1.title.toString().compareTo(h2.title.toString());
564 }
565 });
566
567 for (Header header : accountHeaders) {
568 target.add(headerIndex++, header);
569 }
Amith Yamasani86708a82012-06-06 20:23:08 -0700570 if (!mListeningToAccountUpdates) {
571 AccountManager.get(this).addOnAccountsUpdatedListener(this, null, true);
572 mListeningToAccountUpdates = true;
573 }
Amith Yamasanid1ab8282012-05-18 09:50:08 -0700574 return headerIndex;
575 }
576
Amith Yamasani5203bdf2010-11-04 09:59:44 -0700577 private void getMetaData() {
578 try {
579 ActivityInfo ai = getPackageManager().getActivityInfo(getComponentName(),
580 PackageManager.GET_META_DATA);
581 if (ai == null || ai.metaData == null) return;
582 mTopLevelHeaderId = ai.metaData.getInt(META_DATA_KEY_HEADER_ID);
583 mFragmentClass = ai.metaData.getString(META_DATA_KEY_FRAGMENT_CLASS);
Amith Yamasanid1ab8282012-05-18 09:50:08 -0700584
Amith Yamasanic9fdfa82010-12-14 14:38:16 -0800585 // Check if it has a parent specified and create a Header object
586 final int parentHeaderTitleRes = ai.metaData.getInt(META_DATA_KEY_PARENT_TITLE);
587 String parentFragmentClass = ai.metaData.getString(META_DATA_KEY_PARENT_FRAGMENT_CLASS);
588 if (parentFragmentClass != null) {
589 mParentHeader = new Header();
590 mParentHeader.fragment = parentFragmentClass;
591 if (parentHeaderTitleRes != 0) {
592 mParentHeader.title = getResources().getString(parentHeaderTitleRes);
593 }
594 }
Amith Yamasani5203bdf2010-11-04 09:59:44 -0700595 } catch (NameNotFoundException nnfe) {
Gilles Debunnee78c1872011-06-20 15:00:07 -0700596 // No recovery
Amith Yamasani5203bdf2010-11-04 09:59:44 -0700597 }
598 }
599
Amith Yamasani9e3a4702011-01-11 09:09:26 -0800600 @Override
601 public boolean hasNextButton() {
602 return super.hasNextButton();
603 }
604
605 @Override
606 public Button getNextButton() {
607 return super.getNextButton();
608 }
609
Gilles Debunnee78c1872011-06-20 15:00:07 -0700610 private static class HeaderAdapter extends ArrayAdapter<Header> {
611 static final int HEADER_TYPE_CATEGORY = 0;
612 static final int HEADER_TYPE_NORMAL = 1;
613 static final int HEADER_TYPE_SWITCH = 2;
614 private static final int HEADER_TYPE_COUNT = HEADER_TYPE_SWITCH + 1;
615
616 private final WifiEnabler mWifiEnabler;
617 private final BluetoothEnabler mBluetoothEnabler;
Amith Yamasanid1ab8282012-05-18 09:50:08 -0700618 private AuthenticatorHelper mAuthHelper;
Gilles Debunnee78c1872011-06-20 15:00:07 -0700619
620 private static class HeaderViewHolder {
621 ImageView icon;
622 TextView title;
623 TextView summary;
624 Switch switch_;
625 }
626
627 private LayoutInflater mInflater;
628
629 static int getHeaderType(Header header) {
630 if (header.fragment == null && header.intent == null) {
631 return HEADER_TYPE_CATEGORY;
632 } else if (header.id == R.id.wifi_settings || header.id == R.id.bluetooth_settings) {
633 return HEADER_TYPE_SWITCH;
634 } else {
635 return HEADER_TYPE_NORMAL;
636 }
637 }
638
639 @Override
640 public int getItemViewType(int position) {
641 Header header = getItem(position);
642 return getHeaderType(header);
643 }
644
645 @Override
646 public boolean areAllItemsEnabled() {
647 return false; // because of categories
648 }
649
650 @Override
651 public boolean isEnabled(int position) {
652 return getItemViewType(position) != HEADER_TYPE_CATEGORY;
653 }
654
655 @Override
656 public int getViewTypeCount() {
657 return HEADER_TYPE_COUNT;
658 }
659
660 @Override
661 public boolean hasStableIds() {
662 return true;
663 }
664
Amith Yamasanid1ab8282012-05-18 09:50:08 -0700665 public HeaderAdapter(Context context, List<Header> objects,
666 AuthenticatorHelper authenticatorHelper) {
Gilles Debunnee78c1872011-06-20 15:00:07 -0700667 super(context, 0, objects);
Amith Yamasanid1ab8282012-05-18 09:50:08 -0700668
669 mAuthHelper = authenticatorHelper;
Gilles Debunnee78c1872011-06-20 15:00:07 -0700670 mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
Amith Yamasanid1ab8282012-05-18 09:50:08 -0700671
Gilles Debunneb396c9b2011-06-22 16:07:29 -0700672 // Temp Switches provided as placeholder until the adapter replaces these with actual
Gilles Debunnee78c1872011-06-20 15:00:07 -0700673 // Switches inflated from their layouts. Must be done before adapter is set in super
674 mWifiEnabler = new WifiEnabler(context, new Switch(context));
675 mBluetoothEnabler = new BluetoothEnabler(context, new Switch(context));
676 }
677
678 @Override
679 public View getView(int position, View convertView, ViewGroup parent) {
680 HeaderViewHolder holder;
681 Header header = getItem(position);
682 int headerType = getHeaderType(header);
683 View view = null;
684
685 if (convertView == null) {
686 holder = new HeaderViewHolder();
687 switch (headerType) {
688 case HEADER_TYPE_CATEGORY:
Gilles Debunneb396c9b2011-06-22 16:07:29 -0700689 view = new TextView(getContext(), null,
690 android.R.attr.listSeparatorTextViewStyle);
Gilles Debunnee78c1872011-06-20 15:00:07 -0700691 holder.title = (TextView) view;
692 break;
693
694 case HEADER_TYPE_SWITCH:
Gilles Debunneb396c9b2011-06-22 16:07:29 -0700695 view = mInflater.inflate(R.layout.preference_header_switch_item, parent,
696 false);
Gilles Debunnee78c1872011-06-20 15:00:07 -0700697 holder.icon = (ImageView) view.findViewById(R.id.icon);
Gilles Debunneb396c9b2011-06-22 16:07:29 -0700698 holder.title = (TextView)
699 view.findViewById(com.android.internal.R.id.title);
700 holder.summary = (TextView)
701 view.findViewById(com.android.internal.R.id.summary);
Gilles Debunnee78c1872011-06-20 15:00:07 -0700702 holder.switch_ = (Switch) view.findViewById(R.id.switchWidget);
703 break;
704
705 case HEADER_TYPE_NORMAL:
Gilles Debunneb396c9b2011-06-22 16:07:29 -0700706 view = mInflater.inflate(
Amith Yamasanic8a93172012-06-08 13:35:47 -0700707 R.layout.preference_header_item, parent,
Gilles Debunneb396c9b2011-06-22 16:07:29 -0700708 false);
Amith Yamasanic8a93172012-06-08 13:35:47 -0700709 holder.icon = (ImageView) view.findViewById(R.id.icon);
Gilles Debunneb396c9b2011-06-22 16:07:29 -0700710 holder.title = (TextView)
711 view.findViewById(com.android.internal.R.id.title);
712 holder.summary = (TextView)
713 view.findViewById(com.android.internal.R.id.summary);
Gilles Debunnee78c1872011-06-20 15:00:07 -0700714 break;
715 }
716 view.setTag(holder);
717 } else {
718 view = convertView;
719 holder = (HeaderViewHolder) view.getTag();
720 }
721
722 // All view fields must be updated every time, because the view may be recycled
723 switch (headerType) {
724 case HEADER_TYPE_CATEGORY:
725 holder.title.setText(header.getTitle(getContext().getResources()));
726 break;
727
728 case HEADER_TYPE_SWITCH:
729 // Would need a different treatment if the main menu had more switches
730 if (header.id == R.id.wifi_settings) {
731 mWifiEnabler.setSwitch(holder.switch_);
732 } else {
733 mBluetoothEnabler.setSwitch(holder.switch_);
734 }
735 // No break, fall through on purpose to update common fields
736
737 //$FALL-THROUGH$
738 case HEADER_TYPE_NORMAL:
Amith Yamasani3882c2e2012-06-07 17:03:20 -0700739 if (header.extras != null
740 && header.extras.containsKey(ManageAccountsSettings.KEY_ACCOUNT_TYPE)) {
Amith Yamasanid1ab8282012-05-18 09:50:08 -0700741 String accType = header.extras.getString(
742 ManageAccountsSettings.KEY_ACCOUNT_TYPE);
743 ViewGroup.LayoutParams lp = holder.icon.getLayoutParams();
744 lp.width = getContext().getResources().getDimensionPixelSize(
745 R.dimen.header_icon_width);
746 lp.height = lp.width;
747 holder.icon.setLayoutParams(lp);
748 Drawable icon = mAuthHelper.getDrawableForType(getContext(), accType);
749 holder.icon.setImageDrawable(icon);
750 } else {
751 holder.icon.setImageResource(header.iconRes);
752 }
Gilles Debunnee78c1872011-06-20 15:00:07 -0700753 holder.title.setText(header.getTitle(getContext().getResources()));
754 CharSequence summary = header.getSummary(getContext().getResources());
755 if (!TextUtils.isEmpty(summary)) {
756 holder.summary.setVisibility(View.VISIBLE);
757 holder.summary.setText(summary);
758 } else {
759 holder.summary.setVisibility(View.GONE);
760 }
761 break;
762 }
763
764 return view;
765 }
766
767 public void resume() {
768 mWifiEnabler.resume();
769 mBluetoothEnabler.resume();
770 }
Brian Muramatsuc28af522012-06-28 14:25:14 -0700771
Gilles Debunnee78c1872011-06-20 15:00:07 -0700772 public void pause() {
773 mWifiEnabler.pause();
774 mBluetoothEnabler.pause();
775 }
776 }
777
778 @Override
Amith Yamasanid1ab8282012-05-18 09:50:08 -0700779 public void onHeaderClick(Header header, int position) {
780 boolean revert = false;
781 if (header.id == R.id.account_add) {
782 revert = true;
783 }
784
785 super.onHeaderClick(header, position);
786
787 if (revert && mLastHeader != null) {
788 highlightHeader((int) mLastHeader.id);
789 } else {
790 mLastHeader = header;
791 }
792 }
793
794 @Override
Amith Yamasania4379d62011-07-22 10:34:58 -0700795 public boolean onPreferenceStartFragment(PreferenceFragment caller, Preference pref) {
796 // Override the fragment title for Wallpaper settings
Amith Yamasanidfb65432011-11-29 16:38:14 -0800797 int titleRes = pref.getTitleRes();
Amith Yamasania4379d62011-07-22 10:34:58 -0700798 if (pref.getFragment().equals(WallpaperTypeSettings.class.getName())) {
Amith Yamasanidfb65432011-11-29 16:38:14 -0800799 titleRes = R.string.wallpaper_settings_fragment_title;
Amith Yamasani8666b9e2012-09-27 14:50:13 -0700800 } else if (pref.getFragment().equals(OwnerInfoSettings.class.getName())
801 && UserHandle.myUserId() != UserHandle.USER_OWNER) {
Amith Yamasanib0171712013-04-28 22:13:22 -0700802 if (UserManager.get(this).isLinkedUser()) {
803 titleRes = R.string.profile_info_settings_title;
804 } else {
805 titleRes = R.string.user_info_settings_title;
806 }
Amith Yamasania4379d62011-07-22 10:34:58 -0700807 }
Jean Chalard7dabe452012-05-10 18:08:07 +0900808 startPreferencePanel(pref.getFragment(), pref.getExtras(), titleRes, pref.getTitle(),
809 null, 0);
Amith Yamasania4379d62011-07-22 10:34:58 -0700810 return true;
811 }
812
Maggie Benthall0c5a4012013-03-14 17:41:27 -0400813 @Override
Amith Yamasani3d384f42012-05-11 15:22:04 -0700814 public boolean shouldUpRecreateTask(Intent targetIntent) {
815 return super.shouldUpRecreateTask(new Intent(this, Settings.class));
816 }
817
Amith Yamasania4379d62011-07-22 10:34:58 -0700818 @Override
Gilles Debunnee78c1872011-06-20 15:00:07 -0700819 public void setListAdapter(ListAdapter adapter) {
Amith Yamasaniea7b28c2012-06-20 13:51:40 -0700820 if (adapter == null) {
821 super.setListAdapter(null);
822 } else {
823 super.setListAdapter(new HeaderAdapter(this, getHeaders(), mAuthenticatorHelper));
Gilles Debunnee78c1872011-06-20 15:00:07 -0700824 }
Gilles Debunnee78c1872011-06-20 15:00:07 -0700825 }
826
Amith Yamasani56821db2012-06-05 13:20:45 -0700827 @Override
828 public void onAccountsUpdated(Account[] accounts) {
Jeff Sharkey9ff79c12012-10-03 16:48:17 -0700829 // TODO: watch for package upgrades to invalidate cache; see 7206643
830 mAuthenticatorHelper.updateAuthDescriptions(this);
Amith Yamasani56821db2012-06-05 13:20:45 -0700831 mAuthenticatorHelper.onAccountsUpdated(this, accounts);
832 invalidateHeaders();
833 }
834
Amith Yamasani5203bdf2010-11-04 09:59:44 -0700835 /*
836 * Settings subclasses for launching independently.
837 */
Gilles Debunnee78c1872011-06-20 15:00:07 -0700838 public static class BluetoothSettingsActivity extends Settings { /* empty */ }
839 public static class WirelessSettingsActivity extends Settings { /* empty */ }
840 public static class TetherSettingsActivity extends Settings { /* empty */ }
841 public static class VpnSettingsActivity extends Settings { /* empty */ }
842 public static class DateTimeSettingsActivity extends Settings { /* empty */ }
843 public static class StorageSettingsActivity extends Settings { /* empty */ }
844 public static class WifiSettingsActivity extends Settings { /* empty */ }
repo syncb98463f2011-06-30 10:58:43 -0700845 public static class WifiP2pSettingsActivity extends Settings { /* empty */ }
Gilles Debunnee78c1872011-06-20 15:00:07 -0700846 public static class InputMethodAndLanguageSettingsActivity extends Settings { /* empty */ }
Jeff Browne46c5f32012-04-05 11:42:18 -0700847 public static class KeyboardLayoutPickerActivity extends Settings { /* empty */ }
Gilles Debunnee78c1872011-06-20 15:00:07 -0700848 public static class InputMethodAndSubtypeEnablerActivity extends Settings { /* empty */ }
satoke077d2b2011-07-25 09:38:11 +0900849 public static class SpellCheckersSettingsActivity extends Settings { /* empty */ }
Gilles Debunnee78c1872011-06-20 15:00:07 -0700850 public static class LocalePickerActivity extends Settings { /* empty */ }
851 public static class UserDictionarySettingsActivity extends Settings { /* empty */ }
852 public static class SoundSettingsActivity extends Settings { /* empty */ }
853 public static class DisplaySettingsActivity extends Settings { /* empty */ }
854 public static class DeviceInfoSettingsActivity extends Settings { /* empty */ }
855 public static class ApplicationSettingsActivity extends Settings { /* empty */ }
856 public static class ManageApplicationsActivity extends Settings { /* empty */ }
Dianne Hackborna522a8e2013-01-15 19:02:05 -0800857 public static class AppOpsSummaryActivity extends Settings { /* empty */ }
Gilles Debunnee78c1872011-06-20 15:00:07 -0700858 public static class StorageUseActivity extends Settings { /* empty */ }
859 public static class DevelopmentSettingsActivity extends Settings { /* empty */ }
860 public static class AccessibilitySettingsActivity extends Settings { /* empty */ }
861 public static class SecuritySettingsActivity extends Settings { /* empty */ }
Gilles Debunnea6a8a142011-06-09 11:56:17 -0700862 public static class LocationSettingsActivity extends Settings { /* empty */ }
Gilles Debunnee78c1872011-06-20 15:00:07 -0700863 public static class PrivacySettingsActivity extends Settings { /* empty */ }
Gilles Debunnee78c1872011-06-20 15:00:07 -0700864 public static class RunningServicesActivity extends Settings { /* empty */ }
865 public static class ManageAccountsSettingsActivity extends Settings { /* empty */ }
866 public static class PowerUsageSummaryActivity extends Settings { /* empty */ }
867 public static class AccountSyncSettingsActivity extends Settings { /* empty */ }
868 public static class AccountSyncSettingsInAddAccountActivity extends Settings { /* empty */ }
869 public static class CryptKeeperSettingsActivity extends Settings { /* empty */ }
870 public static class DeviceAdminSettingsActivity extends Settings { /* empty */ }
871 public static class DataUsageSummaryActivity extends Settings { /* empty */ }
Gilles Debunneab189bd2011-07-06 13:10:16 -0700872 public static class AdvancedWifiSettingsActivity extends Settings { /* empty */ }
Gilles Debunneab189bd2011-07-06 13:10:16 -0700873 public static class TextToSpeechSettingsActivity extends Settings { /* empty */ }
Jeff Hamilton3d670de2011-09-21 16:44:36 -0500874 public static class AndroidBeamSettingsActivity extends Settings { /* empty */ }
Jeff Brown9e143f52012-09-19 20:46:07 -0700875 public static class WifiDisplaySettingsActivity extends Settings { /* empty */ }
Daniel Sandler7dee75c2012-11-27 22:41:30 -0500876 public static class DreamSettingsActivity extends Settings { /* empty */ }
Daniel Sandler328e2d22013-01-17 13:14:02 -0500877 public static class NotificationStationActivity extends Settings { /* empty */ }
Amith Yamasani233592b2013-03-01 17:05:23 -0800878 public static class UserSettingsActivity extends Settings { /* empty */ }
Daniel Sandler79b9bfe2013-04-04 14:30:04 -0400879 public static class NotificationAccessSettingsActivity extends Settings { /* empty */ }
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800880}