• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.Context;
20 import android.os.SystemProperties;
21 import android.text.TextUtils;
22 import android.util.Log;
23 import android.util.MathUtils;
24 import android.util.SparseBooleanArray;
25 
26 import com.android.systemui.R;
27 
28 import java.io.PrintWriter;
29 import java.util.Arrays;
30 import java.util.regex.Matcher;
31 import java.util.regex.Pattern;
32 
33 public class DozeParameters {
34     private static final String TAG = "DozeParameters";
35     private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
36 
37     private static final int MAX_DURATION = 60 * 1000;
38 
39     private final Context mContext;
40 
41     private static IntInOutMatcher sPickupSubtypePerformsProxMatcher;
42 
DozeParameters(Context context)43     public DozeParameters(Context context) {
44         mContext = context;
45     }
46 
dump(PrintWriter pw)47     public void dump(PrintWriter pw) {
48         pw.println("  DozeParameters:");
49         pw.print("    getDisplayStateSupported(): "); pw.println(getDisplayStateSupported());
50         pw.print("    getPulseDuration(pickup=false): "); pw.println(getPulseDuration(false));
51         pw.print("    getPulseDuration(pickup=true): "); pw.println(getPulseDuration(true));
52         pw.print("    getPulseInDuration(pickup=false): "); pw.println(getPulseInDuration(false));
53         pw.print("    getPulseInDuration(pickup=true): "); pw.println(getPulseInDuration(true));
54         pw.print("    getPulseInVisibleDuration(): "); pw.println(getPulseVisibleDuration());
55         pw.print("    getPulseOutDuration(): "); pw.println(getPulseOutDuration());
56         pw.print("    getPulseOnSigMotion(): "); pw.println(getPulseOnSigMotion());
57         pw.print("    getVibrateOnSigMotion(): "); pw.println(getVibrateOnSigMotion());
58         pw.print("    getPulseOnPickup(): "); pw.println(getPulseOnPickup());
59         pw.print("    getVibrateOnPickup(): "); pw.println(getVibrateOnPickup());
60         pw.print("    getProxCheckBeforePulse(): "); pw.println(getProxCheckBeforePulse());
61         pw.print("    getPulseOnNotifications(): "); pw.println(getPulseOnNotifications());
62         pw.print("    getPickupVibrationThreshold(): "); pw.println(getPickupVibrationThreshold());
63         pw.print("    getPickupSubtypePerformsProxCheck(): ");pw.println(
64                 dumpPickupSubtypePerformsProxCheck());
65     }
66 
dumpPickupSubtypePerformsProxCheck()67     private String dumpPickupSubtypePerformsProxCheck() {
68         // Refresh sPickupSubtypePerformsProxMatcher
69         getPickupSubtypePerformsProxCheck(0);
70 
71         if (sPickupSubtypePerformsProxMatcher == null) {
72             return "fallback: " + mContext.getResources().getBoolean(
73                     R.bool.doze_pickup_performs_proximity_check);
74         } else {
75             return "spec: " + sPickupSubtypePerformsProxMatcher.mSpec;
76         }
77     }
78 
getDisplayStateSupported()79     public boolean getDisplayStateSupported() {
80         return getBoolean("doze.display.supported", R.bool.doze_display_state_supported);
81     }
82 
getPulseDuration(boolean pickup)83     public int getPulseDuration(boolean pickup) {
84         return getPulseInDuration(pickup) + getPulseVisibleDuration() + getPulseOutDuration();
85     }
86 
getPulseInDuration(boolean pickup)87     public int getPulseInDuration(boolean pickup) {
88         return pickup
89                 ? getInt("doze.pulse.duration.in.pickup", R.integer.doze_pulse_duration_in_pickup)
90                 : getInt("doze.pulse.duration.in", R.integer.doze_pulse_duration_in);
91     }
92 
getPulseVisibleDuration()93     public int getPulseVisibleDuration() {
94         return getInt("doze.pulse.duration.visible", R.integer.doze_pulse_duration_visible);
95     }
96 
getPulseOutDuration()97     public int getPulseOutDuration() {
98         return getInt("doze.pulse.duration.out", R.integer.doze_pulse_duration_out);
99     }
100 
getPulseOnSigMotion()101     public boolean getPulseOnSigMotion() {
102         return getBoolean("doze.pulse.sigmotion", R.bool.doze_pulse_on_significant_motion);
103     }
104 
getVibrateOnSigMotion()105     public boolean getVibrateOnSigMotion() {
106         return SystemProperties.getBoolean("doze.vibrate.sigmotion", false);
107     }
108 
getPulseOnPickup()109     public boolean getPulseOnPickup() {
110         return getBoolean("doze.pulse.pickup", R.bool.doze_pulse_on_pick_up);
111     }
112 
getVibrateOnPickup()113     public boolean getVibrateOnPickup() {
114         return SystemProperties.getBoolean("doze.vibrate.pickup", false);
115     }
116 
getProxCheckBeforePulse()117     public boolean getProxCheckBeforePulse() {
118         return getBoolean("doze.pulse.proxcheck", R.bool.doze_proximity_check_before_pulse);
119     }
120 
getPulseOnNotifications()121     public boolean getPulseOnNotifications() {
122         return getBoolean("doze.pulse.notifications", R.bool.doze_pulse_on_notifications);
123     }
124 
getPickupVibrationThreshold()125     public int getPickupVibrationThreshold() {
126         return getInt("doze.pickup.vibration.threshold", R.integer.doze_pickup_vibration_threshold);
127     }
128 
getBoolean(String propName, int resId)129     private boolean getBoolean(String propName, int resId) {
130         return SystemProperties.getBoolean(propName, mContext.getResources().getBoolean(resId));
131     }
132 
getInt(String propName, int resId)133     private int getInt(String propName, int resId) {
134         int value = SystemProperties.getInt(propName, mContext.getResources().getInteger(resId));
135         return MathUtils.constrain(value, 0, MAX_DURATION);
136     }
137 
getString(String propName, int resId)138     private String getString(String propName, int resId) {
139         return SystemProperties.get(propName, mContext.getString(resId));
140     }
141 
getPickupSubtypePerformsProxCheck(int subType)142     public boolean getPickupSubtypePerformsProxCheck(int subType) {
143         String spec = getString("doze.pickup.proxcheck",
144                 R.string.doze_pickup_subtype_performs_proximity_check);
145 
146         if (TextUtils.isEmpty(spec)) {
147             // Fall back to non-subtype based property.
148             return mContext.getResources().getBoolean(R.bool.doze_pickup_performs_proximity_check);
149         }
150 
151         if (sPickupSubtypePerformsProxMatcher == null
152                 || !TextUtils.equals(spec, sPickupSubtypePerformsProxMatcher.mSpec)) {
153             sPickupSubtypePerformsProxMatcher = new IntInOutMatcher(spec);
154         }
155 
156         return sPickupSubtypePerformsProxMatcher.isIn(subType);
157     }
158 
159 
160     /**
161      * Parses a spec of the form `1,2,3,!5,*`. The resulting object will match numbers that are
162      * listed, will not match numbers that are listed with a ! prefix, and will match / not match
163      * unlisted numbers depending on whether * or !* is present.
164      *
165      * *  -> match any numbers that are not explicitly listed
166      * !* -> don't match any numbers that are not explicitly listed
167      * 2  -> match 2
168      * !3 -> don't match 3
169      *
170      * It is illegal to specify:
171      * - an empty spec
172      * - a spec containing that are empty, or a lone !
173      * - a spec for anything other than numbers or *
174      * - multiple terms for the same number / multiple *s
175      */
176     public static class IntInOutMatcher {
177         private static final String WILDCARD = "*";
178         private static final char OUT_PREFIX = '!';
179 
180         private final SparseBooleanArray mIsIn;
181         private final boolean mDefaultIsIn;
182         final String mSpec;
183 
IntInOutMatcher(String spec)184         public IntInOutMatcher(String spec) {
185             if (TextUtils.isEmpty(spec)) {
186                 throw new IllegalArgumentException("Spec must not be empty");
187             }
188 
189             boolean defaultIsIn = false;
190             boolean foundWildcard = false;
191 
192             mSpec = spec;
193             mIsIn = new SparseBooleanArray();
194 
195             for (String itemPrefixed : spec.split(",", -1)) {
196                 if (itemPrefixed.length() == 0) {
197                     throw new IllegalArgumentException(
198                             "Illegal spec, must not have zero-length items: `" + spec + "`");
199                 }
200                 boolean isIn = itemPrefixed.charAt(0) != OUT_PREFIX;
201                 String item = isIn ? itemPrefixed : itemPrefixed.substring(1);
202 
203                 if (itemPrefixed.length() == 0) {
204                     throw new IllegalArgumentException(
205                             "Illegal spec, must not have zero-length items: `" + spec + "`");
206                 }
207 
208                 if (WILDCARD.equals(item)) {
209                     if (foundWildcard) {
210                         throw new IllegalArgumentException("Illegal spec, `" + WILDCARD +
211                                 "` must not appear multiple times in `" + spec + "`");
212                     }
213                     defaultIsIn = isIn;
214                     foundWildcard = true;
215                 } else {
216                     int key = Integer.parseInt(item);
217                     if (mIsIn.indexOfKey(key) >= 0) {
218                         throw new IllegalArgumentException("Illegal spec, `" + key +
219                                 "` must not appear multiple times in `" + spec + "`");
220                     }
221                     mIsIn.put(key, isIn);
222                 }
223             }
224 
225             if (!foundWildcard) {
226                 throw new IllegalArgumentException("Illegal spec, must specify either * or !*");
227             }
228 
229             mDefaultIsIn = defaultIsIn;
230         }
231 
isIn(int value)232         public boolean isIn(int value) {
233             return (mIsIn.get(value, mDefaultIsIn));
234         }
235     }
236 }
237