blob: 6b7397b3f8caf23997a64effb844e0165887e1cf [file] [log] [blame]
John Spurlockd06aa572014-09-10 10:40:49 -04001/*
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
17package com.android.systemui.statusbar.phone;
18
19import android.content.Context;
20import android.os.SystemProperties;
Adrian Roosb7e4e102016-10-14 13:03:45 -070021import android.os.UserHandle;
Adrian Roosebea7a72016-10-26 12:51:26 -070022import android.provider.Settings;
John Spurlockd06aa572014-09-10 10:40:49 -040023import android.text.TextUtils;
John Spurlockd06aa572014-09-10 10:40:49 -040024import android.util.MathUtils;
Adrian Roos5753f052016-07-13 10:30:37 -070025import android.util.SparseBooleanArray;
John Spurlockd06aa572014-09-10 10:40:49 -040026
Adrian Roos0261fb22017-03-07 20:20:35 +000027import com.android.internal.hardware.AmbientDisplayConfiguration;
John Spurlockd06aa572014-09-10 10:40:49 -040028import com.android.systemui.R;
29
30import java.io.PrintWriter;
John Spurlockd06aa572014-09-10 10:40:49 -040031
32public class DozeParameters {
Selim Cinekbb998c92015-09-22 10:05:29 +020033 private static final int MAX_DURATION = 60 * 1000;
Adrian Roos7a1654e2017-02-14 14:06:29 +010034 public static final String DOZE_SENSORS_WAKE_UP_FULLY = "doze_sensors_wake_up_fully";
John Spurlockd06aa572014-09-10 10:40:49 -040035
36 private final Context mContext;
Adrian Roos0261fb22017-03-07 20:20:35 +000037 private final AmbientDisplayConfiguration mAmbientDisplayConfiguration;
John Spurlockd06aa572014-09-10 10:40:49 -040038
Adrian Roos5753f052016-07-13 10:30:37 -070039 private static IntInOutMatcher sPickupSubtypePerformsProxMatcher;
40
John Spurlockd06aa572014-09-10 10:40:49 -040041 public DozeParameters(Context context) {
42 mContext = context;
Adrian Roos0261fb22017-03-07 20:20:35 +000043 mAmbientDisplayConfiguration = new AmbientDisplayConfiguration(mContext);
John Spurlockd06aa572014-09-10 10:40:49 -040044 }
45
46 public void dump(PrintWriter pw) {
47 pw.println(" DozeParameters:");
John Spurlock190d0262014-09-14 15:39:13 -040048 pw.print(" getDisplayStateSupported(): "); pw.println(getDisplayStateSupported());
John Spurlockf5d250d2014-12-02 10:41:25 -050049 pw.print(" getPulseDuration(pickup=false): "); pw.println(getPulseDuration(false));
50 pw.print(" getPulseDuration(pickup=true): "); pw.println(getPulseDuration(true));
51 pw.print(" getPulseInDuration(pickup=false): "); pw.println(getPulseInDuration(false));
52 pw.print(" getPulseInDuration(pickup=true): "); pw.println(getPulseInDuration(true));
John Spurlockd06aa572014-09-10 10:40:49 -040053 pw.print(" getPulseInVisibleDuration(): "); pw.println(getPulseVisibleDuration());
54 pw.print(" getPulseOutDuration(): "); pw.println(getPulseOutDuration());
John Spurlock190d0262014-09-14 15:39:13 -040055 pw.print(" getPulseOnSigMotion(): "); pw.println(getPulseOnSigMotion());
56 pw.print(" getVibrateOnSigMotion(): "); pw.println(getVibrateOnSigMotion());
John Spurlock190d0262014-09-14 15:39:13 -040057 pw.print(" getVibrateOnPickup(): "); pw.println(getVibrateOnPickup());
John Spurlock686e4d52014-11-20 21:48:09 -050058 pw.print(" getProxCheckBeforePulse(): "); pw.println(getProxCheckBeforePulse());
John Spurlock50a8ea62014-09-16 09:12:03 -040059 pw.print(" getPickupVibrationThreshold(): "); pw.println(getPickupVibrationThreshold());
Adrian Roos5753f052016-07-13 10:30:37 -070060 pw.print(" getPickupSubtypePerformsProxCheck(): ");pw.println(
61 dumpPickupSubtypePerformsProxCheck());
62 }
63
64 private String dumpPickupSubtypePerformsProxCheck() {
65 // Refresh sPickupSubtypePerformsProxMatcher
66 getPickupSubtypePerformsProxCheck(0);
67
68 if (sPickupSubtypePerformsProxMatcher == null) {
69 return "fallback: " + mContext.getResources().getBoolean(
70 R.bool.doze_pickup_performs_proximity_check);
71 } else {
72 return "spec: " + sPickupSubtypePerformsProxMatcher.mSpec;
73 }
John Spurlock190d0262014-09-14 15:39:13 -040074 }
75
76 public boolean getDisplayStateSupported() {
77 return getBoolean("doze.display.supported", R.bool.doze_display_state_supported);
John Spurlockd06aa572014-09-10 10:40:49 -040078 }
79
Adrian Roosa1e6b312017-03-28 16:20:34 -070080 public boolean getDozeSuspendDisplayStateSupported() {
81 return mContext.getResources().getBoolean(R.bool.doze_suspend_display_state_supported);
82 }
83
John Spurlockf5d250d2014-12-02 10:41:25 -050084 public int getPulseDuration(boolean pickup) {
85 return getPulseInDuration(pickup) + getPulseVisibleDuration() + getPulseOutDuration();
John Spurlockd06aa572014-09-10 10:40:49 -040086 }
87
Adrian Roos7294c112016-09-20 14:03:21 -070088 public int getPulseInDuration(boolean pickupOrDoubleTap) {
89 return pickupOrDoubleTap
John Spurlockf5d250d2014-12-02 10:41:25 -050090 ? getInt("doze.pulse.duration.in.pickup", R.integer.doze_pulse_duration_in_pickup)
91 : getInt("doze.pulse.duration.in", R.integer.doze_pulse_duration_in);
John Spurlockd06aa572014-09-10 10:40:49 -040092 }
93
94 public int getPulseVisibleDuration() {
95 return getInt("doze.pulse.duration.visible", R.integer.doze_pulse_duration_visible);
96 }
97
98 public int getPulseOutDuration() {
99 return getInt("doze.pulse.duration.out", R.integer.doze_pulse_duration_out);
100 }
101
John Spurlock190d0262014-09-14 15:39:13 -0400102 public boolean getPulseOnSigMotion() {
103 return getBoolean("doze.pulse.sigmotion", R.bool.doze_pulse_on_significant_motion);
John Spurlockd06aa572014-09-10 10:40:49 -0400104 }
105
John Spurlock190d0262014-09-14 15:39:13 -0400106 public boolean getVibrateOnSigMotion() {
107 return SystemProperties.getBoolean("doze.vibrate.sigmotion", false);
108 }
109
John Spurlock190d0262014-09-14 15:39:13 -0400110 public boolean getVibrateOnPickup() {
111 return SystemProperties.getBoolean("doze.vibrate.pickup", false);
112 }
113
John Spurlock686e4d52014-11-20 21:48:09 -0500114 public boolean getProxCheckBeforePulse() {
115 return getBoolean("doze.pulse.proxcheck", R.bool.doze_proximity_check_before_pulse);
116 }
117
John Spurlock50a8ea62014-09-16 09:12:03 -0400118 public int getPickupVibrationThreshold() {
119 return getInt("doze.pickup.vibration.threshold", R.integer.doze_pickup_vibration_threshold);
120 }
121
Adrian Roosebea7a72016-10-26 12:51:26 -0700122 public boolean getAlwaysOn() {
Adrian Roos0261fb22017-03-07 20:20:35 +0000123 return mAmbientDisplayConfiguration.alwaysOnEnabled(UserHandle.USER_CURRENT);
Adrian Roosebea7a72016-10-26 12:51:26 -0700124 }
125
John Spurlock190d0262014-09-14 15:39:13 -0400126 private boolean getBoolean(String propName, int resId) {
127 return SystemProperties.getBoolean(propName, mContext.getResources().getBoolean(resId));
John Spurlockd06aa572014-09-10 10:40:49 -0400128 }
129
130 private int getInt(String propName, int resId) {
131 int value = SystemProperties.getInt(propName, mContext.getResources().getInteger(resId));
132 return MathUtils.constrain(value, 0, MAX_DURATION);
133 }
134
135 private String getString(String propName, int resId) {
136 return SystemProperties.get(propName, mContext.getString(resId));
137 }
138
Adrian Roos5753f052016-07-13 10:30:37 -0700139 public boolean getPickupSubtypePerformsProxCheck(int subType) {
140 String spec = getString("doze.pickup.proxcheck",
141 R.string.doze_pickup_subtype_performs_proximity_check);
142
143 if (TextUtils.isEmpty(spec)) {
144 // Fall back to non-subtype based property.
145 return mContext.getResources().getBoolean(R.bool.doze_pickup_performs_proximity_check);
146 }
147
148 if (sPickupSubtypePerformsProxMatcher == null
149 || !TextUtils.equals(spec, sPickupSubtypePerformsProxMatcher.mSpec)) {
150 sPickupSubtypePerformsProxMatcher = new IntInOutMatcher(spec);
151 }
152
153 return sPickupSubtypePerformsProxMatcher.isIn(subType);
154 }
155
Adrian Roos67cca742017-04-13 16:52:51 -0700156 public int getPulseVisibleDurationExtended() {
157 return 2 * getPulseVisibleDuration();
158 }
159
Adrian Roos44198f52017-06-02 12:50:38 -0700160 public boolean doubleTapReportsTouchCoordinates() {
161 return mContext.getResources().getBoolean(R.bool.doze_double_tap_reports_touch_coordinates);
162 }
163
Adrian Roos5753f052016-07-13 10:30:37 -0700164
165 /**
166 * Parses a spec of the form `1,2,3,!5,*`. The resulting object will match numbers that are
167 * listed, will not match numbers that are listed with a ! prefix, and will match / not match
168 * unlisted numbers depending on whether * or !* is present.
169 *
170 * * -> match any numbers that are not explicitly listed
171 * !* -> don't match any numbers that are not explicitly listed
172 * 2 -> match 2
173 * !3 -> don't match 3
174 *
175 * It is illegal to specify:
176 * - an empty spec
177 * - a spec containing that are empty, or a lone !
178 * - a spec for anything other than numbers or *
179 * - multiple terms for the same number / multiple *s
180 */
181 public static class IntInOutMatcher {
182 private static final String WILDCARD = "*";
183 private static final char OUT_PREFIX = '!';
184
185 private final SparseBooleanArray mIsIn;
186 private final boolean mDefaultIsIn;
187 final String mSpec;
188
189 public IntInOutMatcher(String spec) {
190 if (TextUtils.isEmpty(spec)) {
191 throw new IllegalArgumentException("Spec must not be empty");
192 }
193
194 boolean defaultIsIn = false;
195 boolean foundWildcard = false;
196
197 mSpec = spec;
198 mIsIn = new SparseBooleanArray();
199
200 for (String itemPrefixed : spec.split(",", -1)) {
201 if (itemPrefixed.length() == 0) {
202 throw new IllegalArgumentException(
203 "Illegal spec, must not have zero-length items: `" + spec + "`");
204 }
205 boolean isIn = itemPrefixed.charAt(0) != OUT_PREFIX;
206 String item = isIn ? itemPrefixed : itemPrefixed.substring(1);
207
208 if (itemPrefixed.length() == 0) {
209 throw new IllegalArgumentException(
210 "Illegal spec, must not have zero-length items: `" + spec + "`");
211 }
212
213 if (WILDCARD.equals(item)) {
214 if (foundWildcard) {
215 throw new IllegalArgumentException("Illegal spec, `" + WILDCARD +
216 "` must not appear multiple times in `" + spec + "`");
217 }
218 defaultIsIn = isIn;
219 foundWildcard = true;
220 } else {
221 int key = Integer.parseInt(item);
222 if (mIsIn.indexOfKey(key) >= 0) {
223 throw new IllegalArgumentException("Illegal spec, `" + key +
224 "` must not appear multiple times in `" + spec + "`");
225 }
226 mIsIn.put(key, isIn);
227 }
228 }
229
230 if (!foundWildcard) {
231 throw new IllegalArgumentException("Illegal spec, must specify either * or !*");
232 }
233
234 mDefaultIsIn = defaultIsIn;
235 }
236
237 public boolean isIn(int value) {
238 return (mIsIn.get(value, mDefaultIsIn));
239 }
240 }
John Spurlockd06aa572014-09-10 10:40:49 -0400241}