OSDN Git Service

f01f1e86dea243bd2629036caf8617af66902969
[android-x86/packages-apps-Settings.git] / src / com / android / settings / DisplaySettings.java
1 /*
2  * Copyright (C) 2010 The Android Open Source Project
3  * Copyright (C) 2014 The CyanogenMod Project
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18 package com.android.settings;
19 import com.android.internal.logging.MetricsLogger;
20
21 import android.app.AlertDialog;
22 import android.content.DialogInterface;
23 import android.preference.CheckBoxPreference;
24
25 import android.os.UserHandle;
26 import android.view.Display;
27 import android.view.IWindowManager;
28 import android.view.WindowManager;
29 import android.view.WindowManagerGlobal;
30 import android.view.WindowManagerImpl;
31 import android.widget.Toast;
32 import com.android.internal.view.RotationPolicy;
33 import com.android.settings.DropDownPreference.Callback;
34 import com.android.settings.search.BaseSearchIndexProvider;
35 import com.android.settings.search.Indexable;
36
37 import static android.provider.Settings.Secure.CAMERA_GESTURE_DISABLED;
38 import static android.provider.Settings.Secure.DOUBLE_TAP_TO_WAKE;
39 import static android.provider.Settings.Secure.DOZE_ENABLED;
40 import static android.provider.Settings.Secure.WAKE_GESTURE_ENABLED;
41 import static android.provider.Settings.System.SCREEN_BRIGHTNESS_MODE;
42 import static android.provider.Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC;
43 import static android.provider.Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL;
44 import static android.provider.Settings.System.SCREEN_OFF_TIMEOUT;
45
46 import android.app.Activity;
47 import android.app.ActivityManagerNative;
48 import android.app.Dialog;
49 import android.app.IActivityManager;
50 import android.app.ProgressDialog;
51 import android.app.UiModeManager;
52 import android.app.admin.DevicePolicyManager;
53 import android.content.ContentResolver;
54 import android.content.Context;
55 import android.content.res.Configuration;
56 import android.content.res.Resources;
57 import android.hardware.Sensor;
58 import android.hardware.SensorManager;
59 import android.os.AsyncTask;
60 import android.os.Build;
61 import android.database.ContentObserver;
62 import android.os.Bundle;
63 import android.os.Handler;
64 import android.os.RemoteException;
65 import android.os.ServiceManager;
66 import android.os.SystemProperties;
67 import android.preference.ListPreference;
68 import android.preference.Preference;
69 import android.preference.PreferenceManager;
70 import android.preference.Preference.OnPreferenceClickListener;
71 import android.preference.PreferenceCategory;
72 import android.preference.PreferenceManager;
73 import android.preference.PreferenceScreen;
74 import android.preference.SwitchPreference;
75 import android.provider.SearchIndexableResource;
76 import android.provider.Settings;
77 import android.text.TextUtils;
78 import android.util.DisplayMetrics;
79 import android.util.Log;
80
81 import java.util.ArrayList;
82 import java.util.List;
83 import com.android.settings.Utils;
84 import com.android.settings.cyanogenmod.DisplayRotation;
85
86 import cyanogenmod.hardware.LiveDisplayManager;
87 import cyanogenmod.providers.CMSettings;
88
89 public class DisplaySettings extends SettingsPreferenceFragment implements
90         Preference.OnPreferenceChangeListener, OnPreferenceClickListener, Indexable {
91     private static final String TAG = "DisplaySettings";
92
93     /** If there is no setting in the provider, use this. */
94     private static final int FALLBACK_SCREEN_TIMEOUT_VALUE = 30000;
95
96     private static final String KEY_CATEGORY_LIGHTS = "lights";
97     private static final String KEY_CATEGORY_DISPLAY = "display";
98     private static final String KEY_CATEGORY_INTERFACE = "interface";
99     private static final String KEY_SCREEN_TIMEOUT = "screen_timeout";
100     private static final String KEY_LCD_DENSITY = "lcd_density";
101     private static final String KEY_FONT_SIZE = "font_size";
102     private static final String KEY_SCREEN_SAVER = "screensaver";
103     private static final String KEY_LIFT_TO_WAKE = "lift_to_wake";
104     private static final String KEY_DOZE = "doze";
105     private static final String KEY_TAP_TO_WAKE = "tap_to_wake";
106     private static final String KEY_AUTO_BRIGHTNESS = "auto_brightness";
107     private static final String KEY_AUTO_ROTATE = "auto_rotate";
108     private static final String KEY_NIGHT_MODE = "night_mode";
109     private static final String KEY_CAMERA_GESTURE = "camera_gesture";
110     private static final String KEY_PROXIMITY_WAKE = "proximity_on_wake";
111     private static final String KEY_DISPLAY_ROTATION = "display_rotation";
112     private static final String KEY_WAKE_WHEN_PLUGGED_OR_UNPLUGGED = "wake_when_plugged_or_unplugged";
113     private static final String KEY_NOTIFICATION_LIGHT = "notification_light";
114     private static final String KEY_BATTERY_LIGHT = "battery_light";
115     private static final String KEY_LIVEDISPLAY = "live_display";
116
117     private static final int DLG_GLOBAL_CHANGE_WARNING = 1;
118
119     private ListPreference mLcdDensityPreference;
120     private FontDialogPreference mFontSizePref;
121     private PreferenceScreen mDisplayRotationPreference;
122     private PreferenceScreen mLiveDisplayPreference;
123
124     private final Configuration mCurConfig = new Configuration();
125
126     private ListPreference mScreenTimeoutPreference;
127     private ListPreference mNightModePreference;
128     private Preference mScreenSaverPreference;
129     private SwitchPreference mAccelerometer;
130     private SwitchPreference mLiftToWakePreference;
131     private SwitchPreference mDozePreference;
132     private SwitchPreference mTapToWakePreference;
133     private SwitchPreference mProximityCheckOnWakePreference;
134     private SwitchPreference mAutoBrightnessPreference;
135     private SwitchPreference mWakeWhenPluggedOrUnplugged;
136
137     private ContentObserver mAccelerometerRotationObserver =
138             new ContentObserver(new Handler()) {
139         @Override
140         public void onChange(boolean selfChange) {
141             updateDisplayRotationPreferenceDescription();
142             updateAccelerometerRotationSwitch();
143         }
144     };
145
146     private final RotationPolicy.RotationPolicyListener mRotationPolicyListener =
147             new RotationPolicy.RotationPolicyListener() {
148         @Override
149         public void onChange() {
150             updateDisplayRotationPreferenceDescription();
151         }
152     };
153     private SwitchPreference mCameraGesturePreference;
154
155     @Override
156     protected int getMetricsCategory() {
157         return MetricsLogger.DISPLAY;
158     }
159
160     @Override
161     public void onCreate(Bundle savedInstanceState) {
162         super.onCreate(savedInstanceState);
163         final Activity activity = getActivity();
164         final ContentResolver resolver = activity.getContentResolver();
165         addPreferencesFromResource(R.xml.display);
166
167         PreferenceCategory displayPrefs = (PreferenceCategory)
168                 findPreference(KEY_CATEGORY_DISPLAY);
169         PreferenceCategory interfacePrefs = (PreferenceCategory)
170                 findPreference(KEY_CATEGORY_INTERFACE);
171         mDisplayRotationPreference = (PreferenceScreen) findPreference(KEY_DISPLAY_ROTATION);
172         mAccelerometer = (SwitchPreference) findPreference(DisplayRotation.KEY_ACCELEROMETER);
173         if (mAccelerometer != null) {
174             mAccelerometer.setPersistent(false);
175         }
176
177         mLiveDisplayPreference = (PreferenceScreen) findPreference(KEY_LIVEDISPLAY);
178         if (!LiveDisplayManager.getInstance(getActivity()).getConfig().isAvailable()) {
179             displayPrefs.removePreference(mLiveDisplayPreference);
180         }
181
182         mScreenSaverPreference = findPreference(KEY_SCREEN_SAVER);
183         if (mScreenSaverPreference != null
184                 && getResources().getBoolean(
185                         com.android.internal.R.bool.config_dreamsSupported) == false) {
186             interfacePrefs.removePreference(mScreenSaverPreference);
187         }
188
189         mScreenTimeoutPreference = (ListPreference) findPreference(KEY_SCREEN_TIMEOUT);
190         final long currentTimeout = Settings.System.getLong(resolver, SCREEN_OFF_TIMEOUT,
191                 FALLBACK_SCREEN_TIMEOUT_VALUE);
192         mScreenTimeoutPreference.setValue(String.valueOf(currentTimeout));
193         mScreenTimeoutPreference.setOnPreferenceChangeListener(this);
194         disableUnusableTimeouts(mScreenTimeoutPreference);
195         updateTimeoutPreferenceDescription(currentTimeout);
196         updateDisplayRotationPreferenceDescription();
197
198         mLcdDensityPreference = (ListPreference) findPreference(KEY_LCD_DENSITY);
199         if (mLcdDensityPreference != null) {
200             if (UserHandle.myUserId() != UserHandle.USER_OWNER) {
201                 interfacePrefs.removePreference(mLcdDensityPreference);
202             } else {
203                 int defaultDensity = getDefaultDensity();
204                 int currentDensity = getCurrentDensity();
205                 if (currentDensity < 10 || currentDensity >= 1000) {
206                     // Unsupported value, force default
207                     currentDensity = defaultDensity;
208                 }
209
210                 int factor = defaultDensity >= 480 ? 40 : 20;
211                 int minimumDensity = defaultDensity - 4 * factor;
212                 int currentIndex = -1;
213                 String[] densityEntries = new String[7];
214                 String[] densityValues = new String[7];
215                 for (int idx = 0; idx < 7; ++idx) {
216                     int val = minimumDensity + factor * idx;
217                     int valueFormatResId = val == defaultDensity
218                             ? R.string.lcd_density_default_value_format
219                             : R.string.lcd_density_value_format;
220
221                     densityEntries[idx] = getString(valueFormatResId, val);
222                     densityValues[idx] = Integer.toString(val);
223                     if (currentDensity == val) {
224                         currentIndex = idx;
225                     }
226                 }
227                 mLcdDensityPreference.setEntries(densityEntries);
228                 mLcdDensityPreference.setEntryValues(densityValues);
229                 if (currentIndex != -1) {
230                     mLcdDensityPreference.setValueIndex(currentIndex);
231                 }
232                 mLcdDensityPreference.setOnPreferenceChangeListener(this);
233                 updateLcdDensityPreferenceDescription(currentDensity);
234             }
235         }
236
237         mFontSizePref = (FontDialogPreference) findPreference(KEY_FONT_SIZE);
238         mFontSizePref.setOnPreferenceChangeListener(this);
239         mFontSizePref.setOnPreferenceClickListener(this);
240
241         mAutoBrightnessPreference = (SwitchPreference) findPreference(KEY_AUTO_BRIGHTNESS);
242         if (mAutoBrightnessPreference != null && isAutomaticBrightnessAvailable(getResources())) {
243             mAutoBrightnessPreference.setOnPreferenceChangeListener(this);
244         } else {
245             if (displayPrefs != null && mAutoBrightnessPreference != null) {
246                 displayPrefs.removePreference(mAutoBrightnessPreference);
247                 mAutoBrightnessPreference = null;
248             }
249         }
250
251         mLiftToWakePreference = (SwitchPreference) findPreference(KEY_LIFT_TO_WAKE);
252         if (mLiftToWakePreference != null && isLiftToWakeAvailable(activity)) {
253             mLiftToWakePreference.setOnPreferenceChangeListener(this);
254         } else {
255             if (displayPrefs != null && mLiftToWakePreference != null) {
256                 displayPrefs.removePreference(mLiftToWakePreference);
257                 mLiftToWakePreference = null;
258             }
259         }
260
261         mDozePreference = (SwitchPreference) findPreference(KEY_DOZE);
262         if (mDozePreference != null && Utils.isDozeAvailable(activity)) {
263             mDozePreference.setOnPreferenceChangeListener(this);
264         } else {
265             if (displayPrefs != null && mDozePreference != null) {
266                 displayPrefs.removePreference(mDozePreference);
267             }
268         }
269
270         mCameraGesturePreference = (SwitchPreference) findPreference(KEY_CAMERA_GESTURE);
271         if (mCameraGesturePreference != null && isCameraGestureAvailable(getResources())) {
272             mCameraGesturePreference.setOnPreferenceChangeListener(this);
273         } else {
274             if (displayPrefs != null && mCameraGesturePreference != null) {
275                 displayPrefs.removePreference(mCameraGesturePreference);
276             }
277         }
278
279         mNightModePreference = (ListPreference) findPreference(KEY_NIGHT_MODE);
280         if (mNightModePreference != null) {
281             final UiModeManager uiManager = (UiModeManager) getSystemService(
282                     Context.UI_MODE_SERVICE);
283             final int currentNightMode = uiManager.getNightMode();
284             mNightModePreference.setValue(String.valueOf(currentNightMode));
285             mNightModePreference.setOnPreferenceChangeListener(this);
286         }
287
288         mTapToWakePreference = (SwitchPreference) findPreference(KEY_TAP_TO_WAKE);
289         if (mTapToWakePreference != null && isTapToWakeAvailable(getResources())) {
290             mTapToWakePreference.setOnPreferenceChangeListener(this);
291         } else {
292             if (displayPrefs != null && mTapToWakePreference != null) {
293                 displayPrefs.removePreference(mTapToWakePreference);
294             }
295         }
296
297         mProximityCheckOnWakePreference = (SwitchPreference) findPreference(KEY_PROXIMITY_WAKE);
298         boolean proximityCheckOnWake = getResources().getBoolean(
299                 org.cyanogenmod.platform.internal.R.bool.config_proximityCheckOnWake);
300         if (!proximityCheckOnWake) {
301             if (displayPrefs != null && mProximityCheckOnWakePreference != null) {
302                 displayPrefs.removePreference(mProximityCheckOnWakePreference);
303             }
304             CMSettings.System.putInt(getContentResolver(), CMSettings.System.PROXIMITY_ON_WAKE, 0);
305         } else {
306             boolean proximityCheckOnWakeDefault = getResources().getBoolean(
307                     org.cyanogenmod.platform.internal.R.bool.config_proximityCheckOnWakeEnabledByDefault);
308             mProximityCheckOnWakePreference.setChecked(CMSettings.System.getInt(getContentResolver(),
309                     CMSettings.System.PROXIMITY_ON_WAKE,
310                     (proximityCheckOnWakeDefault ? 1 : 0)) == 1);
311         }
312
313         mWakeWhenPluggedOrUnplugged =
314                 (SwitchPreference) findPreference(KEY_WAKE_WHEN_PLUGGED_OR_UNPLUGGED);
315         initPulse((PreferenceCategory) findPreference(KEY_CATEGORY_LIGHTS));
316     }
317
318     private int getDefaultDensity() {
319         IWindowManager wm = IWindowManager.Stub.asInterface(ServiceManager.checkService(
320                 Context.WINDOW_SERVICE));
321         try {
322             return wm.getInitialDisplayDensity(Display.DEFAULT_DISPLAY);
323         } catch (RemoteException e) {
324             e.printStackTrace();
325         }
326         return DisplayMetrics.DENSITY_DEVICE;
327     }
328
329     private int getCurrentDensity() {
330         IWindowManager wm = IWindowManager.Stub.asInterface(ServiceManager.checkService(
331                 Context.WINDOW_SERVICE));
332         try {
333             return wm.getBaseDisplayDensity(Display.DEFAULT_DISPLAY);
334         } catch (RemoteException e) {
335             e.printStackTrace();
336         }
337         return DisplayMetrics.DENSITY_DEVICE;
338     }
339
340     private static boolean allowAllRotations(Context context) {
341         return Resources.getSystem().getBoolean(
342                 com.android.internal.R.bool.config_allowAllRotations);
343     }
344
345     private static boolean isLiftToWakeAvailable(Context context) {
346         SensorManager sensors = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
347         return sensors != null && sensors.getDefaultSensor(Sensor.TYPE_WAKE_GESTURE) != null;
348     }
349
350     private static boolean isTapToWakeAvailable(Resources res) {
351         return res.getBoolean(com.android.internal.R.bool.config_supportDoubleTapWake);
352     }
353
354     private static boolean isAutomaticBrightnessAvailable(Resources res) {
355         return res.getBoolean(com.android.internal.R.bool.config_automatic_brightness_available);
356     }
357
358     private void updateAccelerometerRotationSwitch() {
359         if (mAccelerometer != null) {
360             mAccelerometer.setChecked(!RotationPolicy.isRotationLocked(getActivity()));
361         }
362     }
363     private void updateDisplayRotationPreferenceDescription() {
364         if (mDisplayRotationPreference == null) {
365             // The preference was removed, do nothing
366             return;
367         }
368
369         // We have a preference, lets update the summary
370         boolean rotationEnabled = Settings.System.getInt(getContentResolver(),
371                 Settings.System.ACCELEROMETER_ROTATION, 0) != 0;
372
373         if (!rotationEnabled) {
374             mDisplayRotationPreference.setSummary(R.string.display_rotation_disabled);
375             return;
376         }
377
378         StringBuilder summary = new StringBuilder();
379         int mode = Settings.System.getInt(getContentResolver(),
380                 Settings.System.ACCELEROMETER_ROTATION_ANGLES,
381                 DisplayRotation.ROTATION_0_MODE
382                 | DisplayRotation.ROTATION_90_MODE
383                 | DisplayRotation.ROTATION_270_MODE);
384         ArrayList<String> rotationList = new ArrayList<String>();
385         String delim = "";
386
387         if ((mode & DisplayRotation.ROTATION_0_MODE) != 0) {
388             rotationList.add("0");
389         }
390         if ((mode & DisplayRotation.ROTATION_90_MODE) != 0) {
391             rotationList.add("90");
392         }
393         if ((mode & DisplayRotation.ROTATION_180_MODE) != 0) {
394             rotationList.add("180");
395         }
396         if ((mode & DisplayRotation.ROTATION_270_MODE) != 0) {
397             rotationList.add("270");
398         }
399         for (int i = 0; i < rotationList.size(); i++) {
400             summary.append(delim).append(rotationList.get(i));
401             if ((rotationList.size() - i) > 2) {
402                 delim = ", ";
403             } else {
404                 delim = " & ";
405             }
406         }
407         summary.append(" " + getString(R.string.display_rotation_unit));
408         mDisplayRotationPreference.setSummary(summary);
409     }
410
411     private static boolean isCameraGestureAvailable(Resources res) {
412         boolean configSet = res.getInteger(
413                 com.android.internal.R.integer.config_cameraLaunchGestureSensorType) != -1;
414         return configSet &&
415                 !SystemProperties.getBoolean("gesture.disable_camera_launch", false);
416     }
417
418     private void updateTimeoutPreferenceDescription(long currentTimeout) {
419         ListPreference preference = mScreenTimeoutPreference;
420         String summary;
421         if (currentTimeout < 0) {
422             // Unsupported value
423             summary = "";
424         } else {
425             final CharSequence[] entries = preference.getEntries();
426             final CharSequence[] values = preference.getEntryValues();
427             if (entries == null || entries.length == 0) {
428                 summary = "";
429             } else {
430                 int best = 0;
431                 for (int i = 0; i < values.length; i++) {
432                     long timeout = Long.parseLong(values[i].toString());
433                     if (currentTimeout >= timeout) {
434                         best = i;
435                     }
436                 }
437                 summary = preference.getContext().getString(R.string.screen_timeout_summary,
438                         entries[best]);
439             }
440         }
441         preference.setSummary(summary);
442     }
443
444     private void updateLcdDensityPreferenceDescription(int currentDensity) {
445         final int summaryResId = currentDensity == getDefaultDensity()
446                 ? R.string.lcd_density_default_value_format : R.string.lcd_density_value_format;
447         mLcdDensityPreference.setSummary(getString(summaryResId, currentDensity));
448     }
449
450     private void disableUnusableTimeouts(ListPreference screenTimeoutPreference) {
451         final DevicePolicyManager dpm =
452                 (DevicePolicyManager) getActivity().getSystemService(
453                 Context.DEVICE_POLICY_SERVICE);
454         final long maxTimeout = dpm != null ? dpm.getMaximumTimeToLock(null) : 0;
455         if (maxTimeout == 0) {
456             return; // policy not enforced
457         }
458         final CharSequence[] entries = screenTimeoutPreference.getEntries();
459         final CharSequence[] values = screenTimeoutPreference.getEntryValues();
460         ArrayList<CharSequence> revisedEntries = new ArrayList<CharSequence>();
461         ArrayList<CharSequence> revisedValues = new ArrayList<CharSequence>();
462         for (int i = 0; i < values.length; i++) {
463             long timeout = Long.parseLong(values[i].toString());
464             if (timeout <= maxTimeout) {
465                 revisedEntries.add(entries[i]);
466                 revisedValues.add(values[i]);
467             }
468         }
469         if (revisedEntries.size() != entries.length || revisedValues.size() != values.length) {
470             final int userPreference = Integer.parseInt(screenTimeoutPreference.getValue());
471             screenTimeoutPreference.setEntries(
472                     revisedEntries.toArray(new CharSequence[revisedEntries.size()]));
473             screenTimeoutPreference.setEntryValues(
474                     revisedValues.toArray(new CharSequence[revisedValues.size()]));
475             if (userPreference <= maxTimeout) {
476                 screenTimeoutPreference.setValue(String.valueOf(userPreference));
477             } else if (revisedValues.size() > 0
478                     && Long.parseLong(revisedValues.get(revisedValues.size() - 1).toString())
479                     == maxTimeout) {
480                 // If the last one happens to be the same as the max timeout, select that
481                 screenTimeoutPreference.setValue(String.valueOf(maxTimeout));
482             } else {
483                 // There will be no highlighted selection since nothing in the list matches
484                 // maxTimeout. The user can still select anything less than maxTimeout.
485                 // TODO: maybe append maxTimeout to the list and mark selected.
486             }
487         }
488         screenTimeoutPreference.setEnabled(revisedEntries.size() > 0);
489     }
490
491     @Override
492     public void onResume() {
493         super.onResume();
494         updateDisplayRotationPreferenceDescription();
495
496         RotationPolicy.registerRotationPolicyListener(getActivity(),
497                 mRotationPolicyListener);
498
499         final ContentResolver resolver = getContentResolver();
500
501         // Display rotation observer
502         resolver.registerContentObserver(
503                 Settings.System.getUriFor(Settings.System.ACCELEROMETER_ROTATION), true,
504                 mAccelerometerRotationObserver);
505
506         // Default value for wake-on-plug behavior from config.xml
507         boolean wakeUpWhenPluggedOrUnpluggedConfig = getResources().getBoolean(
508                 com.android.internal.R.bool.config_unplugTurnsOnScreen);
509
510         if (mWakeWhenPluggedOrUnplugged != null) {
511         mWakeWhenPluggedOrUnplugged.setChecked(CMSettings.Global.getInt(getContentResolver(),
512                 CMSettings.Global.WAKE_WHEN_PLUGGED_OR_UNPLUGGED,
513                 (wakeUpWhenPluggedOrUnpluggedConfig ? 1 : 0)) == 1);
514         }
515
516         updateState();
517         updateAccelerometerRotationSwitch();
518     }
519
520     @Override
521     public void onPause() {
522         super.onPause();
523
524         RotationPolicy.unregisterRotationPolicyListener(getActivity(),
525                 mRotationPolicyListener);
526
527         // Display rotation observer
528         getContentResolver().unregisterContentObserver(mAccelerometerRotationObserver);
529     }
530
531     @Override
532     public Dialog onCreateDialog(int dialogId) {
533         if (dialogId == DLG_GLOBAL_CHANGE_WARNING) {
534             return Utils.buildGlobalChangeWarningDialog(getActivity(),
535                     R.string.global_font_change_title,
536                     new Runnable() {
537                         public void run() {
538                             mFontSizePref.click();
539                         }
540                     });
541         }
542         return null;
543     }
544
545     private void updateState() {
546         readFontSizePreference(mFontSizePref);
547         updateScreenSaverSummary();
548
549         // Update auto brightness if it is available.
550         if (mAutoBrightnessPreference != null) {
551             int brightnessMode = Settings.System.getInt(getContentResolver(),
552                     SCREEN_BRIGHTNESS_MODE, SCREEN_BRIGHTNESS_MODE_MANUAL);
553             mAutoBrightnessPreference.setChecked(brightnessMode != SCREEN_BRIGHTNESS_MODE_MANUAL);
554         }
555
556         // Update lift-to-wake if it is available.
557         if (mLiftToWakePreference != null) {
558             int value = Settings.Secure.getInt(getContentResolver(), WAKE_GESTURE_ENABLED, 0);
559             mLiftToWakePreference.setChecked(value != 0);
560         }
561
562         // Update doze if it is available.
563         if (mDozePreference != null) {
564             int value = Settings.Secure.getInt(getContentResolver(), DOZE_ENABLED, 1);
565             mDozePreference.setChecked(value != 0);
566         }
567
568         // Update tap to wake if it is available.
569         if (mTapToWakePreference != null) {
570             int value = Settings.Secure.getInt(getContentResolver(), DOUBLE_TAP_TO_WAKE, 0);
571             mTapToWakePreference.setChecked(value != 0);
572         }
573
574         // Update camera gesture #1 if it is available.
575         if (mCameraGesturePreference != null) {
576             int value = Settings.Secure.getInt(getContentResolver(), CAMERA_GESTURE_DISABLED, 0);
577             mCameraGesturePreference.setChecked(value == 0);
578         }
579     }
580
581     private void updateScreenSaverSummary() {
582         if (mScreenSaverPreference != null) {
583             mScreenSaverPreference.setSummary(
584                     DreamSettings.getSummaryTextWithDreamName(getActivity()));
585         }
586     }
587
588     private void writeLcdDensityPreference(final Context context, final int density) {
589         final IActivityManager am = ActivityManagerNative.asInterface(
590                 ServiceManager.checkService("activity"));
591         final IWindowManager wm = IWindowManager.Stub.asInterface(ServiceManager.checkService(
592                 Context.WINDOW_SERVICE));
593         AsyncTask<Void, Void, Void> task = new AsyncTask<Void, Void, Void>() {
594             @Override
595             protected void onPreExecute() {
596                 ProgressDialog dialog = new ProgressDialog(context);
597                 dialog.setMessage(getResources().getString(R.string.restarting_ui));
598                 dialog.setCancelable(false);
599                 dialog.setIndeterminate(true);
600                 dialog.show();
601             }
602             @Override
603             protected Void doInBackground(Void... params) {
604                 // Give the user a second to see the dialog
605                 try {
606                     Thread.sleep(1000);
607                 } catch (InterruptedException e) {
608                     // Ignore
609                 }
610
611                 try {
612                     wm.setForcedDisplayDensity(Display.DEFAULT_DISPLAY, density);
613                 } catch (RemoteException e) {
614                     Log.e(TAG, "Failed to set density to " + density, e);
615                 }
616
617                 // Restart the UI
618                 try {
619                     am.restart();
620                 } catch (RemoteException e) {
621                     Log.e(TAG, "Failed to restart");
622                 }
623                 return null;
624             }
625         };
626         task.execute();
627     }
628
629     // === Pulse notification light ===
630
631     private void initPulse(PreferenceCategory parent) {
632         if (!getResources().getBoolean(
633                 com.android.internal.R.bool.config_intrusiveNotificationLed)) {
634             parent.removePreference(parent.findPreference(KEY_NOTIFICATION_LIGHT));
635         }
636         if (!getResources().getBoolean(
637                 com.android.internal.R.bool.config_intrusiveBatteryLed)
638                 || UserHandle.myUserId() != UserHandle.USER_OWNER) {
639             parent.removePreference(parent.findPreference(KEY_BATTERY_LIGHT));
640         }
641         if (parent.getPreferenceCount() == 0) {
642             getPreferenceScreen().removePreference(parent);
643         }
644     }
645     /**
646      * Reads the current font size and sets the value in the summary text
647      */
648     public void readFontSizePreference(Preference pref) {
649         try {
650             mCurConfig.updateFrom(ActivityManagerNative.getDefault().getConfiguration());
651         } catch (RemoteException e) {
652             Log.w(TAG, "Unable to retrieve font size");
653         }
654
655         // report the current size in the summary text
656         final Resources res = getResources();
657         String fontDesc = FontDialogPreference.getFontSizeDescription(res, mCurConfig.fontScale);
658         pref.setSummary(getString(R.string.summary_font_size, fontDesc));
659     }
660
661     public void writeFontSizePreference(Object objValue) {
662         try {
663             mCurConfig.fontScale = Float.parseFloat(objValue.toString());
664             ActivityManagerNative.getDefault().updatePersistentConfiguration(mCurConfig);
665         } catch (RemoteException e) {
666             Log.w(TAG, "Unable to save font size");
667         }
668     }
669
670     @Override
671     public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
672         if (preference == mWakeWhenPluggedOrUnplugged) {
673             CMSettings.Global.putInt(getContentResolver(),
674                     CMSettings.Global.WAKE_WHEN_PLUGGED_OR_UNPLUGGED,
675                     mWakeWhenPluggedOrUnplugged.isChecked() ? 1 : 0);
676             return true;
677         } else if (preference == mAccelerometer) {
678             RotationPolicy.setRotationLockForAccessibility(getActivity(),
679                     !mAccelerometer.isChecked());
680         }
681
682         return super.onPreferenceTreeClick(preferenceScreen, preference);
683     }
684
685     @Override
686     public boolean onPreferenceChange(Preference preference, Object objValue) {
687         final String key = preference.getKey();
688         if (KEY_SCREEN_TIMEOUT.equals(key)) {
689             try {
690                 int value = Integer.parseInt((String) objValue);
691                 Settings.System.putInt(getContentResolver(), SCREEN_OFF_TIMEOUT, value);
692                 updateTimeoutPreferenceDescription(value);
693             } catch (NumberFormatException e) {
694                 Log.e(TAG, "could not persist screen timeout setting", e);
695             }
696         }
697         if (KEY_LCD_DENSITY.equals(key)) {
698             String newValue = (String) objValue;
699             String oldValue = mLcdDensityPreference.getValue();
700             if (!TextUtils.equals(newValue, oldValue)) {
701                 showLcdConfirmationDialog((String) objValue);
702             }
703             return false;
704         }
705         if (KEY_FONT_SIZE.equals(key)) {
706             writeFontSizePreference(objValue);
707         }
708         if (preference == mAutoBrightnessPreference) {
709             boolean auto = (Boolean) objValue;
710             Settings.System.putInt(getContentResolver(), SCREEN_BRIGHTNESS_MODE,
711                     auto ? SCREEN_BRIGHTNESS_MODE_AUTOMATIC : SCREEN_BRIGHTNESS_MODE_MANUAL);
712         }
713         if (preference == mLiftToWakePreference) {
714             boolean value = (Boolean) objValue;
715             Settings.Secure.putInt(getContentResolver(), WAKE_GESTURE_ENABLED, value ? 1 : 0);
716         }
717         if (preference == mDozePreference) {
718             boolean value = (Boolean) objValue;
719             Settings.Secure.putInt(getContentResolver(), DOZE_ENABLED, value ? 1 : 0);
720         }
721         if (preference == mTapToWakePreference) {
722             boolean value = (Boolean) objValue;
723             Settings.Secure.putInt(getContentResolver(), DOUBLE_TAP_TO_WAKE, value ? 1 : 0);
724         }
725         if (preference == mCameraGesturePreference) {
726             boolean value = (Boolean) objValue;
727             Settings.Secure.putInt(getContentResolver(), CAMERA_GESTURE_DISABLED,
728                     value ? 0 : 1 /* Backwards because setting is for disabling */);
729         }
730         if (preference == mNightModePreference) {
731             try {
732                 final int value = Integer.parseInt((String) objValue);
733                 final UiModeManager uiManager = (UiModeManager) getSystemService(
734                         Context.UI_MODE_SERVICE);
735                 uiManager.setNightMode(value);
736             } catch (NumberFormatException e) {
737                 Log.e(TAG, "could not persist night mode setting", e);
738             }
739         }
740         return true;
741     }
742
743     private void showLcdConfirmationDialog(final String lcdDensity) {
744         AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
745         builder.setTitle(R.string.lcd_density);
746         builder.setMessage(R.string.lcd_density_prompt_message);
747         builder.setPositiveButton(R.string.print_restart,
748                 new DialogInterface.OnClickListener() {
749             public void onClick(DialogInterface dialog, int id) {
750                 try {
751                     int value = Integer.parseInt(lcdDensity);
752                     writeLcdDensityPreference(getActivity(), value);
753                     updateLcdDensityPreferenceDescription(value);
754                 } catch (NumberFormatException e) {
755                     Log.e(TAG, "could not persist display density setting", e);
756                 }
757             }
758         });
759         builder.setNegativeButton(android.R.string.cancel, null);
760         builder.show();
761     }
762
763     @Override
764     public boolean onPreferenceClick(Preference preference) {
765         if (preference == mFontSizePref) {
766             if (Utils.hasMultipleUsers(getActivity())) {
767                 showDialog(DLG_GLOBAL_CHANGE_WARNING);
768                 return true;
769             } else {
770                 mFontSizePref.click();
771             }
772         }
773         return false;
774     }
775
776     @Override
777     protected int getHelpResource() {
778         return R.string.help_uri_display;
779     }
780
781     public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
782             new BaseSearchIndexProvider() {
783
784                 @Override
785                 public List<SearchIndexableResource> getXmlResourcesToIndex(Context context,
786                         boolean enabled) {
787                     ArrayList<SearchIndexableResource> result =
788                             new ArrayList<SearchIndexableResource>();
789
790                     SearchIndexableResource sir = new SearchIndexableResource(context);
791                     sir.xmlResId = R.xml.display;
792                     result.add(sir);
793
794                     return result;
795                 }
796
797                 @Override
798                 public List<String> getNonIndexableKeys(Context context) {
799                     ArrayList<String> result = new ArrayList<String>();
800                     if (!context.getResources().getBoolean(
801                             com.android.internal.R.bool.config_dreamsSupported)) {
802                         result.add(KEY_SCREEN_SAVER);
803                     }
804                     if (!context.getResources().getBoolean(
805                             com.android.internal.R.bool.config_intrusiveNotificationLed)) {
806                         result.add(KEY_NOTIFICATION_LIGHT);
807                     }
808                     if (!context.getResources().getBoolean(
809                             com.android.internal.R.bool.config_intrusiveBatteryLed)) {
810                         result.add(KEY_BATTERY_LIGHT);
811                     }
812                     if (!isAutomaticBrightnessAvailable(context.getResources())) {
813                         result.add(KEY_AUTO_BRIGHTNESS);
814                     }
815                     if (!isLiftToWakeAvailable(context)) {
816                         result.add(KEY_LIFT_TO_WAKE);
817                     }
818                     if (!Utils.isDozeAvailable(context)) {
819                         result.add(KEY_DOZE);
820                     }
821                     if (!isTapToWakeAvailable(context.getResources())) {
822                         result.add(KEY_TAP_TO_WAKE);
823                     }
824                     if (!context.getResources().getBoolean(
825                             org.cyanogenmod.platform.internal.R.bool.config_proximityCheckOnWake)) {
826                         result.add(KEY_PROXIMITY_WAKE);
827                     }
828                     if (!isCameraGestureAvailable(context.getResources())) {
829                         result.add(KEY_CAMERA_GESTURE);
830                     }
831                     return result;
832                 }
833             };
834 }