[pm/metrics][3/n] report uninstall stats on deletion

BUG: 249294752
Test: atest com.android.cts.packagemanager.stats.host.PackageInstallationSessionReportedStatsTests
Change-Id: Ib43e177483d258d5e08e1a0198dc46a895cafc85
This commit is contained in:
Songchun Fan
2022-11-11 14:47:07 -08:00
parent dc0556d7f4
commit cbadbbfaee
5 changed files with 46 additions and 15 deletions

View File

@@ -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.

View File

@@ -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);
}
}

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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())