Loading apex/jobscheduler/service/java/com/android/server/tare/Agent.java +105 −80 Original line number Diff line number Diff line Loading @@ -55,8 +55,6 @@ import com.android.server.pm.UserManagerInternal; import com.android.server.usage.AppStandbyInternal; import com.android.server.utils.AlarmQueue; import libcore.util.EmptyArray; import java.util.List; import java.util.Objects; import java.util.function.Consumer; Loading Loading @@ -154,6 +152,11 @@ class Agent { return balance; } @GuardedBy("mLock") private boolean isAffordableLocked(long balance, long price) { return balance >= price; } @GuardedBy("mLock") void noteInstantaneousEventLocked(final int userId, @NonNull final String pkgName, final int eventId, @Nullable String tag) { Loading Loading @@ -257,105 +260,94 @@ class Agent { @GuardedBy("mLock") void onPricingChangedLocked() { onAnythingChangedLocked(true); } @GuardedBy("mLock") void onAppStatesChangedLocked(final int userId, @NonNull ArraySet<String> pkgNames) { final long now = getCurrentTimeMillis(); final long nowElapsed = SystemClock.elapsedRealtime(); final CompleteEconomicPolicy economicPolicy = mIrs.getCompleteEconomicPolicyLocked(); mCurrentOngoingEvents.forEach((userId, pkgName, ongoingEvents) -> { for (int i = 0; i < pkgNames.size(); ++i) { final String pkgName = pkgNames.valueAt(i); 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); final boolean[] wasAffordable; if (actionAffordabilityNotes != null) { final int size = actionAffordabilityNotes.size(); wasAffordable = new boolean[size]; for (int i = 0; i < size; ++i) { final ActionAffordabilityNote note = actionAffordabilityNotes.valueAt(i); final long originalBalance = mScribe.getLedgerLocked(userId, pkgName).getCurrentBalance(); wasAffordable[i] = originalBalance >= note.getCachedModifiedPrice(); } } else { wasAffordable = EmptyArray.BOOLEAN; } ongoingEvents.forEach((ongoingEvent) -> { // Disable balance check & affordability notifications here because we're in the // middle of updating ongoing action costs/prices and sending out notifications // or rescheduling the balance check alarm would be a waste since we'll have to // redo them again after all of our internal state is updated. stopOngoingActionLocked(userId, pkgName, ongoingEvent.eventId, ongoingEvent.tag, nowElapsed, now, false, false); noteOngoingEventLocked(userId, pkgName, ongoingEvent.eventId, ongoingEvent.tag, nowElapsed, false); }); if (actionAffordabilityNotes != null) { final int size = actionAffordabilityNotes.size(); for (int i = 0; i < size; ++i) { final ActionAffordabilityNote note = actionAffordabilityNotes.valueAt(i); note.recalculateModifiedPrice(economicPolicy, userId, pkgName); final long newBalance = mScribe.getLedgerLocked(userId, pkgName).getCurrentBalance(); final boolean isAffordable = newBalance >= note.getCachedModifiedPrice(); if (wasAffordable[i] != isAffordable) { for (int n = 0; n < size; ++n) { final ActionAffordabilityNote note = actionAffordabilityNotes.valueAt(n); note.recalculateCosts(economicPolicy, userId, pkgName); final boolean isAffordable = isAffordableLocked(newBalance, note.getCachedModifiedPrice()); if (note.isCurrentlyAffordable() != isAffordable) { note.setNewAffordability(isAffordable); mIrs.postAffordabilityChanged(userId, pkgName, note); } } } scheduleBalanceCheckLocked(userId, pkgName); }); } } } @GuardedBy("mLock") void onAppStatesChangedLocked(final int userId, @NonNull ArraySet<String> pkgNames) { private void onAnythingChangedLocked(final boolean updateOngoingEvents) { final long now = getCurrentTimeMillis(); final long nowElapsed = SystemClock.elapsedRealtime(); final CompleteEconomicPolicy economicPolicy = mIrs.getCompleteEconomicPolicyLocked(); for (int i = 0; i < pkgNames.size(); ++i) { final String pkgName = pkgNames.valueAt(i); for (int uIdx = mCurrentOngoingEvents.numMaps() - 1; uIdx >= 0; --uIdx) { final int userId = mCurrentOngoingEvents.keyAt(uIdx); for (int pIdx = mCurrentOngoingEvents.numElementsForKey(userId) - 1; pIdx >= 0; --pIdx) { final String pkgName = mCurrentOngoingEvents.keyAt(uIdx, pIdx); SparseArrayMap<String, OngoingEvent> ongoingEvents = mCurrentOngoingEvents.get(userId, pkgName); mCurrentOngoingEvents.valueAt(uIdx, pIdx); if (ongoingEvents != null) { final ArraySet<ActionAffordabilityNote> actionAffordabilityNotes = mActionAffordabilityNotes.get(userId, pkgName); final boolean[] wasAffordable; if (actionAffordabilityNotes != null) { final int size = actionAffordabilityNotes.size(); wasAffordable = new boolean[size]; for (int n = 0; n < size; ++n) { final ActionAffordabilityNote note = actionAffordabilityNotes.valueAt(n); final long originalBalance = mScribe.getLedgerLocked(userId, pkgName).getCurrentBalance(); wasAffordable[n] = originalBalance >= note.getCachedModifiedPrice(); if (updateOngoingEvents) { mOngoingEventUpdater.reset(userId, pkgName, now, nowElapsed); ongoingEvents.forEach(mOngoingEventUpdater); } } else { wasAffordable = EmptyArray.BOOLEAN; } ongoingEvents.forEach((ongoingEvent) -> { // Disable balance check & affordability notifications here because we're in the // middle of updating ongoing action costs/prices and sending out notifications // or rescheduling the balance check alarm would be a waste since we'll have to // redo them again after all of our internal state is updated. stopOngoingActionLocked(userId, pkgName, ongoingEvent.eventId, ongoingEvent.tag, nowElapsed, now, false, false); noteOngoingEventLocked(userId, pkgName, ongoingEvent.eventId, ongoingEvent.tag, nowElapsed, false); }); scheduleBalanceCheckLocked(userId, pkgName); } } } for (int uIdx = mActionAffordabilityNotes.numMaps() - 1; uIdx >= 0; --uIdx) { final int userId = mActionAffordabilityNotes.keyAt(uIdx); for (int pIdx = mActionAffordabilityNotes.numElementsForKey(userId) - 1; pIdx >= 0; --pIdx) { final String pkgName = mActionAffordabilityNotes.keyAt(uIdx, pIdx); final ArraySet<ActionAffordabilityNote> actionAffordabilityNotes = mActionAffordabilityNotes.valueAt(uIdx, pIdx); if (actionAffordabilityNotes != null) { final int size = actionAffordabilityNotes.size(); final long newBalance = getBalanceLocked(userId, pkgName); for (int n = 0; n < size; ++n) { final ActionAffordabilityNote note = actionAffordabilityNotes.valueAt(n); note.recalculateModifiedPrice(economicPolicy, userId, pkgName); final long newBalance = mScribe.getLedgerLocked(userId, pkgName).getCurrentBalance(); final boolean isAffordable = newBalance >= note.getCachedModifiedPrice(); if (wasAffordable[n] != isAffordable) { note.recalculateCosts(economicPolicy, userId, pkgName); final boolean isAffordable = isAffordableLocked(newBalance, note.getCachedModifiedPrice()); if (note.isCurrentlyAffordable() != isAffordable) { note.setNewAffordability(isAffordable); mIrs.postAffordabilityChanged(userId, pkgName, note); } } } scheduleBalanceCheckLocked(userId, pkgName); } } } Loading @@ -367,9 +359,9 @@ class Agent { } /** * @param updateBalanceCheck Whether or not to reschedule the affordability/balance * @param updateBalanceCheck Whether to reschedule the affordability/balance * check alarm. * @param notifyOnAffordabilityChange Whether or not to evaluate the app's ability to afford * @param notifyOnAffordabilityChange Whether to evaluate the app's ability to afford * registered bills and notify listeners about any changes. */ @GuardedBy("mLock") Loading Loading @@ -486,7 +478,9 @@ class Agent { final long newBalance = ledger.getCurrentBalance(); for (int i = 0; i < actionAffordabilityNotes.size(); ++i) { final ActionAffordabilityNote note = actionAffordabilityNotes.valueAt(i); final boolean isAffordable = newBalance >= note.getCachedModifiedPrice(); final boolean isAffordable = isAffordableLocked(newBalance, note.getCachedModifiedPrice()); if (note.isCurrentlyAffordable() != isAffordable) { note.setNewAffordability(isAffordable); mIrs.postAffordabilityChanged(userId, pkgName, note); Loading Loading @@ -893,6 +887,36 @@ class Agent { } } private class OngoingEventUpdater implements Consumer<OngoingEvent> { private int mUserId; private String mPkgName; private long mNow; private long mNowElapsed; private void reset(int userId, String pkgName, long now, long nowElapsed) { mUserId = userId; mPkgName = pkgName; mNow = now; mNowElapsed = nowElapsed; } @Override public void accept(OngoingEvent ongoingEvent) { // Disable balance check & affordability notifications here because // we're in the middle of updating ongoing action costs/prices and // sending out notifications or rescheduling the balance check alarm // would be a waste since we'll have to redo them again after all of // our internal state is updated. final boolean updateBalanceCheck = false; stopOngoingActionLocked(mUserId, mPkgName, ongoingEvent.eventId, ongoingEvent.tag, mNowElapsed, mNow, updateBalanceCheck, /* notifyOnAffordabilityChange */ false); noteOngoingEventLocked(mUserId, mPkgName, ongoingEvent.eventId, ongoingEvent.tag, mNowElapsed, updateBalanceCheck); } } private final OngoingEventUpdater mOngoingEventUpdater = new OngoingEventUpdater(); private static final class Package { public final String packageName; public final int userId; Loading Loading @@ -971,9 +995,10 @@ class Agent { note.setNewAffordability(true); return; } note.recalculateModifiedPrice(economicPolicy, userId, pkgName); note.recalculateCosts(economicPolicy, userId, pkgName); note.setNewAffordability( getBalanceLocked(userId, pkgName) >= note.getCachedModifiedPrice()); isAffordableLocked(getBalanceLocked(userId, pkgName), note.getCachedModifiedPrice())); mIrs.postAffordabilityChanged(userId, pkgName, note); // Update ongoing alarm scheduleBalanceCheckLocked(userId, pkgName); Loading Loading @@ -1035,7 +1060,7 @@ class Agent { } @VisibleForTesting long recalculateModifiedPrice(@NonNull EconomicPolicy economicPolicy, long recalculateCosts(@NonNull EconomicPolicy economicPolicy, int userId, @NonNull String pkgName) { long modifiedPrice = 0; final List<EconomyManagerInternal.AnticipatedAction> anticipatedActions = Loading Loading @@ -1099,8 +1124,8 @@ class Agent { for (int i = 0; i < actionAffordabilityNotes.size(); ++i) { final ActionAffordabilityNote note = actionAffordabilityNotes.valueAt(i); final boolean isAffordable = newBalance >= note.getCachedModifiedPrice(); final boolean isAffordable = isAffordableLocked( newBalance, note.getCachedModifiedPrice()); if (note.isCurrentlyAffordable() != isAffordable) { note.setNewAffordability(isAffordable); mIrs.postAffordabilityChanged(userId, pkgName, note); Loading Loading @@ -1155,7 +1180,7 @@ class Agent { pw.print(" runtime="); TimeUtils.formatDuration(nowElapsed - ongoingEvent.startTimeElapsed, pw); pw.print(" delta/sec="); pw.print(ongoingEvent.deltaPerSec); pw.print(narcToString(ongoingEvent.deltaPerSec)); pw.print(" refCount="); pw.print(ongoingEvent.refCount); pw.println(); Loading services/tests/servicestests/src/com/android/server/tare/AgentTrendCalculatorTest.java +5 −5 Original line number Diff line number Diff line Loading @@ -115,7 +115,7 @@ public class AgentTrendCalculatorTest { new AnticipatedAction(JobSchedulerEconomicPolicy.ACTION_JOB_TIMEOUT, 1, 0))), mock(AffordabilityChangeListener.class), mEconomicPolicy)); for (ActionAffordabilityNote note : affordabilityNotes) { note.recalculateModifiedPrice(mEconomicPolicy, 0, "com.test.app"); note.recalculateCosts(mEconomicPolicy, 0, "com.test.app"); } trendCalculator.reset(1234, affordabilityNotes); Loading Loading @@ -174,7 +174,7 @@ public class AgentTrendCalculatorTest { new AnticipatedAction(JobSchedulerEconomicPolicy.ACTION_JOB_MAX_RUNNING, 0, 1000))), mock(AffordabilityChangeListener.class), mEconomicPolicy)); for (ActionAffordabilityNote note : affordabilityNotes) { note.recalculateModifiedPrice(mEconomicPolicy, 0, "com.test.app"); note.recalculateCosts(mEconomicPolicy, 0, "com.test.app"); } // Balance is already above threshold and events are all positive delta. Loading Loading @@ -222,7 +222,7 @@ public class AgentTrendCalculatorTest { new AnticipatedAction(JobSchedulerEconomicPolicy.ACTION_JOB_MAX_START, 1, 0))), mock(AffordabilityChangeListener.class), mEconomicPolicy)); for (ActionAffordabilityNote note : affordabilityNotes) { note.recalculateModifiedPrice(mEconomicPolicy, 0, "com.test.app"); note.recalculateCosts(mEconomicPolicy, 0, "com.test.app"); } // Balance is below threshold and events are all positive delta. Loading Loading @@ -278,7 +278,7 @@ public class AgentTrendCalculatorTest { new AnticipatedAction(JobSchedulerEconomicPolicy.ACTION_JOB_MIN_START, 1, 0))), mock(AffordabilityChangeListener.class), mEconomicPolicy)); for (ActionAffordabilityNote note : affordabilityNotes) { note.recalculateModifiedPrice(mEconomicPolicy, 0, "com.test.app"); note.recalculateCosts(mEconomicPolicy, 0, "com.test.app"); } // Balance is below threshold and events are all positive delta. Loading Loading @@ -320,7 +320,7 @@ public class AgentTrendCalculatorTest { new AnticipatedAction(AlarmManagerEconomicPolicy.ACTION_ALARM_CLOCK, 1, 0))), mock(AffordabilityChangeListener.class), mEconomicPolicy)); for (ActionAffordabilityNote note : affordabilityNotes) { note.recalculateModifiedPrice(mEconomicPolicy, 0, "com.test.app"); note.recalculateCosts(mEconomicPolicy, 0, "com.test.app"); } // Balance is between both thresholds and events are mixed positive/negative delta. Loading Loading
apex/jobscheduler/service/java/com/android/server/tare/Agent.java +105 −80 Original line number Diff line number Diff line Loading @@ -55,8 +55,6 @@ import com.android.server.pm.UserManagerInternal; import com.android.server.usage.AppStandbyInternal; import com.android.server.utils.AlarmQueue; import libcore.util.EmptyArray; import java.util.List; import java.util.Objects; import java.util.function.Consumer; Loading Loading @@ -154,6 +152,11 @@ class Agent { return balance; } @GuardedBy("mLock") private boolean isAffordableLocked(long balance, long price) { return balance >= price; } @GuardedBy("mLock") void noteInstantaneousEventLocked(final int userId, @NonNull final String pkgName, final int eventId, @Nullable String tag) { Loading Loading @@ -257,105 +260,94 @@ class Agent { @GuardedBy("mLock") void onPricingChangedLocked() { onAnythingChangedLocked(true); } @GuardedBy("mLock") void onAppStatesChangedLocked(final int userId, @NonNull ArraySet<String> pkgNames) { final long now = getCurrentTimeMillis(); final long nowElapsed = SystemClock.elapsedRealtime(); final CompleteEconomicPolicy economicPolicy = mIrs.getCompleteEconomicPolicyLocked(); mCurrentOngoingEvents.forEach((userId, pkgName, ongoingEvents) -> { for (int i = 0; i < pkgNames.size(); ++i) { final String pkgName = pkgNames.valueAt(i); 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); final boolean[] wasAffordable; if (actionAffordabilityNotes != null) { final int size = actionAffordabilityNotes.size(); wasAffordable = new boolean[size]; for (int i = 0; i < size; ++i) { final ActionAffordabilityNote note = actionAffordabilityNotes.valueAt(i); final long originalBalance = mScribe.getLedgerLocked(userId, pkgName).getCurrentBalance(); wasAffordable[i] = originalBalance >= note.getCachedModifiedPrice(); } } else { wasAffordable = EmptyArray.BOOLEAN; } ongoingEvents.forEach((ongoingEvent) -> { // Disable balance check & affordability notifications here because we're in the // middle of updating ongoing action costs/prices and sending out notifications // or rescheduling the balance check alarm would be a waste since we'll have to // redo them again after all of our internal state is updated. stopOngoingActionLocked(userId, pkgName, ongoingEvent.eventId, ongoingEvent.tag, nowElapsed, now, false, false); noteOngoingEventLocked(userId, pkgName, ongoingEvent.eventId, ongoingEvent.tag, nowElapsed, false); }); if (actionAffordabilityNotes != null) { final int size = actionAffordabilityNotes.size(); for (int i = 0; i < size; ++i) { final ActionAffordabilityNote note = actionAffordabilityNotes.valueAt(i); note.recalculateModifiedPrice(economicPolicy, userId, pkgName); final long newBalance = mScribe.getLedgerLocked(userId, pkgName).getCurrentBalance(); final boolean isAffordable = newBalance >= note.getCachedModifiedPrice(); if (wasAffordable[i] != isAffordable) { for (int n = 0; n < size; ++n) { final ActionAffordabilityNote note = actionAffordabilityNotes.valueAt(n); note.recalculateCosts(economicPolicy, userId, pkgName); final boolean isAffordable = isAffordableLocked(newBalance, note.getCachedModifiedPrice()); if (note.isCurrentlyAffordable() != isAffordable) { note.setNewAffordability(isAffordable); mIrs.postAffordabilityChanged(userId, pkgName, note); } } } scheduleBalanceCheckLocked(userId, pkgName); }); } } } @GuardedBy("mLock") void onAppStatesChangedLocked(final int userId, @NonNull ArraySet<String> pkgNames) { private void onAnythingChangedLocked(final boolean updateOngoingEvents) { final long now = getCurrentTimeMillis(); final long nowElapsed = SystemClock.elapsedRealtime(); final CompleteEconomicPolicy economicPolicy = mIrs.getCompleteEconomicPolicyLocked(); for (int i = 0; i < pkgNames.size(); ++i) { final String pkgName = pkgNames.valueAt(i); for (int uIdx = mCurrentOngoingEvents.numMaps() - 1; uIdx >= 0; --uIdx) { final int userId = mCurrentOngoingEvents.keyAt(uIdx); for (int pIdx = mCurrentOngoingEvents.numElementsForKey(userId) - 1; pIdx >= 0; --pIdx) { final String pkgName = mCurrentOngoingEvents.keyAt(uIdx, pIdx); SparseArrayMap<String, OngoingEvent> ongoingEvents = mCurrentOngoingEvents.get(userId, pkgName); mCurrentOngoingEvents.valueAt(uIdx, pIdx); if (ongoingEvents != null) { final ArraySet<ActionAffordabilityNote> actionAffordabilityNotes = mActionAffordabilityNotes.get(userId, pkgName); final boolean[] wasAffordable; if (actionAffordabilityNotes != null) { final int size = actionAffordabilityNotes.size(); wasAffordable = new boolean[size]; for (int n = 0; n < size; ++n) { final ActionAffordabilityNote note = actionAffordabilityNotes.valueAt(n); final long originalBalance = mScribe.getLedgerLocked(userId, pkgName).getCurrentBalance(); wasAffordable[n] = originalBalance >= note.getCachedModifiedPrice(); if (updateOngoingEvents) { mOngoingEventUpdater.reset(userId, pkgName, now, nowElapsed); ongoingEvents.forEach(mOngoingEventUpdater); } } else { wasAffordable = EmptyArray.BOOLEAN; } ongoingEvents.forEach((ongoingEvent) -> { // Disable balance check & affordability notifications here because we're in the // middle of updating ongoing action costs/prices and sending out notifications // or rescheduling the balance check alarm would be a waste since we'll have to // redo them again after all of our internal state is updated. stopOngoingActionLocked(userId, pkgName, ongoingEvent.eventId, ongoingEvent.tag, nowElapsed, now, false, false); noteOngoingEventLocked(userId, pkgName, ongoingEvent.eventId, ongoingEvent.tag, nowElapsed, false); }); scheduleBalanceCheckLocked(userId, pkgName); } } } for (int uIdx = mActionAffordabilityNotes.numMaps() - 1; uIdx >= 0; --uIdx) { final int userId = mActionAffordabilityNotes.keyAt(uIdx); for (int pIdx = mActionAffordabilityNotes.numElementsForKey(userId) - 1; pIdx >= 0; --pIdx) { final String pkgName = mActionAffordabilityNotes.keyAt(uIdx, pIdx); final ArraySet<ActionAffordabilityNote> actionAffordabilityNotes = mActionAffordabilityNotes.valueAt(uIdx, pIdx); if (actionAffordabilityNotes != null) { final int size = actionAffordabilityNotes.size(); final long newBalance = getBalanceLocked(userId, pkgName); for (int n = 0; n < size; ++n) { final ActionAffordabilityNote note = actionAffordabilityNotes.valueAt(n); note.recalculateModifiedPrice(economicPolicy, userId, pkgName); final long newBalance = mScribe.getLedgerLocked(userId, pkgName).getCurrentBalance(); final boolean isAffordable = newBalance >= note.getCachedModifiedPrice(); if (wasAffordable[n] != isAffordable) { note.recalculateCosts(economicPolicy, userId, pkgName); final boolean isAffordable = isAffordableLocked(newBalance, note.getCachedModifiedPrice()); if (note.isCurrentlyAffordable() != isAffordable) { note.setNewAffordability(isAffordable); mIrs.postAffordabilityChanged(userId, pkgName, note); } } } scheduleBalanceCheckLocked(userId, pkgName); } } } Loading @@ -367,9 +359,9 @@ class Agent { } /** * @param updateBalanceCheck Whether or not to reschedule the affordability/balance * @param updateBalanceCheck Whether to reschedule the affordability/balance * check alarm. * @param notifyOnAffordabilityChange Whether or not to evaluate the app's ability to afford * @param notifyOnAffordabilityChange Whether to evaluate the app's ability to afford * registered bills and notify listeners about any changes. */ @GuardedBy("mLock") Loading Loading @@ -486,7 +478,9 @@ class Agent { final long newBalance = ledger.getCurrentBalance(); for (int i = 0; i < actionAffordabilityNotes.size(); ++i) { final ActionAffordabilityNote note = actionAffordabilityNotes.valueAt(i); final boolean isAffordable = newBalance >= note.getCachedModifiedPrice(); final boolean isAffordable = isAffordableLocked(newBalance, note.getCachedModifiedPrice()); if (note.isCurrentlyAffordable() != isAffordable) { note.setNewAffordability(isAffordable); mIrs.postAffordabilityChanged(userId, pkgName, note); Loading Loading @@ -893,6 +887,36 @@ class Agent { } } private class OngoingEventUpdater implements Consumer<OngoingEvent> { private int mUserId; private String mPkgName; private long mNow; private long mNowElapsed; private void reset(int userId, String pkgName, long now, long nowElapsed) { mUserId = userId; mPkgName = pkgName; mNow = now; mNowElapsed = nowElapsed; } @Override public void accept(OngoingEvent ongoingEvent) { // Disable balance check & affordability notifications here because // we're in the middle of updating ongoing action costs/prices and // sending out notifications or rescheduling the balance check alarm // would be a waste since we'll have to redo them again after all of // our internal state is updated. final boolean updateBalanceCheck = false; stopOngoingActionLocked(mUserId, mPkgName, ongoingEvent.eventId, ongoingEvent.tag, mNowElapsed, mNow, updateBalanceCheck, /* notifyOnAffordabilityChange */ false); noteOngoingEventLocked(mUserId, mPkgName, ongoingEvent.eventId, ongoingEvent.tag, mNowElapsed, updateBalanceCheck); } } private final OngoingEventUpdater mOngoingEventUpdater = new OngoingEventUpdater(); private static final class Package { public final String packageName; public final int userId; Loading Loading @@ -971,9 +995,10 @@ class Agent { note.setNewAffordability(true); return; } note.recalculateModifiedPrice(economicPolicy, userId, pkgName); note.recalculateCosts(economicPolicy, userId, pkgName); note.setNewAffordability( getBalanceLocked(userId, pkgName) >= note.getCachedModifiedPrice()); isAffordableLocked(getBalanceLocked(userId, pkgName), note.getCachedModifiedPrice())); mIrs.postAffordabilityChanged(userId, pkgName, note); // Update ongoing alarm scheduleBalanceCheckLocked(userId, pkgName); Loading Loading @@ -1035,7 +1060,7 @@ class Agent { } @VisibleForTesting long recalculateModifiedPrice(@NonNull EconomicPolicy economicPolicy, long recalculateCosts(@NonNull EconomicPolicy economicPolicy, int userId, @NonNull String pkgName) { long modifiedPrice = 0; final List<EconomyManagerInternal.AnticipatedAction> anticipatedActions = Loading Loading @@ -1099,8 +1124,8 @@ class Agent { for (int i = 0; i < actionAffordabilityNotes.size(); ++i) { final ActionAffordabilityNote note = actionAffordabilityNotes.valueAt(i); final boolean isAffordable = newBalance >= note.getCachedModifiedPrice(); final boolean isAffordable = isAffordableLocked( newBalance, note.getCachedModifiedPrice()); if (note.isCurrentlyAffordable() != isAffordable) { note.setNewAffordability(isAffordable); mIrs.postAffordabilityChanged(userId, pkgName, note); Loading Loading @@ -1155,7 +1180,7 @@ class Agent { pw.print(" runtime="); TimeUtils.formatDuration(nowElapsed - ongoingEvent.startTimeElapsed, pw); pw.print(" delta/sec="); pw.print(ongoingEvent.deltaPerSec); pw.print(narcToString(ongoingEvent.deltaPerSec)); pw.print(" refCount="); pw.print(ongoingEvent.refCount); pw.println(); Loading
services/tests/servicestests/src/com/android/server/tare/AgentTrendCalculatorTest.java +5 −5 Original line number Diff line number Diff line Loading @@ -115,7 +115,7 @@ public class AgentTrendCalculatorTest { new AnticipatedAction(JobSchedulerEconomicPolicy.ACTION_JOB_TIMEOUT, 1, 0))), mock(AffordabilityChangeListener.class), mEconomicPolicy)); for (ActionAffordabilityNote note : affordabilityNotes) { note.recalculateModifiedPrice(mEconomicPolicy, 0, "com.test.app"); note.recalculateCosts(mEconomicPolicy, 0, "com.test.app"); } trendCalculator.reset(1234, affordabilityNotes); Loading Loading @@ -174,7 +174,7 @@ public class AgentTrendCalculatorTest { new AnticipatedAction(JobSchedulerEconomicPolicy.ACTION_JOB_MAX_RUNNING, 0, 1000))), mock(AffordabilityChangeListener.class), mEconomicPolicy)); for (ActionAffordabilityNote note : affordabilityNotes) { note.recalculateModifiedPrice(mEconomicPolicy, 0, "com.test.app"); note.recalculateCosts(mEconomicPolicy, 0, "com.test.app"); } // Balance is already above threshold and events are all positive delta. Loading Loading @@ -222,7 +222,7 @@ public class AgentTrendCalculatorTest { new AnticipatedAction(JobSchedulerEconomicPolicy.ACTION_JOB_MAX_START, 1, 0))), mock(AffordabilityChangeListener.class), mEconomicPolicy)); for (ActionAffordabilityNote note : affordabilityNotes) { note.recalculateModifiedPrice(mEconomicPolicy, 0, "com.test.app"); note.recalculateCosts(mEconomicPolicy, 0, "com.test.app"); } // Balance is below threshold and events are all positive delta. Loading Loading @@ -278,7 +278,7 @@ public class AgentTrendCalculatorTest { new AnticipatedAction(JobSchedulerEconomicPolicy.ACTION_JOB_MIN_START, 1, 0))), mock(AffordabilityChangeListener.class), mEconomicPolicy)); for (ActionAffordabilityNote note : affordabilityNotes) { note.recalculateModifiedPrice(mEconomicPolicy, 0, "com.test.app"); note.recalculateCosts(mEconomicPolicy, 0, "com.test.app"); } // Balance is below threshold and events are all positive delta. Loading Loading @@ -320,7 +320,7 @@ public class AgentTrendCalculatorTest { new AnticipatedAction(AlarmManagerEconomicPolicy.ACTION_ALARM_CLOCK, 1, 0))), mock(AffordabilityChangeListener.class), mEconomicPolicy)); for (ActionAffordabilityNote note : affordabilityNotes) { note.recalculateModifiedPrice(mEconomicPolicy, 0, "com.test.app"); note.recalculateCosts(mEconomicPolicy, 0, "com.test.app"); } // Balance is between both thresholds and events are mixed positive/negative delta. Loading