Update CS so that per-app OEM APIs can be tested
Updates to ConnectivityService so that the set OEM network preference per app APIs can be tested via CTS. Bug: 176496580 Bug: 176494815 Test: atest FrameworksNetTests atest FrameworksNetIntegrationTests atest CtsNetTestCasesLatestSdk Change-Id: I5a47dcece31749293f080af060218d827082eb67
This commit is contained in:
@@ -79,6 +79,8 @@ import static android.net.NetworkCapabilities.TRANSPORT_TEST;
|
|||||||
import static android.net.NetworkCapabilities.TRANSPORT_VPN;
|
import static android.net.NetworkCapabilities.TRANSPORT_VPN;
|
||||||
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
|
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
|
||||||
import static android.net.NetworkRequest.Type.LISTEN_FOR_BEST;
|
import static android.net.NetworkRequest.Type.LISTEN_FOR_BEST;
|
||||||
|
import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_TEST;
|
||||||
|
import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_TEST_ONLY;
|
||||||
import static android.net.shared.NetworkMonitorUtils.isPrivateDnsValidationRequired;
|
import static android.net.shared.NetworkMonitorUtils.isPrivateDnsValidationRequired;
|
||||||
import static android.os.Process.INVALID_UID;
|
import static android.os.Process.INVALID_UID;
|
||||||
import static android.os.Process.VPN_UID;
|
import static android.os.Process.VPN_UID;
|
||||||
@@ -2596,6 +2598,12 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
"ConnectivityService");
|
"ConnectivityService");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void enforceManageTestNetworksPermission() {
|
||||||
|
mContext.enforceCallingOrSelfPermission(
|
||||||
|
android.Manifest.permission.MANAGE_TEST_NETWORKS,
|
||||||
|
"ConnectivityService");
|
||||||
|
}
|
||||||
|
|
||||||
private boolean checkNetworkStackPermission() {
|
private boolean checkNetworkStackPermission() {
|
||||||
return checkAnyPermissionOf(
|
return checkAnyPermissionOf(
|
||||||
android.Manifest.permission.NETWORK_STACK,
|
android.Manifest.permission.NETWORK_STACK,
|
||||||
@@ -9876,8 +9884,15 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
@NonNull final OemNetworkPreferences preference,
|
@NonNull final OemNetworkPreferences preference,
|
||||||
@Nullable final IOnCompleteListener listener) {
|
@Nullable final IOnCompleteListener listener) {
|
||||||
|
|
||||||
|
Objects.requireNonNull(preference, "OemNetworkPreferences must be non-null");
|
||||||
|
// Only bypass the permission/device checks if this is a valid test request.
|
||||||
|
if (isValidTestOemNetworkPreference(preference)) {
|
||||||
|
enforceManageTestNetworksPermission();
|
||||||
|
} else {
|
||||||
enforceAutomotiveDevice();
|
enforceAutomotiveDevice();
|
||||||
enforceOemNetworkPreferencesPermission();
|
enforceOemNetworkPreferencesPermission();
|
||||||
|
validateOemNetworkPreferences(preference);
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Have a priority for each preference.
|
// TODO: Have a priority for each preference.
|
||||||
if (!mProfileNetworkPreferences.isEmpty() || !mMobileDataPreferredUids.isEmpty()) {
|
if (!mProfileNetworkPreferences.isEmpty() || !mMobileDataPreferredUids.isEmpty()) {
|
||||||
@@ -9889,18 +9904,41 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
throwConcurrentPreferenceException();
|
throwConcurrentPreferenceException();
|
||||||
}
|
}
|
||||||
|
|
||||||
Objects.requireNonNull(preference, "OemNetworkPreferences must be non-null");
|
|
||||||
validateOemNetworkPreferences(preference);
|
|
||||||
mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_OEM_NETWORK_PREFERENCE,
|
mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_OEM_NETWORK_PREFERENCE,
|
||||||
new Pair<>(preference, listener)));
|
new Pair<>(preference, listener)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check the validity of an OEM network preference to be used for testing purposes.
|
||||||
|
* @param preference the preference to validate
|
||||||
|
* @return true if this is a valid OEM network preference test request.
|
||||||
|
*/
|
||||||
|
private boolean isValidTestOemNetworkPreference(
|
||||||
|
@NonNull final OemNetworkPreferences preference) {
|
||||||
|
// Allow for clearing of an existing OemNetworkPreference used for testing.
|
||||||
|
// This isn't called on the handler thread so it is possible that mOemNetworkPreferences
|
||||||
|
// changes after this check is complete. This is an unlikely scenario as calling of this API
|
||||||
|
// is controlled by the OEM therefore the added complexity is not worth adding given those
|
||||||
|
// circumstances. That said, it is an edge case to be aware of hence this comment.
|
||||||
|
final boolean isValidTestClearPref = preference.getNetworkPreferences().size() == 0
|
||||||
|
&& isTestOemNetworkPreference(mOemNetworkPreferences);
|
||||||
|
return isTestOemNetworkPreference(preference) || isValidTestClearPref;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isTestOemNetworkPreference(@NonNull final OemNetworkPreferences preference) {
|
||||||
|
final Map<String, Integer> prefMap = preference.getNetworkPreferences();
|
||||||
|
return prefMap.size() == 1
|
||||||
|
&& (prefMap.containsValue(OEM_NETWORK_PREFERENCE_TEST)
|
||||||
|
|| prefMap.containsValue(OEM_NETWORK_PREFERENCE_TEST_ONLY));
|
||||||
|
}
|
||||||
|
|
||||||
private void validateOemNetworkPreferences(@NonNull OemNetworkPreferences preference) {
|
private void validateOemNetworkPreferences(@NonNull OemNetworkPreferences preference) {
|
||||||
for (@OemNetworkPreferences.OemNetworkPreference final int pref
|
for (@OemNetworkPreferences.OemNetworkPreference final int pref
|
||||||
: preference.getNetworkPreferences().values()) {
|
: preference.getNetworkPreferences().values()) {
|
||||||
if (OemNetworkPreferences.OEM_NETWORK_PREFERENCE_UNINITIALIZED == pref) {
|
if (pref <= 0 || OemNetworkPreferences.OEM_NETWORK_PREFERENCE_MAX < pref) {
|
||||||
final String msg = "OEM_NETWORK_PREFERENCE_UNINITIALIZED is an invalid value.";
|
throw new IllegalArgumentException(
|
||||||
throw new IllegalArgumentException(msg);
|
OemNetworkPreferences.oemNetworkPreferenceToString(pref)
|
||||||
|
+ " is an invalid value.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -10124,13 +10162,21 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
case OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY:
|
case OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY:
|
||||||
requests.add(createOemPrivateNetworkRequest());
|
requests.add(createOemPrivateNetworkRequest());
|
||||||
break;
|
break;
|
||||||
|
case OEM_NETWORK_PREFERENCE_TEST:
|
||||||
|
requests.add(createUnmeteredNetworkRequest());
|
||||||
|
requests.add(createTestNetworkRequest());
|
||||||
|
requests.add(createDefaultRequest());
|
||||||
|
break;
|
||||||
|
case OEM_NETWORK_PREFERENCE_TEST_ONLY:
|
||||||
|
requests.add(createTestNetworkRequest());
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
// This should never happen.
|
// This should never happen.
|
||||||
throw new IllegalArgumentException("createNriFromOemNetworkPreferences()"
|
throw new IllegalArgumentException("createNriFromOemNetworkPreferences()"
|
||||||
+ " called with invalid preference of " + preference);
|
+ " called with invalid preference of " + preference);
|
||||||
}
|
}
|
||||||
|
|
||||||
final ArraySet ranges = new ArraySet<Integer>();
|
final ArraySet<UidRange> ranges = new ArraySet<>();
|
||||||
for (final int uid : uids) {
|
for (final int uid : uids) {
|
||||||
ranges.add(new UidRange(uid, uid));
|
ranges.add(new UidRange(uid, uid));
|
||||||
}
|
}
|
||||||
@@ -10162,10 +10208,17 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
}
|
}
|
||||||
|
|
||||||
private NetworkCapabilities createDefaultPerAppNetCap() {
|
private NetworkCapabilities createDefaultPerAppNetCap() {
|
||||||
final NetworkCapabilities netCap = new NetworkCapabilities();
|
final NetworkCapabilities netcap = new NetworkCapabilities();
|
||||||
netCap.addCapability(NET_CAPABILITY_INTERNET);
|
netcap.addCapability(NET_CAPABILITY_INTERNET);
|
||||||
netCap.setRequestorUidAndPackageName(Process.myUid(), mContext.getPackageName());
|
netcap.setRequestorUidAndPackageName(Process.myUid(), mContext.getPackageName());
|
||||||
return netCap;
|
return netcap;
|
||||||
|
}
|
||||||
|
|
||||||
|
private NetworkRequest createTestNetworkRequest() {
|
||||||
|
final NetworkCapabilities netcap = new NetworkCapabilities();
|
||||||
|
netcap.clearAll();
|
||||||
|
netcap.addTransportType(TRANSPORT_TEST);
|
||||||
|
return createNetworkRequest(NetworkRequest.Type.REQUEST, netcap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -113,6 +113,8 @@ import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID;
|
|||||||
import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK;
|
import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK;
|
||||||
import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY;
|
import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY;
|
||||||
import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY;
|
import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY;
|
||||||
|
import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_TEST;
|
||||||
|
import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_TEST_ONLY;
|
||||||
import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_UNINITIALIZED;
|
import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_UNINITIALIZED;
|
||||||
import static android.net.RouteInfo.RTN_UNREACHABLE;
|
import static android.net.RouteInfo.RTN_UNREACHABLE;
|
||||||
import static android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener.PREFIX_OPERATION_ADDED;
|
import static android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener.PREFIX_OPERATION_ADDED;
|
||||||
@@ -10631,8 +10633,7 @@ public class ConnectivityServiceTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testOemNetworkRequestFactoryPreferenceUninitializedThrowsError()
|
public void testOemNetworkRequestFactoryPreferenceUninitializedThrowsError() {
|
||||||
throws PackageManager.NameNotFoundException {
|
|
||||||
@OemNetworkPreferences.OemNetworkPreference final int prefToTest =
|
@OemNetworkPreferences.OemNetworkPreference final int prefToTest =
|
||||||
OEM_NETWORK_PREFERENCE_UNINITIALIZED;
|
OEM_NETWORK_PREFERENCE_UNINITIALIZED;
|
||||||
|
|
||||||
@@ -10894,7 +10895,48 @@ public class ConnectivityServiceTest {
|
|||||||
assertThrows(UnsupportedOperationException.class,
|
assertThrows(UnsupportedOperationException.class,
|
||||||
() -> mService.setOemNetworkPreference(
|
() -> mService.setOemNetworkPreference(
|
||||||
createDefaultOemNetworkPreferences(networkPref),
|
createDefaultOemNetworkPreferences(networkPref),
|
||||||
new TestOemListenerCallback()));
|
null));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSetOemNetworkPreferenceFailsForTestRequestWithoutPermission() {
|
||||||
|
// Calling setOemNetworkPreference() with a test pref requires the permission
|
||||||
|
// MANAGE_TEST_NETWORKS.
|
||||||
|
mockHasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, false);
|
||||||
|
@OemNetworkPreferences.OemNetworkPreference final int networkPref =
|
||||||
|
OEM_NETWORK_PREFERENCE_TEST;
|
||||||
|
|
||||||
|
// Act on ConnectivityService.setOemNetworkPreference()
|
||||||
|
assertThrows(SecurityException.class,
|
||||||
|
() -> mService.setOemNetworkPreference(
|
||||||
|
createDefaultOemNetworkPreferences(networkPref),
|
||||||
|
null));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSetOemNetworkPreferenceFailsForInvalidTestRequest() {
|
||||||
|
assertSetOemNetworkPreferenceFailsForInvalidTestRequest(OEM_NETWORK_PREFERENCE_TEST);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSetOemNetworkPreferenceFailsForInvalidTestOnlyRequest() {
|
||||||
|
assertSetOemNetworkPreferenceFailsForInvalidTestRequest(OEM_NETWORK_PREFERENCE_TEST_ONLY);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertSetOemNetworkPreferenceFailsForInvalidTestRequest(
|
||||||
|
@OemNetworkPreferences.OemNetworkPreference final int oemNetworkPreferenceForTest) {
|
||||||
|
mockHasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, true);
|
||||||
|
final String secondPackage = "does.not.matter";
|
||||||
|
|
||||||
|
// A valid test request would only have a single mapping.
|
||||||
|
final OemNetworkPreferences pref = new OemNetworkPreferences.Builder()
|
||||||
|
.addNetworkPreference(TEST_PACKAGE_NAME, oemNetworkPreferenceForTest)
|
||||||
|
.addNetworkPreference(secondPackage, oemNetworkPreferenceForTest)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// Act on ConnectivityService.setOemNetworkPreference()
|
||||||
|
assertThrows(IllegalArgumentException.class,
|
||||||
|
() -> mService.setOemNetworkPreference(pref, null));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setOemNetworkPreferenceAgentConnected(final int transportType,
|
private void setOemNetworkPreferenceAgentConnected(final int transportType,
|
||||||
@@ -11060,8 +11102,18 @@ public class ConnectivityServiceTest {
|
|||||||
private void setupSetOemNetworkPreferenceForPreferenceTest(
|
private void setupSetOemNetworkPreferenceForPreferenceTest(
|
||||||
@OemNetworkPreferences.OemNetworkPreference final int networkPrefToSetup,
|
@OemNetworkPreferences.OemNetworkPreference final int networkPrefToSetup,
|
||||||
@NonNull final UidRangeParcel[] uidRanges,
|
@NonNull final UidRangeParcel[] uidRanges,
|
||||||
@NonNull final String testPackageName)
|
@NonNull final String testPackageName) throws Exception {
|
||||||
throws Exception {
|
setupSetOemNetworkPreferenceForPreferenceTest(
|
||||||
|
networkPrefToSetup, uidRanges, testPackageName, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupSetOemNetworkPreferenceForPreferenceTest(
|
||||||
|
@OemNetworkPreferences.OemNetworkPreference final int networkPrefToSetup,
|
||||||
|
@NonNull final UidRangeParcel[] uidRanges,
|
||||||
|
@NonNull final String testPackageName,
|
||||||
|
final boolean hasAutomotiveFeature) throws Exception {
|
||||||
|
mockHasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, hasAutomotiveFeature);
|
||||||
|
|
||||||
// These tests work off a single UID therefore using 'start' is valid.
|
// These tests work off a single UID therefore using 'start' is valid.
|
||||||
mockGetApplicationInfo(testPackageName, uidRanges[0].start);
|
mockGetApplicationInfo(testPackageName, uidRanges[0].start);
|
||||||
|
|
||||||
@@ -11365,6 +11417,55 @@ public class ConnectivityServiceTest {
|
|||||||
reset(mMockNetd);
|
reset(mMockNetd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test the tracked default requests allows test requests without standard setup.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testSetOemNetworkPreferenceAllowsValidTestRequestWithoutChecks() throws Exception {
|
||||||
|
@OemNetworkPreferences.OemNetworkPreference int networkPref =
|
||||||
|
OEM_NETWORK_PREFERENCE_TEST;
|
||||||
|
validateSetOemNetworkPreferenceAllowsValidTestPrefRequest(networkPref);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test the tracked default requests allows test only requests without standard setup.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testSetOemNetworkPreferenceAllowsValidTestOnlyRequestWithoutChecks()
|
||||||
|
throws Exception {
|
||||||
|
@OemNetworkPreferences.OemNetworkPreference int networkPref =
|
||||||
|
OEM_NETWORK_PREFERENCE_TEST_ONLY;
|
||||||
|
validateSetOemNetworkPreferenceAllowsValidTestPrefRequest(networkPref);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void validateSetOemNetworkPreferenceAllowsValidTestPrefRequest(int networkPref)
|
||||||
|
throws Exception {
|
||||||
|
// The caller must have the MANAGE_TEST_NETWORKS permission.
|
||||||
|
final int testPackageUid = 123;
|
||||||
|
final String validTestPackageName = "does.not.matter";
|
||||||
|
final UidRangeParcel[] uidRanges =
|
||||||
|
toUidRangeStableParcels(uidRangesForUids(testPackageUid));
|
||||||
|
mServiceContext.setPermission(
|
||||||
|
Manifest.permission.MANAGE_TEST_NETWORKS, PERMISSION_GRANTED);
|
||||||
|
|
||||||
|
// Put the system into a state in which setOemNetworkPreference() would normally fail. This
|
||||||
|
// will confirm that a valid test request can bypass these checks.
|
||||||
|
mockHasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, false);
|
||||||
|
mServiceContext.setPermission(
|
||||||
|
Manifest.permission.CONTROL_OEM_PAID_NETWORK_PREFERENCE, PERMISSION_DENIED);
|
||||||
|
|
||||||
|
// Validate the starting requests only includes the system default request.
|
||||||
|
assertEquals(1, mService.mDefaultNetworkRequests.size());
|
||||||
|
|
||||||
|
// Add an OEM default network request to track.
|
||||||
|
setupSetOemNetworkPreferenceForPreferenceTest(
|
||||||
|
networkPref, uidRanges, validTestPackageName,
|
||||||
|
false /* hasAutomotiveFeature */);
|
||||||
|
|
||||||
|
// Two requests should now exist; the system default and the test request.
|
||||||
|
assertEquals(2, mService.mDefaultNetworkRequests.size());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test the tracked default requests clear previous OEM requests on setOemNetworkPreference().
|
* Test the tracked default requests clear previous OEM requests on setOemNetworkPreference().
|
||||||
*/
|
*/
|
||||||
@@ -11377,7 +11478,7 @@ public class ConnectivityServiceTest {
|
|||||||
final UidRangeParcel[] uidRanges =
|
final UidRangeParcel[] uidRanges =
|
||||||
toUidRangeStableParcels(uidRangesForUids(testPackageUid));
|
toUidRangeStableParcels(uidRangesForUids(testPackageUid));
|
||||||
|
|
||||||
// Validate the starting requests only includes the fallback request.
|
// Validate the starting requests only includes the system default request.
|
||||||
assertEquals(1, mService.mDefaultNetworkRequests.size());
|
assertEquals(1, mService.mDefaultNetworkRequests.size());
|
||||||
|
|
||||||
// Add an OEM default network request to track.
|
// Add an OEM default network request to track.
|
||||||
|
|||||||
Reference in New Issue
Block a user