Merge "Add ContextUtils"
diff --git a/staticlibs/Android.bp b/staticlibs/Android.bp
index 68decf6..0585c09 100644
--- a/staticlibs/Android.bp
+++ b/staticlibs/Android.bp
@@ -70,6 +70,7 @@
"androidx.annotation_annotation",
"framework-annotations-lib",
],
+ lint: { strict_updatability_linting: true },
}
java_defaults {
@@ -83,6 +84,19 @@
],
}
+java_library {
+ name: "net-utils-dnspacket-common",
+ srcs: [
+ "framework/**/DnsPacket.java",
+ "framework/**/DnsPacketUtils.java",
+ ],
+ sdk_version: "module_current",
+ visibility: [
+ "//packages/services/Iwlan:__subpackages__",
+ ],
+ libs: ["framework-annotations-lib"],
+}
+
filegroup {
name: "net-utils-framework-common-srcs",
srcs: ["framework/**/*.java"],
@@ -90,7 +104,6 @@
visibility: [
"//frameworks/base",
"//packages/modules/Connectivity:__subpackages__",
- "//frameworks/base/packages/Connectivity/framework",
],
}
@@ -118,6 +131,7 @@
"com.android.tethering",
"//apex_available:platform",
],
+ lint: { strict_updatability_linting: true },
}
java_library {
@@ -145,6 +159,7 @@
"com.android.tethering",
"//apex_available:platform",
],
+ lint: { strict_updatability_linting: true },
}
java_library {
@@ -169,6 +184,7 @@
"com.android.tethering",
"//apex_available:platform",
],
+ lint: { strict_updatability_linting: true },
}
java_library {
@@ -199,6 +215,7 @@
"com.android.tethering",
"//apex_available:platform",
],
+ lint: { strict_updatability_linting: true },
}
java_library {
@@ -229,6 +246,7 @@
"//frameworks/libs/net/common/device",
"//packages/modules/Wifi/framework/tests:__subpackages__",
],
+ lint: { strict_updatability_linting: true },
}
filegroup {
name: "net-utils-services-common-srcs",
@@ -259,7 +277,9 @@
],
visibility: [
"//frameworks/base/services/net",
+ "//packages/modules/Connectivity/tests:__subpackages__",
],
+ lint: { strict_updatability_linting: true },
}
// Use a filegroup and not a library for telephony sources, as framework-annotations cannot be
@@ -313,3 +333,31 @@
"//packages/modules/Wifi/service",
],
}
+
+// This file group is deprecated; new users should use net-utils-annotations
+filegroup {
+ name: "net-utils-annotations-srcs",
+ srcs: [
+ "annotations/android/net/annotations/PolicyDirection.java",
+ ],
+ visibility: [
+ "//frameworks/base",
+ ],
+}
+
+
+java_library {
+ name: "net-utils-annotations",
+ srcs: [":net-utils-annotations-srcs"],
+ libs: [
+ "framework-annotations-lib",
+ ],
+ sdk_version: "system_current",
+ min_sdk_version: "30",
+ visibility: ["//visibility:public"],
+ apex_available: [
+ "//apex_available:anyapex",
+ "//apex_available:platform",
+ ],
+ lint: { strict_updatability_linting: true },
+}
diff --git a/staticlibs/annotations/android/net/annotations/PolicyDirection.java b/staticlibs/annotations/android/net/annotations/PolicyDirection.java
new file mode 100644
index 0000000..febd9b4
--- /dev/null
+++ b/staticlibs/annotations/android/net/annotations/PolicyDirection.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2019 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 android.net.annotations;
+
+import android.annotation.IntDef;
+import android.net.IpSecManager;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * IPsec traffic direction.
+ *
+ * <p>Mainline modules cannot reference hidden @IntDef. Moving this annotation to a separate class
+ * to allow others to statically include it.
+ *
+ * @hide
+ */
+@IntDef(value = {IpSecManager.DIRECTION_IN, IpSecManager.DIRECTION_OUT})
+@Retention(RetentionPolicy.SOURCE)
+public @interface PolicyDirection {}
diff --git a/staticlibs/framework/com/android/net/module/util/DnsPacket.java b/staticlibs/framework/com/android/net/module/util/DnsPacket.java
index 5ac731c..4c88000 100644
--- a/staticlibs/framework/com/android/net/module/util/DnsPacket.java
+++ b/staticlibs/framework/com/android/net/module/util/DnsPacket.java
@@ -18,12 +18,11 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.text.TextUtils;
+
+import com.android.net.module.util.DnsPacketUtils.DnsRecordParser;
import java.nio.BufferUnderflowException;
import java.nio.ByteBuffer;
-import java.text.DecimalFormat;
-import java.text.FieldPosition;
import java.util.ArrayList;
import java.util.List;
@@ -60,6 +59,11 @@
public final int rcode;
private final int[] mRecordCount;
+ /* If this bit in the 'flags' field is set to 0, the DNS message corresponding to this
+ * header is a query; otherwise, it is a response.
+ */
+ private static final int FLAGS_SECTION_QR_BIT = 15;
+
/**
* Create a new DnsHeader from a positioned ByteBuffer.
*
@@ -80,6 +84,14 @@
}
/**
+ * Determines if the DNS message corresponding to this header is a response, as defined in
+ * RFC 1035 Section 4.1.1.
+ */
+ public boolean isResponse() {
+ return (flags & (1 << FLAGS_SECTION_QR_BIT)) != 0;
+ }
+
+ /**
* Get record count by type.
*/
public int getRecordCount(int type) {
@@ -95,12 +107,8 @@
*/
public class DnsRecord {
private static final int MAXNAMESIZE = 255;
- private static final int MAXLABELSIZE = 63;
- private static final int MAXLABELCOUNT = 128;
public static final int NAME_NORMAL = 0;
public static final int NAME_COMPRESSION = 0xC0;
- private final DecimalFormat mByteFormat = new DecimalFormat();
- private final FieldPosition mPos = new FieldPosition(0);
private static final String TAG = "DnsRecord";
@@ -118,12 +126,12 @@
* advanced to the end of the DNS header record.
* This is meant to chain with other methods reading a DNS response in sequence.
*
- * @param ByteBuffer input of record, must be in network byte order
+ * @param buf ByteBuffer input of record, must be in network byte order
* (which is the default).
*/
DnsRecord(int recordType, @NonNull ByteBuffer buf)
throws BufferUnderflowException, ParseException {
- dName = parseName(buf, 0 /* Parse depth */);
+ dName = DnsRecordParser.parseName(buf, 0 /* Parse depth */);
if (dName.length() > MAXNAMESIZE) {
throw new ParseException(
"Parse name fail, name size is too long: " + dName.length());
@@ -150,66 +158,6 @@
return (mRdata == null) ? null : mRdata.clone();
}
- /**
- * Convert label from {@code byte[]} to {@code String}
- *
- * Follows the same conversion rules of the native code (ns_name.c in libc)
- */
- private String labelToString(@NonNull byte[] label) {
- final StringBuffer sb = new StringBuffer();
- for (int i = 0; i < label.length; ++i) {
- int b = Byte.toUnsignedInt(label[i]);
- // Control characters and non-ASCII characters.
- if (b <= 0x20 || b >= 0x7f) {
- // Append the byte as an escaped decimal number, e.g., "\19" for 0x13.
- sb.append('\\');
- mByteFormat.format(b, sb, mPos);
- } else if (b == '"' || b == '.' || b == ';' || b == '\\'
- || b == '(' || b == ')' || b == '@' || b == '$') {
- // Append the byte as an escaped character, e.g., "\:" for 0x3a.
- sb.append('\\');
- sb.append((char) b);
- } else {
- // Append the byte as a character, e.g., "a" for 0x61.
- sb.append((char) b);
- }
- }
- return sb.toString();
- }
-
- private String parseName(@NonNull ByteBuffer buf, int depth) throws
- BufferUnderflowException, ParseException {
- if (depth > MAXLABELCOUNT) {
- throw new ParseException("Failed to parse name, too many labels");
- }
- final int len = Byte.toUnsignedInt(buf.get());
- final int mask = len & NAME_COMPRESSION;
- if (0 == len) {
- return "";
- } else if (mask != NAME_NORMAL && mask != NAME_COMPRESSION) {
- throw new ParseException("Parse name fail, bad label type");
- } else if (mask == NAME_COMPRESSION) {
- // Name compression based on RFC 1035 - 4.1.4 Message compression
- final int offset = ((len & ~NAME_COMPRESSION) << 8) + Byte.toUnsignedInt(buf.get());
- final int oldPos = buf.position();
- if (offset >= oldPos - 2) {
- throw new ParseException("Parse compression name fail, invalid compression");
- }
- buf.position(offset);
- final String pointed = parseName(buf, depth + 1);
- buf.position(oldPos);
- return pointed;
- } else {
- final byte[] label = new byte[len];
- buf.get(label);
- final String head = labelToString(label);
- if (head.length() > MAXLABELSIZE) {
- throw new ParseException("Parse name fail, invalid label length");
- }
- final String tail = parseName(buf, depth + 1);
- return TextUtils.isEmpty(tail) ? head : head + "." + tail;
- }
- }
}
public static final int QDSECTION = 0;
@@ -224,7 +172,10 @@
protected final List<DnsRecord>[] mRecords;
protected DnsPacket(@NonNull byte[] data) throws ParseException {
- if (null == data) throw new ParseException("Parse header failed, null input data");
+ if (null == data) {
+ throw new ParseException("Parse header failed, null input data");
+ }
+
final ByteBuffer buffer;
try {
buffer = ByteBuffer.wrap(data);
diff --git a/staticlibs/framework/com/android/net/module/util/DnsPacketUtils.java b/staticlibs/framework/com/android/net/module/util/DnsPacketUtils.java
new file mode 100644
index 0000000..677474c
--- /dev/null
+++ b/staticlibs/framework/com/android/net/module/util/DnsPacketUtils.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2019 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.net.module.util;
+
+import static com.android.net.module.util.DnsPacket.DnsRecord.NAME_COMPRESSION;
+import static com.android.net.module.util.DnsPacket.DnsRecord.NAME_NORMAL;
+
+import android.annotation.NonNull;
+import android.text.TextUtils;
+
+import java.nio.BufferUnderflowException;
+import java.nio.ByteBuffer;
+import java.text.DecimalFormat;
+import java.text.FieldPosition;
+
+/**
+ * Utilities for decoding the contents of a DnsPacket.
+ *
+ * @hide
+ */
+public final class DnsPacketUtils {
+ /**
+ * Reads the passed ByteBuffer from its current position and decodes a DNS record.
+ */
+ public static class DnsRecordParser {
+ private static final int MAXLABELSIZE = 63;
+ private static final int MAXLABELCOUNT = 128;
+
+ private static final DecimalFormat sByteFormat = new DecimalFormat();
+ private static final FieldPosition sPos = new FieldPosition(0);
+
+ /**
+ * Convert label from {@code byte[]} to {@code String}
+ *
+ * <p>Follows the same conversion rules of the native code (ns_name.c in libc).
+ */
+ private static String labelToString(@NonNull byte[] label) {
+ final StringBuffer sb = new StringBuffer();
+
+ for (int i = 0; i < label.length; ++i) {
+ int b = Byte.toUnsignedInt(label[i]);
+ // Control characters and non-ASCII characters.
+ if (b <= 0x20 || b >= 0x7f) {
+ // Append the byte as an escaped decimal number, e.g., "\19" for 0x13.
+ sb.append('\\');
+ sByteFormat.format(b, sb, sPos);
+ } else if (b == '"' || b == '.' || b == ';' || b == '\\' || b == '(' || b == ')'
+ || b == '@' || b == '$') {
+ // Append the byte as an escaped character, e.g., "\:" for 0x3a.
+ sb.append('\\');
+ sb.append((char) b);
+ } else {
+ // Append the byte as a character, e.g., "a" for 0x61.
+ sb.append((char) b);
+ }
+ }
+ return sb.toString();
+ }
+
+ /**
+ * Parses the domain / target name of a DNS record.
+ */
+ public static String parseName(ByteBuffer buf, int depth) throws
+ BufferUnderflowException, DnsPacket.ParseException {
+ if (depth > MAXLABELCOUNT) {
+ throw new DnsPacket.ParseException("Failed to parse name, too many labels");
+ }
+ final int len = Byte.toUnsignedInt(buf.get());
+ final int mask = len & NAME_COMPRESSION;
+ if (0 == len) {
+ return "";
+ } else if (mask != NAME_NORMAL && mask != NAME_COMPRESSION) {
+ throw new DnsPacket.ParseException("Parse name fail, bad label type: " + mask);
+ } else if (mask == NAME_COMPRESSION) {
+ // Name compression based on RFC 1035 - 4.1.4 Message compression
+ final int offset = ((len & ~NAME_COMPRESSION) << 8) + Byte.toUnsignedInt(buf.get());
+ final int oldPos = buf.position();
+ if (offset >= oldPos - 2) {
+ throw new DnsPacket.ParseException(
+ "Parse compression name fail, invalid compression");
+ }
+ buf.position(offset);
+ final String pointed = parseName(buf, depth + 1);
+ buf.position(oldPos);
+ return pointed;
+ } else {
+ final byte[] label = new byte[len];
+ buf.get(label);
+ final String head = labelToString(label);
+ if (head.length() > MAXLABELSIZE) {
+ throw new DnsPacket.ParseException("Parse name fail, invalid label length");
+ }
+ final String tail = parseName(buf, depth + 1);
+ return TextUtils.isEmpty(tail) ? head : head + "." + tail;
+ }
+ }
+
+ private DnsRecordParser() {}
+ }
+
+ private DnsPacketUtils() {}
+}
diff --git a/staticlibs/native/OWNERS b/staticlibs/native/OWNERS
deleted file mode 100644
index 7655338..0000000
--- a/staticlibs/native/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-maze@google.com
diff --git a/staticlibs/tests/unit/Android.bp b/staticlibs/tests/unit/Android.bp
index 07a8200..21e8c64 100644
--- a/staticlibs/tests/unit/Android.bp
+++ b/staticlibs/tests/unit/Android.bp
@@ -30,7 +30,8 @@
"//packages/modules/Connectivity/tests:__subpackages__",
"//packages/modules/Connectivity/Tethering/tests:__subpackages__",
"//packages/modules/NetworkStack/tests/integration",
- ]
+ ],
+ lint: { strict_updatability_linting: true },
}
android_test {
@@ -46,4 +47,5 @@
],
jarjar_rules: "jarjar-rules.txt",
test_suites: ["device-tests"],
+ lint: { strict_updatability_linting: true },
}
diff --git a/staticlibs/tests/unit/lint-baseline.xml b/staticlibs/tests/unit/lint-baseline.xml
deleted file mode 100644
index e3a6c1e..0000000
--- a/staticlibs/tests/unit/lint-baseline.xml
+++ /dev/null
@@ -1,48 +0,0 @@
-<?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 R (current min is 29): `android.app.AppOpsManager#noteOp`"
- errorLine1=" when(mMockAppOps.noteOp(AppOpsManager.OPSTR_WIFI_SCAN, mUid, TEST_PKG_NAME,"
- errorLine2=" ~~~~~~">
- <location
- file="frameworks/libs/net/common/tests/unit/src/com/android/net/module/util/LocationPermissionCheckerTest.java"
- line="109"
- column="26"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level R (current min is 29): `android.app.AppOpsManager#noteOp`"
- errorLine1=" when(mMockAppOps.noteOp(eq(AppOpsManager.OPSTR_COARSE_LOCATION), eq(mUid),"
- errorLine2=" ~~~~~~">
- <location
- file="frameworks/libs/net/common/tests/unit/src/com/android/net/module/util/LocationPermissionCheckerTest.java"
- line="111"
- column="26"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level R (current min is 29): `android.app.AppOpsManager#noteOp`"
- errorLine1=" when(mMockAppOps.noteOp(eq(AppOpsManager.OPSTR_FINE_LOCATION), eq(mUid),"
- errorLine2=" ~~~~~~">
- <location
- file="frameworks/libs/net/common/tests/unit/src/com/android/net/module/util/LocationPermissionCheckerTest.java"
- line="114"
- column="26"/>
- </issue>
-
- <issue
- id="NewApi"
- message="Call requires API level R (current min is 29): `android.net.NetworkCapabilities()`"
- errorLine1=" val nc = NetworkCapabilities()"
- errorLine2=" ~~~~~~~~~~~~~~~~~~~~~">
- <location
- file="frameworks/libs/net/common/tests/unit/src/com/android/net/module/util/NetworkCapabilitiesUtilsTest.kt"
- line="93"
- column="18"/>
- </issue>
-
-</issues>
diff --git a/staticlibs/tests/unit/src/com/android/net/module/util/CleanupTest.kt b/staticlibs/tests/unit/src/com/android/net/module/util/CleanupTest.kt
index f4a7d10..0067931 100644
--- a/staticlibs/tests/unit/src/com/android/net/module/util/CleanupTest.kt
+++ b/staticlibs/tests/unit/src/com/android/net/module/util/CleanupTest.kt
@@ -18,13 +18,15 @@
import android.util.Log
import com.android.testutils.tryTest
-import kotlin.test.assertFailsWith
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
+import kotlin.test.assertEquals
+import kotlin.test.assertFailsWith
+import kotlin.test.assertTrue
import kotlin.test.fail
-private val TAG = CleanupTest::class.toString()
+private val TAG = CleanupTest::class.simpleName
@RunWith(JUnit4::class)
class CleanupTest {
@@ -34,69 +36,140 @@
@Test
fun testNotThrow() {
var x = 1
- tryTest {
+ val result = tryTest {
x = 2
Log.e(TAG, "Do nothing")
+ 6
} cleanup {
- assert(x == 2)
+ assertTrue(x == 2)
x = 3
Log.e(TAG, "Do nothing")
}
- assert(x == 3)
+ assertTrue(x == 3)
+ assertTrue(result == 6)
}
@Test
fun testThrowTry() {
var x = 1
- assertFailsWith<TestException1> {
+ val thrown = assertFailsWith<TestException1> {
tryTest {
x = 2
throw TestException1()
x = 4
} cleanup {
- assert(x == 2)
+ assertTrue(x == 2)
x = 3
Log.e(TAG, "Do nothing")
}
}
- assert(x == 3)
+ assertTrue(thrown.suppressedExceptions.isEmpty())
+ assertTrue(x == 3)
}
@Test
fun testThrowCleanup() {
var x = 1
- assertFailsWith<TestException2> {
+ val thrown = assertFailsWith<TestException2> {
tryTest {
x = 2
Log.e(TAG, "Do nothing")
} cleanup {
- assert(x == 2)
+ assertTrue(x == 2)
x = 3
throw TestException2()
x = 4
}
}
- assert(x == 3)
+ assertTrue(thrown.suppressedExceptions.isEmpty())
+ assertTrue(x == 3)
}
@Test
fun testThrowBoth() {
var x = 1
- try {
+ val thrown = assertFailsWith<TestException1> {
tryTest {
x = 2
throw TestException1()
x = 3
} cleanup {
- assert(x == 2)
+ assertTrue(x == 2)
x = 4
throw TestException2()
x = 5
}
- fail("Expected failure with TestException1")
- } catch (e: TestException1) {
- assert(e.suppressedExceptions[0] is TestException2)
}
- assert(x == 4)
+ assertTrue(thrown.suppressedExceptions[0] is TestException2)
+ assertTrue(x == 4)
+ }
+
+ @Test
+ fun testReturn() {
+ val resultIfSuccess = 11
+ val resultIfException = 12
+ fun doTestReturn(crash: Boolean) = tryTest {
+ if (crash) throw RuntimeException() else resultIfSuccess
+ }.catch<RuntimeException> {
+ resultIfException
+ } cleanup {}
+
+ assertTrue(6 == tryTest { 6 } cleanup { Log.e(TAG, "tested") })
+ assertEquals(resultIfSuccess, doTestReturn(crash = false))
+ assertEquals(resultIfException, doTestReturn(crash = true))
+ }
+
+ @Test
+ fun testCatch() {
+ var x = 1
+ tryTest {
+ x = 2
+ throw TestException1()
+ x = 3
+ }.catch<TestException1> {
+ x = 4
+ }.catch<TestException2> {
+ x = 5
+ } cleanup {
+ assertTrue(x == 4)
+ x = 6
+ }
+ assertTrue(x == 6)
+ }
+
+ @Test
+ fun testNotCatch() {
+ var x = 1
+ assertFailsWith<TestException1> {
+ tryTest {
+ x = 2
+ throw TestException1()
+ }.catch<TestException2> {
+ fail("Caught TestException2 instead of TestException1")
+ } cleanup {
+ assertTrue(x == 2)
+ x = 3
+ }
+ }
+ assertTrue(x == 3)
+ }
+
+ @Test
+ fun testThrowInCatch() {
+ var x = 1
+ val thrown = assertFailsWith<TestException2> {
+ tryTest {
+ x = 2
+ throw TestException1()
+ }.catch<TestException1> {
+ x = 3
+ throw TestException2()
+ } cleanup {
+ assertTrue(x == 3)
+ x = 4
+ }
+ }
+ assertTrue(x == 4)
+ assertTrue(thrown.suppressedExceptions.isEmpty())
}
}
diff --git a/staticlibs/tests/unit/src/com/android/net/module/util/CleanupTestJava.java b/staticlibs/tests/unit/src/com/android/net/module/util/CleanupTestJava.java
index ba4e679..83abfa1 100644
--- a/staticlibs/tests/unit/src/com/android/net/module/util/CleanupTestJava.java
+++ b/staticlibs/tests/unit/src/com/android/net/module/util/CleanupTestJava.java
@@ -35,14 +35,16 @@
@Test
public void testNotThrow() {
final AtomicInteger x = new AtomicInteger(1);
- testAndCleanup(() -> {
+ final int a = testAndCleanup(() -> {
x.compareAndSet(1, 2);
Log.e(TAG, "Do nothing");
+ return 6;
}, () -> {
x.compareAndSet(2, 3);
Log.e(TAG, "Do nothing");
});
assertEquals(3, x.get());
+ assertEquals(6, a);
}
@Test
diff --git a/staticlibs/tests/unit/src/com/android/module/util/DnsPacketTest.java b/staticlibs/tests/unit/src/com/android/net/module/util/DnsPacketTest.java
similarity index 100%
rename from staticlibs/tests/unit/src/com/android/module/util/DnsPacketTest.java
rename to staticlibs/tests/unit/src/com/android/net/module/util/DnsPacketTest.java
diff --git a/staticlibs/tests/unit/src/android/net/util/IpRangeTest.java b/staticlibs/tests/unit/src/com/android/net/module/util/IpRangeTest.java
similarity index 98%
rename from staticlibs/tests/unit/src/android/net/util/IpRangeTest.java
rename to staticlibs/tests/unit/src/com/android/net/module/util/IpRangeTest.java
index 677db69..f44b17d 100644
--- a/staticlibs/tests/unit/src/android/net/util/IpRangeTest.java
+++ b/staticlibs/tests/unit/src/com/android/net/module/util/IpRangeTest.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.net.util;
+package com.android.net.module.util;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -28,8 +28,6 @@
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
-import com.android.net.module.util.IpRange;
-
import org.junit.Test;
import org.junit.runner.RunWith;
diff --git a/staticlibs/tests/unit/src/android/net/util/LinkPropertiesUtilsTest.java b/staticlibs/tests/unit/src/com/android/net/module/util/LinkPropertiesUtilsTest.java
similarity index 99%
rename from staticlibs/tests/unit/src/android/net/util/LinkPropertiesUtilsTest.java
rename to staticlibs/tests/unit/src/com/android/net/module/util/LinkPropertiesUtilsTest.java
index 45493bd..3d2d6eb 100644
--- a/staticlibs/tests/unit/src/android/net/util/LinkPropertiesUtilsTest.java
+++ b/staticlibs/tests/unit/src/com/android/net/module/util/LinkPropertiesUtilsTest.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.net.util;
+package com.android.net.module.util;
import static com.android.testutils.MiscAsserts.assertSameElements;
@@ -32,7 +32,6 @@
import androidx.test.runner.AndroidJUnit4;
-import com.android.net.module.util.LinkPropertiesUtils;
import com.android.net.module.util.LinkPropertiesUtils.CompareOrUpdateResult;
import com.android.net.module.util.LinkPropertiesUtils.CompareResult;
diff --git a/staticlibs/tests/unit/src/com/android/net/module/util/LocationPermissionCheckerTest.java b/staticlibs/tests/unit/src/com/android/net/module/util/LocationPermissionCheckerTest.java
index 3fb1e92..84018a5 100644
--- a/staticlibs/tests/unit/src/com/android/net/module/util/LocationPermissionCheckerTest.java
+++ b/staticlibs/tests/unit/src/com/android/net/module/util/LocationPermissionCheckerTest.java
@@ -42,6 +42,8 @@
import android.os.UserHandle;
import android.os.UserManager;
+import androidx.annotation.RequiresApi;
+
import com.android.testutils.DevSdkIgnoreRule;
import org.junit.Assert;
@@ -56,6 +58,7 @@
import java.util.HashMap;
/** Unit tests for {@link LocationPermissionChecker}. */
+@RequiresApi(Build.VERSION_CODES.R)
public class LocationPermissionCheckerTest {
@Rule
public final DevSdkIgnoreRule mIgnoreRule = new DevSdkIgnoreRule(
diff --git a/staticlibs/tests/unit/src/android/net/util/MacAddressUtilsTest.java b/staticlibs/tests/unit/src/com/android/net/module/util/MacAddressUtilsTest.java
similarity index 96%
rename from staticlibs/tests/unit/src/android/net/util/MacAddressUtilsTest.java
rename to staticlibs/tests/unit/src/com/android/net/module/util/MacAddressUtilsTest.java
index 8988571..2550756 100644
--- a/staticlibs/tests/unit/src/android/net/util/MacAddressUtilsTest.java
+++ b/staticlibs/tests/unit/src/com/android/net/module/util/MacAddressUtilsTest.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.net.util;
+package com.android.net.module.util;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -24,8 +24,6 @@
import androidx.test.runner.AndroidJUnit4;
-import com.android.net.module.util.MacAddressUtils;
-
import org.junit.Test;
import org.junit.runner.RunWith;
diff --git a/staticlibs/tests/unit/src/android/net/util/NetUtilsTest.java b/staticlibs/tests/unit/src/com/android/net/module/util/NetUtilsTest.java
similarity index 97%
rename from staticlibs/tests/unit/src/android/net/util/NetUtilsTest.java
rename to staticlibs/tests/unit/src/com/android/net/module/util/NetUtilsTest.java
index d523e14..902c18e 100644
--- a/staticlibs/tests/unit/src/android/net/util/NetUtilsTest.java
+++ b/staticlibs/tests/unit/src/com/android/net/module/util/NetUtilsTest.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.net.util;
+package com.android.net.module.util;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -27,8 +27,6 @@
import androidx.test.runner.AndroidJUnit4;
-import com.android.net.module.util.NetUtils;
-
import org.junit.Test;
import org.junit.runner.RunWith;
diff --git a/staticlibs/tests/unit/src/com/android/net/module/util/NetworkCapabilitiesUtilsTest.kt b/staticlibs/tests/unit/src/com/android/net/module/util/NetworkCapabilitiesUtilsTest.kt
index 5f15c6a..f78c74e 100644
--- a/staticlibs/tests/unit/src/com/android/net/module/util/NetworkCapabilitiesUtilsTest.kt
+++ b/staticlibs/tests/unit/src/com/android/net/module/util/NetworkCapabilitiesUtilsTest.kt
@@ -16,6 +16,7 @@
package com.android.net.module.util
+import android.annotation.TargetApi
import android.net.NetworkCapabilities
import android.net.NetworkCapabilities.NET_CAPABILITY_CBS
import android.net.NetworkCapabilities.NET_CAPABILITY_EIMS
@@ -29,6 +30,7 @@
import android.net.NetworkCapabilities.TRANSPORT_VPN
import android.net.NetworkCapabilities.TRANSPORT_WIFI
import android.net.NetworkCapabilities.TRANSPORT_WIFI_AWARE
+import android.os.Build
import androidx.test.filters.SmallTest
import androidx.test.runner.AndroidJUnit4
import com.android.net.module.util.NetworkCapabilitiesUtils.RESTRICTED_CAPABILITIES
@@ -88,7 +90,9 @@
assertTrue(bits contentEquals unpackBits(packedBits))
}
- @Test
+ // NetworkCapabilities constructor and Builder are not available until R. Mark TargetApi to
+ // ignore the linter error since it's used in only unit test.
+ @Test @TargetApi(Build.VERSION_CODES.R)
fun testInferRestrictedCapability() {
val nc = NetworkCapabilities()
// Default capabilities don't have restricted capability.
diff --git a/staticlibs/testutils/Android.bp b/staticlibs/testutils/Android.bp
index 9fd30f7..1be64c1 100644
--- a/staticlibs/testutils/Android.bp
+++ b/staticlibs/testutils/Android.bp
@@ -38,28 +38,38 @@
"net-utils-device-common-netlink",
"modules-utils-build_system",
],
+ lint: { strict_updatability_linting: true },
}
java_library {
- // Consider using net-tests-utils instead if writing device code.
- // That library has a lot more useful tools into it for users that
- // work on Android and includes this lib.
- name: "net-tests-utils-host-device-common",
- srcs: [
- "hostdevice/**/*.java",
- "hostdevice/**/*.kt",
- ],
- host_supported: true,
- visibility: [
- "//frameworks/libs/net/common/tests:__subpackages__",
- "//frameworks/libs/net/client-libs/tests:__subpackages__",
- ],
- libs: [
- "jsr305",
- ],
- static_libs: [
- "kotlin-test"
- ]
+ // Consider using net-tests-utils instead if writing device code.
+ // That library has a lot more useful tools into it for users that
+ // work on Android and includes this lib.
+ name: "net-tests-utils-host-device-common",
+ srcs: [
+ "hostdevice/**/*.java",
+ "hostdevice/**/*.kt",
+ ],
+ host_supported: true,
+ visibility: [
+ "//frameworks/libs/net/common/tests:__subpackages__",
+ "//frameworks/libs/net/client-libs/tests:__subpackages__",
+ ],
+ // There are downstream branches using an old version of Kotlin
+ // that used to reserve the right to make breaking changes to the
+ // Result type and disallowed returning an instance of it.
+ // Later versions allowed this and there was never a change,
+ // so no matter the version returning Result is always fine,
+ // but on sc-mainline-prod the compiler rejects it without
+ // the following flag.
+ kotlincflags: ["-Xallow-result-return-type"],
+ libs: [
+ "jsr305",
+ ],
+ static_libs: [
+ "kotlin-test"
+ ],
+ lint: { strict_updatability_linting: true },
}
java_test_host {
diff --git a/staticlibs/testutils/app/connectivitychecker/Android.bp b/staticlibs/testutils/app/connectivitychecker/Android.bp
index 79a4343..58f22db 100644
--- a/staticlibs/testutils/app/connectivitychecker/Android.bp
+++ b/staticlibs/testutils/app/connectivitychecker/Android.bp
@@ -30,4 +30,5 @@
"net-tests-utils",
],
host_required: ["net-tests-utils-host-common"],
+ lint: { strict_updatability_linting: true },
}
diff --git a/staticlibs/testutils/hostdevice/com/android/testutils/Cleanup.kt b/staticlibs/testutils/hostdevice/com/android/testutils/Cleanup.kt
index 769d980..1b67f68 100644
--- a/staticlibs/testutils/hostdevice/com/android/testutils/Cleanup.kt
+++ b/staticlibs/testutils/hostdevice/com/android/testutils/Cleanup.kt
@@ -19,8 +19,17 @@
package com.android.testutils
import com.android.testutils.ExceptionUtils.ThrowingRunnable
+import com.android.testutils.ExceptionUtils.ThrowingSupplier
import javax.annotation.CheckReturnValue
+@CheckReturnValue
+fun <T> tryTest(block: () -> T) = TryExpr(
+ try {
+ Result.success(block())
+ } catch (e: Throwable) {
+ Result.failure(e)
+ })
+
/**
* Utility to do cleanup in tests without replacing exceptions with those from a finally block.
*
@@ -51,6 +60,12 @@
* } cleanup {
* cleanup code
* }
+ * Catch blocks can be added with the following syntax :
+ * tryTest {
+ * testing code
+ * }.catch<ExceptionType> { it ->
+ * do something to it
+ * }
*
* Java doesn't allow this kind of syntax, so instead a function taking 2 lambdas is provided.
* testAndCleanup(() -> {
@@ -59,12 +74,26 @@
* cleanup code
* });
*/
-class ExceptionCleanupBlock(val originalException: Exception?) {
- inline infix fun cleanup(block: () -> Unit) {
+
+// Some downstream branches have an older kotlin that doesn't know about value classes.
+// TODO : Change this to "value class" when aosp no longer merges into such branches.
+@Suppress("INLINE_CLASS_DEPRECATED")
+inline class TryExpr<T>(val result: Result<T>) {
+ inline infix fun <reified E : Throwable> catch(block: (E) -> T): TryExpr<T> {
+ val originalException = result.exceptionOrNull()
+ if (originalException !is E) return this
+ return TryExpr(try {
+ Result.success(block(originalException))
+ } catch (e: Exception) {
+ Result.failure(e)
+ })
+ }
+
+ inline infix fun cleanup(block: () -> Unit): T {
try {
block()
- if (null != originalException) throw originalException
- } catch (e: Exception) {
+ } catch (e: Throwable) {
+ val originalException = result.exceptionOrNull()
if (null == originalException) {
throw e
} else {
@@ -72,24 +101,18 @@
throw originalException
}
}
+ return result.getOrThrow()
}
}
-@CheckReturnValue
-inline fun tryTest(block: () -> Unit): ExceptionCleanupBlock {
- try {
- block()
- } catch (e: Exception) {
- return ExceptionCleanupBlock(e)
- }
- return ExceptionCleanupBlock(null)
-}
-
// Java support
-fun testAndCleanup(tryBlock: ThrowingRunnable, cleanupBlock: ThrowingRunnable) {
- tryTest {
- tryBlock.run()
+fun <T> testAndCleanup(tryBlock: ThrowingSupplier<T>, cleanupBlock: ThrowingRunnable): T {
+ return tryTest {
+ tryBlock.get()
} cleanup {
cleanupBlock.run()
}
}
+fun testAndCleanup(tryBlock: ThrowingRunnable, cleanupBlock: ThrowingRunnable) {
+ return testAndCleanup(ThrowingSupplier { tryBlock.run() }, cleanupBlock)
+}