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

Commit f204b36c authored by Anna Bauza's avatar Anna Bauza Committed by Automerger Merge Worker
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 am: cdd7f04f am: 76a1b10a

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/23168143



Change-Id: Ib78f8e4906a993672ae9979f592904e51a4b0ced
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents 02d30ab8 76a1b10a
Loading
Loading
Loading
Loading
+58 −6
Original line number Original line Diff line number Diff line
@@ -99,6 +99,8 @@ public class UserJourneyLogger {
            FrameworkStatsLog.USER_LIFECYCLE_JOURNEY_REPORTED__JOURNEY__GRANT_ADMIN;
            FrameworkStatsLog.USER_LIFECYCLE_JOURNEY_REPORTED__JOURNEY__GRANT_ADMIN;
    public static final int USER_JOURNEY_REVOKE_ADMIN =
    public static final int USER_JOURNEY_REVOKE_ADMIN =
            FrameworkStatsLog.USER_LIFECYCLE_JOURNEY_REPORTED__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 = {
    @IntDef(prefix = {"USER_JOURNEY"}, value = {
            USER_JOURNEY_UNKNOWN,
            USER_JOURNEY_UNKNOWN,
@@ -109,7 +111,8 @@ public class UserJourneyLogger {
            USER_JOURNEY_USER_CREATE,
            USER_JOURNEY_USER_CREATE,
            USER_JOURNEY_USER_REMOVE,
            USER_JOURNEY_USER_REMOVE,
            USER_JOURNEY_GRANT_ADMIN,
            USER_JOURNEY_GRANT_ADMIN,
            USER_JOURNEY_REVOKE_ADMIN
            USER_JOURNEY_REVOKE_ADMIN,
            USER_JOURNEY_USER_LIFECYCLE
    })
    })
    public @interface UserJourney {
    public @interface UserJourney {
    }
    }
@@ -272,11 +275,12 @@ public class UserJourneyLogger {
            int userType, int userFlags, @UserJourneyErrorCode int errorCode) {
            int userType, int userFlags, @UserJourneyErrorCode int errorCode) {
        if (session == null) {
        if (session == null) {
            writeUserLifecycleJourneyReported(-1, journey, originalUserId, targetUserId,
            writeUserLifecycleJourneyReported(-1, journey, originalUserId, targetUserId,
                    userType, userFlags, ERROR_CODE_INVALID_SESSION_ID);
                    userType, userFlags, ERROR_CODE_INVALID_SESSION_ID, -1);
        } else {
        } else {
            final long elapsedTime = System.currentTimeMillis() - session.mStartTimeInMills;
            writeUserLifecycleJourneyReported(
            writeUserLifecycleJourneyReported(
                    session.mSessionId, journey, originalUserId, targetUserId, userType, userFlags,
                    session.mSessionId, journey, originalUserId, targetUserId, userType, userFlags,
                    errorCode);
                    errorCode, elapsedTime);
        }
        }
    }
    }


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


    /**
    /**
@@ -451,6 +455,29 @@ public class UserJourneyLogger {
        return null;
        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
     * 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.
     * 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.
     * Helper class to store user journey and session id.
     *
     *
@@ -542,11 +586,19 @@ public class UserJourneyLogger {
        public final long mSessionId;
        public final long mSessionId;
        @UserJourney
        @UserJourney
        public final int mJourney;
        public final int mJourney;
        public long mStartTimeInMills;


        @VisibleForTesting
        @VisibleForTesting
        public UserJourneySession(long sessionId, @UserJourney int journey) {
        public UserJourneySession(long sessionId, @UserJourney int journey) {
            mJourney = journey;
            mJourney = journey;
            mSessionId = sessionId;
            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 Original line 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_GRANT_ADMIN;
import static com.android.server.pm.UserJourneyLogger.USER_JOURNEY_REVOKE_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_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_REMOVE;


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


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


            try {
            try {
                mAppOpsService.removeUser(userId);
                mAppOpsService.removeUser(userId);
@@ -5560,6 +5563,10 @@ public class UserManagerService extends IUserManager.Stub {
                                mUserJourneyLogger.logUserJourneyFinishWithError(originUserId,
                                mUserJourneyLogger.logUserJourneyFinishWithError(originUserId,
                                        userData.info, USER_JOURNEY_USER_REMOVE,
                                        userData.info, USER_JOURNEY_USER_REMOVE,
                                        ERROR_CODE_UNSPECIFIED);
                                        ERROR_CODE_UNSPECIFIED);
                                mUserJourneyLogger
                                        .logDelayedUserJourneyFinishWithError(originUserId,
                                                userData.info, USER_JOURNEY_USER_LIFECYCLE,
                                                ERROR_CODE_UNSPECIFIED);
                            }
                            }
                            @Override
                            @Override
                            public void userStopAborted(int userIdParam) {
                            public void userStopAborted(int userIdParam) {
@@ -5567,6 +5574,10 @@ public class UserManagerService extends IUserManager.Stub {
                                mUserJourneyLogger.logUserJourneyFinishWithError(originUserId,
                                mUserJourneyLogger.logUserJourneyFinishWithError(originUserId,
                                        userData.info, USER_JOURNEY_USER_REMOVE,
                                        userData.info, USER_JOURNEY_USER_REMOVE,
                                        ERROR_CODE_ABORTED);
                                        ERROR_CODE_ABORTED);
                                mUserJourneyLogger
                                        .logDelayedUserJourneyFinishWithError(originUserId,
                                                userData.info, USER_JOURNEY_USER_LIFECYCLE,
                                                ERROR_CODE_ABORTED);
                            }
                            }
                        });
                        });
            } catch (RemoteException e) {
            } catch (RemoteException e) {
+26 −2
Original line number Original line 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.EVENT_STATE_NONE;
import static com.android.server.pm.UserJourneyLogger.USER_JOURNEY_GRANT_ADMIN;
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_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_REMOVE;
import static com.android.server.pm.UserJourneyLogger.USER_JOURNEY_USER_START;
import static com.android.server.pm.UserJourneyLogger.USER_JOURNEY_USER_START;
import static com.android.server.pm.UserJourneyLogger.USER_JOURNEY_USER_STOP;
import static com.android.server.pm.UserJourneyLogger.USER_JOURNEY_USER_STOP;
@@ -499,6 +500,27 @@ public class UserJourneyLoggerTest {
                0x00000402, ERROR_CODE_UNSPECIFIED, 3);
                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 {
    static class UserLifecycleJourneyReportedCaptor {
        ArgumentCaptor<Long> mSessionId = ArgumentCaptor.forClass(Long.class);
        ArgumentCaptor<Long> mSessionId = ArgumentCaptor.forClass(Long.class);
        ArgumentCaptor<Integer> mJourney = ArgumentCaptor.forClass(Integer.class);
        ArgumentCaptor<Integer> mJourney = ArgumentCaptor.forClass(Integer.class);
@@ -507,6 +529,7 @@ public class UserJourneyLoggerTest {
        ArgumentCaptor<Integer> mUserType = ArgumentCaptor.forClass(Integer.class);
        ArgumentCaptor<Integer> mUserType = ArgumentCaptor.forClass(Integer.class);
        ArgumentCaptor<Integer> mUserFlags = ArgumentCaptor.forClass(Integer.class);
        ArgumentCaptor<Integer> mUserFlags = ArgumentCaptor.forClass(Integer.class);
        ArgumentCaptor<Integer> mErrorCode = ArgumentCaptor.forClass(Integer.class);
        ArgumentCaptor<Integer> mErrorCode = ArgumentCaptor.forClass(Integer.class);
        ArgumentCaptor<Long> mElapsedTime = ArgumentCaptor.forClass(Long.class);


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


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