blob: 0e074c7b871027fbb847f93019e9f633b806f4b9 [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;
Adrian Roosebea7a72016-10-26 12:51:26 -070020import android.os.Build;
John Spurlockd06aa572014-09-10 10:40:49 -040021import android.os.SystemProperties;
Adrian Roosb7e4e102016-10-14 13:03:45 -070022import android.os.UserHandle;
Adrian Roosebea7a72016-10-26 12:51:26 -070023import android.provider.Settings;
John Spurlockd06aa572014-09-10 10:40:49 -040024import android.text.TextUtils;
John Spurlockd06aa572014-09-10 10:40:49 -040025import android.util.MathUtils;
Adrian Roos5753f052016-07-13 10:30:37 -070026import android.util.SparseBooleanArray;
John Spurlockd06aa572014-09-10 10:40:49 -040027
28import 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;
John Spurlockd06aa572014-09-10 10:40:49 -040034
35 private final Context mContext;
36
Adrian Roos5753f052016-07-13 10:30:37 -070037 private static IntInOutMatcher sPickupSubtypePerformsProxMatcher;
38
John Spurlockd06aa572014-09-10 10:40:49 -040039 public DozeParameters(Context context) {
40 mContext = context;
41 }
42
43 public void dump(PrintWriter pw) {
44 pw.println(" DozeParameters:");
John Spurlock190d0262014-09-14 15:39:13 -040045 pw.print(" getDisplayStateSupported(): "); pw.println(getDisplayStateSupported());
John Spurlockf5d250d2014-12-02 10:41:25 -050046 pw.print(" getPulseDuration(pickup=false): "); pw.println(getPulseDuration(false));
47 pw.print(" getPulseDuration(pickup=true): "); pw.println(getPulseDuration(true));
48 pw.print(" getPulseInDuration(pickup=false): "); pw.println(getPulseInDuration(false));
49 pw.print(" getPulseInDuration(pickup=true): "); pw.println(getPulseInDuration(true));
John Spurlockd06aa572014-09-10 10:40:49 -040050 pw.print(" getPulseInVisibleDuration(): "); pw.println(getPulseVisibleDuration());
51 pw.print(" getPulseOutDuration(): "); pw.println(getPulseOutDuration());
John Spurlock190d0262014-09-14 15:39:13 -040052 pw.print(" getPulseOnSigMotion(): "); pw.println(getPulseOnSigMotion());
53 pw.print(" getVibrateOnSigMotion(): "); pw.println(getVibrateOnSigMotion());
John Spurlock190d0262014-09-14 15:39:13 -040054 pw.print(" getVibrateOnPickup(): "); pw.println(getVibrateOnPickup());
John Spurlock686e4d52014-11-20 21:48:09 -050055 pw.print(" getProxCheckBeforePulse(): "); pw.println(getProxCheckBeforePulse());
John Spurlock50a8ea62014-09-16 09:12:03 -040056 pw.print(" getPickupVibrationThreshold(): "); pw.println(getPickupVibrationThreshold());
Adrian Roos5753f052016-07-13 10:30:37 -070057 pw.print(" getPickupSubtypePerformsProxCheck(): ");pw.println(
58 dumpPickupSubtypePerformsProxCheck());
59 }
60
61 private String dumpPickupSubtypePerformsProxCheck() {
62 // Refresh sPickupSubtypePerformsProxMatcher
63 getPickupSubtypePerformsProxCheck(0);
64
65 if (sPickupSubtypePerformsProxMatcher == null) {
66 return "fallback: " + mContext.getResources().getBoolean(
67 R.bool.doze_pickup_performs_proximity_check);
68 } else {
69 return "spec: " + sPickupSubtypePerformsProxMatcher.mSpec;
70 }
John Spurlock190d0262014-09-14 15:39:13 -040071 }
72
73 public boolean getDisplayStateSupported() {
74 return getBoolean("doze.display.supported", R.bool.doze_display_state_supported);
John Spurlockd06aa572014-09-10 10:40:49 -040075 }
76
John Spurlockf5d250d2014-12-02 10:41:25 -050077 public int getPulseDuration(boolean pickup) {
78 return getPulseInDuration(pickup) + getPulseVisibleDuration() + getPulseOutDuration();
John Spurlockd06aa572014-09-10 10:40:49 -040079 }
80
Adrian Roos7294c112016-09-20 14:03:21 -070081 public int getPulseInDuration(boolean pickupOrDoubleTap) {
82 return pickupOrDoubleTap
John Spurlockf5d250d2014-12-02 10:41:25 -050083 ? getInt("doze.pulse.duration.in.pickup", R.integer.doze_pulse_duration_in_pickup)
84 : getInt("doze.pulse.duration.in", R.integer.doze_pulse_duration_in);
John Spurlockd06aa572014-09-10 10:40:49 -040085 }
86
87 public int getPulseVisibleDuration() {
88 return getInt("doze.pulse.duration.visible", R.integer.doze_pulse_duration_visible);
89 }
90
91 public int getPulseOutDuration() {
92 return getInt("doze.pulse.duration.out", R.integer.doze_pulse_duration_out);
93 }
94
John Spurlock190d0262014-09-14 15:39:13 -040095 public boolean getPulseOnSigMotion() {
96 return getBoolean("doze.pulse.sigmotion", R.bool.doze_pulse_on_significant_motion);
John Spurlockd06aa572014-09-10 10:40:49 -040097 }
98
John Spurlock190d0262014-09-14 15:39:13 -040099 public boolean getVibrateOnSigMotion() {
100 return SystemProperties.getBoolean("doze.vibrate.sigmotion", false);
101 }
102
John Spurlock190d0262014-09-14 15:39:13 -0400103 public boolean getVibrateOnPickup() {
104 return SystemProperties.getBoolean("doze.vibrate.pickup", false);
105 }
106
John Spurlock686e4d52014-11-20 21:48:09 -0500107 public boolean getProxCheckBeforePulse() {
108 return getBoolean("doze.pulse.proxcheck", R.bool.doze_proximity_check_before_pulse);
109 }
110
John Spurlock50a8ea62014-09-16 09:12:03 -0400111 public int getPickupVibrationThreshold() {
112 return getInt("doze.pickup.vibration.threshold", R.integer.doze_pickup_vibration_threshold);
113 }
114
Adrian Roosebea7a72016-10-26 12:51:26 -0700115 public boolean getAlwaysOn() {
116 return Build.IS_DEBUGGABLE
117 && Settings.Secure.getIntForUser(mContext.getContentResolver(),
118 Settings.Secure.DOZE_ALWAYS_ON, 0, UserHandle.USER_CURRENT) != 0;
119 }
120
John Spurlock190d0262014-09-14 15:39:13 -0400121 private boolean getBoolean(String propName, int resId) {
122 return SystemProperties.getBoolean(propName, mContext.getResources().getBoolean(resId));
John Spurlockd06aa572014-09-10 10:40:49 -0400123 }
124
125 private int getInt(String propName, int resId) {
126 int value = SystemProperties.getInt(propName, mContext.getResources().getInteger(resId));
127 return MathUtils.constrain(value, 0, MAX_DURATION);
128 }
129
130 private String getString(String propName, int resId) {
131 return SystemProperties.get(propName, mContext.getString(resId));
132 }
133
Adrian Roos5753f052016-07-13 10:30:37 -0700134 public boolean getPickupSubtypePerformsProxCheck(int subType) {
135 String spec = getString("doze.pickup.proxcheck",
136 R.string.doze_pickup_subtype_performs_proximity_check);
137
138 if (TextUtils.isEmpty(spec)) {
139 // Fall back to non-subtype based property.
140 return mContext.getResources().getBoolean(R.bool.doze_pickup_performs_proximity_check);
141 }
142
143 if (sPickupSubtypePerformsProxMatcher == null
144 || !TextUtils.equals(spec, sPickupSubtypePerformsProxMatcher.mSpec)) {
145 sPickupSubtypePerformsProxMatcher = new IntInOutMatcher(spec);
146 }
147
148 return sPickupSubtypePerformsProxMatcher.isIn(subType);
149 }
150
151
152 /**
153 * Parses a spec of the form `1,2,3,!5,*`. The resulting object will match numbers that are
154 * listed, will not match numbers that are listed with a ! prefix, and will match / not match
155 * unlisted numbers depending on whether * or !* is present.
156 *
157 * * -> match any numbers that are not explicitly listed
158 * !* -> don't match any numbers that are not explicitly listed
159 * 2 -> match 2
160 * !3 -> don't match 3
161 *
162 * It is illegal to specify:
163 * - an empty spec
164 * - a spec containing that are empty, or a lone !
165 * - a spec for anything other than numbers or *
166 * - multiple terms for the same number / multiple *s
167 */
168 public static class IntInOutMatcher {
169 private static final String WILDCARD = "*";
170 private static final char OUT_PREFIX = '!';
171
172 private final SparseBooleanArray mIsIn;
173 private final boolean mDefaultIsIn;
174 final String mSpec;
175
176 public IntInOutMatcher(String spec) {
177 if (TextUtils.isEmpty(spec)) {
178 throw new IllegalArgumentException("Spec must not be empty");
179 }
180
181 boolean defaultIsIn = false;
182 boolean foundWildcard = false;
183
184 mSpec = spec;
185 mIsIn = new SparseBooleanArray();
186
187 for (String itemPrefixed : spec.split(",", -1)) {
188 if (itemPrefixed.length() == 0) {
189 throw new IllegalArgumentException(
190 "Illegal spec, must not have zero-length items: `" + spec + "`");
191 }
192 boolean isIn = itemPrefixed.charAt(0) != OUT_PREFIX;
193 String item = isIn ? itemPrefixed : itemPrefixed.substring(1);
194
195 if (itemPrefixed.length() == 0) {
196 throw new IllegalArgumentException(
197 "Illegal spec, must not have zero-length items: `" + spec + "`");
198 }
199
200 if (WILDCARD.equals(item)) {
201 if (foundWildcard) {
202 throw new IllegalArgumentException("Illegal spec, `" + WILDCARD +
203 "` must not appear multiple times in `" + spec + "`");
204 }
205 defaultIsIn = isIn;
206 foundWildcard = true;
207 } else {
208 int key = Integer.parseInt(item);
209 if (mIsIn.indexOfKey(key) >= 0) {
210 throw new IllegalArgumentException("Illegal spec, `" + key +
211 "` must not appear multiple times in `" + spec + "`");
212 }
213 mIsIn.put(key, isIn);
214 }
215 }
216
217 if (!foundWildcard) {
218 throw new IllegalArgumentException("Illegal spec, must specify either * or !*");
219 }
220
221 mDefaultIsIn = defaultIsIn;
222 }
223
224 public boolean isIn(int value) {
225 return (mIsIn.get(value, mDefaultIsIn));
226 }
227 }
John Spurlockd06aa572014-09-10 10:40:49 -0400228}