Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cbadbbfa authored by Songchun Fan's avatar Songchun Fan
Browse files

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

BUG: 249294752
Test: atest com.android.cts.packagemanager.stats.host.PackageInstallationSessionReportedStatsTests
Change-Id: Ib43e177483d258d5e08e1a0198dc46a895cafc85
parent dc0556d7
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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.
+22 −15
Original line number Diff line number Diff line
@@ -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);
    }
}
+4 −0
Original line number Diff line number Diff line
@@ -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);
}
+18 −0
Original line number Diff line number Diff line
@@ -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


+1 −0
Original line number Diff line number Diff line
@@ -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())