1/* 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 19import android.content.ContentResolver; 20import android.content.Context; 21import android.database.ContentObserver; 22import android.os.Bundle; 23import android.os.Handler; 24import android.os.IPowerManager; 25import android.os.Parcel; 26import android.os.Parcelable; 27import android.os.RemoteException; 28import android.os.ServiceManager; 29import android.preference.SeekBarDialogPreference; 30import android.provider.Settings; 31import android.provider.Settings.SettingNotFoundException; 32import android.util.AttributeSet; 33import android.view.View; 34import android.widget.CheckBox; 35import android.widget.CompoundButton; 36import android.widget.SeekBar; 37 38public class BrightnessPreference extends SeekBarDialogPreference implements 39 SeekBar.OnSeekBarChangeListener, CheckBox.OnCheckedChangeListener { 40 41 private SeekBar mSeekBar; 42 private CheckBox mCheckBox; 43 44 private int mOldBrightness; 45 private int mOldAutomatic; 46 47 private boolean mAutomaticAvailable; 48 49 private boolean mRestoredOldState; 50 51 // Backlight range is from 0 - 255. Need to make sure that user 52 // doesn't set the backlight to 0 and get stuck 53 private int mScreenBrightnessDim = 54 getContext().getResources().getInteger(com.android.internal.R.integer.config_screenBrightnessDim); 55 private static final int MAXIMUM_BACKLIGHT = android.os.Power.BRIGHTNESS_ON; 56 57 private ContentObserver mBrightnessObserver = new ContentObserver(new Handler()) { 58 @Override 59 public void onChange(boolean selfChange) { 60 onBrightnessChanged(); 61 } 62 }; 63 64 private ContentObserver mBrightnessModeObserver = new ContentObserver(new Handler()) { 65 @Override 66 public void onChange(boolean selfChange) { 67 onBrightnessModeChanged(); 68 } 69 }; 70 71 public BrightnessPreference(Context context, AttributeSet attrs) { 72 super(context, attrs); 73 74 mAutomaticAvailable = context.getResources().getBoolean( 75 com.android.internal.R.bool.config_automatic_brightness_available); 76 77 setDialogLayoutResource(R.layout.preference_dialog_brightness); 78 setDialogIcon(R.drawable.ic_settings_display); 79 } 80 81 @Override 82 protected void showDialog(Bundle state) { 83 super.showDialog(state); 84 85 getContext().getContentResolver().registerContentObserver( 86 Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS), true, 87 mBrightnessObserver); 88 89 getContext().getContentResolver().registerContentObserver( 90 Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS_MODE), true, 91 mBrightnessModeObserver); 92 mRestoredOldState = false; 93 } 94 95 @Override 96 protected void onBindDialogView(View view) { 97 super.onBindDialogView(view); 98 99 mSeekBar = getSeekBar(view); 100 mSeekBar.setMax(MAXIMUM_BACKLIGHT - mScreenBrightnessDim); 101 mOldBrightness = getBrightness(0); 102 mSeekBar.setProgress(mOldBrightness - mScreenBrightnessDim); 103 104 mCheckBox = (CheckBox)view.findViewById(R.id.automatic_mode); 105 if (mAutomaticAvailable) { 106 mCheckBox.setOnCheckedChangeListener(this); 107 mOldAutomatic = getBrightnessMode(0); 108 mCheckBox.setChecked(mOldAutomatic != 0); 109 } else { 110 mCheckBox.setVisibility(View.GONE); 111 } 112 mSeekBar.setOnSeekBarChangeListener(this); 113 } 114 115 public void onProgressChanged(SeekBar seekBar, int progress, 116 boolean fromTouch) { 117 setBrightness(progress + mScreenBrightnessDim); 118 } 119 120 public void onStartTrackingTouch(SeekBar seekBar) { 121 // NA 122 } 123 124 public void onStopTrackingTouch(SeekBar seekBar) { 125 // NA 126 } 127 128 public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 129 setMode(isChecked ? Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC 130 : Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL); 131 if (!isChecked) { 132 setBrightness(mSeekBar.getProgress() + mScreenBrightnessDim); 133 } 134 } 135 136 private int getBrightness(int defaultValue) { 137 int brightness = defaultValue; 138 try { 139 brightness = Settings.System.getInt(getContext().getContentResolver(), 140 Settings.System.SCREEN_BRIGHTNESS); 141 } catch (SettingNotFoundException snfe) { 142 } 143 return brightness; 144 } 145 146 private int getBrightnessMode(int defaultValue) { 147 int brightnessMode = defaultValue; 148 try { 149 brightnessMode = Settings.System.getInt(getContext().getContentResolver(), 150 Settings.System.SCREEN_BRIGHTNESS_MODE); 151 } catch (SettingNotFoundException snfe) { 152 } 153 return brightnessMode; 154 } 155 156 private void onBrightnessChanged() { 157 int brightness = getBrightness(MAXIMUM_BACKLIGHT); 158 mSeekBar.setProgress(brightness - mScreenBrightnessDim); 159 } 160 161 private void onBrightnessModeChanged() { 162 boolean checked = getBrightnessMode(0) != 0; 163 mCheckBox.setChecked(checked); 164 } 165 166 @Override 167 protected void onDialogClosed(boolean positiveResult) { 168 super.onDialogClosed(positiveResult); 169 170 final ContentResolver resolver = getContext().getContentResolver(); 171 172 if (positiveResult) { 173 Settings.System.putInt(resolver, 174 Settings.System.SCREEN_BRIGHTNESS, 175 mSeekBar.getProgress() + mScreenBrightnessDim); 176 } else { 177 restoreOldState(); 178 } 179 180 resolver.unregisterContentObserver(mBrightnessObserver); 181 resolver.unregisterContentObserver(mBrightnessModeObserver); 182 } 183 184 private void restoreOldState() { 185 if (mRestoredOldState) return; 186 187 if (mAutomaticAvailable) { 188 setMode(mOldAutomatic); 189 } 190 if (!mAutomaticAvailable || mOldAutomatic == 0) { 191 setBrightness(mOldBrightness); 192 } 193 mRestoredOldState = true; 194 } 195 196 private void setBrightness(int brightness) { 197 try { 198 IPowerManager power = IPowerManager.Stub.asInterface( 199 ServiceManager.getService("power")); 200 if (power != null) { 201 power.setBacklightBrightness(brightness); 202 } 203 } catch (RemoteException doe) { 204 205 } 206 } 207 208 private void setMode(int mode) { 209 if (mode == Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC) { 210 mSeekBar.setVisibility(View.GONE); 211 } else { 212 mSeekBar.setVisibility(View.VISIBLE); 213 } 214 Settings.System.putInt(getContext().getContentResolver(), 215 Settings.System.SCREEN_BRIGHTNESS_MODE, mode); 216 } 217 218 @Override 219 protected Parcelable onSaveInstanceState() { 220 final Parcelable superState = super.onSaveInstanceState(); 221 if (getDialog() == null || !getDialog().isShowing()) return superState; 222 223 // Save the dialog state 224 final SavedState myState = new SavedState(superState); 225 myState.automatic = mCheckBox.isChecked(); 226 myState.progress = mSeekBar.getProgress(); 227 myState.oldAutomatic = mOldAutomatic == 1; 228 myState.oldProgress = mOldBrightness; 229 230 // Restore the old state when the activity or dialog is being paused 231 restoreOldState(); 232 return myState; 233 } 234 235 @Override 236 protected void onRestoreInstanceState(Parcelable state) { 237 if (state == null || !state.getClass().equals(SavedState.class)) { 238 // Didn't save state for us in onSaveInstanceState 239 super.onRestoreInstanceState(state); 240 return; 241 } 242 243 SavedState myState = (SavedState) state; 244 super.onRestoreInstanceState(myState.getSuperState()); 245 mOldBrightness = myState.oldProgress; 246 mOldAutomatic = myState.oldAutomatic ? 1 : 0; 247 setMode(myState.automatic ? 1 : 0); 248 setBrightness(myState.progress + mScreenBrightnessDim); 249 } 250 251 private static class SavedState extends BaseSavedState { 252 253 boolean automatic; 254 boolean oldAutomatic; 255 int progress; 256 int oldProgress; 257 258 public SavedState(Parcel source) { 259 super(source); 260 automatic = source.readInt() == 1; 261 progress = source.readInt(); 262 oldAutomatic = source.readInt() == 1; 263 oldProgress = source.readInt(); 264 } 265 266 @Override 267 public void writeToParcel(Parcel dest, int flags) { 268 super.writeToParcel(dest, flags); 269 dest.writeInt(automatic ? 1 : 0); 270 dest.writeInt(progress); 271 dest.writeInt(oldAutomatic ? 1 : 0); 272 dest.writeInt(oldProgress); 273 } 274 275 public SavedState(Parcelable superState) { 276 super(superState); 277 } 278 279 public static final Parcelable.Creator<SavedState> CREATOR = 280 new Parcelable.Creator<SavedState>() { 281 282 public SavedState createFromParcel(Parcel in) { 283 return new SavedState(in); 284 } 285 286 public SavedState[] newArray(int size) { 287 return new SavedState[size]; 288 } 289 }; 290 } 291} 292 293