下面列出了android.os.UserHandle#USER_ALL 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
private void pushSessionTokensChanged(int userId) {
synchronized (mLock) {
List<Bundle> tokens = new ArrayList<>();
for (SessionToken2 token : mSessionRecords.keySet()) {
// TODO(jaewan): Remove the check for UserHandle.USER_ALL (shouldn't happen).
// This happens when called form buildMediaSessionService2List(...).
// (b/73760382)
if (UserHandle.getUserId(token.getUid()) == userId
|| UserHandle.USER_ALL == userId) {
tokens.add(token.toBundle());
}
}
for (SessionTokensListenerRecord record : mSessionTokensListeners) {
// TODO(jaewan): Should userId be mapped through mFullUserIds? (b/73760382)
if (record.mUserId == userId || record.mUserId == UserHandle.USER_ALL) {
try {
record.mListener.onSessionTokensChanged(tokens);
} catch (RemoteException e) {
Log.w(TAG, "Failed to notify session tokens changed", e);
}
}
}
}
}
private List<MediaSessionRecord> getActiveSessionsLocked(int userId) {
List<MediaSessionRecord> records = new ArrayList<>();
if (userId == UserHandle.USER_ALL) {
int size = mUserRecords.size();
for (int i = 0; i < size; i++) {
records.addAll(mUserRecords.valueAt(i).mPriorityStack.getActiveSessions(userId));
}
} else {
FullUserRecord user = getFullUserRecordLocked(userId);
if (user == null) {
Log.w(TAG, "getSessions failed. Unknown user " + userId);
return records;
}
records.addAll(user.mPriorityStack.getActiveSessions(userId));
}
// Return global priority session at the first whenever it's asked.
if (isGlobalPriorityActiveLocked()
&& (userId == UserHandle.USER_ALL
|| userId == mGlobalPrioritySession.getUserId())) {
records.add(0, mGlobalPrioritySession);
}
return records;
}
boolean collectPackageProvidersLocked(String packageName, Set<String> filterByClasses,
boolean doit, boolean evenPersistent, int userId,
ArrayList<ContentProviderRecord> result) {
boolean didSomething = false;
if (userId == UserHandle.USER_ALL || userId == UserHandle.USER_SYSTEM) {
didSomething = collectPackageProvidersLocked(packageName, filterByClasses,
doit, evenPersistent, mSingletonByClass, result);
}
if (!doit && didSomething) {
return true;
}
if (userId == UserHandle.USER_ALL) {
for (int i = 0; i < mProvidersByClassPerUser.size(); i++) {
if (collectPackageProvidersLocked(packageName, filterByClasses,
doit, evenPersistent, mProvidersByClassPerUser.valueAt(i), result)) {
if (!doit) {
return true;
}
didSomething = true;
}
}
} else {
HashMap<ComponentName, ContentProviderRecord> items
= getProvidersByClass(userId);
if (items != null) {
didSomething |= collectPackageProvidersLocked(packageName, filterByClasses,
doit, evenPersistent, items, result);
}
}
return didSomething;
}
private int handleIncomingUser(Uri uri, int pid, int uid, int modeFlags, boolean allowNonFull,
int userId) {
if (userId == UserHandle.USER_CURRENT) {
userId = ActivityManager.getCurrentUser();
}
if (userId == UserHandle.USER_ALL) {
mContext.enforceCallingOrSelfPermission(
Manifest.permission.INTERACT_ACROSS_USERS_FULL, "No access to " + uri);
} else if (userId < 0) {
throw new IllegalArgumentException("Invalid user: " + userId);
} else if (userId != UserHandle.getCallingUserId()) {
if (checkUriPermission(uri, pid, uid, modeFlags,
userId) != PackageManager.PERMISSION_GRANTED) {
boolean allow = false;
if (mContext.checkCallingOrSelfPermission(
Manifest.permission.INTERACT_ACROSS_USERS_FULL)
== PackageManager.PERMISSION_GRANTED) {
allow = true;
} else if (allowNonFull && mContext.checkCallingOrSelfPermission(
Manifest.permission.INTERACT_ACROSS_USERS)
== PackageManager.PERMISSION_GRANTED) {
allow = true;
}
if (!allow) {
final String permissions = allowNonFull
? (Manifest.permission.INTERACT_ACROSS_USERS_FULL + " or " +
Manifest.permission.INTERACT_ACROSS_USERS)
: Manifest.permission.INTERACT_ACROSS_USERS_FULL;
throw new SecurityException("No access to " + uri + ": neither user " + uid
+ " nor current process has " + permissions);
}
}
}
return userId;
}
void resetProcessCrashTimeLocked(boolean resetEntireUser, int appId, int userId) {
final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
for (int ip = pmap.size() - 1; ip >= 0; ip--) {
SparseArray<Long> ba = pmap.valueAt(ip);
for (int i = ba.size() - 1; i >= 0; i--) {
boolean remove = false;
final int entUid = ba.keyAt(i);
if (!resetEntireUser) {
if (userId == UserHandle.USER_ALL) {
if (UserHandle.getAppId(entUid) == appId) {
remove = true;
}
} else {
if (entUid == UserHandle.getUid(userId, appId)) {
remove = true;
}
}
} else if (UserHandle.getUserId(entUid) == userId) {
remove = true;
}
if (remove) {
ba.removeAt(i);
}
}
if (ba.size() == 0) {
pmap.removeAt(ip);
}
}
}
/**
* Get a priority sorted list of sessions. Can filter to only return active
* sessions or sessions.
* <p>Here's the priority order.
* <li>Active sessions whose PlaybackState is active</li>
* <li>Active sessions whose PlaybackState is inactive</li>
* <li>Inactive sessions</li>
*
* @param activeOnly True to only return active sessions, false to return
* all sessions.
* @param userId The user to get sessions for. {@link UserHandle#USER_ALL}
* will return sessions for all users.
* @return The priority sorted list of sessions.
*/
public ArrayList<MediaSessionRecord> getPriorityList(boolean activeOnly, int userId) {
ArrayList<MediaSessionRecord> result = new ArrayList<MediaSessionRecord>();
int lastPlaybackActiveIndex = 0;
int lastActiveIndex = 0;
int size = mSessions.size();
for (int i = 0; i < size; i++) {
final MediaSessionRecord session = mSessions.get(i);
if (userId != UserHandle.USER_ALL && userId != session.getUserId()) {
// Filter out sessions for the wrong user
continue;
}
if (!session.isActive()) {
if (!activeOnly) {
// If we're getting unpublished as well always put them at
// the end
result.add(session);
}
continue;
}
if (session.isPlaybackActive()) {
result.add(lastPlaybackActiveIndex++, session);
lastActiveIndex++;
} else {
result.add(lastActiveIndex++, session);
}
}
return result;
}
private void handleRequireStrongAuth(int strongAuthReason, int userId) {
if (userId == UserHandle.USER_ALL) {
for (int i = 0; i < mStrongAuthForUser.size(); i++) {
int key = mStrongAuthForUser.keyAt(i);
handleRequireStrongAuthOneUser(strongAuthReason, key);
}
} else {
handleRequireStrongAuthOneUser(strongAuthReason, userId);
}
}
public void requireStrongAuth(int strongAuthReason, int userId) {
if (userId == UserHandle.USER_ALL || userId >= UserHandle.USER_SYSTEM) {
mHandler.obtainMessage(MSG_REQUIRE_STRONG_AUTH, strongAuthReason,
userId).sendToTarget();
} else {
throw new IllegalArgumentException(
"userId must be an explicit user id or USER_ALL");
}
}
public boolean enabledAndUserMatches(int nid) {
if (!isEnabledForCurrentProfiles()) {
return false;
}
if (this.userid == UserHandle.USER_ALL) return true;
if (this.isSystem) return true;
if (nid == UserHandle.USER_ALL || nid == this.userid) return true;
return supportsProfiles()
&& mUserProfiles.isCurrentProfile(nid)
&& isPermittedForProfile(nid);
}
int runForceStop(PrintWriter pw) throws RemoteException {
int userId = UserHandle.USER_ALL;
String opt;
while ((opt = getNextOption()) != null) {
if (opt.equals("--user")) {
userId = UserHandle.parseUserArg(getNextArgRequired());
} else {
getErrPrintWriter().println("Error: Unknown option: " + opt);
return -1;
}
}
mInterface.forceStopPackage(getNextArgRequired(), userId);
return 0;
}
private int doCreateSession(SessionParams params, String installerPackageName, int userId)
throws RemoteException {
userId = translateUserId(userId, true /*allowAll*/, "runInstallCreate");
if (userId == UserHandle.USER_ALL) {
userId = UserHandle.USER_SYSTEM;
params.installFlags |= PackageManager.INSTALL_ALL_USERS;
}
final int sessionId = mInterface.getPackageInstaller()
.createSession(params, installerPackageName, userId);
return sessionId;
}
public boolean updateFlags(int userId, int flagMask, int flagValues) {
if (isInstallPermission()) {
userId = UserHandle.USER_ALL;
}
if (!isCompatibleUserId(userId)) {
return false;
}
final int newFlags = flagValues & flagMask;
PermissionState userState = mUserStates.get(userId);
if (userState != null) {
final int oldFlags = userState.mFlags;
userState.mFlags = (userState.mFlags & ~flagMask) | newFlags;
if (userState.isDefault()) {
mUserStates.remove(userId);
}
return userState.mFlags != oldFlags;
} else if (newFlags != 0) {
userState = new PermissionState(mPerm.getName());
userState.mFlags = newFlags;
mUserStates.put(userId, userState);
return true;
}
return false;
}
private void collectMyObserversLocked(boolean leaf, IContentObserver observer,
boolean observerWantsSelfNotifications, int flags,
int targetUserHandle, ArrayList<ObserverCall> calls) {
int N = mObservers.size();
IBinder observerBinder = observer == null ? null : observer.asBinder();
for (int i = 0; i < N; i++) {
ObserverEntry entry = mObservers.get(i);
// Don't notify the observer if it sent the notification and isn't interested
// in self notifications
boolean selfChange = (entry.observer.asBinder() == observerBinder);
if (selfChange && !observerWantsSelfNotifications) {
continue;
}
// Does this observer match the target user?
if (targetUserHandle == UserHandle.USER_ALL
|| entry.userHandle == UserHandle.USER_ALL
|| targetUserHandle == entry.userHandle) {
// Make sure the observer is interested in the notification
if (leaf) {
// If we are at the leaf: we always report, unless the sender has asked
// to skip observers that are notifying for descendants (since they will
// be sending another more specific URI for them).
if ((flags&ContentResolver.NOTIFY_SKIP_NOTIFY_FOR_DESCENDANTS) != 0
&& entry.notifyForDescendants) {
if (DEBUG) Slog.d(TAG, "Skipping " + entry.observer
+ ": skip notify for descendants");
continue;
}
} else {
// If we are not at the leaf: we report if the observer says it wants
// to be notified for all descendants.
if (!entry.notifyForDescendants) {
if (DEBUG) Slog.d(TAG, "Skipping " + entry.observer
+ ": not monitor descendants");
continue;
}
}
if (DEBUG) Slog.d(TAG, "Reporting to " + entry.observer + ": leaf=" + leaf
+ " flags=" + Integer.toHexString(flags)
+ " desc=" + entry.notifyForDescendants);
calls.add(new ObserverCall(this, entry.observer, selfChange,
UserHandle.getUserId(entry.uid)));
}
}
}
int runSendTrimMemory(PrintWriter pw) throws RemoteException {
int userId = UserHandle.USER_CURRENT;
String opt;
while ((opt = getNextOption()) != null) {
if (opt.equals("--user")) {
userId = UserHandle.parseUserArg(getNextArgRequired());
if (userId == UserHandle.USER_ALL) {
getErrPrintWriter().println("Error: Can't use user 'all'");
return -1;
}
} else {
getErrPrintWriter().println("Error: Unknown option: " + opt);
return -1;
}
}
String proc = getNextArgRequired();
String levelArg = getNextArgRequired();
int level;
switch (levelArg) {
case "HIDDEN":
level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
break;
case "RUNNING_MODERATE":
level = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
break;
case "BACKGROUND":
level = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
break;
case "RUNNING_LOW":
level = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
break;
case "MODERATE":
level = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
break;
case "RUNNING_CRITICAL":
level = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
break;
case "COMPLETE":
level = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
break;
default:
try {
level = Integer.parseInt(levelArg);
} catch (NumberFormatException e) {
getErrPrintWriter().println("Error: Unknown level option: " + levelArg);
return -1;
}
}
if (!mInterface.setProcessMemoryTrimLevel(proc, userId, level)) {
getErrPrintWriter().println("Unknown error: failed to set trim level");
return -1;
}
return 0;
}
public boolean setRestriction(int code, boolean restricted,
String[] excludedPackages, int userId) {
boolean changed = false;
if (perUserRestrictions == null && restricted) {
perUserRestrictions = new SparseArray<>();
}
int[] users;
if (userId == UserHandle.USER_ALL) {
List<UserInfo> liveUsers = UserManager.get(mContext).getUsers(false);
users = new int[liveUsers.size()];
for (int i = 0; i < liveUsers.size(); i++) {
users[i] = liveUsers.get(i).id;
}
} else {
users = new int[]{userId};
}
if (perUserRestrictions != null) {
int numUsers = users.length;
for (int i = 0; i < numUsers; i++) {
int thisUserId = users[i];
boolean[] userRestrictions = perUserRestrictions.get(thisUserId);
if (userRestrictions == null && restricted) {
userRestrictions = new boolean[AppOpsManager._NUM_OP];
perUserRestrictions.put(thisUserId, userRestrictions);
}
if (userRestrictions != null && userRestrictions[code] != restricted) {
userRestrictions[code] = restricted;
if (!restricted && isDefault(userRestrictions)) {
perUserRestrictions.remove(thisUserId);
userRestrictions = null;
}
changed = true;
}
if (userRestrictions != null) {
final boolean noExcludedPackages = ArrayUtils.isEmpty(excludedPackages);
if (perUserExcludedPackages == null && !noExcludedPackages) {
perUserExcludedPackages = new SparseArray<>();
}
if (perUserExcludedPackages != null && !Arrays.equals(excludedPackages,
perUserExcludedPackages.get(thisUserId))) {
if (noExcludedPackages) {
perUserExcludedPackages.remove(thisUserId);
if (perUserExcludedPackages.size() <= 0) {
perUserExcludedPackages = null;
}
} else {
perUserExcludedPackages.put(thisUserId, excludedPackages);
}
changed = true;
}
}
}
}
return changed;
}
private void collectMyObserversLocked(boolean leaf, IContentObserver observer,
boolean observerWantsSelfNotifications, int flags,
int targetUserHandle, ArrayList<ObserverCall> calls) {
int N = mObservers.size();
IBinder observerBinder = observer == null ? null : observer.asBinder();
for (int i = 0; i < N; i++) {
ObserverEntry entry = mObservers.get(i);
// Don't notify the observer if it sent the notification and isn't interested
// in self notifications
boolean selfChange = (entry.observer.asBinder() == observerBinder);
if (selfChange && !observerWantsSelfNotifications) {
continue;
}
// Does this observer match the target user?
if (targetUserHandle == UserHandle.USER_ALL
|| entry.userHandle == UserHandle.USER_ALL
|| targetUserHandle == entry.userHandle) {
// Make sure the observer is interested in the notification
if (leaf) {
// If we are at the leaf: we always report, unless the sender has asked
// to skip observers that are notifying for descendants (since they will
// be sending another more specific URI for them).
if ((flags&ContentResolver.NOTIFY_SKIP_NOTIFY_FOR_DESCENDANTS) != 0
&& entry.notifyForDescendants) {
if (DEBUG) Slog.d(TAG, "Skipping " + entry.observer
+ ": skip notify for descendants");
continue;
}
} else {
// If we are not at the leaf: we report if the observer says it wants
// to be notified for all descendants.
if (!entry.notifyForDescendants) {
if (DEBUG) Slog.d(TAG, "Skipping " + entry.observer
+ ": not monitor descendants");
continue;
}
}
if (DEBUG) Slog.d(TAG, "Reporting to " + entry.observer + ": leaf=" + leaf
+ " flags=" + Integer.toHexString(flags)
+ " desc=" + entry.notifyForDescendants);
calls.add(new ObserverCall(this, entry.observer, selfChange,
UserHandle.getUserId(entry.uid)));
}
}
}
/**
* Send a notification when a particular content URI changes.
* Modify the system property used to communicate the version of
* this table, for tables which have such a property. (The Settings
* contract class uses these to provide client-side caches.)
* @param uri to send notifications for
*/
private void sendNotify(Uri uri, int userHandle) {
// Update the system property *first*, so if someone is listening for
// a notification and then using the contract class to get their data,
// the system property will be updated and they'll get the new data.
boolean backedUpDataChanged = false;
String property = null, table = uri.getPathSegments().get(0);
final boolean isGlobal = table.equals(TABLE_GLOBAL);
if (table.equals(TABLE_SYSTEM)) {
property = Settings.System.SYS_PROP_SETTING_VERSION;
backedUpDataChanged = true;
} else if (table.equals(TABLE_SECURE)) {
property = Settings.Secure.SYS_PROP_SETTING_VERSION;
backedUpDataChanged = true;
} else if (isGlobal) {
property = Settings.Global.SYS_PROP_SETTING_VERSION; // this one is global
backedUpDataChanged = true;
}
if (property != null) {
long version = SystemProperties.getLong(property, 0) + 1;
if (LOCAL_LOGV) Log.v(TAG, "property: " + property + "=" + version);
SystemProperties.set(property, Long.toString(version));
}
// Inform the backup manager about a data change
if (backedUpDataChanged) {
mBackupManager.dataChanged();
}
// Now send the notification through the content framework.
String notify = uri.getQueryParameter("notify");
if (notify == null || "true".equals(notify)) {
final int notifyTarget = isGlobal ? UserHandle.USER_ALL : userHandle;
final long oldId = Binder.clearCallingIdentity();
try {
getContext().getContentResolver().notifyChange(uri, null, true, notifyTarget);
} finally {
Binder.restoreCallingIdentity(oldId);
}
if (LOCAL_LOGV) Log.v(TAG, "notifying for " + notifyTarget + ": " + uri);
} else {
if (LOCAL_LOGV) Log.v(TAG, "notification suppressed: " + uri);
}
}
private static void enforceValidUserId(int userId) {
if (userId != UserHandle.USER_ALL && userId < 0) {
throw new IllegalArgumentException("Invalid userId:" + userId);
}
}
public static boolean isInstallPermissionKey(int userId) {
return userId == UserHandle.USER_ALL;
}
/**
* Revoke a runtime permission for a given device user.
*
* @param permission The permission to revoke.
* @param userId The device user id.
* @return The operation result which is either {@link #PERMISSION_OPERATION_SUCCESS},
* or {@link #PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED}, or {@link
* #PERMISSION_OPERATION_FAILURE}.
*/
public int revokeRuntimePermission(BasePermission permission, int userId) {
enforceValidUserId(userId);
if (userId == UserHandle.USER_ALL) {
return PERMISSION_OPERATION_FAILURE;
}
return revokePermission(permission, userId);
}