diff options
5 files changed, 46 insertions, 15 deletions
diff --git a/services/core/java/com/android/server/pm/DeletePackageHelper.java b/services/core/java/com/android/server/pm/DeletePackageHelper.java index 88a3f8e4c8c1..095a7f6066b5 100644 --- a/services/core/java/com/android/server/pm/DeletePackageHelper.java +++ b/services/core/java/com/android/server/pm/DeletePackageHelper.java @@ -261,6 +261,7 @@ final class DeletePackageHelper { final boolean killApp = (deleteFlags & PackageManager.DELETE_DONT_KILL_APP) == 0; info.sendPackageRemovedBroadcasts(killApp, removedBySystem); info.sendSystemPackageUpdatedBroadcasts(); + PackageMetrics.onUninstallSucceeded(info, deleteFlags, mUserManagerInternal); } // Force a gc to clear up things. diff --git a/services/core/java/com/android/server/pm/PackageMetrics.java b/services/core/java/com/android/server/pm/PackageMetrics.java index 0391163856b2..cb87ff5467a8 100644 --- a/services/core/java/com/android/server/pm/PackageMetrics.java +++ b/services/core/java/com/android/server/pm/PackageMetrics.java @@ -19,12 +19,13 @@ package com.android.server.pm; import static android.os.Process.INVALID_UID; import android.annotation.IntDef; +import android.content.pm.PackageManager; import android.content.pm.parsing.ApkLiteParseUtils; -import android.os.UserManager; import android.util.Pair; import android.util.SparseArray; import com.android.internal.util.FrameworkStatsLog; +import com.android.server.LocalServices; import com.android.server.pm.pkg.PackageStateInternal; import java.io.File; @@ -73,6 +74,8 @@ final class PackageMetrics { } private void reportInstallationStats(Computer snapshot, boolean success) { + UserManagerInternal userManagerInternal = + LocalServices.getService(UserManagerInternal.class); // TODO(b/249294752): do not log if adb final long installDurationMillis = System.currentTimeMillis() - mInstallStartTimestampMillis; @@ -93,9 +96,9 @@ final class PackageMetrics { success ? null : packageName /* not report package_name on success */, mInstallRequest.getUid() /* uid */, newUsers /* user_ids */, - getUserTypes(newUsers) /* user_types */, + userManagerInternal.getUserTypesForStatsd(newUsers) /* user_types */, originalUsers /* original_user_ids */, - getUserTypes(originalUsers) /* original_user_types */, + userManagerInternal.getUserTypesForStatsd(originalUsers) /* original_user_types */, mInstallRequest.getReturnCode() /* public_return_code */, 0 /* internal_error_code */, apksSize /* apks_size_bytes */, @@ -163,18 +166,6 @@ final class PackageMetrics { return new Pair<>(stepsArray, durationsArray); } - private static int[] getUserTypes(int[] userIds) { - if (userIds == null) { - return null; - } - final int[] userTypes = new int[userIds.length]; - for (int i = 0; i < userTypes.length; i++) { - String userType = UserManagerService.getInstance().getUserInfo(userIds[i]).userType; - userTypes[i] = UserManager.getUserTypeForStatsd(userType); - } - return userTypes; - } - private static class InstallStep { private final long mStartTimestampMillis; private long mDurationMillis = -1; @@ -191,4 +182,20 @@ final class PackageMetrics { return mDurationMillis; } } + + public static void onUninstallSucceeded(PackageRemovedInfo info, int deleteFlags, + UserManagerInternal userManagerInternal) { + if (info.mIsUpdate) { + // Not logging uninstalls caused by app updates + return; + } + final int[] removedUsers = info.mRemovedUsers; + final int[] removedUserTypes = userManagerInternal.getUserTypesForStatsd(removedUsers); + final int[] originalUsers = info.mOrigUsers; + final int[] originalUserTypes = userManagerInternal.getUserTypesForStatsd(originalUsers); + FrameworkStatsLog.write(FrameworkStatsLog.PACKAGE_UNINSTALLATION_REPORTED, + info.mUid, removedUsers, removedUserTypes, originalUsers, originalUserTypes, + deleteFlags, PackageManager.DELETE_SUCCEEDED, info.mIsRemovedPackageSystemUpdate, + !info.mRemovedForAllUsers); + } } diff --git a/services/core/java/com/android/server/pm/UserManagerInternal.java b/services/core/java/com/android/server/pm/UserManagerInternal.java index 9dafcceefdd0..1420cbf3ae45 100644 --- a/services/core/java/com/android/server/pm/UserManagerInternal.java +++ b/services/core/java/com/android/server/pm/UserManagerInternal.java @@ -437,4 +437,8 @@ public abstract class UserManagerInternal { /** TODO(b/244333150): temporary method until UserVisibilityMediator handles that logic */ public abstract void onUserVisibilityChanged(@UserIdInt int userId, boolean visible); + + /** Return the integer types of the given user IDs. Only used for reporting metrics to statsd. + */ + public abstract int[] getUserTypesForStatsd(@UserIdInt int[] userIds); } diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java index ce4a2ed488ba..73c683274ddf 100644 --- a/services/core/java/com/android/server/pm/UserManagerService.java +++ b/services/core/java/com/android/server/pm/UserManagerService.java @@ -6893,6 +6893,24 @@ public class UserManagerService extends IUserManager.Stub { } }); } + + @Override + public int[] getUserTypesForStatsd(@UserIdInt int[] userIds) { + if (userIds == null) { + return null; + } + final int[] userTypes = new int[userIds.length]; + for (int i = 0; i < userTypes.length; i++) { + final UserInfo userInfo = getUserInfo(userIds[i]); + if (userInfo == null) { + // Not possible because the input user ids should all be valid + userTypes[i] = UserManager.getUserTypeForStatsd(""); + } else { + userTypes[i] = UserManager.getUserTypeForStatsd(userInfo.userType); + } + } + return userTypes; + } } // class LocalService diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/DeletePackageHelperTest.kt b/services/tests/mockingservicestests/src/com/android/server/pm/DeletePackageHelperTest.kt index 7ccd6d993f00..e0662c44b972 100644 --- a/services/tests/mockingservicestests/src/com/android/server/pm/DeletePackageHelperTest.kt +++ b/services/tests/mockingservicestests/src/com/android/server/pm/DeletePackageHelperTest.kt @@ -51,6 +51,7 @@ class DeletePackageHelperTest { mUserManagerInternal = rule.mocks().injector.userManagerInternal whenever(mUserManagerInternal.getUserIds()).thenReturn(intArrayOf(0, 1)) + whenever(mUserManagerInternal.getUserTypesForStatsd(any())).thenReturn(intArrayOf(1, 1)) mPms = createPackageManagerService() doAnswer { false }.`when`(mPms).isPackageDeviceAdmin(any(), any()) |