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

Commit cdd7f04f authored by Anna Bauza's avatar Anna Bauza Committed by Android (Google) Code Review
Browse files

Merge "Add elapsed time to user journey report and user lifecycle journey...

Merge "Add elapsed time to user journey report and user lifecycle journey (from create to delete)" into udc-dev
parents 17d5ffdf 3e94052b
Loading
Loading
Loading
Loading
+58 −6
Original line number Diff line number Diff line
@@ -99,6 +99,8 @@ public class UserJourneyLogger {
            FrameworkStatsLog.USER_LIFECYCLE_JOURNEY_REPORTED__JOURNEY__GRANT_ADMIN;
    public static final int USER_JOURNEY_REVOKE_ADMIN =
            FrameworkStatsLog.USER_LIFECYCLE_JOURNEY_REPORTED__JOURNEY__REVOKE_ADMIN;
    public static final int USER_JOURNEY_USER_LIFECYCLE =
            FrameworkStatsLog.USER_LIFECYCLE_JOURNEY_REPORTED__JOURNEY__USER_LIFECYCLE;

    @IntDef(prefix = {"USER_JOURNEY"}, value = {
            USER_JOURNEY_UNKNOWN,
@@ -109,7 +111,8 @@ public class UserJourneyLogger {
            USER_JOURNEY_USER_CREATE,
            USER_JOURNEY_USER_REMOVE,
            USER_JOURNEY_GRANT_ADMIN,
            USER_JOURNEY_REVOKE_ADMIN
            USER_JOURNEY_REVOKE_ADMIN,
            USER_JOURNEY_USER_LIFECYCLE
    })
    public @interface UserJourney {
    }
@@ -272,11 +275,12 @@ public class UserJourneyLogger {
            int userType, int userFlags, @UserJourneyErrorCode int errorCode) {
        if (session == null) {
            writeUserLifecycleJourneyReported(-1, journey, originalUserId, targetUserId,
                    userType, userFlags, ERROR_CODE_INVALID_SESSION_ID);
                    userType, userFlags, ERROR_CODE_INVALID_SESSION_ID, -1);
        } else {
            final long elapsedTime = System.currentTimeMillis() - session.mStartTimeInMills;
            writeUserLifecycleJourneyReported(
                    session.mSessionId, journey, originalUserId, targetUserId, userType, userFlags,
                    errorCode);
                    errorCode, elapsedTime);
        }
    }

@@ -285,10 +289,10 @@ public class UserJourneyLogger {
     */
    @VisibleForTesting
    public void writeUserLifecycleJourneyReported(long sessionId, int journey, int originalUserId,
            int targetUserId, int userType, int userFlags, int errorCode) {
            int targetUserId, int userType, int userFlags, int errorCode, long elapsedTime) {
        FrameworkStatsLog.write(FrameworkStatsLog.USER_LIFECYCLE_JOURNEY_REPORTED,
                sessionId, journey, originalUserId, targetUserId, userType, userFlags,
                errorCode);
                errorCode, elapsedTime);
    }

    /**
@@ -451,6 +455,29 @@ public class UserJourneyLogger {
        return null;
    }

    /**
     * Log user journey event and report finishing with error
     */
    public UserJourneySession logDelayedUserJourneyFinishWithError(@UserIdInt int originalUserId,
            UserInfo targetUser, @UserJourney int journey, @UserJourneyErrorCode int errorCode) {
        synchronized (mLock) {
            final int key = getUserJourneyKey(targetUser.id, journey);
            final UserJourneySession userJourneySession = mUserIdToUserJourneyMap.get(key);
            if (userJourneySession != null) {
                logUserLifecycleJourneyReported(
                        userJourneySession,
                        journey, originalUserId, targetUser.id,
                        getUserTypeForStatsd(targetUser.userType),
                        targetUser.flags,
                        errorCode);
                mUserIdToUserJourneyMap.remove(key);

                return userJourneySession;
            }
        }
        return null;
    }

    /**
     * Log event and report finish when user is null. This is edge case when UserInfo
     * can not be passed because it is null, therefore all information are passed as arguments.
@@ -532,6 +559,23 @@ public class UserJourneyLogger {
        }
    }

    /**
     * This keeps the start time when finishing extensively long journey was began.
     * For instance full user lifecycle ( from creation to deletion )when user is about to delete
     * we need to get user creation time before it was deleted.
     */
    public UserJourneySession startSessionForDelayedJourney(@UserIdInt int targetId,
            @UserJourney int journey, long startTime) {
        final long newSessionId = ThreadLocalRandom.current().nextLong(1, Long.MAX_VALUE);
        synchronized (mLock) {
            final int key = getUserJourneyKey(targetId, journey);
            final UserJourneySession userJourneySession =
                    new UserJourneySession(newSessionId, journey, startTime);
            mUserIdToUserJourneyMap.append(key, userJourneySession);
            return userJourneySession;
        }
    }

    /**
     * Helper class to store user journey and session id.
     *
@@ -542,11 +586,19 @@ public class UserJourneyLogger {
        public final long mSessionId;
        @UserJourney
        public final int mJourney;
        public long mStartTimeInMills;

        @VisibleForTesting
        public UserJourneySession(long sessionId, @UserJourney int journey) {
            mJourney = journey;
            mSessionId = sessionId;
            mStartTimeInMills = System.currentTimeMillis();
        }
        @VisibleForTesting
        public UserJourneySession(long sessionId, @UserJourney int journey, long startTimeInMills) {
            mJourney = journey;
            mSessionId = sessionId;
            mStartTimeInMills = startTimeInMills;
        }
    }
}
 No newline at end of file
+12 −1
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ import static com.android.server.pm.UserJourneyLogger.ERROR_CODE_USER_IS_NOT_AN_
import static com.android.server.pm.UserJourneyLogger.USER_JOURNEY_GRANT_ADMIN;
import static com.android.server.pm.UserJourneyLogger.USER_JOURNEY_REVOKE_ADMIN;
import static com.android.server.pm.UserJourneyLogger.USER_JOURNEY_USER_CREATE;
import static com.android.server.pm.UserJourneyLogger.USER_JOURNEY_USER_LIFECYCLE;
import static com.android.server.pm.UserJourneyLogger.USER_JOURNEY_USER_REMOVE;

import android.Manifest;
@@ -5535,6 +5536,8 @@ public class UserManagerService extends IUserManager.Stub {
            }

            mUserJourneyLogger.logUserJourneyBegin(userId, USER_JOURNEY_USER_REMOVE);
            mUserJourneyLogger.startSessionForDelayedJourney(userId,
                    USER_JOURNEY_USER_LIFECYCLE, userData.info.creationTime);

            try {
                mAppOpsService.removeUser(userId);
@@ -5560,6 +5563,10 @@ public class UserManagerService extends IUserManager.Stub {
                                mUserJourneyLogger.logUserJourneyFinishWithError(originUserId,
                                        userData.info, USER_JOURNEY_USER_REMOVE,
                                        ERROR_CODE_UNSPECIFIED);
                                mUserJourneyLogger
                                        .logDelayedUserJourneyFinishWithError(originUserId,
                                                userData.info, USER_JOURNEY_USER_LIFECYCLE,
                                                ERROR_CODE_UNSPECIFIED);
                            }
                            @Override
                            public void userStopAborted(int userIdParam) {
@@ -5567,6 +5574,10 @@ public class UserManagerService extends IUserManager.Stub {
                                mUserJourneyLogger.logUserJourneyFinishWithError(originUserId,
                                        userData.info, USER_JOURNEY_USER_REMOVE,
                                        ERROR_CODE_ABORTED);
                                mUserJourneyLogger
                                        .logDelayedUserJourneyFinishWithError(originUserId,
                                                userData.info, USER_JOURNEY_USER_LIFECYCLE,
                                                ERROR_CODE_ABORTED);
                            }
                        });
            } catch (RemoteException e) {
+26 −2
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ import static com.android.server.pm.UserJourneyLogger.EVENT_STATE_FINISH;
import static com.android.server.pm.UserJourneyLogger.EVENT_STATE_NONE;
import static com.android.server.pm.UserJourneyLogger.USER_JOURNEY_GRANT_ADMIN;
import static com.android.server.pm.UserJourneyLogger.USER_JOURNEY_USER_CREATE;
import static com.android.server.pm.UserJourneyLogger.USER_JOURNEY_USER_LIFECYCLE;
import static com.android.server.pm.UserJourneyLogger.USER_JOURNEY_USER_REMOVE;
import static com.android.server.pm.UserJourneyLogger.USER_JOURNEY_USER_START;
import static com.android.server.pm.UserJourneyLogger.USER_JOURNEY_USER_STOP;
@@ -499,6 +500,27 @@ public class UserJourneyLoggerTest {
                0x00000402, ERROR_CODE_UNSPECIFIED, 3);
    }

    @Test
    public void testUserLifecycleJourney() {
        final long startTime = System.currentTimeMillis();
        final UserJourneyLogger.UserJourneySession session = mUserJourneyLogger
                .startSessionForDelayedJourney(10, USER_JOURNEY_USER_LIFECYCLE, startTime);


        final UserLifecycleJourneyReportedCaptor report = new UserLifecycleJourneyReportedCaptor();
        final UserInfo targetUser = new UserInfo(10, "test target user",
                UserInfo.FLAG_ADMIN | UserInfo.FLAG_FULL);
        mUserJourneyLogger.logDelayedUserJourneyFinishWithError(0, targetUser,
                USER_JOURNEY_USER_LIFECYCLE, ERROR_CODE_UNSPECIFIED);


        report.captureAndAssert(mUserJourneyLogger, session.mSessionId,
                USER_JOURNEY_USER_LIFECYCLE, 0, 10,
                FrameworkStatsLog.USER_LIFECYCLE_JOURNEY_REPORTED__USER_TYPE__FULL_SECONDARY,
                0x00000402, ERROR_CODE_UNSPECIFIED, 1);
        assertThat(report.mElapsedTime.getValue() > 0L).isTrue();
    }

    static class UserLifecycleJourneyReportedCaptor {
        ArgumentCaptor<Long> mSessionId = ArgumentCaptor.forClass(Long.class);
        ArgumentCaptor<Integer> mJourney = ArgumentCaptor.forClass(Integer.class);
@@ -507,6 +529,7 @@ public class UserJourneyLoggerTest {
        ArgumentCaptor<Integer> mUserType = ArgumentCaptor.forClass(Integer.class);
        ArgumentCaptor<Integer> mUserFlags = ArgumentCaptor.forClass(Integer.class);
        ArgumentCaptor<Integer> mErrorCode = ArgumentCaptor.forClass(Integer.class);
        ArgumentCaptor<Long> mElapsedTime = ArgumentCaptor.forClass(Long.class);

        public void captureAndAssert(UserJourneyLogger mUserJourneyLogger,
                long sessionId, int journey, int originalUserId,
@@ -518,7 +541,8 @@ public class UserJourneyLoggerTest {
                            mTargetUserId.capture(),
                            mUserType.capture(),
                            mUserFlags.capture(),
                            mErrorCode.capture());
                            mErrorCode.capture(),
                            mElapsedTime.capture());

            assertThat(mSessionId.getValue()).isEqualTo(sessionId);
            assertThat(mJourney.getValue()).isEqualTo(journey);