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

Commit 10051afb authored by jackqdyulei's avatar jackqdyulei Committed by Lei Yu
Browse files

Add whitelist for anomaly detection.

Even though we can add whitelist in config, we still need to have a
on device whitelist to reduce the size of config.

Use doze whitelist here because we already used it to detect whether
we can restrict the app in battery detail page.

Bug: 74241534
Test: RunSettingsRoboTests
Change-Id: I35b6f3eba9fbc8ae51bb02cd9d5416e4360c388e
parent 3c5aeac3
Loading
Loading
Loading
Loading
+22 −18
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@ import android.util.Log;
import com.android.internal.os.BatteryStatsHelper;
import com.android.settings.R;
import com.android.settings.fuelgauge.BatteryUtils;
import com.android.settingslib.fuelgauge.PowerWhitelistBackend;
import com.android.settingslib.utils.ThreadUtils;

import java.util.List;
@@ -81,11 +82,12 @@ public class AnomalyDetectionJobService extends JobService {
            final BatteryStatsHelper batteryStatsHelper = new BatteryStatsHelper(this,
                    true /* collectBatteryBroadcast */);
            final UserManager userManager = getSystemService(UserManager.class);
            final PowerWhitelistBackend powerWhitelistBackend = PowerWhitelistBackend.getInstance();

            for (JobWorkItem item = params.dequeueWork(); item != null;
                    item = params.dequeueWork()) {
                saveAnomalyToDatabase(batteryStatsHelper, userManager, batteryDatabaseManager,
                        batteryUtils, policy, contentResolver,
                        batteryUtils, policy, powerWhitelistBackend, contentResolver,
                        item.getIntent().getExtras());
            }
            jobFinished(params, false /* wantsReschedule */);
@@ -102,7 +104,8 @@ public class AnomalyDetectionJobService extends JobService {
    @VisibleForTesting
    void saveAnomalyToDatabase(BatteryStatsHelper batteryStatsHelper, UserManager userManager,
            BatteryDatabaseManager databaseManager, BatteryUtils batteryUtils,
            BatteryTipPolicy policy, ContentResolver contentResolver, Bundle bundle) {
            BatteryTipPolicy policy, PowerWhitelistBackend powerWhitelistBackend,
            ContentResolver contentResolver, Bundle bundle) {
        // The Example of intentDimsValue is: 35:{1:{1:{1:10013|}|}|}
        final StatsDimensionsValue intentDimsValue =
                bundle.getParcelable(StatsManager.EXTRA_STATS_DIMENSIONS_VALUE);
@@ -119,7 +122,7 @@ public class AnomalyDetectionJobService extends JobService {
            final boolean smartBatteryOn = Settings.Global.getInt(contentResolver,
                    Settings.Global.APP_STANDBY_ENABLED, ON) == ON;
            final String packageName = batteryUtils.getPackageName(uid);

            if (!powerWhitelistBackend.isSysWhitelisted(packageName)) {
                if (anomalyType == StatsManagerConfig.AnomalyType.EXCESSIVE_BG) {
                    // TODO(b/72385333): check battery percentage draining in batterystats
                    if (batteryUtils.isLegacyApp(packageName) && batteryUtils.isAppHeavilyUsed(
@@ -138,6 +141,7 @@ public class AnomalyDetectionJobService extends JobService {
                    databaseManager.insertAnomaly(uid, packageName, anomalyType,
                            AnomalyDatabaseHelper.State.NEW, timeMs);
                }
            }
        } catch (NullPointerException | IndexOutOfBoundsException e) {
            Log.e(TAG, "Parse stats dimensions value error.", e);
        }
+7 −6
Original line number Diff line number Diff line
@@ -18,10 +18,10 @@ package com.android.settings.fuelgauge.batterytip;

import static com.android.settings.fuelgauge.batterytip.AnomalyDatabaseHelper.AnomalyColumns
        .ANOMALY_STATE;
import static com.android.settings.fuelgauge.batterytip.AnomalyDatabaseHelper.AnomalyColumns
        .PACKAGE_NAME;
import static com.android.settings.fuelgauge.batterytip.AnomalyDatabaseHelper.AnomalyColumns
        .ANOMALY_TYPE;
import static com.android.settings.fuelgauge.batterytip.AnomalyDatabaseHelper.AnomalyColumns
        .PACKAGE_NAME;
import static com.android.settings.fuelgauge.batterytip.AnomalyDatabaseHelper.AnomalyColumns
        .TIME_STAMP_MS;
import static com.android.settings.fuelgauge.batterytip.AnomalyDatabaseHelper.AnomalyColumns.UID;
@@ -61,6 +61,7 @@ public class BatteryDatabaseManager {

    /**
     * Insert an anomaly log to database.
     *
     * @param packageName  the package name of the app
     * @param type         the type of the anomaly
     * @param anomalyState the state of the anomaly
+76 −0
Original line number Diff line number Diff line
@@ -17,17 +17,36 @@
package com.android.settings.fuelgauge.batterytip;

import static com.google.common.truth.Truth.assertThat;

import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyLong;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.robolectric.RuntimeEnvironment.application;

import android.app.StatsManager;
import android.app.job.JobInfo;
import android.app.job.JobScheduler;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.StatsDimensionsValue;
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.testutils.SettingsRobolectricTestRunner;
import com.android.settingslib.fuelgauge.PowerWhitelistBackend;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.Shadows;
import org.robolectric.shadows.ShadowJobScheduler;

@@ -36,6 +55,37 @@ import java.util.concurrent.TimeUnit;

@RunWith(SettingsRobolectricTestRunner.class)
public class AnomalyDetectionJobServiceTest {
    private static final int UID = 123;
    private static final String SYSTEM_PACKAGE = "com.android.system";
    @Mock
    private BatteryStatsHelper mBatteryStatsHelper;
    @Mock
    private UserManager mUserManager;
    @Mock
    private BatteryDatabaseManager mBatteryDatabaseManager;
    @Mock
    private BatteryUtils mBatteryUtils;
    @Mock
    private PowerWhitelistBackend mPowerWhitelistBackend;
    @Mock
    private StatsDimensionsValue mStatsDimensionsValue;

    private BatteryTipPolicy mPolicy;
    private Bundle mBundle;
    private AnomalyDetectionJobService mAnomalyDetectionJobService;
    private Context mContext;

    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);

        mContext = RuntimeEnvironment.application;
        mPolicy = new BatteryTipPolicy(mContext);
        mBundle = new Bundle();
        mBundle.putParcelable(StatsManager.EXTRA_STATS_DIMENSIONS_VALUE, mStatsDimensionsValue);

        mAnomalyDetectionJobService = new AnomalyDetectionJobService();
    }

    @Test
    public void testScheduleCleanUp() {
@@ -50,4 +100,30 @@ public class AnomalyDetectionJobServiceTest {
        assertThat(pendingJob.getMaxExecutionDelayMillis())
            .isEqualTo(TimeUnit.MINUTES.toMillis(30));
    }

    @Test
    public void testSaveAnomalyToDatabase_systemWhitelisted_doNotSave() {
        doReturn(SYSTEM_PACKAGE).when(mBatteryUtils).getPackageName(anyInt());
        doReturn(true).when(mPowerWhitelistBackend).isSysWhitelisted(SYSTEM_PACKAGE);

        mAnomalyDetectionJobService.saveAnomalyToDatabase(mBatteryStatsHelper, mUserManager,
                mBatteryDatabaseManager, mBatteryUtils, mPolicy, mPowerWhitelistBackend,
                mContext.getContentResolver(), mBundle);

        verify(mBatteryDatabaseManager, never()).insertAnomaly(anyInt(), anyString(), anyInt(),
                anyInt(), anyLong());
    }

    @Test
    public void testSaveAnomalyToDatabase_normalApp_save() {
        doReturn(SYSTEM_PACKAGE).when(mBatteryUtils).getPackageName(anyInt());
        doReturn(false).when(mPowerWhitelistBackend).isSysWhitelisted(SYSTEM_PACKAGE);

        mAnomalyDetectionJobService.saveAnomalyToDatabase(mBatteryStatsHelper, mUserManager,
                mBatteryDatabaseManager, mBatteryUtils, mPolicy, mPowerWhitelistBackend,
                mContext.getContentResolver(), mBundle);

        verify(mBatteryDatabaseManager).insertAnomaly(anyInt(), anyString(), anyInt(), anyInt(),
                anyLong());
    }
}