• 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.settings.fuelgauge.anomaly;
18 
19 import android.content.Context;
20 import android.net.Uri;
21 import android.provider.Settings;
22 import android.support.annotation.VisibleForTesting;
23 import android.text.format.DateUtils;
24 import android.util.KeyValueListParser;
25 import android.util.Log;
26 
27 import java.util.Arrays;
28 import java.util.Set;
29 import java.util.stream.Collectors;
30 
31 /**
32  * Class to store the policy for anomaly detection, which comes from
33  * {@link android.provider.Settings.Global}
34  */
35 public class AnomalyDetectionPolicy {
36     public static final String TAG = "AnomalyDetectionPolicy";
37 
38     @VisibleForTesting
39     static final String KEY_ANOMALY_DETECTION_ENABLED = "anomaly_detection_enabled";
40     @VisibleForTesting
41     static final String KEY_WAKELOCK_DETECTION_ENABLED = "wakelock_enabled";
42     @VisibleForTesting
43     static final String KEY_WAKEUP_ALARM_DETECTION_ENABLED = "wakeup_alarm_enabled";
44     @VisibleForTesting
45     static final String KEY_BLUETOOTH_SCAN_DETECTION_ENABLED = "bluetooth_scan_enabled";
46     @VisibleForTesting
47     static final String KEY_WAKELOCK_THRESHOLD = "wakelock_threshold";
48     @VisibleForTesting
49     static final String KEY_WAKEUP_ALARM_THRESHOLD = "wakeup_alarm_threshold";
50     @VisibleForTesting
51     static final String KEY_WAKEUP_BLACKLISTED_TAGS = "wakeup_blacklisted_tags";
52     @VisibleForTesting
53     static final String KEY_BLUETOOTH_SCAN_THRESHOLD = "bluetooth_scan_threshold";
54 
55     /**
56      * {@code true} if general anomaly detection is enabled
57      *
58      * @see Settings.Global#ANOMALY_DETECTION_CONSTANTS
59      * @see #KEY_ANOMALY_DETECTION_ENABLED
60      */
61     final boolean anomalyDetectionEnabled;
62 
63     /**
64      * {@code true} if wakelock anomaly detection is enabled
65      *
66      * @see Settings.Global#ANOMALY_DETECTION_CONSTANTS
67      * @see #KEY_WAKELOCK_DETECTION_ENABLED
68      */
69     final boolean wakeLockDetectionEnabled;
70 
71     /**
72      * {@code true} if wakeup alarm detection is enabled
73      *
74      * @see Settings.Global#ANOMALY_DETECTION_CONSTANTS
75      * @see #KEY_WAKEUP_ALARM_DETECTION_ENABLED
76      */
77     final boolean wakeupAlarmDetectionEnabled;
78 
79     /**
80      * {@code true} if bluetooth scanning detection is enabled
81      *
82      * @see Settings.Global#ANOMALY_DETECTION_CONSTANTS
83      * @see #KEY_BLUETOOTH_SCAN_THRESHOLD
84      */
85     final boolean bluetoothScanDetectionEnabled;
86 
87     /**
88      * Threshold for wakelock time in milli seconds
89      *
90      * @see Settings.Global#ANOMALY_DETECTION_CONSTANTS
91      * @see #KEY_WAKELOCK_THRESHOLD
92      */
93     public final long wakeLockThreshold;
94 
95     /**
96      * Threshold for wakeup alarm count per hour
97      *
98      * @see Settings.Global#ANOMALY_DETECTION_CONSTANTS
99      * @see #KEY_WAKEUP_ALARM_THRESHOLD
100      */
101     public final long wakeupAlarmThreshold;
102 
103     /**
104      * Array of blacklisted wakeups, by tag.
105      *
106      * @see Settings.Global#ANOMALY_DETECTION_CONSTANTS
107      * @see #KEY_WAKEUP_BLACKLISTED_TAGS
108      */
109     public final Set<String> wakeupBlacklistedTags;
110 
111     /**
112      * Threshold for bluetooth unoptimized scanning time in milli seconds
113      *
114      * @see Settings.Global#ANOMALY_DETECTION_CONSTANTS
115      * @see #KEY_BLUETOOTH_SCAN_THRESHOLD
116      */
117     public final long bluetoothScanThreshold;
118 
119     private final KeyValueListParserWrapper mParserWrapper;
120 
AnomalyDetectionPolicy(Context context)121     public AnomalyDetectionPolicy(Context context) {
122         this(context, new KeyValueListParserWrapperImpl(new KeyValueListParser(',')));
123     }
124 
125     @VisibleForTesting
AnomalyDetectionPolicy(Context context, KeyValueListParserWrapper parserWrapper)126     AnomalyDetectionPolicy(Context context, KeyValueListParserWrapper parserWrapper) {
127         mParserWrapper = parserWrapper;
128         final String value = Settings.Global.getString(context.getContentResolver(),
129                 Settings.Global.ANOMALY_DETECTION_CONSTANTS);
130 
131         try {
132             mParserWrapper.setString(value);
133         } catch (IllegalArgumentException e) {
134             Log.e(TAG, "Bad anomaly detection constants");
135         }
136 
137         anomalyDetectionEnabled =
138                 mParserWrapper.getBoolean(KEY_ANOMALY_DETECTION_ENABLED, false);
139         wakeLockDetectionEnabled =
140                 mParserWrapper.getBoolean(KEY_WAKELOCK_DETECTION_ENABLED,false);
141         wakeupAlarmDetectionEnabled =
142                 mParserWrapper.getBoolean(KEY_WAKEUP_ALARM_DETECTION_ENABLED,false);
143         bluetoothScanDetectionEnabled = mParserWrapper.getBoolean(
144                 KEY_BLUETOOTH_SCAN_DETECTION_ENABLED, false);
145         wakeLockThreshold = mParserWrapper.getLong(KEY_WAKELOCK_THRESHOLD,
146                 DateUtils.HOUR_IN_MILLIS);
147         wakeupAlarmThreshold = mParserWrapper.getLong(KEY_WAKEUP_ALARM_THRESHOLD, 10);
148         wakeupBlacklistedTags = parseStringSet(KEY_WAKEUP_BLACKLISTED_TAGS, null);
149         bluetoothScanThreshold = mParserWrapper.getLong(KEY_BLUETOOTH_SCAN_THRESHOLD,
150                 30 * DateUtils.MINUTE_IN_MILLIS);
151     }
152 
isAnomalyDetectionEnabled()153     public boolean isAnomalyDetectionEnabled() {
154         return anomalyDetectionEnabled;
155     }
156 
isAnomalyDetectorEnabled(@nomaly.AnomalyType int type)157     public boolean isAnomalyDetectorEnabled(@Anomaly.AnomalyType int type) {
158         switch (type) {
159             case Anomaly.AnomalyType.WAKE_LOCK:
160                 return wakeLockDetectionEnabled;
161             case Anomaly.AnomalyType.WAKEUP_ALARM:
162                 return wakeupAlarmDetectionEnabled;
163             case Anomaly.AnomalyType.BLUETOOTH_SCAN:
164                 return bluetoothScanDetectionEnabled;
165             default:
166                 return false; // Disabled when no this type
167         }
168     }
169 
parseStringSet(final String key, final Set<String> defaultSet)170     private Set<String> parseStringSet(final String key, final Set<String> defaultSet) {
171         final String value = mParserWrapper.getString(key, null);
172         if (value != null) {
173             return Arrays.stream(value.split(":"))
174                     .map(String::trim).map(Uri::decode).collect(Collectors.toSet());
175         } else {
176             return defaultSet;
177         }
178     }
179 }
180