Merge "Check network slicing declaration for network request"

This commit is contained in:
Yuyang Huang
2023-03-01 02:13:31 +00:00
committed by Gerrit Code Review
19 changed files with 1078 additions and 0 deletions

View File

@@ -62,6 +62,17 @@ public final class ConnectivityCompatChanges {
// This was a platform change ID with value 191844585L before T
public static final long RUN_NATIVE_NSD_ONLY_IF_LEGACY_APPS_T_AND_LATER = 235355681L;
/**
* The self certified capabilities check should be enabled after android 13.
*
* <p> See {@link android.net.NetworkCapabilities} for more details.
*
* @hide
*/
@ChangeId
@EnabledAfter(targetSdkVersion = Build.VERSION_CODES.TIRAMISU)
public static final long ENABLE_SELF_CERTIFIED_CAPABILITIES_DECLARATION = 266524688;
private ConnectivityCompatChanges() {
}
}

View File

@@ -113,6 +113,7 @@ import android.app.AppOpsManager;
import android.app.BroadcastOptions;
import android.app.PendingIntent;
import android.app.admin.DevicePolicyManager;
import android.app.compat.CompatChanges;
import android.app.usage.NetworkStatsManager;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
@@ -121,6 +122,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.content.res.XmlResourceParser;
import android.database.ContentObserver;
import android.net.CaptivePortal;
import android.net.CaptivePortalData;
@@ -195,6 +197,7 @@ import android.net.UnderlyingNetworkInfo;
import android.net.Uri;
import android.net.VpnManager;
import android.net.VpnTransportInfo;
import android.net.connectivity.ConnectivityCompatChanges;
import android.net.metrics.IpConnectivityLog;
import android.net.metrics.NetworkEvent;
import android.net.netd.aidl.NativeUidRangeConfig;
@@ -269,6 +272,7 @@ import com.android.networkstack.apishim.BroadcastOptionsShimImpl;
import com.android.networkstack.apishim.ConstantsShim;
import com.android.networkstack.apishim.common.BroadcastOptionsShim;
import com.android.networkstack.apishim.common.UnsupportedApiLevelException;
import com.android.server.connectivity.ApplicationSelfCertifiedNetworkCapabilities;
import com.android.server.connectivity.AutodestructReference;
import com.android.server.connectivity.AutomaticOnOffKeepaliveTracker;
import com.android.server.connectivity.AutomaticOnOffKeepaliveTracker.AutomaticOnOffKeepalive;
@@ -279,6 +283,7 @@ import com.android.server.connectivity.DnsManager;
import com.android.server.connectivity.DnsManager.PrivateDnsValidationUpdate;
import com.android.server.connectivity.DscpPolicyTracker;
import com.android.server.connectivity.FullScore;
import com.android.server.connectivity.InvalidTagException;
import com.android.server.connectivity.KeepaliveTracker;
import com.android.server.connectivity.LingerMonitor;
import com.android.server.connectivity.MockableSystemProperties;
@@ -300,6 +305,8 @@ import com.android.server.connectivity.wear.CompanionDeviceManagerProxyService;
import libcore.io.IoUtils;
import org.xmlpull.v1.XmlPullParserException;
import java.io.FileDescriptor;
import java.io.IOException;
import java.io.PrintWriter;
@@ -902,6 +909,13 @@ public class ConnectivityService extends IConnectivityManager.Stub
// Only the handler thread is allowed to access this field.
private long mIngressRateLimit = -1;
// This is the cache for the packageName -> ApplicationSelfCertifiedNetworkCapabilities. This
// value can be accessed from both handler thread and any random binder thread. Therefore,
// accessing this value requires holding a lock.
@GuardedBy("mSelfCertifiedCapabilityCache")
private final Map<String, ApplicationSelfCertifiedNetworkCapabilities>
mSelfCertifiedCapabilityCache = new HashMap<>();
/**
* Implements support for the legacy "one network per network type" model.
*
@@ -1452,6 +1466,20 @@ public class ConnectivityService extends IConnectivityManager.Stub
public BroadcastOptionsShim makeBroadcastOptionsShim(BroadcastOptions options) {
return BroadcastOptionsShimImpl.newInstance(options);
}
/**
* Wrapper method for
* {@link android.app.compat.CompatChanges#isChangeEnabled(long, String, UserHandle)}.
*
* @param changeId The ID of the compatibility change in question.
* @param packageName The package name of the app in question.
* @param user The user that the operation is done for.
* @return {@code true} if the change is enabled for the specified package.
*/
public boolean isChangeEnabled(long changeId, @NonNull final String packageName,
@NonNull final UserHandle user) {
return CompatChanges.isChangeEnabled(changeId, packageName, user);
}
}
public ConnectivityService(Context context) {
@@ -6319,6 +6347,11 @@ public class ConnectivityService extends IConnectivityManager.Stub
if (isMappedInOemNetworkPreference(packageName)) {
handleSetOemNetworkPreference(mOemNetworkPreferences, null);
}
// Invalidates cache entry when the package is updated.
synchronized (mSelfCertifiedCapabilityCache) {
mSelfCertifiedCapabilityCache.remove(packageName);
}
}
private final BroadcastReceiver mUserIntentReceiver = new BroadcastReceiver() {
@@ -6947,8 +6980,69 @@ public class ConnectivityService extends IConnectivityManager.Stub
asUid, requests, nr, msgr, binder, callbackFlags, callingAttributionTag);
}
private boolean shouldCheckCapabilitiesDeclaration(
@NonNull final NetworkCapabilities networkCapabilities, final int callingUid,
@NonNull final String callingPackageName) {
final UserHandle user = UserHandle.getUserHandleForUid(callingUid);
// Only run the check if the change is enabled.
if (!mDeps.isChangeEnabled(
ConnectivityCompatChanges.ENABLE_SELF_CERTIFIED_CAPABILITIES_DECLARATION,
callingPackageName, user)) {
return false;
}
return networkCapabilities.hasCapability(
NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_BANDWIDTH)
|| networkCapabilities.hasCapability(
NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_LATENCY);
}
private void enforceRequestCapabilitiesDeclaration(@NonNull final String callerPackageName,
@NonNull final NetworkCapabilities networkCapabilities) {
// This check is added to fix the linter error for "current min is 30", which is not going
// to happen because Connectivity service always run in S+.
if (!SdkLevel.isAtLeastS()) {
Log.wtf(TAG, "Connectivity service should always run in at least SDK S");
return;
}
ApplicationSelfCertifiedNetworkCapabilities applicationNetworkCapabilities;
try {
synchronized (mSelfCertifiedCapabilityCache) {
applicationNetworkCapabilities = mSelfCertifiedCapabilityCache.get(
callerPackageName);
if (applicationNetworkCapabilities == null) {
final PackageManager packageManager = mContext.getPackageManager();
final PackageManager.Property networkSliceProperty = packageManager.getProperty(
ConstantsShim.PROPERTY_SELF_CERTIFIED_NETWORK_CAPABILITIES,
callerPackageName
);
final XmlResourceParser parser = packageManager
.getResourcesForApplication(callerPackageName)
.getXml(networkSliceProperty.getResourceId());
applicationNetworkCapabilities =
ApplicationSelfCertifiedNetworkCapabilities.createFromXml(parser);
mSelfCertifiedCapabilityCache.put(callerPackageName,
applicationNetworkCapabilities);
}
}
} catch (PackageManager.NameNotFoundException ne) {
throw new SecurityException(
"Cannot find " + ConstantsShim.PROPERTY_SELF_CERTIFIED_NETWORK_CAPABILITIES
+ " property");
} catch (XmlPullParserException | IOException | InvalidTagException e) {
throw new SecurityException(e.getMessage());
}
applicationNetworkCapabilities.enforceSelfCertifiedNetworkCapabilitiesDeclared(
networkCapabilities);
}
private void enforceNetworkRequestPermissions(NetworkCapabilities networkCapabilities,
String callingPackageName, String callingAttributionTag, final int callingUid) {
if (shouldCheckCapabilitiesDeclaration(networkCapabilities, callingUid,
callingPackageName)) {
enforceRequestCapabilitiesDeclaration(callingPackageName, networkCapabilities);
}
if (networkCapabilities.hasCapability(NET_CAPABILITY_NOT_RESTRICTED) == false) {
// For T+ devices, callers with carrier privilege could request with CBS capabilities.
if (networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_CBS)

View File

@@ -0,0 +1,209 @@
/*
* Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.server.connectivity;
import android.annotation.NonNull;
import android.net.NetworkCapabilities;
import android.util.Log;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException;
import java.util.ArrayDeque;
/**
* The class for parsing and checking the self-declared application network capabilities.
*
* ApplicationSelfCertifiedNetworkCapabilities is an immutable class that
* can parse the self-declared application network capabilities in the application resources. The
* class also provides a helper method to check whether the requested network capabilities
* already self-declared.
*/
public final class ApplicationSelfCertifiedNetworkCapabilities {
public static final String PRIORITIZE_LATENCY = "NET_CAPABILITY_PRIORITIZE_LATENCY";
public static final String PRIORITIZE_BANDWIDTH = "NET_CAPABILITY_PRIORITIZE_BANDWIDTH";
private static final String TAG =
ApplicationSelfCertifiedNetworkCapabilities.class.getSimpleName();
private static final String NETWORK_CAPABILITIES_DECLARATION_TAG =
"network-capabilities-declaration";
private static final String USES_NETWORK_CAPABILITY_TAG = "uses-network-capability";
private static final String NAME_TAG = "name";
private long mRequestedNetworkCapabilities = 0;
/**
* Creates {@link ApplicationSelfCertifiedNetworkCapabilities} from a xml parser.
*
* <p> Here is an example of the xml syntax:
*
* <pre>
* {@code
* <network-capabilities-declaration xmlns:android="http://schemas.android.com/apk/res/android">
* <uses-network-capability android:name="NET_CAPABILITY_PRIORITIZE_LATENCY"/>
* <uses-network-capability android:name="NET_CAPABILITY_PRIORITIZE_BANDWIDTH"/>
* </network-capabilities-declaration>
* }
* </pre>
* <p>
*
* @param xmlParser The underlying {@link XmlPullParser} that will read the xml.
* @return An ApplicationSelfCertifiedNetworkCapabilities object.
* @throws InvalidTagException if the capabilities in xml config contains invalid tag.
* @throws XmlPullParserException if xml parsing failed.
* @throws IOException if unable to read the xml file properly.
*/
@NonNull
public static ApplicationSelfCertifiedNetworkCapabilities createFromXml(
@NonNull final XmlPullParser xmlParser)
throws InvalidTagException, XmlPullParserException, IOException {
return new ApplicationSelfCertifiedNetworkCapabilities(parseXml(xmlParser));
}
private static long parseXml(@NonNull final XmlPullParser xmlParser)
throws InvalidTagException, XmlPullParserException, IOException {
long requestedNetworkCapabilities = 0;
final ArrayDeque<String> openTags = new ArrayDeque<>();
while (checkedNextTag(xmlParser, openTags) != XmlPullParser.START_TAG) {
continue;
}
// Validates the tag is "network-capabilities-declaration"
if (!xmlParser.getName().equals(NETWORK_CAPABILITIES_DECLARATION_TAG)) {
throw new InvalidTagException("Invalid tag: " + xmlParser.getName());
}
checkedNextTag(xmlParser, openTags);
int eventType = xmlParser.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT) {
switch (eventType) {
case XmlPullParser.START_TAG:
// USES_NETWORK_CAPABILITY_TAG should directly be declared under
// NETWORK_CAPABILITIES_DECLARATION_TAG.
if (xmlParser.getName().equals(USES_NETWORK_CAPABILITY_TAG)
&& openTags.size() == 1) {
int capability = parseDeclarationTag(xmlParser);
if (capability >= 0) {
requestedNetworkCapabilities |= 1L << capability;
}
} else {
Log.w(TAG, "Unknown tag: " + xmlParser.getName() + " ,tags stack size: "
+ openTags.size());
}
break;
default:
break;
}
eventType = checkedNextTag(xmlParser, openTags);
}
// Checks all the tags are parsed.
if (!openTags.isEmpty()) {
throw new InvalidTagException("Unbalanced tag: " + openTags.peek());
}
return requestedNetworkCapabilities;
}
private static int parseDeclarationTag(@NonNull final XmlPullParser xmlParser) {
String name = null;
for (int i = 0; i < xmlParser.getAttributeCount(); i++) {
final String attrName = xmlParser.getAttributeName(i);
if (attrName.equals(NAME_TAG)) {
name = xmlParser.getAttributeValue(i);
} else {
Log.w(TAG, "Unknown attribute name: " + attrName);
}
}
if (name != null) {
switch (name) {
case PRIORITIZE_BANDWIDTH:
return NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_BANDWIDTH;
case PRIORITIZE_LATENCY:
return NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_LATENCY;
default:
Log.w(TAG, "Unknown capability declaration name: " + name);
}
} else {
Log.w(TAG, "uses-network-capability name must be specified");
}
// Invalid capability
return -1;
}
private static int checkedNextTag(@NonNull final XmlPullParser xmlParser,
@NonNull final ArrayDeque<String> openTags)
throws XmlPullParserException, IOException, InvalidTagException {
if (xmlParser.getEventType() == XmlPullParser.START_TAG) {
openTags.addFirst(xmlParser.getName());
} else if (xmlParser.getEventType() == XmlPullParser.END_TAG) {
if (!openTags.isEmpty() && openTags.peekFirst().equals(xmlParser.getName())) {
openTags.removeFirst();
} else {
throw new InvalidTagException("Unbalanced tag: " + xmlParser.getName());
}
}
return xmlParser.next();
}
private ApplicationSelfCertifiedNetworkCapabilities(long requestedNetworkCapabilities) {
mRequestedNetworkCapabilities = requestedNetworkCapabilities;
}
/**
* Enforces self-certified capabilities are declared.
*
* @param networkCapabilities the input NetworkCapabilities to check against.
* @throws SecurityException if the capabilities are not properly self-declared.
*/
public void enforceSelfCertifiedNetworkCapabilitiesDeclared(
@NonNull final NetworkCapabilities networkCapabilities) {
if (networkCapabilities.hasCapability(
NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_BANDWIDTH)
&& !hasPrioritizeBandwidth()) {
throw new SecurityException(
"Missing " + ApplicationSelfCertifiedNetworkCapabilities.PRIORITIZE_BANDWIDTH
+ " declaration");
}
if (networkCapabilities.hasCapability(
NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_LATENCY)
&& !hasPrioritizeLatency()) {
throw new SecurityException(
"Missing " + ApplicationSelfCertifiedNetworkCapabilities.PRIORITIZE_LATENCY
+ " declaration");
}
}
/**
* Checks if NET_CAPABILITY_PRIORITIZE_LATENCY is declared.
*/
private boolean hasPrioritizeLatency() {
return (mRequestedNetworkCapabilities & (1L
<< NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_LATENCY)) != 0;
}
/**
* Checks if NET_CAPABILITY_PRIORITIZE_BANDWIDTH is declared.
*/
private boolean hasPrioritizeBandwidth() {
return (mRequestedNetworkCapabilities & (1L
<< NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_BANDWIDTH)) != 0;
}
}

View File

@@ -0,0 +1,28 @@
/*
* Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.server.connectivity;
/**
* An exception thrown when a Tag is not valid in self_certified_network_capabilities.xml.
*/
public class InvalidTagException extends Exception {
public InvalidTagException(String message) {
super(message);
}
}

View File

@@ -47,6 +47,9 @@ java_test_host {
data: [
":CtsHostsideNetworkTestsApp",
":CtsHostsideNetworkTestsApp2",
":CtsHostsideNetworkCapTestsAppWithoutProperty",
":CtsHostsideNetworkCapTestsAppWithProperty",
":CtsHostsideNetworkCapTestsAppSdk33",
] + next_app_data,
per_testcase_directory: true,
}

View File

@@ -0,0 +1,65 @@
//
// Copyright (C) 2023 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
package {
default_applicable_licenses: ["Android-Apache-2.0"],
}
java_defaults {
name: "CtsHostsideNetworkCapTestsAppDefaults",
platform_apis: true,
static_libs: [
"androidx.test.ext.junit",
"androidx.test.rules",
"modules-utils-build",
"cts-net-utils",
],
srcs: ["src/**/*.java"],
// Tag this module as a cts test artifact
test_suites: [
"cts",
"general-tests",
"sts",
],
}
android_test_helper_app {
name: "CtsHostsideNetworkCapTestsAppWithoutProperty",
defaults: [
"cts_support_defaults",
"CtsHostsideNetworkCapTestsAppDefaults"
],
manifest: "AndroidManifestWithoutProperty.xml",
}
android_test_helper_app {
name: "CtsHostsideNetworkCapTestsAppWithProperty",
defaults: [
"cts_support_defaults",
"CtsHostsideNetworkCapTestsAppDefaults"
],
manifest: "AndroidManifestWithProperty.xml",
}
android_test_helper_app {
name: "CtsHostsideNetworkCapTestsAppSdk33",
defaults: [
"cts_support_defaults",
"CtsHostsideNetworkCapTestsAppDefaults"
],
target_sdk_version: "33",
manifest: "AndroidManifestWithoutProperty.xml",
}

View File

@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2023 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.cts.net.hostside.networkslicingtestapp">
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<application>
<uses-library android:name="android.test.runner"/>
<property android:name="android.net.PROPERTY_SELF_CERTIFIED_NETWORK_CAPABILITIES"
android:resource="@xml/self_certified_network_capabilities_both" />
</application>
<instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
android:targetPackage="com.android.cts.net.hostside.networkslicingtestapp"/>
</manifest>

View File

@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2023 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.cts.net.hostside.networkslicingtestapp">
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<application>
<uses-library android:name="android.test.runner"/>
</application>
<instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
android:targetPackage="com.android.cts.net.hostside.networkslicingtestapp"/>
</manifest>

View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2023 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<network-capabilities-declaration xmlns:android="http://schemas.android.com/apk/res/android">
<uses-network-capability android:name="NET_CAPABILITY_PRIORITIZE_LATENCY"/>
<uses-network-capability android:name="NET_CAPABILITY_PRIORITIZE_BANDWIDTH"/>
</network-capabilities-declaration>

View File

@@ -0,0 +1,98 @@
/*
* Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.cts.net.hostside.networkslicingtestapp;
import static org.junit.Assert.assertThrows;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkCapabilities;
import android.net.NetworkRequest;
import android.os.Build;
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;
import com.android.testutils.DevSdkIgnoreRule;
import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
public class NetworkSelfDeclaredCapabilitiesTest {
@Rule
public final DevSdkIgnoreRule mDevSdkIgnoreRule = new DevSdkIgnoreRule();
@Test
@IgnoreUpTo(Build.VERSION_CODES.TIRAMISU)
public void requestNetwork_withoutRequestCapabilities() {
final ConnectivityManager cm =
(ConnectivityManager)
InstrumentationRegistry.getInstrumentation()
.getContext()
.getSystemService(Context.CONNECTIVITY_SERVICE);
final NetworkRequest request =
new NetworkRequest.Builder().build();
final ConnectivityManager.NetworkCallback callback =
new ConnectivityManager.NetworkCallback();
cm.requestNetwork(request, callback);
cm.unregisterNetworkCallback(callback);
}
@Test
@IgnoreUpTo(Build.VERSION_CODES.TIRAMISU)
public void requestNetwork_withSelfDeclaredCapabilities() {
final ConnectivityManager cm =
(ConnectivityManager)
InstrumentationRegistry.getInstrumentation()
.getContext()
.getSystemService(Context.CONNECTIVITY_SERVICE);
final NetworkRequest request =
new NetworkRequest.Builder()
.addCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_BANDWIDTH)
.addCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_LATENCY)
.build();
final ConnectivityManager.NetworkCallback callback =
new ConnectivityManager.NetworkCallback();
cm.requestNetwork(request, callback);
cm.unregisterNetworkCallback(callback);
}
@Test
@IgnoreUpTo(Build.VERSION_CODES.TIRAMISU)
public void requestNetwork_lackingRequiredSelfDeclaredCapabilities() {
final ConnectivityManager cm =
(ConnectivityManager)
InstrumentationRegistry.getInstrumentation()
.getContext()
.getSystemService(Context.CONNECTIVITY_SERVICE);
final NetworkRequest request =
new NetworkRequest.Builder()
.addCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_BANDWIDTH)
.addCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_LATENCY)
.build();
final ConnectivityManager.NetworkCallback callback =
new ConnectivityManager.NetworkCallback();
assertThrows(
SecurityException.class,
() -> cm.requestNetwork(request, callback));
}
}

View File

@@ -0,0 +1,96 @@
/*
* Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.cts.net;
public class HostsideSelfDeclaredNetworkCapabilitiesCheckTest extends HostsideNetworkTestCase {
private static final String TEST_WITH_PROPERTY_IN_CURRENT_SDK_APK =
"CtsHostsideNetworkCapTestsAppWithProperty.apk";
private static final String TEST_WITHOUT_PROPERTY_IN_CURRENT_SDK_APK =
"CtsHostsideNetworkCapTestsAppWithoutProperty.apk";
private static final String TEST_IN_SDK_33_APK =
"CtsHostsideNetworkCapTestsAppSdk33.apk";
private static final String TEST_APP_PKG =
"com.android.cts.net.hostside.networkslicingtestapp";
private static final String TEST_CLASS_NAME = ".NetworkSelfDeclaredCapabilitiesTest";
private static final String WITH_SELF_DECLARED_CAPABILITIES_METHOD =
"requestNetwork_withSelfDeclaredCapabilities";
private static final String LACKING_SELF_DECLARED_CAPABILITIES_METHOD =
"requestNetwork_lackingRequiredSelfDeclaredCapabilities";
private static final String WITHOUT_REQUEST_CAPABILITIES_METHOD =
"requestNetwork_withoutRequestCapabilities";
public void testRequestNetworkInCurrentSdkWithProperty() throws Exception {
uninstallPackage(TEST_APP_PKG, false);
installPackage(TEST_WITH_PROPERTY_IN_CURRENT_SDK_APK);
// If the self-declared capabilities are defined,
// the ConnectivityManager.requestNetwork() call should always pass.
runDeviceTests(TEST_APP_PKG,
TEST_APP_PKG + TEST_CLASS_NAME,
WITH_SELF_DECLARED_CAPABILITIES_METHOD);
runDeviceTests(TEST_APP_PKG,
TEST_APP_PKG + TEST_CLASS_NAME,
WITHOUT_REQUEST_CAPABILITIES_METHOD);
uninstallPackage(TEST_APP_PKG, true);
}
public void testRequestNetworkInCurrentSdkWithoutProperty() throws Exception {
uninstallPackage(TEST_APP_PKG, false);
installPackage(TEST_WITHOUT_PROPERTY_IN_CURRENT_SDK_APK);
// If the self-declared capabilities are not defined,
// the ConnectivityManager.requestNetwork() call will fail if the properly is not declared.
runDeviceTests(TEST_APP_PKG,
TEST_APP_PKG + TEST_CLASS_NAME,
LACKING_SELF_DECLARED_CAPABILITIES_METHOD);
runDeviceTests(TEST_APP_PKG,
TEST_APP_PKG + TEST_CLASS_NAME,
WITHOUT_REQUEST_CAPABILITIES_METHOD);
uninstallPackage(TEST_APP_PKG, true);
}
public void testRequestNetworkInSdk33() throws Exception {
uninstallPackage(TEST_APP_PKG, false);
installPackage(TEST_IN_SDK_33_APK);
// In Sdk33, the ConnectivityManager.requestNetwork() call should always pass.
runDeviceTests(TEST_APP_PKG,
TEST_APP_PKG + TEST_CLASS_NAME,
WITH_SELF_DECLARED_CAPABILITIES_METHOD);
runDeviceTests(TEST_APP_PKG,
TEST_APP_PKG + TEST_CLASS_NAME,
WITHOUT_REQUEST_CAPABILITIES_METHOD);
uninstallPackage(TEST_APP_PKG, true);
}
public void testReinstallPackageWillUpdateProperty() throws Exception {
uninstallPackage(TEST_APP_PKG, false);
installPackage(TEST_WITHOUT_PROPERTY_IN_CURRENT_SDK_APK);
runDeviceTests(TEST_APP_PKG,
TEST_APP_PKG + TEST_CLASS_NAME,
LACKING_SELF_DECLARED_CAPABILITIES_METHOD);
uninstallPackage(TEST_APP_PKG, true);
// Updates package.
installPackage(TEST_WITH_PROPERTY_IN_CURRENT_SDK_APK);
runDeviceTests(TEST_APP_PKG,
TEST_APP_PKG + TEST_CLASS_NAME,
WITH_SELF_DECLARED_CAPABILITIES_METHOD);
uninstallPackage(TEST_APP_PKG, true);
}
}

View File

@@ -183,6 +183,8 @@ import static com.android.testutils.RecorderCallback.CallbackEntry.SUSPENDED;
import static com.android.testutils.RecorderCallback.CallbackEntry.UNAVAILABLE;
import static com.android.testutils.TestPermissionUtil.runAsShell;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
@@ -228,6 +230,7 @@ import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.admin.DevicePolicyManager;
import android.app.usage.NetworkStatsManager;
import android.compat.testing.PlatformCompatChangeRule;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.ContentProvider;
@@ -312,6 +315,7 @@ import android.net.UnderlyingNetworkInfo;
import android.net.Uri;
import android.net.VpnManager;
import android.net.VpnTransportInfo;
import android.net.connectivity.ConnectivityCompatChanges;
import android.net.metrics.IpConnectivityLog;
import android.net.netd.aidl.NativeUidRangeConfig;
import android.net.networkstack.NetworkStackClientBase;
@@ -379,6 +383,7 @@ import com.android.networkstack.apishim.common.UnsupportedApiLevelException;
import com.android.server.ConnectivityService.ConnectivityDiagnosticsCallbackInfo;
import com.android.server.ConnectivityService.NetworkRequestInfo;
import com.android.server.ConnectivityServiceTest.ConnectivityServiceDependencies.ReportedInterfaces;
import com.android.server.connectivity.ApplicationSelfCertifiedNetworkCapabilities;
import com.android.server.connectivity.AutomaticOnOffKeepaliveTracker;
import com.android.server.connectivity.CarrierPrivilegeAuthenticator;
import com.android.server.connectivity.ClatCoordinator;
@@ -406,6 +411,9 @@ import com.android.testutils.RecorderCallback.CallbackEntry;
import com.android.testutils.TestableNetworkCallback;
import com.android.testutils.TestableNetworkOfferCallback;
import libcore.junit.util.compat.CoreCompatChangeRule.DisableCompatChanges;
import libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
@@ -475,6 +483,9 @@ public class ConnectivityServiceTest {
@Rule
public final DevSdkIgnoreRule ignoreRule = new DevSdkIgnoreRule();
@Rule
public final PlatformCompatChangeRule compatChangeRule = new PlatformCompatChangeRule();
private static final int TIMEOUT_MS = 2_000;
// Broadcasts can take a long time to be delivered. The test will not wait for that long unless
// there is a failure, so use a long timeout.
@@ -2105,6 +2116,37 @@ public class ConnectivityServiceTest {
reset(mBroadcastOptionsShim);
return mBroadcastOptionsShim;
}
@GuardedBy("this")
private boolean mForceDisableCompatChangeCheck = true;
/**
* By default, the {@link #isChangeEnabled(long, String, UserHandle)} will always return
* true as the mForceDisableCompatChangeCheck is true and compat change check logic is
* never executed. The compat change check logic can be turned on by calling this method.
* If this method is called, the
* {@link libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges} or
* {@link libcore.junit.util.compat.CoreCompatChangeRule.DisableCompatChanges} must be
* used to turn on/off the compat change flag.
*/
private void enableCompatChangeCheck() {
synchronized (this) {
mForceDisableCompatChangeCheck = false;
}
}
@Override
public boolean isChangeEnabled(long changeId,
@NonNull final String packageName,
@NonNull final UserHandle user) {
synchronized (this) {
if (mForceDisableCompatChangeCheck) {
return false;
} else {
return super.isChangeEnabled(changeId, packageName, user);
}
}
}
}
private class AutomaticOnOffKeepaliveTrackerDependencies
@@ -6310,6 +6352,142 @@ public class ConnectivityServiceTest {
}
}
@Test
@IgnoreUpTo(Build.VERSION_CODES.TIRAMISU)
@DisableCompatChanges(ConnectivityCompatChanges.ENABLE_SELF_CERTIFIED_CAPABILITIES_DECLARATION)
public void testSelfCertifiedCapabilitiesDisabled()
throws Exception {
mDeps.enableCompatChangeCheck();
final NetworkRequest networkRequest = new NetworkRequest.Builder()
.addCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_LATENCY)
.addCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_BANDWIDTH)
.build();
final TestNetworkCallback cb = new TestNetworkCallback();
mCm.requestNetwork(networkRequest, cb);
mCm.unregisterNetworkCallback(cb);
}
/** Set the networkSliceResourceId to 0 will result in NameNotFoundException be thrown. */
private void setupMockForNetworkCapabilitiesResources(int networkSliceResourceId)
throws PackageManager.NameNotFoundException {
if (networkSliceResourceId == 0) {
doThrow(new PackageManager.NameNotFoundException()).when(mPackageManager).getProperty(
ConstantsShim.PROPERTY_SELF_CERTIFIED_NETWORK_CAPABILITIES,
mContext.getPackageName());
} else {
final PackageManager.Property property = new PackageManager.Property(
ConstantsShim.PROPERTY_SELF_CERTIFIED_NETWORK_CAPABILITIES,
networkSliceResourceId,
true /* isResource */,
mContext.getPackageName(),
"dummyClass"
);
doReturn(property).when(mPackageManager).getProperty(
ConstantsShim.PROPERTY_SELF_CERTIFIED_NETWORK_CAPABILITIES,
mContext.getPackageName());
doReturn(mContext.getResources()).when(mPackageManager).getResourcesForApplication(
mContext.getPackageName());
}
}
@Test
@IgnoreUpTo(Build.VERSION_CODES.TIRAMISU)
@EnableCompatChanges(ConnectivityCompatChanges.ENABLE_SELF_CERTIFIED_CAPABILITIES_DECLARATION)
public void requestNetwork_withoutPrioritizeBandwidthDeclaration_shouldThrowException()
throws Exception {
mDeps.enableCompatChangeCheck();
setupMockForNetworkCapabilitiesResources(
com.android.frameworks.tests.net.R.xml.self_certified_capabilities_latency);
final NetworkRequest networkRequest = new NetworkRequest.Builder()
.addCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_BANDWIDTH)
.build();
final TestNetworkCallback cb = new TestNetworkCallback();
final Exception e = assertThrows(SecurityException.class,
() -> mCm.requestNetwork(networkRequest, cb));
assertThat(e.getMessage(),
containsString(ApplicationSelfCertifiedNetworkCapabilities.PRIORITIZE_BANDWIDTH));
}
@Test
@IgnoreUpTo(Build.VERSION_CODES.TIRAMISU)
@EnableCompatChanges(ConnectivityCompatChanges.ENABLE_SELF_CERTIFIED_CAPABILITIES_DECLARATION)
public void requestNetwork_withoutPrioritizeLatencyDeclaration_shouldThrowException()
throws Exception {
mDeps.enableCompatChangeCheck();
setupMockForNetworkCapabilitiesResources(
com.android.frameworks.tests.net.R.xml.self_certified_capabilities_bandwidth);
final NetworkRequest networkRequest = new NetworkRequest.Builder()
.addCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_LATENCY)
.build();
final TestNetworkCallback cb = new TestNetworkCallback();
final Exception e = assertThrows(SecurityException.class,
() -> mCm.requestNetwork(networkRequest, cb));
assertThat(e.getMessage(),
containsString(ApplicationSelfCertifiedNetworkCapabilities.PRIORITIZE_LATENCY));
}
@Test
@IgnoreUpTo(Build.VERSION_CODES.TIRAMISU)
@EnableCompatChanges(ConnectivityCompatChanges.ENABLE_SELF_CERTIFIED_CAPABILITIES_DECLARATION)
public void requestNetwork_withoutNetworkSliceProperty_shouldThrowException() throws Exception {
mDeps.enableCompatChangeCheck();
setupMockForNetworkCapabilitiesResources(0 /* networkSliceResourceId */);
final NetworkRequest networkRequest = new NetworkRequest.Builder()
.addCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_LATENCY)
.addCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_BANDWIDTH)
.build();
final TestNetworkCallback cb = new TestNetworkCallback();
final Exception e = assertThrows(SecurityException.class,
() -> mCm.requestNetwork(networkRequest, cb));
assertThat(e.getMessage(),
containsString(ConstantsShim.PROPERTY_SELF_CERTIFIED_NETWORK_CAPABILITIES));
}
@Test
@IgnoreUpTo(Build.VERSION_CODES.TIRAMISU)
@EnableCompatChanges(ConnectivityCompatChanges.ENABLE_SELF_CERTIFIED_CAPABILITIES_DECLARATION)
public void requestNetwork_withNetworkSliceDeclaration_shouldSucceed() throws Exception {
mDeps.enableCompatChangeCheck();
setupMockForNetworkCapabilitiesResources(
com.android.frameworks.tests.net.R.xml.self_certified_capabilities_both);
final NetworkRequest networkRequest = new NetworkRequest.Builder()
.addCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_LATENCY)
.addCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_BANDWIDTH)
.build();
final TestNetworkCallback cb = new TestNetworkCallback();
mCm.requestNetwork(networkRequest, cb);
mCm.unregisterNetworkCallback(cb);
}
@Test
@IgnoreUpTo(Build.VERSION_CODES.TIRAMISU)
@EnableCompatChanges(ConnectivityCompatChanges.ENABLE_SELF_CERTIFIED_CAPABILITIES_DECLARATION)
public void requestNetwork_withNetworkSliceDeclaration_shouldUseCache() throws Exception {
mDeps.enableCompatChangeCheck();
setupMockForNetworkCapabilitiesResources(
com.android.frameworks.tests.net.R.xml.self_certified_capabilities_both);
final NetworkRequest networkRequest = new NetworkRequest.Builder()
.addCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_LATENCY)
.addCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_BANDWIDTH)
.build();
final TestNetworkCallback cb = new TestNetworkCallback();
mCm.requestNetwork(networkRequest, cb);
mCm.unregisterNetworkCallback(cb);
// Second call should use caches
mCm.requestNetwork(networkRequest, cb);
mCm.unregisterNetworkCallback(cb);
// PackageManager's API only called once because the second call is using cache.
verify(mPackageManager, times(1)).getProperty(
ConstantsShim.PROPERTY_SELF_CERTIFIED_NETWORK_CAPABILITIES,
mContext.getPackageName());
verify(mPackageManager, times(1)).getResourcesForApplication(
mContext.getPackageName());
}
/**
* Validate the service throws if request with CBS but without carrier privilege.
*/

View File

@@ -0,0 +1,96 @@
/*
* Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.server.connectivity
import android.net.NetworkCapabilities
import android.os.Build
import androidx.test.InstrumentationRegistry
import androidx.test.filters.SmallTest
import com.android.frameworks.tests.net.R
import com.android.testutils.DevSdkIgnoreRule
import com.android.testutils.DevSdkIgnoreRunner
import com.google.common.truth.Truth.assertThat
import kotlin.test.assertFailsWith
import org.junit.Test
import org.junit.runner.RunWith
@RunWith(DevSdkIgnoreRunner::class)
@SmallTest
@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.R)
class ApplicationSelfCertifiedNetworkCapabilitiesTest {
private val mResource = InstrumentationRegistry.getContext().getResources()
private val bandwidthCapability = NetworkCapabilities.Builder().apply {
addCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_BANDWIDTH)
}.build()
private val latencyCapability = NetworkCapabilities.Builder().apply {
addCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_LATENCY)
}.build()
private val emptyCapability = NetworkCapabilities.Builder().build()
private val bothCapabilities = NetworkCapabilities.Builder().apply {
addCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_BANDWIDTH)
addCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_LATENCY)
}.build()
@Test
fun parseXmlWithWrongTag_shouldIgnoreWrongTag() {
val parser = mResource.getXml(
R.xml.self_certified_capabilities_wrong_tag
)
val selfDeclaredCaps = ApplicationSelfCertifiedNetworkCapabilities.createFromXml(parser)
selfDeclaredCaps.enforceSelfCertifiedNetworkCapabilitiesDeclared(latencyCapability)
selfDeclaredCaps.enforceSelfCertifiedNetworkCapabilitiesDeclared(bandwidthCapability)
}
@Test
fun parseXmlWithWrongDeclaration_shouldThrowException() {
val parser = mResource.getXml(
R.xml.self_certified_capabilities_wrong_declaration
)
val exception = assertFailsWith<InvalidTagException> {
ApplicationSelfCertifiedNetworkCapabilities.createFromXml(parser)
}
assertThat(exception.message).contains("network-capabilities-declaration1")
}
@Test
fun checkIfSelfCertifiedNetworkCapabilitiesDeclared_shouldThrowExceptionWhenNoDeclaration() {
val parser = mResource.getXml(R.xml.self_certified_capabilities_other)
val selfDeclaredCaps = ApplicationSelfCertifiedNetworkCapabilities.createFromXml(parser)
val exception1 = assertFailsWith<SecurityException> {
selfDeclaredCaps.enforceSelfCertifiedNetworkCapabilitiesDeclared(latencyCapability)
}
assertThat(exception1.message).contains(
ApplicationSelfCertifiedNetworkCapabilities.PRIORITIZE_LATENCY
)
val exception2 = assertFailsWith<SecurityException> {
selfDeclaredCaps.enforceSelfCertifiedNetworkCapabilitiesDeclared(bandwidthCapability)
}
assertThat(exception2.message).contains(
ApplicationSelfCertifiedNetworkCapabilities.PRIORITIZE_BANDWIDTH
)
}
@Test
fun checkIfSelfCertifiedNetworkCapabilitiesDeclared_shouldPassIfDeclarationExist() {
val parser = mResource.getXml(R.xml.self_certified_capabilities_both)
val selfDeclaredCaps = ApplicationSelfCertifiedNetworkCapabilities.createFromXml(parser)
selfDeclaredCaps.enforceSelfCertifiedNetworkCapabilitiesDeclared(latencyCapability)
selfDeclaredCaps.enforceSelfCertifiedNetworkCapabilitiesDeclared(bandwidthCapability)
selfDeclaredCaps.enforceSelfCertifiedNetworkCapabilitiesDeclared(bothCapabilities)
selfDeclaredCaps.enforceSelfCertifiedNetworkCapabilitiesDeclared(emptyCapability)
}
}

View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2023 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<network-capabilities-declaration xmlns:android="http://schemas.android.com/apk/res/android">
<uses-network-capability android:name="NET_CAPABILITY_PRIORITIZE_BANDWIDTH"/>
</network-capabilities-declaration>

View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2023 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<network-capabilities-declaration xmlns:android="http://schemas.android.com/apk/res/android">
<uses-network-capability android:name="NET_CAPABILITY_PRIORITIZE_LATENCY"/>
<uses-network-capability android:name="NET_CAPABILITY_PRIORITIZE_BANDWIDTH"/>
</network-capabilities-declaration>

View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2023 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<network-capabilities-declaration xmlns:android="http://schemas.android.com/apk/res/android">
<uses-network-capability android:name="NET_CAPABILITY_PRIORITIZE_LATENCY"/>
</network-capabilities-declaration>

View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2023 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<network-capabilities-declaration xmlns:android="http://schemas.android.com/apk/res/android">
<uses-network-capability android:name="other"/>
</network-capabilities-declaration>

View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2023 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<network-capabilities-declaration1 xmlns:android="http://schemas.android.com/apk/res/android">
<uses-network-capability android:name="NET_CAPABILITY_PRIORITIZE_LATENCY"/>
</network-capabilities-declaration1>

View File

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2023 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<network-capabilities-declaration xmlns:android="http://schemas.android.com/apk/res/android">
<uses-network-capability1 android:name="NET_CAPABILITY_PRIORITIZE_LATENCY"/>
<uses-network-capability android:name="NET_CAPABILITY_PRIORITIZE_LATENCY"/>
<uses-network-capability android:name="NET_CAPABILITY_PRIORITIZE_BANDWIDTH"/>
</network-capabilities-declaration>