Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 940630ba authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Get anomalyType and autoRestriction from config" into pi-dev

parents 3749a8d8 baf8a0cf
Loading
Loading
Loading
Loading
+35 −19
Original line number Diff line number Diff line
@@ -40,8 +40,11 @@ import android.support.annotation.VisibleForTesting;
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 @@ public class AnomalyDetectionJobService extends JobService {
                    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 @@ public class AnomalyDetectionJobService extends JobService {
    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, anomalyType,
                            AnomalyDatabaseHelper.State.NEW, timeMs);
                        databaseManager.insertAnomaly(uid, packageName, anomalyInfo.anomalyType,
                                AnomalyDatabaseHelper.State.NEW,
                                timeMs);
                    }
                }
            }
        } catch (NullPointerException | IndexOutOfBoundsException e) {
+37 −0
Original line number Diff line number Diff line
/*
 * 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
+0 −23
Original line number Diff line number Diff line
@@ -41,22 +41,6 @@ public class StatsManagerConfig {
     */
    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 @@ public class StatsManagerConfig {
        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();
    }
}
+35 −6
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import static org.mockito.Matchers.any;
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 android.os.UserManager;
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 @@ import java.util.concurrent.TimeUnit;
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 @@ public class AnomalyDetectionJobServiceTest {
    private BatteryTipPolicy mPolicy;
    private Bundle mBundle;
    private AnomalyDetectionJobService mAnomalyDetectionJobService;
    private FakeFeatureFactory mFeatureFactory;
    private Context mContext;

    @Before
@@ -86,6 +94,7 @@ public class AnomalyDetectionJobServiceTest {
        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 @@ public class AnomalyDetectionJobServiceTest {

        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 @@ public class AnomalyDetectionJobServiceTest {

        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 @@ public class AnomalyDetectionJobServiceTest {

        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());
    }
}