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

Commit 13eb2f18 authored by Lei Yu's avatar Lei Yu Committed by Android (Google) Code Review
Browse files

Merge "Add whitelist for anomaly detection." into pi-dev

parents f3cfced1 10051afb
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());
    }
}