Loading apex/jobscheduler/service/java/com/android/server/tare/Agent.java +69 −10 Original line number Diff line number Diff line Loading @@ -44,6 +44,7 @@ import android.util.IndentingPrintWriter; import android.util.Log; import android.util.Slog; import android.util.SparseArrayMap; import android.util.SparseSetArray; import android.util.TimeUtils; import com.android.internal.annotations.GuardedBy; Loading Loading @@ -282,6 +283,7 @@ class Agent { for (int i = 0; i < pkgNames.size(); ++i) { final String pkgName = pkgNames.valueAt(i); final boolean isVip = mIrs.isVip(userId, pkgName); SparseArrayMap<String, OngoingEvent> ongoingEvents = mCurrentOngoingEvents.get(userId, pkgName); if (ongoingEvents != null) { Loading @@ -296,8 +298,8 @@ class Agent { for (int n = 0; n < size; ++n) { final ActionAffordabilityNote note = actionAffordabilityNotes.valueAt(n); note.recalculateCosts(economicPolicy, userId, pkgName); final boolean isAffordable = isAffordableLocked(newBalance, final boolean isAffordable = isVip || isAffordableLocked(newBalance, note.getCachedModifiedPrice(), note.getCtp()); if (note.isCurrentlyAffordable() != isAffordable) { note.setNewAffordability(isAffordable); Loading @@ -310,6 +312,51 @@ class Agent { } } @GuardedBy("mLock") void onVipStatusChangedLocked(final int userId, @NonNull String pkgName) { final long now = getCurrentTimeMillis(); final long nowElapsed = SystemClock.elapsedRealtime(); final CompleteEconomicPolicy economicPolicy = mIrs.getCompleteEconomicPolicyLocked(); final boolean isVip = mIrs.isVip(userId, pkgName); SparseArrayMap<String, OngoingEvent> ongoingEvents = mCurrentOngoingEvents.get(userId, pkgName); if (ongoingEvents != null) { mOngoingEventUpdater.reset(userId, pkgName, now, nowElapsed); ongoingEvents.forEach(mOngoingEventUpdater); } final ArraySet<ActionAffordabilityNote> actionAffordabilityNotes = mActionAffordabilityNotes.get(userId, pkgName); if (actionAffordabilityNotes != null) { final int size = actionAffordabilityNotes.size(); final long newBalance = mScribe.getLedgerLocked(userId, pkgName).getCurrentBalance(); for (int n = 0; n < size; ++n) { final ActionAffordabilityNote note = actionAffordabilityNotes.valueAt(n); note.recalculateCosts(economicPolicy, userId, pkgName); final boolean isAffordable = isVip || isAffordableLocked(newBalance, note.getCachedModifiedPrice(), note.getCtp()); if (note.isCurrentlyAffordable() != isAffordable) { note.setNewAffordability(isAffordable); mIrs.postAffordabilityChanged(userId, pkgName, note); } } } scheduleBalanceCheckLocked(userId, pkgName); } @GuardedBy("mLock") void onVipStatusChangedLocked(@NonNull SparseSetArray<String> pkgs) { for (int u = pkgs.size() - 1; u >= 0; --u) { final int userId = pkgs.keyAt(u); for (int p = pkgs.sizeAt(u) - 1; p >= 0; --p) { onVipStatusChangedLocked(userId, pkgs.valueAt(u, p)); } } } @GuardedBy("mLock") private void onAnythingChangedLocked(final boolean updateOngoingEvents) { final long now = getCurrentTimeMillis(); Loading Loading @@ -347,11 +394,12 @@ class Agent { if (actionAffordabilityNotes != null) { final int size = actionAffordabilityNotes.size(); final long newBalance = getBalanceLocked(userId, pkgName); final boolean isVip = mIrs.isVip(userId, pkgName); for (int n = 0; n < size; ++n) { final ActionAffordabilityNote note = actionAffordabilityNotes.valueAt(n); note.recalculateCosts(economicPolicy, userId, pkgName); final boolean isAffordable = isAffordableLocked(newBalance, final boolean isAffordable = isVip || isAffordableLocked(newBalance, note.getCachedModifiedPrice(), note.getCtp()); if (note.isCurrentlyAffordable() != isAffordable) { note.setNewAffordability(isAffordable); Loading Loading @@ -452,6 +500,14 @@ class Agent { "Tried to adjust system balance for " + appToString(userId, pkgName)); return; } if (mIrs.isVip(userId, pkgName)) { // This could happen if the app was made a VIP after it started performing actions. // Continue recording the transaction for debugging purposes, but don't let it change // any numbers. transaction = new Ledger.Transaction( transaction.startTimeMs, transaction.endTimeMs, transaction.eventId, transaction.tag, 0 /* delta */, transaction.ctp); } final CompleteEconomicPolicy economicPolicy = mIrs.getCompleteEconomicPolicyLocked(); final long originalBalance = ledger.getCurrentBalance(); if (transaction.delta > 0 Loading @@ -477,10 +533,11 @@ class Agent { mActionAffordabilityNotes.get(userId, pkgName); if (actionAffordabilityNotes != null) { final long newBalance = ledger.getCurrentBalance(); final boolean isVip = mIrs.isVip(userId, pkgName); for (int i = 0; i < actionAffordabilityNotes.size(); ++i) { final ActionAffordabilityNote note = actionAffordabilityNotes.valueAt(i); final boolean isAffordable = isAffordableLocked(newBalance, final boolean isAffordable = isVip || isAffordableLocked(newBalance, note.getCachedModifiedPrice(), note.getCtp()); if (note.isCurrentlyAffordable() != isAffordable) { note.setNewAffordability(isAffordable); Loading Loading @@ -866,7 +923,7 @@ class Agent { private void scheduleBalanceCheckLocked(final int userId, @NonNull final String pkgName) { SparseArrayMap<String, OngoingEvent> ongoingEvents = mCurrentOngoingEvents.get(userId, pkgName); if (ongoingEvents == null) { if (ongoingEvents == null || mIrs.isVip(userId, pkgName)) { // No ongoing transactions. No reason to schedule mBalanceThresholdAlarmQueue.removeAlarmForKey(new Package(userId, pkgName)); return; Loading Loading @@ -1059,9 +1116,10 @@ class Agent { note.setNewAffordability(true); return; } final boolean isVip = mIrs.isVip(userId, pkgName); note.recalculateCosts(economicPolicy, userId, pkgName); note.setNewAffordability( isAffordableLocked(getBalanceLocked(userId, pkgName), note.setNewAffordability(isVip || isAffordableLocked(getBalanceLocked(userId, pkgName), note.getCachedModifiedPrice(), note.getCtp())); mIrs.postAffordabilityChanged(userId, pkgName, note); // Update ongoing alarm Loading Loading @@ -1200,11 +1258,12 @@ class Agent { if (actionAffordabilityNotes != null && actionAffordabilityNotes.size() > 0) { final long newBalance = getBalanceLocked(userId, pkgName); final boolean isVip = mIrs.isVip(userId, pkgName); for (int i = 0; i < actionAffordabilityNotes.size(); ++i) { final ActionAffordabilityNote note = actionAffordabilityNotes.valueAt(i); final boolean isAffordable = isAffordableLocked( final boolean isAffordable = isVip || isAffordableLocked( newBalance, note.getCachedModifiedPrice(), note.getCtp()); if (note.isCurrentlyAffordable() != isAffordable) { note.setNewAffordability(isAffordable); Loading apex/jobscheduler/service/java/com/android/server/tare/AlarmManagerEconomicPolicy.java +2 −4 Original line number Diff line number Diff line Loading @@ -149,7 +149,6 @@ public class AlarmManagerEconomicPolicy extends EconomicPolicy { private long mHardSatiatedConsumptionLimit; private final KeyValueListParser mParser = new KeyValueListParser(','); private final InternalResourceService mInternalResourceService; private final Injector mInjector; private final SparseArray<Action> mActions = new SparseArray<>(); Loading @@ -157,7 +156,6 @@ public class AlarmManagerEconomicPolicy extends EconomicPolicy { AlarmManagerEconomicPolicy(InternalResourceService irs, Injector injector) { super(irs); mInternalResourceService = irs; mInjector = injector; loadConstants("", null); } Loading @@ -165,14 +163,14 @@ public class AlarmManagerEconomicPolicy extends EconomicPolicy { @Override void setup(@NonNull DeviceConfig.Properties properties) { super.setup(properties); ContentResolver resolver = mInternalResourceService.getContext().getContentResolver(); ContentResolver resolver = mIrs.getContext().getContentResolver(); loadConstants(mInjector.getSettingsGlobalString(resolver, TARE_ALARM_MANAGER_CONSTANTS), properties); } @Override long getMinSatiatedBalance(final int userId, @NonNull final String pkgName) { if (mInternalResourceService.isPackageExempted(userId, pkgName)) { if (mIrs.isPackageExempted(userId, pkgName)) { return mMinSatiatedBalanceExempted; } // TODO: take other exemptions into account Loading apex/jobscheduler/service/java/com/android/server/tare/EconomicPolicy.java +3 −1 Original line number Diff line number Diff line Loading @@ -169,9 +169,11 @@ public abstract class EconomicPolicy { } } protected final InternalResourceService mIrs; private static final Modifier[] COST_MODIFIER_BY_INDEX = new Modifier[NUM_COST_MODIFIERS]; EconomicPolicy(@NonNull InternalResourceService irs) { mIrs = irs; for (int mId : getCostModifiers()) { initModifier(mId, irs); } Loading Loading @@ -240,7 +242,7 @@ public abstract class EconomicPolicy { @NonNull final Cost getCostOfAction(int actionId, int userId, @NonNull String pkgName) { final Action action = getAction(actionId); if (action == null) { if (action == null || mIrs.isVip(userId, pkgName)) { return new Cost(0, 0); } long ctp = action.costToProduce; Loading apex/jobscheduler/service/java/com/android/server/tare/InternalResourceService.java +97 −3 Original line number Diff line number Diff line Loading @@ -48,6 +48,7 @@ import android.os.Handler; import android.os.IDeviceIdleController; import android.os.Looper; import android.os.Message; import android.os.ParcelFileDescriptor; import android.os.PowerManager; import android.os.RemoteException; import android.os.ServiceManager; Loading Loading @@ -149,6 +150,9 @@ public class InternalResourceService extends SystemService { @GuardedBy("mLock") private ArraySet<String> mExemptedApps = new ArraySet<>(); @GuardedBy("mLock") private final SparseArrayMap<String, Boolean> mVipOverrides = new SparseArrayMap<>(); private volatile boolean mIsEnabled; private volatile int mBootPhase; private volatile boolean mExemptListLoaded; Loading Loading @@ -368,6 +372,21 @@ public class InternalResourceService extends SystemService { return UserHandle.isCore(getUid(userId, pkgName)); } boolean isVip(final int userId, @NonNull String pkgName) { synchronized (mLock) { final Boolean override = mVipOverrides.get(userId, pkgName); if (override != null) { return override; } } if (isSystem(userId, pkgName)) { // The government, I mean the system, can create ARCs as it needs to in order to // operate. return true; } return false; } void onBatteryLevelChanged() { synchronized (mLock) { final int newBatteryLevel = getCurrentBatteryLevel(); Loading Loading @@ -470,6 +489,7 @@ public class InternalResourceService extends SystemService { } synchronized (mLock) { mUidToPackageCache.remove(uid, pkgName); mVipOverrides.delete(userId, pkgName); for (int i = 0; i < mPkgCache.size(); ++i) { final InstalledPackageInfo pkgInfo = mPkgCache.get(i); if (UserHandle.getUserId(pkgInfo.uid) == userId Loading Loading @@ -506,6 +526,7 @@ public class InternalResourceService extends SystemService { void onUserRemoved(final int userId) { synchronized (mLock) { mVipOverrides.delete(userId); ArrayList<String> removedPkgs = new ArrayList<>(); for (int i = mPkgCache.size() - 1; i >= 0; --i) { final InstalledPackageInfo pkgInfo = mPkgCache.get(i); Loading Loading @@ -886,6 +907,15 @@ public class InternalResourceService extends SystemService { Binder.restoreCallingIdentity(identityToken); } } @Override public int handleShellCommand(@NonNull ParcelFileDescriptor in, @NonNull ParcelFileDescriptor out, @NonNull ParcelFileDescriptor err, @NonNull String[] args) { return (new TareShellCommand(InternalResourceService.this)).exec( this, in.getFileDescriptor(), out.getFileDescriptor(), err.getFileDescriptor(), args); } } private final class LocalService implements EconomyManagerInternal { Loading Loading @@ -937,9 +967,9 @@ public class InternalResourceService extends SystemService { if (!mIsEnabled) { return true; } if (isSystem(userId, pkgName)) { if (isVip(userId, pkgName)) { // The government, I mean the system, can create ARCs as it needs to in order to // operate. // allow VIPs to operate. return true; } // TODO: take temp-allowlist into consideration Loading @@ -965,7 +995,7 @@ public class InternalResourceService extends SystemService { if (!mIsEnabled) { return FOREVER_MS; } if (isSystem(userId, pkgName)) { if (isVip(userId, pkgName)) { return FOREVER_MS; } long totalCostPerSecond = 0; Loading Loading @@ -1136,6 +1166,47 @@ public class InternalResourceService extends SystemService { } } // Shell command infrastructure int executeClearVip(@NonNull PrintWriter pw) { synchronized (mLock) { final SparseSetArray<String> changedPkgs = new SparseSetArray<>(); for (int u = mVipOverrides.numMaps() - 1; u >= 0; --u) { final int userId = mVipOverrides.keyAt(u); for (int p = mVipOverrides.numElementsForKeyAt(u) - 1; p >= 0; --p) { changedPkgs.add(userId, mVipOverrides.keyAt(u, p)); } } mVipOverrides.clear(); if (mIsEnabled) { mAgent.onVipStatusChangedLocked(changedPkgs); } } pw.println("Cleared all VIP statuses"); return TareShellCommand.COMMAND_SUCCESS; } int executeSetVip(@NonNull PrintWriter pw, int userId, @NonNull String pkgName, @Nullable Boolean newVipState) { final boolean changed; synchronized (mLock) { final boolean wasVip = isVip(userId, pkgName); if (newVipState == null) { mVipOverrides.delete(userId, pkgName); } else { mVipOverrides.add(userId, pkgName, newVipState); } changed = isVip(userId, pkgName) != wasVip; if (mIsEnabled && changed) { mAgent.onVipStatusChangedLocked(userId, pkgName); } } pw.println(appToString(userId, pkgName) + " VIP status set to " + newVipState + "." + " Final VIP state changed? " + changed); return TareShellCommand.COMMAND_SUCCESS; } // Dump infrastructure private static void dumpHelp(PrintWriter pw) { pw.println("Resource Economy (economy) dump options:"); pw.println(" [-h|--help] [package] ..."); Loading Loading @@ -1173,6 +1244,29 @@ public class InternalResourceService extends SystemService { pw.print("Exempted apps", mExemptedApps); pw.println(); boolean printedVips = false; pw.println(); pw.print("VIPs:"); for (int u = 0; u < mVipOverrides.numMaps(); ++u) { final int userId = mVipOverrides.keyAt(u); for (int p = 0; p < mVipOverrides.numElementsForKeyAt(u); ++p) { final String pkgName = mVipOverrides.keyAt(u, p); printedVips = true; pw.println(); pw.print(appToString(userId, pkgName)); pw.print("="); pw.print(mVipOverrides.valueAt(u, p)); } } if (printedVips) { pw.println(); } else { pw.print(" None"); } pw.println(); pw.println(); mCompleteEconomicPolicy.dump(pw); Loading apex/jobscheduler/service/java/com/android/server/tare/JobSchedulerEconomicPolicy.java +2 −4 Original line number Diff line number Diff line Loading @@ -151,7 +151,6 @@ public class JobSchedulerEconomicPolicy extends EconomicPolicy { private long mHardSatiatedConsumptionLimit; private final KeyValueListParser mParser = new KeyValueListParser(','); private final InternalResourceService mInternalResourceService; private final Injector mInjector; private final SparseArray<Action> mActions = new SparseArray<>(); Loading @@ -159,7 +158,6 @@ public class JobSchedulerEconomicPolicy extends EconomicPolicy { JobSchedulerEconomicPolicy(InternalResourceService irs, Injector injector) { super(irs); mInternalResourceService = irs; mInjector = injector; loadConstants("", null); } Loading @@ -167,14 +165,14 @@ public class JobSchedulerEconomicPolicy extends EconomicPolicy { @Override void setup(@NonNull DeviceConfig.Properties properties) { super.setup(properties); ContentResolver resolver = mInternalResourceService.getContext().getContentResolver(); final ContentResolver resolver = mIrs.getContext().getContentResolver(); loadConstants(mInjector.getSettingsGlobalString(resolver, TARE_JOB_SCHEDULER_CONSTANTS), properties); } @Override long getMinSatiatedBalance(final int userId, @NonNull final String pkgName) { if (mInternalResourceService.isPackageExempted(userId, pkgName)) { if (mIrs.isPackageExempted(userId, pkgName)) { return mMinSatiatedBalanceExempted; } // TODO: take other exemptions into account Loading Loading
apex/jobscheduler/service/java/com/android/server/tare/Agent.java +69 −10 Original line number Diff line number Diff line Loading @@ -44,6 +44,7 @@ import android.util.IndentingPrintWriter; import android.util.Log; import android.util.Slog; import android.util.SparseArrayMap; import android.util.SparseSetArray; import android.util.TimeUtils; import com.android.internal.annotations.GuardedBy; Loading Loading @@ -282,6 +283,7 @@ class Agent { for (int i = 0; i < pkgNames.size(); ++i) { final String pkgName = pkgNames.valueAt(i); final boolean isVip = mIrs.isVip(userId, pkgName); SparseArrayMap<String, OngoingEvent> ongoingEvents = mCurrentOngoingEvents.get(userId, pkgName); if (ongoingEvents != null) { Loading @@ -296,8 +298,8 @@ class Agent { for (int n = 0; n < size; ++n) { final ActionAffordabilityNote note = actionAffordabilityNotes.valueAt(n); note.recalculateCosts(economicPolicy, userId, pkgName); final boolean isAffordable = isAffordableLocked(newBalance, final boolean isAffordable = isVip || isAffordableLocked(newBalance, note.getCachedModifiedPrice(), note.getCtp()); if (note.isCurrentlyAffordable() != isAffordable) { note.setNewAffordability(isAffordable); Loading @@ -310,6 +312,51 @@ class Agent { } } @GuardedBy("mLock") void onVipStatusChangedLocked(final int userId, @NonNull String pkgName) { final long now = getCurrentTimeMillis(); final long nowElapsed = SystemClock.elapsedRealtime(); final CompleteEconomicPolicy economicPolicy = mIrs.getCompleteEconomicPolicyLocked(); final boolean isVip = mIrs.isVip(userId, pkgName); SparseArrayMap<String, OngoingEvent> ongoingEvents = mCurrentOngoingEvents.get(userId, pkgName); if (ongoingEvents != null) { mOngoingEventUpdater.reset(userId, pkgName, now, nowElapsed); ongoingEvents.forEach(mOngoingEventUpdater); } final ArraySet<ActionAffordabilityNote> actionAffordabilityNotes = mActionAffordabilityNotes.get(userId, pkgName); if (actionAffordabilityNotes != null) { final int size = actionAffordabilityNotes.size(); final long newBalance = mScribe.getLedgerLocked(userId, pkgName).getCurrentBalance(); for (int n = 0; n < size; ++n) { final ActionAffordabilityNote note = actionAffordabilityNotes.valueAt(n); note.recalculateCosts(economicPolicy, userId, pkgName); final boolean isAffordable = isVip || isAffordableLocked(newBalance, note.getCachedModifiedPrice(), note.getCtp()); if (note.isCurrentlyAffordable() != isAffordable) { note.setNewAffordability(isAffordable); mIrs.postAffordabilityChanged(userId, pkgName, note); } } } scheduleBalanceCheckLocked(userId, pkgName); } @GuardedBy("mLock") void onVipStatusChangedLocked(@NonNull SparseSetArray<String> pkgs) { for (int u = pkgs.size() - 1; u >= 0; --u) { final int userId = pkgs.keyAt(u); for (int p = pkgs.sizeAt(u) - 1; p >= 0; --p) { onVipStatusChangedLocked(userId, pkgs.valueAt(u, p)); } } } @GuardedBy("mLock") private void onAnythingChangedLocked(final boolean updateOngoingEvents) { final long now = getCurrentTimeMillis(); Loading Loading @@ -347,11 +394,12 @@ class Agent { if (actionAffordabilityNotes != null) { final int size = actionAffordabilityNotes.size(); final long newBalance = getBalanceLocked(userId, pkgName); final boolean isVip = mIrs.isVip(userId, pkgName); for (int n = 0; n < size; ++n) { final ActionAffordabilityNote note = actionAffordabilityNotes.valueAt(n); note.recalculateCosts(economicPolicy, userId, pkgName); final boolean isAffordable = isAffordableLocked(newBalance, final boolean isAffordable = isVip || isAffordableLocked(newBalance, note.getCachedModifiedPrice(), note.getCtp()); if (note.isCurrentlyAffordable() != isAffordable) { note.setNewAffordability(isAffordable); Loading Loading @@ -452,6 +500,14 @@ class Agent { "Tried to adjust system balance for " + appToString(userId, pkgName)); return; } if (mIrs.isVip(userId, pkgName)) { // This could happen if the app was made a VIP after it started performing actions. // Continue recording the transaction for debugging purposes, but don't let it change // any numbers. transaction = new Ledger.Transaction( transaction.startTimeMs, transaction.endTimeMs, transaction.eventId, transaction.tag, 0 /* delta */, transaction.ctp); } final CompleteEconomicPolicy economicPolicy = mIrs.getCompleteEconomicPolicyLocked(); final long originalBalance = ledger.getCurrentBalance(); if (transaction.delta > 0 Loading @@ -477,10 +533,11 @@ class Agent { mActionAffordabilityNotes.get(userId, pkgName); if (actionAffordabilityNotes != null) { final long newBalance = ledger.getCurrentBalance(); final boolean isVip = mIrs.isVip(userId, pkgName); for (int i = 0; i < actionAffordabilityNotes.size(); ++i) { final ActionAffordabilityNote note = actionAffordabilityNotes.valueAt(i); final boolean isAffordable = isAffordableLocked(newBalance, final boolean isAffordable = isVip || isAffordableLocked(newBalance, note.getCachedModifiedPrice(), note.getCtp()); if (note.isCurrentlyAffordable() != isAffordable) { note.setNewAffordability(isAffordable); Loading Loading @@ -866,7 +923,7 @@ class Agent { private void scheduleBalanceCheckLocked(final int userId, @NonNull final String pkgName) { SparseArrayMap<String, OngoingEvent> ongoingEvents = mCurrentOngoingEvents.get(userId, pkgName); if (ongoingEvents == null) { if (ongoingEvents == null || mIrs.isVip(userId, pkgName)) { // No ongoing transactions. No reason to schedule mBalanceThresholdAlarmQueue.removeAlarmForKey(new Package(userId, pkgName)); return; Loading Loading @@ -1059,9 +1116,10 @@ class Agent { note.setNewAffordability(true); return; } final boolean isVip = mIrs.isVip(userId, pkgName); note.recalculateCosts(economicPolicy, userId, pkgName); note.setNewAffordability( isAffordableLocked(getBalanceLocked(userId, pkgName), note.setNewAffordability(isVip || isAffordableLocked(getBalanceLocked(userId, pkgName), note.getCachedModifiedPrice(), note.getCtp())); mIrs.postAffordabilityChanged(userId, pkgName, note); // Update ongoing alarm Loading Loading @@ -1200,11 +1258,12 @@ class Agent { if (actionAffordabilityNotes != null && actionAffordabilityNotes.size() > 0) { final long newBalance = getBalanceLocked(userId, pkgName); final boolean isVip = mIrs.isVip(userId, pkgName); for (int i = 0; i < actionAffordabilityNotes.size(); ++i) { final ActionAffordabilityNote note = actionAffordabilityNotes.valueAt(i); final boolean isAffordable = isAffordableLocked( final boolean isAffordable = isVip || isAffordableLocked( newBalance, note.getCachedModifiedPrice(), note.getCtp()); if (note.isCurrentlyAffordable() != isAffordable) { note.setNewAffordability(isAffordable); Loading
apex/jobscheduler/service/java/com/android/server/tare/AlarmManagerEconomicPolicy.java +2 −4 Original line number Diff line number Diff line Loading @@ -149,7 +149,6 @@ public class AlarmManagerEconomicPolicy extends EconomicPolicy { private long mHardSatiatedConsumptionLimit; private final KeyValueListParser mParser = new KeyValueListParser(','); private final InternalResourceService mInternalResourceService; private final Injector mInjector; private final SparseArray<Action> mActions = new SparseArray<>(); Loading @@ -157,7 +156,6 @@ public class AlarmManagerEconomicPolicy extends EconomicPolicy { AlarmManagerEconomicPolicy(InternalResourceService irs, Injector injector) { super(irs); mInternalResourceService = irs; mInjector = injector; loadConstants("", null); } Loading @@ -165,14 +163,14 @@ public class AlarmManagerEconomicPolicy extends EconomicPolicy { @Override void setup(@NonNull DeviceConfig.Properties properties) { super.setup(properties); ContentResolver resolver = mInternalResourceService.getContext().getContentResolver(); ContentResolver resolver = mIrs.getContext().getContentResolver(); loadConstants(mInjector.getSettingsGlobalString(resolver, TARE_ALARM_MANAGER_CONSTANTS), properties); } @Override long getMinSatiatedBalance(final int userId, @NonNull final String pkgName) { if (mInternalResourceService.isPackageExempted(userId, pkgName)) { if (mIrs.isPackageExempted(userId, pkgName)) { return mMinSatiatedBalanceExempted; } // TODO: take other exemptions into account Loading
apex/jobscheduler/service/java/com/android/server/tare/EconomicPolicy.java +3 −1 Original line number Diff line number Diff line Loading @@ -169,9 +169,11 @@ public abstract class EconomicPolicy { } } protected final InternalResourceService mIrs; private static final Modifier[] COST_MODIFIER_BY_INDEX = new Modifier[NUM_COST_MODIFIERS]; EconomicPolicy(@NonNull InternalResourceService irs) { mIrs = irs; for (int mId : getCostModifiers()) { initModifier(mId, irs); } Loading Loading @@ -240,7 +242,7 @@ public abstract class EconomicPolicy { @NonNull final Cost getCostOfAction(int actionId, int userId, @NonNull String pkgName) { final Action action = getAction(actionId); if (action == null) { if (action == null || mIrs.isVip(userId, pkgName)) { return new Cost(0, 0); } long ctp = action.costToProduce; Loading
apex/jobscheduler/service/java/com/android/server/tare/InternalResourceService.java +97 −3 Original line number Diff line number Diff line Loading @@ -48,6 +48,7 @@ import android.os.Handler; import android.os.IDeviceIdleController; import android.os.Looper; import android.os.Message; import android.os.ParcelFileDescriptor; import android.os.PowerManager; import android.os.RemoteException; import android.os.ServiceManager; Loading Loading @@ -149,6 +150,9 @@ public class InternalResourceService extends SystemService { @GuardedBy("mLock") private ArraySet<String> mExemptedApps = new ArraySet<>(); @GuardedBy("mLock") private final SparseArrayMap<String, Boolean> mVipOverrides = new SparseArrayMap<>(); private volatile boolean mIsEnabled; private volatile int mBootPhase; private volatile boolean mExemptListLoaded; Loading Loading @@ -368,6 +372,21 @@ public class InternalResourceService extends SystemService { return UserHandle.isCore(getUid(userId, pkgName)); } boolean isVip(final int userId, @NonNull String pkgName) { synchronized (mLock) { final Boolean override = mVipOverrides.get(userId, pkgName); if (override != null) { return override; } } if (isSystem(userId, pkgName)) { // The government, I mean the system, can create ARCs as it needs to in order to // operate. return true; } return false; } void onBatteryLevelChanged() { synchronized (mLock) { final int newBatteryLevel = getCurrentBatteryLevel(); Loading Loading @@ -470,6 +489,7 @@ public class InternalResourceService extends SystemService { } synchronized (mLock) { mUidToPackageCache.remove(uid, pkgName); mVipOverrides.delete(userId, pkgName); for (int i = 0; i < mPkgCache.size(); ++i) { final InstalledPackageInfo pkgInfo = mPkgCache.get(i); if (UserHandle.getUserId(pkgInfo.uid) == userId Loading Loading @@ -506,6 +526,7 @@ public class InternalResourceService extends SystemService { void onUserRemoved(final int userId) { synchronized (mLock) { mVipOverrides.delete(userId); ArrayList<String> removedPkgs = new ArrayList<>(); for (int i = mPkgCache.size() - 1; i >= 0; --i) { final InstalledPackageInfo pkgInfo = mPkgCache.get(i); Loading Loading @@ -886,6 +907,15 @@ public class InternalResourceService extends SystemService { Binder.restoreCallingIdentity(identityToken); } } @Override public int handleShellCommand(@NonNull ParcelFileDescriptor in, @NonNull ParcelFileDescriptor out, @NonNull ParcelFileDescriptor err, @NonNull String[] args) { return (new TareShellCommand(InternalResourceService.this)).exec( this, in.getFileDescriptor(), out.getFileDescriptor(), err.getFileDescriptor(), args); } } private final class LocalService implements EconomyManagerInternal { Loading Loading @@ -937,9 +967,9 @@ public class InternalResourceService extends SystemService { if (!mIsEnabled) { return true; } if (isSystem(userId, pkgName)) { if (isVip(userId, pkgName)) { // The government, I mean the system, can create ARCs as it needs to in order to // operate. // allow VIPs to operate. return true; } // TODO: take temp-allowlist into consideration Loading @@ -965,7 +995,7 @@ public class InternalResourceService extends SystemService { if (!mIsEnabled) { return FOREVER_MS; } if (isSystem(userId, pkgName)) { if (isVip(userId, pkgName)) { return FOREVER_MS; } long totalCostPerSecond = 0; Loading Loading @@ -1136,6 +1166,47 @@ public class InternalResourceService extends SystemService { } } // Shell command infrastructure int executeClearVip(@NonNull PrintWriter pw) { synchronized (mLock) { final SparseSetArray<String> changedPkgs = new SparseSetArray<>(); for (int u = mVipOverrides.numMaps() - 1; u >= 0; --u) { final int userId = mVipOverrides.keyAt(u); for (int p = mVipOverrides.numElementsForKeyAt(u) - 1; p >= 0; --p) { changedPkgs.add(userId, mVipOverrides.keyAt(u, p)); } } mVipOverrides.clear(); if (mIsEnabled) { mAgent.onVipStatusChangedLocked(changedPkgs); } } pw.println("Cleared all VIP statuses"); return TareShellCommand.COMMAND_SUCCESS; } int executeSetVip(@NonNull PrintWriter pw, int userId, @NonNull String pkgName, @Nullable Boolean newVipState) { final boolean changed; synchronized (mLock) { final boolean wasVip = isVip(userId, pkgName); if (newVipState == null) { mVipOverrides.delete(userId, pkgName); } else { mVipOverrides.add(userId, pkgName, newVipState); } changed = isVip(userId, pkgName) != wasVip; if (mIsEnabled && changed) { mAgent.onVipStatusChangedLocked(userId, pkgName); } } pw.println(appToString(userId, pkgName) + " VIP status set to " + newVipState + "." + " Final VIP state changed? " + changed); return TareShellCommand.COMMAND_SUCCESS; } // Dump infrastructure private static void dumpHelp(PrintWriter pw) { pw.println("Resource Economy (economy) dump options:"); pw.println(" [-h|--help] [package] ..."); Loading Loading @@ -1173,6 +1244,29 @@ public class InternalResourceService extends SystemService { pw.print("Exempted apps", mExemptedApps); pw.println(); boolean printedVips = false; pw.println(); pw.print("VIPs:"); for (int u = 0; u < mVipOverrides.numMaps(); ++u) { final int userId = mVipOverrides.keyAt(u); for (int p = 0; p < mVipOverrides.numElementsForKeyAt(u); ++p) { final String pkgName = mVipOverrides.keyAt(u, p); printedVips = true; pw.println(); pw.print(appToString(userId, pkgName)); pw.print("="); pw.print(mVipOverrides.valueAt(u, p)); } } if (printedVips) { pw.println(); } else { pw.print(" None"); } pw.println(); pw.println(); mCompleteEconomicPolicy.dump(pw); Loading
apex/jobscheduler/service/java/com/android/server/tare/JobSchedulerEconomicPolicy.java +2 −4 Original line number Diff line number Diff line Loading @@ -151,7 +151,6 @@ public class JobSchedulerEconomicPolicy extends EconomicPolicy { private long mHardSatiatedConsumptionLimit; private final KeyValueListParser mParser = new KeyValueListParser(','); private final InternalResourceService mInternalResourceService; private final Injector mInjector; private final SparseArray<Action> mActions = new SparseArray<>(); Loading @@ -159,7 +158,6 @@ public class JobSchedulerEconomicPolicy extends EconomicPolicy { JobSchedulerEconomicPolicy(InternalResourceService irs, Injector injector) { super(irs); mInternalResourceService = irs; mInjector = injector; loadConstants("", null); } Loading @@ -167,14 +165,14 @@ public class JobSchedulerEconomicPolicy extends EconomicPolicy { @Override void setup(@NonNull DeviceConfig.Properties properties) { super.setup(properties); ContentResolver resolver = mInternalResourceService.getContext().getContentResolver(); final ContentResolver resolver = mIrs.getContext().getContentResolver(); loadConstants(mInjector.getSettingsGlobalString(resolver, TARE_JOB_SCHEDULER_CONSTANTS), properties); } @Override long getMinSatiatedBalance(final int userId, @NonNull final String pkgName) { if (mInternalResourceService.isPackageExempted(userId, pkgName)) { if (mIrs.isPackageExempted(userId, pkgName)) { return mMinSatiatedBalanceExempted; } // TODO: take other exemptions into account Loading