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

Commit 8a85fc81 authored by Kweku Adams's avatar Kweku Adams
Browse files

Add shadow mode.

Add a mode in which the TARE system can go through the motions and
pretend it's doing work without actually affecting client component
behavior.

Bug: 158300259
Test: atest frameworks/base/services/tests/mockingservicestests/src/com/android/server/tare
Test: atest frameworks/base/services/tests/servicestests/src/com/android/server/tare
Test: atest FrameworksMockingServicesTests:AlarmManagerServiceTest
Change-Id: I9eda78ca2437bab23701e7d2d666e5e58b9964cd
parent 6cc3ef13
Loading
Loading
Loading
Loading
+34 −2
Original line number Diff line number Diff line
@@ -16,11 +16,15 @@

package android.app.tare;

import android.annotation.IntDef;
import android.annotation.Nullable;
import android.annotation.SystemService;
import android.content.Context;
import android.util.Log;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

/**
 * Provides access to the resource economy service.
 *
@@ -91,10 +95,38 @@ public class EconomyManager {
        }
    }

    public static final String KEY_ENABLE_TARE = "enable_tare";

    public static final int ENABLED_MODE_OFF = 0;
    public static final int ENABLED_MODE_ON = 1;
    /**
     * Go through the motions, tracking events, updating balances and other TARE state values,
     * but don't use TARE to affect actual device behavior.
     */
    public static final int ENABLED_MODE_SHADOW = 2;

    /** @hide */
    @IntDef(prefix = {"ENABLED_MODE_"}, value = {
            ENABLED_MODE_OFF,
            ENABLED_MODE_ON,
            ENABLED_MODE_SHADOW,
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface EnabledMode {
    }

    public static String enabledModeToString(@EnabledMode int mode) {
        switch (mode) {
            case ENABLED_MODE_OFF: return "ENABLED_MODE_OFF";
            case ENABLED_MODE_ON: return "ENABLED_MODE_ON";
            case ENABLED_MODE_SHADOW: return "ENABLED_MODE_SHADOW";
            default: return "ENABLED_MODE_" + mode;
        }
    }

    public static final String KEY_ENABLE_TARE_MODE = "enable_tare_mode";
    public static final String KEY_ENABLE_POLICY_ALARM = "enable_policy_alarm";
    public static final String KEY_ENABLE_POLICY_JOB_SCHEDULER = "enable_policy_job";
    public static final boolean DEFAULT_ENABLE_TARE = true;
    public static final int DEFAULT_ENABLE_TARE_MODE = ENABLED_MODE_ON;
    public static final boolean DEFAULT_ENABLE_POLICY_ALARM = true;
    public static final boolean DEFAULT_ENABLE_POLICY_JOB_SCHEDULER = true;

+22 −17
Original line number Diff line number Diff line
@@ -77,6 +77,7 @@ import android.app.IAlarmManager;
import android.app.PendingIntent;
import android.app.compat.CompatChanges;
import android.app.role.RoleManager;
import android.app.tare.EconomyManager;
import android.app.usage.UsageStatsManager;
import android.app.usage.UsageStatsManagerInternal;
import android.content.BroadcastReceiver;
@@ -852,7 +853,7 @@ public class AlarmManagerService extends SystemService {
        public boolean KILL_ON_SCHEDULE_EXACT_ALARM_REVOKED =
                DEFAULT_KILL_ON_SCHEDULE_EXACT_ALARM_REVOKED;

        public boolean USE_TARE_POLICY = Settings.Global.DEFAULT_ENABLE_TARE == 1;
        public int USE_TARE_POLICY = Settings.Global.DEFAULT_ENABLE_TARE;

        /**
         * The amount of temporary reserve quota to give apps on receiving the
@@ -892,7 +893,7 @@ public class AlarmManagerService extends SystemService {
                    AlarmManagerEconomicPolicy.POLICY_ALARM);
            onPropertiesChanged(DeviceConfig.getProperties(DeviceConfig.NAMESPACE_ALARM_MANAGER));
            updateTareSettings(
                    economyManagerInternal.isEnabled(AlarmManagerEconomicPolicy.POLICY_ALARM));
                    economyManagerInternal.getEnabledMode(AlarmManagerEconomicPolicy.POLICY_ALARM));
        }

        public void updateAllowWhileIdleWhitelistDurationLocked() {
@@ -1065,18 +1066,19 @@ public class AlarmManagerService extends SystemService {
        }

        @Override
        public void onTareEnabledStateChanged(boolean isTareEnabled) {
            updateTareSettings(isTareEnabled);
        public void onTareEnabledModeChanged(@EconomyManager.EnabledMode int enabledMode) {
            updateTareSettings(enabledMode);
        }

        private void updateTareSettings(boolean isTareEnabled) {
        private void updateTareSettings(int enabledMode) {
            synchronized (mLock) {
                if (USE_TARE_POLICY != isTareEnabled) {
                    USE_TARE_POLICY = isTareEnabled;
                if (USE_TARE_POLICY != enabledMode) {
                    USE_TARE_POLICY = enabledMode;
                    final boolean changed = mAlarmStore.updateAlarmDeliveries(alarm -> {
                        final boolean standbyChanged = adjustDeliveryTimeBasedOnBucketLocked(alarm);
                        final boolean tareChanged = adjustDeliveryTimeBasedOnTareLocked(alarm);
                        if (USE_TARE_POLICY) {
                        if (USE_TARE_POLICY == EconomyManager.ENABLED_MODE_ON) {
                            // Only register listeners if we're going to be acting on the policy.
                            registerTareListener(alarm);
                        } else {
                            mEconomyManagerInternal.unregisterAffordabilityChangeListener(
@@ -1086,7 +1088,7 @@ public class AlarmManagerService extends SystemService {
                        }
                        return standbyChanged || tareChanged;
                    });
                    if (!USE_TARE_POLICY) {
                    if (USE_TARE_POLICY != EconomyManager.ENABLED_MODE_ON) {
                        // Remove the cached values so we don't accidentally use them when TARE is
                        // re-enabled.
                        mAffordabilityCache.clear();
@@ -2526,7 +2528,8 @@ public class AlarmManagerService extends SystemService {
     */
    private boolean adjustDeliveryTimeBasedOnBucketLocked(Alarm alarm) {
        final long nowElapsed = mInjector.getElapsedRealtimeMillis();
        if (mConstants.USE_TARE_POLICY || isExemptFromAppStandby(alarm) || mAppStandbyParole) {
        if (mConstants.USE_TARE_POLICY == EconomyManager.ENABLED_MODE_ON
                || isExemptFromAppStandby(alarm) || mAppStandbyParole) {
            return alarm.setPolicyElapsed(APP_STANDBY_POLICY_INDEX, nowElapsed);
        }

@@ -2586,7 +2589,7 @@ public class AlarmManagerService extends SystemService {
     */
    private boolean adjustDeliveryTimeBasedOnTareLocked(Alarm alarm) {
        final long nowElapsed = mInjector.getElapsedRealtimeMillis();
        if (!mConstants.USE_TARE_POLICY
        if (mConstants.USE_TARE_POLICY != EconomyManager.ENABLED_MODE_ON
                || isExemptFromTare(alarm) || hasEnoughWealthLocked(alarm)) {
            return alarm.setPolicyElapsed(TARE_POLICY_INDEX, nowElapsed);
        }
@@ -2596,7 +2599,8 @@ public class AlarmManagerService extends SystemService {
    }

    private void registerTareListener(Alarm alarm) {
        if (!mConstants.USE_TARE_POLICY) {
        if (mConstants.USE_TARE_POLICY != EconomyManager.ENABLED_MODE_ON) {
            // Only register listeners if we're going to be acting on the policy.
            return;
        }
        mEconomyManagerInternal.registerAffordabilityChangeListener(
@@ -2607,7 +2611,7 @@ public class AlarmManagerService extends SystemService {
    /** Unregister the TARE listener associated with the alarm if it's no longer needed. */
    @GuardedBy("mLock")
    private void maybeUnregisterTareListenerLocked(Alarm alarm) {
        if (!mConstants.USE_TARE_POLICY) {
        if (mConstants.USE_TARE_POLICY != EconomyManager.ENABLED_MODE_ON) {
            return;
        }
        final EconomyManagerInternal.ActionBill bill = TareBill.getAppropriateBill(alarm);
@@ -3126,7 +3130,7 @@ public class AlarmManagerService extends SystemService {
            mConstants.dump(pw);
            pw.println();

            if (mConstants.USE_TARE_POLICY) {
            if (mConstants.USE_TARE_POLICY == EconomyManager.ENABLED_MODE_ON) {
                pw.println("TARE details:");
                pw.increaseIndent();

@@ -4500,7 +4504,8 @@ public class AlarmManagerService extends SystemService {
    }

    private void reportAlarmEventToTare(Alarm alarm) {
        if (!mConstants.USE_TARE_POLICY) {
        // Don't bother reporting events if TARE is completely off.
        if (mConstants.USE_TARE_POLICY == EconomyManager.ENABLED_MODE_OFF) {
            return;
        }
        final boolean allowWhileIdle =
@@ -4805,7 +4810,7 @@ public class AlarmManagerService extends SystemService {
                                if (a.wakeup) {
                                    wakeupUids.add(a.uid);
                                }
                                if (mConstants.USE_TARE_POLICY) {
                                if (mConstants.USE_TARE_POLICY == EconomyManager.ENABLED_MODE_ON) {
                                    if (!isExemptFromTare(a)) {
                                        triggerPackages.add(UserPackage.of(
                                                UserHandle.getUserId(a.creatorUid),
@@ -4823,7 +4828,7 @@ public class AlarmManagerService extends SystemService {
                            }
                            deliverAlarmsLocked(triggerList, nowELAPSED);
                            mTemporaryQuotaReserve.cleanUpExpiredQuotas(nowELAPSED);
                            if (mConstants.USE_TARE_POLICY) {
                            if (mConstants.USE_TARE_POLICY == EconomyManager.ENABLED_MODE_ON) {
                                reorderAlarmsBasedOnTare(triggerPackages);
                            } else {
                                reorderAlarmsBasedOnStandbyBuckets(triggerPackages);
+9 −6
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@ import android.app.job.JobService;
import android.app.job.JobSnapshot;
import android.app.job.JobWorkItem;
import android.app.job.UserVisibleJobSummary;
import android.app.tare.EconomyManager;
import android.app.usage.UsageStatsManager;
import android.app.usage.UsageStatsManagerInternal;
import android.compat.annotation.ChangeId;
@@ -417,7 +418,8 @@ public class JobSchedulerService extends com.android.server.SystemService
            // Load all the constants.
            synchronized (mLock) {
                mConstants.updateTareSettingsLocked(
                        economyManagerInternal.isEnabled(JobSchedulerEconomicPolicy.POLICY_JOB));
                        economyManagerInternal.getEnabledMode(
                                JobSchedulerEconomicPolicy.POLICY_JOB));
            }
            onPropertiesChanged(DeviceConfig.getProperties(DeviceConfig.NAMESPACE_JOB_SCHEDULER));
        }
@@ -514,8 +516,8 @@ public class JobSchedulerService extends com.android.server.SystemService
        }

        @Override
        public void onTareEnabledStateChanged(boolean isTareEnabled) {
            if (mConstants.updateTareSettingsLocked(isTareEnabled)) {
        public void onTareEnabledModeChanged(@EconomyManager.EnabledMode int enabledMode) {
            if (mConstants.updateTareSettingsLocked(enabledMode)) {
                for (int controller = 0; controller < mControllers.size(); controller++) {
                    final StateController sc = mControllers.get(controller);
                    sc.onConstantsUpdatedLocked();
@@ -962,10 +964,11 @@ public class JobSchedulerService extends com.android.server.SystemService
                                    DEFAULT_RUNTIME_USER_INITIATED_DATA_TRANSFER_LIMIT_MS)));
        }

        private boolean updateTareSettingsLocked(boolean isTareEnabled) {
        private boolean updateTareSettingsLocked(@EconomyManager.EnabledMode int enabledMode) {
            boolean changed = false;
            if (USE_TARE_POLICY != isTareEnabled) {
                USE_TARE_POLICY = isTareEnabled;
            final boolean useTare = enabledMode == EconomyManager.ENABLED_MODE_ON;
            if (USE_TARE_POLICY != useTare) {
                USE_TARE_POLICY = useTare;
                changed = true;
            }
            return changed;
+2 −1
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.server.tare;

import static android.app.tare.EconomyManager.ENABLED_MODE_OFF;
import static android.text.format.DateUtils.DAY_IN_MILLIS;

import static com.android.server.tare.EconomicPolicy.REGULATION_BASIC_INCOME;
@@ -1111,7 +1112,7 @@ class Agent {
        final ActionAffordabilityNote note =
                new ActionAffordabilityNote(bill, listener, economicPolicy);
        if (actionAffordabilityNotes.add(note)) {
            if (!mIrs.isEnabled()) {
            if (mIrs.getEnabledMode() == ENABLED_MODE_OFF) {
                // When TARE isn't enabled, we always say something is affordable. We also don't
                // want to silently drop affordability change listeners in case TARE becomes enabled
                // because then clients will be in an ambiguous state.
+8 −5
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.server.tare;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.tare.EconomyManager;

import java.util.ArrayList;
import java.util.Collections;
@@ -121,7 +122,7 @@ public interface EconomyManagerInternal {

    /** Listener for various TARE state changes. */
    interface TareStateChangeListener {
        void onTareEnabledStateChanged(boolean isTareEnabled);
        void onTareEnabledModeChanged(@EconomyManager.EnabledMode int tareEnabledMode);
    }

    /**
@@ -135,11 +136,13 @@ public interface EconomyManagerInternal {
     */
    long getMaxDurationMs(int userId, @NonNull String pkgName, @NonNull ActionBill bill);

    /** Returns true if TARE is enabled. */
    boolean isEnabled();
    /** Returns the current TARE enabled mode. */
    @EconomyManager.EnabledMode
    int getEnabledMode();

    /** Returns true if TARE and the specified policy are enabled. */
    boolean isEnabled(@EconomicPolicy.Policy int policyId);
    /** Returns the current TARE enabled mode for the specified policy. */
    @EconomyManager.EnabledMode
    int getEnabledMode(@EconomicPolicy.Policy int policyId);

    /**
     * Register an {@link AffordabilityChangeListener} to track when an app's ability to afford the
Loading