From 2c8904615a36bcb1e3d5cc2cf3eaa154058ea29d Mon Sep 17 00:00:00 2001 From: Kweku Adams Date: Fri, 30 Jul 2021 14:42:46 -0700 Subject: [PATCH] Add API to get max action duration. Add an API that allows TARE clients to find out the maximum length of time an app can pay for a specific ongoing bill. Bug: 158300259 Test: Android builds Change-Id: Ie6095628b644060b393447762c02c2614ac23aff --- .../server/tare/EconomyManagerInternal.java | 5 +++ .../server/tare/InternalResourceService.java | 36 ++++++++++++++++++- 2 files changed, 40 insertions(+), 1 deletion(-) 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 831c05ff57012..29aa94631d683 100644 --- a/apex/jobscheduler/service/java/com/android/server/tare/EconomyManagerInternal.java +++ b/apex/jobscheduler/service/java/com/android/server/tare/EconomyManagerInternal.java @@ -124,6 +124,11 @@ public interface EconomyManagerInternal { */ boolean canPayFor(int userId, @NonNull String pkgName, @NonNull ActionBill bill); + /** + * Returns the maximum duration (in milliseconds) that the specified app can afford the bill, + * based on current prices. + */ + long getMaxDurationMs(int userId, @NonNull String pkgName, @NonNull ActionBill bill); /** * Register an {@link AffordabilityChangeListener} to track when an app's ability to afford the 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 67d7a95edbb8b..26577b833d7ca 100644 --- a/apex/jobscheduler/service/java/com/android/server/tare/InternalResourceService.java +++ b/apex/jobscheduler/service/java/com/android/server/tare/InternalResourceService.java @@ -104,7 +104,6 @@ public class InternalResourceService extends SystemService { @GuardedBy("mLock") private long mLastUnusedReclamationTime; - @SuppressWarnings("FieldCanBeLocal") private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { @Nullable private String getPackageName(Intent intent) { @@ -514,6 +513,15 @@ public class InternalResourceService extends SystemService { } private final class LocalService implements EconomyManagerInternal { + /** + * Use an extremely large value to indicate that an app can pay for a bill indefinitely. + * The value set here should be large/long enough that there's no reasonable expectation + * of a device operating uninterrupted (or in the exact same state) for that period of time. + * We intentionally don't use Long.MAX_VALUE to avoid potential overflow if a client + * doesn't check the value and just immediately adds it to the current time. + */ + private static final long FOREVER_MS = 27 * 365 * 24 * HOUR_IN_MILLIS; + @Override public void registerAffordabilityChangeListener(int userId, @NonNull String pkgName, @NonNull AffordabilityChangeListener listener, @NonNull ActionBill bill) { @@ -551,6 +559,29 @@ public class InternalResourceService extends SystemService { } } + @Override + public long getMaxDurationMs(int userId, @NonNull String pkgName, + @NonNull ActionBill bill) { + if (!mIsEnabled) { + return FOREVER_MS; + } + long totalCostPerSecond = 0; + final List projectedActions = + bill.getAnticipatedActions(); + for (int i = 0; i < projectedActions.size(); ++i) { + AnticipatedAction action = projectedActions.get(i); + final long cost = + mCompleteEconomicPolicy.getCostOfAction(action.actionId, userId, pkgName); + totalCostPerSecond += cost; + } + if (totalCostPerSecond == 0) { + return FOREVER_MS; + } + synchronized (mLock) { + return mAgent.getBalanceLocked(userId, pkgName) * 1000 / totalCostPerSecond; + } + } + @Override public void noteInstantaneousEvent(int userId, @NonNull String pkgName, int eventId, @Nullable String tag) { @@ -630,6 +661,9 @@ public class InternalResourceService extends SystemService { private void dumpInternal(final IndentingPrintWriter pw) { synchronized (mLock) { + pw.print("Is enabled: "); + pw.println(mIsEnabled); + pw.print("Current battery level: "); pw.println(mCurrentBatteryLevel);