Merge "Moved user visibility callback to its own listener."
This commit is contained in:
@@ -472,18 +472,6 @@ public abstract class SystemService {
|
||||
public void onUserSwitching(@Nullable TargetUser from, @NonNull TargetUser to) {
|
||||
}
|
||||
|
||||
/**
|
||||
* The {@link UserManager#isUserVisible() user visibility} changed.
|
||||
*
|
||||
* <p>This callback is called before the user starts or is switched to (or after it stops), when
|
||||
* its visibility changed because of that action.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
// NOTE: change visible to int if this method becomes a @SystemApi
|
||||
public void onUserVisibilityChanged(@NonNull TargetUser user, boolean visible) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when an existing user is stopping, for system services to finalize any per-user
|
||||
* state they maintain for running users. This is called prior to sending the SHUTDOWN
|
||||
|
||||
@@ -82,10 +82,6 @@ public final class SystemServiceManager implements Dumpable {
|
||||
private static final String USER_STOPPING = "Stop"; // Logged as onUserStopping()
|
||||
private static final String USER_STOPPED = "Cleanup"; // Logged as onUserStopped()
|
||||
private static final String USER_COMPLETED_EVENT = "CompletedEvent"; // onUserCompletedEvent()
|
||||
private static final String USER_VISIBLE = "Visible"; // Logged on onUserVisible() and
|
||||
// onUserStarting() (when visible is true)
|
||||
private static final String USER_INVISIBLE = "Invisible"; // Logged on onUserStopping()
|
||||
// (when visibilityChanged is true)
|
||||
|
||||
// The default number of threads to use if lifecycle thread pool is enabled.
|
||||
private static final int DEFAULT_MAX_USER_POOL_THREADS = 3;
|
||||
@@ -354,57 +350,16 @@ public final class SystemServiceManager implements Dumpable {
|
||||
/**
|
||||
* Starts the given user.
|
||||
*/
|
||||
public void onUserStarting(@NonNull TimingsTraceAndSlog t, @UserIdInt int userId,
|
||||
boolean visible) {
|
||||
EventLog.writeEvent(EventLogTags.SSM_USER_STARTING, userId, visible ? 1 : 0);
|
||||
public void onUserStarting(@NonNull TimingsTraceAndSlog t, @UserIdInt int userId) {
|
||||
EventLog.writeEvent(EventLogTags.SSM_USER_STARTING, userId);
|
||||
|
||||
final TargetUser targetUser = newTargetUser(userId);
|
||||
synchronized (mTargetUsers) {
|
||||
mTargetUsers.put(userId, targetUser);
|
||||
}
|
||||
|
||||
if (visible) {
|
||||
// Must send the user visiiblity change first, for 2 reasons:
|
||||
// 1. Automotive need to update the user-zone mapping ASAP and it's one of the few
|
||||
// services listening to this event (OTOH, there are manyy listeners to USER_STARTING
|
||||
// and some can take a while to process it)
|
||||
// 2. When a user is switched from bg to fg, the onUserVisibilityChanged() callback is
|
||||
// called onUserSwitching(), so calling it before onUserStarting() make it more
|
||||
// consistent with that
|
||||
EventLog.writeEvent(EventLogTags.SSM_USER_VISIBILITY_CHANGED, userId, /* visible= */ 1);
|
||||
onUser(t, USER_VISIBLE, /* prevUser= */ null, targetUser);
|
||||
}
|
||||
onUser(t, USER_STARTING, /* prevUser= */ null, targetUser);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the user visibility.
|
||||
*
|
||||
* <p><b>NOTE: </b>this method should only be called when a user that is already running become
|
||||
* visible; if the user is starting visible, callers should call
|
||||
* {@link #onUserStarting(TimingsTraceAndSlog, int, boolean)} instead.
|
||||
*/
|
||||
public void onUserVisible(@UserIdInt int userId) {
|
||||
EventLog.writeEvent(EventLogTags.SSM_USER_VISIBILITY_CHANGED, userId, /* visible= */ 1);
|
||||
onUser(USER_VISIBLE, userId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the visibility of the system user.
|
||||
*
|
||||
* <p>Since the system user never stops, this method must be called when it's switched from / to
|
||||
* foreground.
|
||||
*/
|
||||
public void onSystemUserVisibilityChanged(boolean visible) {
|
||||
int userId = UserHandle.USER_SYSTEM;
|
||||
EventLog.writeEvent(EventLogTags.SSM_USER_VISIBILITY_CHANGED, userId, visible ? 1 : 0);
|
||||
if (visible) {
|
||||
onUser(USER_VISIBLE, userId);
|
||||
} else {
|
||||
onUser(USER_INVISIBLE, userId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unlocks the given user.
|
||||
*/
|
||||
@@ -452,12 +407,9 @@ public final class SystemServiceManager implements Dumpable {
|
||||
/**
|
||||
* Stops the given user.
|
||||
*/
|
||||
public void onUserStopping(@UserIdInt int userId, boolean visibilityChanged) {
|
||||
EventLog.writeEvent(EventLogTags.SSM_USER_STOPPING, userId, visibilityChanged ? 1 : 0);
|
||||
public void onUserStopping(@UserIdInt int userId) {
|
||||
EventLog.writeEvent(EventLogTags.SSM_USER_STOPPING, userId);
|
||||
onUser(USER_STOPPING, userId);
|
||||
if (visibilityChanged) {
|
||||
onUser(USER_INVISIBLE, userId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -580,12 +532,6 @@ public final class SystemServiceManager implements Dumpable {
|
||||
threadPool.submit(getOnUserCompletedEventRunnable(
|
||||
t, service, serviceName, curUser, completedEventType));
|
||||
break;
|
||||
case USER_VISIBLE:
|
||||
service.onUserVisibilityChanged(curUser, /* visible= */ true);
|
||||
break;
|
||||
case USER_INVISIBLE:
|
||||
service.onUserVisibilityChanged(curUser, /* visible= */ false);
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException(onWhat + " what?");
|
||||
}
|
||||
|
||||
@@ -107,21 +107,21 @@ option java_package com.android.server.am
|
||||
30079 uc_dispatch_user_switch (oldUserId|1|5),(newUserId|1|5)
|
||||
30080 uc_continue_user_switch (oldUserId|1|5),(newUserId|1|5)
|
||||
30081 uc_send_user_broadcast (userId|1|5),(IntentAction|3)
|
||||
|
||||
# Tags below are used by SystemServiceManager - although it's technically part of am, these are
|
||||
# also user switch events and useful to be analyzed together with events above.
|
||||
30082 ssm_user_starting (userId|1|5),(visible|1)
|
||||
30082 ssm_user_starting (userId|1|5)
|
||||
30083 ssm_user_switching (oldUserId|1|5),(newUserId|1|5)
|
||||
30084 ssm_user_unlocking (userId|1|5)
|
||||
30085 ssm_user_unlocked (userId|1|5)
|
||||
30086 ssm_user_stopping (userId|1|5),(visibilityChanged|1)
|
||||
30086 ssm_user_stopping (userId|1|5)
|
||||
30087 ssm_user_stopped (userId|1|5)
|
||||
30088 ssm_user_completed_event (userId|1|5),(eventFlag|1|5)
|
||||
30089 ssm_user_visibility_changed (userId|1|5),(visible|1)
|
||||
|
||||
# Similarly, tags below are used by UserManagerService
|
||||
30091 um_user_visibility_changed (userId|1|5),(visible|1)
|
||||
|
||||
# Foreground service start/stop events.
|
||||
30100 am_foreground_service_start (User|1|5),(Component Name|3),(allowWhileInUse|1),(startReasonCode|3),(targetSdk|1|1),(callerTargetSdk|1|1),(notificationWasDeferred|1),(notificationShown|1),(durationMs|1|3),(startForegroundCount|1|1),(stopReason|3)
|
||||
30101 am_foreground_service_denied (User|1|5),(Component Name|3),(allowWhileInUse|1),(startReasonCode|3),(targetSdk|1|1),(callerTargetSdk|1|1),(notificationWasDeferred|1),(notificationShown|1),(durationMs|1|3),(startForegroundCount|1|1),(stopReason|3)
|
||||
30102 am_foreground_service_stop (User|1|5),(Component Name|3),(allowWhileInUse|1),(startReasonCode|3),(targetSdk|1|1),(callerTargetSdk|1|1),(notificationWasDeferred|1),(notificationShown|1),(durationMs|1|3),(startForegroundCount|1|1),(stopReason|3)
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -177,9 +177,7 @@ class UserController implements Handler.Callback {
|
||||
static final int START_USER_SWITCH_FG_MSG = 120;
|
||||
static final int COMPLETE_USER_SWITCH_MSG = 130;
|
||||
static final int USER_COMPLETED_EVENT_MSG = 140;
|
||||
static final int USER_VISIBLE_MSG = 150;
|
||||
|
||||
private static final int NO_ARG2 = 0;
|
||||
static final int USER_VISIBILITY_CHANGED_MSG = 150;
|
||||
|
||||
// Message constant to clear {@link UserJourneySession} from {@link mUserIdToUserJourneyMap} if
|
||||
// the user journey, defined in the UserLifecycleJourneyReported atom for statsd, is not
|
||||
@@ -439,10 +437,13 @@ class UserController implements Handler.Callback {
|
||||
/** @see #getLastUserUnlockingUptime */
|
||||
private volatile long mLastUserUnlockingUptime = 0;
|
||||
|
||||
// TODO(b/244333150) remove this array and let UserVisibilityMediator call the listeners
|
||||
// directly, as that class should be responsible for all user visibility logic (for example,
|
||||
// when the foreground user is switched out, its profiles also become invisible)
|
||||
/**
|
||||
* List of visible users (as defined by {@link UserManager#isUserVisible()}).
|
||||
*
|
||||
* <p>It's only used to call {@link SystemServiceManager} when the visibility is changed upon
|
||||
* <p>It's only used to call {@link UserManagerInternal} when the visibility is changed upon
|
||||
* the user starting or stopping.
|
||||
*
|
||||
* <p>Note: only the key is used, not the value.
|
||||
@@ -1096,10 +1097,7 @@ class UserController implements Handler.Callback {
|
||||
synchronized (mLock) {
|
||||
visibleBefore = mVisibleUsers.get(userId);
|
||||
if (visibleBefore) {
|
||||
if (DEBUG_MU) {
|
||||
Slogf.d(TAG, "Removing %d from mVisibleUsers", userId);
|
||||
}
|
||||
mVisibleUsers.delete(userId);
|
||||
deleteVisibleUserLocked(userId);
|
||||
visibilityChanged = true;
|
||||
} else {
|
||||
visibilityChanged = false;
|
||||
@@ -1148,6 +1146,20 @@ class UserController implements Handler.Callback {
|
||||
}
|
||||
}
|
||||
|
||||
private void addVisibleUserLocked(@UserIdInt int userId) {
|
||||
if (DEBUG_MU) {
|
||||
Slogf.d(TAG, "adding %d to mVisibleUsers", userId);
|
||||
}
|
||||
mVisibleUsers.put(userId, true);
|
||||
}
|
||||
|
||||
private void deleteVisibleUserLocked(@UserIdInt int userId) {
|
||||
if (DEBUG_MU) {
|
||||
Slogf.d(TAG, "deleting %d from mVisibleUsers", userId);
|
||||
}
|
||||
mVisibleUsers.delete(userId);
|
||||
}
|
||||
|
||||
private void finishUserStopping(final int userId, final UserState uss,
|
||||
final boolean allowDelayedLocking, final boolean visibilityChanged) {
|
||||
EventLog.writeEvent(EventLogTags.UC_FINISH_USER_STOPPING, userId);
|
||||
@@ -1166,7 +1178,10 @@ class UserController implements Handler.Callback {
|
||||
mInjector.batteryStatsServiceNoteEvent(
|
||||
BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
|
||||
Integer.toString(userId), userId);
|
||||
mInjector.getSystemServiceManager().onUserStopping(userId, visibilityChanged);
|
||||
mInjector.getSystemServiceManager().onUserStopping(userId);
|
||||
if (visibilityChanged) {
|
||||
mInjector.onUserVisibilityChanged(userId, /* visible= */ false);
|
||||
}
|
||||
|
||||
Runnable finishUserStoppedAsync = () ->
|
||||
mHandler.post(() -> finishUserStopped(uss, allowDelayedLocking));
|
||||
@@ -1687,7 +1702,15 @@ class UserController implements Handler.Callback {
|
||||
// Make sure the old user is no longer considering the display to be on.
|
||||
mInjector.reportGlobalUsageEvent(UsageEvents.Event.SCREEN_NON_INTERACTIVE);
|
||||
boolean userSwitchUiEnabled;
|
||||
// TODO(b/244333150): temporary state until the callback logic is moved to
|
||||
// UserVisibilityManager
|
||||
int previousCurrentUserId; boolean notifyPreviousCurrentUserId;
|
||||
synchronized (mLock) {
|
||||
previousCurrentUserId = mCurrentUserId;
|
||||
notifyPreviousCurrentUserId = mVisibleUsers.get(previousCurrentUserId);
|
||||
if (notifyPreviousCurrentUserId) {
|
||||
deleteVisibleUserLocked(previousCurrentUserId);
|
||||
}
|
||||
mCurrentUserId = userId;
|
||||
mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
|
||||
userSwitchUiEnabled = mUserSwitchUiEnabled;
|
||||
@@ -1705,6 +1728,11 @@ class UserController implements Handler.Callback {
|
||||
mInjector.getWindowManager().lockNow(null);
|
||||
}
|
||||
}
|
||||
if (notifyPreviousCurrentUserId) {
|
||||
mHandler.sendMessage(mHandler.obtainMessage(USER_VISIBILITY_CHANGED_MSG,
|
||||
previousCurrentUserId, 0));
|
||||
}
|
||||
|
||||
} else {
|
||||
final Integer currentUserIdInt = mCurrentUserId;
|
||||
updateProfileRelatedCaches();
|
||||
@@ -1730,10 +1758,7 @@ class UserController implements Handler.Callback {
|
||||
&& mInjector.getUserManagerInternal().isUserVisible(userId);
|
||||
if (visible) {
|
||||
synchronized (mLock) {
|
||||
if (DEBUG_MU) {
|
||||
Slogf.d(TAG, "Adding %d to mVisibleUsers", userId);
|
||||
}
|
||||
mVisibleUsers.put(userId, true);
|
||||
addVisibleUserLocked(userId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1776,12 +1801,15 @@ class UserController implements Handler.Callback {
|
||||
mHandler.sendMessage(mHandler.obtainMessage(USER_START_MSG, userId,
|
||||
visible ? 1 : 0));
|
||||
t.traceEnd();
|
||||
} else if (visible) {
|
||||
}
|
||||
|
||||
if (visible) {
|
||||
// User was already running and became visible (for example, when switching to a
|
||||
// user that was started in the background before), so it's necessary to explicitly
|
||||
// notify the services (while when the user starts from BOOTING, USER_START_MSG
|
||||
// takes care of that.
|
||||
mHandler.sendMessage(mHandler.obtainMessage(USER_VISIBLE_MSG, userId, NO_ARG2));
|
||||
mHandler.sendMessage(mHandler.obtainMessage(USER_VISIBILITY_CHANGED_MSG, userId,
|
||||
visible ? 1 : 0));
|
||||
}
|
||||
|
||||
t.traceBegin("sendMessages");
|
||||
@@ -2573,7 +2601,8 @@ class UserController implements Handler.Callback {
|
||||
if (!UserManager.isHeadlessSystemUserMode()) {
|
||||
// Don't need to call on HSUM because it will be called when the system user is
|
||||
// restarted on background
|
||||
mInjector.onUserStarting(UserHandle.USER_SYSTEM, /* visible= */ true);
|
||||
mInjector.onUserStarting(UserHandle.USER_SYSTEM);
|
||||
mInjector.onUserVisibilityChanged(UserHandle.USER_SYSTEM, /* visible= */ true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2585,12 +2614,12 @@ class UserController implements Handler.Callback {
|
||||
int userId = UserHandle.USER_SYSTEM;
|
||||
synchronized (mLock) {
|
||||
if (visible) {
|
||||
mVisibleUsers.put(userId, true);
|
||||
addVisibleUserLocked(userId);
|
||||
} else {
|
||||
mVisibleUsers.delete(userId);
|
||||
deleteVisibleUserLocked(userId);
|
||||
}
|
||||
}
|
||||
mInjector.notifySystemUserVisibilityChanged(visible);
|
||||
mInjector.onUserVisibilityChanged(userId, visible);
|
||||
t.traceEnd();
|
||||
}
|
||||
|
||||
@@ -3090,7 +3119,7 @@ class UserController implements Handler.Callback {
|
||||
logUserLifecycleEvent(msg.arg1, USER_LIFECYCLE_EVENT_START_USER,
|
||||
USER_LIFECYCLE_EVENT_STATE_BEGIN);
|
||||
|
||||
mInjector.onUserStarting(/* userId= */ msg.arg1, /* visible= */ msg.arg2 == 1);
|
||||
mInjector.onUserStarting(/* userId= */ msg.arg1);
|
||||
scheduleOnUserCompletedEvent(msg.arg1,
|
||||
UserCompletedEventType.EVENT_TYPE_USER_STARTING,
|
||||
USER_COMPLETED_EVENT_DELAY_MS);
|
||||
@@ -3171,8 +3200,9 @@ class UserController implements Handler.Callback {
|
||||
case COMPLETE_USER_SWITCH_MSG:
|
||||
completeUserSwitch(msg.arg1);
|
||||
break;
|
||||
case USER_VISIBLE_MSG:
|
||||
mInjector.getSystemServiceManager().onUserVisible(/* userId= */ msg.arg1);
|
||||
case USER_VISIBILITY_CHANGED_MSG:
|
||||
mInjector.onUserVisibilityChanged(/* userId= */ msg.arg1,
|
||||
/* visible= */ msg.arg2 == 1);
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
@@ -3704,12 +3734,12 @@ class UserController implements Handler.Callback {
|
||||
return UserManager.isUsersOnSecondaryDisplaysEnabled();
|
||||
}
|
||||
|
||||
void onUserStarting(int userId, boolean visible) {
|
||||
getSystemServiceManager().onUserStarting(TimingsTraceAndSlog.newAsyncLog(), userId,
|
||||
visible);
|
||||
void onUserStarting(@UserIdInt int userId) {
|
||||
getSystemServiceManager().onUserStarting(TimingsTraceAndSlog.newAsyncLog(), userId);
|
||||
}
|
||||
void notifySystemUserVisibilityChanged(boolean visible) {
|
||||
getSystemServiceManager().onSystemUserVisibilityChanged(visible);
|
||||
|
||||
void onUserVisibilityChanged(@UserIdInt int userId, boolean visible) {
|
||||
getUserManagerInternal().onUserVisibilityChanged(userId, visible);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -140,7 +140,9 @@ import com.android.server.location.provider.StationaryThrottlingLocationProvider
|
||||
import com.android.server.location.provider.proxy.ProxyLocationProvider;
|
||||
import com.android.server.location.settings.LocationSettings;
|
||||
import com.android.server.location.settings.LocationUserSettings;
|
||||
import com.android.server.pm.UserManagerInternal;
|
||||
import com.android.server.pm.permission.LegacyPermissionManagerInternal;
|
||||
import com.android.server.utils.Slogf;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.PrintWriter;
|
||||
@@ -308,6 +310,10 @@ public class LocationManagerService extends ILocationManager.Stub implements
|
||||
permissionManagerInternal.setLocationExtraPackagesProvider(
|
||||
userId -> mContext.getResources().getStringArray(
|
||||
com.android.internal.R.array.config_locationExtraPackageNames));
|
||||
|
||||
// TODO(b/241604546): properly handle this callback
|
||||
LocalServices.getService(UserManagerInternal.class).addUserVisibilityListener(
|
||||
(u, v) -> Slogf.i(TAG, "onUserVisibilityChanged(): %d -> %b", u, v));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
@@ -76,6 +76,23 @@ public abstract class UserManagerInternal {
|
||||
default void onUserRemoved(UserInfo user) {}
|
||||
}
|
||||
|
||||
/**
|
||||
* Listener for {@link UserManager#isUserVisible() user visibility} changes.
|
||||
*/
|
||||
public interface UserVisibilityListener {
|
||||
|
||||
/**
|
||||
* Called when the {@link UserManager#isUserVisible() user visibility} changed.
|
||||
*
|
||||
* <p><b>Note:</b> this method is called independently of
|
||||
* {@link com.android.server.SystemService} callbacks; for example, the call with
|
||||
* {@code visible} {@code true} might be called before the
|
||||
* {@link com.android.server.SystemService#onUserStarting(com.android.server.SystemService.TargetUser)}
|
||||
* call.
|
||||
*/
|
||||
void onUserVisibilityChanged(@UserIdInt int userId, boolean visible);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by {@link com.android.server.devicepolicy.DevicePolicyManagerService} to set
|
||||
* restrictions enforced by the user.
|
||||
@@ -390,4 +407,13 @@ public abstract class UserManagerInternal {
|
||||
* would make such call).
|
||||
*/
|
||||
public abstract @UserIdInt int getUserAssignedToDisplay(int displayId);
|
||||
|
||||
/** Adds a {@link UserVisibilityListener}. */
|
||||
public abstract void addUserVisibilityListener(UserVisibilityListener listener);
|
||||
|
||||
/** Removes a {@link UserVisibilityListener}. */
|
||||
public abstract void removeUserVisibilityListener(UserVisibilityListener listener);
|
||||
|
||||
/** TODO(b/244333150): temporary method until UserVisibilityMediator handles that logic */
|
||||
public abstract void onUserVisibilityChanged(@UserIdInt int userId, boolean visible);
|
||||
}
|
||||
|
||||
@@ -96,6 +96,7 @@ import android.text.TextUtils;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.ArraySet;
|
||||
import android.util.AtomicFile;
|
||||
import android.util.EventLog;
|
||||
import android.util.IndentingPrintWriter;
|
||||
import android.util.IntArray;
|
||||
import android.util.Slog;
|
||||
@@ -124,9 +125,11 @@ import com.android.server.BundleUtils;
|
||||
import com.android.server.LocalServices;
|
||||
import com.android.server.LockGuard;
|
||||
import com.android.server.SystemService;
|
||||
import com.android.server.am.EventLogTags;
|
||||
import com.android.server.am.UserState;
|
||||
import com.android.server.pm.UserManagerInternal.UserLifecycleListener;
|
||||
import com.android.server.pm.UserManagerInternal.UserRestrictionsListener;
|
||||
import com.android.server.pm.UserManagerInternal.UserVisibilityListener;
|
||||
import com.android.server.storage.DeviceStorageMonitorInternal;
|
||||
import com.android.server.utils.Slogf;
|
||||
import com.android.server.utils.TimingsTraceAndSlog;
|
||||
@@ -504,6 +507,10 @@ public class UserManagerService extends IUserManager.Stub {
|
||||
@GuardedBy("mUserLifecycleListeners")
|
||||
private final ArrayList<UserLifecycleListener> mUserLifecycleListeners = new ArrayList<>();
|
||||
|
||||
// TODO(b/244333150): temporary array, should belong to UserVisibilityMediator
|
||||
@GuardedBy("mUserVisibilityListeners")
|
||||
private final ArrayList<UserVisibilityListener> mUserVisibilityListeners = new ArrayList<>();
|
||||
|
||||
private final LockPatternUtils mLockPatternUtils;
|
||||
|
||||
private final String ACTION_DISABLE_QUIET_MODE_AFTER_UNLOCK =
|
||||
@@ -6250,6 +6257,9 @@ public class UserManagerService extends IUserManager.Stub {
|
||||
synchronized (mUserLifecycleListeners) {
|
||||
pw.println(" user lifecycle events: " + mUserLifecycleListeners.size());
|
||||
}
|
||||
synchronized (mUserVisibilityListeners) {
|
||||
pw.println(" user visibility events: " + mUserVisibilityListeners.size());
|
||||
}
|
||||
|
||||
// Dump UserTypes
|
||||
pw.println();
|
||||
@@ -6817,8 +6827,39 @@ public class UserManagerService extends IUserManager.Stub {
|
||||
public @UserIdInt int getUserAssignedToDisplay(int displayId) {
|
||||
return mUserVisibilityMediator.getUserAssignedToDisplay(displayId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addUserVisibilityListener(UserVisibilityListener listener) {
|
||||
synchronized (mUserVisibilityListeners) {
|
||||
mUserVisibilityListeners.add(listener);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeUserVisibilityListener(UserVisibilityListener listener) {
|
||||
synchronized (mUserVisibilityListeners) {
|
||||
mUserVisibilityListeners.remove(listener);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUserVisibilityChanged(@UserIdInt int userId, boolean visible) {
|
||||
EventLog.writeEvent(EventLogTags.UM_USER_VISIBILITY_CHANGED, userId, visible ? 1 : 0);
|
||||
mHandler.post(() -> {
|
||||
UserVisibilityListener[] listeners;
|
||||
synchronized (mUserVisibilityListeners) {
|
||||
listeners = new UserVisibilityListener[mUserVisibilityListeners.size()];
|
||||
mUserVisibilityListeners.toArray(listeners);
|
||||
}
|
||||
for (UserVisibilityListener listener : listeners) {
|
||||
listener.onUserVisibilityChanged(userId, visible);
|
||||
}
|
||||
});
|
||||
}
|
||||
} // class LocalService
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Check if user has restrictions
|
||||
* @param restriction restrictions to check
|
||||
|
||||
@@ -38,6 +38,7 @@ import static com.android.server.am.UserController.USER_COMPLETED_EVENT_MSG;
|
||||
import static com.android.server.am.UserController.USER_CURRENT_MSG;
|
||||
import static com.android.server.am.UserController.USER_START_MSG;
|
||||
import static com.android.server.am.UserController.USER_SWITCH_TIMEOUT_MSG;
|
||||
import static com.android.server.am.UserController.USER_VISIBILITY_CHANGED_MSG;
|
||||
|
||||
import static com.google.android.collect.Lists.newArrayList;
|
||||
import static com.google.android.collect.Sets.newHashSet;
|
||||
@@ -158,6 +159,7 @@ public class UserControllerTest {
|
||||
REPORT_USER_SWITCH_MSG,
|
||||
USER_SWITCH_TIMEOUT_MSG,
|
||||
USER_START_MSG,
|
||||
USER_VISIBILITY_CHANGED_MSG,
|
||||
USER_CURRENT_MSG);
|
||||
|
||||
private static final Set<Integer> START_BACKGROUND_USER_MESSAGE_CODES = newHashSet(
|
||||
@@ -964,7 +966,7 @@ public class UserControllerTest {
|
||||
}
|
||||
|
||||
private void verifySystemUserVisibilityChangedNotified(boolean visible) {
|
||||
verify(mInjector).notifySystemUserVisibilityChanged(visible);
|
||||
verify(mInjector).onUserVisibilityChanged(UserHandle.USER_SYSTEM, visible);
|
||||
}
|
||||
|
||||
// Should be public to allow mocking
|
||||
@@ -1104,13 +1106,13 @@ public class UserControllerTest {
|
||||
}
|
||||
|
||||
@Override
|
||||
void onUserStarting(@UserIdInt int userId, boolean visible) {
|
||||
Log.i(TAG, "onUserStarting(" + userId + ", " + visible + ")");
|
||||
void onUserStarting(@UserIdInt int userId) {
|
||||
Log.i(TAG, "onUserStarting(" + userId + ")");
|
||||
}
|
||||
|
||||
@Override
|
||||
void notifySystemUserVisibilityChanged(boolean visible) {
|
||||
Log.i(TAG, "notifySystemUserVisibilityChanged(" + visible + ")");
|
||||
void onUserVisibilityChanged(@UserIdInt int userId, boolean visible) {
|
||||
Log.i(TAG, "onUserVisibilityChanged(" + userId + ", " + visible + ")");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user