Get anomalyType and autoRestriction from config

Now the westworld config provides COOKIES to store private info
for each alert(anomaly). So we could use it to store:
1. AnomalyType: what is the type of anomaly
2. AutoRestriction: whether to auto restrict this anomaly

Bug: 74567790
Test: RunSettingsRoboTests
Change-Id: I15f5e225a4cb1f2da3fe109e56e5222816d179cc
diff --git a/src/com/android/settings/fuelgauge/batterytip/AnomalyDetectionJobService.java b/src/com/android/settings/fuelgauge/batterytip/AnomalyDetectionJobService.java
index c2af02a..619913d 100644
--- a/src/com/android/settings/fuelgauge/batterytip/AnomalyDetectionJobService.java
+++ b/src/com/android/settings/fuelgauge/batterytip/AnomalyDetectionJobService.java
@@ -40,8 +40,11 @@
 import android.util.Log;
 
 import com.android.internal.os.BatteryStatsHelper;
+import com.android.internal.util.ArrayUtils;
 import com.android.settings.R;
 import com.android.settings.fuelgauge.BatteryUtils;
+import com.android.settings.fuelgauge.PowerUsageFeatureProvider;
+import com.android.settings.overlay.FeatureFactory;
 import com.android.settingslib.fuelgauge.PowerWhitelistBackend;
 import com.android.settingslib.utils.ThreadUtils;
 
@@ -84,11 +87,14 @@
                     true /* collectBatteryBroadcast */);
             final UserManager userManager = getSystemService(UserManager.class);
             final PowerWhitelistBackend powerWhitelistBackend = PowerWhitelistBackend.getInstance();
+            final PowerUsageFeatureProvider powerUsageFeatureProvider = FeatureFactory
+                    .getFactory(this).getPowerUsageFeatureProvider(this);
 
             for (JobWorkItem item = params.dequeueWork(); item != null;
                     item = params.dequeueWork()) {
                 saveAnomalyToDatabase(batteryStatsHelper, userManager, batteryDatabaseManager,
                         batteryUtils, policy, powerWhitelistBackend, contentResolver,
+                        powerUsageFeatureProvider,
                         item.getIntent().getExtras());
             }
             jobFinished(params, false /* wantsReschedule */);
@@ -106,42 +112,52 @@
     void saveAnomalyToDatabase(BatteryStatsHelper batteryStatsHelper, UserManager userManager,
             BatteryDatabaseManager databaseManager, BatteryUtils batteryUtils,
             BatteryTipPolicy policy, PowerWhitelistBackend powerWhitelistBackend,
-            ContentResolver contentResolver, Bundle bundle) {
+            ContentResolver contentResolver, PowerUsageFeatureProvider powerUsageFeatureProvider,
+            Bundle bundle) {
         // The Example of intentDimsValue is: 35:{1:{1:{1:10013|}|}|}
         final StatsDimensionsValue intentDimsValue =
                 bundle.getParcelable(StatsManager.EXTRA_STATS_DIMENSIONS_VALUE);
-        final long subscriptionId = bundle.getLong(StatsManager.EXTRA_STATS_SUBSCRIPTION_ID,
-                -1);
         final long timeMs = bundle.getLong(AnomalyDetectionReceiver.KEY_ANOMALY_TIMESTAMP,
                 System.currentTimeMillis());
+        final String[] cookies = bundle.getStringArray(
+                StatsManager.EXTRA_STATS_BROADCAST_SUBSCRIBER_COOKIES);
+        final AnomalyInfo anomalyInfo = new AnomalyInfo(
+                !ArrayUtils.isEmpty(cookies) ? cookies[0] : "");
         Log.i(TAG, "Extra stats value: " + intentDimsValue.toString());
 
         try {
             final int uid = extractUidFromStatsDimensionsValue(intentDimsValue);
-            final int anomalyType = StatsManagerConfig.getAnomalyTypeFromSubscriptionId(
-                    subscriptionId);
-            final boolean smartBatteryOn = Settings.Global.getInt(contentResolver,
-                    Settings.Global.APP_STANDBY_ENABLED, ON) == ON;
+            final boolean autoFeatureOn = powerUsageFeatureProvider.isSmartBatterySupported()
+                    ? Settings.Global.getInt(contentResolver,
+                            Settings.Global.APP_STANDBY_ENABLED, ON) == ON
+                    : Settings.Global.getInt(contentResolver,
+                            Settings.Global.APP_AUTO_RESTRICTION_ENABLED, ON) == ON;
             final String packageName = batteryUtils.getPackageName(uid);
             if (!powerWhitelistBackend.isSysWhitelistedExceptIdle(packageName)
                     && !isSystemUid(uid)) {
-                if (anomalyType == StatsManagerConfig.AnomalyType.EXCESSIVE_BG) {
-                    // TODO(b/72385333): check battery percentage draining in batterystats
-                    if (batteryUtils.isPreOApp(packageName) && batteryUtils.isAppHeavilyUsed(
-                            batteryStatsHelper, userManager, uid,
+                boolean anomalyDetected = true;
+                if (anomalyInfo.anomalyType == StatsManagerConfig.AnomalyType.EXCESSIVE_BG) {
+                    if (!batteryUtils.isPreOApp(packageName)
+                            || !batteryUtils.isAppHeavilyUsed(batteryStatsHelper, userManager, uid,
                             policy.excessiveBgDrainPercentage)) {
-                        Log.e(TAG, "Excessive detected uid=" + uid);
+                        // Don't report if it is not legacy app or haven't used much battery
+                        anomalyDetected = false;
+                    }
+                }
+
+                if (anomalyDetected) {
+                    if (autoFeatureOn && anomalyInfo.autoRestriction) {
+                        // Auto restrict this app
                         batteryUtils.setForceAppStandby(uid, packageName,
                                 AppOpsManager.MODE_IGNORED);
-                        databaseManager.insertAnomaly(uid, packageName, anomalyType,
-                                smartBatteryOn
-                                        ? AnomalyDatabaseHelper.State.AUTO_HANDLED
-                                        : AnomalyDatabaseHelper.State.NEW,
+                        databaseManager.insertAnomaly(uid, packageName, anomalyInfo.anomalyType,
+                                AnomalyDatabaseHelper.State.AUTO_HANDLED,
+                                timeMs);
+                    } else {
+                        databaseManager.insertAnomaly(uid, packageName, anomalyInfo.anomalyType,
+                                AnomalyDatabaseHelper.State.NEW,
                                 timeMs);
                     }
-                } else {
-                    databaseManager.insertAnomaly(uid, packageName, anomalyType,
-                            AnomalyDatabaseHelper.State.NEW, timeMs);
                 }
             }
         } catch (NullPointerException | IndexOutOfBoundsException e) {
diff --git a/src/com/android/settings/fuelgauge/batterytip/AnomalyInfo.java b/src/com/android/settings/fuelgauge/batterytip/AnomalyInfo.java
new file mode 100644
index 0000000..a4077be
--- /dev/null
+++ b/src/com/android/settings/fuelgauge/batterytip/AnomalyInfo.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.fuelgauge.batterytip;
+
+import android.util.KeyValueListParser;
+
+/**
+ * Model class to parse and store anomaly info from westworld
+ */
+public class AnomalyInfo {
+    private static final String KEY_ANOMALY_TYPE = "anomaly_type";
+    private static final String KEY_AUTO_RESTRICTION = "auto_restriction";
+    public final Integer anomalyType;
+    public final boolean autoRestriction;
+
+    public AnomalyInfo(String info) {
+        KeyValueListParser parser = new KeyValueListParser(',');
+        parser.setString(info);
+        anomalyType = parser.getInt(KEY_ANOMALY_TYPE, -1);
+        autoRestriction = parser.getBoolean(KEY_AUTO_RESTRICTION, false);
+    }
+
+}
\ No newline at end of file
diff --git a/src/com/android/settings/fuelgauge/batterytip/StatsManagerConfig.java b/src/com/android/settings/fuelgauge/batterytip/StatsManagerConfig.java
index 62eb7ee..4ae3f10 100644
--- a/src/com/android/settings/fuelgauge/batterytip/StatsManagerConfig.java
+++ b/src/com/android/settings/fuelgauge/batterytip/StatsManagerConfig.java
@@ -41,22 +41,6 @@
      */
     public static final long SUBSCRIBER_ID = 1;
 
-    private static final Map<Long, Integer> ANOMALY_TYPE;
-
-    private static final HashFunction HASH_FUNCTION = Hashing.sha256();
-
-    static {
-        ANOMALY_TYPE = new HashMap<>();
-        ANOMALY_TYPE.put(hash("SUBSCRIPTION:SETTINGS_EXCESSIVE_BACKGROUND_SERVICE"),
-                AnomalyType.EXCESSIVE_BG);
-        ANOMALY_TYPE.put(hash("SUBSCRIPTION:SETTINGS_LONG_UNOPTIMIZED_BLE_SCAN"),
-                AnomalyType.BLUETOOTH_SCAN);
-        ANOMALY_TYPE.put(hash("SUBSCRIPTION:SETTINGS_EXCESSIVE_WAKEUPS_IN_BACKGROUND"),
-                AnomalyType.WAKEUP_ALARM);
-        ANOMALY_TYPE.put(hash("SUBSCRIPTION:SETTINGS_EXCESSIVE_WAKELOCK_ALL_SCREEN_OFF"),
-                AnomalyType.WAKE_LOCK);
-    }
-
     @Retention(RetentionPolicy.SOURCE)
     @IntDef({AnomalyType.NULL,
             AnomalyType.WAKE_LOCK,
@@ -71,11 +55,4 @@
         int EXCESSIVE_BG = 3;
     }
 
-    public static int getAnomalyTypeFromSubscriptionId(long subscriptionId) {
-        return ANOMALY_TYPE.getOrDefault(subscriptionId, AnomalyType.NULL);
-    }
-
-    private static long hash(CharSequence value) {
-        return HASH_FUNCTION.hashUnencodedChars(value).asLong();
-    }
 }
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/AnomalyDetectionJobServiceTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/AnomalyDetectionJobServiceTest.java
index 499ab9d..d2b11fd 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/AnomalyDetectionJobServiceTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/AnomalyDetectionJobServiceTest.java
@@ -22,6 +22,7 @@
 import static org.mockito.Matchers.anyInt;
 import static org.mockito.Matchers.anyLong;
 import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.spy;
@@ -41,6 +42,8 @@
 import com.android.internal.os.BatteryStatsHelper;
 import com.android.settings.R;
 import com.android.settings.fuelgauge.BatteryUtils;
+import com.android.settings.overlay.FeatureFactory;
+import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settingslib.fuelgauge.PowerWhitelistBackend;
 
@@ -60,6 +63,10 @@
 public class AnomalyDetectionJobServiceTest {
     private static final int UID = 123;
     private static final String SYSTEM_PACKAGE = "com.android.system";
+    private static final String SUBSCRIBER_COOKIES_AUTO_RESTRICTION =
+            "anomaly_type=6,auto_restriction=true";
+    private static final String SUBSCRIBER_COOKIES_NOT_AUTO_RESTRICTION =
+            "anomaly_type=6,auto_restriction=false";
     @Mock
     private BatteryStatsHelper mBatteryStatsHelper;
     @Mock
@@ -76,6 +83,7 @@
     private BatteryTipPolicy mPolicy;
     private Bundle mBundle;
     private AnomalyDetectionJobService mAnomalyDetectionJobService;
+    private FakeFeatureFactory mFeatureFactory;
     private Context mContext;
 
     @Before
@@ -86,6 +94,7 @@
         mPolicy = new BatteryTipPolicy(mContext);
         mBundle = new Bundle();
         mBundle.putParcelable(StatsManager.EXTRA_STATS_DIMENSIONS_VALUE, mStatsDimensionsValue);
+        mFeatureFactory = FakeFeatureFactory.setupForTest();
 
         mAnomalyDetectionJobService = spy(new AnomalyDetectionJobService());
     }
@@ -112,7 +121,7 @@
 
         mAnomalyDetectionJobService.saveAnomalyToDatabase(mBatteryStatsHelper, mUserManager,
                 mBatteryDatabaseManager, mBatteryUtils, mPolicy, mPowerWhitelistBackend,
-                mContext.getContentResolver(), mBundle);
+                mContext.getContentResolver(), mFeatureFactory.powerUsageFeatureProvider, mBundle);
 
         verify(mBatteryDatabaseManager, never()).insertAnomaly(anyInt(), anyString(), anyInt(),
                 anyInt(), anyLong());
@@ -125,14 +134,16 @@
 
         mAnomalyDetectionJobService.saveAnomalyToDatabase(mBatteryStatsHelper, mUserManager,
                 mBatteryDatabaseManager, mBatteryUtils, mPolicy, mPowerWhitelistBackend,
-                mContext.getContentResolver(), mBundle);
+                mContext.getContentResolver(), mFeatureFactory.powerUsageFeatureProvider, mBundle);
 
         verify(mBatteryDatabaseManager, never()).insertAnomaly(anyInt(), anyString(), anyInt(),
                 anyInt(), anyLong());
     }
 
     @Test
-    public void testSaveAnomalyToDatabase_normalApp_save() {
+    public void testSaveAnomalyToDatabase_normalAppWithAutoRestriction_save() {
+        mBundle.putStringArray(StatsManager.EXTRA_STATS_BROADCAST_SUBSCRIBER_COOKIES,
+                new String[]{SUBSCRIBER_COOKIES_AUTO_RESTRICTION});
         doReturn(SYSTEM_PACKAGE).when(mBatteryUtils).getPackageName(anyInt());
         doReturn(false).when(mPowerWhitelistBackend).isSysWhitelisted(SYSTEM_PACKAGE);
         doReturn(Process.FIRST_APPLICATION_UID).when(
@@ -140,9 +151,27 @@
 
         mAnomalyDetectionJobService.saveAnomalyToDatabase(mBatteryStatsHelper, mUserManager,
                 mBatteryDatabaseManager, mBatteryUtils, mPolicy, mPowerWhitelistBackend,
-                mContext.getContentResolver(), mBundle);
+                mContext.getContentResolver(), mFeatureFactory.powerUsageFeatureProvider, mBundle);
 
-        verify(mBatteryDatabaseManager).insertAnomaly(anyInt(), anyString(), anyInt(), anyInt(),
-                anyLong());
+        verify(mBatteryDatabaseManager).insertAnomaly(anyInt(), anyString(), eq(6),
+                eq(AnomalyDatabaseHelper.State.AUTO_HANDLED), anyLong());
+    }
+
+
+    @Test
+    public void testSaveAnomalyToDatabase_normalAppWithoutAutoRestriction_save() {
+        mBundle.putStringArray(StatsManager.EXTRA_STATS_BROADCAST_SUBSCRIBER_COOKIES,
+                new String[]{SUBSCRIBER_COOKIES_NOT_AUTO_RESTRICTION});
+        doReturn(SYSTEM_PACKAGE).when(mBatteryUtils).getPackageName(anyInt());
+        doReturn(false).when(mPowerWhitelistBackend).isSysWhitelisted(SYSTEM_PACKAGE);
+        doReturn(Process.FIRST_APPLICATION_UID).when(
+                mAnomalyDetectionJobService).extractUidFromStatsDimensionsValue(any());
+
+        mAnomalyDetectionJobService.saveAnomalyToDatabase(mBatteryStatsHelper, mUserManager,
+                mBatteryDatabaseManager, mBatteryUtils, mPolicy, mPowerWhitelistBackend,
+                mContext.getContentResolver(), mFeatureFactory.powerUsageFeatureProvider, mBundle);
+
+        verify(mBatteryDatabaseManager).insertAnomaly(anyInt(), anyString(), eq(6),
+                eq(AnomalyDatabaseHelper.State.NEW), anyLong());
     }
 }