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