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 8b8a57d248b95..66dc08dd7a46a 100644 --- a/apex/jobscheduler/service/java/com/android/server/tare/Agent.java +++ b/apex/jobscheduler/service/java/com/android/server/tare/Agent.java @@ -34,8 +34,6 @@ import static com.android.server.tare.TareUtils.getCurrentTimeMillis; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Context; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageInfo; import android.os.Handler; import android.os.Looper; import android.os.Message; @@ -606,13 +604,12 @@ class Agent { } /** Returns true if an app should be given credits in the general distributions. */ - private boolean shouldGiveCredits(@NonNull PackageInfo packageInfo) { - final ApplicationInfo applicationInfo = packageInfo.applicationInfo; + private boolean shouldGiveCredits(@NonNull InstalledPackageInfo packageInfo) { // Skip apps that wouldn't be doing any work. Giving them ARCs would be wasteful. - if (applicationInfo == null || !applicationInfo.hasCode()) { + if (!packageInfo.hasCode) { return false; } - final int userId = UserHandle.getUserId(packageInfo.applicationInfo.uid); + final int userId = UserHandle.getUserId(packageInfo.uid); // No point allocating ARCs to the system. It can do whatever it wants. return !mIrs.isSystem(userId, packageInfo.packageName); } @@ -623,15 +620,15 @@ class Agent { @GuardedBy("mLock") void distributeBasicIncomeLocked(int batteryLevel) { - List pkgs = mIrs.getInstalledPackages(); + final List pkgs = mIrs.getInstalledPackages(); final long now = getCurrentTimeMillis(); for (int i = 0; i < pkgs.size(); ++i) { - final PackageInfo pkgInfo = pkgs.get(i); + final InstalledPackageInfo pkgInfo = pkgs.get(i); if (!shouldGiveCredits(pkgInfo)) { continue; } - final int userId = UserHandle.getUserId(pkgInfo.applicationInfo.uid); + final int userId = UserHandle.getUserId(pkgInfo.uid); final String pkgName = pkgInfo.packageName; final Ledger ledger = mScribe.getLedgerLocked(userId, pkgName); final long minBalance = mIrs.getMinBalanceLocked(userId, pkgName); @@ -659,11 +656,11 @@ class Agent { @GuardedBy("mLock") void grantBirthrightsLocked(final int userId) { - final List pkgs = mIrs.getInstalledPackages(userId); + final List pkgs = mIrs.getInstalledPackages(userId); final long now = getCurrentTimeMillis(); for (int i = 0; i < pkgs.size(); ++i) { - final PackageInfo packageInfo = pkgs.get(i); + final InstalledPackageInfo packageInfo = pkgs.get(i); if (!shouldGiveCredits(packageInfo)) { continue; } diff --git a/apex/jobscheduler/service/java/com/android/server/tare/InstalledPackageInfo.java b/apex/jobscheduler/service/java/com/android/server/tare/InstalledPackageInfo.java new file mode 100644 index 0000000000000..da544bb6a2eb6 --- /dev/null +++ b/apex/jobscheduler/service/java/com/android/server/tare/InstalledPackageInfo.java @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.tare; + +import android.annotation.NonNull; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageInfo; +import android.os.UserHandle; + +/** POJO to cache only the information about installed packages that TARE cares about. */ +class InstalledPackageInfo { + static final int NO_UID = -1; + + public final int uid; + public final String packageName; + public final boolean hasCode; + + InstalledPackageInfo(@NonNull PackageInfo packageInfo) { + final ApplicationInfo applicationInfo = packageInfo.applicationInfo; + this.uid = applicationInfo == null ? NO_UID : applicationInfo.uid; + this.packageName = packageInfo.packageName; + this.hasCode = applicationInfo != null && applicationInfo.hasCode(); + } +} 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 6d5c16021ea93..e9270bffec65b 100644 --- a/apex/jobscheduler/service/java/com/android/server/tare/InternalResourceService.java +++ b/apex/jobscheduler/service/java/com/android/server/tare/InternalResourceService.java @@ -131,7 +131,7 @@ public class InternalResourceService extends SystemService { @NonNull @GuardedBy("mLock") - private final List mPkgCache = new ArrayList<>(); + private final List mPkgCache = new ArrayList<>(); /** Cached mapping of UIDs (for all users) to a list of packages in the UID. */ @GuardedBy("mLock") @@ -303,7 +303,7 @@ public class InternalResourceService extends SystemService { } @NonNull - List getInstalledPackages() { + List getInstalledPackages() { synchronized (mLock) { return mPkgCache; } @@ -311,13 +311,12 @@ public class InternalResourceService extends SystemService { /** Returns the installed packages for the specified user. */ @NonNull - List getInstalledPackages(final int userId) { - final List userPkgs = new ArrayList<>(); + List getInstalledPackages(final int userId) { + final List userPkgs = new ArrayList<>(); synchronized (mLock) { for (int i = 0; i < mPkgCache.size(); ++i) { - final PackageInfo packageInfo = mPkgCache.get(i); - if (packageInfo.applicationInfo != null - && UserHandle.getUserId(packageInfo.applicationInfo.uid) == userId) { + final InstalledPackageInfo packageInfo = mPkgCache.get(i); + if (UserHandle.getUserId(packageInfo.uid) == userId) { userPkgs.add(packageInfo); } } @@ -451,7 +450,7 @@ public class InternalResourceService extends SystemService { mPackageToUidCache.add(userId, pkgName, uid); } synchronized (mLock) { - mPkgCache.add(packageInfo); + mPkgCache.add(new InstalledPackageInfo(packageInfo)); mUidToPackageCache.add(uid, pkgName); // TODO: only do this when the user first launches the app (app leaves stopped state) mAgent.grantBirthrightLocked(userId, pkgName); @@ -472,8 +471,8 @@ public class InternalResourceService extends SystemService { synchronized (mLock) { mUidToPackageCache.remove(uid, pkgName); for (int i = 0; i < mPkgCache.size(); ++i) { - PackageInfo pkgInfo = mPkgCache.get(i); - if (UserHandle.getUserId(pkgInfo.applicationInfo.uid) == userId + final InstalledPackageInfo pkgInfo = mPkgCache.get(i); + if (UserHandle.getUserId(pkgInfo.uid) == userId && pkgName.equals(pkgInfo.packageName)) { mPkgCache.remove(i); break; @@ -496,8 +495,11 @@ public class InternalResourceService extends SystemService { void onUserAdded(final int userId) { synchronized (mLock) { - mPkgCache.addAll( - mPackageManager.getInstalledPackagesAsUser(PACKAGE_QUERY_FLAGS, userId)); + final List pkgs = + mPackageManager.getInstalledPackagesAsUser(PACKAGE_QUERY_FLAGS, userId); + for (int i = pkgs.size() - 1; i >= 0; --i) { + mPkgCache.add(new InstalledPackageInfo(pkgs.get(i))); + } mAgent.grantBirthrightsLocked(userId); } } @@ -506,10 +508,10 @@ public class InternalResourceService extends SystemService { synchronized (mLock) { ArrayList removedPkgs = new ArrayList<>(); for (int i = mPkgCache.size() - 1; i >= 0; --i) { - PackageInfo pkgInfo = mPkgCache.get(i); - if (UserHandle.getUserId(pkgInfo.applicationInfo.uid) == userId) { + final InstalledPackageInfo pkgInfo = mPkgCache.get(i); + if (UserHandle.getUserId(pkgInfo.uid) == userId) { removedPkgs.add(pkgInfo.packageName); - mUidToPackageCache.remove(pkgInfo.applicationInfo.uid); + mUidToPackageCache.remove(pkgInfo.uid); mPkgCache.remove(i); break; } @@ -659,8 +661,11 @@ public class InternalResourceService extends SystemService { LocalServices.getService(UserManagerInternal.class); final int[] userIds = userManagerInternal.getUserIds(); for (int userId : userIds) { - mPkgCache.addAll( - mPackageManager.getInstalledPackagesAsUser(PACKAGE_QUERY_FLAGS, userId)); + final List pkgs = + mPackageManager.getInstalledPackagesAsUser(PACKAGE_QUERY_FLAGS, userId); + for (int i = pkgs.size() - 1; i >= 0; --i) { + mPkgCache.add(new InstalledPackageInfo(pkgs.get(i))); + } } } diff --git a/apex/jobscheduler/service/java/com/android/server/tare/Scribe.java b/apex/jobscheduler/service/java/com/android/server/tare/Scribe.java index 8f7657e6c4149..ed915cd88ebeb 100644 --- a/apex/jobscheduler/service/java/com/android/server/tare/Scribe.java +++ b/apex/jobscheduler/service/java/com/android/server/tare/Scribe.java @@ -22,7 +22,6 @@ import static com.android.server.tare.TareUtils.appToString; import android.annotation.NonNull; import android.annotation.Nullable; -import android.content.pm.PackageInfo; import android.os.Environment; import android.os.UserHandle; import android.util.ArraySet; @@ -210,11 +209,11 @@ public class Scribe { mRemainingConsumableCakes = 0; final SparseArray> installedPackagesPerUser = new SparseArray<>(); - final List installedPackages = mIrs.getInstalledPackages(); + final List installedPackages = mIrs.getInstalledPackages(); for (int i = 0; i < installedPackages.size(); ++i) { - final PackageInfo packageInfo = installedPackages.get(i); - if (packageInfo.applicationInfo != null) { - final int userId = UserHandle.getUserId(packageInfo.applicationInfo.uid); + final InstalledPackageInfo packageInfo = installedPackages.get(i); + if (packageInfo.uid != InstalledPackageInfo.NO_UID) { + final int userId = UserHandle.getUserId(packageInfo.uid); ArraySet pkgsForUser = installedPackagesPerUser.get(userId); if (pkgsForUser == null) { pkgsForUser = new ArraySet<>(); diff --git a/services/tests/mockingservicestests/src/com/android/server/tare/ScribeTest.java b/services/tests/mockingservicestests/src/com/android/server/tare/ScribeTest.java index 13510adbb9603..d90d8b8bfac0f 100644 --- a/services/tests/mockingservicestests/src/com/android/server/tare/ScribeTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/tare/ScribeTest.java @@ -68,7 +68,7 @@ public class ScribeTest { private MockitoSession mMockingSession; private Scribe mScribeUnderTest; private File mTestFileDir; - private final List mInstalledPackages = new ArrayList<>(); + private final List mInstalledPackages = new ArrayList<>(); private final List mReports = new ArrayList<>(); @Mock @@ -455,6 +455,6 @@ public class ScribeTest { ApplicationInfo applicationInfo = new ApplicationInfo(); applicationInfo.uid = UserHandle.getUid(userId, Math.abs(pkgName.hashCode())); pkgInfo.applicationInfo = applicationInfo; - mInstalledPackages.add(pkgInfo); + mInstalledPackages.add(new InstalledPackageInfo(pkgInfo)); } }