summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-09-08 13:51:27 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-09-08 13:51:27 +0000
commit4040c179ebe4248b19e9a52b21a268c67154ab64 (patch)
treec8faaef4211326b843bf0fa8cb3fa63cf5fd1ae2
parent92e0137a95c459b7319bc3d94f8b6f1b86a61176 (diff)
parente5a18b52cafa9dfa25a2b06e8c200628e34005c7 (diff)
downloadnet-android13-mainline-go-sdkext-release.tar.gz
Snap for 8756029 from e5a18b52cafa9dfa25a2b06e8c200628e34005c7 to mainline-go-sdkext-releaseaml_go_sdk_330810000android13-mainline-go-sdkext-release
Change-Id: Idf14605a2a4b8e6f1c2c01d6005aa521dcd87514
-rw-r--r--common/Android.bp4
-rw-r--r--common/device/com/android/net/module/util/BpfDump.java49
-rw-r--r--common/device/com/android/net/module/util/bpf/ClatEgress4Key.java37
-rw-r--r--common/device/com/android/net/module/util/bpf/ClatEgress4Value.java46
-rw-r--r--common/device/com/android/net/module/util/bpf/ClatIngress6Key.java41
-rw-r--r--common/device/com/android/net/module/util/bpf/ClatIngress6Value.java37
-rw-r--r--common/device/com/android/net/module/util/bpf/Tether4Key.java81
-rw-r--r--common/device/com/android/net/module/util/bpf/Tether4Value.java97
-rw-r--r--common/device/com/android/net/module/util/bpf/TetherStatsKey.java53
-rw-r--r--common/device/com/android/net/module/util/bpf/TetherStatsValue.java80
-rw-r--r--common/device/com/android/net/module/util/ip/IpNeighborMonitor.java23
-rw-r--r--common/framework/com/android/net/module/util/LocationPermissionChecker.java3
-rw-r--r--common/native/bpf_headers/include/bpf/BpfMap.h32
-rw-r--r--common/native/bpf_headers/include/bpf/bpf_helpers.h50
-rw-r--r--common/native/bpf_syscall_wrappers/include/BpfSyscallWrappers.h8
-rw-r--r--common/native/netjniutils/Android.bp3
-rw-r--r--common/native/netjniutils/netjniutils.cpp25
-rw-r--r--common/netd/libnetdutils/include/netdutils/NetNativeTestBase.h46
-rw-r--r--common/tests/unit/src/com/android/net/module/util/BpfDumpTest.java43
-rw-r--r--common/tests/unit/src/com/android/net/module/util/SharedLogTest.java58
-rw-r--r--common/testutils/devicetests/com/android/testutils/ContextUtils.kt12
-rw-r--r--common/testutils/devicetests/com/android/testutils/TestPermissionUtil.kt18
22 files changed, 541 insertions, 305 deletions
diff --git a/common/Android.bp b/common/Android.bp
index d13f9387..31a72625 100644
--- a/common/Android.bp
+++ b/common/Android.bp
@@ -111,7 +111,6 @@ java_library {
name: "net-utils-device-common-bpf",
srcs: [
"device/com/android/net/module/util/BpfBitmap.java",
- "device/com/android/net/module/util/BpfDump.java",
"device/com/android/net/module/util/BpfMap.java",
"device/com/android/net/module/util/BpfUtils.java",
"device/com/android/net/module/util/HexDump.java",
@@ -119,6 +118,7 @@ java_library {
"device/com/android/net/module/util/JniUtil.java",
"device/com/android/net/module/util/Struct.java",
"device/com/android/net/module/util/TcUtils.java",
+ "device/com/android/net/module/util/bpf/*.java",
],
sdk_version: "module_current",
min_sdk_version: "29",
@@ -232,9 +232,7 @@ java_library {
":net-utils-framework-common-srcs",
],
sdk_version: "module_current",
- min_sdk_version: "29",
libs: [
- "androidx.annotation_annotation",
"framework-annotations-lib",
"framework-connectivity.stubs.module_lib",
"framework-connectivity-t.stubs.module_lib",
diff --git a/common/device/com/android/net/module/util/BpfDump.java b/common/device/com/android/net/module/util/BpfDump.java
deleted file mode 100644
index fec225c1..00000000
--- a/common/device/com/android/net/module/util/BpfDump.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2022 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 android.util.Base64;
-
-import androidx.annotation.NonNull;
-
-/**
- * The classes and the methods for BPF dump utilization.
- */
-public class BpfDump {
- // Using "," as a separator between base64 encoded key and value is safe because base64
- // characters are [0-9a-zA-Z/=+].
- public static final String BASE64_DELIMITER = ",";
-
- /**
- * Encode BPF key and value into a base64 format string which uses the delimiter ',':
- * <base64 encoded key>,<base64 encoded value>
- */
- public static <K extends Struct, V extends Struct> String toBase64EncodedString(
- @NonNull final K key, @NonNull final V value) {
- final byte[] keyBytes = key.writeToBytes();
- final String keyBase64Str = Base64.encodeToString(keyBytes, Base64.DEFAULT)
- .replace("\n", "");
- final byte[] valueBytes = value.writeToBytes();
- final String valueBase64Str = Base64.encodeToString(valueBytes, Base64.DEFAULT)
- .replace("\n", "");
-
- return keyBase64Str + BASE64_DELIMITER + valueBase64Str;
- }
-
- // TODO: add a helper to dump bpf map content with the map name, the header line
- // (ex: "BPF ingress map: iif nat64Prefix v6Addr -> v4Addr oif"), a lambda that
- // knows how to dump each line, and the PrintWriter.
-}
diff --git a/common/device/com/android/net/module/util/bpf/ClatEgress4Key.java b/common/device/com/android/net/module/util/bpf/ClatEgress4Key.java
new file mode 100644
index 00000000..12200ec6
--- /dev/null
+++ b/common/device/com/android/net/module/util/bpf/ClatEgress4Key.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2022 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.bpf;
+
+import com.android.net.module.util.Struct;
+import com.android.net.module.util.Struct.Field;
+import com.android.net.module.util.Struct.Type;
+
+import java.net.Inet4Address;
+
+/** Key type for clat egress IPv4 maps. */
+public class ClatEgress4Key extends Struct {
+ @Field(order = 0, type = Type.U32)
+ public final long iif; // The input interface index
+
+ @Field(order = 1, type = Type.Ipv4Address)
+ public final Inet4Address local4; // The source IPv4 address
+
+ public ClatEgress4Key(final long iif, final Inet4Address local4) {
+ this.iif = iif;
+ this.local4 = local4;
+ }
+}
diff --git a/common/device/com/android/net/module/util/bpf/ClatEgress4Value.java b/common/device/com/android/net/module/util/bpf/ClatEgress4Value.java
new file mode 100644
index 00000000..c10cb4da
--- /dev/null
+++ b/common/device/com/android/net/module/util/bpf/ClatEgress4Value.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2022 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.bpf;
+
+import com.android.net.module.util.Struct;
+import com.android.net.module.util.Struct.Field;
+import com.android.net.module.util.Struct.Type;
+
+import java.net.Inet6Address;
+
+/** Value type for clat egress IPv4 maps. */
+public class ClatEgress4Value extends Struct {
+ @Field(order = 0, type = Type.U32)
+ public final long oif; // The output interface to redirect to
+
+ @Field(order = 1, type = Type.Ipv6Address)
+ public final Inet6Address local6; // The full 128-bits of the source IPv6 address
+
+ @Field(order = 2, type = Type.Ipv6Address)
+ public final Inet6Address pfx96; // The destination /96 nat64 prefix, bottom 32 bits must be 0
+
+ @Field(order = 3, type = Type.U8, padding = 3)
+ public final short oifIsEthernet; // Whether the output interface requires ethernet header
+
+ public ClatEgress4Value(final long oif, final Inet6Address local6, final Inet6Address pfx96,
+ final short oifIsEthernet) {
+ this.oif = oif;
+ this.local6 = local6;
+ this.pfx96 = pfx96;
+ this.oifIsEthernet = oifIsEthernet;
+ }
+}
diff --git a/common/device/com/android/net/module/util/bpf/ClatIngress6Key.java b/common/device/com/android/net/module/util/bpf/ClatIngress6Key.java
new file mode 100644
index 00000000..1e2f4e06
--- /dev/null
+++ b/common/device/com/android/net/module/util/bpf/ClatIngress6Key.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 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.bpf;
+
+import com.android.net.module.util.Struct;
+import com.android.net.module.util.Struct.Field;
+import com.android.net.module.util.Struct.Type;
+
+import java.net.Inet6Address;
+
+/** Key type for clat ingress IPv6 maps. */
+public class ClatIngress6Key extends Struct {
+ @Field(order = 0, type = Type.U32)
+ public final long iif; // The input interface index
+
+ @Field(order = 1, type = Type.Ipv6Address)
+ public final Inet6Address pfx96; // The source /96 nat64 prefix, bottom 32 bits must be 0
+
+ @Field(order = 2, type = Type.Ipv6Address)
+ public final Inet6Address local6; // The full 128-bits of the destination IPv6 address
+
+ public ClatIngress6Key(final long iif, final Inet6Address pfx96, final Inet6Address local6) {
+ this.iif = iif;
+ this.pfx96 = pfx96;
+ this.local6 = local6;
+ }
+}
diff --git a/common/device/com/android/net/module/util/bpf/ClatIngress6Value.java b/common/device/com/android/net/module/util/bpf/ClatIngress6Value.java
new file mode 100644
index 00000000..bfec44fa
--- /dev/null
+++ b/common/device/com/android/net/module/util/bpf/ClatIngress6Value.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2022 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.bpf;
+
+import com.android.net.module.util.Struct;
+import com.android.net.module.util.Struct.Field;
+import com.android.net.module.util.Struct.Type;
+
+import java.net.Inet4Address;
+
+/** Value type for clat ingress IPv6 maps. */
+public class ClatIngress6Value extends Struct {
+ @Field(order = 0, type = Type.U32)
+ public final long oif; // The output interface to redirect to (0 means don't redirect)
+
+ @Field(order = 1, type = Type.Ipv4Address)
+ public final Inet4Address local4; // The destination IPv4 address
+
+ public ClatIngress6Value(final long oif, final Inet4Address local4) {
+ this.oif = oif;
+ this.local4 = local4;
+ }
+}
diff --git a/common/device/com/android/net/module/util/bpf/Tether4Key.java b/common/device/com/android/net/module/util/bpf/Tether4Key.java
new file mode 100644
index 00000000..638576f0
--- /dev/null
+++ b/common/device/com/android/net/module/util/bpf/Tether4Key.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2020 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.bpf;
+
+import android.net.MacAddress;
+
+import androidx.annotation.NonNull;
+
+import com.android.net.module.util.Struct;
+import com.android.net.module.util.Struct.Field;
+import com.android.net.module.util.Struct.Type;
+
+import java.net.Inet4Address;
+import java.net.UnknownHostException;
+import java.util.Objects;
+
+/** Key type for downstream & upstream IPv4 forwarding maps. */
+public class Tether4Key extends Struct {
+ @Field(order = 0, type = Type.U32)
+ public final long iif;
+
+ @Field(order = 1, type = Type.EUI48)
+ public final MacAddress dstMac;
+
+ @Field(order = 2, type = Type.U8, padding = 1)
+ public final short l4proto;
+
+ @Field(order = 3, type = Type.ByteArray, arraysize = 4)
+ public final byte[] src4;
+
+ @Field(order = 4, type = Type.ByteArray, arraysize = 4)
+ public final byte[] dst4;
+
+ @Field(order = 5, type = Type.UBE16)
+ public final int srcPort;
+
+ @Field(order = 6, type = Type.UBE16)
+ public final int dstPort;
+
+ public Tether4Key(final long iif, @NonNull final MacAddress dstMac, final short l4proto,
+ final byte[] src4, final byte[] dst4, final int srcPort,
+ final int dstPort) {
+ Objects.requireNonNull(dstMac);
+
+ this.iif = iif;
+ this.dstMac = dstMac;
+ this.l4proto = l4proto;
+ this.src4 = src4;
+ this.dst4 = dst4;
+ this.srcPort = srcPort;
+ this.dstPort = dstPort;
+ }
+
+ @Override
+ public String toString() {
+ try {
+ return String.format(
+ "iif: %d, dstMac: %s, l4proto: %d, src4: %s, dst4: %s, "
+ + "srcPort: %d, dstPort: %d",
+ iif, dstMac, l4proto,
+ Inet4Address.getByAddress(src4), Inet4Address.getByAddress(dst4),
+ Short.toUnsignedInt((short) srcPort), Short.toUnsignedInt((short) dstPort));
+ } catch (UnknownHostException | IllegalArgumentException e) {
+ return String.format("Invalid IP address", e);
+ }
+ }
+}
diff --git a/common/device/com/android/net/module/util/bpf/Tether4Value.java b/common/device/com/android/net/module/util/bpf/Tether4Value.java
new file mode 100644
index 00000000..de98766e
--- /dev/null
+++ b/common/device/com/android/net/module/util/bpf/Tether4Value.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2020 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.bpf;
+
+import android.net.MacAddress;
+
+import androidx.annotation.NonNull;
+
+import com.android.net.module.util.Struct;
+import com.android.net.module.util.Struct.Field;
+import com.android.net.module.util.Struct.Type;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.Objects;
+
+/** Value type for downstream & upstream IPv4 forwarding maps. */
+public class Tether4Value extends Struct {
+ @Field(order = 0, type = Type.U32)
+ public final long oif;
+
+ // The ethhdr struct which is defined in uapi/linux/if_ether.h
+ @Field(order = 1, type = Type.EUI48)
+ public final MacAddress ethDstMac;
+ @Field(order = 2, type = Type.EUI48)
+ public final MacAddress ethSrcMac;
+ @Field(order = 3, type = Type.UBE16)
+ public final int ethProto; // Packet type ID field.
+
+ @Field(order = 4, type = Type.U16)
+ public final int pmtu;
+
+ @Field(order = 5, type = Type.ByteArray, arraysize = 16)
+ public final byte[] src46;
+
+ @Field(order = 6, type = Type.ByteArray, arraysize = 16)
+ public final byte[] dst46;
+
+ @Field(order = 7, type = Type.UBE16)
+ public final int srcPort;
+
+ @Field(order = 8, type = Type.UBE16)
+ public final int dstPort;
+
+ // TODO: consider using U64.
+ @Field(order = 9, type = Type.U63)
+ public final long lastUsed;
+
+ public Tether4Value(final long oif, @NonNull final MacAddress ethDstMac,
+ @NonNull final MacAddress ethSrcMac, final int ethProto, final int pmtu,
+ final byte[] src46, final byte[] dst46, final int srcPort,
+ final int dstPort, final long lastUsed) {
+ Objects.requireNonNull(ethDstMac);
+ Objects.requireNonNull(ethSrcMac);
+
+ this.oif = oif;
+ this.ethDstMac = ethDstMac;
+ this.ethSrcMac = ethSrcMac;
+ this.ethProto = ethProto;
+ this.pmtu = pmtu;
+ this.src46 = src46;
+ this.dst46 = dst46;
+ this.srcPort = srcPort;
+ this.dstPort = dstPort;
+ this.lastUsed = lastUsed;
+ }
+
+ @Override
+ public String toString() {
+ try {
+ return String.format(
+ "oif: %d, ethDstMac: %s, ethSrcMac: %s, ethProto: %d, pmtu: %d, "
+ + "src46: %s, dst46: %s, srcPort: %d, dstPort: %d, "
+ + "lastUsed: %d",
+ oif, ethDstMac, ethSrcMac, ethProto, pmtu,
+ InetAddress.getByAddress(src46), InetAddress.getByAddress(dst46),
+ Short.toUnsignedInt((short) srcPort), Short.toUnsignedInt((short) dstPort),
+ lastUsed);
+ } catch (UnknownHostException | IllegalArgumentException e) {
+ return String.format("Invalid IP address", e);
+ }
+ }
+}
diff --git a/common/device/com/android/net/module/util/bpf/TetherStatsKey.java b/common/device/com/android/net/module/util/bpf/TetherStatsKey.java
new file mode 100644
index 00000000..c6d595be
--- /dev/null
+++ b/common/device/com/android/net/module/util/bpf/TetherStatsKey.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2020 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.bpf;
+
+import com.android.net.module.util.Struct;
+import com.android.net.module.util.Struct.Field;
+import com.android.net.module.util.Struct.Type;
+
+/** The key of BpfMap which is used for tethering stats. */
+public class TetherStatsKey extends Struct {
+ @Field(order = 0, type = Type.U32)
+ public final long ifindex; // upstream interface index
+
+ public TetherStatsKey(final long ifindex) {
+ this.ifindex = ifindex;
+ }
+
+ // TODO: remove equals, hashCode and toString once aosp/1536721 is merged.
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) return true;
+
+ if (!(obj instanceof TetherStatsKey)) return false;
+
+ final TetherStatsKey that = (TetherStatsKey) obj;
+
+ return ifindex == that.ifindex;
+ }
+
+ @Override
+ public int hashCode() {
+ return Long.hashCode(ifindex);
+ }
+
+ @Override
+ public String toString() {
+ return String.format("ifindex: %d", ifindex);
+ }
+}
diff --git a/common/device/com/android/net/module/util/bpf/TetherStatsValue.java b/common/device/com/android/net/module/util/bpf/TetherStatsValue.java
new file mode 100644
index 00000000..028d217a
--- /dev/null
+++ b/common/device/com/android/net/module/util/bpf/TetherStatsValue.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2020 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.bpf;
+
+import com.android.net.module.util.Struct;
+import com.android.net.module.util.Struct.Field;
+import com.android.net.module.util.Struct.Type;
+
+/** The key of BpfMap which is used for tethering stats. */
+public class TetherStatsValue extends Struct {
+ // Use the signed long variable to store the uint64 stats from stats BPF map.
+ // U63 is enough for each data element even at 5Gbps for ~468 years.
+ // 2^63 / (5 * 1000 * 1000 * 1000) * 8 / 86400 / 365 = 468.
+ @Field(order = 0, type = Type.U63)
+ public final long rxPackets;
+ @Field(order = 1, type = Type.U63)
+ public final long rxBytes;
+ @Field(order = 2, type = Type.U63)
+ public final long rxErrors;
+ @Field(order = 3, type = Type.U63)
+ public final long txPackets;
+ @Field(order = 4, type = Type.U63)
+ public final long txBytes;
+ @Field(order = 5, type = Type.U63)
+ public final long txErrors;
+
+ public TetherStatsValue(final long rxPackets, final long rxBytes, final long rxErrors,
+ final long txPackets, final long txBytes, final long txErrors) {
+ this.rxPackets = rxPackets;
+ this.rxBytes = rxBytes;
+ this.rxErrors = rxErrors;
+ this.txPackets = txPackets;
+ this.txBytes = txBytes;
+ this.txErrors = txErrors;
+ }
+
+ // TODO: remove equals, hashCode and toString once aosp/1536721 is merged.
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) return true;
+
+ if (!(obj instanceof TetherStatsValue)) return false;
+
+ final TetherStatsValue that = (TetherStatsValue) obj;
+
+ return rxPackets == that.rxPackets
+ && rxBytes == that.rxBytes
+ && rxErrors == that.rxErrors
+ && txPackets == that.txPackets
+ && txBytes == that.txBytes
+ && txErrors == that.txErrors;
+ }
+
+ @Override
+ public int hashCode() {
+ return Long.hashCode(rxPackets) ^ Long.hashCode(rxBytes) ^ Long.hashCode(rxErrors)
+ ^ Long.hashCode(txPackets) ^ Long.hashCode(txBytes) ^ Long.hashCode(txErrors);
+ }
+
+ @Override
+ public String toString() {
+ return String.format("rxPackets: %s, rxBytes: %s, rxErrors: %s, txPackets: %s, "
+ + "txBytes: %s, txErrors: %s", rxPackets, rxBytes, rxErrors, txPackets,
+ txBytes, txErrors);
+ }
+}
diff --git a/common/device/com/android/net/module/util/ip/IpNeighborMonitor.java b/common/device/com/android/net/module/util/ip/IpNeighborMonitor.java
index 4a617941..88f8c9d3 100644
--- a/common/device/com/android/net/module/util/ip/IpNeighborMonitor.java
+++ b/common/device/com/android/net/module/util/ip/IpNeighborMonitor.java
@@ -22,7 +22,6 @@ import static com.android.net.module.util.netlink.NetlinkConstants.RTM_DELNEIGH;
import static com.android.net.module.util.netlink.NetlinkConstants.hexify;
import static com.android.net.module.util.netlink.NetlinkConstants.stringForNlMsgType;
-import android.annotation.NonNull;
import android.net.MacAddress;
import android.os.Handler;
import android.system.ErrnoException;
@@ -81,17 +80,15 @@ public class IpNeighborMonitor extends NetlinkMonitor {
* An event about a neighbor.
*/
public static class NeighborEvent {
- public final long elapsedMs;
- public final short msgType;
- public final int ifindex;
- @NonNull
- public final InetAddress ip;
- public final short nudState;
- @NonNull
- public final MacAddress macAddr;
-
- public NeighborEvent(long elapsedMs, short msgType, int ifindex, @NonNull InetAddress ip,
- short nudState, @NonNull MacAddress macAddr) {
+ final long elapsedMs;
+ final short msgType;
+ final int ifindex;
+ final InetAddress ip;
+ final short nudState;
+ final MacAddress macAddr;
+
+ public NeighborEvent(long elapsedMs, short msgType, int ifindex, InetAddress ip,
+ short nudState, MacAddress macAddr) {
this.elapsedMs = elapsedMs;
this.msgType = msgType;
this.ifindex = ifindex;
@@ -104,7 +101,7 @@ public class IpNeighborMonitor extends NetlinkMonitor {
return (msgType != RTM_DELNEIGH) && StructNdMsg.isNudStateConnected(nudState);
}
- public boolean isValid() {
+ boolean isValid() {
return (msgType != RTM_DELNEIGH) && StructNdMsg.isNudStateValid(nudState);
}
diff --git a/common/framework/com/android/net/module/util/LocationPermissionChecker.java b/common/framework/com/android/net/module/util/LocationPermissionChecker.java
index cd1f31cb..e4ce9e80 100644
--- a/common/framework/com/android/net/module/util/LocationPermissionChecker.java
+++ b/common/framework/com/android/net/module/util/LocationPermissionChecker.java
@@ -30,8 +30,6 @@ import android.os.Build;
import android.os.UserHandle;
import android.util.Log;
-import androidx.annotation.RequiresApi;
-
import com.android.internal.annotations.VisibleForTesting;
import java.lang.annotation.Retention;
@@ -43,7 +41,6 @@ import java.lang.annotation.RetentionPolicy;
*
* @hide
*/
-@RequiresApi(Build.VERSION_CODES.R)
public class LocationPermissionChecker {
private static final String TAG = "LocationPermissionChecker";
diff --git a/common/native/bpf_headers/include/bpf/BpfMap.h b/common/native/bpf_headers/include/bpf/BpfMap.h
index 47256fa0..297b2001 100644
--- a/common/native/bpf_headers/include/bpf/BpfMap.h
+++ b/common/native/bpf_headers/include/bpf/BpfMap.h
@@ -50,8 +50,10 @@ class BpfMap {
// (later on, for testing, we still make available a copy assignment operator)
BpfMap<Key, Value>(const BpfMap<Key, Value>&) = delete;
- private:
- void abortOnKeyOrValueSizeMismatch() {
+ protected:
+ // flag must be within BPF_OBJ_FLAG_MASK, ie. 0, BPF_F_RDONLY, BPF_F_WRONLY
+ BpfMap<Key, Value>(const char* pathname, uint32_t flags) {
+ mMapFd.reset(mapRetrieve(pathname, flags));
if (!mMapFd.ok()) abort();
if (isAtLeastKernelVersion(4, 14, 0)) {
if (bpfGetFdKeySize(mMapFd) != sizeof(Key)) abort();
@@ -59,13 +61,6 @@ class BpfMap {
}
}
- protected:
- // flag must be within BPF_OBJ_FLAG_MASK, ie. 0, BPF_F_RDONLY, BPF_F_WRONLY
- BpfMap<Key, Value>(const char* pathname, uint32_t flags) {
- mMapFd.reset(mapRetrieve(pathname, flags));
- abortOnKeyOrValueSizeMismatch();
- }
-
public:
explicit BpfMap<Key, Value>(const char* pathname) : BpfMap<Key, Value>(pathname, 0) {}
@@ -122,11 +117,14 @@ class BpfMap {
if (!mMapFd.ok()) {
return ErrnoErrorf("Pinned map not accessible or does not exist: ({})", path);
}
- // Normally we should return an error here instead of calling abort,
- // but this cannot happen at runtime without a massive code bug (K/V type mismatch)
- // and as such it's better to just blow the system up and let the developer fix it.
- // Crashes are much more likely to be noticed than logs and missing functionality.
- abortOnKeyOrValueSizeMismatch();
+ if (isAtLeastKernelVersion(4, 14, 0)) {
+ // Normally we should return an error here instead of calling abort,
+ // but this cannot happen at runtime without a massive code bug (K/V type mismatch)
+ // and as such it's better to just blow the system up and let the developer fix it.
+ // Crashes are much more likely to be noticed than logs and missing functionality.
+ if (bpfGetFdKeySize(mMapFd) != sizeof(Key)) abort();
+ if (bpfGetFdValueSize(mMapFd) != sizeof(Value)) abort();
+ }
return {};
}
@@ -204,7 +202,11 @@ class BpfMap {
// check BpfMap.isValid() and look at errno and see why systemcall() failed.
[[clang::reinitializes]] void reset(int fd) {
mMapFd.reset(fd);
- if (mMapFd.ok()) abortOnKeyOrValueSizeMismatch();
+ if ((fd >= 0) && isAtLeastKernelVersion(4, 14, 0)) {
+ if (bpfGetFdKeySize(mMapFd) != sizeof(Key)) abort();
+ if (bpfGetFdValueSize(mMapFd) != sizeof(Value)) abort();
+ if (bpfGetFdMapFlags(mMapFd) != 0) abort(); // TODO: fix for BpfMapRO
+ }
}
#endif
diff --git a/common/native/bpf_headers/include/bpf/bpf_helpers.h b/common/native/bpf_headers/include/bpf/bpf_helpers.h
index 236318d6..ae3ad2c9 100644
--- a/common/native/bpf_headers/include/bpf/bpf_helpers.h
+++ b/common/native/bpf_headers/include/bpf/bpf_helpers.h
@@ -30,16 +30,6 @@
// Android T / 13 Beta 3 (api level 33) - added support for 'netd_shared'
#define BPFLOADER_T_BETA3_VERSION 13u
-// v0.18 added support for shared and pindir, but still ignores selinux_content
-// v0.19 added support for selinux_content along with the required selinux changes
-// and should be available starting with Android T Beta 4
-//
-// Android T / 13 (api level 33) - support for shared/selinux_context/pindir
-#define BPFLOADER_T_VERSION 19u
-
-// BpfLoader v0.25+ support obj@ver.o files
-#define BPFLOADER_OBJ_AT_VER_VERSION 25u
-
/* For mainline module use, you can #define BPFLOADER_{MIN/MAX}_VER
* before #include "bpf_helpers.h" to change which bpfloaders will
* process the resulting .o file.
@@ -182,39 +172,20 @@ static int (*bpf_map_delete_elem_unsafe)(const struct bpf_map_def* map,
return bpf_map_delete_elem_unsafe(&the_map, k); \
};
-#ifndef DEFAULT_BPF_MAP_SELINUX_CONTEXT
-#define DEFAULT_BPF_MAP_SELINUX_CONTEXT ""
-#endif
-
-#ifndef DEFAULT_BPF_MAP_PIN_SUBDIR
-#define DEFAULT_BPF_MAP_PIN_SUBDIR ""
-#endif
-
-#ifndef DEFAULT_BPF_MAP_UID
-#define DEFAULT_BPF_MAP_UID AID_ROOT
-#elif BPFLOADER_MIN_VER < 21u
-#error "Bpf Map UID must be left at default of AID_ROOT for BpfLoader prior to v0.21"
-#endif
-
#define DEFINE_BPF_MAP_UGM(the_map, TYPE, KeyType, ValueType, num_entries, usr, grp, md) \
- DEFINE_BPF_MAP_EXT(the_map, TYPE, KeyType, ValueType, num_entries, usr, grp, md, \
- DEFAULT_BPF_MAP_SELINUX_CONTEXT, DEFAULT_BPF_MAP_PIN_SUBDIR, false)
+ DEFINE_BPF_MAP_EXT(the_map, TYPE, KeyType, ValueType, num_entries, usr, grp, md, "", "", false)
#define DEFINE_BPF_MAP(the_map, TYPE, KeyType, ValueType, num_entries) \
- DEFINE_BPF_MAP_UGM(the_map, TYPE, KeyType, ValueType, num_entries, \
- DEFAULT_BPF_MAP_UID, AID_ROOT, 0600)
+ DEFINE_BPF_MAP_UGM(the_map, TYPE, KeyType, ValueType, num_entries, AID_ROOT, AID_ROOT, 0600)
#define DEFINE_BPF_MAP_GWO(the_map, TYPE, KeyType, ValueType, num_entries, gid) \
- DEFINE_BPF_MAP_UGM(the_map, TYPE, KeyType, ValueType, num_entries, \
- DEFAULT_BPF_MAP_UID, gid, 0620)
+ DEFINE_BPF_MAP_UGM(the_map, TYPE, KeyType, ValueType, num_entries, AID_ROOT, gid, 0620)
#define DEFINE_BPF_MAP_GRO(the_map, TYPE, KeyType, ValueType, num_entries, gid) \
- DEFINE_BPF_MAP_UGM(the_map, TYPE, KeyType, ValueType, num_entries, \
- DEFAULT_BPF_MAP_UID, gid, 0640)
+ DEFINE_BPF_MAP_UGM(the_map, TYPE, KeyType, ValueType, num_entries, AID_ROOT, gid, 0640)
#define DEFINE_BPF_MAP_GRW(the_map, TYPE, KeyType, ValueType, num_entries, gid) \
- DEFINE_BPF_MAP_UGM(the_map, TYPE, KeyType, ValueType, num_entries, \
- DEFAULT_BPF_MAP_UID, gid, 0660)
+ DEFINE_BPF_MAP_UGM(the_map, TYPE, KeyType, ValueType, num_entries, AID_ROOT, gid, 0660)
static int (*bpf_probe_read)(void* dst, int size, void* unsafe_ptr) = (void*) BPF_FUNC_probe_read;
static int (*bpf_probe_read_str)(void* dst, int size, void* unsafe_ptr) = (void*) BPF_FUNC_probe_read_str;
@@ -243,18 +214,9 @@ static long (*bpf_get_current_comm)(void* buf, uint32_t buf_size) = (void*) BPF_
SECTION(SECTION_NAME) \
int the_prog
-#ifndef DEFAULT_BPF_PROG_SELINUX_CONTEXT
-#define DEFAULT_BPF_PROG_SELINUX_CONTEXT ""
-#endif
-
-#ifndef DEFAULT_BPF_PROG_PIN_SUBDIR
-#define DEFAULT_BPF_PROG_PIN_SUBDIR ""
-#endif
-
#define DEFINE_BPF_PROG_KVER_RANGE_OPT(SECTION_NAME, prog_uid, prog_gid, the_prog, min_kv, max_kv, \
opt) \
- DEFINE_BPF_PROG_EXT(SECTION_NAME, prog_uid, prog_gid, the_prog, min_kv, max_kv, opt, \
- DEFAULT_BPF_PROG_SELINUX_CONTEXT, DEFAULT_BPF_PROG_PIN_SUBDIR)
+ DEFINE_BPF_PROG_EXT(SECTION_NAME, prog_uid, prog_gid, the_prog, min_kv, max_kv, opt, "", "")
// Programs (here used in the sense of functions/sections) marked optional are allowed to fail
// to load (for example due to missing kernel patches).
diff --git a/common/native/bpf_syscall_wrappers/include/BpfSyscallWrappers.h b/common/native/bpf_syscall_wrappers/include/BpfSyscallWrappers.h
index d5b76701..4b29c448 100644
--- a/common/native/bpf_syscall_wrappers/include/BpfSyscallWrappers.h
+++ b/common/native/bpf_syscall_wrappers/include/BpfSyscallWrappers.h
@@ -150,12 +150,8 @@ inline int detachSingleProgram(bpf_attach_type type, const BPF_FD_TYPE prog_fd,
});
}
-// BPF_OBJ_GET_INFO_BY_FD requires 4.14+ kernel
-//
-// Note: some fields are only defined in newer kernels (ie. the map_info struct grows
-// over time), so we need to check that the field we're interested in is actually
-// supported/returned by the running kernel. We do this by checking it is fully
-// within the bounds of the struct size as reported by the kernel.
+// requires 4.14+ kernel
+
#define DEFINE_BPF_GET_FD_INFO(NAME, FIELD) \
inline int bpfGetFd ## NAME(const BPF_FD_TYPE map_fd) { \
struct bpf_map_info map_info = {}; \
diff --git a/common/native/netjniutils/Android.bp b/common/native/netjniutils/Android.bp
index 22fd1fa4..d8e6a04c 100644
--- a/common/native/netjniutils/Android.bp
+++ b/common/native/netjniutils/Android.bp
@@ -19,9 +19,6 @@ package {
cc_library_static {
name: "libnetjniutils",
srcs: ["netjniutils.cpp"],
- static_libs: [
- "libmodules-utils-build",
- ],
header_libs: ["jni_headers"],
shared_libs: ["liblog"],
export_header_lib_headers: ["jni_headers"],
diff --git a/common/native/netjniutils/netjniutils.cpp b/common/native/netjniutils/netjniutils.cpp
index 8b7f903f..210c6c3a 100644
--- a/common/native/netjniutils/netjniutils.cpp
+++ b/common/native/netjniutils/netjniutils.cpp
@@ -15,7 +15,6 @@
#define LOG_TAG "netjniutils"
#include "netjniutils/netjniutils.h"
-#include <android-modules-utils/sdk_level.h>
#include <dlfcn.h>
#include <stdbool.h>
@@ -30,6 +29,27 @@ namespace netjniutils {
namespace {
+bool IsAtLeastS() {
+ // TODO(b/158749603#comment19): move to android::modules::sdklevel::IsAtLeastS().
+ int api_level = android_get_device_api_level();
+
+ // Guarded check for branches that do not have __ANDROID_API_S__.
+#ifdef __ANDROID_API_S__
+ if (api_level >= __ANDROID_API_S__) {
+ return true;
+ }
+#endif
+
+ if (api_level < __ANDROID_API_R__) {
+ return false;
+ }
+
+ // Device looks like R or above, check codename as it could be (S or above).
+ static constexpr const char* kCodenameProperty = "ro.build.version.codename";
+ char codename[PROP_VALUE_MAX] = { 0 };
+ return (__system_property_get(kCodenameProperty, codename) > 0 &&
+ codename[0] >= 'S' && codename[1] == '\0');
+}
int GetNativeFileDescriptorWithoutNdk(JNIEnv* env, jobject javaFd) {
// Prior to Android S, we need to find the descriptor field in the FileDescriptor class. The
@@ -72,8 +92,7 @@ int GetNativeFileDescriptorWithNdk(JNIEnv* env, jobject javaFd) {
} // namespace
int GetNativeFileDescriptor(JNIEnv* env, jobject javaFd) {
- static const bool preferNdkFileDescriptorApi = []() -> bool
- { return android::modules::sdklevel::IsAtLeastS(); }();
+ static const bool preferNdkFileDescriptorApi = []() -> bool { return IsAtLeastS(); }();
if (preferNdkFileDescriptorApi) {
return GetNativeFileDescriptorWithNdk(env, javaFd);
} else {
diff --git a/common/netd/libnetdutils/include/netdutils/NetNativeTestBase.h b/common/netd/libnetdutils/include/netdutils/NetNativeTestBase.h
deleted file mode 100644
index c8b30c62..00000000
--- a/common/netd/libnetdutils/include/netdutils/NetNativeTestBase.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2022 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.
- *
- */
-#pragma once
-
-#include <android-base/format.h>
-#include <android-base/logging.h>
-#include "gtest/gtest.h"
-
-using ::testing::TestInfo;
-using ::testing::UnitTest;
-
-#define DBG 1
-
-/*
- * Test base class for net native tests to support common usage.
- */
-class NetNativeTestBase : public ::testing::Test {
- public:
- // TODO: update the logging when gtest supports logging the life cycle on each test.
- NetNativeTestBase() {
- if (DBG) LOG(INFO) << getTestCaseLog(true);
- }
- ~NetNativeTestBase() {
- if (DBG) LOG(INFO) << getTestCaseLog(false);
- }
-
- std::string getTestCaseLog(bool running) {
- const TestInfo* const test_info = UnitTest::GetInstance()->current_test_info();
- return fmt::format("{}: {}#{}", (running ? "started" : "finished"),
- test_info->test_suite_name(), test_info->name());
- }
-};
diff --git a/common/tests/unit/src/com/android/net/module/util/BpfDumpTest.java b/common/tests/unit/src/com/android/net/module/util/BpfDumpTest.java
deleted file mode 100644
index b166b4a4..00000000
--- a/common/tests/unit/src/com/android/net/module/util/BpfDumpTest.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2022 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 org.junit.Assert.assertEquals;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class BpfDumpTest {
- @Test
- public void testToBase64EncodedString() {
- final Struct.U32 key = new Struct.U32(123);
- final Struct.U32 value = new Struct.U32(456);
-
- // Verified in python:
- // import base64
- // print(base64.b64encode(b'\x7b\x00\x00\x00')) # key: ewAAAA==
- // print(base64.b64encode(b'\xc8\x01\x00\x00')) # value: yAEAAA==
- assertEquals("7B000000", HexDump.toHexString(key.writeToBytes()));
- assertEquals("C8010000", HexDump.toHexString(value.writeToBytes()));
- assertEquals("ewAAAA==,yAEAAA==", BpfDump.toBase64EncodedString(key, value));
- }
-}
diff --git a/common/tests/unit/src/com/android/net/module/util/SharedLogTest.java b/common/tests/unit/src/com/android/net/module/util/SharedLogTest.java
index aa1bfee4..446e8819 100644
--- a/common/tests/unit/src/com/android/net/module/util/SharedLogTest.java
+++ b/common/tests/unit/src/com/android/net/module/util/SharedLogTest.java
@@ -17,8 +17,6 @@
package com.android.net.module.util;
import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import androidx.test.filters.SmallTest;
@@ -29,24 +27,16 @@ import org.junit.runner.RunWith;
import java.io.ByteArrayOutputStream;
import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.function.Consumer;
@RunWith(AndroidJUnit4.class)
@SmallTest
public class SharedLogTest {
private static final String TIMESTAMP_PATTERN = "\\d{2}:\\d{2}:\\d{2}";
private static final String TIMESTAMP = "HH:MM:SS";
- private static final String TAG = "top";
@Test
public void testBasicOperation() {
- final SharedLog logTop = new SharedLog(TAG);
- assertTrue(TAG.equals(logTop.getTag()));
-
+ final SharedLog logTop = new SharedLog("top");
logTop.mark("first post!");
final SharedLog logLevel2a = logTop.forSubComponent("twoA");
@@ -58,10 +48,8 @@ public class SharedLogTest {
final SharedLog logLevel3 = logLevel2a.forSubComponent("three");
logTop.log("still logging");
- logLevel2b.e(new Exception("Got another exception"));
- logLevel3.i("3 >> 2");
+ logLevel3.log("3 >> 2");
logLevel2a.mark("ok: last post");
- logTop.logf("finished!");
final String[] expected = {
" - MARK first post!",
@@ -71,53 +59,29 @@ public class SharedLogTest {
" - [twoB] ERROR Wait, here's one: Test",
" - [twoA] WARN second post?",
" - still logging",
- " - [twoB] ERROR java.lang.Exception: Got another exception",
" - [twoA.three] 3 >> 2",
" - [twoA] MARK ok: last post",
- " - finished!",
};
// Verify the logs are all there and in the correct order.
- assertDumpLogs(expected, logTop);
+ verifyLogLines(expected, logTop);
// In fact, because they all share the same underlying LocalLog,
// every subcomponent SharedLog's dump() is identical.
- assertDumpLogs(expected, logLevel2a);
- assertDumpLogs(expected, logLevel2b);
- assertDumpLogs(expected, logLevel3);
- }
-
- private static void assertDumpLogs(String[] expected, SharedLog log) {
- verifyLogLines(expected, dump(log));
- verifyLogLines(reverse(expected), reverseDump(log));
- }
-
- private static String dump(SharedLog log) {
- return getSharedLogString(pw -> log.dump(null /* fd */, pw, null /* args */));
+ verifyLogLines(expected, logLevel2a);
+ verifyLogLines(expected, logLevel2b);
+ verifyLogLines(expected, logLevel3);
}
- private static String reverseDump(SharedLog log) {
- return getSharedLogString(pw -> log.reverseDump(pw));
- }
-
- private static String[] reverse(String[] ary) {
- final List<String> ls = new ArrayList<>(Arrays.asList(ary));
- Collections.reverse(ls);
- return ls.toArray(new String[ary.length]);
- }
-
- private static String getSharedLogString(Consumer<PrintWriter> functor) {
+ private static void verifyLogLines(String[] expected, SharedLog log) {
final ByteArrayOutputStream ostream = new ByteArrayOutputStream();
final PrintWriter pw = new PrintWriter(ostream, true);
- functor.accept(pw);
+ log.dump(null, pw, null);
final String dumpOutput = ostream.toString();
- assertNotNull(dumpOutput);
- assertFalse("".equals(dumpOutput));
- return dumpOutput;
- }
+ assertTrue(dumpOutput != null);
+ assertTrue(!"".equals(dumpOutput));
- private static void verifyLogLines(String[] expected, String gottenLogs) {
- final String[] lines = gottenLogs.split("\n");
+ final String[] lines = dumpOutput.split("\n");
assertEquals(expected.length, lines.length);
for (int i = 0; i < expected.length; i++) {
diff --git a/common/testutils/devicetests/com/android/testutils/ContextUtils.kt b/common/testutils/devicetests/com/android/testutils/ContextUtils.kt
index 936b5682..814a75b4 100644
--- a/common/testutils/devicetests/com/android/testutils/ContextUtils.kt
+++ b/common/testutils/devicetests/com/android/testutils/ContextUtils.kt
@@ -53,15 +53,3 @@ fun mockContextAsUser(context: Context, functor: ((Context, UserHandle) -> Unit)
asUserContext
}.`when`(context).createContextAsUser(any(UserHandle::class.java), anyInt() /* flags */)
}
-
-/**
- * Helper function to mock the desired system service.
- *
- * @param context the mock context to set up the getSystemService and getSystemServiceName.
- * @param clazz the system service class that intents to mock.
- * @param service the system service name that intents to mock.
- */
-fun <T> mockService(context: Context, clazz: Class<T>, name: String, service: T) {
- doReturn(service).`when`(context).getSystemService(name)
- doReturn(name).`when`(context).getSystemServiceName(clazz)
-} \ No newline at end of file
diff --git a/common/testutils/devicetests/com/android/testutils/TestPermissionUtil.kt b/common/testutils/devicetests/com/android/testutils/TestPermissionUtil.kt
index a4dbd9ad..f557f186 100644
--- a/common/testutils/devicetests/com/android/testutils/TestPermissionUtil.kt
+++ b/common/testutils/devicetests/com/android/testutils/TestPermissionUtil.kt
@@ -19,7 +19,6 @@
package com.android.testutils
import androidx.test.platform.app.InstrumentationRegistry
-import com.android.modules.utils.build.SdkLevel
import com.android.testutils.ExceptionUtils.ThrowingRunnable
import com.android.testutils.ExceptionUtils.ThrowingSupplier
@@ -32,23 +31,6 @@ import com.android.testutils.ExceptionUtils.ThrowingSupplier
*/
fun <T> runAsShell(vararg permissions: String, task: () -> T): T {
val autom = InstrumentationRegistry.getInstrumentation().uiAutomation
-
- // Calls to adoptShellPermissionIdentity do not nest, and dropShellPermissionIdentity drops all
- // permissions. Thus, nesting calls will almost certainly cause test bugs, On S+, where we can
- // detect this, refuse to do it.
- //
- // TODO: when R is deprecated, we could try to make this work instead.
- // - Get the list of previously-adopted permissions.
- // - Adopt the union of the previously-adopted and newly-requested permissions.
- // - Run the task.
- // - Adopt the previously-adopted permissions, dropping the ones just adopted.
- //
- // This would allow tests (and utility classes, such as the TestCarrierConfigReceiver attempted
- // in aosp/2106007) to call runAsShell even within a test that has already adopted permissions.
- if (SdkLevel.isAtLeastS() && !autom.getAdoptedShellPermissions().isNullOrEmpty()) {
- throw IllegalStateException("adoptShellPermissionIdentity calls must not be nested")
- }
-
autom.adoptShellPermissionIdentity(*permissions)
try {
return task()