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

Commit 3d871397 authored by Kweku Adams's avatar Kweku Adams
Browse files

Properly notify batterystats when packages change idleness.

Tell batterystats when an app changes from idle to not-idle, or vice
versa.

Bug: 230875908
Test: atest AppStandbyControllerTests
Change-Id: If8307a057dc06967f6552ec1c65402e1e3981f69
parent 6cc3ef13
Loading
Loading
Loading
Loading
+24 −2
Original line number Original line Diff line number Diff line
@@ -965,17 +965,21 @@ public class AppStandbyController
            Slog.d(TAG, "   Checking idle state for " + packageName
            Slog.d(TAG, "   Checking idle state for " + packageName
                    + " minBucket=" + standbyBucketToString(minBucket));
                    + " minBucket=" + standbyBucketToString(minBucket));
        }
        }
        final boolean previouslyIdle, stillIdle;
        if (minBucket <= STANDBY_BUCKET_ACTIVE) {
        if (minBucket <= STANDBY_BUCKET_ACTIVE) {
            // No extra processing needed for ACTIVE or higher since apps can't drop into lower
            // No extra processing needed for ACTIVE or higher since apps can't drop into lower
            // buckets.
            // buckets.
            synchronized (mAppIdleLock) {
            synchronized (mAppIdleLock) {
                previouslyIdle = mAppIdleHistory.isIdle(packageName, userId, elapsedRealtime);
                mAppIdleHistory.setAppStandbyBucket(packageName, userId, elapsedRealtime,
                mAppIdleHistory.setAppStandbyBucket(packageName, userId, elapsedRealtime,
                        minBucket, REASON_MAIN_DEFAULT);
                        minBucket, REASON_MAIN_DEFAULT);
                stillIdle = mAppIdleHistory.isIdle(packageName, userId, elapsedRealtime);
            }
            }
            maybeInformListeners(packageName, userId, elapsedRealtime,
            maybeInformListeners(packageName, userId, elapsedRealtime,
                    minBucket, REASON_MAIN_DEFAULT, false);
                    minBucket, REASON_MAIN_DEFAULT, false);
        } else {
        } else {
            synchronized (mAppIdleLock) {
            synchronized (mAppIdleLock) {
                previouslyIdle = mAppIdleHistory.isIdle(packageName, userId, elapsedRealtime);
                final AppIdleHistory.AppUsageHistory app =
                final AppIdleHistory.AppUsageHistory app =
                        mAppIdleHistory.getAppUsageHistory(packageName,
                        mAppIdleHistory.getAppUsageHistory(packageName,
                        userId, elapsedRealtime);
                        userId, elapsedRealtime);
@@ -1073,10 +1077,16 @@ public class AppStandbyController
                if (oldBucket != newBucket || predictionLate) {
                if (oldBucket != newBucket || predictionLate) {
                    mAppIdleHistory.setAppStandbyBucket(packageName, userId,
                    mAppIdleHistory.setAppStandbyBucket(packageName, userId,
                            elapsedRealtime, newBucket, reason);
                            elapsedRealtime, newBucket, reason);
                    stillIdle = mAppIdleHistory.isIdle(packageName, userId, elapsedRealtime);
                    maybeInformListeners(packageName, userId, elapsedRealtime,
                    maybeInformListeners(packageName, userId, elapsedRealtime,
                            newBucket, reason, false);
                            newBucket, reason, false);
                } else {
                    stillIdle = previouslyIdle;
                }
            }
            }
        }
        }
        if (previouslyIdle != stillIdle) {
            notifyBatteryStats(packageName, userId, stillIdle);
        }
        }
    }
    }


@@ -1234,8 +1244,9 @@ public class AppStandbyController
                    appHistory.currentBucket, reason, userStartedInteracting);
                    appHistory.currentBucket, reason, userStartedInteracting);
        }
        }


        if (previouslyIdle) {
        final boolean stillIdle = appHistory.currentBucket >= AppIdleHistory.IDLE_BUCKET_CUTOFF;
            notifyBatteryStats(pkg, userId, false);
        if (previouslyIdle != stillIdle) {
            notifyBatteryStats(pkg, userId, stillIdle);
        }
        }
    }
    }


@@ -1808,8 +1819,14 @@ public class AppStandbyController
                reason = REASON_MAIN_FORCED_BY_SYSTEM
                reason = REASON_MAIN_FORCED_BY_SYSTEM
                        | (app.bucketingReason & REASON_SUB_MASK)
                        | (app.bucketingReason & REASON_SUB_MASK)
                        | (reason & REASON_SUB_MASK);
                        | (reason & REASON_SUB_MASK);
                final boolean previouslyIdle =
                        app.currentBucket >= AppIdleHistory.IDLE_BUCKET_CUTOFF;
                mAppIdleHistory.setAppStandbyBucket(packageName, userId, elapsedRealtime,
                mAppIdleHistory.setAppStandbyBucket(packageName, userId, elapsedRealtime,
                        newBucket, reason, resetTimeout);
                        newBucket, reason, resetTimeout);
                final boolean stillIdle = newBucket >= AppIdleHistory.IDLE_BUCKET_CUTOFF;
                if (previouslyIdle != stillIdle) {
                    notifyBatteryStats(packageName, userId, stillIdle);
                }
                return;
                return;
            }
            }


@@ -1910,8 +1927,13 @@ public class AppStandbyController


            // Make sure we don't put the app in a lower bucket than it's supposed to be in.
            // Make sure we don't put the app in a lower bucket than it's supposed to be in.
            newBucket = Math.min(newBucket, getAppMinBucket(packageName, userId));
            newBucket = Math.min(newBucket, getAppMinBucket(packageName, userId));
            final boolean previouslyIdle = app.currentBucket >= AppIdleHistory.IDLE_BUCKET_CUTOFF;
            mAppIdleHistory.setAppStandbyBucket(packageName, userId, elapsedRealtime, newBucket,
            mAppIdleHistory.setAppStandbyBucket(packageName, userId, elapsedRealtime, newBucket,
                    reason, resetTimeout);
                    reason, resetTimeout);
            final boolean stillIdle = newBucket >= AppIdleHistory.IDLE_BUCKET_CUTOFF;
            if (previouslyIdle != stillIdle) {
                notifyBatteryStats(packageName, userId, stillIdle);
            }
        }
        }
        maybeInformListeners(packageName, userId, elapsedRealtime, newBucket, reason, false);
        maybeInformListeners(packageName, userId, elapsedRealtime, newBucket, reason, false);
    }
    }
+51 −0
Original line number Original line Diff line number Diff line
@@ -87,6 +87,7 @@ import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
import android.content.pm.PackageManagerInternal;
import android.content.pm.ResolveInfo;
import android.content.pm.ResolveInfo;
import android.hardware.display.DisplayManager;
import android.hardware.display.DisplayManager;
import android.os.BatteryStats;
import android.os.Handler;
import android.os.Handler;
import android.os.Looper;
import android.os.Looper;
import android.os.RemoteException;
import android.os.RemoteException;
@@ -119,6 +120,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Arrays;
import java.util.Collections;
import java.util.Collections;
import java.util.List;
import java.util.List;
import java.util.Objects;
import java.util.Random;
import java.util.Random;
import java.util.Set;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.CountDownLatch;
@@ -249,6 +251,8 @@ public class AppStandbyControllerTests {
                        .setLong("elapsed_threshold_rare", RARE_THRESHOLD)
                        .setLong("elapsed_threshold_rare", RARE_THRESHOLD)
                        .setLong("elapsed_threshold_restricted", RESTRICTED_THRESHOLD);
                        .setLong("elapsed_threshold_restricted", RESTRICTED_THRESHOLD);
        DeviceConfig.OnPropertiesChangedListener mPropertiesChangedListener;
        DeviceConfig.OnPropertiesChangedListener mPropertiesChangedListener;
        String mExpectedNoteEventPackage = null;
        int mLastNoteEvent = BatteryStats.HistoryItem.EVENT_NONE;


        MyInjector(Context context, Looper looper) {
        MyInjector(Context context, Looper looper) {
            super(context, looper);
            super(context, looper);
@@ -320,6 +324,9 @@ public class AppStandbyControllerTests {


        @Override
        @Override
        void noteEvent(int event, String packageName, int uid) throws RemoteException {
        void noteEvent(int event, String packageName, int uid) throws RemoteException {
            if (Objects.equals(mExpectedNoteEventPackage, packageName)) {
                mLastNoteEvent = event;
            }
        }
        }


        @Override
        @Override
@@ -2103,6 +2110,50 @@ public class AppStandbyControllerTests {
        assertBucket(STANDBY_BUCKET_FREQUENT, PACKAGE_BACKGROUND_LOCATION);
        assertBucket(STANDBY_BUCKET_FREQUENT, PACKAGE_BACKGROUND_LOCATION);
    }
    }


    @Test
    public void testBatteryStatsNoteEvent() throws Exception {
        mInjector.mExpectedNoteEventPackage = PACKAGE_1;
        reportEvent(mController, USER_INTERACTION, 0, PACKAGE_1);

        mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_RARE,
                REASON_MAIN_FORCED_BY_USER);
        assertEquals(BatteryStats.HistoryItem.EVENT_PACKAGE_INACTIVE, mInjector.mLastNoteEvent);

        mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_ACTIVE,
                REASON_MAIN_FORCED_BY_USER);
        assertEquals(BatteryStats.HistoryItem.EVENT_PACKAGE_ACTIVE, mInjector.mLastNoteEvent);

        // Since we're staying on the PACKAGE_ACTIVE side, noteEvent shouldn't be called.
        // Reset the last event to confirm the method isn't called.
        mInjector.mLastNoteEvent = BatteryStats.HistoryItem.EVENT_NONE;
        mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_WORKING_SET,
                REASON_MAIN_FORCED_BY_USER);
        assertEquals(BatteryStats.HistoryItem.EVENT_NONE, mInjector.mLastNoteEvent);

        mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_RARE,
                REASON_MAIN_FORCED_BY_USER);
        assertEquals(BatteryStats.HistoryItem.EVENT_PACKAGE_INACTIVE, mInjector.mLastNoteEvent);

        // Since we're staying on the PACKAGE_ACTIVE side, noteEvent shouldn't be called.
        // Reset the last event to confirm the method isn't called.
        mInjector.mLastNoteEvent = BatteryStats.HistoryItem.EVENT_NONE;
        mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_RESTRICTED,
                REASON_MAIN_FORCED_BY_USER);
        assertEquals(BatteryStats.HistoryItem.EVENT_NONE, mInjector.mLastNoteEvent);

        mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_FREQUENT,
                REASON_MAIN_FORCED_BY_USER);
        assertEquals(BatteryStats.HistoryItem.EVENT_PACKAGE_ACTIVE, mInjector.mLastNoteEvent);

        mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_RESTRICTED,
                REASON_MAIN_FORCED_BY_USER);
        assertEquals(BatteryStats.HistoryItem.EVENT_PACKAGE_INACTIVE, mInjector.mLastNoteEvent);

        mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_EXEMPTED,
                REASON_MAIN_FORCED_BY_USER);
        assertEquals(BatteryStats.HistoryItem.EVENT_PACKAGE_ACTIVE, mInjector.mLastNoteEvent);
    }

    private String getAdminAppsStr(int userId) {
    private String getAdminAppsStr(int userId) {
        return getAdminAppsStr(userId, mController.getActiveAdminAppsForTest(userId));
        return getAdminAppsStr(userId, mController.getActiveAdminAppsForTest(userId));
    }
    }