diff options
| author | 2024-04-17 12:26:11 +0000 | |
|---|---|---|
| committer | 2024-04-30 18:33:14 +0000 | |
| commit | 29e45bb8e06e4ea79fceb1037b85ec0e7c9990ac (patch) | |
| tree | bb08299ae4391ecebef9298d6660be614f26879c | |
| parent | 4ff9eb1e11693d6c1092ad718a2fa524d33b2bbc (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.java | 15 | ||||
| -rw-r--r-- | services/core/java/com/android/server/pm/PackageMetrics.java | 83 |
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); + } } |