BrightnessController.java revision 6d20526adfd18f7347674d61fe784d456b1b7b61
1/* 2 * Copyright (C) 2013 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.systemui.settings; 18 19import android.content.ContentResolver; 20import android.content.Context; 21import android.database.ContentObserver; 22import android.net.Uri; 23import android.os.AsyncTask; 24import android.os.Handler; 25import android.os.IPowerManager; 26import android.os.PowerManager; 27import android.os.RemoteException; 28import android.os.ServiceManager; 29import android.os.UserHandle; 30import android.provider.Settings; 31import android.widget.ImageView; 32 33import java.util.ArrayList; 34 35public class BrightnessController implements ToggleSlider.Listener { 36 private static final String TAG = "StatusBar.BrightnessController"; 37 private static final boolean SHOW_AUTOMATIC_ICON = false; 38 39 /** 40 * {@link android.provider.Settings.System#SCREEN_AUTO_BRIGHTNESS_ADJ} uses the range [-1, 1]. 41 * Using this factor, it is converted to [0, BRIGHTNESS_ADJ_RESOLUTION] for the SeekBar. 42 */ 43 private static final float BRIGHTNESS_ADJ_RESOLUTION = 100; 44 45 private final int mMinimumBacklight; 46 private final int mMaximumBacklight; 47 48 private final Context mContext; 49 private final ImageView mIcon; 50 private final ToggleSlider mControl; 51 private final boolean mAutomaticAvailable; 52 private final IPowerManager mPower; 53 private final CurrentUserTracker mUserTracker; 54 private final Handler mHandler; 55 private final BrightnessObserver mBrightnessObserver; 56 57 private ArrayList<BrightnessStateChangeCallback> mChangeCallbacks = 58 new ArrayList<BrightnessStateChangeCallback>(); 59 60 private boolean mAutomatic; 61 62 public interface BrightnessStateChangeCallback { 63 public void onBrightnessLevelChanged(); 64 } 65 66 /** ContentObserver to watch brightness **/ 67 private class BrightnessObserver extends ContentObserver { 68 69 private final Uri BRIGHTNESS_MODE_URI = 70 Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS_MODE); 71 private final Uri BRIGHTNESS_URI = 72 Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS); 73 private final Uri BRIGHTNESS_ADJ_URI = 74 Settings.System.getUriFor(Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ); 75 76 public BrightnessObserver(Handler handler) { 77 super(handler); 78 } 79 80 @Override 81 public void onChange(boolean selfChange) { 82 onChange(selfChange, null); 83 } 84 85 @Override 86 public void onChange(boolean selfChange, Uri uri) { 87 if (selfChange) return; 88 if (BRIGHTNESS_MODE_URI.equals(uri)) { 89 updateMode(); 90 updateSlider(); 91 } else if (BRIGHTNESS_URI.equals(uri) && !mAutomatic) { 92 updateSlider(); 93 } else if (BRIGHTNESS_ADJ_URI.equals(uri) && mAutomatic) { 94 updateSlider(); 95 } else { 96 updateMode(); 97 updateSlider(); 98 } 99 for (BrightnessStateChangeCallback cb : mChangeCallbacks) { 100 cb.onBrightnessLevelChanged(); 101 } 102 } 103 104 public void startObserving() { 105 final ContentResolver cr = mContext.getContentResolver(); 106 cr.unregisterContentObserver(this); 107 cr.registerContentObserver( 108 BRIGHTNESS_MODE_URI, 109 false, this, UserHandle.USER_ALL); 110 cr.registerContentObserver( 111 BRIGHTNESS_URI, 112 false, this, UserHandle.USER_ALL); 113 cr.registerContentObserver( 114 BRIGHTNESS_ADJ_URI, 115 false, this, UserHandle.USER_ALL); 116 } 117 118 public void stopObserving() { 119 final ContentResolver cr = mContext.getContentResolver(); 120 cr.unregisterContentObserver(this); 121 } 122 123 } 124 125 public BrightnessController(Context context, ImageView icon, ToggleSlider control) { 126 mContext = context; 127 mIcon = icon; 128 mControl = control; 129 mHandler = new Handler(); 130 mUserTracker = new CurrentUserTracker(mContext) { 131 @Override 132 public void onUserSwitched(int newUserId) { 133 updateMode(); 134 updateSlider(); 135 } 136 }; 137 mBrightnessObserver = new BrightnessObserver(mHandler); 138 139 PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE); 140 mMinimumBacklight = pm.getMinimumScreenBrightnessSetting(); 141 mMaximumBacklight = pm.getMaximumScreenBrightnessSetting(); 142 143 mAutomaticAvailable = context.getResources().getBoolean( 144 com.android.internal.R.bool.config_automatic_brightness_available); 145 mPower = IPowerManager.Stub.asInterface(ServiceManager.getService("power")); 146 } 147 148 public void addStateChangedCallback(BrightnessStateChangeCallback cb) { 149 mChangeCallbacks.add(cb); 150 } 151 152 public boolean removeStateChangedCallback(BrightnessStateChangeCallback cb) { 153 return mChangeCallbacks.remove(cb); 154 } 155 156 @Override 157 public void onInit(ToggleSlider control) { 158 // Do nothing 159 } 160 161 public void registerCallbacks() { 162 mBrightnessObserver.startObserving(); 163 mUserTracker.startTracking(); 164 165 // Update the slider and mode before attaching the listener so we don't receive the 166 // onChanged notifications for the initial values. 167 updateMode(); 168 updateSlider(); 169 170 mControl.setOnChangedListener(this); 171 } 172 173 /** Unregister all call backs, both to and from the controller */ 174 public void unregisterCallbacks() { 175 mBrightnessObserver.stopObserving(); 176 mChangeCallbacks.clear(); 177 mUserTracker.stopTracking(); 178 mControl.setOnChangedListener(null); 179 } 180 181 public void onChanged(ToggleSlider view, boolean tracking, boolean automatic, int value) { 182 updateIcon(mAutomatic); 183 if (!mAutomatic) { 184 final int val = value + mMinimumBacklight; 185 setBrightness(val); 186 if (!tracking) { 187 AsyncTask.execute(new Runnable() { 188 public void run() { 189 Settings.System.putIntForUser(mContext.getContentResolver(), 190 Settings.System.SCREEN_BRIGHTNESS, val, 191 UserHandle.USER_CURRENT); 192 } 193 }); 194 } 195 } else { 196 final float adj = value / (BRIGHTNESS_ADJ_RESOLUTION / 2f) - 1; 197 setBrightnessAdj(adj); 198 if (!tracking) { 199 AsyncTask.execute(new Runnable() { 200 public void run() { 201 Settings.System.putFloatForUser(mContext.getContentResolver(), 202 Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ, adj, 203 UserHandle.USER_CURRENT); 204 } 205 }); 206 } 207 } 208 209 for (BrightnessStateChangeCallback cb : mChangeCallbacks) { 210 cb.onBrightnessLevelChanged(); 211 } 212 } 213 214 private void setMode(int mode) { 215 Settings.System.putIntForUser(mContext.getContentResolver(), 216 Settings.System.SCREEN_BRIGHTNESS_MODE, mode, 217 mUserTracker.getCurrentUserId()); 218 } 219 220 private void setBrightness(int brightness) { 221 try { 222 mPower.setTemporaryScreenBrightnessSettingOverride(brightness); 223 } catch (RemoteException ex) { 224 } 225 } 226 227 private void setBrightnessAdj(float adj) { 228 try { 229 mPower.setTemporaryScreenAutoBrightnessAdjustmentSettingOverride(adj); 230 } catch (RemoteException ex) { 231 } 232 } 233 234 private void updateIcon(boolean automatic) { 235 if (mIcon != null) { 236 mIcon.setImageResource(automatic && SHOW_AUTOMATIC_ICON ? 237 com.android.systemui.R.drawable.ic_qs_brightness_auto_on : 238 com.android.systemui.R.drawable.ic_qs_brightness_auto_off); 239 } 240 } 241 242 /** Fetch the brightness mode from the system settings and update the icon */ 243 private void updateMode() { 244 if (mAutomaticAvailable) { 245 int automatic; 246 automatic = Settings.System.getIntForUser(mContext.getContentResolver(), 247 Settings.System.SCREEN_BRIGHTNESS_MODE, 248 Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL, 249 UserHandle.USER_CURRENT); 250 mAutomatic = automatic != Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL; 251 updateIcon(mAutomatic); 252 } else { 253 mControl.setChecked(false); 254 updateIcon(false /*automatic*/); 255 } 256 } 257 258 /** Fetch the brightness from the system settings and update the slider */ 259 private void updateSlider() { 260 if (mAutomatic) { 261 float value = Settings.System.getFloatForUser(mContext.getContentResolver(), 262 Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ, 0, 263 UserHandle.USER_CURRENT); 264 mControl.setMax((int) BRIGHTNESS_ADJ_RESOLUTION); 265 mControl.setValue((int) ((value + 1) * BRIGHTNESS_ADJ_RESOLUTION / 2f)); 266 } else { 267 int value; 268 value = Settings.System.getIntForUser(mContext.getContentResolver(), 269 Settings.System.SCREEN_BRIGHTNESS, mMaximumBacklight, 270 UserHandle.USER_CURRENT); 271 mControl.setMax(mMaximumBacklight - mMinimumBacklight); 272 mControl.setValue(value - mMinimumBacklight); 273 } 274 } 275 276} 277