blob: 20ec1a695f9ac516c14ac78fa4cac117e0651765 [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;
Amith Yamasania677ee22013-07-26 13:38:41 -070022import android.app.Fragment;
Jaewan Kima3fe77b2013-06-04 21:17:40 +090023import android.content.BroadcastReceiver;
Amith Yamasanic9fdfa82010-12-14 14:38:16 -080024import android.content.ComponentName;
Gilles Debunnee78c1872011-06-20 15:00:07 -070025import android.content.Context;
Amith Yamasani379d9b02010-09-27 12:03:59 -070026import android.content.Intent;
Jaewan Kima3fe77b2013-06-04 21:17:40 +090027import android.content.IntentFilter;
Amith Yamasani233592b2013-03-01 17:05:23 -080028import android.content.RestrictionEntry;
Dianne Hackborncaefa9b2012-10-10 15:05:42 -070029import android.content.SharedPreferences;
Amith Yamasani5203bdf2010-11-04 09:59:44 -070030import android.content.pm.ActivityInfo;
31import android.content.pm.PackageManager;
32import android.content.pm.PackageManager.NameNotFoundException;
Amith Yamasanid1ab8282012-05-18 09:50:08 -070033import android.graphics.drawable.Drawable;
Dianne Hackbornf4eb85b2010-10-29 16:53:04 -070034import android.os.Bundle;
Jeff Sharkey34e964d2012-04-21 15:41:48 -070035import android.os.INetworkManagementService;
36import android.os.RemoteException;
37import android.os.ServiceManager;
Dianne Hackbornbb06a422012-08-16 11:01:57 -070038import android.os.UserHandle;
Jeff Sharkey44202462012-09-19 13:13:45 -070039import android.os.UserManager;
Amith Yamasania4379d62011-07-22 10:34:58 -070040import android.preference.Preference;
Amith Yamasani02cf71a2010-09-21 15:48:52 -070041import android.preference.PreferenceActivity;
Amith Yamasania4379d62011-07-22 10:34:58 -070042import android.preference.PreferenceFragment;
Gilles Debunnee78c1872011-06-20 15:00:07 -070043import android.text.TextUtils;
Amith Yamasanic9fdfa82010-12-14 14:38:16 -080044import android.util.Log;
Gilles Debunnee78c1872011-06-20 15:00:07 -070045import android.view.LayoutInflater;
Amith Yamasanic9fdfa82010-12-14 14:38:16 -080046import android.view.View;
47import android.view.View.OnClickListener;
Gilles Debunnee78c1872011-06-20 15:00:07 -070048import android.view.ViewGroup;
49import android.widget.ArrayAdapter;
Amith Yamasani9e3a4702011-01-11 09:09:26 -080050import android.widget.Button;
Gilles Debunnee78c1872011-06-20 15:00:07 -070051import android.widget.ImageView;
52import android.widget.ListAdapter;
53import android.widget.Switch;
54import android.widget.TextView;
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -080055
Jeff Sharkeycc0d26b2012-11-27 16:42:27 -080056import com.android.internal.util.ArrayUtils;
Amith Yamasania677ee22013-07-26 13:38:41 -070057import com.android.settings.accessibility.AccessibilitySettings;
Alan Viverette341ff662013-07-18 17:49:33 -070058import com.android.settings.accessibility.ToggleAccessibilityServicePreferenceFragment;
Amith Yamasania677ee22013-07-26 13:38:41 -070059import com.android.settings.ChooseLockGeneric.ChooseLockGenericFragment;
60import com.android.settings.ChooseLockPassword.ChooseLockPasswordFragment;
61import com.android.settings.ChooseLockPattern.ChooseLockPatternFragment;
Jeff Sharkeycc0d26b2012-11-27 16:42:27 -080062import com.android.settings.accounts.AccountSyncSettings;
63import com.android.settings.accounts.AuthenticatorHelper;
64import com.android.settings.accounts.ManageAccountsSettings;
Amith Yamasania677ee22013-07-26 13:38:41 -070065import com.android.settings.applications.AppOpsSummary;
66import com.android.settings.applications.ManageApplications;
Jeff Sharkeycc0d26b2012-11-27 16:42:27 -080067import com.android.settings.bluetooth.BluetoothEnabler;
68import com.android.settings.bluetooth.BluetoothSettings;
Amith Yamasania677ee22013-07-26 13:38:41 -070069import com.android.settings.deviceinfo.Memory;
70import com.android.settings.deviceinfo.UsbSettings;
71import com.android.settings.fuelgauge.PowerUsageSummary;
72import com.android.settings.inputmethod.InputMethodAndLanguageSettings;
73import com.android.settings.inputmethod.SpellCheckersSettings;
74import com.android.settings.inputmethod.UserDictionaryList;
75import com.android.settings.nfc.AndroidBeam;
76import com.android.settings.tts.TextToSpeechSettings;
77import com.android.settings.users.AppRestrictionsFragment;
78import com.android.settings.users.UserSettings;
79import com.android.settings.vpn2.VpnSettings;
Jeff Sharkey0c3634c2013-02-20 12:35:16 -080080import com.android.settings.wfd.WifiDisplaySettings;
Amith Yamasania677ee22013-07-26 13:38:41 -070081import com.android.settings.wifi.AdvancedWifiSettings;
Jeff Sharkeycc0d26b2012-11-27 16:42:27 -080082import com.android.settings.wifi.WifiEnabler;
83import com.android.settings.wifi.WifiSettings;
84import com.android.settings.wifi.p2p.WifiP2pSettings;
85
Gilles Debunnee78c1872011-06-20 15:00:07 -070086import java.util.ArrayList;
Amith Yamasanid1ab8282012-05-18 09:50:08 -070087import java.util.Collections;
88import java.util.Comparator;
Amith Yamasani5203bdf2010-11-04 09:59:44 -070089import java.util.HashMap;
Amith Yamasani02cf71a2010-09-21 15:48:52 -070090import java.util.List;
Amith Yamasanid7993472010-08-18 13:59:28 -070091
92/**
93 * Top-level settings activity to handle single pane and double pane UI layout.
94 */
Amith Yamasani56821db2012-06-05 13:20:45 -070095public class Settings extends PreferenceActivity
96 implements ButtonBarHandler, OnAccountsUpdateListener {
Amith Yamasanid7993472010-08-18 13:59:28 -070097
Gilles Debunnee78c1872011-06-20 15:00:07 -070098 private static final String LOG_TAG = "Settings";
Amith Yamasaniea7b28c2012-06-20 13:51:40 -070099
Amith Yamasani5203bdf2010-11-04 09:59:44 -0700100 private static final String META_DATA_KEY_HEADER_ID =
Gilles Debunnee78c1872011-06-20 15:00:07 -0700101 "com.android.settings.TOP_LEVEL_HEADER_ID";
Amith Yamasani5203bdf2010-11-04 09:59:44 -0700102 private static final String META_DATA_KEY_FRAGMENT_CLASS =
Gilles Debunnee78c1872011-06-20 15:00:07 -0700103 "com.android.settings.FRAGMENT_CLASS";
Amith Yamasanic9fdfa82010-12-14 14:38:16 -0800104 private static final String META_DATA_KEY_PARENT_TITLE =
105 "com.android.settings.PARENT_FRAGMENT_TITLE";
106 private static final String META_DATA_KEY_PARENT_FRAGMENT_CLASS =
107 "com.android.settings.PARENT_FRAGMENT_CLASS";
108
Jeff Sharkeycc0d26b2012-11-27 16:42:27 -0800109 private static final String EXTRA_UI_OPTIONS = "settings:ui_options";
Jeff Sharkey9fab0da2011-07-09 17:52:31 -0700110
Amith Yamasanic9fdfa82010-12-14 14:38:16 -0800111 private static final String SAVE_KEY_CURRENT_HEADER = "com.android.settings.CURRENT_HEADER";
112 private static final String SAVE_KEY_PARENT_HEADER = "com.android.settings.PARENT_HEADER";
Amith Yamasani5203bdf2010-11-04 09:59:44 -0700113
114 private String mFragmentClass;
115 private int mTopLevelHeaderId;
Amith Yamasani3965ae62010-11-15 14:45:19 -0800116 private Header mFirstHeader;
Amith Yamasanic9fdfa82010-12-14 14:38:16 -0800117 private Header mCurrentHeader;
118 private Header mParentHeader;
119 private boolean mInLocalHeaderSwitch;
Amith Yamasani5203bdf2010-11-04 09:59:44 -0700120
Amith Yamasanib810a0d2012-03-25 10:12:26 -0700121 // Show only these settings for restricted users
122 private int[] SETTINGS_FOR_RESTRICTED = {
Amith Yamasani32630392012-08-10 19:31:39 -0700123 R.id.wireless_section,
Amith Yamasanib810a0d2012-03-25 10:12:26 -0700124 R.id.wifi_settings,
125 R.id.bluetooth_settings,
Jeff Sharkey38305fb2012-09-14 16:26:51 -0700126 R.id.data_usage_settings,
Amith Yamasani9627a8e2012-09-23 12:54:14 -0700127 R.id.wireless_settings,
Amith Yamasani32630392012-08-10 19:31:39 -0700128 R.id.device_section,
Amith Yamasanib810a0d2012-03-25 10:12:26 -0700129 R.id.sound_settings,
130 R.id.display_settings,
Jeff Sharkey90c8b202012-08-30 15:20:10 -0700131 R.id.storage_settings,
Dianne Hackborn271c8b02012-08-20 17:24:39 -0700132 R.id.application_settings,
Dianne Hackborn52e56a22012-09-12 17:02:23 -0700133 R.id.battery_settings,
Amith Yamasani32630392012-08-10 19:31:39 -0700134 R.id.personal_section,
Amith Yamasani9627a8e2012-09-23 12:54:14 -0700135 R.id.location_settings,
Amith Yamasani3deeeb72012-04-05 14:44:48 -0700136 R.id.security_settings,
Amith Yamasani9627a8e2012-09-23 12:54:14 -0700137 R.id.language_settings,
Amith Yamasani0ca80fe2013-06-03 16:41:03 -0700138 R.id.restriction_settings,
Amith Yamasanidc6bfa62012-09-06 18:04:06 -0700139 R.id.user_settings,
Amith Yamasanid1ab8282012-05-18 09:50:08 -0700140 R.id.account_settings,
Amith Yamasani32630392012-08-10 19:31:39 -0700141 R.id.account_add,
142 R.id.system_section,
Amith Yamasani9627a8e2012-09-23 12:54:14 -0700143 R.id.date_time_settings,
Jeff Brown9e143f52012-09-19 20:46:07 -0700144 R.id.about_settings,
Svetoslav Ganovd4c7b492013-06-11 21:15:11 -0700145 R.id.accessibility_settings,
146 R.id.print_settings
Amith Yamasanib810a0d2012-03-25 10:12:26 -0700147 };
148
Dianne Hackborncaefa9b2012-10-10 15:05:42 -0700149 private SharedPreferences mDevelopmentPreferences;
150 private SharedPreferences.OnSharedPreferenceChangeListener mDevelopmentPreferencesListener;
151
Amith Yamasani02cf71a2010-09-21 15:48:52 -0700152 // TODO: Update Call Settings based on airplane mode state.
Amith Yamasanib61cf512010-09-12 08:17:50 -0700153
Amith Yamasani5203bdf2010-11-04 09:59:44 -0700154 protected HashMap<Integer, Integer> mHeaderIndexMap = new HashMap<Integer, Integer>();
155
Amith Yamasanid1ab8282012-05-18 09:50:08 -0700156 private AuthenticatorHelper mAuthenticatorHelper;
157 private Header mLastHeader;
Amith Yamasani86708a82012-06-06 20:23:08 -0700158 private boolean mListeningToAccountUpdates;
Amith Yamasanid1ab8282012-05-18 09:50:08 -0700159
Jaewan Kima3fe77b2013-06-04 21:17:40 +0900160 private boolean mBatteryPresent = true;
161 private BroadcastReceiver mBatteryInfoReceiver = new BroadcastReceiver() {
162
163 @Override
164 public void onReceive(Context context, Intent intent) {
165 String action = intent.getAction();
166 if (Intent.ACTION_BATTERY_CHANGED.equals(action)) {
167 boolean batteryPresent = Utils.isBatteryPresent(intent);
168
169 if (mBatteryPresent != batteryPresent) {
170 mBatteryPresent = batteryPresent;
171 invalidateHeaders();
172 }
173 }
174 }
175 };
176
Amith Yamasani5203bdf2010-11-04 09:59:44 -0700177 @Override
178 protected void onCreate(Bundle savedInstanceState) {
Jeff Sharkeycc0d26b2012-11-27 16:42:27 -0800179 if (getIntent().hasExtra(EXTRA_UI_OPTIONS)) {
180 getWindow().setUiOptions(getIntent().getIntExtra(EXTRA_UI_OPTIONS, 0));
Jeff Sharkey54d0af52011-08-11 18:26:57 -0700181 }
Jeff Sharkey9fab0da2011-07-09 17:52:31 -0700182
Amith Yamasanid1ab8282012-05-18 09:50:08 -0700183 mAuthenticatorHelper = new AuthenticatorHelper();
184 mAuthenticatorHelper.updateAuthDescriptions(this);
185 mAuthenticatorHelper.onAccountsUpdated(this, null);
186
Dianne Hackborncaefa9b2012-10-10 15:05:42 -0700187 mDevelopmentPreferences = getSharedPreferences(DevelopmentSettings.PREF_FILE,
188 Context.MODE_PRIVATE);
189
Amith Yamasani5203bdf2010-11-04 09:59:44 -0700190 getMetaData();
Amith Yamasanic9fdfa82010-12-14 14:38:16 -0800191 mInLocalHeaderSwitch = true;
Amith Yamasani5203bdf2010-11-04 09:59:44 -0700192 super.onCreate(savedInstanceState);
Amith Yamasanic9fdfa82010-12-14 14:38:16 -0800193 mInLocalHeaderSwitch = false;
Amith Yamasani5203bdf2010-11-04 09:59:44 -0700194
Gilles Debunne3661b622011-06-27 11:19:16 -0700195 if (!onIsHidingHeaders() && onIsMultiPane()) {
Amith Yamasanid1ab8282012-05-18 09:50:08 -0700196 highlightHeader(mTopLevelHeaderId);
Amith Yamasani72aa19d2010-12-09 06:07:12 -0800197 // Force the title so that it doesn't get overridden by a direct launch of
198 // a specific settings screen.
199 setTitle(R.string.settings_label);
200 }
Amith Yamasanic9fdfa82010-12-14 14:38:16 -0800201
202 // Retrieve any saved state
203 if (savedInstanceState != null) {
204 mCurrentHeader = savedInstanceState.getParcelable(SAVE_KEY_CURRENT_HEADER);
205 mParentHeader = savedInstanceState.getParcelable(SAVE_KEY_PARENT_HEADER);
206 }
207
208 // If the current header was saved, switch to it
209 if (savedInstanceState != null && mCurrentHeader != null) {
210 //switchToHeaderLocal(mCurrentHeader);
211 showBreadCrumbs(mCurrentHeader.title, null);
212 }
213
214 if (mParentHeader != null) {
215 setParentTitle(mParentHeader.title, null, new OnClickListener() {
Maggie Benthall0c5a4012013-03-14 17:41:27 -0400216 @Override
Amith Yamasanic9fdfa82010-12-14 14:38:16 -0800217 public void onClick(View v) {
218 switchToParent(mParentHeader.fragment);
219 }
220 });
221 }
Gilles Debunnedc7101f2011-06-27 12:00:49 -0700222
Amith Yamasani3d384f42012-05-11 15:22:04 -0700223 // Override up navigation for multi-pane, since we handle it in the fragment breadcrumbs
224 if (onIsMultiPane()) {
225 getActionBar().setDisplayHomeAsUpEnabled(false);
226 getActionBar().setHomeButtonEnabled(false);
227 }
Amith Yamasanic9fdfa82010-12-14 14:38:16 -0800228 }
229
230 @Override
231 protected void onSaveInstanceState(Bundle outState) {
232 super.onSaveInstanceState(outState);
233
234 // Save the current fragment, if it is the same as originally launched
235 if (mCurrentHeader != null) {
236 outState.putParcelable(SAVE_KEY_CURRENT_HEADER, mCurrentHeader);
237 }
238 if (mParentHeader != null) {
239 outState.putParcelable(SAVE_KEY_PARENT_HEADER, mParentHeader);
240 }
241 }
242
Gilles Debunnee78c1872011-06-20 15:00:07 -0700243 @Override
244 public void onResume() {
245 super.onResume();
246
Dianne Hackborncaefa9b2012-10-10 15:05:42 -0700247 mDevelopmentPreferencesListener = new SharedPreferences.OnSharedPreferenceChangeListener() {
248 @Override
249 public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
250 invalidateHeaders();
251 }
252 };
253 mDevelopmentPreferences.registerOnSharedPreferenceChangeListener(
254 mDevelopmentPreferencesListener);
255
Gilles Debunnee78c1872011-06-20 15:00:07 -0700256 ListAdapter listAdapter = getListAdapter();
257 if (listAdapter instanceof HeaderAdapter) {
258 ((HeaderAdapter) listAdapter).resume();
259 }
Amith Yamasaniea7b28c2012-06-20 13:51:40 -0700260 invalidateHeaders();
Jaewan Kima3fe77b2013-06-04 21:17:40 +0900261
262 registerReceiver(mBatteryInfoReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
Gilles Debunnee78c1872011-06-20 15:00:07 -0700263 }
264
265 @Override
266 public void onPause() {
267 super.onPause();
268
Jaewan Kima3fe77b2013-06-04 21:17:40 +0900269 unregisterReceiver(mBatteryInfoReceiver);
270
Gilles Debunnee78c1872011-06-20 15:00:07 -0700271 ListAdapter listAdapter = getListAdapter();
272 if (listAdapter instanceof HeaderAdapter) {
273 ((HeaderAdapter) listAdapter).pause();
Amith Yamasani86708a82012-06-06 20:23:08 -0700274 }
Dianne Hackborncaefa9b2012-10-10 15:05:42 -0700275
276 mDevelopmentPreferences.unregisterOnSharedPreferenceChangeListener(
277 mDevelopmentPreferencesListener);
278 mDevelopmentPreferencesListener = null;
Amith Yamasani86708a82012-06-06 20:23:08 -0700279 }
280
281 @Override
282 public void onDestroy() {
283 super.onDestroy();
284 if (mListeningToAccountUpdates) {
Amith Yamasani56821db2012-06-05 13:20:45 -0700285 AccountManager.get(this).removeOnAccountsUpdatedListener(this);
Gilles Debunnee78c1872011-06-20 15:00:07 -0700286 }
287 }
288
Amith Yamasania677ee22013-07-26 13:38:41 -0700289 private static final String[] ENTRY_FRAGMENTS = {
290 WirelessSettings.class.getName(),
291 WifiSettings.class.getName(),
292 AdvancedWifiSettings.class.getName(),
293 BluetoothSettings.class.getName(),
294 TetherSettings.class.getName(),
295 WifiP2pSettings.class.getName(),
296 VpnSettings.class.getName(),
297 DateTimeSettings.class.getName(),
298 LocalePicker.class.getName(),
299 InputMethodAndLanguageSettings.class.getName(),
300 SpellCheckersSettings.class.getName(),
301 UserDictionaryList.class.getName(),
302 UserDictionarySettings.class.getName(),
303 SoundSettings.class.getName(),
304 DisplaySettings.class.getName(),
305 DeviceInfoSettings.class.getName(),
306 ManageApplications.class.getName(),
307 NotificationStation.class.getName(),
308 AppOpsSummary.class.getName(),
309 LocationSettings.class.getName(),
310 SecuritySettings.class.getName(),
311 PrivacySettings.class.getName(),
312 DeviceAdminSettings.class.getName(),
313 AccessibilitySettings.class.getName(),
314 TextToSpeechSettings.class.getName(),
315 Memory.class.getName(),
316 DevelopmentSettings.class.getName(),
317 UsbSettings.class.getName(),
318 AndroidBeam.class.getName(),
319 WifiDisplaySettings.class.getName(),
320 PowerUsageSummary.class.getName(),
321 AccountSyncSettings.class.getName(),
322 CryptKeeperSettings.class.getName(),
323 DataUsageSummary.class.getName(),
324 DreamSettings.class.getName(),
325 UserSettings.class.getName(),
326 NotificationAccessSettings.class.getName(),
327 };
328
329 @Override
330 protected boolean isValidFragment(String fragmentName) {
331 // Almost all fragments are wrapped in this,
332 // except for a few that have their own activities.
333 for (int i = 0; i < ENTRY_FRAGMENTS.length; i++) {
334 if (ENTRY_FRAGMENTS[i].equals(fragmentName)) return true;
335 }
336 return false;
337 }
338
Amith Yamasanic9fdfa82010-12-14 14:38:16 -0800339 private void switchToHeaderLocal(Header header) {
340 mInLocalHeaderSwitch = true;
341 switchToHeader(header);
342 mInLocalHeaderSwitch = false;
343 }
344
345 @Override
346 public void switchToHeader(Header header) {
347 if (!mInLocalHeaderSwitch) {
348 mCurrentHeader = null;
349 mParentHeader = null;
350 }
351 super.switchToHeader(header);
352 }
353
354 /**
355 * Switch to parent fragment and store the grand parent's info
Jake Hamby2748fc22011-01-12 15:06:28 -0800356 * @param className name of the activity wrapper for the parent fragment.
Amith Yamasanic9fdfa82010-12-14 14:38:16 -0800357 */
358 private void switchToParent(String className) {
359 final ComponentName cn = new ComponentName(this, className);
360 try {
361 final PackageManager pm = getPackageManager();
362 final ActivityInfo parentInfo = pm.getActivityInfo(cn, PackageManager.GET_META_DATA);
363
364 if (parentInfo != null && parentInfo.metaData != null) {
365 String fragmentClass = parentInfo.metaData.getString(META_DATA_KEY_FRAGMENT_CLASS);
366 CharSequence fragmentTitle = parentInfo.loadLabel(pm);
367 Header parentHeader = new Header();
368 parentHeader.fragment = fragmentClass;
369 parentHeader.title = fragmentTitle;
370 mCurrentHeader = parentHeader;
371
372 switchToHeaderLocal(parentHeader);
Amith Yamasanid1ab8282012-05-18 09:50:08 -0700373 highlightHeader(mTopLevelHeaderId);
Amith Yamasanic9fdfa82010-12-14 14:38:16 -0800374
375 mParentHeader = new Header();
376 mParentHeader.fragment
377 = parentInfo.metaData.getString(META_DATA_KEY_PARENT_FRAGMENT_CLASS);
378 mParentHeader.title = parentInfo.metaData.getString(META_DATA_KEY_PARENT_TITLE);
379 }
380 } catch (NameNotFoundException nnfe) {
Gilles Debunnee78c1872011-06-20 15:00:07 -0700381 Log.w(LOG_TAG, "Could not find parent activity : " + className);
Amith Yamasanic9fdfa82010-12-14 14:38:16 -0800382 }
Amith Yamasani5203bdf2010-11-04 09:59:44 -0700383 }
384
Amith Yamasani3965ae62010-11-15 14:45:19 -0800385 @Override
386 public void onNewIntent(Intent intent) {
387 super.onNewIntent(intent);
388
389 // If it is not launched from history, then reset to top-level
Amith Yamasanief617232012-10-09 16:57:25 -0700390 if ((intent.getFlags() & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) == 0) {
391 if (mFirstHeader != null && !onIsHidingHeaders() && onIsMultiPane()) {
392 switchToHeaderLocal(mFirstHeader);
393 }
394 getListView().setSelectionFromTop(0, 0);
Amith Yamasani3965ae62010-11-15 14:45:19 -0800395 }
396 }
397
Amith Yamasanid1ab8282012-05-18 09:50:08 -0700398 private void highlightHeader(int id) {
399 if (id != 0) {
400 Integer index = mHeaderIndexMap.get(id);
Amith Yamasani5203bdf2010-11-04 09:59:44 -0700401 if (index != null) {
402 getListView().setItemChecked(index, true);
Amith Yamasanief617232012-10-09 16:57:25 -0700403 if (isMultiPane()) {
404 getListView().smoothScrollToPosition(index);
405 }
Amith Yamasani5203bdf2010-11-04 09:59:44 -0700406 }
407 }
408 }
409
Amith Yamasanie0e4fc22010-10-05 11:49:51 -0700410 @Override
411 public Intent getIntent() {
Gilles Debunnee78c1872011-06-20 15:00:07 -0700412 Intent superIntent = super.getIntent();
413 String startingFragment = getStartingFragmentClass(superIntent);
Gilles Debunne3661b622011-06-27 11:19:16 -0700414 // This is called from super.onCreate, isMultiPane() is not yet reliable
415 // Do not use onIsHidingHeaders either, which relies itself on this method
416 if (startingFragment != null && !onIsMultiPane()) {
Gilles Debunnee78c1872011-06-20 15:00:07 -0700417 Intent modIntent = new Intent(superIntent);
Amith Yamasanie0e4fc22010-10-05 11:49:51 -0700418 modIntent.putExtra(EXTRA_SHOW_FRAGMENT, startingFragment);
Gilles Debunnee78c1872011-06-20 15:00:07 -0700419 Bundle args = superIntent.getExtras();
Dianne Hackbornf4eb85b2010-10-29 16:53:04 -0700420 if (args != null) {
421 args = new Bundle(args);
422 } else {
423 args = new Bundle();
424 }
Gilles Debunnee78c1872011-06-20 15:00:07 -0700425 args.putParcelable("intent", superIntent);
426 modIntent.putExtra(EXTRA_SHOW_FRAGMENT_ARGUMENTS, superIntent.getExtras());
Amith Yamasanie0e4fc22010-10-05 11:49:51 -0700427 return modIntent;
428 }
Gilles Debunnee78c1872011-06-20 15:00:07 -0700429 return superIntent;
Amith Yamasanie0e4fc22010-10-05 11:49:51 -0700430 }
431
Amith Yamasani02cf71a2010-09-21 15:48:52 -0700432 /**
Amith Yamasani379d9b02010-09-27 12:03:59 -0700433 * Checks if the component name in the intent is different from the Settings class and
434 * returns the class name to load as a fragment.
435 */
Amith Yamasani5203bdf2010-11-04 09:59:44 -0700436 protected String getStartingFragmentClass(Intent intent) {
437 if (mFragmentClass != null) return mFragmentClass;
438
Dianne Hackbornf4eb85b2010-10-29 16:53:04 -0700439 String intentClass = intent.getComponent().getClassName();
Amith Yamasani379d9b02010-09-27 12:03:59 -0700440 if (intentClass.equals(getClass().getName())) return null;
441
Dianne Hackbornee293792010-11-01 12:32:33 -0700442 if ("com.android.settings.ManageApplications".equals(intentClass)
443 || "com.android.settings.RunningServices".equals(intentClass)
444 || "com.android.settings.applications.StorageUse".equals(intentClass)) {
Gilles Debunnee78c1872011-06-20 15:00:07 -0700445 // Old names of manage apps.
Dianne Hackbornf4eb85b2010-10-29 16:53:04 -0700446 intentClass = com.android.settings.applications.ManageApplications.class.getName();
447 }
448
Amith Yamasani379d9b02010-09-27 12:03:59 -0700449 return intentClass;
450 }
451
452 /**
453 * Override initial header when an activity-alias is causing Settings to be launched
454 * for a specific fragment encoded in the android:name parameter.
455 */
456 @Override
457 public Header onGetInitialHeader() {
458 String fragmentClass = getStartingFragmentClass(super.getIntent());
459 if (fragmentClass != null) {
460 Header header = new Header();
461 header.fragment = fragmentClass;
Amith Yamasanic9fdfa82010-12-14 14:38:16 -0800462 header.title = getTitle();
Amith Yamasanie0e4fc22010-10-05 11:49:51 -0700463 header.fragmentArguments = getIntent().getExtras();
Amith Yamasanic9fdfa82010-12-14 14:38:16 -0800464 mCurrentHeader = header;
Amith Yamasani379d9b02010-09-27 12:03:59 -0700465 return header;
466 }
Gilles Debunnee78c1872011-06-20 15:00:07 -0700467
Gilles Debunneb396c9b2011-06-22 16:07:29 -0700468 return mFirstHeader;
Amith Yamasani379d9b02010-09-27 12:03:59 -0700469 }
470
Dianne Hackbornb7258182011-03-15 16:23:55 -0700471 @Override
Dianne Hackborn48147dc2011-03-18 12:29:41 -0700472 public Intent onBuildStartFragmentIntent(String fragmentName, Bundle args,
473 int titleRes, int shortTitleRes) {
474 Intent intent = super.onBuildStartFragmentIntent(fragmentName, args,
475 titleRes, shortTitleRes);
Jeff Sharkey9fab0da2011-07-09 17:52:31 -0700476
Jeff Sharkeycc0d26b2012-11-27 16:42:27 -0800477 // Some fragments want split ActionBar; these should stay in sync with
478 // uiOptions for fragments also defined as activities in manifest.
479 if (WifiSettings.class.getName().equals(fragmentName) ||
480 WifiP2pSettings.class.getName().equals(fragmentName) ||
Jeff Sharkey0c3634c2013-02-20 12:35:16 -0800481 WifiDisplaySettings.class.getName().equals(fragmentName) ||
Jeff Sharkeycc0d26b2012-11-27 16:42:27 -0800482 BluetoothSettings.class.getName().equals(fragmentName) ||
483 DreamSettings.class.getName().equals(fragmentName) ||
484 ToggleAccessibilityServicePreferenceFragment.class.getName().equals(fragmentName)) {
485 intent.putExtra(EXTRA_UI_OPTIONS, ActivityInfo.UIOPTION_SPLIT_ACTION_BAR_WHEN_NARROW);
Jeff Sharkey9fab0da2011-07-09 17:52:31 -0700486 }
487
Dianne Hackbornb7258182011-03-15 16:23:55 -0700488 intent.setClass(this, SubSettings.class);
489 return intent;
490 }
Amith Yamasaniea7b28c2012-06-20 13:51:40 -0700491
Amith Yamasani379d9b02010-09-27 12:03:59 -0700492 /**
Amith Yamasani02cf71a2010-09-21 15:48:52 -0700493 * Populate the activity with the top-level headers.
494 */
Amith Yamasanid7993472010-08-18 13:59:28 -0700495 @Override
Gilles Debunnee78c1872011-06-20 15:00:07 -0700496 public void onBuildHeaders(List<Header> headers) {
497 loadHeadersFromResource(R.xml.settings_headers, headers);
Gilles Debunnee78c1872011-06-20 15:00:07 -0700498 updateHeaderList(headers);
Amith Yamasani02cf71a2010-09-21 15:48:52 -0700499 }
Amith Yamasanid7993472010-08-18 13:59:28 -0700500
Amith Yamasani02cf71a2010-09-21 15:48:52 -0700501 private void updateHeaderList(List<Header> target) {
Dianne Hackborncaefa9b2012-10-10 15:05:42 -0700502 final boolean showDev = mDevelopmentPreferences.getBoolean(
503 DevelopmentSettings.PREF_SHOW,
504 android.os.Build.TYPE.equals("eng"));
Amith Yamasani02cf71a2010-09-21 15:48:52 -0700505 int i = 0;
Maggie Benthall0c5a4012013-03-14 17:41:27 -0400506
507 final UserManager um = (UserManager) getSystemService(Context.USER_SERVICE);
Dianne Hackborncaefa9b2012-10-10 15:05:42 -0700508 mHeaderIndexMap.clear();
Amith Yamasani02cf71a2010-09-21 15:48:52 -0700509 while (i < target.size()) {
510 Header header = target.get(i);
Amith Yamasani5203bdf2010-11-04 09:59:44 -0700511 // Ids are integers, so downcasting
512 int id = (int) header.id;
Chris Wren2bc32ae2012-09-24 14:23:46 -0400513 if (id == R.id.operator_settings || id == R.id.manufacturer_settings) {
Amith Yamasani02cf71a2010-09-21 15:48:52 -0700514 Utils.updateHeaderToSpecificActivityFromMetaDataOrRemove(this, target, header);
Gilles Debunne2454f492011-06-21 16:16:06 -0700515 } else if (id == R.id.wifi_settings) {
516 // Remove WiFi Settings if WiFi service is not available.
517 if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI)) {
Dianne Hackborncaefa9b2012-10-10 15:05:42 -0700518 target.remove(i);
Gilles Debunne2454f492011-06-21 16:16:06 -0700519 }
Gilles Debunnee78c1872011-06-20 15:00:07 -0700520 } else if (id == R.id.bluetooth_settings) {
521 // Remove Bluetooth Settings if Bluetooth service is not available.
Gilles Debunne2454f492011-06-21 16:16:06 -0700522 if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH)) {
Dianne Hackborncaefa9b2012-10-10 15:05:42 -0700523 target.remove(i);
Gilles Debunnee78c1872011-06-20 15:00:07 -0700524 }
Jeff Sharkey34e964d2012-04-21 15:41:48 -0700525 } else if (id == R.id.data_usage_settings) {
526 // Remove data usage when kernel module not enabled
527 final INetworkManagementService netManager = INetworkManagementService.Stub
528 .asInterface(ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE));
529 try {
530 if (!netManager.isBandwidthControlEnabled()) {
Dianne Hackborncaefa9b2012-10-10 15:05:42 -0700531 target.remove(i);
Jeff Sharkey34e964d2012-04-21 15:41:48 -0700532 }
533 } catch (RemoteException e) {
534 // ignored
535 }
Jaewan Kima3fe77b2013-06-04 21:17:40 +0900536 } else if (id == R.id.battery_settings) {
537 // Remove battery settings when battery is not available. (e.g. TV)
538
539 if (!mBatteryPresent) {
540 target.remove(i);
541 }
Amith Yamasanid1ab8282012-05-18 09:50:08 -0700542 } else if (id == R.id.account_settings) {
543 int headerIndex = i + 1;
544 i = insertAccountsHeaders(target, headerIndex);
Amith Yamasanib810a0d2012-03-25 10:12:26 -0700545 } else if (id == R.id.user_settings) {
Amith Yamasanidc6bfa62012-09-06 18:04:06 -0700546 if (!UserHandle.MU_ENABLED
Jeff Sharkey44202462012-09-19 13:13:45 -0700547 || !UserManager.supportsMultipleUsers()
Amith Yamasanib810a0d2012-03-25 10:12:26 -0700548 || Utils.isMonkeyRunning()) {
Dianne Hackborncaefa9b2012-10-10 15:05:42 -0700549 target.remove(i);
550 }
551 } else if (id == R.id.development_settings) {
552 if (!showDev) {
553 target.remove(i);
Amith Yamasanib810a0d2012-03-25 10:12:26 -0700554 }
Maggie Benthall0c5a4012013-03-14 17:41:27 -0400555 } else if (id == R.id.account_add) {
556 if (um.hasUserRestriction(UserManager.DISALLOW_MODIFY_ACCOUNTS)) {
557 target.remove(i);
558 }
Amith Yamasani0ca80fe2013-06-03 16:41:03 -0700559 } else if (id == R.id.restriction_settings) {
Amith Yamasanid5b1a292013-07-22 16:51:39 -0700560 if (um.isLinkedUser()
561 || um.hasUserRestriction(UserManager.DISALLOW_APP_RESTRICTIONS)) {
Amith Yamasani0ca80fe2013-06-03 16:41:03 -0700562 target.remove(i);
563 }
Amith Yamasanib810a0d2012-03-25 10:12:26 -0700564 }
Dianne Hackborncaefa9b2012-10-10 15:05:42 -0700565
Jaewan Kimbb0e6212013-02-04 15:36:17 +0900566 if (i < target.size() && target.get(i) == header
Amith Yamasanib99f8642012-10-10 21:41:12 -0700567 && UserHandle.MU_ENABLED && UserHandle.myUserId() != 0
Amith Yamasanib810a0d2012-03-25 10:12:26 -0700568 && !ArrayUtils.contains(SETTINGS_FOR_RESTRICTED, id)) {
Dianne Hackborncaefa9b2012-10-10 15:05:42 -0700569 target.remove(i);
Amith Yamasanid7993472010-08-18 13:59:28 -0700570 }
Gilles Debunnee78c1872011-06-20 15:00:07 -0700571
Amith Yamasani5203bdf2010-11-04 09:59:44 -0700572 // Increment if the current one wasn't removed by the Utils code.
Jaewan Kimbb0e6212013-02-04 15:36:17 +0900573 if (i < target.size() && target.get(i) == header) {
Amith Yamasani3965ae62010-11-15 14:45:19 -0800574 // Hold on to the first header, when we need to reset to the top-level
Gilles Debunneb396c9b2011-06-22 16:07:29 -0700575 if (mFirstHeader == null &&
576 HeaderAdapter.getHeaderType(header) != HeaderAdapter.HEADER_TYPE_CATEGORY) {
577 mFirstHeader = header;
578 }
Amith Yamasani5203bdf2010-11-04 09:59:44 -0700579 mHeaderIndexMap.put(id, i);
Amith Yamasani02cf71a2010-09-21 15:48:52 -0700580 i++;
Amith Yamasani5203bdf2010-11-04 09:59:44 -0700581 }
Amith Yamasanid7993472010-08-18 13:59:28 -0700582 }
583 }
584
Amith Yamasanid1ab8282012-05-18 09:50:08 -0700585 private int insertAccountsHeaders(List<Header> target, int headerIndex) {
586 String[] accountTypes = mAuthenticatorHelper.getEnabledAccountTypes();
587 List<Header> accountHeaders = new ArrayList<Header>(accountTypes.length);
588 for (String accountType : accountTypes) {
589 CharSequence label = mAuthenticatorHelper.getLabelForType(this, accountType);
Brian Muramatsuc28af522012-06-28 14:25:14 -0700590 if (label == null) {
591 continue;
592 }
593
Amith Yamasani3882c2e2012-06-07 17:03:20 -0700594 Account[] accounts = AccountManager.get(this).getAccountsByType(accountType);
595 boolean skipToAccount = accounts.length == 1
596 && !mAuthenticatorHelper.hasAccountPreferences(accountType);
Amith Yamasanid1ab8282012-05-18 09:50:08 -0700597 Header accHeader = new Header();
598 accHeader.title = label;
599 if (accHeader.extras == null) {
600 accHeader.extras = new Bundle();
601 }
Amith Yamasani3882c2e2012-06-07 17:03:20 -0700602 if (skipToAccount) {
603 accHeader.breadCrumbTitleRes = R.string.account_sync_settings_title;
604 accHeader.breadCrumbShortTitleRes = R.string.account_sync_settings_title;
605 accHeader.fragment = AccountSyncSettings.class.getName();
606 accHeader.fragmentArguments = new Bundle();
607 // Need this for the icon
608 accHeader.extras.putString(ManageAccountsSettings.KEY_ACCOUNT_TYPE, accountType);
609 accHeader.extras.putParcelable(AccountSyncSettings.ACCOUNT_KEY, accounts[0]);
610 accHeader.fragmentArguments.putParcelable(AccountSyncSettings.ACCOUNT_KEY,
611 accounts[0]);
612 } else {
613 accHeader.breadCrumbTitle = label;
614 accHeader.breadCrumbShortTitle = label;
615 accHeader.fragment = ManageAccountsSettings.class.getName();
616 accHeader.fragmentArguments = new Bundle();
617 accHeader.extras.putString(ManageAccountsSettings.KEY_ACCOUNT_TYPE, accountType);
618 accHeader.fragmentArguments.putString(ManageAccountsSettings.KEY_ACCOUNT_TYPE,
619 accountType);
620 if (!isMultiPane()) {
621 accHeader.fragmentArguments.putString(ManageAccountsSettings.KEY_ACCOUNT_LABEL,
622 label.toString());
623 }
Amith Yamasanid1ab8282012-05-18 09:50:08 -0700624 }
625 accountHeaders.add(accHeader);
626 }
627
628 // Sort by label
629 Collections.sort(accountHeaders, new Comparator<Header>() {
630 @Override
631 public int compare(Header h1, Header h2) {
632 return h1.title.toString().compareTo(h2.title.toString());
633 }
634 });
635
636 for (Header header : accountHeaders) {
637 target.add(headerIndex++, header);
638 }
Amith Yamasani86708a82012-06-06 20:23:08 -0700639 if (!mListeningToAccountUpdates) {
640 AccountManager.get(this).addOnAccountsUpdatedListener(this, null, true);
641 mListeningToAccountUpdates = true;
642 }
Amith Yamasanid1ab8282012-05-18 09:50:08 -0700643 return headerIndex;
644 }
645
Amith Yamasani5203bdf2010-11-04 09:59:44 -0700646 private void getMetaData() {
647 try {
648 ActivityInfo ai = getPackageManager().getActivityInfo(getComponentName(),
649 PackageManager.GET_META_DATA);
650 if (ai == null || ai.metaData == null) return;
651 mTopLevelHeaderId = ai.metaData.getInt(META_DATA_KEY_HEADER_ID);
652 mFragmentClass = ai.metaData.getString(META_DATA_KEY_FRAGMENT_CLASS);
Amith Yamasanid1ab8282012-05-18 09:50:08 -0700653
Amith Yamasanic9fdfa82010-12-14 14:38:16 -0800654 // Check if it has a parent specified and create a Header object
655 final int parentHeaderTitleRes = ai.metaData.getInt(META_DATA_KEY_PARENT_TITLE);
656 String parentFragmentClass = ai.metaData.getString(META_DATA_KEY_PARENT_FRAGMENT_CLASS);
657 if (parentFragmentClass != null) {
658 mParentHeader = new Header();
659 mParentHeader.fragment = parentFragmentClass;
660 if (parentHeaderTitleRes != 0) {
661 mParentHeader.title = getResources().getString(parentHeaderTitleRes);
662 }
663 }
Amith Yamasani5203bdf2010-11-04 09:59:44 -0700664 } catch (NameNotFoundException nnfe) {
Gilles Debunnee78c1872011-06-20 15:00:07 -0700665 // No recovery
Amith Yamasani5203bdf2010-11-04 09:59:44 -0700666 }
667 }
668
Amith Yamasani9e3a4702011-01-11 09:09:26 -0800669 @Override
670 public boolean hasNextButton() {
671 return super.hasNextButton();
672 }
673
674 @Override
675 public Button getNextButton() {
676 return super.getNextButton();
677 }
678
Gilles Debunnee78c1872011-06-20 15:00:07 -0700679 private static class HeaderAdapter extends ArrayAdapter<Header> {
680 static final int HEADER_TYPE_CATEGORY = 0;
681 static final int HEADER_TYPE_NORMAL = 1;
682 static final int HEADER_TYPE_SWITCH = 2;
683 private static final int HEADER_TYPE_COUNT = HEADER_TYPE_SWITCH + 1;
684
685 private final WifiEnabler mWifiEnabler;
686 private final BluetoothEnabler mBluetoothEnabler;
Amith Yamasanid1ab8282012-05-18 09:50:08 -0700687 private AuthenticatorHelper mAuthHelper;
Gilles Debunnee78c1872011-06-20 15:00:07 -0700688
689 private static class HeaderViewHolder {
690 ImageView icon;
691 TextView title;
692 TextView summary;
693 Switch switch_;
694 }
695
696 private LayoutInflater mInflater;
697
698 static int getHeaderType(Header header) {
699 if (header.fragment == null && header.intent == null) {
700 return HEADER_TYPE_CATEGORY;
701 } else if (header.id == R.id.wifi_settings || header.id == R.id.bluetooth_settings) {
702 return HEADER_TYPE_SWITCH;
703 } else {
704 return HEADER_TYPE_NORMAL;
705 }
706 }
707
708 @Override
709 public int getItemViewType(int position) {
710 Header header = getItem(position);
711 return getHeaderType(header);
712 }
713
714 @Override
715 public boolean areAllItemsEnabled() {
716 return false; // because of categories
717 }
718
719 @Override
720 public boolean isEnabled(int position) {
721 return getItemViewType(position) != HEADER_TYPE_CATEGORY;
722 }
723
724 @Override
725 public int getViewTypeCount() {
726 return HEADER_TYPE_COUNT;
727 }
728
729 @Override
730 public boolean hasStableIds() {
731 return true;
732 }
733
Amith Yamasanid1ab8282012-05-18 09:50:08 -0700734 public HeaderAdapter(Context context, List<Header> objects,
735 AuthenticatorHelper authenticatorHelper) {
Gilles Debunnee78c1872011-06-20 15:00:07 -0700736 super(context, 0, objects);
Amith Yamasanid1ab8282012-05-18 09:50:08 -0700737
738 mAuthHelper = authenticatorHelper;
Gilles Debunnee78c1872011-06-20 15:00:07 -0700739 mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
Amith Yamasanid1ab8282012-05-18 09:50:08 -0700740
Gilles Debunneb396c9b2011-06-22 16:07:29 -0700741 // Temp Switches provided as placeholder until the adapter replaces these with actual
Gilles Debunnee78c1872011-06-20 15:00:07 -0700742 // Switches inflated from their layouts. Must be done before adapter is set in super
743 mWifiEnabler = new WifiEnabler(context, new Switch(context));
744 mBluetoothEnabler = new BluetoothEnabler(context, new Switch(context));
745 }
746
747 @Override
748 public View getView(int position, View convertView, ViewGroup parent) {
749 HeaderViewHolder holder;
750 Header header = getItem(position);
751 int headerType = getHeaderType(header);
752 View view = null;
753
754 if (convertView == null) {
755 holder = new HeaderViewHolder();
756 switch (headerType) {
757 case HEADER_TYPE_CATEGORY:
Gilles Debunneb396c9b2011-06-22 16:07:29 -0700758 view = new TextView(getContext(), null,
759 android.R.attr.listSeparatorTextViewStyle);
Gilles Debunnee78c1872011-06-20 15:00:07 -0700760 holder.title = (TextView) view;
761 break;
762
763 case HEADER_TYPE_SWITCH:
Gilles Debunneb396c9b2011-06-22 16:07:29 -0700764 view = mInflater.inflate(R.layout.preference_header_switch_item, parent,
765 false);
Gilles Debunnee78c1872011-06-20 15:00:07 -0700766 holder.icon = (ImageView) view.findViewById(R.id.icon);
Gilles Debunneb396c9b2011-06-22 16:07:29 -0700767 holder.title = (TextView)
768 view.findViewById(com.android.internal.R.id.title);
769 holder.summary = (TextView)
770 view.findViewById(com.android.internal.R.id.summary);
Gilles Debunnee78c1872011-06-20 15:00:07 -0700771 holder.switch_ = (Switch) view.findViewById(R.id.switchWidget);
772 break;
773
774 case HEADER_TYPE_NORMAL:
Gilles Debunneb396c9b2011-06-22 16:07:29 -0700775 view = mInflater.inflate(
Amith Yamasanic8a93172012-06-08 13:35:47 -0700776 R.layout.preference_header_item, parent,
Gilles Debunneb396c9b2011-06-22 16:07:29 -0700777 false);
Amith Yamasanic8a93172012-06-08 13:35:47 -0700778 holder.icon = (ImageView) view.findViewById(R.id.icon);
Gilles Debunneb396c9b2011-06-22 16:07:29 -0700779 holder.title = (TextView)
780 view.findViewById(com.android.internal.R.id.title);
781 holder.summary = (TextView)
782 view.findViewById(com.android.internal.R.id.summary);
Gilles Debunnee78c1872011-06-20 15:00:07 -0700783 break;
784 }
785 view.setTag(holder);
786 } else {
787 view = convertView;
788 holder = (HeaderViewHolder) view.getTag();
789 }
790
791 // All view fields must be updated every time, because the view may be recycled
792 switch (headerType) {
793 case HEADER_TYPE_CATEGORY:
794 holder.title.setText(header.getTitle(getContext().getResources()));
795 break;
796
797 case HEADER_TYPE_SWITCH:
798 // Would need a different treatment if the main menu had more switches
799 if (header.id == R.id.wifi_settings) {
800 mWifiEnabler.setSwitch(holder.switch_);
801 } else {
802 mBluetoothEnabler.setSwitch(holder.switch_);
803 }
804 // No break, fall through on purpose to update common fields
805
806 //$FALL-THROUGH$
807 case HEADER_TYPE_NORMAL:
Amith Yamasani3882c2e2012-06-07 17:03:20 -0700808 if (header.extras != null
809 && header.extras.containsKey(ManageAccountsSettings.KEY_ACCOUNT_TYPE)) {
Amith Yamasanid1ab8282012-05-18 09:50:08 -0700810 String accType = header.extras.getString(
811 ManageAccountsSettings.KEY_ACCOUNT_TYPE);
812 ViewGroup.LayoutParams lp = holder.icon.getLayoutParams();
813 lp.width = getContext().getResources().getDimensionPixelSize(
814 R.dimen.header_icon_width);
815 lp.height = lp.width;
816 holder.icon.setLayoutParams(lp);
817 Drawable icon = mAuthHelper.getDrawableForType(getContext(), accType);
818 holder.icon.setImageDrawable(icon);
819 } else {
820 holder.icon.setImageResource(header.iconRes);
821 }
Gilles Debunnee78c1872011-06-20 15:00:07 -0700822 holder.title.setText(header.getTitle(getContext().getResources()));
823 CharSequence summary = header.getSummary(getContext().getResources());
824 if (!TextUtils.isEmpty(summary)) {
825 holder.summary.setVisibility(View.VISIBLE);
826 holder.summary.setText(summary);
827 } else {
828 holder.summary.setVisibility(View.GONE);
829 }
830 break;
831 }
832
833 return view;
834 }
835
836 public void resume() {
837 mWifiEnabler.resume();
838 mBluetoothEnabler.resume();
839 }
Brian Muramatsuc28af522012-06-28 14:25:14 -0700840
Gilles Debunnee78c1872011-06-20 15:00:07 -0700841 public void pause() {
842 mWifiEnabler.pause();
843 mBluetoothEnabler.pause();
844 }
845 }
846
847 @Override
Amith Yamasanid1ab8282012-05-18 09:50:08 -0700848 public void onHeaderClick(Header header, int position) {
849 boolean revert = false;
850 if (header.id == R.id.account_add) {
851 revert = true;
852 }
853
854 super.onHeaderClick(header, position);
855
856 if (revert && mLastHeader != null) {
857 highlightHeader((int) mLastHeader.id);
858 } else {
859 mLastHeader = header;
860 }
861 }
862
863 @Override
Amith Yamasania4379d62011-07-22 10:34:58 -0700864 public boolean onPreferenceStartFragment(PreferenceFragment caller, Preference pref) {
865 // Override the fragment title for Wallpaper settings
Amith Yamasanidfb65432011-11-29 16:38:14 -0800866 int titleRes = pref.getTitleRes();
Amith Yamasania4379d62011-07-22 10:34:58 -0700867 if (pref.getFragment().equals(WallpaperTypeSettings.class.getName())) {
Amith Yamasanidfb65432011-11-29 16:38:14 -0800868 titleRes = R.string.wallpaper_settings_fragment_title;
Amith Yamasani8666b9e2012-09-27 14:50:13 -0700869 } else if (pref.getFragment().equals(OwnerInfoSettings.class.getName())
870 && UserHandle.myUserId() != UserHandle.USER_OWNER) {
Amith Yamasanib0171712013-04-28 22:13:22 -0700871 if (UserManager.get(this).isLinkedUser()) {
872 titleRes = R.string.profile_info_settings_title;
873 } else {
874 titleRes = R.string.user_info_settings_title;
875 }
Amith Yamasania4379d62011-07-22 10:34:58 -0700876 }
Jean Chalard7dabe452012-05-10 18:08:07 +0900877 startPreferencePanel(pref.getFragment(), pref.getExtras(), titleRes, pref.getTitle(),
878 null, 0);
Amith Yamasania4379d62011-07-22 10:34:58 -0700879 return true;
880 }
881
Maggie Benthall0c5a4012013-03-14 17:41:27 -0400882 @Override
Amith Yamasani3d384f42012-05-11 15:22:04 -0700883 public boolean shouldUpRecreateTask(Intent targetIntent) {
884 return super.shouldUpRecreateTask(new Intent(this, Settings.class));
885 }
886
Amith Yamasania4379d62011-07-22 10:34:58 -0700887 @Override
Gilles Debunnee78c1872011-06-20 15:00:07 -0700888 public void setListAdapter(ListAdapter adapter) {
Amith Yamasaniea7b28c2012-06-20 13:51:40 -0700889 if (adapter == null) {
890 super.setListAdapter(null);
891 } else {
892 super.setListAdapter(new HeaderAdapter(this, getHeaders(), mAuthenticatorHelper));
Gilles Debunnee78c1872011-06-20 15:00:07 -0700893 }
Gilles Debunnee78c1872011-06-20 15:00:07 -0700894 }
895
Amith Yamasani56821db2012-06-05 13:20:45 -0700896 @Override
897 public void onAccountsUpdated(Account[] accounts) {
Jeff Sharkey9ff79c12012-10-03 16:48:17 -0700898 // TODO: watch for package upgrades to invalidate cache; see 7206643
899 mAuthenticatorHelper.updateAuthDescriptions(this);
Amith Yamasani56821db2012-06-05 13:20:45 -0700900 mAuthenticatorHelper.onAccountsUpdated(this, accounts);
901 invalidateHeaders();
902 }
903
Amith Yamasani5203bdf2010-11-04 09:59:44 -0700904 /*
905 * Settings subclasses for launching independently.
906 */
Gilles Debunnee78c1872011-06-20 15:00:07 -0700907 public static class BluetoothSettingsActivity extends Settings { /* empty */ }
908 public static class WirelessSettingsActivity extends Settings { /* empty */ }
909 public static class TetherSettingsActivity extends Settings { /* empty */ }
910 public static class VpnSettingsActivity extends Settings { /* empty */ }
911 public static class DateTimeSettingsActivity extends Settings { /* empty */ }
912 public static class StorageSettingsActivity extends Settings { /* empty */ }
913 public static class WifiSettingsActivity extends Settings { /* empty */ }
repo syncb98463f2011-06-30 10:58:43 -0700914 public static class WifiP2pSettingsActivity extends Settings { /* empty */ }
Gilles Debunnee78c1872011-06-20 15:00:07 -0700915 public static class InputMethodAndLanguageSettingsActivity extends Settings { /* empty */ }
Jeff Browne46c5f32012-04-05 11:42:18 -0700916 public static class KeyboardLayoutPickerActivity extends Settings { /* empty */ }
Gilles Debunnee78c1872011-06-20 15:00:07 -0700917 public static class InputMethodAndSubtypeEnablerActivity extends Settings { /* empty */ }
satoke077d2b2011-07-25 09:38:11 +0900918 public static class SpellCheckersSettingsActivity extends Settings { /* empty */ }
Gilles Debunnee78c1872011-06-20 15:00:07 -0700919 public static class LocalePickerActivity extends Settings { /* empty */ }
920 public static class UserDictionarySettingsActivity extends Settings { /* empty */ }
921 public static class SoundSettingsActivity extends Settings { /* empty */ }
922 public static class DisplaySettingsActivity extends Settings { /* empty */ }
923 public static class DeviceInfoSettingsActivity extends Settings { /* empty */ }
924 public static class ApplicationSettingsActivity extends Settings { /* empty */ }
925 public static class ManageApplicationsActivity extends Settings { /* empty */ }
Dianne Hackborna522a8e2013-01-15 19:02:05 -0800926 public static class AppOpsSummaryActivity extends Settings { /* empty */ }
Gilles Debunnee78c1872011-06-20 15:00:07 -0700927 public static class StorageUseActivity extends Settings { /* empty */ }
928 public static class DevelopmentSettingsActivity extends Settings { /* empty */ }
929 public static class AccessibilitySettingsActivity extends Settings { /* empty */ }
930 public static class SecuritySettingsActivity extends Settings { /* empty */ }
Gilles Debunnea6a8a142011-06-09 11:56:17 -0700931 public static class LocationSettingsActivity extends Settings { /* empty */ }
Gilles Debunnee78c1872011-06-20 15:00:07 -0700932 public static class PrivacySettingsActivity extends Settings { /* empty */ }
Gilles Debunnee78c1872011-06-20 15:00:07 -0700933 public static class RunningServicesActivity extends Settings { /* empty */ }
934 public static class ManageAccountsSettingsActivity extends Settings { /* empty */ }
935 public static class PowerUsageSummaryActivity extends Settings { /* empty */ }
936 public static class AccountSyncSettingsActivity extends Settings { /* empty */ }
937 public static class AccountSyncSettingsInAddAccountActivity extends Settings { /* empty */ }
938 public static class CryptKeeperSettingsActivity extends Settings { /* empty */ }
939 public static class DeviceAdminSettingsActivity extends Settings { /* empty */ }
940 public static class DataUsageSummaryActivity extends Settings { /* empty */ }
Gilles Debunneab189bd2011-07-06 13:10:16 -0700941 public static class AdvancedWifiSettingsActivity extends Settings { /* empty */ }
Gilles Debunneab189bd2011-07-06 13:10:16 -0700942 public static class TextToSpeechSettingsActivity extends Settings { /* empty */ }
Jeff Hamilton3d670de2011-09-21 16:44:36 -0500943 public static class AndroidBeamSettingsActivity extends Settings { /* empty */ }
Jeff Brown9e143f52012-09-19 20:46:07 -0700944 public static class WifiDisplaySettingsActivity extends Settings { /* empty */ }
Daniel Sandler7dee75c2012-11-27 22:41:30 -0500945 public static class DreamSettingsActivity extends Settings { /* empty */ }
Daniel Sandler328e2d22013-01-17 13:14:02 -0500946 public static class NotificationStationActivity extends Settings { /* empty */ }
Amith Yamasani233592b2013-03-01 17:05:23 -0800947 public static class UserSettingsActivity extends Settings { /* empty */ }
Daniel Sandler79b9bfe2013-04-04 14:30:04 -0400948 public static class NotificationAccessSettingsActivity extends Settings { /* empty */ }
Amith Yamasania677ee22013-07-26 13:38:41 -0700949 public static class UsbSettingsActivity extends Settings { /* empty */ }
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800950}