Reduce package cache memory usage.
Only retain the information TARE cares about so we don't waste memory. The cache serves to reduce the number of calls to PackageManager, especially while the device is charging. Bug: 239951405 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: I9e345cc3a88c192e00d401a93cbbe0df74f1596b
This commit is contained in:
@@ -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<PackageInfo> pkgs = mIrs.getInstalledPackages();
|
||||
final List<InstalledPackageInfo> 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<PackageInfo> pkgs = mIrs.getInstalledPackages(userId);
|
||||
final List<InstalledPackageInfo> 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;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -131,7 +131,7 @@ public class InternalResourceService extends SystemService {
|
||||
|
||||
@NonNull
|
||||
@GuardedBy("mLock")
|
||||
private final List<PackageInfo> mPkgCache = new ArrayList<>();
|
||||
private final List<InstalledPackageInfo> 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<PackageInfo> getInstalledPackages() {
|
||||
List<InstalledPackageInfo> getInstalledPackages() {
|
||||
synchronized (mLock) {
|
||||
return mPkgCache;
|
||||
}
|
||||
@@ -311,13 +311,12 @@ public class InternalResourceService extends SystemService {
|
||||
|
||||
/** Returns the installed packages for the specified user. */
|
||||
@NonNull
|
||||
List<PackageInfo> getInstalledPackages(final int userId) {
|
||||
final List<PackageInfo> userPkgs = new ArrayList<>();
|
||||
List<InstalledPackageInfo> getInstalledPackages(final int userId) {
|
||||
final List<InstalledPackageInfo> 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<PackageInfo> 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<String> 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<PackageInfo> pkgs =
|
||||
mPackageManager.getInstalledPackagesAsUser(PACKAGE_QUERY_FLAGS, userId);
|
||||
for (int i = pkgs.size() - 1; i >= 0; --i) {
|
||||
mPkgCache.add(new InstalledPackageInfo(pkgs.get(i)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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<ArraySet<String>> installedPackagesPerUser = new SparseArray<>();
|
||||
final List<PackageInfo> installedPackages = mIrs.getInstalledPackages();
|
||||
final List<InstalledPackageInfo> 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<String> pkgsForUser = installedPackagesPerUser.get(userId);
|
||||
if (pkgsForUser == null) {
|
||||
pkgsForUser = new ArraySet<>();
|
||||
|
||||
@@ -68,7 +68,7 @@ public class ScribeTest {
|
||||
private MockitoSession mMockingSession;
|
||||
private Scribe mScribeUnderTest;
|
||||
private File mTestFileDir;
|
||||
private final List<PackageInfo> mInstalledPackages = new ArrayList<>();
|
||||
private final List<InstalledPackageInfo> mInstalledPackages = new ArrayList<>();
|
||||
private final List<Analyst.Report> 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));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user