Loading services/core/java/com/android/server/pm/PackageManagerService.java +13 −2 Original line number Diff line number Diff line Loading @@ -3984,6 +3984,8 @@ public class PackageManagerService implements PackageSender, TestUtilityService // packageName -> list of components to send broadcasts now final ArrayMap<String, ArrayList<String>> sendNowBroadcasts = new ArrayMap<>(targetSize); final List<PackageMetrics.ComponentStateMetrics> componentStateMetricsList = new ArrayList<PackageMetrics.ComponentStateMetrics>(); synchronized (mLock) { Computer computer = snapshotComputer(); boolean scheduleBroadcastMessage = false; Loading @@ -3997,11 +3999,17 @@ public class PackageManagerService implements PackageSender, TestUtilityService // update enabled settings final ComponentEnabledSetting setting = settings.get(i); final String packageName = setting.getPackageName(); if (!setEnabledSettingInternalLocked(computer, pkgSettings.get(packageName), setting, userId, callingPackage)) { final PackageSetting packageSetting = pkgSettings.get(packageName); final PackageMetrics.ComponentStateMetrics componentStateMetrics = new PackageMetrics.ComponentStateMetrics(setting, UserHandle.getUid(userId, packageSetting.getAppId()), packageSetting.getEnabled(userId)); if (!setEnabledSettingInternalLocked(computer, packageSetting, setting, userId, callingPackage)) { continue; } anyChanged = true; componentStateMetricsList.add(componentStateMetrics); if ((setting.getEnabledFlags() & PackageManager.SYNCHRONOUS) != 0) { isSynchronous = true; Loading Loading @@ -4029,6 +4037,9 @@ public class PackageManagerService implements PackageSender, TestUtilityService return; } // Log the metrics when the component state is changed. PackageMetrics.reportComponentStateChanged(computer, componentStateMetricsList, userId); if (isSynchronous) { flushPackageRestrictionsAsUserInternalLocked(userId); } else { Loading services/core/java/com/android/server/pm/PackageMetrics.java +83 −0 Original line number Diff line number Diff line Loading @@ -19,12 +19,21 @@ package com.android.server.pm; import static android.os.Process.INVALID_UID; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; import android.app.ActivityManager; import android.app.admin.SecurityLog; import android.content.ComponentName; import android.content.pm.ActivityInfo; import android.content.pm.Flags; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.pm.parsing.ApkLiteParseUtils; import android.os.UserHandle; import android.text.TextUtils; import android.util.Pair; import android.util.Slog; import android.util.SparseArray; import com.android.internal.util.FrameworkStatsLog; Loading @@ -41,12 +50,14 @@ import java.nio.file.Path; import java.nio.file.SimpleFileVisitor; import java.nio.file.attribute.BasicFileAttributes; import java.util.ArrayList; import java.util.List; import java.util.concurrent.atomic.AtomicLong; /** * Metrics class for reporting stats to logging infrastructures like statsd */ final class PackageMetrics { private static final String TAG = "PackageMetrics"; public static final int STEP_PREPARE = 1; public static final int STEP_SCAN = 2; public static final int STEP_RECONCILE = 3; Loading Loading @@ -344,4 +355,76 @@ final class PackageMetrics { SecurityLog.writeEvent(SecurityLog.TAG_PACKAGE_UNINSTALLED, packageName, versionCode, userId); } public static class ComponentStateMetrics { public int mUid; public int mComponentOldState; public int mComponentNewState; public boolean mIsForWholeApp; @NonNull private String mPackageName; @Nullable private String mClassName; ComponentStateMetrics(@NonNull PackageManager.ComponentEnabledSetting setting, int uid, int componentOldState) { mUid = uid; mComponentOldState = componentOldState; mComponentNewState = setting.getEnabledState(); mIsForWholeApp = !setting.isComponent(); mPackageName = setting.getPackageName(); mClassName = setting.getClassName(); } public boolean isSameComponent(ActivityInfo activityInfo) { if (activityInfo == null) { return false; } return mIsForWholeApp ? TextUtils.equals(activityInfo.packageName, mPackageName) : activityInfo.getComponentName().equals( new ComponentName(mPackageName, mClassName)); } } public static void reportComponentStateChanged(@NonNull Computer computer, List<ComponentStateMetrics> componentStateMetricsList, @UserIdInt int userId) { if (!Flags.componentStateChangedMetrics()) { return; } if (componentStateMetricsList == null || componentStateMetricsList.isEmpty()) { Slog.d(TAG, "Fail to report component state due to metrics is empty"); return; } boolean isLauncher = false; final List<ResolveInfo> resolveInfosForLauncher = getHomeActivitiesResolveInfoAsUser( computer, userId); final int resolveInfosForLauncherSize = resolveInfosForLauncher != null ? resolveInfosForLauncher.size() : 0; final int metricsSize = componentStateMetricsList.size(); for (int i = 0; i < metricsSize; i++) { final ComponentStateMetrics componentStateMetrics = componentStateMetricsList.get(i); for (int j = 0; j < resolveInfosForLauncherSize; j++) { ResolveInfo resolveInfo = resolveInfosForLauncher.get(j); if (componentStateMetrics.isSameComponent(resolveInfo.activityInfo)) { isLauncher = true; break; } } reportComponentStateChanged(componentStateMetrics.mUid, componentStateMetrics.mComponentOldState, componentStateMetrics.mComponentNewState, isLauncher, componentStateMetrics.mIsForWholeApp); } } private static void reportComponentStateChanged(int uid, int componentOldState, int componentNewState, boolean isLauncher, boolean isForWholeApp) { FrameworkStatsLog.write(FrameworkStatsLog.COMPONENT_STATE_CHANGED_REPORTED, uid, componentOldState, componentNewState, isLauncher, isForWholeApp); } private static List<ResolveInfo> getHomeActivitiesResolveInfoAsUser(@NonNull Computer computer, @UserIdInt int userId) { return computer.queryIntentActivitiesInternal(computer.getHomeIntent(), /* resolvedType */ null, /* flags */ 0, userId); } } Loading
services/core/java/com/android/server/pm/PackageManagerService.java +13 −2 Original line number Diff line number Diff line Loading @@ -3984,6 +3984,8 @@ public class PackageManagerService implements PackageSender, TestUtilityService // packageName -> list of components to send broadcasts now final ArrayMap<String, ArrayList<String>> sendNowBroadcasts = new ArrayMap<>(targetSize); final List<PackageMetrics.ComponentStateMetrics> componentStateMetricsList = new ArrayList<PackageMetrics.ComponentStateMetrics>(); synchronized (mLock) { Computer computer = snapshotComputer(); boolean scheduleBroadcastMessage = false; Loading @@ -3997,11 +3999,17 @@ public class PackageManagerService implements PackageSender, TestUtilityService // update enabled settings final ComponentEnabledSetting setting = settings.get(i); final String packageName = setting.getPackageName(); if (!setEnabledSettingInternalLocked(computer, pkgSettings.get(packageName), setting, userId, callingPackage)) { final PackageSetting packageSetting = pkgSettings.get(packageName); final PackageMetrics.ComponentStateMetrics componentStateMetrics = new PackageMetrics.ComponentStateMetrics(setting, UserHandle.getUid(userId, packageSetting.getAppId()), packageSetting.getEnabled(userId)); if (!setEnabledSettingInternalLocked(computer, packageSetting, setting, userId, callingPackage)) { continue; } anyChanged = true; componentStateMetricsList.add(componentStateMetrics); if ((setting.getEnabledFlags() & PackageManager.SYNCHRONOUS) != 0) { isSynchronous = true; Loading Loading @@ -4029,6 +4037,9 @@ public class PackageManagerService implements PackageSender, TestUtilityService return; } // Log the metrics when the component state is changed. PackageMetrics.reportComponentStateChanged(computer, componentStateMetricsList, userId); if (isSynchronous) { flushPackageRestrictionsAsUserInternalLocked(userId); } else { Loading
services/core/java/com/android/server/pm/PackageMetrics.java +83 −0 Original line number Diff line number Diff line Loading @@ -19,12 +19,21 @@ package com.android.server.pm; import static android.os.Process.INVALID_UID; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; import android.app.ActivityManager; import android.app.admin.SecurityLog; import android.content.ComponentName; import android.content.pm.ActivityInfo; import android.content.pm.Flags; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.pm.parsing.ApkLiteParseUtils; import android.os.UserHandle; import android.text.TextUtils; import android.util.Pair; import android.util.Slog; import android.util.SparseArray; import com.android.internal.util.FrameworkStatsLog; Loading @@ -41,12 +50,14 @@ import java.nio.file.Path; import java.nio.file.SimpleFileVisitor; import java.nio.file.attribute.BasicFileAttributes; import java.util.ArrayList; import java.util.List; import java.util.concurrent.atomic.AtomicLong; /** * Metrics class for reporting stats to logging infrastructures like statsd */ final class PackageMetrics { private static final String TAG = "PackageMetrics"; public static final int STEP_PREPARE = 1; public static final int STEP_SCAN = 2; public static final int STEP_RECONCILE = 3; Loading Loading @@ -344,4 +355,76 @@ final class PackageMetrics { SecurityLog.writeEvent(SecurityLog.TAG_PACKAGE_UNINSTALLED, packageName, versionCode, userId); } public static class ComponentStateMetrics { public int mUid; public int mComponentOldState; public int mComponentNewState; public boolean mIsForWholeApp; @NonNull private String mPackageName; @Nullable private String mClassName; ComponentStateMetrics(@NonNull PackageManager.ComponentEnabledSetting setting, int uid, int componentOldState) { mUid = uid; mComponentOldState = componentOldState; mComponentNewState = setting.getEnabledState(); mIsForWholeApp = !setting.isComponent(); mPackageName = setting.getPackageName(); mClassName = setting.getClassName(); } public boolean isSameComponent(ActivityInfo activityInfo) { if (activityInfo == null) { return false; } return mIsForWholeApp ? TextUtils.equals(activityInfo.packageName, mPackageName) : activityInfo.getComponentName().equals( new ComponentName(mPackageName, mClassName)); } } public static void reportComponentStateChanged(@NonNull Computer computer, List<ComponentStateMetrics> componentStateMetricsList, @UserIdInt int userId) { if (!Flags.componentStateChangedMetrics()) { return; } if (componentStateMetricsList == null || componentStateMetricsList.isEmpty()) { Slog.d(TAG, "Fail to report component state due to metrics is empty"); return; } boolean isLauncher = false; final List<ResolveInfo> resolveInfosForLauncher = getHomeActivitiesResolveInfoAsUser( computer, userId); final int resolveInfosForLauncherSize = resolveInfosForLauncher != null ? resolveInfosForLauncher.size() : 0; final int metricsSize = componentStateMetricsList.size(); for (int i = 0; i < metricsSize; i++) { final ComponentStateMetrics componentStateMetrics = componentStateMetricsList.get(i); for (int j = 0; j < resolveInfosForLauncherSize; j++) { ResolveInfo resolveInfo = resolveInfosForLauncher.get(j); if (componentStateMetrics.isSameComponent(resolveInfo.activityInfo)) { isLauncher = true; break; } } reportComponentStateChanged(componentStateMetrics.mUid, componentStateMetrics.mComponentOldState, componentStateMetrics.mComponentNewState, isLauncher, componentStateMetrics.mIsForWholeApp); } } private static void reportComponentStateChanged(int uid, int componentOldState, int componentNewState, boolean isLauncher, boolean isForWholeApp) { FrameworkStatsLog.write(FrameworkStatsLog.COMPONENT_STATE_CHANGED_REPORTED, uid, componentOldState, componentNewState, isLauncher, isForWholeApp); } private static List<ResolveInfo> getHomeActivitiesResolveInfoAsUser(@NonNull Computer computer, @UserIdInt int userId) { return computer.queryIntentActivitiesInternal(computer.getHomeIntent(), /* resolvedType */ null, /* flags */ 0, userId); } }