diff options
12 files changed, 272 insertions, 70 deletions
diff --git a/apex/jobscheduler/framework/java/android/app/tare/EconomyManager.java b/apex/jobscheduler/framework/java/android/app/tare/EconomyManager.java index 6af24be3a372..299ad66a882c 100644 --- a/apex/jobscheduler/framework/java/android/app/tare/EconomyManager.java +++ b/apex/jobscheduler/framework/java/android/app/tare/EconomyManager.java @@ -91,6 +91,13 @@ public class EconomyManager { } } + public static final String KEY_ENABLE_TARE = "enable_tare"; + 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 boolean DEFAULT_ENABLE_POLICY_ALARM = true; + public static final boolean DEFAULT_ENABLE_POLICY_JOB_SCHEDULER = true; + // Keys for AlarmManager TARE factors /** @hide */ public static final String KEY_AM_MIN_SATIATED_BALANCE_EXEMPTED = diff --git a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java index c622259ef7dc..37fb746fa16f 100644 --- a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java +++ b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java @@ -59,8 +59,6 @@ import static com.android.server.alarm.AlarmManagerService.RemovedAlarm.REMOVE_R import android.Manifest; import android.annotation.NonNull; -import android.annotation.Nullable; -import android.annotation.RequiresPermission; import android.annotation.UserIdInt; import android.app.Activity; import android.app.ActivityManagerInternal; @@ -883,9 +881,11 @@ public class AlarmManagerService extends SystemService { mInjector.registerDeviceConfigListener(this); final EconomyManagerInternal economyManagerInternal = LocalServices.getService(EconomyManagerInternal.class); - economyManagerInternal.registerTareStateChangeListener(this); + economyManagerInternal.registerTareStateChangeListener(this, + AlarmManagerEconomicPolicy.POLICY_ALARM); onPropertiesChanged(DeviceConfig.getProperties(DeviceConfig.NAMESPACE_ALARM_MANAGER)); - updateTareSettings(economyManagerInternal.isEnabled()); + updateTareSettings( + economyManagerInternal.isEnabled(AlarmManagerEconomicPolicy.POLICY_ALARM)); } public void updateAllowWhileIdleWhitelistDurationLocked() { diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java index 1775d908e21b..f5c0ed9f03f7 100644 --- a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java +++ b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java @@ -116,6 +116,7 @@ import com.android.server.job.restrictions.JobRestriction; import com.android.server.job.restrictions.ThermalStatusRestriction; import com.android.server.pm.UserManagerInternal; import com.android.server.tare.EconomyManagerInternal; +import com.android.server.tare.JobSchedulerEconomicPolicy; import com.android.server.usage.AppStandbyInternal; import com.android.server.usage.AppStandbyInternal.AppIdleStateChangeListener; import com.android.server.utils.quota.Categorizer; @@ -373,10 +374,12 @@ public class JobSchedulerService extends com.android.server.SystemService JobSchedulerBackgroundThread.getExecutor(), this); final EconomyManagerInternal economyManagerInternal = LocalServices.getService(EconomyManagerInternal.class); - economyManagerInternal.registerTareStateChangeListener(this); + economyManagerInternal + .registerTareStateChangeListener(this, JobSchedulerEconomicPolicy.POLICY_JOB); // Load all the constants. synchronized (mLock) { - mConstants.updateTareSettingsLocked(economyManagerInternal.isEnabled()); + mConstants.updateTareSettingsLocked( + economyManagerInternal.isEnabled(JobSchedulerEconomicPolicy.POLICY_JOB)); } onPropertiesChanged(DeviceConfig.getProperties(DeviceConfig.NAMESPACE_JOB_SCHEDULER)); } diff --git a/apex/jobscheduler/service/java/com/android/server/tare/Agent.java b/apex/jobscheduler/service/java/com/android/server/tare/Agent.java index 12ec9a4624e7..7a13e3f1fad7 100644 --- a/apex/jobscheduler/service/java/com/android/server/tare/Agent.java +++ b/apex/jobscheduler/service/java/com/android/server/tare/Agent.java @@ -1196,7 +1196,11 @@ class Agent { final EconomyManagerInternal.AnticipatedAction aa = anticipatedActions.get(i); final EconomicPolicy.Action action = economicPolicy.getAction(aa.actionId); if (action == null) { - throw new IllegalArgumentException("Invalid action id: " + aa.actionId); + if ((aa.actionId & EconomicPolicy.ALL_POLICIES) == 0) { + throw new IllegalArgumentException("Invalid action id: " + aa.actionId); + } else { + Slog.w(TAG, "Tracking disabled policy's action? " + aa.actionId); + } } } mListener = listener; diff --git a/apex/jobscheduler/service/java/com/android/server/tare/AlarmManagerEconomicPolicy.java b/apex/jobscheduler/service/java/com/android/server/tare/AlarmManagerEconomicPolicy.java index e791e98a6698..b426f16744e3 100644 --- a/apex/jobscheduler/service/java/com/android/server/tare/AlarmManagerEconomicPolicy.java +++ b/apex/jobscheduler/service/java/com/android/server/tare/AlarmManagerEconomicPolicy.java @@ -117,23 +117,23 @@ public class AlarmManagerEconomicPolicy extends EconomicPolicy { private static final String TAG = "TARE- " + AlarmManagerEconomicPolicy.class.getSimpleName(); public static final int ACTION_ALARM_WAKEUP_EXACT_ALLOW_WHILE_IDLE = - TYPE_ACTION | POLICY_AM | 0; + TYPE_ACTION | POLICY_ALARM | 0; public static final int ACTION_ALARM_WAKEUP_EXACT = - TYPE_ACTION | POLICY_AM | 1; + TYPE_ACTION | POLICY_ALARM | 1; public static final int ACTION_ALARM_WAKEUP_INEXACT_ALLOW_WHILE_IDLE = - TYPE_ACTION | POLICY_AM | 2; + TYPE_ACTION | POLICY_ALARM | 2; public static final int ACTION_ALARM_WAKEUP_INEXACT = - TYPE_ACTION | POLICY_AM | 3; + TYPE_ACTION | POLICY_ALARM | 3; public static final int ACTION_ALARM_NONWAKEUP_EXACT_ALLOW_WHILE_IDLE = - TYPE_ACTION | POLICY_AM | 4; + TYPE_ACTION | POLICY_ALARM | 4; public static final int ACTION_ALARM_NONWAKEUP_EXACT = - TYPE_ACTION | POLICY_AM | 5; + TYPE_ACTION | POLICY_ALARM | 5; public static final int ACTION_ALARM_NONWAKEUP_INEXACT_ALLOW_WHILE_IDLE = - TYPE_ACTION | POLICY_AM | 6; + TYPE_ACTION | POLICY_ALARM | 6; public static final int ACTION_ALARM_NONWAKEUP_INEXACT = - TYPE_ACTION | POLICY_AM | 7; + TYPE_ACTION | POLICY_ALARM | 7; public static final int ACTION_ALARM_CLOCK = - TYPE_ACTION | POLICY_AM | 8; + TYPE_ACTION | POLICY_ALARM | 8; private static final int[] COST_MODIFIERS = new int[]{ COST_MODIFIER_CHARGING, diff --git a/apex/jobscheduler/service/java/com/android/server/tare/CompleteEconomicPolicy.java b/apex/jobscheduler/service/java/com/android/server/tare/CompleteEconomicPolicy.java index 625f99d64ef4..66f7c357d223 100644 --- a/apex/jobscheduler/service/java/com/android/server/tare/CompleteEconomicPolicy.java +++ b/apex/jobscheduler/service/java/com/android/server/tare/CompleteEconomicPolicy.java @@ -18,24 +18,30 @@ package com.android.server.tare; import android.annotation.NonNull; import android.annotation.Nullable; +import android.app.tare.EconomyManager; import android.provider.DeviceConfig; import android.util.ArraySet; import android.util.IndentingPrintWriter; +import android.util.Slog; import android.util.SparseArray; import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.util.ArrayUtils; import libcore.util.EmptyArray; /** Combines all enabled policies into one. */ public class CompleteEconomicPolicy extends EconomicPolicy { + private static final String TAG = "TARE-" + CompleteEconomicPolicy.class.getSimpleName(); + private final CompleteInjector mInjector; private final ArraySet<EconomicPolicy> mEnabledEconomicPolicies = new ArraySet<>(); /** Lazily populated set of actions covered by this policy. */ private final SparseArray<Action> mActions = new SparseArray<>(); /** Lazily populated set of rewards covered by this policy. */ private final SparseArray<Reward> mRewards = new SparseArray<>(); - private final int[] mCostModifiers; + private int mEnabledEconomicPolicyIds = 0; + private int[] mCostModifiers = EmptyArray.INT; private long mInitialConsumptionLimit; private long mHardConsumptionLimit; @@ -47,11 +53,34 @@ public class CompleteEconomicPolicy extends EconomicPolicy { CompleteEconomicPolicy(@NonNull InternalResourceService irs, @NonNull CompleteInjector injector) { super(irs); - if (injector.isPolicyEnabled(POLICY_AM)) { - mEnabledEconomicPolicies.add(new AlarmManagerEconomicPolicy(irs, injector)); + mInjector = injector; + + if (mInjector.isPolicyEnabled(POLICY_ALARM, null)) { + mEnabledEconomicPolicyIds |= POLICY_ALARM; + mEnabledEconomicPolicies.add(new AlarmManagerEconomicPolicy(mIrs, mInjector)); } - if (injector.isPolicyEnabled(POLICY_JS)) { - mEnabledEconomicPolicies.add(new JobSchedulerEconomicPolicy(irs, injector)); + if (mInjector.isPolicyEnabled(POLICY_JOB, null)) { + mEnabledEconomicPolicyIds |= POLICY_JOB; + mEnabledEconomicPolicies.add(new JobSchedulerEconomicPolicy(mIrs, mInjector)); + } + } + + @Override + void setup(@NonNull DeviceConfig.Properties properties) { + super.setup(properties); + + mActions.clear(); + mRewards.clear(); + + mEnabledEconomicPolicies.clear(); + mEnabledEconomicPolicyIds = 0; + if (mInjector.isPolicyEnabled(POLICY_ALARM, properties)) { + mEnabledEconomicPolicyIds |= POLICY_ALARM; + mEnabledEconomicPolicies.add(new AlarmManagerEconomicPolicy(mIrs, mInjector)); + } + if (mInjector.isPolicyEnabled(POLICY_JOB, properties)) { + mEnabledEconomicPolicyIds |= POLICY_JOB; + mEnabledEconomicPolicies.add(new JobSchedulerEconomicPolicy(mIrs, mInjector)); } ArraySet<Integer> costModifiers = new ArraySet<>(); @@ -61,17 +90,8 @@ public class CompleteEconomicPolicy extends EconomicPolicy { costModifiers.add(s); } } - mCostModifiers = new int[costModifiers.size()]; - for (int i = 0; i < costModifiers.size(); ++i) { - mCostModifiers[i] = costModifiers.valueAt(i); - } + mCostModifiers = ArrayUtils.convertToIntArray(costModifiers); - updateLimits(); - } - - @Override - void setup(@NonNull DeviceConfig.Properties properties) { - super.setup(properties); for (int i = 0; i < mEnabledEconomicPolicies.size(); ++i) { mEnabledEconomicPolicies.valueAt(i).setup(properties); } @@ -170,11 +190,37 @@ public class CompleteEconomicPolicy extends EconomicPolicy { return reward; } + boolean isPolicyEnabled(@Policy int policyId) { + return (mEnabledEconomicPolicyIds & policyId) == policyId; + } + + int getEnabledPolicyIds() { + return mEnabledEconomicPolicyIds; + } + @VisibleForTesting static class CompleteInjector extends Injector { - boolean isPolicyEnabled(int policy) { - return true; + boolean isPolicyEnabled(int policy, @Nullable DeviceConfig.Properties properties) { + final String key; + final boolean defaultEnable; + switch (policy) { + case POLICY_ALARM: + key = EconomyManager.KEY_ENABLE_POLICY_ALARM; + defaultEnable = EconomyManager.DEFAULT_ENABLE_POLICY_ALARM; + break; + case POLICY_JOB: + key = EconomyManager.KEY_ENABLE_POLICY_JOB_SCHEDULER; + defaultEnable = EconomyManager.DEFAULT_ENABLE_POLICY_JOB_SCHEDULER; + break; + default: + Slog.wtf(TAG, "Unknown policy: " + policy); + return false; + } + if (properties == null) { + return defaultEnable; + } + return properties.getBoolean(key, defaultEnable); } } @@ -189,7 +235,10 @@ public class CompleteEconomicPolicy extends EconomicPolicy { pw.println("Cached actions:"); pw.increaseIndent(); for (int i = 0; i < mActions.size(); ++i) { - dumpAction(pw, mActions.valueAt(i)); + final Action action = mActions.valueAt(i); + if (action != null) { + dumpAction(pw, action); + } } pw.decreaseIndent(); @@ -197,7 +246,10 @@ public class CompleteEconomicPolicy extends EconomicPolicy { pw.println("Cached rewards:"); pw.increaseIndent(); for (int i = 0; i < mRewards.size(); ++i) { - dumpReward(pw, mRewards.valueAt(i)); + final Reward reward = mRewards.valueAt(i); + if (reward != null) { + dumpReward(pw, reward); + } } pw.decreaseIndent(); diff --git a/apex/jobscheduler/service/java/com/android/server/tare/EconomicPolicy.java b/apex/jobscheduler/service/java/com/android/server/tare/EconomicPolicy.java index 7391bcfa8d88..008dcb8edf63 100644 --- a/apex/jobscheduler/service/java/com/android/server/tare/EconomicPolicy.java +++ b/apex/jobscheduler/service/java/com/android/server/tare/EconomicPolicy.java @@ -57,9 +57,10 @@ public abstract class EconomicPolicy { private static final int SHIFT_POLICY = 28; static final int MASK_POLICY = 0b11 << SHIFT_POLICY; + static final int ALL_POLICIES = MASK_POLICY; // Reserve 0 for the base/common policy. - static final int POLICY_AM = 1 << SHIFT_POLICY; - static final int POLICY_JS = 2 << SHIFT_POLICY; + public static final int POLICY_ALARM = 1 << SHIFT_POLICY; + public static final int POLICY_JOB = 2 << SHIFT_POLICY; static final int MASK_EVENT = -1 ^ (MASK_TYPE | MASK_POLICY); @@ -115,6 +116,15 @@ public abstract class EconomicPolicy { } @IntDef({ + ALL_POLICIES, + POLICY_ALARM, + POLICY_JOB, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface Policy { + } + + @IntDef({ REWARD_TOP_ACTIVITY, REWARD_NOTIFICATION_SEEN, REWARD_NOTIFICATION_INTERACTION, @@ -342,7 +352,7 @@ public abstract class EconomicPolicy { @NonNull static String actionToString(int eventId) { switch (eventId & MASK_POLICY) { - case POLICY_AM: + case POLICY_ALARM: switch (eventId) { case AlarmManagerEconomicPolicy.ACTION_ALARM_WAKEUP_EXACT_ALLOW_WHILE_IDLE: return "ALARM_WAKEUP_EXACT_ALLOW_WHILE_IDLE"; @@ -365,7 +375,7 @@ public abstract class EconomicPolicy { } break; - case POLICY_JS: + case POLICY_JOB: switch (eventId) { case JobSchedulerEconomicPolicy.ACTION_JOB_MAX_START: return "JOB_MAX_START"; diff --git a/apex/jobscheduler/service/java/com/android/server/tare/EconomyManagerInternal.java b/apex/jobscheduler/service/java/com/android/server/tare/EconomyManagerInternal.java index 0fa0c47e1b49..716769c21afc 100644 --- a/apex/jobscheduler/service/java/com/android/server/tare/EconomyManagerInternal.java +++ b/apex/jobscheduler/service/java/com/android/server/tare/EconomyManagerInternal.java @@ -138,6 +138,9 @@ public interface EconomyManagerInternal { /** Returns true if TARE is enabled. */ boolean isEnabled(); + /** Returns true if TARE and the specified policy are enabled. */ + boolean isEnabled(@EconomicPolicy.Policy int policyId); + /** * Register an {@link AffordabilityChangeListener} to track when an app's ability to afford the * indicated bill changes. @@ -155,7 +158,8 @@ public interface EconomyManagerInternal { /** * Register a {@link TareStateChangeListener} to track when TARE's state changes. */ - void registerTareStateChangeListener(@NonNull TareStateChangeListener listener); + void registerTareStateChangeListener(@NonNull TareStateChangeListener listener, + @EconomicPolicy.Policy int policyId); /** * Unregister a {@link TareStateChangeListener} from being notified when TARE's state changes. diff --git a/apex/jobscheduler/service/java/com/android/server/tare/InternalResourceService.java b/apex/jobscheduler/service/java/com/android/server/tare/InternalResourceService.java index ca0b65c2e6c9..dd0a19433683 100644 --- a/apex/jobscheduler/service/java/com/android/server/tare/InternalResourceService.java +++ b/apex/jobscheduler/service/java/com/android/server/tare/InternalResourceService.java @@ -30,6 +30,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.app.AlarmManager; import android.app.AppOpsManager; +import android.app.tare.EconomyManager; import android.app.tare.IEconomyManager; import android.app.usage.UsageEvents; import android.app.usage.UsageStatsManagerInternal; @@ -82,7 +83,6 @@ import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; import java.util.Objects; -import java.util.concurrent.CopyOnWriteArraySet; /** * Responsible for handling app's ARC count based on events, ensuring ARCs are credited when @@ -161,8 +161,9 @@ public class InternalResourceService extends SystemService { @GuardedBy("mPackageToUidCache") private final SparseArrayMap<String, Integer> mPackageToUidCache = new SparseArrayMap<>(); - private final CopyOnWriteArraySet<TareStateChangeListener> mStateChangeListeners = - new CopyOnWriteArraySet<>(); + @GuardedBy("mStateChangeListeners") + private final SparseSetArray<TareStateChangeListener> mStateChangeListeners = + new SparseSetArray<>(); /** * List of packages that are fully restricted and shouldn't be allowed to run in the background. @@ -306,6 +307,7 @@ public class InternalResourceService extends SystemService { private static final int MSG_SCHEDULE_UNUSED_WEALTH_RECLAMATION_EVENT = 1; private static final int MSG_PROCESS_USAGE_EVENT = 2; private static final int MSG_NOTIFY_STATE_CHANGE_LISTENERS = 3; + private static final int MSG_NOTIFY_STATE_CHANGE_LISTENER = 4; private static final String ALARM_TAG_WEALTH_RECLAMATION = "*tare.reclamation*"; /** @@ -442,6 +444,12 @@ public class InternalResourceService extends SystemService { return mIsEnabled; } + boolean isEnabled(int policyId) { + synchronized (mLock) { + return isEnabled() && mCompleteEconomicPolicy.isPolicyEnabled(policyId); + } + } + boolean isPackageExempted(final int userId, @NonNull String pkgName) { synchronized (mLock) { return mExemptedApps.contains(pkgName); @@ -1084,9 +1092,30 @@ public class InternalResourceService extends SystemService { } break; + case MSG_NOTIFY_STATE_CHANGE_LISTENER: { + final int policy = msg.arg1; + final TareStateChangeListener listener = (TareStateChangeListener) msg.obj; + listener.onTareEnabledStateChanged(isEnabled(policy)); + } + break; + case MSG_NOTIFY_STATE_CHANGE_LISTENERS: { - for (TareStateChangeListener listener : mStateChangeListeners) { - listener.onTareEnabledStateChanged(mIsEnabled); + final int changedPolicies = msg.arg1; + synchronized (mStateChangeListeners) { + final int size = mStateChangeListeners.size(); + for (int l = 0; l < size; ++l) { + final int policy = mStateChangeListeners.keyAt(l); + if ((policy & changedPolicies) == 0) { + continue; + } + final ArraySet<TareStateChangeListener> listeners = + mStateChangeListeners.get(policy); + final boolean isEnabled = isEnabled(policy); + for (int p = listeners.size() - 1; p >= 0; --p) { + final TareStateChangeListener listener = listeners.valueAt(p); + listener.onTareEnabledStateChanged(isEnabled); + } + } } } break; @@ -1191,16 +1220,28 @@ public class InternalResourceService extends SystemService { } @Override - public void registerTareStateChangeListener(@NonNull TareStateChangeListener listener) { + public void registerTareStateChangeListener(@NonNull TareStateChangeListener listener, + int policyId) { if (!isTareSupported()) { return; } - mStateChangeListeners.add(listener); + synchronized (mStateChangeListeners) { + if (mStateChangeListeners.add(policyId, listener)) { + mHandler.obtainMessage(MSG_NOTIFY_STATE_CHANGE_LISTENER, policyId, 0, listener) + .sendToTarget(); + } + } } @Override public void unregisterTareStateChangeListener(@NonNull TareStateChangeListener listener) { - mStateChangeListeners.remove(listener); + synchronized (mStateChangeListeners) { + for (int i = mStateChangeListeners.size() - 1; i >= 0; --i) { + final ArraySet<TareStateChangeListener> listeners = + mStateChangeListeners.get(mStateChangeListeners.keyAt(i)); + listeners.remove(listener); + } + } } @Override @@ -1265,6 +1306,11 @@ public class InternalResourceService extends SystemService { } @Override + public boolean isEnabled(int policyId) { + return InternalResourceService.this.isEnabled(policyId); + } + + @Override public void noteInstantaneousEvent(int userId, @NonNull String pkgName, int eventId, @Nullable String tag) { if (!mIsEnabled) { @@ -1303,7 +1349,6 @@ public class InternalResourceService extends SystemService { private class ConfigObserver extends ContentObserver implements DeviceConfig.OnPropertiesChangedListener { - private static final String KEY_DC_ENABLE_TARE = "enable_tare"; private static final String KEY_ENABLE_TIP3 = "enable_tip3"; private static final boolean DEFAULT_ENABLE_TIP3 = true; @@ -1357,7 +1402,7 @@ public class InternalResourceService extends SystemService { continue; } switch (name) { - case KEY_DC_ENABLE_TARE: + case EconomyManager.KEY_ENABLE_TARE: updateEnabledStatus(); break; case KEY_ENABLE_TIP3: @@ -1365,7 +1410,8 @@ public class InternalResourceService extends SystemService { break; default: if (!economicPolicyUpdated - && (name.startsWith("am") || name.startsWith("js"))) { + && (name.startsWith("am") || name.startsWith("js") + || name.startsWith("enable_policy"))) { updateEconomicPolicy(); economicPolicyUpdated = true; } @@ -1377,7 +1423,7 @@ public class InternalResourceService extends SystemService { private void updateEnabledStatus() { // User setting should override DeviceConfig setting. final boolean isTareEnabledDC = DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_TARE, - KEY_DC_ENABLE_TARE, Settings.Global.DEFAULT_ENABLE_TARE == 1); + EconomyManager.KEY_ENABLE_TARE, EconomyManager.DEFAULT_ENABLE_TARE); final boolean isTareEnabled = isTareSupported() && Settings.Global.getInt(mContentResolver, Settings.Global.ENABLE_TARE, isTareEnabledDC ? 1 : 0) == 1; @@ -1388,7 +1434,9 @@ public class InternalResourceService extends SystemService { } else { tearDownEverything(); } - mHandler.sendEmptyMessage(MSG_NOTIFY_STATE_CHANGE_LISTENERS); + mHandler.obtainMessage( + MSG_NOTIFY_STATE_CHANGE_LISTENERS, EconomicPolicy.ALL_POLICIES, 0) + .sendToTarget(); } } @@ -1397,9 +1445,10 @@ public class InternalResourceService extends SystemService { final long initialLimit = mCompleteEconomicPolicy.getInitialSatiatedConsumptionLimit(); final long hardLimit = mCompleteEconomicPolicy.getHardSatiatedConsumptionLimit(); + final int oldEnabledPolicies = mCompleteEconomicPolicy.getEnabledPolicyIds(); mCompleteEconomicPolicy.tearDown(); mCompleteEconomicPolicy = new CompleteEconomicPolicy(InternalResourceService.this); - if (mIsEnabled && mBootPhase >= PHASE_SYSTEM_SERVICES_READY) { + if (mIsEnabled && mBootPhase >= PHASE_THIRD_PARTY_APPS_CAN_START) { mCompleteEconomicPolicy.setup(getAllDeviceConfigProperties()); if (initialLimit != mCompleteEconomicPolicy.getInitialSatiatedConsumptionLimit() || hardLimit @@ -1409,6 +1458,13 @@ public class InternalResourceService extends SystemService { mCompleteEconomicPolicy.getInitialSatiatedConsumptionLimit()); } mAgent.onPricingChangedLocked(); + final int newEnabledPolicies = mCompleteEconomicPolicy.getEnabledPolicyIds(); + if (oldEnabledPolicies != newEnabledPolicies) { + final int changedPolicies = oldEnabledPolicies ^ newEnabledPolicies; + mHandler.obtainMessage( + MSG_NOTIFY_STATE_CHANGE_LISTENERS, changedPolicies, 0) + .sendToTarget(); + } } } } diff --git a/apex/jobscheduler/service/java/com/android/server/tare/JobSchedulerEconomicPolicy.java b/apex/jobscheduler/service/java/com/android/server/tare/JobSchedulerEconomicPolicy.java index 322e824286d5..71c6d099ac77 100644 --- a/apex/jobscheduler/service/java/com/android/server/tare/JobSchedulerEconomicPolicy.java +++ b/apex/jobscheduler/service/java/com/android/server/tare/JobSchedulerEconomicPolicy.java @@ -133,19 +133,19 @@ import android.util.SparseArray; public class JobSchedulerEconomicPolicy extends EconomicPolicy { private static final String TAG = "TARE- " + JobSchedulerEconomicPolicy.class.getSimpleName(); - public static final int ACTION_JOB_MAX_START = TYPE_ACTION | POLICY_JS | 0; - public static final int ACTION_JOB_MAX_RUNNING = TYPE_ACTION | POLICY_JS | 1; - public static final int ACTION_JOB_HIGH_START = TYPE_ACTION | POLICY_JS | 2; - public static final int ACTION_JOB_HIGH_RUNNING = TYPE_ACTION | POLICY_JS | 3; - public static final int ACTION_JOB_DEFAULT_START = TYPE_ACTION | POLICY_JS | 4; - public static final int ACTION_JOB_DEFAULT_RUNNING = TYPE_ACTION | POLICY_JS | 5; - public static final int ACTION_JOB_LOW_START = TYPE_ACTION | POLICY_JS | 6; - public static final int ACTION_JOB_LOW_RUNNING = TYPE_ACTION | POLICY_JS | 7; - public static final int ACTION_JOB_MIN_START = TYPE_ACTION | POLICY_JS | 8; - public static final int ACTION_JOB_MIN_RUNNING = TYPE_ACTION | POLICY_JS | 9; - public static final int ACTION_JOB_TIMEOUT = TYPE_ACTION | POLICY_JS | 10; - - public static final int REWARD_APP_INSTALL = TYPE_REWARD | POLICY_JS | 0; + public static final int ACTION_JOB_MAX_START = TYPE_ACTION | POLICY_JOB | 0; + public static final int ACTION_JOB_MAX_RUNNING = TYPE_ACTION | POLICY_JOB | 1; + public static final int ACTION_JOB_HIGH_START = TYPE_ACTION | POLICY_JOB | 2; + public static final int ACTION_JOB_HIGH_RUNNING = TYPE_ACTION | POLICY_JOB | 3; + public static final int ACTION_JOB_DEFAULT_START = TYPE_ACTION | POLICY_JOB | 4; + public static final int ACTION_JOB_DEFAULT_RUNNING = TYPE_ACTION | POLICY_JOB | 5; + public static final int ACTION_JOB_LOW_START = TYPE_ACTION | POLICY_JOB | 6; + public static final int ACTION_JOB_LOW_RUNNING = TYPE_ACTION | POLICY_JOB | 7; + public static final int ACTION_JOB_MIN_START = TYPE_ACTION | POLICY_JOB | 8; + public static final int ACTION_JOB_MIN_RUNNING = TYPE_ACTION | POLICY_JOB | 9; + public static final int ACTION_JOB_TIMEOUT = TYPE_ACTION | POLICY_JOB | 10; + + public static final int REWARD_APP_INSTALL = TYPE_REWARD | POLICY_JOB | 0; private static final int[] COST_MODIFIERS = new int[]{ COST_MODIFIER_CHARGING, diff --git a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java index 446317e8829f..1b9282d426d0 100644 --- a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java @@ -172,6 +172,7 @@ import com.android.server.SystemService; import com.android.server.pm.permission.PermissionManagerService; import com.android.server.pm.permission.PermissionManagerServiceInternal; import com.android.server.pm.pkg.AndroidPackage; +import com.android.server.tare.AlarmManagerEconomicPolicy; import com.android.server.tare.EconomyManagerInternal; import com.android.server.usage.AppStandbyInternal; @@ -650,7 +651,8 @@ public class AlarmManagerServiceTest { } private void setTareEnabled(boolean enabled) { - when(mEconomyManagerInternal.isEnabled()).thenReturn(enabled); + when(mEconomyManagerInternal.isEnabled(eq(AlarmManagerEconomicPolicy.POLICY_ALARM))) + .thenReturn(enabled); mService.mConstants.onTareEnabledStateChanged(enabled); } diff --git a/services/tests/mockingservicestests/src/com/android/server/tare/CompleteEconomicPolicyTest.java b/services/tests/mockingservicestests/src/com/android/server/tare/CompleteEconomicPolicyTest.java index 47155a1eadd3..6da4ab714d7a 100644 --- a/services/tests/mockingservicestests/src/com/android/server/tare/CompleteEconomicPolicyTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/tare/CompleteEconomicPolicyTest.java @@ -25,6 +25,10 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.when; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; @@ -78,10 +82,13 @@ public class CompleteEconomicPolicyTest { } @Override - boolean isPolicyEnabled(int policy) { + boolean isPolicyEnabled(int policy, @Nullable DeviceConfig.Properties properties) { // Use a limited set of policies so that the test doesn't need to be updated whenever // a policy is added or removed. - return policy == EconomicPolicy.POLICY_AM || policy == EconomicPolicy.POLICY_JS; + if (policy == EconomicPolicy.POLICY_ALARM || policy == EconomicPolicy.POLICY_JOB) { + return super.isPolicyEnabled(policy, properties); + } + return false; } } @@ -116,10 +123,14 @@ public class CompleteEconomicPolicyTest { -> mDeviceConfigPropertiesBuilder.build()) .when(() -> DeviceConfig.getProperties( eq(DeviceConfig.NAMESPACE_TARE), ArgumentMatchers.<String>any())); + mDeviceConfigPropertiesBuilder + .setBoolean(EconomyManager.KEY_ENABLE_POLICY_ALARM, true) + .setBoolean(EconomyManager.KEY_ENABLE_POLICY_JOB_SCHEDULER, true); // Initialize real objects. // Capture the listeners. mEconomicPolicy = new CompleteEconomicPolicy(mIrs, mInjector); + mEconomicPolicy.setup(mDeviceConfigPropertiesBuilder.build()); } @After @@ -129,6 +140,11 @@ public class CompleteEconomicPolicyTest { } } + private void setDeviceConfigBoolean(String key, boolean val) { + mDeviceConfigPropertiesBuilder.setBoolean(key, val); + mEconomicPolicy.setup(mDeviceConfigPropertiesBuilder.build()); + } + private void setDeviceConfigCakes(String key, long valCakes) { mDeviceConfigPropertiesBuilder.setString(key, valCakes + "c"); mEconomicPolicy.setup(mDeviceConfigPropertiesBuilder.build()); @@ -182,4 +198,52 @@ public class CompleteEconomicPolicyTest { assertEquals(arcToCake(13), mEconomicPolicy.getMinSatiatedBalance(0, pkgExempted)); assertEquals(arcToCake(5), mEconomicPolicy.getMinSatiatedBalance(0, "com.any.other.app")); } + + + @Test + public void testPolicyToggling() { + setDeviceConfigBoolean(EconomyManager.KEY_ENABLE_POLICY_ALARM, true); + setDeviceConfigBoolean(EconomyManager.KEY_ENABLE_POLICY_JOB_SCHEDULER, false); + assertEquals(EconomyManager.DEFAULT_AM_INITIAL_CONSUMPTION_LIMIT_CAKES, + mEconomicPolicy.getInitialSatiatedConsumptionLimit()); + assertEquals(EconomyManager.DEFAULT_AM_HARD_CONSUMPTION_LIMIT_CAKES, + mEconomicPolicy.getHardSatiatedConsumptionLimit()); + final String pkgRestricted = "com.pkg.restricted"; + when(mIrs.isPackageRestricted(anyInt(), eq(pkgRestricted))).thenReturn(true); + assertEquals(0, mEconomicPolicy.getMaxSatiatedBalance(0, pkgRestricted)); + assertEquals(EconomyManager.DEFAULT_AM_MAX_SATIATED_BALANCE_CAKES, + mEconomicPolicy.getMaxSatiatedBalance(0, "com.any.other.app")); + final String pkgExempted = "com.pkg.exempted"; + when(mIrs.isPackageExempted(anyInt(), eq(pkgExempted))).thenReturn(true); + assertEquals(EconomyManager.DEFAULT_AM_MIN_SATIATED_BALANCE_EXEMPTED_CAKES, + mEconomicPolicy.getMinSatiatedBalance(0, pkgExempted)); + assertEquals(EconomyManager.DEFAULT_AM_MIN_SATIATED_BALANCE_OTHER_APP_CAKES, + mEconomicPolicy.getMinSatiatedBalance(0, "com.any.other.app")); + assertNotNull(mEconomicPolicy.getAction(AlarmManagerEconomicPolicy.ACTION_ALARM_CLOCK)); + assertNull(mEconomicPolicy.getAction(JobSchedulerEconomicPolicy.ACTION_JOB_LOW_START)); + assertEquals(EconomicPolicy.POLICY_ALARM, mEconomicPolicy.getEnabledPolicyIds()); + assertTrue(mEconomicPolicy.isPolicyEnabled(EconomicPolicy.POLICY_ALARM)); + assertFalse(mEconomicPolicy.isPolicyEnabled(EconomicPolicy.POLICY_JOB)); + + setDeviceConfigBoolean(EconomyManager.KEY_ENABLE_POLICY_ALARM, false); + setDeviceConfigBoolean(EconomyManager.KEY_ENABLE_POLICY_JOB_SCHEDULER, true); + assertEquals(EconomyManager.DEFAULT_JS_INITIAL_CONSUMPTION_LIMIT_CAKES, + mEconomicPolicy.getInitialSatiatedConsumptionLimit()); + assertEquals(EconomyManager.DEFAULT_JS_HARD_CONSUMPTION_LIMIT_CAKES, + mEconomicPolicy.getHardSatiatedConsumptionLimit()); + when(mIrs.isPackageRestricted(anyInt(), eq(pkgRestricted))).thenReturn(true); + assertEquals(0, mEconomicPolicy.getMaxSatiatedBalance(0, pkgRestricted)); + assertEquals(EconomyManager.DEFAULT_JS_MAX_SATIATED_BALANCE_CAKES, + mEconomicPolicy.getMaxSatiatedBalance(0, "com.any.other.app")); + when(mIrs.isPackageExempted(anyInt(), eq(pkgExempted))).thenReturn(true); + assertEquals(EconomyManager.DEFAULT_JS_MIN_SATIATED_BALANCE_EXEMPTED_CAKES, + mEconomicPolicy.getMinSatiatedBalance(0, pkgExempted)); + assertEquals(EconomyManager.DEFAULT_JS_MIN_SATIATED_BALANCE_OTHER_APP_CAKES, + mEconomicPolicy.getMinSatiatedBalance(0, "com.any.other.app")); + assertNull(mEconomicPolicy.getAction(AlarmManagerEconomicPolicy.ACTION_ALARM_CLOCK)); + assertNotNull(mEconomicPolicy.getAction(JobSchedulerEconomicPolicy.ACTION_JOB_LOW_START)); + assertEquals(EconomicPolicy.POLICY_JOB, mEconomicPolicy.getEnabledPolicyIds()); + assertFalse(mEconomicPolicy.isPolicyEnabled(EconomicPolicy.POLICY_ALARM)); + assertTrue(mEconomicPolicy.isPolicyEnabled(EconomicPolicy.POLICY_JOB)); + } } |