diff --git a/services/core/java/com/android/server/utils/quota/CountQuotaTracker.java b/services/core/java/com/android/server/utils/quota/CountQuotaTracker.java index b77df2d188596..9bf046cdaf215 100644 --- a/services/core/java/com/android/server/utils/quota/CountQuotaTracker.java +++ b/services/core/java/com/android/server/utils/quota/CountQuotaTracker.java @@ -27,7 +27,6 @@ import android.content.Context; import android.os.Handler; import android.os.Looper; import android.os.Message; -import android.os.UserHandle; import android.util.ArrayMap; import android.util.LongArrayQueue; import android.util.Slog; @@ -294,12 +293,11 @@ public class CountQuotaTracker extends QuotaTracker { @Override @GuardedBy("mLock") - void handleRemovedAppLocked(String packageName, int uid) { + void handleRemovedAppLocked(final int userId, @NonNull String packageName) { if (packageName == null) { Slog.wtf(TAG, "Told app removed but given null package name."); return; } - final int userId = UserHandle.getUserId(uid); mEventTimes.delete(userId, packageName); mExecutionStatsCache.delete(userId, packageName); diff --git a/services/core/java/com/android/server/utils/quota/MultiRateLimiter.java b/services/core/java/com/android/server/utils/quota/MultiRateLimiter.java index 82c6d01056fda..a8daa3ba07a26 100644 --- a/services/core/java/com/android/server/utils/quota/MultiRateLimiter.java +++ b/services/core/java/com/android/server/utils/quota/MultiRateLimiter.java @@ -19,8 +19,6 @@ package com.android.server.utils.quota; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Context; -import android.content.pm.PackageManager; -import android.util.Slog; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; @@ -57,11 +55,9 @@ public class MultiRateLimiter { private final Object mLock = new Object(); @GuardedBy("mLock") private final CountQuotaTracker[] mQuotaTrackers; - private final PackageManager mPackageManager; - private MultiRateLimiter(List quotaTrackers, PackageManager packageManager) { + private MultiRateLimiter(List quotaTrackers) { mQuotaTrackers = quotaTrackers.toArray(EMPTY_TRACKER_ARRAY); - mPackageManager = packageManager; } /** Record that an event happened and count it towards the given quota. */ @@ -105,17 +101,11 @@ public class MultiRateLimiter { @GuardedBy("mLock") private void clearLocked(int userId, @NonNull String packageName) { - try { - int uid = mPackageManager.getApplicationInfoAsUser(packageName, 0, userId).uid; - for (CountQuotaTracker quotaTracker : mQuotaTrackers) { - // This method behaves as if the package has been removed from the device, which - // isn't the case here, but it does similar clean-up to what we are aiming for here, - // so it works for this use case. - quotaTracker.onAppRemovedLocked(packageName, uid); - } - } catch (PackageManager.NameNotFoundException e) { - Slog.e(TAG, "clear(userId, packageName) called with unrecognized arguments, no " - + "action taken"); + for (CountQuotaTracker quotaTracker : mQuotaTrackers) { + // This method behaves as if the package has been removed from the device, which + // isn't the case here, but it does similar clean-up to what we are aiming for here, + // so it works for this use case. + quotaTracker.onAppRemovedLocked(userId, packageName); } } @@ -126,7 +116,8 @@ public class MultiRateLimiter { private final Context mContext; private final Categorizer mCategorizer; private final Category mCategory; - @Nullable private final QuotaTracker.Injector mInjector; + @Nullable + private final QuotaTracker.Injector mInjector; /** * Creates a new builder and allows to inject an object that can be used @@ -149,7 +140,7 @@ public class MultiRateLimiter { /** * Adds another rate limit to be used in {@link MultiRateLimiter}. * - * @param limit The maximum event count an app can have in the rolling time window. + * @param limit The maximum event count an app can have in the rolling time window. * @param windowSize The rolling time window to use when checking quota usage. */ public Builder addRateLimit(int limit, Duration windowSize) { @@ -182,7 +173,7 @@ public class MultiRateLimiter { * limit. */ public MultiRateLimiter build() { - return new MultiRateLimiter(mQuotaTrackers, mContext.getPackageManager()); + return new MultiRateLimiter(mQuotaTrackers); } } @@ -192,7 +183,7 @@ public class MultiRateLimiter { public final Duration mWindowSize; /** - * @param limit The maximum count of some occurrence in the rolling time window. + * @param limit The maximum count of some occurrence in the rolling time window. * @param windowSize The rolling time window to use when checking quota usage. */ private RateLimit(int limit, Duration windowSize) { @@ -201,7 +192,7 @@ public class MultiRateLimiter { } /** - * @param limit The maximum count of some occurrence in the rolling time window. + * @param limit The maximum count of some occurrence in the rolling time window. * @param windowSize The rolling time window to use when checking quota usage. */ public static RateLimit create(int limit, Duration windowSize) { diff --git a/services/core/java/com/android/server/utils/quota/QuotaTracker.java b/services/core/java/com/android/server/utils/quota/QuotaTracker.java index 673862cc18e52..802ab5b156c83 100644 --- a/services/core/java/com/android/server/utils/quota/QuotaTracker.java +++ b/services/core/java/com/android/server/utils/quota/QuotaTracker.java @@ -132,7 +132,7 @@ abstract class QuotaTracker { case Intent.ACTION_PACKAGE_FULLY_REMOVED: final int uid = intent.getIntExtra(Intent.EXTRA_UID, -1); synchronized (mLock) { - onAppRemovedLocked(getPackageName(intent), uid); + onAppRemovedLocked(UserHandle.getUserId(uid), getPackageName(intent)); } break; case Intent.ACTION_USER_REMOVED: @@ -358,21 +358,20 @@ abstract class QuotaTracker { } @GuardedBy("mLock") - abstract void handleRemovedAppLocked(String packageName, int uid); + abstract void handleRemovedAppLocked(int userId, @NonNull String packageName); @GuardedBy("mLock") - void onAppRemovedLocked(String packageName, int uid) { + void onAppRemovedLocked(final int userId, @NonNull String packageName) { if (packageName == null) { Slog.wtf(TAG, "Told app removed but given null package name."); return; } - final int userId = UserHandle.getUserId(uid); mInQuotaAlarmListener.removeAlarmsLocked(userId, packageName); mFreeQuota.delete(userId, packageName); - handleRemovedAppLocked(packageName, uid); + handleRemovedAppLocked(userId, packageName); } @GuardedBy("mLock") diff --git a/services/tests/mockingservicestests/src/com/android/server/utils/quota/MultiRateLimiterTest.java b/services/tests/mockingservicestests/src/com/android/server/utils/quota/MultiRateLimiterTest.java index ab86e19c4a564..adeb44b362934 100644 --- a/services/tests/mockingservicestests/src/com/android/server/utils/quota/MultiRateLimiterTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/utils/quota/MultiRateLimiterTest.java @@ -16,29 +16,15 @@ package com.android.server.utils.quota; -import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; -import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession; - import static com.google.common.truth.Truth.assertThat; -import static org.mockito.Mockito.when; - -import android.content.ContextWrapper; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageManager; -import android.os.UserHandle; import android.testing.TestableContext; import androidx.test.InstrumentationRegistry; import androidx.test.filters.SmallTest; -import org.junit.After; -import org.junit.Before; import org.junit.Rule; import org.junit.Test; -import org.mockito.Mock; -import org.mockito.MockitoSession; -import org.mockito.quality.Strictness; import java.time.Duration; @@ -46,20 +32,15 @@ import java.time.Duration; public class MultiRateLimiterTest { private static final int USER_ID = 1; - private static final int UID_1 = 10_001; private static final String PACKAGE_NAME_1 = "com.android.package.one"; private static final String PACKAGE_NAME_2 = "com.android.package.two"; private static final String TAG = "tag"; @Rule - public final TestableContext mTestableContext = + public final TestableContext mContext = new TestableContext(InstrumentationRegistry.getContext(), null); private final InjectorForTest mInjector = new InjectorForTest(); - private MockitoSession mMockingSession; - private ContextWrapper mContext; - - @Mock private PackageManager mPackageManager; private static class InjectorForTest extends QuotaTracker.Injector { Duration mElapsedTime = Duration.ZERO; @@ -75,38 +56,9 @@ public class MultiRateLimiterTest { } } - @Before - public void setup() throws Exception { - mMockingSession = mockitoSession() - .initMocks(this) - .strictness(Strictness.LENIENT) - .mockStatic(UserHandle.class) - .startMocking(); - doReturn(USER_ID).when(() -> UserHandle.getUserId(UID_1)); - - ApplicationInfo applicationInfo = new ApplicationInfo(); - applicationInfo.uid = UID_1; - when(mPackageManager.getApplicationInfoAsUser(PACKAGE_NAME_1, 0, USER_ID)) - .thenReturn(applicationInfo); - - mContext = new ContextWrapper(mTestableContext) { - @Override - public PackageManager getPackageManager() { - return mPackageManager; - } - }; - } - - @After - public void tearDown() { - if (mMockingSession != null) { - mMockingSession.finishMocking(); - } - } - @Test public void testSingleRateLimit_belowLimit_isWithinQuota() { - MultiRateLimiter multiRateLimiter = new MultiRateLimiter.Builder(mContext, mInjector) + MultiRateLimiter multiRateLimiter = new MultiRateLimiter.Builder(mContext, mInjector) .addRateLimit(3, Duration.ofSeconds(20)) .build(); @@ -125,7 +77,7 @@ public class MultiRateLimiterTest { @Test public void testSingleRateLimit_aboveLimit_isNotWithinQuota() { - MultiRateLimiter multiRateLimiter = new MultiRateLimiter.Builder(mContext, mInjector) + MultiRateLimiter multiRateLimiter = new MultiRateLimiter.Builder(mContext, mInjector) .addRateLimit(3, Duration.ofSeconds(20)) .build(); @@ -145,7 +97,7 @@ public class MultiRateLimiterTest { @Test public void testSingleRateLimit_afterGoingAboveQuotaAndWaitingWindow_isBackWithinQuota() { - MultiRateLimiter multiRateLimiter = new MultiRateLimiter.Builder(mContext, mInjector) + MultiRateLimiter multiRateLimiter = new MultiRateLimiter.Builder(mContext, mInjector) .addRateLimit(3, Duration.ofSeconds(20)) .build(); @@ -214,7 +166,7 @@ public class MultiRateLimiterTest { @Test public void createSingleRateLimit_testItLimitsOnlyGivenUptc() { - MultiRateLimiter multiRateLimiter = new MultiRateLimiter.Builder(mContext, mInjector) + MultiRateLimiter multiRateLimiter = new MultiRateLimiter.Builder(mContext, mInjector) .addRateLimit(3, Duration.ofSeconds(20)) .build(); @@ -245,7 +197,7 @@ public class MultiRateLimiterTest { @Test public void clearRateLimiterForPackage_afterReachingQuota_quotaIsReset() { - MultiRateLimiter multiRateLimiter = new MultiRateLimiter.Builder(mContext, mInjector) + MultiRateLimiter multiRateLimiter = new MultiRateLimiter.Builder(mContext, mInjector) .addRateLimit(1, Duration.ofSeconds(100)) .build(); @@ -270,7 +222,7 @@ public class MultiRateLimiterTest { @Test public void clearRateLimiterForPackage_doesntAffectOtherPackages() { - MultiRateLimiter multiRateLimiter = new MultiRateLimiter.Builder(mContext, mInjector) + MultiRateLimiter multiRateLimiter = new MultiRateLimiter.Builder(mContext, mInjector) .addRateLimit(1, Duration.ofSeconds(100)) .build();