Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit aa7311c9 authored by Kweku Adams's avatar Kweku Adams
Browse files

Fix/simplify app removal code.

1. Remove a remnant of the original implementation that assumed apps
   were holding credits to the detriment of others and needed to be
   added back to the main pool.
2. Operate at the user level when a user is removed to remove
   unnecessary looping.

Bug: 242899307
Test: atest com.android.cts.net.HostsideRestrictBackgroundNetworkTests --use-modules-in
Test: atest frameworks/base/services/tests/mockingservicestests/src/com/android/server/tare
Test: atest frameworks/base/services/tests/servicestests/src/com/android/server/tare
Change-Id: I6b76a0d652af4a1a248ff5cb29526bef0e9d221d
parent b218fd8f
Loading
Loading
Loading
Loading
+4 −23
Original line number Diff line number Diff line
@@ -816,37 +816,18 @@ class Agent {

    @GuardedBy("mLock")
    void onPackageRemovedLocked(final int userId, @NonNull final String pkgName) {
        reclaimAssetsLocked(userId, pkgName);
        mBalanceThresholdAlarmQueue.removeAlarmForKey(new Package(userId, pkgName));
    }

    /**
     * Reclaims any ARCs granted to the app, making them available to other apps. Also deletes the
     * app's ledger and stops any ongoing event tracking.
     */
    @GuardedBy("mLock")
    private void reclaimAssetsLocked(final int userId, @NonNull final String pkgName) {
        final Ledger ledger = mScribe.getLedgerLocked(userId, pkgName);
        if (ledger.getCurrentBalance() != 0) {
            mScribe.adjustRemainingConsumableCakesLocked(-ledger.getCurrentBalance());
        }
        mScribe.discardLedgerLocked(userId, pkgName);
        mCurrentOngoingEvents.delete(userId, pkgName);
        mBalanceThresholdAlarmQueue.removeAlarmForKey(new Package(userId, pkgName));
    }

    @GuardedBy("mLock")
    void onUserRemovedLocked(final int userId, @NonNull final List<String> pkgNames) {
        reclaimAssetsLocked(userId, pkgNames);
    void onUserRemovedLocked(final int userId) {
        mScribe.discardLedgersLocked(userId);
        mCurrentOngoingEvents.delete(userId);
        mBalanceThresholdAlarmQueue.removeAlarmsForUserId(userId);
    }

    @GuardedBy("mLock")
    private void reclaimAssetsLocked(final int userId, @NonNull final List<String> pkgNames) {
        for (int i = 0; i < pkgNames.size(); ++i) {
            reclaimAssetsLocked(userId, pkgNames.get(i));
        }
    }

    @VisibleForTesting
    static class TrendCalculator implements Consumer<OngoingEvent> {
        static final long WILL_NOT_CROSS_THRESHOLD = -1;
+1 −3
Original line number Diff line number Diff line
@@ -576,17 +576,15 @@ public class InternalResourceService extends SystemService {
    void onUserRemoved(final int userId) {
        synchronized (mLock) {
            mVipOverrides.delete(userId);
            ArrayList<String> removedPkgs = new ArrayList<>();
            final int uIdx = mPkgCache.indexOfKey(userId);
            if (uIdx >= 0) {
                for (int p = mPkgCache.numElementsForKeyAt(uIdx) - 1; p >= 0; --p) {
                    final InstalledPackageInfo pkgInfo = mPkgCache.valueAt(uIdx, p);
                    removedPkgs.add(pkgInfo.packageName);
                    mUidToPackageCache.remove(pkgInfo.uid);
                }
            }
            mPkgCache.delete(userId);
            mAgent.onUserRemovedLocked(userId, removedPkgs);
            mAgent.onUserRemovedLocked(userId);
        }
    }

+6 −0
Original line number Diff line number Diff line
@@ -156,6 +156,12 @@ public class Scribe {
        postWrite();
    }

    @GuardedBy("mIrs.getLock()")
    void discardLedgersLocked(final int userId) {
        mLedgers.delete(userId);
        postWrite();
    }

    @GuardedBy("mIrs.getLock()")
    long getSatiatedConsumptionLimitLocked() {
        return mSatiatedConsumptionLimit;
+28 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.server.tare;

import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
import static com.android.server.tare.TareTestUtils.assertLedgersEqual;

import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.anyInt;
@@ -88,6 +89,33 @@ public class AgentTest {
        }
    }

    @Test
    public void testAppRemoval() {
        final long consumptionLimit = 1_000_000L;
        final long remainingCakes = consumptionLimit / 2;
        mScribe.setConsumptionLimitLocked(consumptionLimit);
        mScribe.adjustRemainingConsumableCakesLocked(remainingCakes - consumptionLimit);
        assertEquals(remainingCakes, mScribe.getRemainingConsumableCakesLocked());

        final int userId = 0;
        final String pkgName = "com.test";
        final Agent agent = new Agent(mIrs, mScribe, mAnalyst);
        final Ledger ledger = mScribe.getLedgerLocked(userId, pkgName);

        doReturn(consumptionLimit).when(mIrs).getConsumptionLimitLocked();
        doReturn(consumptionLimit).when(mEconomicPolicy)
                .getMaxSatiatedBalance(anyInt(), anyString());

        Ledger.Transaction transaction = new Ledger.Transaction(0, 0, 0, null, 5, 10);
        agent.recordTransactionLocked(userId, pkgName, ledger, transaction, false);
        assertEquals(5, ledger.getCurrentBalance());
        assertEquals(remainingCakes - 10, mScribe.getRemainingConsumableCakesLocked());

        agent.onPackageRemovedLocked(userId, pkgName);
        assertEquals(remainingCakes - 10, mScribe.getRemainingConsumableCakesLocked());
        assertLedgersEqual(new Ledger(), mScribe.getLedgerLocked(userId, pkgName));
    }

    @Test
    public void testRecordTransaction_UnderMax() {
        Agent agent = new Agent(mIrs, mScribe, mAnalyst);
+1 −63
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.server.tare;

import static com.android.dx.mockito.inline.extended.ExtendedMockito.inOrder;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
import static com.android.server.tare.TareTestUtils.assertLedgersEqual;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
@@ -30,7 +31,6 @@ import android.content.pm.PackageInfo;
import android.os.UserHandle;
import android.util.Log;
import android.util.SparseArrayMap;
import android.util.SparseLongArray;

import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest;
@@ -345,43 +345,6 @@ public class ScribeTest {
        assertEquals(900, mScribeUnderTest.getRemainingConsumableCakesLocked());
    }

    private void assertLedgersEqual(Ledger expected, Ledger actual) {
        if (expected == null) {
            assertNull(actual);
            return;
        }
        assertNotNull(actual);
        assertEquals(expected.getCurrentBalance(), actual.getCurrentBalance());

        List<Ledger.Transaction> expectedTransactions = expected.getTransactions();
        List<Ledger.Transaction> actualTransactions = actual.getTransactions();
        assertEquals(expectedTransactions.size(), actualTransactions.size());
        for (int i = 0; i < expectedTransactions.size(); ++i) {
            assertTransactionsEqual(expectedTransactions.get(i), actualTransactions.get(i));
        }

        List<Ledger.RewardBucket> expectedRewardBuckets = expected.getRewardBuckets();
        List<Ledger.RewardBucket> actualRewardBuckets = actual.getRewardBuckets();
        assertEquals(expectedRewardBuckets.size(), actualRewardBuckets.size());
        for (int i = 0; i < expectedRewardBuckets.size(); ++i) {
            assertRewardBucketsEqual(expectedRewardBuckets.get(i), actualRewardBuckets.get(i));
        }
    }

    private void assertSparseLongArraysEqual(SparseLongArray expected, SparseLongArray actual) {
        if (expected == null) {
            assertNull(actual);
            return;
        }
        assertNotNull(actual);
        final int size = expected.size();
        assertEquals(size, actual.size());
        for (int i = 0; i < size; ++i) {
            assertEquals(expected.keyAt(i), actual.keyAt(i));
            assertEquals(expected.valueAt(i), actual.valueAt(i));
        }
    }

    private void assertReportListsEqual(List<Analyst.Report> expected,
            List<Analyst.Report> actual) {
        if (expected == null) {
@@ -425,31 +388,6 @@ public class ScribeTest {
        }
    }

    private void assertRewardBucketsEqual(Ledger.RewardBucket expected,
            Ledger.RewardBucket actual) {
        if (expected == null) {
            assertNull(actual);
            return;
        }
        assertNotNull(actual);
        assertEquals(expected.startTimeMs, actual.startTimeMs);
        assertSparseLongArraysEqual(expected.cumulativeDelta, actual.cumulativeDelta);
    }

    private void assertTransactionsEqual(Ledger.Transaction expected, Ledger.Transaction actual) {
        if (expected == null) {
            assertNull(actual);
            return;
        }
        assertNotNull(actual);
        assertEquals(expected.startTimeMs, actual.startTimeMs);
        assertEquals(expected.endTimeMs, actual.endTimeMs);
        assertEquals(expected.eventId, actual.eventId);
        assertEquals(expected.tag, actual.tag);
        assertEquals(expected.delta, actual.delta);
        assertEquals(expected.ctp, actual.ctp);
    }

    private void addInstalledPackage(int userId, String pkgName) {
        PackageInfo pkgInfo = new PackageInfo();
        pkgInfo.packageName = pkgName;
Loading