OSDN Git Service

AOD: Prewarm display while waiting for brightness sensor
[android-x86/frameworks-base.git] / packages / SystemUI / src / com / android / systemui / doze / DozeScreenBrightness.java
1 /*
2  * Copyright (C) 2017 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.doze;
18
19 import android.content.Context;
20 import android.hardware.Sensor;
21 import android.hardware.SensorEvent;
22 import android.hardware.SensorEventListener;
23 import android.hardware.SensorManager;
24 import android.os.Handler;
25
26 import com.android.internal.annotations.VisibleForTesting;
27
28 /**
29  * Controls the screen brightness when dozing.
30  */
31 public class DozeScreenBrightness implements DozeMachine.Part, SensorEventListener {
32     private final Context mContext;
33     private final DozeMachine.Service mDozeService;
34     private final DozeHost mDozeHost;
35     private final Handler mHandler;
36     private final SensorManager mSensorManager;
37     private final Sensor mLightSensor;
38     private final int[] mSensorToBrightness;
39     private final int[] mSensorToScrimOpacity;
40
41     private boolean mRegistered;
42     private int mDefaultDozeBrightness;
43     private boolean mPaused = false;
44     private int mLastSensorValue = -1;
45
46     public DozeScreenBrightness(Context context, DozeMachine.Service service,
47             SensorManager sensorManager, Sensor lightSensor, DozeHost host,
48             Handler handler, int defaultDozeBrightness, int[] sensorToBrightness,
49             int[] sensorToScrimOpacity) {
50         mContext = context;
51         mDozeService = service;
52         mSensorManager = sensorManager;
53         mLightSensor = lightSensor;
54         mDozeHost = host;
55         mHandler = handler;
56
57         mDefaultDozeBrightness = defaultDozeBrightness;
58         mSensorToBrightness = sensorToBrightness;
59         mSensorToScrimOpacity = sensorToScrimOpacity;
60     }
61
62     @VisibleForTesting
63     public DozeScreenBrightness(Context context, DozeMachine.Service service,
64             SensorManager sensorManager, Sensor lightSensor, DozeHost host,
65             Handler handler, AlwaysOnDisplayPolicy policy) {
66         this(context, service, sensorManager, lightSensor, host, handler,
67                 context.getResources().getInteger(
68                         com.android.internal.R.integer.config_screenBrightnessDoze),
69                 policy.screenBrightnessArray, policy.dimmingScrimArray);
70     }
71
72     @Override
73     public void transitionTo(DozeMachine.State oldState, DozeMachine.State newState) {
74         switch (newState) {
75             case INITIALIZED:
76                 resetBrightnessToDefault();
77                 break;
78             case DOZE_AOD:
79             case DOZE_REQUEST_PULSE:
80                 setLightSensorEnabled(true);
81                 break;
82             case DOZE:
83                 setLightSensorEnabled(false);
84                 resetBrightnessToDefault();
85                 break;
86             case FINISH:
87                 setLightSensorEnabled(false);
88                 break;
89         }
90         if (newState != DozeMachine.State.FINISH) {
91             setPaused(newState == DozeMachine.State.DOZE_AOD_PAUSED);
92         }
93     }
94
95     @Override
96     public void onSensorChanged(SensorEvent event) {
97         if (mRegistered) {
98             mLastSensorValue = (int) event.values[0];
99             updateBrightnessAndReady();
100         }
101     }
102
103     private void updateBrightnessAndReady() {
104         if (mRegistered) {
105             int brightness = computeBrightness(mLastSensorValue);
106             boolean brightnessReady = brightness > 0;
107             if (brightnessReady) {
108                 mDozeService.setDozeScreenBrightness(brightness);
109             }
110
111             int scrimOpacity = -1;
112             if (mPaused) {
113                 // If AOD is paused, force the screen black until the
114                 // sensor reports a new brightness. This ensures that when the screen comes on
115                 // again, it will only show after the brightness sensor has stabilized,
116                 // avoiding a potential flicker.
117                 scrimOpacity = 255;
118             } else if (brightnessReady) {
119                 // Only unblank scrim once brightness is ready.
120                 scrimOpacity = computeScrimOpacity(mLastSensorValue);
121             }
122             if (scrimOpacity >= 0) {
123                 mDozeHost.setAodDimmingScrim(scrimOpacity / 255f);
124             }
125         }
126     }
127
128     private int computeScrimOpacity(int sensorValue) {
129         if (sensorValue < 0 || sensorValue >= mSensorToScrimOpacity.length) {
130             return -1;
131         }
132         return mSensorToScrimOpacity[sensorValue];
133     }
134
135     private int computeBrightness(int sensorValue) {
136         if (sensorValue < 0 || sensorValue >= mSensorToBrightness.length) {
137             return -1;
138         }
139         return mSensorToBrightness[sensorValue];
140     }
141
142     @Override
143     public void onAccuracyChanged(Sensor sensor, int accuracy) {
144     }
145
146     private void resetBrightnessToDefault() {
147         mDozeService.setDozeScreenBrightness(mDefaultDozeBrightness);
148         mDozeHost.setAodDimmingScrim(0f);
149     }
150
151     private void setLightSensorEnabled(boolean enabled) {
152         if (enabled && !mRegistered && mLightSensor != null) {
153             // Wait until we get an event from the sensor until indicating ready.
154             mRegistered = mSensorManager.registerListener(this, mLightSensor,
155                     SensorManager.SENSOR_DELAY_NORMAL, mHandler);
156             mLastSensorValue = -1;
157         } else if (!enabled && mRegistered) {
158             mSensorManager.unregisterListener(this);
159             mRegistered = false;
160             mLastSensorValue = -1;
161             // Sensor is not enabled, hence we use the default brightness and are always ready.
162         }
163     }
164
165     private void setPaused(boolean paused) {
166         if (mPaused != paused) {
167             mPaused = paused;
168             updateBrightnessAndReady();
169         }
170     }
171
172 }