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

Commit e56def66 authored by Kweku Adams's avatar Kweku Adams Committed by Android (Google) Code Review
Browse files

Merge "Reduce package cache memory usage."

parents 2b1fdba2 eb3f8c28
Loading
Loading
Loading
Loading
+8 −11
Original line number Diff line number Diff line
@@ -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;
            }
+38 −0
Original line number Diff line number Diff line
/*
 * 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();
    }
}
+22 −17
Original line number Diff line number Diff line
@@ -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)));
            }
        }
    }

+4 −5
Original line number Diff line number Diff line
@@ -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<>();
+2 −2
Original line number Diff line number Diff line
@@ -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));
    }
}