Loading services/core/java/com/android/server/pm/AppsFilterImpl.java +78 −8 Original line number Diff line number Diff line Loading @@ -22,6 +22,15 @@ import static android.os.UserHandle.USER_NULL; import static android.provider.DeviceConfig.NAMESPACE_PACKAGE_MANAGER_SERVICE; import static com.android.internal.annotations.VisibleForTesting.Visibility.PRIVATE; import static com.android.internal.util.FrameworkStatsLog.PACKAGE_MANAGER_APPS_FILTER_CACHE_BUILD_REPORTED; import static com.android.internal.util.FrameworkStatsLog.PACKAGE_MANAGER_APPS_FILTER_CACHE_BUILD_REPORTED__EVENT_TYPE__BOOT; import static com.android.internal.util.FrameworkStatsLog.PACKAGE_MANAGER_APPS_FILTER_CACHE_BUILD_REPORTED__EVENT_TYPE__USER_CREATED; import static com.android.internal.util.FrameworkStatsLog.PACKAGE_MANAGER_APPS_FILTER_CACHE_BUILD_REPORTED__EVENT_TYPE__USER_DELETED; import static com.android.internal.util.FrameworkStatsLog.PACKAGE_MANAGER_APPS_FILTER_CACHE_UPDATE_REPORTED; import static com.android.internal.util.FrameworkStatsLog.PACKAGE_MANAGER_APPS_FILTER_CACHE_UPDATE_REPORTED__EVENT_TYPE__COMPAT_CHANGED; import static com.android.internal.util.FrameworkStatsLog.PACKAGE_MANAGER_APPS_FILTER_CACHE_UPDATE_REPORTED__EVENT_TYPE__PACKAGE_ADDED; import static com.android.internal.util.FrameworkStatsLog.PACKAGE_MANAGER_APPS_FILTER_CACHE_UPDATE_REPORTED__EVENT_TYPE__PACKAGE_DELETED; import static com.android.internal.util.FrameworkStatsLog.PACKAGE_MANAGER_APPS_FILTER_CACHE_UPDATE_REPORTED__EVENT_TYPE__PACKAGE_REPLACED; import static com.android.server.pm.AppsFilterUtils.canQueryAsInstaller; import static com.android.server.pm.AppsFilterUtils.canQueryViaComponents; import static com.android.server.pm.AppsFilterUtils.canQueryViaPackage; Loading @@ -36,6 +45,7 @@ import android.content.pm.PackageManagerInternal; import android.content.pm.SigningDetails; import android.content.pm.UserInfo; import android.os.Handler; import android.os.SystemClock; import android.os.SystemProperties; import android.os.Trace; import android.os.UserHandle; Loading @@ -49,6 +59,7 @@ import com.android.internal.R; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.ArrayUtils; import com.android.internal.util.FrameworkStatsLog; import com.android.server.FgThread; import com.android.server.compat.CompatChange; import com.android.server.om.OverlayReferenceMapper; Loading Loading @@ -351,8 +362,15 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable, if (pkg == null) { return; } final long currentTimeUs = SystemClock.currentTimeMicro(); updateEnabledState(pkg); mAppsFilter.updateShouldFilterCacheForPackage(snapshot, packageName); mAppsFilter.logCacheUpdated( PACKAGE_MANAGER_APPS_FILTER_CACHE_UPDATE_REPORTED__EVENT_TYPE__COMPAT_CHANGED, SystemClock.currentTimeMicro() - currentTimeUs, snapshot.getUserInfos().length, snapshot.getPackageStates().size(), pkg.getUid()); } private void updateEnabledState(@NonNull AndroidPackage pkg) { Loading Loading @@ -465,7 +483,8 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable, mOverlayReferenceMapper.rebuildIfDeferred(); mFeatureConfig.onSystemReady(); updateEntireShouldFilterCacheAsync(pmInternal); updateEntireShouldFilterCacheAsync(pmInternal, PACKAGE_MANAGER_APPS_FILTER_CACHE_BUILD_REPORTED__EVENT_TYPE__BOOT); } /** Loading @@ -476,13 +495,17 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable, */ public void addPackage(Computer snapshot, PackageStateInternal newPkgSetting, boolean isReplace) { final long currentTimeUs = SystemClock.currentTimeMicro(); final int logType = isReplace ? PACKAGE_MANAGER_APPS_FILTER_CACHE_UPDATE_REPORTED__EVENT_TYPE__PACKAGE_REPLACED : PACKAGE_MANAGER_APPS_FILTER_CACHE_UPDATE_REPORTED__EVENT_TYPE__PACKAGE_ADDED; if (DEBUG_TRACING) { Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "filter.addPackage"); } try { if (isReplace) { // let's first remove any prior rules for this package removePackage(snapshot, newPkgSetting, true /*isReplace*/); removePackageInternal(snapshot, newPkgSetting, true /*isReplace*/); } final ArrayMap<String, ? extends PackageStateInternal> settings = snapshot.getPackageStates(); Loading @@ -508,6 +531,8 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable, } } } logCacheUpdated(logType, SystemClock.currentTimeMicro() - currentTimeUs, users.length, settings.size(), newPkgSetting.getAppId()); } else { invalidateCache("addPackage: " + newPkgSetting.getPackageName()); } Loading Loading @@ -757,18 +782,19 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable, } } private void updateEntireShouldFilterCacheAsync(PackageManagerInternal pmInternal) { updateEntireShouldFilterCacheAsync(pmInternal, CACHE_REBUILD_DELAY_MIN_MS); private void updateEntireShouldFilterCacheAsync(PackageManagerInternal pmInternal, int reason) { updateEntireShouldFilterCacheAsync(pmInternal, CACHE_REBUILD_DELAY_MIN_MS, reason); } private void updateEntireShouldFilterCacheAsync(PackageManagerInternal pmInternal, long delayMs) { long delayMs, int reason) { mBackgroundHandler.postDelayed(() -> { if (!mCacheValid.compareAndSet(CACHE_INVALID, CACHE_VALID)) { // Cache is already valid. return; } final long currentTimeUs = SystemClock.currentTimeMicro(); final ArrayMap<String, AndroidPackage> packagesCache = new ArrayMap<>(); final UserInfo[][] usersRef = new UserInfo[1][]; final Computer snapshot = (Computer) pmInternal.snapshot(); Loading @@ -787,11 +813,13 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable, updateEntireShouldFilterCacheInner(snapshot, settings, usersRef[0], USER_ALL); onChanged(); logCacheRebuilt(reason, SystemClock.currentTimeMicro() - currentTimeUs, users.length, settings.size()); if (!mCacheValid.compareAndSet(CACHE_VALID, CACHE_VALID)) { Slog.i(TAG, "Cache invalidated while building, retrying."); updateEntireShouldFilterCacheAsync(pmInternal, Math.min(delayMs * 2, CACHE_REBUILD_DELAY_MAX_MS)); Math.min(delayMs * 2, CACHE_REBUILD_DELAY_MAX_MS), reason); return; } Loading @@ -803,15 +831,27 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable, if (!mCacheReady) { return; } final long currentTimeUs = SystemClock.currentTimeMicro(); updateEntireShouldFilterCache(snapshot, newUserId); logCacheRebuilt( PACKAGE_MANAGER_APPS_FILTER_CACHE_BUILD_REPORTED__EVENT_TYPE__USER_CREATED, SystemClock.currentTimeMicro() - currentTimeUs, snapshot.getUserInfos().length, snapshot.getPackageStates().size()); } public void onUserDeleted(@UserIdInt int userId) { public void onUserDeleted(Computer snapshot, @UserIdInt int userId) { if (!mCacheReady) { return; } final long currentTimeUs = SystemClock.currentTimeMicro(); removeShouldFilterCacheForUser(userId); onChanged(); logCacheRebuilt( PACKAGE_MANAGER_APPS_FILTER_CACHE_BUILD_REPORTED__EVENT_TYPE__USER_DELETED, SystemClock.currentTimeMicro() - currentTimeUs, snapshot.getUserInfos().length, snapshot.getPackageStates().size()); } private void updateShouldFilterCacheForPackage(Computer snapshot, Loading Loading @@ -985,13 +1025,29 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable, addPackage(snapshot, newPkgSetting, false /* isReplace */); } /** * Removes a package for consideration when filtering visibility between apps. * * @param setting the setting of the package being removed. */ public void removePackage(Computer snapshot, PackageStateInternal setting) { final long currentTimeUs = SystemClock.currentTimeMicro(); removePackageInternal(snapshot, setting, false /* isReplace */); logCacheUpdated( PACKAGE_MANAGER_APPS_FILTER_CACHE_UPDATE_REPORTED__EVENT_TYPE__PACKAGE_DELETED, SystemClock.currentTimeMicro() - currentTimeUs, snapshot.getUserInfos().length, snapshot.getPackageStates().size(), setting.getAppId()); } /** * Removes a package for consideration when filtering visibility between apps. * * @param setting the setting of the package being removed. * @param isReplace if the package is being replaced. */ public void removePackage(Computer snapshot, PackageStateInternal setting, private void removePackageInternal(Computer snapshot, PackageStateInternal setting, boolean isReplace) { final ArraySet<String> additionalChangedPackages; final ArrayMap<String, ? extends PackageStateInternal> settings = Loading Loading @@ -1174,4 +1230,18 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable, } } } private void logCacheRebuilt(int eventId, long latency, int userCount, int packageCount) { FrameworkStatsLog.write(PACKAGE_MANAGER_APPS_FILTER_CACHE_BUILD_REPORTED, eventId, latency, userCount, packageCount, mShouldFilterCache.size()); } private void logCacheUpdated(int eventId, long latency, int userCount, int packageCount, int appId) { if (!mCacheReady) { return; } FrameworkStatsLog.write(PACKAGE_MANAGER_APPS_FILTER_CACHE_UPDATE_REPORTED, eventId, appId, latency, userCount, packageCount, mShouldFilterCache.size()); } } services/core/java/com/android/server/pm/PackageManagerService.java +2 −2 Original line number Diff line number Diff line Loading @@ -1147,7 +1147,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService var done = SystemClock.currentTimeMicro(); if (mSnapshotStatistics != null) { mSnapshotStatistics.rebuild(now, done, hits); mSnapshotStatistics.rebuild(now, done, hits, newSnapshot.getPackageStates().size()); } return newSnapshot; } Loading Loading @@ -4220,7 +4220,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService mSettings.removeUserLPw(userId); mPendingBroadcasts.remove(userId); mDeletePackageHelper.removeUnusedPackagesLPw(userManager, userId); mAppsFilter.onUserDeleted(userId); mAppsFilter.onUserDeleted(snapshotComputer(), userId); } mInstantAppRegistry.onUserRemoved(userId); } Loading services/core/java/com/android/server/pm/RemovePackageHelper.java +1 −1 Original line number Diff line number Diff line Loading @@ -308,7 +308,7 @@ final class RemovePackageHelper { mPm.mSettings.getKeySetManagerService().removeAppKeySetDataLPw(packageName); final Computer snapshot = mPm.snapshotComputer(); mPm.mAppsFilter.removePackage(snapshot, snapshot.getPackageStateInternal(packageName), false /* isReplace */); snapshot.getPackageStateInternal(packageName)); removedAppId = mPm.mSettings.removePackageLPw(packageName); if (outInfo != null) { outInfo.mRemovedAppId = removedAppId; Loading services/core/java/com/android/server/pm/SnapshotStatistics.java +79 −38 Original line number Diff line number Diff line Loading @@ -24,11 +24,13 @@ import android.os.SystemClock; import android.text.TextUtils; import com.android.internal.annotations.GuardedBy; import com.android.internal.util.FrameworkStatsLog; import com.android.server.EventLogTags; import java.io.PrintWriter; import java.util.Arrays; import java.util.Locale; import java.util.concurrent.TimeUnit; /** * This class records statistics about PackageManagerService snapshots. It maintains two sets of Loading Loading @@ -59,9 +61,9 @@ public class SnapshotStatistics { public static final int SNAPSHOT_TICK_INTERVAL_MS = 60 * 1000; /** * The number of ticks for long statistics. This is one week. * The interval of the snapshot statistics logging. */ public static final int SNAPSHOT_LONG_TICKS = 7 * 24 * 60; private static final long SNAPSHOT_LOG_INTERVAL_US = TimeUnit.DAYS.toMicros(1); /** * The number snapshot event logs that can be generated in a single logging interval. Loading Loading @@ -92,6 +94,28 @@ public class SnapshotStatistics { */ public static final int SNAPSHOT_SHORT_LIFETIME = 5; /** * Buckets to represent a range of the rebuild latency for the histogram of * snapshot rebuild latency. */ private static final int REBUILD_LATENCY_BUCKET_LESS_THAN_1_MILLIS = 1; private static final int REBUILD_LATENCY_BUCKET_LESS_THAN_2_MILLIS = 2; private static final int REBUILD_LATENCY_BUCKET_LESS_THAN_5_MILLIS = 5; private static final int REBUILD_LATENCY_BUCKET_LESS_THAN_10_MILLIS = 10; private static final int REBUILD_LATENCY_BUCKET_LESS_THAN_20_MILLIS = 20; private static final int REBUILD_LATENCY_BUCKET_LESS_THAN_50_MILLIS = 50; private static final int REBUILD_LATENCY_BUCKET_LESS_THAN_100_MILLIS = 100; /** * Buckets to represent a range of the reuse count for the histogram of * snapshot reuse counts. */ private static final int REUSE_COUNT_BUCKET_LESS_THAN_1 = 1; private static final int REUSE_COUNT_BUCKET_LESS_THAN_10 = 10; private static final int REUSE_COUNT_BUCKET_LESS_THAN_100 = 100; private static final int REUSE_COUNT_BUCKET_LESS_THAN_1000 = 1000; private static final int REUSE_COUNT_BUCKET_LESS_THAN_10000 = 10000; /** * The lock to control access to this object. */ Loading @@ -112,11 +136,6 @@ public class SnapshotStatistics { */ private int mEventsReported = 0; /** * The tick counter. At the default tick interval, this wraps every 4000 years or so. */ private int mTicks = 0; /** * The handler used for the periodic ticks. */ Loading @@ -139,8 +158,6 @@ public class SnapshotStatistics { // The number of bins private int mCount; // The mapping of low integers to bins private int[] mBinMap; // The maximum mapped value. Values at or above this are mapped to the // top bin. private int mMaxBin; Loading @@ -158,16 +175,6 @@ public class SnapshotStatistics { mCount = mUserKey.length + 1; // The maximum value is one more than the last one in the map. mMaxBin = mUserKey[mUserKey.length - 1] + 1; mBinMap = new int[mMaxBin + 1]; int j = 0; for (int i = 0; i < mUserKey.length; i++) { while (j <= mUserKey[i]) { mBinMap[j] = i; j++; } } mBinMap[mMaxBin] = mUserKey.length; } /** Loading @@ -175,9 +182,14 @@ public class SnapshotStatistics { */ public int getBin(int x) { if (x >= 0 && x < mMaxBin) { return mBinMap[x]; for (int i = 0; i < mUserKey.length; i++) { if (x <= mUserKey[i]) { return i; } } return 0; // should not happen } else if (x >= mMaxBin) { return mBinMap[mMaxBin]; return mUserKey.length; } else { // x is negative. The bin will not be used. return 0; Loading Loading @@ -262,6 +274,11 @@ public class SnapshotStatistics { */ public int mMaxBuildTimeUs = 0; /** * The maximum used count since the last log. */ public int mMaxUsedCount = 0; /** * Record the rebuild. The parameters are the length of time it took to build the * latest snapshot, and the number of times the _previous_ snapshot was used. A Loading @@ -279,7 +296,6 @@ public class SnapshotStatistics { } mTotalTimeUs += duration; boolean reportIt = false; if (big) { mBigBuilds++; Loading @@ -290,6 +306,9 @@ public class SnapshotStatistics { if (mMaxBuildTimeUs < duration) { mMaxBuildTimeUs = duration; } if (mMaxUsedCount < used) { mMaxUsedCount = used; } } private Stats(long now) { Loading @@ -313,6 +332,7 @@ public class SnapshotStatistics { mShortLived = orig.mShortLived; mTotalTimeUs = orig.mTotalTimeUs; mMaxBuildTimeUs = orig.mMaxBuildTimeUs; mMaxUsedCount = orig.mMaxUsedCount; } /** Loading Loading @@ -443,18 +463,19 @@ public class SnapshotStatistics { } /** * Report the object via an event. Presumably the record indicates an anomalous * incident. * Report the snapshot statistics to FrameworkStatsLog. */ private void report() { EventLogTags.writePmSnapshotStats( mTotalBuilds, mTotalUsed, mBigBuilds, mShortLived, mMaxBuildTimeUs / US_IN_MS, mTotalTimeUs / US_IN_MS); private void logSnapshotStatistics(int packageCount) { final long avgLatencyUs = (mTotalBuilds == 0 ? 0 : mTotalTimeUs / mTotalBuilds); final int avgUsedCount = (mTotalBuilds == 0 ? 0 : mTotalUsed / mTotalBuilds); FrameworkStatsLog.write( FrameworkStatsLog.PACKAGE_MANAGER_SNAPSHOT_REPORTED, mTimes, mUsed, mMaxBuildTimeUs, mMaxUsedCount, avgLatencyUs, avgUsedCount, packageCount); } } /** * Long statistics. These roll over approximately every week. * Long statistics. These roll over approximately one day. */ private Stats[] mLong; Loading @@ -464,10 +485,14 @@ public class SnapshotStatistics { private Stats[] mShort; /** * The time of the last build. This can be used to compute the length of time a * snapshot existed before being replaced. * The time of last logging to the FrameworkStatsLog. */ private long mLastLogTimeUs; /** * The number of packages on the device. */ private long mLastBuildTime = 0; private int mPackageCount; /** * Create a snapshot object. Initialize the bin levels. The last bin catches Loading @@ -475,8 +500,20 @@ public class SnapshotStatistics { */ public SnapshotStatistics() { // Create the bin thresholds. The time bins are in units of us. mTimeBins = new BinMap(new int[] { 1, 2, 5, 10, 20, 50, 100 }); mUseBins = new BinMap(new int[] { 1, 2, 5, 10, 20, 50, 100 }); mTimeBins = new BinMap(new int[] { REBUILD_LATENCY_BUCKET_LESS_THAN_1_MILLIS, REBUILD_LATENCY_BUCKET_LESS_THAN_2_MILLIS, REBUILD_LATENCY_BUCKET_LESS_THAN_5_MILLIS, REBUILD_LATENCY_BUCKET_LESS_THAN_10_MILLIS, REBUILD_LATENCY_BUCKET_LESS_THAN_20_MILLIS, REBUILD_LATENCY_BUCKET_LESS_THAN_50_MILLIS, REBUILD_LATENCY_BUCKET_LESS_THAN_100_MILLIS }); mUseBins = new BinMap(new int[] { REUSE_COUNT_BUCKET_LESS_THAN_1, REUSE_COUNT_BUCKET_LESS_THAN_10, REUSE_COUNT_BUCKET_LESS_THAN_100, REUSE_COUNT_BUCKET_LESS_THAN_1000, REUSE_COUNT_BUCKET_LESS_THAN_10000 }); // Create the raw statistics final long now = SystemClock.currentTimeMicro(); Loading @@ -484,6 +521,7 @@ public class SnapshotStatistics { mLong[0] = new Stats(now); mShort = new Stats[10]; mShort[0] = new Stats(now); mLastLogTimeUs = now; // Create the message handler for ticks and start the ticker. mHandler = new Handler(Looper.getMainLooper()) { Loading Loading @@ -516,13 +554,14 @@ public class SnapshotStatistics { * @param now The time at which the snapshot rebuild began, in ns. * @param done The time at which the snapshot rebuild completed, in ns. * @param hits The number of times the previous snapshot was used. * @param packageCount The number of packages on the device. */ public final void rebuild(long now, long done, int hits) { public final void rebuild(long now, long done, int hits, int packageCount) { // The duration has a span of about 2000s final int duration = (int) (done - now); boolean reportEvent = false; synchronized (mLock) { mLastBuildTime = now; mPackageCount = packageCount; final int timeBin = mTimeBins.getBin(duration / 1000); final int useBin = mUseBins.getBin(hits); Loading Loading @@ -570,10 +609,12 @@ public class SnapshotStatistics { private void tick() { synchronized (mLock) { long now = SystemClock.currentTimeMicro(); mTicks++; if (mTicks % SNAPSHOT_LONG_TICKS == 0) { if (now - mLastLogTimeUs > SNAPSHOT_LOG_INTERVAL_US) { shift(mLong, now); mLastLogTimeUs = now; mLong[mLong.length - 1].logSnapshotStatistics(mPackageCount); } shift(mShort, now); mEventsReported = 0; } Loading services/tests/servicestests/src/com/android/server/pm/AppsFilterImplTest.java +4 −4 Original line number Diff line number Diff line Loading @@ -387,7 +387,7 @@ public class AppsFilterImplTest { // delete user when(mSnapshot.getUserInfos()).thenReturn(USER_INFO_LIST); appsFilter.onUserDeleted(ADDED_USER); appsFilter.onUserDeleted(mSnapshot, ADDED_USER); for (int subjectUserId : USER_ARRAY) { for (int otherUserId : USER_ARRAY) { Loading Loading @@ -925,7 +925,7 @@ public class AppsFilterImplTest { assertTrue(appsFilter.shouldFilterApplication(mSnapshot, DUMMY_OVERLAY_APPID, overlaySetting, actorSetting, SYSTEM_USER)); appsFilter.removePackage(mSnapshot, targetSetting, false /* isReplace */); appsFilter.removePackage(mSnapshot, targetSetting); // Actor loses visibility to the overlay via removal of the target assertTrue(appsFilter.shouldFilterApplication(mSnapshot, DUMMY_ACTOR_APPID, actorSetting, Loading Loading @@ -1267,7 +1267,7 @@ public class AppsFilterImplTest { watcher.verifyNoChangeReported("get"); // remove a package appsFilter.removePackage(mSnapshot, seesNothing, false /* isReplace */); appsFilter.removePackage(mSnapshot, seesNothing); watcher.verifyChangeReported("removePackage"); } Loading Loading @@ -1337,7 +1337,7 @@ public class AppsFilterImplTest { target.getPackageName())); // New changes don't affect the snapshot appsFilter.removePackage(mSnapshot, target, false); appsFilter.removePackage(mSnapshot, target); assertTrue( appsFilter.shouldFilterApplication(mSnapshot, DUMMY_CALLING_APPID, instrumentation, target, Loading Loading
services/core/java/com/android/server/pm/AppsFilterImpl.java +78 −8 Original line number Diff line number Diff line Loading @@ -22,6 +22,15 @@ import static android.os.UserHandle.USER_NULL; import static android.provider.DeviceConfig.NAMESPACE_PACKAGE_MANAGER_SERVICE; import static com.android.internal.annotations.VisibleForTesting.Visibility.PRIVATE; import static com.android.internal.util.FrameworkStatsLog.PACKAGE_MANAGER_APPS_FILTER_CACHE_BUILD_REPORTED; import static com.android.internal.util.FrameworkStatsLog.PACKAGE_MANAGER_APPS_FILTER_CACHE_BUILD_REPORTED__EVENT_TYPE__BOOT; import static com.android.internal.util.FrameworkStatsLog.PACKAGE_MANAGER_APPS_FILTER_CACHE_BUILD_REPORTED__EVENT_TYPE__USER_CREATED; import static com.android.internal.util.FrameworkStatsLog.PACKAGE_MANAGER_APPS_FILTER_CACHE_BUILD_REPORTED__EVENT_TYPE__USER_DELETED; import static com.android.internal.util.FrameworkStatsLog.PACKAGE_MANAGER_APPS_FILTER_CACHE_UPDATE_REPORTED; import static com.android.internal.util.FrameworkStatsLog.PACKAGE_MANAGER_APPS_FILTER_CACHE_UPDATE_REPORTED__EVENT_TYPE__COMPAT_CHANGED; import static com.android.internal.util.FrameworkStatsLog.PACKAGE_MANAGER_APPS_FILTER_CACHE_UPDATE_REPORTED__EVENT_TYPE__PACKAGE_ADDED; import static com.android.internal.util.FrameworkStatsLog.PACKAGE_MANAGER_APPS_FILTER_CACHE_UPDATE_REPORTED__EVENT_TYPE__PACKAGE_DELETED; import static com.android.internal.util.FrameworkStatsLog.PACKAGE_MANAGER_APPS_FILTER_CACHE_UPDATE_REPORTED__EVENT_TYPE__PACKAGE_REPLACED; import static com.android.server.pm.AppsFilterUtils.canQueryAsInstaller; import static com.android.server.pm.AppsFilterUtils.canQueryViaComponents; import static com.android.server.pm.AppsFilterUtils.canQueryViaPackage; Loading @@ -36,6 +45,7 @@ import android.content.pm.PackageManagerInternal; import android.content.pm.SigningDetails; import android.content.pm.UserInfo; import android.os.Handler; import android.os.SystemClock; import android.os.SystemProperties; import android.os.Trace; import android.os.UserHandle; Loading @@ -49,6 +59,7 @@ import com.android.internal.R; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.ArrayUtils; import com.android.internal.util.FrameworkStatsLog; import com.android.server.FgThread; import com.android.server.compat.CompatChange; import com.android.server.om.OverlayReferenceMapper; Loading Loading @@ -351,8 +362,15 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable, if (pkg == null) { return; } final long currentTimeUs = SystemClock.currentTimeMicro(); updateEnabledState(pkg); mAppsFilter.updateShouldFilterCacheForPackage(snapshot, packageName); mAppsFilter.logCacheUpdated( PACKAGE_MANAGER_APPS_FILTER_CACHE_UPDATE_REPORTED__EVENT_TYPE__COMPAT_CHANGED, SystemClock.currentTimeMicro() - currentTimeUs, snapshot.getUserInfos().length, snapshot.getPackageStates().size(), pkg.getUid()); } private void updateEnabledState(@NonNull AndroidPackage pkg) { Loading Loading @@ -465,7 +483,8 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable, mOverlayReferenceMapper.rebuildIfDeferred(); mFeatureConfig.onSystemReady(); updateEntireShouldFilterCacheAsync(pmInternal); updateEntireShouldFilterCacheAsync(pmInternal, PACKAGE_MANAGER_APPS_FILTER_CACHE_BUILD_REPORTED__EVENT_TYPE__BOOT); } /** Loading @@ -476,13 +495,17 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable, */ public void addPackage(Computer snapshot, PackageStateInternal newPkgSetting, boolean isReplace) { final long currentTimeUs = SystemClock.currentTimeMicro(); final int logType = isReplace ? PACKAGE_MANAGER_APPS_FILTER_CACHE_UPDATE_REPORTED__EVENT_TYPE__PACKAGE_REPLACED : PACKAGE_MANAGER_APPS_FILTER_CACHE_UPDATE_REPORTED__EVENT_TYPE__PACKAGE_ADDED; if (DEBUG_TRACING) { Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "filter.addPackage"); } try { if (isReplace) { // let's first remove any prior rules for this package removePackage(snapshot, newPkgSetting, true /*isReplace*/); removePackageInternal(snapshot, newPkgSetting, true /*isReplace*/); } final ArrayMap<String, ? extends PackageStateInternal> settings = snapshot.getPackageStates(); Loading @@ -508,6 +531,8 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable, } } } logCacheUpdated(logType, SystemClock.currentTimeMicro() - currentTimeUs, users.length, settings.size(), newPkgSetting.getAppId()); } else { invalidateCache("addPackage: " + newPkgSetting.getPackageName()); } Loading Loading @@ -757,18 +782,19 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable, } } private void updateEntireShouldFilterCacheAsync(PackageManagerInternal pmInternal) { updateEntireShouldFilterCacheAsync(pmInternal, CACHE_REBUILD_DELAY_MIN_MS); private void updateEntireShouldFilterCacheAsync(PackageManagerInternal pmInternal, int reason) { updateEntireShouldFilterCacheAsync(pmInternal, CACHE_REBUILD_DELAY_MIN_MS, reason); } private void updateEntireShouldFilterCacheAsync(PackageManagerInternal pmInternal, long delayMs) { long delayMs, int reason) { mBackgroundHandler.postDelayed(() -> { if (!mCacheValid.compareAndSet(CACHE_INVALID, CACHE_VALID)) { // Cache is already valid. return; } final long currentTimeUs = SystemClock.currentTimeMicro(); final ArrayMap<String, AndroidPackage> packagesCache = new ArrayMap<>(); final UserInfo[][] usersRef = new UserInfo[1][]; final Computer snapshot = (Computer) pmInternal.snapshot(); Loading @@ -787,11 +813,13 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable, updateEntireShouldFilterCacheInner(snapshot, settings, usersRef[0], USER_ALL); onChanged(); logCacheRebuilt(reason, SystemClock.currentTimeMicro() - currentTimeUs, users.length, settings.size()); if (!mCacheValid.compareAndSet(CACHE_VALID, CACHE_VALID)) { Slog.i(TAG, "Cache invalidated while building, retrying."); updateEntireShouldFilterCacheAsync(pmInternal, Math.min(delayMs * 2, CACHE_REBUILD_DELAY_MAX_MS)); Math.min(delayMs * 2, CACHE_REBUILD_DELAY_MAX_MS), reason); return; } Loading @@ -803,15 +831,27 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable, if (!mCacheReady) { return; } final long currentTimeUs = SystemClock.currentTimeMicro(); updateEntireShouldFilterCache(snapshot, newUserId); logCacheRebuilt( PACKAGE_MANAGER_APPS_FILTER_CACHE_BUILD_REPORTED__EVENT_TYPE__USER_CREATED, SystemClock.currentTimeMicro() - currentTimeUs, snapshot.getUserInfos().length, snapshot.getPackageStates().size()); } public void onUserDeleted(@UserIdInt int userId) { public void onUserDeleted(Computer snapshot, @UserIdInt int userId) { if (!mCacheReady) { return; } final long currentTimeUs = SystemClock.currentTimeMicro(); removeShouldFilterCacheForUser(userId); onChanged(); logCacheRebuilt( PACKAGE_MANAGER_APPS_FILTER_CACHE_BUILD_REPORTED__EVENT_TYPE__USER_DELETED, SystemClock.currentTimeMicro() - currentTimeUs, snapshot.getUserInfos().length, snapshot.getPackageStates().size()); } private void updateShouldFilterCacheForPackage(Computer snapshot, Loading Loading @@ -985,13 +1025,29 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable, addPackage(snapshot, newPkgSetting, false /* isReplace */); } /** * Removes a package for consideration when filtering visibility between apps. * * @param setting the setting of the package being removed. */ public void removePackage(Computer snapshot, PackageStateInternal setting) { final long currentTimeUs = SystemClock.currentTimeMicro(); removePackageInternal(snapshot, setting, false /* isReplace */); logCacheUpdated( PACKAGE_MANAGER_APPS_FILTER_CACHE_UPDATE_REPORTED__EVENT_TYPE__PACKAGE_DELETED, SystemClock.currentTimeMicro() - currentTimeUs, snapshot.getUserInfos().length, snapshot.getPackageStates().size(), setting.getAppId()); } /** * Removes a package for consideration when filtering visibility between apps. * * @param setting the setting of the package being removed. * @param isReplace if the package is being replaced. */ public void removePackage(Computer snapshot, PackageStateInternal setting, private void removePackageInternal(Computer snapshot, PackageStateInternal setting, boolean isReplace) { final ArraySet<String> additionalChangedPackages; final ArrayMap<String, ? extends PackageStateInternal> settings = Loading Loading @@ -1174,4 +1230,18 @@ public final class AppsFilterImpl extends AppsFilterLocked implements Watchable, } } } private void logCacheRebuilt(int eventId, long latency, int userCount, int packageCount) { FrameworkStatsLog.write(PACKAGE_MANAGER_APPS_FILTER_CACHE_BUILD_REPORTED, eventId, latency, userCount, packageCount, mShouldFilterCache.size()); } private void logCacheUpdated(int eventId, long latency, int userCount, int packageCount, int appId) { if (!mCacheReady) { return; } FrameworkStatsLog.write(PACKAGE_MANAGER_APPS_FILTER_CACHE_UPDATE_REPORTED, eventId, appId, latency, userCount, packageCount, mShouldFilterCache.size()); } }
services/core/java/com/android/server/pm/PackageManagerService.java +2 −2 Original line number Diff line number Diff line Loading @@ -1147,7 +1147,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService var done = SystemClock.currentTimeMicro(); if (mSnapshotStatistics != null) { mSnapshotStatistics.rebuild(now, done, hits); mSnapshotStatistics.rebuild(now, done, hits, newSnapshot.getPackageStates().size()); } return newSnapshot; } Loading Loading @@ -4220,7 +4220,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService mSettings.removeUserLPw(userId); mPendingBroadcasts.remove(userId); mDeletePackageHelper.removeUnusedPackagesLPw(userManager, userId); mAppsFilter.onUserDeleted(userId); mAppsFilter.onUserDeleted(snapshotComputer(), userId); } mInstantAppRegistry.onUserRemoved(userId); } Loading
services/core/java/com/android/server/pm/RemovePackageHelper.java +1 −1 Original line number Diff line number Diff line Loading @@ -308,7 +308,7 @@ final class RemovePackageHelper { mPm.mSettings.getKeySetManagerService().removeAppKeySetDataLPw(packageName); final Computer snapshot = mPm.snapshotComputer(); mPm.mAppsFilter.removePackage(snapshot, snapshot.getPackageStateInternal(packageName), false /* isReplace */); snapshot.getPackageStateInternal(packageName)); removedAppId = mPm.mSettings.removePackageLPw(packageName); if (outInfo != null) { outInfo.mRemovedAppId = removedAppId; Loading
services/core/java/com/android/server/pm/SnapshotStatistics.java +79 −38 Original line number Diff line number Diff line Loading @@ -24,11 +24,13 @@ import android.os.SystemClock; import android.text.TextUtils; import com.android.internal.annotations.GuardedBy; import com.android.internal.util.FrameworkStatsLog; import com.android.server.EventLogTags; import java.io.PrintWriter; import java.util.Arrays; import java.util.Locale; import java.util.concurrent.TimeUnit; /** * This class records statistics about PackageManagerService snapshots. It maintains two sets of Loading Loading @@ -59,9 +61,9 @@ public class SnapshotStatistics { public static final int SNAPSHOT_TICK_INTERVAL_MS = 60 * 1000; /** * The number of ticks for long statistics. This is one week. * The interval of the snapshot statistics logging. */ public static final int SNAPSHOT_LONG_TICKS = 7 * 24 * 60; private static final long SNAPSHOT_LOG_INTERVAL_US = TimeUnit.DAYS.toMicros(1); /** * The number snapshot event logs that can be generated in a single logging interval. Loading Loading @@ -92,6 +94,28 @@ public class SnapshotStatistics { */ public static final int SNAPSHOT_SHORT_LIFETIME = 5; /** * Buckets to represent a range of the rebuild latency for the histogram of * snapshot rebuild latency. */ private static final int REBUILD_LATENCY_BUCKET_LESS_THAN_1_MILLIS = 1; private static final int REBUILD_LATENCY_BUCKET_LESS_THAN_2_MILLIS = 2; private static final int REBUILD_LATENCY_BUCKET_LESS_THAN_5_MILLIS = 5; private static final int REBUILD_LATENCY_BUCKET_LESS_THAN_10_MILLIS = 10; private static final int REBUILD_LATENCY_BUCKET_LESS_THAN_20_MILLIS = 20; private static final int REBUILD_LATENCY_BUCKET_LESS_THAN_50_MILLIS = 50; private static final int REBUILD_LATENCY_BUCKET_LESS_THAN_100_MILLIS = 100; /** * Buckets to represent a range of the reuse count for the histogram of * snapshot reuse counts. */ private static final int REUSE_COUNT_BUCKET_LESS_THAN_1 = 1; private static final int REUSE_COUNT_BUCKET_LESS_THAN_10 = 10; private static final int REUSE_COUNT_BUCKET_LESS_THAN_100 = 100; private static final int REUSE_COUNT_BUCKET_LESS_THAN_1000 = 1000; private static final int REUSE_COUNT_BUCKET_LESS_THAN_10000 = 10000; /** * The lock to control access to this object. */ Loading @@ -112,11 +136,6 @@ public class SnapshotStatistics { */ private int mEventsReported = 0; /** * The tick counter. At the default tick interval, this wraps every 4000 years or so. */ private int mTicks = 0; /** * The handler used for the periodic ticks. */ Loading @@ -139,8 +158,6 @@ public class SnapshotStatistics { // The number of bins private int mCount; // The mapping of low integers to bins private int[] mBinMap; // The maximum mapped value. Values at or above this are mapped to the // top bin. private int mMaxBin; Loading @@ -158,16 +175,6 @@ public class SnapshotStatistics { mCount = mUserKey.length + 1; // The maximum value is one more than the last one in the map. mMaxBin = mUserKey[mUserKey.length - 1] + 1; mBinMap = new int[mMaxBin + 1]; int j = 0; for (int i = 0; i < mUserKey.length; i++) { while (j <= mUserKey[i]) { mBinMap[j] = i; j++; } } mBinMap[mMaxBin] = mUserKey.length; } /** Loading @@ -175,9 +182,14 @@ public class SnapshotStatistics { */ public int getBin(int x) { if (x >= 0 && x < mMaxBin) { return mBinMap[x]; for (int i = 0; i < mUserKey.length; i++) { if (x <= mUserKey[i]) { return i; } } return 0; // should not happen } else if (x >= mMaxBin) { return mBinMap[mMaxBin]; return mUserKey.length; } else { // x is negative. The bin will not be used. return 0; Loading Loading @@ -262,6 +274,11 @@ public class SnapshotStatistics { */ public int mMaxBuildTimeUs = 0; /** * The maximum used count since the last log. */ public int mMaxUsedCount = 0; /** * Record the rebuild. The parameters are the length of time it took to build the * latest snapshot, and the number of times the _previous_ snapshot was used. A Loading @@ -279,7 +296,6 @@ public class SnapshotStatistics { } mTotalTimeUs += duration; boolean reportIt = false; if (big) { mBigBuilds++; Loading @@ -290,6 +306,9 @@ public class SnapshotStatistics { if (mMaxBuildTimeUs < duration) { mMaxBuildTimeUs = duration; } if (mMaxUsedCount < used) { mMaxUsedCount = used; } } private Stats(long now) { Loading @@ -313,6 +332,7 @@ public class SnapshotStatistics { mShortLived = orig.mShortLived; mTotalTimeUs = orig.mTotalTimeUs; mMaxBuildTimeUs = orig.mMaxBuildTimeUs; mMaxUsedCount = orig.mMaxUsedCount; } /** Loading Loading @@ -443,18 +463,19 @@ public class SnapshotStatistics { } /** * Report the object via an event. Presumably the record indicates an anomalous * incident. * Report the snapshot statistics to FrameworkStatsLog. */ private void report() { EventLogTags.writePmSnapshotStats( mTotalBuilds, mTotalUsed, mBigBuilds, mShortLived, mMaxBuildTimeUs / US_IN_MS, mTotalTimeUs / US_IN_MS); private void logSnapshotStatistics(int packageCount) { final long avgLatencyUs = (mTotalBuilds == 0 ? 0 : mTotalTimeUs / mTotalBuilds); final int avgUsedCount = (mTotalBuilds == 0 ? 0 : mTotalUsed / mTotalBuilds); FrameworkStatsLog.write( FrameworkStatsLog.PACKAGE_MANAGER_SNAPSHOT_REPORTED, mTimes, mUsed, mMaxBuildTimeUs, mMaxUsedCount, avgLatencyUs, avgUsedCount, packageCount); } } /** * Long statistics. These roll over approximately every week. * Long statistics. These roll over approximately one day. */ private Stats[] mLong; Loading @@ -464,10 +485,14 @@ public class SnapshotStatistics { private Stats[] mShort; /** * The time of the last build. This can be used to compute the length of time a * snapshot existed before being replaced. * The time of last logging to the FrameworkStatsLog. */ private long mLastLogTimeUs; /** * The number of packages on the device. */ private long mLastBuildTime = 0; private int mPackageCount; /** * Create a snapshot object. Initialize the bin levels. The last bin catches Loading @@ -475,8 +500,20 @@ public class SnapshotStatistics { */ public SnapshotStatistics() { // Create the bin thresholds. The time bins are in units of us. mTimeBins = new BinMap(new int[] { 1, 2, 5, 10, 20, 50, 100 }); mUseBins = new BinMap(new int[] { 1, 2, 5, 10, 20, 50, 100 }); mTimeBins = new BinMap(new int[] { REBUILD_LATENCY_BUCKET_LESS_THAN_1_MILLIS, REBUILD_LATENCY_BUCKET_LESS_THAN_2_MILLIS, REBUILD_LATENCY_BUCKET_LESS_THAN_5_MILLIS, REBUILD_LATENCY_BUCKET_LESS_THAN_10_MILLIS, REBUILD_LATENCY_BUCKET_LESS_THAN_20_MILLIS, REBUILD_LATENCY_BUCKET_LESS_THAN_50_MILLIS, REBUILD_LATENCY_BUCKET_LESS_THAN_100_MILLIS }); mUseBins = new BinMap(new int[] { REUSE_COUNT_BUCKET_LESS_THAN_1, REUSE_COUNT_BUCKET_LESS_THAN_10, REUSE_COUNT_BUCKET_LESS_THAN_100, REUSE_COUNT_BUCKET_LESS_THAN_1000, REUSE_COUNT_BUCKET_LESS_THAN_10000 }); // Create the raw statistics final long now = SystemClock.currentTimeMicro(); Loading @@ -484,6 +521,7 @@ public class SnapshotStatistics { mLong[0] = new Stats(now); mShort = new Stats[10]; mShort[0] = new Stats(now); mLastLogTimeUs = now; // Create the message handler for ticks and start the ticker. mHandler = new Handler(Looper.getMainLooper()) { Loading Loading @@ -516,13 +554,14 @@ public class SnapshotStatistics { * @param now The time at which the snapshot rebuild began, in ns. * @param done The time at which the snapshot rebuild completed, in ns. * @param hits The number of times the previous snapshot was used. * @param packageCount The number of packages on the device. */ public final void rebuild(long now, long done, int hits) { public final void rebuild(long now, long done, int hits, int packageCount) { // The duration has a span of about 2000s final int duration = (int) (done - now); boolean reportEvent = false; synchronized (mLock) { mLastBuildTime = now; mPackageCount = packageCount; final int timeBin = mTimeBins.getBin(duration / 1000); final int useBin = mUseBins.getBin(hits); Loading Loading @@ -570,10 +609,12 @@ public class SnapshotStatistics { private void tick() { synchronized (mLock) { long now = SystemClock.currentTimeMicro(); mTicks++; if (mTicks % SNAPSHOT_LONG_TICKS == 0) { if (now - mLastLogTimeUs > SNAPSHOT_LOG_INTERVAL_US) { shift(mLong, now); mLastLogTimeUs = now; mLong[mLong.length - 1].logSnapshotStatistics(mPackageCount); } shift(mShort, now); mEventsReported = 0; } Loading
services/tests/servicestests/src/com/android/server/pm/AppsFilterImplTest.java +4 −4 Original line number Diff line number Diff line Loading @@ -387,7 +387,7 @@ public class AppsFilterImplTest { // delete user when(mSnapshot.getUserInfos()).thenReturn(USER_INFO_LIST); appsFilter.onUserDeleted(ADDED_USER); appsFilter.onUserDeleted(mSnapshot, ADDED_USER); for (int subjectUserId : USER_ARRAY) { for (int otherUserId : USER_ARRAY) { Loading Loading @@ -925,7 +925,7 @@ public class AppsFilterImplTest { assertTrue(appsFilter.shouldFilterApplication(mSnapshot, DUMMY_OVERLAY_APPID, overlaySetting, actorSetting, SYSTEM_USER)); appsFilter.removePackage(mSnapshot, targetSetting, false /* isReplace */); appsFilter.removePackage(mSnapshot, targetSetting); // Actor loses visibility to the overlay via removal of the target assertTrue(appsFilter.shouldFilterApplication(mSnapshot, DUMMY_ACTOR_APPID, actorSetting, Loading Loading @@ -1267,7 +1267,7 @@ public class AppsFilterImplTest { watcher.verifyNoChangeReported("get"); // remove a package appsFilter.removePackage(mSnapshot, seesNothing, false /* isReplace */); appsFilter.removePackage(mSnapshot, seesNothing); watcher.verifyChangeReported("removePackage"); } Loading Loading @@ -1337,7 +1337,7 @@ public class AppsFilterImplTest { target.getPackageName())); // New changes don't affect the snapshot appsFilter.removePackage(mSnapshot, target, false); appsFilter.removePackage(mSnapshot, target); assertTrue( appsFilter.shouldFilterApplication(mSnapshot, DUMMY_CALLING_APPID, instrumentation, target, Loading