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