Merge changes from topics "enable-policy-ranking", "sendNetworkScore"
* changes:
Adjust a test for policy scoring
Enable policy ranking
Add CTS to verify NetworkAgent#setLingerDuration
Allow network providers to set the linger duration.
Fix nascent timer never get removed
[NS13] Remove the last usage of the legacy int
Add documentation
Use filter from CollectionUtils.
Fix a bug where updates of offers won't find existing offers
[NS12] Address comments on NS09
[NS11] Fix yieldToBadWifi over the policy scoring
Add doc for NetworkScore#getLegacyInt
Expose sendNetworkScore that takes a NetworkScore
diff --git a/Tethering/common/TetheringLib/Android.bp b/Tethering/common/TetheringLib/Android.bp
index 4bc8f93..fce4360 100644
--- a/Tethering/common/TetheringLib/Android.bp
+++ b/Tethering/common/TetheringLib/Android.bp
@@ -25,8 +25,8 @@
],
srcs: [":framework-tethering-srcs"],
- libs: ["framework-connectivity"],
- stub_only_libs: ["framework-connectivity"],
+ libs: ["framework-connectivity.stubs.module_lib"],
+ stub_only_libs: ["framework-connectivity.stubs.module_lib"],
aidl: {
include_dirs: [
"packages/modules/Connectivity/framework/aidl-export",
diff --git a/Tethering/src/android/net/ip/IpServer.java b/Tethering/src/android/net/ip/IpServer.java
index c45ce83..3428c1d 100644
--- a/Tethering/src/android/net/ip/IpServer.java
+++ b/Tethering/src/android/net/ip/IpServer.java
@@ -1054,8 +1054,16 @@
mLastRaParams = newParams;
}
- private void logMessage(State state, int what) {
- mLog.log(state.getName() + " got " + sMagicDecoderRing.get(what, Integer.toString(what)));
+ private void maybeLogMessage(State state, int what) {
+ switch (what) {
+ // Suppress some CMD_* to avoid log flooding.
+ case CMD_IPV6_TETHER_UPDATE:
+ case CMD_NEIGHBOR_EVENT:
+ break;
+ default:
+ mLog.log(state.getName() + " got "
+ + sMagicDecoderRing.get(what, Integer.toString(what)));
+ }
}
private void sendInterfaceState(int newInterfaceState) {
@@ -1095,7 +1103,7 @@
@Override
public boolean processMessage(Message message) {
- logMessage(this, message.what);
+ maybeLogMessage(this, message.what);
switch (message.what) {
case CMD_TETHER_REQUESTED:
mLastError = TetheringManager.TETHER_ERROR_NO_ERROR;
@@ -1180,7 +1188,6 @@
@Override
public boolean processMessage(Message message) {
- logMessage(this, message.what);
switch (message.what) {
case CMD_TETHER_UNREQUESTED:
transitionTo(mInitialState);
@@ -1238,7 +1245,7 @@
public boolean processMessage(Message message) {
if (super.processMessage(message)) return true;
- logMessage(this, message.what);
+ maybeLogMessage(this, message.what);
switch (message.what) {
case CMD_TETHER_REQUESTED:
mLog.e("CMD_TETHER_REQUESTED while in local-only hotspot mode.");
@@ -1306,7 +1313,7 @@
public boolean processMessage(Message message) {
if (super.processMessage(message)) return true;
- logMessage(this, message.what);
+ maybeLogMessage(this, message.what);
switch (message.what) {
case CMD_TETHER_REQUESTED:
mLog.e("CMD_TETHER_REQUESTED while already tethering.");
@@ -1417,7 +1424,7 @@
class WaitingForRestartState extends State {
@Override
public boolean processMessage(Message message) {
- logMessage(this, message.what);
+ maybeLogMessage(this, message.what);
switch (message.what) {
case CMD_TETHER_UNREQUESTED:
transitionTo(mInitialState);
diff --git a/Tethering/src/com/android/networkstack/tethering/Tethering.java b/Tethering/src/com/android/networkstack/tethering/Tethering.java
index 7596380..e4fbd71 100644
--- a/Tethering/src/com/android/networkstack/tethering/Tethering.java
+++ b/Tethering/src/com/android/networkstack/tethering/Tethering.java
@@ -495,11 +495,11 @@
// See NetlinkHandler.cpp: notifyInterfaceChanged.
if (VDBG) Log.d(TAG, "interfaceStatusChanged " + iface + ", " + up);
if (up) {
- maybeTrackNewInterfaceLocked(iface);
+ maybeTrackNewInterface(iface);
} else {
if (ifaceNameToType(iface) == TETHERING_BLUETOOTH
|| ifaceNameToType(iface) == TETHERING_WIGIG) {
- stopTrackingInterfaceLocked(iface);
+ stopTrackingInterface(iface);
} else {
// Ignore usb0 down after enabling RNDIS.
// We will handle disconnect in interfaceRemoved.
@@ -535,12 +535,12 @@
void interfaceAdded(String iface) {
if (VDBG) Log.d(TAG, "interfaceAdded " + iface);
- maybeTrackNewInterfaceLocked(iface);
+ maybeTrackNewInterface(iface);
}
void interfaceRemoved(String iface) {
if (VDBG) Log.d(TAG, "interfaceRemoved " + iface);
- stopTrackingInterfaceLocked(iface);
+ stopTrackingInterface(iface);
}
void startTethering(final TetheringRequestParcel request, final IIntResultListener listener) {
@@ -694,14 +694,14 @@
mEthernetCallback = new EthernetCallback();
mEthernetIfaceRequest = em.requestTetheredInterface(mExecutor, mEthernetCallback);
} else {
- stopEthernetTetheringLocked();
+ stopEthernetTethering();
}
return TETHER_ERROR_NO_ERROR;
}
- private void stopEthernetTetheringLocked() {
+ private void stopEthernetTethering() {
if (mConfiguredEthernetIface != null) {
- stopTrackingInterfaceLocked(mConfiguredEthernetIface);
+ stopTrackingInterface(mConfiguredEthernetIface);
mConfiguredEthernetIface = null;
}
if (mEthernetCallback != null) {
@@ -718,7 +718,7 @@
// Ethernet callback arrived after Ethernet tethering stopped. Ignore.
return;
}
- maybeTrackNewInterfaceLocked(iface, TETHERING_ETHERNET);
+ maybeTrackNewInterface(iface, TETHERING_ETHERNET);
changeInterfaceState(iface, getRequestedState(TETHERING_ETHERNET));
mConfiguredEthernetIface = iface;
}
@@ -729,7 +729,7 @@
// onAvailable called after stopping Ethernet tethering.
return;
}
- stopEthernetTetheringLocked();
+ stopEthernetTethering();
}
}
@@ -1030,7 +1030,7 @@
// We can see this state on the way to both enabled and failure states.
break;
case WifiManager.WIFI_AP_STATE_ENABLED:
- enableWifiIpServingLocked(ifname, ipmode);
+ enableWifiIpServing(ifname, ipmode);
break;
case WifiManager.WIFI_AP_STATE_DISABLING:
// We can see this state on the way to disabled.
@@ -1038,7 +1038,7 @@
case WifiManager.WIFI_AP_STATE_DISABLED:
case WifiManager.WIFI_AP_STATE_FAILED:
default:
- disableWifiIpServingLocked(ifname, curState);
+ disableWifiIpServing(ifname, curState);
break;
}
}
@@ -1062,7 +1062,7 @@
// if no group is formed, bring it down if needed.
if (p2pInfo == null || !p2pInfo.groupFormed) {
- disableWifiP2pIpServingLockedIfNeeded(mWifiP2pTetherInterface);
+ disableWifiP2pIpServingIfNeeded(mWifiP2pTetherInterface);
mWifiP2pTetherInterface = null;
return;
}
@@ -1078,12 +1078,12 @@
mLog.w("P2P tethered interface " + mWifiP2pTetherInterface
+ "is different from current interface "
+ group.getInterface() + ", re-tether it");
- disableWifiP2pIpServingLockedIfNeeded(mWifiP2pTetherInterface);
+ disableWifiP2pIpServingIfNeeded(mWifiP2pTetherInterface);
}
// Finally bring up serving on the new interface
mWifiP2pTetherInterface = group.getInterface();
- enableWifiIpServingLocked(mWifiP2pTetherInterface, IFACE_IP_MODE_LOCAL_ONLY);
+ enableWifiIpServing(mWifiP2pTetherInterface, IFACE_IP_MODE_LOCAL_ONLY);
}
private void handleUserRestrictionAction() {
@@ -1164,7 +1164,7 @@
}
}
- private void disableWifiIpServingLockedCommon(int tetheringType, String ifname, int apState) {
+ private void disableWifiIpServingCommon(int tetheringType, String ifname, int apState) {
mLog.log("Canceling WiFi tethering request -"
+ " type=" + tetheringType
+ " interface=" + ifname
@@ -1191,23 +1191,23 @@
: "specified interface: " + ifname));
}
- private void disableWifiIpServingLocked(String ifname, int apState) {
+ private void disableWifiIpServing(String ifname, int apState) {
// Regardless of whether we requested this transition, the AP has gone
// down. Don't try to tether again unless we're requested to do so.
// TODO: Remove this altogether, once Wi-Fi reliably gives us an
// interface name with every broadcast.
mWifiTetherRequested = false;
- disableWifiIpServingLockedCommon(TETHERING_WIFI, ifname, apState);
+ disableWifiIpServingCommon(TETHERING_WIFI, ifname, apState);
}
- private void disableWifiP2pIpServingLockedIfNeeded(String ifname) {
+ private void disableWifiP2pIpServingIfNeeded(String ifname) {
if (TextUtils.isEmpty(ifname)) return;
- disableWifiIpServingLockedCommon(TETHERING_WIFI_P2P, ifname, /* fake */ 0);
+ disableWifiIpServingCommon(TETHERING_WIFI_P2P, ifname, /* fake */ 0);
}
- private void enableWifiIpServingLocked(String ifname, int wifiIpMode) {
+ private void enableWifiIpServing(String ifname, int wifiIpMode) {
// Map wifiIpMode values to IpServer.Callback serving states, inferring
// from mWifiTetherRequested as a final "best guess".
final int ipServingMode;
@@ -1224,7 +1224,7 @@
}
if (!TextUtils.isEmpty(ifname)) {
- maybeTrackNewInterfaceLocked(ifname);
+ maybeTrackNewInterface(ifname);
changeInterfaceState(ifname, ipServingMode);
} else {
mLog.e(String.format(
@@ -2437,7 +2437,7 @@
mTetherMainSM.sendMessage(which, state, 0, newLp);
}
- private void maybeTrackNewInterfaceLocked(final String iface) {
+ private void maybeTrackNewInterface(final String iface) {
// If we don't care about this type of interface, ignore.
final int interfaceType = ifaceNameToType(iface);
if (interfaceType == TETHERING_INVALID) {
@@ -2457,10 +2457,10 @@
return;
}
- maybeTrackNewInterfaceLocked(iface, interfaceType);
+ maybeTrackNewInterface(iface, interfaceType);
}
- private void maybeTrackNewInterfaceLocked(final String iface, int interfaceType) {
+ private void maybeTrackNewInterface(final String iface, int interfaceType) {
// If we have already started a TISM for this interface, skip.
if (mTetherStates.containsKey(iface)) {
mLog.log("active iface (" + iface + ") reported as added, ignoring");
@@ -2477,7 +2477,7 @@
tetherState.ipServer.start();
}
- private void stopTrackingInterfaceLocked(final String iface) {
+ private void stopTrackingInterface(final String iface) {
final TetherState tetherState = mTetherStates.get(iface);
if (tetherState == null) {
mLog.log("attempting to remove unknown iface (" + iface + "), ignoring");
diff --git a/framework/Android.bp b/framework/Android.bp
index 4fa9ccb..185e8a5 100644
--- a/framework/Android.bp
+++ b/framework/Android.bp
@@ -22,6 +22,7 @@
java_library {
name: "framework-connectivity-protos",
sdk_version: "module_current",
+ min_sdk_version: "30",
proto: {
type: "nano",
},
@@ -77,11 +78,13 @@
java_sdk_library {
name: "framework-connectivity",
- api_only: true,
+ sdk_version: "module_current",
+ min_sdk_version: "30",
defaults: ["framework-module-defaults"],
installable: true,
srcs: [
":framework-connectivity-sources",
+ ":net-utils-framework-common-srcs",
],
aidl: {
include_dirs: [
@@ -93,10 +96,34 @@
"frameworks/native/aidl/binder", // For PersistableBundle.aidl
],
},
+ impl_only_libs: [
+ // TODO (b/183097033) remove once module_current includes core_platform
+ "stable.core.platform.api.stubs",
+ "framework-tethering.stubs.module_lib",
+ "framework-wifi.stubs.module_lib",
+ "net-utils-device-common",
+ ],
libs: [
"unsupportedappusage",
],
+ static_libs: [
+ "framework-connectivity-protos",
+ ],
+ jarjar_rules: "jarjar-rules.txt",
permitted_packages: ["android.net"],
+ impl_library_visibility: [
+ "//packages/modules/Connectivity/Tethering/apex",
+ // In preparation for future move
+ "//packages/modules/Connectivity/apex",
+ "//packages/modules/Connectivity/service",
+ "//frameworks/base/packages/Connectivity/service",
+ "//frameworks/base",
+ "//packages/modules/Connectivity/Tethering/tests/unit",
+ ],
+ apex_available: [
+ "//apex_available:platform",
+ "com.android.tethering",
+ ],
}
cc_defaults {
@@ -105,6 +132,10 @@
"-Wall",
"-Werror",
"-Wno-unused-parameter",
+ // Don't warn about S API usage even with
+ // min_sdk 30: the library is only loaded
+ // on S+ devices
+ "-Wno-unguarded-availability",
"-Wthread-safety",
],
shared_libs: [
@@ -131,6 +162,7 @@
cc_library_shared {
name: "libframework-connectivity-jni",
+ min_sdk_version: "30",
defaults: ["libframework-connectivity-defaults"],
srcs: [
"jni/android_net_NetworkUtils.cpp",
@@ -139,36 +171,6 @@
shared_libs: ["libandroid"],
stl: "libc++_static",
apex_available: [
- "//apex_available:platform",
"com.android.tethering",
],
}
-
-java_library {
- name: "framework-connectivity.impl",
- sdk_version: "module_current",
- srcs: [
- ":framework-connectivity-sources",
- ],
- aidl: {
- include_dirs: [
- "frameworks/base/core/java", // For framework parcelables
- "frameworks/native/aidl/binder", // For PersistableBundle.aidl
- ],
- },
- libs: [
- // TODO (b/183097033) remove once module_current includes core_current
- "stable.core.platform.api.stubs",
- "framework-tethering",
- "framework-wifi",
- "unsupportedappusage",
- ],
- static_libs: [
- "framework-connectivity-protos",
- "net-utils-device-common",
- ],
- jarjar_rules: "jarjar-rules.txt",
- apex_available: ["com.android.tethering"],
- installable: true,
- permitted_packages: ["android.net"],
-}
diff --git a/framework/lint-baseline.xml b/framework/lint-baseline.xml
new file mode 100644
index 0000000..099202f
--- /dev/null
+++ b/framework/lint-baseline.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="5" by="lint 4.1.0" client="cli" variant="all" version="4.1.0">
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `new android.net.ParseException`"
+ errorLine1=" ParseException pe = new ParseException(e.reason, e.getCause());"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/modules/Connectivity/framework/src/android/net/DnsResolver.java"
+ line="301"
+ column="37"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Class requires API level 31 (current min is 30): `android.telephony.TelephonyCallback`"
+ errorLine1=" protected class ActiveDataSubscriptionIdListener extends TelephonyCallback"
+ errorLine2=" ~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/modules/Connectivity/framework/src/android/net/util/MultinetworkPolicyTracker.java"
+ line="96"
+ column="62"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Class requires API level 31 (current min is 30): `android.telephony.TelephonyCallback.ActiveDataSubscriptionIdListener`"
+ errorLine1=" implements TelephonyCallback.ActiveDataSubscriptionIdListener {"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/modules/Connectivity/framework/src/android/net/util/MultinetworkPolicyTracker.java"
+ line="97"
+ column="24"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.TelephonyManager#registerTelephonyCallback`"
+ errorLine1=" ctx.getSystemService(TelephonyManager.class).registerTelephonyCallback("
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/modules/Connectivity/framework/src/android/net/util/MultinetworkPolicyTracker.java"
+ line="126"
+ column="54"/>
+ </issue>
+
+</issues>
diff --git a/framework/src/android/net/ConnectivitySettingsManager.java b/framework/src/android/net/ConnectivitySettingsManager.java
index 5f7f539..03c3600 100644
--- a/framework/src/android/net/ConnectivitySettingsManager.java
+++ b/framework/src/android/net/ConnectivitySettingsManager.java
@@ -1070,7 +1070,7 @@
*/
@NonNull
public static Set<Integer> getUidsAllowedOnRestrictedNetworks(@NonNull Context context) {
- final String uidList = Settings.Secure.getString(
+ final String uidList = Settings.Global.getString(
context.getContentResolver(), UIDS_ALLOWED_ON_RESTRICTED_NETWORKS);
return getUidSetFromString(uidList);
}
@@ -1084,7 +1084,7 @@
public static void setUidsAllowedOnRestrictedNetworks(@NonNull Context context,
@NonNull Set<Integer> uidList) {
final String uids = getUidStringFromSet(uidList);
- Settings.Secure.putString(context.getContentResolver(), UIDS_ALLOWED_ON_RESTRICTED_NETWORKS,
+ Settings.Global.putString(context.getContentResolver(), UIDS_ALLOWED_ON_RESTRICTED_NETWORKS,
uids);
}
}
diff --git a/service/Android.bp b/service/Android.bp
index ec8887c..841e189 100644
--- a/service/Android.bp
+++ b/service/Android.bp
@@ -21,7 +21,7 @@
cc_library_shared {
name: "libservice-connectivity",
- // TODO: build against the NDK (sdk_version: "30" for example)
+ min_sdk_version: "30",
cflags: [
"-Wall",
"-Werror",
@@ -33,13 +33,12 @@
"jni/onload.cpp",
],
stl: "libc++_static",
+ header_libs: [
+ "libbase_headers",
+ ],
shared_libs: [
- "libbase",
"liblog",
"libnativehelper",
- // TODO: remove dependency on ifc_[add/del]_address by having Java code to add/delete
- // addresses, and remove dependency on libnetutils.
- "libnetutils",
],
apex_available: [
"com.android.tethering",
@@ -49,6 +48,7 @@
java_library {
name: "service-connectivity-pre-jarjar",
sdk_version: "system_server_current",
+ min_sdk_version: "30",
srcs: [
"src/**/*.java",
":framework-connectivity-shared-srcs",
@@ -79,7 +79,6 @@
"service-connectivity-protos",
],
apex_available: [
- "//apex_available:platform",
"com.android.tethering",
],
}
@@ -87,6 +86,7 @@
java_library {
name: "service-connectivity-protos",
sdk_version: "system_current",
+ min_sdk_version: "30",
proto: {
type: "nano",
},
@@ -95,7 +95,6 @@
],
libs: ["libprotobuf-java-nano"],
apex_available: [
- "//apex_available:platform",
"com.android.tethering",
],
}
@@ -103,13 +102,13 @@
java_library {
name: "service-connectivity",
sdk_version: "system_server_current",
+ min_sdk_version: "30",
installable: true,
static_libs: [
"service-connectivity-pre-jarjar",
],
jarjar_rules: "jarjar-rules.txt",
apex_available: [
- "//apex_available:platform",
"com.android.tethering",
],
}
diff --git a/service/ServiceConnectivityResources/Android.bp b/service/ServiceConnectivityResources/Android.bp
index 912d99f..f491cc7 100644
--- a/service/ServiceConnectivityResources/Android.bp
+++ b/service/ServiceConnectivityResources/Android.bp
@@ -22,6 +22,7 @@
android_app {
name: "ServiceConnectivityResources",
sdk_version: "module_30",
+ min_sdk_version: "30",
resource_dirs: [
"res",
],
diff --git a/service/jni/com_android_server_TestNetworkService.cpp b/service/jni/com_android_server_TestNetworkService.cpp
index 36a6fde..e7a40e5 100644
--- a/service/jni/com_android_server_TestNetworkService.cpp
+++ b/service/jni/com_android_server_TestNetworkService.cpp
@@ -35,8 +35,6 @@
#include <log/log.h>
-#include "netutils/ifc.h"
-
#include "jni.h"
#include <android-base/stringprintf.h>
#include <android-base/unique_fd.h>
@@ -48,9 +46,8 @@
//------------------------------------------------------------------------------
static void throwException(JNIEnv* env, int error, const char* action, const char* iface) {
- const std::string& msg =
- android::base::StringPrintf("Error %s %s: %s", action, iface, strerror(error));
-
+ const std::string& msg = "Error: " + std::string(action) + " " + std::string(iface) + ": "
+ + std::string(strerror(error));
jniThrowException(env, "java/lang/IllegalStateException", msg.c_str());
}
diff --git a/service/lint-baseline.xml b/service/lint-baseline.xml
new file mode 100644
index 0000000..df57c22
--- /dev/null
+++ b/service/lint-baseline.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<issues format="5" by="lint 4.1.0" client="cli" variant="all" version="4.1.0">
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.telephony.TelephonyManager#isDataCapable`"
+ errorLine1=" if (tm.isDataCapable()) {"
+ errorLine2=" ~~~~~~~~~~~~~">
+ <location
+ file="packages/modules/Connectivity/service/src/com/android/server/ConnectivityService.java"
+ line="791"
+ column="20"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.content.Context#sendStickyBroadcast`"
+ errorLine1=" mUserAllContext.sendStickyBroadcast(intent, options);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/modules/Connectivity/service/src/com/android/server/ConnectivityService.java"
+ line="2693"
+ column="33"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 31 (current min is 30): `android.content.pm.PackageManager#getTargetSdkVersion`"
+ errorLine1=" final int callingVersion = pm.getTargetSdkVersion(callingPackageName);"
+ errorLine2=" ~~~~~~~~~~~~~~~~~~~">
+ <location
+ file="packages/modules/Connectivity/service/src/com/android/server/ConnectivityService.java"
+ line="5894"
+ column="43"/>
+ </issue>
+
+</issues>
diff --git a/service/src/com/android/server/connectivity/PermissionMonitor.java b/service/src/com/android/server/connectivity/PermissionMonitor.java
index 49b43f8..32e06e5 100644
--- a/service/src/com/android/server/connectivity/PermissionMonitor.java
+++ b/service/src/com/android/server/connectivity/PermissionMonitor.java
@@ -197,7 +197,7 @@
// Register UIDS_ALLOWED_ON_RESTRICTED_NETWORKS setting observer
mDeps.registerContentObserver(
userAllContext,
- Settings.Secure.getUriFor(UIDS_ALLOWED_ON_RESTRICTED_NETWORKS),
+ Settings.Global.getUriFor(UIDS_ALLOWED_ON_RESTRICTED_NETWORKS),
false /* notifyForDescendants */,
new ContentObserver(null) {
@Override
@@ -265,7 +265,7 @@
}
@VisibleForTesting
- void updateUidsAllowedOnRestrictedNetworks(final Set<Integer> uids) {
+ synchronized void updateUidsAllowedOnRestrictedNetworks(final Set<Integer> uids) {
mUidsAllowedOnRestrictedNetworks.clear();
mUidsAllowedOnRestrictedNetworks.addAll(uids);
}
@@ -285,7 +285,7 @@
}
@VisibleForTesting
- boolean isUidAllowedOnRestrictedNetworks(final ApplicationInfo appInfo) {
+ synchronized boolean isUidAllowedOnRestrictedNetworks(final ApplicationInfo appInfo) {
if (appInfo == null) return false;
// Check whether package's uid is in allowed on restricted networks uid list. If so, this
// uid can have netd system permission.
@@ -389,6 +389,14 @@
update(users, mApps, false);
}
+ /**
+ * Compare the current network permission and the given package's permission to find out highest
+ * permission for the uid.
+ *
+ * @param currentPermission Current uid network permission
+ * @param name The package has same uid that need compare its permission to update uid network
+ * permission.
+ */
@VisibleForTesting
protected Boolean highestPermissionForUid(Boolean currentPermission, String name) {
if (currentPermission == SYSTEM) {
@@ -472,6 +480,8 @@
final String[] packages = mPackageManager.getPackagesForUid(uid);
if (!CollectionUtils.isEmpty(packages)) {
for (String name : packages) {
+ // If multiple packages have the same UID, give the UID all permissions that
+ // any package in that UID has.
permission = highestPermissionForUid(permission, name);
if (permission == SYSTEM) {
break;
diff --git a/tests/common/java/android/net/NetworkAgentConfigTest.kt b/tests/common/java/android/net/NetworkAgentConfigTest.kt
index 2b45b3d..afaae1c 100644
--- a/tests/common/java/android/net/NetworkAgentConfigTest.kt
+++ b/tests/common/java/android/net/NetworkAgentConfigTest.kt
@@ -59,6 +59,7 @@
@Test @IgnoreUpTo(Build.VERSION_CODES.Q)
fun testBuilder() {
+ val testExtraInfo = "mylegacyExtraInfo"
val config = NetworkAgentConfig.Builder().apply {
setExplicitlySelected(true)
setLegacyType(ConnectivityManager.TYPE_ETHERNET)
@@ -67,6 +68,7 @@
setUnvalidatedConnectivityAcceptable(true)
setLegacyTypeName("TEST_NETWORK")
if (isAtLeastS()) {
+ setLegacyExtraInfo(testExtraInfo)
setNat64DetectionEnabled(false)
setProvisioningNotificationEnabled(false)
setBypassableVpn(true)
@@ -80,6 +82,7 @@
assertTrue(config.isUnvalidatedConnectivityAcceptable())
assertEquals("TEST_NETWORK", config.getLegacyTypeName())
if (isAtLeastS()) {
+ assertEquals(testExtraInfo, config.getLegacyExtraInfo())
assertFalse(config.isNat64DetectionEnabled())
assertFalse(config.isProvisioningNotificationEnabled())
assertTrue(config.isBypassableVpn())
diff --git a/tests/cts/net/src/android/net/cts/IpSecBaseTest.java b/tests/cts/net/src/android/net/cts/IpSecBaseTest.java
index 10e43e7..c54ee91 100644
--- a/tests/cts/net/src/android/net/cts/IpSecBaseTest.java
+++ b/tests/cts/net/src/android/net/cts/IpSecBaseTest.java
@@ -16,6 +16,14 @@
package android.net.cts;
+import static android.net.IpSecAlgorithm.AUTH_CRYPT_AES_GCM;
+import static android.net.IpSecAlgorithm.AUTH_HMAC_MD5;
+import static android.net.IpSecAlgorithm.AUTH_HMAC_SHA1;
+import static android.net.IpSecAlgorithm.AUTH_HMAC_SHA256;
+import static android.net.IpSecAlgorithm.AUTH_HMAC_SHA384;
+import static android.net.IpSecAlgorithm.AUTH_HMAC_SHA512;
+import static android.net.IpSecAlgorithm.CRYPT_AES_CBC;
+
import static org.junit.Assert.assertArrayEquals;
import android.content.Context;
@@ -31,6 +39,12 @@
import androidx.test.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;
+import com.android.modules.utils.build.SdkLevel;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
import java.io.FileDescriptor;
import java.io.IOException;
import java.net.DatagramPacket;
@@ -42,12 +56,10 @@
import java.net.Socket;
import java.net.SocketException;
import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
@RunWith(AndroidJUnit4.class)
public class IpSecBaseTest {
@@ -71,6 +83,18 @@
0x20, 0x21, 0x22, 0x23
};
+ private static final Set<String> MANDATORY_IPSEC_ALGOS_SINCE_P = new HashSet<>();
+
+ static {
+ MANDATORY_IPSEC_ALGOS_SINCE_P.add(CRYPT_AES_CBC);
+ MANDATORY_IPSEC_ALGOS_SINCE_P.add(AUTH_HMAC_MD5);
+ MANDATORY_IPSEC_ALGOS_SINCE_P.add(AUTH_HMAC_SHA1);
+ MANDATORY_IPSEC_ALGOS_SINCE_P.add(AUTH_HMAC_SHA256);
+ MANDATORY_IPSEC_ALGOS_SINCE_P.add(AUTH_HMAC_SHA384);
+ MANDATORY_IPSEC_ALGOS_SINCE_P.add(AUTH_HMAC_SHA512);
+ MANDATORY_IPSEC_ALGOS_SINCE_P.add(AUTH_CRYPT_AES_GCM);
+ }
+
protected static final byte[] AUTH_KEY = getKey(256);
protected static final byte[] CRYPT_KEY = getKey(256);
@@ -89,8 +113,24 @@
.getSystemService(Context.CONNECTIVITY_SERVICE);
}
+ /** Checks if an IPsec algorithm is enabled on the device */
+ protected static boolean hasIpSecAlgorithm(String algorithm) {
+ if (SdkLevel.isAtLeastS()) {
+ return IpSecAlgorithm.getSupportedAlgorithms().contains(algorithm);
+ } else {
+ return MANDATORY_IPSEC_ALGOS_SINCE_P.contains(algorithm);
+ }
+ }
+
+ protected static byte[] getKeyBytes(int byteLength) {
+ return Arrays.copyOf(KEY_DATA, byteLength);
+ }
+
protected static byte[] getKey(int bitLength) {
- return Arrays.copyOf(KEY_DATA, bitLength / 8);
+ if (bitLength % 8 != 0) {
+ throw new IllegalArgumentException("Invalid key length in bits" + bitLength);
+ }
+ return getKeyBytes(bitLength / 8);
}
protected static int getDomain(InetAddress address) {
diff --git a/tests/cts/net/src/android/net/cts/IpSecManagerTest.java b/tests/cts/net/src/android/net/cts/IpSecManagerTest.java
index d08f6e9..e7e1d67 100644
--- a/tests/cts/net/src/android/net/cts/IpSecManagerTest.java
+++ b/tests/cts/net/src/android/net/cts/IpSecManagerTest.java
@@ -16,10 +16,33 @@
package android.net.cts;
+import static android.net.IpSecAlgorithm.AUTH_AES_CMAC;
+import static android.net.IpSecAlgorithm.AUTH_AES_XCBC;
+import static android.net.IpSecAlgorithm.AUTH_CRYPT_AES_GCM;
+import static android.net.IpSecAlgorithm.AUTH_CRYPT_CHACHA20_POLY1305;
+import static android.net.IpSecAlgorithm.AUTH_HMAC_MD5;
+import static android.net.IpSecAlgorithm.AUTH_HMAC_SHA1;
+import static android.net.IpSecAlgorithm.AUTH_HMAC_SHA256;
+import static android.net.IpSecAlgorithm.AUTH_HMAC_SHA384;
+import static android.net.IpSecAlgorithm.AUTH_HMAC_SHA512;
+import static android.net.IpSecAlgorithm.CRYPT_AES_CBC;
+import static android.net.IpSecAlgorithm.CRYPT_AES_CTR;
import static android.net.cts.PacketUtils.AES_CBC_BLK_SIZE;
import static android.net.cts.PacketUtils.AES_CBC_IV_LEN;
+import static android.net.cts.PacketUtils.AES_CMAC_ICV_LEN;
+import static android.net.cts.PacketUtils.AES_CMAC_KEY_LEN;
+import static android.net.cts.PacketUtils.AES_CTR_BLK_SIZE;
+import static android.net.cts.PacketUtils.AES_CTR_IV_LEN;
+import static android.net.cts.PacketUtils.AES_CTR_KEY_LEN;
import static android.net.cts.PacketUtils.AES_GCM_BLK_SIZE;
import static android.net.cts.PacketUtils.AES_GCM_IV_LEN;
+import static android.net.cts.PacketUtils.AES_XCBC_ICV_LEN;
+import static android.net.cts.PacketUtils.AES_XCBC_KEY_LEN;
+import static android.net.cts.PacketUtils.CHACHA20_POLY1305_BLK_SIZE;
+import static android.net.cts.PacketUtils.CHACHA20_POLY1305_ICV_LEN;
+import static android.net.cts.PacketUtils.CHACHA20_POLY1305_IV_LEN;
+import static android.net.cts.PacketUtils.HMAC_SHA512_ICV_LEN;
+import static android.net.cts.PacketUtils.HMAC_SHA512_KEY_LEN;
import static android.net.cts.PacketUtils.IP4_HDRLEN;
import static android.net.cts.PacketUtils.IP6_HDRLEN;
import static android.net.cts.PacketUtils.TCP_HDRLEN_WITH_TIMESTAMP_OPT;
@@ -27,15 +50,20 @@
import static android.system.OsConstants.IPPROTO_TCP;
import static android.system.OsConstants.IPPROTO_UDP;
+import static com.android.compatibility.common.util.PropertyUtil.getFirstApiLevel;
+import static com.android.compatibility.common.util.PropertyUtil.getVendorApiLevel;
+
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeTrue;
import android.net.IpSecAlgorithm;
import android.net.IpSecManager;
import android.net.IpSecTransform;
import android.net.TrafficStats;
+import android.os.Build;
import android.platform.test.annotations.AppModeFull;
import android.system.ErrnoException;
import android.system.Os;
@@ -44,8 +72,11 @@
import androidx.test.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo;
import com.android.testutils.SkipPresubmit;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -56,10 +87,15 @@
import java.net.Inet6Address;
import java.net.InetAddress;
import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
@RunWith(AndroidJUnit4.class)
@AppModeFull(reason = "Socket cannot bind in instant app mode")
public class IpSecManagerTest extends IpSecBaseTest {
+ @Rule public final DevSdkIgnoreRule ignoreRule = new DevSdkIgnoreRule();
private static final String TAG = IpSecManagerTest.class.getSimpleName();
@@ -417,8 +453,12 @@
switch (cryptOrAead.getName()) {
case IpSecAlgorithm.CRYPT_AES_CBC:
return AES_CBC_IV_LEN;
+ case IpSecAlgorithm.CRYPT_AES_CTR:
+ return AES_CTR_IV_LEN;
case IpSecAlgorithm.AUTH_CRYPT_AES_GCM:
return AES_GCM_IV_LEN;
+ case IpSecAlgorithm.AUTH_CRYPT_CHACHA20_POLY1305:
+ return CHACHA20_POLY1305_IV_LEN;
default:
throw new IllegalArgumentException(
"IV length unknown for algorithm" + cryptOrAead.getName());
@@ -433,8 +473,12 @@
switch (cryptOrAead.getName()) {
case IpSecAlgorithm.CRYPT_AES_CBC:
return AES_CBC_BLK_SIZE;
+ case IpSecAlgorithm.CRYPT_AES_CTR:
+ return AES_CTR_BLK_SIZE;
case IpSecAlgorithm.AUTH_CRYPT_AES_GCM:
return AES_GCM_BLK_SIZE;
+ case IpSecAlgorithm.AUTH_CRYPT_CHACHA20_POLY1305:
+ return CHACHA20_POLY1305_BLK_SIZE;
default:
throw new IllegalArgumentException(
"Blk size unknown for algorithm" + cryptOrAead.getName());
@@ -516,7 +560,6 @@
int blkSize,
int truncLenBits)
throws Exception {
-
int innerPacketSize = TEST_DATA.length + transportHdrLen + ipHdrLen;
int outerPacketSize =
PacketUtils.calculateEspPacketSize(
@@ -663,6 +706,41 @@
// checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, true, 1000);
// }
+ @IgnoreUpTo(Build.VERSION_CODES.R)
+ @Test
+ public void testGetSupportedAlgorithms() throws Exception {
+ final Map<String, Integer> algoToRequiredMinSdk = new HashMap<>();
+ algoToRequiredMinSdk.put(CRYPT_AES_CBC, Build.VERSION_CODES.P);
+ algoToRequiredMinSdk.put(AUTH_HMAC_MD5, Build.VERSION_CODES.P);
+ algoToRequiredMinSdk.put(AUTH_HMAC_SHA1, Build.VERSION_CODES.P);
+ algoToRequiredMinSdk.put(AUTH_HMAC_SHA256, Build.VERSION_CODES.P);
+ algoToRequiredMinSdk.put(AUTH_HMAC_SHA384, Build.VERSION_CODES.P);
+ algoToRequiredMinSdk.put(AUTH_HMAC_SHA512, Build.VERSION_CODES.P);
+ algoToRequiredMinSdk.put(AUTH_CRYPT_AES_GCM, Build.VERSION_CODES.P);
+
+ // TODO: b/170424293 Use Build.VERSION_CODES.S when is finalized
+ algoToRequiredMinSdk.put(CRYPT_AES_CTR, Build.VERSION_CODES.R + 1);
+ algoToRequiredMinSdk.put(AUTH_AES_CMAC, Build.VERSION_CODES.R + 1);
+ algoToRequiredMinSdk.put(AUTH_AES_XCBC, Build.VERSION_CODES.R + 1);
+ algoToRequiredMinSdk.put(AUTH_CRYPT_CHACHA20_POLY1305, Build.VERSION_CODES.R + 1);
+
+ final Set<String> supportedAlgos = IpSecAlgorithm.getSupportedAlgorithms();
+
+ // Verify all supported algorithms are valid
+ for (String algo : supportedAlgos) {
+ assertTrue("Found invalid algo " + algo, algoToRequiredMinSdk.keySet().contains(algo));
+ }
+
+ // Verify all mandatory algorithms are supported
+ for (Entry<String, Integer> entry : algoToRequiredMinSdk.entrySet()) {
+ if (Math.min(getFirstApiLevel(), getVendorApiLevel()) >= entry.getValue()) {
+ assertTrue(
+ "Fail to support " + entry.getKey(),
+ supportedAlgos.contains(entry.getKey()));
+ }
+ }
+ }
+
@Test
public void testInterfaceCountersUdp4() throws Exception {
IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
@@ -849,6 +927,152 @@
checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, null, false, 1, true);
}
+ private static IpSecAlgorithm buildCryptAesCtr() throws Exception {
+ return new IpSecAlgorithm(CRYPT_AES_CTR, getKeyBytes(AES_CTR_KEY_LEN));
+ }
+
+ private static IpSecAlgorithm buildAuthHmacSha512() throws Exception {
+ return new IpSecAlgorithm(
+ AUTH_HMAC_SHA512, getKeyBytes(HMAC_SHA512_KEY_LEN), HMAC_SHA512_ICV_LEN * 8);
+ }
+
+ @Test
+ public void testAesCtrHmacSha512Tcp4() throws Exception {
+ assumeTrue(hasIpSecAlgorithm(CRYPT_AES_CTR));
+
+ final IpSecAlgorithm crypt = buildCryptAesCtr();
+ final IpSecAlgorithm auth = buildAuthHmacSha512();
+ checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, false, 1, false);
+ checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, false, 1, true);
+ }
+
+ @Test
+ @SkipPresubmit(reason = "b/186608065 - kernel 5.10 regression in TrafficStats with ipsec")
+ public void testAesCtrHmacSha512Tcp6() throws Exception {
+ assumeTrue(hasIpSecAlgorithm(CRYPT_AES_CTR));
+
+ final IpSecAlgorithm crypt = buildCryptAesCtr();
+ final IpSecAlgorithm auth = buildAuthHmacSha512();
+ checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, null, false, 1, false);
+ checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, null, false, 1, true);
+ }
+
+ @Test
+ public void testAesCtrHmacSha512Udp4() throws Exception {
+ assumeTrue(hasIpSecAlgorithm(CRYPT_AES_CTR));
+
+ final IpSecAlgorithm crypt = buildCryptAesCtr();
+ final IpSecAlgorithm auth = buildAuthHmacSha512();
+ checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, false, 1, false);
+ checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, false, 1, true);
+ }
+
+ @Test
+ public void testAesCtrHmacSha512Udp6() throws Exception {
+ assumeTrue(hasIpSecAlgorithm(CRYPT_AES_CTR));
+
+ final IpSecAlgorithm crypt = buildCryptAesCtr();
+ final IpSecAlgorithm auth = buildAuthHmacSha512();
+ checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, null, false, 1, false);
+ checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, null, false, 1, true);
+ }
+
+ private static IpSecAlgorithm buildCryptAesCbc() throws Exception {
+ return new IpSecAlgorithm(CRYPT_AES_CBC, CRYPT_KEY);
+ }
+
+ private static IpSecAlgorithm buildAuthAesXcbc() throws Exception {
+ return new IpSecAlgorithm(
+ AUTH_AES_XCBC, getKeyBytes(AES_XCBC_KEY_LEN), AES_XCBC_ICV_LEN * 8);
+ }
+
+ private static IpSecAlgorithm buildAuthAesCmac() throws Exception {
+ return new IpSecAlgorithm(
+ AUTH_AES_CMAC, getKeyBytes(AES_CMAC_KEY_LEN), AES_CMAC_ICV_LEN * 8);
+ }
+
+ @Test
+ public void testAesCbcAesXCbcTcp4() throws Exception {
+ assumeTrue(hasIpSecAlgorithm(AUTH_AES_XCBC));
+
+ final IpSecAlgorithm crypt = buildCryptAesCbc();
+ final IpSecAlgorithm auth = buildAuthAesXcbc();
+ checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, false, 1, false);
+ checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, false, 1, true);
+ }
+
+ @Test
+ @SkipPresubmit(reason = "b/186608065 - kernel 5.10 regression in TrafficStats with ipsec")
+ public void testAesCbcAesXCbcTcp6() throws Exception {
+ assumeTrue(hasIpSecAlgorithm(AUTH_AES_XCBC));
+
+ final IpSecAlgorithm crypt = buildCryptAesCbc();
+ final IpSecAlgorithm auth = buildAuthAesXcbc();
+ checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, null, false, 1, false);
+ checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, null, false, 1, true);
+ }
+
+ @Test
+ public void testAesCbcAesXCbcUdp4() throws Exception {
+ assumeTrue(hasIpSecAlgorithm(AUTH_AES_XCBC));
+
+ final IpSecAlgorithm crypt = buildCryptAesCbc();
+ final IpSecAlgorithm auth = buildAuthAesXcbc();
+ checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, false, 1, false);
+ checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, false, 1, true);
+ }
+
+ @Test
+ public void testAesCbcAesXCbcUdp6() throws Exception {
+ assumeTrue(hasIpSecAlgorithm(AUTH_AES_XCBC));
+
+ final IpSecAlgorithm crypt = buildCryptAesCbc();
+ final IpSecAlgorithm auth = buildAuthAesXcbc();
+ checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, null, false, 1, false);
+ checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, null, false, 1, true);
+ }
+
+ @Test
+ public void testAesCbcAesCmacTcp4() throws Exception {
+ assumeTrue(hasIpSecAlgorithm(AUTH_AES_CMAC));
+
+ final IpSecAlgorithm crypt = buildCryptAesCbc();
+ final IpSecAlgorithm auth = buildAuthAesCmac();
+ checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, false, 1, false);
+ checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, false, 1, true);
+ }
+
+ @Test
+ @SkipPresubmit(reason = "b/186608065 - kernel 5.10 regression in TrafficStats with ipsec")
+ public void testAesCbcAesCmacTcp6() throws Exception {
+ assumeTrue(hasIpSecAlgorithm(AUTH_AES_CMAC));
+
+ final IpSecAlgorithm crypt = buildCryptAesCbc();
+ final IpSecAlgorithm auth = buildAuthAesCmac();
+ checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, null, false, 1, false);
+ checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, crypt, auth, null, false, 1, true);
+ }
+
+ @Test
+ public void testAesCbcAesCmacUdp4() throws Exception {
+ assumeTrue(hasIpSecAlgorithm(AUTH_AES_CMAC));
+
+ final IpSecAlgorithm crypt = buildCryptAesCbc();
+ final IpSecAlgorithm auth = buildAuthAesCmac();
+ checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, false, 1, false);
+ checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, false, 1, true);
+ }
+
+ @Test
+ public void testAesCbcAesCmacUdp6() throws Exception {
+ assumeTrue(hasIpSecAlgorithm(AUTH_AES_CMAC));
+
+ final IpSecAlgorithm crypt = buildCryptAesCbc();
+ final IpSecAlgorithm auth = buildAuthAesCmac();
+ checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, null, false, 1, false);
+ checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, crypt, auth, null, false, 1, true);
+ }
+
@Test
public void testAesGcm64Tcp4() throws Exception {
IpSecAlgorithm authCrypt =
@@ -948,6 +1172,48 @@
checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, null, null, authCrypt, false, 1, true);
}
+ private static IpSecAlgorithm buildAuthCryptChaCha20Poly1305() throws Exception {
+ return new IpSecAlgorithm(
+ AUTH_CRYPT_CHACHA20_POLY1305, AEAD_KEY, CHACHA20_POLY1305_ICV_LEN * 8);
+ }
+
+ @Test
+ public void testChaCha20Poly1305Tcp4() throws Exception {
+ assumeTrue(hasIpSecAlgorithm(AUTH_CRYPT_CHACHA20_POLY1305));
+
+ final IpSecAlgorithm authCrypt = buildAuthCryptChaCha20Poly1305();
+ checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, null, authCrypt, false, 1, false);
+ checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, null, authCrypt, false, 1, true);
+ }
+
+ @Test
+ @SkipPresubmit(reason = "b/186608065 - kernel 5.10 regression in TrafficStats with ipsec")
+ public void testChaCha20Poly1305Tcp6() throws Exception {
+ assumeTrue(hasIpSecAlgorithm(AUTH_CRYPT_CHACHA20_POLY1305));
+
+ final IpSecAlgorithm authCrypt = buildAuthCryptChaCha20Poly1305();
+ checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, null, null, authCrypt, false, 1, false);
+ checkTransform(IPPROTO_TCP, IPV6_LOOPBACK, null, null, authCrypt, false, 1, true);
+ }
+
+ @Test
+ public void testChaCha20Poly1305Udp4() throws Exception {
+ assumeTrue(hasIpSecAlgorithm(AUTH_CRYPT_CHACHA20_POLY1305));
+
+ final IpSecAlgorithm authCrypt = buildAuthCryptChaCha20Poly1305();
+ checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, null, authCrypt, false, 1, false);
+ checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, null, authCrypt, false, 1, true);
+ }
+
+ @Test
+ public void testChaCha20Poly1305Udp6() throws Exception {
+ assumeTrue(hasIpSecAlgorithm(AUTH_CRYPT_CHACHA20_POLY1305));
+
+ final IpSecAlgorithm authCrypt = buildAuthCryptChaCha20Poly1305();
+ checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, null, null, authCrypt, false, 1, false);
+ checkTransform(IPPROTO_UDP, IPV6_LOOPBACK, null, null, authCrypt, false, 1, true);
+ }
+
@Test
public void testAesCbcHmacMd5Tcp4UdpEncap() throws Exception {
IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
@@ -1029,6 +1295,66 @@
}
@Test
+ public void testAesCtrHmacSha512Tcp4UdpEncap() throws Exception {
+ assumeTrue(hasIpSecAlgorithm(CRYPT_AES_CTR));
+
+ final IpSecAlgorithm crypt = buildCryptAesCtr();
+ final IpSecAlgorithm auth = buildAuthHmacSha512();
+ checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, true, 1, false);
+ checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, true, 1, true);
+ }
+
+ @Test
+ public void testAesCtrHmacSha512Udp4UdpEncap() throws Exception {
+ assumeTrue(hasIpSecAlgorithm(CRYPT_AES_CTR));
+
+ final IpSecAlgorithm crypt = buildCryptAesCtr();
+ final IpSecAlgorithm auth = buildAuthHmacSha512();
+ checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, true, 1, false);
+ checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, true, 1, true);
+ }
+
+ @Test
+ public void testAesCbcAesXCbcTcp4UdpEncap() throws Exception {
+ assumeTrue(hasIpSecAlgorithm(AUTH_AES_XCBC));
+
+ final IpSecAlgorithm crypt = new IpSecAlgorithm(CRYPT_AES_CBC, CRYPT_KEY);
+ final IpSecAlgorithm auth = new IpSecAlgorithm(AUTH_AES_XCBC, getKey(128), 96);
+ checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, true, 1, false);
+ checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, true, 1, true);
+ }
+
+ @Test
+ public void testAesCbcAesXCbcUdp4UdpEncap() throws Exception {
+ assumeTrue(hasIpSecAlgorithm(AUTH_AES_XCBC));
+
+ final IpSecAlgorithm crypt = new IpSecAlgorithm(CRYPT_AES_CBC, CRYPT_KEY);
+ final IpSecAlgorithm auth = new IpSecAlgorithm(AUTH_AES_XCBC, getKey(128), 96);
+ checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, true, 1, false);
+ checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, true, 1, true);
+ }
+
+ @Test
+ public void testAesCbcAesCmacTcp4UdpEncap() throws Exception {
+ assumeTrue(hasIpSecAlgorithm(AUTH_AES_CMAC));
+
+ final IpSecAlgorithm crypt = new IpSecAlgorithm(CRYPT_AES_CBC, CRYPT_KEY);
+ final IpSecAlgorithm auth = new IpSecAlgorithm(AUTH_AES_CMAC, getKey(128), 96);
+ checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, true, 1, false);
+ checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, crypt, auth, null, true, 1, true);
+ }
+
+ @Test
+ public void testAesCbcAesCmacUdp4UdpEncap() throws Exception {
+ assumeTrue(hasIpSecAlgorithm(AUTH_AES_CMAC));
+
+ final IpSecAlgorithm crypt = new IpSecAlgorithm(CRYPT_AES_CBC, CRYPT_KEY);
+ final IpSecAlgorithm auth = new IpSecAlgorithm(AUTH_AES_CMAC, getKey(128), 96);
+ checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, true, 1, false);
+ checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, auth, null, true, 1, true);
+ }
+
+ @Test
public void testAesGcm64Tcp4UdpEncap() throws Exception {
IpSecAlgorithm authCrypt =
new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 64);
@@ -1077,6 +1403,24 @@
}
@Test
+ public void testChaCha20Poly1305Tcp4UdpEncap() throws Exception {
+ assumeTrue(hasIpSecAlgorithm(AUTH_CRYPT_CHACHA20_POLY1305));
+
+ final IpSecAlgorithm authCrypt = buildAuthCryptChaCha20Poly1305();
+ checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, null, authCrypt, true, 1, false);
+ checkTransform(IPPROTO_TCP, IPV4_LOOPBACK, null, null, authCrypt, true, 1, true);
+ }
+
+ @Test
+ public void testChaCha20Poly1305Udp4UdpEncap() throws Exception {
+ assumeTrue(hasIpSecAlgorithm(AUTH_CRYPT_CHACHA20_POLY1305));
+
+ final IpSecAlgorithm authCrypt = buildAuthCryptChaCha20Poly1305();
+ checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, null, authCrypt, true, 1, false);
+ checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, null, null, authCrypt, true, 1, true);
+ }
+
+ @Test
public void testCryptUdp4() throws Exception {
IpSecAlgorithm crypt = new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
checkTransform(IPPROTO_UDP, IPV4_LOOPBACK, crypt, null, null, false, 1, false);
diff --git a/tests/cts/net/src/android/net/cts/PacketUtils.java b/tests/cts/net/src/android/net/cts/PacketUtils.java
index 0aedecb..7e622f6 100644
--- a/tests/cts/net/src/android/net/cts/PacketUtils.java
+++ b/tests/cts/net/src/android/net/cts/PacketUtils.java
@@ -43,17 +43,35 @@
static final int UDP_HDRLEN = 8;
static final int TCP_HDRLEN = 20;
static final int TCP_HDRLEN_WITH_TIMESTAMP_OPT = TCP_HDRLEN + 12;
+ static final int ESP_BLK_SIZE = 4; // ESP has to be 4-byte aligned
// Not defined in OsConstants
static final int IPPROTO_IPV4 = 4;
static final int IPPROTO_ESP = 50;
// Encryption parameters
- static final int AES_GCM_IV_LEN = 8;
static final int AES_CBC_IV_LEN = 16;
- static final int AES_GCM_BLK_SIZE = 4;
static final int AES_CBC_BLK_SIZE = 16;
+ static final int AES_CTR_KEY_LEN = 20;
+ static final int AES_CTR_BLK_SIZE = ESP_BLK_SIZE;
+ static final int AES_CTR_IV_LEN = 8;
+
+ // AEAD parameters
+ static final int AES_GCM_IV_LEN = 8;
+ static final int AES_GCM_BLK_SIZE = 4;
+ static final int CHACHA20_POLY1305_BLK_SIZE = ESP_BLK_SIZE;
+ static final int CHACHA20_POLY1305_IV_LEN = 8;
+ static final int CHACHA20_POLY1305_ICV_LEN = 16;
+
+ // Authentication parameters
+ static final int HMAC_SHA512_KEY_LEN = 64;
+ static final int HMAC_SHA512_ICV_LEN = 32;
+ static final int AES_XCBC_KEY_LEN = 16;
+ static final int AES_XCBC_ICV_LEN = 12;
+ static final int AES_CMAC_KEY_LEN = 16;
+ static final int AES_CMAC_ICV_LEN = 12;
+
// Encryption algorithms
static final String AES = "AES";
static final String AES_CBC = "AES/CBC/NoPadding";
diff --git a/tests/cts/net/util/Android.bp b/tests/cts/net/util/Android.bp
index 88a2068..b5f1208 100644
--- a/tests/cts/net/util/Android.bp
+++ b/tests/cts/net/util/Android.bp
@@ -26,5 +26,6 @@
"compatibility-device-util-axt",
"junit",
"net-tests-utils",
+ "modules-utils-build",
],
}
diff --git a/tests/cts/net/util/java/android/net/cts/util/CtsNetUtils.java b/tests/cts/net/util/java/android/net/cts/util/CtsNetUtils.java
index d5a26c4..1fbe3b8 100644
--- a/tests/cts/net/util/java/android/net/cts/util/CtsNetUtils.java
+++ b/tests/cts/net/util/java/android/net/cts/util/CtsNetUtils.java
@@ -23,6 +23,7 @@
import static android.net.NetworkCapabilities.TRANSPORT_TEST;
import static android.net.wifi.WifiManager.SCAN_RESULTS_AVAILABLE_ACTION;
+import static com.android.compatibility.common.util.PropertyUtil.getFirstApiLevel;
import static com.android.testutils.TestPermissionUtil.runAsShell;
import static org.junit.Assert.assertEquals;
@@ -55,7 +56,6 @@
import android.os.Binder;
import android.os.Build;
import android.os.IBinder;
-import android.os.SystemProperties;
import android.provider.Settings;
import android.system.Os;
import android.system.OsConstants;
@@ -116,8 +116,7 @@
/** Checks if FEATURE_IPSEC_TUNNELS is enabled on the device */
public boolean hasIpsecTunnelsFeature() {
return mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_IPSEC_TUNNELS)
- || SystemProperties.getInt("ro.product.first_api_level", 0)
- >= Build.VERSION_CODES.Q;
+ || getFirstApiLevel() >= Build.VERSION_CODES.Q;
}
/**
diff --git a/tests/unit/java/com/android/server/connectivity/PermissionMonitorTest.java b/tests/unit/java/com/android/server/connectivity/PermissionMonitorTest.java
index c6e7606..e98f5db 100644
--- a/tests/unit/java/com/android/server/connectivity/PermissionMonitorTest.java
+++ b/tests/unit/java/com/android/server/connectivity/PermissionMonitorTest.java
@@ -73,6 +73,7 @@
import android.os.SystemConfigManager;
import android.os.UserHandle;
import android.os.UserManager;
+import android.provider.Settings;
import android.util.ArraySet;
import android.util.SparseIntArray;
@@ -515,7 +516,7 @@
@Test
public void testUserAndPackageAddRemove() throws Exception {
- final NetdMonitor mNetdMonitor = new NetdMonitor(mNetdService);
+ final NetdMonitor netdMonitor = new NetdMonitor(mNetdService);
// MOCK_UID1: MOCK_PACKAGE1 only has network permission.
// SYSTEM_UID: SYSTEM_PACKAGE1 has system permission.
@@ -531,47 +532,47 @@
// Add SYSTEM_PACKAGE2, expect only have network permission.
mPermissionMonitor.onUserAdded(MOCK_USER1);
addPackageForUsers(new UserHandle[]{MOCK_USER1}, SYSTEM_PACKAGE2, SYSTEM_UID);
- mNetdMonitor.expectPermission(NETWORK, new UserHandle[]{MOCK_USER1}, new int[]{SYSTEM_UID});
+ netdMonitor.expectPermission(NETWORK, new UserHandle[]{MOCK_USER1}, new int[]{SYSTEM_UID});
// Add SYSTEM_PACKAGE1, expect permission escalate.
addPackageForUsers(new UserHandle[]{MOCK_USER1}, SYSTEM_PACKAGE1, SYSTEM_UID);
- mNetdMonitor.expectPermission(SYSTEM, new UserHandle[]{MOCK_USER1}, new int[]{SYSTEM_UID});
+ netdMonitor.expectPermission(SYSTEM, new UserHandle[]{MOCK_USER1}, new int[]{SYSTEM_UID});
mPermissionMonitor.onUserAdded(MOCK_USER2);
- mNetdMonitor.expectPermission(SYSTEM, new UserHandle[]{MOCK_USER1, MOCK_USER2},
+ netdMonitor.expectPermission(SYSTEM, new UserHandle[]{MOCK_USER1, MOCK_USER2},
new int[]{SYSTEM_UID});
addPackageForUsers(new UserHandle[]{MOCK_USER1, MOCK_USER2}, MOCK_PACKAGE1, MOCK_UID1);
- mNetdMonitor.expectPermission(SYSTEM, new UserHandle[]{MOCK_USER1, MOCK_USER2},
+ netdMonitor.expectPermission(SYSTEM, new UserHandle[]{MOCK_USER1, MOCK_USER2},
new int[]{SYSTEM_UID});
- mNetdMonitor.expectPermission(NETWORK, new UserHandle[]{MOCK_USER1, MOCK_USER2},
+ netdMonitor.expectPermission(NETWORK, new UserHandle[]{MOCK_USER1, MOCK_USER2},
new int[]{MOCK_UID1});
// Remove MOCK_UID1, expect no permission left for all user.
mPermissionMonitor.onPackageRemoved(MOCK_PACKAGE1, MOCK_UID1);
removePackageForUsers(new UserHandle[]{MOCK_USER1, MOCK_USER2}, MOCK_PACKAGE1, MOCK_UID1);
- mNetdMonitor.expectNoPermission(new UserHandle[]{MOCK_USER1, MOCK_USER2},
+ netdMonitor.expectNoPermission(new UserHandle[]{MOCK_USER1, MOCK_USER2},
new int[]{MOCK_UID1});
// Remove SYSTEM_PACKAGE1, expect permission downgrade.
when(mPackageManager.getPackagesForUid(anyInt())).thenReturn(new String[]{SYSTEM_PACKAGE2});
removePackageForUsers(new UserHandle[]{MOCK_USER1, MOCK_USER2},
SYSTEM_PACKAGE1, SYSTEM_UID);
- mNetdMonitor.expectPermission(NETWORK, new UserHandle[]{MOCK_USER1, MOCK_USER2},
+ netdMonitor.expectPermission(NETWORK, new UserHandle[]{MOCK_USER1, MOCK_USER2},
new int[]{SYSTEM_UID});
mPermissionMonitor.onUserRemoved(MOCK_USER1);
- mNetdMonitor.expectPermission(NETWORK, new UserHandle[]{MOCK_USER2}, new int[]{SYSTEM_UID});
+ netdMonitor.expectPermission(NETWORK, new UserHandle[]{MOCK_USER2}, new int[]{SYSTEM_UID});
// Remove all packages, expect no permission left.
when(mPackageManager.getPackagesForUid(anyInt())).thenReturn(new String[]{});
removePackageForUsers(new UserHandle[]{MOCK_USER2}, SYSTEM_PACKAGE2, SYSTEM_UID);
- mNetdMonitor.expectNoPermission(new UserHandle[]{MOCK_USER1, MOCK_USER2},
+ netdMonitor.expectNoPermission(new UserHandle[]{MOCK_USER1, MOCK_USER2},
new int[]{SYSTEM_UID, MOCK_UID1});
// Remove last user, expect no redundant clearPermission is invoked.
mPermissionMonitor.onUserRemoved(MOCK_USER2);
- mNetdMonitor.expectNoPermission(new UserHandle[]{MOCK_USER1, MOCK_USER2},
+ netdMonitor.expectNoPermission(new UserHandle[]{MOCK_USER1, MOCK_USER2},
new int[]{SYSTEM_UID, MOCK_UID1});
}
@@ -698,7 +699,7 @@
@Test
public void testPackagePermissionUpdate() throws Exception {
- final NetdServiceMonitor mNetdServiceMonitor = new NetdServiceMonitor(mNetdService);
+ final NetdServiceMonitor netdServiceMonitor = new NetdServiceMonitor(mNetdService);
// MOCK_UID1: MOCK_PACKAGE1 only has internet permission.
// MOCK_UID2: MOCK_PACKAGE2 does not have any permission.
// SYSTEM_UID1: SYSTEM_PACKAGE1 has internet permission and update device stats permission.
@@ -714,29 +715,29 @@
// Send the permission information to netd, expect permission updated.
mPermissionMonitor.sendPackagePermissionsToNetd(netdPermissionsAppIds);
- mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET,
+ netdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET,
new int[]{MOCK_UID1});
- mNetdServiceMonitor.expectPermission(INetd.PERMISSION_NONE, new int[]{MOCK_UID2});
- mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET
+ netdServiceMonitor.expectPermission(INetd.PERMISSION_NONE, new int[]{MOCK_UID2});
+ netdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET
| INetd.PERMISSION_UPDATE_DEVICE_STATS, new int[]{SYSTEM_UID1});
- mNetdServiceMonitor.expectPermission(INetd.PERMISSION_UPDATE_DEVICE_STATS,
+ netdServiceMonitor.expectPermission(INetd.PERMISSION_UPDATE_DEVICE_STATS,
new int[]{SYSTEM_UID2});
// Update permission of MOCK_UID1, expect new permission show up.
mPermissionMonitor.sendPackagePermissionsForUid(MOCK_UID1,
INetd.PERMISSION_INTERNET | INetd.PERMISSION_UPDATE_DEVICE_STATS);
- mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET
+ netdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET
| INetd.PERMISSION_UPDATE_DEVICE_STATS, new int[]{MOCK_UID1});
// Change permissions of SYSTEM_UID2, expect new permission show up and old permission
// revoked.
mPermissionMonitor.sendPackagePermissionsForUid(SYSTEM_UID2,
INetd.PERMISSION_INTERNET);
- mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET, new int[]{SYSTEM_UID2});
+ netdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET, new int[]{SYSTEM_UID2});
// Revoke permission from SYSTEM_UID1, expect no permission stored.
mPermissionMonitor.sendPackagePermissionsForUid(SYSTEM_UID1, INetd.PERMISSION_NONE);
- mNetdServiceMonitor.expectPermission(INetd.PERMISSION_NONE, new int[]{SYSTEM_UID1});
+ netdServiceMonitor.expectPermission(INetd.PERMISSION_NONE, new int[]{SYSTEM_UID1});
}
private PackageInfo setPackagePermissions(String packageName, int uid, String[] permissions)
@@ -757,23 +758,23 @@
@Test
public void testPackageInstall() throws Exception {
- final NetdServiceMonitor mNetdServiceMonitor = new NetdServiceMonitor(mNetdService);
+ final NetdServiceMonitor netdServiceMonitor = new NetdServiceMonitor(mNetdService);
addPackage(MOCK_PACKAGE1, MOCK_UID1, new String[] {INTERNET, UPDATE_DEVICE_STATS});
- mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET
+ netdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET
| INetd.PERMISSION_UPDATE_DEVICE_STATS, new int[]{MOCK_UID1});
addPackage(MOCK_PACKAGE2, MOCK_UID2, new String[] {INTERNET});
- mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET, new int[]{MOCK_UID2});
+ netdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET, new int[]{MOCK_UID2});
}
@Test
public void testPackageInstallSharedUid() throws Exception {
- final NetdServiceMonitor mNetdServiceMonitor = new NetdServiceMonitor(mNetdService);
+ final NetdServiceMonitor netdServiceMonitor = new NetdServiceMonitor(mNetdService);
PackageInfo packageInfo1 = addPackage(MOCK_PACKAGE1, MOCK_UID1,
new String[] {INTERNET, UPDATE_DEVICE_STATS});
- mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET
+ netdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET
| INetd.PERMISSION_UPDATE_DEVICE_STATS, new int[]{MOCK_UID1});
// Install another package with the same uid and no permissions should not cause the UID to
@@ -783,56 +784,56 @@
when(mPackageManager.getPackagesForUid(MOCK_UID1))
.thenReturn(new String[]{MOCK_PACKAGE1, MOCK_PACKAGE2});
mPermissionMonitor.onPackageAdded(MOCK_PACKAGE2, MOCK_UID1);
- mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET
+ netdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET
| INetd.PERMISSION_UPDATE_DEVICE_STATS, new int[]{MOCK_UID1});
}
@Test
public void testPackageUninstallBasic() throws Exception {
- final NetdServiceMonitor mNetdServiceMonitor = new NetdServiceMonitor(mNetdService);
+ final NetdServiceMonitor netdServiceMonitor = new NetdServiceMonitor(mNetdService);
addPackage(MOCK_PACKAGE1, MOCK_UID1, new String[] {INTERNET, UPDATE_DEVICE_STATS});
- mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET
+ netdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET
| INetd.PERMISSION_UPDATE_DEVICE_STATS, new int[]{MOCK_UID1});
when(mPackageManager.getPackagesForUid(MOCK_UID1)).thenReturn(new String[]{});
mPermissionMonitor.onPackageRemoved(MOCK_PACKAGE1, MOCK_UID1);
- mNetdServiceMonitor.expectPermission(INetd.PERMISSION_UNINSTALLED, new int[]{MOCK_UID1});
+ netdServiceMonitor.expectPermission(INetd.PERMISSION_UNINSTALLED, new int[]{MOCK_UID1});
}
@Test
public void testPackageRemoveThenAdd() throws Exception {
- final NetdServiceMonitor mNetdServiceMonitor = new NetdServiceMonitor(mNetdService);
+ final NetdServiceMonitor netdServiceMonitor = new NetdServiceMonitor(mNetdService);
addPackage(MOCK_PACKAGE1, MOCK_UID1, new String[] {INTERNET, UPDATE_DEVICE_STATS});
- mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET
+ netdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET
| INetd.PERMISSION_UPDATE_DEVICE_STATS, new int[]{MOCK_UID1});
when(mPackageManager.getPackagesForUid(MOCK_UID1)).thenReturn(new String[]{});
mPermissionMonitor.onPackageRemoved(MOCK_PACKAGE1, MOCK_UID1);
- mNetdServiceMonitor.expectPermission(INetd.PERMISSION_UNINSTALLED, new int[]{MOCK_UID1});
+ netdServiceMonitor.expectPermission(INetd.PERMISSION_UNINSTALLED, new int[]{MOCK_UID1});
addPackage(MOCK_PACKAGE1, MOCK_UID1, new String[] {INTERNET});
- mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET, new int[]{MOCK_UID1});
+ netdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET, new int[]{MOCK_UID1});
}
@Test
public void testPackageUpdate() throws Exception {
- final NetdServiceMonitor mNetdServiceMonitor = new NetdServiceMonitor(mNetdService);
+ final NetdServiceMonitor netdServiceMonitor = new NetdServiceMonitor(mNetdService);
addPackage(MOCK_PACKAGE1, MOCK_UID1, new String[] {});
- mNetdServiceMonitor.expectPermission(INetd.PERMISSION_NONE, new int[]{MOCK_UID1});
+ netdServiceMonitor.expectPermission(INetd.PERMISSION_NONE, new int[]{MOCK_UID1});
addPackage(MOCK_PACKAGE1, MOCK_UID1, new String[] {INTERNET});
- mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET, new int[]{MOCK_UID1});
+ netdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET, new int[]{MOCK_UID1});
}
@Test
public void testPackageUninstallWithMultiplePackages() throws Exception {
- final NetdServiceMonitor mNetdServiceMonitor = new NetdServiceMonitor(mNetdService);
+ final NetdServiceMonitor netdServiceMonitor = new NetdServiceMonitor(mNetdService);
addPackage(MOCK_PACKAGE1, MOCK_UID1, new String[] {INTERNET, UPDATE_DEVICE_STATS});
- mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET
+ netdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET
| INetd.PERMISSION_UPDATE_DEVICE_STATS, new int[]{MOCK_UID1});
// Mock another package with the same uid but different permissions.
@@ -842,7 +843,7 @@
MOCK_PACKAGE2});
mPermissionMonitor.onPackageRemoved(MOCK_PACKAGE1, MOCK_UID1);
- mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET, new int[]{MOCK_UID1});
+ netdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET, new int[]{MOCK_UID1});
}
@Test
@@ -859,7 +860,7 @@
@Test
public void testUpdateUidPermissionsFromSystemConfig() throws Exception {
- final NetdServiceMonitor mNetdServiceMonitor = new NetdServiceMonitor(mNetdService);
+ final NetdServiceMonitor netdServiceMonitor = new NetdServiceMonitor(mNetdService);
when(mPackageManager.getInstalledPackages(anyInt())).thenReturn(new ArrayList<>());
when(mSystemConfigManager.getSystemPermissionUids(eq(INTERNET)))
.thenReturn(new int[]{ MOCK_UID1, MOCK_UID2 });
@@ -867,15 +868,15 @@
.thenReturn(new int[]{ MOCK_UID2 });
mPermissionMonitor.startMonitoring();
- mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET, new int[]{ MOCK_UID1 });
- mNetdServiceMonitor.expectPermission(
+ netdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET, new int[]{ MOCK_UID1 });
+ netdServiceMonitor.expectPermission(
INetd.PERMISSION_INTERNET | INetd.PERMISSION_UPDATE_DEVICE_STATS,
new int[]{ MOCK_UID2 });
}
@Test
public void testIntentReceiver() throws Exception {
- final NetdServiceMonitor mNetdServiceMonitor = new NetdServiceMonitor(mNetdService);
+ final NetdServiceMonitor netdServiceMonitor = new NetdServiceMonitor(mNetdService);
final ArgumentCaptor<BroadcastReceiver> receiverCaptor =
ArgumentCaptor.forClass(BroadcastReceiver.class);
verify(mContext, times(1)).registerReceiver(receiverCaptor.capture(), any(), any(), any());
@@ -888,7 +889,7 @@
setPackagePermissions(MOCK_PACKAGE1, MOCK_UID1,
new String[] { INTERNET, UPDATE_DEVICE_STATS });
receiver.onReceive(mContext, addedIntent);
- mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET
+ netdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET
| INetd.PERMISSION_UPDATE_DEVICE_STATS, new int[] { MOCK_UID1 });
// Verify receiving PACKAGE_REMOVED intent.
@@ -897,98 +898,140 @@
Uri.fromParts("package", MOCK_PACKAGE1, null /* fragment */));
removedIntent.putExtra(Intent.EXTRA_UID, MOCK_UID1);
receiver.onReceive(mContext, removedIntent);
- mNetdServiceMonitor.expectPermission(INetd.PERMISSION_UNINSTALLED, new int[] { MOCK_UID1 });
+ netdServiceMonitor.expectPermission(INetd.PERMISSION_UNINSTALLED, new int[] { MOCK_UID1 });
+ }
+
+ private ContentObserver expectRegisterContentObserver(Uri expectedUri) {
+ final ArgumentCaptor<ContentObserver> captor =
+ ArgumentCaptor.forClass(ContentObserver.class);
+ verify(mDeps).registerContentObserver(any(),
+ argThat(uri -> uri.equals(expectedUri)), anyBoolean(), captor.capture());
+ return captor.getValue();
+ }
+
+ private void buildAndMockPackageInfoWithPermissions(String packageName, int uid,
+ String... permissions) throws Exception {
+ final PackageInfo packageInfo = setPackagePermissions(packageName, uid, permissions);
+ packageInfo.packageName = packageName;
+ packageInfo.applicationInfo.uid = uid;
}
@Test
public void testUidsAllowedOnRestrictedNetworksChanged() throws Exception {
- final NetdMonitor mNetdMonitor = new NetdMonitor(mNetdService);
- final ArgumentCaptor<ContentObserver> captor =
- ArgumentCaptor.forClass(ContentObserver.class);
- verify(mDeps, times(1)).registerContentObserver(any(),
- argThat(uri -> uri.getEncodedPath().contains(UIDS_ALLOWED_ON_RESTRICTED_NETWORKS)),
- anyBoolean(), captor.capture());
- final ContentObserver contentObserver = captor.getValue();
+ final NetdMonitor netdMonitor = new NetdMonitor(mNetdService);
+ final ContentObserver contentObserver = expectRegisterContentObserver(
+ Settings.Global.getUriFor(UIDS_ALLOWED_ON_RESTRICTED_NETWORKS));
mPermissionMonitor.onUserAdded(MOCK_USER1);
- // Prepare PackageInfo for MOCK_PACKAGE1
- final PackageInfo packageInfo = buildPackageInfo(
- false /* hasSystemPermission */, MOCK_UID1, MOCK_USER1);
- packageInfo.packageName = MOCK_PACKAGE1;
- when(mPackageManager.getPackageInfo(eq(MOCK_PACKAGE1), anyInt())).thenReturn(packageInfo);
- when(mPackageManager.getPackagesForUid(MOCK_UID1)).thenReturn(new String[]{MOCK_PACKAGE1});
- // Prepare PackageInfo for MOCK_PACKAGE2
- final PackageInfo packageInfo2 = buildPackageInfo(
- false /* hasSystemPermission */, MOCK_UID2, MOCK_USER1);
- packageInfo2.packageName = MOCK_PACKAGE2;
- when(mPackageManager.getPackageInfo(eq(MOCK_PACKAGE2), anyInt())).thenReturn(packageInfo2);
- when(mPackageManager.getPackagesForUid(MOCK_UID2)).thenReturn(new String[]{MOCK_PACKAGE2});
+ // Prepare PackageInfo for MOCK_PACKAGE1 and MOCK_PACKAGE2
+ buildAndMockPackageInfoWithPermissions(MOCK_PACKAGE1, MOCK_UID1);
+ buildAndMockPackageInfoWithPermissions(MOCK_PACKAGE2, MOCK_UID2);
// MOCK_UID1 is listed in setting that allow to use restricted networks, MOCK_UID1
// should have SYSTEM permission.
when(mDeps.getUidsAllowedOnRestrictedNetworks(any())).thenReturn(
new ArraySet<>(new Integer[] { MOCK_UID1 }));
contentObserver.onChange(true /* selfChange */);
- mNetdMonitor.expectPermission(SYSTEM, new UserHandle[]{MOCK_USER1}, new int[]{MOCK_UID1});
- mNetdMonitor.expectNoPermission(new UserHandle[]{MOCK_USER1}, new int[]{MOCK_UID2});
+ netdMonitor.expectPermission(SYSTEM, new UserHandle[]{MOCK_USER1}, new int[]{MOCK_UID1});
+ netdMonitor.expectNoPermission(new UserHandle[]{MOCK_USER1}, new int[]{MOCK_UID2});
// MOCK_UID2 is listed in setting that allow to use restricted networks, MOCK_UID2
// should have SYSTEM permission but MOCK_UID1 should revoke permission.
when(mDeps.getUidsAllowedOnRestrictedNetworks(any())).thenReturn(
new ArraySet<>(new Integer[] { MOCK_UID2 }));
contentObserver.onChange(true /* selfChange */);
- mNetdMonitor.expectPermission(SYSTEM, new UserHandle[]{MOCK_USER1}, new int[]{MOCK_UID2});
- mNetdMonitor.expectNoPermission(new UserHandle[]{MOCK_USER1}, new int[]{MOCK_UID1});
+ netdMonitor.expectPermission(SYSTEM, new UserHandle[]{MOCK_USER1}, new int[]{MOCK_UID2});
+ netdMonitor.expectNoPermission(new UserHandle[]{MOCK_USER1}, new int[]{MOCK_UID1});
// No uid lists in setting, should revoke permission from all uids.
when(mDeps.getUidsAllowedOnRestrictedNetworks(any())).thenReturn(new ArraySet<>());
contentObserver.onChange(true /* selfChange */);
- mNetdMonitor.expectNoPermission(
+ netdMonitor.expectNoPermission(
new UserHandle[]{MOCK_USER1}, new int[]{MOCK_UID1, MOCK_UID2});
}
@Test
- public void testAppsAllowedOnRestrictedNetworksChangedWithSharedUid() throws Exception {
- final NetdMonitor mNetdMonitor = new NetdMonitor(mNetdService);
- final ArgumentCaptor<ContentObserver> captor =
- ArgumentCaptor.forClass(ContentObserver.class);
- verify(mDeps, times(1)).registerContentObserver(any(),
- argThat(uri -> uri.getEncodedPath().contains(UIDS_ALLOWED_ON_RESTRICTED_NETWORKS)),
- anyBoolean(), captor.capture());
- final ContentObserver contentObserver = captor.getValue();
+ public void testUidsAllowedOnRestrictedNetworksChangedWithSharedUid() throws Exception {
+ final NetdMonitor netdMonitor = new NetdMonitor(mNetdService);
+ final ContentObserver contentObserver = expectRegisterContentObserver(
+ Settings.Global.getUriFor(UIDS_ALLOWED_ON_RESTRICTED_NETWORKS));
mPermissionMonitor.onUserAdded(MOCK_USER1);
- // Prepare PackageInfo for MOCK_PACKAGE1 and MOCK_PACKAGE2 with shared uid MOCK_UID1.
- final PackageInfo packageInfo = systemPackageInfoWithPermissions(CHANGE_NETWORK_STATE);
- packageInfo.applicationInfo.uid = MOCK_USER1.getUid(MOCK_UID1);
- packageInfo.packageName = MOCK_PACKAGE1;
- final PackageInfo packageInfo2 = buildPackageInfo(
- false /* hasSystemPermission */, MOCK_UID1, MOCK_USER1);
- packageInfo2.packageName = MOCK_PACKAGE2;
- when(mPackageManager.getPackageInfo(eq(MOCK_PACKAGE1), anyInt())).thenReturn(packageInfo);
- when(mPackageManager.getPackageInfo(eq(MOCK_PACKAGE2), anyInt())).thenReturn(packageInfo2);
+ buildAndMockPackageInfoWithPermissions(MOCK_PACKAGE1, MOCK_UID1, CHANGE_NETWORK_STATE);
+ buildAndMockPackageInfoWithPermissions(MOCK_PACKAGE2, MOCK_UID1);
when(mPackageManager.getPackagesForUid(MOCK_UID1))
.thenReturn(new String[]{MOCK_PACKAGE1, MOCK_PACKAGE2});
// MOCK_PACKAGE1 have CHANGE_NETWORK_STATE, MOCK_UID1 should have NETWORK permission.
addPackageForUsers(new UserHandle[]{MOCK_USER1}, MOCK_PACKAGE1, MOCK_UID1);
- mNetdMonitor.expectPermission(NETWORK, new UserHandle[]{MOCK_USER1}, new int[]{MOCK_UID1});
+ netdMonitor.expectPermission(NETWORK, new UserHandle[]{MOCK_USER1}, new int[]{MOCK_UID1});
// MOCK_UID1 is listed in setting that allow to use restricted networks, MOCK_UID1
// should upgrade to SYSTEM permission.
when(mDeps.getUidsAllowedOnRestrictedNetworks(any())).thenReturn(
new ArraySet<>(new Integer[] { MOCK_UID1 }));
contentObserver.onChange(true /* selfChange */);
- mNetdMonitor.expectPermission(SYSTEM, new UserHandle[]{MOCK_USER1}, new int[]{MOCK_UID1});
+ netdMonitor.expectPermission(SYSTEM, new UserHandle[]{MOCK_USER1}, new int[]{MOCK_UID1});
// No app lists in setting, MOCK_UID1 should downgrade to NETWORK permission.
when(mDeps.getUidsAllowedOnRestrictedNetworks(any())).thenReturn(new ArraySet<>());
contentObserver.onChange(true /* selfChange */);
- mNetdMonitor.expectPermission(NETWORK, new UserHandle[]{MOCK_USER1}, new int[]{MOCK_UID1});
+ netdMonitor.expectPermission(NETWORK, new UserHandle[]{MOCK_USER1}, new int[]{MOCK_UID1});
// MOCK_PACKAGE1 removed, should revoke permission from MOCK_UID1.
when(mPackageManager.getPackagesForUid(MOCK_UID1)).thenReturn(new String[]{MOCK_PACKAGE2});
removePackageForUsers(new UserHandle[]{MOCK_USER1}, MOCK_PACKAGE1, MOCK_UID1);
- mNetdMonitor.expectNoPermission(new UserHandle[]{MOCK_USER1}, new int[]{MOCK_UID1});
+ netdMonitor.expectNoPermission(new UserHandle[]{MOCK_USER1}, new int[]{MOCK_UID1});
+ }
+
+ @Test
+ public void testUidsAllowedOnRestrictedNetworksChangedWithMultipleUsers() throws Exception {
+ final NetdMonitor netdMonitor = new NetdMonitor(mNetdService);
+ final ContentObserver contentObserver = expectRegisterContentObserver(
+ Settings.Global.getUriFor(UIDS_ALLOWED_ON_RESTRICTED_NETWORKS));
+
+ // One user MOCK_USER1
+ mPermissionMonitor.onUserAdded(MOCK_USER1);
+ // Prepare PackageInfo for MOCK_PACKAGE1 and MOCK_PACKAGE2.
+ buildAndMockPackageInfoWithPermissions(MOCK_PACKAGE1, MOCK_UID1);
+ buildAndMockPackageInfoWithPermissions(MOCK_PACKAGE2, MOCK_UID2);
+
+ // MOCK_UID1 is listed in setting that allow to use restricted networks, MOCK_UID1
+ // in MOCK_USER1 should have SYSTEM permission and MOCK_UID2 has no permissions.
+ when(mDeps.getUidsAllowedOnRestrictedNetworks(any())).thenReturn(
+ new ArraySet<>(new Integer[] { MOCK_UID1 }));
+ contentObserver.onChange(true /* selfChange */);
+ netdMonitor.expectPermission(SYSTEM, new UserHandle[]{MOCK_USER1}, new int[]{MOCK_UID1});
+ netdMonitor.expectNoPermission(new UserHandle[]{MOCK_USER1}, new int[]{MOCK_UID2});
+
+ // Add user MOCK_USER2.
+ mPermissionMonitor.onUserAdded(MOCK_USER2);
+ // MOCK_UID1 in both users should all have SYSTEM permission and MOCK_UID2 has no
+ // permissions in either user.
+ netdMonitor.expectPermission(
+ SYSTEM, new UserHandle[] { MOCK_USER1, MOCK_USER2 }, new int[]{MOCK_UID1});
+ netdMonitor.expectNoPermission(
+ new UserHandle[] { MOCK_USER1, MOCK_USER2 }, new int[]{MOCK_UID2});
+
+ // MOCK_UID2 is listed in setting that allow to use restricted networks, MOCK_UID2
+ // in both users should have SYSTEM permission and MOCK_UID1 has no permissions.
+ when(mDeps.getUidsAllowedOnRestrictedNetworks(any())).thenReturn(
+ new ArraySet<>(new Integer[] { MOCK_UID2 }));
+ contentObserver.onChange(true /* selfChange */);
+ netdMonitor.expectPermission(
+ SYSTEM, new UserHandle[] { MOCK_USER1, MOCK_USER2 }, new int[]{MOCK_UID2});
+ netdMonitor.expectNoPermission(
+ new UserHandle[] { MOCK_USER1, MOCK_USER2 }, new int[]{MOCK_UID1});
+
+ // Remove user MOCK_USER1
+ mPermissionMonitor.onUserRemoved(MOCK_USER1);
+ netdMonitor.expectPermission(SYSTEM, new UserHandle[] {MOCK_USER2}, new int[]{MOCK_UID2});
+ netdMonitor.expectNoPermission(new UserHandle[] {MOCK_USER2}, new int[]{MOCK_UID1});
+
+ // No uid lists in setting, should revoke permission from all uids.
+ when(mDeps.getUidsAllowedOnRestrictedNetworks(any())).thenReturn(new ArraySet<>());
+ contentObserver.onChange(true /* selfChange */);
+ netdMonitor.expectNoPermission(
+ new UserHandle[]{MOCK_USER2}, new int[]{ MOCK_UID1, MOCK_UID2 });
}
}