1 /*
2  * Copyright (C) 2014 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.statusbar.phone;
18 
19 import android.content.res.Resources;
20 import android.hardware.display.AmbientDisplayConfiguration;
21 import android.os.PowerManager;
22 import android.os.SystemProperties;
23 import android.os.UserHandle;
24 import android.provider.Settings;
25 import android.util.MathUtils;
26 
27 import com.android.systemui.R;
28 import com.android.systemui.dagger.qualifiers.Main;
29 import com.android.systemui.doze.AlwaysOnDisplayPolicy;
30 import com.android.systemui.doze.DozeScreenState;
31 import com.android.systemui.tuner.TunerService;
32 
33 import java.io.PrintWriter;
34 
35 import javax.inject.Inject;
36 import javax.inject.Singleton;
37 
38 /**
39  * Retrieve doze information
40  */
41 @Singleton
42 public class DozeParameters implements TunerService.Tunable,
43         com.android.systemui.plugins.statusbar.DozeParameters {
44     private static final int MAX_DURATION = 60 * 1000;
45     public static final boolean FORCE_NO_BLANKING =
46             SystemProperties.getBoolean("debug.force_no_blanking", false);
47     public static final boolean FORCE_BLANKING =
48             SystemProperties.getBoolean("debug.force_blanking", false);
49 
50     private final AmbientDisplayConfiguration mAmbientDisplayConfiguration;
51     private final PowerManager mPowerManager;
52 
53     private final AlwaysOnDisplayPolicy mAlwaysOnPolicy;
54     private final Resources mResources;
55 
56     private boolean mDozeAlwaysOn;
57     private boolean mControlScreenOffAnimation;
58 
59     @Inject
DozeParameters( @ain Resources resources, AmbientDisplayConfiguration ambientDisplayConfiguration, AlwaysOnDisplayPolicy alwaysOnDisplayPolicy, PowerManager powerManager, TunerService tunerService)60     protected DozeParameters(
61             @Main Resources resources,
62             AmbientDisplayConfiguration ambientDisplayConfiguration,
63             AlwaysOnDisplayPolicy alwaysOnDisplayPolicy,
64             PowerManager powerManager,
65             TunerService tunerService) {
66         mResources = resources;
67         mAmbientDisplayConfiguration = ambientDisplayConfiguration;
68         mAlwaysOnPolicy = alwaysOnDisplayPolicy;
69 
70         mControlScreenOffAnimation = !getDisplayNeedsBlanking();
71         mPowerManager = powerManager;
72         mPowerManager.setDozeAfterScreenOff(!mControlScreenOffAnimation);
73 
74         tunerService.addTunable(
75                 this,
76                 Settings.Secure.DOZE_ALWAYS_ON,
77                 Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED);
78     }
79 
dump(PrintWriter pw)80     public void dump(PrintWriter pw) {
81         pw.println("  DozeParameters:");
82         pw.print("    getDisplayStateSupported(): "); pw.println(getDisplayStateSupported());
83         pw.print("    getPulseDuration(): "); pw.println(getPulseDuration());
84         pw.print("    getPulseInDuration(): "); pw.println(getPulseInDuration());
85         pw.print("    getPulseInVisibleDuration(): "); pw.println(getPulseVisibleDuration());
86         pw.print("    getPulseOutDuration(): "); pw.println(getPulseOutDuration());
87         pw.print("    getPulseOnSigMotion(): "); pw.println(getPulseOnSigMotion());
88         pw.print("    getVibrateOnSigMotion(): "); pw.println(getVibrateOnSigMotion());
89         pw.print("    getVibrateOnPickup(): "); pw.println(getVibrateOnPickup());
90         pw.print("    getProxCheckBeforePulse(): "); pw.println(getProxCheckBeforePulse());
91         pw.print("    getPickupVibrationThreshold(): "); pw.println(getPickupVibrationThreshold());
92     }
93 
getDisplayStateSupported()94     public boolean getDisplayStateSupported() {
95         return getBoolean("doze.display.supported", R.bool.doze_display_state_supported);
96     }
97 
getDozeSuspendDisplayStateSupported()98     public boolean getDozeSuspendDisplayStateSupported() {
99         return mResources.getBoolean(R.bool.doze_suspend_display_state_supported);
100     }
101 
getPulseDuration()102     public int getPulseDuration() {
103         return getPulseInDuration() + getPulseVisibleDuration() + getPulseOutDuration();
104     }
105 
getScreenBrightnessDoze()106     public float getScreenBrightnessDoze() {
107         return mResources.getInteger(
108                 com.android.internal.R.integer.config_screenBrightnessDoze) / 255f;
109     }
110 
getPulseInDuration()111     public int getPulseInDuration() {
112         return getInt("doze.pulse.duration.in", R.integer.doze_pulse_duration_in);
113     }
114 
getPulseVisibleDuration()115     public int getPulseVisibleDuration() {
116         return getInt("doze.pulse.duration.visible", R.integer.doze_pulse_duration_visible);
117     }
118 
getPulseOutDuration()119     public int getPulseOutDuration() {
120         return getInt("doze.pulse.duration.out", R.integer.doze_pulse_duration_out);
121     }
122 
getPulseOnSigMotion()123     public boolean getPulseOnSigMotion() {
124         return getBoolean("doze.pulse.sigmotion", R.bool.doze_pulse_on_significant_motion);
125     }
126 
getVibrateOnSigMotion()127     public boolean getVibrateOnSigMotion() {
128         return SystemProperties.getBoolean("doze.vibrate.sigmotion", false);
129     }
130 
getVibrateOnPickup()131     public boolean getVibrateOnPickup() {
132         return SystemProperties.getBoolean("doze.vibrate.pickup", false);
133     }
134 
getProxCheckBeforePulse()135     public boolean getProxCheckBeforePulse() {
136         return getBoolean("doze.pulse.proxcheck", R.bool.doze_proximity_check_before_pulse);
137     }
138 
getPickupVibrationThreshold()139     public int getPickupVibrationThreshold() {
140         return getInt("doze.pickup.vibration.threshold", R.integer.doze_pickup_vibration_threshold);
141     }
142 
143     /**
144      * For how long a wallpaper can be visible in AoD before it fades aways.
145      * @return duration in millis.
146      */
getWallpaperAodDuration()147     public long getWallpaperAodDuration() {
148         if (shouldControlScreenOff()) {
149             return DozeScreenState.ENTER_DOZE_HIDE_WALLPAPER_DELAY;
150         }
151         return mAlwaysOnPolicy.wallpaperVisibilityDuration;
152     }
153 
154     /**
155      * How long it takes for the wallpaper fade away (Animation duration.)
156      * @return duration in millis.
157      */
getWallpaperFadeOutDuration()158     public long getWallpaperFadeOutDuration() {
159         return mAlwaysOnPolicy.wallpaperFadeOutDuration;
160     }
161 
162     /**
163      * Checks if always on is available and enabled for the current user.
164      * @return {@code true} if enabled and available.
165      */
getAlwaysOn()166     public boolean getAlwaysOn() {
167         return mDozeAlwaysOn;
168     }
169 
170     /**
171      * Some screens need to be completely black before changing the display power mode,
172      * unexpected behavior might happen if this parameter isn't respected.
173      *
174      * @return {@code true} if screen needs to be completely black before a power transition.
175      */
getDisplayNeedsBlanking()176     public boolean getDisplayNeedsBlanking() {
177         return FORCE_BLANKING || !FORCE_NO_BLANKING && mResources.getBoolean(
178                 com.android.internal.R.bool.config_displayBlanksAfterDoze);
179     }
180 
shouldControlScreenOff()181     public boolean shouldControlScreenOff() {
182         return mControlScreenOffAnimation;
183     }
184 
setControlScreenOffAnimation(boolean controlScreenOffAnimation)185     public void setControlScreenOffAnimation(boolean controlScreenOffAnimation) {
186         if (mControlScreenOffAnimation == controlScreenOffAnimation) {
187             return;
188         }
189         mControlScreenOffAnimation = controlScreenOffAnimation;
190         mPowerManager.setDozeAfterScreenOff(!controlScreenOffAnimation);
191     }
192 
getBoolean(String propName, int resId)193     private boolean getBoolean(String propName, int resId) {
194         return SystemProperties.getBoolean(propName, mResources.getBoolean(resId));
195     }
196 
getInt(String propName, int resId)197     private int getInt(String propName, int resId) {
198         int value = SystemProperties.getInt(propName, mResources.getInteger(resId));
199         return MathUtils.constrain(value, 0, MAX_DURATION);
200     }
201 
getPulseVisibleDurationExtended()202     public int getPulseVisibleDurationExtended() {
203         return 2 * getPulseVisibleDuration();
204     }
205 
doubleTapReportsTouchCoordinates()206     public boolean doubleTapReportsTouchCoordinates() {
207         return mResources.getBoolean(R.bool.doze_double_tap_reports_touch_coordinates);
208     }
209 
210     @Override
onTuningChanged(String key, String newValue)211     public void onTuningChanged(String key, String newValue) {
212         mDozeAlwaysOn = mAmbientDisplayConfiguration.alwaysOnEnabled(UserHandle.USER_CURRENT);
213     }
214 
getPolicy()215     public AlwaysOnDisplayPolicy getPolicy() {
216         return mAlwaysOnPolicy;
217     }
218 }
219