Correctly get uids for per-app network preferences
Per-app network functionality assumed all apps were installed for user 0 which is not always the case. This fix will address that by checking for the existance of an app for all users and adding it to the per-app network preference as was originally intended. Prior, no apps were included if they were not installed for user 0 even if they were available for another user such as user 10 in automotive. Bug: 189838408 Test: atest FrameworksNetTests atest FrameworksNetIntegrationTests atest CtsNetTestCases Change-Id: I7d75cdb02041e7a202254be2eaeca6c2b02d7c29
This commit is contained in:
@@ -10077,7 +10077,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
|
|
||||||
private SparseArray<Set<Integer>> createUidsFromOemNetworkPreferences(
|
private SparseArray<Set<Integer>> createUidsFromOemNetworkPreferences(
|
||||||
@NonNull final OemNetworkPreferences preference) {
|
@NonNull final OemNetworkPreferences preference) {
|
||||||
final SparseArray<Set<Integer>> uids = new SparseArray<>();
|
final SparseArray<Set<Integer>> prefToUids = new SparseArray<>();
|
||||||
final PackageManager pm = mContext.getPackageManager();
|
final PackageManager pm = mContext.getPackageManager();
|
||||||
final List<UserHandle> users =
|
final List<UserHandle> users =
|
||||||
mContext.getSystemService(UserManager.class).getUserHandles(true);
|
mContext.getSystemService(UserManager.class).getUserHandles(true);
|
||||||
@@ -10085,29 +10085,29 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
if (VDBG || DDBG) {
|
if (VDBG || DDBG) {
|
||||||
log("No users currently available for setting the OEM network preference.");
|
log("No users currently available for setting the OEM network preference.");
|
||||||
}
|
}
|
||||||
return uids;
|
return prefToUids;
|
||||||
}
|
}
|
||||||
for (final Map.Entry<String, Integer> entry :
|
for (final Map.Entry<String, Integer> entry :
|
||||||
preference.getNetworkPreferences().entrySet()) {
|
preference.getNetworkPreferences().entrySet()) {
|
||||||
@OemNetworkPreferences.OemNetworkPreference final int pref = entry.getValue();
|
@OemNetworkPreferences.OemNetworkPreference final int pref = entry.getValue();
|
||||||
try {
|
|
||||||
final int uid = pm.getApplicationInfo(entry.getKey(), 0).uid;
|
|
||||||
if (!uids.contains(pref)) {
|
|
||||||
uids.put(pref, new ArraySet<>());
|
|
||||||
}
|
|
||||||
for (final UserHandle ui : users) {
|
|
||||||
// Add the rules for all users as this policy is device wide.
|
// Add the rules for all users as this policy is device wide.
|
||||||
uids.get(pref).add(ui.getUid(uid));
|
for (final UserHandle user : users) {
|
||||||
|
try {
|
||||||
|
final int uid = pm.getApplicationInfoAsUser(entry.getKey(), 0, user).uid;
|
||||||
|
if (!prefToUids.contains(pref)) {
|
||||||
|
prefToUids.put(pref, new ArraySet<>());
|
||||||
}
|
}
|
||||||
|
prefToUids.get(pref).add(uid);
|
||||||
} catch (PackageManager.NameNotFoundException e) {
|
} catch (PackageManager.NameNotFoundException e) {
|
||||||
// Although this may seem like an error scenario, it is ok that uninstalled
|
// Although this may seem like an error scenario, it is ok that uninstalled
|
||||||
// packages are sent on a network preference as the system will watch for
|
// packages are sent on a network preference as the system will watch for
|
||||||
// package installations associated with this network preference and update
|
// package installations associated with this network preference and update
|
||||||
// accordingly. This is done so as to minimize race conditions on app install.
|
// accordingly. This is done to minimize race conditions on app install.
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return uids;
|
}
|
||||||
|
return prefToUids;
|
||||||
}
|
}
|
||||||
|
|
||||||
private NetworkRequestInfo createNriFromOemNetworkPreferences(
|
private NetworkRequestInfo createNriFromOemNetworkPreferences(
|
||||||
|
|||||||
@@ -1535,6 +1535,8 @@ public class ConnectivityServiceTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static final int PRIMARY_USER = 0;
|
private static final int PRIMARY_USER = 0;
|
||||||
|
private static final int SECONDARY_USER = 10;
|
||||||
|
private static final int TERTIARY_USER = 11;
|
||||||
private static final UidRange PRIMARY_UIDRANGE =
|
private static final UidRange PRIMARY_UIDRANGE =
|
||||||
UidRange.createForUser(UserHandle.of(PRIMARY_USER));
|
UidRange.createForUser(UserHandle.of(PRIMARY_USER));
|
||||||
private static final int APP1_UID = UserHandle.getUid(PRIMARY_USER, 10100);
|
private static final int APP1_UID = UserHandle.getUid(PRIMARY_USER, 10100);
|
||||||
@@ -1543,8 +1545,8 @@ public class ConnectivityServiceTest {
|
|||||||
private static final UserInfo PRIMARY_USER_INFO = new UserInfo(PRIMARY_USER, "",
|
private static final UserInfo PRIMARY_USER_INFO = new UserInfo(PRIMARY_USER, "",
|
||||||
UserInfo.FLAG_PRIMARY);
|
UserInfo.FLAG_PRIMARY);
|
||||||
private static final UserHandle PRIMARY_USER_HANDLE = new UserHandle(PRIMARY_USER);
|
private static final UserHandle PRIMARY_USER_HANDLE = new UserHandle(PRIMARY_USER);
|
||||||
private static final int SECONDARY_USER = 10;
|
|
||||||
private static final UserHandle SECONDARY_USER_HANDLE = new UserHandle(SECONDARY_USER);
|
private static final UserHandle SECONDARY_USER_HANDLE = new UserHandle(SECONDARY_USER);
|
||||||
|
private static final UserHandle TERTIARY_USER_HANDLE = new UserHandle(TERTIARY_USER);
|
||||||
|
|
||||||
private static final int RESTRICTED_USER = 1;
|
private static final int RESTRICTED_USER = 1;
|
||||||
private static final UserInfo RESTRICTED_USER_INFO = new UserInfo(RESTRICTED_USER, "",
|
private static final UserInfo RESTRICTED_USER_INFO = new UserInfo(RESTRICTED_USER, "",
|
||||||
@@ -10315,29 +10317,30 @@ public class ConnectivityServiceTest {
|
|||||||
fail("TOO_MANY_REQUESTS never thrown");
|
fail("TOO_MANY_REQUESTS never thrown");
|
||||||
}
|
}
|
||||||
|
|
||||||
private UidRange createUidRange(int userId) {
|
private void mockGetApplicationInfo(@NonNull final String packageName, final int uid) {
|
||||||
return UidRange.createForUser(UserHandle.of(userId));
|
mockGetApplicationInfo(packageName, uid, PRIMARY_USER_HANDLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void mockGetApplicationInfo(@NonNull final String packageName, @NonNull final int uid) {
|
private void mockGetApplicationInfo(@NonNull final String packageName, final int uid,
|
||||||
|
@NonNull final UserHandle user) {
|
||||||
final ApplicationInfo applicationInfo = new ApplicationInfo();
|
final ApplicationInfo applicationInfo = new ApplicationInfo();
|
||||||
applicationInfo.uid = uid;
|
applicationInfo.uid = uid;
|
||||||
try {
|
try {
|
||||||
when(mPackageManager.getApplicationInfo(eq(packageName), anyInt()))
|
when(mPackageManager.getApplicationInfoAsUser(eq(packageName), anyInt(), eq(user)))
|
||||||
.thenReturn(applicationInfo);
|
.thenReturn(applicationInfo);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
fail(e.getMessage());
|
fail(e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void mockGetApplicationInfoThrowsNameNotFound(@NonNull final String packageName)
|
private void mockGetApplicationInfoThrowsNameNotFound(@NonNull final String packageName,
|
||||||
|
@NonNull final UserHandle user)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
when(mPackageManager.getApplicationInfo(eq(packageName), anyInt()))
|
when(mPackageManager.getApplicationInfoAsUser(eq(packageName), anyInt(), eq(user)))
|
||||||
.thenThrow(new PackageManager.NameNotFoundException(packageName));
|
.thenThrow(new PackageManager.NameNotFoundException(packageName));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void mockHasSystemFeature(@NonNull final String featureName,
|
private void mockHasSystemFeature(@NonNull final String featureName, final boolean hasFeature) {
|
||||||
@NonNull final boolean hasFeature) {
|
|
||||||
when(mPackageManager.hasSystemFeature(eq(featureName)))
|
when(mPackageManager.hasSystemFeature(eq(featureName)))
|
||||||
.thenReturn(hasFeature);
|
.thenReturn(hasFeature);
|
||||||
}
|
}
|
||||||
@@ -10531,16 +10534,18 @@ public class ConnectivityServiceTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testOemNetworkRequestFactoryMultipleUsersCorrectlySetsUids()
|
public void testOemNetworkRequestFactoryMultipleUsersSetsUids()
|
||||||
throws Exception {
|
throws Exception {
|
||||||
// Arrange users
|
// Arrange users
|
||||||
final int secondUser = 10;
|
final int secondUserTestPackageUid = UserHandle.getUid(SECONDARY_USER, TEST_PACKAGE_UID);
|
||||||
final UserHandle secondUserHandle = new UserHandle(secondUser);
|
final int thirdUserTestPackageUid = UserHandle.getUid(TERTIARY_USER, TEST_PACKAGE_UID);
|
||||||
when(mUserManager.getUserHandles(anyBoolean())).thenReturn(
|
when(mUserManager.getUserHandles(anyBoolean())).thenReturn(
|
||||||
Arrays.asList(PRIMARY_USER_HANDLE, secondUserHandle));
|
Arrays.asList(PRIMARY_USER_HANDLE, SECONDARY_USER_HANDLE, TERTIARY_USER_HANDLE));
|
||||||
|
|
||||||
// Arrange PackageManager mocks
|
// Arrange PackageManager mocks testing for users who have and don't have a package.
|
||||||
mockGetApplicationInfo(TEST_PACKAGE_NAME, TEST_PACKAGE_UID);
|
mockGetApplicationInfoThrowsNameNotFound(TEST_PACKAGE_NAME, PRIMARY_USER_HANDLE);
|
||||||
|
mockGetApplicationInfo(TEST_PACKAGE_NAME, secondUserTestPackageUid, SECONDARY_USER_HANDLE);
|
||||||
|
mockGetApplicationInfo(TEST_PACKAGE_NAME, thirdUserTestPackageUid, TERTIARY_USER_HANDLE);
|
||||||
|
|
||||||
// Build OemNetworkPreferences object
|
// Build OemNetworkPreferences object
|
||||||
final int testOemPref = OEM_NETWORK_PREFERENCE_OEM_PAID;
|
final int testOemPref = OEM_NETWORK_PREFERENCE_OEM_PAID;
|
||||||
@@ -10554,8 +10559,8 @@ public class ConnectivityServiceTest {
|
|||||||
mService.new OemNetworkRequestFactory().createNrisFromOemNetworkPreferences(
|
mService.new OemNetworkRequestFactory().createNrisFromOemNetworkPreferences(
|
||||||
pref));
|
pref));
|
||||||
|
|
||||||
// UIDs for all users and all managed packages should be present.
|
// UIDs for users with installed packages should be present.
|
||||||
// Two users each with two packages.
|
// Three users exist, but only two have the test package installed.
|
||||||
final int expectedUidSize = 2;
|
final int expectedUidSize = 2;
|
||||||
final List<Range<Integer>> uids =
|
final List<Range<Integer>> uids =
|
||||||
new ArrayList<>(nris.get(0).mRequests.get(0).networkCapabilities.getUids());
|
new ArrayList<>(nris.get(0).mRequests.get(0).networkCapabilities.getUids());
|
||||||
@@ -10563,11 +10568,10 @@ public class ConnectivityServiceTest {
|
|||||||
|
|
||||||
// Sort by uid to access nris by index
|
// Sort by uid to access nris by index
|
||||||
uids.sort(Comparator.comparingInt(uid -> uid.getLower()));
|
uids.sort(Comparator.comparingInt(uid -> uid.getLower()));
|
||||||
final int secondUserTestPackageUid = UserHandle.getUid(secondUser, TEST_PACKAGE_UID);
|
assertEquals(secondUserTestPackageUid, (int) uids.get(0).getLower());
|
||||||
assertEquals(TEST_PACKAGE_UID, (int) uids.get(0).getLower());
|
assertEquals(secondUserTestPackageUid, (int) uids.get(0).getUpper());
|
||||||
assertEquals(TEST_PACKAGE_UID, (int) uids.get(0).getUpper());
|
assertEquals(thirdUserTestPackageUid, (int) uids.get(1).getLower());
|
||||||
assertEquals(secondUserTestPackageUid, (int) uids.get(1).getLower());
|
assertEquals(thirdUserTestPackageUid, (int) uids.get(1).getUpper());
|
||||||
assertEquals(secondUserTestPackageUid, (int) uids.get(1).getUpper());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -11368,6 +11372,7 @@ public class ConnectivityServiceTest {
|
|||||||
final UidRangeParcel[] uidRanges =
|
final UidRangeParcel[] uidRanges =
|
||||||
toUidRangeStableParcels(
|
toUidRangeStableParcels(
|
||||||
uidRangesForUids(TEST_PACKAGE_UID, secondUserTestPackageUid));
|
uidRangesForUids(TEST_PACKAGE_UID, secondUserTestPackageUid));
|
||||||
|
mockGetApplicationInfo(TEST_PACKAGE_NAME, secondUserTestPackageUid, secondUserHandle);
|
||||||
setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges, TEST_PACKAGE_NAME);
|
setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges, TEST_PACKAGE_NAME);
|
||||||
|
|
||||||
// Verify the starting state. No networks should be connected.
|
// Verify the starting state. No networks should be connected.
|
||||||
@@ -11410,6 +11415,7 @@ public class ConnectivityServiceTest {
|
|||||||
final UidRangeParcel[] uidRangesBothUsers =
|
final UidRangeParcel[] uidRangesBothUsers =
|
||||||
toUidRangeStableParcels(
|
toUidRangeStableParcels(
|
||||||
uidRangesForUids(TEST_PACKAGE_UID, secondUserTestPackageUid));
|
uidRangesForUids(TEST_PACKAGE_UID, secondUserTestPackageUid));
|
||||||
|
mockGetApplicationInfo(TEST_PACKAGE_NAME, secondUserTestPackageUid, secondUserHandle);
|
||||||
setupSetOemNetworkPreferenceForPreferenceTest(
|
setupSetOemNetworkPreferenceForPreferenceTest(
|
||||||
networkPref, uidRangesSingleUser, TEST_PACKAGE_NAME);
|
networkPref, uidRangesSingleUser, TEST_PACKAGE_NAME);
|
||||||
|
|
||||||
@@ -11466,7 +11472,7 @@ public class ConnectivityServiceTest {
|
|||||||
final UidRangeParcel[] uidRangesSinglePackage =
|
final UidRangeParcel[] uidRangesSinglePackage =
|
||||||
toUidRangeStableParcels(uidRangesForUids(TEST_PACKAGE_UID));
|
toUidRangeStableParcels(uidRangesForUids(TEST_PACKAGE_UID));
|
||||||
mockGetApplicationInfo(TEST_PACKAGE_NAME, TEST_PACKAGE_UID);
|
mockGetApplicationInfo(TEST_PACKAGE_NAME, TEST_PACKAGE_UID);
|
||||||
mockGetApplicationInfoThrowsNameNotFound(packageToInstall);
|
mockGetApplicationInfoThrowsNameNotFound(packageToInstall, PRIMARY_USER_HANDLE);
|
||||||
setOemNetworkPreference(networkPref, TEST_PACKAGE_NAME, packageToInstall);
|
setOemNetworkPreference(networkPref, TEST_PACKAGE_NAME, packageToInstall);
|
||||||
grantUsingBackgroundNetworksPermissionForUid(Binder.getCallingUid(), packageToInstall);
|
grantUsingBackgroundNetworksPermissionForUid(Binder.getCallingUid(), packageToInstall);
|
||||||
|
|
||||||
@@ -11500,7 +11506,7 @@ public class ConnectivityServiceTest {
|
|||||||
false /* shouldDestroyNetwork */);
|
false /* shouldDestroyNetwork */);
|
||||||
|
|
||||||
// Set the system to no longer recognize the package to be installed
|
// Set the system to no longer recognize the package to be installed
|
||||||
mockGetApplicationInfoThrowsNameNotFound(packageToInstall);
|
mockGetApplicationInfoThrowsNameNotFound(packageToInstall, PRIMARY_USER_HANDLE);
|
||||||
|
|
||||||
// Send a broadcast indicating a package was removed.
|
// Send a broadcast indicating a package was removed.
|
||||||
final Intent removedIntent = new Intent(ACTION_PACKAGE_REMOVED);
|
final Intent removedIntent = new Intent(ACTION_PACKAGE_REMOVED);
|
||||||
|
|||||||
Reference in New Issue
Block a user