Merge "Add new atoms to track user journeys, such as user switches." into rvc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
58df220212
@@ -421,6 +421,8 @@ message Atom {
|
|||||||
TvSettingsUIInteracted tvsettings_ui_interacted = 261 [(module) = "tv_settings"];
|
TvSettingsUIInteracted tvsettings_ui_interacted = 261 [(module) = "tv_settings"];
|
||||||
LauncherStaticLayout launcher_snapshot = 262 [(module) = "sysui"];
|
LauncherStaticLayout launcher_snapshot = 262 [(module) = "sysui"];
|
||||||
PackageInstallerV2Reported package_installer_v2_reported = 263 [(module) = "framework"];
|
PackageInstallerV2Reported package_installer_v2_reported = 263 [(module) = "framework"];
|
||||||
|
UserLifecycleJourneyReported user_lifecycle_journey_reported = 264 [(module) = "framework"];
|
||||||
|
UserLifecycleEventOccurred user_lifecycle_event_occurred = 265 [(module) = "framework"];
|
||||||
SdkExtensionStatus sdk_extension_status = 354;
|
SdkExtensionStatus sdk_extension_status = 354;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -9357,3 +9359,82 @@ message SettingSnapshot {
|
|||||||
// Android user index. 0 for primary user, 10, 11 for secondary or profile user
|
// Android user index. 0 for primary user, 10, 11 for secondary or profile user
|
||||||
optional int32 user_id = 7;
|
optional int32 user_id = 7;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An event logged to indicate that a user journey is about to be performed. This atom includes
|
||||||
|
* relevant information about the users involved in the journey. A UserLifecycleEventOccurred event
|
||||||
|
* will immediately follow this atom which will describe the event(s) and its state.
|
||||||
|
*
|
||||||
|
* Logged from:
|
||||||
|
* frameworks/base/services/core/java/com/android/server/am/UserController.java
|
||||||
|
* frameworks/base/services/core/java/com/android/server/pm/UserManagerService.java
|
||||||
|
*/
|
||||||
|
message UserLifecycleJourneyReported {
|
||||||
|
// An identifier to track a chain of user lifecycle events occurring (referenced in the
|
||||||
|
// UserLifecycleEventOccurred atom)
|
||||||
|
optional int64 session_id = 1;
|
||||||
|
|
||||||
|
// Indicates what type of user journey this session is related to
|
||||||
|
enum Journey {
|
||||||
|
UNKNOWN = 0; // Undefined user lifecycle journey
|
||||||
|
USER_SWITCH_UI = 1; // A user switch journey where a UI is shown
|
||||||
|
USER_SWITCH_FG = 2; // A user switch journey without a UI shown
|
||||||
|
USER_START = 3; // A user start journey
|
||||||
|
USER_CREATE = 4; // A user creation journey
|
||||||
|
}
|
||||||
|
optional Journey journey = 2;
|
||||||
|
// Which user the journey is originating from - could be -1 for certain phases (eg USER_CREATE)
|
||||||
|
// This integer is a UserIdInt (eg 0 for the system user, 10 for secondary/guest)
|
||||||
|
optional int32 origin_user = 3;
|
||||||
|
// Which user the journey is targeting
|
||||||
|
// This integer is a UserIdInt (eg 0 for the system user, 10 for secondary/guest)
|
||||||
|
optional int32 target_user = 4;
|
||||||
|
|
||||||
|
// What is the user type of the target user
|
||||||
|
// These should be in sync with USER_TYPE_* flags defined in UserManager.java
|
||||||
|
enum UserType {
|
||||||
|
TYPE_UNKNOWN = 0;
|
||||||
|
FULL_SYSTEM = 1;
|
||||||
|
FULL_SECONDARY = 2;
|
||||||
|
FULL_GUEST = 3;
|
||||||
|
FULL_DEMO = 4;
|
||||||
|
FULL_RESTRICTED = 5;
|
||||||
|
PROFILE_MANAGED = 6;
|
||||||
|
SYSTEM_HEADLESS = 7;
|
||||||
|
}
|
||||||
|
optional UserType user_type = 5;
|
||||||
|
// What are the flags attached to the target user
|
||||||
|
optional int32 user_flags = 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An event logged when a specific user lifecycle event is performed. These events should be
|
||||||
|
* correlated with a UserLifecycleJourneyReported atom via the session_id.
|
||||||
|
* Note: journeys can span over multiple events, hence some events may share a single session id.
|
||||||
|
*
|
||||||
|
* Logged from:
|
||||||
|
* frameworks/base/services/core/java/com/android/server/am/UserController.java
|
||||||
|
* frameworks/base/services/core/java/com/android/server/pm/UserManagerService.java
|
||||||
|
*/
|
||||||
|
message UserLifecycleEventOccurred {
|
||||||
|
// An id which links back to user details (reported in the UserLifecycleJourneyReported atom)
|
||||||
|
optional int64 session_id = 1;
|
||||||
|
// The target user for this event (same as target_user in the UserLifecycleJourneyReported atom)
|
||||||
|
// This integer is a UserIdInt (eg 0 for the system user, 10 for secondary/guest)
|
||||||
|
optional int32 user_id = 2;
|
||||||
|
|
||||||
|
enum Event {
|
||||||
|
UNKNOWN = 0; // Indicates that the associated user journey timed-out or resulted in an error
|
||||||
|
SWITCH_USER = 1; // Indicates that this is a user switch event
|
||||||
|
START_USER = 2; // Indicates that this is a user start event
|
||||||
|
CREATE_USER = 3; // Indicates that this is a user create event
|
||||||
|
}
|
||||||
|
optional Event event = 3;
|
||||||
|
|
||||||
|
enum State {
|
||||||
|
NONE = 0; // Indicates the associated event has no start/end defined
|
||||||
|
BEGIN = 1;
|
||||||
|
FINISH = 2;
|
||||||
|
}
|
||||||
|
optional State state = 4; // Represents the state of an event (beginning/ending)
|
||||||
|
}
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ import android.view.WindowManager.LayoutParams;
|
|||||||
|
|
||||||
import com.android.internal.R;
|
import com.android.internal.R;
|
||||||
import com.android.internal.os.RoSystemProperties;
|
import com.android.internal.os.RoSystemProperties;
|
||||||
|
import com.android.internal.util.FrameworkStatsLog;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
@@ -1840,6 +1841,35 @@ public class UserManager {
|
|||||||
return USER_TYPE_FULL_DEMO.equals(userType);
|
return USER_TYPE_FULL_DEMO.equals(userType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the enum defined in the statsd UserLifecycleJourneyReported atom corresponding to the
|
||||||
|
* user type.
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public static int getUserTypeForStatsd(@NonNull String userType) {
|
||||||
|
switch (userType) {
|
||||||
|
case USER_TYPE_FULL_SYSTEM:
|
||||||
|
return FrameworkStatsLog.USER_LIFECYCLE_JOURNEY_REPORTED__USER_TYPE__FULL_SYSTEM;
|
||||||
|
case USER_TYPE_FULL_SECONDARY:
|
||||||
|
return FrameworkStatsLog.USER_LIFECYCLE_JOURNEY_REPORTED__USER_TYPE__FULL_SECONDARY;
|
||||||
|
case USER_TYPE_FULL_GUEST:
|
||||||
|
return FrameworkStatsLog.USER_LIFECYCLE_JOURNEY_REPORTED__USER_TYPE__FULL_GUEST;
|
||||||
|
case USER_TYPE_FULL_DEMO:
|
||||||
|
return FrameworkStatsLog.USER_LIFECYCLE_JOURNEY_REPORTED__USER_TYPE__FULL_DEMO;
|
||||||
|
case USER_TYPE_FULL_RESTRICTED:
|
||||||
|
return FrameworkStatsLog
|
||||||
|
.USER_LIFECYCLE_JOURNEY_REPORTED__USER_TYPE__FULL_RESTRICTED;
|
||||||
|
case USER_TYPE_PROFILE_MANAGED:
|
||||||
|
return FrameworkStatsLog
|
||||||
|
.USER_LIFECYCLE_JOURNEY_REPORTED__USER_TYPE__PROFILE_MANAGED;
|
||||||
|
case USER_TYPE_SYSTEM_HEADLESS:
|
||||||
|
return FrameworkStatsLog
|
||||||
|
.USER_LIFECYCLE_JOURNEY_REPORTED__USER_TYPE__SYSTEM_HEADLESS;
|
||||||
|
default:
|
||||||
|
return FrameworkStatsLog.USER_LIFECYCLE_JOURNEY_REPORTED__USER_TYPE__TYPE_UNKNOWN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @hide
|
* @hide
|
||||||
* @deprecated Use {@link #isRestrictedProfile()}
|
* @deprecated Use {@link #isRestrictedProfile()}
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ import static com.android.server.am.UserState.STATE_RUNNING_LOCKED;
|
|||||||
import static com.android.server.am.UserState.STATE_RUNNING_UNLOCKED;
|
import static com.android.server.am.UserState.STATE_RUNNING_UNLOCKED;
|
||||||
import static com.android.server.am.UserState.STATE_RUNNING_UNLOCKING;
|
import static com.android.server.am.UserState.STATE_RUNNING_UNLOCKING;
|
||||||
|
|
||||||
|
import android.annotation.IntDef;
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
import android.annotation.UserIdInt;
|
import android.annotation.UserIdInt;
|
||||||
@@ -89,6 +90,7 @@ import android.util.Pair;
|
|||||||
import android.util.Slog;
|
import android.util.Slog;
|
||||||
import android.util.SparseArray;
|
import android.util.SparseArray;
|
||||||
import android.util.SparseIntArray;
|
import android.util.SparseIntArray;
|
||||||
|
import android.util.SparseLongArray;
|
||||||
import android.util.proto.ProtoOutputStream;
|
import android.util.proto.ProtoOutputStream;
|
||||||
|
|
||||||
import com.android.internal.R;
|
import com.android.internal.R;
|
||||||
@@ -112,6 +114,7 @@ import java.util.Arrays;
|
|||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.concurrent.ThreadLocalRandom;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -162,6 +165,46 @@ class UserController implements Handler.Callback {
|
|||||||
// TODO(b/149604218): STOPSHIP remove this constant and the logcat
|
// TODO(b/149604218): STOPSHIP remove this constant and the logcat
|
||||||
private static final boolean TESTS_NEED_LOGCAT = true;
|
private static final boolean TESTS_NEED_LOGCAT = true;
|
||||||
|
|
||||||
|
// Used for statsd logging with UserLifecycleJourneyReported + UserLifecycleEventOccurred atoms
|
||||||
|
private static final long INVALID_SESSION_ID = 0;
|
||||||
|
|
||||||
|
// The various user journeys, defined in the UserLifecycleJourneyReported atom for statsd
|
||||||
|
private static final int USER_JOURNEY_UNKNOWN =
|
||||||
|
FrameworkStatsLog.USER_LIFECYCLE_JOURNEY_REPORTED__JOURNEY__UNKNOWN;
|
||||||
|
private static final int USER_JOURNEY_USER_SWITCH_FG =
|
||||||
|
FrameworkStatsLog.USER_LIFECYCLE_JOURNEY_REPORTED__JOURNEY__USER_SWITCH_FG;
|
||||||
|
private static final int USER_JOURNEY_USER_SWITCH_UI =
|
||||||
|
FrameworkStatsLog.USER_LIFECYCLE_JOURNEY_REPORTED__JOURNEY__USER_SWITCH_UI;
|
||||||
|
private static final int USER_JOURNEY_USER_START =
|
||||||
|
FrameworkStatsLog.USER_LIFECYCLE_JOURNEY_REPORTED__JOURNEY__USER_START;
|
||||||
|
private static final int USER_JOURNEY_USER_CREATE =
|
||||||
|
FrameworkStatsLog.USER_LIFECYCLE_JOURNEY_REPORTED__JOURNEY__USER_CREATE;
|
||||||
|
@IntDef(prefix = { "USER_JOURNEY" }, value = {
|
||||||
|
USER_JOURNEY_UNKNOWN,
|
||||||
|
USER_JOURNEY_USER_SWITCH_FG,
|
||||||
|
USER_JOURNEY_USER_SWITCH_UI,
|
||||||
|
USER_JOURNEY_USER_START,
|
||||||
|
USER_JOURNEY_USER_CREATE,
|
||||||
|
})
|
||||||
|
@interface UserJourney {}
|
||||||
|
|
||||||
|
// The various user lifecycle events, defined in the UserLifecycleEventOccurred atom for statsd
|
||||||
|
private static final int USER_LIFECYCLE_EVENT_UNKNOWN =
|
||||||
|
FrameworkStatsLog.USER_LIFECYCLE_EVENT_OCCURRED__EVENT__UNKNOWN;
|
||||||
|
private static final int USER_LIFECYCLE_EVENT_SWITCH_USER =
|
||||||
|
FrameworkStatsLog.USER_LIFECYCLE_EVENT_OCCURRED__EVENT__SWITCH_USER;
|
||||||
|
private static final int USER_LIFECYCLE_EVENT_START_USER =
|
||||||
|
FrameworkStatsLog.USER_LIFECYCLE_EVENT_OCCURRED__EVENT__START_USER;
|
||||||
|
private static final int USER_LIFECYCLE_EVENT_CREATE_USER =
|
||||||
|
FrameworkStatsLog.USER_LIFECYCLE_EVENT_OCCURRED__EVENT__CREATE_USER;
|
||||||
|
@IntDef(prefix = { "USER_LIFECYCLE_EVENT" }, value = {
|
||||||
|
USER_LIFECYCLE_EVENT_UNKNOWN,
|
||||||
|
USER_LIFECYCLE_EVENT_SWITCH_USER,
|
||||||
|
USER_LIFECYCLE_EVENT_START_USER,
|
||||||
|
USER_LIFECYCLE_EVENT_CREATE_USER,
|
||||||
|
})
|
||||||
|
@interface UserLifecycleEvent {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maximum number of users we allow to be running at a time, including system user.
|
* Maximum number of users we allow to be running at a time, including system user.
|
||||||
*
|
*
|
||||||
@@ -270,6 +313,13 @@ class UserController implements Handler.Callback {
|
|||||||
@GuardedBy("mLock")
|
@GuardedBy("mLock")
|
||||||
private final ArrayList<Integer> mLastActiveUsers = new ArrayList<>();
|
private final ArrayList<Integer> mLastActiveUsers = new ArrayList<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A per-user, journey to session id map, used for statsd logging for the
|
||||||
|
* UserLifecycleJourneyReported and UserLifecycleEventOccurred atoms.
|
||||||
|
*/
|
||||||
|
@GuardedBy("mUserJourneyToSessionIdMap")
|
||||||
|
private final SparseArray<SparseLongArray> mUserJourneyToSessionIdMap = new SparseArray<>();
|
||||||
|
|
||||||
UserController(ActivityManagerService service) {
|
UserController(ActivityManagerService service) {
|
||||||
this(new Injector(service));
|
this(new Injector(service));
|
||||||
}
|
}
|
||||||
@@ -2349,6 +2399,10 @@ class UserController implements Handler.Callback {
|
|||||||
public boolean handleMessage(Message msg) {
|
public boolean handleMessage(Message msg) {
|
||||||
switch (msg.what) {
|
switch (msg.what) {
|
||||||
case START_USER_SWITCH_FG_MSG:
|
case START_USER_SWITCH_FG_MSG:
|
||||||
|
logUserJourneyInfo(getUserInfo(getCurrentUserId()), getUserInfo(msg.arg1),
|
||||||
|
USER_JOURNEY_USER_SWITCH_FG);
|
||||||
|
logUserLifecycleEvent(msg.arg1, USER_JOURNEY_USER_SWITCH_FG,
|
||||||
|
USER_LIFECYCLE_EVENT_SWITCH_USER, true);
|
||||||
startUserInForeground(msg.arg1);
|
startUserInForeground(msg.arg1);
|
||||||
break;
|
break;
|
||||||
case REPORT_USER_SWITCH_MSG:
|
case REPORT_USER_SWITCH_MSG:
|
||||||
@@ -2370,8 +2424,14 @@ class UserController implements Handler.Callback {
|
|||||||
mInjector.batteryStatsServiceNoteEvent(
|
mInjector.batteryStatsServiceNoteEvent(
|
||||||
BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
|
BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
|
||||||
Integer.toString(msg.arg1), msg.arg1);
|
Integer.toString(msg.arg1), msg.arg1);
|
||||||
|
logUserJourneyInfo(null, getUserInfo(msg.arg1), USER_JOURNEY_USER_START);
|
||||||
|
logUserLifecycleEvent(msg.arg1, USER_JOURNEY_USER_START,
|
||||||
|
USER_LIFECYCLE_EVENT_START_USER, true);
|
||||||
mInjector.getSystemServiceManager().startUser(TimingsTraceAndSlog.newAsyncLog(),
|
mInjector.getSystemServiceManager().startUser(TimingsTraceAndSlog.newAsyncLog(),
|
||||||
msg.arg1);
|
msg.arg1);
|
||||||
|
logUserLifecycleEvent(msg.arg1, USER_JOURNEY_USER_START,
|
||||||
|
USER_LIFECYCLE_EVENT_START_USER, false);
|
||||||
|
clearSessionId(msg.arg1, USER_JOURNEY_USER_START);
|
||||||
break;
|
break;
|
||||||
case USER_UNLOCK_MSG:
|
case USER_UNLOCK_MSG:
|
||||||
final int userId = msg.arg1;
|
final int userId = msg.arg1;
|
||||||
@@ -2400,17 +2460,94 @@ class UserController implements Handler.Callback {
|
|||||||
break;
|
break;
|
||||||
case REPORT_USER_SWITCH_COMPLETE_MSG:
|
case REPORT_USER_SWITCH_COMPLETE_MSG:
|
||||||
dispatchUserSwitchComplete(msg.arg1);
|
dispatchUserSwitchComplete(msg.arg1);
|
||||||
|
final int currentJourney = mUserSwitchUiEnabled ? USER_JOURNEY_USER_SWITCH_UI
|
||||||
|
: USER_JOURNEY_USER_SWITCH_FG;
|
||||||
|
logUserLifecycleEvent(msg.arg1, currentJourney,
|
||||||
|
USER_LIFECYCLE_EVENT_SWITCH_USER, false);
|
||||||
|
clearSessionId(msg.arg1, currentJourney);
|
||||||
break;
|
break;
|
||||||
case REPORT_LOCKED_BOOT_COMPLETE_MSG:
|
case REPORT_LOCKED_BOOT_COMPLETE_MSG:
|
||||||
dispatchLockedBootComplete(msg.arg1);
|
dispatchLockedBootComplete(msg.arg1);
|
||||||
break;
|
break;
|
||||||
case START_USER_SWITCH_UI_MSG:
|
case START_USER_SWITCH_UI_MSG:
|
||||||
showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
|
final Pair<UserInfo, UserInfo> fromToUserPair = (Pair<UserInfo, UserInfo>) msg.obj;
|
||||||
|
logUserJourneyInfo(fromToUserPair.first, fromToUserPair.second,
|
||||||
|
USER_JOURNEY_USER_SWITCH_UI);
|
||||||
|
logUserLifecycleEvent(fromToUserPair.second.id, USER_JOURNEY_USER_SWITCH_UI,
|
||||||
|
USER_LIFECYCLE_EVENT_SWITCH_USER, true);
|
||||||
|
showUserSwitchDialog(fromToUserPair);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* statsd helper method for logging the start of a user journey via a UserLifecycleEventOccurred
|
||||||
|
* atom given the originating and targeting users for the journey.
|
||||||
|
*
|
||||||
|
* Note: these info atoms are currently logged more than once per journey since there is no
|
||||||
|
* state associated with the user's ongoing journey - this will be updated in a later CL.
|
||||||
|
*/
|
||||||
|
private void logUserJourneyInfo(UserInfo origin, UserInfo target, @UserJourney int journey) {
|
||||||
|
final long newSessionId = ThreadLocalRandom.current().nextLong(1, Long.MAX_VALUE);
|
||||||
|
synchronized (mUserJourneyToSessionIdMap) {
|
||||||
|
SparseLongArray userSessions = mUserJourneyToSessionIdMap.get(target.id);
|
||||||
|
if (userSessions == null) {
|
||||||
|
userSessions = new SparseLongArray();
|
||||||
|
mUserJourneyToSessionIdMap.put(target.id, userSessions);
|
||||||
|
}
|
||||||
|
final long oldSessionId = userSessions.get(journey);
|
||||||
|
if (oldSessionId != INVALID_SESSION_ID) {
|
||||||
|
// potentially an incomplete or timed-out session
|
||||||
|
FrameworkStatsLog.write(FrameworkStatsLog.USER_LIFECYCLE_EVENT_OCCURRED,
|
||||||
|
oldSessionId, target.id, USER_LIFECYCLE_EVENT_UNKNOWN,
|
||||||
|
FrameworkStatsLog.USER_LIFECYCLE_EVENT_OCCURRED__STATE__NONE);
|
||||||
|
}
|
||||||
|
// update session id
|
||||||
|
userSessions.put(journey, newSessionId);
|
||||||
|
}
|
||||||
|
|
||||||
|
FrameworkStatsLog.write(FrameworkStatsLog.USER_LIFECYCLE_JOURNEY_REPORTED, newSessionId,
|
||||||
|
journey, origin != null ? origin.id : -1,
|
||||||
|
target.id, UserManager.getUserTypeForStatsd(target.userType), target.flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* statsd helper method for logging the begin or finish of the given event for the
|
||||||
|
* UserLifecycleEventOccurred statsd atom.
|
||||||
|
* Note: This does not clear the user's journey session id - if this event represents the end of
|
||||||
|
* a particular journey, call {@link #clearSessionId} to indicate that the session is over.
|
||||||
|
*/
|
||||||
|
private void logUserLifecycleEvent(@UserIdInt int userId, @UserJourney int journey,
|
||||||
|
@UserLifecycleEvent int event, boolean begin) {
|
||||||
|
final long sessionId;
|
||||||
|
synchronized (mUserJourneyToSessionIdMap) {
|
||||||
|
final SparseLongArray eventToSessionMap = mUserJourneyToSessionIdMap.get(userId);
|
||||||
|
if (eventToSessionMap == null || eventToSessionMap.size() == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sessionId = eventToSessionMap.get(journey);
|
||||||
|
if (sessionId == INVALID_SESSION_ID) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FrameworkStatsLog.write(FrameworkStatsLog.USER_LIFECYCLE_EVENT_OCCURRED, sessionId, userId,
|
||||||
|
event, begin ? FrameworkStatsLog.USER_LIFECYCLE_EVENT_OCCURRED__STATE__BEGIN
|
||||||
|
: FrameworkStatsLog.USER_LIFECYCLE_EVENT_OCCURRED__STATE__FINISH);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clears the user's session id associated with the given UserJourney (for statsd).
|
||||||
|
*/
|
||||||
|
private void clearSessionId(@UserIdInt int userId, @UserJourney int journey) {
|
||||||
|
synchronized (mUserJourneyToSessionIdMap) {
|
||||||
|
if (mUserJourneyToSessionIdMap.get(userId) != null) {
|
||||||
|
mUserJourneyToSessionIdMap.get(userId).delete(journey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static class UserProgressListener extends IProgressListener.Stub {
|
private static class UserProgressListener extends IProgressListener.Stub {
|
||||||
private volatile long mUnlockStarted;
|
private volatile long mUnlockStarted;
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -103,6 +103,7 @@ import com.android.internal.logging.MetricsLogger;
|
|||||||
import com.android.internal.os.BackgroundThread;
|
import com.android.internal.os.BackgroundThread;
|
||||||
import com.android.internal.util.DumpUtils;
|
import com.android.internal.util.DumpUtils;
|
||||||
import com.android.internal.util.FastXmlSerializer;
|
import com.android.internal.util.FastXmlSerializer;
|
||||||
|
import com.android.internal.util.FrameworkStatsLog;
|
||||||
import com.android.internal.util.Preconditions;
|
import com.android.internal.util.Preconditions;
|
||||||
import com.android.internal.util.XmlUtils;
|
import com.android.internal.util.XmlUtils;
|
||||||
import com.android.internal.widget.LockPatternUtils;
|
import com.android.internal.widget.LockPatternUtils;
|
||||||
@@ -137,6 +138,7 @@ import java.util.LinkedList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.ThreadLocalRandom;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Service for {@link UserManager}.
|
* Service for {@link UserManager}.
|
||||||
@@ -3244,16 +3246,39 @@ public class UserManagerService extends IUserManager.Stub {
|
|||||||
@NonNull String userType, @UserInfoFlag int flags, @UserIdInt int parentId,
|
@NonNull String userType, @UserInfoFlag int flags, @UserIdInt int parentId,
|
||||||
boolean preCreate, @Nullable String[] disallowedPackages)
|
boolean preCreate, @Nullable String[] disallowedPackages)
|
||||||
throws UserManager.CheckedUserOperationException {
|
throws UserManager.CheckedUserOperationException {
|
||||||
|
final int nextProbableUserId = getNextAvailableId();
|
||||||
final TimingsTraceAndSlog t = new TimingsTraceAndSlog();
|
final TimingsTraceAndSlog t = new TimingsTraceAndSlog();
|
||||||
t.traceBegin("createUser-" + flags);
|
t.traceBegin("createUser-" + flags);
|
||||||
|
final long sessionId = logUserCreateJourneyBegin(nextProbableUserId, userType, flags);
|
||||||
try {
|
try {
|
||||||
return createUserInternalUncheckedNoTracing(name, userType, flags, parentId,
|
return createUserInternalUncheckedNoTracing(name, userType, flags, parentId,
|
||||||
preCreate, disallowedPackages, t);
|
preCreate, disallowedPackages, t);
|
||||||
} finally {
|
} finally {
|
||||||
|
logUserCreateJourneyFinish(sessionId, nextProbableUserId);
|
||||||
t.traceEnd();
|
t.traceEnd();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private long logUserCreateJourneyBegin(@UserIdInt int userId, String userType,
|
||||||
|
@UserInfoFlag int flags) {
|
||||||
|
final long sessionId = ThreadLocalRandom.current().nextLong(1, Long.MAX_VALUE);
|
||||||
|
// log the journey atom with the user metadata
|
||||||
|
FrameworkStatsLog.write(FrameworkStatsLog.USER_LIFECYCLE_JOURNEY_REPORTED, sessionId,
|
||||||
|
FrameworkStatsLog.USER_LIFECYCLE_JOURNEY_REPORTED__JOURNEY__USER_CREATE,
|
||||||
|
/* origin_user= */ -1, userId, UserManager.getUserTypeForStatsd(userType), flags);
|
||||||
|
// log the event atom to indicate the event start
|
||||||
|
FrameworkStatsLog.write(FrameworkStatsLog.USER_LIFECYCLE_EVENT_OCCURRED, sessionId, userId,
|
||||||
|
FrameworkStatsLog.USER_LIFECYCLE_EVENT_OCCURRED__EVENT__CREATE_USER,
|
||||||
|
FrameworkStatsLog.USER_LIFECYCLE_EVENT_OCCURRED__STATE__BEGIN);
|
||||||
|
return sessionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void logUserCreateJourneyFinish(long sessionId, @UserIdInt int userId) {
|
||||||
|
FrameworkStatsLog.write(FrameworkStatsLog.USER_LIFECYCLE_EVENT_OCCURRED, sessionId, userId,
|
||||||
|
FrameworkStatsLog.USER_LIFECYCLE_EVENT_OCCURRED__EVENT__CREATE_USER,
|
||||||
|
FrameworkStatsLog.USER_LIFECYCLE_EVENT_OCCURRED__STATE__FINISH);
|
||||||
|
}
|
||||||
|
|
||||||
private UserInfo createUserInternalUncheckedNoTracing(@Nullable String name,
|
private UserInfo createUserInternalUncheckedNoTracing(@Nullable String name,
|
||||||
@NonNull String userType, @UserInfoFlag int flags, @UserIdInt int parentId,
|
@NonNull String userType, @UserInfoFlag int flags, @UserIdInt int parentId,
|
||||||
boolean preCreate, @Nullable String[] disallowedPackages,
|
boolean preCreate, @Nullable String[] disallowedPackages,
|
||||||
|
|||||||
Reference in New Issue
Block a user