Use UserHandles instead of userId integers.
userId integers are not public API and code should use UserHandle instead. Bug: 170598012 Test: passes existing tests Change-Id: Ic27b93ccfe6bbc97e7419293ce165fee6cd51e6d
This commit is contained in:
@@ -21,6 +21,7 @@ import static android.os.UserHandle.PER_USER_RANGE;
|
|||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
import android.os.Parcel;
|
import android.os.Parcel;
|
||||||
import android.os.Parcelable;
|
import android.os.Parcelable;
|
||||||
|
import android.os.UserHandle;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
@@ -45,6 +46,14 @@ public final class UidRange implements Parcelable {
|
|||||||
return new UidRange(userId * PER_USER_RANGE, (userId + 1) * PER_USER_RANGE - 1);
|
return new UidRange(userId * PER_USER_RANGE, (userId + 1) * PER_USER_RANGE - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Creates a UidRange for the specified user. */
|
||||||
|
public static UidRange createForUser(UserHandle user) {
|
||||||
|
final UserHandle nextUser = UserHandle.of(user.getIdentifier() + 1);
|
||||||
|
final int start = UserHandle.getUid(user, 0 /* appId */);
|
||||||
|
final int end = UserHandle.getUid(nextUser, 0) - 1;
|
||||||
|
return new UidRange(start, end);
|
||||||
|
}
|
||||||
|
|
||||||
/** Returns the smallest user Id which is contained in this UidRange */
|
/** Returns the smallest user Id which is contained in this UidRange */
|
||||||
public int getStartUser() {
|
public int getStartUser() {
|
||||||
return start / PER_USER_RANGE;
|
return start / PER_USER_RANGE;
|
||||||
|
|||||||
@@ -4973,12 +4973,12 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onUserAdded(int userId) {
|
private void onUserAdded(UserHandle user) {
|
||||||
mPermissionMonitor.onUserAdded(userId);
|
mPermissionMonitor.onUserAdded(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onUserRemoved(int userId) {
|
private void onUserRemoved(UserHandle user) {
|
||||||
mPermissionMonitor.onUserRemoved(userId);
|
mPermissionMonitor.onUserRemoved(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
|
private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
|
||||||
@@ -4986,15 +4986,18 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
public void onReceive(Context context, Intent intent) {
|
public void onReceive(Context context, Intent intent) {
|
||||||
ensureRunningOnConnectivityServiceThread();
|
ensureRunningOnConnectivityServiceThread();
|
||||||
final String action = intent.getAction();
|
final String action = intent.getAction();
|
||||||
final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
|
final UserHandle user = intent.getParcelableExtra(Intent.EXTRA_USER);
|
||||||
|
|
||||||
// UserId should be filled for below intents, check the existence.
|
// User should be filled for below intents, check the existence.
|
||||||
if (userId == UserHandle.USER_NULL) return;
|
if (user == null) {
|
||||||
|
Log.wtf(TAG, intent.getAction() + " broadcast without EXTRA_USER");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (Intent.ACTION_USER_ADDED.equals(action)) {
|
if (Intent.ACTION_USER_ADDED.equals(action)) {
|
||||||
onUserAdded(userId);
|
onUserAdded(user);
|
||||||
} else if (Intent.ACTION_USER_REMOVED.equals(action)) {
|
} else if (Intent.ACTION_USER_REMOVED.equals(action)) {
|
||||||
onUserRemoved(userId);
|
onUserRemoved(user);
|
||||||
} else {
|
} else {
|
||||||
Log.wtf(TAG, "received unexpected intent: " + action);
|
Log.wtf(TAG, "received unexpected intent: " + action);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -83,9 +83,8 @@ public class PermissionMonitor implements PackageManagerInternal.PackageListObse
|
|||||||
private final INetd mNetd;
|
private final INetd mNetd;
|
||||||
private final Dependencies mDeps;
|
private final Dependencies mDeps;
|
||||||
|
|
||||||
// Values are User IDs.
|
|
||||||
@GuardedBy("this")
|
@GuardedBy("this")
|
||||||
private final Set<Integer> mUsers = new HashSet<>();
|
private final Set<UserHandle> mUsers = new HashSet<>();
|
||||||
|
|
||||||
// Keys are app uids. Values are true for SYSTEM permission and false for NETWORK permission.
|
// Keys are app uids. Values are true for SYSTEM permission and false for NETWORK permission.
|
||||||
@GuardedBy("this")
|
@GuardedBy("this")
|
||||||
@@ -173,10 +172,7 @@ public class PermissionMonitor implements PackageManagerInternal.PackageListObse
|
|||||||
netdPermsUids.put(uid, netdPermsUids.get(uid) | otherNetdPerms);
|
netdPermsUids.put(uid, netdPermsUids.get(uid) | otherNetdPerms);
|
||||||
}
|
}
|
||||||
|
|
||||||
final List<UserHandle> users = mUserManager.getUserHandles(true /* excludeDying */);
|
mUsers.addAll(mUserManager.getUserHandles(true /* excludeDying */));
|
||||||
for (UserHandle user : users) {
|
|
||||||
mUsers.add(user.getIdentifier());
|
|
||||||
}
|
|
||||||
|
|
||||||
final SparseArray<ArraySet<String>> systemPermission =
|
final SparseArray<ArraySet<String>> systemPermission =
|
||||||
SystemConfig.getInstance().getSystemPermissions();
|
SystemConfig.getInstance().getSystemPermissions();
|
||||||
@@ -259,16 +255,15 @@ public class PermissionMonitor implements PackageManagerInternal.PackageListObse
|
|||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void update(Set<Integer> users, Map<Integer, Boolean> apps, boolean add) {
|
private void update(Set<UserHandle> users, Map<Integer, Boolean> apps, boolean add) {
|
||||||
List<Integer> network = new ArrayList<>();
|
List<Integer> network = new ArrayList<>();
|
||||||
List<Integer> system = new ArrayList<>();
|
List<Integer> system = new ArrayList<>();
|
||||||
for (Entry<Integer, Boolean> app : apps.entrySet()) {
|
for (Entry<Integer, Boolean> app : apps.entrySet()) {
|
||||||
List<Integer> list = app.getValue() ? system : network;
|
List<Integer> list = app.getValue() ? system : network;
|
||||||
for (int user : users) {
|
for (UserHandle user : users) {
|
||||||
final UserHandle handle = UserHandle.of(user);
|
if (user == null) continue;
|
||||||
if (handle == null) continue;
|
|
||||||
|
|
||||||
list.add(UserHandle.getUid(handle, app.getKey()));
|
list.add(UserHandle.getUid(user, app.getKey()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
@@ -291,14 +286,10 @@ public class PermissionMonitor implements PackageManagerInternal.PackageListObse
|
|||||||
*
|
*
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
public synchronized void onUserAdded(int user) {
|
public synchronized void onUserAdded(@NonNull UserHandle user) {
|
||||||
if (user < 0) {
|
|
||||||
loge("Invalid user in onUserAdded: " + user);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
mUsers.add(user);
|
mUsers.add(user);
|
||||||
|
|
||||||
Set<Integer> users = new HashSet<>();
|
Set<UserHandle> users = new HashSet<>();
|
||||||
users.add(user);
|
users.add(user);
|
||||||
update(users, mApps, true);
|
update(users, mApps, true);
|
||||||
}
|
}
|
||||||
@@ -310,14 +301,10 @@ public class PermissionMonitor implements PackageManagerInternal.PackageListObse
|
|||||||
*
|
*
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
public synchronized void onUserRemoved(int user) {
|
public synchronized void onUserRemoved(@NonNull UserHandle user) {
|
||||||
if (user < 0) {
|
|
||||||
loge("Invalid user in onUserRemoved: " + user);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
mUsers.remove(user);
|
mUsers.remove(user);
|
||||||
|
|
||||||
Set<Integer> users = new HashSet<>();
|
Set<UserHandle> users = new HashSet<>();
|
||||||
users.add(user);
|
users.add(user);
|
||||||
update(users, mApps, false);
|
update(users, mApps, false);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -89,8 +89,8 @@ import java.util.Set;
|
|||||||
@RunWith(AndroidJUnit4.class)
|
@RunWith(AndroidJUnit4.class)
|
||||||
@SmallTest
|
@SmallTest
|
||||||
public class PermissionMonitorTest {
|
public class PermissionMonitorTest {
|
||||||
private static final int MOCK_USER1 = 0;
|
private static final UserHandle MOCK_USER1 = UserHandle.of(0);
|
||||||
private static final int MOCK_USER2 = 1;
|
private static final UserHandle MOCK_USER2 = UserHandle.of(1);
|
||||||
private static final int MOCK_UID1 = 10001;
|
private static final int MOCK_UID1 = 10001;
|
||||||
private static final int MOCK_UID2 = 10086;
|
private static final int MOCK_UID2 = 10086;
|
||||||
private static final int SYSTEM_UID1 = 1000;
|
private static final int SYSTEM_UID1 = 1000;
|
||||||
@@ -123,10 +123,7 @@ public class PermissionMonitorTest {
|
|||||||
when(mContext.getPackageManager()).thenReturn(mPackageManager);
|
when(mContext.getPackageManager()).thenReturn(mPackageManager);
|
||||||
when(mContext.getSystemService(eq(Context.USER_SERVICE))).thenReturn(mUserManager);
|
when(mContext.getSystemService(eq(Context.USER_SERVICE))).thenReturn(mUserManager);
|
||||||
when(mUserManager.getUserHandles(eq(true))).thenReturn(
|
when(mUserManager.getUserHandles(eq(true))).thenReturn(
|
||||||
Arrays.asList(new UserHandle[] {
|
Arrays.asList(new UserHandle[] { MOCK_USER1, MOCK_USER2 }));
|
||||||
new UserHandle(MOCK_USER1),
|
|
||||||
new UserHandle(MOCK_USER2),
|
|
||||||
}));
|
|
||||||
|
|
||||||
mPermissionMonitor = spy(new PermissionMonitor(mContext, mNetdService, mDeps));
|
mPermissionMonitor = spy(new PermissionMonitor(mContext, mNetdService, mDeps));
|
||||||
|
|
||||||
@@ -184,7 +181,8 @@ public class PermissionMonitorTest {
|
|||||||
return packageInfo;
|
return packageInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static PackageInfo buildPackageInfo(boolean hasSystemPermission, int uid, int userId) {
|
private static PackageInfo buildPackageInfo(boolean hasSystemPermission, int uid,
|
||||||
|
UserHandle user) {
|
||||||
final PackageInfo pkgInfo;
|
final PackageInfo pkgInfo;
|
||||||
if (hasSystemPermission) {
|
if (hasSystemPermission) {
|
||||||
pkgInfo = systemPackageInfoWithPermissions(
|
pkgInfo = systemPackageInfoWithPermissions(
|
||||||
@@ -192,7 +190,7 @@ public class PermissionMonitorTest {
|
|||||||
} else {
|
} else {
|
||||||
pkgInfo = packageInfoWithPermissions(REQUESTED_PERMISSION_GRANTED, new String[] {}, "");
|
pkgInfo = packageInfoWithPermissions(REQUESTED_PERMISSION_GRANTED, new String[] {}, "");
|
||||||
}
|
}
|
||||||
pkgInfo.applicationInfo.uid = UserHandle.getUid(userId, UserHandle.getAppId(uid));
|
pkgInfo.applicationInfo.uid = UserHandle.getUid(user, UserHandle.getAppId(uid));
|
||||||
return pkgInfo;
|
return pkgInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -382,8 +380,8 @@ public class PermissionMonitorTest {
|
|||||||
}).when(mockNetd).networkClearPermissionForUser(any(int[].class));
|
}).when(mockNetd).networkClearPermissionForUser(any(int[].class));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void expectPermission(Boolean permission, int[] users, int[] apps) {
|
public void expectPermission(Boolean permission, UserHandle[] users, int[] apps) {
|
||||||
for (final int user : users) {
|
for (final UserHandle user : users) {
|
||||||
for (final int app : apps) {
|
for (final int app : apps) {
|
||||||
final int uid = UserHandle.getUid(user, app);
|
final int uid = UserHandle.getUid(user, app);
|
||||||
if (!mApps.containsKey(uid)) {
|
if (!mApps.containsKey(uid)) {
|
||||||
@@ -396,8 +394,8 @@ public class PermissionMonitorTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void expectNoPermission(int[] users, int[] apps) {
|
public void expectNoPermission(UserHandle[] users, int[] apps) {
|
||||||
for (final int user : users) {
|
for (final UserHandle user : users) {
|
||||||
for (final int app : apps) {
|
for (final int app : apps) {
|
||||||
final int uid = UserHandle.getUid(user, app);
|
final int uid = UserHandle.getUid(user, app);
|
||||||
if (mApps.containsKey(uid)) {
|
if (mApps.containsKey(uid)) {
|
||||||
@@ -425,46 +423,48 @@ public class PermissionMonitorTest {
|
|||||||
|
|
||||||
// Add SYSTEM_PACKAGE2, expect only have network permission.
|
// Add SYSTEM_PACKAGE2, expect only have network permission.
|
||||||
mPermissionMonitor.onUserAdded(MOCK_USER1);
|
mPermissionMonitor.onUserAdded(MOCK_USER1);
|
||||||
addPackageForUsers(new int[]{MOCK_USER1}, SYSTEM_PACKAGE2, SYSTEM_UID);
|
addPackageForUsers(new UserHandle[]{MOCK_USER1}, SYSTEM_PACKAGE2, SYSTEM_UID);
|
||||||
mNetdMonitor.expectPermission(NETWORK, new int[]{MOCK_USER1}, new int[]{SYSTEM_UID});
|
mNetdMonitor.expectPermission(NETWORK, new UserHandle[]{MOCK_USER1}, new int[]{SYSTEM_UID});
|
||||||
|
|
||||||
// Add SYSTEM_PACKAGE1, expect permission escalate.
|
// Add SYSTEM_PACKAGE1, expect permission escalate.
|
||||||
addPackageForUsers(new int[]{MOCK_USER1}, SYSTEM_PACKAGE1, SYSTEM_UID);
|
addPackageForUsers(new UserHandle[]{MOCK_USER1}, SYSTEM_PACKAGE1, SYSTEM_UID);
|
||||||
mNetdMonitor.expectPermission(SYSTEM, new int[]{MOCK_USER1}, new int[]{SYSTEM_UID});
|
mNetdMonitor.expectPermission(SYSTEM, new UserHandle[]{MOCK_USER1}, new int[]{SYSTEM_UID});
|
||||||
|
|
||||||
mPermissionMonitor.onUserAdded(MOCK_USER2);
|
mPermissionMonitor.onUserAdded(MOCK_USER2);
|
||||||
mNetdMonitor.expectPermission(SYSTEM, new int[]{MOCK_USER1, MOCK_USER2},
|
mNetdMonitor.expectPermission(SYSTEM, new UserHandle[]{MOCK_USER1, MOCK_USER2},
|
||||||
new int[]{SYSTEM_UID});
|
new int[]{SYSTEM_UID});
|
||||||
|
|
||||||
addPackageForUsers(new int[]{MOCK_USER1, MOCK_USER2}, MOCK_PACKAGE1, MOCK_UID1);
|
addPackageForUsers(new UserHandle[]{MOCK_USER1, MOCK_USER2}, MOCK_PACKAGE1, MOCK_UID1);
|
||||||
mNetdMonitor.expectPermission(SYSTEM, new int[]{MOCK_USER1, MOCK_USER2},
|
mNetdMonitor.expectPermission(SYSTEM, new UserHandle[]{MOCK_USER1, MOCK_USER2},
|
||||||
new int[]{SYSTEM_UID});
|
new int[]{SYSTEM_UID});
|
||||||
mNetdMonitor.expectPermission(NETWORK, new int[]{MOCK_USER1, MOCK_USER2},
|
mNetdMonitor.expectPermission(NETWORK, new UserHandle[]{MOCK_USER1, MOCK_USER2},
|
||||||
new int[]{MOCK_UID1});
|
new int[]{MOCK_UID1});
|
||||||
|
|
||||||
// Remove MOCK_UID1, expect no permission left for all user.
|
// Remove MOCK_UID1, expect no permission left for all user.
|
||||||
mPermissionMonitor.onPackageRemoved(MOCK_PACKAGE1, MOCK_UID1);
|
mPermissionMonitor.onPackageRemoved(MOCK_PACKAGE1, MOCK_UID1);
|
||||||
removePackageForUsers(new int[]{MOCK_USER1, MOCK_USER2}, MOCK_PACKAGE1, MOCK_UID1);
|
removePackageForUsers(new UserHandle[]{MOCK_USER1, MOCK_USER2}, MOCK_PACKAGE1, MOCK_UID1);
|
||||||
mNetdMonitor.expectNoPermission(new int[]{MOCK_USER1, MOCK_USER2}, new int[]{MOCK_UID1});
|
mNetdMonitor.expectNoPermission(new UserHandle[]{MOCK_USER1, MOCK_USER2},
|
||||||
|
new int[]{MOCK_UID1});
|
||||||
|
|
||||||
// Remove SYSTEM_PACKAGE1, expect permission downgrade.
|
// Remove SYSTEM_PACKAGE1, expect permission downgrade.
|
||||||
when(mPackageManager.getPackagesForUid(anyInt())).thenReturn(new String[]{SYSTEM_PACKAGE2});
|
when(mPackageManager.getPackagesForUid(anyInt())).thenReturn(new String[]{SYSTEM_PACKAGE2});
|
||||||
removePackageForUsers(new int[]{MOCK_USER1, MOCK_USER2}, SYSTEM_PACKAGE1, SYSTEM_UID);
|
removePackageForUsers(new UserHandle[]{MOCK_USER1, MOCK_USER2},
|
||||||
mNetdMonitor.expectPermission(NETWORK, new int[]{MOCK_USER1, MOCK_USER2},
|
SYSTEM_PACKAGE1, SYSTEM_UID);
|
||||||
|
mNetdMonitor.expectPermission(NETWORK, new UserHandle[]{MOCK_USER1, MOCK_USER2},
|
||||||
new int[]{SYSTEM_UID});
|
new int[]{SYSTEM_UID});
|
||||||
|
|
||||||
mPermissionMonitor.onUserRemoved(MOCK_USER1);
|
mPermissionMonitor.onUserRemoved(MOCK_USER1);
|
||||||
mNetdMonitor.expectPermission(NETWORK, new int[]{MOCK_USER2}, new int[]{SYSTEM_UID});
|
mNetdMonitor.expectPermission(NETWORK, new UserHandle[]{MOCK_USER2}, new int[]{SYSTEM_UID});
|
||||||
|
|
||||||
// Remove all packages, expect no permission left.
|
// Remove all packages, expect no permission left.
|
||||||
when(mPackageManager.getPackagesForUid(anyInt())).thenReturn(new String[]{});
|
when(mPackageManager.getPackagesForUid(anyInt())).thenReturn(new String[]{});
|
||||||
removePackageForUsers(new int[]{MOCK_USER2}, SYSTEM_PACKAGE2, SYSTEM_UID);
|
removePackageForUsers(new UserHandle[]{MOCK_USER2}, SYSTEM_PACKAGE2, SYSTEM_UID);
|
||||||
mNetdMonitor.expectNoPermission(new int[]{MOCK_USER1, MOCK_USER2},
|
mNetdMonitor.expectNoPermission(new UserHandle[]{MOCK_USER1, MOCK_USER2},
|
||||||
new int[]{SYSTEM_UID, MOCK_UID1});
|
new int[]{SYSTEM_UID, MOCK_UID1});
|
||||||
|
|
||||||
// Remove last user, expect no redundant clearPermission is invoked.
|
// Remove last user, expect no redundant clearPermission is invoked.
|
||||||
mPermissionMonitor.onUserRemoved(MOCK_USER2);
|
mPermissionMonitor.onUserRemoved(MOCK_USER2);
|
||||||
mNetdMonitor.expectNoPermission(new int[]{MOCK_USER1, MOCK_USER2},
|
mNetdMonitor.expectNoPermission(new UserHandle[]{MOCK_USER1, MOCK_USER2},
|
||||||
new int[]{SYSTEM_UID, MOCK_UID1});
|
new int[]{SYSTEM_UID, MOCK_UID1});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -548,14 +548,14 @@ public class PermissionMonitorTest {
|
|||||||
// Normal package add/remove operations will trigger multiple intent for uids corresponding to
|
// Normal package add/remove operations will trigger multiple intent for uids corresponding to
|
||||||
// each user. To simulate generic package operations, the onPackageAdded/Removed will need to be
|
// each user. To simulate generic package operations, the onPackageAdded/Removed will need to be
|
||||||
// called multiple times with the uid corresponding to each user.
|
// called multiple times with the uid corresponding to each user.
|
||||||
private void addPackageForUsers(int[] users, String packageName, int uid) {
|
private void addPackageForUsers(UserHandle[] users, String packageName, int uid) {
|
||||||
for (final int user : users) {
|
for (final UserHandle user : users) {
|
||||||
mPermissionMonitor.onPackageAdded(packageName, UserHandle.getUid(user, uid));
|
mPermissionMonitor.onPackageAdded(packageName, UserHandle.getUid(user, uid));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void removePackageForUsers(int[] users, String packageName, int uid) {
|
private void removePackageForUsers(UserHandle[] users, String packageName, int uid) {
|
||||||
for (final int user : users) {
|
for (final UserHandle user : users) {
|
||||||
mPermissionMonitor.onPackageRemoved(packageName, UserHandle.getUid(user, uid));
|
mPermissionMonitor.onPackageRemoved(packageName, UserHandle.getUid(user, uid));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user