summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apex/jobscheduler/service/java/com/android/server/tare/Agent.java19
-rw-r--r--apex/jobscheduler/service/java/com/android/server/tare/InternalResourceService.java8
-rw-r--r--apex/jobscheduler/service/java/com/android/server/tare/Ledger.java5
-rw-r--r--apex/jobscheduler/service/java/com/android/server/tare/TareUtils.java10
-rw-r--r--services/tests/servicestests/src/com/android/server/tare/LedgerTest.java53
5 files changed, 81 insertions, 14 deletions
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 74ed334df897..59c9c7e943ab 100644
--- a/apex/jobscheduler/service/java/com/android/server/tare/Agent.java
+++ b/apex/jobscheduler/service/java/com/android/server/tare/Agent.java
@@ -26,6 +26,7 @@ import static com.android.server.tare.EconomicPolicy.TYPE_ACTION;
import static com.android.server.tare.EconomicPolicy.TYPE_REWARD;
import static com.android.server.tare.EconomicPolicy.eventToString;
import static com.android.server.tare.EconomicPolicy.getEventType;
+import static com.android.server.tare.TareUtils.getCurrentTimeMillis;
import static com.android.server.tare.TareUtils.narcToString;
import android.annotation.NonNull;
@@ -183,7 +184,7 @@ class Agent {
mCurrentOngoingEvents.get(userId, pkgName);
if (ongoingEvents != null) {
final long nowElapsed = SystemClock.elapsedRealtime();
- final long now = System.currentTimeMillis();
+ final long now = getCurrentTimeMillis();
mTotalDeltaCalculator.reset(ledger, nowElapsed, now);
ongoingEvents.forEach(mTotalDeltaCalculator);
balance += mTotalDeltaCalculator.mTotal;
@@ -194,7 +195,7 @@ class Agent {
@GuardedBy("mLock")
void noteInstantaneousEventLocked(final int userId, @NonNull final String pkgName,
final int eventId, @Nullable String tag) {
- final long now = System.currentTimeMillis();
+ final long now = getCurrentTimeMillis();
final Ledger ledger = getLedgerLocked(userId, pkgName);
final int eventType = getEventType(eventId);
@@ -278,7 +279,7 @@ class Agent {
@GuardedBy("mLock")
void onDeviceStateChangedLocked() {
- final long now = System.currentTimeMillis();
+ final long now = getCurrentTimeMillis();
final long nowElapsed = SystemClock.elapsedRealtime();
mCurrentOngoingEvents.forEach((userId, pkgName, ongoingEvents) -> {
@@ -326,7 +327,7 @@ class Agent {
@GuardedBy("mLock")
void onAppStatesChangedLocked(final int userId, @NonNull ArraySet<String> pkgNames) {
- final long now = System.currentTimeMillis();
+ final long now = getCurrentTimeMillis();
final long nowElapsed = SystemClock.elapsedRealtime();
for (int i = 0; i < pkgNames.size(); ++i) {
@@ -477,7 +478,7 @@ class Agent {
// The earliest transaction won't change until we clean up the ledger, so no point
// continuing to reschedule an existing cleanup.
final long cleanupAlarmElapsed = SystemClock.elapsedRealtime() + MAX_TRANSACTION_AGE_MS
- - (System.currentTimeMillis() - ledger.getEarliestTransaction().endTimeMs);
+ - (getCurrentTimeMillis() - ledger.getEarliestTransaction().endTimeMs);
mLedgerCleanupAlarmListener.addAlarmLocked(userId, pkgName, cleanupAlarmElapsed);
}
// TODO: save changes to disk in a background thread
@@ -509,7 +510,7 @@ class Agent {
@GuardedBy("mLock")
void reclaimUnusedAssetsLocked(double percentage) {
final List<PackageInfo> pkgs = mIrs.getInstalledPackages();
- final long now = System.currentTimeMillis();
+ final long now = getCurrentTimeMillis();
for (int i = 0; i < pkgs.size(); ++i) {
final int userId = UserHandle.getUserId(pkgs.get(i).applicationInfo.uid);
final String pkgName = pkgs.get(i).packageName;
@@ -543,7 +544,7 @@ class Agent {
@GuardedBy("mLock")
void distributeBasicIncomeLocked(int batteryLevel) {
List<PackageInfo> pkgs = mIrs.getInstalledPackages();
- final long now = System.currentTimeMillis();
+ final long now = getCurrentTimeMillis();
for (int i = 0; i < pkgs.size(); ++i) {
final PackageInfo pkgInfo = pkgs.get(i);
final int userId = UserHandle.getUserId(pkgInfo.applicationInfo.uid);
@@ -578,7 +579,7 @@ class Agent {
List<PackageInfo> pkgs = packageManager.getInstalledPackagesAsUser(0, userId);
final long maxBirthright =
mIrs.getMaxCirculationLocked() / mIrs.getInstalledPackages().size();
- final long now = System.currentTimeMillis();
+ final long now = getCurrentTimeMillis();
for (int i = 0; i < pkgs.size(); ++i) {
final PackageInfo packageInfo = pkgs.get(i);
@@ -609,7 +610,7 @@ class Agent {
List<PackageInfo> pkgs = mIrs.getInstalledPackages();
final int numPackages = pkgs.size();
final long maxBirthright = mIrs.getMaxCirculationLocked() / numPackages;
- final long now = System.currentTimeMillis();
+ final long now = getCurrentTimeMillis();
recordTransactionLocked(userId, pkgName, ledger,
new Ledger.Transaction(now, now, REGULATION_BIRTHRIGHT, null,
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 26577b833d7c..aa11add587af 100644
--- a/apex/jobscheduler/service/java/com/android/server/tare/InternalResourceService.java
+++ b/apex/jobscheduler/service/java/com/android/server/tare/InternalResourceService.java
@@ -19,6 +19,8 @@ package com.android.server.tare;
import static android.text.format.DateUtils.HOUR_IN_MILLIS;
import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
+import static com.android.server.tare.TareUtils.getCurrentTimeMillis;
+
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.AlarmManager;
@@ -158,7 +160,7 @@ public class InternalResourceService extends SystemService {
public void onAlarm() {
synchronized (mLock) {
mAgent.reclaimUnusedAssetsLocked(DEFAULT_UNUSED_RECLAMATION_PERCENTAGE);
- mLastUnusedReclamationTime = System.currentTimeMillis();
+ mLastUnusedReclamationTime = getCurrentTimeMillis();
scheduleUnusedWealthReclamationLocked();
}
}
@@ -341,7 +343,7 @@ public class InternalResourceService extends SystemService {
@GuardedBy("mLock")
private void scheduleUnusedWealthReclamationLocked() {
- final long now = System.currentTimeMillis();
+ final long now = getCurrentTimeMillis();
final long nextReclamationTime =
Math.max(mLastUnusedReclamationTime + UNUSED_RECLAMATION_PERIOD_MS, now + 30_000);
mHandler.post(() -> {
@@ -612,7 +614,7 @@ public class InternalResourceService extends SystemService {
return;
}
final long nowElapsed = SystemClock.elapsedRealtime();
- final long now = System.currentTimeMillis();
+ final long now = getCurrentTimeMillis();
synchronized (mLock) {
mAgent.stopOngoingActionLocked(userId, pkgName, eventId, tag, nowElapsed, now);
}
diff --git a/apex/jobscheduler/service/java/com/android/server/tare/Ledger.java b/apex/jobscheduler/service/java/com/android/server/tare/Ledger.java
index ae1bf26f36f2..76543d74f15e 100644
--- a/apex/jobscheduler/service/java/com/android/server/tare/Ledger.java
+++ b/apex/jobscheduler/service/java/com/android/server/tare/Ledger.java
@@ -19,6 +19,7 @@ package com.android.server.tare;
import static android.text.format.DateUtils.HOUR_IN_MILLIS;
import static com.android.server.tare.TareUtils.dumpTime;
+import static com.android.server.tare.TareUtils.getCurrentTimeMillis;
import static com.android.server.tare.TareUtils.narcToString;
import android.annotation.NonNull;
@@ -109,8 +110,8 @@ class Ledger {
/** Deletes transactions that are older than {@code minAgeMs}. */
void removeOldTransactions(long minAgeMs) {
- final long cutoff = System.currentTimeMillis() - minAgeMs;
- while (mTransactions.get(0).endTimeMs <= cutoff) {
+ final long cutoff = getCurrentTimeMillis() - minAgeMs;
+ while (mTransactions.size() > 0 && mTransactions.get(0).endTimeMs <= cutoff) {
mTransactions.remove(0);
}
}
diff --git a/apex/jobscheduler/service/java/com/android/server/tare/TareUtils.java b/apex/jobscheduler/service/java/com/android/server/tare/TareUtils.java
index 2d72f5688688..3c79bb3a796d 100644
--- a/apex/jobscheduler/service/java/com/android/server/tare/TareUtils.java
+++ b/apex/jobscheduler/service/java/com/android/server/tare/TareUtils.java
@@ -20,7 +20,10 @@ import android.annotation.NonNull;
import android.annotation.SuppressLint;
import android.util.IndentingPrintWriter;
+import com.android.internal.annotations.VisibleForTesting;
+
import java.text.SimpleDateFormat;
+import java.time.Clock;
class TareUtils {
private static final long NARC_IN_ARC = 1_000_000_000L;
@@ -29,6 +32,9 @@ class TareUtils {
private static final SimpleDateFormat sDumpDateFormat =
new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
+ @VisibleForTesting
+ static Clock sSystemClock = Clock.systemUTC();
+
static long arcToNarc(int arcs) {
return arcs * NARC_IN_ARC;
}
@@ -37,6 +43,10 @@ class TareUtils {
pw.print(sDumpDateFormat.format(time));
}
+ static long getCurrentTimeMillis() {
+ return sSystemClock.millis();
+ }
+
static int narcToArc(long narcs) {
return (int) (narcs / NARC_IN_ARC);
}
diff --git a/services/tests/servicestests/src/com/android/server/tare/LedgerTest.java b/services/tests/servicestests/src/com/android/server/tare/LedgerTest.java
index 65a97596cd73..4a253234b59e 100644
--- a/services/tests/servicestests/src/com/android/server/tare/LedgerTest.java
+++ b/services/tests/servicestests/src/com/android/server/tare/LedgerTest.java
@@ -19,19 +19,31 @@ package com.android.server.tare;
import static android.text.format.DateUtils.HOUR_IN_MILLIS;
import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
+import static com.android.server.tare.TareUtils.getCurrentTimeMillis;
+
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
+import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import java.time.Clock;
+import java.time.ZoneOffset;
+
/** Test that the ledger records transactions correctly. */
@RunWith(AndroidJUnit4.class)
@SmallTest
public class LedgerTest {
+ @Before
+ public void setUp() {
+ TareUtils.sSystemClock = Clock.fixed(Clock.systemUTC().instant(), ZoneOffset.UTC);
+ }
+
@Test
public void testInitialState() {
final Ledger ledger = new Ledger();
@@ -72,4 +84,45 @@ public class LedgerTest {
assertEquals(1, ledger.get24HourSum(1, 27 * HOUR_IN_MILLIS));
assertEquals(0, ledger.get24HourSum(1, 28 * HOUR_IN_MILLIS));
}
+
+ @Test
+ public void testRemoveOldTransactions() {
+ final Ledger ledger = new Ledger();
+ ledger.removeOldTransactions(24 * HOUR_IN_MILLIS);
+ assertNull(ledger.getEarliestTransaction());
+
+ final long now = getCurrentTimeMillis();
+ Ledger.Transaction transaction1 = new Ledger.Transaction(
+ now - 48 * HOUR_IN_MILLIS, now - 40 * HOUR_IN_MILLIS, 1, null, 4800);
+ Ledger.Transaction transaction2 = new Ledger.Transaction(
+ now - 24 * HOUR_IN_MILLIS, now - 23 * HOUR_IN_MILLIS, 1, null, 600);
+ Ledger.Transaction transaction3 = new Ledger.Transaction(
+ now - 22 * HOUR_IN_MILLIS, now - 21 * HOUR_IN_MILLIS, 1, null, 600);
+ // Instant event
+ Ledger.Transaction transaction4 = new Ledger.Transaction(
+ now - 20 * HOUR_IN_MILLIS, now - 20 * HOUR_IN_MILLIS, 1, null, 500);
+ // Recent event
+ Ledger.Transaction transaction5 = new Ledger.Transaction(
+ now - 5 * MINUTE_IN_MILLIS, now - MINUTE_IN_MILLIS, 1, null, 400);
+ ledger.recordTransaction(transaction1);
+ ledger.recordTransaction(transaction2);
+ ledger.recordTransaction(transaction3);
+ ledger.recordTransaction(transaction4);
+ ledger.recordTransaction(transaction5);
+
+ assertEquals(transaction1, ledger.getEarliestTransaction());
+ ledger.removeOldTransactions(24 * HOUR_IN_MILLIS);
+ assertEquals(transaction2, ledger.getEarliestTransaction());
+ ledger.removeOldTransactions(23 * HOUR_IN_MILLIS);
+ assertEquals(transaction3, ledger.getEarliestTransaction());
+ // Shouldn't delete transaction3 yet since there's still a piece of it within the min age
+ // window.
+ ledger.removeOldTransactions(21 * HOUR_IN_MILLIS + 30 * MINUTE_IN_MILLIS);
+ assertEquals(transaction3, ledger.getEarliestTransaction());
+ // Instant event should be removed as soon as we hit the exact threshold.
+ ledger.removeOldTransactions(20 * HOUR_IN_MILLIS);
+ assertEquals(transaction5, ledger.getEarliestTransaction());
+ ledger.removeOldTransactions(0);
+ assertNull(ledger.getEarliestTransaction());
+ }
}