diff --git a/core/api/current.txt b/core/api/current.txt index e3e307c7262d3..7ed1a4382054e 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -32263,6 +32263,7 @@ package android.os { method @RequiresPermission(anyOf={"android.permission.MANAGE_USERS", "android.permission.INTERACT_ACROSS_USERS"}, conditional=true) public boolean isUserRunningOrStopping(android.os.UserHandle); method public boolean isUserUnlocked(); method @RequiresPermission(anyOf={"android.permission.MANAGE_USERS", "android.permission.INTERACT_ACROSS_USERS"}, conditional=true) public boolean isUserUnlocked(android.os.UserHandle); + method public boolean isUserVisible(); method @RequiresPermission(anyOf={"android.permission.MANAGE_USERS", "android.permission.MODIFY_QUIET_MODE"}, conditional=true) public boolean requestQuietModeEnabled(boolean, @NonNull android.os.UserHandle); method public boolean requestQuietModeEnabled(boolean, @NonNull android.os.UserHandle, int); method @Deprecated public boolean setRestrictionsChallenge(String); diff --git a/core/java/android/os/IUserManager.aidl b/core/java/android/os/IUserManager.aidl index e5de3e157c88c..f69d6b0652467 100644 --- a/core/java/android/os/IUserManager.aidl +++ b/core/java/android/os/IUserManager.aidl @@ -125,6 +125,7 @@ interface IUserManager { boolean isUserUnlocked(int userId); boolean isUserRunning(int userId); boolean isUserForeground(int userId); + boolean isUserVisible(int userId); boolean isUserNameSet(int userId); boolean hasRestrictedProfiles(int userId); boolean requestQuietModeEnabled(String callingPackage, boolean enableQuietMode, int userId, in IntentSender target, int flags); diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java index d14d2e4402fe2..c802e56c8dc75 100644 --- a/core/java/android/os/UserManager.java +++ b/core/java/android/os/UserManager.java @@ -2857,6 +2857,30 @@ public class UserManager { return isUsersOnSecondaryDisplaysEnabled(); } + /** + * Checks if the user is visible at the moment. + * + *

Roughly speaking, a "visible user" is a user that can present UI on at least one display. + * It includes: + * + *

    + *
  1. The current foreground user in the main display. + *
  2. Current background users in secondary displays (for example, passenger users on + * automotive, using the display associated with their seats). + *
  3. Profile users (in the running / started state) of other visible users. + *
+ * + * @return whether the user is visible at the moment, as defined above. + */ + @UserHandleAware + public boolean isUserVisible() { + try { + return mService.isUserVisible(mUserId); + } catch (RemoteException re) { + throw re.rethrowFromSystemServer(); + } + } + /** * Return whether the context user is running in an "unlocked" state. *

diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java index ed745b83b30c7..38318291a328b 100644 --- a/services/core/java/com/android/server/pm/UserManagerService.java +++ b/services/core/java/com/android/server/pm/UserManagerService.java @@ -1654,6 +1654,12 @@ public class UserManagerService extends IUserManager.Stub { return currentUser == userId; } + @Override + public boolean isUserVisible(@UserIdInt int userId) { + // TODO(b/239824814): implement other cases like bg user, profile, user on secondary display + return isUserForeground(userId); + } + @Override public @NonNull String getUserName() { final int callingUid = Binder.getCallingUid();