summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author lpeter <lpeter@google.com> 2024-04-17 12:26:11 +0000
committer lpeter <lpeter@google.com> 2024-04-30 18:33:14 +0000
commit29e45bb8e06e4ea79fceb1037b85ec0e7c9990ac (patch)
treebb08299ae4391ecebef9298d6660be614f26879c
parent4ff9eb1e11693d6c1092ad718a2fa524d33b2bbc (diff)
Implement to log the status of enabling/disabling launcher components
Manual test: Step 1: Download an application (Ex: Smart Launcher 6) Step 2: m statsd_testdrive Step 3: statsd_testdrive 863 Step 4: adb root Step 5: adb shell pm enable --user cur ginlemon.flowerfree/ginlemon.flower.HomeScreen Result: metric_id: 1111 event_metrics { data { aggregated_atom_info { atom { 863: { 1: 10308 2: 0 3: 1 4: 1 5: 0 } } elapsed_timestamp_nanos: 78968154534870 } } } is_active: true estimated_data_bytes: 136 Bug: 316916801 Test: Manual test Change-Id: I5bfe48cf0dc81a5f4679f6c1edbce5e671469c5b
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java15
-rw-r--r--services/core/java/com/android/server/pm/PackageMetrics.java83
2 files changed, 96 insertions, 2 deletions
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 0f4e4821dee8..ae485ede1bec 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -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;
@@ -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;
@@ -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 {
diff --git a/services/core/java/com/android/server/pm/PackageMetrics.java b/services/core/java/com/android/server/pm/PackageMetrics.java
index a0b6897a080e..20598f91a51d 100644
--- a/services/core/java/com/android/server/pm/PackageMetrics.java
+++ b/services/core/java/com/android/server/pm/PackageMetrics.java
@@ -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;
@@ -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;
@@ -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);
+ }
}