• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 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.car.systeminterface;
18 
19 import android.content.ContentResolver;
20 import android.content.Context;
21 import android.database.ContentObserver;
22 import android.hardware.display.DisplayManager;
23 import android.hardware.display.DisplayManager.DisplayListener;
24 import android.os.Handler;
25 import android.os.Looper;
26 import android.os.PowerManager;
27 import android.os.SystemClock;
28 import android.provider.Settings.SettingNotFoundException;
29 import android.provider.Settings.System;
30 import android.util.Log;
31 import android.view.Display;
32 
33 import com.android.car.CarLog;
34 import com.android.car.CarPowerManagementService;
35 
36 /**
37  * Interface that abstracts display operations
38  */
39 public interface DisplayInterface {
40     /**
41      * @param brightness Level from 0 to 100%
42      */
setDisplayBrightness(int brightness)43     void setDisplayBrightness(int brightness);
setDisplayState(boolean on)44     void setDisplayState(boolean on);
startDisplayStateMonitoring(CarPowerManagementService service)45     void startDisplayStateMonitoring(CarPowerManagementService service);
stopDisplayStateMonitoring()46     void stopDisplayStateMonitoring();
47 
48     class DefaultImpl implements DisplayInterface {
49         private final ContentResolver mContentResolver;
50         private final Context mContext;
51         private final DisplayManager mDisplayManager;
52         private final int mMaximumBacklight;
53         private final int mMinimumBacklight;
54         private final PowerManager mPowerManager;
55         private final WakeLockInterface mWakeLockInterface;
56         private CarPowerManagementService mService;
57         private boolean mDisplayStateSet;
58 
59         private ContentObserver mBrightnessObserver =
60                 new ContentObserver(new Handler(Looper.getMainLooper())) {
61                     @Override
62                     public void onChange(boolean selfChange) {
63                         int brightness = mMinimumBacklight;
64                         int range = mMaximumBacklight - mMinimumBacklight;
65 
66                         try {
67                             brightness = System.getInt(mContentResolver, System.SCREEN_BRIGHTNESS);
68                         } catch (SettingNotFoundException e) {
69                             Log.e(CarLog.TAG_POWER, "Could not get SCREEN_BRIGHTNESS:  " + e);
70                         }
71                         // Convert brightness from 0-255 to 0-100%
72                         brightness -= mMinimumBacklight;
73                         brightness *= 100;
74                         brightness += (range + 1) / 2;
75                         brightness /= range;
76                         mService.sendDisplayBrightness(brightness);
77                     }
78                 };
79 
80         private final DisplayManager.DisplayListener mDisplayListener = new DisplayListener() {
81             @Override
82             public void onDisplayAdded(int displayId) {
83                 //ignore
84             }
85 
86             @Override
87             public void onDisplayRemoved(int displayId) {
88                 //ignore
89             }
90 
91             @Override
92             public void onDisplayChanged(int displayId) {
93                 if (displayId == Display.DEFAULT_DISPLAY) {
94                     handleMainDisplayChanged();
95                 }
96             }
97         };
98 
DefaultImpl(Context context, WakeLockInterface wakeLockInterface)99         DefaultImpl(Context context, WakeLockInterface wakeLockInterface) {
100             mContext = context;
101             mContentResolver = mContext.getContentResolver();
102             mDisplayManager = (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE);
103             mPowerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
104             mMaximumBacklight = mPowerManager.getMaximumScreenBrightnessSetting();
105             mMinimumBacklight = mPowerManager.getMinimumScreenBrightnessSetting();
106             mWakeLockInterface = wakeLockInterface;
107         }
108 
handleMainDisplayChanged()109         private void handleMainDisplayChanged() {
110             boolean isOn = isMainDisplayOn();
111             CarPowerManagementService service;
112             synchronized (this) {
113                 if (mDisplayStateSet == isOn) { // same as what is set
114                     return;
115                 }
116                 service = mService;
117             }
118             service.handleMainDisplayChanged(isOn);
119         }
120 
isMainDisplayOn()121         private boolean isMainDisplayOn() {
122             Display disp = mDisplayManager.getDisplay(Display.DEFAULT_DISPLAY);
123             return disp.getState() == Display.STATE_ON;
124         }
125 
126         @Override
setDisplayBrightness(int brightness)127         public void setDisplayBrightness(int brightness) {
128             // Brightness is set in percent.  Need to convert this into 0-255 scale.  The actual
129             //  brightness algorithm should look like this:
130             //
131             //      newBrightness = (brightness * (max - min)) + min
132             //
133             //  Since we're using integer arithmetic, do the multiplication first, then add 50 to
134             //  round up as needed.
135             brightness *= mMaximumBacklight - mMinimumBacklight;    // Multiply by full range
136             brightness += 50;                                       // Integer rounding
137             brightness /= 100;                                      // Divide by 100
138             brightness += mMinimumBacklight;
139             // Range checking
140             if (brightness < mMinimumBacklight) {
141                 brightness = mMinimumBacklight;
142             } else if (brightness > mMaximumBacklight) {
143                 brightness = mMaximumBacklight;
144             }
145             // Set the brightness
146             System.putInt(mContentResolver, System.SCREEN_BRIGHTNESS, brightness);
147         }
148 
149         @Override
startDisplayStateMonitoring(CarPowerManagementService service)150         public void startDisplayStateMonitoring(CarPowerManagementService service) {
151             synchronized (this) {
152                 mService = service;
153                 mDisplayStateSet = isMainDisplayOn();
154             }
155             mContentResolver.registerContentObserver(System.getUriFor(System.SCREEN_BRIGHTNESS),
156                                                      false, mBrightnessObserver);
157             mDisplayManager.registerDisplayListener(mDisplayListener, service.getHandler());
158         }
159 
160         @Override
stopDisplayStateMonitoring()161         public void stopDisplayStateMonitoring() {
162             mDisplayManager.unregisterDisplayListener(mDisplayListener);
163             mContentResolver.unregisterContentObserver(mBrightnessObserver);
164         }
165 
166         @Override
setDisplayState(boolean on)167         public void setDisplayState(boolean on) {
168             synchronized (this) {
169                 mDisplayStateSet = on;
170             }
171             if (on) {
172                 mWakeLockInterface.switchToFullWakeLock();
173                 Log.i(CarLog.TAG_POWER, "on display");
174                 mPowerManager.wakeUp(SystemClock.uptimeMillis());
175             } else {
176                 mWakeLockInterface.switchToPartialWakeLock();
177                 Log.i(CarLog.TAG_POWER, "off display");
178                 mPowerManager.goToSleep(SystemClock.uptimeMillis());
179             }
180         }
181     }
182 }
183