Merge "Make onPackage[Added|Removed] as non-public methods"
diff --git a/Cronet/Android.bp b/Cronet/Android.bp
new file mode 100644
index 0000000..3ce88ef
--- /dev/null
+++ b/Cronet/Android.bp
@@ -0,0 +1,106 @@
+// 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 {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+java_import {
+ name: "cronet_impl_native_java",
+ jars: ["prebuilt/cronet_impl_native_java.jar"],
+ visibility: ["//visibility:private"],
+ apex_available: ["com.android.tethering"],
+ min_sdk_version: "29",
+}
+
+java_import {
+ name: "cronet_impl_common_java",
+ jars: ["prebuilt/cronet_impl_common_java.jar"],
+ visibility: ["//visibility:private"],
+ apex_available: ["com.android.tethering"],
+ min_sdk_version: "29",
+}
+
+java_import {
+ name: "cronet_impl_platform_java",
+ jars: ["prebuilt/cronet_impl_platform_java.jar"],
+ visibility: ["//visibility:private"],
+ apex_available: ["com.android.tethering"],
+ min_sdk_version: "29",
+}
+
+cc_prebuilt_library_shared {
+ name: "libcronet.107.0.5284.2",
+ shared_libs: [
+ "libandroid",
+ "libc",
+ "libdl",
+ "liblog",
+ "libm",
+ ],
+ stl: "libc++_static",
+ target: {
+ android_arm64: {
+ srcs: ["prebuilt/libs/arm64-v8a/libcronet.107.0.5284.2.so"],
+ },
+ android_arm: {
+ srcs: ["prebuilt/libs/armeabi-v7a/libcronet.107.0.5284.2.so"],
+ },
+ android_x86_64: {
+ srcs: ["prebuilt/libs/x86_64/libcronet.107.0.5284.2.so"],
+ },
+ android_x86: {
+ srcs: ["prebuilt/libs/x86/libcronet.107.0.5284.2.so"],
+ },
+ },
+ // These are already stripped, and restripping them just issues diagnostics.
+ strip: {
+ none: true,
+ },
+ apex_available: ["com.android.tethering"],
+ min_sdk_version: "29",
+}
+
+genrule {
+ name: "cronet_api-src",
+ srcs: ["prebuilt/cronet_api-src.jar"],
+ cmd: "cp $(in) $(out)",
+ out: [
+ "cronet_api-src.srcjar",
+ ],
+}
+
+java_sdk_library {
+ name: "framework-cronet",
+ defaults: ["framework-module-defaults"],
+ srcs: [
+ ":cronet_api-src",
+ ],
+ libs: [
+ "androidx.annotation_annotation",
+ ],
+ static_libs: [
+ "androidx.core_core-nodeps",
+ "cronet_impl_common_java",
+ "cronet_impl_native_java",
+ "cronet_impl_platform_java",
+ ],
+ apex_available: ["com.android.tethering"],
+ jarjar_rules: "jarjar-rules.txt",
+ unsafe_ignore_missing_latest_api: true,
+ dist_group: "android",
+ // cronet is used as a shared library.
+ shared_library: true,
+ exclude_kotlinc_generated_files: true,
+}
diff --git a/Cronet/AndroidManifest.xml b/Cronet/AndroidManifest.xml
new file mode 100644
index 0000000..f3b3c3e
--- /dev/null
+++ b/Cronet/AndroidManifest.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * 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.
+ */
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.cronet"
+ android:versionCode="11"
+ android:versionName="R-initial">
+</manifest>
diff --git a/Cronet/OWNERS b/Cronet/OWNERS
new file mode 100644
index 0000000..62c5737
--- /dev/null
+++ b/Cronet/OWNERS
@@ -0,0 +1,2 @@
+set noparent
+file:platform/packages/modules/Connectivity:master:/OWNERS_core_networking
diff --git a/Cronet/TEST_MAPPING b/Cronet/TEST_MAPPING
new file mode 100644
index 0000000..815d496
--- /dev/null
+++ b/Cronet/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+ "postsubmit": [
+ {
+ "name": "CronetApiTest"
+ }
+ ]
+}
diff --git a/Cronet/apex/Android.bp b/Cronet/apex/Android.bp
new file mode 100644
index 0000000..180dafb
--- /dev/null
+++ b/Cronet/apex/Android.bp
@@ -0,0 +1,59 @@
+// 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 {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+// CronetApexDefaults uses apex_defaults cronet_apex_defaults specifies. cronet_apex_defaults
+// could be "CronetApexDefaultsEnabled" or "CronetApexDefaultsDisabled" depending on the branch.
+cronet_apex_defaults = "CronetApexDefaultsEnabled"
+// This is a placeholder comment to avoid merge conflicts
+// as cronet_apex_defaults may have different values
+// depending on the branch
+
+apex_defaults {
+ name: "CronetApexDefaults",
+ defaults: [cronet_apex_defaults],
+}
+
+apex_defaults {
+ name: "CronetApexDefaultsEnabled",
+ jni_libs: ["libcronet.107.0.5284.2"],
+ java_libs: ["framework-cronet"],
+ arch: {
+ riscv64: {
+ // TODO: remove this when there is a riscv64 libcronet
+ exclude_jni_libs: ["libcronet.107.0.5284.2"],
+ },
+ },
+}
+
+apex_defaults {
+ name: "CronetApexDefaultsDisabled",
+}
+
+// TODO: Remove cronet apex after com.android.cronet is removed from PRODUCT_PACKAGES
+apex {
+ name: "com.android.cronet",
+ key: "com.android.cronet.key",
+ updatable: false,
+ manifest: "manifest.json",
+}
+
+apex_key {
+ name: "com.android.cronet.key",
+ public_key: "com.android.cronet.avbpubkey",
+ private_key: "com.android.cronet.pem",
+}
diff --git a/Cronet/apex/AndroidManifest.xml b/Cronet/apex/AndroidManifest.xml
new file mode 100644
index 0000000..650badc
--- /dev/null
+++ b/Cronet/apex/AndroidManifest.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * 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.
+ -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.cronet">
+ <!-- APEX does not have classes.dex -->
+ <application android:hasCode="false" />
+ <uses-sdk
+ android:minSdkVersion="29"
+ />
+</manifest>
diff --git a/Cronet/apex/com.android.cronet.avbpubkey b/Cronet/apex/com.android.cronet.avbpubkey
new file mode 100644
index 0000000..38aebe0
--- /dev/null
+++ b/Cronet/apex/com.android.cronet.avbpubkey
Binary files differ
diff --git a/Cronet/apex/com.android.cronet.pem b/Cronet/apex/com.android.cronet.pem
new file mode 100644
index 0000000..438653f
--- /dev/null
+++ b/Cronet/apex/com.android.cronet.pem
@@ -0,0 +1,51 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIJKAIBAAKCAgEAqpxkMMK57w+fzxLcwF+mEQEbKrDFWXYHL697tv8DBu/aL2tM
+LRHiKFdov0Fsnup++bd9oojI+6qyAyJh4I8nvzKc4onM0eXL++0FPZuiTv6a6r7K
+wyn+NVT2X/0yr2Hs5NL1rKXFmJPAfMoRCW9vQdi5xMlM9QN8mNaqSWddKtrQM3yC
+HDLy2zZd7MlQ1UTnmDqGCG0AVtuM34X0v1o0wAL7UwNdzOARtmnuWzcL5vBwAJg8
+eXFZH5Pt5rITxbU+eYw/V+/sUYyI0Anrj4GG+oyWQxgdxz+FwdpSAt14xtw5IDl7
+pTYqEIm+TQKnWe6NzVWfI89s2nh85hgOSgugfpS4symbfbZd4qNSOcHGQTB1ssvf
+vdYGF1WRFA20VEEOMzTMYsvcfModKNVCpibzHu/SYDIJGL0JyJWu2eIE+mrn3lLD
+nwDZ2P39YyVNpritEkbk5qugaLh9mIFqAD4L4niYLu/AtYq+CXzd7yroM2ycleRq
+JRNsCIUx3A/Z5vKx7IJaMb7Pwap3DAe3u3/2L9NCL6oo074Rf7fh5xkDF4Dua3Gg
+kPw+k183jAQECHORstdVlgVZlMxPif4lxQ8uCHJWxyDsgShPgzMtEjJyrJJQyDon
+X8pN4xqb+WX30XNYBK5sp7x6mc8w4rdAGExhUSdmTS0J/lcfar6A6/j/yg8CAwEA
+AQKCAgAiYafTJ7q+kWB8I2n3Ho9hx95IqRzsHVvvYSbGRve+MyG+App0TrFLvemu
++SlBkTILcs3Prk8KYGjFNu2QimjRIAr7oBd1iSClYSt4Md/wmWBwxAgqclD3QGry
+Bx1quIo7xsOZikKar9PPkg0C4MED/P/ax1JJ4ez/A+uHJVxiIXxpk8LImf/U60zc
+RemTQPKG++w80HKMDmyCMwWSdkRBGZi6Luh9O/51yz0shphQbs2zYPp24r+6HF6J
+6gMQCalQZ1Hwj7oI6RA9FHKzFcA0x5YUaUy+9W8oFK4IQ8duE70zYEIplhO+B3Qh
+ItLEzc0nvwR1+/wMvtE0sU5X36X06AFhkcpjyAdmNVMiG91KGrZqruOufrOQu4VE
+njJ5VEUvWOr+6inZDWIdT3NQvwJCZkT4Vvn9WBAoKM8pkpfhY5HTGq4ttX7McHjF
+p7YBFbHRpzO+OfSwM7f/xq2WLcjOKgsFgv17CUo7KQo1rqWPD/4IKJKW5n6dzDwX
+RRF4dehUMYK2UNAbcN9S8O8nJGcJfb76FExjZtGLrhlDgawLmu71bbq5afot/IQ9
+JuB4KxG59t2JAHGNgM7WfFvcL1Zp1D+kzDEHYKYkyDJh3qB7Tw+StlAQFSQjNBX/
+c1I6DUl68rSHOc2LF4oK8ID1oe/URMg2YoaLlF8un2nGZBfwGQKCAQEA20Ie5hBC
+H8W1vTtyI4jOdn/h11RL8UuLN0xtXYunYCzD4+gAEKsAShbhKnvINThZaoxQ2sxy
+9EB+2Ob8R9muYAxR4Eu4tDBWedYmJEl74MflLMFnIrtFIKy4F54zk7J6uNG3cHRo
+yTpoIcmK101xzz1Ed9Dd0XL6rpegnWIuVlWV4slGAf1l3h6pycfx+HCYcCboz6Nq
+JMA0ioKY0fgz5q+mb7IIObN8JjGdLeBQtNh3fcXby08AT/03psKhjgBsbuyTs7s7
+E3n+jxJ3p4xHP/psU3D/HgKWewp48AJNHY8MLY+Kp0KNoQMSQKHKqsiluGTCKLTJ
+sCWg/2c8xf728wKCAQEAxzNdZ54e6WXexMMIsGoH+wVknTHiizuxN4ZqzY/nCM0M
+9heooChfMAFrq8XMC/6MXgiy5rBhl3H12HlG4S6cq3J07MsMR0N+sUFEobuZURB4
++CbEBebmXx1kymC6FrRG4JuKZWbQ8AKpfd28QO7x915safeq6FA8cILJn4oqBGqQ
+Y8TzMKtuaCzQGoBjSgiMpx1fo9Stl7+dpGiPNsnQEG+SEsXxKoZweJPsuK8G+ZgB
+8YARajLwFfgfsCNp/8fXjA98BYM8eSxURa7USUyCmY4hU3WIGG5qc0/C69Fl35ex
+YZG7XQo1DxW/+gWsdUbAFbI4y+iJ8SRpsFxtFYifdQKCAQA5DiW4PHbYibxXN8bl
+1E3VrEV6oSb57WyWwT6cXyD49+0pu095BuaWYQnK4lcg8j7iaQ0JQraPNNFNZB42
+HEEyIUKVGV9BFGsMXVujibPAtIPAd7t84DqG3Csziillv8YLnhccHk6+PoKmeCm3
+CSIaiZjtjN6MCF2PXUmgatIgCTltwG6FSgleGaCZL3yZ58LjPFzM23tdgN6rRHy7
+9tiaqQ6odi2JxlkCH1sFex/FT6cYhYpCh5ZPOldm/7LGnvmYi9uLo6cl1FMXq/iT
+Ev/feC0EMZ1Rk97QudLqsc6baIQEvxuXlswAICp5wyBX/MqTBzU3HoR1X/VbQOQh
+qc1dAoIBACLjNhqtsNBDzS480krDZz5phWOalwi3naQR4Ka760S5VOnM3vWd3H31
+4bul2sTHAiJ994c7oPv7M4mERAuwNDQ6yYunTDE2+vtkaPbCemmeLvGXKIG4HOTP
+qxVet3i+fiNcWnLD/Rfr/29R5GSi9LHUUbyFaeNiGhPCdDmC4zT+zOcMWWNOwvlv
+z8q0ba9LrAaguF1jJDwNjTh8L4jy84PNZpHvJPvDq/MSRUVbMieInd6EBYjJ/w55
+9GLO8QOhJnkbRSdaAr9eKixCIF/uDHmEUQXi8cEFpZMohwTyGZt9X82szlnPLdfE
+gWjykW/AwmeKXTQpN++J5xDCP0CkOvkCggEBAND4wviHue/+bqY9R5EAIDIZn6kx
+VCK9roebvGjq/Az5AM7IiyUQRANv+6CmeIlXCRBMbaAtgQxhvW5UodA1livgVuzR
+ElF7Br3wfikZ34oWY0Qu8fZI0ru4syAoTiGpaUPJJgStYi76dqne15usTRk/MvwP
+tJzqpkWUYcmNv3g/w92Wr1nIJYXlPKrANSSppRg0P/CAPOHkPxLF0RwC5yIZzC5C
+hiTXSE9AwCFllMRKInnbhUdy/L+xUL6mAbGVvD/DHE7Q2xmPSsdEX5nTZkhEnW/L
+TLLgbsy2+8ouvMJCSNaMq77jq7iCIMTogEfA5GX0UO2Kjf4pnjREOzNQg4I=
+-----END RSA PRIVATE KEY-----
diff --git a/Cronet/apex/com.android.cronet.pk8 b/Cronet/apex/com.android.cronet.pk8
new file mode 100644
index 0000000..a63d761
--- /dev/null
+++ b/Cronet/apex/com.android.cronet.pk8
Binary files differ
diff --git a/Cronet/apex/com.android.cronet.x509.pem b/Cronet/apex/com.android.cronet.x509.pem
new file mode 100644
index 0000000..c9cd874
--- /dev/null
+++ b/Cronet/apex/com.android.cronet.x509.pem
@@ -0,0 +1,35 @@
+-----BEGIN CERTIFICATE-----
+MIIGIzCCBAugAwIBAgIUKEbkVLro9rIJE3M71D8sgUIngUIwDQYJKoZIhvcNAQEL
+BQAwgZ8xCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQH
+DA1Nb3VudGFpbiBWaWV3MRAwDgYDVQQKDAdBbmRyb2lkMRAwDgYDVQQLDAdBbmRy
+b2lkMRswGQYDVQQDDBJjb20uYW5kcm9pZC5jcm9uZXQxIjAgBgkqhkiG9w0BCQEW
+E2FuZHJvaWRAYW5kcm9pZC5jb20wIBcNMTkxMjA1MDcwOTIxWhgPNDc1NzEwMzEw
+NzA5MjFaMIGfMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQG
+A1UEBwwNTW91bnRhaW4gVmlldzEQMA4GA1UECgwHQW5kcm9pZDEQMA4GA1UECwwH
+QW5kcm9pZDEbMBkGA1UEAwwSY29tLmFuZHJvaWQuY3JvbmV0MSIwIAYJKoZIhvcN
+AQkBFhNhbmRyb2lkQGFuZHJvaWQuY29tMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A
+MIICCgKCAgEAwNXIHR2BeZl/R7tOXgC3KK71rrtK98zucfrNBNp/rUiFqiN527P4
+HLW+CAwnFJGLLzHhSbXiZLXyLS7FfPuMeiULUsv1mIVEVwVhtPvbodxwh5szxlVe
+iVf1WkIV90n2tZojTnhMsiEPt0EBWriPJstdO264snqg+oY9Dktxk4tXtTah/rUI
+KWPHeB0SWQMXZTKb30CVVHZfpG/HCXjUlVLx+14/X56EGi8fxd13q5c56qAybx73
+i6+Sm3+F/jcivDpATuPluvcPaZ4Tel9Nz5NjqjycyXBXh8f8azpN1GkJkltE116W
+ZT1iVIJoDAd540UXhW+TpjTeaEH5OeDOWorQM6nE1N9FMiyReprU7tz+HVmyD44Z
+ah43whi3gmwyjgzscW2Z0xGpgVoHgfz/RyBg5+w6p5AGPR0sewv6zr9HvQhpJsoj
+pl+HD9xcrdGb2yMiwm8RuH9dGW0Nos6p1LiXsxg6VBic3N7S+MGXo/dXdX39tkad
+tD+lNskJUJqyx70ynQtRI66YicyxsFv0BImBC+eGECT3hCgyyxnlvTAeRsVsEWtV
+Z+Xwf5M53/8uXkqGal7cC1bHEkG+0zsR8cc0U+22Nif9HQNIrsjEnybOlP6erV/M
+8yX9umVwDz5QlVKCYJFQOq+awSqR9KD9VX3xIRu8kB6aPtB4A7q3828CAwEAAaNT
+MFEwHQYDVR0OBBYEFBQBcdf/bfLa3knW1ukCOFOt++FtMB8GA1UdIwQYMBaAFBQB
+cdf/bfLa3knW1ukCOFOt++FtMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL
+BQADggIBALG0r81xb6NwaGCF79SeDecbnDE1MbQ2+cRt+eU/Wl2SI2oQqbaa/WP7
+k3vsZvsBFI6r+ZBiKizpbT/N1Fx8pcoH7rsL0MoZRXaCZY6kQJLZN6AAvXEo4NR0
+p01zDvGibVk3z87R98IJHlDPU3NrljxxMCsaUxFEAjae4eS4j8G2TFm6DsTVTeqy
+zveh4NdZFsZSyUN8blChFC/7TytlizeSGNlXLMx8e/VAcxIw+wQPWLk5pNnk3TXu
+HcqwAryW/lt46+iVeTpF4ylFqYyab6Vmf9Vp6+HVatg7YkErJACeoeN4eRv6DfeY
+slMqa2i+W+veVAGP4VApg7iZE5RnNPPHn/80yATKAe0/AztoZpQWZ5g1IAnpCISg
+k65FHVhbkcKdjNQePOGwjictq21KaYFrbXfIwqpejxSqQdLMne02Dj/2kv0dU1jV
+JG9YxVWIpobauYD5mmZvN6PTYJWGQRAsIFFyWfhvnEiohGmVLNEQ3uRaue0yNMXc
+V2t8B81/jNGXwi06qxmjCMnMhucSCSFl2a2V5oiDEcVj4YbaJ+CEJPdopMhQwqab
+EgTkJBeEXoPFenToSIprL/YiuBNvvPETyTYN+hAXh3P7MSeWewkgGhpZhuyzT8F0
+vEo+nt5WhRWl0pEVLFLiOOXR+/LAB3aqrPEdd0NXvxiCb/QaZnCp
+-----END CERTIFICATE-----
diff --git a/Cronet/apex/manifest.json b/Cronet/apex/manifest.json
new file mode 100644
index 0000000..0301e9f
--- /dev/null
+++ b/Cronet/apex/manifest.json
@@ -0,0 +1,4 @@
+{
+ "name": "com.android.cronet",
+ "version": 1
+}
diff --git a/Cronet/api/current.txt b/Cronet/api/current.txt
new file mode 100644
index 0000000..21779bc
--- /dev/null
+++ b/Cronet/api/current.txt
@@ -0,0 +1,175 @@
+// Signature format: 2.0
+package org.chromium.net {
+
+ public abstract class CallbackException extends org.chromium.net.CronetException {
+ ctor protected CallbackException(String, Throwable);
+ }
+
+ public abstract class CronetEngine {
+ ctor public CronetEngine();
+ method public abstract java.net.URLStreamHandlerFactory createURLStreamHandlerFactory();
+ method public abstract byte[] getGlobalMetricsDeltas();
+ method public abstract String getVersionString();
+ method public abstract org.chromium.net.UrlRequest.Builder newUrlRequestBuilder(String, org.chromium.net.UrlRequest.Callback, java.util.concurrent.Executor);
+ method public abstract java.net.URLConnection openConnection(java.net.URL) throws java.io.IOException;
+ method public abstract void shutdown();
+ method public abstract void startNetLogToFile(String, boolean);
+ method public abstract void stopNetLog();
+ }
+
+ public static class CronetEngine.Builder {
+ ctor public CronetEngine.Builder(android.content.Context);
+ method public org.chromium.net.CronetEngine.Builder addPublicKeyPins(String, java.util.Set<byte[]>, boolean, java.util.Date);
+ method public org.chromium.net.CronetEngine.Builder addQuicHint(String, int, int);
+ method public org.chromium.net.CronetEngine build();
+ method public org.chromium.net.CronetEngine.Builder enableBrotli(boolean);
+ method public org.chromium.net.CronetEngine.Builder enableHttp2(boolean);
+ method public org.chromium.net.CronetEngine.Builder enableHttpCache(int, long);
+ method public org.chromium.net.CronetEngine.Builder enablePublicKeyPinningBypassForLocalTrustAnchors(boolean);
+ method public org.chromium.net.CronetEngine.Builder enableQuic(boolean);
+ method public String getDefaultUserAgent();
+ method public org.chromium.net.CronetEngine.Builder setLibraryLoader(org.chromium.net.CronetEngine.Builder.LibraryLoader);
+ method public org.chromium.net.CronetEngine.Builder setStoragePath(String);
+ method public org.chromium.net.CronetEngine.Builder setUserAgent(String);
+ field public static final int HTTP_CACHE_DISABLED = 0; // 0x0
+ field public static final int HTTP_CACHE_DISK = 3; // 0x3
+ field public static final int HTTP_CACHE_DISK_NO_HTTP = 2; // 0x2
+ field public static final int HTTP_CACHE_IN_MEMORY = 1; // 0x1
+ }
+
+ public abstract static class CronetEngine.Builder.LibraryLoader {
+ ctor public CronetEngine.Builder.LibraryLoader();
+ method public abstract void loadLibrary(String);
+ }
+
+ public abstract class CronetException extends java.io.IOException {
+ ctor protected CronetException(String, Throwable);
+ }
+
+ public final class InlineExecutionProhibitedException extends java.util.concurrent.RejectedExecutionException {
+ ctor public InlineExecutionProhibitedException();
+ }
+
+ public abstract class NetworkException extends org.chromium.net.CronetException {
+ ctor protected NetworkException(String, Throwable);
+ method public abstract int getCronetInternalErrorCode();
+ method public abstract int getErrorCode();
+ method public abstract boolean immediatelyRetryable();
+ field public static final int ERROR_ADDRESS_UNREACHABLE = 9; // 0x9
+ field public static final int ERROR_CONNECTION_CLOSED = 5; // 0x5
+ field public static final int ERROR_CONNECTION_REFUSED = 7; // 0x7
+ field public static final int ERROR_CONNECTION_RESET = 8; // 0x8
+ field public static final int ERROR_CONNECTION_TIMED_OUT = 6; // 0x6
+ field public static final int ERROR_HOSTNAME_NOT_RESOLVED = 1; // 0x1
+ field public static final int ERROR_INTERNET_DISCONNECTED = 2; // 0x2
+ field public static final int ERROR_NETWORK_CHANGED = 3; // 0x3
+ field public static final int ERROR_OTHER = 11; // 0xb
+ field public static final int ERROR_QUIC_PROTOCOL_FAILED = 10; // 0xa
+ field public static final int ERROR_TIMED_OUT = 4; // 0x4
+ }
+
+ public abstract class QuicException extends org.chromium.net.NetworkException {
+ ctor protected QuicException(String, Throwable);
+ method public abstract int getQuicDetailedErrorCode();
+ }
+
+ public abstract class UploadDataProvider implements java.io.Closeable {
+ ctor public UploadDataProvider();
+ method public void close() throws java.io.IOException;
+ method public abstract long getLength() throws java.io.IOException;
+ method public abstract void read(org.chromium.net.UploadDataSink, java.nio.ByteBuffer) throws java.io.IOException;
+ method public abstract void rewind(org.chromium.net.UploadDataSink) throws java.io.IOException;
+ }
+
+ public final class UploadDataProviders {
+ method public static org.chromium.net.UploadDataProvider create(java.io.File);
+ method public static org.chromium.net.UploadDataProvider create(android.os.ParcelFileDescriptor);
+ method public static org.chromium.net.UploadDataProvider create(java.nio.ByteBuffer);
+ method public static org.chromium.net.UploadDataProvider create(byte[], int, int);
+ method public static org.chromium.net.UploadDataProvider create(byte[]);
+ }
+
+ public abstract class UploadDataSink {
+ ctor public UploadDataSink();
+ method public abstract void onReadError(Exception);
+ method public abstract void onReadSucceeded(boolean);
+ method public abstract void onRewindError(Exception);
+ method public abstract void onRewindSucceeded();
+ }
+
+ public abstract class UrlRequest {
+ ctor public UrlRequest();
+ method public abstract void cancel();
+ method public abstract void followRedirect();
+ method public abstract void getStatus(org.chromium.net.UrlRequest.StatusListener);
+ method public abstract boolean isDone();
+ method public abstract void read(java.nio.ByteBuffer);
+ method public abstract void start();
+ }
+
+ public abstract static class UrlRequest.Builder {
+ ctor public UrlRequest.Builder();
+ method public abstract org.chromium.net.UrlRequest.Builder addHeader(String, String);
+ method public abstract org.chromium.net.UrlRequest.Builder allowDirectExecutor();
+ method public abstract org.chromium.net.UrlRequest build();
+ method public abstract org.chromium.net.UrlRequest.Builder disableCache();
+ method public abstract org.chromium.net.UrlRequest.Builder setHttpMethod(String);
+ method public abstract org.chromium.net.UrlRequest.Builder setPriority(int);
+ method public abstract org.chromium.net.UrlRequest.Builder setUploadDataProvider(org.chromium.net.UploadDataProvider, java.util.concurrent.Executor);
+ field public static final int REQUEST_PRIORITY_HIGHEST = 4; // 0x4
+ field public static final int REQUEST_PRIORITY_IDLE = 0; // 0x0
+ field public static final int REQUEST_PRIORITY_LOW = 2; // 0x2
+ field public static final int REQUEST_PRIORITY_LOWEST = 1; // 0x1
+ field public static final int REQUEST_PRIORITY_MEDIUM = 3; // 0x3
+ }
+
+ public abstract static class UrlRequest.Callback {
+ ctor public UrlRequest.Callback();
+ method public void onCanceled(org.chromium.net.UrlRequest, org.chromium.net.UrlResponseInfo);
+ method public abstract void onFailed(org.chromium.net.UrlRequest, org.chromium.net.UrlResponseInfo, org.chromium.net.CronetException);
+ method public abstract void onReadCompleted(org.chromium.net.UrlRequest, org.chromium.net.UrlResponseInfo, java.nio.ByteBuffer) throws java.lang.Exception;
+ method public abstract void onRedirectReceived(org.chromium.net.UrlRequest, org.chromium.net.UrlResponseInfo, String) throws java.lang.Exception;
+ method public abstract void onResponseStarted(org.chromium.net.UrlRequest, org.chromium.net.UrlResponseInfo) throws java.lang.Exception;
+ method public abstract void onSucceeded(org.chromium.net.UrlRequest, org.chromium.net.UrlResponseInfo);
+ }
+
+ public static class UrlRequest.Status {
+ field public static final int CONNECTING = 10; // 0xa
+ field public static final int DOWNLOADING_PAC_FILE = 5; // 0x5
+ field public static final int ESTABLISHING_PROXY_TUNNEL = 8; // 0x8
+ field public static final int IDLE = 0; // 0x0
+ field public static final int INVALID = -1; // 0xffffffff
+ field public static final int READING_RESPONSE = 14; // 0xe
+ field public static final int RESOLVING_HOST = 9; // 0x9
+ field public static final int RESOLVING_HOST_IN_PAC_FILE = 7; // 0x7
+ field public static final int RESOLVING_PROXY_FOR_URL = 6; // 0x6
+ field public static final int SENDING_REQUEST = 12; // 0xc
+ field public static final int SSL_HANDSHAKE = 11; // 0xb
+ field public static final int WAITING_FOR_AVAILABLE_SOCKET = 2; // 0x2
+ field public static final int WAITING_FOR_CACHE = 4; // 0x4
+ field public static final int WAITING_FOR_DELEGATE = 3; // 0x3
+ field public static final int WAITING_FOR_RESPONSE = 13; // 0xd
+ field public static final int WAITING_FOR_STALLED_SOCKET_POOL = 1; // 0x1
+ }
+
+ public abstract static class UrlRequest.StatusListener {
+ ctor public UrlRequest.StatusListener();
+ method public abstract void onStatus(int);
+ }
+
+ public abstract class UrlResponseInfo {
+ ctor public UrlResponseInfo();
+ method public abstract java.util.Map<java.lang.String,java.util.List<java.lang.String>> getAllHeaders();
+ method public abstract java.util.List<java.util.Map.Entry<java.lang.String,java.lang.String>> getAllHeadersAsList();
+ method public abstract int getHttpStatusCode();
+ method public abstract String getHttpStatusText();
+ method public abstract String getNegotiatedProtocol();
+ method public abstract String getProxyServer();
+ method public abstract long getReceivedByteCount();
+ method public abstract String getUrl();
+ method public abstract java.util.List<java.lang.String> getUrlChain();
+ method public abstract boolean wasCached();
+ }
+
+}
+
diff --git a/Cronet/api/lint-baseline.txt b/Cronet/api/lint-baseline.txt
new file mode 100644
index 0000000..0e2f25b
--- /dev/null
+++ b/Cronet/api/lint-baseline.txt
@@ -0,0 +1,263 @@
+// Baseline format: 1.0
+AcronymName: org.chromium.net.CronetEngine#createURLStreamHandlerFactory():
+ Acronyms should not be capitalized in method names: was `createURLStreamHandlerFactory`, should this be `createUrlStreamHandlerFactory`?
+
+
+AndroidUri: org.chromium.net.CronetEngine#createURLStreamHandlerFactory():
+ Use android.net.Uri instead of java.net.URL (method org.chromium.net.CronetEngine.createURLStreamHandlerFactory())
+AndroidUri: org.chromium.net.CronetEngine#openConnection(java.net.URL):
+ Use android.net.Uri instead of java.net.URL (method org.chromium.net.CronetEngine.openConnection(java.net.URL))
+AndroidUri: org.chromium.net.CronetEngine#openConnection(java.net.URL) parameter #0:
+ Use android.net.Uri instead of java.net.URL (parameter url in org.chromium.net.CronetEngine.openConnection(java.net.URL url))
+
+
+BuilderSetStyle: org.chromium.net.CronetEngine.Builder#enableBrotli(boolean):
+ Builder methods names should use setFoo() / addFoo() / clearFoo() style: method org.chromium.net.CronetEngine.Builder.enableBrotli(boolean)
+BuilderSetStyle: org.chromium.net.CronetEngine.Builder#enableHttp2(boolean):
+ Builder methods names should use setFoo() / addFoo() / clearFoo() style: method org.chromium.net.CronetEngine.Builder.enableHttp2(boolean)
+BuilderSetStyle: org.chromium.net.CronetEngine.Builder#enableHttpCache(int, long):
+ Builder methods names should use setFoo() / addFoo() / clearFoo() style: method org.chromium.net.CronetEngine.Builder.enableHttpCache(int,long)
+BuilderSetStyle: org.chromium.net.CronetEngine.Builder#enablePublicKeyPinningBypassForLocalTrustAnchors(boolean):
+ Builder methods names should use setFoo() / addFoo() / clearFoo() style: method org.chromium.net.CronetEngine.Builder.enablePublicKeyPinningBypassForLocalTrustAnchors(boolean)
+BuilderSetStyle: org.chromium.net.CronetEngine.Builder#enableQuic(boolean):
+ Builder methods names should use setFoo() / addFoo() / clearFoo() style: method org.chromium.net.CronetEngine.Builder.enableQuic(boolean)
+BuilderSetStyle: org.chromium.net.UrlRequest.Builder#allowDirectExecutor():
+ Builder methods names should use setFoo() / addFoo() / clearFoo() style: method org.chromium.net.UrlRequest.Builder.allowDirectExecutor()
+BuilderSetStyle: org.chromium.net.UrlRequest.Builder#disableCache():
+ Builder methods names should use setFoo() / addFoo() / clearFoo() style: method org.chromium.net.UrlRequest.Builder.disableCache()
+
+
+ExecutorRegistration: org.chromium.net.UrlRequest#getStatus(org.chromium.net.UrlRequest.StatusListener):
+ Registration methods should have overload that accepts delivery Executor: `getStatus`
+
+
+GenericException: org.chromium.net.UrlRequest.Callback#onReadCompleted(org.chromium.net.UrlRequest, org.chromium.net.UrlResponseInfo, java.nio.ByteBuffer):
+ Methods must not throw generic exceptions (`java.lang.Exception`)
+GenericException: org.chromium.net.UrlRequest.Callback#onRedirectReceived(org.chromium.net.UrlRequest, org.chromium.net.UrlResponseInfo, String):
+ Methods must not throw generic exceptions (`java.lang.Exception`)
+GenericException: org.chromium.net.UrlRequest.Callback#onResponseStarted(org.chromium.net.UrlRequest, org.chromium.net.UrlResponseInfo):
+ Methods must not throw generic exceptions (`java.lang.Exception`)
+
+
+GetterOnBuilder: org.chromium.net.CronetEngine.Builder#getDefaultUserAgent():
+ Getter should be on the built object, not the builder: method org.chromium.net.CronetEngine.Builder.getDefaultUserAgent()
+
+
+ListenerInterface: org.chromium.net.UrlRequest.StatusListener:
+ Listeners should be an interface, or otherwise renamed Callback: StatusListener
+
+
+ListenerLast: org.chromium.net.CronetEngine#newUrlRequestBuilder(String, org.chromium.net.UrlRequest.Callback, java.util.concurrent.Executor) parameter #2:
+ Listeners should always be at end of argument list (method `newUrlRequestBuilder`)
+
+
+MissingGetterMatchingBuilder: org.chromium.net.CronetEngine.Builder#addPublicKeyPins(String, java.util.Set<byte[]>, boolean, java.util.Date):
+ org.chromium.net.CronetEngine does not declare a `getPublicKeyPinss()` method matching method org.chromium.net.CronetEngine.Builder.addPublicKeyPins(String,java.util.Set<byte[]>,boolean,java.util.Date)
+MissingGetterMatchingBuilder: org.chromium.net.CronetEngine.Builder#addQuicHint(String, int, int):
+ org.chromium.net.CronetEngine does not declare a `getQuicHints()` method matching method org.chromium.net.CronetEngine.Builder.addQuicHint(String,int,int)
+MissingGetterMatchingBuilder: org.chromium.net.CronetEngine.Builder#setLibraryLoader(org.chromium.net.CronetEngine.Builder.LibraryLoader):
+ org.chromium.net.CronetEngine does not declare a `getLibraryLoader()` method matching method org.chromium.net.CronetEngine.Builder.setLibraryLoader(org.chromium.net.CronetEngine.Builder.LibraryLoader)
+MissingGetterMatchingBuilder: org.chromium.net.CronetEngine.Builder#setStoragePath(String):
+ org.chromium.net.CronetEngine does not declare a `getStoragePath()` method matching method org.chromium.net.CronetEngine.Builder.setStoragePath(String)
+MissingGetterMatchingBuilder: org.chromium.net.CronetEngine.Builder#setUserAgent(String):
+ org.chromium.net.CronetEngine does not declare a `getUserAgent()` method matching method org.chromium.net.CronetEngine.Builder.setUserAgent(String)
+MissingGetterMatchingBuilder: org.chromium.net.UrlRequest.Builder#addHeader(String, String):
+ org.chromium.net.UrlRequest does not declare a `getHeaders()` method matching method org.chromium.net.UrlRequest.Builder.addHeader(String,String)
+MissingGetterMatchingBuilder: org.chromium.net.UrlRequest.Builder#setHttpMethod(String):
+ org.chromium.net.UrlRequest does not declare a `getHttpMethod()` method matching method org.chromium.net.UrlRequest.Builder.setHttpMethod(String)
+MissingGetterMatchingBuilder: org.chromium.net.UrlRequest.Builder#setPriority(int):
+ org.chromium.net.UrlRequest does not declare a `getPriority()` method matching method org.chromium.net.UrlRequest.Builder.setPriority(int)
+MissingGetterMatchingBuilder: org.chromium.net.UrlRequest.Builder#setUploadDataProvider(org.chromium.net.UploadDataProvider, java.util.concurrent.Executor):
+ org.chromium.net.UrlRequest does not declare a `getUploadDataProvider()` method matching method org.chromium.net.UrlRequest.Builder.setUploadDataProvider(org.chromium.net.UploadDataProvider,java.util.concurrent.Executor)
+
+
+MissingNullability: org.chromium.net.CallbackException#CallbackException(String, Throwable) parameter #0:
+ Missing nullability on parameter `message` in method `CallbackException`
+MissingNullability: org.chromium.net.CallbackException#CallbackException(String, Throwable) parameter #1:
+ Missing nullability on parameter `cause` in method `CallbackException`
+MissingNullability: org.chromium.net.CronetEngine#createURLStreamHandlerFactory():
+ Missing nullability on method `createURLStreamHandlerFactory` return
+MissingNullability: org.chromium.net.CronetEngine#getGlobalMetricsDeltas():
+ Missing nullability on method `getGlobalMetricsDeltas` return
+MissingNullability: org.chromium.net.CronetEngine#getVersionString():
+ Missing nullability on method `getVersionString` return
+MissingNullability: org.chromium.net.CronetEngine#newUrlRequestBuilder(String, org.chromium.net.UrlRequest.Callback, java.util.concurrent.Executor):
+ Missing nullability on method `newUrlRequestBuilder` return
+MissingNullability: org.chromium.net.CronetEngine#newUrlRequestBuilder(String, org.chromium.net.UrlRequest.Callback, java.util.concurrent.Executor) parameter #0:
+ Missing nullability on parameter `url` in method `newUrlRequestBuilder`
+MissingNullability: org.chromium.net.CronetEngine#newUrlRequestBuilder(String, org.chromium.net.UrlRequest.Callback, java.util.concurrent.Executor) parameter #1:
+ Missing nullability on parameter `callback` in method `newUrlRequestBuilder`
+MissingNullability: org.chromium.net.CronetEngine#newUrlRequestBuilder(String, org.chromium.net.UrlRequest.Callback, java.util.concurrent.Executor) parameter #2:
+ Missing nullability on parameter `executor` in method `newUrlRequestBuilder`
+MissingNullability: org.chromium.net.CronetEngine#openConnection(java.net.URL):
+ Missing nullability on method `openConnection` return
+MissingNullability: org.chromium.net.CronetEngine#openConnection(java.net.URL) parameter #0:
+ Missing nullability on parameter `url` in method `openConnection`
+MissingNullability: org.chromium.net.CronetEngine#startNetLogToFile(String, boolean) parameter #0:
+ Missing nullability on parameter `fileName` in method `startNetLogToFile`
+MissingNullability: org.chromium.net.CronetEngine.Builder#Builder(android.content.Context) parameter #0:
+ Missing nullability on parameter `context` in method `Builder`
+MissingNullability: org.chromium.net.CronetEngine.Builder#addPublicKeyPins(String, java.util.Set<byte[]>, boolean, java.util.Date):
+ Missing nullability on method `addPublicKeyPins` return
+MissingNullability: org.chromium.net.CronetEngine.Builder#addPublicKeyPins(String, java.util.Set<byte[]>, boolean, java.util.Date) parameter #0:
+ Missing nullability on parameter `hostName` in method `addPublicKeyPins`
+MissingNullability: org.chromium.net.CronetEngine.Builder#addPublicKeyPins(String, java.util.Set<byte[]>, boolean, java.util.Date) parameter #1:
+ Missing nullability on parameter `pinsSha256` in method `addPublicKeyPins`
+MissingNullability: org.chromium.net.CronetEngine.Builder#addPublicKeyPins(String, java.util.Set<byte[]>, boolean, java.util.Date) parameter #3:
+ Missing nullability on parameter `expirationDate` in method `addPublicKeyPins`
+MissingNullability: org.chromium.net.CronetEngine.Builder#addQuicHint(String, int, int):
+ Missing nullability on method `addQuicHint` return
+MissingNullability: org.chromium.net.CronetEngine.Builder#addQuicHint(String, int, int) parameter #0:
+ Missing nullability on parameter `host` in method `addQuicHint`
+MissingNullability: org.chromium.net.CronetEngine.Builder#build():
+ Missing nullability on method `build` return
+MissingNullability: org.chromium.net.CronetEngine.Builder#enableBrotli(boolean):
+ Missing nullability on method `enableBrotli` return
+MissingNullability: org.chromium.net.CronetEngine.Builder#enableHttp2(boolean):
+ Missing nullability on method `enableHttp2` return
+MissingNullability: org.chromium.net.CronetEngine.Builder#enableHttpCache(int, long):
+ Missing nullability on method `enableHttpCache` return
+MissingNullability: org.chromium.net.CronetEngine.Builder#enablePublicKeyPinningBypassForLocalTrustAnchors(boolean):
+ Missing nullability on method `enablePublicKeyPinningBypassForLocalTrustAnchors` return
+MissingNullability: org.chromium.net.CronetEngine.Builder#enableQuic(boolean):
+ Missing nullability on method `enableQuic` return
+MissingNullability: org.chromium.net.CronetEngine.Builder#getDefaultUserAgent():
+ Missing nullability on method `getDefaultUserAgent` return
+MissingNullability: org.chromium.net.CronetEngine.Builder#setLibraryLoader(org.chromium.net.CronetEngine.Builder.LibraryLoader):
+ Missing nullability on method `setLibraryLoader` return
+MissingNullability: org.chromium.net.CronetEngine.Builder#setLibraryLoader(org.chromium.net.CronetEngine.Builder.LibraryLoader) parameter #0:
+ Missing nullability on parameter `loader` in method `setLibraryLoader`
+MissingNullability: org.chromium.net.CronetEngine.Builder#setStoragePath(String):
+ Missing nullability on method `setStoragePath` return
+MissingNullability: org.chromium.net.CronetEngine.Builder#setStoragePath(String) parameter #0:
+ Missing nullability on parameter `value` in method `setStoragePath`
+MissingNullability: org.chromium.net.CronetEngine.Builder#setUserAgent(String):
+ Missing nullability on method `setUserAgent` return
+MissingNullability: org.chromium.net.CronetEngine.Builder#setUserAgent(String) parameter #0:
+ Missing nullability on parameter `userAgent` in method `setUserAgent`
+MissingNullability: org.chromium.net.CronetEngine.Builder.LibraryLoader#loadLibrary(String) parameter #0:
+ Missing nullability on parameter `libName` in method `loadLibrary`
+MissingNullability: org.chromium.net.CronetException#CronetException(String, Throwable) parameter #0:
+ Missing nullability on parameter `message` in method `CronetException`
+MissingNullability: org.chromium.net.CronetException#CronetException(String, Throwable) parameter #1:
+ Missing nullability on parameter `cause` in method `CronetException`
+MissingNullability: org.chromium.net.NetworkException#NetworkException(String, Throwable) parameter #0:
+ Missing nullability on parameter `message` in method `NetworkException`
+MissingNullability: org.chromium.net.NetworkException#NetworkException(String, Throwable) parameter #1:
+ Missing nullability on parameter `cause` in method `NetworkException`
+MissingNullability: org.chromium.net.QuicException#QuicException(String, Throwable) parameter #0:
+ Missing nullability on parameter `message` in method `QuicException`
+MissingNullability: org.chromium.net.QuicException#QuicException(String, Throwable) parameter #1:
+ Missing nullability on parameter `cause` in method `QuicException`
+MissingNullability: org.chromium.net.UploadDataProvider#read(org.chromium.net.UploadDataSink, java.nio.ByteBuffer) parameter #0:
+ Missing nullability on parameter `uploadDataSink` in method `read`
+MissingNullability: org.chromium.net.UploadDataProvider#read(org.chromium.net.UploadDataSink, java.nio.ByteBuffer) parameter #1:
+ Missing nullability on parameter `byteBuffer` in method `read`
+MissingNullability: org.chromium.net.UploadDataProvider#rewind(org.chromium.net.UploadDataSink) parameter #0:
+ Missing nullability on parameter `uploadDataSink` in method `rewind`
+MissingNullability: org.chromium.net.UploadDataProviders#create(android.os.ParcelFileDescriptor):
+ Missing nullability on method `create` return
+MissingNullability: org.chromium.net.UploadDataProviders#create(android.os.ParcelFileDescriptor) parameter #0:
+ Missing nullability on parameter `fd` in method `create`
+MissingNullability: org.chromium.net.UploadDataProviders#create(byte[]):
+ Missing nullability on method `create` return
+MissingNullability: org.chromium.net.UploadDataProviders#create(byte[]) parameter #0:
+ Missing nullability on parameter `data` in method `create`
+MissingNullability: org.chromium.net.UploadDataProviders#create(byte[], int, int):
+ Missing nullability on method `create` return
+MissingNullability: org.chromium.net.UploadDataProviders#create(byte[], int, int) parameter #0:
+ Missing nullability on parameter `data` in method `create`
+MissingNullability: org.chromium.net.UploadDataProviders#create(java.io.File):
+ Missing nullability on method `create` return
+MissingNullability: org.chromium.net.UploadDataProviders#create(java.io.File) parameter #0:
+ Missing nullability on parameter `file` in method `create`
+MissingNullability: org.chromium.net.UploadDataProviders#create(java.nio.ByteBuffer):
+ Missing nullability on method `create` return
+MissingNullability: org.chromium.net.UploadDataProviders#create(java.nio.ByteBuffer) parameter #0:
+ Missing nullability on parameter `buffer` in method `create`
+MissingNullability: org.chromium.net.UploadDataSink#onReadError(Exception) parameter #0:
+ Missing nullability on parameter `exception` in method `onReadError`
+MissingNullability: org.chromium.net.UploadDataSink#onRewindError(Exception) parameter #0:
+ Missing nullability on parameter `exception` in method `onRewindError`
+MissingNullability: org.chromium.net.UrlRequest#getStatus(org.chromium.net.UrlRequest.StatusListener) parameter #0:
+ Missing nullability on parameter `listener` in method `getStatus`
+MissingNullability: org.chromium.net.UrlRequest#read(java.nio.ByteBuffer) parameter #0:
+ Missing nullability on parameter `buffer` in method `read`
+MissingNullability: org.chromium.net.UrlRequest.Builder#addHeader(String, String):
+ Missing nullability on method `addHeader` return
+MissingNullability: org.chromium.net.UrlRequest.Builder#addHeader(String, String) parameter #0:
+ Missing nullability on parameter `header` in method `addHeader`
+MissingNullability: org.chromium.net.UrlRequest.Builder#addHeader(String, String) parameter #1:
+ Missing nullability on parameter `value` in method `addHeader`
+MissingNullability: org.chromium.net.UrlRequest.Builder#allowDirectExecutor():
+ Missing nullability on method `allowDirectExecutor` return
+MissingNullability: org.chromium.net.UrlRequest.Builder#build():
+ Missing nullability on method `build` return
+MissingNullability: org.chromium.net.UrlRequest.Builder#disableCache():
+ Missing nullability on method `disableCache` return
+MissingNullability: org.chromium.net.UrlRequest.Builder#setHttpMethod(String):
+ Missing nullability on method `setHttpMethod` return
+MissingNullability: org.chromium.net.UrlRequest.Builder#setHttpMethod(String) parameter #0:
+ Missing nullability on parameter `method` in method `setHttpMethod`
+MissingNullability: org.chromium.net.UrlRequest.Builder#setPriority(int):
+ Missing nullability on method `setPriority` return
+MissingNullability: org.chromium.net.UrlRequest.Builder#setUploadDataProvider(org.chromium.net.UploadDataProvider, java.util.concurrent.Executor):
+ Missing nullability on method `setUploadDataProvider` return
+MissingNullability: org.chromium.net.UrlRequest.Builder#setUploadDataProvider(org.chromium.net.UploadDataProvider, java.util.concurrent.Executor) parameter #0:
+ Missing nullability on parameter `uploadDataProvider` in method `setUploadDataProvider`
+MissingNullability: org.chromium.net.UrlRequest.Builder#setUploadDataProvider(org.chromium.net.UploadDataProvider, java.util.concurrent.Executor) parameter #1:
+ Missing nullability on parameter `executor` in method `setUploadDataProvider`
+MissingNullability: org.chromium.net.UrlRequest.Callback#onCanceled(org.chromium.net.UrlRequest, org.chromium.net.UrlResponseInfo) parameter #0:
+ Missing nullability on parameter `request` in method `onCanceled`
+MissingNullability: org.chromium.net.UrlRequest.Callback#onCanceled(org.chromium.net.UrlRequest, org.chromium.net.UrlResponseInfo) parameter #1:
+ Missing nullability on parameter `info` in method `onCanceled`
+MissingNullability: org.chromium.net.UrlRequest.Callback#onFailed(org.chromium.net.UrlRequest, org.chromium.net.UrlResponseInfo, org.chromium.net.CronetException) parameter #0:
+ Missing nullability on parameter `request` in method `onFailed`
+MissingNullability: org.chromium.net.UrlRequest.Callback#onFailed(org.chromium.net.UrlRequest, org.chromium.net.UrlResponseInfo, org.chromium.net.CronetException) parameter #1:
+ Missing nullability on parameter `info` in method `onFailed`
+MissingNullability: org.chromium.net.UrlRequest.Callback#onFailed(org.chromium.net.UrlRequest, org.chromium.net.UrlResponseInfo, org.chromium.net.CronetException) parameter #2:
+ Missing nullability on parameter `error` in method `onFailed`
+MissingNullability: org.chromium.net.UrlRequest.Callback#onReadCompleted(org.chromium.net.UrlRequest, org.chromium.net.UrlResponseInfo, java.nio.ByteBuffer) parameter #0:
+ Missing nullability on parameter `request` in method `onReadCompleted`
+MissingNullability: org.chromium.net.UrlRequest.Callback#onReadCompleted(org.chromium.net.UrlRequest, org.chromium.net.UrlResponseInfo, java.nio.ByteBuffer) parameter #1:
+ Missing nullability on parameter `info` in method `onReadCompleted`
+MissingNullability: org.chromium.net.UrlRequest.Callback#onReadCompleted(org.chromium.net.UrlRequest, org.chromium.net.UrlResponseInfo, java.nio.ByteBuffer) parameter #2:
+ Missing nullability on parameter `byteBuffer` in method `onReadCompleted`
+MissingNullability: org.chromium.net.UrlRequest.Callback#onRedirectReceived(org.chromium.net.UrlRequest, org.chromium.net.UrlResponseInfo, String) parameter #0:
+ Missing nullability on parameter `request` in method `onRedirectReceived`
+MissingNullability: org.chromium.net.UrlRequest.Callback#onRedirectReceived(org.chromium.net.UrlRequest, org.chromium.net.UrlResponseInfo, String) parameter #1:
+ Missing nullability on parameter `info` in method `onRedirectReceived`
+MissingNullability: org.chromium.net.UrlRequest.Callback#onRedirectReceived(org.chromium.net.UrlRequest, org.chromium.net.UrlResponseInfo, String) parameter #2:
+ Missing nullability on parameter `newLocationUrl` in method `onRedirectReceived`
+MissingNullability: org.chromium.net.UrlRequest.Callback#onResponseStarted(org.chromium.net.UrlRequest, org.chromium.net.UrlResponseInfo) parameter #0:
+ Missing nullability on parameter `request` in method `onResponseStarted`
+MissingNullability: org.chromium.net.UrlRequest.Callback#onResponseStarted(org.chromium.net.UrlRequest, org.chromium.net.UrlResponseInfo) parameter #1:
+ Missing nullability on parameter `info` in method `onResponseStarted`
+MissingNullability: org.chromium.net.UrlRequest.Callback#onSucceeded(org.chromium.net.UrlRequest, org.chromium.net.UrlResponseInfo) parameter #0:
+ Missing nullability on parameter `request` in method `onSucceeded`
+MissingNullability: org.chromium.net.UrlRequest.Callback#onSucceeded(org.chromium.net.UrlRequest, org.chromium.net.UrlResponseInfo) parameter #1:
+ Missing nullability on parameter `info` in method `onSucceeded`
+MissingNullability: org.chromium.net.UrlResponseInfo#getAllHeaders():
+ Missing nullability on method `getAllHeaders` return
+MissingNullability: org.chromium.net.UrlResponseInfo#getAllHeadersAsList():
+ Missing nullability on method `getAllHeadersAsList` return
+MissingNullability: org.chromium.net.UrlResponseInfo#getHttpStatusText():
+ Missing nullability on method `getHttpStatusText` return
+MissingNullability: org.chromium.net.UrlResponseInfo#getNegotiatedProtocol():
+ Missing nullability on method `getNegotiatedProtocol` return
+MissingNullability: org.chromium.net.UrlResponseInfo#getProxyServer():
+ Missing nullability on method `getProxyServer` return
+MissingNullability: org.chromium.net.UrlResponseInfo#getUrl():
+ Missing nullability on method `getUrl` return
+MissingNullability: org.chromium.net.UrlResponseInfo#getUrlChain():
+ Missing nullability on method `getUrlChain` return
+
+
+NotCloseable: org.chromium.net.CronetEngine:
+ Classes that release resources (shutdown()) should implement AutoClosable and CloseGuard: class org.chromium.net.CronetEngine
+
+
+StaticFinalBuilder: org.chromium.net.CronetEngine.Builder:
+ Builder must be final: org.chromium.net.CronetEngine.Builder
+StaticFinalBuilder: org.chromium.net.UrlRequest.Builder:
+ Builder must be final: org.chromium.net.UrlRequest.Builder
diff --git a/Cronet/api/module-lib-current.txt b/Cronet/api/module-lib-current.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/Cronet/api/module-lib-current.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/Cronet/api/module-lib-removed.txt b/Cronet/api/module-lib-removed.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/Cronet/api/module-lib-removed.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/Cronet/api/removed.txt b/Cronet/api/removed.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/Cronet/api/removed.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/Cronet/api/system-current.txt b/Cronet/api/system-current.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/Cronet/api/system-current.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/Cronet/api/system-removed.txt b/Cronet/api/system-removed.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/Cronet/api/system-removed.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/Cronet/api/test-current.txt b/Cronet/api/test-current.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/Cronet/api/test-current.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/Cronet/api/test-removed.txt b/Cronet/api/test-removed.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/Cronet/api/test-removed.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/Cronet/jarjar-rules.txt b/Cronet/jarjar-rules.txt
new file mode 100644
index 0000000..7111ebc
--- /dev/null
+++ b/Cronet/jarjar-rules.txt
@@ -0,0 +1,3 @@
+rule androidx.** com.android.cronet.@0
+rule android.support.** com.android.cronet.@0
+
diff --git a/Cronet/prebuilt/VERSION b/Cronet/prebuilt/VERSION
new file mode 100644
index 0000000..c16ab94
--- /dev/null
+++ b/Cronet/prebuilt/VERSION
@@ -0,0 +1,4 @@
+MAJOR=80
+MINOR=0
+BUILD=3986
+PATCH=0
diff --git a/Cronet/prebuilt/api_version.txt b/Cronet/prebuilt/api_version.txt
new file mode 100644
index 0000000..48082f7
--- /dev/null
+++ b/Cronet/prebuilt/api_version.txt
@@ -0,0 +1 @@
+12
diff --git a/Cronet/prebuilt/cronet_api-src.jar b/Cronet/prebuilt/cronet_api-src.jar
new file mode 100644
index 0000000..924b877
--- /dev/null
+++ b/Cronet/prebuilt/cronet_api-src.jar
Binary files differ
diff --git a/Cronet/prebuilt/cronet_api.jar b/Cronet/prebuilt/cronet_api.jar
new file mode 100644
index 0000000..977b28d
--- /dev/null
+++ b/Cronet/prebuilt/cronet_api.jar
Binary files differ
diff --git a/Cronet/prebuilt/cronet_impl_common_java.jar b/Cronet/prebuilt/cronet_impl_common_java.jar
new file mode 100644
index 0000000..fa71bf3
--- /dev/null
+++ b/Cronet/prebuilt/cronet_impl_common_java.jar
Binary files differ
diff --git a/Cronet/prebuilt/cronet_impl_native_java.jar b/Cronet/prebuilt/cronet_impl_native_java.jar
new file mode 100644
index 0000000..4cdd6f3
--- /dev/null
+++ b/Cronet/prebuilt/cronet_impl_native_java.jar
Binary files differ
diff --git a/Cronet/prebuilt/cronet_impl_platform_java.jar b/Cronet/prebuilt/cronet_impl_platform_java.jar
new file mode 100644
index 0000000..6d6042f
--- /dev/null
+++ b/Cronet/prebuilt/cronet_impl_platform_java.jar
Binary files differ
diff --git a/Cronet/prebuilt/libs/arm64-v8a/libcronet.107.0.5284.2.so b/Cronet/prebuilt/libs/arm64-v8a/libcronet.107.0.5284.2.so
new file mode 100644
index 0000000..7f2540a
--- /dev/null
+++ b/Cronet/prebuilt/libs/arm64-v8a/libcronet.107.0.5284.2.so
Binary files differ
diff --git a/Cronet/prebuilt/libs/armeabi-v7a/libcronet.107.0.5284.2.so b/Cronet/prebuilt/libs/armeabi-v7a/libcronet.107.0.5284.2.so
new file mode 100644
index 0000000..115429a
--- /dev/null
+++ b/Cronet/prebuilt/libs/armeabi-v7a/libcronet.107.0.5284.2.so
Binary files differ
diff --git a/Cronet/prebuilt/libs/x86/libcronet.107.0.5284.2.so b/Cronet/prebuilt/libs/x86/libcronet.107.0.5284.2.so
new file mode 100644
index 0000000..27923f7
--- /dev/null
+++ b/Cronet/prebuilt/libs/x86/libcronet.107.0.5284.2.so
Binary files differ
diff --git a/Cronet/prebuilt/libs/x86_64/libcronet.107.0.5284.2.so b/Cronet/prebuilt/libs/x86_64/libcronet.107.0.5284.2.so
new file mode 100644
index 0000000..803e5cd
--- /dev/null
+++ b/Cronet/prebuilt/libs/x86_64/libcronet.107.0.5284.2.so
Binary files differ
diff --git a/Cronet/tests/apitest/Android.bp b/Cronet/tests/apitest/Android.bp
new file mode 100644
index 0000000..e71c707
--- /dev/null
+++ b/Cronet/tests/apitest/Android.bp
@@ -0,0 +1,46 @@
+//
+// 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 {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+java_library {
+ name: "CronetApiCommonTests",
+ srcs: ["src/**/*.java"],
+ static_libs: [
+ "androidx.test.rules",
+ "androidx.core_core",
+ "junit",
+ ],
+ libs: [
+ "android.test.runner",
+ "android.test.base",
+ "android.test.mock",
+ "androidx.annotation_annotation",
+ "framework-cronet",
+ ],
+}
+
+android_test {
+ name: "CronetApiTest",
+ sdk_version: "test_current",
+ test_suites: ["device-tests"],
+ certificate: "platform",
+ static_libs: [
+ "CronetApiCommonTests",
+ ],
+}
diff --git a/Cronet/tests/apitest/AndroidManifest.xml b/Cronet/tests/apitest/AndroidManifest.xml
new file mode 100644
index 0000000..db0f0b3
--- /dev/null
+++ b/Cronet/tests/apitest/AndroidManifest.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * 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.
+ */
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="org.chromium.net.test">
+
+ <uses-permission android:name="android.permission.INTERNET"/>
+ <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+
+ <application>
+ <uses-library android:name="android.test.runner" />
+ <uses-library android:name="framework-cronet" />
+ </application>
+
+ <instrumentation
+ android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:targetPackage="org.chromium.net.test"
+ android:label="Cronet API Networking Tests" />
+</manifest>
\ No newline at end of file
diff --git a/Cronet/tests/apitest/src/org/chromium/net/test/CronetApiTest.java b/Cronet/tests/apitest/src/org/chromium/net/test/CronetApiTest.java
new file mode 100644
index 0000000..86f2173
--- /dev/null
+++ b/Cronet/tests/apitest/src/org/chromium/net/test/CronetApiTest.java
@@ -0,0 +1,144 @@
+/*
+ * 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 org.chromium.net.test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.os.Handler;
+import android.os.Looper;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.test.platform.app.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import java.nio.ByteBuffer;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Executor;
+import java.util.concurrent.TimeUnit;
+import java.util.Random;
+
+import org.chromium.net.CronetEngine;
+import org.chromium.net.CronetException;
+import org.chromium.net.UrlRequest;
+import org.chromium.net.UrlResponseInfo;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class CronetApiTest {
+ private static final String TAG = CronetApiTest.class.getSimpleName();
+ static final String HTTPS_PREFIX = "https://";
+ static final int TIMEOUT_MS = 12_000;
+
+ private final String[] mTestDomains = {"www.google.com", "www.android.com"};
+ @NonNull
+ private CronetEngine mCronetEngine;
+ @NonNull
+ private ConnectivityManager mCm;
+ @NonNull
+ private Executor mExecutor;
+
+ @Before
+ public void setUp() throws Exception {
+ Context context = InstrumentationRegistry.getInstrumentation().getContext();
+ mCm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
+ CronetEngine.Builder builder = new CronetEngine.Builder(context);
+ builder.enableHttpCache(CronetEngine.Builder.HTTP_CACHE_IN_MEMORY, 100 * 1024)
+ .enableHttp2(true)
+ //.enableBrotli(true)
+ .enableQuic(true);
+ mCronetEngine = builder.build();
+ mExecutor = new Handler(Looper.getMainLooper())::post;
+ }
+
+ static private void assertGreaterThan(String msg, int first, int second) {
+ assertTrue(msg + " Excepted " + first + " to be greater than " + second, first > second);
+ }
+
+ private void assertHasTestableNetworks() {
+ assertNotNull("This test requires a working Internet connection",
+ mCm.getActiveNetwork());
+ }
+
+ private String getRandomDomain() {
+ int index = (new Random()).nextInt(mTestDomains.length);
+ return mTestDomains[index];
+ }
+
+ class VerifyUrlRequestCallback extends UrlRequest.Callback {
+ private final CountDownLatch mLatch = new CountDownLatch(1);
+ private final String mUrl;
+
+ VerifyUrlRequestCallback(@NonNull String url) {
+ this.mUrl = url;
+ }
+
+ public boolean waitForAnswer() throws InterruptedException {
+ return mLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS);
+ }
+
+ @Override
+ public void onRedirectReceived(
+ UrlRequest request, UrlResponseInfo info, String newLocationUrl) {
+ request.followRedirect();
+ }
+
+ @Override
+ public void onResponseStarted(UrlRequest request, UrlResponseInfo info) {
+ request.read(ByteBuffer.allocateDirect(32 * 1024));
+ }
+
+ @Override
+ public void onReadCompleted(
+ UrlRequest request, UrlResponseInfo info, ByteBuffer byteBuffer) {
+ byteBuffer.clear();
+ request.read(byteBuffer);
+ }
+
+
+ @Override
+ public void onSucceeded(UrlRequest request, UrlResponseInfo info) {
+ assertEquals("Unexpected http status code from " + mUrl + ".",
+ 200, info.getHttpStatusCode());
+ assertGreaterThan("Received byte from " + mUrl + " is 0.",
+ (int)info.getReceivedByteCount(), 0);
+ mLatch.countDown();
+ }
+
+ @Override
+ public void onFailed(UrlRequest request, UrlResponseInfo info, CronetException error) {
+ fail(mUrl + error.getMessage());
+ }
+ }
+
+ @Test
+ public void testUrlGet() throws Exception {
+ assertHasTestableNetworks();
+ String url = HTTPS_PREFIX + getRandomDomain();
+ VerifyUrlRequestCallback callback = new VerifyUrlRequestCallback(url);
+ UrlRequest.Builder builder = mCronetEngine.newUrlRequestBuilder(url, callback, mExecutor);
+ builder.build().start();
+ assertTrue(url + " but not complete after " + TIMEOUT_MS + "ms.",
+ callback.waitForAnswer());
+ }
+
+}
diff --git a/OWNERS_core_networking b/OWNERS_core_networking
index bc1d002..3a08422 100644
--- a/OWNERS_core_networking
+++ b/OWNERS_core_networking
@@ -10,6 +10,7 @@
markchien@google.com
martinwu@google.com
maze@google.com
+motomuman@google.com
nuccachen@google.com
paulhu@google.com
prohr@google.com
diff --git a/OWNERS_core_networking_xts b/OWNERS_core_networking_xts
index a6627fe..1844334 100644
--- a/OWNERS_core_networking_xts
+++ b/OWNERS_core_networking_xts
@@ -1,2 +1,7 @@
lorenzo@google.com
-satk@google.com
+satk@google.com #{LAST_RESORT_SUGGESTION}
+
+# For cherry-picks of CLs that are already merged in aosp/master, or flaky test fixes.
+jchalard@google.com #{LAST_RESORT_SUGGESTION}
+maze@google.com #{LAST_RESORT_SUGGESTION}
+reminv@google.com #{LAST_RESORT_SUGGESTION}
diff --git a/TEST_MAPPING b/TEST_MAPPING
index 1e8babf..700a085 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -135,6 +135,37 @@
}
]
},
+ // Test with APK modules only, in cases where APEX is not supported, or the other modules
+ // were simply not updated
+ {
+ "name": "CtsNetTestCasesLatestSdk[CaptivePortalLoginGoogle.apk+NetworkStackGoogle.apk]",
+ "options": [
+ {
+ "exclude-annotation": "com.android.testutils.SkipPresubmit"
+ },
+ {
+ "exclude-annotation": "androidx.test.filters.RequiresDevice"
+ },
+ {
+ "exclude-annotation": "com.android.testutils.ConnectivityModuleTest"
+ }
+ ]
+ },
+ // Test with connectivity/tethering module only, to catch integration issues with older versions
+ // of other modules. "new tethering + old NetworkStack" is not a configuration that should
+ // really exist in the field, but there is no strong guarantee, and it is required by MTS
+ // testing for module qualification, where modules are tested independently.
+ {
+ "name": "CtsNetTestCasesLatestSdk[com.google.android.tethering.apex]",
+ "options": [
+ {
+ "exclude-annotation": "com.android.testutils.SkipPresubmit"
+ },
+ {
+ "exclude-annotation": "androidx.test.filters.RequiresDevice"
+ }
+ ]
+ },
{
"name": "bpf_existence_test[CaptivePortalLoginGoogle.apk+NetworkStackGoogle.apk+com.google.android.resolv.apex+com.google.android.tethering.apex]"
},
@@ -159,38 +190,6 @@
{
"name": "CtsNetTestCasesLatestSdk[CaptivePortalLoginGoogle.apk+NetworkStackGoogle.apk+com.google.android.resolv.apex+com.google.android.tethering.apex]",
"keywords": ["sim"]
- },
- // TODO: move to mainline-presubmit when known green.
- // Test with APK modules only, in cases where APEX is not supported, or the other modules were simply not updated
- {
- "name": "CtsNetTestCasesLatestSdk[CaptivePortalLoginGoogle.apk+NetworkStackGoogle.apk]",
- "options": [
- {
- "exclude-annotation": "com.android.testutils.SkipPresubmit"
- },
- {
- "exclude-annotation": "androidx.test.filters.RequiresDevice"
- },
- {
- "exclude-annotation": "com.android.testutils.ConnectivityModuleTest"
- }
- ]
- },
- // TODO: move to mainline-presubmit when known green.
- // Test with connectivity/tethering module only, to catch integration issues with older versions of other modules.
- // "new tethering + old NetworkStack" is not a configuration that should really exist in the field, but
- // there is no strong guarantee, and it is required by MTS testing for module qualification, where modules
- // are tested independently.
- {
- "name": "CtsNetTestCasesLatestSdk[com.google.android.tethering.apex]",
- "options": [
- {
- "exclude-annotation": "com.android.testutils.SkipPresubmit"
- },
- {
- "exclude-annotation": "androidx.test.filters.RequiresDevice"
- }
- ]
}
],
"imports": [
@@ -205,6 +204,9 @@
},
{
"path": "packages/modules/CaptivePortalLogin"
+ },
+ {
+ "path": "vendor/xts/gts-tests/hostsidetests/networkstack"
}
]
}
diff --git a/Tethering/Android.bp b/Tethering/Android.bp
index f3d6aee..f203191 100644
--- a/Tethering/Android.bp
+++ b/Tethering/Android.bp
@@ -21,11 +21,30 @@
java_defaults {
name: "TetheringApiLevel",
sdk_version: "module_current",
- target_sdk_version: "33",
min_sdk_version: "30",
}
java_defaults {
+ name: "TetheringReleaseTargetSdk",
+ target_sdk_version: "33",
+}
+
+java_defaults {
+ name: "TetheringExternalLibs",
+ // Libraries not including Tethering's own framework-tethering (different flavors of that one
+ // are needed depending on the build rule)
+ libs: [
+ "framework-connectivity.stubs.module_lib",
+ "framework-connectivity-t.stubs.module_lib",
+ "framework-statsd.stubs.module_lib",
+ "framework-wifi",
+ "framework-bluetooth",
+ "unsupportedappusage",
+ ],
+ defaults_visibility: ["//visibility:private"],
+}
+
+java_defaults {
name: "TetheringAndroidLibraryDefaults",
srcs: [
"apishim/**/*.java",
@@ -51,14 +70,9 @@
"netd-client",
"tetheringstatsprotos",
],
+ defaults: ["TetheringExternalLibs"],
libs: [
- "framework-connectivity",
- "framework-connectivity-t.stubs.module_lib",
- "framework-statsd.stubs.module_lib",
"framework-tethering.impl",
- "framework-wifi",
- "framework-bluetooth",
- "unsupportedappusage",
],
plugins: ["java_api_finder"],
manifest: "AndroidManifestBase.xml",
@@ -71,7 +85,8 @@
defaults: [
"ConnectivityNextEnableDefaults",
"TetheringAndroidLibraryDefaults",
- "TetheringApiLevel"
+ "TetheringApiLevel",
+ "TetheringReleaseTargetSdk"
],
static_libs: [
"NetworkStackApiCurrentShims",
@@ -84,7 +99,8 @@
name: "TetheringApiStableLib",
defaults: [
"TetheringAndroidLibraryDefaults",
- "TetheringApiLevel"
+ "TetheringApiLevel",
+ "TetheringReleaseTargetSdk"
],
static_libs: [
"NetworkStackApiStableShims",
@@ -148,9 +164,17 @@
resource_dirs: [
"res",
],
+ // Libs are not actually needed to build here since build rules using these defaults are just
+ // packaging the TetheringApiXLibs in APKs, but they are necessary so that R8 has the right
+ // references to optimize the code. Without these, there will be missing class warnings and code
+ // may be wrongly optimized.
+ // R8 runs after jarjar, so the framework-X libraries need to be the post-jarjar artifacts
+ // (framework-tethering.impl), if they are not just stubs, so that the name of jarjared
+ // classes match.
+ // TODO(b/229727645): ensure R8 fails the build fully if libraries are missing
+ defaults: ["TetheringExternalLibs"],
libs: [
- "framework-tethering",
- "framework-wifi",
+ "framework-tethering.impl",
],
jarjar_rules: "jarjar-rules.txt",
optimize: {
@@ -162,7 +186,12 @@
// Non-updatable tethering running in the system server process for devices not using the module
android_app {
name: "InProcessTethering",
- defaults: ["TetheringAppDefaults", "TetheringApiLevel", "ConnectivityNextEnableDefaults"],
+ defaults: [
+ "TetheringAppDefaults",
+ "TetheringApiLevel",
+ "ConnectivityNextEnableDefaults",
+ "TetheringReleaseTargetSdk"
+ ],
static_libs: ["TetheringApiCurrentLib"],
certificate: "platform",
manifest: "AndroidManifest_InProcess.xml",
diff --git a/Tethering/apex/Android.bp b/Tethering/apex/Android.bp
index 3b5d6bf..c590850 100644
--- a/Tethering/apex/Android.bp
+++ b/Tethering/apex/Android.bp
@@ -54,6 +54,7 @@
name: "com.android.tethering",
defaults: [
"ConnectivityApexDefaults",
+ "CronetApexDefaults",
"r-launched-apex-module",
],
compile_multilib: "both",
@@ -128,7 +129,10 @@
filegroup {
name: "connectivity-hiddenapi-files",
- srcs: ["hiddenapi/*.txt"],
+ srcs: [
+ ":connectivity-t-hiddenapi-files",
+ "hiddenapi/*.txt",
+ ],
visibility: ["//packages/modules/Connectivity:__subpackages__"],
}
@@ -159,16 +163,11 @@
// Additional hidden API flag files to override the defaults. This must only be
// modified by the Soong or platform compat team.
hidden_api: {
- max_target_r_low_priority: [
- "hiddenapi/hiddenapi-max-target-r-loprio.txt",
- ],
max_target_o_low_priority: [
"hiddenapi/hiddenapi-max-target-o-low-priority.txt",
- "hiddenapi/hiddenapi-max-target-o-low-priority-tiramisu.txt",
],
unsupported: [
"hiddenapi/hiddenapi-unsupported.txt",
- "hiddenapi/hiddenapi-unsupported-tiramisu.txt",
],
// The following packages contain classes from other modules on the
diff --git a/Tethering/apishim/31/com/android/networkstack/tethering/apishim/api31/BpfCoordinatorShimImpl.java b/Tethering/apishim/31/com/android/networkstack/tethering/apishim/api31/BpfCoordinatorShimImpl.java
index 776832f..3cad1c6 100644
--- a/Tethering/apishim/31/com/android/networkstack/tethering/apishim/api31/BpfCoordinatorShimImpl.java
+++ b/Tethering/apishim/31/com/android/networkstack/tethering/apishim/api31/BpfCoordinatorShimImpl.java
@@ -28,7 +28,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
-import com.android.net.module.util.BpfMap;
+import com.android.net.module.util.IBpfMap;
import com.android.net.module.util.IBpfMap.ThrowingBiConsumer;
import com.android.net.module.util.SharedLog;
import com.android.net.module.util.bpf.Tether4Key;
@@ -66,31 +66,31 @@
// BPF map for downstream IPv4 forwarding.
@Nullable
- private final BpfMap<Tether4Key, Tether4Value> mBpfDownstream4Map;
+ private final IBpfMap<Tether4Key, Tether4Value> mBpfDownstream4Map;
// BPF map for upstream IPv4 forwarding.
@Nullable
- private final BpfMap<Tether4Key, Tether4Value> mBpfUpstream4Map;
+ private final IBpfMap<Tether4Key, Tether4Value> mBpfUpstream4Map;
// BPF map for downstream IPv6 forwarding.
@Nullable
- private final BpfMap<TetherDownstream6Key, Tether6Value> mBpfDownstream6Map;
+ private final IBpfMap<TetherDownstream6Key, Tether6Value> mBpfDownstream6Map;
// BPF map for upstream IPv6 forwarding.
@Nullable
- private final BpfMap<TetherUpstream6Key, Tether6Value> mBpfUpstream6Map;
+ private final IBpfMap<TetherUpstream6Key, Tether6Value> mBpfUpstream6Map;
// BPF map of tethering statistics of the upstream interface since tethering startup.
@Nullable
- private final BpfMap<TetherStatsKey, TetherStatsValue> mBpfStatsMap;
+ private final IBpfMap<TetherStatsKey, TetherStatsValue> mBpfStatsMap;
// BPF map of per-interface quota for tethering offload.
@Nullable
- private final BpfMap<TetherLimitKey, TetherLimitValue> mBpfLimitMap;
+ private final IBpfMap<TetherLimitKey, TetherLimitValue> mBpfLimitMap;
// BPF map of interface index mapping for XDP.
@Nullable
- private final BpfMap<TetherDevKey, TetherDevValue> mBpfDevMap;
+ private final IBpfMap<TetherDevKey, TetherDevValue> mBpfDevMap;
// Tracking IPv4 rule count while any rule is using the given upstream interfaces. Used for
// reducing the BPF map iteration query. The count is increased or decreased when the rule is
@@ -482,7 +482,7 @@
return true;
}
- private String mapStatus(BpfMap m, String name) {
+ private String mapStatus(IBpfMap m, String name) {
return name + "{" + (m != null ? "OK" : "ERROR") + "}";
}
diff --git a/Tethering/common/TetheringLib/src/android/net/TetheringConfigurationParcel.aidl b/Tethering/common/TetheringLib/src/android/net/TetheringConfigurationParcel.aidl
index 89f3813..168d7f9 100644
--- a/Tethering/common/TetheringLib/src/android/net/TetheringConfigurationParcel.aidl
+++ b/Tethering/common/TetheringLib/src/android/net/TetheringConfigurationParcel.aidl
@@ -21,17 +21,10 @@
* @hide
*/
parcelable TetheringConfigurationParcel {
- int subId;
String[] tetherableUsbRegexs;
String[] tetherableWifiRegexs;
String[] tetherableBluetoothRegexs;
- boolean isDunRequired;
- boolean chooseUpstreamAutomatically;
- int[] preferredUpstreamIfaceTypes;
String[] legacyDhcpRanges;
- String[] defaultIPv4DNS;
- boolean enableLegacyDhcpServer;
String[] provisioningApp;
String provisioningAppNoUi;
- int provisioningCheckPeriod;
}
diff --git a/Tethering/jni/com_android_networkstack_tethering_util_TetheringUtils.cpp b/Tethering/jni/com_android_networkstack_tethering_util_TetheringUtils.cpp
index 291bf54..6699c0d 100644
--- a/Tethering/jni/com_android_networkstack_tethering_util_TetheringUtils.cpp
+++ b/Tethering/jni/com_android_networkstack_tethering_util_TetheringUtils.cpp
@@ -49,8 +49,10 @@
BPF_STMT(BPF_LD | BPF_B | BPF_ABS, kICMPv6TypeOffset),
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, type, 0, 1),
- // Accept or reject.
+ // Accept.
BPF_STMT(BPF_RET | BPF_K, 0xffff),
+
+ // Reject.
BPF_STMT(BPF_RET | BPF_K, 0)
};
diff --git a/Tethering/proguard.flags b/Tethering/proguard.flags
index 2905e28..109bbda 100644
--- a/Tethering/proguard.flags
+++ b/Tethering/proguard.flags
@@ -1,7 +1,10 @@
# Keep class's integer static field for MessageUtils to parsing their name.
--keep class com.android.networkstack.tethering.Tethering$TetherMainSM {
- static final int CMD_*;
- static final int EVENT_*;
+-keepclassmembers class com.android.server.**,android.net.**,com.android.networkstack.** {
+ static final % POLICY_*;
+ static final % NOTIFY_TYPE_*;
+ static final % TRANSPORT_*;
+ static final % CMD_*;
+ static final % EVENT_*;
}
-keep class com.android.networkstack.tethering.util.BpfMap {
@@ -21,12 +24,8 @@
*;
}
--keepclassmembers class android.net.ip.IpServer {
- static final int CMD_*;
-}
-
# The lite proto runtime uses reflection to access fields based on the names in
# the schema, keep all the fields.
-keepclassmembers class * extends com.android.networkstack.tethering.protobuf.MessageLite {
<fields>;
-}
\ No newline at end of file
+}
diff --git a/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java b/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java
index 05a2884..6a5089d 100644
--- a/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java
+++ b/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java
@@ -60,6 +60,7 @@
import com.android.net.module.util.BpfDump;
import com.android.net.module.util.BpfMap;
import com.android.net.module.util.CollectionUtils;
+import com.android.net.module.util.IBpfMap;
import com.android.net.module.util.InterfaceParams;
import com.android.net.module.util.NetworkStackConstants;
import com.android.net.module.util.SharedLog;
@@ -320,7 +321,7 @@
}
/** Get downstream4 BPF map. */
- @Nullable public BpfMap<Tether4Key, Tether4Value> getBpfDownstream4Map() {
+ @Nullable public IBpfMap<Tether4Key, Tether4Value> getBpfDownstream4Map() {
if (!isAtLeastS()) return null;
try {
return new BpfMap<>(TETHER_DOWNSTREAM4_MAP_PATH,
@@ -332,7 +333,7 @@
}
/** Get upstream4 BPF map. */
- @Nullable public BpfMap<Tether4Key, Tether4Value> getBpfUpstream4Map() {
+ @Nullable public IBpfMap<Tether4Key, Tether4Value> getBpfUpstream4Map() {
if (!isAtLeastS()) return null;
try {
return new BpfMap<>(TETHER_UPSTREAM4_MAP_PATH,
@@ -344,7 +345,7 @@
}
/** Get downstream6 BPF map. */
- @Nullable public BpfMap<TetherDownstream6Key, Tether6Value> getBpfDownstream6Map() {
+ @Nullable public IBpfMap<TetherDownstream6Key, Tether6Value> getBpfDownstream6Map() {
if (!isAtLeastS()) return null;
try {
return new BpfMap<>(TETHER_DOWNSTREAM6_FS_PATH,
@@ -356,7 +357,7 @@
}
/** Get upstream6 BPF map. */
- @Nullable public BpfMap<TetherUpstream6Key, Tether6Value> getBpfUpstream6Map() {
+ @Nullable public IBpfMap<TetherUpstream6Key, Tether6Value> getBpfUpstream6Map() {
if (!isAtLeastS()) return null;
try {
return new BpfMap<>(TETHER_UPSTREAM6_FS_PATH, BpfMap.BPF_F_RDWR,
@@ -368,7 +369,7 @@
}
/** Get stats BPF map. */
- @Nullable public BpfMap<TetherStatsKey, TetherStatsValue> getBpfStatsMap() {
+ @Nullable public IBpfMap<TetherStatsKey, TetherStatsValue> getBpfStatsMap() {
if (!isAtLeastS()) return null;
try {
return new BpfMap<>(TETHER_STATS_MAP_PATH,
@@ -380,7 +381,7 @@
}
/** Get limit BPF map. */
- @Nullable public BpfMap<TetherLimitKey, TetherLimitValue> getBpfLimitMap() {
+ @Nullable public IBpfMap<TetherLimitKey, TetherLimitValue> getBpfLimitMap() {
if (!isAtLeastS()) return null;
try {
return new BpfMap<>(TETHER_LIMIT_MAP_PATH,
@@ -392,7 +393,7 @@
}
/** Get dev BPF map. */
- @Nullable public BpfMap<TetherDevKey, TetherDevValue> getBpfDevMap() {
+ @Nullable public IBpfMap<TetherDevKey, TetherDevValue> getBpfDevMap() {
if (!isAtLeastS()) return null;
try {
return new BpfMap<>(TETHER_DEV_MAP_PATH,
@@ -402,6 +403,18 @@
return null;
}
}
+
+ /** Get error BPF map. */
+ @Nullable public IBpfMap<S32, S32> getBpfErrorMap() {
+ if (!isAtLeastS()) return null;
+ try {
+ return new BpfMap<>(TETHER_ERROR_MAP_PATH,
+ BpfMap.BPF_F_RDONLY, S32.class, S32.class);
+ } catch (ErrnoException e) {
+ Log.e(TAG, "Cannot create error map: " + e);
+ return null;
+ }
+ }
}
@VisibleForTesting
@@ -535,6 +548,13 @@
// TODO: Wrap conntrackMonitor stopping function into mBpfCoordinatorShim.
if (!isUsingBpf() || !mDeps.isAtLeastS()) return;
+ // Ignore stopping monitoring if the monitor has never started for a given IpServer.
+ if (!mMonitoringIpServers.contains(ipServer)) {
+ mLog.e("Ignore stopping monitoring because monitoring has never started for "
+ + ipServer.interfaceName());
+ return;
+ }
+
mMonitoringIpServers.remove(ipServer);
if (!mMonitoringIpServers.isEmpty()) return;
@@ -1047,7 +1067,7 @@
}
}
private void dumpBpfStats(@NonNull IndentingPrintWriter pw) {
- try (BpfMap<TetherStatsKey, TetherStatsValue> map = mDeps.getBpfStatsMap()) {
+ try (IBpfMap<TetherStatsKey, TetherStatsValue> map = mDeps.getBpfStatsMap()) {
if (map == null) {
pw.println("No BPF stats map");
return;
@@ -1102,7 +1122,7 @@
}
private void dumpIpv6UpstreamRules(IndentingPrintWriter pw) {
- try (BpfMap<TetherUpstream6Key, Tether6Value> map = mDeps.getBpfUpstream6Map()) {
+ try (IBpfMap<TetherUpstream6Key, Tether6Value> map = mDeps.getBpfUpstream6Map()) {
if (map == null) {
pw.println("No IPv6 upstream");
return;
@@ -1130,7 +1150,7 @@
}
private void dumpIpv6DownstreamRules(IndentingPrintWriter pw) {
- try (BpfMap<TetherDownstream6Key, Tether6Value> map = mDeps.getBpfDownstream6Map()) {
+ try (IBpfMap<TetherDownstream6Key, Tether6Value> map = mDeps.getBpfDownstream6Map()) {
if (map == null) {
pw.println("No IPv6 downstream");
return;
@@ -1161,7 +1181,7 @@
pw.decreaseIndent();
}
- private <K extends Struct, V extends Struct> void dumpRawMap(BpfMap<K, V> map,
+ private <K extends Struct, V extends Struct> void dumpRawMap(IBpfMap<K, V> map,
IndentingPrintWriter pw) throws ErrnoException {
if (map == null) {
pw.println("No BPF support");
@@ -1192,7 +1212,7 @@
// expected argument order.
// TODO: dump downstream4 map.
if (CollectionUtils.contains(args, DUMPSYS_RAWMAP_ARG_STATS)) {
- try (BpfMap<TetherStatsKey, TetherStatsValue> statsMap = mDeps.getBpfStatsMap()) {
+ try (IBpfMap<TetherStatsKey, TetherStatsValue> statsMap = mDeps.getBpfStatsMap()) {
dumpRawMap(statsMap, pw);
} catch (ErrnoException | IOException e) {
pw.println("Error dumping stats map: " + e);
@@ -1200,7 +1220,7 @@
return;
}
if (CollectionUtils.contains(args, DUMPSYS_RAWMAP_ARG_UPSTREAM4)) {
- try (BpfMap<Tether4Key, Tether4Value> upstreamMap = mDeps.getBpfUpstream4Map()) {
+ try (IBpfMap<Tether4Key, Tether4Value> upstreamMap = mDeps.getBpfUpstream4Map()) {
dumpRawMap(upstreamMap, pw);
} catch (ErrnoException | IOException e) {
pw.println("Error dumping IPv4 map: " + e);
@@ -1245,7 +1265,7 @@
}
private void dumpIpv4ForwardingRuleMap(long now, boolean downstream,
- BpfMap<Tether4Key, Tether4Value> map, IndentingPrintWriter pw) throws ErrnoException {
+ IBpfMap<Tether4Key, Tether4Value> map, IndentingPrintWriter pw) throws ErrnoException {
if (map == null) {
pw.println("No IPv4 support");
return;
@@ -1260,8 +1280,8 @@
private void dumpBpfForwardingRulesIpv4(IndentingPrintWriter pw) {
final long now = SystemClock.elapsedRealtimeNanos();
- try (BpfMap<Tether4Key, Tether4Value> upstreamMap = mDeps.getBpfUpstream4Map();
- BpfMap<Tether4Key, Tether4Value> downstreamMap = mDeps.getBpfDownstream4Map()) {
+ try (IBpfMap<Tether4Key, Tether4Value> upstreamMap = mDeps.getBpfUpstream4Map();
+ IBpfMap<Tether4Key, Tether4Value> downstreamMap = mDeps.getBpfDownstream4Map()) {
pw.println("IPv4 Upstream: proto [inDstMac] iif(iface) src -> nat -> "
+ "dst [outDstMac] age");
pw.increaseIndent();
@@ -1279,13 +1299,15 @@
}
private void dumpCounters(@NonNull IndentingPrintWriter pw) {
- if (!mDeps.isAtLeastS()) {
- pw.println("No counter support");
- return;
- }
- try (BpfMap<S32, S32> map = new BpfMap<>(TETHER_ERROR_MAP_PATH, BpfMap.BPF_F_RDONLY,
- S32.class, S32.class)) {
-
+ try (IBpfMap<S32, S32> map = mDeps.getBpfErrorMap()) {
+ if (map == null) {
+ pw.println("No error counter support");
+ return;
+ }
+ if (map.isEmpty()) {
+ pw.println("<empty>");
+ return;
+ }
map.forEach((k, v) -> {
String counterName;
try {
@@ -1299,12 +1321,12 @@
if (v.val > 0) pw.println(String.format("%s: %d", counterName, v.val));
});
} catch (ErrnoException | IOException e) {
- pw.println("Error dumping counter map: " + e);
+ pw.println("Error dumping error counter map: " + e);
}
}
private void dumpDevmap(@NonNull IndentingPrintWriter pw) {
- try (BpfMap<TetherDevKey, TetherDevValue> map = mDeps.getBpfDevMap()) {
+ try (IBpfMap<TetherDevKey, TetherDevValue> map = mDeps.getBpfDevMap()) {
if (map == null) {
pw.println("No devmap support");
return;
@@ -1465,6 +1487,15 @@
// to Objects.hash() to avoid autoboxing overhead.
return Objects.hash(upstreamIfindex, downstreamIfindex, address, srcMac, dstMac);
}
+
+ @Override
+ public String toString() {
+ return "upstreamIfindex: " + upstreamIfindex
+ + ", downstreamIfindex: " + downstreamIfindex
+ + ", address: " + address.getHostAddress()
+ + ", srcMac: " + srcMac
+ + ", dstMac: " + dstMac;
+ }
}
/** Tethering client information class. */
diff --git a/Tethering/src/com/android/networkstack/tethering/TetherLimitKey.java b/Tethering/src/com/android/networkstack/tethering/TetherLimitKey.java
index a7e8ccf..68d694a 100644
--- a/Tethering/src/com/android/networkstack/tethering/TetherLimitKey.java
+++ b/Tethering/src/com/android/networkstack/tethering/TetherLimitKey.java
@@ -28,26 +28,4 @@
public TetherLimitKey(final int 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 TetherLimitKey)) return false;
-
- final TetherLimitKey that = (TetherLimitKey) obj;
-
- return ifindex == that.ifindex;
- }
-
- @Override
- public int hashCode() {
- return Integer.hashCode(ifindex);
- }
-
- @Override
- public String toString() {
- return String.format("ifindex: %d", ifindex);
- }
}
diff --git a/Tethering/src/com/android/networkstack/tethering/TetherLimitValue.java b/Tethering/src/com/android/networkstack/tethering/TetherLimitValue.java
index ed7e7d4..00dfcc6 100644
--- a/Tethering/src/com/android/networkstack/tethering/TetherLimitValue.java
+++ b/Tethering/src/com/android/networkstack/tethering/TetherLimitValue.java
@@ -32,26 +32,4 @@
public TetherLimitValue(final long limit) {
this.limit = limit;
}
-
- // 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 TetherLimitValue)) return false;
-
- final TetherLimitValue that = (TetherLimitValue) obj;
-
- return limit == that.limit;
- }
-
- @Override
- public int hashCode() {
- return Long.hashCode(limit);
- }
-
- @Override
- public String toString() {
- return String.format("limit: %d", limit);
- }
}
diff --git a/Tethering/src/com/android/networkstack/tethering/Tethering.java b/Tethering/src/com/android/networkstack/tethering/Tethering.java
index 0d1b22e..1f3fc11 100644
--- a/Tethering/src/com/android/networkstack/tethering/Tethering.java
+++ b/Tethering/src/com/android/networkstack/tethering/Tethering.java
@@ -2004,10 +2004,6 @@
return;
}
- if (arg1 == UpstreamNetworkMonitor.NOTIFY_TEST_NETWORK_AVAILABLE) {
- chooseUpstreamType(false);
- }
-
if (ns == null || !pertainsToCurrentUpstream(ns)) {
// TODO: In future, this is where upstream evaluation and selection
// could be handled for notifications which include sufficient data.
diff --git a/Tethering/src/com/android/networkstack/tethering/TetheringConfiguration.java b/Tethering/src/com/android/networkstack/tethering/TetheringConfiguration.java
index 696a970..8ef5d71 100644
--- a/Tethering/src/com/android/networkstack/tethering/TetheringConfiguration.java
+++ b/Tethering/src/com/android/networkstack/tethering/TetheringConfiguration.java
@@ -652,21 +652,13 @@
*/
public TetheringConfigurationParcel toStableParcelable() {
final TetheringConfigurationParcel parcel = new TetheringConfigurationParcel();
- parcel.subId = activeDataSubId;
parcel.tetherableUsbRegexs = tetherableUsbRegexs;
parcel.tetherableWifiRegexs = tetherableWifiRegexs;
parcel.tetherableBluetoothRegexs = tetherableBluetoothRegexs;
- parcel.isDunRequired = isDunRequired;
- parcel.chooseUpstreamAutomatically = chooseUpstreamAutomatically;
-
- parcel.preferredUpstreamIfaceTypes = toIntArray(preferredUpstreamIfaceTypes);
-
parcel.legacyDhcpRanges = legacyDhcpRanges;
- parcel.defaultIPv4DNS = defaultIPv4DNS;
- parcel.enableLegacyDhcpServer = mEnableLegacyDhcpServer;
parcel.provisioningApp = provisioningApp;
parcel.provisioningAppNoUi = provisioningAppNoUi;
- parcel.provisioningCheckPeriod = provisioningCheckPeriod;
+
return parcel;
}
}
diff --git a/Tethering/src/com/android/networkstack/tethering/UpstreamNetworkMonitor.java b/Tethering/src/com/android/networkstack/tethering/UpstreamNetworkMonitor.java
index 15df0c6..16c031b 100644
--- a/Tethering/src/com/android/networkstack/tethering/UpstreamNetworkMonitor.java
+++ b/Tethering/src/com/android/networkstack/tethering/UpstreamNetworkMonitor.java
@@ -85,12 +85,11 @@
private static final boolean DBG = false;
private static final boolean VDBG = false;
- public static final int EVENT_ON_CAPABILITIES = 1;
- public static final int EVENT_ON_LINKPROPERTIES = 2;
- public static final int EVENT_ON_LOST = 3;
- public static final int EVENT_DEFAULT_SWITCHED = 4;
- public static final int NOTIFY_LOCAL_PREFIXES = 10;
- public static final int NOTIFY_TEST_NETWORK_AVAILABLE = 11;
+ public static final int EVENT_ON_CAPABILITIES = 1;
+ public static final int EVENT_ON_LINKPROPERTIES = 2;
+ public static final int EVENT_ON_LOST = 3;
+ public static final int EVENT_DEFAULT_SWITCHED = 4;
+ public static final int NOTIFY_LOCAL_PREFIXES = 10;
// This value is used by deprecated preferredUpstreamIfaceTypes selection which is default
// disabled.
@VisibleForTesting
@@ -468,17 +467,6 @@
notifyTarget(EVENT_DEFAULT_SWITCHED, ns);
}
- private void maybeHandleTestNetwork(@NonNull Network network) {
- if (!mPreferTestNetworks) return;
-
- final UpstreamNetworkState ns = mNetworkMap.get(network);
- if (network.equals(mTetheringUpstreamNetwork) || !isTestNetwork(ns)) return;
-
- // Test network is available. Notify tethering.
- Log.d(TAG, "Handle test network: " + network);
- notifyTarget(NOTIFY_TEST_NETWORK_AVAILABLE, ns);
- }
-
private void recomputeLocalPrefixes() {
final HashSet<IpPrefix> localPrefixes = allLocalPrefixes(mNetworkMap.values());
if (!mLocalPrefixes.equals(localPrefixes)) {
@@ -561,12 +549,6 @@
// So it's not useful to do this work for non-LISTEN_ALL callbacks.
if (mCallbackType == CALLBACK_LISTEN_ALL) {
recomputeLocalPrefixes();
-
- // When the LISTEN_ALL network callback calls onLinkPropertiesChanged, it means that
- // all the network information for the network is known (because
- // onLinkPropertiesChanged is called after onAvailable and onCapabilitiesChanged).
- // Inform tethering that the test network might have changed.
- maybeHandleTestNetwork(network);
}
}
diff --git a/Tethering/src/com/android/networkstack/tethering/metrics/TetheringMetrics.java b/Tethering/src/com/android/networkstack/tethering/metrics/TetheringMetrics.java
index d8e631e..ffcea4e 100644
--- a/Tethering/src/com/android/networkstack/tethering/metrics/TetheringMetrics.java
+++ b/Tethering/src/com/android/networkstack/tethering/metrics/TetheringMetrics.java
@@ -75,7 +75,8 @@
.setUserType(userTypeToEnum(callerPkg))
.setUpstreamType(UpstreamType.UT_UNKNOWN)
.setErrorCode(ErrorCode.EC_NO_ERROR)
- .build();
+ .setUpstreamEvents(UpstreamEvents.newBuilder())
+ .setDurationMillis(0);
mBuilderMap.put(downstreamType, statsBuilder);
}
@@ -110,7 +111,8 @@
reported.getErrorCode().getNumber(),
reported.getDownstreamType().getNumber(),
reported.getUpstreamType().getNumber(),
- reported.getUserType().getNumber());
+ reported.getUserType().getNumber(),
+ null, 0);
if (DBG) {
Log.d(TAG, "Write errorCode: " + reported.getErrorCode().getNumber()
+ ", downstreamType: " + reported.getDownstreamType().getNumber()
diff --git a/Tethering/src/com/android/networkstack/tethering/metrics/stats.proto b/Tethering/src/com/android/networkstack/tethering/metrics/stats.proto
index 46a47af..27f2126 100644
--- a/Tethering/src/com/android/networkstack/tethering/metrics/stats.proto
+++ b/Tethering/src/com/android/networkstack/tethering/metrics/stats.proto
@@ -21,12 +21,38 @@
import "frameworks/proto_logging/stats/enums/stats/connectivity/tethering.proto";
+// Logs each upstream for a successful switch over
+message UpstreamEvent {
+ // Transport type of upstream network
+ optional .android.stats.connectivity.UpstreamType upstream_type = 1;
+
+ // A time period that an upstream continued
+ optional int64 duration_millis = 2;
+}
+
+message UpstreamEvents {
+ repeated UpstreamEvent upstream_event = 1;
+}
+
/**
* Logs Tethering events
*/
message NetworkTetheringReported {
- optional .android.stats.connectivity.ErrorCode error_code = 1;
- optional .android.stats.connectivity.DownstreamType downstream_type = 2;
- optional .android.stats.connectivity.UpstreamType upstream_type = 3;
- optional .android.stats.connectivity.UserType user_type = 4;
+ // Tethering error code
+ optional .android.stats.connectivity.ErrorCode error_code = 1;
+
+ // Tethering downstream type
+ optional .android.stats.connectivity.DownstreamType downstream_type = 2;
+
+ // Transport type of upstream network
+ optional .android.stats.connectivity.UpstreamType upstream_type = 3 [deprecated = true];
+
+ // The user type of switching tethering
+ optional .android.stats.connectivity.UserType user_type = 4;
+
+ // Log each transport type of upstream network event
+ optional UpstreamEvents upstream_events = 5;
+
+ // A time period that a downstreams exists
+ optional int64 duration_millis = 6;
}
diff --git a/Tethering/tests/integration/Android.bp b/Tethering/tests/integration/Android.bp
index 9aa2cff..11e3dc0 100644
--- a/Tethering/tests/integration/Android.bp
+++ b/Tethering/tests/integration/Android.bp
@@ -28,6 +28,7 @@
static_libs: [
"NetworkStackApiStableLib",
"androidx.test.rules",
+ "cts-net-utils",
"mockito-target-extended-minus-junit4",
"net-tests-utils",
"net-utils-device-common-bpf",
diff --git a/Tethering/tests/integration/AndroidManifest.xml b/Tethering/tests/integration/AndroidManifest.xml
index 9303d0a..7527913 100644
--- a/Tethering/tests/integration/AndroidManifest.xml
+++ b/Tethering/tests/integration/AndroidManifest.xml
@@ -17,6 +17,7 @@
package="com.android.networkstack.tethering.tests.integration">
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
+ <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<!-- The test need CHANGE_NETWORK_STATE permission to use requestNetwork API to setup test
network. Since R shell application don't have such permission, grant permission to the test
here. TODO: Remove CHANGE_NETWORK_STATE permission here and use adopt shell perssion to
diff --git a/Tethering/tests/integration/src/android/net/EthernetTetheringTest.java b/Tethering/tests/integration/src/android/net/EthernetTetheringTest.java
index 876b945..f0f9a31 100644
--- a/Tethering/tests/integration/src/android/net/EthernetTetheringTest.java
+++ b/Tethering/tests/integration/src/android/net/EthernetTetheringTest.java
@@ -16,29 +16,44 @@
package android.net;
+import static android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS;
import static android.Manifest.permission.DUMP;
import static android.Manifest.permission.MANAGE_TEST_NETWORKS;
import static android.Manifest.permission.NETWORK_SETTINGS;
import static android.Manifest.permission.TETHER_PRIVILEGED;
+import static android.content.pm.PackageManager.FEATURE_WIFI;
import static android.net.InetAddresses.parseNumericAddress;
import static android.net.TetheringManager.CONNECTIVITY_SCOPE_GLOBAL;
import static android.net.TetheringManager.CONNECTIVITY_SCOPE_LOCAL;
import static android.net.TetheringManager.TETHERING_ETHERNET;
import static android.net.TetheringTester.TestDnsPacket;
-import static android.net.TetheringTester.isExpectedIcmpv6Packet;
+import static android.net.TetheringTester.isExpectedIcmpPacket;
+import static android.net.TetheringTester.isExpectedTcpPacket;
import static android.net.TetheringTester.isExpectedUdpDnsPacket;
import static android.net.TetheringTester.isExpectedUdpPacket;
+import static android.system.OsConstants.ICMP_ECHO;
+import static android.system.OsConstants.ICMP_ECHOREPLY;
+import static android.system.OsConstants.IPPROTO_ICMP;
import static android.system.OsConstants.IPPROTO_IP;
import static android.system.OsConstants.IPPROTO_IPV6;
+import static android.system.OsConstants.IPPROTO_TCP;
import static android.system.OsConstants.IPPROTO_UDP;
import static com.android.net.module.util.ConnectivityUtils.isIPv6ULA;
import static com.android.net.module.util.HexDump.dumpHexString;
+import static com.android.net.module.util.IpUtils.icmpChecksum;
+import static com.android.net.module.util.IpUtils.ipChecksum;
import static com.android.net.module.util.NetworkStackConstants.ETHER_TYPE_IPV4;
import static com.android.net.module.util.NetworkStackConstants.ETHER_TYPE_IPV6;
import static com.android.net.module.util.NetworkStackConstants.ICMPV6_ECHO_REPLY_TYPE;
import static com.android.net.module.util.NetworkStackConstants.ICMPV6_ECHO_REQUEST_TYPE;
import static com.android.net.module.util.NetworkStackConstants.ICMPV6_ROUTER_ADVERTISEMENT;
+import static com.android.net.module.util.NetworkStackConstants.ICMP_CHECKSUM_OFFSET;
+import static com.android.net.module.util.NetworkStackConstants.IPV4_CHECKSUM_OFFSET;
+import static com.android.net.module.util.NetworkStackConstants.IPV4_HEADER_MIN_LEN;
+import static com.android.net.module.util.NetworkStackConstants.IPV4_LENGTH_OFFSET;
+import static com.android.net.module.util.NetworkStackConstants.TCPHDR_ACK;
+import static com.android.net.module.util.NetworkStackConstants.TCPHDR_SYN;
import static com.android.testutils.DeviceInfoUtils.KVersion;
import static com.android.testutils.TestNetworkTrackerKt.initTestNetwork;
import static com.android.testutils.TestPermissionUtil.runAsShell;
@@ -54,12 +69,14 @@
import android.app.UiAutomation;
import android.content.Context;
+import android.content.pm.PackageManager;
import android.net.EthernetManager.TetheredInterfaceCallback;
import android.net.EthernetManager.TetheredInterfaceRequest;
import android.net.TetheringManager.StartTetheringCallback;
import android.net.TetheringManager.TetheringEventCallback;
import android.net.TetheringManager.TetheringRequest;
import android.net.TetheringTester.TetheredDevice;
+import android.net.cts.util.CtsNetUtils;
import android.os.Build;
import android.os.Handler;
import android.os.HandlerThread;
@@ -75,6 +92,7 @@
import androidx.test.filters.MediumTest;
import androidx.test.runner.AndroidJUnit4;
+import com.android.modules.utils.build.SdkLevel;
import com.android.net.module.util.BpfDump;
import com.android.net.module.util.Ipv6Utils;
import com.android.net.module.util.PacketBuilder;
@@ -83,6 +101,8 @@
import com.android.net.module.util.bpf.Tether4Value;
import com.android.net.module.util.bpf.TetherStatsKey;
import com.android.net.module.util.bpf.TetherStatsValue;
+import com.android.net.module.util.structs.EthernetHeader;
+import com.android.net.module.util.structs.Icmpv4Header;
import com.android.net.module.util.structs.Ipv4Header;
import com.android.net.module.util.structs.Ipv6Header;
import com.android.net.module.util.structs.UdpHeader;
@@ -139,6 +159,9 @@
// Kernel treats a confirmed UDP connection which active after two seconds as stream mode.
// See upstream commit b7b1d02fc43925a4d569ec221715db2dfa1ce4f5.
private static final int UDP_STREAM_TS_MS = 2000;
+ // Give slack time for waiting UDP stream mode because handling conntrack event in user space
+ // may not in precise time. Used to reduce the flaky rate.
+ private static final int UDP_STREAM_SLACK_MS = 500;
// Per RX UDP packet size: iphdr (20) + udphdr (8) + payload (2) = 30 bytes.
private static final int RX_UDP_PACKET_SIZE = 30;
private static final int RX_UDP_PACKET_COUNT = 456;
@@ -148,7 +171,7 @@
private static final long WAIT_RA_TIMEOUT_MS = 2000;
private static final MacAddress TEST_MAC = MacAddress.fromString("1:2:3:4:5:6");
- private static final LinkAddress TEST_IP4_ADDR = new LinkAddress("10.0.0.1/8");
+ private static final LinkAddress TEST_IP4_ADDR = new LinkAddress("10.0.0.1/24");
private static final LinkAddress TEST_IP6_ADDR = new LinkAddress("2001:db8:1::101/64");
private static final InetAddress TEST_IP4_DNS = parseNumericAddress("8.8.8.8");
private static final InetAddress TEST_IP6_DNS = parseNumericAddress("2001:db8:1::888");
@@ -159,8 +182,11 @@
(Inet6Address) parseNumericAddress("2002:db8:1::515:ca");
private static final ByteBuffer TEST_REACHABILITY_PAYLOAD =
ByteBuffer.wrap(new byte[] { (byte) 0x55, (byte) 0xaa });
+ private static final ByteBuffer EMPTY_PAYLOAD = ByteBuffer.wrap(new byte[0]);
private static final short DNS_PORT = 53;
+ private static final short WINDOW = (short) 0x2000;
+ private static final short URGENT_POINTER = 0;
private static final String DUMPSYS_TETHERING_RAWMAP_ARG = "bpfRawMap";
private static final String DUMPSYS_RAWMAP_ARG_STATS = "--stats";
@@ -171,6 +197,10 @@
private static final int VERSION_TRAFFICCLASS_FLOWLABEL = 0x60000000;
private static final short HOP_LIMIT = 0x40;
+ private static final short ICMPECHO_CODE = 0x0;
+ private static final short ICMPECHO_ID = 0x0;
+ private static final short ICMPECHO_SEQ = 0x0;
+
// TODO: use class DnsPacket to build DNS query and reply message once DnsPacket supports
// building packet for given arguments.
private static final ByteBuffer DNS_QUERY = ByteBuffer.wrap(new byte[] {
@@ -234,6 +264,8 @@
private final Context mContext = InstrumentationRegistry.getContext();
private final EthernetManager mEm = mContext.getSystemService(EthernetManager.class);
private final TetheringManager mTm = mContext.getSystemService(TetheringManager.class);
+ private final PackageManager mPackageManager = mContext.getPackageManager();
+ private final CtsNetUtils mCtsNetUtils = new CtsNetUtils(mContext);
private TestNetworkInterface mDownstreamIface;
private HandlerThread mHandlerThread;
@@ -278,26 +310,26 @@
mUpstreamReader = null;
}
- runAsShell(TETHER_PRIVILEGED, () -> {
- mTm.stopTethering(TETHERING_ETHERNET);
- // Binder call is an async call. Need to hold the shell permission until tethering
- // stopped. This helps to avoid the test become flaky.
- if (mTetheringEventCallback != null) {
- mTetheringEventCallback.awaitInterfaceUntethered();
- mTetheringEventCallback.unregister();
- mTetheringEventCallback = null;
- }
- });
if (mDownstreamReader != null) {
TapPacketReader reader = mDownstreamReader;
mHandler.post(() -> reader.stop());
mDownstreamReader = null;
}
- runAsShell(NETWORK_SETTINGS, () -> {
- mTetheredInterfaceRequester.release();
- });
- setIncludeTestInterfaces(false);
+
+ // To avoid flaky which caused by the next test started but the previous interface is not
+ // untracked from EthernetTracker yet. Just delete the test interface without explicitly
+ // calling TetheringManager#stopTethering could let EthernetTracker untrack the test
+ // interface from server mode before tethering stopped. Thus, awaitInterfaceUntethered
+ // could not only make sure tethering is stopped but also guarantee the test interface is
+ // untracked from EthernetTracker.
maybeDeleteTestInterface();
+ if (mTetheringEventCallback != null) {
+ mTetheringEventCallback.awaitInterfaceUntethered();
+ mTetheringEventCallback.unregister();
+ mTetheringEventCallback = null;
+ }
+ runAsShell(NETWORK_SETTINGS, () -> mTetheredInterfaceRequester.release());
+ setIncludeTestInterfaces(false);
}
@After
@@ -311,6 +343,13 @@
}
private boolean isInterfaceForTetheringAvailable() throws Exception {
+ // Before T, all ethernet interfaces could be used for server mode. Instead of
+ // waiting timeout, just checking whether the system currently has any
+ // ethernet interface is more reliable.
+ if (!SdkLevel.isAtLeastT()) {
+ return runAsShell(CONNECTIVITY_USE_RESTRICTED_NETWORKS, () -> mEm.isAvailable());
+ }
+
// If previous test case doesn't release tethering interface successfully, the other tests
// after that test may be skipped as unexcepted.
// TODO: figure out a better way to check default tethering interface existenion.
@@ -433,7 +472,10 @@
final long deadline = SystemClock.uptimeMillis() + timeoutMs;
do {
byte[] pkt = reader.popPacket(timeoutMs);
- if (isExpectedIcmpv6Packet(pkt, true /* hasEth */, ICMPV6_ROUTER_ADVERTISEMENT)) return;
+ if (isExpectedIcmpPacket(pkt, true /* hasEth */, false /* isIpv4 */,
+ ICMPV6_ROUTER_ADVERTISEMENT)) {
+ return;
+ }
timeoutMs = deadline - SystemClock.uptimeMillis();
} while (timeoutMs > 0);
@@ -690,10 +732,17 @@
}
}
- public Network awaitUpstreamChanged() throws Exception {
+ public Network awaitUpstreamChanged(boolean throwTimeoutException) throws Exception {
if (!mUpstreamLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)) {
- fail("Did not receive upstream " + (mAcceptAnyUpstream ? "any" : mExpectedUpstream)
- + " callback after " + TIMEOUT_MS + "ms");
+ final String errorMessage = "Did not receive upstream "
+ + (mAcceptAnyUpstream ? "any" : mExpectedUpstream)
+ + " callback after " + TIMEOUT_MS + "ms";
+
+ if (throwTimeoutException) {
+ throw new TimeoutException(errorMessage);
+ } else {
+ fail(errorMessage);
+ }
}
return mUpstream;
}
@@ -947,14 +996,16 @@
tester.verifyUpload(request, p -> {
Log.d(TAG, "Packet in upstream: " + dumpHexString(p));
- return isExpectedIcmpv6Packet(p, false /* hasEth */, ICMPV6_ECHO_REQUEST_TYPE);
+ return isExpectedIcmpPacket(p, false /* hasEth */, false /* isIpv4 */,
+ ICMPV6_ECHO_REQUEST_TYPE);
});
ByteBuffer reply = Ipv6Utils.buildEchoReplyPacket(remoteIp6Addr, tethered.ipv6Addr);
tester.verifyDownload(reply, p -> {
Log.d(TAG, "Packet in downstream: " + dumpHexString(p));
- return isExpectedIcmpv6Packet(p, true /* hasEth */, ICMPV6_ECHO_REPLY_TYPE);
+ return isExpectedIcmpPacket(p, true /* hasEth */, false /* isIpv4 */,
+ ICMPV6_ECHO_REPLY_TYPE);
});
}
@@ -985,26 +1036,21 @@
private static final ByteBuffer TX_PAYLOAD =
ByteBuffer.wrap(new byte[] { (byte) 0x56, (byte) 0x78 });
+ private short getEthType(@NonNull final InetAddress srcIp, @NonNull final InetAddress dstIp) {
+ return isAddressIpv4(srcIp, dstIp) ? (short) ETHER_TYPE_IPV4 : (short) ETHER_TYPE_IPV6;
+ }
+
+ private int getIpProto(@NonNull final InetAddress srcIp, @NonNull final InetAddress dstIp) {
+ return isAddressIpv4(srcIp, dstIp) ? IPPROTO_IP : IPPROTO_IPV6;
+ }
+
@NonNull
private ByteBuffer buildUdpPacket(
@Nullable final MacAddress srcMac, @Nullable final MacAddress dstMac,
@NonNull final InetAddress srcIp, @NonNull final InetAddress dstIp,
short srcPort, short dstPort, @Nullable final ByteBuffer payload)
throws Exception {
- int ipProto;
- short ethType;
- if (srcIp instanceof Inet4Address && dstIp instanceof Inet4Address) {
- ipProto = IPPROTO_IP;
- ethType = (short) ETHER_TYPE_IPV4;
- } else if (srcIp instanceof Inet6Address && dstIp instanceof Inet6Address) {
- ipProto = IPPROTO_IPV6;
- ethType = (short) ETHER_TYPE_IPV6;
- } else {
- fail("Unsupported conditions: srcIp " + srcIp + ", dstIp " + dstIp);
- // Make compiler happy to the uninitialized ipProto and ethType.
- return null; // unreachable, the annotation @NonNull of function return value is true.
- }
-
+ final int ipProto = getIpProto(srcIp, dstIp);
final boolean hasEther = (srcMac != null && dstMac != null);
final int payloadLen = (payload == null) ? 0 : payload.limit();
final ByteBuffer buffer = PacketBuilder.allocate(hasEther, ipProto, IPPROTO_UDP,
@@ -1012,7 +1058,9 @@
final PacketBuilder packetBuilder = new PacketBuilder(buffer);
// [1] Ethernet header
- if (hasEther) packetBuilder.writeL2Header(srcMac, dstMac, (short) ethType);
+ if (hasEther) {
+ packetBuilder.writeL2Header(srcMac, dstMac, getEthType(srcIp, dstIp));
+ }
// [2] IP header
if (ipProto == IPPROTO_IP) {
@@ -1171,6 +1219,9 @@
Thread.sleep(UDP_STREAM_TS_MS);
sendUploadPacketUdp(srcMac, dstMac, clientIp, remoteIp, tester, false /* is4To6 */);
+ // Give a slack time for handling conntrack event in user space.
+ Thread.sleep(UDP_STREAM_SLACK_MS);
+
// [1] Verify IPv4 upstream rule map.
final HashMap<Tether4Key, Tether4Value> upstreamMap = pollRawMapFromDump(
Tether4Key.class, Tether4Value.class, DUMPSYS_RAWMAP_ARG_UPSTREAM4);
@@ -1232,6 +1283,52 @@
}
}
+ // TODO: remove triggering upstream reselection once test network can replace selected upstream
+ // network in Tethering module.
+ private void maybeRetryTestedUpstreamChanged(final Network expectedUpstream,
+ final TimeoutException fallbackException) throws Exception {
+ // Fall back original exception because no way to reselect if there is no WIFI feature.
+ assertTrue(fallbackException.toString(), mPackageManager.hasSystemFeature(FEATURE_WIFI));
+
+ // Try to toggle wifi network, if any, to reselect upstream network via default network
+ // switching. Because test network has higher priority than internet network, this can
+ // help selecting test network to be upstream network for testing. This tries to avoid
+ // the flaky upstream selection under multinetwork environment. Internet and test network
+ // upstream changed event order is not guaranteed. Once tethering selects non-test
+ // upstream {wifi, ..}, test network won't be selected anymore. If too many test cases
+ // trigger the reselection, the total test time may over test suite 1 minmute timeout.
+ // Probably need to disable/restore all internet networks in a common place of test
+ // process. Currently, EthernetTetheringTest is part of CTS test which needs wifi network
+ // connection if device has wifi feature. CtsNetUtils#toggleWifi() checks wifi connection
+ // during the toggling process.
+ // See Tethering#chooseUpstreamType, CtsNetUtils#toggleWifi.
+ // TODO: toggle cellular network if the device has no WIFI feature.
+ Log.d(TAG, "Toggle WIFI to retry upstream selection");
+ mCtsNetUtils.toggleWifi();
+
+ // Wait for expected upstream.
+ final CompletableFuture<Network> future = new CompletableFuture<>();
+ final TetheringEventCallback callback = new TetheringEventCallback() {
+ @Override
+ public void onUpstreamChanged(Network network) {
+ Log.d(TAG, "Got upstream changed: " + network);
+ if (Objects.equals(expectedUpstream, network)) {
+ future.complete(network);
+ }
+ }
+ };
+ try {
+ mTm.registerTetheringEventCallback(mHandler::post, callback);
+ assertEquals("onUpstreamChanged for unexpected network", expectedUpstream,
+ future.get(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+ } catch (TimeoutException e) {
+ throw new AssertionError("Did not receive upstream " + expectedUpstream
+ + " callback after " + TIMEOUT_MS + "ms");
+ } finally {
+ mTm.unregisterTetheringEventCallback(callback);
+ }
+ }
+
private TetheringTester initTetheringTester(List<LinkAddress> upstreamAddresses,
List<InetAddress> upstreamDnses) throws Exception {
assumeFalse(isInterfaceForTetheringAvailable());
@@ -1250,8 +1347,17 @@
mTetheringEventCallback = enableEthernetTethering(mDownstreamIface.getInterfaceName(),
mUpstreamTracker.getNetwork());
- assertEquals("onUpstreamChanged for unexpected network", mUpstreamTracker.getNetwork(),
- mTetheringEventCallback.awaitUpstreamChanged());
+
+ try {
+ assertEquals("onUpstreamChanged for test network", mUpstreamTracker.getNetwork(),
+ mTetheringEventCallback.awaitUpstreamChanged(
+ true /* throwTimeoutException */));
+ } catch (TimeoutException e) {
+ // Due to race condition inside tethering module, test network may not be selected as
+ // tethering upstream. Force tethering retry upstream if possible. If it is not
+ // possible to retry, fail the test with the original timeout exception.
+ maybeRetryTestedUpstreamChanged(mUpstreamTracker.getNetwork(), e);
+ }
mDownstreamReader = makePacketReader(mDownstreamIface);
mUpstreamReader = makePacketReader(mUpstreamTracker.getTestIface());
@@ -1431,12 +1537,156 @@
// TODO: test CLAT bpf maps.
}
+ // TODO: support R device. See b/234727688.
@Test
@IgnoreUpTo(Build.VERSION_CODES.R)
public void testTetherClatUdp() throws Exception {
runClatUdpTest();
}
+ // PacketBuilder doesn't support IPv4 ICMP packet. It may need to refactor PacketBuilder first
+ // because ICMP is a specific layer 3 protocol for PacketBuilder which expects packets always
+ // have layer 3 (IP) and layer 4 (TCP, UDP) for now. Since we don't use IPv4 ICMP packet too
+ // much in this test, we just write a ICMP packet builder here.
+ // TODO: move ICMPv4 packet build function to common utilis.
+ @NonNull
+ private ByteBuffer buildIcmpEchoPacketV4(
+ @Nullable final MacAddress srcMac, @Nullable final MacAddress dstMac,
+ @NonNull final Inet4Address srcIp, @NonNull final Inet4Address dstIp,
+ int type, short id, short seq) throws Exception {
+ if (type != ICMP_ECHO && type != ICMP_ECHOREPLY) {
+ fail("Unsupported ICMP type: " + type);
+ }
+
+ // Build ICMP echo id and seq fields as payload. Ignore the data field.
+ final ByteBuffer payload = ByteBuffer.allocate(4);
+ payload.putShort(id);
+ payload.putShort(seq);
+ payload.rewind();
+
+ final boolean hasEther = (srcMac != null && dstMac != null);
+ final int etherHeaderLen = hasEther ? Struct.getSize(EthernetHeader.class) : 0;
+ final int ipv4HeaderLen = Struct.getSize(Ipv4Header.class);
+ final int Icmpv4HeaderLen = Struct.getSize(Icmpv4Header.class);
+ final int payloadLen = payload.limit();
+ final ByteBuffer packet = ByteBuffer.allocate(etherHeaderLen + ipv4HeaderLen
+ + Icmpv4HeaderLen + payloadLen);
+
+ // [1] Ethernet header
+ if (hasEther) {
+ final EthernetHeader ethHeader = new EthernetHeader(dstMac, srcMac, ETHER_TYPE_IPV4);
+ ethHeader.writeToByteBuffer(packet);
+ }
+
+ // [2] IP header
+ final Ipv4Header ipv4Header = new Ipv4Header(TYPE_OF_SERVICE,
+ (short) 0 /* totalLength, calculate later */, ID,
+ FLAGS_AND_FRAGMENT_OFFSET, TIME_TO_LIVE, (byte) IPPROTO_ICMP,
+ (short) 0 /* checksum, calculate later */, srcIp, dstIp);
+ ipv4Header.writeToByteBuffer(packet);
+
+ // [3] ICMP header
+ final Icmpv4Header icmpv4Header = new Icmpv4Header((byte) type, ICMPECHO_CODE,
+ (short) 0 /* checksum, calculate later */);
+ icmpv4Header.writeToByteBuffer(packet);
+
+ // [4] Payload
+ packet.put(payload);
+ packet.flip();
+
+ // [5] Finalize packet
+ // Used for updating IP header fields. If there is Ehternet header, IPv4 header offset
+ // in buffer equals ethernet header length because IPv4 header is located next to ethernet
+ // header. Otherwise, IPv4 header offset is 0.
+ final int ipv4HeaderOffset = hasEther ? etherHeaderLen : 0;
+
+ // Populate the IPv4 totalLength field.
+ packet.putShort(ipv4HeaderOffset + IPV4_LENGTH_OFFSET,
+ (short) (ipv4HeaderLen + Icmpv4HeaderLen + payloadLen));
+
+ // Populate the IPv4 header checksum field.
+ packet.putShort(ipv4HeaderOffset + IPV4_CHECKSUM_OFFSET,
+ ipChecksum(packet, ipv4HeaderOffset /* headerOffset */));
+
+ // Populate the ICMP checksum field.
+ packet.putShort(ipv4HeaderOffset + IPV4_HEADER_MIN_LEN + ICMP_CHECKSUM_OFFSET,
+ icmpChecksum(packet, ipv4HeaderOffset + IPV4_HEADER_MIN_LEN,
+ Icmpv4HeaderLen + payloadLen));
+ return packet;
+ }
+
+ @NonNull
+ private ByteBuffer buildIcmpEchoPacketV4(@NonNull final Inet4Address srcIp,
+ @NonNull final Inet4Address dstIp, int type, short id, short seq)
+ throws Exception {
+ return buildIcmpEchoPacketV4(null /* srcMac */, null /* dstMac */, srcIp, dstIp,
+ type, id, seq);
+ }
+
+ @Test
+ public void testIcmpv4Echo() throws Exception {
+ final TetheringTester tester = initTetheringTester(toList(TEST_IP4_ADDR),
+ toList(TEST_IP4_DNS));
+ final TetheredDevice tethered = tester.createTetheredDevice(TEST_MAC, false /* hasIpv6 */);
+
+ // TODO: remove the connectivity verification for upstream connected notification race.
+ // See the same reason in runUdp4Test().
+ probeV4TetheringConnectivity(tester, tethered, false /* is4To6 */);
+
+ final ByteBuffer request = buildIcmpEchoPacketV4(tethered.macAddr /* srcMac */,
+ tethered.routerMacAddr /* dstMac */, tethered.ipv4Addr /* srcIp */,
+ REMOTE_IP4_ADDR /* dstIp */, ICMP_ECHO, ICMPECHO_ID, ICMPECHO_SEQ);
+ tester.verifyUpload(request, p -> {
+ Log.d(TAG, "Packet in upstream: " + dumpHexString(p));
+
+ return isExpectedIcmpPacket(p, false /* hasEth */, true /* isIpv4 */, ICMP_ECHO);
+ });
+
+ final ByteBuffer reply = buildIcmpEchoPacketV4(REMOTE_IP4_ADDR /* srcIp*/,
+ (Inet4Address) TEST_IP4_ADDR.getAddress() /* dstIp */, ICMP_ECHOREPLY, ICMPECHO_ID,
+ ICMPECHO_SEQ);
+ tester.verifyDownload(reply, p -> {
+ Log.d(TAG, "Packet in downstream: " + dumpHexString(p));
+
+ return isExpectedIcmpPacket(p, true /* hasEth */, true /* isIpv4 */, ICMP_ECHOREPLY);
+ });
+ }
+
+ // TODO: support R device. See b/234727688.
+ @Test
+ @IgnoreUpTo(Build.VERSION_CODES.R)
+ public void testTetherClatIcmp() throws Exception {
+ // CLAT only starts on IPv6 only network.
+ final TetheringTester tester = initTetheringTester(toList(TEST_IP6_ADDR),
+ toList(TEST_IP6_DNS));
+ final TetheredDevice tethered = tester.createTetheredDevice(TEST_MAC, true /* hasIpv6 */);
+
+ // Get CLAT IPv6 address.
+ final Inet6Address clatIp6 = getClatIpv6Address(tester, tethered);
+
+ // Send an IPv4 ICMP packet in original direction.
+ // IPv4 packet -- CLAT translation --> IPv6 packet
+ final ByteBuffer request = buildIcmpEchoPacketV4(tethered.macAddr /* srcMac */,
+ tethered.routerMacAddr /* dstMac */, tethered.ipv4Addr /* srcIp */,
+ (Inet4Address) REMOTE_IP4_ADDR /* dstIp */, ICMP_ECHO, ICMPECHO_ID, ICMPECHO_SEQ);
+ tester.verifyUpload(request, p -> {
+ Log.d(TAG, "Packet in upstream: " + dumpHexString(p));
+
+ return isExpectedIcmpPacket(p, false /* hasEth */, false /* isIpv4 */,
+ ICMPV6_ECHO_REQUEST_TYPE);
+ });
+
+ // Send an IPv6 ICMP packet in reply direction.
+ // IPv6 packet -- CLAT translation --> IPv4 packet
+ final ByteBuffer reply = Ipv6Utils.buildEchoReplyPacket(
+ (Inet6Address) REMOTE_NAT64_ADDR /* srcIp */, clatIp6 /* dstIp */);
+ tester.verifyDownload(reply, p -> {
+ Log.d(TAG, "Packet in downstream: " + dumpHexString(p));
+
+ return isExpectedIcmpPacket(p, true /* hasEth */, true /* isIpv4 */, ICMP_ECHOREPLY);
+ });
+ }
+
@NonNull
private ByteBuffer buildDnsReplyMessageById(short id) {
byte[] replyMessage = Arrays.copyOf(DNS_REPLY, DNS_REPLY.length);
@@ -1512,7 +1762,7 @@
final TestDnsPacket dnsQuery = TestDnsPacket.getTestDnsPacket(buf);
assertNotNull(dnsQuery);
Log.d(TAG, "Forwarded UDP source port: " + udpHeader.srcPort + ", DNS query id: "
- + dnsQuery.getHeader().id);
+ + dnsQuery.getHeader().getId());
// [2] Send DNS reply.
// DNS server --> upstream --> dnsmasq forwarding --> downstream --> tethered device
@@ -1522,7 +1772,193 @@
final Inet4Address remoteIp = (Inet4Address) TEST_IP4_DNS;
final Inet4Address tetheringUpstreamIp = (Inet4Address) TEST_IP4_ADDR.getAddress();
sendDownloadPacketDnsV4(remoteIp, tetheringUpstreamIp, DNS_PORT,
- (short) udpHeader.srcPort, (short) dnsQuery.getHeader().id, tester);
+ (short) udpHeader.srcPort, (short) dnsQuery.getHeader().getId(), tester);
+ }
+
+ @NonNull
+ private ByteBuffer buildTcpPacket(
+ @Nullable final MacAddress srcMac, @Nullable final MacAddress dstMac,
+ @NonNull final InetAddress srcIp, @NonNull final InetAddress dstIp,
+ short srcPort, short dstPort, final short seq, final short ack,
+ final byte tcpFlags, @NonNull final ByteBuffer payload) throws Exception {
+ final int ipProto = getIpProto(srcIp, dstIp);
+ final boolean hasEther = (srcMac != null && dstMac != null);
+ final ByteBuffer buffer = PacketBuilder.allocate(hasEther, ipProto, IPPROTO_TCP,
+ payload.limit());
+ final PacketBuilder packetBuilder = new PacketBuilder(buffer);
+
+ // [1] Ethernet header
+ if (hasEther) {
+ packetBuilder.writeL2Header(srcMac, dstMac, getEthType(srcIp, dstIp));
+ }
+
+ // [2] IP header
+ if (ipProto == IPPROTO_IP) {
+ packetBuilder.writeIpv4Header(TYPE_OF_SERVICE, ID, FLAGS_AND_FRAGMENT_OFFSET,
+ TIME_TO_LIVE, (byte) IPPROTO_TCP, (Inet4Address) srcIp, (Inet4Address) dstIp);
+ } else {
+ packetBuilder.writeIpv6Header(VERSION_TRAFFICCLASS_FLOWLABEL, (byte) IPPROTO_TCP,
+ HOP_LIMIT, (Inet6Address) srcIp, (Inet6Address) dstIp);
+ }
+
+ // [3] TCP header
+ packetBuilder.writeTcpHeader(srcPort, dstPort, seq, ack, tcpFlags, WINDOW, URGENT_POINTER);
+
+ // [4] Payload
+ buffer.put(payload);
+ // in case data might be reused by caller, restore the position and
+ // limit of bytebuffer.
+ payload.clear();
+
+ return packetBuilder.finalizePacket();
+ }
+
+ private void sendDownloadPacketTcp(@NonNull final InetAddress srcIp,
+ @NonNull final InetAddress dstIp, short seq, short ack, byte tcpFlags,
+ @NonNull final ByteBuffer payload, @NonNull final TetheringTester tester,
+ boolean is6To4) throws Exception {
+ if (is6To4) {
+ assertFalse("CLAT download test must sends IPv6 packet", isAddressIpv4(srcIp, dstIp));
+ }
+
+ // Expected received TCP packet IP protocol. While testing CLAT (is6To4 = true), the packet
+ // on downstream must be IPv4. Otherwise, the IP protocol of test packet is the same on
+ // both downstream and upstream.
+ final boolean isIpv4 = is6To4 ? true : isAddressIpv4(srcIp, dstIp);
+
+ final ByteBuffer testPacket = buildTcpPacket(null /* srcMac */, null /* dstMac */,
+ srcIp, dstIp, REMOTE_PORT /* srcPort */, LOCAL_PORT /* dstPort */, seq, ack,
+ tcpFlags, payload);
+ tester.verifyDownload(testPacket, p -> {
+ Log.d(TAG, "Packet in downstream: " + dumpHexString(p));
+
+ return isExpectedTcpPacket(p, true /* hasEther */, isIpv4, seq, payload);
+ });
+ }
+
+ private void sendUploadPacketTcp(@NonNull final MacAddress srcMac,
+ @NonNull final MacAddress dstMac, @NonNull final InetAddress srcIp,
+ @NonNull final InetAddress dstIp, short seq, short ack, byte tcpFlags,
+ @NonNull final ByteBuffer payload, @NonNull final TetheringTester tester,
+ boolean is4To6) throws Exception {
+ if (is4To6) {
+ assertTrue("CLAT upload test must sends IPv4 packet", isAddressIpv4(srcIp, dstIp));
+ }
+
+ // Expected received TCP packet IP protocol. While testing CLAT (is4To6 = true), the packet
+ // on upstream must be IPv6. Otherwise, the IP protocol of test packet is the same on
+ // both downstream and upstream.
+ final boolean isIpv4 = is4To6 ? false : isAddressIpv4(srcIp, dstIp);
+
+ final ByteBuffer testPacket = buildTcpPacket(srcMac, dstMac, srcIp, dstIp,
+ LOCAL_PORT /* srcPort */, REMOTE_PORT /* dstPort */, seq, ack, tcpFlags,
+ payload);
+ tester.verifyUpload(testPacket, p -> {
+ Log.d(TAG, "Packet in upstream: " + dumpHexString(p));
+
+ return isExpectedTcpPacket(p, false /* hasEther */, isIpv4, seq, payload);
+ });
+ }
+
+ void runTcpTest(
+ @NonNull final MacAddress uploadSrcMac, @NonNull final MacAddress uploadDstMac,
+ @NonNull final InetAddress uploadSrcIp, @NonNull final InetAddress uploadDstIp,
+ @NonNull final InetAddress downloadSrcIp, @NonNull final InetAddress downloadDstIp,
+ @NonNull final TetheringTester tester, boolean isClat) throws Exception {
+ // Three way handshake and data transfer.
+ //
+ // Server (base seq = 2000) Client (base seq = 1000)
+ // | |
+ // | [1] [SYN] SEQ = 1000 |
+ // |<---------------------------------------------------------| -
+ // | | ^
+ // | [2] [SYN + ACK] SEQ = 2000, ACK = 1000+1 | |
+ // |--------------------------------------------------------->| three way handshake
+ // | | |
+ // | [3] [ACK] SEQ = 1001, ACK = 2000+1 | v
+ // |<---------------------------------------------------------| -
+ // | | ^
+ // | [4] [ACK] SEQ = 1001, ACK = 2001, 2 byte payload | |
+ // |<---------------------------------------------------------| data transfer
+ // | | |
+ // | [5] [ACK] SEQ = 2001, ACK = 1001+2, 2 byte payload | v
+ // |--------------------------------------------------------->| -
+ // | |
+ //
+
+ // This test can only verify the packets are transferred end to end but TCP state.
+ // TODO: verify TCP state change via /proc/net/nf_conntrack or netlink conntrack event.
+ // [1] [UPLOAD] [SYN]: SEQ = 1000
+ sendUploadPacketTcp(uploadSrcMac, uploadDstMac, uploadSrcIp, uploadDstIp,
+ (short) 1000 /* seq */, (short) 0 /* ack */, TCPHDR_SYN, EMPTY_PAYLOAD,
+ tester, isClat /* is4To6 */);
+
+ // [2] [DONWLOAD] [SYN + ACK]: SEQ = 2000, ACK = 1001
+ sendDownloadPacketTcp(downloadSrcIp, downloadDstIp, (short) 2000 /* seq */,
+ (short) 1001 /* ack */, (byte) ((TCPHDR_SYN | TCPHDR_ACK) & 0xff), EMPTY_PAYLOAD,
+ tester, isClat /* is6To4 */);
+
+ // [3] [UPLOAD] [ACK]: SEQ = 1001, ACK = 2001
+ sendUploadPacketTcp(uploadSrcMac, uploadDstMac, uploadSrcIp, uploadDstIp,
+ (short) 1001 /* seq */, (short) 2001 /* ack */, TCPHDR_ACK, EMPTY_PAYLOAD, tester,
+ isClat /* is4To6 */);
+
+ // [4] [UPLOAD] [ACK]: SEQ = 1001, ACK = 2001, 2 byte payload
+ sendUploadPacketTcp(uploadSrcMac, uploadDstMac, uploadSrcIp, uploadDstIp,
+ (short) 1001 /* seq */, (short) 2001 /* ack */, TCPHDR_ACK, TX_PAYLOAD,
+ tester, isClat /* is4To6 */);
+
+ // [5] [DONWLOAD] [ACK]: SEQ = 2001, ACK = 1003, 2 byte payload
+ sendDownloadPacketTcp(downloadSrcIp, downloadDstIp, (short) 2001 /* seq */,
+ (short) 1003 /* ack */, TCPHDR_ACK, RX_PAYLOAD, tester, isClat /* is6To4 */);
+
+ // TODO: test BPF offload maps.
+ }
+
+ @Test
+ public void testTetherTcpV4() throws Exception {
+ final TetheringTester tester = initTetheringTester(toList(TEST_IP4_ADDR),
+ toList(TEST_IP4_DNS));
+ final TetheredDevice tethered = tester.createTetheredDevice(TEST_MAC, false /* hasIpv6 */);
+
+ // TODO: remove the connectivity verification for upstream connected notification race.
+ // See the same reason in runUdp4Test().
+ probeV4TetheringConnectivity(tester, tethered, false /* is4To6 */);
+
+ runTcpTest(tethered.macAddr /* uploadSrcMac */, tethered.routerMacAddr /* uploadDstMac */,
+ tethered.ipv4Addr /* uploadSrcIp */, REMOTE_IP4_ADDR /* uploadDstIp */,
+ REMOTE_IP4_ADDR /* downloadSrcIp */, TEST_IP4_ADDR.getAddress() /* downloadDstIp */,
+ tester, false /* isClat */);
+ }
+
+ @Test
+ public void testTetherTcpV6() throws Exception {
+ final TetheringTester tester = initTetheringTester(toList(TEST_IP6_ADDR),
+ toList(TEST_IP6_DNS));
+ final TetheredDevice tethered = tester.createTetheredDevice(TEST_MAC, true /* hasIpv6 */);
+
+ runTcpTest(tethered.macAddr /* uploadSrcMac */, tethered.routerMacAddr /* uploadDstMac */,
+ tethered.ipv6Addr /* uploadSrcIp */, REMOTE_IP6_ADDR /* uploadDstIp */,
+ REMOTE_IP6_ADDR /* downloadSrcIp */, tethered.ipv6Addr /* downloadDstIp */,
+ tester, false /* isClat */);
+ }
+
+ // TODO: support R device. See b/234727688.
+ @Test
+ @IgnoreUpTo(Build.VERSION_CODES.R)
+ public void testTetherClatTcp() throws Exception {
+ // CLAT only starts on IPv6 only network.
+ final TetheringTester tester = initTetheringTester(toList(TEST_IP6_ADDR),
+ toList(TEST_IP6_DNS));
+ final TetheredDevice tethered = tester.createTetheredDevice(TEST_MAC, true /* hasIpv6 */);
+
+ // Get CLAT IPv6 address.
+ final Inet6Address clatIp6 = getClatIpv6Address(tester, tethered);
+
+ runTcpTest(tethered.macAddr /* uploadSrcMac */, tethered.routerMacAddr /* uploadDstMac */,
+ tethered.ipv4Addr /* uploadSrcIp */, REMOTE_IP4_ADDR /* uploadDstIp */,
+ REMOTE_NAT64_ADDR /* downloadSrcIp */, clatIp6 /* downloadDstIp */,
+ tester, true /* isClat */);
}
private <T> List<T> toList(T... array) {
diff --git a/Tethering/tests/integration/src/android/net/TetheringTester.java b/Tethering/tests/integration/src/android/net/TetheringTester.java
index 48a406c..ae39b24 100644
--- a/Tethering/tests/integration/src/android/net/TetheringTester.java
+++ b/Tethering/tests/integration/src/android/net/TetheringTester.java
@@ -17,7 +17,9 @@
package android.net;
import static android.net.InetAddresses.parseNumericAddress;
+import static android.system.OsConstants.IPPROTO_ICMP;
import static android.system.OsConstants.IPPROTO_ICMPV6;
+import static android.system.OsConstants.IPPROTO_TCP;
import static android.system.OsConstants.IPPROTO_UDP;
import static com.android.net.module.util.DnsPacket.ANSECTION;
@@ -39,6 +41,7 @@
import static com.android.net.module.util.NetworkStackConstants.IPV6_ADDR_ALL_NODES_MULTICAST;
import static com.android.net.module.util.NetworkStackConstants.NEIGHBOR_ADVERTISEMENT_FLAG_OVERRIDE;
import static com.android.net.module.util.NetworkStackConstants.NEIGHBOR_ADVERTISEMENT_FLAG_SOLICITED;
+import static com.android.net.module.util.NetworkStackConstants.TCPHDR_SYN;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail;
@@ -57,6 +60,7 @@
import com.android.net.module.util.Ipv6Utils;
import com.android.net.module.util.Struct;
import com.android.net.module.util.structs.EthernetHeader;
+import com.android.net.module.util.structs.Icmpv4Header;
import com.android.net.module.util.structs.Icmpv6Header;
import com.android.net.module.util.structs.Ipv4Header;
import com.android.net.module.util.structs.Ipv6Header;
@@ -64,6 +68,7 @@
import com.android.net.module.util.structs.NsHeader;
import com.android.net.module.util.structs.PrefixInformationOption;
import com.android.net.module.util.structs.RaHeader;
+import com.android.net.module.util.structs.TcpHeader;
import com.android.net.module.util.structs.UdpHeader;
import com.android.networkstack.arp.ArpPacket;
import com.android.testutils.TapPacketReader;
@@ -86,7 +91,7 @@
*/
public final class TetheringTester {
private static final String TAG = TetheringTester.class.getSimpleName();
- private static final int PACKET_READ_TIMEOUT_MS = 100;
+ private static final int PACKET_READ_TIMEOUT_MS = 500;
private static final int DHCP_DISCOVER_ATTEMPTS = 10;
private static final int READ_RA_ATTEMPTS = 10;
private static final byte[] DHCP_REQUESTED_PARAMS = new byte[] {
@@ -268,7 +273,8 @@
private List<PrefixInformationOption> getRaPrefixOptions(byte[] packet) {
ByteBuffer buf = ByteBuffer.wrap(packet);
- if (!isExpectedIcmpv6Packet(buf, true /* hasEth */, ICMPV6_ROUTER_ADVERTISEMENT)) {
+ if (!isExpectedIcmpPacket(buf, true /* hasEth */, false /* isIpv4 */,
+ ICMPV6_ROUTER_ADVERTISEMENT)) {
fail("Parsing RA packet fail");
}
@@ -298,7 +304,8 @@
sendRsPacket(srcMac, dstMac);
final byte[] raPacket = verifyPacketNotNull("Receive RA fail", getDownloadPacket(p -> {
- return isExpectedIcmpv6Packet(p, true /* hasEth */, ICMPV6_ROUTER_ADVERTISEMENT);
+ return isExpectedIcmpPacket(p, true /* hasEth */, false /* isIpv4 */,
+ ICMPV6_ROUTER_ADVERTISEMENT);
}));
final List<PrefixInformationOption> options = getRaPrefixOptions(raPacket);
@@ -360,20 +367,27 @@
}
}
- public static boolean isExpectedIcmpv6Packet(byte[] packet, boolean hasEth, int type) {
+ public static boolean isExpectedIcmpPacket(byte[] packet, boolean hasEth, boolean isIpv4,
+ int type) {
final ByteBuffer buf = ByteBuffer.wrap(packet);
- return isExpectedIcmpv6Packet(buf, hasEth, type);
+ return isExpectedIcmpPacket(buf, hasEth, isIpv4, type);
}
- private static boolean isExpectedIcmpv6Packet(ByteBuffer buf, boolean hasEth, int type) {
+ private static boolean isExpectedIcmpPacket(ByteBuffer buf, boolean hasEth, boolean isIpv4,
+ int type) {
try {
- if (hasEth && !hasExpectedEtherHeader(buf, false /* isIpv4 */)) return false;
+ if (hasEth && !hasExpectedEtherHeader(buf, isIpv4)) return false;
- if (!hasExpectedIpHeader(buf, false /* isIpv4 */, IPPROTO_ICMPV6)) return false;
+ final int ipProto = isIpv4 ? IPPROTO_ICMP : IPPROTO_ICMPV6;
+ if (!hasExpectedIpHeader(buf, isIpv4, ipProto)) return false;
- return Struct.parse(Icmpv6Header.class, buf).type == (short) type;
+ if (isIpv4) {
+ return Struct.parse(Icmpv4Header.class, buf).type == (short) type;
+ } else {
+ return Struct.parse(Icmpv6Header.class, buf).type == (short) type;
+ }
} catch (Exception e) {
- // Parsing packet fail means it is not icmpv6 packet.
+ // Parsing packet fail means it is not icmp packet.
}
return false;
@@ -578,6 +592,42 @@
return true;
}
+
+ private static boolean isTcpSynPacket(@NonNull final TcpHeader tcpHeader) {
+ return (tcpHeader.dataOffsetAndControlBits & TCPHDR_SYN) != 0;
+ }
+
+ public static boolean isExpectedTcpPacket(@NonNull final byte[] rawPacket, boolean hasEth,
+ boolean isIpv4, int seq, @NonNull final ByteBuffer payload) {
+ final ByteBuffer buf = ByteBuffer.wrap(rawPacket);
+ try {
+ if (hasEth && !hasExpectedEtherHeader(buf, isIpv4)) return false;
+
+ if (!hasExpectedIpHeader(buf, isIpv4, IPPROTO_TCP)) return false;
+
+ final TcpHeader tcpHeader = Struct.parse(TcpHeader.class, buf);
+ if (tcpHeader.seq != seq) return false;
+
+ // Don't try to parse the payload if it is a TCP SYN segment because additional TCP
+ // option MSS may be added in the SYN segment. Currently, TetherController uses
+ // iptables to limit downstream MSS for IPv4. The additional TCP options will be
+ // misunderstood as payload because parsing TCP options are not supported by class
+ // TcpHeader for now. See TetherController::setupIptablesHooks.
+ // TODO: remove once TcpHeader supports parsing TCP options.
+ if (isTcpSynPacket(tcpHeader)) {
+ Log.d(TAG, "Found SYN segment. Ignore parsing the remaining part of packet.");
+ return true;
+ }
+
+ if (payload.limit() != buf.remaining()) return false;
+ return Arrays.equals(getRemaining(buf), getRemaining(payload.asReadOnlyBuffer()));
+ } catch (Exception e) {
+ // Parsing packet fail means it is not tcp packet.
+ }
+
+ return false;
+ }
+
private void sendUploadPacket(ByteBuffer packet) throws Exception {
mDownstreamReader.sendResponse(packet);
}
diff --git a/Tethering/tests/mts/Android.bp b/Tethering/tests/mts/Android.bp
index a84fdd2..ae36499 100644
--- a/Tethering/tests/mts/Android.bp
+++ b/Tethering/tests/mts/Android.bp
@@ -41,6 +41,8 @@
"ctstestrunner-axt",
"junit",
"junit-params",
+ "connectivity-net-module-utils-bpf",
+ "net-utils-device-common-bpf",
],
jni_libs: [
diff --git a/Tethering/tests/mts/src/android/tethering/mts/SkDestroyListenerTest.java b/Tethering/tests/mts/src/android/tethering/mts/SkDestroyListenerTest.java
new file mode 100644
index 0000000..9494aa4
--- /dev/null
+++ b/Tethering/tests/mts/src/android/tethering/mts/SkDestroyListenerTest.java
@@ -0,0 +1,113 @@
+/*
+ * 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 android.tethering.mts;
+
+import static android.system.OsConstants.AF_INET;
+import static android.system.OsConstants.AF_INET6;
+import static android.system.OsConstants.SOCK_DGRAM;
+import static android.system.OsConstants.SOCK_STREAM;
+
+import static com.android.compatibility.common.util.SystemUtil.runShellCommandOrThrow;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import android.net.TrafficStats;
+import android.os.Build;
+import android.os.Process;
+import android.system.Os;
+import android.util.Pair;
+
+import com.android.net.module.util.BpfDump;
+import com.android.net.module.util.bpf.CookieTagMapKey;
+import com.android.net.module.util.bpf.CookieTagMapValue;
+import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo;
+import com.android.testutils.DevSdkIgnoreRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.FileDescriptor;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@RunWith(DevSdkIgnoreRunner.class)
+@IgnoreUpTo(Build.VERSION_CODES.S_V2)
+public class SkDestroyListenerTest {
+ private static final int COOKIE_TAG = 0x1234abcd;
+ private static final int SOCKET_COUNT = 100;
+ private static final int SOCKET_CLOSE_WAIT_MS = 200;
+ private static final String LINE_DELIMITER = "\\n";
+ private static final String DUMP_COMMAND = "dumpsys netstats --bpfRawMap --cookieTagMap";
+
+ private Map<CookieTagMapKey, CookieTagMapValue> parseBpfRawMap(final String dump) {
+ final Map<CookieTagMapKey, CookieTagMapValue> map = new HashMap<>();
+ for (final String line: dump.split(LINE_DELIMITER)) {
+ final Pair<CookieTagMapKey, CookieTagMapValue> keyValue =
+ BpfDump.fromBase64EncodedString(CookieTagMapKey.class,
+ CookieTagMapValue.class, line.trim());
+ map.put(keyValue.first, keyValue.second);
+ }
+ return map;
+ }
+
+ private int countTaggedSocket() {
+ final String dump = runShellCommandOrThrow(DUMP_COMMAND);
+ final Map<CookieTagMapKey, CookieTagMapValue> cookieTagMap = parseBpfRawMap(dump);
+ int count = 0;
+ for (final CookieTagMapValue value: cookieTagMap.values()) {
+ if (value.tag == COOKIE_TAG && value.uid == Process.myUid()) {
+ count++;
+ }
+ }
+ return count;
+ }
+
+ private boolean noTaggedSocket() {
+ return countTaggedSocket() == 0;
+ }
+
+ private void doTestSkDestroyListener(final int family, final int type) throws Exception {
+ assertTrue("There are tagged sockets before test", noTaggedSocket());
+
+ TrafficStats.setThreadStatsTag(COOKIE_TAG);
+ final List<FileDescriptor> fds = new ArrayList<>();
+ for (int i = 0; i < SOCKET_COUNT; i++) {
+ fds.add(Os.socket(family, type, 0 /* protocol */));
+ }
+ TrafficStats.clearThreadStatsTag();
+ assertEquals("Number of tagged socket does not match after creating sockets",
+ SOCKET_COUNT, countTaggedSocket());
+
+ for (final FileDescriptor fd: fds) {
+ Os.close(fd);
+ }
+ // Wait a bit for skDestroyListener to handle all the netlink messages.
+ Thread.sleep(SOCKET_CLOSE_WAIT_MS);
+ assertTrue("There are tagged sockets after closing sockets", noTaggedSocket());
+ }
+
+ @Test
+ public void testSkDestroyListener() throws Exception {
+ doTestSkDestroyListener(AF_INET, SOCK_STREAM);
+ doTestSkDestroyListener(AF_INET, SOCK_DGRAM);
+ doTestSkDestroyListener(AF_INET6, SOCK_STREAM);
+ doTestSkDestroyListener(AF_INET6, SOCK_DGRAM);
+ }
+}
diff --git a/Tethering/tests/unit/src/android/net/ip/IpServerTest.java b/Tethering/tests/unit/src/android/net/ip/IpServerTest.java
index f242227..f0d9057 100644
--- a/Tethering/tests/unit/src/android/net/ip/IpServerTest.java
+++ b/Tethering/tests/unit/src/android/net/ip/IpServerTest.java
@@ -53,6 +53,7 @@
import static org.mockito.Matchers.anyBoolean;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
@@ -99,6 +100,7 @@
import com.android.net.module.util.InterfaceParams;
import com.android.net.module.util.NetworkStackConstants;
import com.android.net.module.util.SharedLog;
+import com.android.net.module.util.Struct.S32;
import com.android.net.module.util.bpf.Tether4Key;
import com.android.net.module.util.bpf.Tether4Value;
import com.android.net.module.util.bpf.TetherStatsKey;
@@ -108,6 +110,7 @@
import com.android.net.module.util.ip.IpNeighborMonitor.NeighborEvent;
import com.android.net.module.util.ip.IpNeighborMonitor.NeighborEventConsumer;
import com.android.networkstack.tethering.BpfCoordinator;
+import com.android.networkstack.tethering.BpfCoordinator.ClientInfo;
import com.android.networkstack.tethering.BpfCoordinator.Ipv6ForwardingRule;
import com.android.networkstack.tethering.PrivateAddressCoordinator;
import com.android.networkstack.tethering.Tether6Value;
@@ -197,6 +200,7 @@
@Mock private BpfMap<TetherStatsKey, TetherStatsValue> mBpfStatsMap;
@Mock private BpfMap<TetherLimitKey, TetherLimitValue> mBpfLimitMap;
@Mock private BpfMap<TetherDevKey, TetherDevValue> mBpfDevMap;
+ @Mock private BpfMap<S32, S32> mBpfErrorMap;
@Captor private ArgumentCaptor<DhcpServingParamsParcel> mDhcpParamsCaptor;
@@ -271,6 +275,7 @@
mTestAddress);
}
+ @SuppressWarnings("DoNotCall") // Ignore warning for synchronous to call to Thread.run()
private void setUpDhcpServer() throws Exception {
doAnswer(inv -> {
final IDhcpServerCallbacks cb = inv.getArgument(2);
@@ -359,6 +364,11 @@
public BpfMap<TetherDevKey, TetherDevValue> getBpfDevMap() {
return mBpfDevMap;
}
+
+ @Nullable
+ public BpfMap<S32, S32> getBpfErrorMap() {
+ return mBpfErrorMap;
+ }
};
mBpfCoordinator = spy(new BpfCoordinator(mBpfDeps));
@@ -1519,4 +1529,56 @@
verify(mBpfCoordinator, never()).tetherOffloadRuleAdd(
mIpServer, makeForwardingRule(IPSEC_IFINDEX, neigh, mac));
}
+
+ // TODO: move to BpfCoordinatorTest once IpNeighborMonitor is migrated to BpfCoordinator.
+ @Test
+ public void addRemoveTetherClient() throws Exception {
+ initTetheredStateMachine(TETHERING_WIFI, UPSTREAM_IFACE, false /* usingLegacyDhcp */,
+ DEFAULT_USING_BPF_OFFLOAD);
+
+ final int myIfindex = TEST_IFACE_PARAMS.index;
+ final int notMyIfindex = myIfindex - 1;
+
+ final InetAddress neighA = InetAddresses.parseNumericAddress("192.168.80.1");
+ final InetAddress neighB = InetAddresses.parseNumericAddress("192.168.80.2");
+ final InetAddress neighLL = InetAddresses.parseNumericAddress("169.254.0.1");
+ final InetAddress neighMC = InetAddresses.parseNumericAddress("224.0.0.1");
+ final MacAddress macNull = MacAddress.fromString("00:00:00:00:00:00");
+ final MacAddress macA = MacAddress.fromString("00:00:00:00:00:0a");
+ final MacAddress macB = MacAddress.fromString("11:22:33:00:00:0b");
+
+ // Events on other interfaces are ignored.
+ recvNewNeigh(notMyIfindex, neighA, NUD_REACHABLE, macA);
+ verifyNoMoreInteractions(mBpfCoordinator);
+
+ // Events on this interface are received and sent to BpfCoordinator.
+ recvNewNeigh(myIfindex, neighA, NUD_REACHABLE, macA);
+ verify(mBpfCoordinator).tetherOffloadClientAdd(mIpServer, new ClientInfo(myIfindex,
+ TEST_IFACE_PARAMS.macAddr, (Inet4Address) neighA, macA));
+ clearInvocations(mBpfCoordinator);
+
+ recvNewNeigh(myIfindex, neighB, NUD_REACHABLE, macB);
+ verify(mBpfCoordinator).tetherOffloadClientAdd(mIpServer, new ClientInfo(myIfindex,
+ TEST_IFACE_PARAMS.macAddr, (Inet4Address) neighB, macB));
+ clearInvocations(mBpfCoordinator);
+
+ // Link-local and multicast neighbors are ignored.
+ recvNewNeigh(myIfindex, neighLL, NUD_REACHABLE, macA);
+ verifyNoMoreInteractions(mBpfCoordinator);
+ recvNewNeigh(myIfindex, neighMC, NUD_REACHABLE, macA);
+ verifyNoMoreInteractions(mBpfCoordinator);
+ clearInvocations(mBpfCoordinator);
+
+ // A neighbor that is no longer valid causes the client to be removed.
+ // NUD_FAILED events do not have a MAC address.
+ recvNewNeigh(myIfindex, neighA, NUD_FAILED, null);
+ verify(mBpfCoordinator).tetherOffloadClientRemove(mIpServer, new ClientInfo(myIfindex,
+ TEST_IFACE_PARAMS.macAddr, (Inet4Address) neighA, macNull));
+ clearInvocations(mBpfCoordinator);
+
+ // A neighbor that is deleted causes the client to be removed.
+ recvDelNeigh(myIfindex, neighB, NUD_STALE, macB);
+ verify(mBpfCoordinator).tetherOffloadClientRemove(mIpServer, new ClientInfo(myIfindex,
+ TEST_IFACE_PARAMS.macAddr, (Inet4Address) neighB, macNull));
+ }
}
diff --git a/Tethering/tests/unit/src/com/android/networkstack/tethering/BpfCoordinatorTest.java b/Tethering/tests/unit/src/com/android/networkstack/tethering/BpfCoordinatorTest.java
index b100f58..225fed7 100644
--- a/Tethering/tests/unit/src/com/android/networkstack/tethering/BpfCoordinatorTest.java
+++ b/Tethering/tests/unit/src/com/android/networkstack/tethering/BpfCoordinatorTest.java
@@ -94,11 +94,13 @@
import androidx.test.runner.AndroidJUnit4;
import com.android.dx.mockito.inline.extended.ExtendedMockito;
-import com.android.net.module.util.BpfMap;
+import com.android.internal.util.IndentingPrintWriter;
import com.android.net.module.util.CollectionUtils;
+import com.android.net.module.util.IBpfMap;
import com.android.net.module.util.InterfaceParams;
import com.android.net.module.util.NetworkStackConstants;
import com.android.net.module.util.SharedLog;
+import com.android.net.module.util.Struct.S32;
import com.android.net.module.util.bpf.Tether4Key;
import com.android.net.module.util.bpf.Tether4Value;
import com.android.net.module.util.bpf.TetherStatsKey;
@@ -128,6 +130,7 @@
import org.mockito.MockitoAnnotations;
import org.mockito.MockitoSession;
+import java.io.StringWriter;
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetAddress;
@@ -135,6 +138,7 @@
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedHashMap;
+import java.util.Map;
@RunWith(AndroidJUnit4.class)
@SmallTest
@@ -192,13 +196,11 @@
UPSTREAM_IFACE2, UPSTREAM_IFINDEX2, MacAddress.fromString("44:55:66:00:00:0c"),
NetworkStackConstants.ETHER_MTU);
- private static final HashMap<Integer, UpstreamInformation> UPSTREAM_INFORMATIONS =
- new HashMap<Integer, UpstreamInformation>() {{
- put(UPSTREAM_IFINDEX, new UpstreamInformation(UPSTREAM_IFACE_PARAMS,
- PUBLIC_ADDR, NetworkCapabilities.TRANSPORT_CELLULAR, TEST_NET_ID));
- put(UPSTREAM_IFINDEX2, new UpstreamInformation(UPSTREAM_IFACE_PARAMS2,
- PUBLIC_ADDR2, NetworkCapabilities.TRANSPORT_WIFI, TEST_NET_ID2));
- }};
+ private static final Map<Integer, UpstreamInformation> UPSTREAM_INFORMATIONS = Map.of(
+ UPSTREAM_IFINDEX, new UpstreamInformation(UPSTREAM_IFACE_PARAMS,
+ PUBLIC_ADDR, NetworkCapabilities.TRANSPORT_CELLULAR, TEST_NET_ID),
+ UPSTREAM_IFINDEX2, new UpstreamInformation(UPSTREAM_IFACE_PARAMS2,
+ PUBLIC_ADDR2, NetworkCapabilities.TRANSPORT_WIFI, TEST_NET_ID2));
private static final ClientInfo CLIENT_INFO_A = new ClientInfo(DOWNSTREAM_IFINDEX,
DOWNSTREAM_MAC, PRIVATE_ADDR, MAC_A);
@@ -362,9 +364,6 @@
@Mock private IpServer mIpServer2;
@Mock private TetheringConfiguration mTetherConfig;
@Mock private ConntrackMonitor mConntrackMonitor;
- @Mock private BpfMap<TetherDownstream6Key, Tether6Value> mBpfDownstream6Map;
- @Mock private BpfMap<TetherUpstream6Key, Tether6Value> mBpfUpstream6Map;
- @Mock private BpfMap<TetherDevKey, TetherDevValue> mBpfDevMap;
// Late init since methods must be called by the thread that created this object.
private TestableNetworkStatsProviderCbBinder mTetherStatsProviderCb;
@@ -379,14 +378,22 @@
private final ArgumentCaptor<ArrayList> mStringArrayCaptor =
ArgumentCaptor.forClass(ArrayList.class);
private final TestLooper mTestLooper = new TestLooper();
- private final BpfMap<Tether4Key, Tether4Value> mBpfDownstream4Map =
+ private final IBpfMap<Tether4Key, Tether4Value> mBpfDownstream4Map =
spy(new TestBpfMap<>(Tether4Key.class, Tether4Value.class));
- private final BpfMap<Tether4Key, Tether4Value> mBpfUpstream4Map =
+ private final IBpfMap<Tether4Key, Tether4Value> mBpfUpstream4Map =
spy(new TestBpfMap<>(Tether4Key.class, Tether4Value.class));
- private final TestBpfMap<TetherStatsKey, TetherStatsValue> mBpfStatsMap =
+ private final IBpfMap<TetherDownstream6Key, Tether6Value> mBpfDownstream6Map =
+ spy(new TestBpfMap<>(TetherDownstream6Key.class, Tether6Value.class));
+ private final IBpfMap<TetherUpstream6Key, Tether6Value> mBpfUpstream6Map =
+ spy(new TestBpfMap<>(TetherUpstream6Key.class, Tether6Value.class));
+ private final IBpfMap<TetherStatsKey, TetherStatsValue> mBpfStatsMap =
spy(new TestBpfMap<>(TetherStatsKey.class, TetherStatsValue.class));
- private final TestBpfMap<TetherLimitKey, TetherLimitValue> mBpfLimitMap =
+ private final IBpfMap<TetherLimitKey, TetherLimitValue> mBpfLimitMap =
spy(new TestBpfMap<>(TetherLimitKey.class, TetherLimitValue.class));
+ private final IBpfMap<TetherDevKey, TetherDevValue> mBpfDevMap =
+ spy(new TestBpfMap<>(TetherDevKey.class, TetherDevValue.class));
+ private final IBpfMap<S32, S32> mBpfErrorMap =
+ spy(new TestBpfMap<>(S32.class, S32.class));
private BpfCoordinator.Dependencies mDeps =
spy(new BpfCoordinator.Dependencies() {
@NonNull
@@ -424,39 +431,44 @@
}
@Nullable
- public BpfMap<Tether4Key, Tether4Value> getBpfDownstream4Map() {
+ public IBpfMap<Tether4Key, Tether4Value> getBpfDownstream4Map() {
return mBpfDownstream4Map;
}
@Nullable
- public BpfMap<Tether4Key, Tether4Value> getBpfUpstream4Map() {
+ public IBpfMap<Tether4Key, Tether4Value> getBpfUpstream4Map() {
return mBpfUpstream4Map;
}
@Nullable
- public BpfMap<TetherDownstream6Key, Tether6Value> getBpfDownstream6Map() {
+ public IBpfMap<TetherDownstream6Key, Tether6Value> getBpfDownstream6Map() {
return mBpfDownstream6Map;
}
@Nullable
- public BpfMap<TetherUpstream6Key, Tether6Value> getBpfUpstream6Map() {
+ public IBpfMap<TetherUpstream6Key, Tether6Value> getBpfUpstream6Map() {
return mBpfUpstream6Map;
}
@Nullable
- public BpfMap<TetherStatsKey, TetherStatsValue> getBpfStatsMap() {
+ public IBpfMap<TetherStatsKey, TetherStatsValue> getBpfStatsMap() {
return mBpfStatsMap;
}
@Nullable
- public BpfMap<TetherLimitKey, TetherLimitValue> getBpfLimitMap() {
+ public IBpfMap<TetherLimitKey, TetherLimitValue> getBpfLimitMap() {
return mBpfLimitMap;
}
@Nullable
- public BpfMap<TetherDevKey, TetherDevValue> getBpfDevMap() {
+ public IBpfMap<TetherDevKey, TetherDevValue> getBpfDevMap() {
return mBpfDevMap;
}
+
+ @Nullable
+ public IBpfMap<S32, S32> getBpfErrorMap() {
+ return mBpfErrorMap;
+ }
});
@Before public void setUp() {
@@ -1413,7 +1425,7 @@
// [1] Don't stop monitoring if it has never started.
coordinator.stopMonitoring(mIpServer);
- verify(mConntrackMonitor, never()).start();
+ verify(mConntrackMonitor, never()).stop();
// [2] Start monitoring.
coordinator.startMonitoring(mIpServer);
@@ -2092,4 +2104,95 @@
assertNull(mBpfUpstream4Map.getValue(upstream4KeyB));
assertNull(mBpfDownstream4Map.getValue(downstream4KeyB));
}
+
+ @Test
+ public void testIpv6ForwardingRuleToString() throws Exception {
+ final Ipv6ForwardingRule rule = buildTestForwardingRule(UPSTREAM_IFINDEX, NEIGH_A, MAC_A);
+ assertEquals("upstreamIfindex: 1001, downstreamIfindex: 1003, address: 2001:db8::1, "
+ + "srcMac: 12:34:56:78:90:ab, dstMac: 00:00:00:00:00:0a", rule.toString());
+ }
+
+ private void verifyDump(@NonNull final BpfCoordinator coordinator) {
+ final StringWriter stringWriter = new StringWriter();
+ final IndentingPrintWriter ipw = new IndentingPrintWriter(stringWriter, " ");
+ coordinator.dump(ipw);
+ assertFalse(stringWriter.toString().isEmpty());
+ }
+
+ @Test
+ public void testDumpDoesNotCrash() throws Exception {
+ // This dump test only used to for improving mainline module test coverage and doesn't
+ // really do any meaningful tests.
+ // TODO: consider verifying the dump content and separate tests into testDumpXXX().
+ final BpfCoordinator coordinator = makeBpfCoordinator();
+
+ // [1] Dump mostly empty content.
+ verifyDump(coordinator);
+
+ // [2] Dump mostly non-empty content.
+ // Test the following dump function and fill the corresponding content to execute
+ // code as more as possible for test coverage.
+ // - dumpBpfForwardingRulesIpv4
+ // * mBpfDownstream4Map
+ // * mBpfUpstream4Map
+ // - dumpBpfForwardingRulesIpv6
+ // * mBpfDownstream6Map
+ // * mBpfUpstream6Map
+ // - dumpStats
+ // * mBpfStatsMap
+ // - dumpDevmap
+ // * mBpfDevMap
+ // - dumpCounters
+ // * mBpfErrorMap
+ // - dumpIpv6ForwardingRulesByDownstream
+ // * mIpv6ForwardingRules
+
+ // dumpBpfForwardingRulesIpv4
+ mBpfDownstream4Map.insertEntry(
+ new TestDownstream4Key.Builder().build(),
+ new TestDownstream4Value.Builder().build());
+ mBpfUpstream4Map.insertEntry(
+ new TestUpstream4Key.Builder().build(),
+ new TestUpstream4Value.Builder().build());
+
+ // dumpBpfForwardingRulesIpv6
+ final Ipv6ForwardingRule rule = buildTestForwardingRule(UPSTREAM_IFINDEX, NEIGH_A, MAC_A);
+ mBpfDownstream6Map.insertEntry(rule.makeTetherDownstream6Key(), rule.makeTether6Value());
+
+ final TetherUpstream6Key upstream6Key = new TetherUpstream6Key(DOWNSTREAM_IFINDEX,
+ DOWNSTREAM_MAC);
+ final Tether6Value upstream6Value = new Tether6Value(UPSTREAM_IFINDEX,
+ MacAddress.ALL_ZEROS_ADDRESS, MacAddress.ALL_ZEROS_ADDRESS,
+ ETH_P_IPV6, NetworkStackConstants.ETHER_MTU);
+ mBpfUpstream6Map.insertEntry(upstream6Key, upstream6Value);
+
+ // dumpStats
+ mBpfStatsMap.insertEntry(
+ new TetherStatsKey(UPSTREAM_IFINDEX),
+ new TetherStatsValue(
+ 0L /* rxPackets */, 0L /* rxBytes */, 0L /* rxErrors */,
+ 0L /* txPackets */, 0L /* txBytes */, 0L /* txErrors */));
+
+ // dumpDevmap
+ coordinator.addUpstreamNameToLookupTable(UPSTREAM_IFINDEX, UPSTREAM_IFACE);
+ mBpfDevMap.insertEntry(
+ new TetherDevKey(UPSTREAM_IFINDEX),
+ new TetherDevValue(UPSTREAM_IFINDEX));
+
+ // dumpCounters
+ // The error code is defined in packages/modules/Connectivity/bpf_progs/bpf_tethering.h.
+ mBpfErrorMap.insertEntry(
+ new S32(0 /* INVALID_IPV4_VERSION */),
+ new S32(1000 /* count */));
+
+ // dumpIpv6ForwardingRulesByDownstream
+ final HashMap<IpServer, LinkedHashMap<Inet6Address, Ipv6ForwardingRule>>
+ ipv6ForwardingRules = coordinator.getForwardingRulesForTesting();
+ final LinkedHashMap<Inet6Address, Ipv6ForwardingRule> addressRuleMap =
+ new LinkedHashMap<>();
+ addressRuleMap.put(rule.address, rule);
+ ipv6ForwardingRules.put(mIpServer, addressRuleMap);
+
+ verifyDump(coordinator);
+ }
}
diff --git a/Tethering/tests/unit/src/com/android/networkstack/tethering/TestConnectivityManager.java b/Tethering/tests/unit/src/com/android/networkstack/tethering/TestConnectivityManager.java
index e0d77ee..b2cbf75 100644
--- a/Tethering/tests/unit/src/com/android/networkstack/tethering/TestConnectivityManager.java
+++ b/Tethering/tests/unit/src/com/android/networkstack/tethering/TestConnectivityManager.java
@@ -19,7 +19,6 @@
import static android.net.NetworkCapabilities.NET_CAPABILITY_DUN;
import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
-import static android.net.NetworkCapabilities.TRANSPORT_TEST;
import static com.android.networkstack.apishim.common.ShimUtils.isAtLeastS;
@@ -330,28 +329,6 @@
this.legacyType = toLegacyType(networkCapabilities);
}
- // Used for test network only because ConnectivityManager.networkCapabilitiesForType
- // doesn't support "TRANSPORT_TEST -> TYPE_TEST" in #matchesLegacyType. Beware of
- // satisfiedByNetworkCapabilities doesn't check on new |networkCapabilities| as
- // #matchesLegacyType.
- // TODO: refactor when tethering no longer uses CONNECTIVITY_ACTION.
- private TestNetworkAgent(TestConnectivityManager cm) {
- this.cm = cm;
- networkId = new Network(cm.getNetworkId());
- networkCapabilities = new NetworkCapabilities.Builder()
- .addTransportType(TRANSPORT_TEST)
- .addCapability(NET_CAPABILITY_INTERNET)
- .build();
- linkProperties = new LinkProperties();
- legacyType = TYPE_TEST;
- }
-
- // TODO: refactor when tethering no longer uses CONNECTIVITY_ACTION.
- public static TestNetworkAgent buildTestNetworkAgentForTestNetwork(
- TestConnectivityManager cm) {
- return new TestNetworkAgent(cm);
- }
-
private static int toLegacyType(NetworkCapabilities nc) {
for (int type = 0; type < ConnectivityManager.TYPE_TEST; type++) {
if (matchesLegacyType(nc, type)) return type;
diff --git a/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringServiceTest.java b/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringServiceTest.java
index e114cb5..38f1e9c 100644
--- a/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringServiceTest.java
+++ b/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringServiceTest.java
@@ -664,17 +664,17 @@
assertEquals("Internal callback is not registered", 1, callbacks.size());
assertNotNull(weakTm.get());
+ // Calling System.gc() or System.runFinalization() doesn't guarantee GCs or finalizers
+ // are executed synchronously. The finalizer is called after GC on a separate thread.
final int attempts = 100;
final long waitIntervalMs = 50;
for (int i = 0; i < attempts; i++) {
forceGc();
- if (weakTm.get() == null) break;
+ if (weakTm.get() == null && callbacks.size() == 0) break;
Thread.sleep(waitIntervalMs);
}
- assertNull("TetheringManager weak reference still not null after " + attempts
- + " attempts", weakTm.get());
-
+ assertNull("TetheringManager weak reference is not null", weakTm.get());
assertEquals("Internal callback is not unregistered", 0, callbacks.size());
});
}
diff --git a/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java b/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java
index a36d67f..9337b1a 100644
--- a/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java
+++ b/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java
@@ -399,6 +399,7 @@
MacAddress.ALL_ZEROS_ADDRESS);
}
+ @SuppressWarnings("DoNotCall") // Ignore warning for synchronous to call to Thread.run()
@Override
public void makeDhcpServer(String ifName, DhcpServingParamsParcel params,
DhcpServerCallbacks cb) {
@@ -1854,20 +1855,12 @@
private void assertTetherConfigParcelEqual(@NonNull TetheringConfigurationParcel actual,
@NonNull TetheringConfigurationParcel expect) {
- assertEquals(actual.subId, expect.subId);
assertArrayEquals(actual.tetherableUsbRegexs, expect.tetherableUsbRegexs);
assertArrayEquals(actual.tetherableWifiRegexs, expect.tetherableWifiRegexs);
assertArrayEquals(actual.tetherableBluetoothRegexs, expect.tetherableBluetoothRegexs);
- assertEquals(actual.isDunRequired, expect.isDunRequired);
- assertEquals(actual.chooseUpstreamAutomatically, expect.chooseUpstreamAutomatically);
- assertArrayEquals(actual.preferredUpstreamIfaceTypes,
- expect.preferredUpstreamIfaceTypes);
assertArrayEquals(actual.legacyDhcpRanges, expect.legacyDhcpRanges);
- assertArrayEquals(actual.defaultIPv4DNS, expect.defaultIPv4DNS);
- assertEquals(actual.enableLegacyDhcpServer, expect.enableLegacyDhcpServer);
assertArrayEquals(actual.provisioningApp, expect.provisioningApp);
assertEquals(actual.provisioningAppNoUi, expect.provisioningAppNoUi);
- assertEquals(actual.provisioningCheckPeriod, expect.provisioningCheckPeriod);
}
}
diff --git a/Tethering/tests/unit/src/com/android/networkstack/tethering/UpstreamNetworkMonitorTest.java b/Tethering/tests/unit/src/com/android/networkstack/tethering/UpstreamNetworkMonitorTest.java
index b0cb7f2..9b9507b 100644
--- a/Tethering/tests/unit/src/com/android/networkstack/tethering/UpstreamNetworkMonitorTest.java
+++ b/Tethering/tests/unit/src/com/android/networkstack/tethering/UpstreamNetworkMonitorTest.java
@@ -449,36 +449,6 @@
}
@Test
- public void testGetCurrentPreferredUpstream_TestNetworkPreferred() throws Exception {
- mUNM.startTrackDefaultNetwork(mEntitleMgr);
- mUNM.startObserveAllNetworks();
- mUNM.setUpstreamConfig(true /* autoUpstream */, false /* dunRequired */);
- mUNM.setTryCell(true);
- mUNM.setPreferTestNetworks(true);
-
- // [1] Mobile connects, DUN not required -> mobile selected.
- final TestNetworkAgent cellAgent = new TestNetworkAgent(mCM, CELL_CAPABILITIES);
- cellAgent.fakeConnect();
- mCM.makeDefaultNetwork(cellAgent);
- mLooper.dispatchAll();
- assertEquals(cellAgent.networkId, mUNM.getCurrentPreferredUpstream().network);
- assertEquals(0, mCM.mRequested.size());
-
- // [2] Test network connects -> test network selected.
- final TestNetworkAgent testAgent =
- TestNetworkAgent.buildTestNetworkAgentForTestNetwork(mCM);
- testAgent.fakeConnect();
- mLooper.dispatchAll();
- assertEquals(testAgent.networkId, mUNM.getCurrentPreferredUpstream().network);
- assertEquals(0, mCM.mRequested.size());
-
- // [3] Disable test networks preferred -> mobile selected.
- mUNM.setPreferTestNetworks(false);
- assertEquals(cellAgent.networkId, mUNM.getCurrentPreferredUpstream().network);
- assertEquals(0, mCM.mRequested.size());
- }
-
- @Test
public void testLocalPrefixes() throws Exception {
mUNM.startTrackDefaultNetwork(mEntitleMgr);
mUNM.startObserveAllNetworks();
diff --git a/Tethering/tests/unit/src/com/android/networkstack/tethering/metrics/TetheringMetricsTest.java b/Tethering/tests/unit/src/com/android/networkstack/tethering/metrics/TetheringMetricsTest.java
index 6a85718..7fdde97 100644
--- a/Tethering/tests/unit/src/com/android/networkstack/tethering/metrics/TetheringMetricsTest.java
+++ b/Tethering/tests/unit/src/com/android/networkstack/tethering/metrics/TetheringMetricsTest.java
@@ -88,6 +88,8 @@
.setUserType(user)
.setUpstreamType(UpstreamType.UT_UNKNOWN)
.setErrorCode(error)
+ .setUpstreamEvents(UpstreamEvents.newBuilder())
+ .setDurationMillis(0)
.build();
verify(mTetheringMetrics).write(expectedReport);
}
diff --git a/bpf_progs/bpf_net_helpers.h b/bpf_progs/bpf_net_helpers.h
index e382713..c39269e 100644
--- a/bpf_progs/bpf_net_helpers.h
+++ b/bpf_progs/bpf_net_helpers.h
@@ -28,9 +28,12 @@
static int (*bpf_skb_pull_data)(struct __sk_buff* skb, __u32 len) = (void*)BPF_FUNC_skb_pull_data;
-static int (*bpf_skb_load_bytes)(struct __sk_buff* skb, int off, void* to,
+static int (*bpf_skb_load_bytes)(const struct __sk_buff* skb, int off, void* to,
int len) = (void*)BPF_FUNC_skb_load_bytes;
+static int (*bpf_skb_load_bytes_relative)(const struct __sk_buff* skb, int off, void* to, int len,
+ int start_hdr) = (void*)BPF_FUNC_skb_load_bytes_relative;
+
static int (*bpf_skb_store_bytes)(struct __sk_buff* skb, __u32 offset, const void* from, __u32 len,
__u64 flags) = (void*)BPF_FUNC_skb_store_bytes;
diff --git a/bpf_progs/bpf_shared.h b/bpf_progs/bpf_shared.h
index 85b9f86..7b1106a 100644
--- a/bpf_progs/bpf_shared.h
+++ b/bpf_progs/bpf_shared.h
@@ -95,13 +95,13 @@
// 'static' - otherwise these constants end up in .rodata in the resulting .o post compilation
static const int COOKIE_UID_MAP_SIZE = 10000;
-static const int UID_COUNTERSET_MAP_SIZE = 2000;
+static const int UID_COUNTERSET_MAP_SIZE = 4000;
static const int APP_STATS_MAP_SIZE = 10000;
static const int STATS_MAP_SIZE = 5000;
static const int IFACE_INDEX_NAME_MAP_SIZE = 1000;
static const int IFACE_STATS_MAP_SIZE = 1000;
static const int CONFIGURATION_MAP_SIZE = 2;
-static const int UID_OWNER_MAP_SIZE = 2000;
+static const int UID_OWNER_MAP_SIZE = 4000;
#ifdef __cplusplus
diff --git a/bpf_progs/clatd.c b/bpf_progs/clatd.c
index a2214dc..b8c6131 100644
--- a/bpf_progs/clatd.c
+++ b/bpf_progs/clatd.c
@@ -38,8 +38,19 @@
#include "bpf_shared.h"
#include "clat_mark.h"
-// From kernel:include/net/ip.h
-#define IP_DF 0x4000 // Flag: "Don't Fragment"
+// IP flags. (from kernel's include/net/ip.h)
+#define IP_CE 0x8000 // Flag: "Congestion" (really reserved 'evil bit')
+#define IP_DF 0x4000 // Flag: "Don't Fragment"
+#define IP_MF 0x2000 // Flag: "More Fragments"
+#define IP_OFFSET 0x1FFF // "Fragment Offset" part
+
+// from kernel's include/net/ipv6.h
+struct frag_hdr {
+ __u8 nexthdr;
+ __u8 reserved; // always zero
+ __be16 frag_off; // 13 bit offset, 2 bits zero, 1 bit "More Fragments"
+ __be32 identification;
+};
DEFINE_BPF_MAP_GRW(clat_ingress6_map, HASH, ClatIngress6Key, ClatIngress6Value, 16, AID_SYSTEM)
@@ -89,7 +100,32 @@
if (!v) return TC_ACT_PIPE;
- switch (ip6->nexthdr) {
+ __u8 proto = ip6->nexthdr;
+ __be16 ip_id = 0;
+ __be16 frag_off = htons(IP_DF);
+ __u16 tot_len = ntohs(ip6->payload_len) + sizeof(struct iphdr); // cannot overflow, see above
+
+ if (proto == IPPROTO_FRAGMENT) {
+ // Must have (ethernet and) ipv6 header and ipv6 fragment extension header
+ if (data + l2_header_size + sizeof(*ip6) + sizeof(struct frag_hdr) > data_end)
+ return TC_ACT_PIPE;
+ const struct frag_hdr *frag = (const struct frag_hdr *)(ip6 + 1);
+ proto = frag->nexthdr;
+ // Trivial hash of 32-bit IPv6 ID field into 16-bit IPv4 field.
+ ip_id = (frag->identification) ^ (frag->identification >> 16);
+ // Conversion of 16-bit IPv6 frag offset to 16-bit IPv4 frag offset field.
+ // IPv6 is '13 bits of offset in multiples of 8' + 2 zero bits + more fragment bit
+ // IPv4 is zero bit + don't frag bit + more frag bit + '13 bits of offset in multiples of 8'
+ frag_off = ntohs(frag->frag_off);
+ frag_off = ((frag_off & 1) << 13) | (frag_off >> 3);
+ frag_off = htons(frag_off);
+ // Note that by construction tot_len is guaranteed to not underflow here
+ tot_len -= sizeof(struct frag_hdr);
+ // This is a badly formed IPv6 packet with less payload than the size of an IPv6 Frag EH
+ if (tot_len < sizeof(struct iphdr)) return TC_ACT_PIPE;
+ }
+
+ switch (proto) {
case IPPROTO_TCP: // For TCP & UDP the checksum neutrality of the chosen IPv6
case IPPROTO_UDP: // address means there is no need to update their checksums.
case IPPROTO_GRE: // We do not need to bother looking at GRE/ESP headers,
@@ -114,14 +150,14 @@
.version = 4, // u4
.ihl = sizeof(struct iphdr) / sizeof(__u32), // u4
.tos = (ip6->priority << 4) + (ip6->flow_lbl[0] >> 4), // u8
- .tot_len = htons(ntohs(ip6->payload_len) + sizeof(struct iphdr)), // u16
- .id = 0, // u16
- .frag_off = htons(IP_DF), // u16
+ .tot_len = htons(tot_len), // be16
+ .id = ip_id, // be16
+ .frag_off = frag_off, // be16
.ttl = ip6->hop_limit, // u8
- .protocol = ip6->nexthdr, // u8
+ .protocol = proto, // u8
.check = 0, // u16
- .saddr = ip6->saddr.in6_u.u6_addr32[3], // u32
- .daddr = v->local4.s_addr, // u32
+ .saddr = ip6->saddr.in6_u.u6_addr32[3], // be32
+ .daddr = v->local4.s_addr, // be32
};
// Calculate the IPv4 one's complement checksum of the IPv4 header.
@@ -171,6 +207,13 @@
// return -ENOTSUPP;
bpf_csum_update(skb, sum6);
+ if (frag_off != htons(IP_DF)) {
+ // If we're converting an IPv6 Fragment, we need to trim off 8 more bytes
+ // We're beyond recovery on error here... but hard to imagine how this could fail.
+ if (bpf_skb_adjust_room(skb, -(__s32)sizeof(struct frag_hdr), BPF_ADJ_ROOM_NET, /*flags*/0))
+ return TC_ACT_SHOT;
+ }
+
// bpf_skb_change_proto() invalidates all pointers - reload them.
data = (void*)(long)skb->data;
data_end = (void*)(long)skb->data_end;
@@ -211,11 +254,6 @@
DEFINE_BPF_MAP_GRW(clat_egress4_map, HASH, ClatEgress4Key, ClatEgress4Value, 16, AID_SYSTEM)
-DEFINE_BPF_PROG("schedcls/egress4/clat_ether", AID_ROOT, AID_SYSTEM, sched_cls_egress4_clat_ether)
-(struct __sk_buff* skb) {
- return TC_ACT_PIPE;
-}
-
DEFINE_BPF_PROG("schedcls/egress4/clat_rawip", AID_ROOT, AID_SYSTEM, sched_cls_egress4_clat_rawip)
(struct __sk_buff* skb) {
// Must be meta-ethernet IPv4 frame
diff --git a/bpf_progs/netd.c b/bpf_progs/netd.c
index 10559dd..f9484fc 100644
--- a/bpf_progs/netd.c
+++ b/bpf_progs/netd.c
@@ -47,9 +47,16 @@
#define IP_PROTO_OFF offsetof(struct iphdr, protocol)
#define IPV6_PROTO_OFF offsetof(struct ipv6hdr, nexthdr)
+
+// offsetof(struct iphdr, ihl) -- but that's a bitfield
#define IPPROTO_IHL_OFF 0
-#define TCP_FLAG_OFF 13
-#define RST_OFFSET 2
+
+// This is offsetof(struct tcphdr, "32 bit tcp flag field")
+// The tcp flags are after be16 source, dest & be32 seq, ack_seq, hence 12 bytes in.
+//
+// Note that TCP_FLAG_{ACK,PSH,RST,SYN,FIN} are htonl(0x00{10,08,04,02,01}0000)
+// see include/uapi/linux/tcp.h
+#define TCP_FLAG32_OFF 12
// For maps netd does not need to access
#define DEFINE_BPF_MAP_NO_NETD(the_map, TYPE, TypeOfKey, TypeOfValue, num_entries) \
@@ -97,9 +104,15 @@
// programs that need to be usable by netd, but not by netutils_wrappers
// (this is because these are currently attached by the mainline provided libnetd_updatable .so
// which is loaded into netd and thus runs as netd uid/gid/selinux context)
-#define DEFINE_NETD_BPF_PROG(SECTION_NAME, prog_uid, prog_gid, the_prog) \
+#define DEFINE_NETD_BPF_PROG_KVER_RANGE(SECTION_NAME, prog_uid, prog_gid, the_prog, minKV, maxKV) \
DEFINE_BPF_PROG_EXT(SECTION_NAME, prog_uid, prog_gid, the_prog, \
- KVER_NONE, KVER_INF, false, "fs_bpf_netd_readonly", "")
+ minKV, maxKV, false, "fs_bpf_netd_readonly", "")
+
+#define DEFINE_NETD_BPF_PROG_KVER(SECTION_NAME, prog_uid, prog_gid, the_prog, min_kv) \
+ DEFINE_NETD_BPF_PROG_KVER_RANGE(SECTION_NAME, prog_uid, prog_gid, the_prog, min_kv, KVER_INF)
+
+#define DEFINE_NETD_BPF_PROG(SECTION_NAME, prog_uid, prog_gid, the_prog) \
+ DEFINE_NETD_BPF_PROG_KVER(SECTION_NAME, prog_uid, prog_gid, the_prog, KVER_NONE)
// programs that only need to be usable by the system server
#define DEFINE_SYS_BPF_PROG(SECTION_NAME, prog_uid, prog_gid, the_prog) \
@@ -176,46 +189,49 @@
DEFINE_UPDATE_STATS(stats_map_A, StatsKey)
DEFINE_UPDATE_STATS(stats_map_B, StatsKey)
-static inline bool skip_owner_match(struct __sk_buff* skb) {
- int offset = -1;
- int ret = 0;
+// both of these return 0 on success or -EFAULT on failure (and zero out the buffer)
+static __always_inline inline int bpf_skb_load_bytes_net(const struct __sk_buff* skb, int off,
+ void* to, int len, bool is_4_19) {
+ return is_4_19
+ ? bpf_skb_load_bytes_relative(skb, off, to, len, BPF_HDR_START_NET)
+ : bpf_skb_load_bytes(skb, off, to, len);
+}
+
+static __always_inline inline bool skip_owner_match(struct __sk_buff* skb, bool is_4_19) {
if (skb->protocol == htons(ETH_P_IP)) {
- offset = IP_PROTO_OFF;
- uint8_t proto, ihl;
- uint8_t flag;
- ret = bpf_skb_load_bytes(skb, offset, &proto, 1);
- if (!ret) {
- if (proto == IPPROTO_ESP) {
- return true;
- } else if (proto == IPPROTO_TCP) {
- ret = bpf_skb_load_bytes(skb, IPPROTO_IHL_OFF, &ihl, 1);
- ihl = ihl & 0x0F;
- ret = bpf_skb_load_bytes(skb, ihl * 4 + TCP_FLAG_OFF, &flag, 1);
- if (ret == 0 && (flag >> RST_OFFSET & 1)) {
- return true;
- }
- }
- }
- } else if (skb->protocol == htons(ETH_P_IPV6)) {
- offset = IPV6_PROTO_OFF;
uint8_t proto;
- ret = bpf_skb_load_bytes(skb, offset, &proto, 1);
- if (!ret) {
- if (proto == IPPROTO_ESP) {
- return true;
- } else if (proto == IPPROTO_TCP) {
- uint8_t flag;
- ret = bpf_skb_load_bytes(skb, sizeof(struct ipv6hdr) + TCP_FLAG_OFF, &flag, 1);
- if (ret == 0 && (flag >> RST_OFFSET & 1)) {
- return true;
- }
- }
- }
+ // no need to check for success, proto will be zeroed if bpf_skb_load_bytes_net() fails
+ (void)bpf_skb_load_bytes_net(skb, IP_PROTO_OFF, &proto, sizeof(proto), is_4_19);
+ if (proto == IPPROTO_ESP) return true;
+ if (proto != IPPROTO_TCP) return false; // handles read failure above
+ uint8_t ihl;
+ // we don't check for success, as this cannot fail, as it is earlier in the packet than
+ // proto, the reading of which must have succeeded, additionally the next read
+ // (a little bit deeper in the packet in spite of ihl being zeroed) of the tcp flags
+ // field will also fail, and that failure we already handle correctly
+ // (we also don't check that ihl in [0x45,0x4F] nor that ipv4 header checksum is correct)
+ (void)bpf_skb_load_bytes_net(skb, IPPROTO_IHL_OFF, &ihl, sizeof(ihl), is_4_19);
+ uint32_t flag;
+ // if the read below fails, we'll just assume no TCP flags are set, which is fine.
+ (void)bpf_skb_load_bytes_net(skb, (ihl & 0xF) * 4 + TCP_FLAG32_OFF,
+ &flag, sizeof(flag), is_4_19);
+ return flag & TCP_FLAG_RST; // false on read failure
+ } else if (skb->protocol == htons(ETH_P_IPV6)) {
+ uint8_t proto;
+ // no need to check for success, proto will be zeroed if bpf_skb_load_bytes_net() fails
+ (void)bpf_skb_load_bytes_net(skb, IPV6_PROTO_OFF, &proto, sizeof(proto), is_4_19);
+ if (proto == IPPROTO_ESP) return true;
+ if (proto != IPPROTO_TCP) return false; // handles read failure above
+ uint32_t flag;
+ // if the read below fails, we'll just assume no TCP flags are set, which is fine.
+ (void)bpf_skb_load_bytes_net(skb, sizeof(struct ipv6hdr) + TCP_FLAG32_OFF,
+ &flag, sizeof(flag), is_4_19);
+ return flag & TCP_FLAG_RST; // false on read failure
}
return false;
}
-static __always_inline BpfConfig getConfig(uint32_t configKey) {
+static __always_inline inline BpfConfig getConfig(uint32_t configKey) {
uint32_t mapSettingKey = configKey;
BpfConfig* config = bpf_configuration_map_lookup_elem(&mapSettingKey);
if (!config) {
@@ -230,8 +246,9 @@
// DROP_IF_UNSET is set of rules that should DROP if globally enabled, and per-uid bit is NOT set
#define DROP_IF_UNSET (DOZABLE_MATCH | POWERSAVE_MATCH | RESTRICTED_MATCH | LOW_POWER_STANDBY_MATCH)
-static inline int bpf_owner_match(struct __sk_buff* skb, uint32_t uid, int direction) {
- if (skip_owner_match(skb)) return BPF_PASS;
+static __always_inline inline int bpf_owner_match(struct __sk_buff* skb, uint32_t uid,
+ int direction, bool is_4_19) {
+ if (skip_owner_match(skb, is_4_19)) return BPF_PASS;
if (is_system_uid(uid)) return BPF_PASS;
@@ -273,7 +290,8 @@
}
}
-static __always_inline inline int bpf_traffic_account(struct __sk_buff* skb, int direction) {
+static __always_inline inline int bpf_traffic_account(struct __sk_buff* skb, int direction,
+ bool is_4_19) {
uint32_t sock_uid = bpf_get_socket_uid(skb);
uint64_t cookie = bpf_get_socket_cookie(skb);
UidTagValue* utag = bpf_cookie_tag_map_lookup_elem(&cookie);
@@ -293,7 +311,7 @@
return BPF_PASS;
}
- int match = bpf_owner_match(skb, sock_uid, direction);
+ int match = bpf_owner_match(skb, sock_uid, direction, is_4_19);
if ((direction == BPF_EGRESS) && (match == BPF_DROP)) {
// If an outbound packet is going to be dropped, we do not count that
// traffic.
@@ -338,14 +356,28 @@
return match;
}
-DEFINE_NETD_BPF_PROG("cgroupskb/ingress/stats", AID_ROOT, AID_SYSTEM, bpf_cgroup_ingress)
+DEFINE_NETD_BPF_PROG_KVER_RANGE("cgroupskb/ingress/stats$4_19", AID_ROOT, AID_SYSTEM,
+ bpf_cgroup_ingress_4_19, KVER(4, 19, 0), KVER_INF)
(struct __sk_buff* skb) {
- return bpf_traffic_account(skb, BPF_INGRESS);
+ return bpf_traffic_account(skb, BPF_INGRESS, /* is_4_19 */ true);
}
-DEFINE_NETD_BPF_PROG("cgroupskb/egress/stats", AID_ROOT, AID_SYSTEM, bpf_cgroup_egress)
+DEFINE_NETD_BPF_PROG_KVER_RANGE("cgroupskb/ingress/stats$4_14", AID_ROOT, AID_SYSTEM,
+ bpf_cgroup_ingress_4_14, KVER_NONE, KVER(4, 19, 0))
(struct __sk_buff* skb) {
- return bpf_traffic_account(skb, BPF_EGRESS);
+ return bpf_traffic_account(skb, BPF_INGRESS, /* is_4_19 */ false);
+}
+
+DEFINE_NETD_BPF_PROG_KVER_RANGE("cgroupskb/egress/stats$4_19", AID_ROOT, AID_SYSTEM,
+ bpf_cgroup_egress_4_19, KVER(4, 19, 0), KVER_INF)
+(struct __sk_buff* skb) {
+ return bpf_traffic_account(skb, BPF_EGRESS, /* is_4_19 */ true);
+}
+
+DEFINE_NETD_BPF_PROG_KVER_RANGE("cgroupskb/egress/stats$4_14", AID_ROOT, AID_SYSTEM,
+ bpf_cgroup_egress_4_14, KVER_NONE, KVER(4, 19, 0))
+(struct __sk_buff* skb) {
+ return bpf_traffic_account(skb, BPF_EGRESS, /* is_4_19 */ false);
}
// WARNING: Android T's non-updatable netd depends on the name of this program.
@@ -419,7 +451,8 @@
return BPF_NOMATCH;
}
-DEFINE_NETD_BPF_PROG("cgroupsock/inet/create", AID_ROOT, AID_ROOT, inet_socket_create)
+DEFINE_NETD_BPF_PROG_KVER("cgroupsock/inet/create", AID_ROOT, AID_ROOT, inet_socket_create,
+ KVER(4, 14, 0))
(struct bpf_sock* sk) {
uint64_t gid_uid = bpf_get_current_uid_gid();
/*
diff --git a/bpf_progs/offload.c b/bpf_progs/offload.c
index bb9fc34..c7b444d 100644
--- a/bpf_progs/offload.c
+++ b/bpf_progs/offload.c
@@ -91,8 +91,11 @@
// ----- Tethering Error Counters -----
-DEFINE_BPF_MAP_GRW(tether_error_map, ARRAY, uint32_t, uint32_t, BPF_TETHER_ERR__MAX,
- TETHERING_GID)
+// Note that pre-T devices with Mediatek chipsets may have a kernel bug (bad patch
+// "[ALPS05162612] bpf: fix ubsan error") making it impossible to write to non-zero
+// offset of bpf map ARRAYs. This file (offload.o) loads on T, but luckily this
+// array is only written by bpf code, and only read by userspace.
+DEFINE_BPF_MAP_RO(tether_error_map, ARRAY, uint32_t, uint32_t, BPF_TETHER_ERR__MAX, TETHERING_GID)
#define COUNT_AND_RETURN(counter, ret) do { \
uint32_t code = BPF_TETHER_ERR_ ## counter; \
diff --git a/bpf_progs/test.c b/bpf_progs/test.c
index d42205f..c11c358 100644
--- a/bpf_progs/test.c
+++ b/bpf_progs/test.c
@@ -40,6 +40,10 @@
#define TETHERING_GID AID_NETWORK_STACK
#endif
+// This is non production code, only used for testing
+// Needed because the bitmap array definition is non-kosher for pre-T OS devices.
+#define THIS_BPF_PROGRAM_IS_FOR_TEST_PURPOSES_ONLY
+
#include "bpf_helpers.h"
#include "bpf_net_helpers.h"
#include "bpf_tethering.h"
diff --git a/common/src/com/android/net/module/util/bpf/ClatEgress4Key.java b/common/src/com/android/net/module/util/bpf/ClatEgress4Key.java
index 12200ec..f0af3dd 100644
--- a/common/src/com/android/net/module/util/bpf/ClatEgress4Key.java
+++ b/common/src/com/android/net/module/util/bpf/ClatEgress4Key.java
@@ -24,13 +24,13 @@
/** 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 = 0, type = Type.S32)
+ public final int 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) {
+ public ClatEgress4Key(final int iif, final Inet4Address local4) {
this.iif = iif;
this.local4 = local4;
}
diff --git a/common/src/com/android/net/module/util/bpf/ClatEgress4Value.java b/common/src/com/android/net/module/util/bpf/ClatEgress4Value.java
index c10cb4d..69fab09 100644
--- a/common/src/com/android/net/module/util/bpf/ClatEgress4Value.java
+++ b/common/src/com/android/net/module/util/bpf/ClatEgress4Value.java
@@ -24,8 +24,8 @@
/** 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 = 0, type = Type.S32)
+ public final int 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
@@ -36,7 +36,7 @@
@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,
+ public ClatEgress4Value(final int oif, final Inet6Address local6, final Inet6Address pfx96,
final short oifIsEthernet) {
this.oif = oif;
this.local6 = local6;
diff --git a/common/src/com/android/net/module/util/bpf/ClatIngress6Key.java b/common/src/com/android/net/module/util/bpf/ClatIngress6Key.java
index 1e2f4e0..561113c 100644
--- a/common/src/com/android/net/module/util/bpf/ClatIngress6Key.java
+++ b/common/src/com/android/net/module/util/bpf/ClatIngress6Key.java
@@ -24,8 +24,8 @@
/** 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 = 0, type = Type.S32)
+ public final int 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
@@ -33,7 +33,7 @@
@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) {
+ public ClatIngress6Key(final int iif, final Inet6Address pfx96, final Inet6Address local6) {
this.iif = iif;
this.pfx96 = pfx96;
this.local6 = local6;
diff --git a/common/src/com/android/net/module/util/bpf/ClatIngress6Value.java b/common/src/com/android/net/module/util/bpf/ClatIngress6Value.java
index bfec44f..fb81caa 100644
--- a/common/src/com/android/net/module/util/bpf/ClatIngress6Value.java
+++ b/common/src/com/android/net/module/util/bpf/ClatIngress6Value.java
@@ -24,13 +24,13 @@
/** 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 = 0, type = Type.S32)
+ public final int 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) {
+ public ClatIngress6Value(final int oif, final Inet4Address local4) {
this.oif = oif;
this.local4 = local4;
}
diff --git a/common/src/com/android/net/module/util/bpf/CookieTagMapValue.java b/common/src/com/android/net/module/util/bpf/CookieTagMapValue.java
index e1a221f..3fbd6fc 100644
--- a/common/src/com/android/net/module/util/bpf/CookieTagMapValue.java
+++ b/common/src/com/android/net/module/util/bpf/CookieTagMapValue.java
@@ -24,13 +24,13 @@
* Value for cookie tag map.
*/
public class CookieTagMapValue extends Struct {
- @Field(order = 0, type = Type.U32)
- public final long uid;
+ @Field(order = 0, type = Type.S32)
+ public final int uid;
@Field(order = 1, type = Type.U32)
public final long tag;
- public CookieTagMapValue(final long uid, final long tag) {
+ public CookieTagMapValue(final int uid, final long tag) {
this.uid = uid;
this.tag = tag;
}
diff --git a/common/src/com/android/net/module/util/bpf/Tether4Key.java b/common/src/com/android/net/module/util/bpf/Tether4Key.java
index 8273e6a..738256a 100644
--- a/common/src/com/android/net/module/util/bpf/Tether4Key.java
+++ b/common/src/com/android/net/module/util/bpf/Tether4Key.java
@@ -75,7 +75,7 @@
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);
+ return "Invalid IP address" + e;
}
}
}
diff --git a/common/src/com/android/net/module/util/bpf/Tether4Value.java b/common/src/com/android/net/module/util/bpf/Tether4Value.java
index 74fdda2..449c1da 100644
--- a/common/src/com/android/net/module/util/bpf/Tether4Value.java
+++ b/common/src/com/android/net/module/util/bpf/Tether4Value.java
@@ -91,7 +91,7 @@
Short.toUnsignedInt((short) srcPort), Short.toUnsignedInt((short) dstPort),
lastUsed);
} catch (UnknownHostException | IllegalArgumentException e) {
- return String.format("Invalid IP address", e);
+ return "Invalid IP address" + e;
}
}
}
diff --git a/common/src/com/android/net/module/util/bpf/TetherStatsKey.java b/common/src/com/android/net/module/util/bpf/TetherStatsKey.java
index c6d595b..68111b6 100644
--- a/common/src/com/android/net/module/util/bpf/TetherStatsKey.java
+++ b/common/src/com/android/net/module/util/bpf/TetherStatsKey.java
@@ -22,32 +22,10 @@
/** 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
+ @Field(order = 0, type = Type.S32)
+ public final int ifindex; // upstream interface index
- public TetherStatsKey(final long ifindex) {
+ public TetherStatsKey(final int 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/src/com/android/net/module/util/bpf/TetherStatsValue.java b/common/src/com/android/net/module/util/bpf/TetherStatsValue.java
index 028d217..f05d1b7 100644
--- a/common/src/com/android/net/module/util/bpf/TetherStatsValue.java
+++ b/common/src/com/android/net/module/util/bpf/TetherStatsValue.java
@@ -47,34 +47,4 @@
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/framework-t/Android.bp b/framework-t/Android.bp
index 2e49307..d40fad9 100644
--- a/framework-t/Android.bp
+++ b/framework-t/Android.bp
@@ -75,6 +75,12 @@
],
}
+filegroup {
+ name: "connectivity-t-hiddenapi-files",
+ srcs: ["hiddenapi/*.txt"],
+ visibility: ["//packages/modules/Connectivity:__subpackages__"],
+}
+
java_library {
name: "framework-connectivity-t-pre-jarjar",
defaults: ["framework-connectivity-t-defaults"],
@@ -114,6 +120,19 @@
"com.android.connectivity",
"com.android.nearby",
],
+
+ hidden_api: {
+ max_target_o_low_priority: [
+ "hiddenapi/hiddenapi-max-target-o-low-priority-tiramisu.txt",
+ ],
+ max_target_r_low_priority: [
+ "hiddenapi/hiddenapi-max-target-r-loprio.txt",
+ ],
+ unsupported: [
+ "hiddenapi/hiddenapi-unsupported-tiramisu.txt",
+ ],
+ },
+
impl_library_visibility: [
"//packages/modules/Connectivity/Tethering/apex",
// In preparation for future move
diff --git a/Tethering/apex/hiddenapi/hiddenapi-max-target-o-low-priority-tiramisu.txt b/framework-t/hiddenapi/hiddenapi-max-target-o-low-priority-tiramisu.txt
similarity index 100%
rename from Tethering/apex/hiddenapi/hiddenapi-max-target-o-low-priority-tiramisu.txt
rename to framework-t/hiddenapi/hiddenapi-max-target-o-low-priority-tiramisu.txt
diff --git a/Tethering/apex/hiddenapi/hiddenapi-max-target-r-loprio.txt b/framework-t/hiddenapi/hiddenapi-max-target-r-loprio.txt
similarity index 100%
rename from Tethering/apex/hiddenapi/hiddenapi-max-target-r-loprio.txt
rename to framework-t/hiddenapi/hiddenapi-max-target-r-loprio.txt
diff --git a/Tethering/apex/hiddenapi/hiddenapi-unsupported-tiramisu.txt b/framework-t/hiddenapi/hiddenapi-unsupported-tiramisu.txt
similarity index 100%
rename from Tethering/apex/hiddenapi/hiddenapi-unsupported-tiramisu.txt
rename to framework-t/hiddenapi/hiddenapi-unsupported-tiramisu.txt
diff --git a/framework-t/src/android/net/IpSecAlgorithm.java b/framework-t/src/android/net/IpSecAlgorithm.java
index 10a22ac..a39a80d 100644
--- a/framework-t/src/android/net/IpSecAlgorithm.java
+++ b/framework-t/src/android/net/IpSecAlgorithm.java
@@ -488,4 +488,4 @@
&& Arrays.equals(lhs.mKey, rhs.mKey)
&& lhs.mTruncLenBits == rhs.mTruncLenBits);
}
-};
+}
diff --git a/framework-t/src/android/net/NetworkIdentity.java b/framework-t/src/android/net/NetworkIdentity.java
index da5f88d..48e5092 100644
--- a/framework-t/src/android/net/NetworkIdentity.java
+++ b/framework-t/src/android/net/NetworkIdentity.java
@@ -34,8 +34,8 @@
import android.telephony.TelephonyManager;
import android.util.proto.ProtoOutputStream;
+import com.android.net.module.util.BitUtils;
import com.android.net.module.util.CollectionUtils;
-import com.android.net.module.util.NetworkCapabilitiesUtils;
import com.android.net.module.util.NetworkIdentityUtils;
import java.lang.annotation.Retention;
@@ -85,6 +85,12 @@
private static final long SUPPORTED_OEM_MANAGED_TYPES = OEM_PAID | OEM_PRIVATE;
+ // Need to be synchronized with ConnectivityManager.
+ // TODO: Use {@code ConnectivityManager#*} when visible.
+ static final int TYPE_TEST = 18;
+ private static final int MAX_NETWORK_TYPE = TYPE_TEST;
+ private static final int MIN_NETWORK_TYPE = TYPE_MOBILE;
+
final int mType;
final int mRatType;
final int mSubId;
@@ -166,7 +172,7 @@
if (oemManaged == OEM_NONE) {
return "OEM_NONE";
}
- final int[] bitPositions = NetworkCapabilitiesUtils.unpackBits(oemManaged);
+ final int[] bitPositions = BitUtils.unpackBits(oemManaged);
final ArrayList<String> oemManagedNames = new ArrayList<String>();
for (int position : bitPositions) {
oemManagedNames.add(nameOfOemManaged(1 << position));
@@ -346,11 +352,6 @@
* Builder class for {@link NetworkIdentity}.
*/
public static final class Builder {
- // Need to be synchronized with ConnectivityManager.
- // TODO: Use {@link ConnectivityManager#MAX_NETWORK_TYPE} when this file is in the module.
- private static final int MAX_NETWORK_TYPE = 18; // TYPE_TEST
- private static final int MIN_NETWORK_TYPE = TYPE_MOBILE;
-
private int mType;
private int mRatType;
private String mSubscriberId;
@@ -413,6 +414,12 @@
final WifiInfo info = (WifiInfo) transportInfo;
setWifiNetworkKey(info.getNetworkKey());
}
+ } else if (mType == TYPE_TEST) {
+ final NetworkSpecifier ns = snapshot.getNetworkCapabilities().getNetworkSpecifier();
+ if (ns instanceof TestNetworkSpecifier) {
+ // Reuse the wifi network key field to identify individual test networks.
+ setWifiNetworkKey(((TestNetworkSpecifier) ns).getInterfaceName());
+ }
}
return this;
}
@@ -574,7 +581,7 @@
}
// Assert non-wifi network cannot have a wifi network key.
- if (mType != TYPE_WIFI && mWifiNetworkKey != null) {
+ if (mType != TYPE_WIFI && mType != TYPE_TEST && mWifiNetworkKey != null) {
throw new IllegalArgumentException("Invalid wifi network key for type " + mType);
}
}
diff --git a/framework-t/src/android/net/NetworkTemplate.java b/framework-t/src/android/net/NetworkTemplate.java
index b82a126..b6bd1a5 100644
--- a/framework-t/src/android/net/NetworkTemplate.java
+++ b/framework-t/src/android/net/NetworkTemplate.java
@@ -50,6 +50,7 @@
import android.text.TextUtils;
import android.util.ArraySet;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.net.module.util.CollectionUtils;
import com.android.net.module.util.NetworkIdentityUtils;
import com.android.net.module.util.NetworkStatsUtils;
@@ -114,6 +115,14 @@
* may offer non-cellular networks like WiFi, which will be matched by this rule.
*/
public static final int MATCH_CARRIER = 10;
+ /**
+ * Match rule to match networks with {@link ConnectivityManager#TYPE_TEST} as the legacy
+ * network type.
+ *
+ * @hide
+ */
+ @VisibleForTesting
+ public static final int MATCH_TEST = 11;
// TODO: Remove this and replace all callers with WIFI_NETWORK_KEY_ALL.
/** @hide */
@@ -176,6 +185,7 @@
case MATCH_BLUETOOTH:
case MATCH_PROXY:
case MATCH_CARRIER:
+ case MATCH_TEST:
return true;
default:
@@ -666,6 +676,8 @@
return matchesProxy(ident);
case MATCH_CARRIER:
return matchesCarrier(ident);
+ case MATCH_TEST:
+ return matchesTest(ident);
default:
// We have no idea what kind of network template we are, so we
// just claim not to match anything.
@@ -776,6 +788,17 @@
&& CollectionUtils.contains(mMatchSubscriberIds, ident.mSubscriberId);
}
+ /**
+ * Check if matches test network. If the wifiNetworkKeys in the template is specified, Then it
+ * will only match a network containing any of the specified the wifi network key. Otherwise,
+ * all test networks would be matched.
+ */
+ private boolean matchesTest(NetworkIdentity ident) {
+ return ident.mType == NetworkIdentity.TYPE_TEST
+ && ((CollectionUtils.isEmpty(mMatchWifiNetworkKeys)
+ || CollectionUtils.contains(mMatchWifiNetworkKeys, ident.mWifiNetworkKey)));
+ }
+
private boolean matchesMobileWildcard(NetworkIdentity ident) {
if (ident.mType == TYPE_WIMAX) {
return true;
@@ -829,6 +852,8 @@
return "PROXY";
case MATCH_CARRIER:
return "CARRIER";
+ case MATCH_TEST:
+ return "TEST";
default:
return "UNKNOWN(" + matchRule + ")";
}
@@ -1079,7 +1104,9 @@
}
private void validateWifiNetworkKeys() {
- if (mMatchRule != MATCH_WIFI && !mMatchWifiNetworkKeys.isEmpty()) {
+ // Also allow querying test networks which use wifi network key as identifier.
+ if (mMatchRule != MATCH_WIFI && mMatchRule != MATCH_TEST
+ && !mMatchWifiNetworkKeys.isEmpty()) {
throw new IllegalArgumentException("Trying to build non wifi match rule: "
+ mMatchRule + " with wifi network keys");
}
diff --git a/framework/Android.bp b/framework/Android.bp
index fcce7a5..485961c 100644
--- a/framework/Android.bp
+++ b/framework/Android.bp
@@ -228,12 +228,13 @@
],
out: ["framework_connectivity_jarjar_rules.txt"],
cmd: "$(location jarjar-rules-generator) " +
- "--jars $(location :framework-connectivity-pre-jarjar{.jar}) " +
+ "$(location :framework-connectivity-pre-jarjar{.jar}) " +
"$(location :framework-connectivity-t-pre-jarjar{.jar}) " +
"--prefix android.net.connectivity " +
"--apistubs $(location :framework-connectivity.stubs.module_lib{.jar}) " +
- "$(location :framework-connectivity-t.stubs.module_lib{.jar}) " +
- "--unsupportedapi $(locations :connectivity-hiddenapi-files) " +
+ "--apistubs $(location :framework-connectivity-t.stubs.module_lib{.jar}) " +
+ // Make a ":"-separated list. There will be an extra ":" but empty items are ignored.
+ "--unsupportedapi $$(printf ':%s' $(locations :connectivity-hiddenapi-files)) " +
"--excludes $(location jarjar-excludes.txt) " +
"--output $(out)",
visibility: [
diff --git a/framework/api/system-current.txt b/framework/api/system-current.txt
index f1298ce..8b35197 100644
--- a/framework/api/system-current.txt
+++ b/framework/api/system-current.txt
@@ -433,6 +433,7 @@
public abstract class QosFilter {
method @NonNull public abstract android.net.Network getNetwork();
method public abstract boolean matchesLocalAddress(@NonNull java.net.InetAddress, int, int);
+ method public boolean matchesProtocol(int);
method public abstract boolean matchesRemoteAddress(@NonNull java.net.InetAddress, int, int);
}
@@ -453,6 +454,7 @@
public final class QosSocketInfo implements android.os.Parcelable {
ctor public QosSocketInfo(@NonNull android.net.Network, @NonNull java.net.Socket) throws java.io.IOException;
+ ctor public QosSocketInfo(@NonNull android.net.Network, @NonNull java.net.DatagramSocket) throws java.io.IOException;
method public int describeContents();
method @NonNull public java.net.InetSocketAddress getLocalSocketAddress();
method @NonNull public android.net.Network getNetwork();
@@ -480,6 +482,14 @@
ctor public SocketNotBoundException();
}
+ public class SocketNotConnectedException extends java.lang.Exception {
+ ctor public SocketNotConnectedException();
+ }
+
+ public class SocketRemoteAddressChangedException extends java.lang.Exception {
+ ctor public SocketRemoteAddressChangedException();
+ }
+
public final class StaticIpConfiguration implements android.os.Parcelable {
ctor public StaticIpConfiguration();
ctor public StaticIpConfiguration(@Nullable android.net.StaticIpConfiguration);
diff --git a/framework/src/android/net/ConnectivityManager.java b/framework/src/android/net/ConnectivityManager.java
index 1fbbd25..b5c3c64 100644
--- a/framework/src/android/net/ConnectivityManager.java
+++ b/framework/src/android/net/ConnectivityManager.java
@@ -1167,6 +1167,8 @@
return "PROXY";
case TYPE_VPN:
return "VPN";
+ case TYPE_TEST:
+ return "TEST";
default:
return Integer.toString(type);
}
@@ -4078,7 +4080,7 @@
}
}
- private class CallbackHandler extends Handler {
+ private static class CallbackHandler extends Handler {
private static final String TAG = "ConnectivityManager.CallbackHandler";
private static final boolean DBG = false;
@@ -4093,7 +4095,10 @@
@Override
public void handleMessage(Message message) {
if (message.what == EXPIRE_LEGACY_REQUEST) {
- expireRequest((NetworkCapabilities) message.obj, message.arg1);
+ // the sInstance can't be null because to send this message a ConnectivityManager
+ // instance must have been created prior to creating the thread on which this
+ // Handler is running.
+ sInstance.expireRequest((NetworkCapabilities) message.obj, message.arg1);
return;
}
diff --git a/framework/src/android/net/DnsResolver.java b/framework/src/android/net/DnsResolver.java
index 5e637f9..c6034f1 100644
--- a/framework/src/android/net/DnsResolver.java
+++ b/framework/src/android/net/DnsResolver.java
@@ -542,7 +542,7 @@
DnsAddressAnswer(@NonNull byte[] data) throws ParseException {
super(data);
- if ((mHeader.flags & (1 << 15)) == 0) {
+ if ((mHeader.getFlags() & (1 << 15)) == 0) {
throw new ParseException("Not an answer packet");
}
if (mHeader.getRecordCount(QDSECTION) == 0) {
diff --git a/framework/src/android/net/NetworkAgentConfig.java b/framework/src/android/net/NetworkAgentConfig.java
index b6f3314..da12a0a 100644
--- a/framework/src/android/net/NetworkAgentConfig.java
+++ b/framework/src/android/net/NetworkAgentConfig.java
@@ -188,7 +188,8 @@
* Set to true if the PRIVATE_DNS_BROKEN notification has shown for this network.
* Reset this bit when private DNS mode is changed from strict mode to opportunistic/off mode.
*
- * This is not parceled, because it would not make sense.
+ * This is not parceled, because it would not make sense. It's also ignored by the
+ * equals() and hashcode() methods.
*
* @hide
*/
@@ -503,8 +504,10 @@
&& provisioningNotificationDisabled == that.provisioningNotificationDisabled
&& skip464xlat == that.skip464xlat
&& legacyType == that.legacyType
+ && legacySubType == that.legacySubType
&& Objects.equals(subscriberId, that.subscriberId)
&& Objects.equals(legacyTypeName, that.legacyTypeName)
+ && Objects.equals(legacySubTypeName, that.legacySubTypeName)
&& Objects.equals(mLegacyExtraInfo, that.mLegacyExtraInfo)
&& excludeLocalRouteVpn == that.excludeLocalRouteVpn
&& mVpnRequiresValidation == that.mVpnRequiresValidation;
@@ -514,8 +517,8 @@
public int hashCode() {
return Objects.hash(allowBypass, explicitlySelected, acceptUnvalidated,
acceptPartialConnectivity, provisioningNotificationDisabled, subscriberId,
- skip464xlat, legacyType, legacyTypeName, mLegacyExtraInfo, excludeLocalRouteVpn,
- mVpnRequiresValidation);
+ skip464xlat, legacyType, legacySubType, legacyTypeName, legacySubTypeName,
+ mLegacyExtraInfo, excludeLocalRouteVpn, mVpnRequiresValidation);
}
@Override
@@ -529,8 +532,10 @@
+ ", subscriberId = '" + subscriberId + '\''
+ ", skip464xlat = " + skip464xlat
+ ", legacyType = " + legacyType
+ + ", legacySubType = " + legacySubType
+ ", hasShownBroken = " + hasShownBroken
+ ", legacyTypeName = '" + legacyTypeName + '\''
+ + ", legacySubTypeName = '" + legacySubTypeName + '\''
+ ", legacyExtraInfo = '" + mLegacyExtraInfo + '\''
+ ", excludeLocalRouteVpn = '" + excludeLocalRouteVpn + '\''
+ ", vpnRequiresValidation = '" + mVpnRequiresValidation + '\''
diff --git a/framework/src/android/net/NetworkCapabilities.java b/framework/src/android/net/NetworkCapabilities.java
index ea8a3df..e07601f 100644
--- a/framework/src/android/net/NetworkCapabilities.java
+++ b/framework/src/android/net/NetworkCapabilities.java
@@ -17,6 +17,7 @@
package android.net;
import static com.android.internal.annotations.VisibleForTesting.Visibility.PRIVATE;
+import static com.android.net.module.util.BitUtils.appendStringRepresentationOfBitMaskToStringBuilder;
import android.annotation.IntDef;
import android.annotation.LongDef;
@@ -36,6 +37,7 @@
import android.util.Range;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.net.module.util.BitUtils;
import com.android.net.module.util.CollectionUtils;
import com.android.net.module.util.NetworkCapabilitiesUtils;
@@ -185,10 +187,18 @@
NET_ENTERPRISE_ID_4,
NET_ENTERPRISE_ID_5,
})
-
public @interface EnterpriseId {
}
+ private static final int ALL_VALID_ENTERPRISE_IDS;
+ static {
+ int enterpriseIds = 0;
+ for (int i = NET_ENTERPRISE_ID_1; i <= NET_ENTERPRISE_ID_5; ++i) {
+ enterpriseIds |= 1 << i;
+ }
+ ALL_VALID_ENTERPRISE_IDS = enterpriseIds;
+ }
+
/**
* Bitfield representing the network's enterprise capability identifier. If any are specified
* they will be satisfied by any Network that matches all of them.
@@ -209,7 +219,7 @@
if (hasCapability(NET_CAPABILITY_ENTERPRISE) && mEnterpriseId == 0) {
return new int[]{NET_ENTERPRISE_ID_1};
}
- return NetworkCapabilitiesUtils.unpackBits(mEnterpriseId);
+ return BitUtils.unpackBits(mEnterpriseId);
}
/**
@@ -622,11 +632,20 @@
private static final int MIN_NET_CAPABILITY = NET_CAPABILITY_MMS;
private static final int MAX_NET_CAPABILITY = NET_CAPABILITY_PRIORITIZE_BANDWIDTH;
+ private static final int ALL_VALID_CAPABILITIES;
+ static {
+ int caps = 0;
+ for (int i = MIN_NET_CAPABILITY; i <= MAX_NET_CAPABILITY; ++i) {
+ caps |= 1 << i;
+ }
+ ALL_VALID_CAPABILITIES = caps;
+ }
+
/**
* Network capabilities that are expected to be mutable, i.e., can change while a particular
* network is connected.
*/
- private static final long MUTABLE_CAPABILITIES = NetworkCapabilitiesUtils.packBitList(
+ private static final long MUTABLE_CAPABILITIES = BitUtils.packBitList(
// TRUSTED can change when user explicitly connects to an untrusted network in Settings.
// http://b/18206275
NET_CAPABILITY_TRUSTED,
@@ -661,7 +680,7 @@
/**
* Capabilities that are set by default when the object is constructed.
*/
- private static final long DEFAULT_CAPABILITIES = NetworkCapabilitiesUtils.packBitList(
+ private static final long DEFAULT_CAPABILITIES = BitUtils.packBitList(
NET_CAPABILITY_NOT_RESTRICTED,
NET_CAPABILITY_TRUSTED,
NET_CAPABILITY_NOT_VPN);
@@ -670,7 +689,7 @@
* Capabilities that are managed by ConnectivityService.
*/
private static final long CONNECTIVITY_MANAGED_CAPABILITIES =
- NetworkCapabilitiesUtils.packBitList(
+ BitUtils.packBitList(
NET_CAPABILITY_VALIDATED,
NET_CAPABILITY_CAPTIVE_PORTAL,
NET_CAPABILITY_FOREGROUND,
@@ -683,7 +702,7 @@
* INTERNET, IMS, SUPL, etc.
*/
private static final long TEST_NETWORKS_ALLOWED_CAPABILITIES =
- NetworkCapabilitiesUtils.packBitList(
+ BitUtils.packBitList(
NET_CAPABILITY_NOT_METERED,
NET_CAPABILITY_TEMPORARILY_NOT_METERED,
NET_CAPABILITY_NOT_RESTRICTED,
@@ -783,7 +802,7 @@
* @return an array of capability values for this instance.
*/
public @NonNull @NetCapability int[] getCapabilities() {
- return NetworkCapabilitiesUtils.unpackBits(mNetworkCapabilities);
+ return BitUtils.unpackBits(mNetworkCapabilities);
}
/**
@@ -793,7 +812,7 @@
* @hide
*/
public @NetCapability int[] getForbiddenCapabilities() {
- return NetworkCapabilitiesUtils.unpackBits(mForbiddenNetworkCapabilities);
+ return BitUtils.unpackBits(mForbiddenNetworkCapabilities);
}
@@ -805,8 +824,8 @@
*/
public void setCapabilities(@NetCapability int[] capabilities,
@NetCapability int[] forbiddenCapabilities) {
- mNetworkCapabilities = NetworkCapabilitiesUtils.packBits(capabilities);
- mForbiddenNetworkCapabilities = NetworkCapabilitiesUtils.packBits(forbiddenCapabilities);
+ mNetworkCapabilities = BitUtils.packBits(capabilities);
+ mForbiddenNetworkCapabilities = BitUtils.packBits(forbiddenCapabilities);
}
/**
@@ -943,7 +962,7 @@
& NON_REQUESTABLE_CAPABILITIES;
if (nonRequestable != 0) {
- return capabilityNameOf(NetworkCapabilitiesUtils.unpackBits(nonRequestable)[0]);
+ return capabilityNameOf(BitUtils.unpackBits(nonRequestable)[0]);
}
if (mLinkUpBandwidthKbps != 0 || mLinkDownBandwidthKbps != 0) return "link bandwidth";
if (hasSignalStrength()) return "signalStrength";
@@ -1146,6 +1165,15 @@
/** @hide */
public static final int MAX_TRANSPORT = TRANSPORT_USB;
+ private static final int ALL_VALID_TRANSPORTS;
+ static {
+ int transports = 0;
+ for (int i = MIN_TRANSPORT; i <= MAX_TRANSPORT; ++i) {
+ transports |= 1 << i;
+ }
+ ALL_VALID_TRANSPORTS = transports;
+ }
+
/** @hide */
public static boolean isValidTransport(@Transport int transportType) {
return (MIN_TRANSPORT <= transportType) && (transportType <= MAX_TRANSPORT);
@@ -1167,7 +1195,7 @@
* Allowed transports on an unrestricted test network (in addition to TRANSPORT_TEST).
*/
private static final long UNRESTRICTED_TEST_NETWORKS_ALLOWED_TRANSPORTS =
- NetworkCapabilitiesUtils.packBitList(
+ BitUtils.packBitList(
TRANSPORT_TEST,
// Test eth networks are created with EthernetManager#setIncludeTestInterfaces
TRANSPORT_ETHERNET,
@@ -1232,7 +1260,7 @@
*/
@SystemApi
@NonNull public @Transport int[] getTransportTypes() {
- return NetworkCapabilitiesUtils.unpackBits(mTransportTypes);
+ return BitUtils.unpackBits(mTransportTypes);
}
/**
@@ -1242,7 +1270,7 @@
* @hide
*/
public void setTransportTypes(@Transport int[] transportTypes) {
- mTransportTypes = NetworkCapabilitiesUtils.packBits(transportTypes);
+ mTransportTypes = BitUtils.packBits(transportTypes);
}
/**
@@ -2015,9 +2043,9 @@
long oldImmutableCapabilities = this.mNetworkCapabilities & mask;
long newImmutableCapabilities = that.mNetworkCapabilities & mask;
if (oldImmutableCapabilities != newImmutableCapabilities) {
- String before = capabilityNamesOf(NetworkCapabilitiesUtils.unpackBits(
+ String before = capabilityNamesOf(BitUtils.unpackBits(
oldImmutableCapabilities));
- String after = capabilityNamesOf(NetworkCapabilitiesUtils.unpackBits(
+ String after = capabilityNamesOf(BitUtils.unpackBits(
newImmutableCapabilities));
joiner.add(String.format("immutable capabilities changed: %s -> %s", before, after));
}
@@ -2038,6 +2066,36 @@
}
/**
+ * Returns a short but human-readable string of updates from an older set of capabilities.
+ * @param old the old capabilities to diff from
+ * @return a string fit for logging differences, or null if no differences.
+ * this never returns the empty string.
+ * @hide
+ */
+ @Nullable
+ public String describeCapsDifferencesFrom(@Nullable final NetworkCapabilities old) {
+ final long oldCaps = null == old ? 0 : old.mNetworkCapabilities;
+ final long changed = oldCaps ^ mNetworkCapabilities;
+ if (0 == changed) return null;
+ // If the control reaches here, there are changes (additions, removals, or both) so
+ // the code below is guaranteed to add something to the string and can't return "".
+ final long removed = oldCaps & changed;
+ final long added = mNetworkCapabilities & changed;
+ final StringBuilder sb = new StringBuilder();
+ if (0 != removed) {
+ sb.append("-");
+ appendStringRepresentationOfBitMaskToStringBuilder(sb, removed,
+ NetworkCapabilities::capabilityNameOf, "-");
+ }
+ if (0 != added) {
+ sb.append("+");
+ appendStringRepresentationOfBitMaskToStringBuilder(sb, added,
+ NetworkCapabilities::capabilityNameOf, "+");
+ }
+ return sb.toString();
+ }
+
+ /**
* Checks that our requestable capabilities are the same as those of the given
* {@code NetworkCapabilities}.
*
@@ -2114,9 +2172,9 @@
@Override
public void writeToParcel(Parcel dest, int flags) {
- dest.writeLong(mNetworkCapabilities);
- dest.writeLong(mForbiddenNetworkCapabilities);
- dest.writeLong(mTransportTypes);
+ dest.writeLong(mNetworkCapabilities & ALL_VALID_CAPABILITIES);
+ dest.writeLong(mForbiddenNetworkCapabilities & ALL_VALID_CAPABILITIES);
+ dest.writeLong(mTransportTypes & ALL_VALID_TRANSPORTS);
dest.writeInt(mLinkUpBandwidthKbps);
dest.writeInt(mLinkDownBandwidthKbps);
dest.writeParcelable((Parcelable) mNetworkSpecifier, flags);
@@ -2132,7 +2190,7 @@
dest.writeString(mRequestorPackageName);
dest.writeIntArray(CollectionUtils.toIntArray(mSubIds));
dest.writeTypedList(mUnderlyingNetworks);
- dest.writeInt(mEnterpriseId);
+ dest.writeInt(mEnterpriseId & ALL_VALID_ENTERPRISE_IDS);
}
public static final @android.annotation.NonNull Creator<NetworkCapabilities> CREATOR =
@@ -2140,10 +2198,10 @@
@Override
public NetworkCapabilities createFromParcel(Parcel in) {
NetworkCapabilities netCap = new NetworkCapabilities();
-
- netCap.mNetworkCapabilities = in.readLong();
- netCap.mForbiddenNetworkCapabilities = in.readLong();
- netCap.mTransportTypes = in.readLong();
+ // Validate the unparceled data, in case the parceling party was malicious.
+ netCap.mNetworkCapabilities = in.readLong() & ALL_VALID_CAPABILITIES;
+ netCap.mForbiddenNetworkCapabilities = in.readLong() & ALL_VALID_CAPABILITIES;
+ netCap.mTransportTypes = in.readLong() & ALL_VALID_TRANSPORTS;
netCap.mLinkUpBandwidthKbps = in.readInt();
netCap.mLinkDownBandwidthKbps = in.readInt();
netCap.mNetworkSpecifier = in.readParcelable(null);
@@ -2167,7 +2225,7 @@
netCap.mSubIds.add(subIdInts[i]);
}
netCap.setUnderlyingNetworks(in.createTypedArrayList(Network.CREATOR));
- netCap.mEnterpriseId = in.readInt();
+ netCap.mEnterpriseId = in.readInt() & ALL_VALID_ENTERPRISE_IDS;
return netCap;
}
@Override
@@ -2287,32 +2345,6 @@
return sb.toString();
}
-
- private interface NameOf {
- String nameOf(int value);
- }
-
- /**
- * @hide
- */
- public static void appendStringRepresentationOfBitMaskToStringBuilder(@NonNull StringBuilder sb,
- long bitMask, @NonNull NameOf nameFetcher, @NonNull String separator) {
- int bitPos = 0;
- boolean firstElementAdded = false;
- while (bitMask != 0) {
- if ((bitMask & 1) != 0) {
- if (firstElementAdded) {
- sb.append(separator);
- } else {
- firstElementAdded = true;
- }
- sb.append(nameFetcher.nameOf(bitPos));
- }
- bitMask >>= 1;
- ++bitPos;
- }
- }
-
/**
* @hide
*/
diff --git a/framework/src/android/net/QosFilter.java b/framework/src/android/net/QosFilter.java
index 01dc4bb..a731b23 100644
--- a/framework/src/android/net/QosFilter.java
+++ b/framework/src/android/net/QosFilter.java
@@ -97,10 +97,15 @@
* Determines whether or not the parameter will be matched with this filter.
*
* @param protocol the protocol such as TCP or UDP included in IP packet filter set of a QoS
- * flow assigned on {@link Network}.
+ * flow assigned on {@link Network}. Only {@code IPPROTO_TCP} and {@code
+ * IPPROTO_UDP} currently supported.
* @return whether the parameters match the socket type of the filter
- * @hide
*/
- public abstract boolean matchesProtocol(int protocol);
+ // Since this method is added in U, it's required to be default method for binary compatibility
+ // with existing @SystemApi.
+ // IPPROTO_* are not compile-time constants, so they are not annotated with @IntDef.
+ public boolean matchesProtocol(int protocol) {
+ return false;
+ }
}
diff --git a/framework/src/android/net/QosSocketInfo.java b/framework/src/android/net/QosSocketInfo.java
index da9b356..1c3db23 100644
--- a/framework/src/android/net/QosSocketInfo.java
+++ b/framework/src/android/net/QosSocketInfo.java
@@ -144,7 +144,6 @@
*
* @param network the network
* @param socket the bound {@link DatagramSocket}
- * @hide
*/
public QosSocketInfo(@NonNull final Network network, @NonNull final DatagramSocket socket)
throws IOException {
diff --git a/framework/src/android/net/SocketNotConnectedException.java b/framework/src/android/net/SocketNotConnectedException.java
index fa2a615..a6357c7 100644
--- a/framework/src/android/net/SocketNotConnectedException.java
+++ b/framework/src/android/net/SocketNotConnectedException.java
@@ -16,13 +16,18 @@
package android.net;
+import android.annotation.SystemApi;
+
+import com.android.internal.annotations.VisibleForTesting;
+
/**
* Thrown when a previously bound socket becomes unbound.
*
* @hide
*/
+@SystemApi
public class SocketNotConnectedException extends Exception {
- /** @hide */
+ @VisibleForTesting
public SocketNotConnectedException() {
super("The socket is not connected");
}
diff --git a/framework/src/android/net/SocketRemoteAddressChangedException.java b/framework/src/android/net/SocketRemoteAddressChangedException.java
index ecaeebc..e13d5ed 100644
--- a/framework/src/android/net/SocketRemoteAddressChangedException.java
+++ b/framework/src/android/net/SocketRemoteAddressChangedException.java
@@ -16,13 +16,18 @@
package android.net;
+import android.annotation.SystemApi;
+
+import com.android.internal.annotations.VisibleForTesting;
+
/**
* Thrown when the local address of the socket has changed.
*
* @hide
*/
+@SystemApi
public class SocketRemoteAddressChangedException extends Exception {
- /** @hide */
+ @VisibleForTesting
public SocketRemoteAddressChangedException() {
super("The remote address of the socket changed");
}
diff --git a/framework/src/android/net/util/MultinetworkPolicyTracker.java b/framework/src/android/net/util/MultinetworkPolicyTracker.java
deleted file mode 100644
index c1790c9..0000000
--- a/framework/src/android/net/util/MultinetworkPolicyTracker.java
+++ /dev/null
@@ -1,269 +0,0 @@
-/*
- * Copyright (C) 2016 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.util;
-
-import static android.net.ConnectivitySettingsManager.NETWORK_AVOID_BAD_WIFI;
-import static android.net.ConnectivitySettingsManager.NETWORK_METERED_MULTIPATH_PREFERENCE;
-
-import android.annotation.NonNull;
-import android.annotation.TargetApi;
-import android.content.BroadcastReceiver;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.res.Resources;
-import android.database.ContentObserver;
-import android.net.ConnectivityResources;
-import android.net.Uri;
-import android.os.Build;
-import android.os.Handler;
-import android.provider.Settings;
-import android.telephony.SubscriptionManager;
-import android.telephony.TelephonyCallback;
-import android.telephony.TelephonyManager;
-import android.util.Log;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.concurrent.Executor;
-import java.util.concurrent.RejectedExecutionException;
-
-/**
- * A class to encapsulate management of the "Smart Networking" capability of
- * avoiding bad Wi-Fi when, for example upstream connectivity is lost or
- * certain critical link failures occur.
- *
- * This enables the device to switch to another form of connectivity, like
- * mobile, if it's available and working.
- *
- * The Runnable |avoidBadWifiCallback|, if given, is posted to the supplied
- * Handler' whenever the computed "avoid bad wifi" value changes.
- *
- * Disabling this reverts the device to a level of networking sophistication
- * circa 2012-13 by disabling disparate code paths each of which contribute to
- * maintaining continuous, working Internet connectivity.
- *
- * @hide
- */
-public class MultinetworkPolicyTracker {
- private static String TAG = MultinetworkPolicyTracker.class.getSimpleName();
-
- private final Context mContext;
- private final ConnectivityResources mResources;
- private final Handler mHandler;
- private final Runnable mAvoidBadWifiCallback;
- private final List<Uri> mSettingsUris;
- private final ContentResolver mResolver;
- private final SettingObserver mSettingObserver;
- private final BroadcastReceiver mBroadcastReceiver;
-
- private volatile boolean mAvoidBadWifi = true;
- private volatile int mMeteredMultipathPreference;
- private int mActiveSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
- private volatile long mTestAllowBadWifiUntilMs = 0;
-
- // Mainline module can't use internal HandlerExecutor, so add an identical executor here.
- private static class HandlerExecutor implements Executor {
- @NonNull
- private final Handler mHandler;
-
- HandlerExecutor(@NonNull Handler handler) {
- mHandler = handler;
- }
- @Override
- public void execute(Runnable command) {
- if (!mHandler.post(command)) {
- throw new RejectedExecutionException(mHandler + " is shutting down");
- }
- }
- }
- // TODO: Set the mini sdk to 31 and remove @TargetApi annotation when b/205923322 is addressed.
- @VisibleForTesting @TargetApi(Build.VERSION_CODES.S)
- protected class ActiveDataSubscriptionIdListener extends TelephonyCallback
- implements TelephonyCallback.ActiveDataSubscriptionIdListener {
- @Override
- public void onActiveDataSubscriptionIdChanged(int subId) {
- mActiveSubId = subId;
- reevaluateInternal();
- }
- }
-
- public MultinetworkPolicyTracker(Context ctx, Handler handler) {
- this(ctx, handler, null);
- }
-
- // TODO: Set the mini sdk to 31 and remove @TargetApi annotation when b/205923322 is addressed.
- @TargetApi(Build.VERSION_CODES.S)
- public MultinetworkPolicyTracker(Context ctx, Handler handler, Runnable avoidBadWifiCallback) {
- mContext = ctx;
- mResources = new ConnectivityResources(ctx);
- mHandler = handler;
- mAvoidBadWifiCallback = avoidBadWifiCallback;
- mSettingsUris = Arrays.asList(
- Settings.Global.getUriFor(NETWORK_AVOID_BAD_WIFI),
- Settings.Global.getUriFor(NETWORK_METERED_MULTIPATH_PREFERENCE));
- mResolver = mContext.getContentResolver();
- mSettingObserver = new SettingObserver();
- mBroadcastReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- reevaluateInternal();
- }
- };
-
- ctx.getSystemService(TelephonyManager.class).registerTelephonyCallback(
- new HandlerExecutor(handler), new ActiveDataSubscriptionIdListener());
-
- updateAvoidBadWifi();
- updateMeteredMultipathPreference();
- }
-
- public void start() {
- for (Uri uri : mSettingsUris) {
- mResolver.registerContentObserver(uri, false, mSettingObserver);
- }
-
- final IntentFilter intentFilter = new IntentFilter();
- intentFilter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
- mContext.registerReceiverForAllUsers(mBroadcastReceiver, intentFilter,
- null /* broadcastPermission */, mHandler);
-
- reevaluate();
- }
-
- public void shutdown() {
- mResolver.unregisterContentObserver(mSettingObserver);
-
- mContext.unregisterReceiver(mBroadcastReceiver);
- }
-
- public boolean getAvoidBadWifi() {
- return mAvoidBadWifi;
- }
-
- // TODO: move this to MultipathPolicyTracker.
- public int getMeteredMultipathPreference() {
- return mMeteredMultipathPreference;
- }
-
- /**
- * Whether the device or carrier configuration disables avoiding bad wifi by default.
- */
- public boolean configRestrictsAvoidBadWifi() {
- final boolean allowBadWifi = mTestAllowBadWifiUntilMs > 0
- && mTestAllowBadWifiUntilMs > System.currentTimeMillis();
- // If the config returns true, then avoid bad wifi design can be controlled by the
- // NETWORK_AVOID_BAD_WIFI setting.
- if (allowBadWifi) return true;
-
- // TODO: use R.integer.config_networkAvoidBadWifi directly
- final int id = mResources.get().getIdentifier("config_networkAvoidBadWifi",
- "integer", mResources.getResourcesContext().getPackageName());
- return (getResourcesForActiveSubId().getInteger(id) == 0);
- }
-
- /**
- * Temporarily allow bad wifi to override {@code config_networkAvoidBadWifi} configuration.
- * The value works when the time set is more than {@link System.currentTimeMillis()}.
- */
- public void setTestAllowBadWifiUntil(long timeMs) {
- Log.d(TAG, "setTestAllowBadWifiUntil: " + timeMs);
- mTestAllowBadWifiUntilMs = timeMs;
- reevaluateInternal();
- }
-
- @VisibleForTesting
- @NonNull
- protected Resources getResourcesForActiveSubId() {
- return SubscriptionManager.getResourcesForSubId(
- mResources.getResourcesContext(), mActiveSubId);
- }
-
- /**
- * Whether we should display a notification when wifi becomes unvalidated.
- */
- public boolean shouldNotifyWifiUnvalidated() {
- return configRestrictsAvoidBadWifi() && getAvoidBadWifiSetting() == null;
- }
-
- public String getAvoidBadWifiSetting() {
- return Settings.Global.getString(mResolver, NETWORK_AVOID_BAD_WIFI);
- }
-
- @VisibleForTesting
- public void reevaluate() {
- mHandler.post(this::reevaluateInternal);
- }
-
- /**
- * Reevaluate the settings. Must be called on the handler thread.
- */
- private void reevaluateInternal() {
- if (updateAvoidBadWifi() && mAvoidBadWifiCallback != null) {
- mAvoidBadWifiCallback.run();
- }
- updateMeteredMultipathPreference();
- }
-
- public boolean updateAvoidBadWifi() {
- final boolean settingAvoidBadWifi = "1".equals(getAvoidBadWifiSetting());
- final boolean prev = mAvoidBadWifi;
- mAvoidBadWifi = settingAvoidBadWifi || !configRestrictsAvoidBadWifi();
- return mAvoidBadWifi != prev;
- }
-
- /**
- * The default (device and carrier-dependent) value for metered multipath preference.
- */
- public int configMeteredMultipathPreference() {
- // TODO: use R.integer.config_networkMeteredMultipathPreference directly
- final int id = mResources.get().getIdentifier("config_networkMeteredMultipathPreference",
- "integer", mResources.getResourcesContext().getPackageName());
- return mResources.get().getInteger(id);
- }
-
- public void updateMeteredMultipathPreference() {
- String setting = Settings.Global.getString(mResolver, NETWORK_METERED_MULTIPATH_PREFERENCE);
- try {
- mMeteredMultipathPreference = Integer.parseInt(setting);
- } catch (NumberFormatException e) {
- mMeteredMultipathPreference = configMeteredMultipathPreference();
- }
- }
-
- private class SettingObserver extends ContentObserver {
- public SettingObserver() {
- super(null);
- }
-
- @Override
- public void onChange(boolean selfChange) {
- Log.wtf(TAG, "Should never be reached.");
- }
-
- @Override
- public void onChange(boolean selfChange, Uri uri) {
- if (!mSettingsUris.contains(uri)) {
- Log.wtf(TAG, "Unexpected settings observation: " + uri);
- }
- reevaluate();
- }
- }
-}
diff --git a/nearby/halfsheet/Android.bp b/nearby/halfsheet/Android.bp
index 486a3ff..c84caa6 100644
--- a/nearby/halfsheet/Android.bp
+++ b/nearby/halfsheet/Android.bp
@@ -23,7 +23,6 @@
sdk_version: "module_current",
// This is included in tethering apex, which uses min SDK 30
min_sdk_version: "30",
- target_sdk_version: "current",
updatable: true,
certificate: ":com.android.nearby.halfsheetcertificate",
libs: [
diff --git a/nearby/halfsheet/res/values-ro/strings.xml b/nearby/halfsheet/res/values-ro/strings.xml
index 5b50f15..189f698 100644
--- a/nearby/halfsheet/res/values-ro/strings.xml
+++ b/nearby/halfsheet/res/values-ro/strings.xml
@@ -18,12 +18,12 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="fast_pair_setup_in_progress" msgid="4158762239172829807">"Începe configurarea…"</string>
- <string name="fast_pair_title_setup" msgid="2894360355540593246">"Configurați dispozitivul"</string>
+ <string name="fast_pair_title_setup" msgid="2894360355540593246">"Configurează dispozitivul"</string>
<string name="fast_pair_device_ready" msgid="2903490346082833101">"Dispozitivul s-a conectat"</string>
<string name="fast_pair_title_fail" msgid="5677174346601290232">"Nu s-a putut conecta"</string>
<string name="paring_action_done" msgid="6888875159174470731">"Gata"</string>
- <string name="paring_action_save" msgid="6259357442067880136">"Salvați"</string>
- <string name="paring_action_connect" msgid="4801102939608129181">"Conectați"</string>
- <string name="paring_action_launch" msgid="8940808384126591230">"Configurați"</string>
+ <string name="paring_action_save" msgid="6259357442067880136">"Salvează"</string>
+ <string name="paring_action_connect" msgid="4801102939608129181">"Conectează"</string>
+ <string name="paring_action_launch" msgid="8940808384126591230">"Configurează"</string>
<string name="paring_action_settings" msgid="424875657242864302">"Setări"</string>
</resources>
diff --git a/nearby/service/Android.bp b/nearby/service/Android.bp
index d318a80..6065f7f 100644
--- a/nearby/service/Android.bp
+++ b/nearby/service/Android.bp
@@ -85,10 +85,10 @@
],
libs: [
"androidx.annotation_annotation",
- "framework-bluetooth.stubs.module_lib", // TODO(b/215722418): Change to framework-bluetooth once fixed
+ "framework-bluetooth",
"error_prone_annotations",
"framework-connectivity-t.impl",
- "framework-statsd.stubs.module_lib",
+ "framework-statsd",
],
static_libs: [
"androidx.core_core",
diff --git a/nearby/tests/cts/fastpair/src/android/nearby/cts/DataElementTest.java b/nearby/tests/cts/fastpair/src/android/nearby/cts/DataElementTest.java
index ec6e89a..3654d0d 100644
--- a/nearby/tests/cts/fastpair/src/android/nearby/cts/DataElementTest.java
+++ b/nearby/tests/cts/fastpair/src/android/nearby/cts/DataElementTest.java
@@ -36,7 +36,7 @@
@RequiresApi(Build.VERSION_CODES.TIRAMISU)
public class DataElementTest {
- private static final int KEY = 1234;
+ private static final int KEY = 1;
private static final byte[] VALUE = new byte[]{1, 1, 1, 1};
@Test
diff --git a/nearby/tests/cts/fastpair/src/android/nearby/cts/NearbyDeviceParcelableTest.java b/nearby/tests/cts/fastpair/src/android/nearby/cts/NearbyDeviceParcelableTest.java
index dd9cbb0..654b852 100644
--- a/nearby/tests/cts/fastpair/src/android/nearby/cts/NearbyDeviceParcelableTest.java
+++ b/nearby/tests/cts/fastpair/src/android/nearby/cts/NearbyDeviceParcelableTest.java
@@ -22,7 +22,6 @@
import android.nearby.NearbyDevice;
import android.nearby.NearbyDeviceParcelable;
-import android.nearby.PublicCredential;
import android.os.Build;
import android.os.Parcel;
@@ -60,32 +59,6 @@
.setData(SCAN_DATA);
}
- /** Verify toString returns expected string. */
- @Test
- @SdkSuppress(minSdkVersion = 33, codeName = "T")
- public void testToString() {
- PublicCredential publicCredential =
- new PublicCredential.Builder(
- new byte[] {1},
- new byte[] {2},
- new byte[] {3},
- new byte[] {4},
- new byte[] {5})
- .build();
- NearbyDeviceParcelable nearbyDeviceParcelable =
- mBuilder.setFastPairModelId(null)
- .setData(null)
- .setPublicCredential(publicCredential)
- .build();
-
- assertThat(nearbyDeviceParcelable.toString())
- .isEqualTo(
- "NearbyDeviceParcelable[scanType=2, name=testDevice, medium=BLE, "
- + "txPower=0, rssi=-60, action=0, bluetoothAddress="
- + BLUETOOTH_ADDRESS
- + ", fastPairModelId=null, data=null, salt=null]");
- }
-
@Test
@SdkSuppress(minSdkVersion = 33, codeName = "T")
public void test_defaultNullFields() {
diff --git a/nearby/tests/cts/fastpair/src/android/nearby/cts/PresenceBroadcastRequestTest.java b/nearby/tests/cts/fastpair/src/android/nearby/cts/PresenceBroadcastRequestTest.java
index 1daa410..eaa5ca1 100644
--- a/nearby/tests/cts/fastpair/src/android/nearby/cts/PresenceBroadcastRequestTest.java
+++ b/nearby/tests/cts/fastpair/src/android/nearby/cts/PresenceBroadcastRequestTest.java
@@ -54,7 +54,7 @@
private static final byte[] SECRETE_ID = new byte[]{1, 2, 3, 4};
private static final byte[] AUTHENTICITY_KEY = new byte[]{0, 1, 1, 1};
private static final byte[] METADATA_ENCRYPTION_KEY = new byte[]{1, 1, 3, 4, 5};
- private static final int KEY = 1234;
+ private static final int KEY = 3;
private static final byte[] VALUE = new byte[]{1, 1, 1, 1};
private static final String DEVICE_NAME = "test_device";
diff --git a/nearby/tests/cts/fastpair/src/android/nearby/cts/PresenceDeviceTest.java b/nearby/tests/cts/fastpair/src/android/nearby/cts/PresenceDeviceTest.java
index 5fefc68..94f8fe7 100644
--- a/nearby/tests/cts/fastpair/src/android/nearby/cts/PresenceDeviceTest.java
+++ b/nearby/tests/cts/fastpair/src/android/nearby/cts/PresenceDeviceTest.java
@@ -45,7 +45,7 @@
private static final int RSSI = -40;
private static final int MEDIUM = NearbyDevice.Medium.BLE;
private static final String DEVICE_NAME = "testDevice";
- private static final int KEY = 1234;
+ private static final int KEY = 3;
private static final byte[] VALUE = new byte[]{1, 1, 1, 1};
private static final byte[] SALT = new byte[]{2, 3};
private static final byte[] SECRET_ID = new byte[]{11, 13};
diff --git a/nearby/tests/cts/fastpair/src/android/nearby/cts/PresenceScanFilterTest.java b/nearby/tests/cts/fastpair/src/android/nearby/cts/PresenceScanFilterTest.java
index b7fe40a..cecdfd2 100644
--- a/nearby/tests/cts/fastpair/src/android/nearby/cts/PresenceScanFilterTest.java
+++ b/nearby/tests/cts/fastpair/src/android/nearby/cts/PresenceScanFilterTest.java
@@ -48,7 +48,7 @@
private static final byte[] PUBLIC_KEY = new byte[]{1, 1, 2, 2};
private static final byte[] ENCRYPTED_METADATA = new byte[]{1, 2, 3, 4, 5};
private static final byte[] METADATA_ENCRYPTION_KEY_TAG = new byte[]{1, 1, 3, 4, 5};
- private static final int KEY = 1234;
+ private static final int KEY = 3;
private static final byte[] VALUE = new byte[]{1, 1, 1, 1};
diff --git a/nearby/tests/multidevices/clients/test_service/fastpair_seeker_data_provider/Android.bp b/nearby/tests/multidevices/clients/test_service/fastpair_seeker_data_provider/Android.bp
index 328751a..b406776 100644
--- a/nearby/tests/multidevices/clients/test_service/fastpair_seeker_data_provider/Android.bp
+++ b/nearby/tests/multidevices/clients/test_service/fastpair_seeker_data_provider/Android.bp
@@ -23,8 +23,8 @@
static_libs: [
// TODO(b/228406038): Remove "framework-nearby-static" once Fast Pair system APIs add back.
"framework-nearby-static",
+ "gson",
"guava",
- "gson-prebuilt-jar",
],
}
diff --git a/nearby/tests/unit/src/com/android/server/nearby/fastpair/cache/FastPairCacheManagerTest.java b/nearby/tests/unit/src/com/android/server/nearby/fastpair/cache/FastPairCacheManagerTest.java
index adae97d..fdda6f7 100644
--- a/nearby/tests/unit/src/com/android/server/nearby/fastpair/cache/FastPairCacheManagerTest.java
+++ b/nearby/tests/unit/src/com/android/server/nearby/fastpair/cache/FastPairCacheManagerTest.java
@@ -81,30 +81,20 @@
Context mContext = ApplicationProvider.getApplicationContext();
when(mDiscoveryItem.getCopyOfStoredItem()).thenReturn(mStoredDiscoveryItem);
when(mDiscoveryItem.getTriggerId()).thenReturn(MODEL_ID);
-
- FastPairCacheManager fastPairCacheManager = new FastPairCacheManager(mContext);
- fastPairCacheManager.saveDiscoveryItem(mDiscoveryItem);
- assertThat(fastPairCacheManager.getStoredDiscoveryItem(MODEL_ID).getAppName())
- .isEqualTo(APP_NAME);
- }
-
- @Test
- @SdkSuppress(minSdkVersion = 32, codeName = "T")
- public void getAllInfo() {
- Context mContext = ApplicationProvider.getApplicationContext();
- when(mDiscoveryItem.getCopyOfStoredItem()).thenReturn(mStoredDiscoveryItem);
- when(mDiscoveryItem.getTriggerId()).thenReturn(MODEL_ID);
when(mDiscoveryItem2.getCopyOfStoredItem()).thenReturn(mStoredDiscoveryItem2);
when(mDiscoveryItem2.getTriggerId()).thenReturn(MODEL_ID2);
FastPairCacheManager fastPairCacheManager = new FastPairCacheManager(mContext);
fastPairCacheManager.saveDiscoveryItem(mDiscoveryItem);
-
- assertThat(fastPairCacheManager.getAllSavedStoreDiscoveryItem()).hasSize(2);
+ assertThat(fastPairCacheManager.getStoredDiscoveryItem(MODEL_ID).getAppName())
+ .isEqualTo(APP_NAME);
+ assertThat(fastPairCacheManager.getAllSavedStoreDiscoveryItem()).hasSize(1);
fastPairCacheManager.saveDiscoveryItem(mDiscoveryItem2);
-
- assertThat(fastPairCacheManager.getAllSavedStoreDiscoveryItem()).hasSize(3);
+ assertThat(fastPairCacheManager.getStoredDiscoveryItem(MODEL_ID2).getAppName())
+ .isEqualTo(APP_NAME);
+ assertThat(fastPairCacheManager.getAllSavedStoreDiscoveryItem()).hasSize(2);
+ fastPairCacheManager.cleanUp();
}
@Test
diff --git a/netd/BpfHandler.cpp b/netd/BpfHandler.cpp
index 994db1d..7950ff7 100644
--- a/netd/BpfHandler.cpp
+++ b/netd/BpfHandler.cpp
@@ -87,7 +87,16 @@
RETURN_IF_NOT_OK(checkProgramAccessible(XT_BPF_INGRESS_PROG_PATH));
RETURN_IF_NOT_OK(attachProgramToCgroup(BPF_EGRESS_PROG_PATH, cg_fd, BPF_CGROUP_INET_EGRESS));
RETURN_IF_NOT_OK(attachProgramToCgroup(BPF_INGRESS_PROG_PATH, cg_fd, BPF_CGROUP_INET_INGRESS));
- RETURN_IF_NOT_OK(attachProgramToCgroup(CGROUP_SOCKET_PROG_PATH, cg_fd, BPF_CGROUP_INET_SOCK_CREATE));
+
+ // For the devices that support cgroup socket filter, the socket filter
+ // should be loaded successfully by bpfloader. So we attach the filter to
+ // cgroup if the program is pinned properly.
+ // TODO: delete the if statement once all devices should support cgroup
+ // socket filter (ie. the minimum kernel version required is 4.14).
+ if (!access(CGROUP_SOCKET_PROG_PATH, F_OK)) {
+ RETURN_IF_NOT_OK(
+ attachProgramToCgroup(CGROUP_SOCKET_PROG_PATH, cg_fd, BPF_CGROUP_INET_SOCK_CREATE));
+ }
return netdutils::status::ok;
}
@@ -110,12 +119,12 @@
}
Status BpfHandler::initMaps() {
- std::lock_guard guard(mMutex);
- RETURN_IF_NOT_OK(mCookieTagMap.init(COOKIE_TAG_MAP_PATH));
RETURN_IF_NOT_OK(mStatsMapA.init(STATS_MAP_A_PATH));
RETURN_IF_NOT_OK(mStatsMapB.init(STATS_MAP_B_PATH));
RETURN_IF_NOT_OK(mConfigurationMap.init(CONFIGURATION_MAP_PATH));
RETURN_IF_NOT_OK(mUidPermissionMap.init(UID_PERMISSION_MAP_PATH));
+ // initialized last so mCookieTagMap.isValid() implies everything else is valid too
+ RETURN_IF_NOT_OK(mCookieTagMap.init(COOKIE_TAG_MAP_PATH));
ALOGI("%s successfully", __func__);
return netdutils::status::ok;
@@ -133,7 +142,6 @@
}
int BpfHandler::tagSocket(int sockFd, uint32_t tag, uid_t chargeUid, uid_t realUid) {
- std::lock_guard guard(mMutex);
if (!mCookieTagMap.isValid()) return -EPERM;
if (chargeUid != realUid && !hasUpdateDeviceStatsPermission(realUid)) return -EPERM;
@@ -185,9 +193,9 @@
uint32_t perUidEntryCount = 0;
// Now we go through the stats map and count how many entries are associated
// with chargeUid. If the uid entry hit the limit for each chargeUid, we block
- // the request to prevent the map from overflow. It is safe here to iterate
- // over the map since when mMutex is hold, system server cannot toggle
- // the live stats map and clean it. So nobody can delete entries from the map.
+ // the request to prevent the map from overflow. Note though that it isn't really
+ // safe here to iterate over the map since it might be modified by the system server,
+ // which might toggle the live stats map and clean it.
const auto countUidStatsEntries = [chargeUid, &totalEntryCount, &perUidEntryCount](
const StatsKey& key,
const BpfMap<StatsKey, StatsValue>&) {
@@ -227,9 +235,9 @@
}
// Update the tag information of a socket to the cookieUidMap. Use BPF_ANY
// flag so it will insert a new entry to the map if that value doesn't exist
- // yet. And update the tag if there is already a tag stored. Since the eBPF
+ // yet and update the tag if there is already a tag stored. Since the eBPF
// program in kernel only read this map, and is protected by rcu read lock. It
- // should be fine to cocurrently update the map while eBPF program is running.
+ // should be fine to concurrently update the map while eBPF program is running.
res = mCookieTagMap.writeValue(sock_cookie, newKey, BPF_ANY);
if (!res.ok()) {
ALOGE("Failed to tag the socket: %s, fd: %d", strerror(res.error().code()),
@@ -240,8 +248,6 @@
}
int BpfHandler::untagSocket(int sockFd) {
- std::lock_guard guard(mMutex);
-
uint64_t sock_cookie = getSocketCookie(sockFd);
if (sock_cookie == NONEXISTENT_COOKIE) return -errno;
diff --git a/netd/BpfHandler.h b/netd/BpfHandler.h
index 5ee04d1..925a725 100644
--- a/netd/BpfHandler.h
+++ b/netd/BpfHandler.h
@@ -16,8 +16,6 @@
#pragma once
-#include <mutex>
-
#include <netdutils/Status.h>
#include "bpf/BpfMap.h"
#include "bpf_shared.h"
@@ -66,8 +64,6 @@
BpfMapRO<uint32_t, uint32_t> mConfigurationMap;
BpfMap<uint32_t, uint8_t> mUidPermissionMap;
- std::mutex mMutex;
-
// The limit on the number of stats entries a uid can have in the per uid stats map. BpfHandler
// will block that specific uid from tagging new sockets after the limit is reached.
const uint32_t mPerUidStatsEntriesLimit;
diff --git a/netd/BpfHandlerTest.cpp b/netd/BpfHandlerTest.cpp
index 99160da..f5c9a68 100644
--- a/netd/BpfHandlerTest.cpp
+++ b/netd/BpfHandlerTest.cpp
@@ -53,7 +53,6 @@
BpfMap<uint32_t, uint8_t> mFakeUidPermissionMap;
void SetUp() {
- std::lock_guard guard(mBh.mMutex);
ASSERT_EQ(0, setrlimitForTest());
mFakeCookieTagMap.resetMap(BPF_MAP_TYPE_HASH, TEST_MAP_SIZE);
diff --git a/service-t/Android.bp b/service-t/Android.bp
index 1b9f2ec..9bf9135 100644
--- a/service-t/Android.bp
+++ b/service-t/Android.bp
@@ -49,7 +49,7 @@
"framework-annotations-lib",
"framework-connectivity-pre-jarjar",
"framework-connectivity-t-pre-jarjar",
- "framework-tethering.stubs.module_lib",
+ "framework-tethering",
"service-connectivity-pre-jarjar",
"service-nearby-pre-jarjar",
"ServiceConnectivityResources",
diff --git a/service-t/native/libs/libnetworkstats/BpfNetworkStats.cpp b/service-t/native/libs/libnetworkstats/BpfNetworkStats.cpp
index 6605428..28de881 100644
--- a/service-t/native/libs/libnetworkstats/BpfNetworkStats.cpp
+++ b/service-t/native/libs/libnetworkstats/BpfNetworkStats.cpp
@@ -40,10 +40,6 @@
using base::Result;
-// The target map for stats reading should be the inactive map, which is opposite
-// from the config value.
-static constexpr char const* STATS_MAP_PATH[] = {STATS_MAP_B_PATH, STATS_MAP_A_PATH};
-
int bpfGetUidStatsInternal(uid_t uid, Stats* stats,
const BpfMap<uint32_t, StatsValue>& appUidStatsMap) {
auto statsEntry = appUidStatsMap.readValue(uid);
@@ -171,30 +167,42 @@
int limitUid) {
static BpfMapRO<uint32_t, IfaceValue> ifaceIndexNameMap(IFACE_INDEX_NAME_MAP_PATH);
static BpfMapRO<uint32_t, uint32_t> configurationMap(CONFIGURATION_MAP_PATH);
+ static BpfMap<StatsKey, StatsValue> statsMapA(STATS_MAP_A_PATH);
+ static BpfMap<StatsKey, StatsValue> statsMapB(STATS_MAP_B_PATH);
auto configuration = configurationMap.readValue(CURRENT_STATS_MAP_CONFIGURATION_KEY);
if (!configuration.ok()) {
ALOGE("Cannot read the old configuration from map: %s",
configuration.error().message().c_str());
return -configuration.error().code();
}
- if (configuration.value() != SELECT_MAP_A && configuration.value() != SELECT_MAP_B) {
+ // The target map for stats reading should be the inactive map, which is opposite
+ // from the config value.
+ BpfMap<StatsKey, StatsValue> *inactiveStatsMap;
+ switch (configuration.value()) {
+ case SELECT_MAP_A:
+ inactiveStatsMap = &statsMapB;
+ break;
+ case SELECT_MAP_B:
+ inactiveStatsMap = &statsMapA;
+ break;
+ default:
ALOGE("%s unknown configuration value: %d", __func__, configuration.value());
return -EINVAL;
}
- const char* statsMapPath = STATS_MAP_PATH[configuration.value()];
- // TODO: fix this to not constantly reopen the bpf map
- BpfMap<StatsKey, StatsValue> statsMap(statsMapPath);
// It is safe to read and clear the old map now since the
// networkStatsFactory should call netd to swap the map in advance already.
- int ret = parseBpfNetworkStatsDetailInternal(lines, limitIfaces, limitTag, limitUid, statsMap,
- ifaceIndexNameMap);
+ // TODO: the above comment feels like it may be obsolete / out of date,
+ // since we no longer swap the map via netd binder rpc - though we do
+ // still swap it.
+ int ret = parseBpfNetworkStatsDetailInternal(lines, limitIfaces, limitTag, limitUid,
+ *inactiveStatsMap, ifaceIndexNameMap);
if (ret) {
ALOGE("parse detail network stats failed: %s", strerror(errno));
return ret;
}
- Result<void> res = statsMap.clear();
+ Result<void> res = inactiveStatsMap->clear();
if (!res.ok()) {
ALOGE("Clean up current stats map failed: %s", strerror(res.error().code()));
return -res.error().code();
diff --git a/service-t/src/com/android/server/IpSecService.java b/service-t/src/com/android/server/IpSecService.java
index 16b9f1e..6cee08a 100644
--- a/service-t/src/com/android/server/IpSecService.java
+++ b/service-t/src/com/android/server/IpSecService.java
@@ -859,6 +859,13 @@
mIkey,
0xffffffff,
mIfId);
+ mNetd.ipSecDeleteSecurityPolicy(
+ mUid,
+ selAddrFamily,
+ IpSecManager.DIRECTION_FWD,
+ mIkey,
+ 0xffffffff,
+ mIfId);
}
} catch (ServiceSpecificException | RemoteException e) {
Log.e(
diff --git a/service-t/src/com/android/server/ethernet/EthernetCallback.java b/service-t/src/com/android/server/ethernet/EthernetCallback.java
new file mode 100644
index 0000000..5461156
--- /dev/null
+++ b/service-t/src/com/android/server/ethernet/EthernetCallback.java
@@ -0,0 +1,57 @@
+/*
+ * 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.server.ethernet;
+
+import android.net.EthernetNetworkManagementException;
+import android.net.INetworkInterfaceOutcomeReceiver;
+import android.os.RemoteException;
+import android.util.Log;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+/** Convenience wrapper for INetworkInterfaceOutcomeReceiver */
+@VisibleForTesting
+public class EthernetCallback {
+ private static final String TAG = EthernetCallback.class.getSimpleName();
+ private final INetworkInterfaceOutcomeReceiver mReceiver;
+
+ public EthernetCallback(INetworkInterfaceOutcomeReceiver receiver) {
+ mReceiver = receiver;
+ }
+
+ /** Calls INetworkInterfaceOutcomeReceiver#onResult */
+ public void onResult(String ifname) {
+ try {
+ if (mReceiver != null) {
+ mReceiver.onResult(ifname);
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to report error to OutcomeReceiver", e);
+ }
+ }
+
+ /** Calls INetworkInterfaceOutcomeReceiver#onError */
+ public void onError(String msg) {
+ try {
+ if (mReceiver != null) {
+ mReceiver.onError(new EthernetNetworkManagementException(msg));
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to report error to OutcomeReceiver", e);
+ }
+ }
+}
diff --git a/service-t/src/com/android/server/ethernet/EthernetConfigStore.java b/service-t/src/com/android/server/ethernet/EthernetConfigStore.java
index 17abbab..156b526 100644
--- a/service-t/src/com/android/server/ethernet/EthernetConfigStore.java
+++ b/service-t/src/com/android/server/ethernet/EthernetConfigStore.java
@@ -116,6 +116,10 @@
}
public void write(String iface, IpConfiguration config) {
+ final File directory = new File(APEX_IP_CONFIG_FILE_PATH);
+ if (!directory.exists()) {
+ directory.mkdirs();
+ }
write(iface, config, APEX_IP_CONFIG_FILE_PATH + CONFIG_FILE);
}
diff --git a/service-t/src/com/android/server/ethernet/EthernetNetworkFactory.java b/service-t/src/com/android/server/ethernet/EthernetNetworkFactory.java
index e5bddf6..00f6c56 100644
--- a/service-t/src/com/android/server/ethernet/EthernetNetworkFactory.java
+++ b/service-t/src/com/android/server/ethernet/EthernetNetworkFactory.java
@@ -22,9 +22,7 @@
import android.net.ConnectivityManager;
import android.net.ConnectivityResources;
import android.net.EthernetManager;
-import android.net.EthernetNetworkManagementException;
import android.net.EthernetNetworkSpecifier;
-import android.net.INetworkInterfaceOutcomeReceiver;
import android.net.IpConfiguration;
import android.net.IpConfiguration.IpAssignment;
import android.net.IpConfiguration.ProxySettings;
@@ -42,7 +40,6 @@
import android.os.ConditionVariable;
import android.os.Handler;
import android.os.Looper;
-import android.os.RemoteException;
import android.text.TextUtils;
import android.util.AndroidRuntimeException;
import android.util.ArraySet;
@@ -190,22 +187,19 @@
* {@code null} is passed, then the network's current
* {@link NetworkCapabilities} will be used in support of existing APIs as
* the public API does not allow this.
- * @param listener an optional {@link INetworkInterfaceOutcomeReceiver} to notify callers of
- * completion.
*/
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
protected void updateInterface(@NonNull final String ifaceName,
@Nullable final IpConfiguration ipConfig,
- @Nullable final NetworkCapabilities capabilities,
- @Nullable final INetworkInterfaceOutcomeReceiver listener) {
+ @Nullable final NetworkCapabilities capabilities) {
if (!hasInterface(ifaceName)) {
- maybeSendNetworkManagementCallbackForUntracked(ifaceName, listener);
return;
}
final NetworkInterfaceState iface = mTrackingInterfaces.get(ifaceName);
- iface.updateInterface(ipConfig, capabilities, listener);
+ iface.updateInterface(ipConfig, capabilities);
mTrackingInterfaces.put(ifaceName, iface);
+ return;
}
private static NetworkCapabilities mixInCapabilities(NetworkCapabilities nc,
@@ -238,10 +232,8 @@
/** Returns true if state has been modified */
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
- protected boolean updateInterfaceLinkState(@NonNull final String ifaceName, final boolean up,
- @Nullable final INetworkInterfaceOutcomeReceiver listener) {
+ protected boolean updateInterfaceLinkState(@NonNull final String ifaceName, final boolean up) {
if (!hasInterface(ifaceName)) {
- maybeSendNetworkManagementCallbackForUntracked(ifaceName, listener);
return false;
}
@@ -250,14 +242,7 @@
}
NetworkInterfaceState iface = mTrackingInterfaces.get(ifaceName);
- return iface.updateLinkState(up, listener);
- }
-
- private void maybeSendNetworkManagementCallbackForUntracked(
- String ifaceName, INetworkInterfaceOutcomeReceiver listener) {
- maybeSendNetworkManagementCallback(listener, null,
- new EthernetNetworkManagementException(
- ifaceName + " can't be updated as it is not available."));
+ return iface.updateLinkState(up);
}
@VisibleForTesting
@@ -265,25 +250,6 @@
return mTrackingInterfaces.containsKey(ifaceName);
}
- private static void maybeSendNetworkManagementCallback(
- @Nullable final INetworkInterfaceOutcomeReceiver listener,
- @Nullable final String iface,
- @Nullable final EthernetNetworkManagementException e) {
- if (null == listener) {
- return;
- }
-
- try {
- if (iface != null) {
- listener.onResult(iface);
- } else {
- listener.onError(e);
- }
- } catch (RemoteException re) {
- Log.e(TAG, "Can't send onComplete for network management callback", re);
- }
- }
-
@VisibleForTesting
static class NetworkInterfaceState {
final String name;
@@ -332,11 +298,6 @@
private class EthernetIpClientCallback extends IpClientCallbacks {
private final ConditionVariable mIpClientStartCv = new ConditionVariable(false);
private final ConditionVariable mIpClientShutdownCv = new ConditionVariable(false);
- @Nullable INetworkInterfaceOutcomeReceiver mNetworkManagementListener;
-
- EthernetIpClientCallback(@Nullable final INetworkInterfaceOutcomeReceiver listener) {
- mNetworkManagementListener = listener;
- }
@Override
public void onIpClientCreated(IIpClient ipClient) {
@@ -372,14 +333,14 @@
@Override
public void onProvisioningSuccess(LinkProperties newLp) {
- handleIpEvent(() -> onIpLayerStarted(newLp, mNetworkManagementListener));
+ handleIpEvent(() -> onIpLayerStarted(newLp));
}
@Override
public void onProvisioningFailure(LinkProperties newLp) {
// This cannot happen due to provisioning timeout, because our timeout is 0. It can
// happen due to errors while provisioning or on provisioning loss.
- handleIpEvent(() -> onIpLayerStopped(mNetworkManagementListener));
+ handleIpEvent(() -> onIpLayerStopped());
}
@Override
@@ -491,13 +452,11 @@
}
void updateInterface(@Nullable final IpConfiguration ipConfig,
- @Nullable final NetworkCapabilities capabilities,
- @Nullable final INetworkInterfaceOutcomeReceiver listener) {
+ @Nullable final NetworkCapabilities capabilities) {
if (DBG) {
Log.d(TAG, "updateInterface, iface: " + name
+ ", ipConfig: " + ipConfig + ", old ipConfig: " + mIpConfig
+ ", capabilities: " + capabilities + ", old capabilities: " + mCapabilities
- + ", listener: " + listener
);
}
@@ -510,7 +469,9 @@
// TODO: Update this logic to only do a restart if required. Although a restart may
// be required due to the capabilities or ipConfiguration values, not all
// capabilities changes require a restart.
- restart(listener);
+ if (mIpClient != null) {
+ restart();
+ }
}
boolean isRestricted() {
@@ -518,10 +479,6 @@
}
private void start() {
- start(null);
- }
-
- private void start(@Nullable final INetworkInterfaceOutcomeReceiver listener) {
if (mIpClient != null) {
if (DBG) Log.d(TAG, "IpClient already started");
return;
@@ -530,7 +487,7 @@
Log.d(TAG, String.format("Starting Ethernet IpClient(%s)", name));
}
- mIpClientCallback = new EthernetIpClientCallback(listener);
+ mIpClientCallback = new EthernetIpClientCallback();
mDeps.makeIpClient(mContext, name, mIpClientCallback);
mIpClientCallback.awaitIpClientStart();
@@ -540,8 +497,7 @@
provisionIpClient(mIpClient, mIpConfig, sTcpBufferSizes);
}
- void onIpLayerStarted(@NonNull final LinkProperties linkProperties,
- @Nullable final INetworkInterfaceOutcomeReceiver listener) {
+ void onIpLayerStarted(@NonNull final LinkProperties linkProperties) {
if (mNetworkAgent != null) {
Log.e(TAG, "Already have a NetworkAgent - aborting new request");
stop();
@@ -573,40 +529,18 @@
});
mNetworkAgent.register();
mNetworkAgent.markConnected();
- realizeNetworkManagementCallback(name, null);
}
- void onIpLayerStopped(@Nullable final INetworkInterfaceOutcomeReceiver listener) {
+ void onIpLayerStopped() {
// There is no point in continuing if the interface is gone as stop() will be triggered
// by removeInterface() when processed on the handler thread and start() won't
// work for a non-existent interface.
if (null == mDeps.getNetworkInterfaceByName(name)) {
if (DBG) Log.d(TAG, name + " is no longer available.");
// Send a callback in case a provisioning request was in progress.
- maybeSendNetworkManagementCallbackForAbort();
return;
}
- restart(listener);
- }
-
- private void maybeSendNetworkManagementCallbackForAbort() {
- realizeNetworkManagementCallback(null,
- new EthernetNetworkManagementException(
- "The IP provisioning request has been aborted."));
- }
-
- // Must be called on the handler thread
- private void realizeNetworkManagementCallback(@Nullable final String iface,
- @Nullable final EthernetNetworkManagementException e) {
- ensureRunningOnEthernetHandlerThread();
- if (null == mIpClientCallback) {
- return;
- }
-
- EthernetNetworkFactory.maybeSendNetworkManagementCallback(
- mIpClientCallback.mNetworkManagementListener, iface, e);
- // Only send a single callback per listener.
- mIpClientCallback.mNetworkManagementListener = null;
+ restart();
}
private void ensureRunningOnEthernetHandlerThread() {
@@ -626,6 +560,13 @@
void updateNeighborLostEvent(String logMsg) {
Log.i(TAG, "updateNeighborLostEvent " + logMsg);
+ if (mIpConfig.getIpAssignment() == IpAssignment.STATIC) {
+ // Ignore NUD failures for static IP configurations, where restarting the IpClient
+ // will not fix connectivity.
+ // In this scenario, NetworkMonitor will not verify the network, so it will
+ // eventually be torn down.
+ return;
+ }
// Reachability lost will be seen only if the gateway is not reachable.
// Since ethernet FW doesn't have the mechanism to scan for new networks
// like WiFi, simply restart.
@@ -636,12 +577,8 @@
}
/** Returns true if state has been modified */
- boolean updateLinkState(final boolean up,
- @Nullable final INetworkInterfaceOutcomeReceiver listener) {
+ boolean updateLinkState(final boolean up) {
if (mLinkUp == up) {
- EthernetNetworkFactory.maybeSendNetworkManagementCallback(listener, null,
- new EthernetNetworkManagementException(
- "No changes with requested link state " + up + " for " + name));
return false;
}
mLinkUp = up;
@@ -654,25 +591,27 @@
registerNetworkOffer();
}
- EthernetNetworkFactory.maybeSendNetworkManagementCallback(listener, name, null);
return true;
}
private void stop() {
+ // Unregister NetworkAgent before stopping IpClient, so destroyNativeNetwork (which
+ // deletes routes) hopefully happens before stop() finishes execution. Otherwise, it may
+ // delete the new routes when IpClient gets restarted.
+ if (mNetworkAgent != null) {
+ mNetworkAgent.unregister();
+ mNetworkAgent = null;
+ }
+
// Invalidate all previous start requests
if (mIpClient != null) {
mIpClient.shutdown();
mIpClientCallback.awaitIpClientShutdown();
mIpClient = null;
}
- // Send an abort callback if an updateInterface request was in progress.
- maybeSendNetworkManagementCallbackForAbort();
+
mIpClientCallback = null;
- if (mNetworkAgent != null) {
- mNetworkAgent.unregister();
- mNetworkAgent = null;
- }
mLinkProperties.clear();
}
@@ -723,13 +662,9 @@
}
void restart() {
- restart(null);
- }
-
- void restart(@Nullable final INetworkInterfaceOutcomeReceiver listener) {
if (DBG) Log.d(TAG, "reconnecting Ethernet");
stop();
- start(listener);
+ start();
}
@Override
diff --git a/service-t/src/com/android/server/ethernet/EthernetServiceImpl.java b/service-t/src/com/android/server/ethernet/EthernetServiceImpl.java
index dae3d2a..edf04b2 100644
--- a/service-t/src/com/android/server/ethernet/EthernetServiceImpl.java
+++ b/service-t/src/com/android/server/ethernet/EthernetServiceImpl.java
@@ -260,7 +260,7 @@
@Override
public void updateConfiguration(@NonNull final String iface,
@NonNull final EthernetNetworkUpdateRequest request,
- @Nullable final INetworkInterfaceOutcomeReceiver listener) {
+ @Nullable final INetworkInterfaceOutcomeReceiver cb) {
Objects.requireNonNull(iface);
Objects.requireNonNull(request);
throwIfEthernetNotStarted();
@@ -277,31 +277,31 @@
}
mTracker.updateConfiguration(
- iface, request.getIpConfiguration(), nc, listener);
+ iface, request.getIpConfiguration(), nc, new EthernetCallback(cb));
}
@Override
public void enableInterface(@NonNull final String iface,
- @Nullable final INetworkInterfaceOutcomeReceiver listener) {
- Log.i(TAG, "enableInterface called with: iface=" + iface + ", listener=" + listener);
+ @Nullable final INetworkInterfaceOutcomeReceiver cb) {
+ Log.i(TAG, "enableInterface called with: iface=" + iface + ", cb=" + cb);
Objects.requireNonNull(iface);
throwIfEthernetNotStarted();
enforceAdminPermission(iface, false, "enableInterface()");
- mTracker.enableInterface(iface, listener);
+ mTracker.enableInterface(iface, new EthernetCallback(cb));
}
@Override
public void disableInterface(@NonNull final String iface,
- @Nullable final INetworkInterfaceOutcomeReceiver listener) {
- Log.i(TAG, "disableInterface called with: iface=" + iface + ", listener=" + listener);
+ @Nullable final INetworkInterfaceOutcomeReceiver cb) {
+ Log.i(TAG, "disableInterface called with: iface=" + iface + ", cb=" + cb);
Objects.requireNonNull(iface);
throwIfEthernetNotStarted();
enforceAdminPermission(iface, false, "disableInterface()");
- mTracker.disableInterface(iface, listener);
+ mTracker.disableInterface(iface, new EthernetCallback(cb));
}
@Override
diff --git a/service-t/src/com/android/server/ethernet/EthernetTracker.java b/service-t/src/com/android/server/ethernet/EthernetTracker.java
index ba367cf..95baf81 100644
--- a/service-t/src/com/android/server/ethernet/EthernetTracker.java
+++ b/service-t/src/com/android/server/ethernet/EthernetTracker.java
@@ -29,7 +29,6 @@
import android.net.EthernetManager;
import android.net.IEthernetServiceListener;
import android.net.INetd;
-import android.net.INetworkInterfaceOutcomeReceiver;
import android.net.ITetheredInterfaceCallback;
import android.net.InterfaceConfigurationParcel;
import android.net.IpConfiguration;
@@ -271,7 +270,7 @@
}
writeIpConfiguration(iface, ipConfiguration);
mHandler.post(() -> {
- mFactory.updateInterface(iface, ipConfiguration, null, null);
+ mFactory.updateInterface(iface, ipConfiguration, null);
broadcastInterfaceStateChange(iface);
});
}
@@ -303,9 +302,14 @@
final int state = getInterfaceState(iface);
final int role = getInterfaceRole(iface);
final IpConfiguration config = getIpConfigurationForCallback(iface, state);
+ final boolean isRestricted = isRestrictedInterface(iface);
final int n = mListeners.beginBroadcast();
for (int i = 0; i < n; i++) {
try {
+ if (isRestricted) {
+ final ListenerInfo info = (ListenerInfo) mListeners.getBroadcastCookie(i);
+ if (!info.canUseRestrictedNetworks) continue;
+ }
mListeners.getBroadcastItem(i).onInterfaceStateChanged(iface, state, role, config);
} catch (RemoteException e) {
// Do nothing here.
@@ -335,7 +339,7 @@
protected void updateConfiguration(@NonNull final String iface,
@Nullable final IpConfiguration ipConfig,
@Nullable final NetworkCapabilities capabilities,
- @Nullable final INetworkInterfaceOutcomeReceiver listener) {
+ @Nullable final EthernetCallback cb) {
if (DBG) {
Log.i(TAG, "updateConfiguration, iface: " + iface + ", capabilities: " + capabilities
+ ", ipConfig: " + ipConfig);
@@ -353,21 +357,29 @@
mNetworkCapabilities.put(iface, capabilities);
}
mHandler.post(() -> {
- mFactory.updateInterface(iface, localIpConfig, capabilities, listener);
- broadcastInterfaceStateChange(iface);
+ mFactory.updateInterface(iface, localIpConfig, capabilities);
+
+ // only broadcast state change when the ip configuration is updated.
+ if (ipConfig != null) {
+ broadcastInterfaceStateChange(iface);
+ }
+ // Always return success. Even if the interface does not currently exist, the
+ // IpConfiguration and NetworkCapabilities were saved and will be applied if an
+ // interface with the given name is ever added.
+ cb.onResult(iface);
});
}
@VisibleForTesting(visibility = PACKAGE)
protected void enableInterface(@NonNull final String iface,
- @Nullable final INetworkInterfaceOutcomeReceiver listener) {
- mHandler.post(() -> updateInterfaceState(iface, true, listener));
+ @Nullable final EthernetCallback cb) {
+ mHandler.post(() -> updateInterfaceState(iface, true, cb));
}
@VisibleForTesting(visibility = PACKAGE)
protected void disableInterface(@NonNull final String iface,
- @Nullable final INetworkInterfaceOutcomeReceiver listener) {
- mHandler.post(() -> updateInterfaceState(iface, false, listener));
+ @Nullable final EthernetCallback cb) {
+ mHandler.post(() -> updateInterfaceState(iface, false, cb));
}
IpConfiguration getIpConfiguration(String iface) {
@@ -571,8 +583,14 @@
// Bring up the interface so we get link status indications.
try {
PermissionUtils.enforceNetworkStackPermission(mContext);
- NetdUtils.setInterfaceUp(mNetd, iface);
+ // Read the flags before attempting to bring up the interface. If the interface is
+ // already running an UP event is created after adding the interface.
config = NetdUtils.getInterfaceConfigParcel(mNetd, iface);
+ if (NetdUtils.hasFlag(config, INetd.IF_STATE_DOWN)) {
+ // As a side-effect, NetdUtils#setInterfaceUp() also clears the interface's IPv4
+ // address and readds it which *could* lead to unexpected behavior in the future.
+ NetdUtils.setInterfaceUp(mNetd, iface);
+ }
} catch (IllegalStateException e) {
// Either the system is crashing or the interface has disappeared. Just ignore the
// error; we haven't modified any state because we only do that if our calls succeed.
@@ -608,24 +626,33 @@
// Note: if the interface already has link (e.g., if we crashed and got
// restarted while it was running), we need to fake a link up notification so we
// start configuring it.
- if (NetdUtils.hasFlag(config, "running")) {
- updateInterfaceState(iface, true);
+ if (NetdUtils.hasFlag(config, INetd.IF_FLAG_RUNNING)) {
+ // no need to send an interface state change as this is not a true "state change". The
+ // callers (maybeTrackInterface() and setTetheringInterfaceMode()) already broadcast the
+ // state change.
+ mFactory.updateInterfaceLinkState(iface, true);
}
}
private void updateInterfaceState(String iface, boolean up) {
- updateInterfaceState(iface, up, null /* listener */);
+ updateInterfaceState(iface, up, new EthernetCallback(null /* cb */));
}
- private void updateInterfaceState(@NonNull final String iface, final boolean up,
- @Nullable final INetworkInterfaceOutcomeReceiver listener) {
+ // TODO(b/225315248): enable/disableInterface() should not affect link state.
+ private void updateInterfaceState(String iface, boolean up, EthernetCallback cb) {
final int mode = getInterfaceMode(iface);
- final boolean factoryLinkStateUpdated = (mode == INTERFACE_MODE_CLIENT)
- && mFactory.updateInterfaceLinkState(iface, up, listener);
+ if (mode == INTERFACE_MODE_SERVER || !mFactory.hasInterface(iface)) {
+ // The interface is in server mode or is not tracked.
+ cb.onError("Failed to set link state " + (up ? "up" : "down") + " for " + iface);
+ return;
+ }
- if (factoryLinkStateUpdated) {
+ if (mFactory.updateInterfaceLinkState(iface, up)) {
broadcastInterfaceStateChange(iface);
}
+ // If updateInterfaceLinkState returns false, the interface is already in the correct state.
+ // Always return success.
+ cb.onResult(iface);
}
private void maybeUpdateServerModeInterfaceState(String iface, boolean available) {
diff --git a/service-t/src/com/android/server/net/BpfInterfaceMapUpdater.java b/service-t/src/com/android/server/net/BpfInterfaceMapUpdater.java
index 3b44d81..ceae9ba 100644
--- a/service-t/src/com/android/server/net/BpfInterfaceMapUpdater.java
+++ b/service-t/src/com/android/server/net/BpfInterfaceMapUpdater.java
@@ -22,14 +22,16 @@
import android.os.RemoteException;
import android.os.ServiceSpecificException;
import android.system.ErrnoException;
+import android.util.IndentingPrintWriter;
import android.util.Log;
import com.android.internal.annotations.VisibleForTesting;
import com.android.net.module.util.BaseNetdUnsolicitedEventListener;
+import com.android.net.module.util.BpfDump;
import com.android.net.module.util.BpfMap;
import com.android.net.module.util.IBpfMap;
import com.android.net.module.util.InterfaceParams;
-import com.android.net.module.util.Struct.U32;
+import com.android.net.module.util.Struct.S32;
/**
* Monitor interface added (without removed) and right interface name and its index to bpf map.
@@ -39,7 +41,7 @@
// This is current path but may be changed soon.
private static final String IFACE_INDEX_NAME_MAP_PATH =
"/sys/fs/bpf/netd_shared/map_netd_iface_index_name_map";
- private final IBpfMap<U32, InterfaceMapValue> mBpfMap;
+ private final IBpfMap<S32, InterfaceMapValue> mBpfMap;
private final INetd mNetd;
private final Handler mHandler;
private final Dependencies mDeps;
@@ -62,10 +64,10 @@
@VisibleForTesting
public static class Dependencies {
/** Create BpfMap for updating interface and index mapping. */
- public IBpfMap<U32, InterfaceMapValue> getInterfaceMap() {
+ public IBpfMap<S32, InterfaceMapValue> getInterfaceMap() {
try {
return new BpfMap<>(IFACE_INDEX_NAME_MAP_PATH, BpfMap.BPF_F_RDWR,
- U32.class, InterfaceMapValue.class);
+ S32.class, InterfaceMapValue.class);
} catch (ErrnoException e) {
Log.e(TAG, "Cannot create interface map: " + e);
return null;
@@ -124,7 +126,7 @@
}
try {
- mBpfMap.updateEntry(new U32(iface.index), new InterfaceMapValue(ifaceName));
+ mBpfMap.updateEntry(new S32(iface.index), new InterfaceMapValue(ifaceName));
} catch (ErrnoException e) {
Log.e(TAG, "Unable to update entry for " + ifaceName + ", " + e);
}
@@ -136,4 +138,37 @@
mHandler.post(() -> addInterface(ifName));
}
}
+
+ /** get interface name by interface index from bpf map */
+ public String getIfNameByIndex(final int index) {
+ try {
+ final InterfaceMapValue value = mBpfMap.getValue(new S32(index));
+ if (value == null) {
+ Log.e(TAG, "No if name entry for index " + index);
+ return null;
+ }
+ return value.getInterfaceNameString();
+ } catch (ErrnoException e) {
+ Log.e(TAG, "Failed to get entry for index " + index + ": " + e);
+ return null;
+ }
+ }
+
+ /**
+ * Dump BPF map
+ *
+ * @param pw print writer
+ */
+ public void dump(final IndentingPrintWriter pw) {
+ pw.println("BPF map status:");
+ pw.increaseIndent();
+ BpfDump.dumpMapStatus(mBpfMap, pw, "IfaceIndexNameMap", IFACE_INDEX_NAME_MAP_PATH);
+ pw.decreaseIndent();
+ pw.println("BPF map content:");
+ pw.increaseIndent();
+ BpfDump.dumpMap(mBpfMap, pw, "IfaceIndexNameMap",
+ (key, value) -> "ifaceIndex=" + key.val
+ + " ifaceName=" + value.getInterfaceNameString());
+ pw.decreaseIndent();
+ }
}
diff --git a/service-t/src/com/android/server/net/InterfaceMapValue.java b/service-t/src/com/android/server/net/InterfaceMapValue.java
index 42c0044..95da981 100644
--- a/service-t/src/com/android/server/net/InterfaceMapValue.java
+++ b/service-t/src/com/android/server/net/InterfaceMapValue.java
@@ -16,20 +16,45 @@
package com.android.server.net;
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.util.Arrays;
/**
* The value of bpf interface index map which is used for NetworkStatsService.
*/
public class InterfaceMapValue extends Struct {
+ private static final int IF_NAME_SIZE = 16;
+
@Field(order = 0, type = Type.ByteArray, arraysize = 16)
public final byte[] interfaceName;
public InterfaceMapValue(String iface) {
- final byte[] ifaceArray = iface.getBytes();
- interfaceName = new byte[16];
// All array bytes after the interface name, if any, must be 0.
- System.arraycopy(ifaceArray, 0, interfaceName, 0, ifaceArray.length);
+ interfaceName = Arrays.copyOf(iface.getBytes(), IF_NAME_SIZE);
+ }
+
+ /**
+ * Constructor for Struct#parse. Build this struct from byte array of interface name.
+ *
+ * @param ifName Byte array of interface name, length is expected to be IF_NAME_SIZE(16).
+ * If longer or shorter, interface name will be truncated or padded with zeros.
+ * All array bytes after the interface name, if any, must be 0.
+ */
+ public InterfaceMapValue(final byte[] ifName) {
+ interfaceName = Arrays.copyOf(ifName, IF_NAME_SIZE);
+ }
+
+ /** Returns the length of the null-terminated string. */
+ private int strlen(byte[] str) {
+ for (int i = 0; i < str.length; ++i) {
+ if (str[i] == '\0') {
+ return i;
+ }
+ }
+ return str.length;
+ }
+
+ public String getInterfaceNameString() {
+ return new String(interfaceName, 0 /* offset */, strlen(interfaceName));
}
}
diff --git a/service-t/src/com/android/server/net/NetworkStatsFactory.java b/service-t/src/com/android/server/net/NetworkStatsFactory.java
index c9d1718..8161f50 100644
--- a/service-t/src/com/android/server/net/NetworkStatsFactory.java
+++ b/service-t/src/com/android/server/net/NetworkStatsFactory.java
@@ -296,6 +296,16 @@
return mTunAnd464xlatAdjustedStats.clone();
}
+ /**
+ * Remove stats from {@code mPersistSnapshot} and {@code mTunAnd464xlatAdjustedStats} for the
+ * given uids.
+ */
+ public void removeUidsLocked(int[] uids) {
+ synchronized (mPersistentDataLock) {
+ mPersistSnapshot.removeUids(uids);
+ mTunAnd464xlatAdjustedStats.removeUids(uids);
+ }
+ }
public void assertEquals(NetworkStats expected, NetworkStats actual) {
if (expected.size() != actual.size()) {
diff --git a/service-t/src/com/android/server/net/NetworkStatsService.java b/service-t/src/com/android/server/net/NetworkStatsService.java
index c4ffdec..cf53002 100644
--- a/service-t/src/com/android/server/net/NetworkStatsService.java
+++ b/service-t/src/com/android/server/net/NetworkStatsService.java
@@ -56,7 +56,6 @@
import static android.net.netstats.NetworkStatsDataMigrationUtils.PREFIX_XT;
import static android.os.Trace.TRACE_TAG_NETWORK;
import static android.system.OsConstants.ENOENT;
-import static android.system.OsConstants.R_OK;
import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
import static android.text.format.DateUtils.DAY_IN_MILLIS;
import static android.text.format.DateUtils.HOUR_IN_MILLIS;
@@ -134,7 +133,6 @@
import android.service.NetworkInterfaceProto;
import android.service.NetworkStatsServiceDumpProto;
import android.system.ErrnoException;
-import android.system.Os;
import android.telephony.PhoneStateListener;
import android.telephony.SubscriptionPlan;
import android.text.TextUtils;
@@ -162,11 +160,13 @@
import com.android.net.module.util.LocationPermissionChecker;
import com.android.net.module.util.NetworkStatsUtils;
import com.android.net.module.util.PermissionUtils;
+import com.android.net.module.util.SharedLog;
import com.android.net.module.util.Struct;
-import com.android.net.module.util.Struct.U32;
+import com.android.net.module.util.Struct.S32;
import com.android.net.module.util.Struct.U8;
import com.android.net.module.util.bpf.CookieTagMapKey;
import com.android.net.module.util.bpf.CookieTagMapValue;
+import com.android.server.BpfNetMaps;
import java.io.File;
import java.io.FileDescriptor;
@@ -252,6 +252,8 @@
"/sys/fs/bpf/netd_shared/map_netd_stats_map_A";
private static final String STATS_MAP_B_PATH =
"/sys/fs/bpf/netd_shared/map_netd_stats_map_B";
+ private static final String IFACE_STATS_MAP_PATH =
+ "/sys/fs/bpf/netd_shared/map_netd_iface_stats_map";
/**
* DeviceConfig flag used to indicate whether the files should be stored in the apex data
@@ -406,11 +408,12 @@
* mActiveUidCounterSet to avoid accessing kernel too frequently.
*/
private SparseIntArray mActiveUidCounterSet = new SparseIntArray();
- private final IBpfMap<U32, U8> mUidCounterSetMap;
+ private final IBpfMap<S32, U8> mUidCounterSetMap;
private final IBpfMap<CookieTagMapKey, CookieTagMapValue> mCookieTagMap;
private final IBpfMap<StatsMapKey, StatsMapValue> mStatsMapA;
private final IBpfMap<StatsMapKey, StatsMapValue> mStatsMapB;
private final IBpfMap<UidStatsMapKey, StatsMapValue> mAppUidStatsMap;
+ private final IBpfMap<S32, StatsMapValue> mIfaceStatsMap;
/** Data layer operation counters for splicing into other structures. */
private NetworkStats mUidOperations = new NetworkStats(0L, 10);
@@ -427,12 +430,7 @@
private long mLastStatsSessionPoll;
private final Object mOpenSessionCallsLock = new Object();
- /**
- * Map from UID to number of opened sessions. This is used for rate-limt an app to open
- * session frequently
- */
- @GuardedBy("mOpenSessionCallsLock")
- private final SparseIntArray mOpenSessionCallsPerUid = new SparseIntArray();
+
/**
* Map from key {@code OpenSessionKey} to count of opened sessions. This is for recording
* the caller of open session and it is only for debugging.
@@ -454,6 +452,9 @@
@NonNull
private final BpfInterfaceMapUpdater mInterfaceMapUpdater;
+ @Nullable
+ private final SkDestroyListener mSkDestroyListener;
+
private static @NonNull Clock getDefaultClock() {
return new BestClock(ZoneOffset.UTC, SystemClock.currentNetworkTimeClock(),
Clock.systemUTC());
@@ -587,6 +588,19 @@
mStatsMapA = mDeps.getStatsMapA();
mStatsMapB = mDeps.getStatsMapB();
mAppUidStatsMap = mDeps.getAppUidStatsMap();
+ mIfaceStatsMap = mDeps.getIfaceStatsMap();
+
+ // TODO: Remove bpfNetMaps creation and always start SkDestroyListener
+ // Following code is for the experiment to verify the SkDestroyListener refactoring. Based
+ // on the experiment flag, BpfNetMaps starts C SkDestroyListener (existing code) or
+ // NetworkStatsService starts Java SkDestroyListener (new code).
+ final BpfNetMaps bpfNetMaps = mDeps.makeBpfNetMaps(mContext);
+ if (bpfNetMaps.isSkDestroyListenerRunning()) {
+ mSkDestroyListener = null;
+ } else {
+ mSkDestroyListener = mDeps.makeSkDestroyListener(mCookieTagMap, mHandler);
+ mHandler.post(mSkDestroyListener::start);
+ }
}
/**
@@ -724,10 +738,10 @@
}
/** Get counter sets map for each UID. */
- public IBpfMap<U32, U8> getUidCounterSetMap() {
+ public IBpfMap<S32, U8> getUidCounterSetMap() {
try {
- return new BpfMap<U32, U8>(UID_COUNTERSET_MAP_PATH, BpfMap.BPF_F_RDWR,
- U32.class, U8.class);
+ return new BpfMap<S32, U8>(UID_COUNTERSET_MAP_PATH, BpfMap.BPF_F_RDWR,
+ S32.class, U8.class);
} catch (ErrnoException e) {
Log.wtf(TAG, "Cannot open uid counter set map: " + e);
return null;
@@ -778,10 +792,31 @@
}
}
+ /** Gets interface stats map */
+ public IBpfMap<S32, StatsMapValue> getIfaceStatsMap() {
+ try {
+ return new BpfMap<S32, StatsMapValue>(IFACE_STATS_MAP_PATH,
+ BpfMap.BPF_F_RDWR, S32.class, StatsMapValue.class);
+ } catch (ErrnoException e) {
+ throw new IllegalStateException("Failed to open interface stats map", e);
+ }
+ }
+
/** Gets whether the build is userdebug. */
public boolean isDebuggable() {
return Build.isDebuggable();
}
+
+ /** Create a new BpfNetMaps. */
+ public BpfNetMaps makeBpfNetMaps(Context ctx) {
+ return new BpfNetMaps(ctx);
+ }
+
+ /** Create a new SkDestroyListener. */
+ public SkDestroyListener makeSkDestroyListener(
+ IBpfMap<CookieTagMapKey, CookieTagMapValue> cookieTagMap, Handler handler) {
+ return new SkDestroyListener(cookieTagMap, handler, new SharedLog(TAG));
+ }
}
/**
@@ -1293,7 +1328,7 @@
mNetd.bandwidthSetGlobalAlert(mGlobalAlertBytes);
} catch (IllegalStateException e) {
Log.w(TAG, "problem registering for global alert: " + e);
- } catch (RemoteException e) {
+ } catch (RemoteException | ServiceSpecificException e) {
// ignored; service lives in system_server
}
invokeForAllStatsProviderCallbacks((cb) -> cb.mProvider.onSetAlert(mGlobalAlertBytes));
@@ -1321,9 +1356,6 @@
mOpenSessionCallsPerCaller.put(key, Integer.sum(callsPerCaller, 1));
}
- int callsPerUid = mOpenSessionCallsPerUid.get(key.uid, 0);
- mOpenSessionCallsPerUid.put(key.uid, callsPerUid + 1);
-
if (key.uid == android.os.Process.SYSTEM_UID) {
return false;
}
@@ -1719,7 +1751,7 @@
if (set == SET_DEFAULT) {
try {
- mUidCounterSetMap.deleteEntry(new U32(uid));
+ mUidCounterSetMap.deleteEntry(new S32(uid));
} catch (ErrnoException e) {
Log.w(TAG, "UidCounterSetMap.deleteEntry(" + uid + ") failed with errno: " + e);
}
@@ -1727,7 +1759,7 @@
}
try {
- mUidCounterSetMap.updateEntry(new U32(uid), new U8((short) set));
+ mUidCounterSetMap.updateEntry(new S32(uid), new U8((short) set));
} catch (ErrnoException e) {
Log.w(TAG, "UidCounterSetMap.updateEntry(" + uid + ", " + set
+ ") failed with errno: " + e);
@@ -2444,7 +2476,7 @@
deleteStatsMapTagData(mStatsMapB, uid);
try {
- mUidCounterSetMap.deleteEntry(new U32(uid));
+ mUidCounterSetMap.deleteEntry(new S32(uid));
} catch (ErrnoException e) {
logErrorIfNotErrNoent(e, "Failed to delete tag data from uid counter set map");
}
@@ -2469,13 +2501,12 @@
mUidRecorder.removeUidsLocked(uids);
mUidTagRecorder.removeUidsLocked(uids);
+ mStatsFactory.removeUidsLocked(uids);
// Clear kernel stats associated with UID
for (int uid : uids) {
deleteKernelTagData(uid);
}
-
- // TODO: Remove the UID's entries from mOpenSessionCallsPerUid and
- // mOpenSessionCallsPerCaller
+ // TODO: Remove the UID's entries from mOpenSessionCallsPerCaller.
}
/**
@@ -2713,6 +2744,12 @@
}
pw.println();
+ pw.println("InterfaceMapUpdater:");
+ pw.increaseIndent();
+ mInterfaceMapUpdater.dump(pw);
+ pw.decreaseIndent();
+
+ pw.println();
pw.println("BPF map status:");
pw.increaseIndent();
dumpMapStatus(pw);
@@ -2727,6 +2764,9 @@
dumpCookieTagMapLocked(pw);
dumpUidCounterSetMapLocked(pw);
dumpAppUidStatsMapLocked(pw);
+ dumpStatsMapLocked(mStatsMapA, pw, "mStatsMapA");
+ dumpStatsMapLocked(mStatsMapB, pw, "mStatsMapB");
+ dumpIfaceStatsMapLocked(pw);
pw.decreaseIndent();
}
}
@@ -2794,24 +2834,14 @@
}
}
- private <K extends Struct, V extends Struct> String getMapStatus(
- final IBpfMap<K, V> map, final String path) {
- if (map != null) {
- return "OK";
- }
- try {
- Os.access(path, R_OK);
- return "NULL(map is pinned to " + path + ")";
- } catch (ErrnoException e) {
- return "NULL(map is not pinned to " + path + ": " + Os.strerror(e.errno) + ")";
- }
- }
-
private void dumpMapStatus(final IndentingPrintWriter pw) {
- pw.println("mCookieTagMap: " + getMapStatus(mCookieTagMap, COOKIE_TAG_MAP_PATH));
- pw.println("mUidCounterSetMap: "
- + getMapStatus(mUidCounterSetMap, UID_COUNTERSET_MAP_PATH));
- pw.println("mAppUidStatsMap: " + getMapStatus(mAppUidStatsMap, APP_UID_STATS_MAP_PATH));
+ BpfDump.dumpMapStatus(mCookieTagMap, pw, "mCookieTagMap", COOKIE_TAG_MAP_PATH);
+ BpfDump.dumpMapStatus(mUidCounterSetMap, pw, "mUidCounterSetMap", UID_COUNTERSET_MAP_PATH);
+ BpfDump.dumpMapStatus(mAppUidStatsMap, pw, "mAppUidStatsMap", APP_UID_STATS_MAP_PATH);
+ BpfDump.dumpMapStatus(mStatsMapA, pw, "mStatsMapA", STATS_MAP_A_PATH);
+ BpfDump.dumpMapStatus(mStatsMapB, pw, "mStatsMapB", STATS_MAP_B_PATH);
+ // mIfaceStatsMap is always not null but dump status to be consistent with other maps.
+ BpfDump.dumpMapStatus(mIfaceStatsMap, pw, "mIfaceStatsMap", IFACE_STATS_MAP_PATH);
}
@GuardedBy("mStatsLock")
@@ -2819,24 +2849,10 @@
if (mCookieTagMap == null) {
return;
}
- pw.println("mCookieTagMap:");
- pw.increaseIndent();
- try {
- mCookieTagMap.forEach((key, value) -> {
- // value could be null if there is a concurrent entry deletion.
- // http://b/220084230.
- if (value != null) {
- pw.println("cookie=" + key.socketCookie
- + " tag=0x" + Long.toHexString(value.tag)
- + " uid=" + value.uid);
- } else {
- pw.println("Entry is deleted while dumping, iterating from first entry");
- }
- });
- } catch (ErrnoException e) {
- pw.println("mCookieTagMap dump end with error: " + Os.strerror(e.errno));
- }
- pw.decreaseIndent();
+ BpfDump.dumpMap(mCookieTagMap, pw, "mCookieTagMap",
+ (key, value) -> "cookie=" + key.socketCookie
+ + " tag=0x" + Long.toHexString(value.tag)
+ + " uid=" + value.uid);
}
@GuardedBy("mStatsLock")
@@ -2844,22 +2860,8 @@
if (mUidCounterSetMap == null) {
return;
}
- pw.println("mUidCounterSetMap:");
- pw.increaseIndent();
- try {
- mUidCounterSetMap.forEach((uid, set) -> {
- // set could be null if there is a concurrent entry deletion.
- // http://b/220084230.
- if (set != null) {
- pw.println("uid=" + uid.val + " set=" + set.val);
- } else {
- pw.println("Entry is deleted while dumping, iterating from first entry");
- }
- });
- } catch (ErrnoException e) {
- pw.println("mUidCounterSetMap dump end with error: " + Os.strerror(e.errno));
- }
- pw.decreaseIndent();
+ BpfDump.dumpMap(mUidCounterSetMap, pw, "mUidCounterSetMap",
+ (uid, set) -> "uid=" + uid.val + " set=" + set.val);
}
@GuardedBy("mStatsLock")
@@ -2867,27 +2869,51 @@
if (mAppUidStatsMap == null) {
return;
}
- pw.println("mAppUidStatsMap:");
- pw.increaseIndent();
- pw.println("uid rxBytes rxPackets txBytes txPackets");
- try {
- mAppUidStatsMap.forEach((key, value) -> {
- // value could be null if there is a concurrent entry deletion.
- // http://b/220084230.
- if (value != null) {
- pw.println(key.uid + " "
+ BpfDump.dumpMap(mAppUidStatsMap, pw, "mAppUidStatsMap",
+ "uid rxBytes rxPackets txBytes txPackets",
+ (key, value) -> key.uid + " "
+ + value.rxBytes + " "
+ + value.rxPackets + " "
+ + value.txBytes + " "
+ + value.txPackets);
+ }
+
+ @GuardedBy("mStatsLock")
+ private void dumpStatsMapLocked(final IBpfMap<StatsMapKey, StatsMapValue> statsMap,
+ final IndentingPrintWriter pw, final String mapName) {
+ if (statsMap == null) {
+ return;
+ }
+
+ BpfDump.dumpMap(statsMap, pw, mapName,
+ "ifaceIndex ifaceName tag_hex uid_int cnt_set rxBytes rxPackets txBytes txPackets",
+ (key, value) -> {
+ final String ifName = mInterfaceMapUpdater.getIfNameByIndex(key.ifaceIndex);
+ return key.ifaceIndex + " "
+ + (ifName != null ? ifName : "unknown") + " "
+ + "0x" + Long.toHexString(key.tag) + " "
+ + key.uid + " "
+ + key.counterSet + " "
+ value.rxBytes + " "
+ value.rxPackets + " "
+ value.txBytes + " "
- + value.txPackets);
- } else {
- pw.println("Entry is deleted while dumping, iterating from first entry");
- }
- });
- } catch (ErrnoException e) {
- pw.println("mAppUidStatsMap dump end with error: " + Os.strerror(e.errno));
- }
- pw.decreaseIndent();
+ + value.txPackets;
+ });
+ }
+
+ @GuardedBy("mStatsLock")
+ private void dumpIfaceStatsMapLocked(final IndentingPrintWriter pw) {
+ BpfDump.dumpMap(mIfaceStatsMap, pw, "mIfaceStatsMap",
+ "ifaceIndex ifaceName rxBytes rxPackets txBytes txPackets",
+ (key, value) -> {
+ final String ifName = mInterfaceMapUpdater.getIfNameByIndex(key.val);
+ return key.val + " "
+ + (ifName != null ? ifName : "unknown") + " "
+ + value.rxBytes + " "
+ + value.rxPackets + " "
+ + value.txBytes + " "
+ + value.txPackets;
+ });
}
private NetworkStats readNetworkStatsSummaryDev() {
@@ -2924,7 +2950,7 @@
*/
private NetworkStats getNetworkStatsUidDetail(String[] ifaces)
throws RemoteException {
- final NetworkStats uidSnapshot = readNetworkStatsUidDetail(UID_ALL, ifaces, TAG_ALL);
+ final NetworkStats uidSnapshot = readNetworkStatsUidDetail(UID_ALL, ifaces, TAG_ALL);
// fold tethering stats and operations into uid snapshot
final NetworkStats tetherSnapshot = getNetworkStatsTethering(STATS_PER_UID);
@@ -2939,6 +2965,7 @@
uidSnapshot.combineAllValues(providerStats);
uidSnapshot.combineAllValues(mUidOperations);
+ uidSnapshot.filter(UID_ALL, ifaces, TAG_ALL);
return uidSnapshot;
}
diff --git a/service-t/src/com/android/server/net/SkDestroyListener.java b/service-t/src/com/android/server/net/SkDestroyListener.java
new file mode 100644
index 0000000..7b68f89
--- /dev/null
+++ b/service-t/src/com/android/server/net/SkDestroyListener.java
@@ -0,0 +1,75 @@
+/*
+ * 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.server.net;
+
+import static android.system.OsConstants.NETLINK_INET_DIAG;
+
+import android.os.Handler;
+import android.system.ErrnoException;
+
+import com.android.net.module.util.IBpfMap;
+import com.android.net.module.util.SharedLog;
+import com.android.net.module.util.bpf.CookieTagMapKey;
+import com.android.net.module.util.bpf.CookieTagMapValue;
+import com.android.net.module.util.ip.NetlinkMonitor;
+import com.android.net.module.util.netlink.InetDiagMessage;
+import com.android.net.module.util.netlink.NetlinkMessage;
+import com.android.net.module.util.netlink.StructInetDiagSockId;
+
+/**
+ * Monitor socket destroy and delete entry from cookie tag bpf map.
+ */
+public class SkDestroyListener extends NetlinkMonitor {
+ private static final int SKNLGRP_INET_TCP_DESTROY = 1;
+ private static final int SKNLGRP_INET_UDP_DESTROY = 2;
+ private static final int SKNLGRP_INET6_TCP_DESTROY = 3;
+ private static final int SKNLGRP_INET6_UDP_DESTROY = 4;
+
+ // TODO: if too many sockets are closed too quickly, this can overflow the socket buffer, and
+ // some entries in mCookieTagMap will not be freed. In order to fix this it would be needed to
+ // periodically dump all sockets and remove the tag entries for sockets that have been closed.
+ // For now, set a large-enough buffer that hundreds of sockets can be closed without getting
+ // ENOBUFS and leaking mCookieTagMap entries.
+ private static final int SOCK_RCV_BUF_SIZE = 512 * 1024;
+
+ private final IBpfMap<CookieTagMapKey, CookieTagMapValue> mCookieTagMap;
+
+ SkDestroyListener(final IBpfMap<CookieTagMapKey, CookieTagMapValue> cookieTagMap,
+ final Handler handler, final SharedLog log) {
+ super(handler, log, "SkDestroyListener", NETLINK_INET_DIAG,
+ 1 << (SKNLGRP_INET_TCP_DESTROY - 1)
+ | 1 << (SKNLGRP_INET_UDP_DESTROY - 1)
+ | 1 << (SKNLGRP_INET6_TCP_DESTROY - 1)
+ | 1 << (SKNLGRP_INET6_UDP_DESTROY - 1),
+ SOCK_RCV_BUF_SIZE);
+ mCookieTagMap = cookieTagMap;
+ }
+
+ @Override
+ public void processNetlinkMessage(final NetlinkMessage nlMsg, final long whenMs) {
+ if (!(nlMsg instanceof InetDiagMessage)) {
+ mLog.e("Received non InetDiagMessage");
+ return;
+ }
+ final StructInetDiagSockId sockId = ((InetDiagMessage) nlMsg).inetDiagMsg.id;
+ try {
+ mCookieTagMap.deleteEntry(new CookieTagMapKey(sockId.cookie));
+ } catch (ErrnoException e) {
+ mLog.e("Failed to delete CookieTagMap entry for " + sockId.cookie + ": " + e);
+ }
+ }
+}
diff --git a/service-t/src/com/android/server/net/StatsMapKey.java b/service-t/src/com/android/server/net/StatsMapKey.java
index ea8d836..44269b3 100644
--- a/service-t/src/com/android/server/net/StatsMapKey.java
+++ b/service-t/src/com/android/server/net/StatsMapKey.java
@@ -24,8 +24,8 @@
* Key for both stats maps.
*/
public class StatsMapKey extends Struct {
- @Field(order = 0, type = Type.U32)
- public final long uid;
+ @Field(order = 0, type = Type.S32)
+ public final int uid;
@Field(order = 1, type = Type.U32)
public final long tag;
@@ -33,11 +33,11 @@
@Field(order = 2, type = Type.U32)
public final long counterSet;
- @Field(order = 3, type = Type.U32)
- public final long ifaceIndex;
+ @Field(order = 3, type = Type.S32)
+ public final int ifaceIndex;
- public StatsMapKey(final long uid, final long tag, final long counterSet,
- final long ifaceIndex) {
+ public StatsMapKey(final int uid, final long tag, final long counterSet,
+ final int ifaceIndex) {
this.uid = uid;
this.tag = tag;
this.counterSet = counterSet;
diff --git a/service-t/src/com/android/server/net/UidStatsMapKey.java b/service-t/src/com/android/server/net/UidStatsMapKey.java
index 2849f94..59025fd 100644
--- a/service-t/src/com/android/server/net/UidStatsMapKey.java
+++ b/service-t/src/com/android/server/net/UidStatsMapKey.java
@@ -24,10 +24,10 @@
* Key for uid stats map.
*/
public class UidStatsMapKey extends Struct {
- @Field(order = 0, type = Type.U32)
- public final long uid;
+ @Field(order = 0, type = Type.S32)
+ public final int uid;
- public UidStatsMapKey(final long uid) {
+ public UidStatsMapKey(final int uid) {
this.uid = uid;
}
}
diff --git a/service/Android.bp b/service/Android.bp
index b68d389..296f6d9 100644
--- a/service/Android.bp
+++ b/service/Android.bp
@@ -143,15 +143,25 @@
"src/**/*.java",
":framework-connectivity-shared-srcs",
":services-connectivity-shared-srcs",
+ ":statslog-connectivity-java-gen",
],
libs: [
"framework-annotations-lib",
"framework-connectivity-pre-jarjar",
+ // The framework-connectivity-t library is only available on T+ platforms
+ // so any calls to it must be protected with a check to ensure that it is
+ // available. The linter will detect any unprotected calls through an API
+ // but not direct calls to the implementation. So, this depends on the
+ // module lib stubs directly to ensure the linter will work correctly
+ // as depending on framework-connectivity-t would cause it to be compiled
+ // against the implementation because the two libraries are in the same
+ // APEX.
"framework-connectivity-t.stubs.module_lib",
- "framework-tethering.stubs.module_lib",
- "framework-wifi.stubs.module_lib",
+ "framework-tethering",
+ "framework-wifi",
"unsupportedappusage",
"ServiceConnectivityResources",
+ "framework-statsd",
],
static_libs: [
// Do not add libs here if they are already included
@@ -169,6 +179,7 @@
"networkstack-client",
"PlatformProperties",
"service-connectivity-protos",
+ "service-connectivity-stats-protos",
"NetworkStackApiStableShims",
],
apex_available: [
@@ -192,7 +203,7 @@
libs: [
"framework-annotations-lib",
"framework-connectivity-pre-jarjar",
- "framework-wifi.stubs.module_lib",
+ "framework-wifi",
"service-connectivity-pre-jarjar",
],
visibility: [
@@ -214,13 +225,18 @@
apex_available: [
"com.android.tethering",
],
- lint: { strict_updatability_linting: true },
+ lint: {
+ strict_updatability_linting: true,
+ },
}
java_defaults {
name: "service-connectivity-defaults",
sdk_version: "system_server_current",
min_sdk_version: "30",
+ defaults: [
+ "standalone-system-server-module-optimize-defaults",
+ ],
// This library combines system server jars that have access to different bootclasspath jars.
// Lower SDK service jars must not depend on higher SDK jars as that would let them
// transitively depend on the wrong bootclasspath jars. Sources also cannot be added here as
@@ -241,8 +257,8 @@
"framework-annotations-lib",
"framework-connectivity.impl",
"framework-connectivity-t.impl",
- "framework-tethering.stubs.module_lib",
- "framework-wifi.stubs.module_lib",
+ "framework-tethering",
+ "framework-wifi",
"libprotobuf-java-nano",
],
jarjar_rules: ":connectivity-jarjar-rules",
@@ -250,11 +266,11 @@
"com.android.tethering",
],
optimize: {
- enabled: true,
- shrink: true,
proguard_flags_files: ["proguard.flags"],
},
- lint: { strict_updatability_linting: true },
+ lint: {
+ strict_updatability_linting: true,
+ },
}
// A special library created strictly for use by the tests as they need the
@@ -275,6 +291,20 @@
installable: true,
}
+java_library_static {
+ name: "service-connectivity-stats-protos",
+ sdk_version: "system_current",
+ min_sdk_version: "30",
+ proto: {
+ type: "lite",
+ },
+ srcs: [
+ "src/com/android/metrics/stats.proto",
+ ],
+ static_libs: ["ConnectivityServiceprotos"],
+ apex_available: ["com.android.tethering"],
+}
+
genrule {
name: "connectivity-jarjar-rules",
defaults: ["jarjar-rules-combine-defaults"],
@@ -307,7 +337,7 @@
],
out: ["service_connectivity_jarjar_rules.txt"],
cmd: "$(location jarjar-rules-generator) " +
- "--jars $(location :service-connectivity-pre-jarjar{.jar}) " +
+ "$(location :service-connectivity-pre-jarjar{.jar}) " +
"$(location :service-connectivity-tiramisu-pre-jarjar{.jar}) " +
"--prefix android.net.connectivity " +
"--excludes $(location jarjar-excludes.txt) " +
@@ -326,9 +356,16 @@
],
out: ["service_nearby_jarjar_rules.txt"],
cmd: "$(location jarjar-rules-generator) " +
- "--jars $(location :service-nearby-pre-jarjar{.jar}) " +
+ "$(location :service-nearby-pre-jarjar{.jar}) " +
"--prefix com.android.server.nearby " +
"--excludes $(location jarjar-excludes.txt) " +
"--output $(out)",
visibility: ["//visibility:private"],
}
+
+genrule {
+ name: "statslog-connectivity-java-gen",
+ tools: ["stats-log-api-gen"],
+ cmd: "$(location stats-log-api-gen) --java $(out) --module connectivity --javaPackage com.android.server --javaClass ConnectivityStatsLog",
+ out: ["com/android/server/ConnectivityStatsLog.java"],
+}
diff --git a/service/ServiceConnectivityResources/Android.bp b/service/ServiceConnectivityResources/Android.bp
index 02b2875..2260596 100644
--- a/service/ServiceConnectivityResources/Android.bp
+++ b/service/ServiceConnectivityResources/Android.bp
@@ -21,9 +21,8 @@
android_app {
name: "ServiceConnectivityResources",
- sdk_version: "module_30",
+ sdk_version: "module_current",
min_sdk_version: "30",
- target_sdk_version: "33",
resource_dirs: [
"res",
],
diff --git a/service/ServiceConnectivityResources/res/values-es-rUS/strings.xml b/service/ServiceConnectivityResources/res/values-es-rUS/strings.xml
index fdca468..b24dee0 100644
--- a/service/ServiceConnectivityResources/res/values-es-rUS/strings.xml
+++ b/service/ServiceConnectivityResources/res/values-es-rUS/strings.xml
@@ -22,7 +22,7 @@
<string name="network_available_sign_in" msgid="2622520134876355561">"Acceder a la red"</string>
<!-- no translation found for network_available_sign_in_detailed (8439369644697866359) -->
<skip />
- <string name="wifi_no_internet" msgid="1326348603404555475">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g>no tiene acceso a Internet"</string>
+ <string name="wifi_no_internet" msgid="1326348603404555475">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> no tiene acceso a Internet"</string>
<string name="wifi_no_internet_detailed" msgid="1746921096565304090">"Presiona para ver opciones"</string>
<string name="mobile_no_internet" msgid="4087718456753201450">"La red móvil no tiene acceso a Internet"</string>
<string name="other_networks_no_internet" msgid="5693932964749676542">"La red no tiene acceso a Internet"</string>
diff --git a/service/ServiceConnectivityResources/res/values-kk/strings.xml b/service/ServiceConnectivityResources/res/values-kk/strings.xml
index 00c0f39..efe23b6 100644
--- a/service/ServiceConnectivityResources/res/values-kk/strings.xml
+++ b/service/ServiceConnectivityResources/res/values-kk/strings.xml
@@ -33,7 +33,7 @@
<string name="network_switch_metered_detail" msgid="1257300152739542096">"Құрылғы <xliff:g id="PREVIOUS_NETWORK">%2$s</xliff:g> желісінде интернетпен байланыс жоғалған жағдайда <xliff:g id="NEW_NETWORK">%1$s</xliff:g> желісін пайдаланады. Деректер ақысы алынуы мүмкін."</string>
<string name="network_switch_metered_toast" msgid="70691146054130335">"<xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> желісінен <xliff:g id="NEW_NETWORK">%2$s</xliff:g> желісіне ауысты"</string>
<string-array name="network_switch_type_name">
- <item msgid="3004933964374161223">"мобильдік деректер"</item>
+ <item msgid="3004933964374161223">"мобильдік интернет"</item>
<item msgid="5624324321165953608">"Wi-Fi"</item>
<item msgid="5667906231066981731">"Bluetooth"</item>
<item msgid="346574747471703768">"Ethernet"</item>
diff --git a/service/ServiceConnectivityResources/res/values-nb/strings.xml b/service/ServiceConnectivityResources/res/values-nb/strings.xml
index 00a0728..4439048 100644
--- a/service/ServiceConnectivityResources/res/values-nb/strings.xml
+++ b/service/ServiceConnectivityResources/res/values-nb/strings.xml
@@ -34,7 +34,7 @@
<string name="network_switch_metered_toast" msgid="70691146054130335">"Byttet fra <xliff:g id="PREVIOUS_NETWORK">%1$s</xliff:g> til <xliff:g id="NEW_NETWORK">%2$s</xliff:g>"</string>
<string-array name="network_switch_type_name">
<item msgid="3004933964374161223">"mobildata"</item>
- <item msgid="5624324321165953608">"Wi-Fi"</item>
+ <item msgid="5624324321165953608">"Wifi"</item>
<item msgid="5667906231066981731">"Bluetooth"</item>
<item msgid="346574747471703768">"Ethernet"</item>
<item msgid="5734728378097476003">"VPN"</item>
diff --git a/service/ServiceConnectivityResources/res/values-ro/strings.xml b/service/ServiceConnectivityResources/res/values-ro/strings.xml
index fa5848f..4ff5290 100644
--- a/service/ServiceConnectivityResources/res/values-ro/strings.xml
+++ b/service/ServiceConnectivityResources/res/values-ro/strings.xml
@@ -18,12 +18,12 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="connectivityResourcesAppLabel" msgid="2476261877900882974">"Resurse pentru conectivitatea sistemului"</string>
- <string name="wifi_available_sign_in" msgid="8041178343789805553">"Conectați-vă la rețeaua Wi-Fi"</string>
- <string name="network_available_sign_in" msgid="2622520134876355561">"Conectați-vă la rețea"</string>
+ <string name="wifi_available_sign_in" msgid="8041178343789805553">"Conectează-te la rețeaua Wi-Fi"</string>
+ <string name="network_available_sign_in" msgid="2622520134876355561">"Conectează-te la rețea"</string>
<!-- no translation found for network_available_sign_in_detailed (8439369644697866359) -->
<skip />
<string name="wifi_no_internet" msgid="1326348603404555475">"<xliff:g id="NETWORK_SSID">%1$s</xliff:g> nu are acces la internet"</string>
- <string name="wifi_no_internet_detailed" msgid="1746921096565304090">"Atingeți pentru opțiuni"</string>
+ <string name="wifi_no_internet_detailed" msgid="1746921096565304090">"Atinge pentru opțiuni"</string>
<string name="mobile_no_internet" msgid="4087718456753201450">"Rețeaua mobilă nu are acces la internet"</string>
<string name="other_networks_no_internet" msgid="5693932964749676542">"Rețeaua nu are acces la internet"</string>
<string name="private_dns_broken_detailed" msgid="2677123850463207823">"Serverul DNS privat nu poate fi accesat"</string>
diff --git a/service/ServiceConnectivityResources/res/values/config.xml b/service/ServiceConnectivityResources/res/values/config.xml
index bff6953..22d9b01 100644
--- a/service/ServiceConnectivityResources/res/values/config.xml
+++ b/service/ServiceConnectivityResources/res/values/config.xml
@@ -78,6 +78,27 @@
Settings.Global.NETWORK_AVOID_BAD_WIFI. This is the default value of that setting. -->
<integer translatable="false" name="config_networkAvoidBadWifi">1</integer>
+ <!-- Whether the device should actively prefer bad wifi to good cell on Android 12/13.
+
+ This setting only makes sense if the system is configured not to avoid bad wifis
+ (config_networkAvoidBadWifi=0 and Settings.Global.NETWORK_AVOID_BAD_WIFI=IGNORE
+ or PROMPT), otherwise it's not used.
+
+ On Android 12 and 13, if this is 0, when ranking a bad wifi that never validated against
+ validated mobile data, the system will prefer mobile data. It will prefer wifi if wifi
+ loses validation later. This is the default behavior up to Android 13.
+ This behavior avoids the device losing internet access when walking past a wifi network
+ with no internet access.
+
+ If this is 1, then in the same scenario, the system will prefer mobile data until the wifi
+ completes its first validation attempt (or the attempt times out), and after that it
+ will prefer the wifi even if it doesn't provide internet access, unless there is a captive
+ portal on that wifi.
+
+ On Android 14 and above, the behavior is always like 1, regardless of the value of this
+ setting. -->
+ <integer translatable="false" name="config_activelyPreferBadWifi">0</integer>
+
<!-- Array of ConnectivityManager.TYPE_xxxx constants for networks that may only
be controlled by systemOrSignature apps. -->
<integer-array translatable="false" name="config_protectedNetworks">
diff --git a/service/ServiceConnectivityResources/res/values/overlayable.xml b/service/ServiceConnectivityResources/res/values/overlayable.xml
index 3389d63..4c85e8c 100644
--- a/service/ServiceConnectivityResources/res/values/overlayable.xml
+++ b/service/ServiceConnectivityResources/res/values/overlayable.xml
@@ -24,6 +24,7 @@
<item type="integer" name="config_networkMeteredMultipathPreference"/>
<item type="array" name="config_networkSupportedKeepaliveCount"/>
<item type="integer" name="config_networkAvoidBadWifi"/>
+ <item type="integer" name="config_activelyPreferBadWifi"/>
<item type="array" name="config_protectedNetworks"/>
<item type="bool" name="config_vehicleInternalNetworkAlwaysRequested"/>
<item type="integer" name="config_networkWakeupPacketMark"/>
diff --git a/service/jni/com_android_server_BpfNetMaps.cpp b/service/jni/com_android_server_BpfNetMaps.cpp
index 71fa8e4..799ac5c 100644
--- a/service/jni/com_android_server_BpfNetMaps.cpp
+++ b/service/jni/com_android_server_BpfNetMaps.cpp
@@ -47,8 +47,8 @@
ALOGE("%s failed, error code = %d", __func__, status.code()); \
} while (0)
-static void native_init(JNIEnv* env, jclass clazz) {
- Status status = mTc.start();
+static void native_init(JNIEnv* env, jclass clazz, jboolean startSkDestroyListener) {
+ Status status = mTc.start(startSkDestroyListener);
CHECK_LOG(status);
if (!isOk(status)) {
uid_t uid = getuid();
@@ -201,7 +201,7 @@
// clang-format off
static const JNINativeMethod gMethods[] = {
/* name, signature, funcPtr */
- {"native_init", "()V",
+ {"native_init", "(Z)V",
(void*)native_init},
{"native_addNaughtyApp", "(I)I",
(void*)native_addNaughtyApp},
diff --git a/service/jni/com_android_server_connectivity_ClatCoordinator.cpp b/service/jni/com_android_server_connectivity_ClatCoordinator.cpp
index de0e20a..5cd6e5d 100644
--- a/service/jni/com_android_server_connectivity_ClatCoordinator.cpp
+++ b/service/jni/com_android_server_connectivity_ClatCoordinator.cpp
@@ -87,7 +87,8 @@
// Picks a random interface ID that is checksum neutral with the IPv4 address and the NAT64 prefix.
jstring com_android_server_connectivity_ClatCoordinator_generateIpv6Address(
- JNIEnv* env, jobject clazz, jstring ifaceStr, jstring v4Str, jstring prefix64Str) {
+ JNIEnv* env, jobject clazz, jstring ifaceStr, jstring v4Str, jstring prefix64Str,
+ jint mark) {
ScopedUtfChars iface(env, ifaceStr);
ScopedUtfChars addr4(env, v4Str);
ScopedUtfChars prefix64(env, prefix64Str);
@@ -111,7 +112,7 @@
}
in6_addr v6;
- if (net::clat::generateIpv6Address(iface.c_str(), v4, nat64Prefix, &v6)) {
+ if (net::clat::generateIpv6Address(iface.c_str(), v4, nat64Prefix, &v6, mark)) {
jniThrowExceptionFmt(env, "java/io/IOException",
"Unable to find global source address on %s for %s", iface.c_str(),
prefix64.c_str());
@@ -447,7 +448,7 @@
{"native_selectIpv4Address", "(Ljava/lang/String;I)Ljava/lang/String;",
(void*)com_android_server_connectivity_ClatCoordinator_selectIpv4Address},
{"native_generateIpv6Address",
- "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;",
+ "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)Ljava/lang/String;",
(void*)com_android_server_connectivity_ClatCoordinator_generateIpv6Address},
{"native_createTunInterface", "(Ljava/lang/String;)I",
(void*)com_android_server_connectivity_ClatCoordinator_createTunInterface},
diff --git a/service/mdns/com/android/server/connectivity/mdns/MdnsConfigs.java b/service/mdns/com/android/server/connectivity/mdns/MdnsConfigs.java
index 922037b..41abba7 100644
--- a/service/mdns/com/android/server/connectivity/mdns/MdnsConfigs.java
+++ b/service/mdns/com/android/server/connectivity/mdns/MdnsConfigs.java
@@ -89,4 +89,16 @@
public static boolean preferIpv6() {
return false;
}
+
+ public static boolean removeServiceAfterTtlExpires() {
+ return false;
+ }
+
+ public static boolean allowSearchOptionsToRemoveExpiredService() {
+ return false;
+ }
+
+ public static boolean allowNetworkInterfaceIndexPropagation() {
+ return true;
+ }
}
\ No newline at end of file
diff --git a/service/mdns/com/android/server/connectivity/mdns/MdnsPacketReader.java b/service/mdns/com/android/server/connectivity/mdns/MdnsPacketReader.java
index 61c5f5a..856a2cd 100644
--- a/service/mdns/com/android/server/connectivity/mdns/MdnsPacketReader.java
+++ b/service/mdns/com/android/server/connectivity/mdns/MdnsPacketReader.java
@@ -16,8 +16,11 @@
package com.android.server.connectivity.mdns;
+import android.annotation.Nullable;
import android.util.SparseArray;
+import com.android.server.connectivity.mdns.MdnsServiceInfo.TextEntry;
+
import java.io.EOFException;
import java.io.IOException;
import java.net.DatagramPacket;
@@ -195,6 +198,16 @@
return val;
}
+ @Nullable
+ public TextEntry readTextEntry() throws EOFException {
+ int len = readUInt8();
+ checkRemaining(len);
+ byte[] bytes = new byte[len];
+ System.arraycopy(buf, pos, bytes, 0, bytes.length);
+ pos += len;
+ return TextEntry.fromBytes(bytes);
+ }
+
/**
* Reads a specific number of bytes.
*
diff --git a/service/mdns/com/android/server/connectivity/mdns/MdnsPacketWriter.java b/service/mdns/com/android/server/connectivity/mdns/MdnsPacketWriter.java
index 2fed36d..b78aa5d 100644
--- a/service/mdns/com/android/server/connectivity/mdns/MdnsPacketWriter.java
+++ b/service/mdns/com/android/server/connectivity/mdns/MdnsPacketWriter.java
@@ -16,6 +16,8 @@
package com.android.server.connectivity.mdns;
+import com.android.server.connectivity.mdns.MdnsServiceInfo.TextEntry;
+
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.SocketAddress;
@@ -147,6 +149,12 @@
writeBytes(utf8);
}
+ public void writeTextEntry(TextEntry textEntry) throws IOException {
+ byte[] bytes = textEntry.toBytes();
+ writeUInt8(bytes.length);
+ writeBytes(bytes);
+ }
+
/**
* Writes a series of labels. Uses name compression.
*
diff --git a/service/mdns/com/android/server/connectivity/mdns/MdnsResponse.java b/service/mdns/com/android/server/connectivity/mdns/MdnsResponse.java
index 9f3894f..c94e3c6 100644
--- a/service/mdns/com/android/server/connectivity/mdns/MdnsResponse.java
+++ b/service/mdns/com/android/server/connectivity/mdns/MdnsResponse.java
@@ -35,6 +35,7 @@
private MdnsInetAddressRecord inet4AddressRecord;
private MdnsInetAddressRecord inet6AddressRecord;
private long lastUpdateTime;
+ private int interfaceIndex = MdnsSocket.INTERFACE_INDEX_UNSPECIFIED;
/** Constructs a new, empty response. */
public MdnsResponse(long now) {
@@ -203,6 +204,21 @@
return true;
}
+ /**
+ * Updates the index of the network interface at which this response was received. Can be set to
+ * {@link MdnsSocket#INTERFACE_INDEX_UNSPECIFIED} if unset.
+ */
+ public synchronized void setInterfaceIndex(int interfaceIndex) {
+ this.interfaceIndex = interfaceIndex;
+ }
+
+ /**
+ * Returns the index of the network interface at which this response was received. Can be set to
+ * {@link MdnsSocket#INTERFACE_INDEX_UNSPECIFIED} if unset.
+ */
+ public synchronized int getInterfaceIndex() {
+ return interfaceIndex;
+ }
/** Gets the IPv6 address record. */
public synchronized MdnsInetAddressRecord getInet6AddressRecord() {
diff --git a/service/mdns/com/android/server/connectivity/mdns/MdnsResponseDecoder.java b/service/mdns/com/android/server/connectivity/mdns/MdnsResponseDecoder.java
index 3e5fc42..57b241e 100644
--- a/service/mdns/com/android/server/connectivity/mdns/MdnsResponseDecoder.java
+++ b/service/mdns/com/android/server/connectivity/mdns/MdnsResponseDecoder.java
@@ -92,9 +92,12 @@
* the responses for completeness; the caller should do that.
*
* @param packet The packet to read from.
+ * @param interfaceIndex the network interface index (or {@link
+ * MdnsSocket#INTERFACE_INDEX_UNSPECIFIED} if not known) at which the packet was received
* @return A list of mDNS responses, or null if the packet contained no appropriate responses.
*/
- public int decode(@NonNull DatagramPacket packet, @NonNull List<MdnsResponse> responses) {
+ public int decode(@NonNull DatagramPacket packet, @NonNull List<MdnsResponse> responses,
+ int interfaceIndex) {
MdnsPacketReader reader = new MdnsPacketReader(packet);
List<MdnsRecord> records;
@@ -281,8 +284,10 @@
MdnsResponse response = findResponseWithHostName(responses, inetRecord.getName());
if (inetRecord.getInet4Address() != null && response != null) {
response.setInet4AddressRecord(inetRecord);
+ response.setInterfaceIndex(interfaceIndex);
} else if (inetRecord.getInet6Address() != null && response != null) {
response.setInet6AddressRecord(inetRecord);
+ response.setInterfaceIndex(interfaceIndex);
}
}
}
diff --git a/service/mdns/com/android/server/connectivity/mdns/MdnsSearchOptions.java b/service/mdns/com/android/server/connectivity/mdns/MdnsSearchOptions.java
index 6e90d2c..195bc8e 100644
--- a/service/mdns/com/android/server/connectivity/mdns/MdnsSearchOptions.java
+++ b/service/mdns/com/android/server/connectivity/mdns/MdnsSearchOptions.java
@@ -43,7 +43,7 @@
@Override
public MdnsSearchOptions createFromParcel(Parcel source) {
return new MdnsSearchOptions(source.createStringArrayList(),
- source.readBoolean());
+ source.readBoolean(), source.readBoolean());
}
@Override
@@ -55,14 +55,16 @@
private final List<String> subtypes;
private final boolean isPassiveMode;
+ private final boolean removeExpiredService;
/** Parcelable constructs for a {@link MdnsServiceInfo}. */
- MdnsSearchOptions(List<String> subtypes, boolean isPassiveMode) {
+ MdnsSearchOptions(List<String> subtypes, boolean isPassiveMode, boolean removeExpiredService) {
this.subtypes = new ArrayList<>();
if (subtypes != null) {
this.subtypes.addAll(subtypes);
}
this.isPassiveMode = isPassiveMode;
+ this.removeExpiredService = removeExpiredService;
}
/** Returns a {@link Builder} for {@link MdnsSearchOptions}. */
@@ -91,6 +93,11 @@
return isPassiveMode;
}
+ /** Returns {@code true} if service will be removed after its TTL expires. */
+ public boolean removeExpiredService() {
+ return removeExpiredService;
+ }
+
@Override
public int describeContents() {
return 0;
@@ -100,12 +107,14 @@
public void writeToParcel(Parcel out, int flags) {
out.writeStringList(subtypes);
out.writeBoolean(isPassiveMode);
+ out.writeBoolean(removeExpiredService);
}
/** A builder to create {@link MdnsSearchOptions}. */
public static final class Builder {
private final Set<String> subtypes;
private boolean isPassiveMode = true;
+ private boolean removeExpiredService;
private Builder() {
subtypes = new ArraySet<>();
@@ -136,8 +145,7 @@
/**
* Sets if the passive mode scan should be used. The passive mode scans less frequently in
- * order
- * to conserve battery and produce less network traffic.
+ * order to conserve battery and produce less network traffic.
*
* @param isPassiveMode If set to {@code true}, passive mode will be used. If set to {@code
* false}, active mode will be used.
@@ -147,9 +155,20 @@
return this;
}
+ /**
+ * Sets if the service should be removed after TTL.
+ *
+ * @param removeExpiredService If set to {@code true}, the service will be removed after TTL
+ */
+ public Builder setRemoveExpiredService(boolean removeExpiredService) {
+ this.removeExpiredService = removeExpiredService;
+ return this;
+ }
+
/** Builds a {@link MdnsSearchOptions} with the arguments supplied to this builder. */
public MdnsSearchOptions build() {
- return new MdnsSearchOptions(new ArrayList<>(subtypes), isPassiveMode);
+ return new MdnsSearchOptions(
+ new ArrayList<>(subtypes), isPassiveMode, removeExpiredService);
}
}
}
\ No newline at end of file
diff --git a/service/mdns/com/android/server/connectivity/mdns/MdnsServiceInfo.java b/service/mdns/com/android/server/connectivity/mdns/MdnsServiceInfo.java
index 2e4a4e5..7d645e3 100644
--- a/service/mdns/com/android/server/connectivity/mdns/MdnsServiceInfo.java
+++ b/service/mdns/com/android/server/connectivity/mdns/MdnsServiceInfo.java
@@ -17,11 +17,16 @@
package com.android.server.connectivity.mdns;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
+import com.android.net.module.util.ByteUtils;
+
+import java.nio.charset.Charset;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
@@ -34,6 +39,8 @@
* @hide
*/
public class MdnsServiceInfo implements Parcelable {
+ private static final Charset US_ASCII = Charset.forName("us-ascii");
+ private static final Charset UTF_8 = Charset.forName("utf-8");
/** @hide */
public static final Parcelable.Creator<MdnsServiceInfo> CREATOR =
@@ -49,7 +56,9 @@
source.readInt(),
source.readString(),
source.readString(),
- source.createStringArrayList());
+ source.createStringArrayList(),
+ source.createTypedArrayList(TextEntry.CREATOR),
+ source.readInt());
}
@Override
@@ -65,8 +74,59 @@
private final int port;
private final String ipv4Address;
private final String ipv6Address;
- private final Map<String, String> attributes = new HashMap<>();
- List<String> textStrings;
+ final List<String> textStrings;
+ @Nullable
+ final List<TextEntry> textEntries;
+ private final int interfaceIndex;
+
+ private final Map<String, byte[]> attributes;
+
+ /** Constructs a {@link MdnsServiceInfo} object with default values. */
+ public MdnsServiceInfo(
+ String serviceInstanceName,
+ String[] serviceType,
+ List<String> subtypes,
+ String[] hostName,
+ int port,
+ String ipv4Address,
+ String ipv6Address,
+ List<String> textStrings) {
+ this(
+ serviceInstanceName,
+ serviceType,
+ subtypes,
+ hostName,
+ port,
+ ipv4Address,
+ ipv6Address,
+ textStrings,
+ /* textEntries= */ null,
+ /* interfaceIndex= */ -1);
+ }
+
+ /** Constructs a {@link MdnsServiceInfo} object with default values. */
+ public MdnsServiceInfo(
+ String serviceInstanceName,
+ String[] serviceType,
+ List<String> subtypes,
+ String[] hostName,
+ int port,
+ String ipv4Address,
+ String ipv6Address,
+ List<String> textStrings,
+ @Nullable List<TextEntry> textEntries) {
+ this(
+ serviceInstanceName,
+ serviceType,
+ subtypes,
+ hostName,
+ port,
+ ipv4Address,
+ ipv6Address,
+ textStrings,
+ textEntries,
+ /* interfaceIndex= */ -1);
+ }
/**
* Constructs a {@link MdnsServiceInfo} object with default values.
@@ -81,7 +141,9 @@
int port,
String ipv4Address,
String ipv6Address,
- List<String> textStrings) {
+ List<String> textStrings,
+ @Nullable List<TextEntry> textEntries,
+ int interfaceIndex) {
this.serviceInstanceName = serviceInstanceName;
this.serviceType = serviceType;
this.subtypes = new ArrayList<>();
@@ -92,16 +154,41 @@
this.port = port;
this.ipv4Address = ipv4Address;
this.ipv6Address = ipv6Address;
+ this.textStrings = new ArrayList<>();
if (textStrings != null) {
- for (String text : textStrings) {
- int pos = text.indexOf('=');
- if (pos < 1) {
- continue;
- }
- attributes.put(text.substring(0, pos).toLowerCase(Locale.ENGLISH),
- text.substring(++pos));
+ this.textStrings.addAll(textStrings);
+ }
+ this.textEntries = (textEntries == null) ? null : new ArrayList<>(textEntries);
+
+ // The module side sends both {@code textStrings} and {@code textEntries} for backward
+ // compatibility. We should prefer only {@code textEntries} if it's not null.
+ List<TextEntry> entries =
+ (this.textEntries != null) ? this.textEntries : parseTextStrings(this.textStrings);
+ Map<String, byte[]> attributes = new HashMap<>(entries.size());
+ for (TextEntry entry : entries) {
+ String key = entry.getKey().toLowerCase(Locale.ENGLISH);
+
+ // Per https://datatracker.ietf.org/doc/html/rfc6763#section-6.4, only the first entry
+ // of the same key should be accepted:
+ // If a client receives a TXT record containing the same key more than once, then the
+ // client MUST silently ignore all but the first occurrence of that attribute.
+ if (!attributes.containsKey(key)) {
+ attributes.put(key, entry.getValue());
}
}
+ this.attributes = Collections.unmodifiableMap(attributes);
+ this.interfaceIndex = interfaceIndex;
+ }
+
+ private static List<TextEntry> parseTextStrings(List<String> textStrings) {
+ List<TextEntry> list = new ArrayList(textStrings.size());
+ for (String textString : textStrings) {
+ TextEntry entry = TextEntry.fromString(textString);
+ if (entry != null) {
+ list.add(entry);
+ }
+ }
+ return Collections.unmodifiableList(list);
}
/** @return the name of this service instance. */
@@ -148,16 +235,43 @@
}
/**
- * @return the attribute value for {@code key}.
- * @return {@code null} if no attribute value exists for {@code key}.
+ * Returns the index of the network interface at which this response was received, or -1 if the
+ * index is not known.
*/
+ public int getInterfaceIndex() {
+ return interfaceIndex;
+ }
+
+ /**
+ * Returns attribute value for {@code key} as a UTF-8 string. It's the caller who must make sure
+ * that the value of {@code key} is indeed a UTF-8 string. {@code null} will be returned if no
+ * attribute value exists for {@code key}.
+ */
+ @Nullable
public String getAttributeByKey(@NonNull String key) {
+ byte[] value = getAttributeAsBytes(key);
+ if (value == null) {
+ return null;
+ }
+ return new String(value, UTF_8);
+ }
+
+ /**
+ * Returns the attribute value for {@code key} as a byte array. {@code null} will be returned if
+ * no attribute value exists for {@code key}.
+ */
+ @Nullable
+ public byte[] getAttributeAsBytes(@NonNull String key) {
return attributes.get(key.toLowerCase(Locale.ENGLISH));
}
/** @return an immutable map of all attributes. */
public Map<String, String> getAttributes() {
- return Collections.unmodifiableMap(attributes);
+ Map<String, String> map = new HashMap<>(attributes.size());
+ for (Map.Entry<String, byte[]> kv : attributes.entrySet()) {
+ map.put(kv.getKey(), new String(kv.getValue(), UTF_8));
+ }
+ return Collections.unmodifiableMap(map);
}
@Override
@@ -167,14 +281,6 @@
@Override
public void writeToParcel(Parcel out, int flags) {
- if (textStrings == null) {
- // Lazily initialize the parcelable field mTextStrings.
- textStrings = new ArrayList<>(attributes.size());
- for (Map.Entry<String, String> kv : attributes.entrySet()) {
- textStrings.add(String.format(Locale.ROOT, "%s=%s", kv.getKey(), kv.getValue()));
- }
- }
-
out.writeString(serviceInstanceName);
out.writeStringArray(serviceType);
out.writeStringList(subtypes);
@@ -183,6 +289,8 @@
out.writeString(ipv4Address);
out.writeString(ipv6Address);
out.writeStringList(textStrings);
+ out.writeTypedList(textEntries);
+ out.writeInt(interfaceIndex);
}
@Override
@@ -195,4 +303,114 @@
ipv4Address,
port);
}
+
+
+ /** Represents a DNS TXT key-value pair defined by RFC 6763. */
+ public static final class TextEntry implements Parcelable {
+ public static final Parcelable.Creator<TextEntry> CREATOR =
+ new Parcelable.Creator<TextEntry>() {
+ @Override
+ public TextEntry createFromParcel(Parcel source) {
+ return new TextEntry(source);
+ }
+
+ @Override
+ public TextEntry[] newArray(int size) {
+ return new TextEntry[size];
+ }
+ };
+
+ private final String key;
+ private final byte[] value;
+
+ /** Creates a new {@link TextEntry} instance from a '=' separated string. */
+ @Nullable
+ public static TextEntry fromString(String textString) {
+ return fromBytes(textString.getBytes(UTF_8));
+ }
+
+ /** Creates a new {@link TextEntry} instance from a '=' separated byte array. */
+ @Nullable
+ public static TextEntry fromBytes(byte[] textBytes) {
+ int delimitPos = ByteUtils.indexOf(textBytes, (byte) '=');
+
+ // Per https://datatracker.ietf.org/doc/html/rfc6763#section-6.4:
+ // 1. The key MUST be at least one character. DNS-SD TXT record strings
+ // beginning with an '=' character (i.e., the key is missing) MUST be
+ // silently ignored.
+ // 2. If there is no '=' in a DNS-SD TXT record string, then it is a
+ // boolean attribute, simply identified as being present, with no value.
+ if (delimitPos < 0) {
+ return new TextEntry(new String(textBytes, US_ASCII), "");
+ } else if (delimitPos == 0) {
+ return null;
+ }
+ return new TextEntry(
+ new String(Arrays.copyOf(textBytes, delimitPos), US_ASCII),
+ Arrays.copyOfRange(textBytes, delimitPos + 1, textBytes.length));
+ }
+
+ /** Creates a new {@link TextEntry} with given key and value of a UTF-8 string. */
+ public TextEntry(String key, String value) {
+ this(key, value.getBytes(UTF_8));
+ }
+
+ /** Creates a new {@link TextEntry} with given key and value of a byte array. */
+ public TextEntry(String key, byte[] value) {
+ this.key = key;
+ this.value = value.clone();
+ }
+
+ private TextEntry(Parcel in) {
+ key = in.readString();
+ value = in.createByteArray();
+ }
+
+ public String getKey() {
+ return key;
+ }
+
+ public byte[] getValue() {
+ return value.clone();
+ }
+
+ /** Converts this {@link TextEntry} instance to '=' separated byte array. */
+ public byte[] toBytes() {
+ return ByteUtils.concat(key.getBytes(US_ASCII), new byte[]{'='}, value);
+ }
+
+ /** Converts this {@link TextEntry} instance to '=' separated string. */
+ @Override
+ public String toString() {
+ return key + "=" + new String(value, UTF_8);
+ }
+
+ @Override
+ public boolean equals(@Nullable Object other) {
+ if (this == other) {
+ return true;
+ } else if (!(other instanceof TextEntry)) {
+ return false;
+ }
+ TextEntry otherEntry = (TextEntry) other;
+
+ return key.equals(otherEntry.key) && Arrays.equals(value, otherEntry.value);
+ }
+
+ @Override
+ public int hashCode() {
+ return 31 * key.hashCode() + Arrays.hashCode(value);
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeString(key);
+ out.writeByteArray(value);
+ }
+ }
}
\ No newline at end of file
diff --git a/service/mdns/com/android/server/connectivity/mdns/MdnsServiceTypeClient.java b/service/mdns/com/android/server/connectivity/mdns/MdnsServiceTypeClient.java
index e335de9..be993e2 100644
--- a/service/mdns/com/android/server/connectivity/mdns/MdnsServiceTypeClient.java
+++ b/service/mdns/com/android/server/connectivity/mdns/MdnsServiceTypeClient.java
@@ -16,7 +16,11 @@
package com.android.server.connectivity.mdns;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+
import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.SystemClock;
import android.text.TextUtils;
import android.util.ArraySet;
import android.util.Pair;
@@ -28,12 +32,12 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
/**
* Instance of this class sends and receives mDNS packets of a given service type and invoke
@@ -53,6 +57,12 @@
private final Object lock = new Object();
private final Set<MdnsServiceBrowserListener> listeners = new ArraySet<>();
private final Map<String, MdnsResponse> instanceNameToResponse = new HashMap<>();
+ private final boolean removeServiceAfterTtlExpires =
+ MdnsConfigs.removeServiceAfterTtlExpires();
+ private final boolean allowSearchOptionsToRemoveExpiredService =
+ MdnsConfigs.allowSearchOptionsToRemoveExpiredService();
+
+ @Nullable private MdnsSearchOptions searchOptions;
// The session ID increases when startSendAndReceive() is called where we schedule a
// QueryTask for
@@ -100,7 +110,9 @@
port,
ipv4Address,
ipv6Address,
- response.getTextRecord().getStrings());
+ response.getTextRecord().getStrings(),
+ response.getTextRecord().getEntries(),
+ response.getInterfaceIndex());
}
/**
@@ -115,6 +127,7 @@
@NonNull MdnsServiceBrowserListener listener,
@NonNull MdnsSearchOptions searchOptions) {
synchronized (lock) {
+ this.searchOptions = searchOptions;
if (!listeners.contains(listener)) {
listeners.add(listener);
for (MdnsResponse existingResponse : instanceNameToResponse.values()) {
@@ -164,10 +177,23 @@
}
public synchronized void processResponse(@NonNull MdnsResponse response) {
- if (response.isGoodbye()) {
- onGoodbyeReceived(response.getServiceInstanceName());
+ if (shouldRemoveServiceAfterTtlExpires()) {
+ // Because {@link QueryTask} and {@link processResponse} are running in different
+ // threads. We need to synchronize {@link lock} to protect
+ // {@link instanceNameToResponse} won’t be modified at the same time.
+ synchronized (lock) {
+ if (response.isGoodbye()) {
+ onGoodbyeReceived(response.getServiceInstanceName());
+ } else {
+ onResponseReceived(response);
+ }
+ }
} else {
- onResponseReceived(response);
+ if (response.isGoodbye()) {
+ onGoodbyeReceived(response.getServiceInstanceName());
+ } else {
+ onResponseReceived(response);
+ }
}
}
@@ -212,6 +238,15 @@
}
}
+ private boolean shouldRemoveServiceAfterTtlExpires() {
+ if (removeServiceAfterTtlExpires) {
+ return true;
+ }
+ return allowSearchOptionsToRemoveExpiredService
+ && searchOptions != null
+ && searchOptions.removeExpiredService();
+ }
+
@VisibleForTesting
MdnsPacketWriter createMdnsPacketWriter() {
return new MdnsPacketWriter(DEFAULT_MTU);
@@ -359,11 +394,27 @@
listener.onDiscoveryQuerySent(result.second, result.first);
}
}
+ if (shouldRemoveServiceAfterTtlExpires()) {
+ Iterator<MdnsResponse> iter = instanceNameToResponse.values().iterator();
+ while (iter.hasNext()) {
+ MdnsResponse existingResponse = iter.next();
+ if (existingResponse.isComplete()
+ && existingResponse
+ .getServiceRecord()
+ .getRemainingTTL(SystemClock.elapsedRealtime())
+ == 0) {
+ iter.remove();
+ for (MdnsServiceBrowserListener listener : listeners) {
+ listener.onServiceRemoved(
+ existingResponse.getServiceInstanceName());
+ }
+ }
+ }
+ }
QueryTaskConfig config = this.config.getConfigForNextRun();
requestTaskFuture =
executor.schedule(
- new QueryTask(config), config.timeToRunNextTaskInMs,
- TimeUnit.MILLISECONDS);
+ new QueryTask(config), config.timeToRunNextTaskInMs, MILLISECONDS);
}
}
}
diff --git a/service/mdns/com/android/server/connectivity/mdns/MdnsSocket.java b/service/mdns/com/android/server/connectivity/mdns/MdnsSocket.java
index 34db7f0..3442430 100644
--- a/service/mdns/com/android/server/connectivity/mdns/MdnsSocket.java
+++ b/service/mdns/com/android/server/connectivity/mdns/MdnsSocket.java
@@ -19,11 +19,13 @@
import android.annotation.NonNull;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.connectivity.mdns.util.MdnsLogger;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetSocketAddress;
import java.net.MulticastSocket;
+import java.net.SocketException;
import java.util.List;
/**
@@ -35,6 +37,9 @@
// TODO(b/242631897): Resolve nullness suppression.
@SuppressWarnings("nullness")
public class MdnsSocket {
+ private static final MdnsLogger LOGGER = new MdnsLogger("MdnsSocket");
+
+ static final int INTERFACE_INDEX_UNSPECIFIED = -1;
private static final InetSocketAddress MULTICAST_IPV4_ADDRESS =
new InetSocketAddress(MdnsConstants.getMdnsIPv4Address(), MdnsConstants.MDNS_PORT);
private static final InetSocketAddress MULTICAST_IPV6_ADDRESS =
@@ -103,6 +108,19 @@
multicastNetworkInterfaceProvider.stopWatchingConnectivityChanges();
}
+ /**
+ * Returns the index of the network interface that this socket is bound to. If the interface
+ * cannot be determined, returns -1.
+ */
+ public int getInterfaceIndex() {
+ try {
+ return multicastSocket.getNetworkInterface().getIndex();
+ } catch (SocketException e) {
+ LOGGER.e("Failed to retrieve interface index for socket.", e);
+ return -1;
+ }
+ }
+
@VisibleForTesting
MulticastSocket createMulticastSocket(int port) throws IOException {
return new MulticastSocket(port);
diff --git a/service/mdns/com/android/server/connectivity/mdns/MdnsSocketClient.java b/service/mdns/com/android/server/connectivity/mdns/MdnsSocketClient.java
index 010f761..6cbe3c7 100644
--- a/service/mdns/com/android/server/connectivity/mdns/MdnsSocketClient.java
+++ b/service/mdns/com/android/server/connectivity/mdns/MdnsSocketClient.java
@@ -79,6 +79,8 @@
private final boolean checkMulticastResponse = MdnsConfigs.checkMulticastResponse();
private final long checkMulticastResponseIntervalMs =
MdnsConfigs.checkMulticastResponseIntervalMs();
+ private final boolean propagateInterfaceIndex =
+ MdnsConfigs.allowNetworkInterfaceIndexPropagation();
private final Object socketLock = new Object();
private final Object timerObject = new Object();
// If multicast response was received in the current session. The value is reset in the
@@ -382,7 +384,12 @@
if (!shouldStopSocketLoop) {
String responseType = socket == multicastSocket ? MULTICAST_TYPE : UNICAST_TYPE;
- processResponsePacket(packet, responseType);
+ processResponsePacket(
+ packet,
+ responseType,
+ /* interfaceIndex= */ (socket == null || !propagateInterfaceIndex)
+ ? MdnsSocket.INTERFACE_INDEX_UNSPECIFIED
+ : socket.getInterfaceIndex());
}
} catch (IOException e) {
if (!shouldStopSocketLoop) {
@@ -393,12 +400,12 @@
LOGGER.log("Receive thread stopped.");
}
- private int processResponsePacket(@NonNull DatagramPacket packet, String responseType)
- throws IOException {
+ private int processResponsePacket(
+ @NonNull DatagramPacket packet, String responseType, int interfaceIndex) {
int packetNumber = ++receivedPacketNumber;
List<MdnsResponse> responses = new LinkedList<>();
- int errorCode = responseDecoder.decode(packet, responses);
+ int errorCode = responseDecoder.decode(packet, responses, interfaceIndex);
if (errorCode == MdnsResponseDecoder.SUCCESS) {
if (responseType.equals(MULTICAST_TYPE)) {
receivedMulticastResponse = true;
@@ -414,7 +421,8 @@
}
for (MdnsResponse response : responses) {
String serviceInstanceName = response.getServiceInstanceName();
- LOGGER.log("mDNS %s response received: %s", responseType, serviceInstanceName);
+ LOGGER.log("mDNS %s response received: %s at ifIndex %d", responseType,
+ serviceInstanceName, interfaceIndex);
if (callback != null) {
callback.onResponseReceived(response);
}
diff --git a/service/mdns/com/android/server/connectivity/mdns/MdnsTextRecord.java b/service/mdns/com/android/server/connectivity/mdns/MdnsTextRecord.java
index a364560..73ecdfa 100644
--- a/service/mdns/com/android/server/connectivity/mdns/MdnsTextRecord.java
+++ b/service/mdns/com/android/server/connectivity/mdns/MdnsTextRecord.java
@@ -17,6 +17,7 @@
package com.android.server.connectivity.mdns;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.connectivity.mdns.MdnsServiceInfo.TextEntry;
import java.io.IOException;
import java.util.ArrayList;
@@ -24,12 +25,12 @@
import java.util.List;
import java.util.Objects;
-/** An mDNS "TXT" record, which contains a list of text strings. */
+/** An mDNS "TXT" record, which contains a list of {@link TextEntry}. */
// TODO(b/242631897): Resolve nullness suppression.
@SuppressWarnings("nullness")
@VisibleForTesting
public class MdnsTextRecord extends MdnsRecord {
- private List<String> strings;
+ private List<TextEntry> entries;
public MdnsTextRecord(String[] name, MdnsPacketReader reader) throws IOException {
super(name, TYPE_TXT, reader);
@@ -37,22 +38,34 @@
/** Returns the list of strings. */
public List<String> getStrings() {
- return Collections.unmodifiableList(strings);
+ final List<String> list = new ArrayList<>(entries.size());
+ for (TextEntry entry : entries) {
+ list.add(entry.toString());
+ }
+ return Collections.unmodifiableList(list);
+ }
+
+ /** Returns the list of TXT key-value pairs. */
+ public List<TextEntry> getEntries() {
+ return Collections.unmodifiableList(entries);
}
@Override
protected void readData(MdnsPacketReader reader) throws IOException {
- strings = new ArrayList<>();
+ entries = new ArrayList<>();
while (reader.getRemaining() > 0) {
- strings.add(reader.readString());
+ TextEntry entry = reader.readTextEntry();
+ if (entry != null) {
+ entries.add(entry);
+ }
}
}
@Override
protected void writeData(MdnsPacketWriter writer) throws IOException {
- if (strings != null) {
- for (String string : strings) {
- writer.writeString(string);
+ if (entries != null) {
+ for (TextEntry entry : entries) {
+ writer.writeTextEntry(entry);
}
}
}
@@ -61,9 +74,9 @@
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("TXT: {");
- if (strings != null) {
- for (String string : strings) {
- sb.append(' ').append(string);
+ if (entries != null) {
+ for (TextEntry entry : entries) {
+ sb.append(' ').append(entry);
}
}
sb.append("}");
@@ -73,7 +86,7 @@
@Override
public int hashCode() {
- return (super.hashCode() * 31) + Objects.hash(strings);
+ return (super.hashCode() * 31) + Objects.hash(entries);
}
@Override
@@ -85,6 +98,6 @@
return false;
}
- return super.equals(other) && Objects.equals(strings, ((MdnsTextRecord) other).strings);
+ return super.equals(other) && Objects.equals(entries, ((MdnsTextRecord) other).entries);
}
}
\ No newline at end of file
diff --git a/service/native/TrafficController.cpp b/service/native/TrafficController.cpp
index a26d1e6..8f6df21 100644
--- a/service/native/TrafficController.cpp
+++ b/service/native/TrafficController.cpp
@@ -181,9 +181,13 @@
return netdutils::status::ok;
}
-Status TrafficController::start() {
+Status TrafficController::start(bool startSkDestroyListener) {
RETURN_IF_NOT_OK(initMaps());
+ if (!startSkDestroyListener) {
+ return netdutils::status::ok;
+ }
+
auto result = makeSkDestroyListener();
if (!isOk(result)) {
ALOGE("Unable to create SkDestroyListener: %s", toString(result).c_str());
@@ -591,7 +595,7 @@
}
}
-void TrafficController::dump(int fd, bool verbose) {
+void TrafficController::dump(int fd, bool verbose __unused) {
std::lock_guard guard(mMutex);
DumpWriter dw(fd);
@@ -619,157 +623,6 @@
getMapStatus(mConfigurationMap.getMap(), CONFIGURATION_MAP_PATH).c_str());
dw.println("mUidOwnerMap status: %s",
getMapStatus(mUidOwnerMap.getMap(), UID_OWNER_MAP_PATH).c_str());
-
- if (!verbose) {
- return;
- }
-
- dw.blankline();
- dw.println("BPF map content:");
-
- ScopedIndent indentForMapContent(dw);
-
- // Print CookieTagMap content.
- // TagSocketTest in CTS was using the output of mCookieTagMap dump.
- // So, mCookieTagMap dump can not be removed until the previous CTS support period is over.
- dumpBpfMap("mCookieTagMap", dw, "");
- const auto printCookieTagInfo = [&dw](const uint64_t& key, const UidTagValue& value,
- const BpfMap<uint64_t, UidTagValue>&) {
- dw.println("cookie=%" PRIu64 " tag=0x%x uid=%u", key, value.tag, value.uid);
- return base::Result<void>();
- };
- base::Result<void> res = mCookieTagMap.iterateWithValue(printCookieTagInfo);
- if (!res.ok()) {
- dw.println("mCookieTagMap print end with error: %s", res.error().message().c_str());
- }
-
-
- // Print uidStatsMap content.
- std::string statsHeader = StringPrintf("ifaceIndex ifaceName tag_hex uid_int cnt_set rxBytes"
- " rxPackets txBytes txPackets");
- dumpBpfMap("mStatsMapA", dw, statsHeader);
- const auto printStatsInfo = [&dw, this](const StatsKey& key, const StatsValue& value,
- const BpfMap<StatsKey, StatsValue>&) {
- uint32_t ifIndex = key.ifaceIndex;
- auto ifname = mIfaceIndexNameMap.readValue(ifIndex);
- if (!ifname.ok()) {
- ifname = IfaceValue{"unknown"};
- }
- dw.println("%u %s 0x%x %u %u %" PRIu64 " %" PRIu64 " %" PRIu64 " %" PRIu64, ifIndex,
- ifname.value().name, key.tag, key.uid, key.counterSet, value.rxBytes,
- value.rxPackets, value.txBytes, value.txPackets);
- return base::Result<void>();
- };
- res = mStatsMapA.iterateWithValue(printStatsInfo);
- if (!res.ok()) {
- dw.println("mStatsMapA print end with error: %s", res.error().message().c_str());
- }
-
- // Print TagStatsMap content.
- dumpBpfMap("mStatsMapB", dw, statsHeader);
- res = mStatsMapB.iterateWithValue(printStatsInfo);
- if (!res.ok()) {
- dw.println("mStatsMapB print end with error: %s", res.error().message().c_str());
- }
-
- // Print ifaceIndexToNameMap content.
- dumpBpfMap("mIfaceIndexNameMap", dw, "");
- const auto printIfaceNameInfo = [&dw](const uint32_t& key, const IfaceValue& value,
- const BpfMap<uint32_t, IfaceValue>&) {
- const char* ifname = value.name;
- dw.println("ifaceIndex=%u ifaceName=%s", key, ifname);
- return base::Result<void>();
- };
- res = mIfaceIndexNameMap.iterateWithValue(printIfaceNameInfo);
- if (!res.ok()) {
- dw.println("mIfaceIndexNameMap print end with error: %s", res.error().message().c_str());
- }
-
- // Print ifaceStatsMap content
- std::string ifaceStatsHeader = StringPrintf("ifaceIndex ifaceName rxBytes rxPackets txBytes"
- " txPackets");
- dumpBpfMap("mIfaceStatsMap:", dw, ifaceStatsHeader);
- const auto printIfaceStatsInfo = [&dw, this](const uint32_t& key, const StatsValue& value,
- const BpfMap<uint32_t, StatsValue>&) {
- auto ifname = mIfaceIndexNameMap.readValue(key);
- if (!ifname.ok()) {
- ifname = IfaceValue{"unknown"};
- }
- dw.println("%u %s %" PRIu64 " %" PRIu64 " %" PRIu64 " %" PRIu64, key, ifname.value().name,
- value.rxBytes, value.rxPackets, value.txBytes, value.txPackets);
- return base::Result<void>();
- };
- res = mIfaceStatsMap.iterateWithValue(printIfaceStatsInfo);
- if (!res.ok()) {
- dw.println("mIfaceStatsMap print end with error: %s", res.error().message().c_str());
- }
-
- dw.blankline();
-
- uint32_t key = UID_RULES_CONFIGURATION_KEY;
- auto configuration = mConfigurationMap.readValue(key);
- if (configuration.ok()) {
- dw.println("current ownerMatch configuration: %d%s", configuration.value(),
- uidMatchTypeToString(configuration.value()).c_str());
- } else {
- dw.println("mConfigurationMap read ownerMatch configure failed with error: %s",
- configuration.error().message().c_str());
- }
-
- key = CURRENT_STATS_MAP_CONFIGURATION_KEY;
- configuration = mConfigurationMap.readValue(key);
- if (configuration.ok()) {
- const char* statsMapDescription = "???";
- switch (configuration.value()) {
- case SELECT_MAP_A:
- statsMapDescription = "SELECT_MAP_A";
- break;
- case SELECT_MAP_B:
- statsMapDescription = "SELECT_MAP_B";
- break;
- // No default clause, so if we ever add a third map, this code will fail to build.
- }
- dw.println("current statsMap configuration: %d %s", configuration.value(),
- statsMapDescription);
- } else {
- dw.println("mConfigurationMap read stats map configure failed with error: %s",
- configuration.error().message().c_str());
- }
- dumpBpfMap("mUidOwnerMap", dw, "");
- const auto printUidMatchInfo = [&dw, this](const uint32_t& key, const UidOwnerValue& value,
- const BpfMap<uint32_t, UidOwnerValue>&) {
- if (value.rule & IIF_MATCH) {
- auto ifname = mIfaceIndexNameMap.readValue(value.iif);
- if (ifname.ok()) {
- dw.println("%u %s %s", key, uidMatchTypeToString(value.rule).c_str(),
- ifname.value().name);
- } else {
- dw.println("%u %s %u", key, uidMatchTypeToString(value.rule).c_str(), value.iif);
- }
- } else {
- dw.println("%u %s", key, uidMatchTypeToString(value.rule).c_str());
- }
- return base::Result<void>();
- };
- res = mUidOwnerMap.iterateWithValue(printUidMatchInfo);
- if (!res.ok()) {
- dw.println("mUidOwnerMap print end with error: %s", res.error().message().c_str());
- }
- dumpBpfMap("mUidPermissionMap", dw, "");
- const auto printUidPermissionInfo = [&dw](const uint32_t& key, const int& value,
- const BpfMap<uint32_t, uint8_t>&) {
- dw.println("%u %s", key, UidPermissionTypeToString(value).c_str());
- return base::Result<void>();
- };
- res = mUidPermissionMap.iterateWithValue(printUidPermissionInfo);
- if (!res.ok()) {
- dw.println("mUidPermissionMap print end with error: %s", res.error().message().c_str());
- }
-
- dumpBpfMap("mPrivilegedUser", dw, "");
- for (uid_t uid : mPrivilegedUser) {
- dw.println("%u ALLOW_UPDATE_DEVICE_STATS", (uint32_t)uid);
- }
}
} // namespace net
diff --git a/service/native/TrafficControllerTest.cpp b/service/native/TrafficControllerTest.cpp
index d08ffee..57f32af 100644
--- a/service/native/TrafficControllerTest.cpp
+++ b/service/native/TrafficControllerTest.cpp
@@ -59,8 +59,6 @@
constexpr uid_t TEST_UID3 = 98765;
constexpr uint32_t TEST_TAG = 42;
constexpr uint32_t TEST_COUNTERSET = 1;
-constexpr int TEST_COOKIE = 1;
-constexpr char TEST_IFNAME[] = "test0";
constexpr int TEST_IFINDEX = 999;
constexpr int RXPACKETS = 1;
constexpr int RXBYTES = 100;
@@ -770,116 +768,6 @@
expectPrivilegedUserSetEmpty();
}
-TEST_F(TrafficControllerTest, TestDumpsys) {
- StatsKey tagStatsMapKey;
- populateFakeStats(TEST_COOKIE, TEST_UID, TEST_TAG, &tagStatsMapKey);
- populateFakeCounterSet(TEST_UID3, TEST_COUNTERSET);
-
- // Expect: (part of this depends on hard-code values in populateFakeStats())
- //
- // mCookieTagMap:
- // cookie=1 tag=0x2a uid=10086
- //
- // mUidCounterSetMap:
- // 98765 1
- //
- // mAppUidStatsMap::
- // uid rxBytes rxPackets txBytes txPackets
- // 10086 100 1 0 0
- //
- // mStatsMapA:
- // ifaceIndex ifaceName tag_hex uid_int cnt_set rxBytes rxPackets txBytes txPackets
- // 999 test0 0x2a 10086 1 100 1 0 0
- std::vector<std::string> expectedLines = {
- "mCookieTagMap:",
- fmt::format("cookie={} tag={:#x} uid={}", TEST_COOKIE, TEST_TAG, TEST_UID),
- "mStatsMapA",
- "ifaceIndex ifaceName tag_hex uid_int cnt_set rxBytes rxPackets txBytes txPackets",
- fmt::format("{} {} {:#x} {} {} {} {} {} {}",
- TEST_IFINDEX, TEST_IFNAME, TEST_TAG, TEST_UID, TEST_COUNTERSET, RXBYTES,
- RXPACKETS, TXBYTES, TXPACKETS)};
-
- populateFakeIfaceIndexName(TEST_IFNAME, TEST_IFINDEX);
- expectedLines.emplace_back("mIfaceIndexNameMap:");
- expectedLines.emplace_back(fmt::format("ifaceIndex={} ifaceName={}",
- TEST_IFINDEX, TEST_IFNAME));
-
- ASSERT_TRUE(isOk(updateUidOwnerMaps({TEST_UID}, HAPPY_BOX_MATCH,
- TrafficController::IptOpInsert)));
- expectedLines.emplace_back("mUidOwnerMap:");
- expectedLines.emplace_back(fmt::format("{} HAPPY_BOX_MATCH", TEST_UID));
-
- mTc.setPermissionForUids(INetd::PERMISSION_UPDATE_DEVICE_STATS, {TEST_UID2});
- expectedLines.emplace_back("mUidPermissionMap:");
- expectedLines.emplace_back(fmt::format("{} BPF_PERMISSION_UPDATE_DEVICE_STATS", TEST_UID2));
- expectedLines.emplace_back("mPrivilegedUser:");
- expectedLines.emplace_back(fmt::format("{} ALLOW_UPDATE_DEVICE_STATS", TEST_UID2));
- EXPECT_TRUE(expectDumpsysContains(expectedLines));
-}
-
-TEST_F(TrafficControllerTest, dumpsysInvalidMaps) {
- makeTrafficControllerMapsInvalid();
-
- const std::string kErrIterate = "print end with error: Get firstKey map -1 failed: "
- "Bad file descriptor";
- const std::string kErrReadRulesConfig = "read ownerMatch configure failed with error: "
- "Read value of map -1 failed: Bad file descriptor";
- const std::string kErrReadStatsMapConfig = "read stats map configure failed with error: "
- "Read value of map -1 failed: Bad file descriptor";
-
- std::vector<std::string> expectedLines = {
- fmt::format("mCookieTagMap {}", kErrIterate),
- fmt::format("mStatsMapA {}", kErrIterate),
- fmt::format("mStatsMapB {}", kErrIterate),
- fmt::format("mIfaceIndexNameMap {}", kErrIterate),
- fmt::format("mIfaceStatsMap {}", kErrIterate),
- fmt::format("mConfigurationMap {}", kErrReadRulesConfig),
- fmt::format("mConfigurationMap {}", kErrReadStatsMapConfig),
- fmt::format("mUidOwnerMap {}", kErrIterate),
- fmt::format("mUidPermissionMap {}", kErrIterate)};
- EXPECT_TRUE(expectDumpsysContains(expectedLines));
-}
-
-TEST_F(TrafficControllerTest, uidMatchTypeToString) {
- // NO_MATCH(0) can't be verified because match type flag is added by OR operator.
- // See TrafficController::addRule()
- static const struct TestConfig {
- UidOwnerMatchType uidOwnerMatchType;
- std::string expected;
- } testConfigs[] = {
- // clang-format off
- {HAPPY_BOX_MATCH, "HAPPY_BOX_MATCH"},
- {DOZABLE_MATCH, "DOZABLE_MATCH"},
- {STANDBY_MATCH, "STANDBY_MATCH"},
- {POWERSAVE_MATCH, "POWERSAVE_MATCH"},
- {HAPPY_BOX_MATCH, "HAPPY_BOX_MATCH"},
- {RESTRICTED_MATCH, "RESTRICTED_MATCH"},
- {LOW_POWER_STANDBY_MATCH, "LOW_POWER_STANDBY_MATCH"},
- {IIF_MATCH, "IIF_MATCH"},
- {LOCKDOWN_VPN_MATCH, "LOCKDOWN_VPN_MATCH"},
- {OEM_DENY_1_MATCH, "OEM_DENY_1_MATCH"},
- {OEM_DENY_2_MATCH, "OEM_DENY_2_MATCH"},
- {OEM_DENY_3_MATCH, "OEM_DENY_3_MATCH"},
- // clang-format on
- };
-
- for (const auto& config : testConfigs) {
- SCOPED_TRACE(fmt::format("testConfig: [{}, {}]", config.uidOwnerMatchType,
- config.expected));
-
- // Test private function uidMatchTypeToString() via dumpsys.
- ASSERT_TRUE(isOk(updateUidOwnerMaps({TEST_UID}, config.uidOwnerMatchType,
- TrafficController::IptOpInsert)));
- std::vector<std::string> expectedLines;
- expectedLines.emplace_back(fmt::format("{} {}", TEST_UID, config.expected));
- EXPECT_TRUE(expectDumpsysContains(expectedLines));
-
- // Clean up the stubs.
- ASSERT_TRUE(isOk(updateUidOwnerMaps({TEST_UID}, config.uidOwnerMatchType,
- TrafficController::IptOpDelete)));
- }
-}
-
TEST_F(TrafficControllerTest, getFirewallType) {
static const struct TestConfig {
ChildChain childChain;
diff --git a/service/native/include/TrafficController.h b/service/native/include/TrafficController.h
index 8512929..b44d795 100644
--- a/service/native/include/TrafficController.h
+++ b/service/native/include/TrafficController.h
@@ -38,7 +38,7 @@
/*
* Initialize the whole controller
*/
- netdutils::Status start();
+ netdutils::Status start(bool startSkDestroyListener);
/*
* Swap the stats map config from current active stats map to the idle one.
diff --git a/service/native/libs/libclat/clatutils.cpp b/service/native/libs/libclat/clatutils.cpp
index 4a125ba..be86612 100644
--- a/service/native/libs/libclat/clatutils.cpp
+++ b/service/native/libs/libclat/clatutils.cpp
@@ -126,10 +126,19 @@
// Picks a random interface ID that is checksum neutral with the IPv4 address and the NAT64 prefix.
int generateIpv6Address(const char* iface, const in_addr v4, const in6_addr& nat64Prefix,
- in6_addr* v6) {
+ in6_addr* v6, uint32_t mark) {
int s = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
if (s == -1) return -errno;
+ // Socket's mark affects routing decisions (network selection)
+ // An fwmark is necessary for clat to bypass the VPN during initialization.
+ if ((mark != MARK_UNSET) && setsockopt(s, SOL_SOCKET, SO_MARK, &mark, sizeof(mark))) {
+ int ret = errno;
+ ALOGE("setsockopt(SOL_SOCKET, SO_MARK) failed: %s", strerror(errno));
+ close(s);
+ return -ret;
+ }
+
if (setsockopt(s, SOL_SOCKET, SO_BINDTODEVICE, iface, strlen(iface) + 1) == -1) {
close(s);
return -errno;
diff --git a/service/native/libs/libclat/clatutils_test.cpp b/service/native/libs/libclat/clatutils_test.cpp
index 8cca1f4..abd4e81 100644
--- a/service/native/libs/libclat/clatutils_test.cpp
+++ b/service/native/libs/libclat/clatutils_test.cpp
@@ -202,7 +202,8 @@
in6_addr v6;
EXPECT_EQ(1, inet_pton(AF_INET6, "::", &v6)); // initialize as zero
- EXPECT_EQ(-ENETUNREACH, generateIpv6Address(tun.name().c_str(), v4, nat64Prefix, &v6));
+ // 0u is MARK_UNSET
+ EXPECT_EQ(-ENETUNREACH, generateIpv6Address(tun.name().c_str(), v4, nat64Prefix, &v6, 0u));
EXPECT_TRUE(IN6_IS_ADDR_ULA(&v6));
tun.destroy();
diff --git a/service/native/libs/libclat/include/libclat/clatutils.h b/service/native/libs/libclat/include/libclat/clatutils.h
index 812c86e..991b193 100644
--- a/service/native/libs/libclat/include/libclat/clatutils.h
+++ b/service/native/libs/libclat/include/libclat/clatutils.h
@@ -24,7 +24,7 @@
in_addr_t selectIpv4Address(const in_addr ip, int16_t prefixlen);
void makeChecksumNeutral(in6_addr* v6, const in_addr v4, const in6_addr& nat64Prefix);
int generateIpv6Address(const char* iface, const in_addr v4, const in6_addr& nat64Prefix,
- in6_addr* v6);
+ in6_addr* v6, uint32_t mark);
int detect_mtu(const struct in6_addr* plat_subnet, uint32_t plat_suffix, uint32_t mark);
int configure_packet_socket(int sock, in6_addr* addr, int ifindex);
diff --git a/service/proguard.flags b/service/proguard.flags
index f546e82..864a28b 100644
--- a/service/proguard.flags
+++ b/service/proguard.flags
@@ -1,15 +1,17 @@
-# Make sure proguard keeps all connectivity classes
-# TODO: instead of keeping everything, consider listing only "entry points"
-# (service loader, JNI registered methods, etc) and letting the optimizer do its job
--keep class android.net.** { *; }
--keep class !com.android.server.nearby.**,com.android.server.** { *; }
-# Prevent proguard from stripping out any nearby-service and fast-pair-lite-protos fields.
--keep class com.android.server.nearby.NearbyService { *; }
+# Keep JNI registered methods
+-keepclasseswithmembers,includedescriptorclasses class * { native <methods>; }
-# The lite proto runtime uses reflection to access fields based on the names in
-# the schema, keep all the fields.
-# This replicates the base proguard rule used by the build by default
-# (proguard_basic_keeps.flags), but needs to be specified here because the
-# com.google.protobuf package is jarjared to use a package prefix.
--keepclassmembers class * extends **.com.google.protobuf.MessageLite { <fields>; }
+# Keep classes extending structured message.
+-keepclassmembers public class * extends **.com.android.net.module.util.Struct {
+ *;
+}
+
+-keepclassmembers class com.android.server.**,android.net.**,com.android.networkstack.** {
+ static final % POLICY_*;
+ static final % NOTIFY_TYPE_*;
+ static final % TRANSPORT_*;
+ static final % CMD_*;
+ static final % EVENT_*;
+}
+
diff --git a/service/src/com/android/metrics/stats.proto b/service/src/com/android/metrics/stats.proto
new file mode 100644
index 0000000..48b8316
--- /dev/null
+++ b/service/src/com/android/metrics/stats.proto
@@ -0,0 +1,286 @@
+/*
+ * 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.
+ */
+
+syntax = "proto2";
+option java_multiple_files = true;
+
+package com.android.metrics;
+
+import "frameworks/proto_logging/stats/enums/stats/connectivity/connectivity_service.proto";
+
+/**
+ * Logs NSD(Network service discovery) client session
+ *
+ * Log from:
+ * packages/modules/Connectivity/service-t/src/com/android/server/NsdService
+ */
+message NetworkNsdReported {
+ // Indicate if the device is using the legacy or the new implementation
+ optional bool is_legacy = 1;
+
+ // It is a random number to represent different clients. Each client is an app on the device.
+ optional int32 client_id = 2;
+
+ // It is a increment_number to represent different transactions.
+ // Each transaction is a request from an app client.
+ optional int32 transaction_id = 3;
+
+ // Indicate the service in resolution is a known service in the discovered services cache
+ optional bool is_known_service = 4;
+
+ // Record each NSD session type
+ optional .android.stats.connectivity.NsdEventType type = 5;
+
+ // The process duration of the event in milli-second
+ optional int64 event_duration_millisec = 6;
+
+ // Record each mdns query result
+ optional .android.stats.connectivity.MdnsQueryResult query_result = 7;
+
+ // Count of services in cache at the end of discovery
+ optional int32 found_service_count = 8;
+
+ // Count of found callback when discovery is stopped
+ optional int32 found_callback_count = 9;
+
+ // Count of lost callback when discovery is stopped
+ optional int32 lost_callback_count = 10;
+
+ // Record query service count before unregistered service
+ optional int32 replied_requests_count = 11;
+}
+
+/**
+ * Logs the number of network count on each list of transports
+ *
+ * Logs from:
+ * packages/modules/Connectivity/service/src/com/android/server/ConnectivityService.java
+ */
+message NetworkCountPerTransports {
+ // the number of network count on each list of transports
+ repeated NetworkCountForTransports network_count_for_transports = 1;
+}
+
+/**
+ * Logs the number of network count and transport type
+ *
+ * Logs from:
+ * packages/modules/Connectivity/service/src/com/android/server/ConnectivityService.java
+ */
+message NetworkCountForTransports {
+ // Transport types of the network
+ optional int32 transport_types = 1;
+
+ // Number of networks for one list of transport types
+ optional int32 network_count = 2;
+}
+
+/**
+ * Logs a list of networks
+ *
+ * Logs from:
+ * packages/modules/Connectivity/service/src/com/android/server/ConnectivityService.java
+ */
+message NetworkList {
+ repeated NetworkDescription network_description = 1;
+}
+
+/**
+ * Logs connection duration in seconds and list of transports
+ *
+ * Logs from:
+ * packages/modules/Connectivity/service/src/com/android/server/ConnectivityService.java
+ */
+message ConnectionDurationForTransports {
+ // Transport types of the network
+ optional int32 transport_types = 1;
+
+ // Time duration that the device stays connected to the network
+ optional int32 duration_sec = 2;
+}
+
+/**
+ * Logs connection duration on each list of transports, in seconds
+ *
+ * Logs from:
+ * packages/modules/Connectivity/service/src/com/android/server/ConnectivityService.java
+ */
+message ConnectionDurationPerTransports {
+ repeated ConnectionDurationForTransports connection_duration_for_transports = 1;
+}
+
+/**
+ * Logs network request count & request type
+ *
+ * Logs from:
+ * packages/modules/Connectivity/service/src/com/android/server/ConnectivityService.java
+ */
+message RequestCountForType {
+ // The type of network request
+ optional .android.stats.connectivity.RequestType request_type = 1;
+
+ // Number of network requests
+ optional int32 request_count = 2;
+}
+
+/**
+ * Logs network request count
+ *
+ * Logs from:
+ * packages/modules/Connectivity/service/src/com/android/server/ConnectivityService.java
+ */
+message NetworkRequestCount {
+ // Network request count for request type
+ repeated RequestCountForType request_count_for_type = 1;
+}
+
+/**
+ * Logs information about a network
+ *
+ * Logs from:
+ * packages/modules/Connectivity/service/src/com/android/server/ConnectivityService.java
+ */
+message NetworkDescription {
+ // The transport types of the network. A network may include multiple transport types.
+ // Each transfer type is represented by a different bit, defined in
+ // packages/modules/Connectivity/framework/src/android/net/NetworkCapabilities.java
+ optional int32 transport_types = 1;
+
+ // Indicates the network is metered, non-metered or temporarily-unmetered
+ optional .android.stats.connectivity.MeteredState metered_state = 2;
+
+ // Indicates the network is validated, non-validated, partial or portal
+ optional .android.stats.connectivity.ValidatedState validated_state = 3;
+
+ // Record the bitmask of all the policies applied to this score of network.
+ // Each policy is represented by a different bit, defined in
+ // packages/modules/Connectivity/service/src/com/android/server/connectivity/FullScore.java
+ optional int64 score_policies = 4;
+
+ // The capabilities of the network. A network may include multiple network capabilities.
+ // Each capability is represented by a different bit, defined in
+ // packages/modules/Connectivity/framework/src/android/net/NetworkCapabilities.java
+ optional int64 capabilities = 5;
+
+ // Bitfield representing the network's enterprise capability identifier, defined in
+ // packages/modules/Connectivity/framework/src/android/net/NetworkCapabilities.java
+ optional int32 enterprise_id = 6;
+}
+
+/**
+ * Pulls a list of NumberOfRematchesPerReason.
+ *
+ * Pulled from:
+ * packages/modules/Connectivity/service/src/com/android/server/ConnectivityService.java
+ */
+message NumberOfRematchesPerReason {
+ // Number of network rematches for each rematch reason
+ repeated NumberOfRematchesForReason number_of_rematches_per_reason= 1;
+}
+
+/**
+ * Logs number of network rematches for rematch reason
+ *
+ * Logs from:
+ * packages/modules/Connectivity/service/src/com/android/server/ConnectivityService.java
+ */
+message NumberOfRematchesForReason {
+ // The reason of network rematch
+ optional .android.stats.connectivity.RematchReason rematch_reason = 1;
+
+ // Number of network rematches
+ optional int32 rematch_count = 2;
+};
+
+/**
+ * Pulls information for connectivity stats.
+ *
+ * Pulled from:
+ * packages/modules/Connectivity/service/src/com/android/server/ConnectivityService.java
+ */
+message ConnectivityStateSample {
+ // Number of networks per list of transports
+ optional NetworkCountPerTransports network_count_per_transports = 1;
+
+ // This is a list of networks with their transports and the duration
+ optional ConnectionDurationPerTransports connection_duration_per_transports = 2;
+
+ // Number of requests per category
+ optional NetworkRequestCount network_request_count = 3;
+
+ // Full list of network details (slice by transport / meteredness / internet+validated)
+ optional NetworkList networks = 4;
+}
+
+
+/**
+ * Pulls information for network selection rematch info.
+ *
+ * Pulled from:
+ * packages/modules/Connectivity/service/src/com/android/server/ConnectivityService.java
+ */
+message NetworkSelectionRematchReasonsInfo {
+ // Number of rematch per rematch reason
+ optional NumberOfRematchesPerReason number_of_rematches_per_reason = 1;
+}
+
+/**
+ * Logs rematch information for the default network
+ *
+ * Logs from:
+ * packages/modules/Connectivity/service/src/com/android/server/ConnectivityService.java
+ */
+message DefaultNetworkRematchInfo {
+ // The session id comes from each reboot, this is used to correlate the statistics of the
+ // networkselect on the same boot
+ optional int64 session_id = 1;
+
+ // The information of old device default network
+ optional NetworkDescription old_network = 2;
+
+ // The information of new device default network
+ optional NetworkDescription new_network = 3;
+
+ // The reason of network rematch
+ optional .android.stats.connectivity.RematchReason rematch_reason = 4;
+
+ // The time duration the device kept the old network as the default in seconds
+ optional int32 time_duration_on_old_network_sec = 5;
+}
+
+/**
+ * Logs network selection performance
+ *
+ * Logs from:
+ * packages/modules/Connectivity/service/src/com/android/server/ConnectivityService.java
+ */
+message NetworkSelectionPerformance {
+ // Number of network requests
+ optional int32 number_of_network_requests = 1;
+
+ // List of networks right now
+ // (slice by transport / meteredness / internet+validated)
+ optional NetworkList networks = 2;
+
+ // The latency of selection computed in milli-second
+ optional int32 selection_computed_latency_milli = 3;
+
+ // The latency of selection applied in milli-second
+ optional int32 selection_applied_latency_milli = 4;
+
+ // The latency of selection issued in milli-second
+ optional int32 selection_issued_latency_milli = 5;
+}
diff --git a/service/src/com/android/server/BpfNetMaps.java b/service/src/com/android/server/BpfNetMaps.java
index 7387483..aea2103 100644
--- a/service/src/com/android/server/BpfNetMaps.java
+++ b/service/src/com/android/server/BpfNetMaps.java
@@ -27,12 +27,17 @@
import static android.net.ConnectivityManager.FIREWALL_RULE_ALLOW;
import static android.net.ConnectivityManager.FIREWALL_RULE_DENY;
import static android.net.INetd.PERMISSION_INTERNET;
+import static android.net.INetd.PERMISSION_NONE;
import static android.net.INetd.PERMISSION_UNINSTALLED;
+import static android.net.INetd.PERMISSION_UPDATE_DEVICE_STATS;
import static android.system.OsConstants.EINVAL;
import static android.system.OsConstants.ENODEV;
import static android.system.OsConstants.ENOENT;
import static android.system.OsConstants.EOPNOTSUPP;
+import static com.android.server.ConnectivityStatsLog.NETWORK_BPF_MAP_INFO;
+
+import android.app.StatsManager;
import android.content.Context;
import android.net.INetd;
import android.os.RemoteException;
@@ -40,21 +45,32 @@
import android.provider.DeviceConfig;
import android.system.ErrnoException;
import android.system.Os;
+import android.util.ArraySet;
+import android.util.IndentingPrintWriter;
import android.util.Log;
+import android.util.Pair;
+import android.util.StatsEvent;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.modules.utils.BackgroundThread;
import com.android.modules.utils.build.SdkLevel;
+import com.android.net.module.util.BpfDump;
import com.android.net.module.util.BpfMap;
import com.android.net.module.util.DeviceConfigUtils;
+import com.android.net.module.util.IBpfMap;
+import com.android.net.module.util.Struct;
+import com.android.net.module.util.Struct.S32;
import com.android.net.module.util.Struct.U32;
import com.android.net.module.util.Struct.U8;
+import com.android.net.module.util.bpf.CookieTagMapKey;
+import com.android.net.module.util.bpf.CookieTagMapValue;
import java.io.FileDescriptor;
import java.io.IOException;
import java.util.Arrays;
-import java.util.HashSet;
+import java.util.List;
import java.util.Set;
-import java.util.stream.Collectors;
+import java.util.StringJoiner;
/**
* BpfNetMaps is responsible for providing traffic controller relevant functionality.
@@ -95,16 +111,19 @@
"/sys/fs/bpf/netd_shared/map_netd_uid_owner_map";
private static final String UID_PERMISSION_MAP_PATH =
"/sys/fs/bpf/netd_shared/map_netd_uid_permission_map";
- private static final U32 UID_RULES_CONFIGURATION_KEY = new U32(0);
- private static final U32 CURRENT_STATS_MAP_CONFIGURATION_KEY = new U32(1);
+ private static final String COOKIE_TAG_MAP_PATH =
+ "/sys/fs/bpf/netd_shared/map_netd_cookie_tag_map";
+ private static final S32 UID_RULES_CONFIGURATION_KEY = new S32(0);
+ private static final S32 CURRENT_STATS_MAP_CONFIGURATION_KEY = new S32(1);
private static final long UID_RULES_DEFAULT_CONFIGURATION = 0;
private static final long STATS_SELECT_MAP_A = 0;
private static final long STATS_SELECT_MAP_B = 1;
- private static BpfMap<U32, U32> sConfigurationMap = null;
+ private static IBpfMap<S32, U32> sConfigurationMap = null;
// BpfMap for UID_OWNER_MAP_PATH. This map is not accessed by others.
- private static BpfMap<U32, UidOwnerValue> sUidOwnerMap = null;
- private static BpfMap<U32, U8> sUidPermissionMap = null;
+ private static IBpfMap<S32, UidOwnerValue> sUidOwnerMap = null;
+ private static IBpfMap<S32, U8> sUidPermissionMap = null;
+ private static IBpfMap<CookieTagMapKey, CookieTagMapValue> sCookieTagMap = null;
// LINT.IfChange(match_type)
@VisibleForTesting public static final long NO_MATCH = 0;
@@ -122,6 +141,25 @@
@VisibleForTesting public static final long OEM_DENY_3_MATCH = (1 << 11);
// LINT.ThenChange(packages/modules/Connectivity/bpf_progs/bpf_shared.h)
+ private static final List<Pair<Integer, String>> PERMISSION_LIST = Arrays.asList(
+ Pair.create(PERMISSION_INTERNET, "PERMISSION_INTERNET"),
+ Pair.create(PERMISSION_UPDATE_DEVICE_STATS, "PERMISSION_UPDATE_DEVICE_STATS")
+ );
+ private static final List<Pair<Long, String>> MATCH_LIST = Arrays.asList(
+ Pair.create(HAPPY_BOX_MATCH, "HAPPY_BOX_MATCH"),
+ Pair.create(PENALTY_BOX_MATCH, "PENALTY_BOX_MATCH"),
+ Pair.create(DOZABLE_MATCH, "DOZABLE_MATCH"),
+ Pair.create(STANDBY_MATCH, "STANDBY_MATCH"),
+ Pair.create(POWERSAVE_MATCH, "POWERSAVE_MATCH"),
+ Pair.create(RESTRICTED_MATCH, "RESTRICTED_MATCH"),
+ Pair.create(LOW_POWER_STANDBY_MATCH, "LOW_POWER_STANDBY_MATCH"),
+ Pair.create(IIF_MATCH, "IIF_MATCH"),
+ Pair.create(LOCKDOWN_VPN_MATCH, "LOCKDOWN_VPN_MATCH"),
+ Pair.create(OEM_DENY_1_MATCH, "OEM_DENY_1_MATCH"),
+ Pair.create(OEM_DENY_2_MATCH, "OEM_DENY_2_MATCH"),
+ Pair.create(OEM_DENY_3_MATCH, "OEM_DENY_3_MATCH")
+ );
+
/**
* Set sEnableJavaBpfMap for test.
*/
@@ -134,7 +172,7 @@
* Set configurationMap for test.
*/
@VisibleForTesting
- public static void setConfigurationMapForTest(BpfMap<U32, U32> configurationMap) {
+ public static void setConfigurationMapForTest(IBpfMap<S32, U32> configurationMap) {
sConfigurationMap = configurationMap;
}
@@ -142,7 +180,7 @@
* Set uidOwnerMap for test.
*/
@VisibleForTesting
- public static void setUidOwnerMapForTest(BpfMap<U32, UidOwnerValue> uidOwnerMap) {
+ public static void setUidOwnerMapForTest(IBpfMap<S32, UidOwnerValue> uidOwnerMap) {
sUidOwnerMap = uidOwnerMap;
}
@@ -150,37 +188,55 @@
* Set uidPermissionMap for test.
*/
@VisibleForTesting
- public static void setUidPermissionMapForTest(BpfMap<U32, U8> uidPermissionMap) {
+ public static void setUidPermissionMapForTest(IBpfMap<S32, U8> uidPermissionMap) {
sUidPermissionMap = uidPermissionMap;
}
- private static BpfMap<U32, U32> getConfigurationMap() {
+ /**
+ * Set cookieTagMap for test.
+ */
+ @VisibleForTesting
+ public static void setCookieTagMapForTest(
+ IBpfMap<CookieTagMapKey, CookieTagMapValue> cookieTagMap) {
+ sCookieTagMap = cookieTagMap;
+ }
+
+ private static IBpfMap<S32, U32> getConfigurationMap() {
try {
return new BpfMap<>(
- CONFIGURATION_MAP_PATH, BpfMap.BPF_F_RDWR, U32.class, U32.class);
+ CONFIGURATION_MAP_PATH, BpfMap.BPF_F_RDWR, S32.class, U32.class);
} catch (ErrnoException e) {
throw new IllegalStateException("Cannot open netd configuration map", e);
}
}
- private static BpfMap<U32, UidOwnerValue> getUidOwnerMap() {
+ private static IBpfMap<S32, UidOwnerValue> getUidOwnerMap() {
try {
return new BpfMap<>(
- UID_OWNER_MAP_PATH, BpfMap.BPF_F_RDWR, U32.class, UidOwnerValue.class);
+ UID_OWNER_MAP_PATH, BpfMap.BPF_F_RDWR, S32.class, UidOwnerValue.class);
} catch (ErrnoException e) {
throw new IllegalStateException("Cannot open uid owner map", e);
}
}
- private static BpfMap<U32, U8> getUidPermissionMap() {
+ private static IBpfMap<S32, U8> getUidPermissionMap() {
try {
return new BpfMap<>(
- UID_PERMISSION_MAP_PATH, BpfMap.BPF_F_RDWR, U32.class, U8.class);
+ UID_PERMISSION_MAP_PATH, BpfMap.BPF_F_RDWR, S32.class, U8.class);
} catch (ErrnoException e) {
throw new IllegalStateException("Cannot open uid permission map", e);
}
}
+ private static IBpfMap<CookieTagMapKey, CookieTagMapValue> getCookieTagMap() {
+ try {
+ return new BpfMap<>(COOKIE_TAG_MAP_PATH, BpfMap.BPF_F_RDWR,
+ CookieTagMapKey.class, CookieTagMapValue.class);
+ } catch (ErrnoException e) {
+ throw new IllegalStateException("Cannot open cookie tag map", e);
+ }
+ }
+
private static void initBpfMaps() {
if (sConfigurationMap == null) {
sConfigurationMap = getConfigurationMap();
@@ -210,6 +266,10 @@
if (sUidPermissionMap == null) {
sUidPermissionMap = getUidPermissionMap();
}
+
+ if (sCookieTagMap == null) {
+ sCookieTagMap = getCookieTagMap();
+ }
}
/**
@@ -226,10 +286,14 @@
Log.d(TAG, "BpfNetMaps is initialized with sEnableJavaBpfMap=" + sEnableJavaBpfMap);
initBpfMaps();
- native_init();
+ native_init(!sEnableJavaBpfMap /* startSkDestroyListener */);
sInitialized = true;
}
+ public boolean isSkDestroyListenerRunning() {
+ return !sEnableJavaBpfMap;
+ }
+
/**
* Dependencies of BpfNetMaps, for injection in tests.
*/
@@ -248,6 +312,22 @@
public int synchronizeKernelRCU() {
return native_synchronizeKernelRCU();
}
+
+ /**
+ * Build Stats Event for NETWORK_BPF_MAP_INFO atom
+ */
+ public StatsEvent buildStatsEvent(final int cookieTagMapSize, final int uidOwnerMapSize,
+ final int uidPermissionMapSize) {
+ return ConnectivityStatsLog.buildStatsEvent(NETWORK_BPF_MAP_INFO, cookieTagMapSize,
+ uidOwnerMapSize, uidPermissionMapSize);
+ }
+
+ /**
+ * Call native_dump
+ */
+ public void nativeDump(final FileDescriptor fd, final boolean verbose) {
+ native_dump(fd, verbose);
+ }
}
/** Constructor used after T that doesn't need to use netd anymore. */
@@ -336,7 +416,7 @@
private void removeRule(final int uid, final long match, final String caller) {
try {
synchronized (sUidOwnerMap) {
- final UidOwnerValue oldMatch = sUidOwnerMap.getValue(new U32(uid));
+ final UidOwnerValue oldMatch = sUidOwnerMap.getValue(new S32(uid));
if (oldMatch == null) {
throw new ServiceSpecificException(ENOENT,
@@ -349,9 +429,9 @@
);
if (newMatch.rule == 0) {
- sUidOwnerMap.deleteEntry(new U32(uid));
+ sUidOwnerMap.deleteEntry(new S32(uid));
} else {
- sUidOwnerMap.updateEntry(new U32(uid), newMatch);
+ sUidOwnerMap.updateEntry(new S32(uid), newMatch);
}
}
} catch (ErrnoException e) {
@@ -360,7 +440,7 @@
}
}
- private void addRule(final int uid, final long match, final long iif, final String caller) {
+ private void addRule(final int uid, final long match, final int iif, final String caller) {
if (match != IIF_MATCH && iif != 0) {
throw new ServiceSpecificException(EINVAL,
"Non-interface match must have zero interface index");
@@ -368,7 +448,7 @@
try {
synchronized (sUidOwnerMap) {
- final UidOwnerValue oldMatch = sUidOwnerMap.getValue(new U32(uid));
+ final UidOwnerValue oldMatch = sUidOwnerMap.getValue(new S32(uid));
final UidOwnerValue newMatch;
if (oldMatch != null) {
@@ -382,7 +462,7 @@
match
);
}
- sUidOwnerMap.updateEntry(new U32(uid), newMatch);
+ sUidOwnerMap.updateEntry(new S32(uid), newMatch);
}
} catch (ErrnoException e) {
throw new ServiceSpecificException(e.errno,
@@ -518,6 +598,14 @@
}
}
+ private Set<Integer> asSet(final int[] uids) {
+ final Set<Integer> uidSet = new ArraySet<>();
+ for (final int uid: uids) {
+ uidSet.add(uid);
+ }
+ return uidSet;
+ }
+
/**
* Replaces the contents of the specified UID-based firewall chain.
* Enables the chain for specified uids and disables the chain for non-specified uids.
@@ -539,15 +627,17 @@
// ConnectivityManager#replaceFirewallChain API
throw new IllegalArgumentException("Invalid firewall chain: " + chain);
}
- final Set<Integer> uidSet = Arrays.stream(uids).boxed().collect(Collectors.toSet());
- final Set<Integer> uidSetToRemoveRule = new HashSet<>();
+ final Set<Integer> uidSet = asSet(uids);
+ final Set<Integer> uidSetToRemoveRule = new ArraySet<>();
try {
synchronized (sUidOwnerMap) {
sUidOwnerMap.forEach((uid, config) -> {
// config could be null if there is a concurrent entry deletion.
- // http://b/220084230.
- if (config != null
- && !uidSet.contains((int) uid.val) && (config.rule & match) != 0) {
+ // http://b/220084230. But sUidOwnerMap update must be done while holding a
+ // lock, so this should not happen.
+ if (config == null) {
+ Log.wtf(TAG, "sUidOwnerMap entry was deleted while holding a lock");
+ } else if (!uidSet.contains((int) uid.val) && (config.rule & match) != 0) {
uidSetToRemoveRule.add((int) uid.val);
}
});
@@ -792,7 +882,7 @@
if (permissions == PERMISSION_UNINSTALLED || permissions == PERMISSION_INTERNET) {
for (final int uid : uids) {
try {
- sUidPermissionMap.deleteEntry(new U32(uid));
+ sUidPermissionMap.deleteEntry(new S32(uid));
} catch (ErrnoException e) {
Log.e(TAG, "Failed to remove uid " + uid + " from permission map: " + e);
}
@@ -802,7 +892,7 @@
for (final int uid : uids) {
try {
- sUidPermissionMap.updateEntry(new U32(uid), new U8((short) permissions));
+ sUidPermissionMap.updateEntry(new S32(uid), new U8((short) permissions));
} catch (ErrnoException e) {
Log.e(TAG, "Failed to set permission "
+ permissions + " to uid " + uid + ": " + e);
@@ -813,24 +903,160 @@
}
}
+ /** Register callback for statsd to pull atom. */
+ public void setPullAtomCallback(final Context context) {
+ throwIfPreT("setPullAtomCallback is not available on pre-T devices");
+
+ final StatsManager statsManager = context.getSystemService(StatsManager.class);
+ statsManager.setPullAtomCallback(NETWORK_BPF_MAP_INFO, null /* metadata */,
+ BackgroundThread.getExecutor(), this::pullBpfMapInfoAtom);
+ }
+
+ private <K extends Struct, V extends Struct> int getMapSize(IBpfMap<K, V> map)
+ throws ErrnoException {
+ // forEach could restart iteration from the beginning if there is a concurrent entry
+ // deletion. netd and skDestroyListener could delete CookieTagMap entry concurrently.
+ // So using Set to count the number of entry in the map.
+ Set<K> keySet = new ArraySet<>();
+ map.forEach((k, v) -> keySet.add(k));
+ return keySet.size();
+ }
+
+ /** Callback for StatsManager#setPullAtomCallback */
+ @VisibleForTesting
+ public int pullBpfMapInfoAtom(final int atomTag, final List<StatsEvent> data) {
+ if (atomTag != NETWORK_BPF_MAP_INFO) {
+ Log.e(TAG, "Unexpected atom tag: " + atomTag);
+ return StatsManager.PULL_SKIP;
+ }
+
+ try {
+ data.add(mDeps.buildStatsEvent(getMapSize(sCookieTagMap), getMapSize(sUidOwnerMap),
+ getMapSize(sUidPermissionMap)));
+ } catch (ErrnoException e) {
+ Log.e(TAG, "Failed to pull NETWORK_BPF_MAP_INFO atom: " + e);
+ return StatsManager.PULL_SKIP;
+ }
+ return StatsManager.PULL_SUCCESS;
+ }
+
+ private String permissionToString(int permissionMask) {
+ if (permissionMask == PERMISSION_NONE) {
+ return "PERMISSION_NONE";
+ }
+ if (permissionMask == PERMISSION_UNINSTALLED) {
+ // PERMISSION_UNINSTALLED should never appear in the map
+ return "PERMISSION_UNINSTALLED error!";
+ }
+
+ final StringJoiner sj = new StringJoiner(" ");
+ for (Pair<Integer, String> permission: PERMISSION_LIST) {
+ final int permissionFlag = permission.first;
+ final String permissionName = permission.second;
+ if ((permissionMask & permissionFlag) != 0) {
+ sj.add(permissionName);
+ permissionMask &= ~permissionFlag;
+ }
+ }
+ if (permissionMask != 0) {
+ sj.add("PERMISSION_UNKNOWN(" + permissionMask + ")");
+ }
+ return sj.toString();
+ }
+
+ private String matchToString(long matchMask) {
+ if (matchMask == NO_MATCH) {
+ return "NO_MATCH";
+ }
+
+ final StringJoiner sj = new StringJoiner(" ");
+ for (Pair<Long, String> match: MATCH_LIST) {
+ final long matchFlag = match.first;
+ final String matchName = match.second;
+ if ((matchMask & matchFlag) != 0) {
+ sj.add(matchName);
+ matchMask &= ~matchFlag;
+ }
+ }
+ if (matchMask != 0) {
+ sj.add("UNKNOWN_MATCH(" + matchMask + ")");
+ }
+ return sj.toString();
+ }
+
+ private void dumpOwnerMatchConfig(final IndentingPrintWriter pw) {
+ try {
+ final long match = sConfigurationMap.getValue(UID_RULES_CONFIGURATION_KEY).val;
+ pw.println("current ownerMatch configuration: " + match + " " + matchToString(match));
+ } catch (ErrnoException e) {
+ pw.println("Failed to read ownerMatch configuration: " + e);
+ }
+ }
+
+ private void dumpCurrentStatsMapConfig(final IndentingPrintWriter pw) {
+ try {
+ final long config = sConfigurationMap.getValue(CURRENT_STATS_MAP_CONFIGURATION_KEY).val;
+ final String currentStatsMap =
+ (config == STATS_SELECT_MAP_A) ? "SELECT_MAP_A" : "SELECT_MAP_B";
+ pw.println("current statsMap configuration: " + config + " " + currentStatsMap);
+ } catch (ErrnoException e) {
+ pw.println("Falied to read current statsMap configuration: " + e);
+ }
+ }
+
/**
* Dump BPF maps
*
+ * @param pw print writer
* @param fd file descriptor to output
+ * @param verbose verbose dump flag, if true dump the BpfMap contents
* @throws IOException when file descriptor is invalid.
* @throws ServiceSpecificException when the method is called on an unsupported device.
*/
- public void dump(final FileDescriptor fd, boolean verbose)
+ public void dump(final IndentingPrintWriter pw, final FileDescriptor fd, boolean verbose)
throws IOException, ServiceSpecificException {
if (PRE_T) {
throw new ServiceSpecificException(
EOPNOTSUPP, "dumpsys connectivity trafficcontroller dump not available on pre-T"
+ " devices, use dumpsys netd trafficcontroller instead.");
}
- native_dump(fd, verbose);
+ mDeps.nativeDump(fd, verbose);
+
+ pw.println();
+ pw.println("sEnableJavaBpfMap: " + sEnableJavaBpfMap);
+ if (verbose) {
+ pw.println();
+ pw.println("BPF map content:");
+ pw.increaseIndent();
+
+ dumpOwnerMatchConfig(pw);
+ dumpCurrentStatsMapConfig(pw);
+ pw.println();
+
+ // TODO: Remove CookieTagMap content dump
+ // NetworkStatsService also dumps CookieTagMap and NetworkStatsService is a right place
+ // to dump CookieTagMap. But the TagSocketTest in CTS depends on this dump so the tests
+ // need to be updated before remove the dump from BpfNetMaps.
+ BpfDump.dumpMap(sCookieTagMap, pw, "sCookieTagMap",
+ (key, value) -> "cookie=" + key.socketCookie
+ + " tag=0x" + Long.toHexString(value.tag)
+ + " uid=" + value.uid);
+ BpfDump.dumpMap(sUidOwnerMap, pw, "sUidOwnerMap",
+ (uid, match) -> {
+ if ((match.rule & IIF_MATCH) != 0) {
+ // TODO: convert interface index to interface name by IfaceIndexNameMap
+ return uid.val + " " + matchToString(match.rule) + " " + match.iif;
+ } else {
+ return uid.val + " " + matchToString(match.rule);
+ }
+ });
+ BpfDump.dumpMap(sUidPermissionMap, pw, "sUidPermissionMap",
+ (uid, permission) -> uid.val + " " + permissionToString(permission.val));
+ pw.decreaseIndent();
+ }
}
- private static native void native_init();
+ private static native void native_init(boolean startSkDestroyListener);
private native int native_addNaughtyApp(int uid);
private native int native_removeNaughtyApp(int uid);
private native int native_addNiceApp(int uid);
@@ -843,6 +1069,6 @@
private native int native_updateUidLockdownRule(int uid, boolean add);
private native int native_swapActiveStatsMap();
private native void native_setPermissionForUids(int permissions, int[] uids);
- private native void native_dump(FileDescriptor fd, boolean verbose);
+ private static native void native_dump(FileDescriptor fd, boolean verbose);
private static native int native_synchronizeKernelRCU();
}
diff --git a/service/src/com/android/server/ConnectivityService.java b/service/src/com/android/server/ConnectivityService.java
old mode 100644
new mode 100755
index 218cbde..9b1fa45
--- a/service/src/com/android/server/ConnectivityService.java
+++ b/service/src/com/android/server/ConnectivityService.java
@@ -205,7 +205,6 @@
import android.net.resolv.aidl.Nat64PrefixEventParcel;
import android.net.resolv.aidl.PrivateDnsValidationEventParcel;
import android.net.shared.PrivateDnsConfig;
-import android.net.util.MultinetworkPolicyTracker;
import android.net.wifi.WifiInfo;
import android.os.BatteryStatsManager;
import android.os.Binder;
@@ -250,13 +249,13 @@
import com.android.modules.utils.BasicShellCommandHandler;
import com.android.modules.utils.build.SdkLevel;
import com.android.net.module.util.BaseNetdUnsolicitedEventListener;
+import com.android.net.module.util.BitUtils;
import com.android.net.module.util.CollectionUtils;
import com.android.net.module.util.DeviceConfigUtils;
import com.android.net.module.util.InterfaceParams;
import com.android.net.module.util.LinkPropertiesUtils.CompareOrUpdateResult;
import com.android.net.module.util.LinkPropertiesUtils.CompareResult;
import com.android.net.module.util.LocationPermissionChecker;
-import com.android.net.module.util.NetworkCapabilitiesUtils;
import com.android.net.module.util.PerUidCounter;
import com.android.net.module.util.PermissionUtils;
import com.android.net.module.util.TcUtils;
@@ -272,6 +271,7 @@
import com.android.server.connectivity.KeepaliveTracker;
import com.android.server.connectivity.LingerMonitor;
import com.android.server.connectivity.MockableSystemProperties;
+import com.android.server.connectivity.MultinetworkPolicyTracker;
import com.android.server.connectivity.NetworkAgentInfo;
import com.android.server.connectivity.NetworkDiagnostics;
import com.android.server.connectivity.NetworkNotificationManager;
@@ -353,13 +353,22 @@
// connect anyway?" dialog after the user selects a network that doesn't validate.
private static final int PROMPT_UNVALIDATED_DELAY_MS = 8 * 1000;
+ // How long to wait before considering that a network is bad in the absence of any form
+ // of connectivity (valid, partial, captive portal). If none has been detected after this
+ // delay, the stack considers this network bad, which may affect how it's handled in ranking
+ // according to config_networkAvoidBadWifi.
+ // Timeout in case the "actively prefer bad wifi" feature is on
+ private static final int ACTIVELY_PREFER_BAD_WIFI_INITIAL_TIMEOUT_MS = 20 * 1000;
+ // Timeout in case the "actively prefer bad wifi" feature is off
+ private static final int DONT_ACTIVELY_PREFER_BAD_WIFI_INITIAL_TIMEOUT_MS = 8 * 1000;
+
// Default to 30s linger time-out, and 5s for nascent network. Modifiable only for testing.
private static final String LINGER_DELAY_PROPERTY = "persist.netmon.linger";
private static final int DEFAULT_LINGER_DELAY_MS = 30_000;
private static final int DEFAULT_NASCENT_DELAY_MS = 5_000;
// The maximum value for the blocking validation result, in milliseconds.
- public static final int MAX_VALIDATION_FAILURE_BLOCKING_TIME_MS = 10000;
+ public static final int MAX_VALIDATION_IGNORE_AFTER_ROAM_TIME_MS = 10000;
// The maximum number of network request allowed per uid before an exception is thrown.
@VisibleForTesting
@@ -581,12 +590,6 @@
private static final int EVENT_SET_ACCEPT_UNVALIDATED = 28;
/**
- * used to ask the user to confirm a connection to an unvalidated network.
- * obj = network
- */
- private static final int EVENT_PROMPT_UNVALIDATED = 29;
-
- /**
* used internally to (re)configure always-on networks.
*/
private static final int EVENT_CONFIGURE_ALWAYS_ON_NETWORKS = 30;
@@ -725,6 +728,14 @@
private static final int EVENT_INGRESS_RATE_LIMIT_CHANGED = 56;
/**
+ * The initial evaluation period is over for this network.
+ *
+ * If no form of connectivity has been found on this network (valid, partial, captive portal)
+ * then the stack will now consider it to have been determined bad.
+ */
+ private static final int EVENT_INITIAL_EVALUATION_TIMEOUT = 57;
+
+ /**
* Argument for {@link #EVENT_PROVISIONING_NOTIFICATION} to indicate that the notification
* should be shown.
*/
@@ -775,7 +786,8 @@
final ConnectivityDiagnosticsHandler mConnectivityDiagnosticsHandler;
private final DnsManager mDnsManager;
- private final NetworkRanker mNetworkRanker;
+ @VisibleForTesting
+ final NetworkRanker mNetworkRanker;
private boolean mSystemReady;
private Intent mInitialBroadcast;
@@ -1409,7 +1421,6 @@
new RequestInfoPerUidCounter(MAX_NETWORK_REQUESTS_PER_SYSTEM_UID - 1);
mMetricsLog = logger;
- mNetworkRanker = new NetworkRanker();
final NetworkRequest defaultInternetRequest = createDefaultRequest();
mDefaultRequest = new NetworkRequestInfo(
Process.myUid(), defaultInternetRequest, null,
@@ -1530,6 +1541,9 @@
mMultinetworkPolicyTracker = mDeps.makeMultinetworkPolicyTracker(
mContext, mHandler, () -> updateAvoidBadWifi());
+ mNetworkRanker =
+ new NetworkRanker(new NetworkRanker.Configuration(activelyPreferBadWifi()));
+
mMultinetworkPolicyTracker.start();
mDnsManager = new DnsManager(mContext, mDnsResolver);
@@ -1744,7 +1758,8 @@
synchronized (mNetworkForNetId) {
for (int i = 0; i < mNetworkForNetId.size(); i++) {
final NetworkAgentInfo nai = mNetworkForNetId.valueAt(i);
- if (nai.isVPN() && nai.everConnected && nai.networkCapabilities.appliesToUid(uid)) {
+ if (nai.isVPN() && nai.everConnected()
+ && nai.networkCapabilities.appliesToUid(uid)) {
return nai;
}
}
@@ -1967,6 +1982,9 @@
@Nullable
public NetworkInfo getNetworkInfoForUid(Network network, int uid, boolean ignoreBlocked) {
enforceAccessPermission();
+ if (uid != mDeps.getCallingUid()) {
+ enforceNetworkStackPermission(mContext);
+ }
final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
if (nai == null) return null;
return getFilteredNetworkInfo(nai, uid, ignoreBlocked);
@@ -2478,7 +2496,7 @@
final ArrayList<NetworkStateSnapshot> result = new ArrayList<>();
for (Network network : getAllNetworks()) {
final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
- if (nai != null && nai.everConnected) {
+ if (nai != null && nai.everConnected()) {
// TODO (b/73321673) : NetworkStateSnapshot contains a copy of the
// NetworkCapabilities, which may contain UIDs of apps to which the
// network applies. Should the UIDs be cleared so as not to leak or
@@ -3039,6 +3057,11 @@
if (!ConnectivitySettingsManager.getMobileDataPreferredUids(mContext).isEmpty()) {
updateMobileDataPreferredUids();
}
+
+ // On T+ devices, register callback for statsd to pull NETWORK_BPF_MAP_INFO atom
+ if (SdkLevel.isAtLeastT()) {
+ mBpfNetMaps.setPullAtomCallback(mContext);
+ }
}
/**
@@ -3069,7 +3092,7 @@
* Reads the network specific MTU size from resources.
* and set it on it's iface.
*/
- private void updateMtu(LinkProperties newLp, LinkProperties oldLp) {
+ private void updateMtu(@NonNull LinkProperties newLp, @Nullable LinkProperties oldLp) {
final String iface = newLp.getInterfaceName();
final int mtu = newLp.getMtu();
if (oldLp == null && mtu == 0) {
@@ -3102,7 +3125,7 @@
@VisibleForTesting
protected static final String DEFAULT_TCP_BUFFER_SIZES = "4096,87380,110208,4096,16384,110208";
- private void updateTcpBufferSizes(String tcpBufferSizes) {
+ private void updateTcpBufferSizes(@Nullable String tcpBufferSizes) {
String[] values = null;
if (tcpBufferSizes != null) {
values = tcpBufferSizes.split(",");
@@ -3336,17 +3359,6 @@
pw.increaseIndent();
mNetworkActivityTracker.dump(pw);
pw.decreaseIndent();
-
- // pre-T is logged by netd.
- if (SdkLevel.isAtLeastT()) {
- pw.println();
- pw.println("BPF programs & maps:");
- pw.increaseIndent();
- // Flush is required. Otherwise, the traces in fd can interleave with traces in pw.
- pw.flush();
- dumpTrafficController(pw, fd, /*verbose=*/ true);
- pw.decreaseIndent();
- }
}
private void dumpNetworks(IndentingPrintWriter pw) {
@@ -3448,7 +3460,7 @@
private void dumpTrafficController(IndentingPrintWriter pw, final FileDescriptor fd,
boolean verbose) {
try {
- mBpfNetMaps.dump(fd, verbose);
+ mBpfNetMaps.dump(pw, fd, verbose);
} catch (ServiceSpecificException e) {
pw.println(e.getMessage());
} catch (IOException e) {
@@ -3531,7 +3543,7 @@
}
// If the network has been destroyed, the only thing that it can do is disconnect.
- if (nai.destroyed && !isDisconnectRequest(msg)) {
+ if (nai.isDestroyed() && !isDisconnectRequest(msg)) {
return;
}
@@ -3560,7 +3572,7 @@
break;
}
case NetworkAgent.EVENT_SET_EXPLICITLY_SELECTED: {
- if (nai.everConnected) {
+ if (nai.everConnected()) {
loge("ERROR: cannot call explicitlySelected on already-connected network");
// Note that if the NAI had been connected, this would affect the
// score, and therefore would require re-mixing the score and performing
@@ -3638,8 +3650,18 @@
break;
}
case NetworkAgent.EVENT_UNREGISTER_AFTER_REPLACEMENT: {
- // If nai is not yet created, or is already destroyed, ignore.
- if (!shouldDestroyNativeNetwork(nai)) break;
+ if (!nai.isCreated()) {
+ Log.d(TAG, "unregisterAfterReplacement on uncreated " + nai.toShortString()
+ + ", tearing down instead");
+ teardownUnneededNetwork(nai);
+ break;
+ }
+
+ if (nai.isDestroyed()) {
+ Log.d(TAG, "unregisterAfterReplacement on destroyed " + nai.toShortString()
+ + ", ignoring");
+ break;
+ }
final int timeoutMs = (int) arg.second;
if (timeoutMs < 0 || timeoutMs > NetworkAgent.MAX_TEARDOWN_DELAY_MS) {
@@ -3690,7 +3712,7 @@
final int netId = msg.arg2;
final NetworkAgentInfo nai = getNetworkAgentInfoForNetId(netId);
// If a network has already been destroyed, all NetworkMonitor updates are ignored.
- if (nai != null && nai.destroyed) return true;
+ if (nai != null && nai.isDestroyed()) return true;
switch (msg.what) {
default:
return false;
@@ -3739,19 +3761,6 @@
case EVENT_PROVISIONING_NOTIFICATION: {
final boolean visible = toBool(msg.arg1);
// If captive portal status has changed, update capabilities or disconnect.
- if (nai != null && (visible != nai.lastCaptivePortalDetected)) {
- nai.lastCaptivePortalDetected = visible;
- nai.everCaptivePortalDetected |= visible;
- if (nai.lastCaptivePortalDetected &&
- ConnectivitySettingsManager.CAPTIVE_PORTAL_MODE_AVOID
- == getCaptivePortalMode()) {
- if (DBG) log("Avoiding captive portal network: " + nai.toShortString());
- nai.onPreventAutomaticReconnect();
- teardownUnneededNetwork(nai);
- break;
- }
- updateCapabilitiesForNetwork(nai);
- }
if (!visible) {
// Only clear SIGN_IN and NETWORK_SWITCH notifications here, or else other
// notifications belong to the same network may be cleared unexpectedly.
@@ -3787,7 +3796,22 @@
private void handleNetworkTested(
@NonNull NetworkAgentInfo nai, int testResult, @NonNull String redirectUrl) {
- final boolean valid = ((testResult & NETWORK_VALIDATION_RESULT_VALID) != 0);
+ final boolean valid = (testResult & NETWORK_VALIDATION_RESULT_VALID) != 0;
+ final boolean partial = (testResult & NETWORK_VALIDATION_RESULT_PARTIAL) != 0;
+ final boolean portal = !TextUtils.isEmpty(redirectUrl);
+
+ // If there is any kind of working networking, then the NAI has been evaluated
+ // once. {@see NetworkAgentInfo#setEvaluated}, which returns whether this is
+ // the first time this ever happened.
+ final boolean someConnectivity = (valid || partial || portal);
+ final boolean becameEvaluated = someConnectivity && nai.setEvaluated();
+ // Because of b/245893397, if the score is updated when updateCapabilities is called,
+ // any callback that receives onAvailable for that rematch receives an extra caps
+ // callback. To prevent that, update the score in the agent so the updates below won't
+ // see an update to both caps and score at the same time.
+ // TODO : fix b/245893397 and remove this.
+ if (becameEvaluated) nai.updateScoreForNetworkAgentUpdate();
+
if (!valid && shouldIgnoreValidationFailureAfterRoam(nai)) {
// Assume the validation failure is due to a temporary failure after roaming
// and ignore it. NetworkMonitor will continue to retry validation. If it
@@ -3796,11 +3820,14 @@
return;
}
- final boolean wasValidated = nai.lastValidated;
- final boolean wasPartial = nai.partialConnectivity;
- nai.partialConnectivity = ((testResult & NETWORK_VALIDATION_RESULT_PARTIAL) != 0);
- final boolean partialConnectivityChanged =
- (wasPartial != nai.partialConnectivity);
+ final boolean wasValidated = nai.isValidated();
+ final boolean wasPartial = nai.partialConnectivity();
+ final boolean wasPortal = nai.captivePortalDetected();
+ nai.setPartialConnectivity(partial);
+ nai.setCaptivePortalDetected(portal);
+ nai.updateScoreForNetworkAgentUpdate();
+ final boolean partialConnectivityChanged = (wasPartial != partial);
+ final boolean portalChanged = (wasPortal != portal);
if (DBG) {
final String logMsg = !TextUtils.isEmpty(redirectUrl)
@@ -3808,10 +3835,9 @@
: "";
log(nai.toShortString() + " validation " + (valid ? "passed" : "failed") + logMsg);
}
- if (valid != nai.lastValidated) {
+ if (valid != wasValidated) {
final FullScore oldScore = nai.getScore();
- nai.lastValidated = valid;
- nai.everValidated |= valid;
+ nai.setValidated(valid);
updateCapabilities(oldScore, nai, nai.networkCapabilities);
if (valid) {
handleFreshlyValidatedNetwork(nai);
@@ -3832,8 +3858,23 @@
}
} else if (partialConnectivityChanged) {
updateCapabilitiesForNetwork(nai);
+ } else if (portalChanged) {
+ if (portal && ConnectivitySettingsManager.CAPTIVE_PORTAL_MODE_AVOID
+ == getCaptivePortalMode()) {
+ if (DBG) log("Avoiding captive portal network: " + nai.toShortString());
+ nai.onPreventAutomaticReconnect();
+ teardownUnneededNetwork(nai);
+ return;
+ } else {
+ updateCapabilitiesForNetwork(nai);
+ }
+ } else if (becameEvaluated) {
+ // If valid or partial connectivity changed, updateCapabilities* has
+ // done the rematch.
+ rematchAllNetworksAndRequests();
}
updateInetCondition(nai);
+
// Let the NetworkAgent know the state of its network
// TODO: Evaluate to update partial connectivity to status to NetworkAgent.
nai.onValidationStatusChanged(
@@ -3841,16 +3882,16 @@
redirectUrl);
// If NetworkMonitor detects partial connectivity before
- // EVENT_PROMPT_UNVALIDATED arrives, show the partial connectivity notification
+ // EVENT_INITIAL_EVALUATION_TIMEOUT arrives, show the partial connectivity notification
// immediately. Re-notify partial connectivity silently if no internet
// notification already there.
- if (!wasPartial && nai.partialConnectivity) {
+ if (!wasPartial && nai.partialConnectivity()) {
// Remove delayed message if there is a pending message.
- mHandler.removeMessages(EVENT_PROMPT_UNVALIDATED, nai.network);
- handlePromptUnvalidated(nai.network);
+ mHandler.removeMessages(EVENT_INITIAL_EVALUATION_TIMEOUT, nai.network);
+ handleInitialEvaluationTimeout(nai.network);
}
- if (wasValidated && !nai.lastValidated) {
+ if (wasValidated && !nai.isValidated()) {
handleNetworkUnvalidated(nai);
}
}
@@ -4197,18 +4238,24 @@
}
private static boolean shouldDestroyNativeNetwork(@NonNull NetworkAgentInfo nai) {
- return nai.created && !nai.destroyed;
+ return nai.isCreated() && !nai.isDestroyed();
}
- private boolean shouldIgnoreValidationFailureAfterRoam(NetworkAgentInfo nai) {
+ @VisibleForTesting
+ boolean shouldIgnoreValidationFailureAfterRoam(NetworkAgentInfo nai) {
// T+ devices should use unregisterAfterReplacement.
if (SdkLevel.isAtLeastT()) return false;
+
+ // If the network never roamed, return false. The check below is not sufficient if time
+ // since boot is less than blockTimeOut, though that's extremely unlikely to happen.
+ if (nai.lastRoamTime == 0) return false;
+
final long blockTimeOut = Long.valueOf(mResources.get().getInteger(
R.integer.config_validationFailureAfterRoamIgnoreTimeMillis));
- if (blockTimeOut <= MAX_VALIDATION_FAILURE_BLOCKING_TIME_MS
+ if (blockTimeOut <= MAX_VALIDATION_IGNORE_AFTER_ROAM_TIME_MS
&& blockTimeOut >= 0) {
- final long currentTimeMs = SystemClock.elapsedRealtime();
- long timeSinceLastRoam = currentTimeMs - nai.lastRoamTimestamp;
+ final long currentTimeMs = SystemClock.elapsedRealtime();
+ long timeSinceLastRoam = currentTimeMs - nai.lastRoamTime;
if (timeSinceLastRoam <= blockTimeOut) {
log ("blocked because only " + timeSinceLastRoam + "ms after roam");
return true;
@@ -4312,7 +4359,7 @@
}
// Delayed teardown.
- if (nai.created) {
+ if (nai.isCreated()) {
try {
mNetd.networkSetPermissionForNetwork(nai.network.netId, INetd.PERMISSION_SYSTEM);
} catch (RemoteException e) {
@@ -4333,7 +4380,7 @@
// for an unnecessarily long time.
destroyNativeNetwork(nai);
}
- if (!nai.created && !SdkLevel.isAtLeastT()) {
+ if (!nai.isCreated() && !SdkLevel.isAtLeastT()) {
// Backwards compatibility: send onNetworkDestroyed even if network was never created.
// This can never run if the code above runs because shouldDestroyNativeNetwork is
// false if the network was never created.
@@ -4394,11 +4441,11 @@
mDnsManager.removeNetwork(nai.network);
// clean up tc police filters on interface.
- if (nai.everConnected && canNetworkBeRateLimited(nai) && mIngressRateLimit >= 0) {
+ if (nai.everConnected() && canNetworkBeRateLimited(nai) && mIngressRateLimit >= 0) {
mDeps.disableIngressRateLimit(nai.linkProperties.getInterfaceName());
}
- nai.destroyed = true;
+ nai.setDestroyed();
nai.onNetworkDestroyed();
}
@@ -4527,7 +4574,7 @@
private boolean unneeded(NetworkAgentInfo nai, UnneededFor reason) {
ensureRunningOnConnectivityServiceThread();
- if (!nai.everConnected || nai.isVPN() || nai.isInactive()
+ if (!nai.everConnected() || nai.isVPN() || nai.isInactive()
|| nai.getScore().getKeepConnectedReason() != NetworkScore.KEEP_CONNECTED_NONE) {
return false;
}
@@ -4582,7 +4629,7 @@
if (req.isListen() || req.isListenForBest()) {
continue;
}
- // If this Network is already the highest scoring Network for a request, or if
+ // If this Network is already the best Network for a request, or if
// there is hope for it to become one if it validated, then it is needed.
if (candidate.satisfies(req)) {
// As soon as a network is found that satisfies a request, return. Specifically for
@@ -4859,7 +4906,7 @@
return;
}
- if (nai.everValidated) {
+ if (nai.everValidated()) {
// The network validated while the dialog box was up. Take no action.
return;
}
@@ -4904,7 +4951,7 @@
return;
}
- if (nai.lastValidated) {
+ if (nai.isValidated()) {
// The network validated while the dialog box was up. Take no action.
return;
}
@@ -4936,22 +4983,22 @@
private void handleSetAvoidUnvalidated(Network network) {
NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
- if (nai == null || nai.lastValidated) {
+ if (nai == null || nai.isValidated()) {
// Nothing to do. The network either disconnected or revalidated.
return;
}
- if (!nai.avoidUnvalidated) {
- nai.avoidUnvalidated = true;
+ if (0L == nai.getAvoidUnvalidated()) {
+ nai.setAvoidUnvalidated();
nai.updateScoreForNetworkAgentUpdate();
rematchAllNetworksAndRequests();
}
}
- private void scheduleUnvalidatedPrompt(NetworkAgentInfo nai) {
- if (VDBG) log("scheduleUnvalidatedPrompt " + nai.network);
+ /** Schedule evaluation timeout */
+ @VisibleForTesting
+ public void scheduleEvaluationTimeout(@NonNull final Network network, final long delayMs) {
mHandler.sendMessageDelayed(
- mHandler.obtainMessage(EVENT_PROMPT_UNVALIDATED, nai.network),
- PROMPT_UNVALIDATED_DELAY_MS);
+ mHandler.obtainMessage(EVENT_INITIAL_EVALUATION_TIMEOUT, network), delayMs);
}
@Override
@@ -5036,6 +5083,10 @@
return mMultinetworkPolicyTracker.getAvoidBadWifi();
}
+ private boolean activelyPreferBadWifi() {
+ return mMultinetworkPolicyTracker.getActivelyPreferBadWifi();
+ }
+
/**
* Return whether the device should maintain continuous, working connectivity by switching away
* from WiFi networks having no connectivity.
@@ -5051,14 +5102,21 @@
private void updateAvoidBadWifi() {
ensureRunningOnConnectivityServiceThread();
// Agent info scores and offer scores depend on whether cells yields to bad wifi.
+ final boolean avoidBadWifi = avoidBadWifi();
for (final NetworkAgentInfo nai : mNetworkAgentInfos) {
nai.updateScoreForNetworkAgentUpdate();
+ if (avoidBadWifi) {
+ // If the device is now avoiding bad wifi, remove notifications that might have
+ // been put up when the device didn't.
+ mNotifier.clearNotification(nai.network.getNetId(), NotificationType.LOST_INTERNET);
+ }
}
// UpdateOfferScore will update mNetworkOffers inline, so make a copy first.
final ArrayList<NetworkOfferInfo> offersToUpdate = new ArrayList<>(mNetworkOffers);
for (final NetworkOfferInfo noi : offersToUpdate) {
updateOfferScore(noi.offer);
}
+ mNetworkRanker.setConfiguration(new NetworkRanker.Configuration(activelyPreferBadWifi()));
rematchAllNetworksAndRequests();
}
@@ -5073,25 +5131,36 @@
pw.println("Bad Wi-Fi avoidance: " + avoidBadWifi());
pw.increaseIndent();
- pw.println("Config restrict: " + configRestrict);
+ pw.println("Config restrict: " + configRestrict);
+ pw.println("Actively prefer bad wifi: " + activelyPreferBadWifi());
- final String value = mMultinetworkPolicyTracker.getAvoidBadWifiSetting();
+ final String settingValue = mMultinetworkPolicyTracker.getAvoidBadWifiSetting();
String description;
// Can't use a switch statement because strings are legal case labels, but null is not.
- if ("0".equals(value)) {
+ if ("0".equals(settingValue)) {
description = "get stuck";
- } else if (value == null) {
+ } else if (settingValue == null) {
description = "prompt";
- } else if ("1".equals(value)) {
+ } else if ("1".equals(settingValue)) {
description = "avoid";
} else {
- description = value + " (?)";
+ description = settingValue + " (?)";
}
- pw.println("User setting: " + description);
+ pw.println("Avoid bad wifi setting: " + description);
+ final Boolean configValue = mMultinetworkPolicyTracker.deviceConfigActivelyPreferBadWifi();
+ if (null == configValue) {
+ description = "unset";
+ } else if (configValue) {
+ description = "force true";
+ } else {
+ description = "force false";
+ }
+ pw.println("Actively prefer bad wifi conf: " + description);
+ pw.println();
pw.println("Network overrides:");
pw.increaseIndent();
for (NetworkAgentInfo nai : networksSortedById()) {
- if (nai.avoidUnvalidated) {
+ if (0L != nai.getAvoidUnvalidated()) {
pw.println(nai.toShortString());
}
}
@@ -5162,7 +5231,7 @@
private boolean shouldPromptUnvalidated(NetworkAgentInfo nai) {
// Don't prompt if the network is validated, and don't prompt on captive portals
// because we're already prompting the user to sign in.
- if (nai.everValidated || nai.everCaptivePortalDetected) {
+ if (nai.everValidated() || nai.everCaptivePortalDetected()) {
return false;
}
@@ -5170,8 +5239,8 @@
// partial connectivity and selected don't ask again. This ensures that if the device
// automatically connects to a network that has partial Internet access, the user will
// always be able to use it, either because they've already chosen "don't ask again" or
- // because we have prompt them.
- if (nai.partialConnectivity && !nai.networkAgentConfig.acceptPartialConnectivity) {
+ // because we have prompted them.
+ if (nai.partialConnectivity() && !nai.networkAgentConfig.acceptPartialConnectivity) {
return true;
}
@@ -5186,24 +5255,39 @@
return false;
}
- private void handlePromptUnvalidated(Network network) {
- if (VDBG || DDBG) log("handlePromptUnvalidated " + network);
- NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
+ private void handleInitialEvaluationTimeout(@NonNull final Network network) {
+ if (VDBG || DDBG) log("handleInitialEvaluationTimeout " + network);
- if (nai == null || !shouldPromptUnvalidated(nai)) {
- return;
+ NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
+ if (null == nai) return;
+
+ if (nai.setEvaluated()) {
+ // If setEvaluated() returned true, the network never had any form of connectivity.
+ // This may have an impact on request matching if bad WiFi avoidance is off and the
+ // network was found not to have Internet access.
+ nai.updateScoreForNetworkAgentUpdate();
+ rematchAllNetworksAndRequests();
+
+ // Also, if this is WiFi and it should be preferred actively, now is the time to
+ // prompt the user that they walked past and connected to a bad WiFi.
+ if (nai.networkCapabilities.hasTransport(TRANSPORT_WIFI)
+ && !avoidBadWifi()
+ && activelyPreferBadWifi()) {
+ // The notification will be removed if the network validates or disconnects.
+ showNetworkNotification(nai, NotificationType.LOST_INTERNET);
+ return;
+ }
}
+ if (!shouldPromptUnvalidated(nai)) return;
+
// Stop automatically reconnecting to this network in the future. Automatically connecting
// to a network that provides no or limited connectivity is not useful, because the user
// cannot use that network except through the notification shown by this method, and the
// notification is only shown if the network is explicitly selected by the user.
nai.onPreventAutomaticReconnect();
- // TODO: Evaluate if it's needed to wait 8 seconds for triggering notification when
- // NetworkMonitor detects the network is partial connectivity. Need to change the design to
- // popup the notification immediately when the network is partial connectivity.
- if (nai.partialConnectivity) {
+ if (nai.partialConnectivity()) {
showNetworkNotification(nai, NotificationType.PARTIAL_CONNECTIVITY);
} else {
showNetworkNotification(nai, NotificationType.NO_INTERNET);
@@ -5341,8 +5425,8 @@
handleSetAvoidUnvalidated((Network) msg.obj);
break;
}
- case EVENT_PROMPT_UNVALIDATED: {
- handlePromptUnvalidated((Network) msg.obj);
+ case EVENT_INITIAL_EVALUATION_TIMEOUT: {
+ handleInitialEvaluationTimeout((Network) msg.obj);
break;
}
case EVENT_CONFIGURE_ALWAYS_ON_NETWORKS: {
@@ -5557,7 +5641,7 @@
return;
}
// Revalidate if the app report does not match our current validated state.
- if (hasConnectivity == nai.lastValidated) {
+ if (hasConnectivity == nai.isValidated()) {
mConnectivityDiagnosticsHandler.sendMessage(
mConnectivityDiagnosticsHandler.obtainMessage(
ConnectivityDiagnosticsHandler.EVENT_NETWORK_CONNECTIVITY_REPORTED,
@@ -5571,7 +5655,7 @@
}
// Validating a network that has not yet connected could result in a call to
// rematchNetworkAndRequests() which is not meant to work on such networks.
- if (!nai.everConnected) {
+ if (!nai.everConnected()) {
return;
}
final NetworkCapabilities nc = getNetworkCapabilitiesInternal(nai);
@@ -5678,7 +5762,7 @@
return mProxyTracker.getGlobalProxy();
}
- private void handleApplyDefaultProxy(ProxyInfo proxy) {
+ private void handleApplyDefaultProxy(@Nullable ProxyInfo proxy) {
if (proxy != null && TextUtils.isEmpty(proxy.getHost())
&& Uri.EMPTY.equals(proxy.getPacFileUrl())) {
proxy = null;
@@ -5690,8 +5774,8 @@
// when any network changes proxy.
// TODO: Remove usage of broadcast extras as they are deprecated and not applicable in a
// multi-network world where an app might be bound to a non-default network.
- private void updateProxy(LinkProperties newLp, LinkProperties oldLp) {
- ProxyInfo newProxyInfo = newLp == null ? null : newLp.getHttpProxy();
+ private void updateProxy(@NonNull LinkProperties newLp, @Nullable LinkProperties oldLp) {
+ ProxyInfo newProxyInfo = newLp.getHttpProxy();
ProxyInfo oldProxyInfo = oldLp == null ? null : oldLp.getHttpProxy();
if (!ProxyTracker.proxyInfoEqual(newProxyInfo, oldProxyInfo)) {
@@ -6923,6 +7007,7 @@
@Override
public void unofferNetwork(@NonNull final INetworkOfferCallback callback) {
+ Objects.requireNonNull(callback);
mHandler.sendMessage(mHandler.obtainMessage(EVENT_UNREGISTER_NETWORK_OFFER, callback));
}
@@ -7415,7 +7500,7 @@
}
private void updateLinkProperties(NetworkAgentInfo networkAgent, @NonNull LinkProperties newLp,
- @NonNull LinkProperties oldLp) {
+ @Nullable LinkProperties oldLp) {
int netId = networkAgent.network.getNetId();
// The NetworkAgent does not know whether clatd is running on its network or not, or whether
@@ -7467,12 +7552,16 @@
}
// Start or stop DNS64 detection and 464xlat according to network state.
networkAgent.clatd.update();
- notifyIfacesChangedForNetworkStats();
+ // Notify NSS when relevant events happened. Currently, NSS only cares about
+ // interface changed to update clat interfaces accounting.
+ final boolean interfacesChanged = oldLp == null
+ || !Objects.equals(newLp.getAllInterfaceNames(), oldLp.getAllInterfaceNames());
+ if (interfacesChanged) {
+ notifyIfacesChangedForNetworkStats();
+ }
networkAgent.networkMonitor().notifyLinkPropertiesChanged(
new LinkProperties(newLp, true /* parcelSensitiveFields */));
- if (networkAgent.everConnected) {
- notifyNetworkCallbacks(networkAgent, ConnectivityManager.CALLBACK_IP_CHANGED);
- }
+ notifyNetworkCallbacks(networkAgent, ConnectivityManager.CALLBACK_IP_CHANGED);
}
mKeepaliveTracker.handleCheckKeepalivesStillValid(networkAgent);
@@ -7556,12 +7645,11 @@
}
- private void updateInterfaces(final @Nullable LinkProperties newLp,
+ private void updateInterfaces(final @NonNull LinkProperties newLp,
final @Nullable LinkProperties oldLp, final int netId,
final @NonNull NetworkCapabilities caps) {
final CompareResult<String> interfaceDiff = new CompareResult<>(
- oldLp != null ? oldLp.getAllInterfaceNames() : null,
- newLp != null ? newLp.getAllInterfaceNames() : null);
+ oldLp != null ? oldLp.getAllInterfaceNames() : null, newLp.getAllInterfaceNames());
if (!interfaceDiff.added.isEmpty()) {
for (final String iface : interfaceDiff.added) {
try {
@@ -7622,12 +7710,13 @@
* Have netd update routes from oldLp to newLp.
* @return true if routes changed between oldLp and newLp
*/
- private boolean updateRoutes(LinkProperties newLp, LinkProperties oldLp, int netId) {
+ private boolean updateRoutes(@NonNull LinkProperties newLp, @Nullable LinkProperties oldLp,
+ int netId) {
// compare the route diff to determine which routes have been updated
final CompareOrUpdateResult<RouteInfo.RouteKey, RouteInfo> routeDiff =
new CompareOrUpdateResult<>(
oldLp != null ? oldLp.getAllRoutes() : null,
- newLp != null ? newLp.getAllRoutes() : null,
+ newLp.getAllRoutes(),
(r) -> r.getRouteKey());
// add routes before removing old in case it helps with continuous connectivity
@@ -7677,7 +7766,8 @@
|| !routeDiff.updated.isEmpty();
}
- private void updateDnses(LinkProperties newLp, LinkProperties oldLp, int netId) {
+ private void updateDnses(@NonNull LinkProperties newLp, @Nullable LinkProperties oldLp,
+ int netId) {
if (oldLp != null && newLp.isIdenticalDnses(oldLp)) {
return; // no updating necessary
}
@@ -7694,8 +7784,8 @@
}
}
- private void updateVpnFiltering(LinkProperties newLp, LinkProperties oldLp,
- NetworkAgentInfo nai) {
+ private void updateVpnFiltering(@NonNull LinkProperties newLp, @Nullable LinkProperties oldLp,
+ @NonNull NetworkAgentInfo nai) {
final String oldIface = getVpnIsolationInterface(nai, nai.networkCapabilities, oldLp);
final String newIface = getVpnIsolationInterface(nai, nai.networkCapabilities, newLp);
final boolean wasFiltering = requiresVpnAllowRule(nai, oldLp, oldIface);
@@ -7751,7 +7841,7 @@
@NonNull final NetworkCapabilities newNc) {
final int oldPermission = getNetworkPermission(nai.networkCapabilities);
final int newPermission = getNetworkPermission(newNc);
- if (oldPermission != newPermission && nai.created && !nai.isVPN()) {
+ if (oldPermission != newPermission && nai.isCreated() && !nai.isVPN()) {
try {
mNetd.networkSetPermissionForNetwork(nai.network.getNetId(), newPermission);
} catch (RemoteException | ServiceSpecificException e) {
@@ -7766,7 +7856,7 @@
@NonNull NetworkCapabilities agentCaps, @NonNull NetworkCapabilities newNc) {
underlyingNetworks = underlyingNetworksOrDefault(
agentCaps.getOwnerUid(), underlyingNetworks);
- long transportTypes = NetworkCapabilitiesUtils.packBits(agentCaps.getTransportTypes());
+ long transportTypes = BitUtils.packBits(agentCaps.getTransportTypes());
int downKbps = NetworkCapabilities.LINK_BANDWIDTH_UNSPECIFIED;
int upKbps = NetworkCapabilities.LINK_BANDWIDTH_UNSPECIFIED;
// metered if any underlying is metered, or originally declared metered by the agent.
@@ -7819,7 +7909,7 @@
suspended = false;
}
- newNc.setTransportTypes(NetworkCapabilitiesUtils.unpackBits(transportTypes));
+ newNc.setTransportTypes(BitUtils.unpackBits(transportTypes));
newNc.setLinkDownstreamBandwidthKbps(downKbps);
newNc.setLinkUpstreamBandwidthKbps(upKbps);
newNc.setCapability(NET_CAPABILITY_NOT_METERED, !metered);
@@ -7841,9 +7931,9 @@
// causing a connect/teardown loop.
// TODO: remove this altogether and make it the responsibility of the NetworkProviders to
// avoid connect/teardown loops.
- if (nai.everConnected &&
- !nai.isVPN() &&
- !nai.networkCapabilities.satisfiedByImmutableNetworkCapabilities(nc)) {
+ if (nai.everConnected()
+ && !nai.isVPN()
+ && !nai.networkCapabilities.satisfiedByImmutableNetworkCapabilities(nc)) {
// TODO: consider not complaining when a network agent degrades its capabilities if this
// does not cause any request (that is not a listen) currently matching that agent to
// stop being matched by the updated agent.
@@ -7855,12 +7945,12 @@
// Don't modify caller's NetworkCapabilities.
final NetworkCapabilities newNc = new NetworkCapabilities(nc);
- if (nai.lastValidated) {
+ if (nai.isValidated()) {
newNc.addCapability(NET_CAPABILITY_VALIDATED);
} else {
newNc.removeCapability(NET_CAPABILITY_VALIDATED);
}
- if (nai.lastCaptivePortalDetected) {
+ if (nai.captivePortalDetected()) {
newNc.addCapability(NET_CAPABILITY_CAPTIVE_PORTAL);
} else {
newNc.removeCapability(NET_CAPABILITY_CAPTIVE_PORTAL);
@@ -7870,7 +7960,7 @@
} else {
newNc.addCapability(NET_CAPABILITY_FOREGROUND);
}
- if (nai.partialConnectivity) {
+ if (nai.partialConnectivity()) {
newNc.addCapability(NET_CAPABILITY_PARTIAL_CONNECTIVITY);
} else {
newNc.removeCapability(NET_CAPABILITY_PARTIAL_CONNECTIVITY);
@@ -7931,6 +8021,10 @@
@NonNull final NetworkCapabilities nc) {
NetworkCapabilities newNc = mixInCapabilities(nai, nc);
if (Objects.equals(nai.networkCapabilities, newNc)) return;
+ final String differences = newNc.describeCapsDifferencesFrom(nai.networkCapabilities);
+ if (null != differences) {
+ Log.i(TAG, "Update capabilities for net " + nai.network + " : " + differences);
+ }
updateNetworkPermissions(nai, newNc);
final NetworkCapabilities prevNc = nai.getAndSetNetworkCapabilities(newNc);
@@ -8117,7 +8211,7 @@
// that happens to prevent false alarms.
final Set<UidRange> prevUids = prevNc == null ? null : prevNc.getUidRanges();
final Set<UidRange> newUids = newNc == null ? null : newNc.getUidRanges();
- if (nai.isVPN() && nai.everConnected && !UidRange.hasSameUids(prevUids, newUids)
+ if (nai.isVPN() && nai.everConnected() && !UidRange.hasSameUids(prevUids, newUids)
&& (nai.linkProperties.getHttpProxy() != null || isProxySetOnAnyDefaultNetwork())) {
mProxyTracker.sendProxyBroadcast();
}
@@ -8228,7 +8322,8 @@
}
}
- public void handleUpdateLinkProperties(NetworkAgentInfo nai, LinkProperties newLp) {
+ public void handleUpdateLinkProperties(@NonNull NetworkAgentInfo nai,
+ @NonNull LinkProperties newLp) {
ensureRunningOnConnectivityServiceThread();
if (!mNetworkAgentInfos.contains(nai)) {
@@ -8237,8 +8332,8 @@
}
if (VDBG || DDBG) {
log("Update of LinkProperties for " + nai.toShortString()
- + "; created=" + nai.created
- + "; everConnected=" + nai.everConnected);
+ + "; created=" + nai.getCreatedTime()
+ + "; firstConnected=" + nai.getConnectedTime());
}
// TODO: eliminate this defensive copy after confirming that updateLinkProperties does not
// modify its oldLp parameter.
@@ -8670,7 +8765,7 @@
}
previousSatisfier.removeRequest(previousRequest.requestId);
if (canSupportGracefulNetworkSwitch(previousSatisfier, newSatisfier)
- && !previousSatisfier.destroyed) {
+ && !previousSatisfier.isDestroyed()) {
// If this network switch can't be supported gracefully, the request is not
// lingered. This allows letting go of the network sooner to reclaim some
// performance on the new network, since the radio can't do both at the same
@@ -8732,9 +8827,6 @@
// Gather the list of all relevant agents.
final ArrayList<NetworkAgentInfo> nais = new ArrayList<>();
for (final NetworkAgentInfo nai : mNetworkAgentInfos) {
- if (!nai.everConnected) {
- continue;
- }
nais.add(nai);
}
@@ -8858,7 +8950,6 @@
}
for (final NetworkAgentInfo nai : nais) {
- if (!nai.everConnected) continue;
final boolean oldBackground = oldBgNetworks.contains(nai);
// Process listen requests and update capabilities if the background state has
// changed for this network. For consistency with previous behavior, send onLost
@@ -8942,7 +9033,7 @@
// The new default network can be newly null if and only if the old default
// network doesn't satisfy the default request any more because it lost a
// capability.
- mDefaultInetConditionPublished = newDefaultNetwork.lastValidated ? 100 : 0;
+ mDefaultInetConditionPublished = newDefaultNetwork.isValidated() ? 100 : 0;
mLegacyTypeTracker.add(
newDefaultNetwork.networkInfo.getType(), newDefaultNetwork);
}
@@ -8963,7 +9054,7 @@
// they may get old info. Reverse this after the old startUsing api is removed.
// This is on top of the multiple intent sequencing referenced in the todo above.
for (NetworkAgentInfo nai : nais) {
- if (nai.everConnected) {
+ if (nai.everConnected()) {
addNetworkToLegacyTypeTracker(nai);
}
}
@@ -9089,12 +9180,12 @@
private void updateInetCondition(NetworkAgentInfo nai) {
// Don't bother updating until we've graduated to validated at least once.
- if (!nai.everValidated) return;
+ if (!nai.everValidated()) return;
// For now only update icons for the default connection.
// TODO: Update WiFi and cellular icons separately. b/17237507
if (!isDefaultNetwork(nai)) return;
- int newInetCondition = nai.lastValidated ? 100 : 0;
+ int newInetCondition = nai.isValidated() ? 100 : 0;
// Don't repeat publish.
if (newInetCondition == mDefaultInetConditionPublished) return;
@@ -9121,7 +9212,7 @@
// SUSPENDED state is currently only overridden from CONNECTED state. In the case the
// network agent is created, then goes to suspended, then goes out of suspended without
// ever setting connected. Check if network agent is ever connected to update the state.
- newInfo.setDetailedState(nai.everConnected
+ newInfo.setDetailedState(nai.everConnected()
? NetworkInfo.DetailedState.CONNECTED
: NetworkInfo.DetailedState.CONNECTING,
info.getReason(),
@@ -9146,7 +9237,7 @@
+ oldInfo.getState() + " to " + state);
}
- if (!networkAgent.created
+ if (!networkAgent.isCreated()
&& (state == NetworkInfo.State.CONNECTED
|| (state == NetworkInfo.State.CONNECTING && networkAgent.isVPN()))) {
@@ -9160,13 +9251,13 @@
// anything happens to the network.
updateCapabilitiesForNetwork(networkAgent);
}
- networkAgent.created = true;
+ networkAgent.setCreated();
networkAgent.onNetworkCreated();
updateAllowedUids(networkAgent, null, networkAgent.networkCapabilities);
}
- if (!networkAgent.everConnected && state == NetworkInfo.State.CONNECTED) {
- networkAgent.everConnected = true;
+ if (!networkAgent.everConnected() && state == NetworkInfo.State.CONNECTED) {
+ networkAgent.setConnected();
// NetworkCapabilities need to be set before sending the private DNS config to
// NetworkMonitor, otherwise NetworkMonitor cannot determine if validation is required.
@@ -9211,7 +9302,10 @@
networkAgent.networkMonitor().notifyNetworkConnected(params.linkProperties,
params.networkCapabilities);
}
- scheduleUnvalidatedPrompt(networkAgent);
+ final long delay = activelyPreferBadWifi()
+ ? ACTIVELY_PREFER_BAD_WIFI_INITIAL_TIMEOUT_MS
+ : DONT_ACTIVELY_PREFER_BAD_WIFI_INITIAL_TIMEOUT_MS;
+ scheduleEvaluationTimeout(networkAgent.network, delay);
// Whether a particular NetworkRequest listen should cause signal strength thresholds to
// be communicated to a particular NetworkAgent depends only on the network's immutable,
@@ -9250,8 +9344,8 @@
// TODO(b/122649188): send the broadcast only to VPN users.
mProxyTracker.sendProxyBroadcast();
}
- } else if (networkAgent.created && (oldInfo.getState() == NetworkInfo.State.SUSPENDED ||
- state == NetworkInfo.State.SUSPENDED)) {
+ } else if (networkAgent.isCreated() && (oldInfo.getState() == NetworkInfo.State.SUSPENDED
+ || state == NetworkInfo.State.SUSPENDED)) {
mLegacyTypeTracker.update(networkAgent);
}
}
@@ -9451,7 +9545,7 @@
}
}
for (NetworkAgentInfo nai : mNetworkAgentInfos) {
- if (nai.everConnected && (activeNetIds.contains(nai.network().netId) || nai.isVPN())) {
+ if (activeNetIds.contains(nai.network().netId) || nai.isVPN()) {
defaultNetworks.add(nai.network);
}
}
@@ -9625,6 +9719,8 @@
try {
switch (cmd) {
case "airplane-mode":
+ // Usage : adb shell cmd connectivity airplane-mode [enable|disable]
+ // If no argument, get and display the current status
final String action = getNextArg();
if ("enable".equals(action)) {
setAirplaneMode(true);
@@ -9642,6 +9738,27 @@
onHelp();
return -1;
}
+ case "reevaluate":
+ // Usage : adb shell cmd connectivity reevaluate <netId>
+ // If netId is omitted, then reevaluate the default network
+ final String netId = getNextArg();
+ final NetworkAgentInfo nai;
+ if (null == netId) {
+ // Note that the command is running on the wrong thread to call this,
+ // so this could in principle return stale data. But it can't crash.
+ nai = getDefaultNetwork();
+ } else {
+ // If netId can't be parsed, this throws NumberFormatException, which
+ // is passed back to adb who prints it.
+ nai = getNetworkAgentInfoForNetId(Integer.parseInt(netId));
+ }
+ if (null == nai) {
+ pw.println("Unknown network (net ID not found or no default network)");
+ return 0;
+ }
+ Log.d(TAG, "Reevaluating network " + nai.network);
+ reportNetworkConnectivity(nai.network, !nai.isValidated());
+ return 0;
default:
return handleDefaultCommands(cmd);
}
@@ -9671,15 +9788,15 @@
return ((VpnTransportInfo) ti).getType();
}
- private void maybeUpdateWifiRoamTimestamp(NetworkAgentInfo nai, NetworkCapabilities nc) {
- if (nai == null) return;
+ private void maybeUpdateWifiRoamTimestamp(@NonNull NetworkAgentInfo nai,
+ @NonNull NetworkCapabilities nc) {
final TransportInfo prevInfo = nai.networkCapabilities.getTransportInfo();
final TransportInfo newInfo = nc.getTransportInfo();
if (!(prevInfo instanceof WifiInfo) || !(newInfo instanceof WifiInfo)) {
return;
}
if (!TextUtils.equals(((WifiInfo)prevInfo).getBSSID(), ((WifiInfo)newInfo).getBSSID())) {
- nai.lastRoamTimestamp = SystemClock.elapsedRealtime();
+ nai.lastRoamTime = SystemClock.elapsedRealtime();
}
}
diff --git a/service/src/com/android/server/UidOwnerValue.java b/service/src/com/android/server/UidOwnerValue.java
index f89e354..d6c0e0d 100644
--- a/service/src/com/android/server/UidOwnerValue.java
+++ b/service/src/com/android/server/UidOwnerValue.java
@@ -21,14 +21,14 @@
/** Value type for per uid traffic control configuration map */
public class UidOwnerValue extends Struct {
// Allowed interface index. Only applicable if IIF_MATCH is set in the rule bitmask below.
- @Field(order = 0, type = Type.U32)
- public final long iif;
+ @Field(order = 0, type = Type.S32)
+ public final int iif;
// A bitmask of match type.
@Field(order = 1, type = Type.U32)
public final long rule;
- public UidOwnerValue(final long iif, final long rule) {
+ public UidOwnerValue(final int iif, final long rule) {
this.iif = iif;
this.rule = rule;
}
diff --git a/service/src/com/android/server/connectivity/ClatCoordinator.java b/service/src/com/android/server/connectivity/ClatCoordinator.java
index e1c7b64..5d04632 100644
--- a/service/src/com/android/server/connectivity/ClatCoordinator.java
+++ b/service/src/com/android/server/connectivity/ClatCoordinator.java
@@ -113,12 +113,12 @@
return "/sys/fs/bpf/net_shared/map_clatd_clat_" + which + "_map";
}
- private static String makeProgPath(boolean ingress, boolean ether) {
- String path = "/sys/fs/bpf/net_shared/prog_clatd_schedcls_"
- + (ingress ? "ingress6" : "egress4")
- + "_clat_"
+ private static final String CLAT_EGRESS4_RAWIP_PROG_PATH =
+ "/sys/fs/bpf/net_shared/prog_clatd_schedcls_egress4_clat_rawip";
+
+ private static String makeIngressProgPath(boolean ether) {
+ return "/sys/fs/bpf/net_shared/prog_clatd_schedcls_ingress6_clat_"
+ (ether ? "ether" : "rawip");
- return path;
}
@NonNull
@@ -183,8 +183,8 @@
*/
@NonNull
public String generateIpv6Address(@NonNull String iface, @NonNull String v4,
- @NonNull String prefix64) throws IOException {
- return native_generateIpv6Address(iface, v4, prefix64);
+ @NonNull String prefix64, int mark) throws IOException {
+ return native_generateIpv6Address(iface, v4, prefix64, mark);
}
/**
@@ -478,7 +478,7 @@
// tc filter add dev .. egress prio 4 protocol ip bpf object-pinned /sys/fs/bpf/...
// direct-action
mDeps.tcFilterAddDevBpf(tracker.v4ifIndex, EGRESS, (short) PRIO_CLAT, (short) ETH_P_IP,
- makeProgPath(EGRESS, RAWIP));
+ CLAT_EGRESS4_RAWIP_PROG_PATH);
} catch (IOException e) {
Log.e(TAG, "tc filter add dev (" + tracker.v4ifIndex + "[" + tracker.v4iface
+ "]) egress prio PRIO_CLAT protocol ip failure: " + e);
@@ -504,7 +504,7 @@
// tc filter add dev .. ingress prio 4 protocol ipv6 bpf object-pinned /sys/fs/bpf/...
// direct-action
mDeps.tcFilterAddDevBpf(tracker.ifIndex, INGRESS, (short) PRIO_CLAT,
- (short) ETH_P_IPV6, makeProgPath(INGRESS, isEthernet));
+ (short) ETH_P_IPV6, makeIngressProgPath(isEthernet));
} catch (IOException e) {
Log.e(TAG, "tc filter add dev (" + tracker.ifIndex + "[" + tracker.iface
+ "]) ingress prio PRIO_CLAT protocol ipv6 failure: " + e);
@@ -595,13 +595,17 @@
Log.i(TAG, "untag socket cookie " + cookie);
}
+ private boolean isStarted() {
+ return mClatdTracker != null;
+ }
+
/**
* Start clatd for a given interface and NAT64 prefix.
*/
public String clatStart(final String iface, final int netId,
@NonNull final IpPrefix nat64Prefix)
throws IOException {
- if (mClatdTracker != null) {
+ if (isStarted()) {
throw new IOException("Clatd is already running on " + mClatdTracker.iface
+ " (pid " + mClatdTracker.pid + ")");
}
@@ -625,10 +629,11 @@
}
// [2] Generate a checksum-neutral IID.
+ final Integer fwmark = getFwmark(netId);
final String pfx96Str = nat64Prefix.getAddress().getHostAddress();
final String v6Str;
try {
- v6Str = mDeps.generateIpv6Address(iface, v4Str, pfx96Str);
+ v6Str = mDeps.generateIpv6Address(iface, v4Str, pfx96Str, fwmark);
} catch (IOException e) {
throw new IOException("no IPv6 addresses were available for clat: " + e);
}
@@ -672,7 +677,6 @@
}
// Detect ipv4 mtu.
- final Integer fwmark = getFwmark(netId);
final int detectedMtu;
try {
detectedMtu = mDeps.detectMtu(pfx96Str,
@@ -833,7 +837,7 @@
* Stop clatd
*/
public void clatStop() throws IOException {
- if (mClatdTracker == null) {
+ if (!isStarted()) {
throw new IOException("Clatd has not started");
}
Log.i(TAG, "Stopping clatd pid=" + mClatdTracker.pid + " on " + mClatdTracker.iface);
@@ -895,19 +899,23 @@
}
/**
- * Dump the cordinator information.
+ * Dump the coordinator information.
*
* @param pw print writer.
*/
public void dump(@NonNull IndentingPrintWriter pw) {
// TODO: move map dump to a global place to avoid duplicate dump while there are two or
// more IPv6 only networks.
- pw.println("CLAT tracker: " + mClatdTracker.toString());
- pw.println("Forwarding rules:");
- pw.increaseIndent();
- dumpBpfIngress(pw);
- dumpBpfEgress(pw);
- pw.decreaseIndent();
+ if (isStarted()) {
+ pw.println("CLAT tracker: " + mClatdTracker);
+ pw.println("Forwarding rules:");
+ pw.increaseIndent();
+ dumpBpfIngress(pw);
+ dumpBpfEgress(pw);
+ pw.decreaseIndent();
+ } else {
+ pw.println("<not started>");
+ }
pw.println();
}
@@ -923,7 +931,7 @@
private static native String native_selectIpv4Address(String v4addr, int prefixlen)
throws IOException;
private static native String native_generateIpv6Address(String iface, String v4,
- String prefix64) throws IOException;
+ String prefix64, int mark) throws IOException;
private static native int native_createTunInterface(String tuniface) throws IOException;
private static native int native_detectMtu(String platSubnet, int platSuffix, int mark)
throws IOException;
diff --git a/service/src/com/android/server/connectivity/DscpPolicyValue.java b/service/src/com/android/server/connectivity/DscpPolicyValue.java
index fed96b4..7b11eda 100644
--- a/service/src/com/android/server/connectivity/DscpPolicyValue.java
+++ b/service/src/com/android/server/connectivity/DscpPolicyValue.java
@@ -37,8 +37,8 @@
@Field(order = 1, type = Type.ByteArray, arraysize = 16)
public final byte[] dst46;
- @Field(order = 2, type = Type.U32)
- public final long ifIndex;
+ @Field(order = 2, type = Type.S32)
+ public final int ifIndex;
@Field(order = 3, type = Type.UBE16)
public final int srcPort;
@@ -116,7 +116,7 @@
return mask;
}
- private DscpPolicyValue(final InetAddress src46, final InetAddress dst46, final long ifIndex,
+ private DscpPolicyValue(final InetAddress src46, final InetAddress dst46, final int ifIndex,
final int srcPort, final int dstPortStart, final int dstPortEnd, final short proto,
final byte dscp) {
this.src46 = toAddressField(src46);
@@ -136,7 +136,7 @@
this.mask = makeMask(this.src46, this.dst46, srcPort, dstPortStart, proto, dscp);
}
- public DscpPolicyValue(final InetAddress src46, final InetAddress dst46, final long ifIndex,
+ public DscpPolicyValue(final InetAddress src46, final InetAddress dst46, final int ifIndex,
final int srcPort, final Range<Integer> dstPort, final short proto,
final byte dscp) {
this(src46, dst46, ifIndex, srcPort, dstPort != null ? dstPort.getLower() : -1,
diff --git a/service/src/com/android/server/connectivity/FullScore.java b/service/src/com/android/server/connectivity/FullScore.java
index c4754eb..2303894 100644
--- a/service/src/com/android/server/connectivity/FullScore.java
+++ b/service/src/com/android/server/connectivity/FullScore.java
@@ -23,8 +23,10 @@
import static android.net.NetworkScore.KEEP_CONNECTED_NONE;
import static android.net.NetworkScore.POLICY_YIELD_TO_BAD_WIFI;
-import android.annotation.IntDef;
+import static com.android.net.module.util.BitUtils.appendStringRepresentationOfBitMaskToStringBuilder;
+
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.net.NetworkAgentConfig;
import android.net.NetworkCapabilities;
import android.net.NetworkScore;
@@ -35,8 +37,6 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.MessageUtils;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
import java.util.StringJoiner;
/**
@@ -49,53 +49,54 @@
public class FullScore {
private static final String TAG = FullScore.class.getSimpleName();
- /** @hide */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(prefix = {"POLICY_"}, value = {
- POLICY_IS_VALIDATED,
- POLICY_IS_VPN,
- POLICY_EVER_USER_SELECTED,
- POLICY_ACCEPT_UNVALIDATED,
- POLICY_IS_UNMETERED
- })
- public @interface Policy {
- }
-
// Agent-managed policies are in NetworkScore. They start from 1.
// CS-managed policies, counting from 63 downward
// This network is validated. CS-managed because the source of truth is in NetworkCapabilities.
/** @hide */
public static final int POLICY_IS_VALIDATED = 63;
+ // This network has been validated at least once since it was connected.
+ /** @hide */
+ public static final int POLICY_EVER_VALIDATED = 62;
+
// This is a VPN and behaves as one for scoring purposes.
/** @hide */
- public static final int POLICY_IS_VPN = 62;
+ public static final int POLICY_IS_VPN = 61;
// This network has been selected by the user manually from settings or a 3rd party app
// at least once. @see NetworkAgentConfig#explicitlySelected.
/** @hide */
- public static final int POLICY_EVER_USER_SELECTED = 61;
+ public static final int POLICY_EVER_USER_SELECTED = 60;
// The user has indicated in UI that this network should be used even if it doesn't
// validate. @see NetworkAgentConfig#acceptUnvalidated.
/** @hide */
- public static final int POLICY_ACCEPT_UNVALIDATED = 60;
+ public static final int POLICY_ACCEPT_UNVALIDATED = 59;
+
+ // The user explicitly said in UI to avoid this network when unvalidated.
+ // TODO : remove setAvoidUnvalidated and instead disconnect the network when the user
+ // chooses to move away from this network, and remove this flag.
+ /** @hide */
+ public static final int POLICY_AVOIDED_WHEN_UNVALIDATED = 58;
// This network is unmetered. @see NetworkCapabilities.NET_CAPABILITY_NOT_METERED.
/** @hide */
- public static final int POLICY_IS_UNMETERED = 59;
+ public static final int POLICY_IS_UNMETERED = 57;
// This network is invincible. This is useful for offers until there is an API to listen
// to requests.
/** @hide */
- public static final int POLICY_IS_INVINCIBLE = 58;
+ public static final int POLICY_IS_INVINCIBLE = 56;
- // This network has been validated at least once since it was connected, but not explicitly
- // avoided in UI.
- // TODO : remove setAvoidUnvalidated and instead disconnect the network when the user
- // chooses to move away from this network, and remove this flag.
- /** @hide */
- public static final int POLICY_EVER_VALIDATED_NOT_AVOIDED_WHEN_BAD = 57;
+ // This network has undergone initial validation.
+ //
+ // The stack considers that any result finding some working connectivity (valid, partial,
+ // captive portal) is an initial validation. Negative result (not valid), however, is not
+ // considered initial validation until {@link ConnectivityService#PROMPT_UNVALIDATED_DELAY_MS}
+ // have elapsed. This is because some networks may spuriously fail for a short time immediately
+ // after associating. If no positive result is found after the timeout has elapsed, then
+ // the network has been evaluated once.
+ public static final int POLICY_EVER_EVALUATED = 55;
// The network agent has communicated that this network no longer functions, and the underlying
// native network has been destroyed. The network will still be reported to clients as connected
@@ -103,7 +104,7 @@
// This network should lose to an identical network that has not been destroyed, but should
// otherwise be scored exactly the same.
/** @hide */
- public static final int POLICY_IS_DESTROYED = 56;
+ public static final int POLICY_IS_DESTROYED = 54;
// To help iterate when printing
@VisibleForTesting
@@ -154,7 +155,9 @@
* @param caps the NetworkCapabilities of the network
* @param config the NetworkAgentConfig of the network
* @param everValidated whether this network has ever validated
+ * @param avoidUnvalidated whether the user said in UI to avoid this network when unvalidated
* @param yieldToBadWiFi whether this network yields to a previously validated wifi gone bad
+ * @param everEvaluated whether this network ever evaluated at least once
* @param destroyed whether this network has been destroyed pending a replacement connecting
* @return a FullScore that is appropriate to use for ranking.
*/
@@ -163,18 +166,20 @@
// connectivity for backward compatibility.
public static FullScore fromNetworkScore(@NonNull final NetworkScore score,
@NonNull final NetworkCapabilities caps, @NonNull final NetworkAgentConfig config,
- final boolean everValidated, final boolean yieldToBadWiFi, final boolean destroyed) {
+ final boolean everValidated, final boolean avoidUnvalidated,
+ final boolean yieldToBadWiFi, final boolean everEvaluated, final boolean destroyed) {
return withPolicies(score.getPolicies(),
score.getKeepConnectedReason(),
caps.hasCapability(NET_CAPABILITY_VALIDATED),
- caps.hasTransport(TRANSPORT_VPN),
- caps.hasCapability(NET_CAPABILITY_NOT_METERED),
- everValidated,
+ everValidated, caps.hasTransport(TRANSPORT_VPN),
config.explicitlySelected,
config.acceptUnvalidated,
+ avoidUnvalidated,
+ caps.hasCapability(NET_CAPABILITY_NOT_METERED),
yieldToBadWiFi,
- destroyed,
- false /* invincible */); // only prospective scores can be invincible
+ false /* invincible */, // only prospective scores can be invincible
+ everEvaluated,
+ destroyed);
}
/**
@@ -194,25 +199,31 @@
@NonNull final NetworkCapabilities caps, final boolean yieldToBadWiFi) {
// If the network offers Internet access, it may validate.
final boolean mayValidate = caps.hasCapability(NET_CAPABILITY_INTERNET);
- // VPN transports are known in advance.
- final boolean vpn = caps.hasTransport(TRANSPORT_VPN);
- // Prospective scores are always unmetered, because unmetered networks are stronger
- // than metered networks, and it's not known in advance whether the network is metered.
- final boolean unmetered = true;
// If the offer may validate, then it should be considered to have validated at some point
final boolean everValidated = mayValidate;
+ // VPN transports are known in advance.
+ final boolean vpn = caps.hasTransport(TRANSPORT_VPN);
// The network hasn't been chosen by the user (yet, at least).
final boolean everUserSelected = false;
// Don't assume the user will accept unvalidated connectivity.
final boolean acceptUnvalidated = false;
- // A network can only be destroyed once it has connected.
- final boolean destroyed = false;
+ // A prospective network is never avoided when unvalidated, because the user has never
+ // had the opportunity to say so in UI.
+ final boolean avoidUnvalidated = false;
+ // Prospective scores are always unmetered, because unmetered networks are stronger
+ // than metered networks, and it's not known in advance whether the network is metered.
+ final boolean unmetered = true;
// A prospective score is invincible if the legacy int in the filter is over the maximum
// score.
final boolean invincible = score.getLegacyInt() > NetworkRanker.LEGACY_INT_MAX;
+ // A prospective network will eventually be evaluated.
+ final boolean everEvaluated = true;
+ // A network can only be destroyed once it has connected.
+ final boolean destroyed = false;
return withPolicies(score.getPolicies(), KEEP_CONNECTED_NONE,
- mayValidate, vpn, unmetered, everValidated, everUserSelected, acceptUnvalidated,
- yieldToBadWiFi, destroyed, invincible);
+ mayValidate, everValidated, vpn, everUserSelected,
+ acceptUnvalidated, avoidUnvalidated, unmetered, yieldToBadWiFi,
+ invincible, everEvaluated, destroyed);
}
/**
@@ -228,18 +239,21 @@
public FullScore mixInScore(@NonNull final NetworkCapabilities caps,
@NonNull final NetworkAgentConfig config,
final boolean everValidated,
+ final boolean avoidUnvalidated,
final boolean yieldToBadWifi,
+ final boolean everEvaluated,
final boolean destroyed) {
return withPolicies(mPolicies, mKeepConnectedReason,
caps.hasCapability(NET_CAPABILITY_VALIDATED),
- caps.hasTransport(TRANSPORT_VPN),
- caps.hasCapability(NET_CAPABILITY_NOT_METERED),
- everValidated,
+ everValidated, caps.hasTransport(TRANSPORT_VPN),
config.explicitlySelected,
config.acceptUnvalidated,
+ avoidUnvalidated,
+ caps.hasCapability(NET_CAPABILITY_NOT_METERED),
yieldToBadWifi,
- destroyed,
- false /* invincible */); // only prospective scores can be invincible
+ false /* invincible */, // only prospective scores can be invincible
+ everEvaluated,
+ destroyed);
}
// TODO : this shouldn't manage bad wifi avoidance – instead this should be done by the
@@ -248,24 +262,28 @@
private static FullScore withPolicies(final long externalPolicies,
@KeepConnectedReason final int keepConnectedReason,
final boolean isValidated,
- final boolean isVpn,
- final boolean isUnmetered,
final boolean everValidated,
+ final boolean isVpn,
final boolean everUserSelected,
final boolean acceptUnvalidated,
+ final boolean avoidUnvalidated,
+ final boolean isUnmetered,
final boolean yieldToBadWiFi,
- final boolean destroyed,
- final boolean invincible) {
+ final boolean invincible,
+ final boolean everEvaluated,
+ final boolean destroyed) {
return new FullScore((externalPolicies & EXTERNAL_POLICIES_MASK)
| (isValidated ? 1L << POLICY_IS_VALIDATED : 0)
+ | (everValidated ? 1L << POLICY_EVER_VALIDATED : 0)
| (isVpn ? 1L << POLICY_IS_VPN : 0)
- | (isUnmetered ? 1L << POLICY_IS_UNMETERED : 0)
- | (everValidated ? 1L << POLICY_EVER_VALIDATED_NOT_AVOIDED_WHEN_BAD : 0)
| (everUserSelected ? 1L << POLICY_EVER_USER_SELECTED : 0)
| (acceptUnvalidated ? 1L << POLICY_ACCEPT_UNVALIDATED : 0)
+ | (avoidUnvalidated ? 1L << POLICY_AVOIDED_WHEN_UNVALIDATED : 0)
+ | (isUnmetered ? 1L << POLICY_IS_UNMETERED : 0)
| (yieldToBadWiFi ? 1L << POLICY_YIELD_TO_BAD_WIFI : 0)
- | (destroyed ? 1L << POLICY_IS_DESTROYED : 0)
- | (invincible ? 1L << POLICY_IS_INVINCIBLE : 0),
+ | (invincible ? 1L << POLICY_IS_INVINCIBLE : 0)
+ | (everEvaluated ? 1L << POLICY_EVER_EVALUATED : 0)
+ | (destroyed ? 1L << POLICY_IS_DESTROYED : 0),
keepConnectedReason);
}
@@ -318,6 +336,35 @@
+ 5 * mKeepConnectedReason;
}
+ /**
+ * Returns a short but human-readable string of updates from an older score.
+ * @param old the old capabilities to diff from
+ * @return a string fit for logging differences, or null if no differences.
+ * this method cannot return the empty string.
+ */
+ @Nullable
+ public String describeDifferencesFrom(@Nullable final FullScore old) {
+ final long oldPolicies = null == old ? 0 : old.mPolicies;
+ final long changed = oldPolicies ^ mPolicies;
+ if (0 == changed) return null;
+ // If the control reaches here, there are changes (additions, removals, or both) so
+ // the code below is guaranteed to add something to the string and can't return "".
+ final long removed = oldPolicies & changed;
+ final long added = mPolicies & changed;
+ final StringBuilder sb = new StringBuilder();
+ if (0 != removed) {
+ sb.append("-");
+ appendStringRepresentationOfBitMaskToStringBuilder(sb, removed,
+ FullScore::policyNameOf, "-");
+ }
+ if (0 != added) {
+ sb.append("+");
+ appendStringRepresentationOfBitMaskToStringBuilder(sb, added,
+ FullScore::policyNameOf, "+");
+ }
+ return sb.toString();
+ }
+
// Example output :
// Score(Policies : EVER_USER_SELECTED&IS_VALIDATED ; KeepConnected : )
@Override
diff --git a/service/src/com/android/server/connectivity/LingerMonitor.java b/service/src/com/android/server/connectivity/LingerMonitor.java
index 032612c..df34ce7 100644
--- a/service/src/com/android/server/connectivity/LingerMonitor.java
+++ b/service/src/com/android/server/connectivity/LingerMonitor.java
@@ -229,8 +229,8 @@
@Nullable final NetworkAgentInfo toNai) {
if (VDBG) {
Log.d(TAG, "noteLingerDefaultNetwork from=" + fromNai.toShortString()
- + " everValidated=" + fromNai.everValidated
- + " lastValidated=" + fromNai.lastValidated
+ + " firstValidated=" + fromNai.getFirstValidationTime()
+ + " lastValidated=" + fromNai.getCurrentValidationTime()
+ " to=" + toNai.toShortString());
}
@@ -253,7 +253,7 @@
// 1. User connects to wireless printer.
// 2. User turns on cellular data.
// 3. We show a notification.
- if (!fromNai.everValidated) return;
+ if (!fromNai.everValidated()) return;
// If this network is a captive portal, don't notify. This cannot happen on initial connect
// to a captive portal, because the everValidated check above will fail. However, it can
@@ -286,7 +286,7 @@
// because its score changed.
// TODO: instead of just skipping notification, keep a note of it, and show it if it becomes
// unvalidated.
- if (fromNai.lastValidated) return;
+ if (fromNai.isValidated()) return;
if (!isNotificationEnabled(fromNai, toNai)) return;
diff --git a/service/src/com/android/server/connectivity/MultinetworkPolicyTracker.java b/service/src/com/android/server/connectivity/MultinetworkPolicyTracker.java
new file mode 100644
index 0000000..58196f7
--- /dev/null
+++ b/service/src/com/android/server/connectivity/MultinetworkPolicyTracker.java
@@ -0,0 +1,387 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.connectivity;
+
+import static android.net.ConnectivitySettingsManager.NETWORK_AVOID_BAD_WIFI;
+import static android.net.ConnectivitySettingsManager.NETWORK_METERED_MULTIPATH_PREFERENCE;
+
+import android.annotation.NonNull;
+import android.annotation.TargetApi;
+import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.res.Resources;
+import android.database.ContentObserver;
+import android.net.ConnectivityResources;
+import android.net.Uri;
+import android.os.Build;
+import android.os.Handler;
+import android.provider.DeviceConfig;
+import android.provider.Settings;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyCallback;
+import android.telephony.TelephonyManager;
+import android.util.Log;
+
+import com.android.connectivity.resources.R;
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.modules.utils.build.SdkLevel;
+import com.android.net.module.util.DeviceConfigUtils;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.Executor;
+import java.util.concurrent.RejectedExecutionException;
+
+/**
+ * A class to encapsulate management of the "Smart Networking" capability of
+ * avoiding bad Wi-Fi when, for example upstream connectivity is lost or
+ * certain critical link failures occur.
+ *
+ * This enables the device to switch to another form of connectivity, like
+ * mobile, if it's available and working.
+ *
+ * The Runnable |avoidBadWifiCallback|, if given, is posted to the supplied
+ * Handler' whenever the computed "avoid bad wifi" value changes.
+ *
+ * Disabling this reverts the device to a level of networking sophistication
+ * circa 2012-13 by disabling disparate code paths each of which contribute to
+ * maintaining continuous, working Internet connectivity.
+ *
+ * @hide
+ */
+public class MultinetworkPolicyTracker {
+ private static String TAG = MultinetworkPolicyTracker.class.getSimpleName();
+
+ // See Dependencies#getConfigActivelyPreferBadWifi
+ public static final String CONFIG_ACTIVELY_PREFER_BAD_WIFI = "actively_prefer_bad_wifi";
+
+ private final Context mContext;
+ private final ConnectivityResources mResources;
+ private final Handler mHandler;
+ private final Runnable mAvoidBadWifiCallback;
+ private final List<Uri> mSettingsUris;
+ private final ContentResolver mResolver;
+ private final SettingObserver mSettingObserver;
+ private final BroadcastReceiver mBroadcastReceiver;
+
+ private volatile boolean mAvoidBadWifi = true;
+ private volatile int mMeteredMultipathPreference;
+ private int mActiveSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+ private volatile long mTestAllowBadWifiUntilMs = 0;
+
+ /**
+ * Dependencies for testing
+ */
+ @VisibleForTesting
+ public static class Dependencies {
+ /**
+ * @see DeviceConfigUtils#getDeviceConfigPropertyInt
+ */
+ protected int getConfigActivelyPreferBadWifi() {
+ // CONFIG_ACTIVELY_PREFER_BAD_WIFI is not a feature to be rolled out, but an override
+ // for tests and an emergency kill switch (which could force the behavior on OR off).
+ // As such it uses a -1/null/1 scheme, but features should use
+ // DeviceConfigUtils#isFeatureEnabled instead, to make sure rollbacks disable the
+ // feature before it's ready on R and before.
+ return DeviceConfig.getInt(DeviceConfig.NAMESPACE_CONNECTIVITY,
+ CONFIG_ACTIVELY_PREFER_BAD_WIFI, 0);
+ }
+
+ /**
+ @see DeviceConfig#addOnPropertiesChangedListener
+ */
+ protected void addOnDevicePropertiesChangedListener(@NonNull final Executor executor,
+ @NonNull final DeviceConfig.OnPropertiesChangedListener listener) {
+ DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_CONNECTIVITY,
+ executor, listener);
+ }
+
+ @VisibleForTesting
+ @NonNull
+ protected Resources getResourcesForActiveSubId(
+ @NonNull final ConnectivityResources resources, final int activeSubId) {
+ return SubscriptionManager.getResourcesForSubId(
+ resources.getResourcesContext(), activeSubId);
+ }
+ }
+ private final Dependencies mDeps;
+
+ /**
+ * Whether to prefer bad wifi to a network that yields to bad wifis, even if it never validated
+ *
+ * This setting only makes sense if the system is configured not to avoid bad wifis, i.e.
+ * if mAvoidBadWifi is true. If it's not, then no network ever yields to bad wifis
+ * ({@see FullScore#POLICY_YIELD_TO_BAD_WIFI}) and this setting has therefore no effect.
+ *
+ * If this is false, when ranking a bad wifi that never validated against cell data (or any
+ * network that yields to bad wifis), the ranker will prefer cell data. It will prefer wifi
+ * if wifi loses validation later. This behavior avoids the device losing internet access when
+ * walking past a wifi network with no internet access.
+ * This is the default behavior up to Android T, but it can be overridden through an overlay
+ * to behave like below.
+ *
+ * If this is true, then in the same scenario, the ranker will prefer cell data until
+ * the wifi completes its first validation attempt (or the attempt times out after
+ * ConnectivityService#PROMPT_UNVALIDATED_DELAY_MS), then it will prefer the wifi even if it
+ * doesn't provide internet access, unless there is a captive portal on that wifi.
+ * This is the behavior in U and above.
+ */
+ private boolean mActivelyPreferBadWifi;
+
+ // Mainline module can't use internal HandlerExecutor, so add an identical executor here.
+ private static class HandlerExecutor implements Executor {
+ @NonNull
+ private final Handler mHandler;
+
+ HandlerExecutor(@NonNull Handler handler) {
+ mHandler = handler;
+ }
+ @Override
+ public void execute(Runnable command) {
+ if (!mHandler.post(command)) {
+ throw new RejectedExecutionException(mHandler + " is shutting down");
+ }
+ }
+ }
+ // TODO: Set the mini sdk to 31 and remove @TargetApi annotation when b/205923322 is addressed.
+ @VisibleForTesting @TargetApi(Build.VERSION_CODES.S)
+ protected class ActiveDataSubscriptionIdListener extends TelephonyCallback
+ implements TelephonyCallback.ActiveDataSubscriptionIdListener {
+ @Override
+ public void onActiveDataSubscriptionIdChanged(int subId) {
+ mActiveSubId = subId;
+ reevaluateInternal();
+ }
+ }
+
+ public MultinetworkPolicyTracker(Context ctx, Handler handler, Runnable avoidBadWifiCallback) {
+ this(ctx, handler, avoidBadWifiCallback, new Dependencies());
+ }
+
+ public MultinetworkPolicyTracker(Context ctx, Handler handler, Runnable avoidBadWifiCallback,
+ Dependencies deps) {
+ mContext = ctx;
+ mResources = new ConnectivityResources(ctx);
+ mHandler = handler;
+ mAvoidBadWifiCallback = avoidBadWifiCallback;
+ mDeps = deps;
+ mSettingsUris = Arrays.asList(
+ Settings.Global.getUriFor(NETWORK_AVOID_BAD_WIFI),
+ Settings.Global.getUriFor(NETWORK_METERED_MULTIPATH_PREFERENCE));
+ mResolver = mContext.getContentResolver();
+ mSettingObserver = new SettingObserver();
+ mBroadcastReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ reevaluateInternal();
+ }
+ };
+
+ updateAvoidBadWifi();
+ updateMeteredMultipathPreference();
+ }
+
+ // TODO: Set the mini sdk to 31 and remove @TargetApi annotation when b/205923322 is addressed.
+ @TargetApi(Build.VERSION_CODES.S)
+ public void start() {
+ for (Uri uri : mSettingsUris) {
+ mResolver.registerContentObserver(uri, false, mSettingObserver);
+ }
+
+ final IntentFilter intentFilter = new IntentFilter();
+ intentFilter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
+ mContext.registerReceiverForAllUsers(mBroadcastReceiver, intentFilter,
+ null /* broadcastPermission */, mHandler);
+
+ final Executor handlerExecutor = new HandlerExecutor(mHandler);
+ mContext.getSystemService(TelephonyManager.class).registerTelephonyCallback(
+ handlerExecutor, new ActiveDataSubscriptionIdListener());
+ mDeps.addOnDevicePropertiesChangedListener(handlerExecutor,
+ properties -> reevaluateInternal());
+
+ reevaluate();
+ }
+
+ public void shutdown() {
+ mResolver.unregisterContentObserver(mSettingObserver);
+
+ mContext.unregisterReceiver(mBroadcastReceiver);
+ }
+
+ public boolean getAvoidBadWifi() {
+ return mAvoidBadWifi;
+ }
+
+ public boolean getActivelyPreferBadWifi() {
+ return mActivelyPreferBadWifi;
+ }
+
+ // TODO: move this to MultipathPolicyTracker.
+ public int getMeteredMultipathPreference() {
+ return mMeteredMultipathPreference;
+ }
+
+ /**
+ * Whether the device or carrier configuration disables avoiding bad wifi by default.
+ */
+ public boolean configRestrictsAvoidBadWifi() {
+ final boolean allowBadWifi = mTestAllowBadWifiUntilMs > 0
+ && mTestAllowBadWifiUntilMs > System.currentTimeMillis();
+ // If the config returns true, then avoid bad wifi design can be controlled by the
+ // NETWORK_AVOID_BAD_WIFI setting.
+ if (allowBadWifi) return true;
+
+ return mDeps.getResourcesForActiveSubId(mResources, mActiveSubId)
+ .getInteger(R.integer.config_networkAvoidBadWifi) == 0;
+ }
+
+ /**
+ * Whether the device config prefers bad wifi actively, when it doesn't avoid them
+ *
+ * This is only relevant when the device is configured not to avoid bad wifis. In this
+ * case, "actively" preferring a bad wifi means that the device will switch to a bad
+ * wifi it just connected to, as long as it's not a captive portal.
+ *
+ * On U and above this always returns true. On T and below it reads a configuration option.
+ */
+ public boolean configActivelyPrefersBadWifi() {
+ // See the definition of config_activelyPreferBadWifi for a description of its meaning.
+ // On U and above, the config is ignored, and bad wifi is always actively preferred.
+ if (SdkLevel.isAtLeastU()) return true;
+
+ // On T and below, 1 means to actively prefer bad wifi, 0 means not to prefer
+ // bad wifi (only stay stuck on it if already on there). This implementation treats
+ // any non-0 value like 1, on the assumption that anybody setting it non-zero wants
+ // the newer behavior.
+ return 0 != mDeps.getResourcesForActiveSubId(mResources, mActiveSubId)
+ .getInteger(R.integer.config_activelyPreferBadWifi);
+ }
+
+ /**
+ * Temporarily allow bad wifi to override {@code config_networkAvoidBadWifi} configuration.
+ * The value works when the time set is more than {@link System.currentTimeMillis()}.
+ */
+ public void setTestAllowBadWifiUntil(long timeMs) {
+ Log.d(TAG, "setTestAllowBadWifiUntil: " + timeMs);
+ mTestAllowBadWifiUntilMs = timeMs;
+ reevaluateInternal();
+ }
+
+ /**
+ * Whether we should display a notification when wifi becomes unvalidated.
+ */
+ public boolean shouldNotifyWifiUnvalidated() {
+ return configRestrictsAvoidBadWifi() && getAvoidBadWifiSetting() == null;
+ }
+
+ public String getAvoidBadWifiSetting() {
+ return Settings.Global.getString(mResolver, NETWORK_AVOID_BAD_WIFI);
+ }
+
+ /**
+ * Returns whether device config says the device should actively prefer bad wifi.
+ *
+ * {@see #configActivelyPrefersBadWifi} for a description of what this does. This device
+ * config overrides that config overlay.
+ *
+ * @return True on Android U and above.
+ * True if device config says to actively prefer bad wifi.
+ * False if device config says not to actively prefer bad wifi.
+ * null if device config doesn't have an opinion (then fall back on the resource).
+ */
+ public Boolean deviceConfigActivelyPreferBadWifi() {
+ if (SdkLevel.isAtLeastU()) return true;
+ switch (mDeps.getConfigActivelyPreferBadWifi()) {
+ case 1:
+ return Boolean.TRUE;
+ case -1:
+ return Boolean.FALSE;
+ default:
+ return null;
+ }
+ }
+
+ @VisibleForTesting
+ public void reevaluate() {
+ mHandler.post(this::reevaluateInternal);
+ }
+
+ /**
+ * Reevaluate the settings. Must be called on the handler thread.
+ */
+ private void reevaluateInternal() {
+ if (updateAvoidBadWifi() && mAvoidBadWifiCallback != null) {
+ mAvoidBadWifiCallback.run();
+ }
+ updateMeteredMultipathPreference();
+ }
+
+ public boolean updateAvoidBadWifi() {
+ final boolean settingAvoidBadWifi = "1".equals(getAvoidBadWifiSetting());
+ final boolean prevAvoid = mAvoidBadWifi;
+ mAvoidBadWifi = settingAvoidBadWifi || !configRestrictsAvoidBadWifi();
+
+ final boolean prevActive = mActivelyPreferBadWifi;
+ final Boolean deviceConfigPreferBadWifi = deviceConfigActivelyPreferBadWifi();
+ if (null == deviceConfigPreferBadWifi) {
+ mActivelyPreferBadWifi = configActivelyPrefersBadWifi();
+ } else {
+ mActivelyPreferBadWifi = deviceConfigPreferBadWifi;
+ }
+
+ return mAvoidBadWifi != prevAvoid || mActivelyPreferBadWifi != prevActive;
+ }
+
+ /**
+ * The default (device and carrier-dependent) value for metered multipath preference.
+ */
+ public int configMeteredMultipathPreference() {
+ return mDeps.getResourcesForActiveSubId(mResources, mActiveSubId)
+ .getInteger(R.integer.config_networkMeteredMultipathPreference);
+ }
+
+ public void updateMeteredMultipathPreference() {
+ String setting = Settings.Global.getString(mResolver, NETWORK_METERED_MULTIPATH_PREFERENCE);
+ try {
+ mMeteredMultipathPreference = Integer.parseInt(setting);
+ } catch (NumberFormatException e) {
+ mMeteredMultipathPreference = configMeteredMultipathPreference();
+ }
+ }
+
+ private class SettingObserver extends ContentObserver {
+ public SettingObserver() {
+ super(null);
+ }
+
+ @Override
+ public void onChange(boolean selfChange) {
+ Log.wtf(TAG, "Should never be reached.");
+ }
+
+ @Override
+ public void onChange(boolean selfChange, Uri uri) {
+ if (!mSettingsUris.contains(uri)) {
+ Log.wtf(TAG, "Unexpected settings observation: " + uri);
+ }
+ reevaluate();
+ }
+ }
+}
diff --git a/service/src/com/android/server/connectivity/Nat464Xlat.java b/service/src/com/android/server/connectivity/Nat464Xlat.java
index e4ad391..2ac2ad3 100644
--- a/service/src/com/android/server/connectivity/Nat464Xlat.java
+++ b/service/src/com/android/server/connectivity/Nat464Xlat.java
@@ -22,6 +22,7 @@
import static com.android.net.module.util.CollectionUtils.contains;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.net.ConnectivityManager;
import android.net.IDnsResolver;
import android.net.INetd;
@@ -144,7 +145,7 @@
&& nai.netAgentConfig().skip464xlat;
return (supported || isTestNetwork) && connected && isIpv6OnlyNetwork && !skip464xlat
- && !nai.destroyed && (nai.networkCapabilities.hasTransport(TRANSPORT_CELLULAR)
+ && !nai.isDestroyed() && (nai.networkCapabilities.hasTransport(TRANSPORT_CELLULAR)
? isCellular464XlatEnabled() : true);
}
@@ -420,7 +421,7 @@
* This is necessary because the LinkProperties in mNetwork come from the transport layer, which
* has no idea that 464xlat is running on top of it.
*/
- public void fixupLinkProperties(@NonNull LinkProperties oldLp, @NonNull LinkProperties lp) {
+ public void fixupLinkProperties(@Nullable LinkProperties oldLp, @NonNull LinkProperties lp) {
// This must be done even if clatd is not running, because otherwise shouldStartClat would
// never return true.
lp.setNat64Prefix(selectNat64Prefix());
@@ -433,6 +434,8 @@
}
Log.d(TAG, "clatd running, updating NAI for " + mIface);
+ // oldLp can't be null here since shouldStartClat checks null LinkProperties to start clat.
+ // Thus, the status won't pass isRunning check if the oldLp is null.
for (LinkProperties stacked: oldLp.getStackedLinks()) {
if (Objects.equals(mIface, stacked.getInterfaceName())) {
lp.addStackedLink(stacked);
@@ -540,6 +543,9 @@
*/
public void dump(IndentingPrintWriter pw) {
if (SdkLevel.isAtLeastT()) {
+ // Dump ClatCoordinator information while clatd has been started but not running. The
+ // reason is that it helps to have more information if clatd is started but the
+ // v4-* interface doesn't bring up. See #isStarted, #isRunning.
if (isStarted()) {
pw.println("ClatCoordinator:");
pw.increaseIndent();
diff --git a/service/src/com/android/server/connectivity/NetworkAgentInfo.java b/service/src/com/android/server/connectivity/NetworkAgentInfo.java
index 04f378f..85282cb 100644
--- a/service/src/com/android/server/connectivity/NetworkAgentInfo.java
+++ b/service/src/com/android/server/connectivity/NetworkAgentInfo.java
@@ -61,6 +61,7 @@
import android.util.Pair;
import android.util.SparseArray;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.IndentingPrintWriter;
import com.android.internal.util.WakeupMessage;
import com.android.modules.utils.build.SdkLevel;
@@ -189,42 +190,221 @@
// field instead.
private @Nullable NetworkCapabilities mDeclaredCapabilitiesUnsanitized;
- // Indicates if netd has been told to create this Network. From this point on the appropriate
- // routing rules are setup and routes are added so packets can begin flowing over the Network.
- // This is a sticky bit; once set it is never cleared.
- public boolean created;
- // Set to true after the first time this network is marked as CONNECTED. Once set, the network
- // shows up in API calls, is able to satisfy NetworkRequests and can become the default network.
- // This is a sticky bit; once set it is never cleared.
- public boolean everConnected;
- // Whether this network has been destroyed and is being kept temporarily until it is replaced.
- public boolean destroyed;
- // To check how long it has been since last roam.
- public long lastRoamTimestamp;
+ // Timestamp (SystemClock.elapsedRealtime()) when netd has been told to create this Network, or
+ // 0 if it hasn't been done yet.
+ // From this point on, the appropriate routing rules are setup and routes are added so packets
+ // can begin flowing over the Network.
+ // This is a sticky value; once set != 0 it is never changed.
+ private long mCreatedTime;
- // Set to true if this Network successfully passed validation or if it did not satisfy the
- // default NetworkRequest in which case validation will not be attempted.
- // This is a sticky bit; once set it is never cleared even if future validation attempts fail.
- public boolean everValidated;
+ /** Notify this NAI that netd was just told to create this network */
+ public void setCreated() {
+ if (0L != mCreatedTime) throw new IllegalStateException("Already created");
+ mCreatedTime = SystemClock.elapsedRealtime();
+ }
- // The result of the last validation attempt on this network (true if validated, false if not).
- public boolean lastValidated;
+ /** Returns whether netd was told to create this network */
+ public boolean isCreated() {
+ return mCreatedTime != 0L;
+ }
- // If true, becoming unvalidated will lower the network's score. This is only meaningful if the
- // system is configured not to do this for certain networks, e.g., if the
- // config_networkAvoidBadWifi option is set to 0 and the user has not overridden that via
- // Settings.Global.NETWORK_AVOID_BAD_WIFI.
- public boolean avoidUnvalidated;
+ // Get the time (SystemClock.elapsedRealTime) when this network was created (or 0 if never).
+ public long getCreatedTime() {
+ return mCreatedTime;
+ }
- // Whether a captive portal was ever detected on this network.
- // This is a sticky bit; once set it is never cleared.
- public boolean everCaptivePortalDetected;
+ // Timestamp of the first time (SystemClock.elapsedRealtime()) this network is marked as
+ // connected, or 0 if this network has never been marked connected. Once set to non-zero, the
+ // network shows up in API calls, is able to satisfy NetworkRequests and can become the default
+ // network.
+ // This is a sticky value; once set != 0 it is never changed.
+ private long mConnectedTime;
- // Whether a captive portal was found during the last network validation attempt.
- public boolean lastCaptivePortalDetected;
+ /** Notify this NAI that this network just connected */
+ public void setConnected() {
+ if (0L != mConnectedTime) throw new IllegalStateException("Already connected");
+ mConnectedTime = SystemClock.elapsedRealtime();
+ }
- // Set to true when partial connectivity was detected.
- public boolean partialConnectivity;
+ /** Return whether this network ever connected */
+ public boolean everConnected() {
+ return mConnectedTime != 0L;
+ }
+
+ // Get the time (SystemClock.elapsedRealTime()) when this network was first connected, or 0 if
+ // never.
+ public long getConnectedTime() {
+ return mConnectedTime;
+ }
+
+ // When this network has been destroyed and is being kept temporarily until it is replaced,
+ // this is set to that timestamp (SystemClock.elapsedRealtime()). Zero otherwise.
+ private long mDestroyedTime;
+
+ /** Notify this NAI that this network was destroyed */
+ public void setDestroyed() {
+ if (0L != mDestroyedTime) throw new IllegalStateException("Already destroyed");
+ mDestroyedTime = SystemClock.elapsedRealtime();
+ }
+
+ /** Return whether this network was destroyed */
+ public boolean isDestroyed() {
+ return 0L != mDestroyedTime;
+ }
+
+ // Timestamp of the last roaming (SystemClock.elapsedRealtime()) or 0 if never roamed.
+ public long lastRoamTime;
+
+ // Timestamp (SystemClock.elapsedRealtime()) of the first time this network successfully
+ // passed validation or was deemed exempt of validation (see
+ // {@link NetworkMonitorUtils#isValidationRequired}). Zero if the network requires
+ // validation but never passed it successfully.
+ // This is a sticky value; once set it is never changed even if further validation attempts are
+ // made (whether they succeed or fail).
+ private long mFirstValidationTime;
+
+ // Timestamp (SystemClock.elapsedRealtime()) at which the latest validation attempt succeeded,
+ // or 0 if the latest validation attempt failed.
+ private long mCurrentValidationTime;
+
+ /** Notify this NAI that this network just finished a validation check */
+ public void setValidated(final boolean validated) {
+ final long nowOrZero = validated ? SystemClock.elapsedRealtime() : 0L;
+ if (validated && 0L == mFirstValidationTime) {
+ mFirstValidationTime = nowOrZero;
+ }
+ mCurrentValidationTime = nowOrZero;
+ }
+
+ /**
+ * Returns whether this network is currently validated.
+ *
+ * This is the result of the latest validation check. {@see #getCurrentValidationTime} for
+ * when that check was performed.
+ */
+ public boolean isValidated() {
+ return 0L != mCurrentValidationTime;
+ }
+
+ /**
+ * Returns whether this network ever passed the validation checks successfully.
+ *
+ * Note that the network may no longer be validated at this time ever if this is true.
+ * @see #isValidated
+ */
+ public boolean everValidated() {
+ return 0L != mFirstValidationTime;
+ }
+
+ // Get the time (SystemClock.elapsedRealTime()) when this network was most recently validated,
+ // or 0 if this network was found not to validate on the last attempt.
+ public long getCurrentValidationTime() {
+ return mCurrentValidationTime;
+ }
+
+ // Get the time (SystemClock.elapsedRealTime()) when this network was validated for the first
+ // time (or 0 if never).
+ public long getFirstValidationTime() {
+ return mFirstValidationTime;
+ }
+
+ // Timestamp (SystemClock.elapsedRealtime()) at which the user requested this network be
+ // avoided when unvalidated. Zero if this never happened for this network.
+ // This is only meaningful if the system is configured to have some cell networks yield
+ // to bad wifi, e.g., if the config_networkAvoidBadWifi option is set to 0 and the user has
+ // not overridden that via Settings.Global.NETWORK_AVOID_BAD_WIFI.
+ //
+ // Normally the system always prefers a validated network to a non-validated one, even if
+ // the non-validated one is cheaper. However, some cell networks may be configured by the
+ // setting above to yield to WiFi even if that WiFi network goes bad. When this configuration
+ // is active, specific networks can be marked to override this configuration so that the
+ // system will revert to preferring such a cell to this network when this network goes bad. This
+ // is achieved by calling {@link ConnectivityManager#setAvoidUnvalidated()}, and this field
+ // is set to non-zero when this happened to this network.
+ private long mAvoidUnvalidated;
+
+ /** Set this network as being avoided when unvalidated. {@see mAvoidUnvalidated} */
+ public void setAvoidUnvalidated() {
+ if (0L != mAvoidUnvalidated) throw new IllegalStateException("Already avoided unvalidated");
+ mAvoidUnvalidated = SystemClock.elapsedRealtime();
+ }
+
+ // Get the time (SystemClock.elapsedRealTime()) when this network was set to being avoided
+ // when unvalidated, or 0 if this never happened.
+ public long getAvoidUnvalidated() {
+ return mAvoidUnvalidated;
+ }
+
+ // Timestamp (SystemClock.elapsedRealtime()) at which a captive portal was first detected
+ // on this network, or zero if this never happened.
+ // This is a sticky value; once set != 0 it is never changed.
+ private long mFirstCaptivePortalDetectedTime;
+
+ // Timestamp (SystemClock.elapsedRealtime()) at which the latest validation attempt found a
+ // captive portal, or zero if the latest attempt didn't find a captive portal.
+ private long mCurrentCaptivePortalDetectedTime;
+
+ /** Notify this NAI that a captive portal has just been detected on this network */
+ public void setCaptivePortalDetected(final boolean hasCaptivePortal) {
+ if (!hasCaptivePortal) {
+ mCurrentCaptivePortalDetectedTime = 0L;
+ return;
+ }
+ final long now = SystemClock.elapsedRealtime();
+ if (0L == mFirstCaptivePortalDetectedTime) mFirstCaptivePortalDetectedTime = now;
+ mCurrentCaptivePortalDetectedTime = now;
+ }
+
+ /** Return whether a captive portal has ever been detected on this network */
+ public boolean everCaptivePortalDetected() {
+ return 0L != mFirstCaptivePortalDetectedTime;
+ }
+
+ /** Return whether this network has been detected to be behind a captive portal at the moment */
+ public boolean captivePortalDetected() {
+ return 0L != mCurrentCaptivePortalDetectedTime;
+ }
+
+ // Timestamp (SystemClock.elapsedRealtime()) at which the latest validation attempt found
+ // partial connectivity, or zero if the latest attempt didn't find partial connectivity.
+ private long mPartialConnectivityTime;
+
+ public void setPartialConnectivity(final boolean value) {
+ mPartialConnectivityTime = value ? SystemClock.elapsedRealtime() : 0L;
+ }
+
+ /** Return whether this NAI has partial connectivity */
+ public boolean partialConnectivity() {
+ return 0L != mPartialConnectivityTime;
+ }
+
+ // Timestamp (SystemClock.elapsedRealTime()) at which the first validation attempt concluded,
+ // or timed out after {@link ConnectivityService#PROMPT_UNVALIDATED_DELAY_MS}. 0 if not yet.
+ private long mFirstEvaluationConcludedTime;
+
+ /**
+ * Notify this NAI that this network has been evaluated.
+ *
+ * The stack considers that any result finding some working connectivity (valid, partial,
+ * captive portal) is an initial validation. Negative result (not valid), however, is not
+ * considered initial validation until {@link ConnectivityService#PROMPT_UNVALIDATED_DELAY_MS}
+ * have elapsed. This is because some networks may spuriously fail for a short time immediately
+ * after associating. If no positive result is found after the timeout has elapsed, then
+ * the network has been evaluated once.
+ *
+ * @return true the first time this is called on this object, then always returns false.
+ */
+ public boolean setEvaluated() {
+ if (0L != mFirstEvaluationConcludedTime) return false;
+ mFirstEvaluationConcludedTime = SystemClock.elapsedRealtime();
+ return true;
+ }
+
+ /** When this network ever concluded its first evaluation, or 0 if this never happened. */
+ @VisibleForTesting
+ public long getFirstEvaluationConcludedTime() {
+ return mFirstEvaluationConcludedTime;
+ }
// Delay between when the network is disconnected and when the native network is destroyed.
public int teardownDelayMs;
@@ -241,6 +421,9 @@
// URL, Terms & Conditions URL, and network friendly name.
public CaptivePortalData networkAgentPortalData;
+ // Indicate whether this device has the automotive feature.
+ private final boolean mHasAutomotiveFeature;
+
/**
* Sets the capabilities sent by the agent for later retrieval.
*
@@ -282,9 +465,8 @@
+ networkCapabilities.getOwnerUid() + " to " + nc.getOwnerUid());
nc.setOwnerUid(networkCapabilities.getOwnerUid());
}
- restrictCapabilitiesFromNetworkAgent(nc, creatorUid,
- mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE),
- carrierPrivilegeAuthenticator);
+ restrictCapabilitiesFromNetworkAgent(
+ nc, creatorUid, mHasAutomotiveFeature, carrierPrivilegeAuthenticator);
return nc;
}
@@ -453,6 +635,8 @@
? nc.getUnderlyingNetworks().toArray(new Network[0])
: null;
mCreationTime = System.currentTimeMillis();
+ mHasAutomotiveFeature =
+ mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE);
}
private class AgentDeathMonitor implements IBinder.DeathRecipient {
@@ -819,8 +1003,7 @@
@NonNull final NetworkCapabilities nc) {
final NetworkCapabilities oldNc = networkCapabilities;
networkCapabilities = nc;
- mScore = mScore.mixInScore(networkCapabilities, networkAgentConfig, everValidatedForYield(),
- yieldToBadWiFi(), destroyed);
+ updateScoreForNetworkAgentUpdate();
final NetworkMonitorManager nm = mNetworkMonitor;
if (nm != null) {
nm.notifyNetworkCapabilitiesChanged(nc);
@@ -983,13 +1166,13 @@
// Does this network satisfy request?
public boolean satisfies(NetworkRequest request) {
- return created &&
- request.networkCapabilities.satisfiedByNetworkCapabilities(networkCapabilities);
+ return everConnected()
+ && request.networkCapabilities.satisfiedByNetworkCapabilities(networkCapabilities);
}
public boolean satisfiesImmutableCapabilitiesOf(NetworkRequest request) {
- return created &&
- request.networkCapabilities.satisfiedByImmutableNetworkCapabilities(
+ return everConnected()
+ && request.networkCapabilities.satisfiedByImmutableNetworkCapabilities(
networkCapabilities);
}
@@ -1022,8 +1205,11 @@
* Mix-in the ConnectivityService-managed bits in the score.
*/
public void setScore(final NetworkScore score) {
+ final FullScore oldScore = mScore;
mScore = FullScore.fromNetworkScore(score, networkCapabilities, networkAgentConfig,
- everValidatedForYield(), yieldToBadWiFi(), destroyed);
+ everValidated(), 0L != getAvoidUnvalidated(), yieldToBadWiFi(),
+ 0L != mFirstEvaluationConcludedTime, isDestroyed());
+ maybeLogDifferences(oldScore);
}
/**
@@ -1032,12 +1218,22 @@
* Call this after changing any data that might affect the score (e.g., agent config).
*/
public void updateScoreForNetworkAgentUpdate() {
+ final FullScore oldScore = mScore;
mScore = mScore.mixInScore(networkCapabilities, networkAgentConfig,
- everValidatedForYield(), yieldToBadWiFi(), destroyed);
+ everValidated(), 0L != getAvoidUnvalidated(), yieldToBadWiFi(),
+ 0L != mFirstEvaluationConcludedTime, isDestroyed());
+ maybeLogDifferences(oldScore);
}
- private boolean everValidatedForYield() {
- return everValidated && !avoidUnvalidated;
+ /**
+ * Prints score differences to logcat, if any.
+ * @param oldScore the old score. Differences from |oldScore| to |this| are logged, if any.
+ */
+ public void maybeLogDifferences(final FullScore oldScore) {
+ final String differences = mScore.describeDifferencesFrom(oldScore);
+ if (null != differences) {
+ Log.i(TAG, "Update score for net " + network + " : " + differences);
+ }
}
/**
@@ -1324,14 +1520,17 @@
+ networkInfo.toShortString() + "} "
+ "created=" + Instant.ofEpochMilli(mCreationTime) + " "
+ mScore + " "
- + (created ? " created" : "")
- + (destroyed ? " destroyed" : "")
+ + (isCreated() ? " created " + getCreatedTime() : "")
+ + (isDestroyed() ? " destroyed " + mDestroyedTime : "")
+ (isNascent() ? " nascent" : (isLingering() ? " lingering" : ""))
- + (everValidated ? " everValidated" : "")
- + (lastValidated ? " lastValidated" : "")
- + (partialConnectivity ? " partialConnectivity" : "")
- + (everCaptivePortalDetected ? " everCaptivePortal" : "")
- + (lastCaptivePortalDetected ? " isCaptivePortal" : "")
+ + (everValidated() ? " firstValidated " + getFirstValidationTime() : "")
+ + (isValidated() ? " lastValidated " + getCurrentValidationTime() : "")
+ + (partialConnectivity()
+ ? " partialConnectivity " + mPartialConnectivityTime : "")
+ + (everCaptivePortalDetected()
+ ? " firstCaptivePortalDetected " + mFirstCaptivePortalDetectedTime : "")
+ + (captivePortalDetected()
+ ? " currentCaptivePortalDetected " + mCurrentCaptivePortalDetectedTime : "")
+ (networkAgentConfig.explicitlySelected ? " explicitlySelected" : "")
+ (networkAgentConfig.acceptUnvalidated ? " acceptUnvalidated" : "")
+ (networkAgentConfig.acceptPartialConnectivity ? " acceptPartialConnectivity" : "")
@@ -1349,7 +1548,7 @@
*
* This is often not enough for debugging purposes for anything complex, but the full form
* is very long and hard to read, so this is useful when there isn't a lot of ambiguity.
- * This represents the network with something like "[100 WIFI|VPN]" or "[108 MOBILE]".
+ * This represents the network with something like "[100 WIFI|VPN]" or "[108 CELLULAR]".
*/
public String toShortString() {
return "[" + network.getNetId() + " "
diff --git a/service/src/com/android/server/connectivity/NetworkNotificationManager.java b/service/src/com/android/server/connectivity/NetworkNotificationManager.java
index 155f6c4..45da0ea 100644
--- a/service/src/com/android/server/connectivity/NetworkNotificationManager.java
+++ b/service/src/com/android/server/connectivity/NetworkNotificationManager.java
@@ -394,8 +394,9 @@
Toast.makeText(mContext, text, Toast.LENGTH_LONG).show();
}
- @VisibleForTesting
- static String tagFor(int id) {
+ /** Get the logging tag for a notification ID */
+ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
+ public static String tagFor(int id) {
return String.format("ConnectivityNotification:%d", id);
}
diff --git a/service/src/com/android/server/connectivity/NetworkRanker.java b/service/src/com/android/server/connectivity/NetworkRanker.java
index babc353..d94c8dc 100644
--- a/service/src/com/android/server/connectivity/NetworkRanker.java
+++ b/service/src/com/android/server/connectivity/NetworkRanker.java
@@ -16,6 +16,7 @@
package com.android.server.connectivity;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL;
import static android.net.NetworkCapabilities.TRANSPORT_BLUETOOTH;
import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
import static android.net.NetworkCapabilities.TRANSPORT_ETHERNET;
@@ -26,8 +27,10 @@
import static com.android.net.module.util.CollectionUtils.filter;
import static com.android.server.connectivity.FullScore.POLICY_ACCEPT_UNVALIDATED;
+import static com.android.server.connectivity.FullScore.POLICY_AVOIDED_WHEN_UNVALIDATED;
+import static com.android.server.connectivity.FullScore.POLICY_EVER_EVALUATED;
import static com.android.server.connectivity.FullScore.POLICY_EVER_USER_SELECTED;
-import static com.android.server.connectivity.FullScore.POLICY_EVER_VALIDATED_NOT_AVOIDED_WHEN_BAD;
+import static com.android.server.connectivity.FullScore.POLICY_EVER_VALIDATED;
import static com.android.server.connectivity.FullScore.POLICY_IS_DESTROYED;
import static com.android.server.connectivity.FullScore.POLICY_IS_INVINCIBLE;
import static com.android.server.connectivity.FullScore.POLICY_IS_VALIDATED;
@@ -38,18 +41,39 @@
import android.net.NetworkCapabilities;
import android.net.NetworkRequest;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.net.module.util.CollectionUtils;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
+import java.util.Objects;
import java.util.function.Predicate;
/**
* A class that knows how to find the best network matching a request out of a list of networks.
*/
public class NetworkRanker {
+ /**
+ * Home for all configurations of NetworkRanker
+ */
+ public static final class Configuration {
+ private final boolean mActivelyPreferBadWifi;
+
+ public Configuration(final boolean activelyPreferBadWifi) {
+ this.mActivelyPreferBadWifi = activelyPreferBadWifi;
+ }
+
+ /**
+ * @see MultinetworkPolicyTracker#getActivelyPreferBadWifi()
+ */
+ public boolean activelyPreferBadWifi() {
+ return mActivelyPreferBadWifi;
+ }
+ }
+ @NonNull private volatile Configuration mConf;
+
// Historically the legacy ints have been 0~100 in principle (though the highest score in
// AOSP has always been 90). This is relied on by VPNs that send a legacy score of 101.
public static final int LEGACY_INT_MAX = 100;
@@ -64,7 +88,22 @@
NetworkCapabilities getCapsNoCopy();
}
- public NetworkRanker() { }
+ public NetworkRanker(@NonNull final Configuration conf) {
+ // Because mConf is volatile, the only way it could be seen null would be an access to it
+ // on some other thread during this constructor. But this is not possible because mConf is
+ // private and `this` doesn't escape this constructor.
+ setConfiguration(conf);
+ }
+
+ public void setConfiguration(@NonNull final Configuration conf) {
+ mConf = Objects.requireNonNull(conf);
+ }
+
+ // There shouldn't be a use case outside of testing
+ @VisibleForTesting
+ public Configuration getConfiguration() {
+ return mConf;
+ }
/**
* Find the best network satisfying this request among the list of passed networks.
@@ -103,9 +142,42 @@
}
}
- private <T extends Scoreable> boolean isBadWiFi(@NonNull final T candidate) {
- return candidate.getScore().hasPolicy(POLICY_EVER_VALIDATED_NOT_AVOIDED_WHEN_BAD)
- && candidate.getCapsNoCopy().hasTransport(TRANSPORT_WIFI);
+ /**
+ * Returns whether the wifi passed as an argument is a preferred network to yielding cell.
+ *
+ * When comparing bad wifi to cell with POLICY_YIELD_TO_BAD_WIFI, it may be necessary to
+ * know if a particular bad wifi is preferred to such a cell network. This method computes
+ * and returns this.
+ *
+ * @param candidate a bad wifi to evaluate
+ * @return whether this candidate is preferred to cell with POLICY_YIELD_TO_BAD_WIFI
+ */
+ private <T extends Scoreable> boolean isPreferredBadWiFi(@NonNull final T candidate) {
+ final FullScore score = candidate.getScore();
+ final NetworkCapabilities caps = candidate.getCapsNoCopy();
+
+ // Whatever the policy, only WiFis can be preferred bad WiFis.
+ if (!caps.hasTransport(TRANSPORT_WIFI)) return false;
+ // Validated networks aren't bad networks, so a fortiori can't be preferred bad WiFis.
+ if (score.hasPolicy(POLICY_IS_VALIDATED)) return false;
+ // A WiFi that the user explicitly wanted to avoid in UI is never a preferred bad WiFi.
+ if (score.hasPolicy(POLICY_AVOIDED_WHEN_UNVALIDATED)) return false;
+
+ if (mConf.activelyPreferBadWifi()) {
+ // If a network is still evaluating, don't prefer it.
+ if (!score.hasPolicy(POLICY_EVER_EVALUATED)) return false;
+
+ // If a network is not a captive portal, then prefer it.
+ if (!caps.hasCapability(NET_CAPABILITY_CAPTIVE_PORTAL)) return true;
+
+ // If it's a captive portal, prefer it if it previously validated but is no longer
+ // validated (i.e., the user logged in in the past, but later the portal closed).
+ return score.hasPolicy(POLICY_EVER_VALIDATED);
+ } else {
+ // Under the original "prefer bad WiFi" policy, only networks that have ever validated
+ // are preferred.
+ return score.hasPolicy(POLICY_EVER_VALIDATED);
+ }
}
/**
@@ -128,7 +200,7 @@
// No network with the policy : do nothing.
return;
}
- if (!CollectionUtils.any(rejected, n -> isBadWiFi(n))) {
+ if (!CollectionUtils.any(rejected, n -> isPreferredBadWiFi(n))) {
// No bad WiFi : do nothing.
return;
}
@@ -138,7 +210,7 @@
// wifis by the following policies (e.g. exiting).
final ArrayList<T> acceptedYielders = new ArrayList<>(accepted);
final ArrayList<T> rejectedWithBadWiFis = new ArrayList<>(rejected);
- partitionInto(rejectedWithBadWiFis, n -> isBadWiFi(n), accepted, rejected);
+ partitionInto(rejectedWithBadWiFis, n -> isPreferredBadWiFi(n), accepted, rejected);
accepted.addAll(acceptedYielders);
return;
}
diff --git a/tests/common/java/android/net/NetworkCapabilitiesTest.java b/tests/common/java/android/net/NetworkCapabilitiesTest.java
index c30e1d3..7b374d2 100644
--- a/tests/common/java/android/net/NetworkCapabilitiesTest.java
+++ b/tests/common/java/android/net/NetworkCapabilitiesTest.java
@@ -36,6 +36,7 @@
import static android.net.NetworkCapabilities.NET_CAPABILITY_PARTIAL_CONNECTIVITY;
import static android.net.NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_BANDWIDTH;
import static android.net.NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_LATENCY;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_SUPL;
import static android.net.NetworkCapabilities.NET_CAPABILITY_TRUSTED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_WIFI_P2P;
@@ -1370,4 +1371,23 @@
assertEquals(expectedNcBuilder.build(), restrictedNc);
}
+
+ @Test
+ public void testDescribeCapsDifferences() throws Exception {
+ final NetworkCapabilities nc1 = new NetworkCapabilities.Builder()
+ .addCapability(NET_CAPABILITY_MMS)
+ .addCapability(NET_CAPABILITY_OEM_PAID)
+ .addCapability(NET_CAPABILITY_INTERNET)
+ .build();
+ final NetworkCapabilities nc2 = new NetworkCapabilities.Builder()
+ .addCapability(NET_CAPABILITY_CAPTIVE_PORTAL)
+ .addCapability(NET_CAPABILITY_SUPL)
+ .addCapability(NET_CAPABILITY_VALIDATED)
+ .addCapability(NET_CAPABILITY_INTERNET)
+ .build();
+ assertEquals("-MMS-OEM_PAID+SUPL+VALIDATED+CAPTIVE_PORTAL",
+ nc2.describeCapsDifferencesFrom(nc1));
+ assertEquals("-SUPL-VALIDATED-CAPTIVE_PORTAL+MMS+OEM_PAID",
+ nc1.describeCapsDifferencesFrom(nc2));
+ }
}
diff --git a/tests/common/java/android/net/metrics/IpConnectivityLogTest.java b/tests/common/java/android/net/metrics/IpConnectivityLogTest.java
index ab97f2d..b6e9b95 100644
--- a/tests/common/java/android/net/metrics/IpConnectivityLogTest.java
+++ b/tests/common/java/android/net/metrics/IpConnectivityLogTest.java
@@ -19,11 +19,11 @@
import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
-import static com.android.net.module.util.NetworkCapabilitiesUtils.unpackBits;
+import static com.android.net.module.util.BitUtils.unpackBits;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.timeout;
+import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import android.net.ConnectivityMetricsEvent;
@@ -51,6 +51,7 @@
private static final int FAKE_NET_ID = 100;
private static final int[] FAKE_TRANSPORT_TYPES = unpackBits(TRANSPORT_WIFI);
private static final long FAKE_TIME_STAMP = System.currentTimeMillis();
+ private static final long THREAD_TIMEOUT_MS = 10_000L;
private static final String FAKE_INTERFACE_NAME = "test";
private static final IpReachabilityEvent FAKE_EV =
new IpReachabilityEvent(IpReachabilityEvent.NUD_FAILED);
@@ -93,22 +94,26 @@
final int nCallers = 10;
final int nEvents = 10;
+ final Thread[] threads = new Thread[nCallers];
for (int n = 0; n < nCallers; n++) {
final int i = n;
- new Thread() {
- public void run() {
- for (int j = 0; j < nEvents; j++) {
- assertTrue(logger.log(makeExpectedEvent(
- FAKE_TIME_STAMP + i * 100 + j,
- FAKE_NET_ID + i * 100 + j,
- ((i + j) % 2 == 0) ? TRANSPORT_WIFI : TRANSPORT_CELLULAR,
- FAKE_INTERFACE_NAME)));
- }
+ threads[i] = new Thread(() -> {
+ for (int j = 0; j < nEvents; j++) {
+ assertTrue(logger.log(makeExpectedEvent(
+ FAKE_TIME_STAMP + i * 100 + j,
+ FAKE_NET_ID + i * 100 + j,
+ ((i + j) % 2 == 0) ? TRANSPORT_WIFI : TRANSPORT_CELLULAR,
+ FAKE_INTERFACE_NAME)));
}
- }.start();
+ });
+ threads[i].start();
+ }
+ // To ensure the events have been sent out on each thread. Wait for the thread to die.
+ for (Thread thread : threads) {
+ thread.join(THREAD_TIMEOUT_MS);
}
- List<ConnectivityMetricsEvent> got = verifyEvents(nCallers * nEvents, 200);
+ final List<ConnectivityMetricsEvent> got = verifyEvents(nCallers * nEvents);
Collections.sort(got, EVENT_COMPARATOR);
Iterator<ConnectivityMetricsEvent> iter = got.iterator();
for (int i = 0; i < nCallers; i++) {
@@ -123,17 +128,13 @@
}
}
- private List<ConnectivityMetricsEvent> verifyEvents(int n, int timeoutMs) throws Exception {
+ private List<ConnectivityMetricsEvent> verifyEvents(int n) throws Exception {
ArgumentCaptor<ConnectivityMetricsEvent> captor =
ArgumentCaptor.forClass(ConnectivityMetricsEvent.class);
- verify(mMockService, timeout(timeoutMs).times(n)).logEvent(captor.capture());
+ verify(mMockService, times(n)).logEvent(captor.capture());
return captor.getAllValues();
}
- private List<ConnectivityMetricsEvent> verifyEvents(int n) throws Exception {
- return verifyEvents(n, 10);
- }
-
private ConnectivityMetricsEvent makeExpectedEvent(long timestamp, int netId, long transports,
String ifname) {
diff --git a/tests/cts/OWNERS b/tests/cts/OWNERS
index 875b4a2..089d06f 100644
--- a/tests/cts/OWNERS
+++ b/tests/cts/OWNERS
@@ -1,3 +1,7 @@
# Bug template url: http://b/new?component=31808
set noparent
file:platform/packages/modules/Connectivity:master:/OWNERS_core_networking_xts
+
+# Only temporary ownership to improve ethernet code quality (b/236280707)
+# TODO: remove by 12/31/2022
+per-file net/src/android/net/cts/EthernetManagerTest.kt = prohr@google.com #{LAST_RESORT_SUGGESTION}
diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkPolicyTestUtils.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkPolicyTestUtils.java
index 7842eec..deca6a2 100644
--- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkPolicyTestUtils.java
+++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/NetworkPolicyTestUtils.java
@@ -117,6 +117,7 @@
return false;
}
if (mDataSaverSupported == null) {
+ setRestrictBackgroundInternal(false);
assertMyRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_DISABLED);
try {
setRestrictBackgroundInternal(true);
diff --git a/tests/cts/net/Android.bp b/tests/cts/net/Android.bp
index a6179fc..23cb15c 100644
--- a/tests/cts/net/Android.bp
+++ b/tests/cts/net/Android.bp
@@ -61,7 +61,9 @@
// uncomment when b/13249961 is fixed
// sdk_version: "current",
platform_apis: true,
- required: ["ConnectivityChecker"],
+ data: [":ConnectivityChecker"],
+ per_testcase_directory: true,
+ host_required: ["net-tests-utils-host-common"],
test_config_template: "AndroidTestTemplate.xml",
}
diff --git a/tests/cts/net/AndroidManifest.xml b/tests/cts/net/AndroidManifest.xml
index 6b5bb93..25490da 100644
--- a/tests/cts/net/AndroidManifest.xml
+++ b/tests/cts/net/AndroidManifest.xml
@@ -35,6 +35,7 @@
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />
+ <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" />
<!-- TODO (b/186093901): remove after fixing resource querying -->
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
diff --git a/tests/cts/net/jni/NativeMultinetworkJni.cpp b/tests/cts/net/jni/NativeMultinetworkJni.cpp
index 60e31bc..6610d10 100644
--- a/tests/cts/net/jni/NativeMultinetworkJni.cpp
+++ b/tests/cts/net/jni/NativeMultinetworkJni.cpp
@@ -40,8 +40,12 @@
#define LOGD(fmt, ...) \
__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, fmt, ##__VA_ARGS__)
-#define EXPECT_GE(env, actual, expected, msg) \
+// Since the tests in this file commonly pass expression statements as parameters to these macros,
+// get the returned value of the statements to avoid statement double-called.
+#define EXPECT_GE(env, actual_stmt, expected_stmt, msg) \
do { \
+ const auto expected = (expected_stmt); \
+ const auto actual = (actual_stmt); \
if (actual < expected) { \
jniThrowExceptionFmt(env, "java/lang/AssertionError", \
"%s:%d: %s EXPECT_GE: expected %d, got %d", \
@@ -49,8 +53,10 @@
} \
} while (0)
-#define EXPECT_GT(env, actual, expected, msg) \
+#define EXPECT_GT(env, actual_stmt, expected_stmt, msg) \
do { \
+ const auto expected = (expected_stmt); \
+ const auto actual = (actual_stmt); \
if (actual <= expected) { \
jniThrowExceptionFmt(env, "java/lang/AssertionError", \
"%s:%d: %s EXPECT_GT: expected %d, got %d", \
@@ -58,8 +64,10 @@
} \
} while (0)
-#define EXPECT_EQ(env, expected, actual, msg) \
+#define EXPECT_EQ(env, expected_stmt, actual_stmt, msg) \
do { \
+ const auto expected = (expected_stmt); \
+ const auto actual = (actual_stmt); \
if (actual != expected) { \
jniThrowExceptionFmt(env, "java/lang/AssertionError", \
"%s:%d: %s EXPECT_EQ: expected %d, got %d", \
@@ -110,6 +118,18 @@
// If there is no valid answer, test will fail.
continue;
}
+
+ const int rtype = ns_rr_type(rr);
+ if (family == AF_INET) {
+ // If there is no expected address type, test will fail.
+ if (rtype != ns_t_a) continue;
+ } else if (family == AF_INET6) {
+ // If there is no expected address type, test will fail.
+ if (rtype != ns_t_aaaa) continue;
+ } else {
+ return -EAFNOSUPPORT;
+ }
+
const uint8_t* rdata = ns_rr_rdata(rr);
char buffer[INET6_ADDRSTRLEN];
if (inet_ntop(family, (const char*) rdata, buffer, sizeof(buffer)) == NULL) {
@@ -161,7 +181,7 @@
// V6
fd = android_res_nquery(handle, kHostname, ns_c_in, ns_t_aaaa, 0);
EXPECT_GE(env, fd, 0, "v6 res_nquery");
- EXPECT_EQ(env, 0, expectAnswersValid(env, fd, AF_INET, ns_r_noerror),
+ EXPECT_EQ(env, 0, expectAnswersValid(env, fd, AF_INET6, ns_r_noerror),
"v6 res_nquery check answers");
}
diff --git a/tests/cts/net/src/android/net/cts/BatteryStatsManagerTest.java b/tests/cts/net/src/android/net/cts/BatteryStatsManagerTest.java
index 6b2a1ee..e2821cb 100644
--- a/tests/cts/net/src/android/net/cts/BatteryStatsManagerTest.java
+++ b/tests/cts/net/src/android/net/cts/BatteryStatsManagerTest.java
@@ -21,12 +21,14 @@
import static androidx.test.InstrumentationRegistry.getContext;
+import static com.android.compatibility.common.util.BatteryUtils.hasBattery;
import static com.android.compatibility.common.util.SystemUtil.runShellCommand;
import static com.android.testutils.MiscAsserts.assertThrows;
import static com.android.testutils.TestPermissionUtil.runAsShell;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeTrue;
import android.content.Context;
import android.content.pm.PackageManager;
@@ -97,6 +99,7 @@
@RequiresDevice // Virtual hardware does not support wifi battery stats
public void testReportNetworkInterfaceForTransports() throws Exception {
try {
+ assumeTrue("Battery is not present. Ignore test.", hasBattery());
// Simulate the device being unplugged from charging.
executeShellCommand("cmd battery unplug");
executeShellCommand("cmd battery set status " + BATTERY_STATUS_DISCHARGING);
diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
index cece4df..218eb04 100644
--- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
+++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
@@ -165,7 +165,6 @@
import android.os.Process;
import android.os.ServiceManager;
import android.os.SystemClock;
-import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.VintfRuntimeInfo;
import android.platform.test.annotations.AppModeFull;
@@ -271,7 +270,10 @@
private static final int MIN_KEEPALIVE_INTERVAL = 10;
private static final int NETWORK_CALLBACK_TIMEOUT_MS = 30_000;
- private static final int LISTEN_ACTIVITY_TIMEOUT_MS = 5_000;
+ // Timeout for waiting network to be validated. Set the timeout to 30s, which is more than
+ // DNS timeout.
+ // TODO(b/252972908): reset the original timer when aosp/2188755 is ramped up.
+ private static final int LISTEN_ACTIVITY_TIMEOUT_MS = 30_000;
private static final int NO_CALLBACK_TIMEOUT_MS = 100;
private static final int SOCKET_TIMEOUT_MS = 100;
private static final int NUM_TRIES_MULTIPATH_PREF_CHECK = 20;
@@ -353,7 +355,8 @@
// Get com.android.internal.R.array.networkAttributes
int resId = mContext.getResources().getIdentifier("networkAttributes", "array", "android");
String[] naStrings = mContext.getResources().getStringArray(resId);
- boolean wifiOnly = SystemProperties.getBoolean("ro.radio.noril", false);
+ boolean wifiOnly = mPackageManager.hasSystemFeature(FEATURE_WIFI)
+ && !mPackageManager.hasSystemFeature(FEATURE_TELEPHONY);
for (String naString : naStrings) {
try {
final String[] splitConfig = naString.split(",");
@@ -2618,8 +2621,7 @@
// the network with the TEST transport. Also wait for validation here, in case there
// is a bug that's only visible when the network is validated.
setWifiMeteredStatusAndWait(ssid, true /* isMetered */, true /* waitForValidation */);
- defaultCallback.expectCallback(CallbackEntry.LOST, wifiNetwork,
- NETWORK_CALLBACK_TIMEOUT_MS);
+ defaultCallback.expect(CallbackEntry.LOST, wifiNetwork, NETWORK_CALLBACK_TIMEOUT_MS);
waitForAvailable(defaultCallback, tnt.getNetwork());
// Depending on if this device has cellular connectivity or not, multiple available
// callbacks may be received. Eventually, metered Wi-Fi should be the final available
@@ -2628,10 +2630,9 @@
waitForAvailable(systemDefaultCallback, TRANSPORT_WIFI);
}, /* cleanup */ () -> {
// Validate that removing the test network will fallback to the default network.
- runWithShellPermissionIdentity(tnt::teardown);
- defaultCallback.expectCallback(CallbackEntry.LOST, tnt.getNetwork(),
- NETWORK_CALLBACK_TIMEOUT_MS);
- waitForAvailable(defaultCallback);
+ runWithShellPermissionIdentity(tnt::teardown);
+ defaultCallback.expect(CallbackEntry.LOST, tnt, NETWORK_CALLBACK_TIMEOUT_MS);
+ waitForAvailable(defaultCallback);
}, /* cleanup */ () -> {
setWifiMeteredStatusAndWait(ssid, oldMeteredValue, false /* waitForValidation */);
}, /* cleanup */ () -> {
@@ -2666,8 +2667,7 @@
waitForAvailable(systemDefaultCallback, wifiNetwork);
}, /* cleanup */ () -> {
runWithShellPermissionIdentity(tnt::teardown);
- defaultCallback.expectCallback(CallbackEntry.LOST, tnt.getNetwork(),
- NETWORK_CALLBACK_TIMEOUT_MS);
+ defaultCallback.expect(CallbackEntry.LOST, tnt, NETWORK_CALLBACK_TIMEOUT_MS);
// This network preference should only ever use the test network therefore available
// should not trigger when the test network goes down (e.g. switch to cellular).
@@ -2751,6 +2751,27 @@
mCm.getActiveNetwork(), false /* accept */ , false /* always */));
}
+ private void ensureCellIsValidatedBeforeMockingValidationUrls() {
+ // Verify that current supported network is validated so that the mock http server will not
+ // apply to unexpected networks. Also see aosp/2208680.
+ //
+ // This may also apply to wifi in principle, but in practice methods that mock validation
+ // URL all disconnect wifi forcefully anyway, so don't wait for wifi to validate.
+ if (mPackageManager.hasSystemFeature(FEATURE_TELEPHONY)) {
+ ensureValidatedNetwork(makeCellNetworkRequest());
+ }
+ }
+
+ private void ensureValidatedNetwork(NetworkRequest request) {
+ final TestableNetworkCallback cb = new TestableNetworkCallback();
+ mCm.registerNetworkCallback(request, cb);
+ cb.eventuallyExpect(CallbackEntry.NETWORK_CAPS_UPDATED,
+ NETWORK_CALLBACK_TIMEOUT_MS,
+ entry -> ((CallbackEntry.CapabilitiesChanged) entry).getCaps()
+ .hasCapability(NET_CAPABILITY_VALIDATED));
+ mCm.unregisterNetworkCallback(cb);
+ }
+
@AppModeFull(reason = "WRITE_DEVICE_CONFIG permission can't be granted to instant apps")
@Test
public void testAcceptPartialConnectivity_validatedNetwork() throws Exception {
@@ -2882,7 +2903,8 @@
assertTrue(mCm.getNetworkCapabilities(wifiNetwork).hasCapability(
NET_CAPABILITY_VALIDATED));
- // Configure response code for unvalidated network
+ // The cell network has already been checked to be validated.
+ // Configure response code for unvalidated network.
configTestServer(Status.INTERNAL_ERROR, Status.INTERNAL_ERROR);
mCm.reportNetworkConnectivity(wifiNetwork, false);
// Default network should stay on unvalidated wifi because avoid bad wifi is disabled.
@@ -2970,6 +2992,8 @@
}
private Network prepareValidatedNetwork() throws Exception {
+ ensureCellIsValidatedBeforeMockingValidationUrls();
+
prepareHttpServer();
configTestServer(Status.NO_CONTENT, Status.NO_CONTENT);
// Disconnect wifi first then start wifi network with configuration.
@@ -2980,6 +3004,8 @@
}
private Network preparePartialConnectivity() throws Exception {
+ ensureCellIsValidatedBeforeMockingValidationUrls();
+
prepareHttpServer();
// Configure response code for partial connectivity
configTestServer(Status.INTERNAL_ERROR /* httpsStatusCode */,
@@ -2993,6 +3019,8 @@
}
private Network prepareUnvalidatedNetwork() throws Exception {
+ ensureCellIsValidatedBeforeMockingValidationUrls();
+
prepareHttpServer();
// Configure response code for unvalidated network
configTestServer(Status.INTERNAL_ERROR /* httpsStatusCode */,
diff --git a/tests/cts/net/src/android/net/cts/DeviceConfigRule.kt b/tests/cts/net/src/android/net/cts/DeviceConfigRule.kt
index 9599d4e..3a36cee 100644
--- a/tests/cts/net/src/android/net/cts/DeviceConfigRule.kt
+++ b/tests/cts/net/src/android/net/cts/DeviceConfigRule.kt
@@ -27,6 +27,9 @@
import org.junit.rules.TestRule
import org.junit.runner.Description
import org.junit.runners.model.Statement
+import java.util.concurrent.CompletableFuture
+import java.util.concurrent.Executor
+import java.util.concurrent.TimeUnit
private val TAG = DeviceConfigRule::class.simpleName
@@ -110,17 +113,60 @@
* Set a configuration key/value. After the test case ends, it will be restored to the value it
* had when this method was first called.
*/
- fun setConfig(namespace: String, key: String, value: String?) {
- runAsShell(READ_DEVICE_CONFIG, WRITE_DEVICE_CONFIG) {
- val keyPair = Pair(namespace, key)
- if (!originalConfig.containsKey(keyPair)) {
- originalConfig[keyPair] = DeviceConfig.getProperty(namespace, key)
+ fun setConfig(namespace: String, key: String, value: String?): String? {
+ Log.i(TAG, "Setting config \"$key\" to \"$value\"")
+ val readWritePermissions = arrayOf(READ_DEVICE_CONFIG, WRITE_DEVICE_CONFIG)
+
+ val keyPair = Pair(namespace, key)
+ val existingValue = runAsShell(*readWritePermissions) {
+ DeviceConfig.getProperty(namespace, key)
+ }
+ if (!originalConfig.containsKey(keyPair)) {
+ originalConfig[keyPair] = existingValue
+ }
+ usedConfig[keyPair] = value
+ if (existingValue == value) {
+ // Already the correct value. There may be a race if a change is already in flight,
+ // but if multiple threads update the config there is no way to fix that anyway.
+ Log.i(TAG, "\"$key\" already had value \"$value\"")
+ return value
+ }
+
+ val future = CompletableFuture<String>()
+ val listener = DeviceConfig.OnPropertiesChangedListener {
+ // The listener receives updates for any change to any key, so don't react to
+ // changes that do not affect the relevant key
+ if (!it.keyset.contains(key)) return@OnPropertiesChangedListener
+ // "null" means absent in DeviceConfig : there is no such thing as a present but
+ // null value, so the following works even if |value| is null.
+ if (it.getString(key, null) == value) {
+ future.complete(value)
}
- usedConfig[keyPair] = value
- DeviceConfig.setProperty(namespace, key, value, false /* makeDefault */)
+ }
+
+ return tryTest {
+ runAsShell(*readWritePermissions) {
+ DeviceConfig.addOnPropertiesChangedListener(
+ DeviceConfig.NAMESPACE_CONNECTIVITY,
+ inlineExecutor,
+ listener)
+ DeviceConfig.setProperty(
+ DeviceConfig.NAMESPACE_CONNECTIVITY,
+ key,
+ value,
+ false /* makeDefault */)
+ // Don't drop the permission until the config is applied, just in case
+ future.get(NetworkValidationTestUtil.TIMEOUT_MS, TimeUnit.MILLISECONDS)
+ }.also {
+ Log.i(TAG, "Config \"$key\" successfully set to \"$value\"")
+ }
+ } cleanup {
+ DeviceConfig.removeOnPropertiesChangedListener(listener)
}
}
+ private val inlineExecutor get() = Executor { r -> r.run() }
+
/**
* Add an action to be run after config cleanup when the current test case ends.
*/
diff --git a/tests/cts/net/src/android/net/cts/DnsResolverTest.java b/tests/cts/net/src/android/net/cts/DnsResolverTest.java
index 0c53411..3821cea 100644
--- a/tests/cts/net/src/android/net/cts/DnsResolverTest.java
+++ b/tests/cts/net/src/android/net/cts/DnsResolverTest.java
@@ -200,13 +200,13 @@
super(data);
// Check QR field.(query (0), or a response (1)).
- if ((mHeader.flags & (1 << 15)) == 0) {
+ if ((mHeader.getFlags() & (1 << 15)) == 0) {
throw new DnsParseException("Not an answer packet");
}
}
int getRcode() {
- return mHeader.rcode;
+ return mHeader.getFlags() & 0x0F;
}
int getANCount() {
diff --git a/tests/cts/net/src/android/net/cts/DscpPolicyTest.kt b/tests/cts/net/src/android/net/cts/DscpPolicyTest.kt
index 8940075..db13c49 100644
--- a/tests/cts/net/src/android/net/cts/DscpPolicyTest.kt
+++ b/tests/cts/net/src/android/net/cts/DscpPolicyTest.kt
@@ -105,6 +105,7 @@
private const val TAG = "DscpPolicyTest"
private const val PACKET_TIMEOUT_MS = 2_000L
+private const val IPV6_ADDRESS_WAIT_TIME_MS = 10_000L
@AppModeFull(reason = "Instant apps cannot create test networks")
@RunWith(AndroidJUnit4::class)
@@ -222,7 +223,7 @@
var inet6Addr: Inet6Address? = null
val onLinkPrefix = raResponder.prefix
val startTime = SystemClock.elapsedRealtime()
- while (SystemClock.elapsedRealtime() - startTime < PACKET_TIMEOUT_MS) {
+ while (SystemClock.elapsedRealtime() - startTime < IPV6_ADDRESS_WAIT_TIME_MS) {
SystemClock.sleep(50 /* ms */)
val sock = Os.socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP)
try {
diff --git a/tests/cts/net/src/android/net/cts/EthernetManagerTest.kt b/tests/cts/net/src/android/net/cts/EthernetManagerTest.kt
index ce8584f..7e91478 100644
--- a/tests/cts/net/src/android/net/cts/EthernetManagerTest.kt
+++ b/tests/cts/net/src/android/net/cts/EthernetManagerTest.kt
@@ -41,6 +41,8 @@
import android.net.MacAddress
import android.net.Network
import android.net.NetworkCapabilities
+import android.net.NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED
+import android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED
import android.net.NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED
import android.net.NetworkCapabilities.NET_CAPABILITY_TRUSTED
import android.net.NetworkCapabilities.TRANSPORT_ETHERNET
@@ -55,8 +57,9 @@
import android.os.Handler
import android.os.Looper
import android.os.OutcomeReceiver
+import android.os.SystemProperties
+import android.os.Process
import android.platform.test.annotations.AppModeFull
-import android.util.ArraySet
import androidx.test.platform.app.InstrumentationRegistry
import com.android.net.module.util.ArrayTrackRecord
import com.android.net.module.util.TrackRecord
@@ -66,21 +69,24 @@
import com.android.testutils.DeviceInfoUtils.isKernelVersionAtLeast
import com.android.testutils.RecorderCallback.CallbackEntry.Available
import com.android.testutils.RecorderCallback.CallbackEntry.CapabilitiesChanged
+import com.android.testutils.RecorderCallback.CallbackEntry.LinkPropertiesChanged
import com.android.testutils.RecorderCallback.CallbackEntry.Lost
import com.android.testutils.RouterAdvertisementResponder
-import com.android.testutils.SkipPresubmit
import com.android.testutils.TapPacketReader
import com.android.testutils.TestableNetworkCallback
-import com.android.testutils.anyNetwork
+import com.android.testutils.assertThrows
import com.android.testutils.runAsShell
import com.android.testutils.waitForIdle
import org.junit.After
+import org.junit.Assume.assumeFalse
import org.junit.Assume.assumeTrue
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
+import java.io.IOException
import java.net.Inet6Address
import java.util.Random
+import java.net.Socket
import java.util.concurrent.CompletableFuture
import java.util.concurrent.ExecutionException
import java.util.concurrent.TimeUnit
@@ -95,11 +101,13 @@
import kotlin.test.fail
private const val TAG = "EthernetManagerTest"
-// TODO: try to lower this timeout in the future. Currently, ethernet tests are still flaky because
-// the interface is not ready fast enough (mostly due to the up / up / down / up issue).
-private const val TIMEOUT_MS = 2000L
+// This timeout does not affect the test duration for passing tests. It needs to be long enough to
+// account for RS delay (and potentially the first retry interval (4s)). There have been failures
+// where the interface did not gain provisioning within the allotted timeout.
+private const val TIMEOUT_MS = 10_000L
// Timeout used to confirm no callbacks matching given criteria are received. Must be long enough to
// process all callbacks including ip provisioning when using the updateConfiguration API.
+// Note that increasing this timeout increases the test duration.
private const val NO_CALLBACK_TIMEOUT_MS = 500L
private val DEFAULT_IP_CONFIGURATION = IpConfiguration(IpConfiguration.IpAssignment.DHCP,
@@ -109,6 +117,10 @@
.addTransportType(TRANSPORT_ETHERNET)
.removeCapability(NET_CAPABILITY_TRUSTED)
.build()
+private val TEST_CAPS = NetworkCapabilities.Builder(ETH_REQUEST.networkCapabilities)
+ .addCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED)
+ .addCapability(NET_CAPABILITY_NOT_CONGESTED)
+ .build()
private val STATIC_IP_CONFIGURATION = IpConfiguration.Builder()
.setStaticIpConfiguration(StaticIpConfiguration.Builder()
.setIpAddress(LinkAddress("192.0.2.1/30")).build())
@@ -119,7 +131,6 @@
@RunWith(DevSdkIgnoreRunner::class)
// This test depends on behavior introduced post-T as part of connectivity module updates
@ConnectivityModuleTest
-@SkipPresubmit(reason = "Flaky: b/240323229; remove annotation after fixing")
@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.S_V2)
class EthernetManagerTest {
@@ -145,12 +156,17 @@
private val raResponder: RouterAdvertisementResponder
private val tnm: TestNetworkManager
val name get() = tapInterface.interfaceName
+ val onLinkPrefix get() = raResponder.prefix
init {
tnm = runAsShell(MANAGE_TEST_NETWORKS) {
context.getSystemService(TestNetworkManager::class.java)
}
tapInterface = runAsShell(MANAGE_TEST_NETWORKS) {
+ // Configuring a tun/tap interface always enables the carrier. If hasCarrier is
+ // false, it is subsequently disabled. This means that the interface may briefly get
+ // link. With IPv6 provisioning delays (RS delay and DAD) disabled, this can cause
+ // tests that expect no network to come up when hasCarrier is false to become flaky.
tnm.createTapInterface(hasCarrier, false /* bringUp */)
}
val mtu = tapInterface.mtu
@@ -193,9 +209,35 @@
val state: Int,
val role: Int,
val configuration: IpConfiguration?
- ) : CallbackEntry()
+ ) : CallbackEntry() {
+ override fun toString(): String {
+ val stateString = when (state) {
+ STATE_ABSENT -> "STATE_ABSENT"
+ STATE_LINK_UP -> "STATE_LINK_UP"
+ STATE_LINK_DOWN -> "STATE_LINK_DOWN"
+ else -> state.toString()
+ }
+ val roleString = when (role) {
+ ROLE_NONE -> "ROLE_NONE"
+ ROLE_CLIENT -> "ROLE_CLIENT"
+ ROLE_SERVER -> "ROLE_SERVER"
+ else -> role.toString()
+ }
+ return ("InterfaceStateChanged(iface=$iface, state=$stateString, " +
+ "role=$roleString, ipConfig=$configuration)")
+ }
+ }
- data class EthernetStateChanged(val state: Int) : CallbackEntry()
+ data class EthernetStateChanged(val state: Int) : CallbackEntry() {
+ override fun toString(): String {
+ val stateString = when (state) {
+ ETHERNET_STATE_ENABLED -> "ETHERNET_STATE_ENABLED"
+ ETHERNET_STATE_DISABLED -> "ETHERNET_STATE_DISABLED"
+ else -> state.toString()
+ }
+ return "EthernetStateChanged(state=$stateString)"
+ }
+ }
}
override fun onInterfaceStateChanged(
@@ -212,7 +254,7 @@
}
fun <T : CallbackEntry> expectCallback(expected: T): T {
- val event = pollForNextCallback()
+ val event = pollOrThrow()
assertEquals(expected, event)
return event as T
}
@@ -229,18 +271,20 @@
InterfaceStateChanged(iface, state, role,
if (state != STATE_ABSENT) DEFAULT_IP_CONFIGURATION else null)
- fun pollForNextCallback(): CallbackEntry {
+ fun pollOrThrow(): CallbackEntry {
return events.poll(TIMEOUT_MS) ?: fail("Did not receive callback after ${TIMEOUT_MS}ms")
}
fun eventuallyExpect(expected: CallbackEntry) = events.poll(TIMEOUT_MS) { it == expected }
fun eventuallyExpect(iface: EthernetTestInterface, state: Int, role: Int) {
- assertNotNull(eventuallyExpect(createChangeEvent(iface.name, state, role)))
+ val event = createChangeEvent(iface.name, state, role)
+ assertNotNull(eventuallyExpect(event), "Never received expected $event")
}
fun eventuallyExpect(state: Int) {
- assertNotNull(eventuallyExpect(EthernetStateChanged(state)))
+ val event = EthernetStateChanged(state)
+ assertNotNull(eventuallyExpect(event), "Never received expected $event")
}
fun assertNoCallback() {
@@ -260,8 +304,8 @@
available.completeExceptionally(IllegalStateException("onUnavailable was called"))
}
- fun expectOnAvailable(): String {
- return available.get(TIMEOUT_MS, TimeUnit.MILLISECONDS)
+ fun expectOnAvailable(timeout: Long = TIMEOUT_MS): String {
+ return available.get(timeout, TimeUnit.MILLISECONDS)
}
fun expectOnUnavailable() {
@@ -282,10 +326,12 @@
private val result = CompletableFuture<String>()
override fun onResult(iface: String) {
+ assertFalse(result.isDone())
result.complete(iface)
}
override fun onError(e: EthernetNetworkManagementException) {
+ assertFalse(result.isDone())
result.completeExceptionally(e)
}
@@ -306,14 +352,24 @@
}
}
+ private fun isEthernetSupported() = em != null
+
@Before
fun setUp() {
+ assumeTrue(isEthernetSupported())
setIncludeTestInterfaces(true)
addInterfaceStateListener(ifaceListener)
+ // Handler.post() events may get processed after native fd events, so it is possible that
+ // RTM_NEWLINK (from a subsequent createInterface() call) arrives before the interface state
+ // listener is registered. This affects the callbacks and breaks the tests.
+ // setEthernetEnabled() will always wait on a callback, so it is used as a barrier to ensure
+ // proper listener registration before proceeding.
+ setEthernetEnabled(true)
}
@After
fun tearDown() {
+ if (!isEthernetSupported()) return
// Reenable ethernet, so ABSENT callbacks are received.
setEthernetEnabled(true)
@@ -326,7 +382,10 @@
setIncludeTestInterfaces(false)
for (listener in addedListeners) {
+ // Even if a given listener was not registered as both an interface and ethernet state
+ // listener, calling remove is safe.
em.removeInterfaceStateListener(listener)
+ em.removeEthernetStateListener(listener)
}
registeredCallbacks.forEach { cm.unregisterNetworkCallback(it) }
releaseTetheredInterface()
@@ -335,10 +394,25 @@
// Setting the carrier up / down relies on TUNSETCARRIER which was added in kernel version 5.0.
private fun assumeChangingCarrierSupported() = assumeTrue(isKernelVersionAtLeast("5.0.0"))
+ private fun isAdbOverEthernet(): Boolean {
+ // If no ethernet interface is available, adb is not connected over ethernet.
+ if (em.getInterfaceList().isEmpty()) return false
+
+ // cuttlefish is special and does not connect adb over ethernet.
+ if (SystemProperties.get("ro.product.board", "") == "cutf") return false
+
+ // Check if adb is connected over the network.
+ return (SystemProperties.getInt("persist.adb.tcp.port", -1) > -1 ||
+ SystemProperties.getInt("service.adb.tcp.port", -1) > -1)
+ }
+
private fun addInterfaceStateListener(listener: EthernetStateListener) {
- runAsShell(CONNECTIVITY_USE_RESTRICTED_NETWORKS) {
- em.addInterfaceStateListener(handler::post, listener)
- }
+ em.addInterfaceStateListener(handler::post, listener)
+ addedListeners.add(listener)
+ }
+
+ private fun addEthernetStateListener(listener: EthernetStateListener) {
+ em.addEthernetStateListener(handler::post, listener)
addedListeners.add(listener)
}
@@ -372,14 +446,18 @@
}
private fun requestNetwork(request: NetworkRequest): TestableNetworkCallback {
- return TestableNetworkCallback().also {
+ return TestableNetworkCallback(
+ timeoutMs = TIMEOUT_MS,
+ noCallbackTimeoutMs = NO_CALLBACK_TIMEOUT_MS).also {
cm.requestNetwork(request, it)
registeredCallbacks.add(it)
}
}
private fun registerNetworkListener(request: NetworkRequest): TestableNetworkCallback {
- return TestableNetworkCallback().also {
+ return TestableNetworkCallback(
+ timeoutMs = TIMEOUT_MS,
+ noCallbackTimeoutMs = NO_CALLBACK_TIMEOUT_MS).also {
cm.registerNetworkCallback(request, it)
registeredCallbacks.add(it)
}
@@ -431,82 +509,82 @@
}
}
+ // WARNING: check that isAdbOverEthernet() is false before calling setEthernetEnabled(false).
private fun setEthernetEnabled(enabled: Boolean) {
runAsShell(NETWORK_SETTINGS) { em.setEthernetEnabled(enabled) }
val listener = EthernetStateListener()
- em.addEthernetStateListener(handler::post, listener)
- try {
- listener.eventuallyExpect(
- if (enabled) ETHERNET_STATE_ENABLED else ETHERNET_STATE_DISABLED)
- } finally {
- em.removeEthernetStateListener(listener)
- }
+ addEthernetStateListener(listener)
+ listener.eventuallyExpect(if (enabled) ETHERNET_STATE_ENABLED else ETHERNET_STATE_DISABLED)
}
// NetworkRequest.Builder does not create a copy of the passed NetworkRequest, so in order to
// keep ETH_REQUEST as it is, a defensive copy is created here.
- private fun NetworkRequest.createCopyWithEthernetSpecifier(ifaceName: String) =
+ private fun NetworkRequest.copyWithEthernetSpecifier(ifaceName: String) =
NetworkRequest.Builder(NetworkRequest(ETH_REQUEST))
.setNetworkSpecifier(EthernetNetworkSpecifier(ifaceName)).build()
- // It can take multiple seconds for the network to become available.
- private fun TestableNetworkCallback.expectAvailable() =
- expectCallback<Available>(anyNetwork(), 5000 /* ms timeout */).network
-
- private fun TestableNetworkCallback.expectLost(n: Network = anyNetwork()) =
- expectCallback<Lost>(n, 5000 /* ms timeout */)
-
// b/233534110: eventuallyExpect<Lost>() does not advance ReadHead, use
// eventuallyExpect(Lost::class) instead.
private fun TestableNetworkCallback.eventuallyExpectLost(n: Network? = null) =
- eventuallyExpect(Lost::class, TIMEOUT_MS) { n?.equals(it.network) ?: true }
+ eventuallyExpect(Lost::class) { n?.equals(it.network) ?: true }
private fun TestableNetworkCallback.assertNeverLost(n: Network? = null) =
- assertNoCallbackThat(NO_CALLBACK_TIMEOUT_MS) {
+ assertNoCallbackThat() {
it is Lost && (n?.equals(it.network) ?: true)
}
private fun TestableNetworkCallback.assertNeverAvailable(n: Network? = null) =
- assertNoCallbackThat() { it is Available && (n?.equals(it.network) ?: true) }
+ assertNoCallbackThat { it is Available && (n?.equals(it.network) ?: true) }
private fun TestableNetworkCallback.expectCapabilitiesWithInterfaceName(name: String) =
- expectCapabilitiesThat(anyNetwork()) {
- it.networkSpecifier == EthernetNetworkSpecifier(name)
- }
+ expect<CapabilitiesChanged> { it.caps.networkSpecifier == EthernetNetworkSpecifier(name) }
- private fun TestableNetworkCallback.expectCapabilitiesWithCapability(cap: Int) =
- expectCapabilitiesThat(anyNetwork(), TIMEOUT_MS) {
- it.hasCapability(cap)
+ private fun TestableNetworkCallback.eventuallyExpectCapabilities(nc: NetworkCapabilities) {
+ // b/233534110: eventuallyExpect<CapabilitiesChanged>() does not advance ReadHead.
+ eventuallyExpect(CapabilitiesChanged::class) {
+ // CS may mix in additional capabilities, so NetworkCapabilities#equals cannot be used.
+ // Check if all expected capabilities are present instead.
+ it is CapabilitiesChanged && nc.capabilities.all { c -> it.caps.hasCapability(c) }
}
+ }
- private fun TestableNetworkCallback.expectLinkPropertiesWithLinkAddress(addr: LinkAddress) =
- expectLinkPropertiesThat(anyNetwork(), TIMEOUT_MS) {
- // LinkAddress.equals isn't possible as the system changes the LinkAddress.flags value.
- // any() must be used since the interface may also have a link-local address.
- it.linkAddresses.any { x -> x.isSameAddressAs(addr) }
+ private fun TestableNetworkCallback.eventuallyExpectLpForStaticConfig(
+ config: StaticIpConfiguration
+ ) {
+ // b/233534110: eventuallyExpect<LinkPropertiesChanged>() does not advance ReadHead.
+ eventuallyExpect(LinkPropertiesChanged::class) {
+ it is LinkPropertiesChanged && it.lp.linkAddresses.any { la ->
+ la.isSameAddressAs(config.ipAddress)
+ }
}
+ }
@Test
fun testCallbacks() {
+ // Only run this test when no non-restricted / physical interfaces are present.
+ // This test ensures that interface state listeners function properly, so the assumption
+ // check is explicitly *not* using an interface state listener.
+ // Since restricted interfaces cannot be used for tethering,
+ // assumeNoInterfaceForTetheringAvailable() is an okay proxy.
+ assumeNoInterfaceForTetheringAvailable()
+
// If an interface exists when the callback is registered, it is reported on registration.
val iface = createInterface()
val listener1 = EthernetStateListener()
addInterfaceStateListener(listener1)
- validateListenerOnRegistration(listener1)
+ listener1.expectCallback(iface, STATE_LINK_UP, ROLE_CLIENT)
// If an interface appears, existing callbacks see it.
- // TODO: fix the up/up/down/up callbacks and only send down/up.
val iface2 = createInterface()
- listener1.expectCallback(iface2, STATE_LINK_UP, ROLE_CLIENT)
- listener1.expectCallback(iface2, STATE_LINK_UP, ROLE_CLIENT)
listener1.expectCallback(iface2, STATE_LINK_DOWN, ROLE_CLIENT)
listener1.expectCallback(iface2, STATE_LINK_UP, ROLE_CLIENT)
// Register a new listener, it should see state of all existing interfaces immediately.
val listener2 = EthernetStateListener()
addInterfaceStateListener(listener2)
- validateListenerOnRegistration(listener2)
+ listener2.expectCallback(iface, STATE_LINK_UP, ROLE_CLIENT)
+ listener2.expectCallback(iface2, STATE_LINK_UP, ROLE_CLIENT)
// Removing interfaces first sends link down, then STATE_ABSENT/ROLE_NONE.
removeInterface(iface)
@@ -523,12 +601,32 @@
}
}
+ @Test
+ fun testCallbacks_withRunningInterface() {
+ assumeFalse(isAdbOverEthernet())
+ // Only run this test when no non-restricted / physical interfaces are present.
+ assumeNoInterfaceForTetheringAvailable()
+
+ val iface = createInterface()
+ val listener = EthernetStateListener()
+ addInterfaceStateListener(listener)
+ listener.eventuallyExpect(iface, STATE_LINK_UP, ROLE_CLIENT)
+
+ // Remove running interface. The interface stays running but is no longer tracked.
+ setEthernetEnabled(false)
+ listener.expectCallback(iface, STATE_ABSENT, ROLE_NONE)
+
+ setEthernetEnabled(true)
+ listener.expectCallback(iface, STATE_LINK_UP, ROLE_CLIENT)
+ listener.assertNoCallback()
+ }
+
private fun assumeNoInterfaceForTetheringAvailable() {
// Interfaces that have configured NetworkCapabilities will never be used for tethering,
// see aosp/2123900.
try {
// assumeException does not exist.
- requestTetheredInterface().expectOnAvailable()
+ requestTetheredInterface().expectOnAvailable(NO_CALLBACK_TIMEOUT_MS)
// interface used for tethering is available, throw an assumption error.
assumeTrue(false)
} catch (e: TimeoutException) {
@@ -564,28 +662,6 @@
listener.expectCallback(iface, STATE_LINK_UP, ROLE_CLIENT)
}
- /**
- * Validate all interfaces are returned for an EthernetStateListener upon registration.
- */
- private fun validateListenerOnRegistration(listener: EthernetStateListener) {
- // Get all tracked interfaces to validate on listener registration. Ordering and interface
- // state (up/down) can't be validated for interfaces not created as part of testing.
- val ifaces = em.getInterfaceList()
- val polledIfaces = ArraySet<String>()
- for (i in ifaces) {
- val event = (listener.pollForNextCallback() as InterfaceStateChanged)
- val iface = event.iface
- assertTrue(polledIfaces.add(iface), "Duplicate interface $iface returned")
- assertTrue(ifaces.contains(iface), "Untracked interface $iface returned")
- // If the event's iface was created in the test, additional criteria can be validated.
- createdIfaces.find { it.name.equals(iface) }?.let {
- assertEquals(event, listener.createChangeEvent(it.name, STATE_LINK_UP, ROLE_CLIENT))
- }
- }
- // Assert all callbacks are accounted for.
- listener.assertNoCallback()
- }
-
@Test
fun testGetInterfaceList() {
// Create two test interfaces and check the return list contains the interface names.
@@ -612,9 +688,11 @@
// install a listener which will later be used to verify the Lost callback
val listenerCb = registerNetworkListener(ETH_REQUEST)
+ // assert the network is only brought up by a request.
+ listenerCb.assertNeverAvailable()
val cb = requestNetwork(ETH_REQUEST)
- val network = cb.expectAvailable()
+ val network = cb.expect<Available>().network
cb.assertNeverLost()
releaseRequest(cb)
@@ -631,7 +709,7 @@
// createInterface and the interface actually being properly registered with the ethernet
// module, so it is extremely unlikely that the CS handler thread has not run until then.
val iface = createInterface()
- val network = cb.expectAvailable()
+ val network = cb.expect<Available>().network
// remove interface before network request has been removed
cb.assertNeverLost()
@@ -644,9 +722,9 @@
val iface1 = createInterface()
val iface2 = createInterface()
- val cb = requestNetwork(ETH_REQUEST.createCopyWithEthernetSpecifier(iface2.name))
+ val cb = requestNetwork(ETH_REQUEST.copyWithEthernetSpecifier(iface2.name))
- val network = cb.expectAvailable()
+ cb.expect<Available>()
cb.expectCapabilitiesWithInterfaceName(iface2.name)
removeInterface(iface1)
@@ -660,7 +738,7 @@
val iface1 = createInterface()
val cb = requestNetwork(ETH_REQUEST)
- val network = cb.expectAvailable()
+ val network = cb.expect<Available>().network
// create another network and verify the request sticks to the current network
val iface2 = createInterface()
@@ -669,7 +747,7 @@
// remove iface1 and verify the request brings up iface2
removeInterface(iface1)
cb.eventuallyExpectLost(network)
- val network2 = cb.expectAvailable()
+ cb.expect<Available>()
}
@Test
@@ -677,16 +755,16 @@
val iface1 = createInterface()
val iface2 = createInterface()
- val cb1 = requestNetwork(ETH_REQUEST.createCopyWithEthernetSpecifier(iface1.name))
- val cb2 = requestNetwork(ETH_REQUEST.createCopyWithEthernetSpecifier(iface2.name))
+ val cb1 = requestNetwork(ETH_REQUEST.copyWithEthernetSpecifier(iface1.name))
+ val cb2 = requestNetwork(ETH_REQUEST.copyWithEthernetSpecifier(iface2.name))
val cb3 = requestNetwork(ETH_REQUEST)
- cb1.expectAvailable()
+ cb1.expect<Available>()
cb1.expectCapabilitiesWithInterfaceName(iface1.name)
- cb2.expectAvailable()
+ cb2.expect<Available>()
cb2.expectCapabilitiesWithInterfaceName(iface2.name)
// this request can be matched by either network.
- cb3.expectAvailable()
+ cb3.expect<Available>()
cb1.assertNeverLost()
cb2.assertNeverLost()
@@ -701,10 +779,10 @@
val cb1 = requestNetwork(ETH_REQUEST)
val iface = createInterface()
- val network = cb1.expectAvailable()
+ val network = cb1.expect<Available>().network
val cb2 = requestNetwork(ETH_REQUEST)
- cb2.expectAvailable()
+ cb2.expect<Available>()
// release the first request; this used to trigger b/197548738
releaseRequest(cb1)
@@ -721,15 +799,31 @@
val iface = createInterface(false /* hasCarrier */)
val cb = requestNetwork(ETH_REQUEST)
- cb.assertNeverAvailable()
+ // TUNSETCARRIER races with the bring up code, so the network *can* become available despite
+ // it being "created with no carrier".
+ // TODO(b/249611919): re-enable assertion once kernel supports IFF_NO_CARRIER.
+ // cb.assertNeverAvailable()
iface.setCarrierEnabled(true)
- cb.expectAvailable()
+ cb.expect<Available>()
iface.setCarrierEnabled(false)
cb.eventuallyExpectLost()
}
+ // TODO: move to MTS
+ @Test
+ fun testNetworkRequest_linkPropertiesUpdate() {
+ val iface = createInterface()
+ val cb = requestNetwork(ETH_REQUEST)
+ // b/233534110: eventuallyExpect<LinkPropertiesChanged>() does not advance ReadHead
+ cb.eventuallyExpect(LinkPropertiesChanged::class) {
+ it is LinkPropertiesChanged && it.lp.addresses.any {
+ address -> iface.onLinkPrefix.contains(address)
+ }
+ }
+ }
+
@Test
fun testRemoveInterface_whileInServerMode() {
assumeNoInterfaceForTetheringAvailable()
@@ -756,75 +850,142 @@
fun testEnableDisableInterface_withActiveRequest() {
val iface = createInterface()
val cb = requestNetwork(ETH_REQUEST)
- cb.expectAvailable()
+ cb.expect<Available>()
cb.assertNeverLost()
disableInterface(iface).expectResult(iface.name)
cb.eventuallyExpectLost()
enableInterface(iface).expectResult(iface.name)
- cb.expectAvailable()
+ cb.expect<Available>()
+ }
+
+ @Test
+ fun testEnableDisableInterface_withoutStateChange() {
+ val iface = createInterface()
+ // Interface is already enabled, so enableInterface() should return success
+ enableInterface(iface).expectResult(iface.name)
+
+ disableInterface(iface).expectResult(iface.name)
+ // Interface is already disabled, so disableInterface() should return success.
+ disableInterface(iface).expectResult(iface.name)
+ }
+
+ @Test
+ fun testEnableDisableInterface_withMissingInterface() {
+ val iface = createInterface()
+ removeInterface(iface)
+ // Interface does not exist, enable/disableInterface() should both return an error.
+ enableInterface(iface).expectError()
+ disableInterface(iface).expectError()
}
@Test
fun testUpdateConfiguration_forBothIpConfigAndCapabilities() {
val iface = createInterface()
- val cb = requestNetwork(ETH_REQUEST.createCopyWithEthernetSpecifier(iface.name))
- val network = cb.expectAvailable()
- cb.assertNeverLost()
+ val cb = requestNetwork(ETH_REQUEST.copyWithEthernetSpecifier(iface.name))
+ cb.expect<Available>()
- val testCapability = NET_CAPABILITY_TEMPORARILY_NOT_METERED
- val nc = NetworkCapabilities
- .Builder(ETH_REQUEST.networkCapabilities)
- .addCapability(testCapability)
- .build()
- updateConfiguration(iface, STATIC_IP_CONFIGURATION, nc)
-
- // UpdateConfiguration() currently does a restarts on the ethernet interface therefore lost
- // will be expected first before available, as part of the restart.
- cb.expectLost(network)
- cb.expectAvailable()
- cb.expectCapabilitiesWithCapability(testCapability)
- cb.expectLinkPropertiesWithLinkAddress(
- STATIC_IP_CONFIGURATION.staticIpConfiguration.ipAddress!!)
+ updateConfiguration(iface, STATIC_IP_CONFIGURATION, TEST_CAPS).expectResult(iface.name)
+ cb.eventuallyExpectCapabilities(TEST_CAPS)
+ cb.eventuallyExpectLpForStaticConfig(STATIC_IP_CONFIGURATION.staticIpConfiguration)
}
@Test
fun testUpdateConfiguration_forOnlyIpConfig() {
- val iface: EthernetTestInterface = createInterface()
- val cb = requestNetwork(ETH_REQUEST.createCopyWithEthernetSpecifier(iface.name))
- val network = cb.expectAvailable()
- cb.assertNeverLost()
+ val iface = createInterface()
+ val cb = requestNetwork(ETH_REQUEST.copyWithEthernetSpecifier(iface.name))
+ cb.expect<Available>()
- updateConfiguration(iface, STATIC_IP_CONFIGURATION)
-
- // UpdateConfiguration() currently does a restarts on the ethernet interface therefore lost
- // will be expected first before available, as part of the restart.
- cb.expectLost(network)
- cb.expectAvailable()
- cb.expectCallback<CapabilitiesChanged>()
- cb.expectLinkPropertiesWithLinkAddress(
- STATIC_IP_CONFIGURATION.staticIpConfiguration.ipAddress!!)
+ updateConfiguration(iface, STATIC_IP_CONFIGURATION).expectResult(iface.name)
+ cb.eventuallyExpectLpForStaticConfig(STATIC_IP_CONFIGURATION.staticIpConfiguration)
}
@Test
fun testUpdateConfiguration_forOnlyCapabilities() {
- val iface: EthernetTestInterface = createInterface()
- val cb = requestNetwork(ETH_REQUEST.createCopyWithEthernetSpecifier(iface.name))
- val network = cb.expectAvailable()
- cb.assertNeverLost()
+ val iface = createInterface()
+ val cb = requestNetwork(ETH_REQUEST.copyWithEthernetSpecifier(iface.name))
+ cb.expect<Available>()
- val testCapability = NET_CAPABILITY_TEMPORARILY_NOT_METERED
- val nc = NetworkCapabilities
- .Builder(ETH_REQUEST.networkCapabilities)
- .addCapability(testCapability)
- .build()
- updateConfiguration(iface, capabilities = nc)
+ updateConfiguration(iface, capabilities = TEST_CAPS).expectResult(iface.name)
+ cb.eventuallyExpectCapabilities(TEST_CAPS)
+ }
- // UpdateConfiguration() currently does a restarts on the ethernet interface therefore lost
+ @Test
+ fun testUpdateConfiguration_forAllowedUids() {
+ // Configure a restricted network.
+ val iface = createInterface()
+ val request = NetworkRequest.Builder(ETH_REQUEST.copyWithEthernetSpecifier(iface.name))
+ .removeCapability(NET_CAPABILITY_NOT_RESTRICTED).build()
+ updateConfiguration(iface, capabilities = request.networkCapabilities)
+ .expectResult(iface.name)
+
+ // Request the restricted network as the shell with CONNECTIVITY_USE_RESTRICTED_NETWORKS.
+ val cb = runAsShell(CONNECTIVITY_USE_RESTRICTED_NETWORKS) { requestNetwork(request) }
+ val network = cb.expect<Available>().network
+ cb.assertNeverLost(network)
+
+ // The network is restricted therefore binding to it when available will fail.
+ Socket().use { socket ->
+ assertThrows(IOException::class.java, { network.bindSocket(socket) })
+ }
+
+ // Add the test process UID to the allowed UIDs for the network and ultimately bind again.
+ val allowedUids = setOf(Process.myUid())
+ val nc = NetworkCapabilities.Builder(request.networkCapabilities)
+ .setAllowedUids(allowedUids).build()
+ updateConfiguration(iface, capabilities = nc).expectResult(iface.name)
+
+ // UpdateConfiguration() currently does a restart on the ethernet interface therefore lost
// will be expected first before available, as part of the restart.
- cb.expectLost(network)
- cb.expectAvailable()
- cb.expectCapabilitiesWithCapability(testCapability)
+ cb.expect<Lost>(network)
+ val updatedNetwork = cb.expect<Available>().network
+ // With the test process UID allowed, binding to a restricted network should be successful.
+ Socket().use { socket -> updatedNetwork.bindSocket(socket) }
+
+ // Reset capabilities to not-restricted, otherwise tearDown won't see the interface callback
+ // as ifaceListener does not have the restricted permission.
+ // TODO: Find a better way to do this when there are more tests around restricted
+ // interfaces.
+ updateConfiguration(iface, capabilities = TEST_CAPS).expectResult(iface.name)
+ }
+
+ // TODO: consider only having this test in MTS as it makes use of the fact that
+ // setEthernetEnabled(false) untracks all interfaces. This behavior is an implementation detail
+ // and may change in the future.
+ @Test
+ fun testUpdateConfiguration_onUntrackedInterface() {
+ assumeFalse(isAdbOverEthernet())
+ val iface = createInterface()
+ setEthernetEnabled(false)
+
+ // Updating the IpConfiguration and NetworkCapabilities on absent interfaces is a supported
+ // use case.
+ updateConfiguration(iface, STATIC_IP_CONFIGURATION, TEST_CAPS).expectResult(iface.name)
+
+ setEthernetEnabled(true)
+ val cb = requestNetwork(ETH_REQUEST)
+ cb.expect<Available>()
+ cb.eventuallyExpectCapabilities(TEST_CAPS)
+ cb.eventuallyExpectLpForStaticConfig(STATIC_IP_CONFIGURATION.staticIpConfiguration)
+ }
+
+ @Test
+ fun testUpdateConfiguration_withLinkDown() {
+ assumeChangingCarrierSupported()
+ // createInterface without carrier is racy, so create it and then remove carrier.
+ val iface = createInterface()
+ val cb = requestNetwork(ETH_REQUEST)
+ cb.expect<Available>()
+
+ iface.setCarrierEnabled(false)
+ cb.eventuallyExpectLost()
+
+ updateConfiguration(iface, STATIC_IP_CONFIGURATION, TEST_CAPS).expectResult(iface.name)
+ cb.assertNoCallback()
+
+ iface.setCarrierEnabled(true)
+ cb.eventuallyExpectCapabilities(TEST_CAPS)
+ cb.eventuallyExpectLpForStaticConfig(STATIC_IP_CONFIGURATION.staticIpConfiguration)
}
}
diff --git a/tests/cts/net/src/android/net/cts/Ikev2VpnTest.java b/tests/cts/net/src/android/net/cts/Ikev2VpnTest.java
index 2b1d173..ac50740 100644
--- a/tests/cts/net/src/android/net/cts/Ikev2VpnTest.java
+++ b/tests/cts/net/src/android/net/cts/Ikev2VpnTest.java
@@ -24,7 +24,6 @@
import static com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity;
import static com.android.modules.utils.build.SdkLevel.isAtLeastT;
import static com.android.testutils.DevSdkIgnoreRuleKt.SC_V2;
-import static com.android.testutils.TestableNetworkCallbackKt.anyNetwork;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
@@ -520,8 +519,7 @@
HexDump.hexStringToByteArray(authResp));
// Verify the VPN network came up
- final Network vpnNetwork = cb.expectCallback(CallbackEntry.AVAILABLE, anyNetwork())
- .getNetwork();
+ final Network vpnNetwork = cb.expect(CallbackEntry.AVAILABLE).getNetwork();
if (testSessionKey) {
final VpnProfileStateShim profileState = mVmShim.getProvisionedVpnProfileState();
@@ -536,8 +534,8 @@
&& caps.hasCapability(NET_CAPABILITY_INTERNET)
&& !caps.hasCapability(NET_CAPABILITY_VALIDATED)
&& Process.myUid() == caps.getOwnerUid());
- cb.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, vpnNetwork);
- cb.expectCallback(CallbackEntry.BLOCKED_STATUS, vpnNetwork);
+ cb.expect(CallbackEntry.LINK_PROPERTIES_CHANGED, vpnNetwork);
+ cb.expect(CallbackEntry.BLOCKED_STATUS, vpnNetwork);
// A VPN that requires validation is initially not validated, while one that doesn't
// immediately validate automatically. Because this VPN can't actually access Internet,
diff --git a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt
index d4f3d57..6df71c8 100644
--- a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt
+++ b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt
@@ -73,6 +73,8 @@
import android.os.Message
import android.os.SystemClock
import android.platform.test.annotations.AppModeFull
+import android.system.OsConstants.IPPROTO_TCP
+import android.system.OsConstants.IPPROTO_UDP
import android.telephony.TelephonyManager
import android.telephony.data.EpsBearerQosSessionAttributes
import android.util.DebugUtils.valueToString
@@ -117,6 +119,7 @@
import org.mockito.Mockito.mock
import org.mockito.Mockito.timeout
import org.mockito.Mockito.verify
+import java.io.Closeable
import java.io.IOException
import java.net.DatagramSocket
import java.net.InetAddress
@@ -174,7 +177,7 @@
private val mFakeConnectivityService = FakeConnectivityService()
private val agentsToCleanUp = mutableListOf<NetworkAgent>()
private val callbacksToCleanUp = mutableListOf<TestableNetworkCallback>()
- private var qosTestSocket: Socket? = null
+ private var qosTestSocket: Closeable? = null // either Socket or DatagramSocket
@Before
fun setUp() {
@@ -332,6 +335,28 @@
mFakeConnectivityService.connect(it.registerForTest(Network(FAKE_NET_ID)))
}
+ fun assertLinkPropertiesEventually(
+ n: Network,
+ description: String,
+ condition: (LinkProperties?) -> Boolean
+ ): LinkProperties? {
+ val deadline = SystemClock.elapsedRealtime() + DEFAULT_TIMEOUT_MS
+ do {
+ val lp = mCM.getLinkProperties(n)
+ if (condition(lp)) return lp
+ SystemClock.sleep(10 /* ms */)
+ } while (SystemClock.elapsedRealtime() < deadline)
+ fail("Network $n LinkProperties did not $description after $DEFAULT_TIMEOUT_MS ms")
+ }
+
+ fun assertLinkPropertiesEventuallyNotNull(n: Network) {
+ assertLinkPropertiesEventually(n, "become non-null") { it != null }
+ }
+
+ fun assertLinkPropertiesEventuallyNull(n: Network) {
+ assertLinkPropertiesEventually(n, "become null") { it == null }
+ }
+
@Test
fun testSetSubtypeNameAndExtraInfoByAgentConfig() {
val subtypeLTE = TelephonyManager.NETWORK_TYPE_LTE
@@ -378,7 +403,7 @@
fun testConnectAndUnregister() {
val (agent, callback) = createConnectedNetworkAgent()
unregister(agent)
- callback.expectCallback<Lost>(agent.network!!)
+ callback.expect<Lost>(agent.network!!)
assertFailsWith<IllegalStateException>("Must not be able to register an agent twice") {
agent.register()
}
@@ -429,7 +454,7 @@
agent.sendNetworkCapabilities(nc)
callbacks[0].expectCapabilitiesThat(agent.network!!) { it.signalStrength == 55 }
callbacks[1].expectCapabilitiesThat(agent.network!!) { it.signalStrength == 55 }
- callbacks[2].expectCallback<Lost>(agent.network!!)
+ callbacks[2].expect<Lost>(agent.network!!)
}
callbacks.forEach {
mCM.unregisterNetworkCallback(it)
@@ -507,12 +532,12 @@
agent.markConnected()
// Make sure the UIDs have been ignored.
- callback.expectCallback<Available>(agent.network!!)
+ callback.expect<Available>(agent.network!!)
callback.expectCapabilitiesThat(agent.network!!) {
it.allowedUids.isEmpty() && !it.hasCapability(NET_CAPABILITY_VALIDATED)
}
- callback.expectCallback<LinkPropertiesChanged>(agent.network!!)
- callback.expectCallback<BlockedStatus>(agent.network!!)
+ callback.expect<LinkPropertiesChanged>(agent.network!!)
+ callback.expect<BlockedStatus>(agent.network!!)
callback.expectCapabilitiesThat(agent.network!!) {
it.allowedUids.isEmpty() && it.hasCapability(NET_CAPABILITY_VALIDATED)
}
@@ -552,7 +577,7 @@
.setLegacyInt(WORSE_NETWORK_SCORE)
.setExiting(true)
.build())
- callback.expectCallback<Available>(agent2.network!!)
+ callback.expect<Available>(agent2.network!!)
// tearDown() will unregister the requests and agents
}
@@ -636,7 +661,7 @@
}
unregister(agent)
- callback.expectCallback<Lost>(agent.network!!)
+ callback.expect<Lost>(agent.network!!)
}
private fun unregister(agent: TestableNetworkAgent) {
@@ -809,14 +834,14 @@
agentStronger.register()
agentStronger.markConnected()
commonCallback.expectAvailableCallbacks(agentStronger.network!!)
- callbackWeaker.expectCallback<Losing>(agentWeaker.network!!)
+ callbackWeaker.expect<Losing>(agentWeaker.network!!)
val expectedRemainingLingerDuration = lingerStart +
NetworkAgent.MIN_LINGER_TIMER_MS.toLong() - SystemClock.elapsedRealtime()
// If the available callback is too late. The remaining duration will be reduced.
assertTrue(expectedRemainingLingerDuration > 0,
"expected remaining linger duration is $expectedRemainingLingerDuration")
callbackWeaker.assertNoCallback(expectedRemainingLingerDuration)
- callbackWeaker.expectCallback<Lost>(agentWeaker.network!!)
+ callbackWeaker.expect<Lost>(agentWeaker.network!!)
}
@Test
@@ -883,7 +908,7 @@
bestMatchingCb.assertNoCallback()
agent1.unregister()
agentsToCleanUp.remove(agent1)
- bestMatchingCb.expectCallback<Lost>(agent1.network!!)
+ bestMatchingCb.expect<Lost>(agent1.network!!)
// tearDown() will unregister the requests and agents
}
@@ -930,34 +955,49 @@
}
}
- private fun setupForQosCallbackTesting(): Pair<TestableNetworkAgent, Socket> {
- val request = NetworkRequest.Builder()
- .clearCapabilities()
- .addTransportType(TRANSPORT_TEST)
- .build()
+ private fun <T : Closeable> setupForQosCallbackTest(creator: (TestableNetworkAgent) -> T) =
+ createConnectedNetworkAgent().first.let { Pair(it, creator(it)) }
- val callback = TestableNetworkCallback(timeoutMs = DEFAULT_TIMEOUT_MS)
- requestNetwork(request, callback)
- val (agent, _) = createConnectedNetworkAgent()
+ private fun setupForQosSocket() = setupForQosCallbackTest {
+ agent: TestableNetworkAgent -> Socket()
+ .also { assertNotNull(agent.network?.bindSocket(it))
+ it.bind(InetSocketAddress(InetAddress.getLoopbackAddress(), 0)) }
+ }
- qosTestSocket = assertNotNull(agent.network?.socketFactory?.createSocket()).also {
- it.bind(InetSocketAddress(InetAddress.getLoopbackAddress(), 0))
- }
- return Pair(agent, qosTestSocket!!)
+ private fun setupForQosDatagram() = setupForQosCallbackTest {
+ agent: TestableNetworkAgent -> DatagramSocket(
+ InetSocketAddress(InetAddress.getLoopbackAddress(), 0))
+ .also { assertNotNull(agent.network?.bindSocket(it)) }
}
@AppModeFull(reason = "Instant apps don't have permission to bind sockets.")
@Test
- fun testQosCallbackRegisterWithUnregister() {
- val (agent, socket) = setupForQosCallbackTesting()
+ fun testQosCallbackRegisterAndUnregister() {
+ validateQosCallbackRegisterAndUnregister(IPPROTO_TCP)
+ }
+ @AppModeFull(reason = "Instant apps don't have permission to bind sockets.")
+ @Test
+ fun testQosCallbackRegisterAndUnregisterWithDatagramSocket() {
+ validateQosCallbackRegisterAndUnregister(IPPROTO_UDP)
+ }
+
+ private fun validateQosCallbackRegisterAndUnregister(proto: Int) {
+ val (agent, qosTestSocket) = when (proto) {
+ IPPROTO_TCP -> setupForQosSocket()
+ IPPROTO_UDP -> setupForQosDatagram()
+ else -> fail("unsupported protocol")
+ }
val qosCallback = TestableQosCallback()
var callbackId = -1
Executors.newSingleThreadExecutor().let { executor ->
try {
- val info = QosSocketInfo(agent.network!!, socket)
+ val info = QosSocketInfo(agent, qosTestSocket)
mCM.registerQosCallback(info, executor, qosCallback)
- callbackId = agent.expectCallback<OnRegisterQosCallback>().callbackId
+ agent.expectCallback<OnRegisterQosCallback>().let {
+ callbackId = it.callbackId
+ assertTrue(it.filter.matchesProtocol(proto))
+ }
assertFailsWith<QosCallbackRegistrationException>(
"The same callback cannot be " +
@@ -965,7 +1005,7 @@
mCM.registerQosCallback(info, executor, qosCallback)
}
} finally {
- socket.close()
+ qosTestSocket.close()
mCM.unregisterQosCallback(qosCallback)
agent.expectCallback<OnUnregisterQosCallback> { it.callbackId == callbackId }
executor.shutdown()
@@ -976,11 +1016,31 @@
@AppModeFull(reason = "Instant apps don't have permission to bind sockets.")
@Test
fun testQosCallbackOnQosSession() {
- val (agent, socket) = setupForQosCallbackTesting()
+ validateQosCallbackOnQosSession(IPPROTO_TCP)
+ }
+
+ @AppModeFull(reason = "Instant apps don't have permission to bind sockets.")
+ @Test
+ fun testQosCallbackOnQosSessionWithDatagramSocket() {
+ validateQosCallbackOnQosSession(IPPROTO_UDP)
+ }
+
+ fun QosSocketInfo(agent: NetworkAgent, socket: Closeable) = when (socket) {
+ is Socket -> QosSocketInfo(agent.network, socket)
+ is DatagramSocket -> QosSocketInfo(agent.network, socket)
+ else -> fail("unexpected socket type")
+ }
+
+ private fun validateQosCallbackOnQosSession(proto: Int) {
+ val (agent, qosTestSocket) = when (proto) {
+ IPPROTO_TCP -> setupForQosSocket()
+ IPPROTO_UDP -> setupForQosDatagram()
+ else -> fail("unsupported protocol")
+ }
val qosCallback = TestableQosCallback()
Executors.newSingleThreadExecutor().let { executor ->
try {
- val info = QosSocketInfo(agent.network!!, socket)
+ val info = QosSocketInfo(agent, qosTestSocket)
assertEquals(agent.network, info.getNetwork())
mCM.registerQosCallback(info, executor, qosCallback)
val callbackId = agent.expectCallback<OnRegisterQosCallback>().callbackId
@@ -1009,8 +1069,7 @@
agent.sendQosSessionLost(callbackId, sessId, QosSession.TYPE_EPS_BEARER)
qosCallback.assertNoCallback()
} finally {
- socket.close()
-
+ qosTestSocket.close()
// safety precaution
mCM.unregisterQosCallback(qosCallback)
@@ -1022,11 +1081,11 @@
@AppModeFull(reason = "Instant apps don't have permission to bind sockets.")
@Test
fun testQosCallbackOnError() {
- val (agent, socket) = setupForQosCallbackTesting()
+ val (agent, qosTestSocket) = setupForQosSocket()
val qosCallback = TestableQosCallback()
Executors.newSingleThreadExecutor().let { executor ->
try {
- val info = QosSocketInfo(agent.network!!, socket)
+ val info = QosSocketInfo(agent.network!!, qosTestSocket)
mCM.registerQosCallback(info, executor, qosCallback)
val callbackId = agent.expectCallback<OnRegisterQosCallback>().callbackId
@@ -1048,7 +1107,7 @@
agent.sendQosSessionLost(callbackId, sessId, QosSession.TYPE_EPS_BEARER)
qosCallback.assertNoCallback()
} finally {
- socket.close()
+ qosTestSocket.close()
// Make sure that the callback is fully unregistered
mCM.unregisterQosCallback(qosCallback)
@@ -1061,12 +1120,12 @@
@AppModeFull(reason = "Instant apps don't have permission to bind sockets.")
@Test
fun testQosCallbackIdsAreMappedCorrectly() {
- val (agent, socket) = setupForQosCallbackTesting()
+ val (agent, qosTestSocket) = setupForQosSocket()
val qosCallback1 = TestableQosCallback()
val qosCallback2 = TestableQosCallback()
Executors.newSingleThreadExecutor().let { executor ->
try {
- val info = QosSocketInfo(agent.network!!, socket)
+ val info = QosSocketInfo(agent.network!!, qosTestSocket)
mCM.registerQosCallback(info, executor, qosCallback1)
val callbackId1 = agent.expectCallback<OnRegisterQosCallback>().callbackId
@@ -1088,7 +1147,7 @@
qosCallback1.assertNoCallback()
qosCallback2.expectCallback<OnQosSessionAvailable> { sessId2 == it.sess.sessionId }
} finally {
- socket.close()
+ qosTestSocket.close()
// Make sure that the callback is fully unregistered
mCM.unregisterQosCallback(qosCallback1)
@@ -1102,13 +1161,13 @@
@AppModeFull(reason = "Instant apps don't have permission to bind sockets.")
@Test
fun testQosCallbackWhenNetworkReleased() {
- val (agent, socket) = setupForQosCallbackTesting()
+ val (agent, qosTestSocket) = setupForQosSocket()
Executors.newSingleThreadExecutor().let { executor ->
try {
val qosCallback1 = TestableQosCallback()
val qosCallback2 = TestableQosCallback()
try {
- val info = QosSocketInfo(agent.network!!, socket)
+ val info = QosSocketInfo(agent.network!!, qosTestSocket)
mCM.registerQosCallback(info, executor, qosCallback1)
mCM.registerQosCallback(info, executor, qosCallback2)
agent.unregister()
@@ -1121,12 +1180,12 @@
it.ex.cause is NetworkReleasedException
}
} finally {
- socket.close()
+ qosTestSocket.close()
mCM.unregisterQosCallback(qosCallback1)
mCM.unregisterQosCallback(qosCallback2)
}
} finally {
- socket.close()
+ qosTestSocket.close()
executor.shutdown()
}
}
@@ -1163,7 +1222,7 @@
// testCallback will not see any events. agent2 is be torn down because it has no requests.
val (agent2, network2) = connectNetwork()
matchAllCallback.expectAvailableThenValidatedCallbacks(network2)
- matchAllCallback.expectCallback<Lost>(network2)
+ matchAllCallback.expect<Lost>(network2)
agent2.expectCallback<OnNetworkUnwanted>()
agent2.expectCallback<OnNetworkDestroyed>()
assertNull(mCM.getLinkProperties(network2))
@@ -1191,7 +1250,7 @@
// As soon as the replacement arrives, network1 is disconnected.
// Check that this happens before the replacement timeout (5 seconds) fires.
- matchAllCallback.expectCallback<Lost>(network1, 2_000 /* timeoutMs */)
+ matchAllCallback.expect<Lost>(network1, 2_000 /* timeoutMs */)
agent1.expectCallback<OnNetworkUnwanted>()
// Test lingering:
@@ -1204,19 +1263,19 @@
val network4 = agent4.network!!
matchAllCallback.expectAvailableThenValidatedCallbacks(network4)
agent4.sendNetworkScore(NetworkScore.Builder().setTransportPrimary(true).build())
- matchAllCallback.expectCallback<Losing>(network3)
+ matchAllCallback.expect<Losing>(network3)
testCallback.expectAvailableCallbacks(network4, validated = true)
mCM.unregisterNetworkCallback(agent4callback)
agent3.unregisterAfterReplacement(5_000)
agent3.expectCallback<OnNetworkUnwanted>()
- matchAllCallback.expectCallback<Lost>(network3, 1000L)
+ matchAllCallback.expect<Lost>(network3, 1000L)
agent3.expectCallback<OnNetworkDestroyed>()
// Now mark network4 awaiting replacement with a low timeout, and check that if no
// replacement arrives, it is torn down.
agent4.unregisterAfterReplacement(100 /* timeoutMillis */)
- matchAllCallback.expectCallback<Lost>(network4, 1000L /* timeoutMs */)
- testCallback.expectCallback<Lost>(network4, 1000L /* timeoutMs */)
+ matchAllCallback.expect<Lost>(network4, 1000L /* timeoutMs */)
+ testCallback.expect<Lost>(network4, 1000L /* timeoutMs */)
agent4.expectCallback<OnNetworkDestroyed>()
agent4.expectCallback<OnNetworkUnwanted>()
@@ -1227,13 +1286,45 @@
testCallback.expectAvailableThenValidatedCallbacks(network5)
agent5.unregisterAfterReplacement(5_000 /* timeoutMillis */)
agent5.unregister()
- matchAllCallback.expectCallback<Lost>(network5, 1000L /* timeoutMs */)
- testCallback.expectCallback<Lost>(network5, 1000L /* timeoutMs */)
+ matchAllCallback.expect<Lost>(network5, 1000L /* timeoutMs */)
+ testCallback.expect<Lost>(network5, 1000L /* timeoutMs */)
agent5.expectCallback<OnNetworkDestroyed>()
agent5.expectCallback<OnNetworkUnwanted>()
+ // If unregisterAfterReplacement is called before markConnected, the network disconnects.
+ val specifier6 = UUID.randomUUID().toString()
+ val callback = TestableNetworkCallback()
+ requestNetwork(makeTestNetworkRequest(specifier = specifier6), callback)
+ val agent6 = createNetworkAgent(specifier = specifier6)
+ val network6 = agent6.register()
+ // No callbacks are sent, so check the LinkProperties to see if the network has connected.
+ assertLinkPropertiesEventuallyNotNull(agent6.network!!)
+
+ // unregisterAfterReplacement tears down the network immediately.
+ // Approximately check that this is the case by picking an unregister timeout that's longer
+ // than the timeout of the expectCallback<OnNetworkUnwanted> below.
+ // TODO: consider adding configurable timeouts to TestableNetworkAgent expectations.
+ val timeoutMs = agent6.DEFAULT_TIMEOUT_MS.toInt() + 1_000
+ agent6.unregisterAfterReplacement(timeoutMs)
+ agent6.expectCallback<OnNetworkUnwanted>()
+ if (!SdkLevel.isAtLeastT()) {
+ // Before T, onNetworkDestroyed is called even if the network was never created.
+ agent6.expectCallback<OnNetworkDestroyed>()
+ }
+ // Poll for LinkProperties becoming null, because when onNetworkUnwanted is called, the
+ // network has not yet been removed from the CS data structures.
+ assertLinkPropertiesEventuallyNull(agent6.network!!)
+ assertFalse(mCM.getAllNetworks().contains(agent6.network!!))
+
+ // After unregisterAfterReplacement is called, the network is no longer usable and
+ // markConnected has no effect.
+ agent6.markConnected()
+ agent6.assertNoCallback()
+ assertNull(mCM.getLinkProperties(agent6.network!!))
+ matchAllCallback.assertNoCallback(200 /* timeoutMs */)
+
// If wifi is replaced within the timeout, the device does not switch to cellular.
- val (cellAgent, cellNetwork) = connectNetwork(TRANSPORT_CELLULAR)
+ val (_, cellNetwork) = connectNetwork(TRANSPORT_CELLULAR)
testCallback.expectAvailableThenValidatedCallbacks(cellNetwork)
matchAllCallback.expectAvailableThenValidatedCallbacks(cellNetwork)
@@ -1243,7 +1334,7 @@
it.hasCapability(NET_CAPABILITY_VALIDATED)
}
matchAllCallback.expectAvailableCallbacks(wifiNetwork, validated = false)
- matchAllCallback.expectCallback<Losing>(cellNetwork)
+ matchAllCallback.expect<Losing>(cellNetwork)
matchAllCallback.expectCapabilitiesThat(wifiNetwork) {
it.hasCapability(NET_CAPABILITY_VALIDATED)
}
@@ -1272,7 +1363,7 @@
val (newWifiAgent, newWifiNetwork) = connectNetwork(TRANSPORT_WIFI)
testCallback.expectAvailableCallbacks(newWifiNetwork, validated = true)
matchAllCallback.expectAvailableThenValidatedCallbacks(newWifiNetwork)
- matchAllCallback.expectCallback<Lost>(wifiNetwork)
+ matchAllCallback.expect<Lost>(wifiNetwork)
wifiAgent.expectCallback<OnNetworkUnwanted>()
}
@@ -1291,7 +1382,7 @@
// lost callback should be sent still.
agent.markConnected()
agent.unregister()
- callback.expectCallback<Available>(agent.network!!)
+ callback.expect<Available>(agent.network!!)
callback.eventuallyExpect<Lost> { it.network == agent.network }
}
}
diff --git a/tests/cts/net/src/android/net/cts/NetworkScoreTest.kt b/tests/cts/net/src/android/net/cts/NetworkScoreTest.kt
index 8f17199..eb41d71 100644
--- a/tests/cts/net/src/android/net/cts/NetworkScoreTest.kt
+++ b/tests/cts/net/src/android/net/cts/NetworkScoreTest.kt
@@ -34,6 +34,7 @@
import com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity
import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo
import com.android.testutils.DevSdkIgnoreRunner
+import com.android.testutils.RecorderCallback.CallbackEntry
import com.android.testutils.TestableNetworkCallback
import com.android.testutils.TestableNetworkCallback.HasNetwork
import org.junit.After
@@ -76,7 +77,18 @@
@After
fun tearDown() {
- agentsToCleanUp.forEach { it.unregister() }
+ val agentCleanUpCb = TestableNetworkCallback(TIMEOUT_MS).also { cb ->
+ mCm.registerNetworkCallback(
+ NetworkRequest.Builder().clearCapabilities()
+ .addTransportType(NetworkCapabilities.TRANSPORT_TEST).build(), cb, mHandler
+ )
+ }
+ agentsToCleanUp.forEach {
+ it.unregister()
+ agentCleanUpCb.eventuallyExpect<CallbackEntry.Lost> { cb -> cb.network == it.network }
+ }
+ mCm.unregisterNetworkCallback(agentCleanUpCb)
+
mHandlerThread.quitSafely()
callbacksToCleanUp.forEach { mCm.unregisterNetworkCallback(it) }
}
diff --git a/tests/cts/net/src/android/net/cts/NsdManagerTest.kt b/tests/cts/net/src/android/net/cts/NsdManagerTest.kt
index a02be85..d598830 100644
--- a/tests/cts/net/src/android/net/cts/NsdManagerTest.kt
+++ b/tests/cts/net/src/android/net/cts/NsdManagerTest.kt
@@ -65,6 +65,7 @@
import com.android.testutils.filters.CtsNetTestCasesMaxTargetSdk30
import com.android.testutils.runAsShell
import com.android.testutils.tryTest
+import com.android.testutils.waitForIdle
import org.junit.After
import org.junit.Assert.assertArrayEquals
import org.junit.Assert.assertFalse
@@ -121,6 +122,7 @@
cm.unregisterNetworkCallback(requestCb)
agent.unregister()
iface.fileDescriptor.close()
+ agent.waitForIdle(TIMEOUT_MS)
}
}
@@ -291,7 +293,7 @@
val agent = registerTestNetworkAgent(iface.interfaceName)
val network = agent.network ?: fail("Registered agent should have a network")
// The network has no INTERNET capability, so will be marked validated immediately
- cb.expectAvailableThenValidatedCallbacks(network)
+ cb.expectAvailableThenValidatedCallbacks(network, TIMEOUT_MS)
return TestTapNetwork(iface, cb, agent, network)
}
@@ -319,6 +321,7 @@
testNetwork2.close(cm)
}
}
+ handlerThread.waitForIdle(TIMEOUT_MS)
handlerThread.quitSafely()
}
diff --git a/tests/cts/net/src/android/net/cts/QosCallbackExceptionTest.java b/tests/cts/net/src/android/net/cts/QosCallbackExceptionTest.java
index cd43a34..04abd72 100644
--- a/tests/cts/net/src/android/net/cts/QosCallbackExceptionTest.java
+++ b/tests/cts/net/src/android/net/cts/QosCallbackExceptionTest.java
@@ -17,6 +17,7 @@
package android.net.cts;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
@@ -24,8 +25,11 @@
import android.net.QosCallbackException;
import android.net.SocketLocalAddressChangedException;
import android.net.SocketNotBoundException;
+import android.net.SocketNotConnectedException;
+import android.net.SocketRemoteAddressChangedException;
import android.os.Build;
+import com.android.testutils.ConnectivityModuleTest;
import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo;
import com.android.testutils.DevSdkIgnoreRunner;
@@ -34,14 +38,9 @@
@RunWith(DevSdkIgnoreRunner.class)
@IgnoreUpTo(Build.VERSION_CODES.R)
+@ConnectivityModuleTest
public class QosCallbackExceptionTest {
private static final String ERROR_MESSAGE = "Test Error Message";
- private static final String ERROR_MSG_SOCK_NOT_BOUND = "The socket is unbound";
- private static final String ERROR_MSG_NET_RELEASED =
- "The network was released and is no longer available";
- private static final String ERROR_MSG_SOCK_ADDR_CHANGED =
- "The local address of the socket changed";
-
@Test
public void testQosCallbackException() throws Exception {
@@ -57,33 +56,65 @@
public void testNetworkReleasedExceptions() throws Exception {
final Throwable netReleasedException = new NetworkReleasedException();
final QosCallbackException exception = new QosCallbackException(netReleasedException);
-
- assertTrue(exception.getCause() instanceof NetworkReleasedException);
- assertEquals(netReleasedException, exception.getCause());
- assertTrue(exception.getMessage().contains(ERROR_MSG_NET_RELEASED));
- assertThrowableMessageContains(exception, ERROR_MSG_NET_RELEASED);
+ validateQosCallbackException(
+ exception, netReleasedException, NetworkReleasedException.class);
}
@Test
public void testSocketNotBoundExceptions() throws Exception {
final Throwable sockNotBoundException = new SocketNotBoundException();
final QosCallbackException exception = new QosCallbackException(sockNotBoundException);
-
- assertTrue(exception.getCause() instanceof SocketNotBoundException);
- assertEquals(sockNotBoundException, exception.getCause());
- assertTrue(exception.getMessage().contains(ERROR_MSG_SOCK_NOT_BOUND));
- assertThrowableMessageContains(exception, ERROR_MSG_SOCK_NOT_BOUND);
+ validateQosCallbackException(
+ exception, sockNotBoundException, SocketNotBoundException.class);
}
@Test
public void testSocketLocalAddressChangedExceptions() throws Exception {
- final Throwable localAddrChangedException = new SocketLocalAddressChangedException();
- final QosCallbackException exception = new QosCallbackException(localAddrChangedException);
+ final Throwable localAddressChangedException = new SocketLocalAddressChangedException();
+ final QosCallbackException exception =
+ new QosCallbackException(localAddressChangedException);
+ validateQosCallbackException(
+ exception, localAddressChangedException, SocketLocalAddressChangedException.class);
+ }
- assertTrue(exception.getCause() instanceof SocketLocalAddressChangedException);
- assertEquals(localAddrChangedException, exception.getCause());
- assertTrue(exception.getMessage().contains(ERROR_MSG_SOCK_ADDR_CHANGED));
- assertThrowableMessageContains(exception, ERROR_MSG_SOCK_ADDR_CHANGED);
+ @Test
+ @IgnoreUpTo(Build.VERSION_CODES.S)
+ public void testSocketNotConnectedExceptions() throws Exception {
+ final Throwable sockNotConnectedException = new SocketNotConnectedException();
+ final QosCallbackException exception = new QosCallbackException(sockNotConnectedException);
+ validateQosCallbackException(
+ exception, sockNotConnectedException, SocketNotConnectedException.class);
+ }
+
+ @Test
+ @IgnoreUpTo(Build.VERSION_CODES.S)
+ public void testSocketRemoteAddressChangedExceptions() throws Exception {
+ final Throwable remoteAddressChangedException = new SocketRemoteAddressChangedException();
+ final QosCallbackException exception =
+ new QosCallbackException(remoteAddressChangedException);
+ validateQosCallbackException(
+ exception, remoteAddressChangedException,
+ SocketRemoteAddressChangedException.class);
+ }
+
+ private void validateQosCallbackException(
+ QosCallbackException e, Throwable cause, Class c) throws Exception {
+ if (c == SocketNotConnectedException.class) {
+ assertTrue(e.getCause() instanceof SocketNotConnectedException);
+ } else if (c == SocketRemoteAddressChangedException.class) {
+ assertTrue(e.getCause() instanceof SocketRemoteAddressChangedException);
+ } else if (c == SocketLocalAddressChangedException.class) {
+ assertTrue(e.getCause() instanceof SocketLocalAddressChangedException);
+ } else if (c == SocketNotBoundException.class) {
+ assertTrue(e.getCause() instanceof SocketNotBoundException);
+ } else if (c == NetworkReleasedException.class) {
+ assertTrue(e.getCause() instanceof NetworkReleasedException);
+ } else {
+ fail("unexpected error msg.");
+ }
+ assertEquals(cause, e.getCause());
+ assertFalse(e.getMessage().isEmpty());
+ assertThrowableMessageContains(e, e.getMessage());
}
private void assertThrowableMessageContains(QosCallbackException exception, String errorMsg)
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 f035f72..9d1fa60 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
@@ -357,7 +357,7 @@
public Network connectToCell() throws InterruptedException {
if (cellConnectAttempted()) {
- throw new IllegalStateException("Already connected");
+ mCm.unregisterNetworkCallback(mCellNetworkCallback);
}
NetworkRequest cellRequest = new NetworkRequest.Builder()
.addTransportType(TRANSPORT_CELLULAR)
diff --git a/tests/cts/net/util/java/android/net/cts/util/IkeSessionTestUtils.java b/tests/cts/net/util/java/android/net/cts/util/IkeSessionTestUtils.java
index 244bfc5..11eb466 100644
--- a/tests/cts/net/util/java/android/net/cts/util/IkeSessionTestUtils.java
+++ b/tests/cts/net/util/java/android/net/cts/util/IkeSessionTestUtils.java
@@ -27,6 +27,7 @@
import android.net.InetAddresses;
import android.net.ipsec.ike.ChildSaProposal;
import android.net.ipsec.ike.IkeFqdnIdentification;
+import android.net.ipsec.ike.IkeIdentification;
import android.net.ipsec.ike.IkeIpv4AddrIdentification;
import android.net.ipsec.ike.IkeIpv6AddrIdentification;
import android.net.ipsec.ike.IkeSaProposal;
@@ -57,6 +58,11 @@
}
private static IkeSessionParams getTestIkeSessionParams(boolean testIpv6) {
+ return getTestIkeSessionParams(testIpv6, new IkeFqdnIdentification(TEST_IDENTITY));
+ }
+
+ public static IkeSessionParams getTestIkeSessionParams(boolean testIpv6,
+ IkeIdentification identification) {
final String testServer = testIpv6 ? TEST_SERVER_ADDR_V6 : TEST_SERVER_ADDR_V4;
final InetAddress addr = InetAddresses.parseNumericAddress(testServer);
final IkeSessionParams.Builder ikeOptionsBuilder =
diff --git a/tests/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt b/tests/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt
index 73e4c0e..26b058d 100644
--- a/tests/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt
+++ b/tests/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt
@@ -37,7 +37,7 @@
import android.net.TestNetworkStackClient
import android.net.Uri
import android.net.metrics.IpConnectivityLog
-import android.net.util.MultinetworkPolicyTracker
+import com.android.server.connectivity.MultinetworkPolicyTracker
import android.os.ConditionVariable
import android.os.IBinder
import android.os.SystemConfigManager
@@ -211,10 +211,15 @@
doReturn(TestNetIdManager()).`when`(deps).makeNetIdManager()
doReturn(mock(BpfNetMaps::class.java)).`when`(deps).getBpfNetMaps(any(), any())
doAnswer { inv ->
- object : MultinetworkPolicyTracker(inv.getArgument(0), inv.getArgument(1),
- inv.getArgument(2)) {
- override fun getResourcesForActiveSubId() = resources
- }
+ MultinetworkPolicyTracker(inv.getArgument(0),
+ inv.getArgument(1),
+ inv.getArgument(2),
+ object : MultinetworkPolicyTracker.Dependencies() {
+ override fun getResourcesForActiveSubId(
+ connResources: ConnectivityResources,
+ activeSubId: Int
+ ) = resources
+ })
}.`when`(deps).makeMultinetworkPolicyTracker(any(), any(), any())
return deps
}
diff --git a/tests/integration/util/com/android/server/NetworkAgentWrapper.java b/tests/integration/util/com/android/server/NetworkAgentWrapper.java
index 97688d5..28edcb2 100644
--- a/tests/integration/util/com/android/server/NetworkAgentWrapper.java
+++ b/tests/integration/util/com/android/server/NetworkAgentWrapper.java
@@ -269,6 +269,7 @@
mNetworkAgent.sendNetworkScore(score);
}
+ // TODO : remove adjustScore and replace with the appropriate exiting flags.
public void adjustScore(int change) {
final int newLegacyScore = mScore.getLegacyInt() + change;
final NetworkScore.Builder builder = new NetworkScore.Builder()
diff --git a/tests/mts/bpf_existence_test.cpp b/tests/mts/bpf_existence_test.cpp
index c7e8b97..aa5654a 100644
--- a/tests/mts/bpf_existence_test.cpp
+++ b/tests/mts/bpf_existence_test.cpp
@@ -100,13 +100,11 @@
NETD "map_netd_uid_counterset_map",
NETD "map_netd_uid_owner_map",
NETD "map_netd_uid_permission_map",
- SHARED "prog_clatd_schedcls_egress4_clat_ether",
SHARED "prog_clatd_schedcls_egress4_clat_rawip",
SHARED "prog_clatd_schedcls_ingress6_clat_ether",
SHARED "prog_clatd_schedcls_ingress6_clat_rawip",
NETD "prog_netd_cgroupskb_egress_stats",
NETD "prog_netd_cgroupskb_ingress_stats",
- NETD "prog_netd_cgroupsock_inet_create",
NETD "prog_netd_schedact_ingress_account",
NETD "prog_netd_skfilter_allowlist_xtbpf",
NETD "prog_netd_skfilter_denylist_xtbpf",
@@ -114,6 +112,11 @@
NETD "prog_netd_skfilter_ingress_xtbpf",
};
+// Provided by *current* mainline module for T+ devices with 4.14+ kernels
+static const set<string> MAINLINE_FOR_T_4_14_PLUS = {
+ NETD "prog_netd_cgroupsock_inet_create",
+};
+
// Provided by *current* mainline module for T+ devices with 5.4+ kernels
static const set<string> MAINLINE_FOR_T_5_4_PLUS = {
SHARED "prog_block_bind4_block_port",
@@ -152,6 +155,7 @@
// Nothing added or removed in SCv2.
DO_EXPECT(IsAtLeastT(), MAINLINE_FOR_T_PLUS);
+ DO_EXPECT(IsAtLeastT() && isAtLeastKernelVersion(4, 14, 0), MAINLINE_FOR_T_4_14_PLUS);
DO_EXPECT(IsAtLeastT() && isAtLeastKernelVersion(5, 4, 0), MAINLINE_FOR_T_5_4_PLUS);
DO_EXPECT(IsAtLeastT() && isAtLeastKernelVersion(5, 15, 0), MAINLINE_FOR_T_5_15_PLUS);
}
diff --git a/tests/unit/Android.bp b/tests/unit/Android.bp
index cb68235..437622b 100644
--- a/tests/unit/Android.bp
+++ b/tests/unit/Android.bp
@@ -101,7 +101,7 @@
],
static_libs: [
"androidx.test.rules",
- "androidx.test.uiautomator",
+ "androidx.test.uiautomator_uiautomator",
"bouncycastle-repackaged-unbundled",
"core-tests-support",
"FrameworksNetCommonTests",
diff --git a/tests/unit/java/android/app/usage/NetworkStatsManagerTest.java b/tests/unit/java/android/app/usage/NetworkStatsManagerTest.java
index 8a537be..679427a 100644
--- a/tests/unit/java/android/app/usage/NetworkStatsManagerTest.java
+++ b/tests/unit/java/android/app/usage/NetworkStatsManagerTest.java
@@ -16,7 +16,16 @@
package android.app.usage;
+import static android.net.ConnectivityManager.TYPE_MOBILE;
+import static android.net.ConnectivityManager.TYPE_WIFI;
+import static android.net.NetworkStats.DEFAULT_NETWORK_NO;
+import static android.net.NetworkStats.METERED_NO;
import static android.net.NetworkStats.METERED_YES;
+import static android.net.NetworkStats.ROAMING_NO;
+import static android.net.NetworkStats.SET_ALL;
+import static android.net.NetworkStats.SET_DEFAULT;
+import static android.net.NetworkStats.TAG_NONE;
+import static android.net.NetworkStatsHistory.FIELD_ALL;
import static android.net.NetworkTemplate.MATCH_MOBILE;
import static android.net.NetworkTemplate.MATCH_WIFI;
@@ -34,7 +43,6 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
-import android.net.ConnectivityManager;
import android.net.INetworkStatsService;
import android.net.INetworkStatsSession;
import android.net.NetworkStats.Entry;
@@ -86,31 +94,17 @@
final int uid2 = 10002;
final int uid3 = 10003;
- Entry uid1Entry1 = new Entry("if1", uid1,
- android.net.NetworkStats.SET_DEFAULT, android.net.NetworkStats.TAG_NONE,
- android.net.NetworkStats.METERED_NO, android.net.NetworkStats.ROAMING_NO,
- android.net.NetworkStats.DEFAULT_NETWORK_NO,
- 100, 10, 200, 20, 0);
+ Entry uid1Entry1 = new Entry("if1", uid1, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+ DEFAULT_NETWORK_NO, 100, 10, 200, 20, 0);
- Entry uid1Entry2 = new Entry(
- "if2", uid1,
- android.net.NetworkStats.SET_DEFAULT, android.net.NetworkStats.TAG_NONE,
- android.net.NetworkStats.METERED_NO, android.net.NetworkStats.ROAMING_NO,
- android.net.NetworkStats.DEFAULT_NETWORK_NO,
- 100, 10, 200, 20, 0);
+ Entry uid1Entry2 = new Entry("if2", uid1, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+ DEFAULT_NETWORK_NO, 100, 10, 200, 20, 0);
- Entry uid2Entry1 = new Entry("if1", uid2,
- android.net.NetworkStats.SET_DEFAULT, android.net.NetworkStats.TAG_NONE,
- android.net.NetworkStats.METERED_NO, android.net.NetworkStats.ROAMING_NO,
- android.net.NetworkStats.DEFAULT_NETWORK_NO,
- 150, 10, 250, 20, 0);
+ Entry uid2Entry1 = new Entry("if1", uid2, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+ DEFAULT_NETWORK_NO, 150, 10, 250, 20, 0);
- Entry uid2Entry2 = new Entry(
- "if2", uid2,
- android.net.NetworkStats.SET_DEFAULT, android.net.NetworkStats.TAG_NONE,
- android.net.NetworkStats.METERED_NO, android.net.NetworkStats.ROAMING_NO,
- android.net.NetworkStats.DEFAULT_NETWORK_NO,
- 150, 10, 250, 20, 0);
+ Entry uid2Entry2 = new Entry("if2", uid2, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+ DEFAULT_NETWORK_NO, 150, 10, 250, 20, 0);
NetworkStatsHistory history1 = new NetworkStatsHistory(10, 2);
history1.recordData(10, 20, uid1Entry1);
@@ -125,9 +119,8 @@
when(mStatsSession.getRelevantUids()).thenReturn(new int[] { uid1, uid2, uid3 });
when(mStatsSession.getHistoryIntervalForUid(any(NetworkTemplate.class),
- eq(uid1), eq(android.net.NetworkStats.SET_ALL),
- eq(android.net.NetworkStats.TAG_NONE),
- eq(NetworkStatsHistory.FIELD_ALL), eq(startTime), eq(endTime)))
+ eq(uid1), eq(SET_ALL), eq(TAG_NONE),
+ eq(FIELD_ALL), eq(startTime), eq(endTime)))
.then((InvocationOnMock inv) -> {
NetworkTemplate template = inv.getArgument(0);
assertEquals(MATCH_MOBILE_ALL, template.getMatchRule());
@@ -136,9 +129,8 @@
});
when(mStatsSession.getHistoryIntervalForUid(any(NetworkTemplate.class),
- eq(uid2), eq(android.net.NetworkStats.SET_ALL),
- eq(android.net.NetworkStats.TAG_NONE),
- eq(NetworkStatsHistory.FIELD_ALL), eq(startTime), eq(endTime)))
+ eq(uid2), eq(SET_ALL), eq(TAG_NONE),
+ eq(FIELD_ALL), eq(startTime), eq(endTime)))
.then((InvocationOnMock inv) -> {
NetworkTemplate template = inv.getArgument(0);
assertEquals(MATCH_MOBILE_ALL, template.getMatchRule());
@@ -148,7 +140,7 @@
NetworkStats stats = mManager.queryDetails(
- ConnectivityManager.TYPE_MOBILE, TEST_SUBSCRIBER_ID, startTime, endTime);
+ TYPE_MOBILE, TEST_SUBSCRIBER_ID, startTime, endTime);
NetworkStats.Bucket bucket = new NetworkStats.Bucket();
@@ -202,35 +194,34 @@
verify(mStatsSession, times(1)).getHistoryIntervalForUid(
eq(expectedTemplate),
- eq(uid1), eq(android.net.NetworkStats.SET_ALL),
- eq(android.net.NetworkStats.TAG_NONE),
- eq(NetworkStatsHistory.FIELD_ALL), eq(startTime), eq(endTime));
+ eq(uid1), eq(SET_ALL),
+ eq(TAG_NONE),
+ eq(FIELD_ALL), eq(startTime), eq(endTime));
verify(mStatsSession, times(1)).getHistoryIntervalForUid(
eq(expectedTemplate),
- eq(uid2), eq(android.net.NetworkStats.SET_ALL),
- eq(android.net.NetworkStats.TAG_NONE),
- eq(NetworkStatsHistory.FIELD_ALL), eq(startTime), eq(endTime));
+ eq(uid2), eq(SET_ALL),
+ eq(TAG_NONE),
+ eq(FIELD_ALL), eq(startTime), eq(endTime));
assertFalse(stats.hasNextBucket());
}
@Test
public void testNetworkTemplateWhenRunningQueryDetails_NoSubscriberId() throws RemoteException {
- runQueryDetailsAndCheckTemplate(ConnectivityManager.TYPE_MOBILE,
- null /* subscriberId */, new NetworkTemplate.Builder(MATCH_MOBILE)
- .setMeteredness(METERED_YES).build());
- runQueryDetailsAndCheckTemplate(ConnectivityManager.TYPE_WIFI,
- "" /* subscriberId */, new NetworkTemplate.Builder(MATCH_WIFI).build());
- runQueryDetailsAndCheckTemplate(ConnectivityManager.TYPE_WIFI,
- null /* subscriberId */, new NetworkTemplate.Builder(MATCH_WIFI).build());
+ runQueryDetailsAndCheckTemplate(TYPE_MOBILE, null /* subscriberId */,
+ new NetworkTemplate.Builder(MATCH_MOBILE).setMeteredness(METERED_YES).build());
+ runQueryDetailsAndCheckTemplate(TYPE_WIFI, "" /* subscriberId */,
+ new NetworkTemplate.Builder(MATCH_WIFI).build());
+ runQueryDetailsAndCheckTemplate(TYPE_WIFI, null /* subscriberId */,
+ new NetworkTemplate.Builder(MATCH_WIFI).build());
}
@Test
public void testNetworkTemplateWhenRunningQueryDetails_MergedCarrierWifi()
throws RemoteException {
- runQueryDetailsAndCheckTemplate(ConnectivityManager.TYPE_WIFI,
- TEST_SUBSCRIBER_ID, new NetworkTemplate.Builder(MATCH_WIFI)
+ runQueryDetailsAndCheckTemplate(TYPE_WIFI, TEST_SUBSCRIBER_ID,
+ new NetworkTemplate.Builder(MATCH_WIFI)
.setSubscriberIds(Set.of(TEST_SUBSCRIBER_ID)).build());
}
@@ -244,7 +235,7 @@
when(mStatsSession.getTaggedSummaryForAllUid(any(NetworkTemplate.class),
anyLong(), anyLong()))
.thenReturn(new android.net.NetworkStats(0, 0));
- final NetworkTemplate template = new NetworkTemplate.Builder(NetworkTemplate.MATCH_MOBILE)
+ final NetworkTemplate template = new NetworkTemplate.Builder(MATCH_MOBILE)
.setMeteredness(NetworkStats.Bucket.METERED_YES).build();
NetworkStats stats = mManager.queryTaggedSummary(template, startTime, endTime);
@@ -265,12 +256,12 @@
when(mStatsSession.getHistoryIntervalForNetwork(any(NetworkTemplate.class),
anyInt(), anyLong(), anyLong()))
.thenReturn(new NetworkStatsHistory(10, 0));
- final NetworkTemplate template = new NetworkTemplate.Builder(NetworkTemplate.MATCH_MOBILE)
+ final NetworkTemplate template = new NetworkTemplate.Builder(MATCH_MOBILE)
.setMeteredness(NetworkStats.Bucket.METERED_YES).build();
NetworkStats stats = mManager.queryDetailsForDevice(template, startTime, endTime);
verify(mStatsSession, times(1)).getHistoryIntervalForNetwork(
- eq(template), eq(NetworkStatsHistory.FIELD_ALL), eq(startTime), eq(endTime));
+ eq(template), eq(FIELD_ALL), eq(startTime), eq(endTime));
assertFalse(stats.hasNextBucket());
}
diff --git a/tests/unit/java/android/net/Ikev2VpnProfileTest.java b/tests/unit/java/android/net/Ikev2VpnProfileTest.java
index 5cb014f..3b68120 100644
--- a/tests/unit/java/android/net/Ikev2VpnProfileTest.java
+++ b/tests/unit/java/android/net/Ikev2VpnProfileTest.java
@@ -18,6 +18,7 @@
import static android.net.cts.util.IkeSessionTestUtils.CHILD_PARAMS;
import static android.net.cts.util.IkeSessionTestUtils.IKE_PARAMS_V6;
+import static android.net.cts.util.IkeSessionTestUtils.getTestIkeSessionParams;
import static com.android.testutils.DevSdkIgnoreRuleKt.SC_V2;
@@ -28,6 +29,7 @@
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
+import android.net.ipsec.ike.IkeKeyIdIdentification;
import android.net.ipsec.ike.IkeTunnelConnectionParams;
import android.os.Build;
import android.test.mock.MockContext;
@@ -446,6 +448,40 @@
}
@Test
+ public void testBuildWithIkeTunConnParamsConvertToVpnProfile() throws Exception {
+ // Special keyId that contains delimiter character of VpnProfile
+ final byte[] keyId = "foo\0bar".getBytes();
+ final IkeTunnelConnectionParams tunnelParams = new IkeTunnelConnectionParams(
+ getTestIkeSessionParams(true /* testIpv6 */, new IkeKeyIdIdentification(keyId)),
+ CHILD_PARAMS);
+ final Ikev2VpnProfile ikev2VpnProfile = new Ikev2VpnProfile.Builder(tunnelParams).build();
+ final VpnProfile vpnProfile = ikev2VpnProfile.toVpnProfile();
+
+ assertEquals(VpnProfile.TYPE_IKEV2_FROM_IKE_TUN_CONN_PARAMS, vpnProfile.type);
+
+ // Username, password, server, ipsecIdentifier, ipsecCaCert, ipsecSecret, ipsecUserCert and
+ // getAllowedAlgorithms should not be set if IkeTunnelConnectionParams is set.
+ assertEquals("", vpnProfile.server);
+ assertEquals("", vpnProfile.ipsecIdentifier);
+ assertEquals("", vpnProfile.username);
+ assertEquals("", vpnProfile.password);
+ assertEquals("", vpnProfile.ipsecCaCert);
+ assertEquals("", vpnProfile.ipsecSecret);
+ assertEquals("", vpnProfile.ipsecUserCert);
+ assertEquals(0, vpnProfile.getAllowedAlgorithms().size());
+
+ // IkeTunnelConnectionParams should stay the same.
+ assertEquals(tunnelParams, vpnProfile.ikeTunConnParams);
+
+ // Convert to disk-stable format and then back to Ikev2VpnProfile should be the same.
+ final VpnProfile decodedVpnProfile =
+ VpnProfile.decode(vpnProfile.key, vpnProfile.encode());
+ final Ikev2VpnProfile convertedIkev2VpnProfile =
+ Ikev2VpnProfile.fromVpnProfile(decodedVpnProfile);
+ assertEquals(ikev2VpnProfile, convertedIkev2VpnProfile);
+ }
+
+ @Test
public void testConversionIsLosslessWithIkeTunConnParams() throws Exception {
final IkeTunnelConnectionParams tunnelParams =
new IkeTunnelConnectionParams(IKE_PARAMS_V6, CHILD_PARAMS);
@@ -471,6 +507,23 @@
new Ikev2VpnProfile.Builder(tunnelParams2).build());
}
+ @Test
+ public void testBuildProfileWithNullProxy() throws Exception {
+ final Ikev2VpnProfile ikev2VpnProfile =
+ new Ikev2VpnProfile.Builder(SERVER_ADDR_STRING, IDENTITY_STRING)
+ .setAuthUsernamePassword(USERNAME_STRING, PASSWORD_STRING, mServerRootCa)
+ .build();
+
+ // ProxyInfo should be null for the profile without setting ProxyInfo.
+ assertNull(ikev2VpnProfile.getProxyInfo());
+
+ // ProxyInfo should stay null after performing toVpnProfile() and fromVpnProfile()
+ final VpnProfile vpnProfile = ikev2VpnProfile.toVpnProfile();
+ assertNull(vpnProfile.proxy);
+
+ final Ikev2VpnProfile convertedIkev2VpnProfile = Ikev2VpnProfile.fromVpnProfile(vpnProfile);
+ assertNull(convertedIkev2VpnProfile.getProxyInfo());
+ }
private static class CertificateAndKey {
public final X509Certificate cert;
diff --git a/tests/unit/java/android/net/NetworkStatsTest.java b/tests/unit/java/android/net/NetworkStatsTest.java
index 709b722..126ad55 100644
--- a/tests/unit/java/android/net/NetworkStatsTest.java
+++ b/tests/unit/java/android/net/NetworkStatsTest.java
@@ -1067,6 +1067,38 @@
}
}
+ @Test
+ public void testClearInterfaces() {
+ final NetworkStats stats = new NetworkStats(TEST_START, 1);
+ final NetworkStats.Entry entry1 = new NetworkStats.Entry(
+ "test1", 10100, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+ DEFAULT_NETWORK_NO, 1024L, 50L, 100L, 20L, 0L);
+
+ final NetworkStats.Entry entry2 = new NetworkStats.Entry(
+ "test2", 10101, SET_DEFAULT, 0xF0DD, METERED_NO, ROAMING_NO,
+ DEFAULT_NETWORK_NO, 51200, 25L, 101010L, 50L, 0L);
+
+ stats.insertEntry(entry1);
+ stats.insertEntry(entry2);
+
+ // Verify that the interfaces have indeed been recorded.
+ assertEquals(2, stats.size());
+ assertValues(stats, 0, "test1", 10100, SET_DEFAULT, TAG_NONE, METERED_NO,
+ ROAMING_NO, DEFAULT_NETWORK_NO, 1024L, 50L, 100L, 20L, 0L);
+ assertValues(stats, 1, "test2", 10101, SET_DEFAULT, 0xF0DD, METERED_NO,
+ ROAMING_NO, DEFAULT_NETWORK_NO, 51200, 25L, 101010L, 50L, 0L);
+
+ // Clear interfaces.
+ stats.clearInterfaces();
+
+ // Verify that the interfaces are cleared.
+ assertEquals(2, stats.size());
+ assertValues(stats, 0, null /* iface */, 10100, SET_DEFAULT, TAG_NONE, METERED_NO,
+ ROAMING_NO, DEFAULT_NETWORK_NO, 1024L, 50L, 100L, 20L, 0L);
+ assertValues(stats, 1, null /* iface */, 10101, SET_DEFAULT, 0xF0DD, METERED_NO,
+ ROAMING_NO, DEFAULT_NETWORK_NO, 51200, 25L, 101010L, 50L, 0L);
+ }
+
private static void assertContains(NetworkStats stats, String iface, int uid, int set,
int tag, int metered, int roaming, int defaultNetwork, long rxBytes, long rxPackets,
long txBytes, long txPackets, long operations) {
diff --git a/tests/unit/java/android/net/NetworkTemplateTest.kt b/tests/unit/java/android/net/NetworkTemplateTest.kt
index 3e9662d..6c39169 100644
--- a/tests/unit/java/android/net/NetworkTemplateTest.kt
+++ b/tests/unit/java/android/net/NetworkTemplateTest.kt
@@ -19,7 +19,10 @@
import android.app.usage.NetworkStatsManager.NETWORK_TYPE_5G_NSA
import android.content.Context
import android.net.ConnectivityManager.TYPE_MOBILE
+import android.net.ConnectivityManager.TYPE_TEST
import android.net.ConnectivityManager.TYPE_WIFI
+import android.net.NetworkCapabilities.TRANSPORT_TEST
+import android.net.NetworkCapabilities.TRANSPORT_WIFI
import android.net.NetworkIdentity.OEM_NONE
import android.net.NetworkIdentity.OEM_PAID
import android.net.NetworkIdentity.OEM_PRIVATE
@@ -31,6 +34,7 @@
import android.net.NetworkStats.ROAMING_ALL
import android.net.NetworkTemplate.MATCH_MOBILE
import android.net.NetworkTemplate.MATCH_MOBILE_WILDCARD
+import android.net.NetworkTemplate.MATCH_TEST
import android.net.NetworkTemplate.MATCH_WIFI
import android.net.NetworkTemplate.MATCH_WIFI_WILDCARD
import android.net.NetworkTemplate.NETWORK_TYPE_ALL
@@ -97,6 +101,14 @@
(oemManaged and OEM_PAID) == OEM_PAID)
setCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE,
(oemManaged and OEM_PRIVATE) == OEM_PRIVATE)
+ if (type == TYPE_TEST) {
+ wifiKey?.let { TestNetworkSpecifier(it) }?.let {
+ // Must have a single non-test transport specified to use setNetworkSpecifier.
+ // Put an arbitrary transport type which is not used in this test.
+ addTransportType(TRANSPORT_TEST)
+ addTransportType(TRANSPORT_WIFI)
+ setNetworkSpecifier(it) }
+ }
setTransportInfo(mockWifiInfo)
}
return NetworkStateSnapshot(mock(Network::class.java), caps, lp, subscriberId, type)
@@ -233,6 +245,32 @@
}
@Test
+ fun testTestNetworkTemplateMatches() {
+ val templateTestKey1 = NetworkTemplate.Builder(MATCH_TEST)
+ .setWifiNetworkKeys(setOf(TEST_WIFI_KEY1)).build()
+ val templateTestKey2 = NetworkTemplate.Builder(MATCH_TEST)
+ .setWifiNetworkKeys(setOf(TEST_WIFI_KEY2)).build()
+ val templateTestAll = NetworkTemplate.Builder(MATCH_TEST).build()
+
+ val stateWifiKey1 = buildNetworkState(TYPE_WIFI, null /* subscriberId */, TEST_WIFI_KEY1,
+ OEM_NONE, true /* metered */)
+ val stateTestKey1 = buildNetworkState(TYPE_TEST, null /* subscriberId */, TEST_WIFI_KEY1,
+ OEM_NONE, true /* metered */)
+ val identWifi1 = buildNetworkIdentity(mockContext, stateWifiKey1,
+ false /* defaultNetwork */, NetworkTemplate.NETWORK_TYPE_ALL)
+ val identTest1 = buildNetworkIdentity(mockContext, stateTestKey1,
+ false /* defaultNetwork */, NETWORK_TYPE_ALL)
+
+ // Verify that the template matches corresponding type and the subscriberId.
+ templateTestKey1.assertDoesNotMatch(identWifi1)
+ templateTestKey1.assertMatches(identTest1)
+ templateTestKey2.assertDoesNotMatch(identWifi1)
+ templateTestKey2.assertDoesNotMatch(identTest1)
+ templateTestAll.assertDoesNotMatch(identWifi1)
+ templateTestAll.assertMatches(identTest1)
+ }
+
+ @Test
fun testCarrierMeteredMatches() {
val templateCarrierImsi1Metered = buildTemplateCarrierMetered(TEST_IMSI1)
diff --git a/tests/unit/java/com/android/server/BpfNetMapsTest.java b/tests/unit/java/com/android/server/BpfNetMapsTest.java
index be286ec..0e17cd7 100644
--- a/tests/unit/java/com/android/server/BpfNetMapsTest.java
+++ b/tests/unit/java/com/android/server/BpfNetMapsTest.java
@@ -30,16 +30,23 @@
import static android.net.INetd.PERMISSION_NONE;
import static android.net.INetd.PERMISSION_UNINSTALLED;
import static android.net.INetd.PERMISSION_UPDATE_DEVICE_STATS;
+import static android.system.OsConstants.EINVAL;
import static android.system.OsConstants.EPERM;
import static com.android.server.BpfNetMaps.DOZABLE_MATCH;
import static com.android.server.BpfNetMaps.HAPPY_BOX_MATCH;
import static com.android.server.BpfNetMaps.IIF_MATCH;
import static com.android.server.BpfNetMaps.LOCKDOWN_VPN_MATCH;
+import static com.android.server.BpfNetMaps.LOW_POWER_STANDBY_MATCH;
import static com.android.server.BpfNetMaps.NO_MATCH;
+import static com.android.server.BpfNetMaps.OEM_DENY_1_MATCH;
+import static com.android.server.BpfNetMaps.OEM_DENY_2_MATCH;
+import static com.android.server.BpfNetMaps.OEM_DENY_3_MATCH;
import static com.android.server.BpfNetMaps.PENALTY_BOX_MATCH;
import static com.android.server.BpfNetMaps.POWERSAVE_MATCH;
import static com.android.server.BpfNetMaps.RESTRICTED_MATCH;
+import static com.android.server.BpfNetMaps.STANDBY_MATCH;
+import static com.android.server.ConnectivityStatsLog.NETWORK_BPF_MAP_INFO;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -47,20 +54,29 @@
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeFalse;
+import static org.mockito.Mockito.any;
import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
+import android.app.StatsManager;
import android.content.Context;
import android.net.INetd;
import android.os.Build;
import android.os.ServiceSpecificException;
+import android.system.ErrnoException;
+import android.util.IndentingPrintWriter;
import androidx.test.filters.SmallTest;
import com.android.modules.utils.build.SdkLevel;
-import com.android.net.module.util.BpfMap;
+import com.android.net.module.util.IBpfMap;
+import com.android.net.module.util.Struct.S32;
import com.android.net.module.util.Struct.U32;
import com.android.net.module.util.Struct.U8;
+import com.android.net.module.util.bpf.CookieTagMapKey;
+import com.android.net.module.util.bpf.CookieTagMapValue;
import com.android.testutils.DevSdkIgnoreRule;
import com.android.testutils.DevSdkIgnoreRule.IgnoreAfter;
import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo;
@@ -74,6 +90,9 @@
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import java.io.FileDescriptor;
+import java.io.StringWriter;
+import java.util.ArrayList;
import java.util.List;
@RunWith(DevSdkIgnoreRunner.class)
@@ -92,8 +111,8 @@
private static final int NO_IIF = 0;
private static final int NULL_IIF = 0;
private static final String CHAINNAME = "fw_dozable";
- private static final U32 UID_RULES_CONFIGURATION_KEY = new U32(0);
- private static final U32 CURRENT_STATS_MAP_CONFIGURATION_KEY = new U32(1);
+ private static final S32 UID_RULES_CONFIGURATION_KEY = new S32(0);
+ private static final S32 CURRENT_STATS_MAP_CONFIGURATION_KEY = new S32(1);
private static final List<Integer> FIREWALL_CHAINS = List.of(
FIREWALL_CHAIN_DOZABLE,
FIREWALL_CHAIN_STANDBY,
@@ -113,10 +132,12 @@
@Mock INetd mNetd;
@Mock BpfNetMaps.Dependencies mDeps;
@Mock Context mContext;
- private final BpfMap<U32, U32> mConfigurationMap = new TestBpfMap<>(U32.class, U32.class);
- private final BpfMap<U32, UidOwnerValue> mUidOwnerMap =
- new TestBpfMap<>(U32.class, UidOwnerValue.class);
- private final BpfMap<U32, U8> mUidPermissionMap = new TestBpfMap<>(U32.class, U8.class);
+ private final IBpfMap<S32, U32> mConfigurationMap = new TestBpfMap<>(S32.class, U32.class);
+ private final IBpfMap<S32, UidOwnerValue> mUidOwnerMap =
+ new TestBpfMap<>(S32.class, UidOwnerValue.class);
+ private final IBpfMap<S32, U8> mUidPermissionMap = new TestBpfMap<>(S32.class, U8.class);
+ private final IBpfMap<CookieTagMapKey, CookieTagMapValue> mCookieTagMap =
+ spy(new TestBpfMap<>(CookieTagMapKey.class, CookieTagMapValue.class));
@Before
public void setUp() throws Exception {
@@ -125,8 +146,12 @@
doReturn(0).when(mDeps).synchronizeKernelRCU();
BpfNetMaps.setEnableJavaBpfMapForTest(true /* enable */);
BpfNetMaps.setConfigurationMapForTest(mConfigurationMap);
+ mConfigurationMap.updateEntry(UID_RULES_CONFIGURATION_KEY, new U32(0));
+ mConfigurationMap.updateEntry(
+ CURRENT_STATS_MAP_CONFIGURATION_KEY, new U32(STATS_SELECT_MAP_A));
BpfNetMaps.setUidOwnerMapForTest(mUidOwnerMap);
BpfNetMaps.setUidPermissionMapForTest(mUidPermissionMap);
+ BpfNetMaps.setCookieTagMapForTest(mCookieTagMap);
mBpfNetMaps = new BpfNetMaps(mContext, mNetd, mDeps);
}
@@ -279,9 +304,9 @@
() -> mBpfNetMaps.setChildChain(FIREWALL_CHAIN_DOZABLE, true /* enable */));
}
- private void checkUidOwnerValue(final long uid, final long expectedIif,
+ private void checkUidOwnerValue(final int uid, final int expectedIif,
final long expectedMatch) throws Exception {
- final UidOwnerValue config = mUidOwnerMap.getValue(new U32(uid));
+ final UidOwnerValue config = mUidOwnerMap.getValue(new S32(uid));
if (expectedMatch == 0) {
assertNull(config);
} else {
@@ -290,8 +315,8 @@
}
}
- private void doTestRemoveNaughtyApp(final long iif, final long match) throws Exception {
- mUidOwnerMap.updateEntry(new U32(TEST_UID), new UidOwnerValue(iif, match));
+ private void doTestRemoveNaughtyApp(final int iif, final long match) throws Exception {
+ mUidOwnerMap.updateEntry(new S32(TEST_UID), new UidOwnerValue(iif, match));
mBpfNetMaps.removeNaughtyApp(TEST_UID);
@@ -328,9 +353,9 @@
() -> mBpfNetMaps.removeNaughtyApp(TEST_UID));
}
- private void doTestAddNaughtyApp(final long iif, final long match) throws Exception {
+ private void doTestAddNaughtyApp(final int iif, final long match) throws Exception {
if (match != NO_MATCH) {
- mUidOwnerMap.updateEntry(new U32(TEST_UID), new UidOwnerValue(iif, match));
+ mUidOwnerMap.updateEntry(new S32(TEST_UID), new UidOwnerValue(iif, match));
}
mBpfNetMaps.addNaughtyApp(TEST_UID);
@@ -360,8 +385,8 @@
() -> mBpfNetMaps.addNaughtyApp(TEST_UID));
}
- private void doTestRemoveNiceApp(final long iif, final long match) throws Exception {
- mUidOwnerMap.updateEntry(new U32(TEST_UID), new UidOwnerValue(iif, match));
+ private void doTestRemoveNiceApp(final int iif, final long match) throws Exception {
+ mUidOwnerMap.updateEntry(new S32(TEST_UID), new UidOwnerValue(iif, match));
mBpfNetMaps.removeNiceApp(TEST_UID);
@@ -398,9 +423,9 @@
() -> mBpfNetMaps.removeNiceApp(TEST_UID));
}
- private void doTestAddNiceApp(final long iif, final long match) throws Exception {
+ private void doTestAddNiceApp(final int iif, final long match) throws Exception {
if (match != NO_MATCH) {
- mUidOwnerMap.updateEntry(new U32(TEST_UID), new UidOwnerValue(iif, match));
+ mUidOwnerMap.updateEntry(new S32(TEST_UID), new UidOwnerValue(iif, match));
}
mBpfNetMaps.addNiceApp(TEST_UID);
@@ -430,10 +455,10 @@
() -> mBpfNetMaps.addNiceApp(TEST_UID));
}
- private void doTestUpdateUidLockdownRule(final long iif, final long match, final boolean add)
+ private void doTestUpdateUidLockdownRule(final int iif, final long match, final boolean add)
throws Exception {
if (match != NO_MATCH) {
- mUidOwnerMap.updateEntry(new U32(TEST_UID), new UidOwnerValue(iif, match));
+ mUidOwnerMap.updateEntry(new S32(TEST_UID), new UidOwnerValue(iif, match));
}
mBpfNetMaps.updateUidLockdownRule(TEST_UID, add);
@@ -503,8 +528,8 @@
final int uid1 = TEST_UIDS[1];
final long match0 = DOZABLE_MATCH;
final long match1 = DOZABLE_MATCH | POWERSAVE_MATCH | RESTRICTED_MATCH;
- mUidOwnerMap.updateEntry(new U32(uid0), new UidOwnerValue(NO_IIF, match0));
- mUidOwnerMap.updateEntry(new U32(uid1), new UidOwnerValue(NO_IIF, match1));
+ mUidOwnerMap.updateEntry(new S32(uid0), new UidOwnerValue(NO_IIF, match0));
+ mUidOwnerMap.updateEntry(new S32(uid1), new UidOwnerValue(NO_IIF, match1));
mBpfNetMaps.addUidInterfaceRules(TEST_IF_NAME, TEST_UIDS);
@@ -519,8 +544,8 @@
final int uid1 = TEST_UIDS[1];
final long match0 = IIF_MATCH;
final long match1 = IIF_MATCH | DOZABLE_MATCH | POWERSAVE_MATCH | RESTRICTED_MATCH;
- mUidOwnerMap.updateEntry(new U32(uid0), new UidOwnerValue(TEST_IF_INDEX + 1, match0));
- mUidOwnerMap.updateEntry(new U32(uid1), new UidOwnerValue(NULL_IIF, match1));
+ mUidOwnerMap.updateEntry(new S32(uid0), new UidOwnerValue(TEST_IF_INDEX + 1, match0));
+ mUidOwnerMap.updateEntry(new S32(uid1), new UidOwnerValue(NULL_IIF, match1));
mBpfNetMaps.addUidInterfaceRules(TEST_IF_NAME, TEST_UIDS);
@@ -543,8 +568,8 @@
final int uid1 = TEST_UIDS[1];
final long match0 = IIF_MATCH;
final long match1 = IIF_MATCH | DOZABLE_MATCH | POWERSAVE_MATCH | RESTRICTED_MATCH;
- mUidOwnerMap.updateEntry(new U32(uid0), new UidOwnerValue(TEST_IF_INDEX, match0));
- mUidOwnerMap.updateEntry(new U32(uid1), new UidOwnerValue(NULL_IIF, match1));
+ mUidOwnerMap.updateEntry(new S32(uid0), new UidOwnerValue(TEST_IF_INDEX, match0));
+ mUidOwnerMap.updateEntry(new S32(uid1), new UidOwnerValue(NULL_IIF, match1));
mBpfNetMaps.addUidInterfaceRules(null /* ifName */, TEST_UIDS);
@@ -552,12 +577,12 @@
checkUidOwnerValue(uid1, NULL_IIF, match1);
}
- private void doTestRemoveUidInterfaceRules(final long iif0, final long match0,
- final long iif1, final long match1) throws Exception {
+ private void doTestRemoveUidInterfaceRules(final int iif0, final long match0,
+ final int iif1, final long match1) throws Exception {
final int uid0 = TEST_UIDS[0];
final int uid1 = TEST_UIDS[1];
- mUidOwnerMap.updateEntry(new U32(uid0), new UidOwnerValue(iif0, match0));
- mUidOwnerMap.updateEntry(new U32(uid1), new UidOwnerValue(iif1, match1));
+ mUidOwnerMap.updateEntry(new S32(uid0), new UidOwnerValue(iif0, match0));
+ mUidOwnerMap.updateEntry(new S32(uid1), new UidOwnerValue(iif1, match1));
mBpfNetMaps.removeUidInterfaceRules(TEST_UIDS);
@@ -580,7 +605,7 @@
}
private void doTestSetUidRule(final List<Integer> testChains) throws Exception {
- mUidOwnerMap.updateEntry(new U32(TEST_UID), new UidOwnerValue(TEST_IF_INDEX, IIF_MATCH));
+ mUidOwnerMap.updateEntry(new S32(TEST_UID), new UidOwnerValue(TEST_IF_INDEX, IIF_MATCH));
for (final int chain: testChains) {
final int ruleToAddMatch = mBpfNetMaps.isFirewallAllowList(chain)
@@ -684,8 +709,8 @@
final int uid1 = TEST_UIDS[1];
final long match0 = POWERSAVE_MATCH;
final long match1 = POWERSAVE_MATCH | RESTRICTED_MATCH;
- mUidOwnerMap.updateEntry(new U32(uid0), new UidOwnerValue(NO_IIF, match0));
- mUidOwnerMap.updateEntry(new U32(uid1), new UidOwnerValue(NO_IIF, match1));
+ mUidOwnerMap.updateEntry(new S32(uid0), new UidOwnerValue(NO_IIF, match0));
+ mUidOwnerMap.updateEntry(new S32(uid1), new UidOwnerValue(NO_IIF, match1));
mBpfNetMaps.replaceUidChain(FIREWALL_CHAIN_DOZABLE, new int[]{uid1});
@@ -700,8 +725,8 @@
final int uid1 = TEST_UIDS[1];
final long match0 = IIF_MATCH;
final long match1 = IIF_MATCH | POWERSAVE_MATCH | RESTRICTED_MATCH;
- mUidOwnerMap.updateEntry(new U32(uid0), new UidOwnerValue(TEST_IF_INDEX, match0));
- mUidOwnerMap.updateEntry(new U32(uid1), new UidOwnerValue(NULL_IIF, match1));
+ mUidOwnerMap.updateEntry(new S32(uid0), new UidOwnerValue(TEST_IF_INDEX, match0));
+ mUidOwnerMap.updateEntry(new S32(uid1), new UidOwnerValue(NULL_IIF, match1));
mBpfNetMaps.replaceUidChain(FIREWALL_CHAIN_DOZABLE, TEST_UIDS);
@@ -716,8 +741,8 @@
final int uid1 = TEST_UIDS[1];
final long match0 = IIF_MATCH | DOZABLE_MATCH;
final long match1 = IIF_MATCH | POWERSAVE_MATCH | RESTRICTED_MATCH;
- mUidOwnerMap.updateEntry(new U32(uid0), new UidOwnerValue(TEST_IF_INDEX, match0));
- mUidOwnerMap.updateEntry(new U32(uid1), new UidOwnerValue(NULL_IIF, match1));
+ mUidOwnerMap.updateEntry(new S32(uid0), new UidOwnerValue(TEST_IF_INDEX, match0));
+ mUidOwnerMap.updateEntry(new S32(uid1), new UidOwnerValue(NULL_IIF, match1));
mBpfNetMaps.replaceUidChain(FIREWALL_CHAIN_DOZABLE, new int[]{uid1});
@@ -755,8 +780,8 @@
final int uid0 = TEST_UIDS[0];
final int uid1 = TEST_UIDS[1];
- assertEquals(PERMISSION_UPDATE_DEVICE_STATS, mUidPermissionMap.getValue(new U32(uid0)).val);
- assertEquals(PERMISSION_UPDATE_DEVICE_STATS, mUidPermissionMap.getValue(new U32(uid1)).val);
+ assertEquals(PERMISSION_UPDATE_DEVICE_STATS, mUidPermissionMap.getValue(new S32(uid0)).val);
+ assertEquals(PERMISSION_UPDATE_DEVICE_STATS, mUidPermissionMap.getValue(new S32(uid1)).val);
}
@Test
@@ -767,8 +792,8 @@
final int uid0 = TEST_UIDS[0];
final int uid1 = TEST_UIDS[1];
- assertEquals(permission, mUidPermissionMap.getValue(new U32(uid0)).val);
- assertEquals(permission, mUidPermissionMap.getValue(new U32(uid1)).val);
+ assertEquals(permission, mUidPermissionMap.getValue(new S32(uid0)).val);
+ assertEquals(permission, mUidPermissionMap.getValue(new S32(uid1)).val);
}
@Test
@@ -779,8 +804,8 @@
mBpfNetMaps.setNetPermForUids(PERMISSION_INTERNET, TEST_UIDS);
mBpfNetMaps.setNetPermForUids(PERMISSION_NONE, new int[]{uid0});
- assertEquals(PERMISSION_NONE, mUidPermissionMap.getValue(new U32(uid0)).val);
- assertNull(mUidPermissionMap.getValue(new U32(uid1)));
+ assertEquals(PERMISSION_NONE, mUidPermissionMap.getValue(new S32(uid0)).val);
+ assertNull(mUidPermissionMap.getValue(new S32(uid1)));
}
@Test
@@ -791,8 +816,8 @@
mBpfNetMaps.setNetPermForUids(PERMISSION_UPDATE_DEVICE_STATS, TEST_UIDS);
mBpfNetMaps.setNetPermForUids(PERMISSION_NONE, new int[]{uid0});
- assertEquals(PERMISSION_NONE, mUidPermissionMap.getValue(new U32(uid0)).val);
- assertEquals(PERMISSION_UPDATE_DEVICE_STATS, mUidPermissionMap.getValue(new U32(uid1)).val);
+ assertEquals(PERMISSION_NONE, mUidPermissionMap.getValue(new S32(uid0)).val);
+ assertEquals(PERMISSION_UPDATE_DEVICE_STATS, mUidPermissionMap.getValue(new S32(uid1)).val);
}
@Test
@@ -804,8 +829,8 @@
mBpfNetMaps.setNetPermForUids(permission, TEST_UIDS);
mBpfNetMaps.setNetPermForUids(PERMISSION_NONE, new int[]{uid0});
- assertEquals(PERMISSION_NONE, mUidPermissionMap.getValue(new U32(uid0)).val);
- assertEquals(permission, mUidPermissionMap.getValue(new U32(uid1)).val);
+ assertEquals(PERMISSION_NONE, mUidPermissionMap.getValue(new S32(uid0)).val);
+ assertEquals(permission, mUidPermissionMap.getValue(new S32(uid1)).val);
}
@Test
@@ -817,8 +842,8 @@
mBpfNetMaps.setNetPermForUids(permission, TEST_UIDS);
mBpfNetMaps.setNetPermForUids(PERMISSION_UNINSTALLED, new int[]{uid0});
- assertNull(mUidPermissionMap.getValue(new U32(uid0)));
- assertEquals(permission, mUidPermissionMap.getValue(new U32(uid1)).val);
+ assertNull(mUidPermissionMap.getValue(new S32(uid0)));
+ assertEquals(permission, mUidPermissionMap.getValue(new S32(uid1)).val);
}
@Test
@@ -829,28 +854,28 @@
final int permission = PERMISSION_INTERNET | PERMISSION_UPDATE_DEVICE_STATS;
mBpfNetMaps.setNetPermForUids(permission, TEST_UIDS);
- assertEquals(permission, mUidPermissionMap.getValue(new U32(uid0)).val);
- assertEquals(permission, mUidPermissionMap.getValue(new U32(uid1)).val);
+ assertEquals(permission, mUidPermissionMap.getValue(new S32(uid0)).val);
+ assertEquals(permission, mUidPermissionMap.getValue(new S32(uid1)).val);
mBpfNetMaps.setNetPermForUids(permission, TEST_UIDS);
- assertEquals(permission, mUidPermissionMap.getValue(new U32(uid0)).val);
- assertEquals(permission, mUidPermissionMap.getValue(new U32(uid1)).val);
+ assertEquals(permission, mUidPermissionMap.getValue(new S32(uid0)).val);
+ assertEquals(permission, mUidPermissionMap.getValue(new S32(uid1)).val);
mBpfNetMaps.setNetPermForUids(PERMISSION_NONE, TEST_UIDS);
- assertEquals(PERMISSION_NONE, mUidPermissionMap.getValue(new U32(uid0)).val);
- assertEquals(PERMISSION_NONE, mUidPermissionMap.getValue(new U32(uid1)).val);
+ assertEquals(PERMISSION_NONE, mUidPermissionMap.getValue(new S32(uid0)).val);
+ assertEquals(PERMISSION_NONE, mUidPermissionMap.getValue(new S32(uid1)).val);
mBpfNetMaps.setNetPermForUids(PERMISSION_NONE, TEST_UIDS);
- assertEquals(PERMISSION_NONE, mUidPermissionMap.getValue(new U32(uid0)).val);
- assertEquals(PERMISSION_NONE, mUidPermissionMap.getValue(new U32(uid1)).val);
+ assertEquals(PERMISSION_NONE, mUidPermissionMap.getValue(new S32(uid0)).val);
+ assertEquals(PERMISSION_NONE, mUidPermissionMap.getValue(new S32(uid1)).val);
mBpfNetMaps.setNetPermForUids(PERMISSION_UNINSTALLED, TEST_UIDS);
- assertNull(mUidPermissionMap.getValue(new U32(uid0)));
- assertNull(mUidPermissionMap.getValue(new U32(uid1)));
+ assertNull(mUidPermissionMap.getValue(new S32(uid0)));
+ assertNull(mUidPermissionMap.getValue(new S32(uid1)));
mBpfNetMaps.setNetPermForUids(PERMISSION_UNINSTALLED, TEST_UIDS);
- assertNull(mUidPermissionMap.getValue(new U32(uid0)));
- assertNull(mUidPermissionMap.getValue(new U32(uid1)));
+ assertNull(mUidPermissionMap.getValue(new S32(uid0)));
+ assertNull(mUidPermissionMap.getValue(new S32(uid1)));
}
@Test
@@ -877,4 +902,179 @@
assertThrows(ServiceSpecificException.class, () -> mBpfNetMaps.swapActiveStatsMap());
}
+
+ @Test
+ @IgnoreUpTo(Build.VERSION_CODES.S_V2)
+ public void testPullBpfMapInfo() throws Exception {
+ // mCookieTagMap has 1 entry
+ mCookieTagMap.updateEntry(new CookieTagMapKey(0), new CookieTagMapValue(0, 0));
+
+ // mUidOwnerMap has 2 entries
+ mUidOwnerMap.updateEntry(new S32(0), new UidOwnerValue(0, 0));
+ mUidOwnerMap.updateEntry(new S32(1), new UidOwnerValue(0, 0));
+
+ // mUidPermissionMap has 3 entries
+ mUidPermissionMap.updateEntry(new S32(0), new U8((short) 0));
+ mUidPermissionMap.updateEntry(new S32(1), new U8((short) 0));
+ mUidPermissionMap.updateEntry(new S32(2), new U8((short) 0));
+
+ final int ret = mBpfNetMaps.pullBpfMapInfoAtom(NETWORK_BPF_MAP_INFO, new ArrayList<>());
+ assertEquals(StatsManager.PULL_SUCCESS, ret);
+ verify(mDeps).buildStatsEvent(
+ 1 /* cookieTagMapSize */, 2 /* uidOwnerMapSize */, 3 /* uidPermissionMapSize */);
+ }
+
+ @Test
+ @IgnoreUpTo(Build.VERSION_CODES.S_V2)
+ public void testPullBpfMapInfoGetMapSizeFailure() throws Exception {
+ doThrow(new ErrnoException("", EINVAL)).when(mCookieTagMap).forEach(any());
+ final int ret = mBpfNetMaps.pullBpfMapInfoAtom(NETWORK_BPF_MAP_INFO, new ArrayList<>());
+ assertEquals(StatsManager.PULL_SKIP, ret);
+ }
+
+ @Test
+ @IgnoreUpTo(Build.VERSION_CODES.S_V2)
+ public void testPullBpfMapInfoUnexpectedAtomTag() {
+ final int ret = mBpfNetMaps.pullBpfMapInfoAtom(-1 /* atomTag */, new ArrayList<>());
+ assertEquals(StatsManager.PULL_SKIP, ret);
+ }
+
+ private void assertDumpContains(final String dump, final String message) {
+ assertTrue(String.format("dump(%s) does not contain '%s'", dump, message),
+ dump.contains(message));
+ }
+
+ private String getDump() throws Exception {
+ final StringWriter sw = new StringWriter();
+ mBpfNetMaps.dump(new IndentingPrintWriter(sw), new FileDescriptor(), true /* verbose */);
+ return sw.toString();
+ }
+
+ private void doTestDumpUidPermissionMap(final int permission, final String permissionString)
+ throws Exception {
+ mUidPermissionMap.updateEntry(new S32(TEST_UID), new U8((short) permission));
+ assertDumpContains(getDump(), TEST_UID + " " + permissionString);
+ }
+
+ @Test
+ @IgnoreUpTo(Build.VERSION_CODES.S_V2)
+ public void testDumpUidPermissionMap() throws Exception {
+ doTestDumpUidPermissionMap(PERMISSION_NONE, "PERMISSION_NONE");
+ doTestDumpUidPermissionMap(PERMISSION_INTERNET | PERMISSION_UPDATE_DEVICE_STATS,
+ "PERMISSION_INTERNET PERMISSION_UPDATE_DEVICE_STATS");
+ }
+
+ @Test
+ @IgnoreUpTo(Build.VERSION_CODES.S_V2)
+ public void testDumpUidPermissionMapInvalidPermission() throws Exception {
+ doTestDumpUidPermissionMap(PERMISSION_UNINSTALLED, "PERMISSION_UNINSTALLED error!");
+ doTestDumpUidPermissionMap(PERMISSION_INTERNET | 1 << 6,
+ "PERMISSION_INTERNET PERMISSION_UNKNOWN(64)");
+ }
+
+ void doTestDumpUidOwnerMap(final int iif, final long match, final String matchString)
+ throws Exception {
+ mUidOwnerMap.updateEntry(new S32(TEST_UID), new UidOwnerValue(iif, match));
+ assertDumpContains(getDump(), TEST_UID + " " + matchString);
+ }
+
+ void doTestDumpUidOwnerMap(final long match, final String matchString) throws Exception {
+ doTestDumpUidOwnerMap(0 /* iif */, match, matchString);
+ }
+
+ @Test
+ @IgnoreUpTo(Build.VERSION_CODES.S_V2)
+ public void testDumpUidOwnerMap() throws Exception {
+ doTestDumpUidOwnerMap(HAPPY_BOX_MATCH, "HAPPY_BOX_MATCH");
+ doTestDumpUidOwnerMap(PENALTY_BOX_MATCH, "PENALTY_BOX_MATCH");
+ doTestDumpUidOwnerMap(DOZABLE_MATCH, "DOZABLE_MATCH");
+ doTestDumpUidOwnerMap(STANDBY_MATCH, "STANDBY_MATCH");
+ doTestDumpUidOwnerMap(POWERSAVE_MATCH, "POWERSAVE_MATCH");
+ doTestDumpUidOwnerMap(RESTRICTED_MATCH, "RESTRICTED_MATCH");
+ doTestDumpUidOwnerMap(LOW_POWER_STANDBY_MATCH, "LOW_POWER_STANDBY_MATCH");
+ doTestDumpUidOwnerMap(LOCKDOWN_VPN_MATCH, "LOCKDOWN_VPN_MATCH");
+ doTestDumpUidOwnerMap(OEM_DENY_1_MATCH, "OEM_DENY_1_MATCH");
+ doTestDumpUidOwnerMap(OEM_DENY_2_MATCH, "OEM_DENY_2_MATCH");
+ doTestDumpUidOwnerMap(OEM_DENY_3_MATCH, "OEM_DENY_3_MATCH");
+
+ doTestDumpUidOwnerMap(HAPPY_BOX_MATCH | POWERSAVE_MATCH,
+ "HAPPY_BOX_MATCH POWERSAVE_MATCH");
+ doTestDumpUidOwnerMap(DOZABLE_MATCH | LOCKDOWN_VPN_MATCH | OEM_DENY_1_MATCH,
+ "DOZABLE_MATCH LOCKDOWN_VPN_MATCH OEM_DENY_1_MATCH");
+ }
+
+ @Test
+ @IgnoreUpTo(Build.VERSION_CODES.S_V2)
+ public void testDumpUidOwnerMapWithIifMatch() throws Exception {
+ doTestDumpUidOwnerMap(TEST_IF_INDEX, IIF_MATCH, "IIF_MATCH " + TEST_IF_INDEX);
+ doTestDumpUidOwnerMap(TEST_IF_INDEX,
+ IIF_MATCH | DOZABLE_MATCH | LOCKDOWN_VPN_MATCH | OEM_DENY_1_MATCH,
+ "DOZABLE_MATCH IIF_MATCH LOCKDOWN_VPN_MATCH OEM_DENY_1_MATCH " + TEST_IF_INDEX);
+ }
+
+ @Test
+ @IgnoreUpTo(Build.VERSION_CODES.S_V2)
+ public void testDumpUidOwnerMapWithInvalidMatch() throws Exception {
+ final long invalid_match = 1L << 31;
+ doTestDumpUidOwnerMap(invalid_match, "UNKNOWN_MATCH(" + invalid_match + ")");
+ doTestDumpUidOwnerMap(DOZABLE_MATCH | invalid_match,
+ "DOZABLE_MATCH UNKNOWN_MATCH(" + invalid_match + ")");
+ }
+
+ @Test
+ @IgnoreUpTo(Build.VERSION_CODES.S_V2)
+ public void testDumpCurrentStatsMapConfig() throws Exception {
+ mConfigurationMap.updateEntry(
+ CURRENT_STATS_MAP_CONFIGURATION_KEY, new U32(STATS_SELECT_MAP_A));
+ assertDumpContains(getDump(), "current statsMap configuration: 0 SELECT_MAP_A");
+
+ mConfigurationMap.updateEntry(
+ CURRENT_STATS_MAP_CONFIGURATION_KEY, new U32(STATS_SELECT_MAP_B));
+ assertDumpContains(getDump(), "current statsMap configuration: 1 SELECT_MAP_B");
+ }
+
+ private void doTestDumpOwnerMatchConfig(final long match, final String matchString)
+ throws Exception {
+ mConfigurationMap.updateEntry(UID_RULES_CONFIGURATION_KEY, new U32(match));
+ assertDumpContains(getDump(),
+ "current ownerMatch configuration: " + match + " " + matchString);
+ }
+
+ @Test
+ @IgnoreUpTo(Build.VERSION_CODES.S_V2)
+ public void testDumpUidOwnerMapConfig() throws Exception {
+ doTestDumpOwnerMatchConfig(HAPPY_BOX_MATCH, "HAPPY_BOX_MATCH");
+ doTestDumpOwnerMatchConfig(PENALTY_BOX_MATCH, "PENALTY_BOX_MATCH");
+ doTestDumpOwnerMatchConfig(DOZABLE_MATCH, "DOZABLE_MATCH");
+ doTestDumpOwnerMatchConfig(STANDBY_MATCH, "STANDBY_MATCH");
+ doTestDumpOwnerMatchConfig(POWERSAVE_MATCH, "POWERSAVE_MATCH");
+ doTestDumpOwnerMatchConfig(RESTRICTED_MATCH, "RESTRICTED_MATCH");
+ doTestDumpOwnerMatchConfig(LOW_POWER_STANDBY_MATCH, "LOW_POWER_STANDBY_MATCH");
+ doTestDumpOwnerMatchConfig(IIF_MATCH, "IIF_MATCH");
+ doTestDumpOwnerMatchConfig(LOCKDOWN_VPN_MATCH, "LOCKDOWN_VPN_MATCH");
+ doTestDumpOwnerMatchConfig(OEM_DENY_1_MATCH, "OEM_DENY_1_MATCH");
+ doTestDumpOwnerMatchConfig(OEM_DENY_2_MATCH, "OEM_DENY_2_MATCH");
+ doTestDumpOwnerMatchConfig(OEM_DENY_3_MATCH, "OEM_DENY_3_MATCH");
+
+ doTestDumpOwnerMatchConfig(HAPPY_BOX_MATCH | POWERSAVE_MATCH,
+ "HAPPY_BOX_MATCH POWERSAVE_MATCH");
+ doTestDumpOwnerMatchConfig(DOZABLE_MATCH | LOCKDOWN_VPN_MATCH | OEM_DENY_1_MATCH,
+ "DOZABLE_MATCH LOCKDOWN_VPN_MATCH OEM_DENY_1_MATCH");
+ }
+
+ @Test
+ @IgnoreUpTo(Build.VERSION_CODES.S_V2)
+ public void testDumpUidOwnerMapConfigWithInvalidMatch() throws Exception {
+ final long invalid_match = 1L << 31;
+ doTestDumpOwnerMatchConfig(invalid_match, "UNKNOWN_MATCH(" + invalid_match + ")");
+ doTestDumpOwnerMatchConfig(DOZABLE_MATCH | invalid_match,
+ "DOZABLE_MATCH UNKNOWN_MATCH(" + invalid_match + ")");
+ }
+
+ @Test
+ @IgnoreUpTo(Build.VERSION_CODES.S_V2)
+ public void testDumpCookieTagMap() throws Exception {
+ mCookieTagMap.updateEntry(new CookieTagMapKey(123), new CookieTagMapValue(456, 0x789));
+ assertDumpContains(getDump(), "cookie=123 tag=0x789 uid=456");
+ }
}
diff --git a/tests/unit/java/com/android/server/ConnectivityServiceTest.java b/tests/unit/java/com/android/server/ConnectivityServiceTest.java
old mode 100644
new mode 100755
index 887482e..083f34d
--- a/tests/unit/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/unit/java/com/android/server/ConnectivityServiceTest.java
@@ -302,7 +302,6 @@
import android.net.resolv.aidl.Nat64PrefixEventParcel;
import android.net.resolv.aidl.PrivateDnsValidationEventParcel;
import android.net.shared.PrivateDnsConfig;
-import android.net.util.MultinetworkPolicyTracker;
import android.net.wifi.WifiInfo;
import android.os.BadParcelableException;
import android.os.BatteryStatsManager;
@@ -357,17 +356,19 @@
import com.android.net.module.util.CollectionUtils;
import com.android.net.module.util.LocationPermissionChecker;
import com.android.net.module.util.NetworkMonitorUtils;
+import com.android.networkstack.apishim.ConstantsShim;
import com.android.networkstack.apishim.NetworkAgentConfigShimImpl;
-import com.android.networkstack.apishim.api29.ConstantsShim;
import com.android.server.ConnectivityService.ConnectivityDiagnosticsCallbackInfo;
import com.android.server.ConnectivityService.NetworkRequestInfo;
import com.android.server.ConnectivityServiceTest.ConnectivityServiceDependencies.ReportedInterfaces;
import com.android.server.connectivity.CarrierPrivilegeAuthenticator;
import com.android.server.connectivity.ClatCoordinator;
import com.android.server.connectivity.ConnectivityFlags;
-import com.android.server.connectivity.MockableSystemProperties;
+import com.android.server.connectivity.MultinetworkPolicyTracker;
+import com.android.server.connectivity.MultinetworkPolicyTrackerTestDependencies;
import com.android.server.connectivity.Nat464Xlat;
import com.android.server.connectivity.NetworkAgentInfo;
+import com.android.server.connectivity.NetworkNotificationManager;
import com.android.server.connectivity.NetworkNotificationManager.NotificationType;
import com.android.server.connectivity.ProxyTracker;
import com.android.server.connectivity.QosCallbackTracker;
@@ -440,8 +441,6 @@
import java.util.regex.Pattern;
import java.util.stream.Collectors;
-import kotlin.reflect.KClass;
-
/**
* Tests for {@link ConnectivityService}.
*
@@ -1067,38 +1066,41 @@
* @param hasInternet Indicate if network should pretend to have NET_CAPABILITY_INTERNET.
*/
public void connect(boolean validated, boolean hasInternet, boolean isStrictMode) {
- ConnectivityManager.NetworkCallback callback = null;
final ConditionVariable validatedCv = new ConditionVariable();
+ final ConditionVariable capsChangedCv = new ConditionVariable();
+ final NetworkRequest request = new NetworkRequest.Builder()
+ .addTransportType(getNetworkCapabilities().getTransportTypes()[0])
+ .clearCapabilities()
+ .build();
if (validated) {
setNetworkValid(isStrictMode);
- NetworkRequest request = new NetworkRequest.Builder()
- .addTransportType(getNetworkCapabilities().getTransportTypes()[0])
- .clearCapabilities()
- .build();
- callback = new ConnectivityManager.NetworkCallback() {
- public void onCapabilitiesChanged(Network network,
- NetworkCapabilities networkCapabilities) {
- if (network.equals(getNetwork()) &&
- networkCapabilities.hasCapability(NET_CAPABILITY_VALIDATED)) {
+ }
+ final NetworkCallback callback = new NetworkCallback() {
+ public void onCapabilitiesChanged(Network network,
+ NetworkCapabilities networkCapabilities) {
+ if (network.equals(getNetwork())) {
+ capsChangedCv.open();
+ if (networkCapabilities.hasCapability(NET_CAPABILITY_VALIDATED)) {
validatedCv.open();
}
}
- };
- mCm.registerNetworkCallback(request, callback);
- }
+ }
+ };
+ mCm.registerNetworkCallback(request, callback);
+
if (hasInternet) {
addCapability(NET_CAPABILITY_INTERNET);
}
connectWithoutInternet();
+ waitFor(capsChangedCv);
if (validated) {
// Wait for network to validate.
waitFor(validatedCv);
setNetworkInvalid(isStrictMode);
}
-
- if (callback != null) mCm.unregisterNetworkCallback(callback);
+ mCm.unregisterNetworkCallback(callback);
}
public void connectWithCaptivePortal(String redirectUrl, boolean isStrictMode) {
@@ -1169,10 +1171,11 @@
void setNetworkPartialValid(boolean isStrictMode) {
setNetworkPartial();
mNmValidationResult |= NETWORK_VALIDATION_RESULT_VALID;
+ mNmValidationRedirectUrl = null;
int probesCompleted = NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS
| NETWORK_VALIDATION_PROBE_HTTP;
int probesSucceeded = NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTP;
- // Suppose the partial network cannot pass the private DNS validation as well, so only
+ // Assume the partial network cannot pass the private DNS validation as well, so only
// add NETWORK_VALIDATION_PROBE_DNS in probesCompleted but not probesSucceeded.
if (isStrictMode) {
probesCompleted |= NETWORK_VALIDATION_PROBE_PRIVDNS;
@@ -1603,9 +1606,9 @@
mMockVpn = new MockVpn(userId);
}
- private void mockUidNetworkingBlocked() {
+ private void mockUidNetworkingBlocked(int uid) {
doAnswer(i -> isUidBlocked(mBlockedReasons, i.getArgument(1))
- ).when(mNetworkPolicyManager).isUidNetworkingBlocked(anyInt(), anyBoolean());
+ ).when(mNetworkPolicyManager).isUidNetworkingBlocked(eq(uid), anyBoolean());
}
private boolean isUidBlocked(int blockedReasons, boolean meteredNetwork) {
@@ -1632,12 +1635,7 @@
volatile int mConfigMeteredMultipathPreference;
WrappedMultinetworkPolicyTracker(Context c, Handler h, Runnable r) {
- super(c, h, r);
- }
-
- @Override
- protected Resources getResourcesForActiveSubId() {
- return mResources;
+ super(c, h, r, new MultinetworkPolicyTrackerTestDependencies(mResources));
}
@Override
@@ -1836,30 +1834,20 @@
.getIdentifier(eq("config_networkSupportedKeepaliveCount"), eq("array"), any());
doReturn(R.array.network_switch_type_name).when(mResources)
.getIdentifier(eq("network_switch_type_name"), eq("array"), any());
- doReturn(R.integer.config_networkAvoidBadWifi).when(mResources)
- .getIdentifier(eq("config_networkAvoidBadWifi"), eq("integer"), any());
doReturn(1).when(mResources).getInteger(R.integer.config_networkAvoidBadWifi);
+ doReturn(0).when(mResources).getInteger(R.integer.config_activelyPreferBadWifi);
doReturn(true).when(mResources)
.getBoolean(R.bool.config_cellular_radio_timesharing_capable);
}
class ConnectivityServiceDependencies extends ConnectivityService.Dependencies {
final ConnectivityResources mConnRes;
- @Mock final MockableSystemProperties mSystemProperties;
ConnectivityServiceDependencies(final Context mockResContext) {
- mSystemProperties = mock(MockableSystemProperties.class);
- doReturn(false).when(mSystemProperties).getBoolean("ro.radio.noril", false);
-
mConnRes = new ConnectivityResources(mockResContext);
}
@Override
- public MockableSystemProperties getSystemProperties() {
- return mSystemProperties;
- }
-
- @Override
public HandlerThread makeHandlerThread() {
return mCsHandlerThread;
}
@@ -2348,7 +2336,7 @@
b = registerConnectivityBroadcast(1);
final TestNetworkCallback callback = new TestNetworkCallback();
mCm.requestNetwork(legacyRequest, callback);
- callback.expectCallback(CallbackEntry.AVAILABLE, mCellNetworkAgent);
+ callback.expect(CallbackEntry.AVAILABLE, mCellNetworkAgent);
mCm.unregisterNetworkCallback(callback);
b.expectNoBroadcast(800); // 800ms long enough to at least flake if this is sent
@@ -2420,7 +2408,7 @@
// is added in case of flakiness.
final int nascentTimeoutMs =
mService.mNascentDelayMs + mService.mNascentDelayMs / 4;
- listenCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent, nascentTimeoutMs);
+ listenCallback.expect(CallbackEntry.LOST, mWiFiNetworkAgent, nascentTimeoutMs);
// 2. Create a network that is satisfied by a request comes later.
mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
@@ -2436,7 +2424,7 @@
// to get disconnected as usual if the request is released after the nascent timer expires.
listenCallback.assertNoCallback(nascentTimeoutMs);
mCm.unregisterNetworkCallback(wifiCallback);
- listenCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
+ listenCallback.expect(CallbackEntry.LOST, mWiFiNetworkAgent);
// 3. Create a network that is satisfied by a request comes later.
mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
@@ -2447,7 +2435,7 @@
// Verify that the network will still be torn down after the request gets removed.
mCm.unregisterNetworkCallback(wifiCallback);
- listenCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
+ listenCallback.expect(CallbackEntry.LOST, mWiFiNetworkAgent);
// There is no need to ensure that LOSING is never sent in the common case that the
// network immediately satisfies a request that was already present, because it is already
@@ -2493,7 +2481,7 @@
assertFalse(isForegroundNetwork(mCellNetworkAgent));
mCellNetworkAgent.disconnect();
- bgMobileListenCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
+ bgMobileListenCallback.expect(CallbackEntry.LOST, mCellNetworkAgent);
fgMobileListenCallback.assertNoCallback();
mCm.unregisterNetworkCallback(wifiListenCallback);
@@ -2701,7 +2689,7 @@
final TestNetworkCallback generalCb = new TestNetworkCallback();
final TestNetworkCallback defaultCb = new TestNetworkCallback();
mCm.registerNetworkCallback(
- new NetworkRequest.Builder().addTransportType(transport | transport).build(),
+ new NetworkRequest.Builder().addTransportType(transport).build(),
generalCb);
mCm.registerDefaultNetworkCallback(defaultCb);
@@ -2721,7 +2709,7 @@
// Make sure the default request goes to net 2
generalCb.expectAvailableCallbacksUnvalidated(net2);
if (expectLingering) {
- generalCb.expectCallback(CallbackEntry.LOSING, net1);
+ generalCb.expectLosing(net1);
}
generalCb.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, net2);
defaultCb.expectAvailableDoubleValidatedCallbacks(net2);
@@ -2738,7 +2726,7 @@
net1.expectDisconnected(TEST_CALLBACK_TIMEOUT_MS);
}
net1.disconnect();
- generalCb.expectCallback(CallbackEntry.LOST, net1);
+ generalCb.expect(CallbackEntry.LOST, net1);
// Remove primary from net 2
net2.setScore(new NetworkScore.Builder().build());
@@ -2766,7 +2754,7 @@
// get LOSING. If the radio can't time share, this is a hard loss, since the last
// request keeping up this network has been removed and the network isn't lingering
// for any other request.
- generalCb.expectCallback(CallbackEntry.LOSING, net2);
+ generalCb.expectLosing(net2);
net2.assertNotDisconnected(TEST_CALLBACK_TIMEOUT_MS);
generalCb.assertNoCallback();
net2.expectDisconnected(UNREASONABLY_LONG_ALARM_WAIT_MS);
@@ -2774,7 +2762,7 @@
net2.expectDisconnected(TEST_CALLBACK_TIMEOUT_MS);
}
net2.disconnect();
- generalCb.expectCallback(CallbackEntry.LOST, net2);
+ generalCb.expect(CallbackEntry.LOST, net2);
defaultCb.assertNoCallback();
net3.disconnect();
@@ -2956,13 +2944,14 @@
@Test
public void testRequiresValidation() {
- assertTrue(NetworkMonitorUtils.isValidationRequired(false /* isVpnValidationRequired */,
+ assertTrue(NetworkMonitorUtils.isValidationRequired(false /* isDunValidationRequired */,
+ false /* isVpnValidationRequired */,
mCm.getDefaultRequest().networkCapabilities));
}
/**
* Utility NetworkCallback for testing. The caller must explicitly test for all the callbacks
- * this class receives, by calling expectCallback() exactly once each time a callback is
+ * this class receives, by calling expect() exactly once each time a callback is
* received. assertNoCallback may be called at any time.
*/
private class TestNetworkCallback extends TestableNetworkCallback {
@@ -2977,20 +2966,24 @@
assertNoCallback(0 /* timeout */);
}
- @Override
- public <T extends CallbackEntry> T expectCallback(final KClass<T> type, final HasNetwork n,
- final long timeoutMs) {
- final T callback = super.expectCallback(type, n, timeoutMs);
- if (callback instanceof CallbackEntry.Losing) {
- // TODO : move this to the specific test(s) needing this rather than here.
- final CallbackEntry.Losing losing = (CallbackEntry.Losing) callback;
- final int maxMsToLive = losing.getMaxMsToLive();
- String msg = String.format(
- "Invalid linger time value %d, must be between %d and %d",
- maxMsToLive, 0, mService.mLingerDelayMs);
- assertTrue(msg, 0 <= maxMsToLive && maxMsToLive <= mService.mLingerDelayMs);
+ public CallbackEntry.Losing expectLosing(final HasNetwork n, final long timeoutMs) {
+ final CallbackEntry.Losing losing = expect(CallbackEntry.LOSING, n, timeoutMs);
+ final int maxMsToLive = losing.getMaxMsToLive();
+ if (maxMsToLive < 0 || maxMsToLive > mService.mLingerDelayMs) {
+ // maxMsToLive is the value that was received in the onLosing callback. That must
+ // not be negative, so check that.
+ // Also, maxMsToLive is the remaining time until the network expires.
+ // mService.mLingerDelayMs is how long the network takes from when it's first
+ // detected to be unneeded to when it expires, so maxMsToLive should never
+ // be greater than that.
+ fail(String.format("Invalid linger time value %d, must be between %d and %d",
+ maxMsToLive, 0, mService.mLingerDelayMs));
}
- return callback;
+ return losing;
+ }
+
+ public CallbackEntry.Losing expectLosing(final HasNetwork n) {
+ return expectLosing(n, getDefaultTimeoutMs());
}
}
@@ -3004,19 +2997,19 @@
static void expectOnLost(TestNetworkAgentWrapper network, TestNetworkCallback ... callbacks) {
for (TestNetworkCallback c : callbacks) {
- c.expectCallback(CallbackEntry.LOST, network);
+ c.expect(CallbackEntry.LOST, network);
}
}
static void expectAvailableCallbacksUnvalidatedWithSpecifier(TestNetworkAgentWrapper network,
NetworkSpecifier specifier, TestNetworkCallback ... callbacks) {
for (TestNetworkCallback c : callbacks) {
- c.expectCallback(CallbackEntry.AVAILABLE, network);
+ c.expect(CallbackEntry.AVAILABLE, network);
c.expectCapabilitiesThat(network, (nc) ->
!nc.hasCapability(NET_CAPABILITY_VALIDATED)
&& Objects.equals(specifier, nc.getNetworkSpecifier()));
- c.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, network);
- c.expectCallback(CallbackEntry.BLOCKED_STATUS, network);
+ c.expect(CallbackEntry.LINK_PROPERTIES_CHANGED, network);
+ c.expect(CallbackEntry.BLOCKED_STATUS, network);
}
}
@@ -3099,16 +3092,16 @@
b = registerConnectivityBroadcast(2);
mWiFiNetworkAgent.disconnect();
- genericNetworkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
- wifiNetworkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
+ genericNetworkCallback.expect(CallbackEntry.LOST, mWiFiNetworkAgent);
+ wifiNetworkCallback.expect(CallbackEntry.LOST, mWiFiNetworkAgent);
cellNetworkCallback.assertNoCallback();
b.expectBroadcast();
assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback);
b = registerConnectivityBroadcast(1);
mCellNetworkAgent.disconnect();
- genericNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
- cellNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
+ genericNetworkCallback.expect(CallbackEntry.LOST, mCellNetworkAgent);
+ cellNetworkCallback.expect(CallbackEntry.LOST, mCellNetworkAgent);
b.expectBroadcast();
assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback);
@@ -3129,21 +3122,21 @@
mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
mWiFiNetworkAgent.connect(true);
genericNetworkCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
- genericNetworkCallback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent);
+ genericNetworkCallback.expectLosing(mCellNetworkAgent);
genericNetworkCallback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
wifiNetworkCallback.expectAvailableThenValidatedCallbacks(mWiFiNetworkAgent);
- cellNetworkCallback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent);
+ cellNetworkCallback.expectLosing(mCellNetworkAgent);
assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback);
mWiFiNetworkAgent.disconnect();
- genericNetworkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
- wifiNetworkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
+ genericNetworkCallback.expect(CallbackEntry.LOST, mWiFiNetworkAgent);
+ wifiNetworkCallback.expect(CallbackEntry.LOST, mWiFiNetworkAgent);
assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback);
mCellNetworkAgent.disconnect();
- genericNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
- cellNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
+ genericNetworkCallback.expect(CallbackEntry.LOST, mCellNetworkAgent);
+ cellNetworkCallback.expect(CallbackEntry.LOST, mCellNetworkAgent);
assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback);
}
@@ -3276,7 +3269,7 @@
// We then get LOSING when wifi validates and cell is outscored.
callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
// TODO: Investigate sending validated before losing.
- callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent);
+ callback.expectLosing(mCellNetworkAgent);
callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
defaultCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent);
assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
@@ -3285,15 +3278,15 @@
mEthernetNetworkAgent.connect(true);
callback.expectAvailableCallbacksUnvalidated(mEthernetNetworkAgent);
// TODO: Investigate sending validated before losing.
- callback.expectCallback(CallbackEntry.LOSING, mWiFiNetworkAgent);
+ callback.expectLosing(mWiFiNetworkAgent);
callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mEthernetNetworkAgent);
defaultCallback.expectAvailableDoubleValidatedCallbacks(mEthernetNetworkAgent);
assertEquals(mEthernetNetworkAgent.getNetwork(), mCm.getActiveNetwork());
assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
mEthernetNetworkAgent.disconnect();
- callback.expectCallback(CallbackEntry.LOST, mEthernetNetworkAgent);
- defaultCallback.expectCallback(CallbackEntry.LOST, mEthernetNetworkAgent);
+ callback.expect(CallbackEntry.LOST, mEthernetNetworkAgent);
+ defaultCallback.expect(CallbackEntry.LOST, mEthernetNetworkAgent);
defaultCallback.expectAvailableCallbacksValidated(mWiFiNetworkAgent);
assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
@@ -3309,7 +3302,7 @@
newNetwork = mWiFiNetworkAgent;
}
- callback.expectCallback(CallbackEntry.LOSING, oldNetwork);
+ callback.expectLosing(oldNetwork);
// TODO: should we send an AVAILABLE callback to newNetwork, to indicate that it is no
// longer lingering?
defaultCallback.expectAvailableCallbacksValidated(newNetwork);
@@ -3323,7 +3316,7 @@
// We expect a notification about the capabilities change, and nothing else.
defaultCallback.expectCapabilitiesWithout(NET_CAPABILITY_NOT_METERED, mWiFiNetworkAgent);
defaultCallback.assertNoCallback();
- callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
+ callback.expect(CallbackEntry.LOST, mWiFiNetworkAgent);
assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
// Wifi no longer satisfies our listen, which is for an unmetered network.
@@ -3332,11 +3325,11 @@
// Disconnect our test networks.
mWiFiNetworkAgent.disconnect();
- defaultCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
+ defaultCallback.expect(CallbackEntry.LOST, mWiFiNetworkAgent);
defaultCallback.expectAvailableCallbacksValidated(mCellNetworkAgent);
assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
mCellNetworkAgent.disconnect();
- defaultCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
+ defaultCallback.expect(CallbackEntry.LOST, mCellNetworkAgent);
waitForIdle();
assertEquals(null, mCm.getActiveNetwork());
@@ -3367,8 +3360,8 @@
assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
mWiFiNetworkAgent.disconnect();
- callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
- defaultCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
+ callback.expect(CallbackEntry.LOST, mWiFiNetworkAgent);
+ defaultCallback.expect(CallbackEntry.LOST, mWiFiNetworkAgent);
defaultCallback.expectAvailableCallbacksUnvalidated(mCellNetworkAgent);
assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
@@ -3379,19 +3372,19 @@
mWiFiNetworkAgent.connect(true);
callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
// TODO: Investigate sending validated before losing.
- callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent);
+ callback.expectLosing(mCellNetworkAgent);
callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
defaultCallback.expectAvailableThenValidatedCallbacks(mWiFiNetworkAgent);
assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
mWiFiNetworkAgent.disconnect();
- callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
- defaultCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
+ callback.expect(CallbackEntry.LOST, mWiFiNetworkAgent);
+ defaultCallback.expect(CallbackEntry.LOST, mWiFiNetworkAgent);
defaultCallback.expectAvailableCallbacksUnvalidated(mCellNetworkAgent);
mCellNetworkAgent.disconnect();
- callback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
- defaultCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
+ callback.expect(CallbackEntry.LOST, mCellNetworkAgent);
+ defaultCallback.expect(CallbackEntry.LOST, mCellNetworkAgent);
waitForIdle();
assertEquals(null, mCm.getActiveNetwork());
@@ -3406,7 +3399,7 @@
defaultCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent);
callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
// TODO: Investigate sending validated before losing.
- callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent);
+ callback.expectLosing(mCellNetworkAgent);
callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
@@ -3417,13 +3410,13 @@
// TODO: should this cause an AVAILABLE callback, to indicate that the network is no longer
// lingering?
mCm.unregisterNetworkCallback(noopCallback);
- callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent);
+ callback.expectLosing(mCellNetworkAgent);
// Similar to the above: lingering can start even after the lingered request is removed.
// Disconnect wifi and switch to cell.
mWiFiNetworkAgent.disconnect();
- callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
- defaultCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
+ callback.expect(CallbackEntry.LOST, mWiFiNetworkAgent);
+ defaultCallback.expect(CallbackEntry.LOST, mWiFiNetworkAgent);
defaultCallback.expectAvailableCallbacksValidated(mCellNetworkAgent);
assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
@@ -3442,12 +3435,12 @@
callback.assertNoCallback();
// Now unregister cellRequest and expect cell to start lingering.
mCm.unregisterNetworkCallback(noopCallback);
- callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent);
+ callback.expectLosing(mCellNetworkAgent);
// Let linger run its course.
callback.assertNoCallback();
final int lingerTimeoutMs = mService.mLingerDelayMs + mService.mLingerDelayMs / 4;
- callback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent, lingerTimeoutMs);
+ callback.expect(CallbackEntry.LOST, mCellNetworkAgent, lingerTimeoutMs);
// Register a TRACK_DEFAULT request and check that it does not affect lingering.
TestNetworkCallback trackDefaultCallback = new TestNetworkCallback();
@@ -3456,20 +3449,20 @@
mEthernetNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_ETHERNET);
mEthernetNetworkAgent.connect(true);
callback.expectAvailableCallbacksUnvalidated(mEthernetNetworkAgent);
- callback.expectCallback(CallbackEntry.LOSING, mWiFiNetworkAgent);
+ callback.expectLosing(mWiFiNetworkAgent);
callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mEthernetNetworkAgent);
trackDefaultCallback.expectAvailableDoubleValidatedCallbacks(mEthernetNetworkAgent);
defaultCallback.expectAvailableDoubleValidatedCallbacks(mEthernetNetworkAgent);
assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
// Let linger run its course.
- callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent, lingerTimeoutMs);
+ callback.expect(CallbackEntry.LOST, mWiFiNetworkAgent, lingerTimeoutMs);
// Clean up.
mEthernetNetworkAgent.disconnect();
- callback.expectCallback(CallbackEntry.LOST, mEthernetNetworkAgent);
- defaultCallback.expectCallback(CallbackEntry.LOST, mEthernetNetworkAgent);
- trackDefaultCallback.expectCallback(CallbackEntry.LOST, mEthernetNetworkAgent);
+ callback.expect(CallbackEntry.LOST, mEthernetNetworkAgent);
+ defaultCallback.expect(CallbackEntry.LOST, mEthernetNetworkAgent);
+ trackDefaultCallback.expect(CallbackEntry.LOST, mEthernetNetworkAgent);
mCm.unregisterNetworkCallback(callback);
mCm.unregisterNetworkCallback(defaultCallback);
@@ -3516,7 +3509,7 @@
mWiFiNetworkAgent.connect(true);
defaultCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent);
callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
- callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent);
+ callback.expectLosing(mCellNetworkAgent);
callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
// File a request for cellular, then release it.
@@ -3525,7 +3518,7 @@
NetworkCallback noopCallback = new NetworkCallback();
mCm.requestNetwork(cellRequest, noopCallback);
mCm.unregisterNetworkCallback(noopCallback);
- callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent);
+ callback.expectLosing(mCellNetworkAgent);
// Let linger run its course.
callback.assertNoCallback();
@@ -3538,6 +3531,58 @@
mCm.unregisterNetworkCallback(callback);
}
+ /** Expects the specified notification and returns the notification ID. */
+ private int expectNotification(TestNetworkAgentWrapper agent, NotificationType type) {
+ verify(mNotificationManager, timeout(TIMEOUT_MS)).notify(
+ eq(NetworkNotificationManager.tagFor(agent.getNetwork().netId)),
+ eq(type.eventId), any());
+ return type.eventId;
+ }
+
+ private void expectNoNotification(@NonNull final TestNetworkAgentWrapper agent) {
+ verify(mNotificationManager, never()).notifyAsUser(anyString(), anyInt(), any(), any());
+ }
+
+ /**
+ * Expects the specified notification happens when the unvalidated prompt message arrives
+ *
+ * @return the notification ID.
+ **/
+ private int expectUnvalidationCheckWillNotify(TestNetworkAgentWrapper agent,
+ NotificationType type) {
+ mService.scheduleEvaluationTimeout(agent.getNetwork(), 0 /* delayMs */);
+ waitForIdle();
+ return expectNotification(agent, type);
+ }
+
+ /**
+ * Expects that the notification for the specified network is cleared.
+ *
+ * This generally happens when the network disconnects or when the newtwork validates. During
+ * normal usage the notification is also cleared by the system when the notification is tapped.
+ */
+ private void expectClearNotification(TestNetworkAgentWrapper agent, NotificationType type) {
+ verify(mNotificationManager, timeout(TIMEOUT_MS)).cancel(
+ eq(NetworkNotificationManager.tagFor(agent.getNetwork().netId)), eq(type.eventId));
+ }
+
+ /**
+ * Expects that no notification happens when the unvalidated prompt message arrives
+ *
+ * @return the notification ID.
+ **/
+ private void expectUnvalidationCheckWillNotNotify(TestNetworkAgentWrapper agent) {
+ mService.scheduleEvaluationTimeout(agent.getNetwork(), 0 /*delayMs */);
+ waitForIdle();
+ expectNoNotification(agent);
+ }
+
+ private void expectDisconnectAndClearNotifications(TestNetworkCallback callback,
+ TestNetworkAgentWrapper agent, NotificationType type) {
+ callback.expect(CallbackEntry.LOST, agent);
+ expectClearNotification(agent, type);
+ }
+
private NativeNetworkConfig nativeNetworkConfigPhysical(int netId, int permission) {
return new NativeNetworkConfig(netId, NativeNetworkType.PHYSICAL, permission,
/*secure=*/ false, VpnManager.TYPE_VPN_NONE, /*excludeLocalRoutes=*/ false);
@@ -3658,10 +3703,13 @@
mWiFiNetworkAgent.connect(false);
callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
- // Cell Remains the default.
+ // Cell remains the default.
assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
- // Lower wifi's score to below than cell, and check that it doesn't disconnect because
+ // Expect a high-priority NO_INTERNET notification.
+ expectUnvalidationCheckWillNotify(mWiFiNetworkAgent, NotificationType.NO_INTERNET);
+
+ // Lower WiFi's score to lower than cell, and check that it doesn't disconnect because
// it's explicitly selected.
mWiFiNetworkAgent.adjustScore(-40);
mWiFiNetworkAgent.adjustScore(40);
@@ -3670,35 +3718,44 @@
// If the user chooses yes on the "No Internet access, stay connected?" dialog, we switch to
// wifi even though it's unvalidated.
mCm.setAcceptUnvalidated(mWiFiNetworkAgent.getNetwork(), true, false);
- callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent);
+ callback.expectLosing(mCellNetworkAgent);
assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
// Disconnect wifi, and then reconnect, again with explicitlySelected=true.
mWiFiNetworkAgent.disconnect();
- callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
+ expectDisconnectAndClearNotifications(callback, mWiFiNetworkAgent,
+ NotificationType.NO_INTERNET);
+
mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
mWiFiNetworkAgent.explicitlySelected(true, false);
mWiFiNetworkAgent.connect(false);
callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
+ // Expect a high-priority NO_INTERNET notification.
+ expectUnvalidationCheckWillNotify(mWiFiNetworkAgent, NotificationType.NO_INTERNET);
+
// If the user chooses no on the "No Internet access, stay connected?" dialog, we ask the
// network to disconnect.
mCm.setAcceptUnvalidated(mWiFiNetworkAgent.getNetwork(), false, false);
- callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
+ expectDisconnectAndClearNotifications(callback, mWiFiNetworkAgent,
+ NotificationType.NO_INTERNET);
+ reset(mNotificationManager);
// Reconnect, again with explicitlySelected=true, but this time validate.
+ // Expect no notifications.
mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
mWiFiNetworkAgent.explicitlySelected(true, false);
mWiFiNetworkAgent.connect(true);
callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
- callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent);
+ callback.expectLosing(mCellNetworkAgent);
callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
+ expectUnvalidationCheckWillNotNotify(mWiFiNetworkAgent);
mEthernetNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_ETHERNET);
mEthernetNetworkAgent.connect(true);
callback.expectAvailableCallbacksUnvalidated(mEthernetNetworkAgent);
- callback.expectCallback(CallbackEntry.LOSING, mWiFiNetworkAgent);
+ callback.expectLosing(mWiFiNetworkAgent);
callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mEthernetNetworkAgent);
assertEquals(mEthernetNetworkAgent.getNetwork(), mCm.getActiveNetwork());
callback.assertNoCallback();
@@ -3707,32 +3764,92 @@
// (i.e., with explicitlySelected=true and acceptUnvalidated=true). Expect to switch to
// wifi immediately.
mWiFiNetworkAgent.disconnect();
- callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
+ callback.expect(CallbackEntry.LOST, mWiFiNetworkAgent);
mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
mWiFiNetworkAgent.explicitlySelected(true, true);
mWiFiNetworkAgent.connect(false);
callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
- callback.expectCallback(CallbackEntry.LOSING, mEthernetNetworkAgent);
+ callback.expectLosing(mEthernetNetworkAgent);
assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
mEthernetNetworkAgent.disconnect();
- callback.expectCallback(CallbackEntry.LOST, mEthernetNetworkAgent);
+ callback.expect(CallbackEntry.LOST, mEthernetNetworkAgent);
+ expectUnvalidationCheckWillNotNotify(mWiFiNetworkAgent);
// Disconnect and reconnect with explicitlySelected=false and acceptUnvalidated=true.
// Check that the network is not scored specially and that the device prefers cell data.
mWiFiNetworkAgent.disconnect();
- callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
+ callback.expect(CallbackEntry.LOST, mWiFiNetworkAgent);
+
mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
mWiFiNetworkAgent.explicitlySelected(false, true);
mWiFiNetworkAgent.connect(false);
callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
+ expectUnvalidationCheckWillNotNotify(mWiFiNetworkAgent);
// Clean up.
mWiFiNetworkAgent.disconnect();
mCellNetworkAgent.disconnect();
- callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
- callback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
+ callback.expect(CallbackEntry.LOST, mWiFiNetworkAgent);
+ callback.expect(CallbackEntry.LOST, mCellNetworkAgent);
+ }
+
+ private void doTestFirstEvaluation(
+ @NonNull final Consumer<TestNetworkAgentWrapper> doConnect,
+ final boolean waitForSecondCaps,
+ final boolean evaluatedByValidation)
+ throws Exception {
+ final NetworkRequest request = new NetworkRequest.Builder()
+ .addTransportType(TRANSPORT_WIFI)
+ .build();
+ TestNetworkCallback callback = new TestNetworkCallback();
+ mCm.registerNetworkCallback(request, callback);
+
+ mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
+ doConnect.accept(mWiFiNetworkAgent);
+ // Expect the available callbacks, but don't require specific values for their arguments
+ // since this method doesn't know how the network was connected.
+ callback.expect(CallbackEntry.AVAILABLE, mWiFiNetworkAgent);
+ callback.expect(CallbackEntry.NETWORK_CAPS_UPDATED, mWiFiNetworkAgent);
+ callback.expect(CallbackEntry.LINK_PROPERTIES_CHANGED, mWiFiNetworkAgent);
+ callback.expect(CallbackEntry.BLOCKED_STATUS, mWiFiNetworkAgent);
+ if (waitForSecondCaps) {
+ // This is necessary because of b/245893397, the same bug that happens where we use
+ // expectAvailableDoubleValidatedCallbacks.
+ callback.expect(CallbackEntry.NETWORK_CAPS_UPDATED, mWiFiNetworkAgent);
+ }
+ final NetworkAgentInfo nai =
+ mService.getNetworkAgentInfoForNetwork(mWiFiNetworkAgent.getNetwork());
+ final long firstEvaluation = nai.getFirstEvaluationConcludedTime();
+ if (evaluatedByValidation) {
+ assertNotEquals(0L, firstEvaluation);
+ } else {
+ assertEquals(0L, firstEvaluation);
+ }
+ mService.scheduleEvaluationTimeout(mWiFiNetworkAgent.getNetwork(), 0L /* timeout */);
+ waitForIdle();
+ if (evaluatedByValidation) {
+ assertEquals(firstEvaluation, nai.getFirstEvaluationConcludedTime());
+ } else {
+ assertNotEquals(0L, nai.getFirstEvaluationConcludedTime());
+ }
+ mWiFiNetworkAgent.disconnect();
+ callback.expect(CallbackEntry.LOST, mWiFiNetworkAgent);
+
+ mCm.unregisterNetworkCallback(callback);
+ }
+
+ @Test
+ public void testEverEvaluated() throws Exception {
+ doTestFirstEvaluation(naw -> naw.connect(true /* validated */),
+ true /* waitForSecondCaps */, true /* immediatelyEvaluated */);
+ doTestFirstEvaluation(naw -> naw.connectWithPartialConnectivity(),
+ true /* waitForSecondCaps */, true /* immediatelyEvaluated */);
+ doTestFirstEvaluation(naw -> naw.connectWithCaptivePortal(TEST_REDIRECT_URL, false),
+ true /* waitForSecondCaps */, true /* immediatelyEvaluated */);
+ doTestFirstEvaluation(naw -> naw.connect(false /* validated */),
+ false /* waitForSecondCaps */, false /* immediatelyEvaluated */);
}
private void tryNetworkFactoryRequests(int capability) throws Exception {
@@ -4093,6 +4210,12 @@
assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
callback.assertNoCallback();
+ // Expect a PARTIAL_CONNECTIVITY notification. The notification appears as soon as partial
+ // connectivity is detected, and is low priority because the network was not explicitly
+ // selected by the user. This happens if we reconnect to a network where the user previously
+ // accepted partial connectivity without checking "always".
+ expectNotification(mWiFiNetworkAgent, NotificationType.PARTIAL_CONNECTIVITY);
+
// With HTTPS probe disabled, NetworkMonitor should pass the network validation with http
// probe.
mWiFiNetworkAgent.setNetworkPartialValid(false /* isStrictMode */);
@@ -4105,18 +4228,22 @@
waitForIdle();
verify(mWiFiNetworkAgent.mNetworkMonitor, times(1)).setAcceptPartialConnectivity();
- // Need a trigger point to let NetworkMonitor tell ConnectivityService that network is
+ // Need a trigger point to let NetworkMonitor tell ConnectivityService that the network is
// validated.
mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), true);
- callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent);
+ callback.expectLosing(mCellNetworkAgent);
NetworkCapabilities nc = callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED,
mWiFiNetworkAgent);
assertTrue(nc.hasCapability(NET_CAPABILITY_PARTIAL_CONNECTIVITY));
assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
+ // Once the network validates, the notification disappears.
+ expectClearNotification(mWiFiNetworkAgent, NotificationType.PARTIAL_CONNECTIVITY);
+
// Disconnect and reconnect wifi with partial connectivity again.
mWiFiNetworkAgent.disconnect();
- callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
+ callback.expect(CallbackEntry.LOST, mWiFiNetworkAgent);
+
mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
mWiFiNetworkAgent.connectWithPartialConnectivity();
callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
@@ -4124,34 +4251,42 @@
// Mobile data should be the default network.
assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
+ waitForIdle();
+
+ // Expect a low-priority PARTIAL_CONNECTIVITY notification as soon as partial connectivity
+ // is detected.
+ expectNotification(mWiFiNetworkAgent, NotificationType.PARTIAL_CONNECTIVITY);
// If the user chooses no, disconnect wifi immediately.
- mCm.setAcceptPartialConnectivity(mWiFiNetworkAgent.getNetwork(), false/* accept */,
+ mCm.setAcceptPartialConnectivity(mWiFiNetworkAgent.getNetwork(), false /* accept */,
false /* always */);
- callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
+ callback.expect(CallbackEntry.LOST, mWiFiNetworkAgent);
+ expectClearNotification(mWiFiNetworkAgent, NotificationType.PARTIAL_CONNECTIVITY);
+ reset(mNotificationManager);
- // If user accepted partial connectivity before, and device reconnects to that network
- // again, but now the network has full connectivity. The network shouldn't contain
+ // If the user accepted partial connectivity before, and the device connects to that network
+ // again, but now the network has full connectivity, then the network shouldn't contain
// NET_CAPABILITY_PARTIAL_CONNECTIVITY.
mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
// acceptUnvalidated is also used as setting for accepting partial networks.
mWiFiNetworkAgent.explicitlySelected(true /* explicitlySelected */,
true /* acceptUnvalidated */);
mWiFiNetworkAgent.connect(true);
+ expectUnvalidationCheckWillNotNotify(mWiFiNetworkAgent);
// If user accepted partial connectivity network before,
// NetworkMonitor#setAcceptPartialConnectivity() will be called in
// ConnectivityService#updateNetworkInfo().
callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
verify(mWiFiNetworkAgent.mNetworkMonitor, times(1)).setAcceptPartialConnectivity();
- callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent);
+ callback.expectLosing(mCellNetworkAgent);
nc = callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
assertFalse(nc.hasCapability(NET_CAPABILITY_PARTIAL_CONNECTIVITY));
// Wifi should be the default network.
assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
mWiFiNetworkAgent.disconnect();
- callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
+ callback.expect(CallbackEntry.LOST, mWiFiNetworkAgent);
// The user accepted partial connectivity and selected "don't ask again". Now the user
// reconnects to the partial connectivity network. Switch to wifi as soon as partial
@@ -4165,17 +4300,19 @@
// ConnectivityService#updateNetworkInfo().
callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
verify(mWiFiNetworkAgent.mNetworkMonitor, times(1)).setAcceptPartialConnectivity();
- callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent);
+ callback.expectLosing(mCellNetworkAgent);
assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
callback.expectCapabilitiesWith(NET_CAPABILITY_PARTIAL_CONNECTIVITY, mWiFiNetworkAgent);
+ expectUnvalidationCheckWillNotNotify(mWiFiNetworkAgent);
+
mWiFiNetworkAgent.setNetworkValid(false /* isStrictMode */);
- // Need a trigger point to let NetworkMonitor tell ConnectivityService that network is
+ // Need a trigger point to let NetworkMonitor tell ConnectivityService that the network is
// validated.
mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), true);
callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
mWiFiNetworkAgent.disconnect();
- callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
+ callback.expect(CallbackEntry.LOST, mWiFiNetworkAgent);
// If the user accepted partial connectivity, and the device auto-reconnects to the partial
// connectivity network, it should contain both PARTIAL_CONNECTIVITY and VALIDATED.
@@ -4189,19 +4326,22 @@
mWiFiNetworkAgent.connectWithPartialValidConnectivity(false /* isStrictMode */);
callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
verify(mWiFiNetworkAgent.mNetworkMonitor, times(1)).setAcceptPartialConnectivity();
- callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent);
+ callback.expectLosing(mCellNetworkAgent);
callback.expectCapabilitiesWith(
NET_CAPABILITY_PARTIAL_CONNECTIVITY | NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
+ expectUnvalidationCheckWillNotNotify(mWiFiNetworkAgent);
mWiFiNetworkAgent.disconnect();
- callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
+ callback.expect(CallbackEntry.LOST, mWiFiNetworkAgent);
+ verifyNoMoreInteractions(mNotificationManager);
}
@Test
public void testCaptivePortalOnPartialConnectivity() throws Exception {
- final TestNetworkCallback captivePortalCallback = new TestNetworkCallback();
- final NetworkRequest captivePortalRequest = new NetworkRequest.Builder()
- .addCapability(NET_CAPABILITY_CAPTIVE_PORTAL).build();
- mCm.registerNetworkCallback(captivePortalRequest, captivePortalCallback);
+ final TestNetworkCallback wifiCallback = new TestNetworkCallback();
+ final NetworkRequest wifiRequest = new NetworkRequest.Builder()
+ .addTransportType(TRANSPORT_WIFI)
+ .build();
+ mCm.registerNetworkCallback(wifiRequest, wifiCallback);
final TestNetworkCallback validatedCallback = new TestNetworkCallback();
final NetworkRequest validatedRequest = new NetworkRequest.Builder()
@@ -4213,21 +4353,28 @@
mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
String redirectUrl = "http://android.com/path";
mWiFiNetworkAgent.connectWithCaptivePortal(redirectUrl, false /* isStrictMode */);
- captivePortalCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
+ wifiCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
assertEquals(mWiFiNetworkAgent.waitForRedirectUrl(), redirectUrl);
+ // This is necessary because of b/245893397, the same bug that happens where we use
+ // expectAvailableDoubleValidatedCallbacks.
+ // TODO : fix b/245893397 and remove this.
+ wifiCallback.expectCapabilitiesWith(NET_CAPABILITY_CAPTIVE_PORTAL, mWiFiNetworkAgent);
+
// Check that startCaptivePortalApp sends the expected command to NetworkMonitor.
mCm.startCaptivePortalApp(mWiFiNetworkAgent.getNetwork());
verify(mWiFiNetworkAgent.mNetworkMonitor, timeout(TIMEOUT_MS).times(1))
.launchCaptivePortalApp();
// Report that the captive portal is dismissed with partial connectivity, and check that
- // callbacks are fired.
+ // callbacks are fired with PARTIAL and without CAPTIVE_PORTAL.
mWiFiNetworkAgent.setNetworkPartial();
mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), true);
waitForIdle();
- captivePortalCallback.expectCapabilitiesWith(NET_CAPABILITY_PARTIAL_CONNECTIVITY,
- mWiFiNetworkAgent);
+ wifiCallback.expectCapabilitiesThat(
+ mWiFiNetworkAgent, nc ->
+ nc.hasCapability(NET_CAPABILITY_PARTIAL_CONNECTIVITY)
+ && !nc.hasCapability(NET_CAPABILITY_CAPTIVE_PORTAL));
// Report partial connectivity is accepted.
mWiFiNetworkAgent.setNetworkPartialValid(false /* isStrictMode */);
@@ -4235,13 +4382,12 @@
false /* always */);
waitForIdle();
mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), true);
- captivePortalCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
+ wifiCallback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
validatedCallback.expectAvailableCallbacksValidated(mWiFiNetworkAgent);
- NetworkCapabilities nc =
- validatedCallback.expectCapabilitiesWith(NET_CAPABILITY_PARTIAL_CONNECTIVITY,
+ validatedCallback.expectCapabilitiesWith(NET_CAPABILITY_PARTIAL_CONNECTIVITY,
mWiFiNetworkAgent);
- mCm.unregisterNetworkCallback(captivePortalCallback);
+ mCm.unregisterNetworkCallback(wifiCallback);
mCm.unregisterNetworkCallback(validatedCallback);
}
@@ -4268,7 +4414,7 @@
// Take down network.
// Expect onLost callback.
mWiFiNetworkAgent.disconnect();
- captivePortalCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
+ captivePortalCallback.expect(CallbackEntry.LOST, mWiFiNetworkAgent);
// Bring up a network with a captive portal.
// Expect onAvailable callback of listen for NET_CAPABILITY_CAPTIVE_PORTAL.
@@ -4282,7 +4428,7 @@
// Expect onLost callback because network no longer provides NET_CAPABILITY_CAPTIVE_PORTAL.
mWiFiNetworkAgent.setNetworkValid(false /* isStrictMode */);
mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), true);
- captivePortalCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
+ captivePortalCallback.expect(CallbackEntry.LOST, mWiFiNetworkAgent);
// Expect NET_CAPABILITY_VALIDATED onAvailable callback.
validatedCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent);
@@ -4291,7 +4437,7 @@
// Expect NET_CAPABILITY_VALIDATED onLost callback.
mWiFiNetworkAgent.setNetworkInvalid(false /* isStrictMode */);
mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), false);
- validatedCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
+ validatedCallback.expect(CallbackEntry.LOST, mWiFiNetworkAgent);
}
@Test
@@ -4323,7 +4469,12 @@
mWiFiNetworkAgent.setNetworkPortal("http://example.com", false /* isStrictMode */);
mCm.reportNetworkConnectivity(wifiNetwork, false);
captivePortalCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
- validatedCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
+ validatedCallback.expect(CallbackEntry.LOST, mWiFiNetworkAgent);
+ // This is necessary because of b/245893397, the same bug that happens where we use
+ // expectAvailableDoubleValidatedCallbacks.
+ // TODO : fix b/245893397 and remove this.
+ captivePortalCallback.expect(CallbackEntry.NETWORK_CAPS_UPDATED,
+ mWiFiNetworkAgent);
// Check that startCaptivePortalApp sends the expected command to NetworkMonitor.
mCm.startCaptivePortalApp(wifiNetwork);
@@ -4346,7 +4497,7 @@
mWiFiNetworkAgent.setNetworkValid(false /* isStrictMode */);
mWiFiNetworkAgent.mNetworkMonitor.forceReevaluation(Process.myUid());
validatedCallback.expectAvailableCallbacksValidated(mWiFiNetworkAgent);
- captivePortalCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
+ captivePortalCallback.expect(CallbackEntry.LOST, mWiFiNetworkAgent);
mCm.unregisterNetworkCallback(validatedCallback);
mCm.unregisterNetworkCallback(captivePortalCallback);
@@ -4610,6 +4761,81 @@
return new NetworkRequest.Builder().addTransportType(TRANSPORT_WIFI);
}
+ // A NetworkSpecifier subclass that matches all networks but must not be visible to apps.
+ static class ConfidentialMatchAllNetworkSpecifier extends NetworkSpecifier implements
+ Parcelable {
+ public static final Parcelable.Creator<ConfidentialMatchAllNetworkSpecifier> CREATOR =
+ new Parcelable.Creator<ConfidentialMatchAllNetworkSpecifier>() {
+ public ConfidentialMatchAllNetworkSpecifier createFromParcel(Parcel in) {
+ return new ConfidentialMatchAllNetworkSpecifier();
+ }
+
+ public ConfidentialMatchAllNetworkSpecifier[] newArray(int size) {
+ return new ConfidentialMatchAllNetworkSpecifier[size];
+ }
+ };
+ @Override
+ public boolean canBeSatisfiedBy(NetworkSpecifier other) {
+ return true;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {}
+
+ @Override
+ public NetworkSpecifier redact() {
+ return null;
+ }
+ }
+
+ // A network specifier that matches either another LocalNetworkSpecifier with the same
+ // string or a ConfidentialMatchAllNetworkSpecifier, and can be passed to apps as is.
+ static class LocalStringNetworkSpecifier extends NetworkSpecifier implements Parcelable {
+ public static final Parcelable.Creator<LocalStringNetworkSpecifier> CREATOR =
+ new Parcelable.Creator<LocalStringNetworkSpecifier>() {
+ public LocalStringNetworkSpecifier createFromParcel(Parcel in) {
+ return new LocalStringNetworkSpecifier(in);
+ }
+
+ public LocalStringNetworkSpecifier[] newArray(int size) {
+ return new LocalStringNetworkSpecifier[size];
+ }
+ };
+ private String mString;
+
+ LocalStringNetworkSpecifier(String string) {
+ mString = string;
+ }
+
+ LocalStringNetworkSpecifier(Parcel in) {
+ mString = in.readString();
+ }
+
+ @Override
+ public boolean canBeSatisfiedBy(NetworkSpecifier other) {
+ if (other instanceof LocalStringNetworkSpecifier) {
+ return TextUtils.equals(mString,
+ ((LocalStringNetworkSpecifier) other).mString);
+ }
+ if (other instanceof ConfidentialMatchAllNetworkSpecifier) return true;
+ return false;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeString(mString);
+ }
+ }
+
/**
* Verify request matching behavior with network specifiers.
*
@@ -4619,56 +4845,6 @@
*/
@Test
public void testNetworkSpecifier() throws Exception {
- // A NetworkSpecifier subclass that matches all networks but must not be visible to apps.
- class ConfidentialMatchAllNetworkSpecifier extends NetworkSpecifier implements
- Parcelable {
- @Override
- public boolean canBeSatisfiedBy(NetworkSpecifier other) {
- return true;
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {}
-
- @Override
- public NetworkSpecifier redact() {
- return null;
- }
- }
-
- // A network specifier that matches either another LocalNetworkSpecifier with the same
- // string or a ConfidentialMatchAllNetworkSpecifier, and can be passed to apps as is.
- class LocalStringNetworkSpecifier extends NetworkSpecifier implements Parcelable {
- private String mString;
-
- LocalStringNetworkSpecifier(String string) {
- mString = string;
- }
-
- @Override
- public boolean canBeSatisfiedBy(NetworkSpecifier other) {
- if (other instanceof LocalStringNetworkSpecifier) {
- return TextUtils.equals(mString,
- ((LocalStringNetworkSpecifier) other).mString);
- }
- if (other instanceof ConfidentialMatchAllNetworkSpecifier) return true;
- return false;
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
- @Override
- public void writeToParcel(Parcel dest, int flags) {}
- }
-
-
NetworkRequest rEmpty1 = newWifiRequestBuilder().build();
NetworkRequest rEmpty2 = newWifiRequestBuilder().setNetworkSpecifier((String) null).build();
NetworkRequest rEmpty3 = newWifiRequestBuilder().setNetworkSpecifier("").build();
@@ -4752,6 +4928,29 @@
return mContext.getAttributionTag();
}
+ static class NonParcelableSpecifier extends NetworkSpecifier {
+ @Override
+ public boolean canBeSatisfiedBy(NetworkSpecifier other) {
+ return false;
+ }
+ }
+ static class ParcelableSpecifier extends NonParcelableSpecifier implements Parcelable {
+ public static final Parcelable.Creator<NonParcelableSpecifier> CREATOR =
+ new Parcelable.Creator<NonParcelableSpecifier>() {
+ public NonParcelableSpecifier createFromParcel(Parcel in) {
+ return new NonParcelableSpecifier();
+ }
+
+ public NonParcelableSpecifier[] newArray(int size) {
+ return new NonParcelableSpecifier[size];
+ }
+ };
+ @Override public int describeContents() {
+ return 0;
+ }
+ @Override public void writeToParcel(Parcel p, int flags) {}
+ }
+
@Test
public void testInvalidNetworkSpecifier() {
assertThrows(IllegalArgumentException.class, () -> {
@@ -4769,17 +4968,6 @@
mContext.getPackageName(), getAttributionTag());
});
- class NonParcelableSpecifier extends NetworkSpecifier {
- @Override
- public boolean canBeSatisfiedBy(NetworkSpecifier other) {
- return false;
- }
- };
- class ParcelableSpecifier extends NonParcelableSpecifier implements Parcelable {
- @Override public int describeContents() { return 0; }
- @Override public void writeToParcel(Parcel p, int flags) {}
- }
-
final NetworkRequest.Builder builder =
new NetworkRequest.Builder().addTransportType(TRANSPORT_ETHERNET);
assertThrows(ClassCastException.class, () -> {
@@ -4887,7 +5075,7 @@
// Bring down cell. Expect no default network callback, since it wasn't the default.
mCellNetworkAgent.disconnect();
- cellNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
+ cellNetworkCallback.expect(CallbackEntry.LOST, mCellNetworkAgent);
defaultNetworkCallback.assertNoCallback();
systemDefaultCallback.assertNoCallback();
assertEquals(defaultNetworkCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
@@ -4906,14 +5094,14 @@
// followed by AVAILABLE cell.
mWiFiNetworkAgent.disconnect();
cellNetworkCallback.assertNoCallback();
- defaultNetworkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
+ defaultNetworkCallback.expect(CallbackEntry.LOST, mWiFiNetworkAgent);
defaultNetworkCallback.expectAvailableCallbacksValidated(mCellNetworkAgent);
- systemDefaultCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
+ systemDefaultCallback.expect(CallbackEntry.LOST, mWiFiNetworkAgent);
systemDefaultCallback.expectAvailableCallbacksValidated(mCellNetworkAgent);
mCellNetworkAgent.disconnect();
- cellNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
- defaultNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
- systemDefaultCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
+ cellNetworkCallback.expect(CallbackEntry.LOST, mCellNetworkAgent);
+ defaultNetworkCallback.expect(CallbackEntry.LOST, mCellNetworkAgent);
+ systemDefaultCallback.expect(CallbackEntry.LOST, mCellNetworkAgent);
waitForIdle();
assertEquals(null, mCm.getActiveNetwork());
@@ -4925,7 +5113,7 @@
assertEquals(null, systemDefaultCallback.getLastAvailableNetwork());
mMockVpn.disconnect();
- defaultNetworkCallback.expectCallback(CallbackEntry.LOST, mMockVpn);
+ defaultNetworkCallback.expect(CallbackEntry.LOST, mMockVpn);
systemDefaultCallback.assertNoCallback();
waitForIdle();
assertEquals(null, mCm.getActiveNetwork());
@@ -4954,7 +5142,7 @@
lp.setInterfaceName("foonet_data0");
mCellNetworkAgent.sendLinkProperties(lp);
// We should get onLinkPropertiesChanged().
- cellNetworkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED,
+ cellNetworkCallback.expect(CallbackEntry.LINK_PROPERTIES_CHANGED,
mCellNetworkAgent);
cellNetworkCallback.assertNoCallback();
@@ -4962,7 +5150,7 @@
mCellNetworkAgent.suspend();
cellNetworkCallback.expectCapabilitiesWithout(NET_CAPABILITY_NOT_SUSPENDED,
mCellNetworkAgent);
- cellNetworkCallback.expectCallback(CallbackEntry.SUSPENDED, mCellNetworkAgent);
+ cellNetworkCallback.expect(CallbackEntry.SUSPENDED, mCellNetworkAgent);
cellNetworkCallback.assertNoCallback();
assertEquals(NetworkInfo.State.SUSPENDED, mCm.getActiveNetworkInfo().getState());
@@ -4978,7 +5166,7 @@
mCellNetworkAgent.resume();
cellNetworkCallback.expectCapabilitiesWith(NET_CAPABILITY_NOT_SUSPENDED,
mCellNetworkAgent);
- cellNetworkCallback.expectCallback(CallbackEntry.RESUMED, mCellNetworkAgent);
+ cellNetworkCallback.expect(CallbackEntry.RESUMED, mCellNetworkAgent);
cellNetworkCallback.assertNoCallback();
assertEquals(NetworkInfo.State.CONNECTED, mCm.getActiveNetworkInfo().getState());
@@ -5049,9 +5237,9 @@
otherUidCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
includeOtherUidsCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
mWiFiNetworkAgent.disconnect();
- callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
- otherUidCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
- includeOtherUidsCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
+ callback.expect(CallbackEntry.LOST, mWiFiNetworkAgent);
+ otherUidCallback.expect(CallbackEntry.LOST, mWiFiNetworkAgent);
+ includeOtherUidsCallback.expect(CallbackEntry.LOST, mWiFiNetworkAgent);
// Only the includeOtherUidsCallback sees a VPN that does not apply to its UID.
final UidRange range = UidRange.createForUser(UserHandle.of(RESTRICTED_USER));
@@ -5062,7 +5250,7 @@
otherUidCallback.assertNoCallback();
mMockVpn.disconnect();
- includeOtherUidsCallback.expectCallback(CallbackEntry.LOST, mMockVpn);
+ includeOtherUidsCallback.expect(CallbackEntry.LOST, mMockVpn);
callback.assertNoCallback();
otherUidCallback.assertNoCallback();
}
@@ -5196,10 +5384,10 @@
// When wifi connects, cell lingers.
callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
- callback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent);
+ callback.expectLosing(mCellNetworkAgent);
callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
fgCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
- fgCallback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent);
+ fgCallback.expectLosing(mCellNetworkAgent);
fgCallback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
assertTrue(isForegroundNetwork(mCellNetworkAgent));
assertTrue(isForegroundNetwork(mWiFiNetworkAgent));
@@ -5207,7 +5395,7 @@
// When lingering is complete, cell is still there but is now in the background.
waitForIdle();
int timeoutMs = TEST_LINGER_DELAY_MS + TEST_LINGER_DELAY_MS / 4;
- fgCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent, timeoutMs);
+ fgCallback.expect(CallbackEntry.LOST, mCellNetworkAgent, timeoutMs);
// Expect a network capabilities update sans FOREGROUND.
callback.expectCapabilitiesWithout(NET_CAPABILITY_FOREGROUND, mCellNetworkAgent);
assertFalse(isForegroundNetwork(mCellNetworkAgent));
@@ -5230,7 +5418,7 @@
// Release the request. The network immediately goes into the background, since it was not
// lingering.
mCm.unregisterNetworkCallback(cellCallback);
- fgCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
+ fgCallback.expect(CallbackEntry.LOST, mCellNetworkAgent);
// Expect a network capabilities update sans FOREGROUND.
callback.expectCapabilitiesWithout(NET_CAPABILITY_FOREGROUND, mCellNetworkAgent);
assertFalse(isForegroundNetwork(mCellNetworkAgent));
@@ -5238,8 +5426,8 @@
// Disconnect wifi and check that cell is foreground again.
mWiFiNetworkAgent.disconnect();
- callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
- fgCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
+ callback.expect(CallbackEntry.LOST, mWiFiNetworkAgent);
+ fgCallback.expect(CallbackEntry.LOST, mWiFiNetworkAgent);
fgCallback.expectAvailableCallbacksValidated(mCellNetworkAgent);
assertTrue(isForegroundNetwork(mCellNetworkAgent));
@@ -5398,7 +5586,7 @@
// Cell disconnects. There is still the "mobile data always on" request outstanding,
// and the test factory should see it now that it isn't hopelessly outscored.
mCellNetworkAgent.disconnect();
- cellNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
+ cellNetworkCallback.expect(CallbackEntry.LOST, mCellNetworkAgent);
// Wait for the network to be removed from internal structures before
// calling synchronous getter
waitForIdle();
@@ -5421,7 +5609,7 @@
testFactory.assertRequestCountEquals(0);
assertFalse(testFactory.getMyStartRequested());
// ... and cell data to be torn down immediately since it is no longer nascent.
- cellNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
+ cellNetworkCallback.expect(CallbackEntry.LOST, mCellNetworkAgent);
waitForIdle();
assertLength(1, mCm.getAllNetworks());
testFactory.terminate();
@@ -5493,6 +5681,24 @@
}
@Test
+ public void testActivelyPreferBadWifiSetting() throws Exception {
+ doReturn(1).when(mResources).getInteger(R.integer.config_activelyPreferBadWifi);
+ mPolicyTracker.reevaluate();
+ waitForIdle();
+ assertTrue(mService.mNetworkRanker.getConfiguration().activelyPreferBadWifi());
+
+ doReturn(0).when(mResources).getInteger(R.integer.config_activelyPreferBadWifi);
+ mPolicyTracker.reevaluate();
+ waitForIdle();
+ if (SdkLevel.isAtLeastU()) {
+ // U+ ignore the setting and always actively prefers bad wifi
+ assertTrue(mService.mNetworkRanker.getConfiguration().activelyPreferBadWifi());
+ } else {
+ assertFalse(mService.mNetworkRanker.getConfiguration().activelyPreferBadWifi());
+ }
+ }
+
+ @Test
public void testOffersAvoidsBadWifi() throws Exception {
// Normal mode : the carrier doesn't restrict moving away from bad wifi.
// This has getAvoidBadWifi return true.
@@ -5580,7 +5786,7 @@
// Disconnect wifi and pretend the carrier restricts moving away from bad wifi.
mWiFiNetworkAgent.disconnect();
- wifiNetworkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
+ wifiNetworkCallback.expect(CallbackEntry.LOST, mWiFiNetworkAgent);
// This has getAvoidBadWifi return false. This test doesn't change the value of the
// associated setting.
doReturn(0).when(mResources).getInteger(R.integer.config_networkAvoidBadWifi);
@@ -5609,6 +5815,52 @@
wifiCallback.assertNoCallback();
}
+ public void doTestPreferBadWifi(final boolean preferBadWifi) throws Exception {
+ // Pretend we're on a carrier that restricts switching away from bad wifi, and
+ // depending on the parameter one that may indeed prefer bad wifi.
+ doReturn(0).when(mResources).getInteger(R.integer.config_networkAvoidBadWifi);
+ doReturn(preferBadWifi ? 1 : 0).when(mResources)
+ .getInteger(R.integer.config_activelyPreferBadWifi);
+ mPolicyTracker.reevaluate();
+
+ registerDefaultNetworkCallbacks();
+ final NetworkRequest wifiRequest = new NetworkRequest.Builder()
+ .clearCapabilities()
+ .addTransportType(TRANSPORT_WIFI)
+ .build();
+ final TestableNetworkCallback wifiCallback = new TestableNetworkCallback();
+ mCm.registerNetworkCallback(wifiRequest, wifiCallback);
+
+ // Bring up validated cell and unvalidated wifi.
+ mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR);
+ mCellNetworkAgent.connect(true);
+ mDefaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent);
+
+ mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
+ mWiFiNetworkAgent.connect(false);
+ wifiCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
+
+ if (preferBadWifi) {
+ expectUnvalidationCheckWillNotify(mWiFiNetworkAgent, NotificationType.LOST_INTERNET);
+ mDefaultNetworkCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
+ } else {
+ expectUnvalidationCheckWillNotNotify(mWiFiNetworkAgent);
+ mDefaultNetworkCallback.assertNoCallback();
+ }
+ }
+
+ @Test
+ public void testPreferBadWifi_doNotPrefer() throws Exception {
+ // Starting with U this mode is no longer supported and can't actually be tested
+ assumeFalse(SdkLevel.isAtLeastU());
+ doTestPreferBadWifi(false /* preferBadWifi */);
+ }
+
+ @Test
+ public void testPreferBadWifi_doPrefer() throws Exception {
+ doTestPreferBadWifi(true /* preferBadWifi */);
+ }
+
@Test
public void testAvoidBadWifi() throws Exception {
final ContentResolver cr = mServiceContext.getContentResolver();
@@ -5632,7 +5884,8 @@
TestNetworkCallback validatedWifiCallback = new TestNetworkCallback();
mCm.registerNetworkCallback(validatedWifiRequest, validatedWifiCallback);
- Settings.Global.putInt(cr, ConnectivitySettingsManager.NETWORK_AVOID_BAD_WIFI, 0);
+ // Prompt mode, so notifications can be tested
+ Settings.Global.putString(cr, ConnectivitySettingsManager.NETWORK_AVOID_BAD_WIFI, null);
mPolicyTracker.reevaluate();
// Bring up validated cell.
@@ -5653,7 +5906,8 @@
mWiFiNetworkAgent.setNetworkInvalid(false /* isStrictMode */);
mCm.reportNetworkConnectivity(wifiNetwork, false);
defaultCallback.expectCapabilitiesWithout(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
- validatedWifiCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
+ validatedWifiCallback.expect(CallbackEntry.LOST, mWiFiNetworkAgent);
+ expectNotification(mWiFiNetworkAgent, NotificationType.LOST_INTERNET);
// Because avoid bad wifi is off, we don't switch to cellular.
defaultCallback.assertNoCallback();
@@ -5669,14 +5923,20 @@
mPolicyTracker.reevaluate();
defaultCallback.expectAvailableCallbacksValidated(mCellNetworkAgent);
assertEquals(mCm.getActiveNetwork(), cellNetwork);
+ expectClearNotification(mWiFiNetworkAgent, NotificationType.LOST_INTERNET);
// Switch back to a restrictive carrier.
doReturn(0).when(mResources).getInteger(R.integer.config_networkAvoidBadWifi);
mPolicyTracker.reevaluate();
defaultCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
assertEquals(mCm.getActiveNetwork(), wifiNetwork);
+ // A notification was already shown for this very network.
+ expectNoNotification(mWiFiNetworkAgent);
// Simulate the user selecting "switch" on the dialog, and check that we switch to cell.
+ // In principle this is a little bit unrealistic because the switch to a less restrictive
+ // carrier above should have remove the notification but this doesn't matter for the
+ // purposes of this test.
mCm.setAvoidUnvalidated(wifiNetwork);
defaultCallback.expectAvailableCallbacksValidated(mCellNetworkAgent);
assertFalse(mCm.getNetworkCapabilities(wifiNetwork).hasCapability(
@@ -5697,7 +5957,8 @@
mWiFiNetworkAgent.setNetworkInvalid(false /* isStrictMode */);
mCm.reportNetworkConnectivity(wifiNetwork, false);
defaultCallback.expectCapabilitiesWithout(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
- validatedWifiCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
+ validatedWifiCallback.expect(CallbackEntry.LOST, mWiFiNetworkAgent);
+ expectNotification(mWiFiNetworkAgent, NotificationType.LOST_INTERNET);
// Simulate the user selecting "switch" and checking the don't ask again checkbox.
Settings.Global.putInt(cr, ConnectivitySettingsManager.NETWORK_AVOID_BAD_WIFI, 1);
@@ -5710,6 +5971,7 @@
assertTrue(mCm.getNetworkCapabilities(cellNetwork).hasCapability(
NET_CAPABILITY_VALIDATED));
assertEquals(mCm.getActiveNetwork(), cellNetwork);
+ expectClearNotification(mWiFiNetworkAgent, NotificationType.LOST_INTERNET);
// Simulate the user turning the cellular fallback setting off and then on.
// We switch to wifi and then to cell.
@@ -5717,6 +5979,9 @@
mPolicyTracker.reevaluate();
defaultCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
assertEquals(mCm.getActiveNetwork(), wifiNetwork);
+ // Notification is cleared again because CS doesn't particularly remember that it has
+ // cleared it before, and if it hasn't cleared it before then it should do so now.
+ expectClearNotification(mWiFiNetworkAgent, NotificationType.LOST_INTERNET);
Settings.Global.putInt(cr, ConnectivitySettingsManager.NETWORK_AVOID_BAD_WIFI, 1);
mPolicyTracker.reevaluate();
defaultCallback.expectAvailableCallbacksValidated(mCellNetworkAgent);
@@ -5724,9 +5989,11 @@
// If cell goes down, we switch to wifi.
mCellNetworkAgent.disconnect();
- defaultCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
+ defaultCallback.expect(CallbackEntry.LOST, mCellNetworkAgent);
defaultCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
validatedWifiCallback.assertNoCallback();
+ // Notification is cleared yet again because the device switched to wifi.
+ expectClearNotification(mWiFiNetworkAgent, NotificationType.LOST_INTERNET);
mCm.unregisterNetworkCallback(cellNetworkCallback);
mCm.unregisterNetworkCallback(validatedWifiCallback);
@@ -5788,7 +6055,7 @@
networkCallback.expectAvailableCallbacks(mWiFiNetworkAgent, false, false, false,
TEST_CALLBACK_TIMEOUT_MS);
mWiFiNetworkAgent.disconnect();
- networkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
+ networkCallback.expect(CallbackEntry.LOST, mWiFiNetworkAgent);
// Validate that UNAVAILABLE is not called
networkCallback.assertNoCallback();
@@ -5808,7 +6075,7 @@
mCm.requestNetwork(nr, networkCallback, timeoutMs);
// pass timeout and validate that UNAVAILABLE is called
- networkCallback.expectCallback(CallbackEntry.UNAVAILABLE, (Network) null);
+ networkCallback.expect(CallbackEntry.UNAVAILABLE);
// create a network satisfying request - validate that request not triggered
mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
@@ -5892,7 +6159,7 @@
// onUnavailable!
testFactory.triggerUnfulfillable(newRequest);
- networkCallback.expectCallback(CallbackEntry.UNAVAILABLE, (Network) null);
+ networkCallback.expect(CallbackEntry.UNAVAILABLE);
// Declaring a request unfulfillable releases it automatically.
testFactory.expectRequestRemove();
@@ -5974,20 +6241,20 @@
mCallbacks.add(new CallbackValue(CallbackType.ON_ERROR, error));
}
- private void expectCallback(CallbackValue callbackValue) throws InterruptedException {
+ private void expect(CallbackValue callbackValue) throws InterruptedException {
assertEquals(callbackValue, mCallbacks.poll(TIMEOUT_MS, TimeUnit.MILLISECONDS));
}
public void expectStarted() throws Exception {
- expectCallback(new CallbackValue(CallbackType.ON_STARTED));
+ expect(new CallbackValue(CallbackType.ON_STARTED));
}
public void expectStopped() throws Exception {
- expectCallback(new CallbackValue(CallbackType.ON_STOPPED));
+ expect(new CallbackValue(CallbackType.ON_STOPPED));
}
public void expectError(int error) throws Exception {
- expectCallback(new CallbackValue(CallbackType.ON_ERROR, error));
+ expect(new CallbackValue(CallbackType.ON_ERROR, error));
}
}
@@ -6047,21 +6314,21 @@
mCallbacks.add(new CallbackValue(CallbackType.ON_ERROR, error));
}
- private void expectCallback(CallbackValue callbackValue) throws InterruptedException {
+ private void expect(CallbackValue callbackValue) throws InterruptedException {
assertEquals(callbackValue, mCallbacks.poll(TIMEOUT_MS, TimeUnit.MILLISECONDS));
}
public void expectStarted() throws InterruptedException {
- expectCallback(new CallbackValue(CallbackType.ON_STARTED));
+ expect(new CallbackValue(CallbackType.ON_STARTED));
}
public void expectStopped() throws InterruptedException {
- expectCallback(new CallbackValue(CallbackType.ON_STOPPED));
+ expect(new CallbackValue(CallbackType.ON_STOPPED));
}
public void expectError(int error) throws InterruptedException {
- expectCallback(new CallbackValue(CallbackType.ON_ERROR, error));
+ expect(new CallbackValue(CallbackType.ON_ERROR, error));
}
public void assertNoCallback() {
@@ -6857,7 +7124,7 @@
// Disconnect wifi aware network.
wifiAware.disconnect();
- callback.expectCallbackThat(TIMEOUT_MS, (info) -> info instanceof CallbackEntry.Lost);
+ callback.expect(CallbackEntry.LOST, TIMEOUT_MS);
mCm.unregisterNetworkCallback(callback);
verifyNoNetwork();
@@ -6904,12 +7171,12 @@
// ConnectivityService.
TestNetworkAgentWrapper networkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, lp);
networkAgent.connect(true);
- networkCallback.expectCallback(CallbackEntry.AVAILABLE, networkAgent);
- networkCallback.expectCallback(CallbackEntry.NETWORK_CAPS_UPDATED, networkAgent);
+ networkCallback.expect(CallbackEntry.AVAILABLE, networkAgent);
+ networkCallback.expect(CallbackEntry.NETWORK_CAPS_UPDATED, networkAgent);
CallbackEntry.LinkPropertiesChanged cbi =
- networkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED,
+ networkCallback.expect(CallbackEntry.LINK_PROPERTIES_CHANGED,
networkAgent);
- networkCallback.expectCallback(CallbackEntry.BLOCKED_STATUS, networkAgent);
+ networkCallback.expect(CallbackEntry.BLOCKED_STATUS, networkAgent);
networkCallback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, networkAgent);
networkCallback.assertNoCallback();
checkDirectlyConnectedRoutes(cbi.getLp(), asList(myIpv4Address),
@@ -6924,7 +7191,7 @@
newLp.addLinkAddress(myIpv6Address1);
newLp.addLinkAddress(myIpv6Address2);
networkAgent.sendLinkProperties(newLp);
- cbi = networkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, networkAgent);
+ cbi = networkCallback.expect(CallbackEntry.LINK_PROPERTIES_CHANGED, networkAgent);
networkCallback.assertNoCallback();
checkDirectlyConnectedRoutes(cbi.getLp(),
asList(myIpv4Address, myIpv6Address1, myIpv6Address2),
@@ -6932,17 +7199,38 @@
mCm.unregisterNetworkCallback(networkCallback);
}
- private void expectNotifyNetworkStatus(List<Network> defaultNetworks, String defaultIface,
- Integer vpnUid, String vpnIfname, List<String> underlyingIfaces) throws Exception {
+ private void expectNotifyNetworkStatus(List<Network> allNetworks, List<Network> defaultNetworks,
+ String defaultIface, Integer vpnUid, String vpnIfname, List<String> underlyingIfaces)
+ throws Exception {
ArgumentCaptor<List<Network>> defaultNetworksCaptor = ArgumentCaptor.forClass(List.class);
ArgumentCaptor<List<UnderlyingNetworkInfo>> vpnInfosCaptor =
ArgumentCaptor.forClass(List.class);
+ ArgumentCaptor<List<NetworkStateSnapshot>> snapshotsCaptor =
+ ArgumentCaptor.forClass(List.class);
verify(mStatsManager, atLeastOnce()).notifyNetworkStatus(defaultNetworksCaptor.capture(),
- any(List.class), eq(defaultIface), vpnInfosCaptor.capture());
+ snapshotsCaptor.capture(), eq(defaultIface), vpnInfosCaptor.capture());
assertSameElements(defaultNetworks, defaultNetworksCaptor.getValue());
+ List<Network> snapshotNetworks = new ArrayList<Network>();
+ for (NetworkStateSnapshot ns : snapshotsCaptor.getValue()) {
+ snapshotNetworks.add(ns.getNetwork());
+ }
+ assertSameElements(allNetworks, snapshotNetworks);
+
+ if (defaultIface != null) {
+ assertNotNull(
+ "Did not find interface " + defaultIface + " in call to notifyNetworkStatus",
+ CollectionUtils.findFirst(snapshotsCaptor.getValue(), (ns) -> {
+ final LinkProperties lp = ns.getLinkProperties();
+ if (lp != null && TextUtils.equals(defaultIface, lp.getInterfaceName())) {
+ return true;
+ }
+ return false;
+ }));
+ }
+
List<UnderlyingNetworkInfo> infos = vpnInfosCaptor.getValue();
if (vpnUid != null) {
assertEquals("Should have exactly one VPN:", 1, infos.size());
@@ -6957,28 +7245,47 @@
}
private void expectNotifyNetworkStatus(
- List<Network> defaultNetworks, String defaultIface) throws Exception {
- expectNotifyNetworkStatus(defaultNetworks, defaultIface, null, null, List.of());
+ List<Network> allNetworks, List<Network> defaultNetworks, String defaultIface)
+ throws Exception {
+ expectNotifyNetworkStatus(allNetworks, defaultNetworks, defaultIface, null, null,
+ List.of());
+ }
+
+ private List<Network> onlyCell() {
+ return List.of(mCellNetworkAgent.getNetwork());
+ }
+
+ private List<Network> onlyWifi() {
+ return List.of(mWiFiNetworkAgent.getNetwork());
+ }
+
+ private List<Network> cellAndWifi() {
+ return List.of(mCellNetworkAgent.getNetwork(), mWiFiNetworkAgent.getNetwork());
}
@Test
public void testStatsIfacesChanged() throws Exception {
- mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR);
- mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
-
- final List<Network> onlyCell = List.of(mCellNetworkAgent.getNetwork());
- final List<Network> onlyWifi = List.of(mWiFiNetworkAgent.getNetwork());
-
LinkProperties cellLp = new LinkProperties();
cellLp.setInterfaceName(MOBILE_IFNAME);
LinkProperties wifiLp = new LinkProperties();
wifiLp.setInterfaceName(WIFI_IFNAME);
- // Simple connection should have updated ifaces
+ mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp);
+ mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
+
+ // Simple connection with initial LP should have updated ifaces.
mCellNetworkAgent.connect(false);
- mCellNetworkAgent.sendLinkProperties(cellLp);
waitForIdle();
- expectNotifyNetworkStatus(onlyCell, MOBILE_IFNAME);
+ expectNotifyNetworkStatus(onlyCell(), onlyCell(), MOBILE_IFNAME);
+ reset(mStatsManager);
+
+ // Verify change fields other than interfaces does not trigger a notification to NSS.
+ cellLp.addLinkAddress(new LinkAddress("192.0.2.4/24"));
+ cellLp.addRoute(new RouteInfo((IpPrefix) null, InetAddress.getByName("192.0.2.4"),
+ MOBILE_IFNAME));
+ cellLp.setDnsServers(List.of(InetAddress.getAllByName("8.8.8.8")));
+ mCellNetworkAgent.sendLinkProperties(cellLp);
+ verifyNoMoreInteractions(mStatsManager);
reset(mStatsManager);
// Default network switch should update ifaces.
@@ -6986,37 +7293,56 @@
mWiFiNetworkAgent.sendLinkProperties(wifiLp);
waitForIdle();
assertEquals(wifiLp, mService.getActiveLinkProperties());
- expectNotifyNetworkStatus(onlyWifi, WIFI_IFNAME);
+ expectNotifyNetworkStatus(cellAndWifi(), onlyWifi(), WIFI_IFNAME);
+ reset(mStatsManager);
+
+ // Disconnecting a network updates ifaces again. The soon-to-be disconnected interface is
+ // still in the list to ensure that stats are counted on that interface.
+ // TODO: this means that if anything else uses that interface for any other reason before
+ // notifyNetworkStatus is called again, traffic on that interface will be accounted to the
+ // disconnected network. This is likely a bug in ConnectivityService; it should probably
+ // call notifyNetworkStatus again without the disconnected network.
+ mCellNetworkAgent.disconnect();
+ waitForIdle();
+ expectNotifyNetworkStatus(cellAndWifi(), onlyWifi(), WIFI_IFNAME);
+ verifyNoMoreInteractions(mStatsManager);
+ reset(mStatsManager);
+
+ // Connecting a network updates ifaces even if the network doesn't become default.
+ mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp);
+ mCellNetworkAgent.connect(false);
+ waitForIdle();
+ expectNotifyNetworkStatus(cellAndWifi(), onlyWifi(), WIFI_IFNAME);
reset(mStatsManager);
// Disconnect should update ifaces.
mWiFiNetworkAgent.disconnect();
waitForIdle();
- expectNotifyNetworkStatus(onlyCell, MOBILE_IFNAME);
+ expectNotifyNetworkStatus(onlyCell(), onlyCell(), MOBILE_IFNAME);
reset(mStatsManager);
// Metered change should update ifaces
mCellNetworkAgent.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
waitForIdle();
- expectNotifyNetworkStatus(onlyCell, MOBILE_IFNAME);
+ expectNotifyNetworkStatus(onlyCell(), onlyCell(), MOBILE_IFNAME);
reset(mStatsManager);
mCellNetworkAgent.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
waitForIdle();
- expectNotifyNetworkStatus(onlyCell, MOBILE_IFNAME);
+ expectNotifyNetworkStatus(onlyCell(), onlyCell(), MOBILE_IFNAME);
reset(mStatsManager);
// Temp metered change shouldn't update ifaces
mCellNetworkAgent.addCapability(NET_CAPABILITY_TEMPORARILY_NOT_METERED);
waitForIdle();
- verify(mStatsManager, never()).notifyNetworkStatus(eq(onlyCell),
+ verify(mStatsManager, never()).notifyNetworkStatus(eq(onlyCell()),
any(List.class), eq(MOBILE_IFNAME), any(List.class));
reset(mStatsManager);
// Roaming change should update ifaces
mCellNetworkAgent.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING);
waitForIdle();
- expectNotifyNetworkStatus(onlyCell, MOBILE_IFNAME);
+ expectNotifyNetworkStatus(onlyCell(), onlyCell(), MOBILE_IFNAME);
reset(mStatsManager);
// Test VPNs.
@@ -7030,8 +7356,8 @@
List.of(mCellNetworkAgent.getNetwork(), mMockVpn.getNetwork());
// A VPN with default (null) underlying networks sets the underlying network's interfaces...
- expectNotifyNetworkStatus(cellAndVpn, MOBILE_IFNAME, Process.myUid(), VPN_IFNAME,
- List.of(MOBILE_IFNAME));
+ expectNotifyNetworkStatus(cellAndVpn, cellAndVpn, MOBILE_IFNAME, Process.myUid(),
+ VPN_IFNAME, List.of(MOBILE_IFNAME));
// ...and updates them as the default network switches.
mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
@@ -7040,15 +7366,16 @@
final Network[] onlyNull = new Network[]{null};
final List<Network> wifiAndVpn =
List.of(mWiFiNetworkAgent.getNetwork(), mMockVpn.getNetwork());
- final List<Network> cellAndWifi =
- List.of(mCellNetworkAgent.getNetwork(), mWiFiNetworkAgent.getNetwork());
+ final List<Network> cellWifiAndVpn =
+ List.of(mCellNetworkAgent.getNetwork(), mWiFiNetworkAgent.getNetwork(),
+ mMockVpn.getNetwork());
final Network[] cellNullAndWifi =
new Network[]{mCellNetworkAgent.getNetwork(), null, mWiFiNetworkAgent.getNetwork()};
waitForIdle();
assertEquals(wifiLp, mService.getActiveLinkProperties());
- expectNotifyNetworkStatus(wifiAndVpn, WIFI_IFNAME, Process.myUid(), VPN_IFNAME,
- List.of(WIFI_IFNAME));
+ expectNotifyNetworkStatus(cellWifiAndVpn, wifiAndVpn, WIFI_IFNAME, Process.myUid(),
+ VPN_IFNAME, List.of(WIFI_IFNAME));
reset(mStatsManager);
// A VPN that sets its underlying networks passes the underlying interfaces, and influences
@@ -7057,23 +7384,23 @@
// MOBILE_IFNAME even though the default network is wifi.
// TODO: fix this to pass in the actual default network interface. Whether or not the VPN
// applies to the system server UID should not have any bearing on network stats.
- mMockVpn.setUnderlyingNetworks(onlyCell.toArray(new Network[0]));
+ mMockVpn.setUnderlyingNetworks(onlyCell().toArray(new Network[0]));
waitForIdle();
- expectNotifyNetworkStatus(wifiAndVpn, MOBILE_IFNAME, Process.myUid(), VPN_IFNAME,
- List.of(MOBILE_IFNAME));
+ expectNotifyNetworkStatus(cellWifiAndVpn, wifiAndVpn, MOBILE_IFNAME, Process.myUid(),
+ VPN_IFNAME, List.of(MOBILE_IFNAME));
reset(mStatsManager);
- mMockVpn.setUnderlyingNetworks(cellAndWifi.toArray(new Network[0]));
+ mMockVpn.setUnderlyingNetworks(cellAndWifi().toArray(new Network[0]));
waitForIdle();
- expectNotifyNetworkStatus(wifiAndVpn, MOBILE_IFNAME, Process.myUid(), VPN_IFNAME,
- List.of(MOBILE_IFNAME, WIFI_IFNAME));
+ expectNotifyNetworkStatus(cellWifiAndVpn, wifiAndVpn, MOBILE_IFNAME, Process.myUid(),
+ VPN_IFNAME, List.of(MOBILE_IFNAME, WIFI_IFNAME));
reset(mStatsManager);
// Null underlying networks are ignored.
mMockVpn.setUnderlyingNetworks(cellNullAndWifi);
waitForIdle();
- expectNotifyNetworkStatus(wifiAndVpn, MOBILE_IFNAME, Process.myUid(), VPN_IFNAME,
- List.of(MOBILE_IFNAME, WIFI_IFNAME));
+ expectNotifyNetworkStatus(cellWifiAndVpn, wifiAndVpn, MOBILE_IFNAME, Process.myUid(),
+ VPN_IFNAME, List.of(MOBILE_IFNAME, WIFI_IFNAME));
reset(mStatsManager);
// If an underlying network disconnects, that interface should no longer be underlying.
@@ -7086,8 +7413,8 @@
mCellNetworkAgent.disconnect();
waitForIdle();
assertNull(mService.getLinkProperties(mCellNetworkAgent.getNetwork()));
- expectNotifyNetworkStatus(wifiAndVpn, MOBILE_IFNAME, Process.myUid(), VPN_IFNAME,
- List.of(MOBILE_IFNAME, WIFI_IFNAME));
+ expectNotifyNetworkStatus(cellWifiAndVpn, wifiAndVpn, MOBILE_IFNAME, Process.myUid(),
+ VPN_IFNAME, List.of(MOBILE_IFNAME, WIFI_IFNAME));
// Confirm that we never tell NetworkStatsService that cell is no longer the underlying
// network for the VPN...
@@ -7122,25 +7449,25 @@
// Also, for the same reason as above, the active interface passed in is null.
mMockVpn.setUnderlyingNetworks(new Network[0]);
waitForIdle();
- expectNotifyNetworkStatus(wifiAndVpn, null);
+ expectNotifyNetworkStatus(wifiAndVpn, wifiAndVpn, null);
reset(mStatsManager);
// Specifying only a null underlying network is the same as no networks.
mMockVpn.setUnderlyingNetworks(onlyNull);
waitForIdle();
- expectNotifyNetworkStatus(wifiAndVpn, null);
+ expectNotifyNetworkStatus(wifiAndVpn, wifiAndVpn, null);
reset(mStatsManager);
// Specifying networks that are all disconnected is the same as specifying no networks.
- mMockVpn.setUnderlyingNetworks(onlyCell.toArray(new Network[0]));
+ mMockVpn.setUnderlyingNetworks(onlyCell().toArray(new Network[0]));
waitForIdle();
- expectNotifyNetworkStatus(wifiAndVpn, null);
+ expectNotifyNetworkStatus(wifiAndVpn, wifiAndVpn, null);
reset(mStatsManager);
// Passing in null again means follow the default network again.
mMockVpn.setUnderlyingNetworks(null);
waitForIdle();
- expectNotifyNetworkStatus(wifiAndVpn, WIFI_IFNAME, Process.myUid(), VPN_IFNAME,
+ expectNotifyNetworkStatus(wifiAndVpn, wifiAndVpn, WIFI_IFNAME, Process.myUid(), VPN_IFNAME,
List.of(WIFI_IFNAME));
reset(mStatsManager);
}
@@ -7159,7 +7486,7 @@
NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, PERMISSION_GRANTED);
TestNetworkCallback callback = new TestNetworkCallback();
mCm.registerDefaultNetworkCallback(callback);
- callback.expectCallback(CallbackEntry.AVAILABLE, mCellNetworkAgent);
+ callback.expect(CallbackEntry.AVAILABLE, mCellNetworkAgent);
callback.expectCapabilitiesThat(
mCellNetworkAgent, nc -> Arrays.equals(adminUids, nc.getAdministratorUids()));
mCm.unregisterNetworkCallback(callback);
@@ -7170,7 +7497,7 @@
mServiceContext.setPermission(NETWORK_STACK, PERMISSION_DENIED);
callback = new TestNetworkCallback();
mCm.registerDefaultNetworkCallback(callback);
- callback.expectCallback(CallbackEntry.AVAILABLE, mCellNetworkAgent);
+ callback.expect(CallbackEntry.AVAILABLE, mCellNetworkAgent);
callback.expectCapabilitiesThat(
mCellNetworkAgent, nc -> nc.getAdministratorUids().length == 0);
}
@@ -7195,7 +7522,7 @@
mWiFiNetworkAgent.connect(true /* validated */);
final List<Network> none = List.of();
- expectNotifyNetworkStatus(none, null); // Wifi is not the default network
+ expectNotifyNetworkStatus(onlyWifi(), none, null); // Wifi is not the default network
// Create a virtual network based on the wifi network.
final int ownerUid = 10042;
@@ -7220,7 +7547,9 @@
assertFalse(nc.hasTransport(TRANSPORT_WIFI));
assertFalse(nc.hasCapability(NET_CAPABILITY_NOT_METERED));
final List<Network> onlyVcn = List.of(vcn.getNetwork());
- expectNotifyNetworkStatus(onlyVcn, vcnIface, ownerUid, vcnIface, List.of(WIFI_IFNAME));
+ final List<Network> vcnAndWifi = List.of(vcn.getNetwork(), mWiFiNetworkAgent.getNetwork());
+ expectNotifyNetworkStatus(vcnAndWifi, onlyVcn, vcnIface, ownerUid, vcnIface,
+ List.of(WIFI_IFNAME));
// Add NOT_METERED to the underlying network, check that it is not propagated.
mWiFiNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED);
@@ -7243,7 +7572,10 @@
nc = mCm.getNetworkCapabilities(vcn.getNetwork());
assertFalse(nc.hasTransport(TRANSPORT_WIFI));
assertFalse(nc.hasCapability(NET_CAPABILITY_NOT_ROAMING));
- expectNotifyNetworkStatus(onlyVcn, vcnIface, ownerUid, vcnIface, List.of(MOBILE_IFNAME));
+ final List<Network> vcnWifiAndCell = List.of(vcn.getNetwork(),
+ mWiFiNetworkAgent.getNetwork(), mCellNetworkAgent.getNetwork());
+ expectNotifyNetworkStatus(vcnWifiAndCell, onlyVcn, vcnIface, ownerUid, vcnIface,
+ List.of(MOBILE_IFNAME));
}
@Test
@@ -7424,12 +7756,12 @@
assertTrue(new ArraySet<>(resolvrParams.tlsServers).containsAll(
asList("2001:db8::1", "192.0.2.1")));
reset(mMockDnsResolver);
- cellNetworkCallback.expectCallback(CallbackEntry.AVAILABLE, mCellNetworkAgent);
- cellNetworkCallback.expectCallback(CallbackEntry.NETWORK_CAPS_UPDATED,
+ cellNetworkCallback.expect(CallbackEntry.AVAILABLE, mCellNetworkAgent);
+ cellNetworkCallback.expect(CallbackEntry.NETWORK_CAPS_UPDATED,
mCellNetworkAgent);
- CallbackEntry.LinkPropertiesChanged cbi = cellNetworkCallback.expectCallback(
+ CallbackEntry.LinkPropertiesChanged cbi = cellNetworkCallback.expect(
CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent);
- cellNetworkCallback.expectCallback(CallbackEntry.BLOCKED_STATUS, mCellNetworkAgent);
+ cellNetworkCallback.expect(CallbackEntry.BLOCKED_STATUS, mCellNetworkAgent);
cellNetworkCallback.assertNoCallback();
assertFalse(cbi.getLp().isPrivateDnsActive());
assertNull(cbi.getLp().getPrivateDnsServerName());
@@ -7460,7 +7792,7 @@
setPrivateDnsSettings(PRIVATE_DNS_MODE_PROVIDER_HOSTNAME, "strict.example.com");
// Can't test dns configuration for strict mode without properly mocking
// out the DNS lookups, but can test that LinkProperties is updated.
- cbi = cellNetworkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED,
+ cbi = cellNetworkCallback.expect(CallbackEntry.LINK_PROPERTIES_CHANGED,
mCellNetworkAgent);
cellNetworkCallback.assertNoCallback();
assertTrue(cbi.getLp().isPrivateDnsActive());
@@ -7493,12 +7825,12 @@
mCellNetworkAgent.sendLinkProperties(lp);
mCellNetworkAgent.connect(false);
waitForIdle();
- cellNetworkCallback.expectCallback(CallbackEntry.AVAILABLE, mCellNetworkAgent);
- cellNetworkCallback.expectCallback(CallbackEntry.NETWORK_CAPS_UPDATED,
+ cellNetworkCallback.expect(CallbackEntry.AVAILABLE, mCellNetworkAgent);
+ cellNetworkCallback.expect(CallbackEntry.NETWORK_CAPS_UPDATED,
mCellNetworkAgent);
- CallbackEntry.LinkPropertiesChanged cbi = cellNetworkCallback.expectCallback(
+ CallbackEntry.LinkPropertiesChanged cbi = cellNetworkCallback.expect(
CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent);
- cellNetworkCallback.expectCallback(CallbackEntry.BLOCKED_STATUS, mCellNetworkAgent);
+ cellNetworkCallback.expect(CallbackEntry.BLOCKED_STATUS, mCellNetworkAgent);
cellNetworkCallback.assertNoCallback();
assertFalse(cbi.getLp().isPrivateDnsActive());
assertNull(cbi.getLp().getPrivateDnsServerName());
@@ -7516,7 +7848,7 @@
LinkProperties lp2 = new LinkProperties(lp);
lp2.addDnsServer(InetAddress.getByName("145.100.185.16"));
mCellNetworkAgent.sendLinkProperties(lp2);
- cbi = cellNetworkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED,
+ cbi = cellNetworkCallback.expect(CallbackEntry.LINK_PROPERTIES_CHANGED,
mCellNetworkAgent);
cellNetworkCallback.assertNoCallback();
assertFalse(cbi.getLp().isPrivateDnsActive());
@@ -7543,7 +7875,7 @@
mService.mResolverUnsolEventCallback.onPrivateDnsValidationEvent(
makePrivateDnsValidationEvent(mCellNetworkAgent.getNetwork().netId,
"145.100.185.16", "", VALIDATION_RESULT_SUCCESS));
- cbi = cellNetworkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED,
+ cbi = cellNetworkCallback.expect(CallbackEntry.LINK_PROPERTIES_CHANGED,
mCellNetworkAgent);
cellNetworkCallback.assertNoCallback();
assertTrue(cbi.getLp().isPrivateDnsActive());
@@ -7555,7 +7887,7 @@
LinkProperties lp3 = new LinkProperties(lp2);
lp3.setMtu(1300);
mCellNetworkAgent.sendLinkProperties(lp3);
- cbi = cellNetworkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED,
+ cbi = cellNetworkCallback.expect(CallbackEntry.LINK_PROPERTIES_CHANGED,
mCellNetworkAgent);
cellNetworkCallback.assertNoCallback();
assertTrue(cbi.getLp().isPrivateDnsActive());
@@ -7568,7 +7900,7 @@
LinkProperties lp4 = new LinkProperties(lp3);
lp4.removeDnsServer(InetAddress.getByName("145.100.185.16"));
mCellNetworkAgent.sendLinkProperties(lp4);
- cbi = cellNetworkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED,
+ cbi = cellNetworkCallback.expect(CallbackEntry.LINK_PROPERTIES_CHANGED,
mCellNetworkAgent);
cellNetworkCallback.assertNoCallback();
assertFalse(cbi.getLp().isPrivateDnsActive());
@@ -7760,7 +8092,7 @@
mMockVpn.setUnderlyingNetworks(new Network[]{wifiNetwork});
// onCapabilitiesChanged() should be called because
// NetworkCapabilities#mUnderlyingNetworks is updated.
- CallbackEntry ce = callback.expectCallback(CallbackEntry.NETWORK_CAPS_UPDATED,
+ CallbackEntry ce = callback.expect(CallbackEntry.NETWORK_CAPS_UPDATED,
mMockVpn);
final NetworkCapabilities vpnNc1 = ((CallbackEntry.CapabilitiesChanged) ce).getCaps();
// Since the wifi network hasn't brought up,
@@ -7797,7 +8129,7 @@
// 2. When a network connects, updateNetworkInfo propagates underlying network
// capabilities before rematching networks.
// Given that this scenario can't really happen, this is probably fine for now.
- ce = callback.expectCallback(CallbackEntry.NETWORK_CAPS_UPDATED, mMockVpn);
+ ce = callback.expect(CallbackEntry.NETWORK_CAPS_UPDATED, mMockVpn);
final NetworkCapabilities vpnNc2 = ((CallbackEntry.CapabilitiesChanged) ce).getCaps();
// The wifi network is brought up, NetworkCapabilities#mUnderlyingNetworks is updated to
// it.
@@ -7811,7 +8143,7 @@
// Disconnect the network, and expect to see the VPN capabilities change accordingly.
mWiFiNetworkAgent.disconnect();
- callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
+ callback.expect(CallbackEntry.LOST, mWiFiNetworkAgent);
callback.expectCapabilitiesThat(mMockVpn, (nc) ->
nc.getTransportTypes().length == 1 && nc.hasTransport(TRANSPORT_VPN));
@@ -7857,7 +8189,7 @@
callback.expectCapabilitiesThat(mMockVpn,
nc -> !nc.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)
&& nc.hasTransport(TRANSPORT_CELLULAR));
- callback.expectCallback(CallbackEntry.SUSPENDED, mMockVpn);
+ callback.expect(CallbackEntry.SUSPENDED, mMockVpn);
callback.assertNoCallback();
assertFalse(mCm.getNetworkCapabilities(mMockVpn.getNetwork())
@@ -7875,7 +8207,7 @@
callback.expectCapabilitiesThat(mMockVpn,
nc -> nc.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)
&& nc.hasTransport(TRANSPORT_WIFI));
- callback.expectCallback(CallbackEntry.RESUMED, mMockVpn);
+ callback.expect(CallbackEntry.RESUMED, mMockVpn);
callback.assertNoCallback();
assertTrue(mCm.getNetworkCapabilities(mMockVpn.getNetwork())
@@ -7912,7 +8244,7 @@
callback.expectCapabilitiesThat(mMockVpn,
nc -> !nc.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)
&& nc.hasTransport(TRANSPORT_CELLULAR));
- callback.expectCallback(CallbackEntry.SUSPENDED, mMockVpn);
+ callback.expect(CallbackEntry.SUSPENDED, mMockVpn);
callback.assertNoCallback();
assertFalse(mCm.getNetworkCapabilities(mMockVpn.getNetwork())
@@ -7928,7 +8260,7 @@
callback.expectCapabilitiesThat(mMockVpn,
nc -> nc.hasCapability(NET_CAPABILITY_NOT_SUSPENDED)
&& nc.hasTransport(TRANSPORT_CELLULAR));
- callback.expectCallback(CallbackEntry.RESUMED, mMockVpn);
+ callback.expect(CallbackEntry.RESUMED, mMockVpn);
callback.assertNoCallback();
assertTrue(mCm.getNetworkCapabilities(mMockVpn.getNetwork())
@@ -7988,6 +8320,7 @@
// VPN networks do not satisfy the default request and are automatically validated
// by NetworkMonitor
assertFalse(NetworkMonitorUtils.isValidationRequired(
+ false /* isDunValidationRequired */,
NetworkAgentConfigShimImpl.newInstance(mMockVpn.getNetworkAgentConfig())
.isVpnValidationRequired(),
mMockVpn.getAgent().getNetworkCapabilities()));
@@ -8008,10 +8341,10 @@
ranges.clear();
mMockVpn.setUids(ranges);
- genericNetworkCallback.expectCallback(CallbackEntry.LOST, mMockVpn);
+ genericNetworkCallback.expect(CallbackEntry.LOST, mMockVpn);
genericNotVpnNetworkCallback.assertNoCallback();
wifiNetworkCallback.assertNoCallback();
- vpnNetworkCallback.expectCallback(CallbackEntry.LOST, mMockVpn);
+ vpnNetworkCallback.expect(CallbackEntry.LOST, mMockVpn);
// TODO : The default network callback should actually get a LOST call here (also see the
// comment below for AVAILABLE). This is because ConnectivityService does not look at UID
@@ -8019,7 +8352,7 @@
// can't currently update their UIDs without disconnecting, so this does not matter too
// much, but that is the reason the test here has to check for an update to the
// capabilities instead of the expected LOST then AVAILABLE.
- defaultCallback.expectCallback(CallbackEntry.NETWORK_CAPS_UPDATED, mMockVpn);
+ defaultCallback.expect(CallbackEntry.NETWORK_CAPS_UPDATED, mMockVpn);
systemDefaultCallback.assertNoCallback();
ranges.add(new UidRange(uid, uid));
@@ -8031,25 +8364,25 @@
vpnNetworkCallback.expectAvailableCallbacksValidated(mMockVpn);
// TODO : Here like above, AVAILABLE would be correct, but because this can't actually
// happen outside of the test, ConnectivityService does not rematch callbacks.
- defaultCallback.expectCallback(CallbackEntry.NETWORK_CAPS_UPDATED, mMockVpn);
+ defaultCallback.expect(CallbackEntry.NETWORK_CAPS_UPDATED, mMockVpn);
systemDefaultCallback.assertNoCallback();
mWiFiNetworkAgent.disconnect();
- genericNetworkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
- genericNotVpnNetworkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
- wifiNetworkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
+ genericNetworkCallback.expect(CallbackEntry.LOST, mWiFiNetworkAgent);
+ genericNotVpnNetworkCallback.expect(CallbackEntry.LOST, mWiFiNetworkAgent);
+ wifiNetworkCallback.expect(CallbackEntry.LOST, mWiFiNetworkAgent);
vpnNetworkCallback.assertNoCallback();
defaultCallback.assertNoCallback();
- systemDefaultCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
+ systemDefaultCallback.expect(CallbackEntry.LOST, mWiFiNetworkAgent);
mMockVpn.disconnect();
- genericNetworkCallback.expectCallback(CallbackEntry.LOST, mMockVpn);
+ genericNetworkCallback.expect(CallbackEntry.LOST, mMockVpn);
genericNotVpnNetworkCallback.assertNoCallback();
wifiNetworkCallback.assertNoCallback();
- vpnNetworkCallback.expectCallback(CallbackEntry.LOST, mMockVpn);
- defaultCallback.expectCallback(CallbackEntry.LOST, mMockVpn);
+ vpnNetworkCallback.expect(CallbackEntry.LOST, mMockVpn);
+ defaultCallback.expect(CallbackEntry.LOST, mMockVpn);
systemDefaultCallback.assertNoCallback();
assertEquals(null, mCm.getActiveNetwork());
@@ -8107,7 +8440,7 @@
assertEquals(defaultCallback.getLastAvailableNetwork(), mCm.getActiveNetwork());
mMockVpn.disconnect();
- defaultCallback.expectCallback(CallbackEntry.LOST, mMockVpn);
+ defaultCallback.expect(CallbackEntry.LOST, mMockVpn);
defaultCallback.expectAvailableCallbacksValidated(mWiFiNetworkAgent);
mCm.unregisterNetworkCallback(defaultCallback);
@@ -8140,6 +8473,7 @@
assertTrue(nc.hasCapability(NET_CAPABILITY_INTERNET));
assertFalse(NetworkMonitorUtils.isValidationRequired(
+ false /* isDunValidationRequired */,
NetworkAgentConfigShimImpl.newInstance(mMockVpn.getNetworkAgentConfig())
.isVpnValidationRequired(),
mMockVpn.getAgent().getNetworkCapabilities()));
@@ -8155,7 +8489,7 @@
callback.assertNoCallback();
mMockVpn.disconnect();
- callback.expectCallback(CallbackEntry.LOST, mMockVpn);
+ callback.expect(CallbackEntry.LOST, mMockVpn);
callback.expectAvailableCallbacksValidated(mEthernetNetworkAgent);
}
@@ -8289,7 +8623,7 @@
&& caps.hasTransport(TRANSPORT_CELLULAR) && !caps.hasTransport(TRANSPORT_WIFI)
&& !caps.hasCapability(NET_CAPABILITY_NOT_METERED)
&& !caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED));
- vpnNetworkCallback.expectCallback(CallbackEntry.SUSPENDED, mMockVpn);
+ vpnNetworkCallback.expect(CallbackEntry.SUSPENDED, mMockVpn);
// Add NOT_SUSPENDED again and observe VPN is no longer suspended.
mCellNetworkAgent.addCapability(NET_CAPABILITY_NOT_SUSPENDED);
@@ -8298,7 +8632,7 @@
&& caps.hasTransport(TRANSPORT_CELLULAR) && !caps.hasTransport(TRANSPORT_WIFI)
&& !caps.hasCapability(NET_CAPABILITY_NOT_METERED)
&& caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED));
- vpnNetworkCallback.expectCallback(CallbackEntry.RESUMED, mMockVpn);
+ vpnNetworkCallback.expect(CallbackEntry.RESUMED, mMockVpn);
// Use Wifi but not cell. Note the VPN is now unmetered and not suspended.
mMockVpn.setUnderlyingNetworks(
@@ -8334,7 +8668,7 @@
&& caps.hasTransport(TRANSPORT_CELLULAR)
&& !caps.hasCapability(NET_CAPABILITY_NOT_METERED)
&& !caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED));
- vpnNetworkCallback.expectCallback(CallbackEntry.SUSPENDED, mMockVpn);
+ vpnNetworkCallback.expect(CallbackEntry.SUSPENDED, mMockVpn);
assertDefaultNetworkCapabilities(userId, mCellNetworkAgent, mWiFiNetworkAgent);
// Use both again.
@@ -8346,7 +8680,7 @@
&& caps.hasTransport(TRANSPORT_CELLULAR) && caps.hasTransport(TRANSPORT_WIFI)
&& !caps.hasCapability(NET_CAPABILITY_NOT_METERED)
&& caps.hasCapability(NET_CAPABILITY_NOT_SUSPENDED));
- vpnNetworkCallback.expectCallback(CallbackEntry.RESUMED, mMockVpn);
+ vpnNetworkCallback.expect(CallbackEntry.RESUMED, mMockVpn);
assertDefaultNetworkCapabilities(userId, mCellNetworkAgent, mWiFiNetworkAgent);
// Disconnect cell. Receive update without even removing the dead network from the
@@ -8487,7 +8821,7 @@
// Change the VPN's capabilities somehow (specifically, disconnect wifi).
mWiFiNetworkAgent.disconnect();
- callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
+ callback.expect(CallbackEntry.LOST, mWiFiNetworkAgent);
callback.expectCapabilitiesThat(mMockVpn, (caps)
-> caps.getUids().size() == 2
&& caps.getUids().contains(singleUidRange)
@@ -8775,7 +9109,7 @@
final DetailedBlockedStatusCallback detailedCallback = new DetailedBlockedStatusCallback();
mCm.registerNetworkCallback(cellRequest, detailedCallback);
- mockUidNetworkingBlocked();
+ mockUidNetworkingBlocked(Process.myUid());
mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR);
mCellNetworkAgent.connect(true);
@@ -8890,7 +9224,7 @@
public void testNetworkBlockedStatusBeforeAndAfterConnect() throws Exception {
final TestNetworkCallback defaultCallback = new TestNetworkCallback();
mCm.registerDefaultNetworkCallback(defaultCallback);
- mockUidNetworkingBlocked();
+ mockUidNetworkingBlocked(Process.myUid());
// No Networkcallbacks invoked before any network is active.
setBlockedReasonChanged(BLOCKED_REASON_BATTERY_SAVER);
@@ -8911,7 +9245,7 @@
// Switch to METERED network. Restrict the use of the network.
mWiFiNetworkAgent.disconnect();
- defaultCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
+ defaultCallback.expect(CallbackEntry.LOST, mWiFiNetworkAgent);
defaultCallback.expectAvailableCallbacksValidatedAndBlocked(mCellNetworkAgent);
// Network becomes NOT_METERED.
@@ -8925,7 +9259,7 @@
defaultCallback.assertNoCallback();
mCellNetworkAgent.disconnect();
- defaultCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
+ defaultCallback.expect(CallbackEntry.LOST, mCellNetworkAgent);
defaultCallback.assertNoCallback();
mCm.unregisterNetworkCallback(defaultCallback);
@@ -8989,10 +9323,9 @@
// Expect exactly one blocked callback for each agent.
for (int i = 0; i < agents.length; i++) {
- CallbackEntry e = callback.expectCallbackThat(TIMEOUT_MS, (c) ->
- c instanceof CallbackEntry.BlockedStatus
- && ((CallbackEntry.BlockedStatus) c).getBlocked() == blocked);
- Network network = e.getNetwork();
+ final CallbackEntry e = callback.expect(CallbackEntry.BLOCKED_STATUS, TIMEOUT_MS,
+ c -> c.getBlocked() == blocked);
+ final Network network = e.getNetwork();
assertTrue("Received unexpected blocked callback for network " + network,
expectedNetworks.remove(network));
}
@@ -9197,7 +9530,7 @@
assertNetworkInfo(TYPE_WIFI, DetailedState.CONNECTED);
mMockVpn.disconnect();
- defaultCallback.expectCallback(CallbackEntry.LOST, mMockVpn);
+ defaultCallback.expect(CallbackEntry.LOST, mMockVpn);
defaultCallback.expectAvailableCallbacksUnvalidatedAndBlocked(mWiFiNetworkAgent);
vpnUidCallback.assertNoCallback();
vpnUidDefaultCallback.assertNoCallback();
@@ -9349,9 +9682,9 @@
cellLp.addLinkAddress(new LinkAddress("192.0.2.2/25"));
cellLp.addRoute(new RouteInfo(new IpPrefix("0.0.0.0/0"), null, "rmnet0"));
mCellNetworkAgent.sendLinkProperties(cellLp);
- callback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent);
- defaultCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent);
- systemDefaultCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED,
+ callback.expect(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent);
+ defaultCallback.expect(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent);
+ systemDefaultCallback.expect(CallbackEntry.LINK_PROPERTIES_CHANGED,
mCellNetworkAgent);
waitForIdle();
assertNull(mMockVpn.getAgent());
@@ -9360,9 +9693,9 @@
// Expect lockdown VPN to come up.
ExpectedBroadcast b1 = expectConnectivityAction(TYPE_MOBILE, DetailedState.DISCONNECTED);
mCellNetworkAgent.disconnect();
- callback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
- defaultCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
- systemDefaultCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
+ callback.expect(CallbackEntry.LOST, mCellNetworkAgent);
+ defaultCallback.expect(CallbackEntry.LOST, mCellNetworkAgent);
+ systemDefaultCallback.expect(CallbackEntry.LOST, mCellNetworkAgent);
b1.expectBroadcast();
// When lockdown VPN is active, the NetworkInfo state in CONNECTIVITY_ACTION is overwritten
@@ -9440,8 +9773,8 @@
// fact that a VPN is connected should only result in the VPN itself being unblocked, not
// any other network. Bug in isUidBlockedByVpn?
callback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
- callback.expectCallback(CallbackEntry.LOST, mMockVpn);
- defaultCallback.expectCallback(CallbackEntry.LOST, mMockVpn);
+ callback.expect(CallbackEntry.LOST, mMockVpn);
+ defaultCallback.expect(CallbackEntry.LOST, mMockVpn);
defaultCallback.expectAvailableCallbacksUnvalidatedAndBlocked(mWiFiNetworkAgent);
systemDefaultCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
@@ -9474,7 +9807,7 @@
// Disconnect cell. Nothing much happens since it's not the default network.
mCellNetworkAgent.disconnect();
- callback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
+ callback.expect(CallbackEntry.LOST, mCellNetworkAgent);
defaultCallback.assertNoCallback();
systemDefaultCallback.assertNoCallback();
@@ -9487,12 +9820,12 @@
b1 = expectConnectivityAction(TYPE_WIFI, DetailedState.DISCONNECTED);
b2 = expectConnectivityAction(TYPE_VPN, DetailedState.DISCONNECTED);
mWiFiNetworkAgent.disconnect();
- callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
- systemDefaultCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
+ callback.expect(CallbackEntry.LOST, mWiFiNetworkAgent);
+ systemDefaultCallback.expect(CallbackEntry.LOST, mWiFiNetworkAgent);
b1.expectBroadcast();
callback.expectCapabilitiesThat(mMockVpn, nc -> !nc.hasTransport(TRANSPORT_WIFI));
mMockVpn.expectStopVpnRunnerPrivileged();
- callback.expectCallback(CallbackEntry.LOST, mMockVpn);
+ callback.expect(CallbackEntry.LOST, mMockVpn);
b2.expectBroadcast();
VMSHandlerThread.quitSafely();
@@ -9664,7 +9997,7 @@
reset(mMockNetd);
mCellNetworkAgent.removeCapability(testCap);
- callbackWithCap.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
+ callbackWithCap.expect(CallbackEntry.LOST, mCellNetworkAgent);
callbackWithoutCap.assertNoCallback();
verify(mMockNetd).networkClearDefault();
@@ -9854,7 +10187,7 @@
// the NAT64 prefix was removed because one was never discovered.
cellLp.addLinkAddress(myIpv4);
mCellNetworkAgent.sendLinkProperties(cellLp);
- networkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent);
+ networkCallback.expect(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent);
assertRoutesAdded(cellNetId, ipv4Subnet);
verify(mMockDnsResolver, times(1)).stopPrefix64Discovery(cellNetId);
verify(mMockDnsResolver, atLeastOnce()).setResolverConfiguration(any());
@@ -9877,7 +10210,7 @@
// Remove IPv4 address. Expect prefix discovery to be started again.
cellLp.removeLinkAddress(myIpv4);
mCellNetworkAgent.sendLinkProperties(cellLp);
- networkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent);
+ networkCallback.expect(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent);
verify(mMockDnsResolver, times(1)).startPrefix64Discovery(cellNetId);
assertRoutesRemoved(cellNetId, ipv4Subnet);
@@ -9886,7 +10219,7 @@
assertNull(mCm.getLinkProperties(mCellNetworkAgent.getNetwork()).getNat64Prefix());
mService.mResolverUnsolEventCallback.onNat64PrefixEvent(
makeNat64PrefixEvent(cellNetId, PREFIX_OPERATION_ADDED, kNat64PrefixString, 96));
- LinkProperties lpBeforeClat = networkCallback.expectCallback(
+ LinkProperties lpBeforeClat = networkCallback.expect(
CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent).getLp();
assertEquals(0, lpBeforeClat.getStackedLinks().size());
assertEquals(kNat64Prefix, lpBeforeClat.getNat64Prefix());
@@ -9894,7 +10227,7 @@
// Clat iface comes up. Expect stacked link to be added.
clat.interfaceLinkStateChanged(CLAT_MOBILE_IFNAME, true);
- networkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent);
+ networkCallback.expect(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent);
List<LinkProperties> stackedLps = mCm.getLinkProperties(mCellNetworkAgent.getNetwork())
.getStackedLinks();
assertEquals(makeClatLinkProperties(myIpv4), stackedLps.get(0));
@@ -9903,7 +10236,7 @@
// Change trivial linkproperties and see if stacked link is preserved.
cellLp.addDnsServer(InetAddress.getByName("8.8.8.8"));
mCellNetworkAgent.sendLinkProperties(cellLp);
- networkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent);
+ networkCallback.expect(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent);
List<LinkProperties> stackedLpsAfterChange =
mCm.getLinkProperties(mCellNetworkAgent.getNetwork()).getStackedLinks();
@@ -9952,13 +10285,13 @@
cellLp.addLinkAddress(myIpv4);
cellLp.addRoute(ipv4Subnet);
mCellNetworkAgent.sendLinkProperties(cellLp);
- networkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent);
+ networkCallback.expect(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent);
assertRoutesAdded(cellNetId, ipv4Subnet);
verifyClatdStop(null /* inOrder */, MOBILE_IFNAME);
verify(mMockDnsResolver, times(1)).stopPrefix64Discovery(cellNetId);
// As soon as stop is called, the linkproperties lose the stacked interface.
- networkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent);
+ networkCallback.expect(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent);
LinkProperties actualLpAfterIpv4 = mCm.getLinkProperties(mCellNetworkAgent.getNetwork());
LinkProperties expected = new LinkProperties(cellLp);
expected.setNat64Prefix(kOtherNat64Prefix);
@@ -9990,12 +10323,12 @@
cellLp.removeRoute(new RouteInfo(myIpv4, null, MOBILE_IFNAME));
cellLp.removeDnsServer(InetAddress.getByName("8.8.8.8"));
mCellNetworkAgent.sendLinkProperties(cellLp);
- networkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent);
+ networkCallback.expect(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent);
assertRoutesRemoved(cellNetId, ipv4Subnet); // Directly-connected routes auto-added.
verify(mMockDnsResolver, times(1)).startPrefix64Discovery(cellNetId);
mService.mResolverUnsolEventCallback.onNat64PrefixEvent(makeNat64PrefixEvent(
cellNetId, PREFIX_OPERATION_ADDED, kNat64PrefixString, 96));
- networkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent);
+ networkCallback.expect(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent);
verifyClatdStart(null /* inOrder */, MOBILE_IFNAME, cellNetId, kNat64Prefix.toString());
// Clat iface comes up. Expect stacked link to be added.
@@ -10020,7 +10353,7 @@
verify(mMockNetd, times(1)).interfaceGetCfg(CLAT_MOBILE_IFNAME);
// Clean up.
mCellNetworkAgent.disconnect();
- networkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
+ networkCallback.expect(CallbackEntry.LOST, mCellNetworkAgent);
networkCallback.assertNoCallback();
verify(mMockNetd, times(1)).idletimerRemoveInterface(eq(MOBILE_IFNAME), anyInt(),
eq(Integer.toString(TRANSPORT_CELLULAR)));
@@ -10059,7 +10392,7 @@
// Disconnect the network. clat is stopped and the network is destroyed.
mCellNetworkAgent.disconnect();
- networkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
+ networkCallback.expect(CallbackEntry.LOST, mCellNetworkAgent);
networkCallback.assertNoCallback();
verifyClatdStop(null /* inOrder */, MOBILE_IFNAME);
verify(mMockNetd).idletimerRemoveInterface(eq(MOBILE_IFNAME), anyInt(),
@@ -10233,7 +10566,7 @@
// clat has been stopped, or the test will be flaky.
ExpectedBroadcast b = expectConnectivityAction(TYPE_WIFI, DetailedState.DISCONNECTED);
mWiFiNetworkAgent.disconnect();
- callback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
+ callback.expect(CallbackEntry.LOST, mWiFiNetworkAgent);
b.expectBroadcast();
verifyClatdStop(inOrder, iface);
@@ -10307,7 +10640,7 @@
// Network switch
mWiFiNetworkAgent.connect(true);
networkCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
- networkCallback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent);
+ networkCallback.expectLosing(mCellNetworkAgent);
networkCallback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
verify(mMockNetd, times(1)).idletimerAddInterface(eq(WIFI_IFNAME), anyInt(),
eq(Integer.toString(TRANSPORT_WIFI)));
@@ -10317,7 +10650,7 @@
// Disconnect wifi and switch back to cell
reset(mMockNetd);
mWiFiNetworkAgent.disconnect();
- networkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
+ networkCallback.expect(CallbackEntry.LOST, mWiFiNetworkAgent);
assertNoCallbacks(networkCallback);
verify(mMockNetd, times(1)).idletimerRemoveInterface(eq(WIFI_IFNAME), anyInt(),
eq(Integer.toString(TRANSPORT_WIFI)));
@@ -10331,7 +10664,7 @@
mWiFiNetworkAgent.sendLinkProperties(wifiLp);
mWiFiNetworkAgent.connect(true);
networkCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
- networkCallback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent);
+ networkCallback.expectLosing(mCellNetworkAgent);
networkCallback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
verify(mMockNetd, times(1)).idletimerAddInterface(eq(WIFI_IFNAME), anyInt(),
eq(Integer.toString(TRANSPORT_WIFI)));
@@ -10341,7 +10674,7 @@
// Disconnect cell
reset(mMockNetd);
mCellNetworkAgent.disconnect();
- networkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
+ networkCallback.expect(CallbackEntry.LOST, mCellNetworkAgent);
// LOST callback is triggered earlier than removing idle timer. Broadcast should also be
// sent as network being switched. Ensure rule removal for cell will not be triggered
// unexpectedly before network being removed.
@@ -10391,11 +10724,11 @@
LinkProperties lp = new LinkProperties();
lp.setTcpBufferSizes(testTcpBufferSizes);
mCellNetworkAgent.sendLinkProperties(lp);
- networkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent);
+ networkCallback.expect(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent);
verifyTcpBufferSizeChange(testTcpBufferSizes);
// Clean up.
mCellNetworkAgent.disconnect();
- networkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
+ networkCallback.expect(CallbackEntry.LOST, mCellNetworkAgent);
networkCallback.assertNoCallback();
mCm.unregisterNetworkCallback(networkCallback);
}
@@ -12013,9 +12346,9 @@
// While the default callback doesn't see the network before it's validated, the listen
// sees the network come up and validate later
allNetworksCb.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
- allNetworksCb.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent);
+ allNetworksCb.expectLosing(mCellNetworkAgent);
allNetworksCb.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
- allNetworksCb.expectCallback(CallbackEntry.LOST, mCellNetworkAgent,
+ allNetworksCb.expect(CallbackEntry.LOST, mCellNetworkAgent,
TEST_LINGER_DELAY_MS * 2);
// The cell network has disconnected (see LOST above) because it was outscored and
@@ -12027,7 +12360,7 @@
// The cell network gets torn down right away.
allNetworksCb.expectAvailableCallbacksUnvalidated(mCellNetworkAgent);
- allNetworksCb.expectCallback(CallbackEntry.LOST, mCellNetworkAgent,
+ allNetworksCb.expect(CallbackEntry.LOST, mCellNetworkAgent,
TEST_NASCENT_DELAY_MS * 2);
allNetworksCb.assertNoCallback();
@@ -12044,8 +12377,8 @@
mWiFiNetworkAgent.disconnect();
- allNetworksCb.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
- mDefaultNetworkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
+ allNetworksCb.expect(CallbackEntry.LOST, mWiFiNetworkAgent);
+ mDefaultNetworkCallback.expect(CallbackEntry.LOST, mWiFiNetworkAgent);
mDefaultNetworkCallback.expectAvailableCallbacksValidated(mCellNetworkAgent);
// Reconnect a WiFi network and make sure the cell network is still not torn down.
@@ -12058,10 +12391,8 @@
// Now remove the reason to keep connected and make sure the network lingers and is
// torn down.
mCellNetworkAgent.setScore(new NetworkScore.Builder().setLegacyInt(30).build());
- allNetworksCb.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent,
- TEST_NASCENT_DELAY_MS * 2);
- allNetworksCb.expectCallback(CallbackEntry.LOST, mCellNetworkAgent,
- TEST_LINGER_DELAY_MS * 2);
+ allNetworksCb.expectLosing(mCellNetworkAgent, TEST_NASCENT_DELAY_MS * 2);
+ allNetworksCb.expect(CallbackEntry.LOST, mCellNetworkAgent, TEST_LINGER_DELAY_MS * 2);
mDefaultNetworkCallback.assertNoCallback();
mCm.unregisterNetworkCallback(allNetworksCb);
@@ -12830,6 +13161,12 @@
if (null != mTestPackageDefaultNetworkCallback2) {
mCm.unregisterNetworkCallback(mTestPackageDefaultNetworkCallback2);
}
+ mSystemDefaultNetworkCallback = null;
+ mDefaultNetworkCallback = null;
+ mProfileDefaultNetworkCallback = null;
+ mTestPackageDefaultNetworkCallback = null;
+ mProfileDefaultNetworkCallbackAsAppUid2 = null;
+ mTestPackageDefaultNetworkCallback2 = null;
}
private void setupMultipleDefaultNetworksForOemNetworkPreferenceNotCurrentUidTest(
@@ -13026,7 +13363,7 @@
setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, false);
// At this point, with no network is available, the lost callback should trigger
- defaultNetworkCallback.expectCallback(CallbackEntry.LOST, mEthernetNetworkAgent);
+ defaultNetworkCallback.expect(CallbackEntry.LOST, mEthernetNetworkAgent);
otherUidDefaultCallback.assertNoCallback();
// Confirm we can unregister without issues.
@@ -13072,7 +13409,7 @@
otherUidDefaultCallback.assertNoCallback();
// At this point, with no network is available, the lost callback should trigger
- defaultNetworkCallback.expectCallback(CallbackEntry.LOST, mEthernetNetworkAgent);
+ defaultNetworkCallback.expect(CallbackEntry.LOST, mEthernetNetworkAgent);
otherUidDefaultCallback.assertNoCallback();
// Confirm we can unregister without issues.
@@ -13134,13 +13471,13 @@
// Since the callback didn't use the per-app network, only the other UID gets a callback.
// Because the preference specifies no fallback, it does not switch to cellular.
defaultNetworkCallback.assertNoCallback();
- otherUidDefaultCallback.expectCallback(CallbackEntry.LOST, mEthernetNetworkAgent);
+ otherUidDefaultCallback.expect(CallbackEntry.LOST, mEthernetNetworkAgent);
// Now bring down the default network.
setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, false);
// As this callback was tracking the default, this should now trigger.
- defaultNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
+ defaultNetworkCallback.expect(CallbackEntry.LOST, mCellNetworkAgent);
otherUidDefaultCallback.assertNoCallback();
// Confirm we can unregister without issues.
@@ -14254,7 +14591,7 @@
mWiFiNetworkAgent.disconnect();
bestMatchingCb.assertNoCallback();
mCellNetworkAgent.disconnect();
- bestMatchingCb.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
+ bestMatchingCb.expect(CallbackEntry.LOST, mCellNetworkAgent);
}
private UidRangeParcel[] uidRangeFor(final UserHandle handle) {
@@ -14399,7 +14736,7 @@
if (allowFallback && !connectWorkProfileAgentAhead) {
assertNoCallbacks(profileDefaultNetworkCallback);
} else if (!connectWorkProfileAgentAhead) {
- profileDefaultNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
+ profileDefaultNetworkCallback.expect(CallbackEntry.LOST, mCellNetworkAgent);
if (disAllowProfileDefaultNetworkCallback != null) {
assertNoCallbacks(disAllowProfileDefaultNetworkCallback);
}
@@ -14469,10 +14806,10 @@
// apps on this network see the appropriate callbacks, and the app on the work profile
// doesn't because it continues to use the enterprise network.
mCellNetworkAgent.disconnect();
- mSystemDefaultNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
- mDefaultNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
+ mSystemDefaultNetworkCallback.expect(CallbackEntry.LOST, mCellNetworkAgent);
+ mDefaultNetworkCallback.expect(CallbackEntry.LOST, mCellNetworkAgent);
if (disAllowProfileDefaultNetworkCallback != null) {
- disAllowProfileDefaultNetworkCallback.expectCallback(
+ disAllowProfileDefaultNetworkCallback.expect(
CallbackEntry.LOST, mCellNetworkAgent);
}
profileDefaultNetworkCallback.assertNoCallback();
@@ -14494,7 +14831,7 @@
// When the agent disconnects, test that the app on the work profile falls back to the
// default network.
workAgent.disconnect();
- profileDefaultNetworkCallback.expectCallback(CallbackEntry.LOST, workAgent);
+ profileDefaultNetworkCallback.expect(CallbackEntry.LOST, workAgent);
if (allowFallback) {
profileDefaultNetworkCallback.expectAvailableCallbacksValidated(mCellNetworkAgent);
if (disAllowProfileDefaultNetworkCallback != null) {
@@ -14511,14 +14848,14 @@
inOrder.verify(mMockNetd).networkDestroy(workAgent.getNetwork().netId);
mCellNetworkAgent.disconnect();
- mSystemDefaultNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
- mDefaultNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
+ mSystemDefaultNetworkCallback.expect(CallbackEntry.LOST, mCellNetworkAgent);
+ mDefaultNetworkCallback.expect(CallbackEntry.LOST, mCellNetworkAgent);
if (disAllowProfileDefaultNetworkCallback != null) {
- disAllowProfileDefaultNetworkCallback.expectCallback(
+ disAllowProfileDefaultNetworkCallback.expect(
CallbackEntry.LOST, mCellNetworkAgent);
}
if (allowFallback) {
- profileDefaultNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
+ profileDefaultNetworkCallback.expect(CallbackEntry.LOST, mCellNetworkAgent);
}
// Waiting for the handler to be idle before checking for networkDestroy is necessary
@@ -14561,7 +14898,7 @@
// When the agent disconnects, test that the app on the work profile fall back to the
// default network.
workAgent2.disconnect();
- profileDefaultNetworkCallback.expectCallback(CallbackEntry.LOST, workAgent2);
+ profileDefaultNetworkCallback.expect(CallbackEntry.LOST, workAgent2);
if (disAllowProfileDefaultNetworkCallback != null) {
assertNoCallbacks(disAllowProfileDefaultNetworkCallback);
}
@@ -15171,11 +15508,11 @@
workAgent4.disconnect();
workAgent5.disconnect();
- appCb1.expectCallback(CallbackEntry.LOST, workAgent1);
- appCb2.expectCallback(CallbackEntry.LOST, workAgent2);
- appCb3.expectCallback(CallbackEntry.LOST, workAgent3);
- appCb4.expectCallback(CallbackEntry.LOST, workAgent4);
- appCb5.expectCallback(CallbackEntry.LOST, workAgent5);
+ appCb1.expect(CallbackEntry.LOST, workAgent1);
+ appCb2.expect(CallbackEntry.LOST, workAgent2);
+ appCb3.expect(CallbackEntry.LOST, workAgent3);
+ appCb4.expect(CallbackEntry.LOST, workAgent4);
+ appCb5.expect(CallbackEntry.LOST, workAgent5);
appCb1.expectAvailableCallbacksValidated(mCellNetworkAgent);
appCb2.assertNoCallback();
@@ -15599,11 +15936,19 @@
mServiceContext.setPermission(NETWORK_FACTORY, PERMISSION_GRANTED);
mServiceContext.setPermission(MANAGE_TEST_NETWORKS, PERMISSION_GRANTED);
- // In this test the automotive feature will be enabled.
- mockHasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, true);
+ // Has automotive feature.
+ validateAutomotiveEthernetAllowedUids(true);
+
+ // No automotive feature.
+ validateAutomotiveEthernetAllowedUids(false);
+ }
+
+ private void validateAutomotiveEthernetAllowedUids(final boolean hasAutomotiveFeature)
+ throws Exception {
+ mockHasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, hasAutomotiveFeature);
// Simulate a restricted ethernet network.
- final NetworkCapabilities.Builder agentNetCaps = new NetworkCapabilities.Builder()
+ final NetworkCapabilities.Builder ncb = new NetworkCapabilities.Builder()
.addTransportType(TRANSPORT_ETHERNET)
.addCapability(NET_CAPABILITY_INTERNET)
.addCapability(NET_CAPABILITY_NOT_SUSPENDED)
@@ -15611,8 +15956,34 @@
.removeCapability(NET_CAPABILITY_NOT_RESTRICTED);
mEthernetNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_ETHERNET,
- new LinkProperties(), agentNetCaps.build());
- validateAllowedUids(mEthernetNetworkAgent, TRANSPORT_ETHERNET, agentNetCaps, true);
+ new LinkProperties(), ncb.build());
+
+ final ArraySet<Integer> serviceUidSet = new ArraySet<>();
+ serviceUidSet.add(TEST_PACKAGE_UID);
+
+ final TestNetworkCallback cb = new TestNetworkCallback();
+
+ mCm.requestNetwork(new NetworkRequest.Builder()
+ .addTransportType(TRANSPORT_ETHERNET)
+ .removeCapability(NET_CAPABILITY_NOT_RESTRICTED)
+ .build(), cb);
+ mEthernetNetworkAgent.connect(true);
+ cb.expectAvailableThenValidatedCallbacks(mEthernetNetworkAgent);
+
+ // Cell gets to set the service UID as access UID
+ ncb.setAllowedUids(serviceUidSet);
+ mEthernetNetworkAgent.setNetworkCapabilities(ncb.build(), true /* sendToCS */);
+ if (SdkLevel.isAtLeastT() && hasAutomotiveFeature) {
+ cb.expectCapabilitiesThat(mEthernetNetworkAgent,
+ caps -> caps.getAllowedUids().equals(serviceUidSet));
+ } else {
+ // S and no automotive feature must ignore access UIDs.
+ cb.assertNoCallback(TEST_CALLBACK_TIMEOUT_MS);
+ }
+
+ mEthernetNetworkAgent.disconnect();
+ cb.expect(CallbackEntry.LOST, mEthernetNetworkAgent);
+ mCm.unregisterNetworkCallback(cb);
}
@Test
@@ -15626,7 +15997,7 @@
// Simulate a restricted telephony network. The telephony factory is entitled to set
// the access UID to the service package on any of its restricted networks.
- final NetworkCapabilities.Builder agentNetCaps = new NetworkCapabilities.Builder()
+ final NetworkCapabilities.Builder ncb = new NetworkCapabilities.Builder()
.addTransportType(TRANSPORT_CELLULAR)
.addCapability(NET_CAPABILITY_INTERNET)
.addCapability(NET_CAPABILITY_NOT_SUSPENDED)
@@ -15635,13 +16006,8 @@
.setNetworkSpecifier(new TelephonyNetworkSpecifier(1 /* subid */));
mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR,
- new LinkProperties(), agentNetCaps.build());
- validateAllowedUids(mCellNetworkAgent, TRANSPORT_CELLULAR, agentNetCaps, false);
- }
+ new LinkProperties(), ncb.build());
- private void validateAllowedUids(final TestNetworkAgentWrapper testAgent,
- @NetworkCapabilities.Transport final int transportUnderTest,
- final NetworkCapabilities.Builder ncb, final boolean forAutomotive) throws Exception {
final ArraySet<Integer> serviceUidSet = new ArraySet<>();
serviceUidSet.add(TEST_PACKAGE_UID);
final ArraySet<Integer> nonServiceUidSet = new ArraySet<>();
@@ -15652,34 +16018,28 @@
final TestNetworkCallback cb = new TestNetworkCallback();
- /* Test setting UIDs */
// Cell gets to set the service UID as access UID
mCm.requestNetwork(new NetworkRequest.Builder()
- .addTransportType(transportUnderTest)
+ .addTransportType(TRANSPORT_CELLULAR)
.removeCapability(NET_CAPABILITY_NOT_RESTRICTED)
.build(), cb);
- testAgent.connect(true);
- cb.expectAvailableThenValidatedCallbacks(testAgent);
+ mCellNetworkAgent.connect(true);
+ cb.expectAvailableThenValidatedCallbacks(mCellNetworkAgent);
ncb.setAllowedUids(serviceUidSet);
- testAgent.setNetworkCapabilities(ncb.build(), true /* sendToCS */);
+ mCellNetworkAgent.setNetworkCapabilities(ncb.build(), true /* sendToCS */);
if (SdkLevel.isAtLeastT()) {
- cb.expectCapabilitiesThat(testAgent,
+ cb.expectCapabilitiesThat(mCellNetworkAgent,
caps -> caps.getAllowedUids().equals(serviceUidSet));
} else {
// S must ignore access UIDs.
cb.assertNoCallback(TEST_CALLBACK_TIMEOUT_MS);
}
- /* Test setting UIDs is rejected when expected */
- if (forAutomotive) {
- mockHasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, false);
- }
-
// ...but not to some other UID. Rejection sets UIDs to the empty set
ncb.setAllowedUids(nonServiceUidSet);
- testAgent.setNetworkCapabilities(ncb.build(), true /* sendToCS */);
+ mCellNetworkAgent.setNetworkCapabilities(ncb.build(), true /* sendToCS */);
if (SdkLevel.isAtLeastT()) {
- cb.expectCapabilitiesThat(testAgent,
+ cb.expectCapabilitiesThat(mCellNetworkAgent,
caps -> caps.getAllowedUids().isEmpty());
} else {
// S must ignore access UIDs.
@@ -15688,18 +16048,18 @@
// ...and also not to multiple UIDs even including the service UID
ncb.setAllowedUids(serviceUidSetPlus);
- testAgent.setNetworkCapabilities(ncb.build(), true /* sendToCS */);
+ mCellNetworkAgent.setNetworkCapabilities(ncb.build(), true /* sendToCS */);
cb.assertNoCallback(TEST_CALLBACK_TIMEOUT_MS);
- testAgent.disconnect();
- cb.expectCallback(CallbackEntry.LOST, testAgent);
+ mCellNetworkAgent.disconnect();
+ cb.expect(CallbackEntry.LOST, mCellNetworkAgent);
mCm.unregisterNetworkCallback(cb);
// Must be unset before touching the transports, because remove and add transport types
// check the specifier on the builder immediately, contradicting normal builder semantics
// TODO : fix the builder
ncb.setNetworkSpecifier(null);
- ncb.removeTransportType(transportUnderTest);
+ ncb.removeTransportType(TRANSPORT_CELLULAR);
ncb.addTransportType(TRANSPORT_WIFI);
// Wifi does not get to set access UID, even to the correct UID
mCm.requestNetwork(new NetworkRequest.Builder()
@@ -16002,8 +16362,8 @@
// callback with wifi network from fallback request.
mCellNetworkAgent.disconnect();
mDefaultNetworkCallback.assertNoCallback();
- cellNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
- mTestPackageDefaultNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
+ cellNetworkCallback.expect(CallbackEntry.LOST, mCellNetworkAgent);
+ mTestPackageDefaultNetworkCallback.expect(CallbackEntry.LOST, mCellNetworkAgent);
mTestPackageDefaultNetworkCallback.expectAvailableCallbacksValidated(mWiFiNetworkAgent);
assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetworkForUid(TEST_PACKAGE_UID));
inorder.verify(mMockNetd, times(1)).networkAddUidRangesParcel(wifiConfig);
@@ -16030,7 +16390,7 @@
// Wifi network disconnected. mTestPackageDefaultNetworkCallback should not receive
// any callback.
mWiFiNetworkAgent.disconnect();
- mDefaultNetworkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
+ mDefaultNetworkCallback.expect(CallbackEntry.LOST, mWiFiNetworkAgent);
mDefaultNetworkCallback.expectAvailableCallbacksValidated(mCellNetworkAgent);
mTestPackageDefaultNetworkCallback.assertNoCallback();
assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetworkForUid(TEST_PACKAGE_UID));
@@ -16279,7 +16639,7 @@
// Disconnect wifi
mWiFiNetworkAgent.disconnect();
assertNoCallbacks(mProfileDefaultNetworkCallback, mTestPackageDefaultNetworkCallback);
- mDefaultNetworkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
+ mDefaultNetworkCallback.expect(CallbackEntry.LOST, mWiFiNetworkAgent);
mDefaultNetworkCallback.expectAvailableCallbacksValidated(mCellNetworkAgent);
}
@@ -16457,20 +16817,44 @@
}
@Test
- public void testIgnoreValidationAfterRoamDisabled() throws Exception {
- assumeFalse(SdkLevel.isAtLeastT());
- // testIgnoreValidationAfterRoam off
- doReturn(-1).when(mResources)
+ public void testOfferNetwork_ChecksArgumentsOutsideOfHandler() throws Exception {
+ final TestableNetworkOfferCallback callback = new TestableNetworkOfferCallback(
+ TIMEOUT_MS /* timeout */, TEST_CALLBACK_TIMEOUT_MS /* noCallbackTimeout */);
+ final NetworkProvider testProvider = new NetworkProvider(mServiceContext,
+ mCsHandlerThread.getLooper(), "Test provider");
+ final NetworkCapabilities caps = new NetworkCapabilities.Builder()
+ .addCapability(NET_CAPABILITY_INTERNET)
+ .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED)
+ .build();
+
+ final NetworkScore score = new NetworkScore.Builder().build();
+ testProvider.registerNetworkOffer(score, caps, r -> r.run(), callback);
+ testProvider.unregisterNetworkOffer(callback);
+
+ assertThrows(NullPointerException.class,
+ () -> mService.offerNetwork(100, score, caps, null));
+ assertThrows(NullPointerException.class, () -> mService.unofferNetwork(null));
+ }
+
+ public void doTestIgnoreValidationAfterRoam(int resValue, final boolean enabled)
+ throws Exception {
+ doReturn(resValue).when(mResources)
.getInteger(R.integer.config_validationFailureAfterRoamIgnoreTimeMillis);
+ final String bssid1 = "AA:AA:AA:AA:AA:AA";
+ final String bssid2 = "BB:BB:BB:BB:BB:BB";
mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR);
mCellNetworkAgent.connect(true);
NetworkCapabilities wifiNc1 = new NetworkCapabilities()
+ .addCapability(NET_CAPABILITY_INTERNET)
+ .addCapability(NET_CAPABILITY_NOT_VPN)
+ .addCapability(NET_CAPABILITY_NOT_RESTRICTED)
+ .addCapability(NET_CAPABILITY_TRUSTED)
+ .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED)
.addTransportType(TRANSPORT_WIFI)
- .setTransportInfo(new WifiInfo.Builder().setBssid("AA:AA:AA:AA:AA:AA").build());
- NetworkCapabilities wifiNc2 = new NetworkCapabilities()
- .addTransportType(TRANSPORT_WIFI)
- .setTransportInfo(new WifiInfo.Builder().setBssid("BB:BB:BB:BB:BB:BB").build());
+ .setTransportInfo(new WifiInfo.Builder().setBssid(bssid1).build());
+ NetworkCapabilities wifiNc2 = new NetworkCapabilities(wifiNc1)
+ .setTransportInfo(new WifiInfo.Builder().setBssid(bssid2).build());
final LinkProperties wifiLp = new LinkProperties();
wifiLp.setInterfaceName(WIFI_IFNAME);
mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, wifiLp, wifiNc1);
@@ -16480,70 +16864,142 @@
final TestNetworkCallback wifiNetworkCallback = new TestNetworkCallback();
final NetworkRequest wifiRequest = new NetworkRequest.Builder()
.addTransportType(TRANSPORT_WIFI).build();
- mCm.registerNetworkCallback(wifiRequest, wifiNetworkCallback);
+ mCm.requestNetwork(wifiRequest, wifiNetworkCallback);
wifiNetworkCallback.expectAvailableCallbacksValidated(mWiFiNetworkAgent);
registerDefaultNetworkCallbacks();
mDefaultNetworkCallback.expectAvailableCallbacksValidated(mWiFiNetworkAgent);
- // Wi-Fi roaming from wifiNc1 to wifiNc2.
+ // There is a bug in the current code where ignoring validation after roam will not
+ // correctly change the default network if the result if the validation is partial or
+ // captive portal. TODO : fix the bug and reinstate this code.
+ if (false) {
+ // Wi-Fi roaming from wifiNc1 to wifiNc2 but the network is now behind a captive portal.
+ mWiFiNetworkAgent.setNetworkCapabilities(wifiNc2, true /* sendToConnectivityService */);
+ // The only thing changed in this CAPS is the BSSID, which can't be tested for in this
+ // test because it's redacted.
+ wifiNetworkCallback.expect(CallbackEntry.NETWORK_CAPS_UPDATED,
+ mWiFiNetworkAgent);
+ mDefaultNetworkCallback.expect(CallbackEntry.NETWORK_CAPS_UPDATED,
+ mWiFiNetworkAgent);
+ mWiFiNetworkAgent.setNetworkPortal(TEST_REDIRECT_URL, false /* isStrictMode */);
+ mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), false);
+ // Wi-Fi is now detected to have a portal : cell should become the default network.
+ mDefaultNetworkCallback.expectAvailableCallbacksValidated(mCellNetworkAgent);
+ wifiNetworkCallback.expectCapabilitiesWithout(NET_CAPABILITY_VALIDATED,
+ mWiFiNetworkAgent);
+ wifiNetworkCallback.expectCapabilitiesWith(NET_CAPABILITY_CAPTIVE_PORTAL,
+ mWiFiNetworkAgent);
+
+ // Wi-Fi becomes valid again. The default network goes back to Wi-Fi.
+ mWiFiNetworkAgent.setNetworkValid(false /* isStrictMode */);
+ mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), true);
+ mDefaultNetworkCallback.expectAvailableCallbacksValidated(mWiFiNetworkAgent);
+ wifiNetworkCallback.expectCapabilitiesWithout(NET_CAPABILITY_CAPTIVE_PORTAL,
+ mWiFiNetworkAgent);
+
+ // Wi-Fi roaming from wifiNc2 to wifiNc1, and the network now has partial connectivity.
+ mWiFiNetworkAgent.setNetworkCapabilities(wifiNc1, true);
+ wifiNetworkCallback.expect(CallbackEntry.NETWORK_CAPS_UPDATED,
+ mWiFiNetworkAgent);
+ mDefaultNetworkCallback.expect(CallbackEntry.NETWORK_CAPS_UPDATED,
+ mWiFiNetworkAgent);
+ mWiFiNetworkAgent.setNetworkPartial();
+ mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), false);
+ // Wi-Fi now only offers partial connectivity, so in the absence of accepting partial
+ // connectivity explicitly for this network, it loses default status to cell.
+ mDefaultNetworkCallback.expectAvailableCallbacksValidated(mCellNetworkAgent);
+ wifiNetworkCallback.expectCapabilitiesWith(NET_CAPABILITY_PARTIAL_CONNECTIVITY,
+ mWiFiNetworkAgent);
+
+ // Wi-Fi becomes valid again. The default network goes back to Wi-Fi.
+ mWiFiNetworkAgent.setNetworkValid(false /* isStrictMode */);
+ mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), true);
+ mDefaultNetworkCallback.expectAvailableCallbacksValidated(mWiFiNetworkAgent);
+ wifiNetworkCallback.expectCapabilitiesWithout(NET_CAPABILITY_PARTIAL_CONNECTIVITY,
+ mWiFiNetworkAgent);
+ }
+ mCm.unregisterNetworkCallback(wifiNetworkCallback);
+
+ // Wi-Fi roams from wifiNc1 to wifiNc2, and now becomes really invalid. If validation
+ // failures after roam are not ignored, this will cause cell to become the default network.
+ // If they are ignored, this will not cause a switch until later.
mWiFiNetworkAgent.setNetworkCapabilities(wifiNc2, true);
- mWiFiNetworkAgent.setNetworkInvalid(false);
+ mDefaultNetworkCallback.expect(CallbackEntry.NETWORK_CAPS_UPDATED,
+ mWiFiNetworkAgent);
+ mWiFiNetworkAgent.setNetworkInvalid(false /* isStrictMode */);
mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), false);
- mDefaultNetworkCallback.expectAvailableCallbacksValidated(mCellNetworkAgent);
+
+ if (enabled) {
+ // Network validation failed, but the result will be ignored.
+ assertTrue(mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).hasCapability(
+ NET_CAPABILITY_VALIDATED));
+ mWiFiNetworkAgent.setNetworkValid(false);
+
+ // Behavior of after config_validationFailureAfterRoamIgnoreTimeMillis
+ ConditionVariable waitForValidationBlock = new ConditionVariable();
+ doReturn(50).when(mResources)
+ .getInteger(R.integer.config_validationFailureAfterRoamIgnoreTimeMillis);
+ // Wi-Fi roaming from wifiNc2 to wifiNc1.
+ mWiFiNetworkAgent.setNetworkCapabilities(wifiNc1, true);
+ mWiFiNetworkAgent.setNetworkInvalid(false);
+ waitForValidationBlock.block(150);
+ mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), false);
+ mDefaultNetworkCallback.expectAvailableCallbacksValidated(mCellNetworkAgent);
+ } else {
+ mDefaultNetworkCallback.expectAvailableCallbacksValidated(mCellNetworkAgent);
+ }
+
+ // Wi-Fi is still connected and would become the default network if cell were to
+ // disconnect. This assertion ensures that the switch to cellular was not caused by
+ // Wi-Fi disconnecting (e.g., because the capability change to wifiNc2 caused it
+ // to stop satisfying the default request).
+ mCellNetworkAgent.disconnect();
+ mDefaultNetworkCallback.expect(CallbackEntry.LOST, mCellNetworkAgent);
+ mDefaultNetworkCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
+
+ }
+
+ @Test
+ public void testIgnoreValidationAfterRoamDisabled() throws Exception {
+ doTestIgnoreValidationAfterRoam(-1, false /* enabled */);
}
@Test
public void testIgnoreValidationAfterRoamEnabled() throws Exception {
- assumeFalse(SdkLevel.isAtLeastT());
- // testIgnoreValidationAfterRoam on
- doReturn(5000).when(mResources)
- .getInteger(R.integer.config_validationFailureAfterRoamIgnoreTimeMillis);
-
- mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR);
- mCellNetworkAgent.connect(true);
- NetworkCapabilities wifiNc1 = new NetworkCapabilities()
- .addTransportType(TRANSPORT_WIFI)
- .setTransportInfo(new WifiInfo.Builder().setBssid("AA:AA:AA:AA:AA:AA").build());
- NetworkCapabilities wifiNc2 = new NetworkCapabilities()
- .addTransportType(TRANSPORT_WIFI)
- .setTransportInfo(new WifiInfo.Builder().setBssid("BB:BB:BB:BB:BB:BB").build());
- final LinkProperties wifiLp = new LinkProperties();
- wifiLp.setInterfaceName(WIFI_IFNAME);
- mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, wifiLp, wifiNc1);
- mWiFiNetworkAgent.connect(true);
-
- // The default network will be switching to Wi-Fi Network.
- final TestNetworkCallback wifiNetworkCallback = new TestNetworkCallback();
- final NetworkRequest wifiRequest = new NetworkRequest.Builder()
- .addTransportType(TRANSPORT_WIFI).build();
- mCm.registerNetworkCallback(wifiRequest, wifiNetworkCallback);
- wifiNetworkCallback.expectAvailableCallbacksValidated(mWiFiNetworkAgent);
- registerDefaultNetworkCallbacks();
- mDefaultNetworkCallback.expectAvailableCallbacksValidated(mWiFiNetworkAgent);
-
- // Wi-Fi roaming from wifiNc1 to wifiNc2.
- mWiFiNetworkAgent.setNetworkCapabilities(wifiNc2, true);
- mWiFiNetworkAgent.setNetworkInvalid(false);
- mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), false);
-
- // Network validation failed, but the result will be ignored.
- assertTrue(mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).hasCapability(
- NET_CAPABILITY_VALIDATED));
- mWiFiNetworkAgent.setNetworkValid(false);
-
- // Behavior of after config_validationFailureAfterRoamIgnoreTimeMillis
- ConditionVariable waitForValidationBlock = new ConditionVariable();
- doReturn(50).when(mResources)
- .getInteger(R.integer.config_validationFailureAfterRoamIgnoreTimeMillis);
- // Wi-Fi roaming from wifiNc2 to wifiNc1.
- mWiFiNetworkAgent.setNetworkCapabilities(wifiNc1, true);
- mWiFiNetworkAgent.setNetworkInvalid(false);
- waitForValidationBlock.block(150);
- mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), false);
- mDefaultNetworkCallback.expectAvailableCallbacksValidated(mCellNetworkAgent);
+ final boolean enabled = !SdkLevel.isAtLeastT();
+ doTestIgnoreValidationAfterRoam(5_000, enabled);
}
@Test
+ public void testShouldIgnoreValidationFailureAfterRoam() {
+ // Always disabled on T+.
+ assumeFalse(SdkLevel.isAtLeastT());
+
+ NetworkAgentInfo nai = fakeWifiNai(new NetworkCapabilities());
+
+ // Enabled, but never roamed.
+ doReturn(5_000).when(mResources)
+ .getInteger(R.integer.config_validationFailureAfterRoamIgnoreTimeMillis);
+ assertEquals(0, nai.lastRoamTime);
+ assertFalse(mService.shouldIgnoreValidationFailureAfterRoam(nai));
+
+ // Roamed recently.
+ nai.lastRoamTime = SystemClock.elapsedRealtime() - 500 /* ms */;
+ assertTrue(mService.shouldIgnoreValidationFailureAfterRoam(nai));
+
+ // Disabled due to invalid setting (maximum is 10 seconds).
+ doReturn(15_000).when(mResources)
+ .getInteger(R.integer.config_validationFailureAfterRoamIgnoreTimeMillis);
+ assertFalse(mService.shouldIgnoreValidationFailureAfterRoam(nai));
+
+ // Disabled.
+ doReturn(-1).when(mResources)
+ .getInteger(R.integer.config_validationFailureAfterRoamIgnoreTimeMillis);
+ assertFalse(mService.shouldIgnoreValidationFailureAfterRoam(nai));
+ }
+
+
+ @Test
public void testLegacyTetheringApiGuardWithProperPermission() throws Exception {
final String testIface = "test0";
mServiceContext.setPermission(ACCESS_NETWORK_STATE, PERMISSION_DENIED);
@@ -16574,4 +17030,43 @@
verify(mTetheringManager).getTetherableWifiRegexs();
});
}
+
+ @Test
+ public void testGetNetworkInfoForUid() throws Exception {
+ // Setup and verify getNetworkInfoForUid cannot be called without Network Stack permission,
+ // when querying NetworkInfo for other uid.
+ verifyNoNetwork();
+ mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
+ mServiceContext.setPermission(NETWORK_STACK, PERMISSION_DENIED);
+ mServiceContext.setPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
+ PERMISSION_DENIED);
+
+ final int otherUid = Process.myUid() + 1;
+ assertNull(mCm.getActiveNetwork());
+ assertNull(mCm.getNetworkInfoForUid(mCm.getActiveNetwork(),
+ Process.myUid(), false /* ignoreBlocked */));
+ assertThrows(SecurityException.class, () -> mCm.getNetworkInfoForUid(
+ mCm.getActiveNetwork(), otherUid, false /* ignoreBlocked */));
+ withPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, () ->
+ assertNull(mCm.getNetworkInfoForUid(mCm.getActiveNetwork(),
+ otherUid, false /* ignoreBlocked */)));
+
+ // Bringing up validated wifi and verify again. Make the other uid be blocked,
+ // verify the method returns result accordingly.
+ mWiFiNetworkAgent.connect(true);
+ setBlockedReasonChanged(BLOCKED_REASON_BATTERY_SAVER);
+ mockUidNetworkingBlocked(otherUid);
+ withPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, () ->
+ verifyActiveNetwork(TRANSPORT_WIFI));
+ checkNetworkInfo(mCm.getNetworkInfoForUid(mCm.getActiveNetwork(),
+ Process.myUid(), false /* ignoreBlocked */), TYPE_WIFI, DetailedState.CONNECTED);
+ assertThrows(SecurityException.class, () -> mCm.getNetworkInfoForUid(
+ mCm.getActiveNetwork(), otherUid, false /* ignoreBlocked */));
+ withPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, () ->
+ checkNetworkInfo(mCm.getNetworkInfoForUid(mCm.getActiveNetwork(),
+ otherUid, false /* ignoreBlocked */), TYPE_WIFI, DetailedState.BLOCKED));
+ withPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, () ->
+ checkNetworkInfo(mCm.getNetworkInfoForUid(mCm.getActiveNetwork(),
+ otherUid, true /* ignoreBlocked */), TYPE_WIFI, DetailedState.CONNECTED));
+ }
}
diff --git a/tests/unit/java/com/android/server/IpSecServiceParameterizedTest.java b/tests/unit/java/com/android/server/IpSecServiceParameterizedTest.java
index 9401d47..624071a 100644
--- a/tests/unit/java/com/android/server/IpSecServiceParameterizedTest.java
+++ b/tests/unit/java/com/android/server/IpSecServiceParameterizedTest.java
@@ -748,6 +748,13 @@
// Verify quota and RefcountedResource objects cleaned up
assertEquals(0, userRecord.mTunnelQuotaTracker.mCurrent);
verify(mMockNetd).ipSecRemoveTunnelInterface(eq(createTunnelResp.interfaceName));
+
+ for (int direction : new int[] {DIRECTION_OUT, DIRECTION_IN, DIRECTION_FWD}) {
+ verify(mMockNetd, times(ADDRESS_FAMILIES.length))
+ .ipSecDeleteSecurityPolicy(
+ anyInt(), anyInt(), eq(direction), anyInt(), anyInt(), anyInt());
+ }
+
try {
userRecord.mTunnelInterfaceRecords.getRefcountedResourceOrThrow(
createTunnelResp.resourceId);
diff --git a/tests/unit/java/com/android/server/connectivity/ClatCoordinatorTest.java b/tests/unit/java/com/android/server/connectivity/ClatCoordinatorTest.java
index 7646c19..b651c33 100644
--- a/tests/unit/java/com/android/server/connectivity/ClatCoordinatorTest.java
+++ b/tests/unit/java/com/android/server/connectivity/ClatCoordinatorTest.java
@@ -220,12 +220,12 @@
*/
@Override
public String generateIpv6Address(@NonNull String iface, @NonNull String v4,
- @NonNull String prefix64) throws IOException {
+ @NonNull String prefix64, int mark) throws IOException {
if (BASE_IFACE.equals(iface) && XLAT_LOCAL_IPV4ADDR_STRING.equals(v4)
- && NAT64_PREFIX_STRING.equals(prefix64)) {
+ && NAT64_PREFIX_STRING.equals(prefix64) && MARK == mark) {
return XLAT_LOCAL_IPV6ADDR_STRING;
}
- fail("unsupported args: " + iface + ", " + v4 + ", " + prefix64);
+ fail("unsupported args: " + iface + ", " + v4 + ", " + prefix64 + ", " + mark);
return null;
}
@@ -417,7 +417,7 @@
// Generate a checksum-neutral IID.
inOrder.verify(mDeps).generateIpv6Address(eq(BASE_IFACE),
- eq(XLAT_LOCAL_IPV4ADDR_STRING), eq(NAT64_PREFIX_STRING));
+ eq(XLAT_LOCAL_IPV4ADDR_STRING), eq(NAT64_PREFIX_STRING), eq(MARK));
// Open, configure and bring up the tun interface.
inOrder.verify(mDeps).createTunInterface(eq(STACKED_IFACE));
@@ -516,28 +516,38 @@
assertEquals(65508, ClatCoordinator.adjustMtu(CLAT_MAX_MTU + 1 /* over maximum mtu */));
}
- @Test
- public void testDump() throws Exception {
- final ClatCoordinator coordinator = makeClatCoordinator();
+ private void verifyDump(final ClatCoordinator coordinator, boolean clatStarted) {
final StringWriter stringWriter = new StringWriter();
final IndentingPrintWriter ipw = new IndentingPrintWriter(stringWriter, " ");
- coordinator.clatStart(BASE_IFACE, NETID, NAT64_IP_PREFIX);
coordinator.dump(ipw);
final String[] dumpStrings = stringWriter.toString().split("\n");
- assertEquals(6, dumpStrings.length);
- assertEquals("CLAT tracker: iface: test0 (1000), v4iface: v4-test0 (1001), "
- + "v4: /192.0.0.46, v6: /2001:db8:0:b11::464, pfx96: /64:ff9b::, "
- + "pid: 10483, cookie: 27149", dumpStrings[0].trim());
- assertEquals("Forwarding rules:", dumpStrings[1].trim());
- assertEquals("BPF ingress map: iif nat64Prefix v6Addr -> v4Addr oif",
- dumpStrings[2].trim());
- assertEquals("1000 /64:ff9b::/96 /2001:db8:0:b11::464 -> /192.0.0.46 1001",
- dumpStrings[3].trim());
- assertEquals("BPF egress map: iif v4Addr -> v6Addr nat64Prefix oif",
- dumpStrings[4].trim());
- assertEquals("1001 /192.0.0.46 -> /2001:db8:0:b11::464 /64:ff9b::/96 1000 ether",
- dumpStrings[5].trim());
+ if (clatStarted) {
+ assertEquals(6, dumpStrings.length);
+ assertEquals("CLAT tracker: iface: test0 (1000), v4iface: v4-test0 (1001), "
+ + "v4: /192.0.0.46, v6: /2001:db8:0:b11::464, pfx96: /64:ff9b::, "
+ + "pid: 10483, cookie: 27149", dumpStrings[0].trim());
+ assertEquals("Forwarding rules:", dumpStrings[1].trim());
+ assertEquals("BPF ingress map: iif nat64Prefix v6Addr -> v4Addr oif",
+ dumpStrings[2].trim());
+ assertEquals("1000 /64:ff9b::/96 /2001:db8:0:b11::464 -> /192.0.0.46 1001",
+ dumpStrings[3].trim());
+ assertEquals("BPF egress map: iif v4Addr -> v6Addr nat64Prefix oif",
+ dumpStrings[4].trim());
+ assertEquals("1001 /192.0.0.46 -> /2001:db8:0:b11::464 /64:ff9b::/96 1000 ether",
+ dumpStrings[5].trim());
+ } else {
+ assertEquals(1, dumpStrings.length);
+ assertEquals("<not started>", dumpStrings[0].trim());
+ }
+ }
+
+ @Test
+ public void testDump() throws Exception {
+ final ClatCoordinator coordinator = makeClatCoordinator();
+ verifyDump(coordinator, false /* clatStarted */);
+ coordinator.clatStart(BASE_IFACE, NETID, NAT64_IP_PREFIX);
+ verifyDump(coordinator, true /* clatStarted */);
}
@Test
@@ -548,25 +558,18 @@
() -> coordinator.clatStart(BASE_IFACE, NETID, invalidPrefix));
}
- private void assertStartClat(final TestDependencies deps) throws Exception {
- final ClatCoordinator coordinator = new ClatCoordinator(deps);
- assertNotNull(coordinator.clatStart(BASE_IFACE, NETID, NAT64_IP_PREFIX));
- }
-
- private void assertNotStartClat(final TestDependencies deps) {
- // Expect that the injection function of TestDependencies causes clatStart() failed.
- final ClatCoordinator coordinator = new ClatCoordinator(deps);
- assertThrows(IOException.class,
- () -> coordinator.clatStart(BASE_IFACE, NETID, NAT64_IP_PREFIX));
- }
-
private void checkNotStartClat(final TestDependencies deps, final boolean needToCloseTunFd,
final boolean needToClosePacketSockFd, final boolean needToCloseRawSockFd)
throws Exception {
- // [1] Expect that modified TestDependencies can't start clatd.
- // Use precise check to make sure that there is no unexpected file descriptor closing.
clearInvocations(TUN_PFD, RAW_SOCK_PFD, PACKET_SOCK_PFD);
- assertNotStartClat(deps);
+
+ // [1] Expect that modified TestDependencies can't start clatd.
+ // Expect that the injection function of TestDependencies causes clatStart() failed.
+ final ClatCoordinator coordinatorWithBrokenDeps = new ClatCoordinator(deps);
+ assertThrows(IOException.class,
+ () -> coordinatorWithBrokenDeps.clatStart(BASE_IFACE, NETID, NAT64_IP_PREFIX));
+
+ // Use precise check to make sure that there is no unexpected file descriptor closing.
if (needToCloseTunFd) {
verify(TUN_PFD).close();
} else {
@@ -583,10 +586,15 @@
verify(RAW_SOCK_PFD, never()).close();
}
+ // Check that dump doesn't crash after any clat starting failure.
+ verifyDump(coordinatorWithBrokenDeps, false /* clatStarted */);
+
// [2] Expect that unmodified TestDependencies can start clatd.
// Used to make sure that the above modified TestDependencies has really broken the
// clatd starting.
- assertStartClat(new TestDependencies());
+ final ClatCoordinator coordinatorWithDefaultDeps = new ClatCoordinator(
+ new TestDependencies());
+ assertNotNull(coordinatorWithDefaultDeps.clatStart(BASE_IFACE, NETID, NAT64_IP_PREFIX));
}
// The following testNotStartClat* tests verifies bunches of code for unwinding the
@@ -609,7 +617,7 @@
class FailureDependencies extends TestDependencies {
@Override
public String generateIpv6Address(@NonNull String iface, @NonNull String v4,
- @NonNull String prefix64) throws IOException {
+ @NonNull String prefix64, int mark) throws IOException {
throw new IOException();
}
}
diff --git a/tests/unit/java/com/android/server/connectivity/FullScoreTest.kt b/tests/unit/java/com/android/server/connectivity/FullScoreTest.kt
index a194131..3520c5b 100644
--- a/tests/unit/java/com/android/server/connectivity/FullScoreTest.kt
+++ b/tests/unit/java/com/android/server/connectivity/FullScoreTest.kt
@@ -29,6 +29,7 @@
import com.android.server.connectivity.FullScore.MAX_CS_MANAGED_POLICY
import com.android.server.connectivity.FullScore.MIN_CS_MANAGED_POLICY
import com.android.server.connectivity.FullScore.POLICY_ACCEPT_UNVALIDATED
+import com.android.server.connectivity.FullScore.POLICY_EVER_EVALUATED
import com.android.server.connectivity.FullScore.POLICY_EVER_USER_SELECTED
import com.android.server.connectivity.FullScore.POLICY_IS_DESTROYED
import com.android.server.connectivity.FullScore.POLICY_IS_UNMETERED
@@ -56,6 +57,7 @@
vpn: Boolean = false,
onceChosen: Boolean = false,
acceptUnvalidated: Boolean = false,
+ everEvaluated: Boolean = true,
destroyed: Boolean = false
): FullScore {
val nac = NetworkAgentConfig.Builder().apply {
@@ -66,7 +68,8 @@
if (vpn) addTransportType(NetworkCapabilities.TRANSPORT_VPN)
if (validated) addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)
}.build()
- return mixInScore(nc, nac, validated, false /* yieldToBadWifi */, destroyed)
+ return mixInScore(nc, nac, validated, false /* avoidUnvalidated */,
+ false /* yieldToBadWifi */, everEvaluated, destroyed)
}
private val TAG = this::class.simpleName
@@ -122,6 +125,7 @@
assertTrue(ns.withPolicies(onceChosen = true).hasPolicy(POLICY_EVER_USER_SELECTED))
assertTrue(ns.withPolicies(acceptUnvalidated = true).hasPolicy(POLICY_ACCEPT_UNVALIDATED))
assertTrue(ns.withPolicies(destroyed = true).hasPolicy(POLICY_IS_DESTROYED))
+ assertTrue(ns.withPolicies(everEvaluated = true).hasPolicy(POLICY_EVER_EVALUATED))
}
@Test
@@ -148,4 +152,16 @@
assertNotEquals(ns3, ns1)
assertFalse(ns1.equals(ns4))
}
+
+ @Test
+ fun testDescribeDifferences() {
+ val ns1 = FullScore((1L shl POLICY_EVER_EVALUATED) or (1L shl POLICY_IS_VALIDATED),
+ KEEP_CONNECTED_NONE)
+ val ns2 = FullScore((1L shl POLICY_IS_VALIDATED) or (1L shl POLICY_IS_VPN) or
+ (1L shl POLICY_IS_DESTROYED), KEEP_CONNECTED_NONE)
+ assertEquals("-EVER_EVALUATED+IS_DESTROYED+IS_VPN",
+ ns2.describeDifferencesFrom(ns1))
+ assertEquals("-IS_DESTROYED-IS_VPN+EVER_EVALUATED",
+ ns1.describeDifferencesFrom(ns2))
+ }
}
diff --git a/tests/unit/java/com/android/server/connectivity/IpConnectivityMetricsTest.java b/tests/unit/java/com/android/server/connectivity/IpConnectivityMetricsTest.java
index ad8613f..719314a 100644
--- a/tests/unit/java/com/android/server/connectivity/IpConnectivityMetricsTest.java
+++ b/tests/unit/java/com/android/server/connectivity/IpConnectivityMetricsTest.java
@@ -23,6 +23,7 @@
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -47,6 +48,7 @@
import android.net.metrics.ValidationProbeEvent;
import android.os.Build;
import android.os.Parcelable;
+import android.os.SystemClock;
import android.system.OsConstants;
import android.test.suitebuilder.annotation.SmallTest;
import android.util.Base64;
@@ -138,7 +140,7 @@
private void logDefaultNetworkEvent(long timeMs, NetworkAgentInfo nai,
NetworkAgentInfo oldNai) {
final Network network = (nai != null) ? nai.network() : null;
- final boolean validated = (nai != null) ? nai.lastValidated : false;
+ final boolean validated = (nai != null) ? nai.isValidated() : false;
final LinkProperties lp = (nai != null) ? nai.linkProperties : null;
final NetworkCapabilities nc = (nai != null) ? nai.networkCapabilities : null;
@@ -614,7 +616,10 @@
when(nai.network()).thenReturn(new Network(netId));
nai.linkProperties = new LinkProperties();
nai.networkCapabilities = new NetworkCapabilities();
- nai.lastValidated = true;
+ nai.setValidated(true);
+ doReturn(true).when(nai).isValidated();
+ doReturn(SystemClock.elapsedRealtime()).when(nai).getFirstValidationTime();
+ doReturn(SystemClock.elapsedRealtime()).when(nai).getCurrentValidationTime();
for (int t : BitUtils.unpackBits(transports)) {
nai.networkCapabilities.addTransportType(t);
}
@@ -629,8 +634,6 @@
return nai;
}
-
-
static void verifySerialization(String want, String output) {
try {
byte[] got = Base64.decode(output, Base64.DEFAULT);
diff --git a/tests/unit/java/com/android/server/connectivity/LingerMonitorTest.java b/tests/unit/java/com/android/server/connectivity/LingerMonitorTest.java
index 58a7c89..0d371fa 100644
--- a/tests/unit/java/com/android/server/connectivity/LingerMonitorTest.java
+++ b/tests/unit/java/com/android/server/connectivity/LingerMonitorTest.java
@@ -21,6 +21,7 @@
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyBoolean;
import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
@@ -30,6 +31,7 @@
import android.app.PendingIntent;
import android.content.Context;
+import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.net.ConnectivityManager;
import android.net.ConnectivityResources;
@@ -85,12 +87,14 @@
@Mock NetworkNotificationManager mNotifier;
@Mock Resources mResources;
@Mock QosCallbackTracker mQosCallbackTracker;
+ @Mock PackageManager mPackageManager;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
when(mCtx.getResources()).thenReturn(mResources);
when(mCtx.getPackageName()).thenReturn("com.android.server.connectivity");
+ doReturn(mPackageManager).when(mCtx).getPackageManager();
ConnectivityResources.setResourcesContextForTest(mCtx);
mMonitor = new TestableLingerMonitor(mCtx, mNotifier, HIGH_DAILY_LIMIT, HIGH_RATE_LIMIT);
@@ -272,9 +276,8 @@
public void testIgnoreNeverValidatedNetworks() {
setNotificationType(LingerMonitor.NOTIFY_TYPE_TOAST);
setNotificationSwitch(transition(WIFI, CELLULAR));
- NetworkAgentInfo from = wifiNai(100);
+ NetworkAgentInfo from = wifiNai(100, false /* setEverValidated */);
NetworkAgentInfo to = cellNai(101);
- from.everValidated = false;
mMonitor.noteLingerDefaultNetwork(from, to);
verifyNoNotifications();
@@ -286,7 +289,7 @@
setNotificationSwitch(transition(WIFI, CELLULAR));
NetworkAgentInfo from = wifiNai(100);
NetworkAgentInfo to = cellNai(101);
- from.lastValidated = true;
+ from.setValidated(true);
mMonitor.noteLingerDefaultNetwork(from, to);
verifyNoNotifications();
@@ -363,7 +366,8 @@
eq(NotificationType.NETWORK_SWITCH), eq(from), eq(to), any(), eq(true));
}
- NetworkAgentInfo nai(int netId, int transport, int networkType, String networkTypeName) {
+ NetworkAgentInfo nai(int netId, int transport, int networkType, String networkTypeName,
+ boolean setEverValidated) {
NetworkInfo info = new NetworkInfo(networkType, 0, networkTypeName, "");
NetworkCapabilities caps = new NetworkCapabilities();
caps.addCapability(0);
@@ -373,18 +377,32 @@
mCtx, null, new NetworkAgentConfig.Builder().build(), mConnService, mNetd,
mDnsResolver, NetworkProvider.ID_NONE, Binder.getCallingUid(), TEST_LINGER_DELAY_MS,
mQosCallbackTracker, new ConnectivityService.Dependencies());
- nai.everValidated = true;
+ if (setEverValidated) {
+ // As tests in this class deal with testing lingering, most tests are interested
+ // in networks that can be lingered, and therefore must have validated in the past.
+ // Thus, pretend the network validated once, then became invalidated.
+ nai.setValidated(true);
+ nai.setValidated(false);
+ }
return nai;
}
NetworkAgentInfo wifiNai(int netId) {
+ return wifiNai(netId, true /* setEverValidated */);
+ }
+
+ NetworkAgentInfo wifiNai(int netId, boolean setEverValidated) {
return nai(netId, NetworkCapabilities.TRANSPORT_WIFI,
- ConnectivityManager.TYPE_WIFI, WIFI);
+ ConnectivityManager.TYPE_WIFI, WIFI, setEverValidated);
}
NetworkAgentInfo cellNai(int netId) {
+ return cellNai(netId, true /* setEverValidated */);
+ }
+
+ NetworkAgentInfo cellNai(int netId, boolean setEverValidated) {
return nai(netId, NetworkCapabilities.TRANSPORT_CELLULAR,
- ConnectivityManager.TYPE_MOBILE, CELLULAR);
+ ConnectivityManager.TYPE_MOBILE, CELLULAR, setEverValidated);
}
public static class TestableLingerMonitor extends LingerMonitor {
diff --git a/tests/unit/java/android/net/util/MultinetworkPolicyTrackerTest.kt b/tests/unit/java/com/android/server/connectivity/MultinetworkPolicyTrackerTest.kt
similarity index 74%
rename from tests/unit/java/android/net/util/MultinetworkPolicyTrackerTest.kt
rename to tests/unit/java/com/android/server/connectivity/MultinetworkPolicyTrackerTest.kt
index 576b8d3..b52e8a8 100644
--- a/tests/unit/java/android/net/util/MultinetworkPolicyTrackerTest.kt
+++ b/tests/unit/java/com/android/server/connectivity/MultinetworkPolicyTrackerTest.kt
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.net.util
+package com.android.server.connectivity
import android.content.Context
import android.content.res.Resources
@@ -24,8 +24,10 @@
import android.net.ConnectivityResources
import android.net.ConnectivitySettingsManager.NETWORK_AVOID_BAD_WIFI
import android.net.ConnectivitySettingsManager.NETWORK_METERED_MULTIPATH_PREFERENCE
-import android.net.util.MultinetworkPolicyTracker.ActiveDataSubscriptionIdListener
+import com.android.server.connectivity.MultinetworkPolicyTracker.ActiveDataSubscriptionIdListener
import android.os.Build
+import android.os.Handler
+import android.os.test.TestLooper
import android.provider.Settings
import android.telephony.SubscriptionInfo
import android.telephony.SubscriptionManager
@@ -34,18 +36,18 @@
import androidx.test.filters.SmallTest
import com.android.connectivity.resources.R
import com.android.internal.util.test.FakeSettingsProvider
+import com.android.modules.utils.build.SdkLevel
import com.android.testutils.DevSdkIgnoreRule
import com.android.testutils.DevSdkIgnoreRunner
import org.junit.After
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
+import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentCaptor
import org.mockito.ArgumentMatchers.anyInt
-import org.mockito.ArgumentMatchers.argThat
-import org.mockito.ArgumentMatchers.eq
import org.mockito.Mockito.any
import org.mockito.Mockito.doCallRealMethod
import org.mockito.Mockito.doReturn
@@ -53,20 +55,21 @@
import org.mockito.Mockito.times
import org.mockito.Mockito.verify
+const val HANDLER_TIMEOUT_MS = 400
+
/**
* Tests for [MultinetworkPolicyTracker].
*
* Build, install and run with:
- * atest android.net.util.MultinetworkPolicyTrackerTest
+ * atest FrameworksNetTest:MultinetworkPolicyTrackerTest
*/
@RunWith(DevSdkIgnoreRunner::class)
@SmallTest
@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.R)
class MultinetworkPolicyTrackerTest {
private val resources = mock(Resources::class.java).also {
- doReturn(R.integer.config_networkAvoidBadWifi).`when`(it).getIdentifier(
- eq("config_networkAvoidBadWifi"), eq("integer"), any())
doReturn(0).`when`(it).getInteger(R.integer.config_networkAvoidBadWifi)
+ doReturn(0).`when`(it).getInteger(R.integer.config_activelyPreferBadWifi)
}
private val telephonyManager = mock(TelephonyManager::class.java)
private val subscriptionManager = mock(SubscriptionManager::class.java).also {
@@ -90,7 +93,11 @@
Settings.Global.putString(resolver, NETWORK_AVOID_BAD_WIFI, "1")
ConnectivityResources.setResourcesContextForTest(it)
}
- private val tracker = MultinetworkPolicyTracker(context, null /* handler */)
+ private val csLooper = TestLooper()
+ private val handler = Handler(csLooper.looper)
+ private val trackerDependencies = MultinetworkPolicyTrackerTestDependencies(resources)
+ private val tracker = MultinetworkPolicyTracker(context, handler,
+ null /* avoidBadWifiCallback */, trackerDependencies)
private fun assertMultipathPreference(preference: Int) {
Settings.Global.putString(resolver, NETWORK_METERED_MULTIPATH_PREFERENCE,
@@ -99,6 +106,11 @@
assertEquals(preference, tracker.meteredMultipathPreference)
}
+ @Before
+ fun setUp() {
+ tracker.start()
+ }
+
@After
fun tearDown() {
ConnectivityResources.setResourcesContextForTest(null)
@@ -113,6 +125,7 @@
@Test
fun testUpdateAvoidBadWifi() {
+ doReturn(0).`when`(resources).getInteger(R.integer.config_activelyPreferBadWifi)
Settings.Global.putString(resolver, NETWORK_AVOID_BAD_WIFI, "0")
assertTrue(tracker.updateAvoidBadWifi())
assertFalse(tracker.avoidBadWifi)
@@ -120,6 +133,36 @@
doReturn(1).`when`(resources).getInteger(R.integer.config_networkAvoidBadWifi)
assertTrue(tracker.updateAvoidBadWifi())
assertTrue(tracker.avoidBadWifi)
+
+ if (SdkLevel.isAtLeastU()) {
+ // On U+, the system always prefers bad wifi.
+ assertTrue(tracker.activelyPreferBadWifi)
+ } else {
+ assertFalse(tracker.activelyPreferBadWifi)
+ }
+
+ doReturn(1).`when`(resources).getInteger(R.integer.config_activelyPreferBadWifi)
+ if (SdkLevel.isAtLeastU()) {
+ // On U+, this didn't change the setting
+ assertFalse(tracker.updateAvoidBadWifi())
+ } else {
+ // On T-, this must have changed the setting
+ assertTrue(tracker.updateAvoidBadWifi())
+ }
+ // In all cases, now the system actively prefers bad wifi
+ assertTrue(tracker.activelyPreferBadWifi)
+
+ // Remaining tests are only useful on T-, which support both the old and new mode.
+ if (SdkLevel.isAtLeastU()) return
+
+ doReturn(0).`when`(resources).getInteger(R.integer.config_activelyPreferBadWifi)
+ assertTrue(tracker.updateAvoidBadWifi())
+ assertFalse(tracker.activelyPreferBadWifi)
+
+ // Simulate update of device config
+ trackerDependencies.putConfigActivelyPreferBadWifi(1)
+ csLooper.dispatchAll()
+ assertTrue(tracker.activelyPreferBadWifi)
}
@Test
@@ -138,6 +181,8 @@
Settings.Global.putString(resolver, NETWORK_METERED_MULTIPATH_PREFERENCE,
MULTIPATH_PREFERENCE_PERFORMANCE.toString())
+ assertTrue(tracker.avoidBadWifi)
+
val listenerCaptor = ArgumentCaptor.forClass(
ActiveDataSubscriptionIdListener::class.java)
verify(telephonyManager, times(1))
@@ -145,10 +190,6 @@
val listener = listenerCaptor.value
listener.onActiveDataSubscriptionIdChanged(testSubId)
- // Check it get resource value with test sub id.
- verify(subscriptionManager, times(1)).getActiveSubscriptionInfo(testSubId)
- verify(context).createConfigurationContext(argThat { it.mcc == 310 && it.mnc == 210 })
-
// Check if avoidBadWifi and meteredMultipathPreference values have been updated.
assertFalse(tracker.avoidBadWifi)
assertEquals(MULTIPATH_PREFERENCE_PERFORMANCE, tracker.meteredMultipathPreference)
diff --git a/tests/unit/java/com/android/server/connectivity/MultinetworkPolicyTrackerTestDependencies.kt b/tests/unit/java/com/android/server/connectivity/MultinetworkPolicyTrackerTestDependencies.kt
new file mode 100644
index 0000000..744c020
--- /dev/null
+++ b/tests/unit/java/com/android/server/connectivity/MultinetworkPolicyTrackerTestDependencies.kt
@@ -0,0 +1,47 @@
+package com.android.server.connectivity
+
+import android.content.res.Resources
+import android.net.ConnectivityResources
+import android.provider.DeviceConfig
+import android.provider.DeviceConfig.NAMESPACE_CONNECTIVITY
+import android.provider.DeviceConfig.OnPropertiesChangedListener
+import com.android.internal.annotations.GuardedBy
+import com.android.server.connectivity.MultinetworkPolicyTracker.CONFIG_ACTIVELY_PREFER_BAD_WIFI
+import java.util.concurrent.Executor
+
+class MultinetworkPolicyTrackerTestDependencies(private val resources: Resources) :
+ MultinetworkPolicyTracker.Dependencies() {
+ @GuardedBy("listeners")
+ private var configActivelyPreferBadWifi = 0
+ // TODO : move this to an actual fake device config object
+ @GuardedBy("listeners")
+ private val listeners = mutableListOf<Pair<Executor, OnPropertiesChangedListener>>()
+
+ fun putConfigActivelyPreferBadWifi(value: Int) {
+ synchronized(listeners) {
+ if (value == configActivelyPreferBadWifi) return
+ configActivelyPreferBadWifi = value
+ val p = DeviceConfig.Properties(NAMESPACE_CONNECTIVITY,
+ mapOf(CONFIG_ACTIVELY_PREFER_BAD_WIFI to value.toString()))
+ listeners.forEach { (executor, listener) ->
+ executor.execute { listener.onPropertiesChanged(p) }
+ }
+ }
+ }
+
+ override fun getConfigActivelyPreferBadWifi(): Int {
+ return synchronized(listeners) { configActivelyPreferBadWifi }
+ }
+
+ override fun addOnDevicePropertiesChangedListener(
+ e: Executor,
+ listener: OnPropertiesChangedListener
+ ) {
+ synchronized(listeners) {
+ listeners.add(e to listener)
+ }
+ }
+
+ override fun getResourcesForActiveSubId(res: ConnectivityResources, id: Int): Resources =
+ resources
+}
diff --git a/tests/unit/java/com/android/server/connectivity/NetworkRankerTest.kt b/tests/unit/java/com/android/server/connectivity/NetworkRankerTest.kt
index 6f9f430..1e3f389 100644
--- a/tests/unit/java/com/android/server/connectivity/NetworkRankerTest.kt
+++ b/tests/unit/java/com/android/server/connectivity/NetworkRankerTest.kt
@@ -17,31 +17,38 @@
package com.android.server.connectivity
import android.net.NetworkCapabilities
+import android.net.NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL as NET_CAP_PORTAL
import android.net.NetworkCapabilities.TRANSPORT_CELLULAR
import android.net.NetworkCapabilities.TRANSPORT_WIFI
import android.net.NetworkScore.KEEP_CONNECTED_NONE
-import android.net.NetworkScore.POLICY_EXITING
-import android.net.NetworkScore.POLICY_TRANSPORT_PRIMARY
-import android.net.NetworkScore.POLICY_YIELD_TO_BAD_WIFI
+import android.net.NetworkScore.POLICY_EXITING as EXITING
+import android.net.NetworkScore.POLICY_TRANSPORT_PRIMARY as PRIMARY
+import android.net.NetworkScore.POLICY_YIELD_TO_BAD_WIFI as YIELD_TO_BAD_WIFI
import android.os.Build
import androidx.test.filters.SmallTest
-import com.android.server.connectivity.FullScore.POLICY_EVER_VALIDATED_NOT_AVOIDED_WHEN_BAD
-import com.android.server.connectivity.FullScore.POLICY_IS_VALIDATED
+import com.android.connectivity.resources.R
+import com.android.server.connectivity.FullScore.POLICY_AVOIDED_WHEN_UNVALIDATED as AVOIDED_UNVALID
+import com.android.server.connectivity.FullScore.POLICY_EVER_EVALUATED as EVER_EVALUATED
+import com.android.server.connectivity.FullScore.POLICY_EVER_VALIDATED as EVER_VALIDATED
+import com.android.server.connectivity.FullScore.POLICY_IS_VALIDATED as IS_VALIDATED
import com.android.testutils.DevSdkIgnoreRule
-import com.android.testutils.DevSdkIgnoreRunner
+import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
import kotlin.test.assertEquals
private fun score(vararg policies: Int) = FullScore(
policies.fold(0L) { acc, e -> acc or (1L shl e) }, KEEP_CONNECTED_NONE)
-private fun caps(transport: Int) = NetworkCapabilities.Builder().addTransportType(transport).build()
+private fun caps(transport: Int, vararg capabilities: Int) =
+ NetworkCapabilities.Builder().addTransportType(transport).apply {
+ capabilities.forEach { addCapability(it) }
+ }.build()
@SmallTest
-@RunWith(DevSdkIgnoreRunner::class)
-@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.R)
-class NetworkRankerTest {
- private val mRanker = NetworkRanker()
+@RunWith(Parameterized::class)
+class NetworkRankerTest(private val activelyPreferBadWifi: Boolean) {
+ private val mRanker = NetworkRanker(NetworkRanker.Configuration(activelyPreferBadWifi))
private class TestScore(private val sc: FullScore, private val nc: NetworkCapabilities)
: NetworkRanker.Scoreable {
@@ -49,124 +56,144 @@
override fun getCapsNoCopy(): NetworkCapabilities = nc
}
+ @get:Rule
+ val mIgnoreRule: DevSdkIgnoreRule = DevSdkIgnoreRule(ignoreClassUpTo = Build.VERSION_CODES.R)
+
+ companion object {
+ @JvmStatic
+ @Parameterized.Parameters
+ fun ranker() = listOf(true, false)
+ }
+
+ // Helpers to shorten syntax
+ private fun rank(vararg scores: TestScore) =
+ mRanker.getBestNetworkByPolicy(scores.toList(), null /* currentSatisfier */)
+ val CAPS_CELL = caps(TRANSPORT_CELLULAR)
+ val CAPS_WIFI = caps(TRANSPORT_WIFI)
+ val CAPS_WIFI_PORTAL = caps(TRANSPORT_WIFI, NET_CAP_PORTAL)
+
@Test
- fun testYieldToBadWiFiOneCell() {
+ fun testYieldToBadWiFi_oneCell() {
// Only cell, it wins
- val winner = TestScore(score(POLICY_YIELD_TO_BAD_WIFI, POLICY_IS_VALIDATED),
- caps(TRANSPORT_CELLULAR))
- val scores = listOf(winner)
- assertEquals(winner, mRanker.getBestNetworkByPolicy(scores, null))
+ val cell = TestScore(score(EVER_EVALUATED, YIELD_TO_BAD_WIFI, IS_VALIDATED), CAPS_CELL)
+ assertEquals(cell, rank(cell))
}
@Test
- fun testYieldToBadWiFiOneCellOneBadWiFi() {
+ fun testPreferBadWifi_oneCellOneEvaluatingWifi() {
+ val wifi = TestScore(score(), caps(TRANSPORT_WIFI))
+ val cell = TestScore(score(YIELD_TO_BAD_WIFI, IS_VALIDATED, EVER_EVALUATED), CAPS_CELL)
+ assertEquals(cell, rank(wifi, cell))
+ }
+
+ @Test
+ fun testYieldToBadWiFi_oneCellOneBadWiFi() {
// Bad wifi wins against yielding validated cell
- val winner = TestScore(score(POLICY_EVER_VALIDATED_NOT_AVOIDED_WHEN_BAD),
- caps(TRANSPORT_WIFI))
- val scores = listOf(
- winner,
- TestScore(score(POLICY_YIELD_TO_BAD_WIFI, POLICY_IS_VALIDATED),
- caps(TRANSPORT_CELLULAR))
- )
- assertEquals(winner, mRanker.getBestNetworkByPolicy(scores, null))
+ val badWifi = TestScore(score(EVER_EVALUATED, EVER_VALIDATED), CAPS_WIFI)
+ val cell = TestScore(score(EVER_EVALUATED, YIELD_TO_BAD_WIFI, IS_VALIDATED), CAPS_CELL)
+ assertEquals(badWifi, rank(badWifi, cell))
}
@Test
- fun testYieldToBadWiFiOneCellTwoBadWiFi() {
+ fun testPreferBadWifi_oneCellOneBadWifi() {
+ val badWifi = TestScore(score(EVER_EVALUATED), CAPS_WIFI)
+ val cell = TestScore(score(EVER_EVALUATED, YIELD_TO_BAD_WIFI, IS_VALIDATED), CAPS_CELL)
+ val winner = if (activelyPreferBadWifi) badWifi else cell
+ assertEquals(winner, rank(badWifi, cell))
+ }
+
+ @Test
+ fun testPreferBadWifi_oneCellOneCaptivePortalWifi() {
+ val portalWifi = TestScore(score(EVER_EVALUATED), CAPS_WIFI_PORTAL)
+ val cell = TestScore(score(EVER_EVALUATED, YIELD_TO_BAD_WIFI, IS_VALIDATED), CAPS_CELL)
+ assertEquals(cell, rank(portalWifi, cell))
+ }
+
+ @Test
+ fun testYieldToBadWifi_oneCellOneCaptivePortalWifiThatClosed() {
+ val portalWifiClosed = TestScore(score(EVER_EVALUATED, EVER_VALIDATED), CAPS_WIFI_PORTAL)
+ val cell = TestScore(score(EVER_EVALUATED, YIELD_TO_BAD_WIFI, IS_VALIDATED), CAPS_CELL)
+ assertEquals(portalWifiClosed, rank(portalWifiClosed, cell))
+ }
+
+ @Test
+ fun testYieldToBadWifi_avoidUnvalidated() {
+ // Bad wifi avoided when unvalidated loses against yielding validated cell
+ val cell = TestScore(score(EVER_EVALUATED, YIELD_TO_BAD_WIFI, IS_VALIDATED), CAPS_CELL)
+ val avoidedWifi = TestScore(score(EVER_EVALUATED, EVER_VALIDATED, AVOIDED_UNVALID),
+ CAPS_WIFI)
+ assertEquals(cell, rank(cell, avoidedWifi))
+ }
+
+ @Test
+ fun testYieldToBadWiFi_oneCellTwoBadWiFi() {
// Bad wifi wins against yielding validated cell. Prefer the one that's primary.
- val winner = TestScore(score(POLICY_EVER_VALIDATED_NOT_AVOIDED_WHEN_BAD,
- POLICY_TRANSPORT_PRIMARY), caps(TRANSPORT_WIFI))
- val scores = listOf(
- winner,
- TestScore(score(POLICY_EVER_VALIDATED_NOT_AVOIDED_WHEN_BAD),
- caps(TRANSPORT_WIFI)),
- TestScore(score(POLICY_YIELD_TO_BAD_WIFI, POLICY_IS_VALIDATED),
- caps(TRANSPORT_CELLULAR))
- )
- assertEquals(winner, mRanker.getBestNetworkByPolicy(scores, null))
+ val primaryBadWifi = TestScore(score(EVER_EVALUATED, EVER_VALIDATED, PRIMARY), CAPS_WIFI)
+ val secondaryBadWifi = TestScore(score(EVER_EVALUATED, EVER_VALIDATED), CAPS_WIFI)
+ val cell = TestScore(score(EVER_EVALUATED, YIELD_TO_BAD_WIFI, IS_VALIDATED), CAPS_CELL)
+ assertEquals(primaryBadWifi, rank(primaryBadWifi, secondaryBadWifi, cell))
}
@Test
- fun testYieldToBadWiFiOneCellTwoBadWiFiOneNotAvoided() {
+ fun testYieldToBadWiFi_oneCellTwoBadWiFiOneNotAvoided() {
// Bad wifi ever validated wins against bad wifi that never was validated (or was
// avoided when bad).
- val winner = TestScore(score(POLICY_EVER_VALIDATED_NOT_AVOIDED_WHEN_BAD),
- caps(TRANSPORT_WIFI))
- val scores = listOf(
- winner,
- TestScore(score(), caps(TRANSPORT_WIFI)),
- TestScore(score(POLICY_YIELD_TO_BAD_WIFI, POLICY_IS_VALIDATED),
- caps(TRANSPORT_CELLULAR))
- )
- assertEquals(winner, mRanker.getBestNetworkByPolicy(scores, null))
+ val badWifi = TestScore(score(EVER_EVALUATED, EVER_VALIDATED), CAPS_WIFI)
+ val neverValidatedWifi = TestScore(score(), CAPS_WIFI)
+ val cell = TestScore(score(EVER_EVALUATED, YIELD_TO_BAD_WIFI, IS_VALIDATED), CAPS_CELL)
+ assertEquals(badWifi, rank(badWifi, neverValidatedWifi, cell))
}
@Test
- fun testYieldToBadWiFiOneCellOneBadWiFiOneGoodWiFi() {
+ fun testYieldToBadWiFi_oneCellOneBadWiFiOneGoodWiFi() {
// Good wifi wins
- val winner = TestScore(score(POLICY_EVER_VALIDATED_NOT_AVOIDED_WHEN_BAD,
- POLICY_IS_VALIDATED), caps(TRANSPORT_WIFI))
- val scores = listOf(
- winner,
- TestScore(score(POLICY_EVER_VALIDATED_NOT_AVOIDED_WHEN_BAD,
- POLICY_TRANSPORT_PRIMARY), caps(TRANSPORT_WIFI)),
- TestScore(score(POLICY_YIELD_TO_BAD_WIFI, POLICY_IS_VALIDATED),
- caps(TRANSPORT_CELLULAR))
- )
- assertEquals(winner, mRanker.getBestNetworkByPolicy(scores, null))
+ val goodWifi = TestScore(score(EVER_EVALUATED, EVER_VALIDATED, IS_VALIDATED), CAPS_WIFI)
+ val badWifi = TestScore(score(EVER_EVALUATED, EVER_VALIDATED, PRIMARY), CAPS_WIFI)
+ val cell = TestScore(score(EVER_EVALUATED, YIELD_TO_BAD_WIFI, IS_VALIDATED), CAPS_CELL)
+ assertEquals(goodWifi, rank(goodWifi, badWifi, cell))
}
@Test
- fun testYieldToBadWiFiTwoCellsOneBadWiFi() {
+ fun testPreferBadWifi_oneCellOneBadWifiOneEvaluatingWifi() {
+ val cell = TestScore(score(EVER_EVALUATED, YIELD_TO_BAD_WIFI, IS_VALIDATED), CAPS_CELL)
+ val badWifi = TestScore(score(EVER_EVALUATED), CAPS_WIFI)
+ val evaluatingWifi = TestScore(score(), CAPS_WIFI)
+ val winner = if (activelyPreferBadWifi) badWifi else cell
+ assertEquals(winner, rank(cell, badWifi, evaluatingWifi))
+ }
+
+ @Test
+ fun testYieldToBadWiFi_twoCellsOneBadWiFi() {
// Cell that doesn't yield wins over cell that yields and bad wifi
- val winner = TestScore(score(POLICY_IS_VALIDATED), caps(TRANSPORT_CELLULAR))
- val scores = listOf(
- winner,
- TestScore(score(POLICY_EVER_VALIDATED_NOT_AVOIDED_WHEN_BAD,
- POLICY_TRANSPORT_PRIMARY), caps(TRANSPORT_WIFI)),
- TestScore(score(POLICY_YIELD_TO_BAD_WIFI, POLICY_IS_VALIDATED),
- caps(TRANSPORT_CELLULAR))
- )
- assertEquals(winner, mRanker.getBestNetworkByPolicy(scores, null))
+ val cellNotYield = TestScore(score(EVER_EVALUATED, IS_VALIDATED), CAPS_CELL)
+ val badWifi = TestScore(score(EVER_EVALUATED, EVER_VALIDATED, PRIMARY), CAPS_WIFI)
+ val cellYield = TestScore(score(EVER_EVALUATED, YIELD_TO_BAD_WIFI, IS_VALIDATED), CAPS_CELL)
+ assertEquals(cellNotYield, rank(cellNotYield, badWifi, cellYield))
}
@Test
- fun testYieldToBadWiFiTwoCellsOneBadWiFiOneGoodWiFi() {
+ fun testYieldToBadWiFi_twoCellsOneBadWiFiOneGoodWiFi() {
// Good wifi wins over cell that doesn't yield and cell that yields
- val winner = TestScore(score(POLICY_IS_VALIDATED), caps(TRANSPORT_WIFI))
- val scores = listOf(
- winner,
- TestScore(score(POLICY_EVER_VALIDATED_NOT_AVOIDED_WHEN_BAD,
- POLICY_TRANSPORT_PRIMARY), caps(TRANSPORT_WIFI)),
- TestScore(score(POLICY_IS_VALIDATED), caps(TRANSPORT_CELLULAR)),
- TestScore(score(POLICY_YIELD_TO_BAD_WIFI, POLICY_IS_VALIDATED),
- caps(TRANSPORT_CELLULAR))
- )
- assertEquals(winner, mRanker.getBestNetworkByPolicy(scores, null))
+ val goodWifi = TestScore(score(EVER_EVALUATED, IS_VALIDATED), CAPS_WIFI)
+ val badWifi = TestScore(score(EVER_EVALUATED, EVER_VALIDATED, PRIMARY), CAPS_WIFI)
+ val cellNotYield = TestScore(score(EVER_EVALUATED, IS_VALIDATED), CAPS_CELL)
+ val cellYield = TestScore(score(EVER_EVALUATED, YIELD_TO_BAD_WIFI, IS_VALIDATED), CAPS_CELL)
+ assertEquals(goodWifi, rank(goodWifi, badWifi, cellNotYield, cellYield))
}
@Test
- fun testYieldToBadWiFiOneExitingGoodWiFi() {
+ fun testYieldToBadWiFi_oneExitingGoodWiFi() {
// Yielding cell wins over good exiting wifi
- val winner = TestScore(score(POLICY_YIELD_TO_BAD_WIFI, POLICY_IS_VALIDATED),
- caps(TRANSPORT_CELLULAR))
- val scores = listOf(
- winner,
- TestScore(score(POLICY_IS_VALIDATED, POLICY_EXITING), caps(TRANSPORT_WIFI))
- )
- assertEquals(winner, mRanker.getBestNetworkByPolicy(scores, null))
+ val cell = TestScore(score(EVER_EVALUATED, YIELD_TO_BAD_WIFI, IS_VALIDATED), CAPS_CELL)
+ val exitingWifi = TestScore(score(EVER_EVALUATED, IS_VALIDATED, EXITING), CAPS_WIFI)
+ assertEquals(cell, rank(cell, exitingWifi))
}
@Test
- fun testYieldToBadWiFiOneExitingBadWiFi() {
+ fun testYieldToBadWiFi_oneExitingBadWiFi() {
// Yielding cell wins over bad exiting wifi
- val winner = TestScore(score(POLICY_YIELD_TO_BAD_WIFI, POLICY_IS_VALIDATED),
- caps(TRANSPORT_CELLULAR))
- val scores = listOf(
- winner,
- TestScore(score(POLICY_EVER_VALIDATED_NOT_AVOIDED_WHEN_BAD,
- POLICY_EXITING), caps(TRANSPORT_WIFI))
- )
- assertEquals(winner, mRanker.getBestNetworkByPolicy(scores, null))
+ val cell = TestScore(score(EVER_EVALUATED, YIELD_TO_BAD_WIFI, IS_VALIDATED), CAPS_CELL)
+ val badExitingWifi = TestScore(score(EVER_EVALUATED, EVER_VALIDATED, EXITING), CAPS_WIFI)
+ assertEquals(cell, rank(cell, badExitingWifi))
}
}
diff --git a/tests/unit/java/com/android/server/connectivity/VpnTest.java b/tests/unit/java/com/android/server/connectivity/VpnTest.java
index f159859..3c23d7b 100644
--- a/tests/unit/java/com/android/server/connectivity/VpnTest.java
+++ b/tests/unit/java/com/android/server/connectivity/VpnTest.java
@@ -20,6 +20,8 @@
import static android.Manifest.permission.CONTROL_VPN;
import static android.content.pm.PackageManager.PERMISSION_DENIED;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+import static android.net.ConnectivityDiagnosticsManager.ConnectivityDiagnosticsCallback;
+import static android.net.ConnectivityDiagnosticsManager.DataStallReport;
import static android.net.ConnectivityManager.NetworkCallback;
import static android.net.INetd.IF_STATE_DOWN;
import static android.net.INetd.IF_STATE_UP;
@@ -29,7 +31,7 @@
import static android.os.Build.VERSION_CODES.S_V2;
import static android.os.UserHandle.PER_USER_RANGE;
-import static com.android.modules.utils.build.SdkLevel.isAtLeastT;
+import static com.android.net.module.util.NetworkStackConstants.IPV6_MIN_MTU;
import static com.android.testutils.Cleanup.testAndCleanup;
import static com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo;
import static com.android.testutils.MiscAsserts.assertThrows;
@@ -41,7 +43,6 @@
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
-import static org.junit.Assume.assumeTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
@@ -78,6 +79,7 @@
import android.content.pm.ServiceInfo;
import android.content.pm.UserInfo;
import android.content.res.Resources;
+import android.net.ConnectivityDiagnosticsManager;
import android.net.ConnectivityManager;
import android.net.INetd;
import android.net.Ikev2VpnProfile;
@@ -92,6 +94,7 @@
import android.net.LinkProperties;
import android.net.LocalSocket;
import android.net.Network;
+import android.net.NetworkAgent;
import android.net.NetworkAgentConfig;
import android.net.NetworkCapabilities;
import android.net.NetworkInfo.DetailedState;
@@ -117,6 +120,7 @@
import android.os.ConditionVariable;
import android.os.INetworkManagementService;
import android.os.ParcelFileDescriptor;
+import android.os.PersistableBundle;
import android.os.PowerWhitelistManager;
import android.os.Process;
import android.os.UserHandle;
@@ -136,7 +140,6 @@
import com.android.internal.net.VpnConfig;
import com.android.internal.net.VpnProfile;
import com.android.internal.util.HexDump;
-import com.android.modules.utils.build.SdkLevel;
import com.android.server.DeviceIdleInternal;
import com.android.server.IpSecService;
import com.android.server.VpnTestBase;
@@ -203,6 +206,7 @@
private static final byte[] TEST_VPN_PSK = "psk".getBytes();
private static final int IP4_PREFIX_LEN = 32;
+ private static final int IP6_PREFIX_LEN = 64;
private static final int MIN_PORT = 0;
private static final int MAX_PORT = 65535;
@@ -216,15 +220,28 @@
InetAddresses.parseNumericAddress("192.0.2.201");
private static final InetAddress TEST_VPN_INTERNAL_IP =
InetAddresses.parseNumericAddress("198.51.100.10");
+ private static final InetAddress TEST_VPN_INTERNAL_IP6 =
+ InetAddresses.parseNumericAddress("2001:db8::1");
private static final InetAddress TEST_VPN_INTERNAL_DNS =
InetAddresses.parseNumericAddress("8.8.8.8");
+ private static final InetAddress TEST_VPN_INTERNAL_DNS6 =
+ InetAddresses.parseNumericAddress("2001:4860:4860::8888");
private static final IkeTrafficSelector IN_TS =
new IkeTrafficSelector(MIN_PORT, MAX_PORT, TEST_VPN_INTERNAL_IP, TEST_VPN_INTERNAL_IP);
+ private static final IkeTrafficSelector IN_TS6 =
+ new IkeTrafficSelector(
+ MIN_PORT, MAX_PORT, TEST_VPN_INTERNAL_IP6, TEST_VPN_INTERNAL_IP6);
private static final IkeTrafficSelector OUT_TS =
new IkeTrafficSelector(MIN_PORT, MAX_PORT,
InetAddresses.parseNumericAddress("0.0.0.0"),
InetAddresses.parseNumericAddress("255.255.255.255"));
+ private static final IkeTrafficSelector OUT_TS6 =
+ new IkeTrafficSelector(
+ MIN_PORT,
+ MAX_PORT,
+ InetAddresses.parseNumericAddress("::"),
+ InetAddresses.parseNumericAddress("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"));
private static final Network TEST_NETWORK = new Network(Integer.MAX_VALUE);
private static final Network TEST_NETWORK_2 = new Network(Integer.MAX_VALUE - 1);
@@ -248,6 +265,7 @@
@Mock private Vpn.Ikev2SessionCreator mIkev2SessionCreator;
@Mock private Vpn.VpnNetworkAgentWrapper mMockNetworkAgent;
@Mock private ConnectivityManager mConnectivityManager;
+ @Mock private ConnectivityDiagnosticsManager mCdm;
@Mock private IpSecService mIpSecService;
@Mock private VpnProfileStore mVpnProfileStore;
@Mock private ScheduledThreadPoolExecutor mExecutor;
@@ -275,6 +293,10 @@
mIpSecManager = new IpSecManager(mContext, mIpSecService);
mTestDeps = spy(new TestDeps());
+ doReturn(IPV6_MIN_MTU)
+ .when(mTestDeps)
+ .calculateVpnMtu(any(), anyInt(), anyInt(), anyBoolean());
+ doReturn(1500).when(mTestDeps).getJavaNetworkInterfaceMtu(any(), anyInt());
when(mContext.getPackageManager()).thenReturn(mPackageManager);
setMockedPackages(sPackages);
@@ -286,6 +308,8 @@
mockService(NotificationManager.class, Context.NOTIFICATION_SERVICE, mNotificationManager);
mockService(ConnectivityManager.class, Context.CONNECTIVITY_SERVICE, mConnectivityManager);
mockService(IpSecManager.class, Context.IPSEC_SERVICE, mIpSecManager);
+ mockService(ConnectivityDiagnosticsManager.class, Context.CONNECTIVITY_DIAGNOSTICS_SERVICE,
+ mCdm);
when(mContext.getString(R.string.config_customVpnAlwaysOnDisconnectedDialogComponent))
.thenReturn(Resources.getSystem().getString(
R.string.config_customVpnAlwaysOnDisconnectedDialogComponent));
@@ -311,6 +335,8 @@
IpSecManager.Status.OK, TEST_TUNNEL_RESOURCE_ID, TEST_IFACE_NAME);
when(mIpSecService.createTunnelInterface(any(), any(), any(), any(), any()))
.thenReturn(tunnelResp);
+ doReturn(new LinkProperties()).when(mConnectivityManager).getLinkProperties(any());
+
// The unit test should know what kind of permission it needs and set the permission by
// itself, so set the default value of Context#checkCallingOrSelfPermission to
// PERMISSION_DENIED.
@@ -341,7 +367,7 @@
@After
public void tearDown() throws Exception {
- doReturn(PERMISSION_DENIED).when(mContext).checkCallingOrSelfPermission(CONTROL_VPN);
+ doReturn(PERMISSION_DENIED).when(mContext).checkCallingOrSelfPermission(any());
}
private <T> void mockService(Class<T> clazz, String name, T service) {
@@ -695,7 +721,6 @@
@Test
public void testPrepare_throwSecurityExceptionWhenGivenPackageDoesNotBelongToTheCaller()
throws Exception {
- assumeTrue(isAtLeastT());
final Vpn vpn = createVpnAndSetupUidChecks();
assertThrows(SecurityException.class,
() -> vpn.prepare("com.not.vpn.owner", null, VpnManager.TYPE_VPN_SERVICE));
@@ -944,12 +969,15 @@
@Test
public void testSetAndGetAppExclusionListRestrictedUser() throws Exception {
final Vpn vpn = prepareVpnForVerifyAppExclusionList();
+
// Mock it to restricted profile
when(mUserManager.getUserInfo(anyInt())).thenReturn(RESTRICTED_PROFILE_A);
+
// Restricted users cannot configure VPNs
assertThrows(SecurityException.class,
() -> vpn.setAppExclusionList(TEST_VPN_PKG, new ArrayList<>()));
- assertThrows(SecurityException.class, () -> vpn.getAppExclusionList(TEST_VPN_PKG));
+
+ assertEquals(Arrays.asList(PKGS), vpn.getAppExclusionList(TEST_VPN_PKG));
}
@Test
@@ -970,31 +998,6 @@
AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN, AppOpsManager.OPSTR_ACTIVATE_VPN);
}
- private void setAppOpsPermission() {
- doAnswer(invocation -> {
- when(mAppOps.noteOpNoThrow(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN,
- Process.myUid(), TEST_VPN_PKG,
- null /* attributionTag */, null /* message */))
- .thenReturn(AppOpsManager.MODE_ALLOWED);
- return null;
- }).when(mAppOps).setMode(
- eq(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN),
- eq(Process.myUid()),
- eq(TEST_VPN_PKG),
- eq(AppOpsManager.MODE_ALLOWED));
- }
-
- @Test
- public void testProvisionVpnProfileNotPreconsented_withControlVpnPermission() throws Exception {
- setAppOpsPermission();
- doReturn(PERMISSION_GRANTED).when(mContext).checkCallingOrSelfPermission(CONTROL_VPN);
- final Vpn vpn = createVpnAndSetupUidChecks();
-
- // ACTIVATE_PLATFORM_VPN will be granted if VPN app has CONTROL_VPN permission.
- checkProvisionVpnProfile(vpn, true /* expectedResult */,
- AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN);
- }
-
@Test
public void testProvisionVpnProfileVpnServicePreconsented() throws Exception {
final Vpn vpn = createVpnAndSetupUidChecks(AppOpsManager.OPSTR_ACTIVATE_VPN);
@@ -1190,7 +1193,6 @@
@Test
public void testStartOpAndFinishOpWillBeCalledWhenPlatformVpnIsOnAndOff() throws Exception {
- assumeTrue(SdkLevel.isAtLeastT());
final Vpn vpn = createVpnAndSetupUidChecks(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN);
when(mVpnProfileStore.get(vpn.getProfileNameForPackage(TEST_VPN_PKG)))
.thenReturn(mVpnProfile.encode());
@@ -1216,7 +1218,6 @@
@Test
public void testStartOpWithSeamlessHandover() throws Exception {
- assumeTrue(SdkLevel.isAtLeastT());
final Vpn vpn = createVpnAndSetupUidChecks(AppOpsManager.OPSTR_ACTIVATE_VPN);
assertTrue(vpn.prepare(TEST_VPN_PKG, null, VpnManager.TYPE_VPN_SERVICE));
final VpnConfig config = new VpnConfig();
@@ -1248,7 +1249,7 @@
}
private void verifyVpnManagerEvent(String sessionKey, String category, int errorClass,
- int errorCode, VpnProfileState... profileState) {
+ int errorCode, String[] packageName, VpnProfileState... profileState) {
final Context userContext =
mContext.createContextAsUser(UserHandle.of(PRIMARY_USER.id), 0 /* flags */);
final ArgumentCaptor<Intent> intentArgumentCaptor = ArgumentCaptor.forClass(Intent.class);
@@ -1258,9 +1259,11 @@
for (int i = 0; i < verifyTimes; i++) {
final Intent intent = intentArgumentCaptor.getAllValues().get(i);
+ assertEquals(packageName[i], intent.getPackage());
assertEquals(sessionKey, intent.getStringExtra(VpnManager.EXTRA_SESSION_KEY));
final Set<String> categories = intent.getCategories();
assertTrue(categories.contains(category));
+ assertEquals(1, categories.size());
assertEquals(errorClass,
intent.getIntExtra(VpnManager.EXTRA_ERROR_CLASS, -1 /* defaultValue */));
assertEquals(errorCode,
@@ -1273,9 +1276,21 @@
reset(userContext);
}
+ private void verifyDeactivatedByUser(String sessionKey, String[] packageName) {
+ // CATEGORY_EVENT_DEACTIVATED_BY_USER is not an error event, so both of errorClass and
+ // errorCode won't be set.
+ verifyVpnManagerEvent(sessionKey, VpnManager.CATEGORY_EVENT_DEACTIVATED_BY_USER,
+ -1 /* errorClass */, -1 /* errorCode */, packageName, null /* profileState */);
+ }
+
+ private void verifyAlwaysOnStateChanged(String[] packageName, VpnProfileState... profileState) {
+ verifyVpnManagerEvent(null /* sessionKey */,
+ VpnManager.CATEGORY_EVENT_ALWAYS_ON_STATE_CHANGED, -1 /* errorClass */,
+ -1 /* errorCode */, packageName, profileState);
+ }
+
@Test
public void testVpnManagerEventForUserDeactivated() throws Exception {
- assumeTrue(SdkLevel.isAtLeastT());
// For security reasons, Vpn#prepare() will check that oldPackage and newPackage are either
// null or the package of the caller. This test will call Vpn#prepare() to pretend the old
// VPN is replaced by a new one. But only Settings can change to some other packages, and
@@ -1293,10 +1308,7 @@
verifyPlatformVpnIsDeactivated(TEST_VPN_PKG);
verifyPowerSaveTempWhitelistApp(TEST_VPN_PKG);
reset(mDeviceIdleInternal);
- // CATEGORY_EVENT_DEACTIVATED_BY_USER is not an error event, so both of errorClass and
- // errorCode won't be set.
- verifyVpnManagerEvent(sessionKey1, VpnManager.CATEGORY_EVENT_DEACTIVATED_BY_USER,
- -1 /* errorClass */, -1 /* errorCode */, null /* profileState */);
+ verifyDeactivatedByUser(sessionKey1, new String[] {TEST_VPN_PKG});
reset(mAppOps);
// Test the case that the user chooses another vpn and the original one is replaced.
@@ -1306,15 +1318,11 @@
verifyPlatformVpnIsDeactivated(TEST_VPN_PKG);
verifyPowerSaveTempWhitelistApp(TEST_VPN_PKG);
reset(mDeviceIdleInternal);
- // CATEGORY_EVENT_DEACTIVATED_BY_USER is not an error event, so both of errorClass and
- // errorCode won't be set.
- verifyVpnManagerEvent(sessionKey2, VpnManager.CATEGORY_EVENT_DEACTIVATED_BY_USER,
- -1 /* errorClass */, -1 /* errorCode */, null /* profileState */);
+ verifyDeactivatedByUser(sessionKey2, new String[] {TEST_VPN_PKG});
}
@Test
public void testVpnManagerEventForAlwaysOnChanged() throws Exception {
- assumeTrue(SdkLevel.isAtLeastT());
// Calling setAlwaysOnPackage() needs to hold CONTROL_VPN.
doReturn(PERMISSION_GRANTED).when(mContext).checkCallingOrSelfPermission(CONTROL_VPN);
final Vpn vpn = createVpn(PRIMARY_USER.id);
@@ -1323,9 +1331,8 @@
null /* lockdownAllowlist */));
verifyPowerSaveTempWhitelistApp(PKGS[1]);
reset(mDeviceIdleInternal);
- verifyVpnManagerEvent(null /* sessionKey */,
- VpnManager.CATEGORY_EVENT_ALWAYS_ON_STATE_CHANGED, -1 /* errorClass */,
- -1 /* errorCode */, new VpnProfileState(VpnProfileState.STATE_DISCONNECTED,
+ verifyAlwaysOnStateChanged(new String[] {PKGS[1]},
+ new VpnProfileState(VpnProfileState.STATE_DISCONNECTED,
null /* sessionKey */, true /* alwaysOn */, false /* lockdown */));
// Enable VPN lockdown for PKGS[1].
@@ -1333,9 +1340,8 @@
null /* lockdownAllowlist */));
verifyPowerSaveTempWhitelistApp(PKGS[1]);
reset(mDeviceIdleInternal);
- verifyVpnManagerEvent(null /* sessionKey */,
- VpnManager.CATEGORY_EVENT_ALWAYS_ON_STATE_CHANGED, -1 /* errorClass */,
- -1 /* errorCode */, new VpnProfileState(VpnProfileState.STATE_DISCONNECTED,
+ verifyAlwaysOnStateChanged(new String[] {PKGS[1]},
+ new VpnProfileState(VpnProfileState.STATE_DISCONNECTED,
null /* sessionKey */, true /* alwaysOn */, true /* lockdown */));
// Disable VPN lockdown for PKGS[1].
@@ -1343,9 +1349,8 @@
null /* lockdownAllowlist */));
verifyPowerSaveTempWhitelistApp(PKGS[1]);
reset(mDeviceIdleInternal);
- verifyVpnManagerEvent(null /* sessionKey */,
- VpnManager.CATEGORY_EVENT_ALWAYS_ON_STATE_CHANGED, -1 /* errorClass */,
- -1 /* errorCode */, new VpnProfileState(VpnProfileState.STATE_DISCONNECTED,
+ verifyAlwaysOnStateChanged(new String[] {PKGS[1]},
+ new VpnProfileState(VpnProfileState.STATE_DISCONNECTED,
null /* sessionKey */, true /* alwaysOn */, false /* lockdown */));
// Disable VPN always-on.
@@ -1353,9 +1358,8 @@
null /* lockdownAllowlist */));
verifyPowerSaveTempWhitelistApp(PKGS[1]);
reset(mDeviceIdleInternal);
- verifyVpnManagerEvent(null /* sessionKey */,
- VpnManager.CATEGORY_EVENT_ALWAYS_ON_STATE_CHANGED, -1 /* errorClass */,
- -1 /* errorCode */, new VpnProfileState(VpnProfileState.STATE_DISCONNECTED,
+ verifyAlwaysOnStateChanged(new String[] {PKGS[1]},
+ new VpnProfileState(VpnProfileState.STATE_DISCONNECTED,
null /* sessionKey */, false /* alwaysOn */, false /* lockdown */));
// Enable VPN always-on for PKGS[1] again.
@@ -1363,9 +1367,8 @@
null /* lockdownAllowlist */));
verifyPowerSaveTempWhitelistApp(PKGS[1]);
reset(mDeviceIdleInternal);
- verifyVpnManagerEvent(null /* sessionKey */,
- VpnManager.CATEGORY_EVENT_ALWAYS_ON_STATE_CHANGED, -1 /* errorClass */,
- -1 /* errorCode */, new VpnProfileState(VpnProfileState.STATE_DISCONNECTED,
+ verifyAlwaysOnStateChanged(new String[] {PKGS[1]},
+ new VpnProfileState(VpnProfileState.STATE_DISCONNECTED,
null /* sessionKey */, true /* alwaysOn */, false /* lockdown */));
// Enable VPN always-on for PKGS[2].
@@ -1377,9 +1380,8 @@
// Pass 2 VpnProfileState objects to verifyVpnManagerEvent(), the first one is sent to
// PKGS[1] to notify PKGS[1] that the VPN always-on is disabled, the second one is sent to
// PKGS[2] to notify PKGS[2] that the VPN always-on is enabled.
- verifyVpnManagerEvent(null /* sessionKey */,
- VpnManager.CATEGORY_EVENT_ALWAYS_ON_STATE_CHANGED, -1 /* errorClass */,
- -1 /* errorCode */, new VpnProfileState(VpnProfileState.STATE_DISCONNECTED,
+ verifyAlwaysOnStateChanged(new String[] {PKGS[1], PKGS[2]},
+ new VpnProfileState(VpnProfileState.STATE_DISCONNECTED,
null /* sessionKey */, false /* alwaysOn */, false /* lockdown */),
new VpnProfileState(VpnProfileState.STATE_DISCONNECTED,
null /* sessionKey */, true /* alwaysOn */, false /* lockdown */));
@@ -1459,7 +1461,7 @@
final ArgumentCaptor<NetworkCallback> networkCallbackCaptor =
ArgumentCaptor.forClass(NetworkCallback.class);
verify(mConnectivityManager, timeout(TEST_TIMEOUT_MS))
- .requestNetwork(any(), networkCallbackCaptor.capture());
+ .registerSystemDefaultNetworkCallback(networkCallbackCaptor.capture(), any());
// onAvailable() will trigger onDefaultNetworkChanged(), so NetdUtils#setInterfaceUp will be
// invoked. Set the return value of INetd#interfaceGetCfg to prevent NullPointerException.
@@ -1501,7 +1503,8 @@
verifyPowerSaveTempWhitelistApp(TEST_VPN_PKG);
reset(mDeviceIdleInternal);
- verifyVpnManagerEvent(sessionKey, category, errorType, errorCode, null /* profileState */);
+ verifyVpnManagerEvent(sessionKey, category, errorType, errorCode,
+ new String[] {TEST_VPN_PKG}, null /* profileState */);
if (errorType == VpnManager.ERROR_CLASS_NOT_RECOVERABLE) {
verify(mConnectivityManager, timeout(TEST_TIMEOUT_MS))
.unregisterNetworkCallback(eq(cb));
@@ -1712,9 +1715,12 @@
}
private ChildSessionConfiguration createChildConfig() {
- return new ChildSessionConfiguration.Builder(Arrays.asList(IN_TS), Arrays.asList(OUT_TS))
+ return new ChildSessionConfiguration.Builder(
+ Arrays.asList(IN_TS, IN_TS6), Arrays.asList(OUT_TS, OUT_TS6))
.addInternalAddress(new LinkAddress(TEST_VPN_INTERNAL_IP, IP4_PREFIX_LEN))
+ .addInternalAddress(new LinkAddress(TEST_VPN_INTERNAL_IP6, IP6_PREFIX_LEN))
.addInternalDnsServer(TEST_VPN_INTERNAL_DNS)
+ .addInternalDnsServer(TEST_VPN_INTERNAL_DNS6)
.build();
}
@@ -1761,9 +1767,19 @@
private PlatformVpnSnapshot verifySetupPlatformVpn(IkeSessionConfiguration ikeConfig)
throws Exception {
+ return verifySetupPlatformVpn(ikeConfig, true);
+ }
+
+ private PlatformVpnSnapshot verifySetupPlatformVpn(
+ IkeSessionConfiguration ikeConfig, boolean mtuSupportsIpv6) throws Exception {
+ if (!mtuSupportsIpv6) {
+ doReturn(IPV6_MIN_MTU - 1).when(mTestDeps).calculateVpnMtu(any(), anyInt(), anyInt(),
+ anyBoolean());
+ }
+
doReturn(mMockNetworkAgent).when(mTestDeps)
.newNetworkAgent(
- any(), any(), anyString(), any(), any(), any(), any(), any());
+ any(), any(), anyString(), any(), any(), any(), any(), any(), any());
final Vpn vpn = createVpnAndSetupUidChecks(AppOpsManager.OPSTR_ACTIVATE_PLATFORM_VPN);
when(mVpnProfileStore.get(vpn.getProfileNameForPackage(TEST_VPN_PKG)))
@@ -1793,24 +1809,44 @@
ArgumentCaptor.forClass(NetworkAgentConfig.class);
verify(mTestDeps).newNetworkAgent(
any(), any(), anyString(), ncCaptor.capture(), lpCaptor.capture(),
- any(), nacCaptor.capture(), any());
+ any(), nacCaptor.capture(), any(), any());
// Check LinkProperties
final LinkProperties lp = lpCaptor.getValue();
- final List<RouteInfo> expectedRoutes = Arrays.asList(
- new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), null /*gateway*/,
- TEST_IFACE_NAME, RouteInfo.RTN_UNICAST),
- new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), null /*gateway*/,
- TEST_IFACE_NAME, RTN_UNREACHABLE));
- assertEquals(expectedRoutes, lp.getRoutes());
-
- // Check internal addresses
+ final List<RouteInfo> expectedRoutes =
+ new ArrayList<>(
+ Arrays.asList(
+ new RouteInfo(
+ new IpPrefix(Inet4Address.ANY, 0),
+ null /* gateway */,
+ TEST_IFACE_NAME,
+ RouteInfo.RTN_UNICAST)));
final List<LinkAddress> expectedAddresses =
- Arrays.asList(new LinkAddress(TEST_VPN_INTERNAL_IP, IP4_PREFIX_LEN));
- assertEquals(expectedAddresses, lp.getLinkAddresses());
+ new ArrayList<>(
+ Arrays.asList(new LinkAddress(TEST_VPN_INTERNAL_IP, IP4_PREFIX_LEN)));
+ final List<InetAddress> expectedDns = new ArrayList<>(Arrays.asList(TEST_VPN_INTERNAL_DNS));
- // Check internal DNS
- assertEquals(Arrays.asList(TEST_VPN_INTERNAL_DNS), lp.getDnsServers());
+ if (mtuSupportsIpv6) {
+ expectedRoutes.add(
+ new RouteInfo(
+ new IpPrefix(Inet6Address.ANY, 0),
+ null /* gateway */,
+ TEST_IFACE_NAME,
+ RouteInfo.RTN_UNICAST));
+ expectedAddresses.add(new LinkAddress(TEST_VPN_INTERNAL_IP6, IP6_PREFIX_LEN));
+ expectedDns.add(TEST_VPN_INTERNAL_DNS6);
+ } else {
+ expectedRoutes.add(
+ new RouteInfo(
+ new IpPrefix(Inet6Address.ANY, 0),
+ null /* gateway */,
+ TEST_IFACE_NAME,
+ RTN_UNREACHABLE));
+ }
+
+ assertEquals(expectedRoutes, lp.getRoutes());
+ assertEquals(expectedAddresses, lp.getLinkAddresses());
+ assertEquals(expectedDns, lp.getDnsServers());
// Check NetworkCapabilities
assertEquals(Arrays.asList(TEST_NETWORK), ncCaptor.getValue().getUnderlyingNetworks());
@@ -1829,10 +1865,23 @@
}
@Test
+ public void testStartPlatformVpn_mtuDoesNotSupportIpv6() throws Exception {
+ final PlatformVpnSnapshot vpnSnapShot =
+ verifySetupPlatformVpn(
+ createIkeConfig(createIkeConnectInfo(), true /* isMobikeEnabled */),
+ false /* mtuSupportsIpv6 */);
+ vpnSnapShot.vpn.mVpnRunner.exitVpnRunner();
+ }
+
+ @Test
public void testStartPlatformVpnMobility_mobikeEnabled() throws Exception {
final PlatformVpnSnapshot vpnSnapShot = verifySetupPlatformVpn(
createIkeConfig(createIkeConnectInfo(), true /* isMobikeEnabled */));
+ // Set new MTU on a different network
+ final int newMtu = IPV6_MIN_MTU + 1;
+ doReturn(newMtu).when(mTestDeps).calculateVpnMtu(any(), anyInt(), anyInt(), anyBoolean());
+
// Mock network loss and verify a cleanup task is scheduled
vpnSnapShot.nwCb.onLost(TEST_NETWORK);
verify(mExecutor).schedule(any(Runnable.class), anyLong(), any());
@@ -1861,6 +1910,61 @@
vpnSnapShot.vpn.mNetworkCapabilities.getUnderlyingNetworks());
verify(mMockNetworkAgent)
.doSetUnderlyingNetworks(Collections.singletonList(TEST_NETWORK_2));
+ verify(mMockNetworkAgent).doSendLinkProperties(argThat(lp -> lp.getMtu() == newMtu));
+ verify(mMockNetworkAgent, never()).unregister();
+
+ vpnSnapShot.vpn.mVpnRunner.exitVpnRunner();
+ }
+
+ @Test
+ public void testStartPlatformVpnMobility_mobikeEnabledMtuDoesNotSupportIpv6() throws Exception {
+ final PlatformVpnSnapshot vpnSnapShot =
+ verifySetupPlatformVpn(
+ createIkeConfig(createIkeConnectInfo(), true /* isMobikeEnabled */));
+
+ // Set MTU below 1280
+ final int newMtu = IPV6_MIN_MTU - 1;
+ doReturn(newMtu).when(mTestDeps).calculateVpnMtu(any(), anyInt(), anyInt(), anyBoolean());
+
+ // Mock new network available & MOBIKE procedures
+ vpnSnapShot.nwCb.onAvailable(TEST_NETWORK_2);
+ vpnSnapShot.ikeCb.onIkeSessionConnectionInfoChanged(createIkeConnectInfo_2());
+ vpnSnapShot.childCb.onIpSecTransformsMigrated(
+ createIpSecTransform(), createIpSecTransform());
+
+ // Verify removal of IPv6 addresses and routes triggers a network agent restart
+ final ArgumentCaptor<LinkProperties> lpCaptor =
+ ArgumentCaptor.forClass(LinkProperties.class);
+ verify(mTestDeps, times(2))
+ .newNetworkAgent(any(), any(), anyString(), any(), lpCaptor.capture(), any(), any(),
+ any(), any());
+ verify(mMockNetworkAgent).unregister();
+ // mMockNetworkAgent is an old NetworkAgent, so it won't update LinkProperties after
+ // unregistering.
+ verify(mMockNetworkAgent, never()).doSendLinkProperties(any());
+
+ final LinkProperties lp = lpCaptor.getValue();
+
+ for (LinkAddress addr : lp.getLinkAddresses()) {
+ if (addr.isIpv6()) {
+ fail("IPv6 address found on VPN with MTU < IPv6 minimum MTU");
+ }
+ }
+
+ for (InetAddress dnsAddr : lp.getDnsServers()) {
+ if (dnsAddr instanceof Inet6Address) {
+ fail("IPv6 DNS server found on VPN with MTU < IPv6 minimum MTU");
+ }
+ }
+
+ for (RouteInfo routeInfo : lp.getRoutes()) {
+ if (routeInfo.getDestinationLinkAddress().isIpv6()
+ && !routeInfo.isIPv6UnreachableDefault()) {
+ fail("IPv6 route found on VPN with MTU < IPv6 minimum MTU");
+ }
+ }
+
+ assertEquals(newMtu, lp.getMtu());
vpnSnapShot.vpn.mVpnRunner.exitVpnRunner();
}
@@ -1907,26 +2011,7 @@
vpnSnapShot.vpn.mVpnRunner.exitVpnRunner();
}
- private void verifyHandlingNetworkLoss() throws Exception {
- final ArgumentCaptor<LinkProperties> lpCaptor =
- ArgumentCaptor.forClass(LinkProperties.class);
- verify(mMockNetworkAgent).doSendLinkProperties(lpCaptor.capture());
- final LinkProperties lp = lpCaptor.getValue();
-
- assertNull(lp.getInterfaceName());
- final List<RouteInfo> expectedRoutes = Arrays.asList(
- new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), null /*gateway*/,
- null /*iface*/, RTN_UNREACHABLE),
- new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), null /*gateway*/,
- null /*iface*/, RTN_UNREACHABLE));
- assertEquals(expectedRoutes, lp.getRoutes());
- }
-
- @Test
- public void testStartPlatformVpnHandlesNetworkLoss_mobikeEnabled() throws Exception {
- final PlatformVpnSnapshot vpnSnapShot = verifySetupPlatformVpn(
- createIkeConfig(createIkeConnectInfo(), false /* isMobikeEnabled */));
-
+ private void verifyHandlingNetworkLoss(PlatformVpnSnapshot vpnSnapShot) throws Exception {
// Forget the #sendLinkProperties during first setup.
reset(mMockNetworkAgent);
@@ -1940,21 +2025,142 @@
verify(mExecutor).schedule(runnableCaptor.capture(), anyLong(), any());
runnableCaptor.getValue().run();
- verifyHandlingNetworkLoss();
+ final ArgumentCaptor<LinkProperties> lpCaptor =
+ ArgumentCaptor.forClass(LinkProperties.class);
+ verify(mMockNetworkAgent).doSendLinkProperties(lpCaptor.capture());
+ final LinkProperties lp = lpCaptor.getValue();
+
+ assertNull(lp.getInterfaceName());
+ final List<RouteInfo> expectedRoutes = Arrays.asList(
+ new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), null /* gateway */,
+ null /* iface */, RTN_UNREACHABLE),
+ new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), null /* gateway */,
+ null /* iface */, RTN_UNREACHABLE));
+ assertEquals(expectedRoutes, lp.getRoutes());
+
+ verify(mMockNetworkAgent).unregister();
+ }
+
+ @Test
+ public void testStartPlatformVpnHandlesNetworkLoss_mobikeEnabled() throws Exception {
+ final PlatformVpnSnapshot vpnSnapShot = verifySetupPlatformVpn(
+ createIkeConfig(createIkeConnectInfo(), true /* isMobikeEnabled */));
+ verifyHandlingNetworkLoss(vpnSnapShot);
}
@Test
public void testStartPlatformVpnHandlesNetworkLoss_mobikeDisabled() throws Exception {
final PlatformVpnSnapshot vpnSnapShot = verifySetupPlatformVpn(
createIkeConfig(createIkeConnectInfo(), false /* isMobikeEnabled */));
+ verifyHandlingNetworkLoss(vpnSnapShot);
+ }
- // Forget the #sendLinkProperties during first setup.
- reset(mMockNetworkAgent);
+ private ConnectivityDiagnosticsCallback getConnectivityDiagCallback() {
+ final ArgumentCaptor<ConnectivityDiagnosticsCallback> cdcCaptor =
+ ArgumentCaptor.forClass(ConnectivityDiagnosticsCallback.class);
+ verify(mCdm).registerConnectivityDiagnosticsCallback(
+ any(), any(), cdcCaptor.capture());
+ return cdcCaptor.getValue();
+ }
- // Mock network loss
- vpnSnapShot.nwCb.onLost(TEST_NETWORK);
+ private DataStallReport createDataStallReport() {
+ return new DataStallReport(TEST_NETWORK, 1234 /* reportTimestamp */,
+ 1 /* detectionMethod */, new LinkProperties(), new NetworkCapabilities(),
+ new PersistableBundle());
+ }
- verifyHandlingNetworkLoss();
+ private void verifyMobikeTriggered(List<Network> expected) {
+ final ArgumentCaptor<Network> networkCaptor = ArgumentCaptor.forClass(Network.class);
+ verify(mIkeSessionWrapper).setNetwork(networkCaptor.capture());
+ assertEquals(expected, Collections.singletonList(networkCaptor.getValue()));
+ }
+
+ @Test
+ public void testDataStallInIkev2VpnMobikeDisabled() throws Exception {
+ verifySetupPlatformVpn(
+ createIkeConfig(createIkeConnectInfo(), false /* isMobikeEnabled */));
+
+ doReturn(TEST_NETWORK).when(mMockNetworkAgent).getNetwork();
+ final ConnectivityDiagnosticsCallback connectivityDiagCallback =
+ getConnectivityDiagCallback();
+ final DataStallReport report = createDataStallReport();
+ connectivityDiagCallback.onDataStallSuspected(report);
+
+ // Should not trigger MOBIKE if MOBIKE is not enabled
+ verify(mIkeSessionWrapper, never()).setNetwork(any());
+ }
+
+ @Test
+ public void testDataStallInIkev2VpnRecoveredByMobike() throws Exception {
+ final PlatformVpnSnapshot vpnSnapShot = verifySetupPlatformVpn(
+ createIkeConfig(createIkeConnectInfo(), true /* isMobikeEnabled */));
+
+ doReturn(TEST_NETWORK).when(mMockNetworkAgent).getNetwork();
+ final ConnectivityDiagnosticsCallback connectivityDiagCallback =
+ getConnectivityDiagCallback();
+ final DataStallReport report = createDataStallReport();
+ connectivityDiagCallback.onDataStallSuspected(report);
+
+ // Verify MOBIKE is triggered
+ verifyMobikeTriggered(vpnSnapShot.vpn.mNetworkCapabilities.getUnderlyingNetworks());
+
+ // Expect to skip other data stall event if MOBIKE was started.
+ reset(mIkeSessionWrapper);
+ connectivityDiagCallback.onDataStallSuspected(report);
+ verify(mIkeSessionWrapper, never()).setNetwork(any());
+
+ reset(mIkev2SessionCreator);
+
+ // Send validation status update.
+ // Recovered and get network validated. It should not trigger the ike session reset.
+ ((Vpn.IkeV2VpnRunner) vpnSnapShot.vpn.mVpnRunner).onValidationStatus(
+ NetworkAgent.VALIDATION_STATUS_VALID);
+ verify(mIkev2SessionCreator, never()).createIkeSession(
+ any(), any(), any(), any(), any(), any());
+
+ // Send invalid result to verify no ike session reset since the data stall suspected
+ // variables(timer counter and boolean) was reset.
+ ((Vpn.IkeV2VpnRunner) vpnSnapShot.vpn.mVpnRunner).onValidationStatus(
+ NetworkAgent.VALIDATION_STATUS_NOT_VALID);
+ final ArgumentCaptor<Runnable> runnableCaptor = ArgumentCaptor.forClass(Runnable.class);
+ verify(mExecutor).schedule(runnableCaptor.capture(), anyLong(), any());
+ runnableCaptor.getValue().run();
+ verify(mIkev2SessionCreator, never()).createIkeSession(
+ any(), any(), any(), any(), any(), any());
+ }
+
+ @Test
+ public void testDataStallInIkev2VpnNotRecoveredByMobike() throws Exception {
+ final PlatformVpnSnapshot vpnSnapShot = verifySetupPlatformVpn(
+ createIkeConfig(createIkeConnectInfo(), true /* isMobikeEnabled */));
+
+ final ConnectivityDiagnosticsCallback connectivityDiagCallback =
+ getConnectivityDiagCallback();
+
+ doReturn(TEST_NETWORK).when(mMockNetworkAgent).getNetwork();
+ final DataStallReport report = createDataStallReport();
+ connectivityDiagCallback.onDataStallSuspected(report);
+
+ verifyMobikeTriggered(vpnSnapShot.vpn.mNetworkCapabilities.getUnderlyingNetworks());
+
+ reset(mIkev2SessionCreator);
+
+ // Send validation status update should result in ike session reset.
+ ((Vpn.IkeV2VpnRunner) vpnSnapShot.vpn.mVpnRunner).onValidationStatus(
+ NetworkAgent.VALIDATION_STATUS_NOT_VALID);
+
+ // Verify reset is scheduled and run.
+ final ArgumentCaptor<Runnable> runnableCaptor = ArgumentCaptor.forClass(Runnable.class);
+ verify(mExecutor).schedule(runnableCaptor.capture(), anyLong(), any());
+
+ // Another invalid status reported should not trigger other scheduled recovery.
+ reset(mExecutor);
+ ((Vpn.IkeV2VpnRunner) vpnSnapShot.vpn.mVpnRunner).onValidationStatus(
+ NetworkAgent.VALIDATION_STATUS_NOT_VALID);
+ verify(mExecutor, never()).schedule(runnableCaptor.capture(), anyLong(), any());
+
+ runnableCaptor.getValue().run();
+ verify(mIkev2SessionCreator).createIkeSession(any(), any(), any(), any(), any(), any());
}
@Test
diff --git a/tests/unit/java/com/android/server/connectivity/mdns/MdnsRecordTests.java b/tests/unit/java/com/android/server/connectivity/mdns/MdnsRecordTests.java
index fdb4d4a..9fc4674 100644
--- a/tests/unit/java/com/android/server/connectivity/mdns/MdnsRecordTests.java
+++ b/tests/unit/java/com/android/server/connectivity/mdns/MdnsRecordTests.java
@@ -22,16 +22,19 @@
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertThrows;
import android.util.Log;
import com.android.net.module.util.HexDump;
+import com.android.server.connectivity.mdns.MdnsServiceInfo.TextEntry;
import com.android.testutils.DevSdkIgnoreRule;
import com.android.testutils.DevSdkIgnoreRunner;
import org.junit.Test;
import org.junit.runner.RunWith;
+import java.io.EOFException;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.Inet4Address;
@@ -309,6 +312,14 @@
assertEquals("b=1234567890", strings.get(1));
assertEquals("xyz=!@#$", strings.get(2));
+ List<TextEntry> entries = record.getEntries();
+ assertNotNull(entries);
+ assertEquals(3, entries.size());
+
+ assertEquals(new TextEntry("a", "hello there"), entries.get(0));
+ assertEquals(new TextEntry("b", "1234567890"), entries.get(1));
+ assertEquals(new TextEntry("xyz", "!@#$"), entries.get(2));
+
// Encode
MdnsPacketWriter writer = new MdnsPacketWriter(MAX_PACKET_SIZE);
record.write(writer, record.getReceiptTime());
@@ -321,4 +332,48 @@
assertEquals(dataInText, dataOutText);
}
+
+ @Test
+ public void textRecord_recordDoesNotHaveDataOfGivenLength_throwsEOFException()
+ throws Exception {
+ final byte[] dataIn = HexDump.hexStringToByteArray(
+ "0474657374000010"
+ + "000100001194000D"
+ + "0D613D68656C6C6F" //The TXT entry starts with length of 13, but only 12
+ + "2074686572"); // characters are following it.
+ DatagramPacket packet = new DatagramPacket(dataIn, dataIn.length);
+ MdnsPacketReader reader = new MdnsPacketReader(packet);
+ String[] name = reader.readLabels();
+ MdnsRecord.labelsToString(name);
+ reader.readUInt16();
+
+ assertThrows(EOFException.class, () -> new MdnsTextRecord(name, reader));
+ }
+
+ @Test
+ public void textRecord_entriesIncludeNonUtf8Bytes_returnsTheSameUtf8Bytes() throws Exception {
+ final byte[] dataIn = HexDump.hexStringToByteArray(
+ "0474657374000010"
+ + "0001000011940024"
+ + "0D613D68656C6C6F"
+ + "2074686572650C62"
+ + "3D31323334353637"
+ + "3839300878797A3D"
+ + "FFEFDFCF");
+ DatagramPacket packet = new DatagramPacket(dataIn, dataIn.length);
+ MdnsPacketReader reader = new MdnsPacketReader(packet);
+ String[] name = reader.readLabels();
+ MdnsRecord.labelsToString(name);
+ reader.readUInt16();
+
+ MdnsTextRecord record = new MdnsTextRecord(name, reader);
+
+ List<TextEntry> entries = record.getEntries();
+ assertNotNull(entries);
+ assertEquals(3, entries.size());
+ assertEquals(new TextEntry("a", "hello there"), entries.get(0));
+ assertEquals(new TextEntry("b", "1234567890"), entries.get(1));
+ assertEquals(new TextEntry("xyz", HexDump.hexStringToByteArray("FFEFDFCF")),
+ entries.get(2));
+ }
}
diff --git a/tests/unit/java/com/android/server/connectivity/mdns/MdnsResponseDecoderTests.java b/tests/unit/java/com/android/server/connectivity/mdns/MdnsResponseDecoderTests.java
index ea9156c..8d0ace5 100644
--- a/tests/unit/java/com/android/server/connectivity/mdns/MdnsResponseDecoderTests.java
+++ b/tests/unit/java/com/android/server/connectivity/mdns/MdnsResponseDecoderTests.java
@@ -106,9 +106,9 @@
+ "63616C0000018001000000780004C0A8010A000001800100000078"
+ "0004C0A8010A00000000000000");
- private static final String DUMMY_CAST_SERVICE_NAME = "_googlecast";
- private static final String[] DUMMY_CAST_SERVICE_TYPE =
- new String[] {DUMMY_CAST_SERVICE_NAME, "_tcp", "local"};
+ private static final String CAST_SERVICE_NAME = "_googlecast";
+ private static final String[] CAST_SERVICE_TYPE =
+ new String[] {CAST_SERVICE_NAME, "_tcp", "local"};
private final List<MdnsResponse> responses = new LinkedList<>();
@@ -116,13 +116,13 @@
@Before
public void setUp() {
- MdnsResponseDecoder decoder = new MdnsResponseDecoder(mClock, DUMMY_CAST_SERVICE_TYPE);
+ MdnsResponseDecoder decoder = new MdnsResponseDecoder(mClock, CAST_SERVICE_TYPE);
assertNotNull(data);
DatagramPacket packet = new DatagramPacket(data, data.length);
packet.setSocketAddress(
new InetSocketAddress(MdnsConstants.getMdnsIPv4Address(), MdnsConstants.MDNS_PORT));
responses.clear();
- int errorCode = decoder.decode(packet, responses);
+ int errorCode = decoder.decode(packet, responses, MdnsSocket.INTERFACE_INDEX_UNSPECIFIED);
assertEquals(MdnsResponseDecoder.SUCCESS, errorCode);
assertEquals(1, responses.size());
}
@@ -135,7 +135,7 @@
packet.setSocketAddress(
new InetSocketAddress(MdnsConstants.getMdnsIPv4Address(), MdnsConstants.MDNS_PORT));
responses.clear();
- int errorCode = decoder.decode(packet, responses);
+ int errorCode = decoder.decode(packet, responses, MdnsSocket.INTERFACE_INDEX_UNSPECIFIED);
assertEquals(MdnsResponseDecoder.SUCCESS, errorCode);
assertEquals(2, responses.size());
}
@@ -153,7 +153,7 @@
MdnsServiceRecord serviceRecord = response.getServiceRecord();
String serviceName = serviceRecord.getServiceName();
- assertEquals(DUMMY_CAST_SERVICE_NAME, serviceName);
+ assertEquals(CAST_SERVICE_NAME, serviceName);
String serviceInstanceName = serviceRecord.getServiceInstanceName();
assertEquals("Johnny's Chromecast", serviceInstanceName);
@@ -187,14 +187,14 @@
@Test
public void testDecodeIPv6AnswerPacket() throws IOException {
- MdnsResponseDecoder decoder = new MdnsResponseDecoder(mClock, DUMMY_CAST_SERVICE_TYPE);
+ MdnsResponseDecoder decoder = new MdnsResponseDecoder(mClock, CAST_SERVICE_TYPE);
assertNotNull(data6);
DatagramPacket packet = new DatagramPacket(data6, data6.length);
packet.setSocketAddress(
new InetSocketAddress(MdnsConstants.getMdnsIPv6Address(), MdnsConstants.MDNS_PORT));
responses.clear();
- int errorCode = decoder.decode(packet, responses);
+ int errorCode = decoder.decode(packet, responses, MdnsSocket.INTERFACE_INDEX_UNSPECIFIED);
assertEquals(MdnsResponseDecoder.SUCCESS, errorCode);
MdnsResponse response = responses.get(0);
@@ -234,4 +234,19 @@
response.setTextRecord(null);
assertFalse(response.isComplete());
}
+
+ @Test
+ public void decode_withInterfaceIndex_populatesInterfaceIndex() {
+ MdnsResponseDecoder decoder = new MdnsResponseDecoder(mClock, CAST_SERVICE_TYPE);
+ assertNotNull(data6);
+ DatagramPacket packet = new DatagramPacket(data6, data6.length);
+ packet.setSocketAddress(
+ new InetSocketAddress(MdnsConstants.getMdnsIPv6Address(), MdnsConstants.MDNS_PORT));
+
+ responses.clear();
+ int errorCode = decoder.decode(packet, responses, /* interfaceIndex= */ 10);
+ assertEquals(errorCode, MdnsResponseDecoder.SUCCESS);
+ assertEquals(responses.size(), 1);
+ assertEquals(responses.get(0).getInterfaceIndex(), 10);
+ }
}
\ No newline at end of file
diff --git a/tests/unit/java/com/android/server/connectivity/mdns/MdnsResponseTests.java b/tests/unit/java/com/android/server/connectivity/mdns/MdnsResponseTests.java
index ae16f2b..771e42c 100644
--- a/tests/unit/java/com/android/server/connectivity/mdns/MdnsResponseTests.java
+++ b/tests/unit/java/com/android/server/connectivity/mdns/MdnsResponseTests.java
@@ -222,6 +222,19 @@
}
@Test
+ public void getInterfaceIndex_returnsDefaultValue() {
+ MdnsResponse response = new MdnsResponse(/* now= */ 0);
+ assertEquals(response.getInterfaceIndex(), -1);
+ }
+
+ @Test
+ public void getInterfaceIndex_afterSet_returnsValue() {
+ MdnsResponse response = new MdnsResponse(/* now= */ 0);
+ response.setInterfaceIndex(5);
+ assertEquals(response.getInterfaceIndex(), 5);
+ }
+
+ @Test
public void mergeRecordsFrom_indicates_change_on_ipv4_address() throws IOException {
MdnsResponse response = makeMdnsResponse(
0,
diff --git a/tests/unit/java/com/android/server/connectivity/mdns/MdnsServiceInfoTest.java b/tests/unit/java/com/android/server/connectivity/mdns/MdnsServiceInfoTest.java
new file mode 100644
index 0000000..d3934c2
--- /dev/null
+++ b/tests/unit/java/com/android/server/connectivity/mdns/MdnsServiceInfoTest.java
@@ -0,0 +1,273 @@
+/*
+ * 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.server.connectivity.mdns;
+
+import static com.android.testutils.DevSdkIgnoreRuleKt.SC_V2;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import android.os.Parcel;
+
+import com.android.server.connectivity.mdns.MdnsServiceInfo.TextEntry;
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRunner;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.List;
+import java.util.Map;
+
+@RunWith(DevSdkIgnoreRunner.class)
+@DevSdkIgnoreRule.IgnoreUpTo(SC_V2)
+public class MdnsServiceInfoTest {
+ @Test
+ public void constructor_createWithOnlyTextStrings_correctAttributes() {
+ MdnsServiceInfo info =
+ new MdnsServiceInfo(
+ "my-mdns-service",
+ new String[] {"_googlecast", "_tcp"},
+ List.of(),
+ new String[] {"my-host", "local"},
+ 12345,
+ "192.168.1.1",
+ "2001::1",
+ List.of("vn=Google Inc.", "mn=Google Nest Hub Max"),
+ /* textEntries= */ null);
+
+ assertTrue(info.getAttributeByKey("vn").equals("Google Inc."));
+ assertTrue(info.getAttributeByKey("mn").equals("Google Nest Hub Max"));
+ }
+
+ @Test
+ public void constructor_createWithOnlyTextEntries_correctAttributes() {
+ MdnsServiceInfo info =
+ new MdnsServiceInfo(
+ "my-mdns-service",
+ new String[] {"_googlecast", "_tcp"},
+ List.of(),
+ new String[] {"my-host", "local"},
+ 12345,
+ "192.168.1.1",
+ "2001::1",
+ /* textStrings= */ null,
+ List.of(MdnsServiceInfo.TextEntry.fromString("vn=Google Inc."),
+ MdnsServiceInfo.TextEntry.fromString("mn=Google Nest Hub Max")));
+
+ assertTrue(info.getAttributeByKey("vn").equals("Google Inc."));
+ assertTrue(info.getAttributeByKey("mn").equals("Google Nest Hub Max"));
+ }
+
+ @Test
+ public void constructor_createWithBothTextStringsAndTextEntries_acceptsOnlyTextEntries() {
+ MdnsServiceInfo info =
+ new MdnsServiceInfo(
+ "my-mdns-service",
+ new String[] {"_googlecast", "_tcp"},
+ List.of(),
+ new String[] {"my-host", "local"},
+ 12345,
+ "192.168.1.1",
+ "2001::1",
+ List.of("vn=Alphabet Inc.", "mn=Google Nest Hub Max", "id=12345"),
+ List.of(
+ MdnsServiceInfo.TextEntry.fromString("vn=Google Inc."),
+ MdnsServiceInfo.TextEntry.fromString("mn=Google Nest Hub Max")));
+
+ assertEquals(Map.of("vn", "Google Inc.", "mn", "Google Nest Hub Max"),
+ info.getAttributes());
+ }
+
+ @Test
+ public void constructor_createWithDuplicateKeys_acceptsTheFirstOne() {
+ MdnsServiceInfo info =
+ new MdnsServiceInfo(
+ "my-mdns-service",
+ new String[] {"_googlecast", "_tcp"},
+ List.of(),
+ new String[] {"my-host", "local"},
+ 12345,
+ "192.168.1.1",
+ "2001::1",
+ List.of("vn=Alphabet Inc.", "mn=Google Nest Hub Max", "id=12345"),
+ List.of(MdnsServiceInfo.TextEntry.fromString("vn=Google Inc."),
+ MdnsServiceInfo.TextEntry.fromString("mn=Google Nest Hub Max"),
+ MdnsServiceInfo.TextEntry.fromString("mn=Google WiFi Router")));
+
+ assertEquals(Map.of("vn", "Google Inc.", "mn", "Google Nest Hub Max"),
+ info.getAttributes());
+ }
+
+ @Test
+ public void getInterfaceIndex_constructorWithDefaultValues_returnsMinusOne() {
+ MdnsServiceInfo info =
+ new MdnsServiceInfo(
+ "my-mdns-service",
+ new String[] {"_googlecast", "_tcp"},
+ List.of(),
+ new String[] {"my-host", "local"},
+ 12345,
+ "192.168.1.1",
+ "2001::1",
+ List.of());
+
+ assertEquals(info.getInterfaceIndex(), -1);
+ }
+
+ @Test
+ public void getInterfaceIndex_constructorWithInterfaceIndex_returnsProvidedIndex() {
+ MdnsServiceInfo info =
+ new MdnsServiceInfo(
+ "my-mdns-service",
+ new String[] {"_googlecast", "_tcp"},
+ List.of(),
+ new String[] {"my-host", "local"},
+ 12345,
+ "192.168.1.1",
+ "2001::1",
+ List.of(),
+ /* textEntries= */ null,
+ /* interfaceIndex= */ 20);
+
+ assertEquals(info.getInterfaceIndex(), 20);
+ }
+
+ @Test
+ public void parcelable_canBeParceledAndUnparceled() {
+ Parcel parcel = Parcel.obtain();
+ MdnsServiceInfo beforeParcel =
+ new MdnsServiceInfo(
+ "my-mdns-service",
+ new String[] {"_googlecast", "_tcp"},
+ List.of(),
+ new String[] {"my-host", "local"},
+ 12345,
+ "192.168.1.1",
+ "2001::1",
+ List.of("vn=Alphabet Inc.", "mn=Google Nest Hub Max", "id=12345"),
+ List.of(
+ MdnsServiceInfo.TextEntry.fromString("vn=Google Inc."),
+ MdnsServiceInfo.TextEntry.fromString("mn=Google Nest Hub Max")));
+
+ beforeParcel.writeToParcel(parcel, 0);
+ parcel.setDataPosition(0);
+ MdnsServiceInfo afterParcel = MdnsServiceInfo.CREATOR.createFromParcel(parcel);
+
+ assertEquals(beforeParcel.getServiceInstanceName(), afterParcel.getServiceInstanceName());
+ assertArrayEquals(beforeParcel.getServiceType(), afterParcel.getServiceType());
+ assertEquals(beforeParcel.getSubtypes(), afterParcel.getSubtypes());
+ assertArrayEquals(beforeParcel.getHostName(), afterParcel.getHostName());
+ assertEquals(beforeParcel.getPort(), afterParcel.getPort());
+ assertEquals(beforeParcel.getIpv4Address(), afterParcel.getIpv4Address());
+ assertEquals(beforeParcel.getIpv6Address(), afterParcel.getIpv6Address());
+ assertEquals(beforeParcel.getAttributes(), afterParcel.getAttributes());
+ }
+
+ @Test
+ public void textEntry_parcelable_canBeParceledAndUnparceled() {
+ Parcel parcel = Parcel.obtain();
+ TextEntry beforeParcel = new TextEntry("AA", new byte[] {(byte) 0xFF, (byte) 0xFC});
+
+ beforeParcel.writeToParcel(parcel, 0);
+ parcel.setDataPosition(0);
+ TextEntry afterParcel = TextEntry.CREATOR.createFromParcel(parcel);
+
+ assertEquals(beforeParcel, afterParcel);
+ }
+
+ @Test
+ public void textEntry_fromString_keyValueAreExpected() {
+ TextEntry entry = TextEntry.fromString("AA=xxyyzz");
+
+ assertEquals("AA", entry.getKey());
+ assertArrayEquals(new byte[] {'x', 'x', 'y', 'y', 'z', 'z'}, entry.getValue());
+ }
+
+ @Test
+ public void textEntry_fromStringToString_textUnchanged() {
+ TextEntry entry = TextEntry.fromString("AA=xxyyzz");
+
+ assertEquals("AA=xxyyzz", entry.toString());
+ }
+
+ @Test
+ public void textEntry_fromStringWithoutAssignPunc_valueisEmpty() {
+ TextEntry entry = TextEntry.fromString("AA");
+
+ assertEquals("AA", entry.getKey());
+ assertArrayEquals(new byte[] {}, entry.getValue());
+ }
+
+ @Test
+ public void textEntry_fromStringAssignPuncAtBeginning_returnsNull() {
+ TextEntry entry = TextEntry.fromString("=AA");
+
+ assertNull(entry);
+ }
+
+ @Test
+ public void textEntry_fromBytes_keyAndValueAreExpected() {
+ TextEntry entry = TextEntry.fromBytes(
+ new byte[] {'A', 'A', '=', 'x', 'x', 'y', 'y', 'z', 'z'});
+
+ assertEquals("AA", entry.getKey());
+ assertArrayEquals(new byte[] {'x', 'x', 'y', 'y', 'z', 'z'}, entry.getValue());
+ }
+
+ @Test
+ public void textEntry_fromBytesToBytes_textUnchanged() {
+ TextEntry entry = TextEntry.fromBytes(
+ new byte[] {'A', 'A', '=', 'x', 'x', 'y', 'y', 'z', 'z'});
+
+ assertArrayEquals(new byte[] {'A', 'A', '=', 'x', 'x', 'y', 'y', 'z', 'z'},
+ entry.toBytes());
+ }
+
+ @Test
+ public void textEntry_fromBytesWithoutAssignPunc_valueisEmpty() {
+ TextEntry entry = TextEntry.fromBytes(new byte[] {'A', 'A'});
+
+ assertEquals("AA", entry.getKey());
+ assertArrayEquals(new byte[] {}, entry.getValue());
+ }
+
+ @Test
+ public void textEntry_fromBytesAssignPuncAtBeginning_returnsNull() {
+ TextEntry entry = TextEntry.fromBytes(new byte[] {'=', 'A', 'A'});
+
+ assertNull(entry);
+ }
+
+ @Test
+ public void textEntry_fromNonUtf8Bytes_keyValueAreExpected() {
+ TextEntry entry = TextEntry.fromBytes(
+ new byte[] {'A', 'A', '=', (byte) 0xFF, (byte) 0xFE, (byte) 0xFD});
+
+ assertEquals("AA", entry.getKey());
+ assertArrayEquals(new byte[] {(byte) 0xFF, (byte) 0xFE, (byte) 0xFD}, entry.getValue());
+ }
+
+ @Test
+ public void textEntry_equals() {
+ assertEquals(new TextEntry("AA", "xxyyzz"), new TextEntry("AA", "xxyyzz"));
+ assertEquals(new TextEntry("BB", "xxyyzz"), new TextEntry("BB", "xxyyzz"));
+ assertEquals(new TextEntry("AA", "XXYYZZ"), new TextEntry("AA", "XXYYZZ"));
+ }
+}
diff --git a/tests/unit/java/com/android/server/connectivity/mdns/MdnsServiceTypeClientTests.java b/tests/unit/java/com/android/server/connectivity/mdns/MdnsServiceTypeClientTests.java
index 5843fd0..6b10c71 100644
--- a/tests/unit/java/com/android/server/connectivity/mdns/MdnsServiceTypeClientTests.java
+++ b/tests/unit/java/com/android/server/connectivity/mdns/MdnsServiceTypeClientTests.java
@@ -32,8 +32,11 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import static java.nio.charset.StandardCharsets.UTF_8;
+
import android.annotation.NonNull;
+import com.android.server.connectivity.mdns.MdnsServiceInfo.TextEntry;
import com.android.server.connectivity.mdns.MdnsServiceTypeClient.QueryTaskConfig;
import com.android.testutils.DevSdkIgnoreRule;
import com.android.testutils.DevSdkIgnoreRunner;
@@ -53,7 +56,6 @@
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.SocketAddress;
-import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -399,7 +401,8 @@
ipV4Address,
5353,
Collections.singletonList("ABCDE"),
- Collections.emptyMap());
+ Collections.emptyMap(),
+ /* interfaceIndex= */ 20);
client.processResponse(initialResponse);
// Process a second response with a different port and updated text attributes.
@@ -409,7 +412,8 @@
ipV4Address,
5354,
Collections.singletonList("ABCDE"),
- Collections.singletonMap("key", "value"));
+ Collections.singletonMap("key", "value"),
+ /* interfaceIndex= */ 20);
client.processResponse(secondResponse);
// Verify onServiceFound was called once for the initial response.
@@ -420,6 +424,7 @@
assertEquals(initialServiceInfo.getPort(), 5353);
assertEquals(initialServiceInfo.getSubtypes(), Collections.singletonList("ABCDE"));
assertNull(initialServiceInfo.getAttributeByKey("key"));
+ assertEquals(initialServiceInfo.getInterfaceIndex(), 20);
// Verify onServiceUpdated was called once for the second response.
verify(mockListenerOne).onServiceUpdated(serviceInfoCaptor.capture());
@@ -430,6 +435,7 @@
assertTrue(updatedServiceInfo.hasSubtypes());
assertEquals(updatedServiceInfo.getSubtypes(), Collections.singletonList("ABCDE"));
assertEquals(updatedServiceInfo.getAttributeByKey("key"), "value");
+ assertEquals(updatedServiceInfo.getInterfaceIndex(), 20);
}
@Test
@@ -444,7 +450,8 @@
ipV6Address,
5353,
Collections.singletonList("ABCDE"),
- Collections.emptyMap());
+ Collections.emptyMap(),
+ /* interfaceIndex= */ 20);
client.processResponse(initialResponse);
// Process a second response with a different port and updated text attributes.
@@ -454,7 +461,8 @@
ipV6Address,
5354,
Collections.singletonList("ABCDE"),
- Collections.singletonMap("key", "value"));
+ Collections.singletonMap("key", "value"),
+ /* interfaceIndex= */ 20);
client.processResponse(secondResponse);
System.out.println("secondResponses ip"
@@ -468,6 +476,7 @@
assertEquals(initialServiceInfo.getPort(), 5353);
assertEquals(initialServiceInfo.getSubtypes(), Collections.singletonList("ABCDE"));
assertNull(initialServiceInfo.getAttributeByKey("key"));
+ assertEquals(initialServiceInfo.getInterfaceIndex(), 20);
// Verify onServiceUpdated was called once for the second response.
verify(mockListenerOne).onServiceUpdated(serviceInfoCaptor.capture());
@@ -478,6 +487,7 @@
assertTrue(updatedServiceInfo.hasSubtypes());
assertEquals(updatedServiceInfo.getSubtypes(), Collections.singletonList("ABCDE"));
assertEquals(updatedServiceInfo.getAttributeByKey("key"), "value");
+ assertEquals(updatedServiceInfo.getInterfaceIndex(), 20);
}
@Test
@@ -495,7 +505,7 @@
}
@Test
- public void reportExistingServiceToNewlyRegisteredListeners() throws UnknownHostException {
+ public void reportExistingServiceToNewlyRegisteredListeners() throws Exception {
// Process the initial response.
MdnsResponse initialResponse =
createResponse(
@@ -725,14 +735,26 @@
}
}
- // Creates a complete mDNS response.
private MdnsResponse createResponse(
@NonNull String serviceInstanceName,
@NonNull String host,
int port,
@NonNull List<String> subtypes,
@NonNull Map<String, String> textAttributes)
- throws UnknownHostException {
+ throws Exception {
+ return createResponse(serviceInstanceName, host, port, subtypes, textAttributes,
+ /* interfaceIndex= */ -1);
+ }
+
+ // Creates a complete mDNS response.
+ private MdnsResponse createResponse(
+ @NonNull String serviceInstanceName,
+ @NonNull String host,
+ int port,
+ @NonNull List<String> subtypes,
+ @NonNull Map<String, String> textAttributes,
+ int interfaceIndex)
+ throws Exception {
String[] hostName = new String[]{"hostname"};
MdnsServiceRecord serviceRecord = mock(MdnsServiceRecord.class);
when(serviceRecord.getServiceHost()).thenReturn(hostName);
@@ -745,18 +767,23 @@
when(inetAddressRecord.getInet6Address())
.thenReturn((Inet6Address) Inet6Address.getByName(host));
response.setInet6AddressRecord(inetAddressRecord);
+ response.setInterfaceIndex(interfaceIndex);
} else {
when(inetAddressRecord.getInet4Address())
.thenReturn((Inet4Address) Inet4Address.getByName(host));
response.setInet4AddressRecord(inetAddressRecord);
+ response.setInterfaceIndex(interfaceIndex);
}
MdnsTextRecord textRecord = mock(MdnsTextRecord.class);
List<String> textStrings = new ArrayList<>();
+ List<TextEntry> textEntries = new ArrayList<>();
for (Map.Entry<String, String> kv : textAttributes.entrySet()) {
textStrings.add(kv.getKey() + "=" + kv.getValue());
+ textEntries.add(new TextEntry(kv.getKey(), kv.getValue().getBytes(UTF_8)));
}
when(textRecord.getStrings()).thenReturn(textStrings);
+ when(textRecord.getEntries()).thenReturn(textEntries);
response.setServiceRecord(serviceRecord);
response.setTextRecord(textRecord);
diff --git a/tests/unit/java/com/android/server/connectivity/mdns/MdnsSocketClientTests.java b/tests/unit/java/com/android/server/connectivity/mdns/MdnsSocketClientTests.java
index 21ed7eb..b4442a5 100644
--- a/tests/unit/java/com/android/server/connectivity/mdns/MdnsSocketClientTests.java
+++ b/tests/unit/java/com/android/server/connectivity/mdns/MdnsSocketClientTests.java
@@ -18,13 +18,16 @@
import static com.android.testutils.DevSdkIgnoreRuleKt.SC_V2;
+import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.timeout;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -45,6 +48,7 @@
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
import org.mockito.ArgumentMatchers;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@@ -490,4 +494,55 @@
assertFalse(mdnsClient.receivedUnicastResponse);
assertFalse(mdnsClient.cannotReceiveMulticastResponse.get());
}
+
+ @Test
+ public void startDiscovery_andPropagateInterfaceIndex_includesInterfaceIndex()
+ throws Exception {
+ //MdnsConfigsFlagsImpl.allowNetworkInterfaceIndexPropagation.override(true);
+
+ when(mockMulticastSocket.getInterfaceIndex()).thenReturn(21);
+ mdnsClient =
+ new MdnsSocketClient(mContext, mockMulticastLock) {
+ @Override
+ MdnsSocket createMdnsSocket(int port) {
+ if (port == MdnsConstants.MDNS_PORT) {
+ return mockMulticastSocket;
+ }
+ return mockUnicastSocket;
+ }
+ };
+ mdnsClient.setCallback(mockCallback);
+ mdnsClient.startDiscovery();
+
+ verify(mockCallback, timeout(TIMEOUT).atLeastOnce())
+ .onResponseReceived(argThat(response -> response.getInterfaceIndex() == 21));
+ }
+
+ @Test
+ @Ignore("MdnsConfigs is not configurable currently.")
+ public void startDiscovery_andDoNotPropagateInterfaceIndex_doesNotIncludeInterfaceIndex()
+ throws Exception {
+ //MdnsConfigsFlagsImpl.allowNetworkInterfaceIndexPropagation.override(false);
+
+ when(mockMulticastSocket.getInterfaceIndex()).thenReturn(21);
+ mdnsClient =
+ new MdnsSocketClient(mContext, mockMulticastLock) {
+ @Override
+ MdnsSocket createMdnsSocket(int port) {
+ if (port == MdnsConstants.MDNS_PORT) {
+ return mockMulticastSocket;
+ }
+ return mockUnicastSocket;
+ }
+ };
+ mdnsClient.setCallback(mockCallback);
+ mdnsClient.startDiscovery();
+
+ ArgumentCaptor<MdnsResponse> mdnsResponseCaptor =
+ ArgumentCaptor.forClass(MdnsResponse.class);
+ verify(mockMulticastSocket, never()).getInterfaceIndex();
+ verify(mockCallback, timeout(TIMEOUT).atLeast(1))
+ .onResponseReceived(mdnsResponseCaptor.capture());
+ assertEquals(-1, mdnsResponseCaptor.getValue().getInterfaceIndex());
+ }
}
\ No newline at end of file
diff --git a/tests/unit/java/com/android/server/ethernet/EthernetNetworkFactoryTest.java b/tests/unit/java/com/android/server/ethernet/EthernetNetworkFactoryTest.java
index 503d920..949e0c2 100644
--- a/tests/unit/java/com/android/server/ethernet/EthernetNetworkFactoryTest.java
+++ b/tests/unit/java/com/android/server/ethernet/EthernetNetworkFactoryTest.java
@@ -20,13 +20,11 @@
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.ArgumentMatchers.same;
import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.never;
@@ -38,9 +36,7 @@
import android.content.Context;
import android.content.res.Resources;
import android.net.ConnectivityManager;
-import android.net.EthernetNetworkManagementException;
import android.net.EthernetNetworkSpecifier;
-import android.net.INetworkInterfaceOutcomeReceiver;
import android.net.IpConfiguration;
import android.net.LinkAddress;
import android.net.LinkProperties;
@@ -55,7 +51,6 @@
import android.net.ip.IpClientManager;
import android.os.Build;
import android.os.Handler;
-import android.os.IBinder;
import android.os.Looper;
import android.os.test.TestLooper;
@@ -74,9 +69,6 @@
import org.mockito.MockitoAnnotations;
import java.util.Objects;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeUnit;
@SmallTest
@RunWith(DevSdkIgnoreRunner.class)
@@ -84,7 +76,6 @@
public class EthernetNetworkFactoryTest {
private static final int TIMEOUT_MS = 2_000;
private static final String TEST_IFACE = "test123";
- private static final INetworkInterfaceOutcomeReceiver NULL_LISTENER = null;
private static final String IP_ADDR = "192.0.2.2/25";
private static final LinkAddress LINK_ADDR = new LinkAddress(IP_ADDR);
private static final String HW_ADDR = "01:02:03:04:05:06";
@@ -241,7 +232,7 @@
final IpConfiguration ipConfig = createDefaultIpConfig();
mNetFactory.addInterface(iface, HW_ADDR, ipConfig,
createInterfaceCapsBuilder(transportType).build());
- assertTrue(mNetFactory.updateInterfaceLinkState(iface, true, NULL_LISTENER));
+ assertTrue(mNetFactory.updateInterfaceLinkState(iface, true));
ArgumentCaptor<NetworkOfferCallback> captor = ArgumentCaptor.forClass(
NetworkOfferCallback.class);
@@ -295,7 +286,7 @@
// then calling onNetworkUnwanted.
mNetFactory.addInterface(iface, HW_ADDR, createDefaultIpConfig(),
createInterfaceCapsBuilder(NetworkCapabilities.TRANSPORT_ETHERNET).build());
- assertTrue(mNetFactory.updateInterfaceLinkState(iface, true, NULL_LISTENER));
+ assertTrue(mNetFactory.updateInterfaceLinkState(iface, true));
clearInvocations(mIpClient);
clearInvocations(mNetworkAgent);
@@ -305,81 +296,23 @@
public void testUpdateInterfaceLinkStateForActiveProvisioningInterface() throws Exception {
initEthernetNetworkFactory();
createInterfaceUndergoingProvisioning(TEST_IFACE);
- final TestNetworkManagementListener listener = new TestNetworkManagementListener();
// verify that the IpClient gets shut down when interface state changes to down.
- final boolean ret =
- mNetFactory.updateInterfaceLinkState(TEST_IFACE, false /* up */, listener);
+ final boolean ret = mNetFactory.updateInterfaceLinkState(TEST_IFACE, false /* up */);
assertTrue(ret);
verify(mIpClient).shutdown();
- assertEquals(TEST_IFACE, listener.expectOnResult());
- }
-
- @Test
- public void testUpdateInterfaceLinkStateForProvisionedInterface() throws Exception {
- initEthernetNetworkFactory();
- createAndVerifyProvisionedInterface(TEST_IFACE);
- final TestNetworkManagementListener listenerDown = new TestNetworkManagementListener();
- final TestNetworkManagementListener listenerUp = new TestNetworkManagementListener();
-
- final boolean retDown =
- mNetFactory.updateInterfaceLinkState(TEST_IFACE, false /* up */, listenerDown);
-
- assertTrue(retDown);
- verifyStop();
- assertEquals(TEST_IFACE, listenerDown.expectOnResult());
-
- final boolean retUp =
- mNetFactory.updateInterfaceLinkState(TEST_IFACE, true /* up */, listenerUp);
-
- assertTrue(retUp);
- assertEquals(TEST_IFACE, listenerUp.expectOnResult());
- }
-
- @Test
- public void testUpdateInterfaceLinkStateForUnprovisionedInterface() throws Exception {
- initEthernetNetworkFactory();
- createUnprovisionedInterface(TEST_IFACE);
- final TestNetworkManagementListener listener = new TestNetworkManagementListener();
-
- final boolean ret =
- mNetFactory.updateInterfaceLinkState(TEST_IFACE, false /* up */, listener);
-
- assertTrue(ret);
- // There should not be an active IPClient or NetworkAgent.
- verify(mDeps, never()).makeIpClient(any(), any(), any());
- verify(mDeps, never())
- .makeEthernetNetworkAgent(any(), any(), any(), any(), any(), any(), any());
- assertEquals(TEST_IFACE, listener.expectOnResult());
}
@Test
public void testUpdateInterfaceLinkStateForNonExistingInterface() throws Exception {
initEthernetNetworkFactory();
- final TestNetworkManagementListener listener = new TestNetworkManagementListener();
// if interface was never added, link state cannot be updated.
- final boolean ret =
- mNetFactory.updateInterfaceLinkState(TEST_IFACE, true /* up */, listener);
+ final boolean ret = mNetFactory.updateInterfaceLinkState(TEST_IFACE, true /* up */);
assertFalse(ret);
verifyNoStopOrStart();
- listener.expectOnError();
- }
-
- @Test
- public void testUpdateInterfaceLinkStateWithNoChanges() throws Exception {
- initEthernetNetworkFactory();
- createAndVerifyProvisionedInterface(TEST_IFACE);
- final TestNetworkManagementListener listener = new TestNetworkManagementListener();
-
- final boolean ret =
- mNetFactory.updateInterfaceLinkState(TEST_IFACE, true /* up */, listener);
-
- assertFalse(ret);
- verifyNoStopOrStart();
- listener.expectOnError();
}
@Test
@@ -416,17 +349,6 @@
}
@Test
- public void testLinkPropertiesChanged() throws Exception {
- initEthernetNetworkFactory();
- createAndVerifyProvisionedInterface(TEST_IFACE);
-
- LinkProperties lp = new LinkProperties();
- mIpClientCallbacks.onLinkPropertiesChange(lp);
- mLooper.dispatchAll();
- verify(mNetworkAgent).sendLinkPropertiesImpl(same(lp));
- }
-
- @Test
public void testNetworkUnwanted() throws Exception {
initEthernetNetworkFactory();
createAndVerifyProvisionedInterface(TEST_IFACE);
@@ -571,127 +493,16 @@
verify(mNetworkAgent).markConnected();
}
- private static final class TestNetworkManagementListener
- implements INetworkInterfaceOutcomeReceiver {
- private final CompletableFuture<String> mResult = new CompletableFuture<>();
-
- @Override
- public void onResult(@NonNull String iface) {
- mResult.complete(iface);
- }
-
- @Override
- public void onError(@NonNull EthernetNetworkManagementException exception) {
- mResult.completeExceptionally(exception);
- }
-
- String expectOnResult() throws Exception {
- return mResult.get(TIMEOUT_MS, TimeUnit.MILLISECONDS);
- }
-
- void expectOnError() throws Exception {
- assertThrows(EthernetNetworkManagementException.class, () -> {
- try {
- mResult.get();
- } catch (ExecutionException e) {
- throw e.getCause();
- }
- });
- }
-
- @Override
- public IBinder asBinder() {
- return null;
- }
- }
-
- @Test
- public void testUpdateInterfaceCallsListenerCorrectlyOnSuccess() throws Exception {
- initEthernetNetworkFactory();
- createAndVerifyProvisionedInterface(TEST_IFACE);
- final NetworkCapabilities capabilities = createDefaultFilterCaps();
- final IpConfiguration ipConfiguration = createStaticIpConfig();
- final TestNetworkManagementListener listener = new TestNetworkManagementListener();
-
- mNetFactory.updateInterface(TEST_IFACE, ipConfiguration, capabilities, listener);
- triggerOnProvisioningSuccess();
-
- assertEquals(TEST_IFACE, listener.expectOnResult());
- }
-
- @Test
- public void testUpdateInterfaceAbortsOnConcurrentRemoveInterface() throws Exception {
- initEthernetNetworkFactory();
- verifyNetworkManagementCallIsAbortedWhenInterrupted(
- TEST_IFACE,
- () -> mNetFactory.removeInterface(TEST_IFACE));
- }
-
- @Test
- public void testUpdateInterfaceAbortsOnConcurrentUpdateInterfaceLinkState() throws Exception {
- initEthernetNetworkFactory();
- verifyNetworkManagementCallIsAbortedWhenInterrupted(
- TEST_IFACE,
- () -> mNetFactory.updateInterfaceLinkState(TEST_IFACE, false, NULL_LISTENER));
- }
-
- @Test
- public void testUpdateInterfaceAbortsOnNetworkUneededRemovesAllRequests() throws Exception {
- initEthernetNetworkFactory();
- verifyNetworkManagementCallIsAbortedWhenInterrupted(
- TEST_IFACE,
- () -> mNetworkOfferCallback.onNetworkUnneeded(mRequestToKeepNetworkUp));
- }
-
- @Test
- public void testUpdateInterfaceCallsListenerCorrectlyOnConcurrentRequests() throws Exception {
- initEthernetNetworkFactory();
- final NetworkCapabilities capabilities = createDefaultFilterCaps();
- final IpConfiguration ipConfiguration = createStaticIpConfig();
- final TestNetworkManagementListener successfulListener =
- new TestNetworkManagementListener();
-
- // If two calls come in before the first one completes, the first listener will be aborted
- // and the second one will be successful.
- verifyNetworkManagementCallIsAbortedWhenInterrupted(
- TEST_IFACE,
- () -> {
- mNetFactory.updateInterface(
- TEST_IFACE, ipConfiguration, capabilities, successfulListener);
- triggerOnProvisioningSuccess();
- });
-
- assertEquals(successfulListener.expectOnResult(), TEST_IFACE);
- assertEquals(TEST_IFACE, successfulListener.expectOnResult());
- }
-
- private void verifyNetworkManagementCallIsAbortedWhenInterrupted(
- @NonNull final String iface,
- @NonNull final Runnable interruptingRunnable) throws Exception {
- createAndVerifyProvisionedInterface(iface);
- final NetworkCapabilities capabilities = createDefaultFilterCaps();
- final IpConfiguration ipConfiguration = createStaticIpConfig();
- final TestNetworkManagementListener failedListener = new TestNetworkManagementListener();
-
- // An active update request will be aborted on interrupt prior to provisioning completion.
- mNetFactory.updateInterface(iface, ipConfiguration, capabilities, failedListener);
- interruptingRunnable.run();
-
- failedListener.expectOnError();
- }
-
@Test
public void testUpdateInterfaceRestartsAgentCorrectly() throws Exception {
initEthernetNetworkFactory();
createAndVerifyProvisionedInterface(TEST_IFACE);
final NetworkCapabilities capabilities = createDefaultFilterCaps();
final IpConfiguration ipConfiguration = createStaticIpConfig();
- final TestNetworkManagementListener listener = new TestNetworkManagementListener();
- mNetFactory.updateInterface(TEST_IFACE, ipConfiguration, capabilities, listener);
+ mNetFactory.updateInterface(TEST_IFACE, ipConfiguration, capabilities);
triggerOnProvisioningSuccess();
- assertEquals(TEST_IFACE, listener.expectOnResult());
verify(mDeps).makeEthernetNetworkAgent(any(), any(),
eq(capabilities), any(), any(), any(), any());
verifyRestart(ipConfiguration);
@@ -703,12 +514,10 @@
// No interface exists due to not calling createAndVerifyProvisionedInterface(...).
final NetworkCapabilities capabilities = createDefaultFilterCaps();
final IpConfiguration ipConfiguration = createStaticIpConfig();
- final TestNetworkManagementListener listener = new TestNetworkManagementListener();
- mNetFactory.updateInterface(TEST_IFACE, ipConfiguration, capabilities, listener);
+ mNetFactory.updateInterface(TEST_IFACE, ipConfiguration, capabilities);
verifyNoStopOrStart();
- listener.expectOnError();
}
@Test
@@ -717,8 +526,8 @@
createAndVerifyProvisionedInterface(TEST_IFACE);
final IpConfiguration initialIpConfig = createStaticIpConfig();
- mNetFactory.updateInterface(TEST_IFACE, initialIpConfig, null /*capabilities*/,
- null /*listener*/);
+ mNetFactory.updateInterface(TEST_IFACE, initialIpConfig, null /*capabilities*/);
+
triggerOnProvisioningSuccess();
verifyRestart(initialIpConfig);
@@ -729,8 +538,7 @@
// verify that sending a null ipConfig does not update the current ipConfig.
- mNetFactory.updateInterface(TEST_IFACE, null /*ipConfig*/, null /*capabilities*/,
- null /*listener*/);
+ mNetFactory.updateInterface(TEST_IFACE, null /*ipConfig*/, null /*capabilities*/);
triggerOnProvisioningSuccess();
verifyRestart(initialIpConfig);
}
@@ -739,7 +547,7 @@
public void testOnNetworkNeededOnStaleNetworkOffer() throws Exception {
initEthernetNetworkFactory();
createAndVerifyProvisionedInterface(TEST_IFACE);
- mNetFactory.updateInterfaceLinkState(TEST_IFACE, false, null);
+ mNetFactory.updateInterfaceLinkState(TEST_IFACE, false);
verify(mNetworkProvider).unregisterNetworkOffer(mNetworkOfferCallback);
// It is possible that even after a network offer is unregistered, CS still sends it
// onNetworkNeeded() callbacks.
diff --git a/tests/unit/java/com/android/server/ethernet/EthernetServiceImplTest.java b/tests/unit/java/com/android/server/ethernet/EthernetServiceImplTest.java
index a1d93a0..9bf893a 100644
--- a/tests/unit/java/com/android/server/ethernet/EthernetServiceImplTest.java
+++ b/tests/unit/java/com/android/server/ethernet/EthernetServiceImplTest.java
@@ -21,6 +21,7 @@
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.fail;
+import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.isNull;
@@ -209,7 +210,8 @@
NULL_LISTENER);
verify(mEthernetTracker).updateConfiguration(eq(TEST_IFACE),
eq(UPDATE_REQUEST_WITHOUT_CAPABILITIES.getIpConfiguration()),
- eq(UPDATE_REQUEST_WITHOUT_CAPABILITIES.getNetworkCapabilities()), isNull());
+ eq(UPDATE_REQUEST_WITHOUT_CAPABILITIES.getNetworkCapabilities()),
+ any(EthernetCallback.class));
}
private void denyManageEthPermission() {
@@ -285,7 +287,8 @@
verify(mEthernetTracker).updateConfiguration(
eq(TEST_IFACE),
eq(UPDATE_REQUEST.getIpConfiguration()),
- eq(UPDATE_REQUEST.getNetworkCapabilities()), eq(NULL_LISTENER));
+ eq(UPDATE_REQUEST.getNetworkCapabilities()),
+ any(EthernetCallback.class));
}
@Test
@@ -303,19 +306,20 @@
verify(mEthernetTracker).updateConfiguration(
eq(TEST_IFACE),
isNull(),
- eq(ncWithSpecifier), eq(NULL_LISTENER));
+ eq(ncWithSpecifier), any(EthernetCallback.class));
}
@Test
public void testEnableInterface() {
mEthernetServiceImpl.enableInterface(TEST_IFACE, NULL_LISTENER);
- verify(mEthernetTracker).enableInterface(eq(TEST_IFACE), eq(NULL_LISTENER));
+ verify(mEthernetTracker).enableInterface(eq(TEST_IFACE),
+ any(EthernetCallback.class));
}
@Test
public void testDisableInterface() {
mEthernetServiceImpl.disableInterface(TEST_IFACE, NULL_LISTENER);
- verify(mEthernetTracker).disableInterface(eq(TEST_IFACE), eq(NULL_LISTENER));
+ verify(mEthernetTracker).disableInterface(eq(TEST_IFACE), any(EthernetCallback.class));
}
@Test
@@ -328,7 +332,7 @@
mEthernetServiceImpl.updateConfiguration(TEST_IFACE, request, NULL_LISTENER);
verify(mEthernetTracker).updateConfiguration(eq(TEST_IFACE),
eq(request.getIpConfiguration()),
- eq(request.getNetworkCapabilities()), isNull());
+ eq(request.getNetworkCapabilities()), any(EthernetCallback.class));
}
@Test
@@ -337,7 +341,8 @@
NULL_LISTENER);
verify(mEthernetTracker).updateConfiguration(eq(TEST_IFACE),
eq(UPDATE_REQUEST_WITHOUT_IP_CONFIG.getIpConfiguration()),
- eq(UPDATE_REQUEST_WITHOUT_IP_CONFIG.getNetworkCapabilities()), isNull());
+ eq(UPDATE_REQUEST_WITHOUT_IP_CONFIG.getNetworkCapabilities()),
+ any(EthernetCallback.class));
}
@Test
@@ -369,7 +374,7 @@
verify(mEthernetTracker).updateConfiguration(
eq(TEST_IFACE),
eq(request.getIpConfiguration()),
- eq(request.getNetworkCapabilities()), eq(NULL_LISTENER));
+ eq(request.getNetworkCapabilities()), any(EthernetCallback.class));
}
@Test
@@ -379,7 +384,8 @@
denyManageEthPermission();
mEthernetServiceImpl.enableInterface(TEST_IFACE, NULL_LISTENER);
- verify(mEthernetTracker).enableInterface(eq(TEST_IFACE), eq(NULL_LISTENER));
+ verify(mEthernetTracker).enableInterface(eq(TEST_IFACE),
+ any(EthernetCallback.class));
}
@Test
@@ -389,7 +395,8 @@
denyManageEthPermission();
mEthernetServiceImpl.disableInterface(TEST_IFACE, NULL_LISTENER);
- verify(mEthernetTracker).disableInterface(eq(TEST_IFACE), eq(NULL_LISTENER));
+ verify(mEthernetTracker).disableInterface(eq(TEST_IFACE),
+ any(EthernetCallback.class));
}
private void denyPermissions(String... permissions) {
diff --git a/tests/unit/java/com/android/server/ethernet/EthernetTrackerTest.java b/tests/unit/java/com/android/server/ethernet/EthernetTrackerTest.java
index 0376a2a..5e7f0ff 100644
--- a/tests/unit/java/com/android/server/ethernet/EthernetTrackerTest.java
+++ b/tests/unit/java/com/android/server/ethernet/EthernetTrackerTest.java
@@ -23,25 +23,15 @@
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
-import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
-import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
import android.content.Context;
-import android.net.EthernetManager;
-import android.net.IEthernetServiceListener;
import android.net.INetd;
-import android.net.INetworkInterfaceOutcomeReceiver;
import android.net.InetAddresses;
-import android.net.InterfaceConfigurationParcel;
import android.net.IpConfiguration;
import android.net.IpConfiguration.IpAssignment;
import android.net.IpConfiguration.ProxySettings;
@@ -67,7 +57,6 @@
import java.net.InetAddress;
import java.util.ArrayList;
-import java.util.concurrent.atomic.AtomicBoolean;
@SmallTest
@RunWith(DevSdkIgnoreRunner.class)
@@ -76,7 +65,7 @@
private static final String TEST_IFACE = "test123";
private static final int TIMEOUT_MS = 1_000;
private static final String THREAD_NAME = "EthernetServiceThread";
- private static final INetworkInterfaceOutcomeReceiver NULL_LISTENER = null;
+ private static final EthernetCallback NULL_CB = new EthernetCallback(null);
private EthernetTracker tracker;
private HandlerThread mHandlerThread;
@Mock private Context mContext;
@@ -88,8 +77,8 @@
public void setUp() throws RemoteException {
MockitoAnnotations.initMocks(this);
initMockResources();
- when(mFactory.updateInterfaceLinkState(anyString(), anyBoolean(), any())).thenReturn(false);
- when(mNetd.interfaceGetList()).thenReturn(new String[0]);
+ doReturn(false).when(mFactory).updateInterfaceLinkState(anyString(), anyBoolean());
+ doReturn(new String[0]).when(mNetd).interfaceGetList();
mHandlerThread = new HandlerThread(THREAD_NAME);
mHandlerThread.start();
tracker = new EthernetTracker(mContext, mHandlerThread.getThreadHandler(), mFactory, mNetd,
@@ -102,8 +91,8 @@
}
private void initMockResources() {
- when(mDeps.getInterfaceRegexFromResource(eq(mContext))).thenReturn("");
- when(mDeps.getInterfaceConfigFromResource(eq(mContext))).thenReturn(new String[0]);
+ doReturn("").when(mDeps).getInterfaceRegexFromResource(eq(mContext));
+ doReturn(new String[0]).when(mDeps).getInterfaceConfigFromResource(eq(mContext));
}
private void waitForIdle() {
@@ -344,31 +333,13 @@
new StaticIpConfiguration.Builder().setIpAddress(linkAddr).build();
final IpConfiguration ipConfig =
new IpConfiguration.Builder().setStaticIpConfiguration(staticIpConfig).build();
- final INetworkInterfaceOutcomeReceiver listener = null;
+ final EthernetCallback listener = new EthernetCallback(null);
tracker.updateConfiguration(TEST_IFACE, ipConfig, capabilities, listener);
waitForIdle();
verify(mFactory).updateInterface(
- eq(TEST_IFACE), eq(ipConfig), eq(capabilities), eq(listener));
- }
-
- @Test
- public void testEnableInterfaceCorrectlyCallsFactory() {
- tracker.enableInterface(TEST_IFACE, NULL_LISTENER);
- waitForIdle();
-
- verify(mFactory).updateInterfaceLinkState(eq(TEST_IFACE), eq(true /* up */),
- eq(NULL_LISTENER));
- }
-
- @Test
- public void testDisableInterfaceCorrectlyCallsFactory() {
- tracker.disableInterface(TEST_IFACE, NULL_LISTENER);
- waitForIdle();
-
- verify(mFactory).updateInterfaceLinkState(eq(TEST_IFACE), eq(false /* up */),
- eq(NULL_LISTENER));
+ eq(TEST_IFACE), eq(ipConfig), eq(capabilities));
}
@Test
@@ -403,74 +374,4 @@
assertTrue(isValidTestInterface);
}
-
- public static class EthernetStateListener extends IEthernetServiceListener.Stub {
- @Override
- public void onEthernetStateChanged(int state) { }
-
- @Override
- public void onInterfaceStateChanged(String iface, int state, int role,
- IpConfiguration configuration) { }
- }
-
- private InterfaceConfigurationParcel createMockedIfaceParcel(final String ifname,
- final String hwAddr) {
- final InterfaceConfigurationParcel ifaceParcel = new InterfaceConfigurationParcel();
- ifaceParcel.ifName = ifname;
- ifaceParcel.hwAddr = hwAddr;
- ifaceParcel.flags = new String[] {INetd.IF_STATE_UP};
- return ifaceParcel;
- }
-
- @Test
- public void testListenEthernetStateChange() throws Exception {
- tracker.setIncludeTestInterfaces(true);
- waitForIdle();
-
- final String testIface = "testtap123";
- final String testHwAddr = "11:22:33:44:55:66";
- final InterfaceConfigurationParcel ifaceParcel = createMockedIfaceParcel(testIface,
- testHwAddr);
- when(mNetd.interfaceGetList()).thenReturn(new String[] {testIface});
- when(mNetd.interfaceGetCfg(eq(testIface))).thenReturn(ifaceParcel);
- doReturn(new String[] {testIface}).when(mFactory).getAvailableInterfaces(anyBoolean());
-
- final AtomicBoolean ifaceUp = new AtomicBoolean(true);
- doAnswer(inv -> ifaceUp.get()).when(mFactory).hasInterface(testIface);
- doAnswer(inv ->
- ifaceUp.get() ? EthernetManager.STATE_LINK_UP : EthernetManager.STATE_ABSENT)
- .when(mFactory).getInterfaceState(testIface);
- doAnswer(inv -> {
- ifaceUp.set(true);
- return null;
- }).when(mFactory).addInterface(eq(testIface), eq(testHwAddr), any(), any());
- doAnswer(inv -> {
- ifaceUp.set(false);
- return null;
- }).when(mFactory).removeInterface(testIface);
-
- final EthernetStateListener listener = spy(new EthernetStateListener());
- tracker.addListener(listener, true /* canUseRestrictedNetworks */);
- // Check default state.
- waitForIdle();
- verify(listener).onInterfaceStateChanged(eq(testIface), eq(EthernetManager.STATE_LINK_UP),
- anyInt(), any());
- verify(listener).onEthernetStateChanged(eq(EthernetManager.ETHERNET_STATE_ENABLED));
- reset(listener);
-
- tracker.setEthernetEnabled(false);
- waitForIdle();
- verify(mFactory).removeInterface(eq(testIface));
- verify(listener).onEthernetStateChanged(eq(EthernetManager.ETHERNET_STATE_DISABLED));
- verify(listener).onInterfaceStateChanged(eq(testIface), eq(EthernetManager.STATE_ABSENT),
- anyInt(), any());
- reset(listener);
-
- tracker.setEthernetEnabled(true);
- waitForIdle();
- verify(mFactory).addInterface(eq(testIface), eq(testHwAddr), any(), any());
- verify(listener).onEthernetStateChanged(eq(EthernetManager.ETHERNET_STATE_ENABLED));
- verify(listener).onInterfaceStateChanged(eq(testIface), eq(EthernetManager.STATE_LINK_UP),
- anyInt(), any());
- }
}
diff --git a/tests/unit/java/com/android/server/net/BpfInterfaceMapUpdaterTest.java b/tests/unit/java/com/android/server/net/BpfInterfaceMapUpdaterTest.java
index c6852d1..c730856 100644
--- a/tests/unit/java/com/android/server/net/BpfInterfaceMapUpdaterTest.java
+++ b/tests/unit/java/com/android/server/net/BpfInterfaceMapUpdaterTest.java
@@ -16,7 +16,14 @@
package com.android.server.net;
+import static android.system.OsConstants.EPERM;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
@@ -27,15 +34,18 @@
import android.os.Build;
import android.os.Handler;
import android.os.test.TestLooper;
+import android.system.ErrnoException;
+import android.util.IndentingPrintWriter;
import androidx.test.filters.SmallTest;
import com.android.net.module.util.BaseNetdUnsolicitedEventListener;
import com.android.net.module.util.IBpfMap;
import com.android.net.module.util.InterfaceParams;
-import com.android.net.module.util.Struct.U32;
+import com.android.net.module.util.Struct.S32;
import com.android.testutils.DevSdkIgnoreRule;
import com.android.testutils.DevSdkIgnoreRunner;
+import com.android.testutils.TestBpfMap;
import org.junit.Before;
import org.junit.Test;
@@ -44,6 +54,9 @@
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
@SmallTest
@RunWith(DevSdkIgnoreRunner.class)
@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.S_V2)
@@ -56,13 +69,14 @@
private final TestLooper mLooper = new TestLooper();
private BaseNetdUnsolicitedEventListener mListener;
private BpfInterfaceMapUpdater mUpdater;
- @Mock private IBpfMap<U32, InterfaceMapValue> mBpfMap;
+ private IBpfMap<S32, InterfaceMapValue> mBpfMap =
+ spy(new TestBpfMap<>(S32.class, InterfaceMapValue.class));
@Mock private INetd mNetd;
@Mock private Context mContext;
private class TestDependencies extends BpfInterfaceMapUpdater.Dependencies {
@Override
- public IBpfMap<U32, InterfaceMapValue> getInterfaceMap() {
+ public IBpfMap<S32, InterfaceMapValue> getInterfaceMap() {
return mBpfMap;
}
@@ -100,7 +114,7 @@
ArgumentCaptor.forClass(BaseNetdUnsolicitedEventListener.class);
verify(mNetd).registerUnsolicitedEventListener(listenerCaptor.capture());
mListener = listenerCaptor.getValue();
- verify(mBpfMap).updateEntry(eq(new U32(TEST_INDEX)),
+ verify(mBpfMap).updateEntry(eq(new S32(TEST_INDEX)),
eq(new InterfaceMapValue(TEST_INTERFACE_NAME)));
}
@@ -110,7 +124,7 @@
mListener.onInterfaceAdded(TEST_INTERFACE_NAME2);
mLooper.dispatchAll();
- verify(mBpfMap).updateEntry(eq(new U32(TEST_INDEX2)),
+ verify(mBpfMap).updateEntry(eq(new S32(TEST_INDEX2)),
eq(new InterfaceMapValue(TEST_INTERFACE_NAME2)));
// Check that when onInterfaceRemoved is called, nothing happens.
@@ -118,4 +132,43 @@
mLooper.dispatchAll();
verifyNoMoreInteractions(mBpfMap);
}
+
+ @Test
+ public void testGetIfNameByIndex() throws Exception {
+ mBpfMap.updateEntry(new S32(TEST_INDEX), new InterfaceMapValue(TEST_INTERFACE_NAME));
+ assertEquals(TEST_INTERFACE_NAME, mUpdater.getIfNameByIndex(TEST_INDEX));
+ }
+
+ @Test
+ public void testGetIfNameByIndexNoEntry() {
+ assertNull(mUpdater.getIfNameByIndex(TEST_INDEX));
+ }
+
+ @Test
+ public void testGetIfNameByIndexException() throws Exception {
+ doThrow(new ErrnoException("", EPERM)).when(mBpfMap).getValue(new S32(TEST_INDEX));
+ assertNull(mUpdater.getIfNameByIndex(TEST_INDEX));
+ }
+
+ private void assertDumpContains(final String dump, final String message) {
+ assertTrue(String.format("dump(%s) does not contain '%s'", dump, message),
+ dump.contains(message));
+ }
+
+ private String getDump() {
+ final StringWriter sw = new StringWriter();
+ mUpdater.dump(new IndentingPrintWriter(new PrintWriter(sw), " "));
+ return sw.toString();
+ }
+
+ @Test
+ public void testDump() throws ErrnoException {
+ mBpfMap.updateEntry(new S32(TEST_INDEX), new InterfaceMapValue(TEST_INTERFACE_NAME));
+ mBpfMap.updateEntry(new S32(TEST_INDEX2), new InterfaceMapValue(TEST_INTERFACE_NAME2));
+
+ final String dump = getDump();
+ assertDumpContains(dump, "IfaceIndexNameMap: OK");
+ assertDumpContains(dump, "ifaceIndex=1 ifaceName=test1");
+ assertDumpContains(dump, "ifaceIndex=2 ifaceName=test2");
+ }
}
diff --git a/tests/unit/java/com/android/server/net/InterfaceMapValueTest.java b/tests/unit/java/com/android/server/net/InterfaceMapValueTest.java
new file mode 100644
index 0000000..ee13d5f
--- /dev/null
+++ b/tests/unit/java/com/android/server/net/InterfaceMapValueTest.java
@@ -0,0 +1,68 @@
+/*
+ * 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.server.net;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class InterfaceMapValueTest {
+ private static final String IF_NAME = "wlan0";
+ private static final byte[] IF_NAME_BYTE = new byte[]{'w', 'l', 'a', 'n', '0'};
+ private static final byte[] IF_NAME_BYTE_WITH_PADDING =
+ new byte[]{'w', 'l', 'a', 'n', '0', 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0}; // IF_NAME_BYTE_WITH_PADDING.length = 16
+ private static final byte[] IF_NAME_BYTE_LONG =
+ new byte[]{'w', 'l', 'a', 'n', '0', 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0}; // IF_NAME_BYTE_LONG.length = 24
+
+ @Test
+ public void testInterfaceMapValueFromString() {
+ final InterfaceMapValue value = new InterfaceMapValue(IF_NAME);
+ assertArrayEquals(IF_NAME_BYTE_WITH_PADDING, value.interfaceName);
+ }
+
+ @Test
+ public void testInterfaceMapValueFromByte() {
+ final InterfaceMapValue value = new InterfaceMapValue(IF_NAME_BYTE_WITH_PADDING);
+ assertArrayEquals(IF_NAME_BYTE_WITH_PADDING, value.interfaceName);
+ }
+
+ @Test
+ public void testInterfaceMapValueFromByteShort() {
+ final InterfaceMapValue value = new InterfaceMapValue(IF_NAME_BYTE);
+ assertArrayEquals(IF_NAME_BYTE_WITH_PADDING, value.interfaceName);
+ }
+
+ @Test
+ public void testInterfaceMapValueFromByteLong() {
+ final InterfaceMapValue value = new InterfaceMapValue(IF_NAME_BYTE_LONG);
+ assertArrayEquals(IF_NAME_BYTE_WITH_PADDING, value.interfaceName);
+ }
+
+ @Test
+ public void testGetInterfaceNameString() {
+ final InterfaceMapValue value = new InterfaceMapValue(IF_NAME_BYTE_WITH_PADDING);
+ assertEquals(IF_NAME, value.getInterfaceNameString());
+ }
+}
diff --git a/tests/unit/java/com/android/server/net/NetworkStatsFactoryTest.java b/tests/unit/java/com/android/server/net/NetworkStatsFactoryTest.java
index 14455fa..04db6d3 100644
--- a/tests/unit/java/com/android/server/net/NetworkStatsFactoryTest.java
+++ b/tests/unit/java/com/android/server/net/NetworkStatsFactoryTest.java
@@ -25,6 +25,7 @@
import static android.net.NetworkStats.SET_ALL;
import static android.net.NetworkStats.SET_DEFAULT;
import static android.net.NetworkStats.SET_FOREGROUND;
+import static android.net.NetworkStats.TAG_ALL;
import static android.net.NetworkStats.TAG_NONE;
import static android.net.NetworkStats.UID_ALL;
@@ -89,6 +90,7 @@
// related to networkStatsFactory is compiled to a minimal native library and loaded here.
System.loadLibrary("networkstatsfactorytestjni");
doReturn(mBpfNetMaps).when(mDeps).createBpfNetMaps(any());
+
mFactory = new NetworkStatsFactory(mContext, mDeps);
mFactory.updateUnderlyingNetworkInfos(new UnderlyingNetworkInfo[0]);
}
@@ -462,6 +464,46 @@
assertNoStatsEntry(stats, "wlan0", 1029, SET_DEFAULT, 0x0);
}
+ @Test
+ public void testRemoveUidsStats() throws Exception {
+ final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 1)
+ .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 16L, 1L, 16L, 1L, 0L)
+ .insertEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE,
+ 256L, 16L, 512L, 32L, 0L)
+ .insertEntry(TEST_IFACE, UID_GREEN, SET_DEFAULT, TAG_NONE, 64L, 3L, 1024L, 8L, 0L);
+
+ doReturn(stats).when(mDeps).getNetworkStatsDetail(anyInt(), any(),
+ anyInt());
+
+ final String[] ifaces = new String[]{TEST_IFACE};
+ final NetworkStats res = mFactory.readNetworkStatsDetail(UID_ALL, ifaces, TAG_ALL);
+
+ // Verify that the result of the mocked stats are expected.
+ assertValues(res, TEST_IFACE, UID_RED, 16L, 1L, 16L, 1L);
+ assertValues(res, TEST_IFACE, UID_BLUE, 256L, 16L, 512L, 32L);
+ assertValues(res, TEST_IFACE, UID_GREEN, 64L, 3L, 1024L, 8L);
+
+ // Assume the apps were removed.
+ final int[] removedUids = new int[]{UID_RED, UID_BLUE};
+ mFactory.removeUidsLocked(removedUids);
+
+ // Return empty stats for reading the result of removing uids stats later.
+ doReturn(buildEmptyStats()).when(mDeps).getNetworkStatsDetail(anyInt(), any(),
+ anyInt());
+
+ final NetworkStats removedUidsStats =
+ mFactory.readNetworkStatsDetail(UID_ALL, ifaces, TAG_ALL);
+
+ // Verify that the stats of the removed uids were removed.
+ assertValues(removedUidsStats, TEST_IFACE, UID_RED, 0L, 0L, 0L, 0L);
+ assertValues(removedUidsStats, TEST_IFACE, UID_BLUE, 0L, 0L, 0L, 0L);
+ assertValues(removedUidsStats, TEST_IFACE, UID_GREEN, 64L, 3L, 1024L, 8L);
+ }
+
+ private NetworkStats buildEmptyStats() {
+ return new NetworkStats(SystemClock.elapsedRealtime(), 0);
+ }
+
private NetworkStats parseNetworkStatsFromGoldenSample(int resourceId, int initialSize,
boolean consumeHeader, boolean checkActive, boolean isUidData) throws IOException {
final NetworkStats stats =
diff --git a/tests/unit/java/com/android/server/net/NetworkStatsServiceTest.java b/tests/unit/java/com/android/server/net/NetworkStatsServiceTest.java
index 153f121..e8f30d6 100644
--- a/tests/unit/java/com/android/server/net/NetworkStatsServiceTest.java
+++ b/tests/unit/java/com/android/server/net/NetworkStatsServiceTest.java
@@ -25,6 +25,7 @@
import static android.content.pm.PackageManager.PERMISSION_DENIED;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.net.ConnectivityManager.TYPE_MOBILE;
+import static android.net.ConnectivityManager.TYPE_TEST;
import static android.net.ConnectivityManager.TYPE_WIFI;
import static android.net.NetworkIdentity.OEM_PAID;
import static android.net.NetworkIdentity.OEM_PRIVATE;
@@ -48,6 +49,7 @@
import static android.net.NetworkStats.UID_ALL;
import static android.net.NetworkStatsHistory.FIELD_ALL;
import static android.net.NetworkTemplate.MATCH_MOBILE;
+import static android.net.NetworkTemplate.MATCH_TEST;
import static android.net.NetworkTemplate.MATCH_WIFI;
import static android.net.NetworkTemplate.OEM_MANAGED_NO;
import static android.net.NetworkTemplate.OEM_MANAGED_YES;
@@ -73,19 +75,21 @@
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
+import static org.mockito.AdditionalMatchers.aryEq;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
import android.annotation.NonNull;
import android.app.AlarmManager;
@@ -107,6 +111,7 @@
import android.net.NetworkStatsHistory;
import android.net.NetworkTemplate;
import android.net.TelephonyNetworkSpecifier;
+import android.net.TestNetworkSpecifier;
import android.net.TetherStatsParcel;
import android.net.TetheringManager;
import android.net.UnderlyingNetworkInfo;
@@ -121,6 +126,7 @@
import android.provider.Settings;
import android.system.ErrnoException;
import android.telephony.TelephonyManager;
+import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.Pair;
@@ -135,10 +141,11 @@
import com.android.net.module.util.IBpfMap;
import com.android.net.module.util.LocationPermissionChecker;
import com.android.net.module.util.Struct;
-import com.android.net.module.util.Struct.U32;
+import com.android.net.module.util.Struct.S32;
import com.android.net.module.util.Struct.U8;
import com.android.net.module.util.bpf.CookieTagMapKey;
import com.android.net.module.util.bpf.CookieTagMapValue;
+import com.android.server.BpfNetMaps;
import com.android.server.net.NetworkStatsService.AlertObserver;
import com.android.server.net.NetworkStatsService.NetworkStatsSettings;
import com.android.server.net.NetworkStatsService.NetworkStatsSettings.Config;
@@ -172,6 +179,7 @@
import java.time.ZonedDateTime;
import java.time.temporal.ChronoUnit;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
@@ -209,9 +217,11 @@
private static final Network WIFI_NETWORK = new Network(100);
private static final Network MOBILE_NETWORK = new Network(101);
private static final Network VPN_NETWORK = new Network(102);
+ private static final Network TEST_NETWORK = new Network(103);
private static final Network[] NETWORKS_WIFI = new Network[]{ WIFI_NETWORK };
private static final Network[] NETWORKS_MOBILE = new Network[]{ MOBILE_NETWORK };
+ private static final Network[] NETWORKS_TEST = new Network[]{ TEST_NETWORK };
private static final long WAIT_TIMEOUT = 2 * 1000; // 2 secs
private static final int INVALID_TYPE = -1;
@@ -241,7 +251,11 @@
private HandlerThread mHandlerThread;
@Mock
private LocationPermissionChecker mLocationPermissionChecker;
- private TestBpfMap<U32, U8> mUidCounterSetMap = spy(new TestBpfMap<>(U32.class, U8.class));
+ private TestBpfMap<S32, U8> mUidCounterSetMap = spy(new TestBpfMap<>(S32.class, U8.class));
+ @Mock
+ private BpfNetMaps mBpfNetMaps;
+ @Mock
+ private SkDestroyListener mSkDestroyListener;
private TestBpfMap<CookieTagMapKey, CookieTagMapValue> mCookieTagMap = new TestBpfMap<>(
CookieTagMapKey.class, CookieTagMapValue.class);
@@ -251,7 +265,8 @@
StatsMapValue.class);
private TestBpfMap<UidStatsMapKey, StatsMapValue> mAppUidStatsMap = new TestBpfMap<>(
UidStatsMapKey.class, StatsMapValue.class);
-
+ private TestBpfMap<S32, StatsMapValue> mIfaceStatsMap = new TestBpfMap<>(
+ S32.class, StatsMapValue.class);
private NetworkStatsService mService;
private INetworkStatsSession mSession;
private AlertObserver mAlertObserver;
@@ -336,9 +351,9 @@
final Context context = InstrumentationRegistry.getContext();
mServiceContext = new MockContext(context);
- when(mLocationPermissionChecker.checkCallersLocationPermission(
- any(), any(), anyInt(), anyBoolean(), any())).thenReturn(true);
- when(sWifiInfo.getNetworkKey()).thenReturn(TEST_WIFI_NETWORK_KEY);
+ doReturn(true).when(mLocationPermissionChecker).checkCallersLocationPermission(
+ any(), any(), anyInt(), anyBoolean(), any());
+ doReturn(TEST_WIFI_NETWORK_KEY).when(sWifiInfo).getNetworkKey();
mStatsDir = TestIoUtils.createTemporaryDirectory(getClass().getSimpleName());
mLegacyStatsDir = TestIoUtils.createTemporaryDirectory(
getClass().getSimpleName() + "-legacy");
@@ -355,9 +370,9 @@
mElapsedRealtime = 0L;
- expectDefaultSettings();
- expectNetworkStatsUidDetail(buildEmptyStats());
- expectSystemReady();
+ mockDefaultSettings();
+ mockNetworkStatsUidDetail(buildEmptyStats());
+ prepareForSystemReady();
mService.systemReady();
// Verify that system ready fetches realtime stats
verify(mStatsFactory).readNetworkStatsDetail(UID_ALL, INTERFACES_ALL, TAG_ALL);
@@ -380,6 +395,10 @@
verify(mNetd).registerUnsolicitedEventListener(alertObserver.capture());
mAlertObserver = alertObserver.getValue();
+ // Make augmentWithStackedInterfaces returns the interfaces that was passed to it.
+ doAnswer(inv -> ((String[]) inv.getArgument(0)).clone())
+ .when(mStatsFactory).augmentWithStackedInterfaces(any());
+
// Catch TetheringEventCallback during systemReady().
ArgumentCaptor<TetheringManager.TetheringEventCallback> tetheringEventCbCaptor =
ArgumentCaptor.forClass(TetheringManager.TetheringEventCallback.class);
@@ -466,7 +485,7 @@
}
@Override
- public IBpfMap<U32, U8> getUidCounterSetMap() {
+ public IBpfMap<S32, U8> getUidCounterSetMap() {
return mUidCounterSetMap;
}
@@ -491,9 +510,25 @@
}
@Override
+ public IBpfMap<S32, StatsMapValue> getIfaceStatsMap() {
+ return mIfaceStatsMap;
+ }
+
+ @Override
public boolean isDebuggable() {
return mIsDebuggable == Boolean.TRUE;
}
+
+ @Override
+ public BpfNetMaps makeBpfNetMaps(Context ctx) {
+ return mBpfNetMaps;
+ }
+
+ @Override
+ public SkDestroyListener makeSkDestroyListener(
+ IBpfMap<CookieTagMapKey, CookieTagMapValue> cookieTagMap, Handler handler) {
+ return mSkDestroyListener;
+ }
};
}
@@ -514,10 +549,10 @@
private void initWifiStats(NetworkStateSnapshot snapshot) throws Exception {
// pretend that wifi network comes online; service should ask about full
// network state, and poll any existing interfaces before updating.
- expectDefaultSettings();
+ mockDefaultSettings();
NetworkStateSnapshot[] states = new NetworkStateSnapshot[] {snapshot};
- expectNetworkStatsSummary(buildEmptyStats());
- expectNetworkStatsUidDetail(buildEmptyStats());
+ mockNetworkStatsSummary(buildEmptyStats());
+ mockNetworkStatsUidDetail(buildEmptyStats());
mService.notifyNetworkStatus(NETWORKS_WIFI, states, getActiveIface(states),
new UnderlyingNetworkInfo[0]);
@@ -526,10 +561,10 @@
private void incrementWifiStats(long durationMillis, String iface,
long rxb, long rxp, long txb, long txp) throws Exception {
incrementCurrentTime(durationMillis);
- expectDefaultSettings();
- expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
+ mockDefaultSettings();
+ mockNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
.insertEntry(iface, rxb, rxp, txb, txp));
- expectNetworkStatsUidDetail(buildEmptyStats());
+ mockNetworkStatsUidDetail(buildEmptyStats());
forcePollAndWaitForIdle();
}
@@ -595,10 +630,10 @@
// pretend that wifi network comes online; service should ask about full
// network state, and poll any existing interfaces before updating.
- expectDefaultSettings();
+ mockDefaultSettings();
NetworkStateSnapshot[] states = new NetworkStateSnapshot[] {buildWifiState()};
- expectNetworkStatsSummary(buildEmptyStats());
- expectNetworkStatsUidDetail(buildEmptyStats());
+ mockNetworkStatsSummary(buildEmptyStats());
+ mockNetworkStatsUidDetail(buildEmptyStats());
mService.notifyNetworkStatus(NETWORKS_WIFI, states, getActiveIface(states),
new UnderlyingNetworkInfo[0]);
@@ -609,10 +644,10 @@
// modify some number on wifi, and trigger poll event
incrementCurrentTime(HOUR_IN_MILLIS);
- expectDefaultSettings();
- expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
+ mockDefaultSettings();
+ mockNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
.insertEntry(TEST_IFACE, 1024L, 8L, 2048L, 16L));
- expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 2)
+ mockNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 2)
.insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 512L, 4L, 256L, 2L, 0L)
.insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xFAAD, 256L, 2L, 128L, 1L, 0L)
.insertEntry(TEST_IFACE, UID_RED, SET_FOREGROUND, TAG_NONE, 512L, 4L, 256L, 2L, 0L)
@@ -623,7 +658,7 @@
mService.incrementOperationCount(UID_RED, 0xFAAD, 4);
mService.noteUidForeground(UID_RED, true);
verify(mUidCounterSetMap).updateEntry(
- eq(new U32(UID_RED)), eq(new U8((short) SET_FOREGROUND)));
+ eq(new S32(UID_RED)), eq(new U8((short) SET_FOREGROUND)));
mService.incrementOperationCount(UID_RED, 0xFAAD, 6);
forcePollAndWaitForIdle();
@@ -640,14 +675,14 @@
// graceful shutdown system, which should trigger persist of stats, and
// clear any values in memory.
- expectDefaultSettings();
+ mockDefaultSettings();
mServiceContext.sendBroadcast(new Intent(Intent.ACTION_SHUTDOWN));
assertStatsFilesExist(true);
// boot through serviceReady() again
- expectDefaultSettings();
- expectNetworkStatsUidDetail(buildEmptyStats());
- expectSystemReady();
+ mockDefaultSettings();
+ mockNetworkStatsUidDetail(buildEmptyStats());
+ prepareForSystemReady();
mService.systemReady();
@@ -672,20 +707,20 @@
// pretend that wifi network comes online; service should ask about full
// network state, and poll any existing interfaces before updating.
- expectSettings(0L, HOUR_IN_MILLIS, WEEK_IN_MILLIS);
+ mockSettings(HOUR_IN_MILLIS, WEEK_IN_MILLIS);
NetworkStateSnapshot[] states = new NetworkStateSnapshot[] {buildWifiState()};
- expectNetworkStatsSummary(buildEmptyStats());
- expectNetworkStatsUidDetail(buildEmptyStats());
+ mockNetworkStatsSummary(buildEmptyStats());
+ mockNetworkStatsUidDetail(buildEmptyStats());
mService.notifyNetworkStatus(NETWORKS_WIFI, states, getActiveIface(states),
new UnderlyingNetworkInfo[0]);
// modify some number on wifi, and trigger poll event
incrementCurrentTime(2 * HOUR_IN_MILLIS);
- expectSettings(0L, HOUR_IN_MILLIS, WEEK_IN_MILLIS);
- expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
+ mockSettings(HOUR_IN_MILLIS, WEEK_IN_MILLIS);
+ mockNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
.insertEntry(TEST_IFACE, 512L, 4L, 512L, 4L));
- expectNetworkStatsUidDetail(buildEmptyStats());
+ mockNetworkStatsUidDetail(buildEmptyStats());
forcePollAndWaitForIdle();
// verify service recorded history
@@ -697,9 +732,9 @@
// now change bucket duration setting and trigger another poll with
// exact same values, which should resize existing buckets.
- expectSettings(0L, 30 * MINUTE_IN_MILLIS, WEEK_IN_MILLIS);
- expectNetworkStatsSummary(buildEmptyStats());
- expectNetworkStatsUidDetail(buildEmptyStats());
+ mockSettings(30 * MINUTE_IN_MILLIS, WEEK_IN_MILLIS);
+ mockNetworkStatsSummary(buildEmptyStats());
+ mockNetworkStatsUidDetail(buildEmptyStats());
forcePollAndWaitForIdle();
// verify identical stats, but spread across 4 buckets now
@@ -713,20 +748,20 @@
@Test
public void testUidStatsAcrossNetworks() throws Exception {
// pretend first mobile network comes online
- expectDefaultSettings();
+ mockDefaultSettings();
NetworkStateSnapshot[] states = new NetworkStateSnapshot[] {buildMobileState(IMSI_1)};
- expectNetworkStatsSummary(buildEmptyStats());
- expectNetworkStatsUidDetail(buildEmptyStats());
+ mockNetworkStatsSummary(buildEmptyStats());
+ mockNetworkStatsUidDetail(buildEmptyStats());
mService.notifyNetworkStatus(NETWORKS_MOBILE, states, getActiveIface(states),
new UnderlyingNetworkInfo[0]);
// create some traffic on first network
incrementCurrentTime(HOUR_IN_MILLIS);
- expectDefaultSettings();
- expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
+ mockDefaultSettings();
+ mockNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
.insertEntry(TEST_IFACE, 2048L, 16L, 512L, 4L));
- expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 3)
+ mockNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 3)
.insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1536L, 12L, 512L, 4L, 0L)
.insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L)
.insertEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 512L, 4L, 0L, 0L, 0L));
@@ -744,11 +779,11 @@
// now switch networks; this also tests that we're okay with interfaces
// disappearing, to verify we don't count backwards.
incrementCurrentTime(HOUR_IN_MILLIS);
- expectDefaultSettings();
+ mockDefaultSettings();
states = new NetworkStateSnapshot[] {buildMobileState(IMSI_2)};
- expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
+ mockNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
.insertEntry(TEST_IFACE, 2048L, 16L, 512L, 4L));
- expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 3)
+ mockNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 3)
.insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1536L, 12L, 512L, 4L, 0L)
.insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L)
.insertEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 512L, 4L, 0L, 0L, 0L));
@@ -760,10 +795,10 @@
// create traffic on second network
incrementCurrentTime(HOUR_IN_MILLIS);
- expectDefaultSettings();
- expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
+ mockDefaultSettings();
+ mockNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
.insertEntry(TEST_IFACE, 2176L, 17L, 1536L, 12L));
- expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
+ mockNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
.insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 1536L, 12L, 512L, 4L, 0L)
.insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 512L, 4L, 512L, 4L, 0L)
.insertEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 640L, 5L, 1024L, 8L, 0L)
@@ -788,20 +823,20 @@
@Test
public void testUidRemovedIsMoved() throws Exception {
// pretend that network comes online
- expectDefaultSettings();
+ mockDefaultSettings();
NetworkStateSnapshot[] states = new NetworkStateSnapshot[] {buildWifiState()};
- expectNetworkStatsSummary(buildEmptyStats());
- expectNetworkStatsUidDetail(buildEmptyStats());
+ mockNetworkStatsSummary(buildEmptyStats());
+ mockNetworkStatsUidDetail(buildEmptyStats());
mService.notifyNetworkStatus(NETWORKS_WIFI, states, getActiveIface(states),
new UnderlyingNetworkInfo[0]);
// create some traffic
incrementCurrentTime(HOUR_IN_MILLIS);
- expectDefaultSettings();
- expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
+ mockDefaultSettings();
+ mockNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
.insertEntry(TEST_IFACE, 4128L, 258L, 544L, 34L));
- expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
+ mockNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
.insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 16L, 1L, 16L, 1L, 0L)
.insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xFAAD, 16L, 1L, 16L, 1L, 0L)
.insertEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE,
@@ -817,13 +852,12 @@
assertUidTotal(sTemplateWifi, UID_BLUE, 4096L, 258L, 512L, 32L, 0);
assertUidTotal(sTemplateWifi, UID_GREEN, 16L, 1L, 16L, 1L, 0);
-
// now pretend two UIDs are uninstalled, which should migrate stats to
// special "removed" bucket.
- expectDefaultSettings();
- expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
+ mockDefaultSettings();
+ mockNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
.insertEntry(TEST_IFACE, 4128L, 258L, 544L, 34L));
- expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
+ mockNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
.insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 16L, 1L, 16L, 1L, 0L)
.insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xFAAD, 16L, 1L, 16L, 1L, 0L)
.insertEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE,
@@ -860,8 +894,8 @@
new NetworkStateSnapshot[]{buildMobileState(IMSI_1)};
// 3G network comes online.
- expectNetworkStatsSummary(buildEmptyStats());
- expectNetworkStatsUidDetail(buildEmptyStats());
+ mockNetworkStatsSummary(buildEmptyStats());
+ mockNetworkStatsUidDetail(buildEmptyStats());
setMobileRatTypeAndWaitForIdle(TelephonyManager.NETWORK_TYPE_UMTS);
mService.notifyNetworkStatus(NETWORKS_MOBILE, states, getActiveIface(states),
@@ -869,7 +903,7 @@
// Create some traffic.
incrementCurrentTime(MINUTE_IN_MILLIS);
- expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
+ mockNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
.addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE,
METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 12L, 18L, 14L, 1L, 0L)));
forcePollAndWaitForIdle();
@@ -883,7 +917,7 @@
// 4G network comes online.
incrementCurrentTime(MINUTE_IN_MILLIS);
setMobileRatTypeAndWaitForIdle(TelephonyManager.NETWORK_TYPE_LTE);
- expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
+ mockNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
// Append more traffic on existing 3g stats entry.
.addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE,
METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 16L, 22L, 17L, 2L, 0L))
@@ -903,7 +937,7 @@
// 5g network comes online.
incrementCurrentTime(MINUTE_IN_MILLIS);
setMobileRatTypeAndWaitForIdle(TelephonyManager.NETWORK_TYPE_NR);
- expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
+ mockNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
// Existing stats remains.
.addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE,
METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 16L, 22L, 17L, 2L, 0L))
@@ -934,14 +968,16 @@
.setRatType(TelephonyManager.NETWORK_TYPE_NR)
.setMeteredness(METERED_NO).build();
- expectDefaultSettings();
- expectNetworkStatsSummary(buildEmptyStats());
- expectNetworkStatsUidDetail(buildEmptyStats());
+ mockDefaultSettings();
+ mockNetworkStatsSummary(buildEmptyStats());
+ mockNetworkStatsUidDetail(buildEmptyStats());
// Pretend that 5g mobile network comes online
final NetworkStateSnapshot[] mobileStates =
- new NetworkStateSnapshot[] {buildMobileState(IMSI_1), buildMobileState(TEST_IFACE2,
- IMSI_1, true /* isTemporarilyNotMetered */, false /* isRoaming */)};
+ new NetworkStateSnapshot[] {buildMobileState(IMSI_1), buildStateOfTransport(
+ NetworkCapabilities.TRANSPORT_CELLULAR, TYPE_MOBILE,
+ TEST_IFACE2, IMSI_1, null /* wifiNetworkKey */,
+ true /* isTemporarilyNotMetered */, false /* isRoaming */)};
setMobileRatTypeAndWaitForIdle(TelephonyManager.NETWORK_TYPE_NR);
mService.notifyNetworkStatus(NETWORKS_MOBILE, mobileStates,
getActiveIface(mobileStates), new UnderlyingNetworkInfo[0]);
@@ -951,7 +987,7 @@
// and DEFAULT_NETWORK_YES, because these three properties aren't tracked at that layer.
// They are layered on top by inspecting the iface properties.
incrementCurrentTime(HOUR_IN_MILLIS);
- expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
+ mockNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
.insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO,
DEFAULT_NETWORK_YES, 128L, 2L, 128L, 2L, 0L)
.insertEntry(TEST_IFACE2, UID_RED, SET_DEFAULT, TAG_NONE, METERED_YES, ROAMING_NO,
@@ -984,14 +1020,14 @@
NetworkStateSnapshot[] states = new NetworkStateSnapshot[]{
buildOemManagedMobileState(IMSI_1, false,
new int[]{NetworkCapabilities.NET_CAPABILITY_OEM_PAID})};
- expectNetworkStatsSummary(buildEmptyStats());
- expectNetworkStatsUidDetail(buildEmptyStats());
+ mockNetworkStatsSummary(buildEmptyStats());
+ mockNetworkStatsUidDetail(buildEmptyStats());
mService.notifyNetworkStatus(NETWORKS_MOBILE, states, getActiveIface(states),
new UnderlyingNetworkInfo[0]);
// Create some traffic.
incrementCurrentTime(MINUTE_IN_MILLIS);
- expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
+ mockNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
.addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE,
METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 36L, 41L, 24L, 96L, 0L)));
forcePollAndWaitForIdle();
@@ -999,14 +1035,14 @@
// OEM_PRIVATE network comes online.
states = new NetworkStateSnapshot[]{buildOemManagedMobileState(IMSI_1, false,
new int[]{NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE})};
- expectNetworkStatsSummary(buildEmptyStats());
- expectNetworkStatsUidDetail(buildEmptyStats());
+ mockNetworkStatsSummary(buildEmptyStats());
+ mockNetworkStatsUidDetail(buildEmptyStats());
mService.notifyNetworkStatus(NETWORKS_MOBILE, states, getActiveIface(states),
new UnderlyingNetworkInfo[0]);
// Create some traffic.
incrementCurrentTime(MINUTE_IN_MILLIS);
- expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
+ mockNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
.addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE,
METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 49L, 71L, 72L, 48L, 0L)));
forcePollAndWaitForIdle();
@@ -1015,28 +1051,28 @@
states = new NetworkStateSnapshot[]{buildOemManagedMobileState(IMSI_1, false,
new int[]{NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE,
NetworkCapabilities.NET_CAPABILITY_OEM_PAID})};
- expectNetworkStatsSummary(buildEmptyStats());
- expectNetworkStatsUidDetail(buildEmptyStats());
+ mockNetworkStatsSummary(buildEmptyStats());
+ mockNetworkStatsUidDetail(buildEmptyStats());
mService.notifyNetworkStatus(NETWORKS_MOBILE, states, getActiveIface(states),
new UnderlyingNetworkInfo[0]);
// Create some traffic.
incrementCurrentTime(MINUTE_IN_MILLIS);
- expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
+ mockNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
.addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE,
METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 57L, 86L, 83L, 93L, 0L)));
forcePollAndWaitForIdle();
// OEM_NONE network comes online.
states = new NetworkStateSnapshot[]{buildOemManagedMobileState(IMSI_1, false, new int[]{})};
- expectNetworkStatsSummary(buildEmptyStats());
- expectNetworkStatsUidDetail(buildEmptyStats());
+ mockNetworkStatsSummary(buildEmptyStats());
+ mockNetworkStatsUidDetail(buildEmptyStats());
mService.notifyNetworkStatus(NETWORKS_MOBILE, states, getActiveIface(states),
new UnderlyingNetworkInfo[0]);
// Create some traffic.
incrementCurrentTime(MINUTE_IN_MILLIS);
- expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
+ mockNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
.addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE,
METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 29L, 73L, 34L, 31L, 0L)));
forcePollAndWaitForIdle();
@@ -1070,8 +1106,8 @@
// TODO: support per IMSI state
private void setMobileRatTypeAndWaitForIdle(int ratType) {
- when(mNetworkStatsSubscriptionsMonitor.getRatTypeForSubscriberId(anyString()))
- .thenReturn(ratType);
+ doReturn(ratType).when(mNetworkStatsSubscriptionsMonitor)
+ .getRatTypeForSubscriberId(anyString());
mService.handleOnCollapsedRatTypeChanged();
HandlerUtils.waitForIdle(mHandlerThread, WAIT_TIMEOUT);
}
@@ -1079,19 +1115,19 @@
@Test
public void testSummaryForAllUid() throws Exception {
// pretend that network comes online
- expectDefaultSettings();
+ mockDefaultSettings();
NetworkStateSnapshot[] states = new NetworkStateSnapshot[] {buildWifiState()};
- expectNetworkStatsSummary(buildEmptyStats());
- expectNetworkStatsUidDetail(buildEmptyStats());
+ mockNetworkStatsSummary(buildEmptyStats());
+ mockNetworkStatsUidDetail(buildEmptyStats());
mService.notifyNetworkStatus(NETWORKS_WIFI, states, getActiveIface(states),
new UnderlyingNetworkInfo[0]);
// create some traffic for two apps
incrementCurrentTime(HOUR_IN_MILLIS);
- expectDefaultSettings();
- expectNetworkStatsSummary(buildEmptyStats());
- expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
+ mockDefaultSettings();
+ mockNetworkStatsSummary(buildEmptyStats());
+ mockNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
.insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 50L, 5L, 50L, 5L, 0L)
.insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 10L, 1L, 10L, 1L, 0L)
.insertEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 1024L, 8L, 512L, 4L, 0L));
@@ -1106,9 +1142,9 @@
// now create more traffic in next hour, but only for one app
incrementCurrentTime(HOUR_IN_MILLIS);
- expectDefaultSettings();
- expectNetworkStatsSummary(buildEmptyStats());
- expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
+ mockDefaultSettings();
+ mockNetworkStatsSummary(buildEmptyStats());
+ mockNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
.insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 50L, 5L, 50L, 5L, 0L)
.insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 10L, 1L, 10L, 1L, 0L)
.insertEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE,
@@ -1138,10 +1174,10 @@
@Test
public void testGetLatestSummary() throws Exception {
// Pretend that network comes online.
- expectDefaultSettings();
+ mockDefaultSettings();
NetworkStateSnapshot[] states = new NetworkStateSnapshot[]{buildWifiState()};
- expectNetworkStatsSummary(buildEmptyStats());
- expectNetworkStatsUidDetail(buildEmptyStats());
+ mockNetworkStatsSummary(buildEmptyStats());
+ mockNetworkStatsUidDetail(buildEmptyStats());
mService.notifyNetworkStatus(NETWORKS_WIFI, states, getActiveIface(states),
new UnderlyingNetworkInfo[0]);
@@ -1151,8 +1187,8 @@
NetworkStats.Entry entry = new NetworkStats.Entry(
TEST_IFACE, UID_ALL, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
DEFAULT_NETWORK_NO, 50L, 5L, 51L, 1L, 3L);
- expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1).insertEntry(entry));
- expectNetworkStatsUidDetail(buildEmptyStats());
+ mockNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1).insertEntry(entry));
+ mockNetworkStatsUidDetail(buildEmptyStats());
forcePollAndWaitForIdle();
// Verify the mocked stats is returned by querying with the range of the latest bucket.
@@ -1173,64 +1209,127 @@
}
@Test
- public void testUidStatsForTransport() throws Exception {
- // pretend that network comes online
- expectDefaultSettings();
- NetworkStateSnapshot[] states = new NetworkStateSnapshot[] {buildWifiState()};
- expectNetworkStatsSummary(buildEmptyStats());
- expectNetworkStatsUidDetail(buildEmptyStats());
+ public void testQueryTestNetworkUsage() throws Exception {
+ final NetworkTemplate templateTestAll = new NetworkTemplate.Builder(MATCH_TEST).build();
+ final NetworkTemplate templateTestIface1 = new NetworkTemplate.Builder(MATCH_TEST)
+ .setWifiNetworkKeys(Set.of(TEST_IFACE)).build();
+ final NetworkTemplate templateTestIface2 = new NetworkTemplate.Builder(MATCH_TEST)
+ .setWifiNetworkKeys(Set.of(TEST_IFACE2)).build();
+ // Test networks might use interface as subscriberId to identify individual networks.
+ // Simulate both cases.
+ final NetworkStateSnapshot[] states =
+ new NetworkStateSnapshot[]{buildTestState(TEST_IFACE, TEST_IFACE),
+ buildTestState(TEST_IFACE2, null /* wifiNetworkKey */)};
- mService.notifyNetworkStatus(NETWORKS_WIFI, states, getActiveIface(states),
+ // Test networks comes online.
+ mockNetworkStatsSummary(buildEmptyStats());
+ mockNetworkStatsUidDetail(buildEmptyStats());
+ mService.notifyNetworkStatus(NETWORKS_TEST, states, getActiveIface(states),
new UnderlyingNetworkInfo[0]);
- NetworkStats.Entry entry1 = new NetworkStats.Entry(
- TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
- DEFAULT_NETWORK_NO, 50L, 5L, 50L, 5L, 0L);
- NetworkStats.Entry entry2 = new NetworkStats.Entry(
- TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, METERED_NO, ROAMING_NO,
- DEFAULT_NETWORK_NO, 50L, 5L, 50L, 5L, 0L);
- NetworkStats.Entry entry3 = new NetworkStats.Entry(
- TEST_IFACE, UID_BLUE, SET_DEFAULT, 0xBEEF, METERED_NO, ROAMING_NO,
- DEFAULT_NETWORK_NO, 1024L, 8L, 512L, 4L, 0L);
+ // Create some traffic on both interfaces.
+ incrementCurrentTime(MINUTE_IN_MILLIS);
+ mockNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
+ .addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE,
+ METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 12L, 18L, 14L, 1L, 0L))
+ .addEntry(new NetworkStats.Entry(TEST_IFACE2, UID_RED, SET_DEFAULT, TAG_NONE,
+ METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 7L, 3L, 5L, 1L, 1L)));
+ forcePollAndWaitForIdle();
+ // Verify test network templates gets stats. Stats of test networks without subscriberId
+ // can only be matched by templates without subscriberId requirement.
+ assertUidTotal(templateTestAll, UID_RED, 19L, 21L, 19L, 2L, 1);
+ assertUidTotal(templateTestIface1, UID_RED, 12L, 18L, 14L, 1L, 0);
+ assertUidTotal(templateTestIface2, UID_RED, 0L, 0L, 0L, 0L, 0);
+ }
+
+ @Test
+ public void testUidStatsForTransport() throws Exception {
+ // Setup both wifi and mobile networks, and set mobile network as the default interface.
+ mockDefaultSettings();
+ mockNetworkStatsUidDetail(buildEmptyStats());
+
+ final NetworkStateSnapshot mobileState = buildStateOfTransport(
+ NetworkCapabilities.TRANSPORT_CELLULAR, TYPE_MOBILE,
+ TEST_IFACE2, IMSI_1, null /* wifiNetworkKey */,
+ false /* isTemporarilyNotMetered */, false /* isRoaming */);
+
+ final NetworkStateSnapshot[] states = new NetworkStateSnapshot[] {
+ mobileState, buildWifiState()};
+ mService.notifyNetworkStatus(NETWORKS_MOBILE, states, getActiveIface(states),
+ new UnderlyingNetworkInfo[0]);
+ setMobileRatTypeAndWaitForIdle(TelephonyManager.NETWORK_TYPE_LTE);
+
+ // Mock traffic on wifi network.
+ final NetworkStats.Entry entry1 = new NetworkStats.Entry(
+ TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
+ DEFAULT_NETWORK_NO, 50L, 5L, 50L, 5L, 1L);
+ final NetworkStats.Entry entry2 = new NetworkStats.Entry(
+ TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, METERED_NO, ROAMING_NO,
+ DEFAULT_NETWORK_NO, 50L, 5L, 50L, 5L, 1L);
+ final NetworkStats.Entry entry3 = new NetworkStats.Entry(
+ TEST_IFACE, UID_BLUE, SET_DEFAULT, 0xBEEF, METERED_NO, ROAMING_NO,
+ DEFAULT_NETWORK_NO, 1024L, 8L, 512L, 4L, 2L);
+
+ final TetherStatsParcel[] emptyTetherStats = {};
+ // The interfaces that expect to be used to query the stats.
+ final String[] wifiIfaces = {TEST_IFACE};
incrementCurrentTime(HOUR_IN_MILLIS);
- expectDefaultSettings();
- expectNetworkStatsSummary(buildEmptyStats());
- expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 3)
+ mockDefaultSettings();
+ mockNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 3)
.insertEntry(entry1)
.insertEntry(entry2)
- .insertEntry(entry3));
+ .insertEntry(entry3), emptyTetherStats, wifiIfaces);
+
+ // getUidStatsForTransport (through getNetworkStatsUidDetail) adds all operation counts
+ // with active interface, and the interface here is mobile interface, so this test makes
+ // sure these operations are not surfaced in getUidStatsForTransport if the transport
+ // doesn't match them.
mService.incrementOperationCount(UID_RED, 0xF00D, 1);
+ final NetworkStats wifiStats = mService.getUidStatsForTransport(
+ NetworkCapabilities.TRANSPORT_WIFI);
- NetworkStats stats = mService.getUidStatsForTransport(NetworkCapabilities.TRANSPORT_WIFI);
+ assertEquals(3, wifiStats.size());
+ // The iface field of the returned stats should be null because getUidStatsForTransport
+ // clears the interface fields before it returns the result.
+ assertValues(wifiStats, null /* iface */, UID_RED, SET_DEFAULT, TAG_NONE,
+ METERED_NO, ROAMING_NO, METERED_NO, 50L, 5L, 50L, 5L, 1L);
+ assertValues(wifiStats, null /* iface */, UID_RED, SET_DEFAULT, 0xF00D,
+ METERED_NO, ROAMING_NO, METERED_NO, 50L, 5L, 50L, 5L, 1L);
+ assertValues(wifiStats, null /* iface */, UID_BLUE, SET_DEFAULT, 0xBEEF,
+ METERED_NO, ROAMING_NO, METERED_NO, 1024L, 8L, 512L, 4L, 2L);
- assertEquals(3, stats.size());
- entry1.operations = 1;
- entry1.iface = null;
- assertEquals(entry1, stats.getValues(0, null));
- entry2.operations = 1;
- entry2.iface = null;
- assertEquals(entry2, stats.getValues(1, null));
- entry3.iface = null;
- assertEquals(entry3, stats.getValues(2, null));
+ final String[] mobileIfaces = {TEST_IFACE2};
+ mockNetworkStatsUidDetail(buildEmptyStats(), emptyTetherStats, mobileIfaces);
+ final NetworkStats mobileStats = mService.getUidStatsForTransport(
+ NetworkCapabilities.TRANSPORT_CELLULAR);
+
+ assertEquals(2, mobileStats.size());
+ // Verify the operation count stats that caused by incrementOperationCount only appears
+ // on the mobile interface since incrementOperationCount attributes them onto the active
+ // interface.
+ assertValues(mobileStats, null /* iface */, UID_RED, SET_DEFAULT, 0xF00D,
+ METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 0L, 0L, 0L, 0L, 1);
+ assertValues(mobileStats, null /* iface */, UID_RED, SET_DEFAULT, TAG_NONE,
+ METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 0L, 0L, 0L, 0L, 1);
}
@Test
public void testForegroundBackground() throws Exception {
// pretend that network comes online
- expectDefaultSettings();
+ mockDefaultSettings();
NetworkStateSnapshot[] states = new NetworkStateSnapshot[] {buildWifiState()};
- expectNetworkStatsSummary(buildEmptyStats());
- expectNetworkStatsUidDetail(buildEmptyStats());
+ mockNetworkStatsSummary(buildEmptyStats());
+ mockNetworkStatsUidDetail(buildEmptyStats());
mService.notifyNetworkStatus(NETWORKS_WIFI, states, getActiveIface(states),
new UnderlyingNetworkInfo[0]);
// create some initial traffic
incrementCurrentTime(HOUR_IN_MILLIS);
- expectDefaultSettings();
- expectNetworkStatsSummary(buildEmptyStats());
- expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
+ mockDefaultSettings();
+ mockNetworkStatsSummary(buildEmptyStats());
+ mockNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
.insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 128L, 2L, 128L, 2L, 0L)
.insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 64L, 1L, 64L, 1L, 0L));
mService.incrementOperationCount(UID_RED, 0xF00D, 1);
@@ -1243,16 +1342,16 @@
// now switch to foreground
incrementCurrentTime(HOUR_IN_MILLIS);
- expectDefaultSettings();
- expectNetworkStatsSummary(buildEmptyStats());
- expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
+ mockDefaultSettings();
+ mockNetworkStatsSummary(buildEmptyStats());
+ mockNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
.insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 128L, 2L, 128L, 2L, 0L)
.insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, 64L, 1L, 64L, 1L, 0L)
.insertEntry(TEST_IFACE, UID_RED, SET_FOREGROUND, TAG_NONE, 32L, 2L, 32L, 2L, 0L)
.insertEntry(TEST_IFACE, UID_RED, SET_FOREGROUND, 0xFAAD, 1L, 1L, 1L, 1L, 0L));
mService.noteUidForeground(UID_RED, true);
verify(mUidCounterSetMap).updateEntry(
- eq(new U32(UID_RED)), eq(new U8((short) SET_FOREGROUND)));
+ eq(new S32(UID_RED)), eq(new U8((short) SET_FOREGROUND)));
mService.incrementOperationCount(UID_RED, 0xFAAD, 1);
forcePollAndWaitForIdle();
@@ -1277,23 +1376,23 @@
@Test
public void testMetered() throws Exception {
// pretend that network comes online
- expectDefaultSettings();
+ mockDefaultSettings();
NetworkStateSnapshot[] states =
new NetworkStateSnapshot[] {buildWifiState(true /* isMetered */, TEST_IFACE)};
- expectNetworkStatsSummary(buildEmptyStats());
- expectNetworkStatsUidDetail(buildEmptyStats());
+ mockNetworkStatsSummary(buildEmptyStats());
+ mockNetworkStatsUidDetail(buildEmptyStats());
mService.notifyNetworkStatus(NETWORKS_WIFI, states, getActiveIface(states),
new UnderlyingNetworkInfo[0]);
// create some initial traffic
incrementCurrentTime(HOUR_IN_MILLIS);
- expectDefaultSettings();
- expectNetworkStatsSummary(buildEmptyStats());
+ mockDefaultSettings();
+ mockNetworkStatsSummary(buildEmptyStats());
// Note that all traffic from NetworkManagementService is tagged as METERED_NO, ROAMING_NO
// and DEFAULT_NETWORK_YES, because these three properties aren't tracked at that layer.
// We layer them on top by inspecting the iface properties.
- expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
+ mockNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
.insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
DEFAULT_NETWORK_YES, 128L, 2L, 128L, 2L, 0L)
.insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, METERED_NO, ROAMING_NO,
@@ -1317,24 +1416,26 @@
@Test
public void testRoaming() throws Exception {
// pretend that network comes online
- expectDefaultSettings();
+ mockDefaultSettings();
NetworkStateSnapshot[] states =
- new NetworkStateSnapshot[] {buildMobileState(TEST_IFACE, IMSI_1,
- false /* isTemporarilyNotMetered */, true /* isRoaming */)};
- expectNetworkStatsSummary(buildEmptyStats());
- expectNetworkStatsUidDetail(buildEmptyStats());
+ new NetworkStateSnapshot[] {buildStateOfTransport(
+ NetworkCapabilities.TRANSPORT_CELLULAR, TYPE_MOBILE,
+ TEST_IFACE, IMSI_1, null /* wifiNetworkKey */,
+ false /* isTemporarilyNotMetered */, true /* isRoaming */)};
+ mockNetworkStatsSummary(buildEmptyStats());
+ mockNetworkStatsUidDetail(buildEmptyStats());
mService.notifyNetworkStatus(NETWORKS_MOBILE, states, getActiveIface(states),
new UnderlyingNetworkInfo[0]);
// Create some traffic
incrementCurrentTime(HOUR_IN_MILLIS);
- expectDefaultSettings();
- expectNetworkStatsSummary(buildEmptyStats());
+ mockDefaultSettings();
+ mockNetworkStatsSummary(buildEmptyStats());
// Note that all traffic from NetworkManagementService is tagged as METERED_NO and
// ROAMING_NO, because metered and roaming isn't tracked at that layer. We layer it
// on top by inspecting the iface properties.
- expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
+ mockNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
.insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_ALL, ROAMING_NO,
DEFAULT_NETWORK_YES, 128L, 2L, 128L, 2L, 0L)
.insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, METERED_ALL, ROAMING_NO,
@@ -1357,18 +1458,18 @@
@Test
public void testTethering() throws Exception {
// pretend first mobile network comes online
- expectDefaultSettings();
+ mockDefaultSettings();
final NetworkStateSnapshot[] states =
new NetworkStateSnapshot[]{buildMobileState(IMSI_1)};
- expectNetworkStatsSummary(buildEmptyStats());
- expectNetworkStatsUidDetail(buildEmptyStats());
+ mockNetworkStatsSummary(buildEmptyStats());
+ mockNetworkStatsUidDetail(buildEmptyStats());
mService.notifyNetworkStatus(NETWORKS_MOBILE, states, getActiveIface(states),
new UnderlyingNetworkInfo[0]);
// create some tethering traffic
incrementCurrentTime(HOUR_IN_MILLIS);
- expectDefaultSettings();
+ mockDefaultSettings();
// Register custom provider and retrieve callback.
final TestableNetworkStatsProviderBinder provider =
@@ -1400,8 +1501,8 @@
final TetherStatsParcel[] tetherStatsParcels =
{buildTetherStatsParcel(TEST_IFACE, 1408L, 10L, 256L, 1L, 0)};
- expectNetworkStatsSummary(swIfaceStats);
- expectNetworkStatsUidDetail(localUidStats, tetherStatsParcels);
+ mockNetworkStatsSummary(swIfaceStats);
+ mockNetworkStatsUidDetail(localUidStats, tetherStatsParcels, INTERFACES_ALL);
forcePollAndWaitForIdle();
// verify service recorded history
@@ -1414,10 +1515,10 @@
public void testRegisterUsageCallback() throws Exception {
// pretend that wifi network comes online; service should ask about full
// network state, and poll any existing interfaces before updating.
- expectDefaultSettings();
+ mockDefaultSettings();
NetworkStateSnapshot[] states = new NetworkStateSnapshot[] {buildWifiState()};
- expectNetworkStatsSummary(buildEmptyStats());
- expectNetworkStatsUidDetail(buildEmptyStats());
+ mockNetworkStatsSummary(buildEmptyStats());
+ mockNetworkStatsUidDetail(buildEmptyStats());
mService.notifyNetworkStatus(NETWORKS_WIFI, states, getActiveIface(states),
new UnderlyingNetworkInfo[0]);
@@ -1429,9 +1530,9 @@
DataUsageRequest.REQUEST_ID_UNSET, sTemplateWifi, thresholdInBytes);
// Force poll
- expectDefaultSettings();
- expectNetworkStatsSummary(buildEmptyStats());
- expectNetworkStatsUidDetail(buildEmptyStats());
+ mockDefaultSettings();
+ mockNetworkStatsSummary(buildEmptyStats());
+ mockNetworkStatsUidDetail(buildEmptyStats());
// Register and verify request and that binder was called
DataUsageRequest request = mService.registerUsageCallback(
@@ -1449,10 +1550,10 @@
// modify some number on wifi, and trigger poll event
// not enough traffic to call data usage callback
incrementCurrentTime(HOUR_IN_MILLIS);
- expectDefaultSettings();
- expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
+ mockDefaultSettings();
+ mockNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
.insertEntry(TEST_IFACE, 1024L, 1L, 2048L, 2L));
- expectNetworkStatsUidDetail(buildEmptyStats());
+ mockNetworkStatsUidDetail(buildEmptyStats());
forcePollAndWaitForIdle();
// verify service recorded history
@@ -1464,10 +1565,10 @@
// and bump forward again, with counters going higher. this is
// important, since it will trigger the data usage callback
incrementCurrentTime(DAY_IN_MILLIS);
- expectDefaultSettings();
- expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
+ mockDefaultSettings();
+ mockNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
.insertEntry(TEST_IFACE, 4096000L, 4L, 8192000L, 8L));
- expectNetworkStatsUidDetail(buildEmptyStats());
+ mockNetworkStatsUidDetail(buildEmptyStats());
forcePollAndWaitForIdle();
// verify service recorded history
@@ -1478,8 +1579,8 @@
mUsageCallback.expectOnThresholdReached(request);
// Allow binder to disconnect
- when(mUsageCallbackBinder.unlinkToDeath(any(IBinder.DeathRecipient.class), anyInt()))
- .thenReturn(true);
+ doReturn(true).when(mUsageCallbackBinder)
+ .unlinkToDeath(any(IBinder.DeathRecipient.class), anyInt());
// Unregister request
mService.unregisterUsageRequest(request);
@@ -1504,11 +1605,11 @@
@Test
public void testStatsProviderUpdateStats() throws Exception {
// Pretend that network comes online.
- expectDefaultSettings();
+ mockDefaultSettings();
final NetworkStateSnapshot[] states =
new NetworkStateSnapshot[]{buildWifiState(true /* isMetered */, TEST_IFACE)};
- expectNetworkStatsSummary(buildEmptyStats());
- expectNetworkStatsUidDetail(buildEmptyStats());
+ mockNetworkStatsSummary(buildEmptyStats());
+ mockNetworkStatsUidDetail(buildEmptyStats());
// Register custom provider and retrieve callback.
final TestableNetworkStatsProviderBinder provider =
@@ -1537,7 +1638,7 @@
// Make another empty mutable stats object. This is necessary since the new NetworkStats
// object will be used to compare with the old one in NetworkStatsRecoder, two of them
// cannot be the same object.
- expectNetworkStatsUidDetail(buildEmptyStats());
+ mockNetworkStatsUidDetail(buildEmptyStats());
forcePollAndWaitForIdle();
@@ -1566,14 +1667,14 @@
@Test
public void testDualVilteProviderStats() throws Exception {
// Pretend that network comes online.
- expectDefaultSettings();
+ mockDefaultSettings();
final int subId1 = 1;
final int subId2 = 2;
final NetworkStateSnapshot[] states = new NetworkStateSnapshot[]{
buildImsState(IMSI_1, subId1, TEST_IFACE),
buildImsState(IMSI_2, subId2, TEST_IFACE2)};
- expectNetworkStatsSummary(buildEmptyStats());
- expectNetworkStatsUidDetail(buildEmptyStats());
+ mockNetworkStatsSummary(buildEmptyStats());
+ mockNetworkStatsUidDetail(buildEmptyStats());
// Register custom provider and retrieve callback.
final TestableNetworkStatsProviderBinder provider =
@@ -1604,7 +1705,7 @@
// Make another empty mutable stats object. This is necessary since the new NetworkStats
// object will be used to compare with the old one in NetworkStatsRecoder, two of them
// cannot be the same object.
- expectNetworkStatsUidDetail(buildEmptyStats());
+ mockNetworkStatsUidDetail(buildEmptyStats());
forcePollAndWaitForIdle();
@@ -1637,7 +1738,7 @@
@Test
public void testStatsProviderSetAlert() throws Exception {
// Pretend that network comes online.
- expectDefaultSettings();
+ mockDefaultSettings();
NetworkStateSnapshot[] states =
new NetworkStateSnapshot[]{buildWifiState(true /* isMetered */, TEST_IFACE)};
mService.notifyNetworkStatus(NETWORKS_WIFI, states, getActiveIface(states),
@@ -1661,7 +1762,7 @@
}
private void setCombineSubtypeEnabled(boolean enable) {
- when(mSettings.getCombineSubtypeEnabled()).thenReturn(enable);
+ doReturn(enable).when(mSettings).getCombineSubtypeEnabled();
mHandler.post(() -> mContentObserver.onChange(false, Settings.Global
.getUriFor(Settings.Global.NETSTATS_COMBINE_SUBTYPE_ENABLED)));
waitForIdle();
@@ -1687,8 +1788,8 @@
final NetworkStateSnapshot[] states =
new NetworkStateSnapshot[]{buildMobileState(IMSI_1)};
- expectNetworkStatsSummary(buildEmptyStats());
- expectNetworkStatsUidDetail(buildEmptyStats());
+ mockNetworkStatsSummary(buildEmptyStats());
+ mockNetworkStatsUidDetail(buildEmptyStats());
// 3G network comes online.
setMobileRatTypeAndWaitForIdle(TelephonyManager.NETWORK_TYPE_UMTS);
@@ -1697,7 +1798,7 @@
// Create some traffic.
incrementCurrentTime(MINUTE_IN_MILLIS);
- expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
+ mockNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
.addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE,
METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 12L, 18L, 14L, 1L, 0L)));
forcePollAndWaitForIdle();
@@ -1721,7 +1822,7 @@
// Create some traffic.
incrementCurrentTime(MINUTE_IN_MILLIS);
// Append more traffic on existing snapshot.
- expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
+ mockNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
.addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE,
METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 12L + 4L, 18L + 4L, 14L + 3L,
1L + 1L, 0L))
@@ -1744,7 +1845,7 @@
// Create some traffic.
incrementCurrentTime(MINUTE_IN_MILLIS);
// Append more traffic on existing snapshot.
- expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
+ mockNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
.addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE,
METERED_NO, ROAMING_NO, DEFAULT_NETWORK_NO, 22L, 26L, 19L, 5L, 0L))
.addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_FOREGROUND, TAG_NONE,
@@ -1761,16 +1862,16 @@
@Test
public void testOperationCount_nonDefault_traffic() throws Exception {
// Pretend mobile network comes online, but wifi is the default network.
- expectDefaultSettings();
+ mockDefaultSettings();
NetworkStateSnapshot[] states = new NetworkStateSnapshot[]{
buildWifiState(true /*isMetered*/, TEST_IFACE2), buildMobileState(IMSI_1)};
- expectNetworkStatsUidDetail(buildEmptyStats());
+ mockNetworkStatsUidDetail(buildEmptyStats());
mService.notifyNetworkStatus(NETWORKS_WIFI, states, getActiveIface(states),
new UnderlyingNetworkInfo[0]);
// Create some traffic on mobile network.
incrementCurrentTime(HOUR_IN_MILLIS);
- expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 4)
+ mockNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 4)
.insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
DEFAULT_NETWORK_NO, 2L, 1L, 3L, 4L, 0L)
.insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, METERED_NO, ROAMING_NO,
@@ -1821,8 +1922,8 @@
*/
@Test
public void testEnforceTemplateLocationPermission() throws Exception {
- when(mLocationPermissionChecker.checkCallersLocationPermission(
- any(), any(), anyInt(), anyBoolean(), any())).thenReturn(false);
+ doReturn(false).when(mLocationPermissionChecker)
+ .checkCallersLocationPermission(any(), any(), anyInt(), anyBoolean(), any());
initWifiStats(buildWifiState(true, TEST_IFACE, IMSI_1));
assertThrows(SecurityException.class, () ->
assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0));
@@ -1830,8 +1931,8 @@
assertNetworkTotal(sTemplateCarrierWifi1, 0L, 0L, 0L, 0L, 0);
assertNetworkTotal(sTemplateImsi1, 0L, 0L, 0L, 0L, 0);
- when(mLocationPermissionChecker.checkCallersLocationPermission(
- any(), any(), anyInt(), anyBoolean(), any())).thenReturn(true);
+ doReturn(true).when(mLocationPermissionChecker)
+ .checkCallersLocationPermission(any(), any(), anyInt(), anyBoolean(), any());
assertNetworkTotal(sTemplateCarrierWifi1, 0L, 0L, 0L, 0L, 0);
assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0);
assertNetworkTotal(sTemplateImsi1, 0L, 0L, 0L, 0L, 0);
@@ -1843,7 +1944,7 @@
@Test
public void testDataMigration() throws Exception {
assertStatsFilesExist(false);
- expectDefaultSettings();
+ mockDefaultSettings();
NetworkStateSnapshot[] states = new NetworkStateSnapshot[] {buildWifiState()};
@@ -1852,10 +1953,9 @@
// modify some number on wifi, and trigger poll event
incrementCurrentTime(HOUR_IN_MILLIS);
- // expectDefaultSettings();
- expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
+ mockNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
.insertEntry(TEST_IFACE, 1024L, 8L, 2048L, 16L));
- expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 2)
+ mockNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 2)
.insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 512L, 4L, 256L, 2L, 0L)
.insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xFAAD, 256L, 2L, 128L, 1L, 0L)
.insertEntry(TEST_IFACE, UID_RED, SET_FOREGROUND, TAG_NONE, 512L, 4L, 256L, 2L, 0L)
@@ -1867,7 +1967,7 @@
mService.incrementOperationCount(UID_RED, 0xFAAD, 4);
mService.noteUidForeground(UID_RED, true);
verify(mUidCounterSetMap).updateEntry(
- eq(new U32(UID_RED)), eq(new U8((short) SET_FOREGROUND)));
+ eq(new S32(UID_RED)), eq(new U8((short) SET_FOREGROUND)));
mService.incrementOperationCount(UID_RED, 0xFAAD, 6);
forcePollAndWaitForIdle();
@@ -1892,9 +1992,9 @@
getLegacyCollection(PREFIX_UID_TAG, true /* includeTags */));
// Mock zero usage and boot through serviceReady(), verify there is no imported data.
- expectDefaultSettings();
- expectNetworkStatsUidDetail(buildEmptyStats());
- expectSystemReady();
+ mockDefaultSettings();
+ mockNetworkStatsUidDetail(buildEmptyStats());
+ prepareForSystemReady();
mService.systemReady();
assertStatsFilesExist(false);
@@ -1905,9 +2005,9 @@
assertStatsFilesExist(false);
// Boot through systemReady() again.
- expectDefaultSettings();
- expectNetworkStatsUidDetail(buildEmptyStats());
- expectSystemReady();
+ mockDefaultSettings();
+ mockNetworkStatsUidDetail(buildEmptyStats());
+ prepareForSystemReady();
mService.systemReady();
// After systemReady(), the service should have historical stats loaded again.
@@ -1928,7 +2028,7 @@
@Test
public void testDataMigration_differentFromFallback() throws Exception {
assertStatsFilesExist(false);
- expectDefaultSettings();
+ mockDefaultSettings();
NetworkStateSnapshot[] states = new NetworkStateSnapshot[]{buildWifiState()};
@@ -1937,9 +2037,9 @@
// modify some number on wifi, and trigger poll event
incrementCurrentTime(HOUR_IN_MILLIS);
- expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
+ mockNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
.insertEntry(TEST_IFACE, 1024L, 8L, 2048L, 16L));
- expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
+ mockNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
.insertEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE, 128L, 1L, 128L, 1L, 0L));
forcePollAndWaitForIdle();
// Simulate shutdown to force persisting data
@@ -1980,9 +2080,9 @@
getLegacyCollection(PREFIX_UID_TAG, true /* includeTags */));
// Mock zero usage and boot through serviceReady(), verify there is no imported data.
- expectDefaultSettings();
- expectNetworkStatsUidDetail(buildEmptyStats());
- expectSystemReady();
+ mockDefaultSettings();
+ mockNetworkStatsUidDetail(buildEmptyStats());
+ prepareForSystemReady();
mService.systemReady();
assertStatsFilesExist(false);
@@ -1993,9 +2093,9 @@
assertStatsFilesExist(false);
// Boot through systemReady() again.
- expectDefaultSettings();
- expectNetworkStatsUidDetail(buildEmptyStats());
- expectSystemReady();
+ mockDefaultSettings();
+ mockNetworkStatsUidDetail(buildEmptyStats());
+ prepareForSystemReady();
mService.systemReady();
// Verify the result read from public API matches the result returned from the importer.
@@ -2028,6 +2128,59 @@
}
}
+ @Test
+ public void testStatsFactoryRemoveUids() throws Exception {
+ // pretend that network comes online
+ mockDefaultSettings();
+ NetworkStateSnapshot[] states = new NetworkStateSnapshot[] {buildWifiState()};
+ mockNetworkStatsSummary(buildEmptyStats());
+ mockNetworkStatsUidDetail(buildEmptyStats());
+
+ mService.notifyNetworkStatus(NETWORKS_WIFI, states, getActiveIface(states),
+ new UnderlyingNetworkInfo[0]);
+
+ // Create some traffic
+ incrementCurrentTime(HOUR_IN_MILLIS);
+ mockDefaultSettings();
+ final NetworkStats stats = new NetworkStats(getElapsedRealtime(), 1)
+ .insertEntry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE, 16L, 1L, 16L, 1L, 0L)
+ .insertEntry(TEST_IFACE, UID_BLUE, SET_DEFAULT, TAG_NONE,
+ 4096L, 258L, 512L, 32L, 0L)
+ .insertEntry(TEST_IFACE, UID_GREEN, SET_DEFAULT, TAG_NONE, 64L, 3L, 1024L, 8L, 0L);
+ mockNetworkStatsUidDetail(stats);
+
+ forcePollAndWaitForIdle();
+
+ // Verify service recorded history
+ assertUidTotal(sTemplateWifi, UID_RED, 16L, 1L, 16L, 1L, 0);
+ assertUidTotal(sTemplateWifi, UID_BLUE, 4096L, 258L, 512L, 32L, 0);
+ assertUidTotal(sTemplateWifi, UID_GREEN, 64L, 3L, 1024L, 8L, 0);
+
+ // Simulate that the apps are removed.
+ final Intent intentBlue = new Intent(ACTION_UID_REMOVED);
+ intentBlue.putExtra(EXTRA_UID, UID_BLUE);
+ mServiceContext.sendBroadcast(intentBlue);
+
+ final Intent intentRed = new Intent(ACTION_UID_REMOVED);
+ intentRed.putExtra(EXTRA_UID, UID_RED);
+ mServiceContext.sendBroadcast(intentRed);
+
+ final int[] removedUids = {UID_BLUE, UID_RED};
+
+ final ArgumentCaptor<int[]> removedUidsCaptor = ArgumentCaptor.forClass(int[].class);
+ verify(mStatsFactory, times(2)).removeUidsLocked(removedUidsCaptor.capture());
+ final List<int[]> captureRemovedUids = removedUidsCaptor.getAllValues();
+ // Simulate that the stats are removed in NetworkStatsFactory.
+ if (captureRemovedUids.contains(removedUids)) {
+ stats.removeUids(removedUids);
+ }
+
+ // Verify the stats of the removed uid is removed.
+ assertUidTotal(sTemplateWifi, UID_RED, 0L, 0L, 0L, 0L, 0);
+ assertUidTotal(sTemplateWifi, UID_BLUE, 0L, 0L, 0L, 0L, 0);
+ assertUidTotal(sTemplateWifi, UID_GREEN, 64L, 3L, 1024L, 8L, 0);
+ }
+
private void assertShouldRunComparison(boolean expected, boolean isDebuggable) {
assertEquals("shouldRunComparison (debuggable=" + isDebuggable + "): ",
expected, mService.shouldRunComparison());
@@ -2090,8 +2243,8 @@
rxBytes, rxPackets, txBytes, txPackets, operations);
}
- private void expectSystemReady() throws Exception {
- expectNetworkStatsSummary(buildEmptyStats());
+ private void prepareForSystemReady() throws Exception {
+ mockNetworkStatsSummary(buildEmptyStats());
}
private String getActiveIface(NetworkStateSnapshot... states) throws Exception {
@@ -2101,57 +2254,55 @@
return states[0].getLinkProperties().getInterfaceName();
}
- // TODO: These expect* methods are used to have NetworkStatsService returns the given stats
- // instead of expecting anything. Therefore, these methods should be renamed properly.
- private void expectNetworkStatsSummary(NetworkStats summary) throws Exception {
- expectNetworkStatsSummaryDev(summary.clone());
- expectNetworkStatsSummaryXt(summary.clone());
+ private void mockNetworkStatsSummary(NetworkStats summary) throws Exception {
+ mockNetworkStatsSummaryDev(summary.clone());
+ mockNetworkStatsSummaryXt(summary.clone());
}
- private void expectNetworkStatsSummaryDev(NetworkStats summary) throws Exception {
- when(mStatsFactory.readNetworkStatsSummaryDev()).thenReturn(summary);
+ private void mockNetworkStatsSummaryDev(NetworkStats summary) throws Exception {
+ doReturn(summary).when(mStatsFactory).readNetworkStatsSummaryDev();
}
- private void expectNetworkStatsSummaryXt(NetworkStats summary) throws Exception {
- when(mStatsFactory.readNetworkStatsSummaryXt()).thenReturn(summary);
+ private void mockNetworkStatsSummaryXt(NetworkStats summary) throws Exception {
+ doReturn(summary).when(mStatsFactory).readNetworkStatsSummaryXt();
}
- private void expectNetworkStatsUidDetail(NetworkStats detail) throws Exception {
+ private void mockNetworkStatsUidDetail(NetworkStats detail) throws Exception {
final TetherStatsParcel[] tetherStatsParcels = {};
- expectNetworkStatsUidDetail(detail, tetherStatsParcels);
+ mockNetworkStatsUidDetail(detail, tetherStatsParcels, INTERFACES_ALL);
}
- private void expectNetworkStatsUidDetail(NetworkStats detail,
- TetherStatsParcel[] tetherStatsParcels) throws Exception {
- when(mStatsFactory.readNetworkStatsDetail(UID_ALL, INTERFACES_ALL, TAG_ALL))
- .thenReturn(detail);
+ private void mockNetworkStatsUidDetail(NetworkStats detail,
+ TetherStatsParcel[] tetherStatsParcels, String[] ifaces) throws Exception {
+
+ doReturn(detail).when(mStatsFactory)
+ .readNetworkStatsDetail(eq(UID_ALL), aryEq(ifaces), eq(TAG_ALL));
// also include tethering details, since they are folded into UID
- when(mNetd.tetherGetStats()).thenReturn(tetherStatsParcels);
+ doReturn(tetherStatsParcels).when(mNetd).tetherGetStats();
}
- private void expectDefaultSettings() throws Exception {
- expectSettings(0L, HOUR_IN_MILLIS, WEEK_IN_MILLIS);
+ private void mockDefaultSettings() throws Exception {
+ mockSettings(HOUR_IN_MILLIS, WEEK_IN_MILLIS);
}
- private void expectSettings(long persistBytes, long bucketDuration, long deleteAge)
- throws Exception {
- when(mSettings.getPollInterval()).thenReturn(HOUR_IN_MILLIS);
- when(mSettings.getPollDelay()).thenReturn(0L);
- when(mSettings.getSampleEnabled()).thenReturn(true);
- when(mSettings.getCombineSubtypeEnabled()).thenReturn(false);
+ private void mockSettings(long bucketDuration, long deleteAge) throws Exception {
+ doReturn(HOUR_IN_MILLIS).when(mSettings).getPollInterval();
+ doReturn(0L).when(mSettings).getPollDelay();
+ doReturn(true).when(mSettings).getSampleEnabled();
+ doReturn(false).when(mSettings).getCombineSubtypeEnabled();
final Config config = new Config(bucketDuration, deleteAge, deleteAge);
- when(mSettings.getDevConfig()).thenReturn(config);
- when(mSettings.getXtConfig()).thenReturn(config);
- when(mSettings.getUidConfig()).thenReturn(config);
- when(mSettings.getUidTagConfig()).thenReturn(config);
+ doReturn(config).when(mSettings).getDevConfig();
+ doReturn(config).when(mSettings).getXtConfig();
+ doReturn(config).when(mSettings).getUidConfig();
+ doReturn(config).when(mSettings).getUidTagConfig();
- when(mSettings.getGlobalAlertBytes(anyLong())).thenReturn(MB_IN_BYTES);
- when(mSettings.getDevPersistBytes(anyLong())).thenReturn(MB_IN_BYTES);
- when(mSettings.getXtPersistBytes(anyLong())).thenReturn(MB_IN_BYTES);
- when(mSettings.getUidPersistBytes(anyLong())).thenReturn(MB_IN_BYTES);
- when(mSettings.getUidTagPersistBytes(anyLong())).thenReturn(MB_IN_BYTES);
+ doReturn(MB_IN_BYTES).when(mSettings).getGlobalAlertBytes(anyLong());
+ doReturn(MB_IN_BYTES).when(mSettings).getDevPersistBytes(anyLong());
+ doReturn(MB_IN_BYTES).when(mSettings).getXtPersistBytes(anyLong());
+ doReturn(MB_IN_BYTES).when(mSettings).getUidPersistBytes(anyLong());
+ doReturn(MB_IN_BYTES).when(mSettings).getUidTagPersistBytes(anyLong());
}
private void assertStatsFilesExist(boolean exist) {
@@ -2193,24 +2344,34 @@
}
private static NetworkStateSnapshot buildMobileState(String subscriberId) {
- return buildMobileState(TEST_IFACE, subscriberId, false /* isTemporarilyNotMetered */,
- false /* isRoaming */);
+ return buildStateOfTransport(NetworkCapabilities.TRANSPORT_CELLULAR, TYPE_MOBILE,
+ TEST_IFACE, subscriberId, null /* wifiNetworkKey */,
+ false /* isTemporarilyNotMetered */, false /* isRoaming */);
}
- private static NetworkStateSnapshot buildMobileState(String iface, String subscriberId,
+ private static NetworkStateSnapshot buildTestState(@NonNull String iface,
+ @Nullable String wifiNetworkKey) {
+ return buildStateOfTransport(NetworkCapabilities.TRANSPORT_TEST, TYPE_TEST,
+ iface, null /* subscriberId */, wifiNetworkKey,
+ false /* isTemporarilyNotMetered */, false /* isRoaming */);
+ }
+
+ private static NetworkStateSnapshot buildStateOfTransport(int transport, int legacyType,
+ String iface, String subscriberId, String wifiNetworkKey,
boolean isTemporarilyNotMetered, boolean isRoaming) {
final LinkProperties prop = new LinkProperties();
prop.setInterfaceName(iface);
final NetworkCapabilities capabilities = new NetworkCapabilities();
- if (isTemporarilyNotMetered) {
- capabilities.addCapability(
- NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED);
- }
+ capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED,
+ isTemporarilyNotMetered);
capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING, !isRoaming);
- capabilities.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
+ capabilities.addTransportType(transport);
+ if (legacyType == TYPE_TEST && !TextUtils.isEmpty(wifiNetworkKey)) {
+ capabilities.setNetworkSpecifier(new TestNetworkSpecifier(wifiNetworkKey));
+ }
return new NetworkStateSnapshot(
- MOBILE_NETWORK, capabilities, prop, subscriberId, TYPE_MOBILE);
+ MOBILE_NETWORK, capabilities, prop, subscriberId, legacyType);
}
private NetworkStats buildEmptyStats() {
@@ -2304,13 +2465,13 @@
mAppUidStatsMap.insertEntry(new UidStatsMapKey(uid), new StatsMapValue(10, 10000, 6, 6000));
- mUidCounterSetMap.insertEntry(new U32(uid), new U8((short) 1));
+ mUidCounterSetMap.insertEntry(new S32(uid), new U8((short) 1));
assertTrue(cookieTagMapContainsUid(uid));
assertTrue(statsMapContainsUid(mStatsMapA, uid));
assertTrue(statsMapContainsUid(mStatsMapB, uid));
assertTrue(mAppUidStatsMap.containsKey(new UidStatsMapKey(uid)));
- assertTrue(mUidCounterSetMap.containsKey(new U32(uid)));
+ assertTrue(mUidCounterSetMap.containsKey(new S32(uid)));
}
@Test
@@ -2327,14 +2488,14 @@
assertFalse(statsMapContainsUid(mStatsMapA, UID_BLUE));
assertFalse(statsMapContainsUid(mStatsMapB, UID_BLUE));
assertFalse(mAppUidStatsMap.containsKey(new UidStatsMapKey(UID_BLUE)));
- assertFalse(mUidCounterSetMap.containsKey(new U32(UID_BLUE)));
+ assertFalse(mUidCounterSetMap.containsKey(new S32(UID_BLUE)));
// assert that UID_RED related tag data is still in the maps.
assertTrue(cookieTagMapContainsUid(UID_RED));
assertTrue(statsMapContainsUid(mStatsMapA, UID_RED));
assertTrue(statsMapContainsUid(mStatsMapB, UID_RED));
assertTrue(mAppUidStatsMap.containsKey(new UidStatsMapKey(UID_RED)));
- assertTrue(mUidCounterSetMap.containsKey(new U32(UID_RED)));
+ assertTrue(mUidCounterSetMap.containsKey(new S32(UID_RED)));
}
private void assertDumpContains(final String dump, final String message) {
@@ -2408,4 +2569,49 @@
assertDumpContains(dump, "uid rxBytes rxPackets txBytes txPackets");
assertDumpContains(dump, "1002 10000 10 6000 6");
}
+
+ private void doTestDumpStatsMap(final String expectedIfaceName) throws ErrnoException {
+ initBpfMapsWithTagData(UID_BLUE);
+
+ final String dump = getDump();
+ assertDumpContains(dump, "mStatsMapA: OK");
+ assertDumpContains(dump, "mStatsMapB: OK");
+ assertDumpContains(dump,
+ "ifaceIndex ifaceName tag_hex uid_int cnt_set rxBytes rxPackets txBytes txPackets");
+ assertDumpContains(dump, "10 " + expectedIfaceName + " 0x2 1002 0 5000 5 3000 3");
+ assertDumpContains(dump, "10 " + expectedIfaceName + " 0x1 1002 0 5000 5 3000 3");
+ }
+
+ @Test
+ public void testDumpStatsMap() throws ErrnoException {
+ doReturn("wlan0").when(mBpfInterfaceMapUpdater).getIfNameByIndex(10 /* index */);
+ doTestDumpStatsMap("wlan0");
+ }
+
+ @Test
+ public void testDumpStatsMapUnknownInterface() throws ErrnoException {
+ doReturn(null).when(mBpfInterfaceMapUpdater).getIfNameByIndex(10 /* index */);
+ doTestDumpStatsMap("unknown");
+ }
+
+ void doTestDumpIfaceStatsMap(final String expectedIfaceName) throws Exception {
+ mIfaceStatsMap.insertEntry(new S32(10), new StatsMapValue(3, 3000, 3, 3000));
+
+ final String dump = getDump();
+ assertDumpContains(dump, "mIfaceStatsMap: OK");
+ assertDumpContains(dump, "ifaceIndex ifaceName rxBytes rxPackets txBytes txPackets");
+ assertDumpContains(dump, "10 " + expectedIfaceName + " 3000 3 3000 3");
+ }
+
+ @Test
+ public void testDumpIfaceStatsMap() throws Exception {
+ doReturn("wlan0").when(mBpfInterfaceMapUpdater).getIfNameByIndex(10 /* index */);
+ doTestDumpIfaceStatsMap("wlan0");
+ }
+
+ @Test
+ public void testDumpIfaceStatsMapUnknownInterface() throws Exception {
+ doReturn(null).when(mBpfInterfaceMapUpdater).getIfNameByIndex(10 /* index */);
+ doTestDumpIfaceStatsMap("unknown");
+ }
}
diff --git a/tools/Android.bp b/tools/Android.bp
index 1fa93bb..3ce76f6 100644
--- a/tools/Android.bp
+++ b/tools/Android.bp
@@ -27,14 +27,6 @@
"gen_jarjar.py",
],
main: "gen_jarjar.py",
- version: {
- py2: {
- enabled: false,
- },
- py3: {
- enabled: true,
- },
- },
visibility: ["//packages/modules/Connectivity:__subpackages__"],
}
@@ -48,6 +40,7 @@
java_library {
name: "jarjar-rules-generator-testjavalib",
srcs: ["testdata/java/**/*.java"],
+ libs: ["unsupportedappusage"],
visibility: ["//visibility:private"],
}
@@ -67,6 +60,17 @@
compile_dex: false,
}
+java_library {
+ name: "framework-connectivity-t.stubs.module_lib-for-test",
+ visibility: ["//visibility:private"],
+ static_libs: [
+ "framework-connectivity-t.stubs.module_lib",
+ ],
+ // Not strictly necessary but specified as this MUST not have generate
+ // a dex jar as that will break the tests.
+ compile_dex: false,
+}
+
python_test_host {
name: "jarjar-rules-generator-test",
srcs: [
@@ -75,17 +79,12 @@
],
data: [
"testdata/test-jarjar-excludes.txt",
+ // two unsupportedappusage lists with different classes to test using multiple lists
"testdata/test-unsupportedappusage.txt",
+ "testdata/test-other-unsupportedappusage.txt",
":framework-connectivity.stubs.module_lib-for-test",
+ ":framework-connectivity-t.stubs.module_lib-for-test",
":jarjar-rules-generator-testjavalib",
],
main: "gen_jarjar_test.py",
- version: {
- py2: {
- enabled: false,
- },
- py3: {
- enabled: true,
- },
- },
}
diff --git a/tools/gen_jarjar.py b/tools/gen_jarjar.py
index 2ff53fa..eb686ce 100755
--- a/tools/gen_jarjar.py
+++ b/tools/gen_jarjar.py
@@ -28,8 +28,8 @@
def parse_arguments(argv):
parser = argparse.ArgumentParser()
parser.add_argument(
- '--jars', nargs='+',
- help='Path to pre-jarjar JAR. Can be followed by multiple space-separated paths.')
+ 'jars', nargs='+',
+ help='Path to pre-jarjar JAR. Multiple jars can be specified.')
parser.add_argument(
'--prefix', required=True,
help='Package prefix to use for jarjared classes, '
@@ -37,18 +37,17 @@
parser.add_argument(
'--output', required=True, help='Path to output jarjar rules file.')
parser.add_argument(
- '--apistubs', nargs='*', default=[],
- help='Path to API stubs jar. Classes that are API will not be jarjared. Can be followed by '
- 'multiple space-separated paths.')
+ '--apistubs', action='append', default=[],
+ help='Path to API stubs jar. Classes that are API will not be jarjared. Can be repeated to '
+ 'specify multiple jars.')
parser.add_argument(
- '--unsupportedapi', nargs='*', default=[],
- help='Path to UnsupportedAppUsage hidden API .txt lists. '
- 'Classes that have UnsupportedAppUsage API will not be jarjared. Can be followed by '
- 'multiple space-separated paths.')
+ '--unsupportedapi',
+ help='Column(:)-separated paths to UnsupportedAppUsage hidden API .txt lists. '
+ 'Classes that have UnsupportedAppUsage API will not be jarjared.')
parser.add_argument(
- '--excludes', nargs='*', default=[],
- help='Path to files listing classes that should not be jarjared. Can be followed by '
- 'multiple space-separated paths. '
+ '--excludes', action='append', default=[],
+ help='Path to files listing classes that should not be jarjared. Can be repeated to '
+ 'specify multiple files.'
'Each file should contain one full-match regex per line. Empty lines or lines '
'starting with "#" are ignored.')
return parser.parse_args(argv)
@@ -103,8 +102,10 @@
for apistubs_file in args.apistubs:
excluded_classes.update(_list_toplevel_jar_classes(apistubs_file))
- for unsupportedapi_file in args.unsupportedapi:
- excluded_classes.update(_list_hiddenapi_classes(unsupportedapi_file))
+ unsupportedapi_files = (args.unsupportedapi and args.unsupportedapi.split(':')) or []
+ for unsupportedapi_file in unsupportedapi_files:
+ if unsupportedapi_file:
+ excluded_classes.update(_list_hiddenapi_classes(unsupportedapi_file))
exclude_regexes = []
for exclude_file in args.excludes:
diff --git a/tools/gen_jarjar_test.py b/tools/gen_jarjar_test.py
index 8d8e82b..f5bf499 100644
--- a/tools/gen_jarjar_test.py
+++ b/tools/gen_jarjar_test.py
@@ -31,11 +31,11 @@
class TestGenJarjar(unittest.TestCase):
def test_gen_rules(self):
args = gen_jarjar.parse_arguments([
- "--jars", "jarjar-rules-generator-testjavalib.jar",
+ "jarjar-rules-generator-testjavalib.jar",
"--prefix", "jarjar.prefix",
"--output", "test-output-rules.txt",
"--apistubs", "framework-connectivity.stubs.module_lib.jar",
- "--unsupportedapi", "testdata/test-unsupportedappusage.txt",
+ "--unsupportedapi", ":testdata/test-unsupportedappusage.txt",
"--excludes", "testdata/test-jarjar-excludes.txt",
])
gen_jarjar.make_jarjar_rules(args)
@@ -43,6 +43,39 @@
with open(args.output) as out:
lines = out.readlines()
+ self.maxDiff = None
+ self.assertListEqual([
+ 'rule android.net.IpSecTransform jarjar.prefix.@0\n',
+ 'rule android.net.IpSecTransformTest jarjar.prefix.@0\n',
+ 'rule android.net.IpSecTransformTest$* jarjar.prefix.@0\n',
+ 'rule test.unsupportedappusage.OtherUnsupportedUsageClass jarjar.prefix.@0\n',
+ 'rule test.unsupportedappusage.OtherUnsupportedUsageClassTest jarjar.prefix.@0\n',
+ 'rule test.unsupportedappusage.OtherUnsupportedUsageClassTest$* jarjar.prefix.@0\n',
+ 'rule test.utils.TestUtilClass jarjar.prefix.@0\n',
+ 'rule test.utils.TestUtilClassTest jarjar.prefix.@0\n',
+ 'rule test.utils.TestUtilClassTest$* jarjar.prefix.@0\n',
+ 'rule test.utils.TestUtilClass$TestInnerClass jarjar.prefix.@0\n',
+ 'rule test.utils.TestUtilClass$TestInnerClassTest jarjar.prefix.@0\n',
+ 'rule test.utils.TestUtilClass$TestInnerClassTest$* jarjar.prefix.@0\n'
+ ], lines)
+
+ def test_gen_rules_repeated_args(self):
+ args = gen_jarjar.parse_arguments([
+ "jarjar-rules-generator-testjavalib.jar",
+ "--prefix", "jarjar.prefix",
+ "--output", "test-output-rules.txt",
+ "--apistubs", "framework-connectivity.stubs.module_lib.jar",
+ "--apistubs", "framework-connectivity-t.stubs.module_lib.jar",
+ "--unsupportedapi",
+ "testdata/test-unsupportedappusage.txt:testdata/test-other-unsupportedappusage.txt",
+ "--excludes", "testdata/test-jarjar-excludes.txt",
+ ])
+ gen_jarjar.make_jarjar_rules(args)
+
+ with open(args.output) as out:
+ lines = out.readlines()
+
+ self.maxDiff = None
self.assertListEqual([
'rule test.utils.TestUtilClass jarjar.prefix.@0\n',
'rule test.utils.TestUtilClassTest jarjar.prefix.@0\n',
diff --git a/tools/gn2bp/Android.bp.swp b/tools/gn2bp/Android.bp.swp
new file mode 100644
index 0000000..a86eea4
--- /dev/null
+++ b/tools/gn2bp/Android.bp.swp
@@ -0,0 +1,10765 @@
+// 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.
+//
+// This file is automatically generated by gen_android_bp. Do not edit.
+
+// GN: //base/allocator:buildflags
+genrule {
+ name: "cronet_aml_base_allocator_buildflags",
+ cmd: "echo '--flags USE_PARTITION_ALLOC=\"false\" USE_ALLOCATOR_SHIM=\"true\" USE_PARTITION_ALLOC_AS_MALLOC=\"false\" USE_BACKUP_REF_PTR=\"false\" USE_ASAN_BACKUP_REF_PTR=\"false\" USE_PARTITION_ALLOC_AS_GWP_ASAN_STORE=\"false\" USE_MTE_CHECKED_PTR=\"false\" FORCE_ENABLE_RAW_PTR_EXCLUSION=\"false\"' | " +
+ "$(location build/write_buildflag_header.py) --output " +
+ "$(out) " +
+ "--rulename " +
+ "//base/allocator:buildflags " +
+ "--gen-dir " +
+ ". " +
+ "--definitions " +
+ "/dev/stdin",
+ out: [
+ "base/allocator/buildflags.h",
+ ],
+ tool_files: [
+ "build/write_buildflag_header.py",
+ ],
+}
+
+// GN: //base/allocator/partition_allocator:chromecast_buildflags
+genrule {
+ name: "cronet_aml_base_allocator_partition_allocator_chromecast_buildflags",
+ cmd: "echo '--flags PA_IS_CAST_ANDROID=\"false\" PA_IS_CASTOS=\"false\"' | " +
+ "$(location build/write_buildflag_header.py) --output " +
+ "$(out) " +
+ "--rulename " +
+ "//base/allocator/partition_allocator:chromecast_buildflags " +
+ "--gen-dir " +
+ ". " +
+ "--definitions " +
+ "/dev/stdin",
+ out: [
+ "base/allocator/partition_allocator/chromecast_buildflags.h",
+ ],
+ tool_files: [
+ "build/write_buildflag_header.py",
+ ],
+}
+
+// GN: //base/allocator/partition_allocator:chromeos_buildflags
+genrule {
+ name: "cronet_aml_base_allocator_partition_allocator_chromeos_buildflags",
+ cmd: "echo '--flags PA_IS_CHROMEOS_ASH=\"false\"' | " +
+ "$(location build/write_buildflag_header.py) --output " +
+ "$(out) " +
+ "--rulename " +
+ "//base/allocator/partition_allocator:chromeos_buildflags " +
+ "--gen-dir " +
+ ". " +
+ "--definitions " +
+ "/dev/stdin",
+ out: [
+ "base/allocator/partition_allocator/chromeos_buildflags.h",
+ ],
+ tool_files: [
+ "build/write_buildflag_header.py",
+ ],
+}
+
+// GN: //base/allocator/partition_allocator:debugging_buildflags
+genrule {
+ name: "cronet_aml_base_allocator_partition_allocator_debugging_buildflags",
+ cmd: "echo '--flags PA_DCHECK_IS_ON=\"true\" PA_EXPENSIVE_DCHECKS_ARE_ON=\"true\" PA_DCHECK_IS_CONFIGURABLE=\"false\"' | " +
+ "$(location build/write_buildflag_header.py) --output " +
+ "$(out) " +
+ "--rulename " +
+ "//base/allocator/partition_allocator:debugging_buildflags " +
+ "--gen-dir " +
+ ". " +
+ "--definitions " +
+ "/dev/stdin",
+ out: [
+ "base/allocator/partition_allocator/partition_alloc_base/debug/debugging_buildflags.h",
+ ],
+ tool_files: [
+ "build/write_buildflag_header.py",
+ ],
+}
+
+// GN: //base/allocator/partition_allocator:logging_buildflags
+genrule {
+ name: "cronet_aml_base_allocator_partition_allocator_logging_buildflags",
+ cmd: "echo '--flags PA_ENABLE_LOG_ERROR_NOT_REACHED=\"false\"' | " +
+ "$(location build/write_buildflag_header.py) --output " +
+ "$(out) " +
+ "--rulename " +
+ "//base/allocator/partition_allocator:logging_buildflags " +
+ "--gen-dir " +
+ ". " +
+ "--definitions " +
+ "/dev/stdin",
+ out: [
+ "base/allocator/partition_allocator/logging_buildflags.h",
+ ],
+ tool_files: [
+ "build/write_buildflag_header.py",
+ ],
+}
+
+// GN: //base/allocator/partition_allocator:partition_alloc
+cc_library_static {
+ name: "cronet_aml_base_allocator_partition_allocator_partition_alloc",
+ srcs: [
+ ":cronet_aml_third_party_android_ndk_cpu_features",
+ "base/allocator/partition_allocator/address_pool_manager.cc",
+ "base/allocator/partition_allocator/address_pool_manager_bitmap.cc",
+ "base/allocator/partition_allocator/address_space_randomization.cc",
+ "base/allocator/partition_allocator/allocation_guard.cc",
+ "base/allocator/partition_allocator/dangling_raw_ptr_checks.cc",
+ "base/allocator/partition_allocator/gwp_asan_support.cc",
+ "base/allocator/partition_allocator/memory_reclaimer.cc",
+ "base/allocator/partition_allocator/oom.cc",
+ "base/allocator/partition_allocator/oom_callback.cc",
+ "base/allocator/partition_allocator/page_allocator.cc",
+ "base/allocator/partition_allocator/page_allocator_internals_posix.cc",
+ "base/allocator/partition_allocator/partition_address_space.cc",
+ "base/allocator/partition_allocator/partition_alloc.cc",
+ "base/allocator/partition_allocator/partition_alloc_base/check.cc",
+ "base/allocator/partition_allocator/partition_alloc_base/cpu.cc",
+ "base/allocator/partition_allocator/partition_alloc_base/debug/alias.cc",
+ "base/allocator/partition_allocator/partition_alloc_base/files/file_path.cc",
+ "base/allocator/partition_allocator/partition_alloc_base/files/file_util_posix.cc",
+ "base/allocator/partition_allocator/partition_alloc_base/logging.cc",
+ "base/allocator/partition_allocator/partition_alloc_base/memory/ref_counted.cc",
+ "base/allocator/partition_allocator/partition_alloc_base/native_library.cc",
+ "base/allocator/partition_allocator/partition_alloc_base/native_library_posix.cc",
+ "base/allocator/partition_allocator/partition_alloc_base/pkey.cc",
+ "base/allocator/partition_allocator/partition_alloc_base/posix/safe_strerror.cc",
+ "base/allocator/partition_allocator/partition_alloc_base/rand_util.cc",
+ "base/allocator/partition_allocator/partition_alloc_base/rand_util_posix.cc",
+ "base/allocator/partition_allocator/partition_alloc_base/strings/stringprintf.cc",
+ "base/allocator/partition_allocator/partition_alloc_base/threading/platform_thread.cc",
+ "base/allocator/partition_allocator/partition_alloc_base/threading/platform_thread_posix.cc",
+ "base/allocator/partition_allocator/partition_alloc_base/time/time.cc",
+ "base/allocator/partition_allocator/partition_alloc_base/time/time_android.cc",
+ "base/allocator/partition_allocator/partition_alloc_base/time/time_conversion_posix.cc",
+ "base/allocator/partition_allocator/partition_alloc_base/time/time_now_posix.cc",
+ "base/allocator/partition_allocator/partition_alloc_base/time/time_override.cc",
+ "base/allocator/partition_allocator/partition_alloc_hooks.cc",
+ "base/allocator/partition_allocator/partition_bucket.cc",
+ "base/allocator/partition_allocator/partition_oom.cc",
+ "base/allocator/partition_allocator/partition_page.cc",
+ "base/allocator/partition_allocator/partition_root.cc",
+ "base/allocator/partition_allocator/partition_stats.cc",
+ "base/allocator/partition_allocator/random.cc",
+ "base/allocator/partition_allocator/reservation_offset_table.cc",
+ "base/allocator/partition_allocator/spinning_mutex.cc",
+ "base/allocator/partition_allocator/starscan/metadata_allocator.cc",
+ "base/allocator/partition_allocator/starscan/pcscan.cc",
+ "base/allocator/partition_allocator/starscan/pcscan_internal.cc",
+ "base/allocator/partition_allocator/starscan/pcscan_scheduling.cc",
+ "base/allocator/partition_allocator/starscan/snapshot.cc",
+ "base/allocator/partition_allocator/starscan/stack/asm/x64/push_registers_asm.cc",
+ "base/allocator/partition_allocator/starscan/stack/stack.cc",
+ "base/allocator/partition_allocator/starscan/stats_collector.cc",
+ "base/allocator/partition_allocator/starscan/write_protector.cc",
+ "base/allocator/partition_allocator/tagging.cc",
+ "base/allocator/partition_allocator/thread_cache.cc",
+ ],
+ generated_headers: [
+ "cronet_aml_base_allocator_partition_allocator_chromecast_buildflags",
+ "cronet_aml_base_allocator_partition_allocator_chromeos_buildflags",
+ "cronet_aml_base_allocator_partition_allocator_debugging_buildflags",
+ "cronet_aml_base_allocator_partition_allocator_logging_buildflags",
+ "cronet_aml_base_allocator_partition_allocator_partition_alloc_buildflags",
+ ],
+ export_generated_headers: [
+ "cronet_aml_base_allocator_partition_allocator_chromecast_buildflags",
+ "cronet_aml_base_allocator_partition_allocator_chromeos_buildflags",
+ "cronet_aml_base_allocator_partition_allocator_debugging_buildflags",
+ "cronet_aml_base_allocator_partition_allocator_logging_buildflags",
+ "cronet_aml_base_allocator_partition_allocator_partition_alloc_buildflags",
+ ],
+ defaults: [
+ "cronet_aml_defaults",
+ ],
+ cflags: [
+ "-DANDROID",
+ "-DANDROID_NDK_VERSION_ROLL=r23_1",
+ "-DCR_CLANG_REVISION=\"llvmorg-16-init-8697-g60809cd2-1\"",
+ "-DCR_LIBCXX_REVISION=47b31179d10646029c260702650a25d24f555acc",
+ "-DDCHECK_ALWAYS_ON=1",
+ "-DDYNAMIC_ANNOTATIONS_ENABLED=1",
+ "-DHAVE_SYS_UIO_H",
+ "-DIS_PARTITION_ALLOC_IMPL",
+ "-DPA_PCSCAN_STACK_SUPPORTED",
+ "-D_DEBUG",
+ "-D_GNU_SOURCE",
+ "-D_LIBCPP_AVAILABILITY_CUSTOM_VERBOSE_ABORT_PROVIDED=1",
+ "-D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS",
+ "-D_LIBCPP_ENABLE_ASSERTIONS_DEFAULT=1",
+ "-D_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS",
+ "-D__STDC_CONSTANT_MACROS",
+ "-D__STDC_FORMAT_MACROS",
+ ],
+ local_include_dirs: [
+ "./",
+ "buildtools/third_party/libc++/",
+ "buildtools/third_party/libc++/trunk/include",
+ "buildtools/third_party/libc++abi/trunk/include",
+ "third_party/android_ndk/sources/android/cpufeatures/",
+ "third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include",
+ ],
+ cpp_std: "c++20",
+}
+
+// GN: //base/allocator/partition_allocator:partition_alloc_buildflags
+genrule {
+ name: "cronet_aml_base_allocator_partition_allocator_partition_alloc_buildflags",
+ cmd: "echo '--flags ENABLE_PARTITION_ALLOC_AS_MALLOC_SUPPORT=\"true\" ENABLE_BACKUP_REF_PTR_SUPPORT=\"true\" ENABLE_BACKUP_REF_PTR_SLOW_CHECKS=\"false\" ENABLE_DANGLING_RAW_PTR_CHECKS=\"false\" PUT_REF_COUNT_IN_PREVIOUS_SLOT=\"true\" ENABLE_GWP_ASAN_SUPPORT=\"true\" ENABLE_MTE_CHECKED_PTR_SUPPORT=\"false\" RECORD_ALLOC_INFO=\"false\" USE_FREESLOT_BITMAP=\"false\" GLUE_CORE_POOLS=\"false\" ENABLE_SHADOW_METADATA_FOR_64_BITS_POINTERS=\"false\" STARSCAN=\"true\" PA_USE_BASE_TRACING=\"true\" ENABLE_PKEYS=\"false\"' | " +
+ "$(location build/write_buildflag_header.py) --output " +
+ "$(out) " +
+ "--rulename " +
+ "//base/allocator/partition_allocator:partition_alloc_buildflags " +
+ "--gen-dir " +
+ ". " +
+ "--definitions " +
+ "/dev/stdin",
+ out: [
+ "base/allocator/partition_allocator/partition_alloc_buildflags.h",
+ ],
+ tool_files: [
+ "build/write_buildflag_header.py",
+ ],
+}
+
+// GN: //base:anchor_functions_buildflags
+genrule {
+ name: "cronet_aml_base_anchor_functions_buildflags",
+ cmd: "echo '--flags USE_LLD=\"true\" SUPPORTS_CODE_ORDERING=\"true\"' | " +
+ "$(location build/write_buildflag_header.py) --output " +
+ "$(out) " +
+ "--rulename " +
+ "//base:anchor_functions_buildflags " +
+ "--gen-dir " +
+ ". " +
+ "--definitions " +
+ "/dev/stdin",
+ out: [
+ "base/android/library_loader/anchor_functions_buildflags.h",
+ ],
+ tool_files: [
+ "build/write_buildflag_header.py",
+ ],
+}
+
+// GN: //base:android_runtime_jni_headers
+genrule {
+ name: "cronet_aml_base_android_runtime_jni_headers",
+ cmd: "$(location base/android/jni_generator/jni_generator.py) --ptr_type " +
+ "long " +
+ " " +
+ " " +
+ "--output_dir " +
+ "$(genDir)/base/android_runtime_jni_headers " +
+ "--includes " +
+ "base/android/jni_generator/jni_generator_helper.h " +
+ "--jar_file " +
+ "$(location third_party/android_sdk/public/platforms/android-33/android.jar) " +
+ "--output_name " +
+ "Runnable_jni.h " +
+ "--output_name " +
+ "Runtime_jni.h " +
+ "--input_file " +
+ "java/lang/Runnable.class " +
+ "--input_file " +
+ "java/lang/Runtime.class " +
+ "--javap " +
+ "$$(find out/.path -name javap)",
+ out: [
+ "base/android_runtime_jni_headers/Runnable_jni.h",
+ "base/android_runtime_jni_headers/Runtime_jni.h",
+ ],
+ tool_files: [
+ "base/android/jni_generator/jni_generator.py",
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/gn_helpers.py",
+ "third_party/android_sdk/public/platforms/android-33/android.jar",
+ ],
+}
+
+// GN: //base:base
+cc_library_static {
+ name: "cronet_aml_base_base",
+ srcs: [
+ ":cronet_aml_base_numerics_base_numerics",
+ ":cronet_aml_third_party_abseil_cpp_absl",
+ ":cronet_aml_third_party_abseil_cpp_absl_algorithm_algorithm",
+ ":cronet_aml_third_party_abseil_cpp_absl_algorithm_container",
+ ":cronet_aml_third_party_abseil_cpp_absl_base_atomic_hook",
+ ":cronet_aml_third_party_abseil_cpp_absl_base_base",
+ ":cronet_aml_third_party_abseil_cpp_absl_base_base_internal",
+ ":cronet_aml_third_party_abseil_cpp_absl_base_config",
+ ":cronet_aml_third_party_abseil_cpp_absl_base_core_headers",
+ ":cronet_aml_third_party_abseil_cpp_absl_base_cycleclock_internal",
+ ":cronet_aml_third_party_abseil_cpp_absl_base_dynamic_annotations",
+ ":cronet_aml_third_party_abseil_cpp_absl_base_endian",
+ ":cronet_aml_third_party_abseil_cpp_absl_base_errno_saver",
+ ":cronet_aml_third_party_abseil_cpp_absl_base_fast_type_id",
+ ":cronet_aml_third_party_abseil_cpp_absl_base_log_severity",
+ ":cronet_aml_third_party_abseil_cpp_absl_base_malloc_internal",
+ ":cronet_aml_third_party_abseil_cpp_absl_base_prefetch",
+ ":cronet_aml_third_party_abseil_cpp_absl_base_raw_logging_internal",
+ ":cronet_aml_third_party_abseil_cpp_absl_base_spinlock_wait",
+ ":cronet_aml_third_party_abseil_cpp_absl_base_strerror",
+ ":cronet_aml_third_party_abseil_cpp_absl_base_throw_delegate",
+ ":cronet_aml_third_party_abseil_cpp_absl_cleanup_cleanup",
+ ":cronet_aml_third_party_abseil_cpp_absl_cleanup_cleanup_internal",
+ ":cronet_aml_third_party_abseil_cpp_absl_container_btree",
+ ":cronet_aml_third_party_abseil_cpp_absl_container_common",
+ ":cronet_aml_third_party_abseil_cpp_absl_container_common_policy_traits",
+ ":cronet_aml_third_party_abseil_cpp_absl_container_compressed_tuple",
+ ":cronet_aml_third_party_abseil_cpp_absl_container_container_memory",
+ ":cronet_aml_third_party_abseil_cpp_absl_container_fixed_array",
+ ":cronet_aml_third_party_abseil_cpp_absl_container_flat_hash_map",
+ ":cronet_aml_third_party_abseil_cpp_absl_container_flat_hash_set",
+ ":cronet_aml_third_party_abseil_cpp_absl_container_hash_function_defaults",
+ ":cronet_aml_third_party_abseil_cpp_absl_container_hash_policy_traits",
+ ":cronet_aml_third_party_abseil_cpp_absl_container_hashtable_debug_hooks",
+ ":cronet_aml_third_party_abseil_cpp_absl_container_hashtablez_sampler",
+ ":cronet_aml_third_party_abseil_cpp_absl_container_inlined_vector",
+ ":cronet_aml_third_party_abseil_cpp_absl_container_inlined_vector_internal",
+ ":cronet_aml_third_party_abseil_cpp_absl_container_layout",
+ ":cronet_aml_third_party_abseil_cpp_absl_container_node_hash_map",
+ ":cronet_aml_third_party_abseil_cpp_absl_container_node_hash_set",
+ ":cronet_aml_third_party_abseil_cpp_absl_container_node_slot_policy",
+ ":cronet_aml_third_party_abseil_cpp_absl_container_raw_hash_map",
+ ":cronet_aml_third_party_abseil_cpp_absl_container_raw_hash_set",
+ ":cronet_aml_third_party_abseil_cpp_absl_debugging_debugging_internal",
+ ":cronet_aml_third_party_abseil_cpp_absl_debugging_demangle_internal",
+ ":cronet_aml_third_party_abseil_cpp_absl_debugging_examine_stack",
+ ":cronet_aml_third_party_abseil_cpp_absl_debugging_failure_signal_handler",
+ ":cronet_aml_third_party_abseil_cpp_absl_debugging_stacktrace",
+ ":cronet_aml_third_party_abseil_cpp_absl_debugging_symbolize",
+ ":cronet_aml_third_party_abseil_cpp_absl_functional_any_invocable",
+ ":cronet_aml_third_party_abseil_cpp_absl_functional_bind_front",
+ ":cronet_aml_third_party_abseil_cpp_absl_functional_function_ref",
+ ":cronet_aml_third_party_abseil_cpp_absl_hash_city",
+ ":cronet_aml_third_party_abseil_cpp_absl_hash_hash",
+ ":cronet_aml_third_party_abseil_cpp_absl_hash_low_level_hash",
+ ":cronet_aml_third_party_abseil_cpp_absl_memory_memory",
+ ":cronet_aml_third_party_abseil_cpp_absl_meta_type_traits",
+ ":cronet_aml_third_party_abseil_cpp_absl_numeric_bits",
+ ":cronet_aml_third_party_abseil_cpp_absl_numeric_int128",
+ ":cronet_aml_third_party_abseil_cpp_absl_numeric_representation",
+ ":cronet_aml_third_party_abseil_cpp_absl_profiling_exponential_biased",
+ ":cronet_aml_third_party_abseil_cpp_absl_profiling_sample_recorder",
+ ":cronet_aml_third_party_abseil_cpp_absl_random_distributions",
+ ":cronet_aml_third_party_abseil_cpp_absl_random_internal_distribution_caller",
+ ":cronet_aml_third_party_abseil_cpp_absl_random_internal_fast_uniform_bits",
+ ":cronet_aml_third_party_abseil_cpp_absl_random_internal_fastmath",
+ ":cronet_aml_third_party_abseil_cpp_absl_random_internal_generate_real",
+ ":cronet_aml_third_party_abseil_cpp_absl_random_internal_iostream_state_saver",
+ ":cronet_aml_third_party_abseil_cpp_absl_random_internal_nonsecure_base",
+ ":cronet_aml_third_party_abseil_cpp_absl_random_internal_pcg_engine",
+ ":cronet_aml_third_party_abseil_cpp_absl_random_internal_platform",
+ ":cronet_aml_third_party_abseil_cpp_absl_random_internal_pool_urbg",
+ ":cronet_aml_third_party_abseil_cpp_absl_random_internal_randen",
+ ":cronet_aml_third_party_abseil_cpp_absl_random_internal_randen_engine",
+ ":cronet_aml_third_party_abseil_cpp_absl_random_internal_randen_hwaes",
+ ":cronet_aml_third_party_abseil_cpp_absl_random_internal_randen_hwaes_impl",
+ ":cronet_aml_third_party_abseil_cpp_absl_random_internal_randen_slow",
+ ":cronet_aml_third_party_abseil_cpp_absl_random_internal_salted_seed_seq",
+ ":cronet_aml_third_party_abseil_cpp_absl_random_internal_seed_material",
+ ":cronet_aml_third_party_abseil_cpp_absl_random_internal_traits",
+ ":cronet_aml_third_party_abseil_cpp_absl_random_internal_uniform_helper",
+ ":cronet_aml_third_party_abseil_cpp_absl_random_internal_wide_multiply",
+ ":cronet_aml_third_party_abseil_cpp_absl_random_random",
+ ":cronet_aml_third_party_abseil_cpp_absl_random_seed_gen_exception",
+ ":cronet_aml_third_party_abseil_cpp_absl_random_seed_sequences",
+ ":cronet_aml_third_party_abseil_cpp_absl_status_status",
+ ":cronet_aml_third_party_abseil_cpp_absl_status_statusor",
+ ":cronet_aml_third_party_abseil_cpp_absl_strings_cord",
+ ":cronet_aml_third_party_abseil_cpp_absl_strings_cord_internal",
+ ":cronet_aml_third_party_abseil_cpp_absl_strings_cordz_functions",
+ ":cronet_aml_third_party_abseil_cpp_absl_strings_cordz_handle",
+ ":cronet_aml_third_party_abseil_cpp_absl_strings_cordz_info",
+ ":cronet_aml_third_party_abseil_cpp_absl_strings_cordz_statistics",
+ ":cronet_aml_third_party_abseil_cpp_absl_strings_cordz_update_scope",
+ ":cronet_aml_third_party_abseil_cpp_absl_strings_cordz_update_tracker",
+ ":cronet_aml_third_party_abseil_cpp_absl_strings_internal",
+ ":cronet_aml_third_party_abseil_cpp_absl_strings_str_format",
+ ":cronet_aml_third_party_abseil_cpp_absl_strings_str_format_internal",
+ ":cronet_aml_third_party_abseil_cpp_absl_strings_strings",
+ ":cronet_aml_third_party_abseil_cpp_absl_synchronization_graphcycles_internal",
+ ":cronet_aml_third_party_abseil_cpp_absl_synchronization_kernel_timeout_internal",
+ ":cronet_aml_third_party_abseil_cpp_absl_synchronization_synchronization",
+ ":cronet_aml_third_party_abseil_cpp_absl_time_internal_cctz_civil_time",
+ ":cronet_aml_third_party_abseil_cpp_absl_time_internal_cctz_time_zone",
+ ":cronet_aml_third_party_abseil_cpp_absl_time_time",
+ ":cronet_aml_third_party_abseil_cpp_absl_types_bad_optional_access",
+ ":cronet_aml_third_party_abseil_cpp_absl_types_bad_variant_access",
+ ":cronet_aml_third_party_abseil_cpp_absl_types_compare",
+ ":cronet_aml_third_party_abseil_cpp_absl_types_optional",
+ ":cronet_aml_third_party_abseil_cpp_absl_types_span",
+ ":cronet_aml_third_party_abseil_cpp_absl_types_variant",
+ ":cronet_aml_third_party_abseil_cpp_absl_utility_utility",
+ ":cronet_aml_third_party_android_ndk_cpu_features",
+ ":cronet_aml_third_party_ashmem_ashmem",
+ "base/allocator/allocator_check.cc",
+ "base/allocator/allocator_extension.cc",
+ "base/allocator/dispatcher/dispatcher.cc",
+ "base/allocator/dispatcher/internal/dispatch_data.cc",
+ "base/allocator/dispatcher/reentry_guard.cc",
+ "base/allocator/partition_allocator/shim/allocator_shim.cc",
+ "base/allocator/partition_allocator/shim/allocator_shim_default_dispatch_to_linker_wrapped_symbols.cc",
+ "base/android/android_hardware_buffer_compat.cc",
+ "base/android/android_image_reader_compat.cc",
+ "base/android/apk_assets.cc",
+ "base/android/application_status_listener.cc",
+ "base/android/base_feature_list.cc",
+ "base/android/base_features.cc",
+ "base/android/base_jni_onload.cc",
+ "base/android/build_info.cc",
+ "base/android/bundle_utils.cc",
+ "base/android/callback_android.cc",
+ "base/android/child_process_service.cc",
+ "base/android/command_line_android.cc",
+ "base/android/content_uri_utils.cc",
+ "base/android/cpu_features.cc",
+ "base/android/early_trace_event_binding.cc",
+ "base/android/event_log.cc",
+ "base/android/feature_list_jni.cc",
+ "base/android/features_jni.cc",
+ "base/android/field_trial_list.cc",
+ "base/android/important_file_writer_android.cc",
+ "base/android/int_string_callback.cc",
+ "base/android/jank_metric_uma_recorder.cc",
+ "base/android/java_exception_reporter.cc",
+ "base/android/java_handler_thread.cc",
+ "base/android/java_heap_dump_generator.cc",
+ "base/android/java_runtime.cc",
+ "base/android/jni_android.cc",
+ "base/android/jni_array.cc",
+ "base/android/jni_registrar.cc",
+ "base/android/jni_string.cc",
+ "base/android/jni_utils.cc",
+ "base/android/jni_weak_ref.cc",
+ "base/android/library_loader/anchor_functions.cc",
+ "base/android/library_loader/library_loader_hooks.cc",
+ "base/android/library_loader/library_prefetcher.cc",
+ "base/android/library_loader/library_prefetcher_hooks.cc",
+ "base/android/locale_utils.cc",
+ "base/android/memory_pressure_listener_android.cc",
+ "base/android/native_uma_recorder.cc",
+ "base/android/path_service_android.cc",
+ "base/android/path_utils.cc",
+ "base/android/radio_utils.cc",
+ "base/android/reached_addresses_bitset.cc",
+ "base/android/reached_code_profiler_stub.cc",
+ "base/android/remove_stale_data.cc",
+ "base/android/scoped_hardware_buffer_fence_sync.cc",
+ "base/android/scoped_hardware_buffer_handle.cc",
+ "base/android/scoped_java_ref.cc",
+ "base/android/statistics_recorder_android.cc",
+ "base/android/sys_utils.cc",
+ "base/android/task_scheduler/post_task_android.cc",
+ "base/android/task_scheduler/task_runner_android.cc",
+ "base/android/thread_instruction_count.cc",
+ "base/android/timezone_utils.cc",
+ "base/android/trace_event_binding.cc",
+ "base/android/unguessable_token_android.cc",
+ "base/at_exit.cc",
+ "base/barrier_closure.cc",
+ "base/base64.cc",
+ "base/base64url.cc",
+ "base/base_paths.cc",
+ "base/base_paths_android.cc",
+ "base/big_endian.cc",
+ "base/build_time.cc",
+ "base/callback_list.cc",
+ "base/check.cc",
+ "base/check_is_test.cc",
+ "base/check_op.cc",
+ "base/command_line.cc",
+ "base/containers/flat_tree.cc",
+ "base/containers/intrusive_heap.cc",
+ "base/containers/linked_list.cc",
+ "base/cpu.cc",
+ "base/cpu_reduction_experiment.cc",
+ "base/debug/activity_analyzer.cc",
+ "base/debug/activity_tracker.cc",
+ "base/debug/alias.cc",
+ "base/debug/asan_invalid_access.cc",
+ "base/debug/buffered_dwarf_reader.cc",
+ "base/debug/crash_logging.cc",
+ "base/debug/debugger.cc",
+ "base/debug/debugger_posix.cc",
+ "base/debug/dump_without_crashing.cc",
+ "base/debug/dwarf_line_no.cc",
+ "base/debug/elf_reader.cc",
+ "base/debug/proc_maps_linux.cc",
+ "base/debug/profiler.cc",
+ "base/debug/stack_trace.cc",
+ "base/debug/stack_trace_android.cc",
+ "base/debug/task_trace.cc",
+ "base/environment.cc",
+ "base/feature_list.cc",
+ "base/features.cc",
+ "base/file_descriptor_posix.cc",
+ "base/file_descriptor_store.cc",
+ "base/files/file.cc",
+ "base/files/file_descriptor_watcher_posix.cc",
+ "base/files/file_enumerator.cc",
+ "base/files/file_enumerator_posix.cc",
+ "base/files/file_path.cc",
+ "base/files/file_path_watcher.cc",
+ "base/files/file_path_watcher_inotify.cc",
+ "base/files/file_posix.cc",
+ "base/files/file_proxy.cc",
+ "base/files/file_tracing.cc",
+ "base/files/file_util.cc",
+ "base/files/file_util_android.cc",
+ "base/files/file_util_posix.cc",
+ "base/files/important_file_writer.cc",
+ "base/files/important_file_writer_cleaner.cc",
+ "base/files/memory_mapped_file.cc",
+ "base/files/memory_mapped_file_posix.cc",
+ "base/files/safe_base_name.cc",
+ "base/files/scoped_file.cc",
+ "base/files/scoped_file_android.cc",
+ "base/files/scoped_temp_dir.cc",
+ "base/functional/callback_helpers.cc",
+ "base/functional/callback_internal.cc",
+ "base/guid.cc",
+ "base/hash/hash.cc",
+ "base/hash/legacy_hash.cc",
+ "base/hash/md5_boringssl.cc",
+ "base/hash/sha1_boringssl.cc",
+ "base/json/json_file_value_serializer.cc",
+ "base/json/json_parser.cc",
+ "base/json/json_reader.cc",
+ "base/json/json_string_value_serializer.cc",
+ "base/json/json_value_converter.cc",
+ "base/json/json_writer.cc",
+ "base/json/string_escape.cc",
+ "base/json/values_util.cc",
+ "base/lazy_instance_helpers.cc",
+ "base/linux_util.cc",
+ "base/location.cc",
+ "base/logging.cc",
+ "base/memory/aligned_memory.cc",
+ "base/memory/discardable_memory.cc",
+ "base/memory/discardable_memory_allocator.cc",
+ "base/memory/discardable_shared_memory.cc",
+ "base/memory/madv_free_discardable_memory_allocator_posix.cc",
+ "base/memory/madv_free_discardable_memory_posix.cc",
+ "base/memory/memory_pressure_listener.cc",
+ "base/memory/memory_pressure_monitor.cc",
+ "base/memory/nonscannable_memory.cc",
+ "base/memory/page_size_posix.cc",
+ "base/memory/platform_shared_memory_handle.cc",
+ "base/memory/platform_shared_memory_mapper_android.cc",
+ "base/memory/platform_shared_memory_region.cc",
+ "base/memory/platform_shared_memory_region_android.cc",
+ "base/memory/raw_ptr.cc",
+ "base/memory/raw_ptr_asan_bound_arg_tracker.cc",
+ "base/memory/raw_ptr_asan_service.cc",
+ "base/memory/read_only_shared_memory_region.cc",
+ "base/memory/ref_counted.cc",
+ "base/memory/ref_counted_memory.cc",
+ "base/memory/shared_memory_mapper.cc",
+ "base/memory/shared_memory_mapping.cc",
+ "base/memory/shared_memory_security_policy.cc",
+ "base/memory/shared_memory_tracker.cc",
+ "base/memory/unsafe_shared_memory_pool.cc",
+ "base/memory/unsafe_shared_memory_region.cc",
+ "base/memory/weak_ptr.cc",
+ "base/memory/writable_shared_memory_region.cc",
+ "base/message_loop/message_pump.cc",
+ "base/message_loop/message_pump_android.cc",
+ "base/message_loop/message_pump_default.cc",
+ "base/message_loop/message_pump_epoll.cc",
+ "base/message_loop/message_pump_libevent.cc",
+ "base/message_loop/watchable_io_message_pump_posix.cc",
+ "base/message_loop/work_id_provider.cc",
+ "base/metrics/bucket_ranges.cc",
+ "base/metrics/crc32.cc",
+ "base/metrics/dummy_histogram.cc",
+ "base/metrics/field_trial.cc",
+ "base/metrics/field_trial_param_associator.cc",
+ "base/metrics/field_trial_params.cc",
+ "base/metrics/histogram.cc",
+ "base/metrics/histogram_base.cc",
+ "base/metrics/histogram_delta_serialization.cc",
+ "base/metrics/histogram_functions.cc",
+ "base/metrics/histogram_samples.cc",
+ "base/metrics/histogram_snapshot_manager.cc",
+ "base/metrics/metrics_hashes.cc",
+ "base/metrics/persistent_histogram_allocator.cc",
+ "base/metrics/persistent_histogram_storage.cc",
+ "base/metrics/persistent_memory_allocator.cc",
+ "base/metrics/persistent_sample_map.cc",
+ "base/metrics/ranges_manager.cc",
+ "base/metrics/sample_map.cc",
+ "base/metrics/sample_vector.cc",
+ "base/metrics/single_sample_metrics.cc",
+ "base/metrics/sparse_histogram.cc",
+ "base/metrics/statistics_recorder.cc",
+ "base/metrics/user_metrics.cc",
+ "base/native_library.cc",
+ "base/native_library_posix.cc",
+ "base/observer_list_internal.cc",
+ "base/observer_list_threadsafe.cc",
+ "base/observer_list_types.cc",
+ "base/one_shot_event.cc",
+ "base/os_compat_android.cc",
+ "base/path_service.cc",
+ "base/pending_task.cc",
+ "base/pickle.cc",
+ "base/posix/can_lower_nice_to.cc",
+ "base/posix/file_descriptor_shuffle.cc",
+ "base/posix/global_descriptors.cc",
+ "base/posix/safe_strerror.cc",
+ "base/posix/unix_domain_socket.cc",
+ "base/power_monitor/battery_level_provider.cc",
+ "base/power_monitor/battery_state_sampler.cc",
+ "base/power_monitor/moving_average.cc",
+ "base/power_monitor/power_monitor.cc",
+ "base/power_monitor/power_monitor_device_source.cc",
+ "base/power_monitor/power_monitor_device_source_android.cc",
+ "base/power_monitor/power_monitor_features.cc",
+ "base/power_monitor/power_monitor_source.cc",
+ "base/power_monitor/sampling_event_source.cc",
+ "base/power_monitor/timer_sampling_event_source.cc",
+ "base/process/environment_internal.cc",
+ "base/process/internal_linux.cc",
+ "base/process/kill.cc",
+ "base/process/kill_posix.cc",
+ "base/process/launch.cc",
+ "base/process/launch_posix.cc",
+ "base/process/memory.cc",
+ "base/process/memory_linux.cc",
+ "base/process/process_android.cc",
+ "base/process/process_handle.cc",
+ "base/process/process_handle_linux.cc",
+ "base/process/process_handle_posix.cc",
+ "base/process/process_iterator.cc",
+ "base/process/process_iterator_linux.cc",
+ "base/process/process_metrics.cc",
+ "base/process/process_metrics_linux.cc",
+ "base/process/process_metrics_posix.cc",
+ "base/process/process_posix.cc",
+ "base/profiler/arm_cfi_table.cc",
+ "base/profiler/frame.cc",
+ "base/profiler/metadata_recorder.cc",
+ "base/profiler/module_cache.cc",
+ "base/profiler/module_cache_posix.cc",
+ "base/profiler/sample_metadata.cc",
+ "base/profiler/sampling_profiler_thread_token.cc",
+ "base/profiler/stack_base_address_posix.cc",
+ "base/profiler/stack_buffer.cc",
+ "base/profiler/stack_copier.cc",
+ "base/profiler/stack_copier_signal.cc",
+ "base/profiler/stack_copier_suspend.cc",
+ "base/profiler/stack_sampler.cc",
+ "base/profiler/stack_sampler_android.cc",
+ "base/profiler/stack_sampler_impl.cc",
+ "base/profiler/stack_sampling_profiler.cc",
+ "base/profiler/thread_delegate_posix.cc",
+ "base/profiler/unwinder.cc",
+ "base/rand_util.cc",
+ "base/rand_util_posix.cc",
+ "base/run_loop.cc",
+ "base/sampling_heap_profiler/lock_free_address_hash_set.cc",
+ "base/sampling_heap_profiler/poisson_allocation_sampler.cc",
+ "base/sampling_heap_profiler/sampling_heap_profiler.cc",
+ "base/scoped_add_feature_flags.cc",
+ "base/scoped_environment_variable_override.cc",
+ "base/scoped_native_library.cc",
+ "base/sequence_checker.cc",
+ "base/sequence_checker_impl.cc",
+ "base/sequence_token.cc",
+ "base/strings/abseil_string_conversions.cc",
+ "base/strings/abseil_string_number_conversions.cc",
+ "base/strings/escape.cc",
+ "base/strings/latin1_string_conversions.cc",
+ "base/strings/pattern.cc",
+ "base/strings/safe_sprintf.cc",
+ "base/strings/strcat.cc",
+ "base/strings/string_number_conversions.cc",
+ "base/strings/string_piece.cc",
+ "base/strings/string_split.cc",
+ "base/strings/string_util.cc",
+ "base/strings/string_util_constants.cc",
+ "base/strings/stringprintf.cc",
+ "base/strings/sys_string_conversions_posix.cc",
+ "base/strings/utf_offset_string_conversions.cc",
+ "base/strings/utf_string_conversion_utils.cc",
+ "base/strings/utf_string_conversions.cc",
+ "base/substring_set_matcher/matcher_string_pattern.cc",
+ "base/substring_set_matcher/substring_set_matcher.cc",
+ "base/supports_user_data.cc",
+ "base/sync_socket.cc",
+ "base/sync_socket_posix.cc",
+ "base/synchronization/atomic_flag.cc",
+ "base/synchronization/condition_variable_posix.cc",
+ "base/synchronization/lock.cc",
+ "base/synchronization/lock_impl_posix.cc",
+ "base/synchronization/waitable_event_posix.cc",
+ "base/synchronization/waitable_event_watcher_posix.cc",
+ "base/syslog_logging.cc",
+ "base/system/sys_info.cc",
+ "base/system/sys_info_android.cc",
+ "base/system/sys_info_linux.cc",
+ "base/system/sys_info_posix.cc",
+ "base/system/system_monitor.cc",
+ "base/task/cancelable_task_tracker.cc",
+ "base/task/common/checked_lock_impl.cc",
+ "base/task/common/lazy_now.cc",
+ "base/task/common/operations_controller.cc",
+ "base/task/common/scoped_defer_task_posting.cc",
+ "base/task/common/task_annotator.cc",
+ "base/task/current_thread.cc",
+ "base/task/default_delayed_task_handle_delegate.cc",
+ "base/task/deferred_sequenced_task_runner.cc",
+ "base/task/delayed_task_handle.cc",
+ "base/task/lazy_thread_pool_task_runner.cc",
+ "base/task/post_job.cc",
+ "base/task/scoped_set_task_priority_for_current_thread.cc",
+ "base/task/sequence_manager/associated_thread_id.cc",
+ "base/task/sequence_manager/atomic_flag_set.cc",
+ "base/task/sequence_manager/delayed_task_handle_delegate.cc",
+ "base/task/sequence_manager/enqueue_order_generator.cc",
+ "base/task/sequence_manager/fence.cc",
+ "base/task/sequence_manager/hierarchical_timing_wheel.cc",
+ "base/task/sequence_manager/sequence_manager.cc",
+ "base/task/sequence_manager/sequence_manager_impl.cc",
+ "base/task/sequence_manager/sequenced_task_source.cc",
+ "base/task/sequence_manager/task_order.cc",
+ "base/task/sequence_manager/task_queue.cc",
+ "base/task/sequence_manager/task_queue_impl.cc",
+ "base/task/sequence_manager/task_queue_selector.cc",
+ "base/task/sequence_manager/tasks.cc",
+ "base/task/sequence_manager/thread_controller.cc",
+ "base/task/sequence_manager/thread_controller_impl.cc",
+ "base/task/sequence_manager/thread_controller_power_monitor.cc",
+ "base/task/sequence_manager/thread_controller_with_message_pump_impl.cc",
+ "base/task/sequence_manager/time_domain.cc",
+ "base/task/sequence_manager/timing_wheel.cc",
+ "base/task/sequence_manager/wake_up_queue.cc",
+ "base/task/sequence_manager/work_deduplicator.cc",
+ "base/task/sequence_manager/work_queue.cc",
+ "base/task/sequence_manager/work_queue_sets.cc",
+ "base/task/sequenced_task_runner.cc",
+ "base/task/simple_task_executor.cc",
+ "base/task/single_thread_task_executor.cc",
+ "base/task/single_thread_task_runner.cc",
+ "base/task/task_executor.cc",
+ "base/task/task_features.cc",
+ "base/task/task_runner.cc",
+ "base/task/task_traits.cc",
+ "base/task/thread_pool.cc",
+ "base/task/thread_pool/delayed_priority_queue.cc",
+ "base/task/thread_pool/delayed_task_manager.cc",
+ "base/task/thread_pool/environment_config.cc",
+ "base/task/thread_pool/initialization_util.cc",
+ "base/task/thread_pool/job_task_source.cc",
+ "base/task/thread_pool/pooled_parallel_task_runner.cc",
+ "base/task/thread_pool/pooled_sequenced_task_runner.cc",
+ "base/task/thread_pool/pooled_single_thread_task_runner_manager.cc",
+ "base/task/thread_pool/pooled_task_runner_delegate.cc",
+ "base/task/thread_pool/priority_queue.cc",
+ "base/task/thread_pool/sequence.cc",
+ "base/task/thread_pool/service_thread.cc",
+ "base/task/thread_pool/task.cc",
+ "base/task/thread_pool/task_source.cc",
+ "base/task/thread_pool/task_source_sort_key.cc",
+ "base/task/thread_pool/task_tracker.cc",
+ "base/task/thread_pool/thread_group.cc",
+ "base/task/thread_pool/thread_group_impl.cc",
+ "base/task/thread_pool/thread_group_native.cc",
+ "base/task/thread_pool/thread_pool_impl.cc",
+ "base/task/thread_pool/thread_pool_instance.cc",
+ "base/task/thread_pool/worker_thread.cc",
+ "base/task/thread_pool/worker_thread_stack.cc",
+ "base/third_party/cityhash/city.cc",
+ "base/third_party/cityhash_v103/src/city_v103.cc",
+ "base/third_party/nspr/prtime.cc",
+ "base/third_party/superfasthash/superfasthash.c",
+ "base/threading/hang_watcher.cc",
+ "base/threading/platform_thread.cc",
+ "base/threading/platform_thread_android.cc",
+ "base/threading/platform_thread_internal_posix.cc",
+ "base/threading/platform_thread_posix.cc",
+ "base/threading/platform_thread_ref.cc",
+ "base/threading/post_task_and_reply_impl.cc",
+ "base/threading/scoped_blocking_call.cc",
+ "base/threading/scoped_blocking_call_internal.cc",
+ "base/threading/scoped_thread_priority.cc",
+ "base/threading/sequence_local_storage_map.cc",
+ "base/threading/sequence_local_storage_slot.cc",
+ "base/threading/sequenced_task_runner_handle.cc",
+ "base/threading/simple_thread.cc",
+ "base/threading/thread.cc",
+ "base/threading/thread_checker.cc",
+ "base/threading/thread_checker_impl.cc",
+ "base/threading/thread_collision_warner.cc",
+ "base/threading/thread_id_name_manager.cc",
+ "base/threading/thread_local_storage.cc",
+ "base/threading/thread_local_storage_posix.cc",
+ "base/threading/thread_restrictions.cc",
+ "base/threading/thread_task_runner_handle.cc",
+ "base/threading/watchdog.cc",
+ "base/time/clock.cc",
+ "base/time/default_clock.cc",
+ "base/time/default_tick_clock.cc",
+ "base/time/tick_clock.cc",
+ "base/time/time.cc",
+ "base/time/time_android.cc",
+ "base/time/time_conversion_posix.cc",
+ "base/time/time_delta_from_string.cc",
+ "base/time/time_exploded_icu.cc",
+ "base/time/time_exploded_posix.cc",
+ "base/time/time_now_posix.cc",
+ "base/time/time_override.cc",
+ "base/time/time_to_iso8601.cc",
+ "base/timer/elapsed_timer.cc",
+ "base/timer/hi_res_timer_manager_posix.cc",
+ "base/timer/lap_timer.cc",
+ "base/timer/timer.cc",
+ "base/timer/wall_clock_timer.cc",
+ "base/token.cc",
+ "base/trace_event/heap_profiler_allocation_context.cc",
+ "base/trace_event/heap_profiler_allocation_context_tracker.cc",
+ "base/trace_event/memory_allocator_dump_guid.cc",
+ "base/trace_event/trace_event_stub.cc",
+ "base/trace_event/trace_id_helper.cc",
+ "base/unguessable_token.cc",
+ "base/value_iterators.cc",
+ "base/values.cc",
+ "base/version.cc",
+ "base/vlog.cc",
+ ],
+ shared_libs: [
+ "libandroid",
+ "liblog",
+ ],
+ static_libs: [
+ "cronet_aml_base_allocator_partition_allocator_partition_alloc",
+ "cronet_aml_base_base_static",
+ "cronet_aml_base_third_party_double_conversion_double_conversion",
+ "cronet_aml_base_third_party_dynamic_annotations_dynamic_annotations",
+ "cronet_aml_third_party_boringssl_boringssl",
+ "cronet_aml_third_party_icu_icui18n",
+ "cronet_aml_third_party_icu_icuuc_private",
+ "cronet_aml_third_party_libevent_libevent",
+ "cronet_aml_third_party_modp_b64_modp_b64",
+ ],
+ generated_headers: [
+ "cronet_aml_base_allocator_buildflags",
+ "cronet_aml_base_allocator_partition_allocator_chromecast_buildflags",
+ "cronet_aml_base_allocator_partition_allocator_chromeos_buildflags",
+ "cronet_aml_base_allocator_partition_allocator_debugging_buildflags",
+ "cronet_aml_base_allocator_partition_allocator_logging_buildflags",
+ "cronet_aml_base_allocator_partition_allocator_partition_alloc_buildflags",
+ "cronet_aml_base_anchor_functions_buildflags",
+ "cronet_aml_base_android_runtime_jni_headers",
+ "cronet_aml_base_base_jni_headers",
+ "cronet_aml_base_build_date",
+ "cronet_aml_base_cfi_buildflags",
+ "cronet_aml_base_clang_profiling_buildflags",
+ "cronet_aml_base_debugging_buildflags",
+ "cronet_aml_base_feature_list_buildflags",
+ "cronet_aml_base_ios_cronet_buildflags",
+ "cronet_aml_base_logging_buildflags",
+ "cronet_aml_base_message_pump_buildflags",
+ "cronet_aml_base_orderfile_buildflags",
+ "cronet_aml_base_parsing_buildflags",
+ "cronet_aml_base_power_monitor_buildflags",
+ "cronet_aml_base_profiler_buildflags",
+ "cronet_aml_base_sanitizer_buildflags",
+ "cronet_aml_base_synchronization_buildflags",
+ "cronet_aml_base_tracing_buildflags",
+ "cronet_aml_build_branding_buildflags",
+ "cronet_aml_build_chromecast_buildflags",
+ "cronet_aml_build_chromeos_buildflags",
+ "cronet_aml_build_config_compiler_compiler_buildflags",
+ ],
+ export_generated_headers: [
+ "cronet_aml_base_allocator_buildflags",
+ "cronet_aml_base_allocator_partition_allocator_chromecast_buildflags",
+ "cronet_aml_base_allocator_partition_allocator_chromeos_buildflags",
+ "cronet_aml_base_allocator_partition_allocator_debugging_buildflags",
+ "cronet_aml_base_allocator_partition_allocator_logging_buildflags",
+ "cronet_aml_base_allocator_partition_allocator_partition_alloc_buildflags",
+ "cronet_aml_base_anchor_functions_buildflags",
+ "cronet_aml_base_android_runtime_jni_headers",
+ "cronet_aml_base_base_jni_headers",
+ "cronet_aml_base_build_date",
+ "cronet_aml_base_cfi_buildflags",
+ "cronet_aml_base_clang_profiling_buildflags",
+ "cronet_aml_base_debugging_buildflags",
+ "cronet_aml_base_feature_list_buildflags",
+ "cronet_aml_base_ios_cronet_buildflags",
+ "cronet_aml_base_logging_buildflags",
+ "cronet_aml_base_message_pump_buildflags",
+ "cronet_aml_base_orderfile_buildflags",
+ "cronet_aml_base_parsing_buildflags",
+ "cronet_aml_base_power_monitor_buildflags",
+ "cronet_aml_base_profiler_buildflags",
+ "cronet_aml_base_sanitizer_buildflags",
+ "cronet_aml_base_synchronization_buildflags",
+ "cronet_aml_base_tracing_buildflags",
+ "cronet_aml_build_branding_buildflags",
+ "cronet_aml_build_chromecast_buildflags",
+ "cronet_aml_build_chromeos_buildflags",
+ "cronet_aml_build_config_compiler_compiler_buildflags",
+ ],
+ defaults: [
+ "cronet_aml_defaults",
+ ],
+ cflags: [
+ "-DABSL_ALLOCATOR_NOTHROW=1",
+ "-DANDROID",
+ "-DANDROID_NDK_VERSION_ROLL=r23_1",
+ "-DBASE_IMPLEMENTATION",
+ "-DCR_CLANG_REVISION=\"llvmorg-16-init-8697-g60809cd2-1\"",
+ "-DCR_LIBCXX_REVISION=47b31179d10646029c260702650a25d24f555acc",
+ "-DDCHECK_ALWAYS_ON=1",
+ "-DDYNAMIC_ANNOTATIONS_ENABLED=1",
+ "-DHAVE_SYS_UIO_H",
+ "-DICU_UTIL_DATA_IMPL=ICU_UTIL_DATA_FILE",
+ "-DUSE_CHROMIUM_ICU=1",
+ "-DU_ENABLE_DYLOAD=0",
+ "-DU_ENABLE_RESOURCE_TRACING=0",
+ "-DU_ENABLE_TRACING=1",
+ "-DU_STATIC_IMPLEMENTATION",
+ "-DU_USING_ICU_NAMESPACE=0",
+ "-D_DEBUG",
+ "-D_GNU_SOURCE",
+ "-D_LIBCPP_AVAILABILITY_CUSTOM_VERBOSE_ABORT_PROVIDED=1",
+ "-D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS",
+ "-D_LIBCPP_ENABLE_ASSERTIONS_DEFAULT=1",
+ "-D_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS",
+ "-D__STDC_CONSTANT_MACROS",
+ "-D__STDC_FORMAT_MACROS",
+ ],
+ local_include_dirs: [
+ "./",
+ "buildtools/third_party/libc++/",
+ "buildtools/third_party/libc++/trunk/include",
+ "buildtools/third_party/libc++abi/trunk/include",
+ "third_party/abseil-cpp/",
+ "third_party/android_ndk/sources/android/cpufeatures/",
+ "third_party/boringssl/src/include/",
+ "third_party/icu/source/common/",
+ "third_party/icu/source/i18n/",
+ "third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include",
+ ],
+ header_libs: [
+ "jni_headers",
+ ],
+ cpp_std: "c++20",
+}
+
+// GN: //base:base_jni_headers
+genrule {
+ name: "cronet_aml_base_base_jni_headers",
+ srcs: [
+ "base/android/java/src/org/chromium/base/ApkAssets.java",
+ "base/android/java/src/org/chromium/base/ApplicationStatus.java",
+ "base/android/java/src/org/chromium/base/BaseFeatureList.java",
+ "base/android/java/src/org/chromium/base/BuildInfo.java",
+ "base/android/java/src/org/chromium/base/BundleUtils.java",
+ "base/android/java/src/org/chromium/base/Callback.java",
+ "base/android/java/src/org/chromium/base/CommandLine.java",
+ "base/android/java/src/org/chromium/base/ContentUriUtils.java",
+ "base/android/java/src/org/chromium/base/CpuFeatures.java",
+ "base/android/java/src/org/chromium/base/EarlyTraceEvent.java",
+ "base/android/java/src/org/chromium/base/EventLog.java",
+ "base/android/java/src/org/chromium/base/FeatureList.java",
+ "base/android/java/src/org/chromium/base/Features.java",
+ "base/android/java/src/org/chromium/base/FieldTrialList.java",
+ "base/android/java/src/org/chromium/base/FileUtils.java",
+ "base/android/java/src/org/chromium/base/ImportantFileWriterAndroid.java",
+ "base/android/java/src/org/chromium/base/IntStringCallback.java",
+ "base/android/java/src/org/chromium/base/JNIUtils.java",
+ "base/android/java/src/org/chromium/base/JavaExceptionReporter.java",
+ "base/android/java/src/org/chromium/base/JavaHandlerThread.java",
+ "base/android/java/src/org/chromium/base/LocaleUtils.java",
+ "base/android/java/src/org/chromium/base/MemoryPressureListener.java",
+ "base/android/java/src/org/chromium/base/PathService.java",
+ "base/android/java/src/org/chromium/base/PathUtils.java",
+ "base/android/java/src/org/chromium/base/PowerMonitor.java",
+ "base/android/java/src/org/chromium/base/RadioUtils.java",
+ "base/android/java/src/org/chromium/base/SysUtils.java",
+ "base/android/java/src/org/chromium/base/ThreadUtils.java",
+ "base/android/java/src/org/chromium/base/TimezoneUtils.java",
+ "base/android/java/src/org/chromium/base/TraceEvent.java",
+ "base/android/java/src/org/chromium/base/UnguessableToken.java",
+ "base/android/java/src/org/chromium/base/jank_tracker/JankMetricUMARecorder.java",
+ "base/android/java/src/org/chromium/base/library_loader/LibraryLoader.java",
+ "base/android/java/src/org/chromium/base/library_loader/LibraryPrefetcher.java",
+ "base/android/java/src/org/chromium/base/memory/JavaHeapDumpGenerator.java",
+ "base/android/java/src/org/chromium/base/metrics/NativeUmaRecorder.java",
+ "base/android/java/src/org/chromium/base/metrics/StatisticsRecorderAndroid.java",
+ "base/android/java/src/org/chromium/base/process_launcher/ChildProcessService.java",
+ "base/android/java/src/org/chromium/base/task/PostTask.java",
+ "base/android/java/src/org/chromium/base/task/TaskRunnerImpl.java",
+ ],
+ cmd: "$(location base/android/jni_generator/jni_generator.py) --ptr_type " +
+ "long " +
+ " " +
+ " " +
+ "--output_dir " +
+ "$(genDir)/base/base_jni_headers " +
+ "--includes " +
+ "base/android/jni_generator/jni_generator_helper.h " +
+ "--use_proxy_hash " +
+ "--output_name " +
+ "ApkAssets_jni.h " +
+ "--output_name " +
+ "ApplicationStatus_jni.h " +
+ "--output_name " +
+ "BaseFeatureList_jni.h " +
+ "--output_name " +
+ "BuildInfo_jni.h " +
+ "--output_name " +
+ "BundleUtils_jni.h " +
+ "--output_name " +
+ "Callback_jni.h " +
+ "--output_name " +
+ "CommandLine_jni.h " +
+ "--output_name " +
+ "ContentUriUtils_jni.h " +
+ "--output_name " +
+ "CpuFeatures_jni.h " +
+ "--output_name " +
+ "EarlyTraceEvent_jni.h " +
+ "--output_name " +
+ "EventLog_jni.h " +
+ "--output_name " +
+ "FeatureList_jni.h " +
+ "--output_name " +
+ "Features_jni.h " +
+ "--output_name " +
+ "FieldTrialList_jni.h " +
+ "--output_name " +
+ "FileUtils_jni.h " +
+ "--output_name " +
+ "ImportantFileWriterAndroid_jni.h " +
+ "--output_name " +
+ "IntStringCallback_jni.h " +
+ "--output_name " +
+ "JNIUtils_jni.h " +
+ "--output_name " +
+ "JavaExceptionReporter_jni.h " +
+ "--output_name " +
+ "JavaHandlerThread_jni.h " +
+ "--output_name " +
+ "LocaleUtils_jni.h " +
+ "--output_name " +
+ "MemoryPressureListener_jni.h " +
+ "--output_name " +
+ "PathService_jni.h " +
+ "--output_name " +
+ "PathUtils_jni.h " +
+ "--output_name " +
+ "PowerMonitor_jni.h " +
+ "--output_name " +
+ "RadioUtils_jni.h " +
+ "--output_name " +
+ "SysUtils_jni.h " +
+ "--output_name " +
+ "ThreadUtils_jni.h " +
+ "--output_name " +
+ "TimezoneUtils_jni.h " +
+ "--output_name " +
+ "TraceEvent_jni.h " +
+ "--output_name " +
+ "UnguessableToken_jni.h " +
+ "--output_name " +
+ "JankMetricUMARecorder_jni.h " +
+ "--output_name " +
+ "LibraryLoader_jni.h " +
+ "--output_name " +
+ "LibraryPrefetcher_jni.h " +
+ "--output_name " +
+ "JavaHeapDumpGenerator_jni.h " +
+ "--output_name " +
+ "NativeUmaRecorder_jni.h " +
+ "--output_name " +
+ "StatisticsRecorderAndroid_jni.h " +
+ "--output_name " +
+ "ChildProcessService_jni.h " +
+ "--output_name " +
+ "PostTask_jni.h " +
+ "--output_name " +
+ "TaskRunnerImpl_jni.h " +
+ "--input_file " +
+ "$(location base/android/java/src/org/chromium/base/ApkAssets.java) " +
+ "--input_file " +
+ "$(location base/android/java/src/org/chromium/base/ApplicationStatus.java) " +
+ "--input_file " +
+ "$(location base/android/java/src/org/chromium/base/BaseFeatureList.java) " +
+ "--input_file " +
+ "$(location base/android/java/src/org/chromium/base/BuildInfo.java) " +
+ "--input_file " +
+ "$(location base/android/java/src/org/chromium/base/BundleUtils.java) " +
+ "--input_file " +
+ "$(location base/android/java/src/org/chromium/base/Callback.java) " +
+ "--input_file " +
+ "$(location base/android/java/src/org/chromium/base/CommandLine.java) " +
+ "--input_file " +
+ "$(location base/android/java/src/org/chromium/base/ContentUriUtils.java) " +
+ "--input_file " +
+ "$(location base/android/java/src/org/chromium/base/CpuFeatures.java) " +
+ "--input_file " +
+ "$(location base/android/java/src/org/chromium/base/EarlyTraceEvent.java) " +
+ "--input_file " +
+ "$(location base/android/java/src/org/chromium/base/EventLog.java) " +
+ "--input_file " +
+ "$(location base/android/java/src/org/chromium/base/FeatureList.java) " +
+ "--input_file " +
+ "$(location base/android/java/src/org/chromium/base/Features.java) " +
+ "--input_file " +
+ "$(location base/android/java/src/org/chromium/base/FieldTrialList.java) " +
+ "--input_file " +
+ "$(location base/android/java/src/org/chromium/base/FileUtils.java) " +
+ "--input_file " +
+ "$(location base/android/java/src/org/chromium/base/ImportantFileWriterAndroid.java) " +
+ "--input_file " +
+ "$(location base/android/java/src/org/chromium/base/IntStringCallback.java) " +
+ "--input_file " +
+ "$(location base/android/java/src/org/chromium/base/JNIUtils.java) " +
+ "--input_file " +
+ "$(location base/android/java/src/org/chromium/base/JavaExceptionReporter.java) " +
+ "--input_file " +
+ "$(location base/android/java/src/org/chromium/base/JavaHandlerThread.java) " +
+ "--input_file " +
+ "$(location base/android/java/src/org/chromium/base/LocaleUtils.java) " +
+ "--input_file " +
+ "$(location base/android/java/src/org/chromium/base/MemoryPressureListener.java) " +
+ "--input_file " +
+ "$(location base/android/java/src/org/chromium/base/PathService.java) " +
+ "--input_file " +
+ "$(location base/android/java/src/org/chromium/base/PathUtils.java) " +
+ "--input_file " +
+ "$(location base/android/java/src/org/chromium/base/PowerMonitor.java) " +
+ "--input_file " +
+ "$(location base/android/java/src/org/chromium/base/RadioUtils.java) " +
+ "--input_file " +
+ "$(location base/android/java/src/org/chromium/base/SysUtils.java) " +
+ "--input_file " +
+ "$(location base/android/java/src/org/chromium/base/ThreadUtils.java) " +
+ "--input_file " +
+ "$(location base/android/java/src/org/chromium/base/TimezoneUtils.java) " +
+ "--input_file " +
+ "$(location base/android/java/src/org/chromium/base/TraceEvent.java) " +
+ "--input_file " +
+ "$(location base/android/java/src/org/chromium/base/UnguessableToken.java) " +
+ "--input_file " +
+ "$(location base/android/java/src/org/chromium/base/jank_tracker/JankMetricUMARecorder.java) " +
+ "--input_file " +
+ "$(location base/android/java/src/org/chromium/base/library_loader/LibraryLoader.java) " +
+ "--input_file " +
+ "$(location base/android/java/src/org/chromium/base/library_loader/LibraryPrefetcher.java) " +
+ "--input_file " +
+ "$(location base/android/java/src/org/chromium/base/memory/JavaHeapDumpGenerator.java) " +
+ "--input_file " +
+ "$(location base/android/java/src/org/chromium/base/metrics/NativeUmaRecorder.java) " +
+ "--input_file " +
+ "$(location base/android/java/src/org/chromium/base/metrics/StatisticsRecorderAndroid.java) " +
+ "--input_file " +
+ "$(location base/android/java/src/org/chromium/base/process_launcher/ChildProcessService.java) " +
+ "--input_file " +
+ "$(location base/android/java/src/org/chromium/base/task/PostTask.java) " +
+ "--input_file " +
+ "$(location base/android/java/src/org/chromium/base/task/TaskRunnerImpl.java)",
+ out: [
+ "base/base_jni_headers/ApkAssets_jni.h",
+ "base/base_jni_headers/ApplicationStatus_jni.h",
+ "base/base_jni_headers/BaseFeatureList_jni.h",
+ "base/base_jni_headers/BuildInfo_jni.h",
+ "base/base_jni_headers/BundleUtils_jni.h",
+ "base/base_jni_headers/Callback_jni.h",
+ "base/base_jni_headers/ChildProcessService_jni.h",
+ "base/base_jni_headers/CommandLine_jni.h",
+ "base/base_jni_headers/ContentUriUtils_jni.h",
+ "base/base_jni_headers/CpuFeatures_jni.h",
+ "base/base_jni_headers/EarlyTraceEvent_jni.h",
+ "base/base_jni_headers/EventLog_jni.h",
+ "base/base_jni_headers/FeatureList_jni.h",
+ "base/base_jni_headers/Features_jni.h",
+ "base/base_jni_headers/FieldTrialList_jni.h",
+ "base/base_jni_headers/FileUtils_jni.h",
+ "base/base_jni_headers/ImportantFileWriterAndroid_jni.h",
+ "base/base_jni_headers/IntStringCallback_jni.h",
+ "base/base_jni_headers/JNIUtils_jni.h",
+ "base/base_jni_headers/JankMetricUMARecorder_jni.h",
+ "base/base_jni_headers/JavaExceptionReporter_jni.h",
+ "base/base_jni_headers/JavaHandlerThread_jni.h",
+ "base/base_jni_headers/JavaHeapDumpGenerator_jni.h",
+ "base/base_jni_headers/LibraryLoader_jni.h",
+ "base/base_jni_headers/LibraryPrefetcher_jni.h",
+ "base/base_jni_headers/LocaleUtils_jni.h",
+ "base/base_jni_headers/MemoryPressureListener_jni.h",
+ "base/base_jni_headers/NativeUmaRecorder_jni.h",
+ "base/base_jni_headers/PathService_jni.h",
+ "base/base_jni_headers/PathUtils_jni.h",
+ "base/base_jni_headers/PostTask_jni.h",
+ "base/base_jni_headers/PowerMonitor_jni.h",
+ "base/base_jni_headers/RadioUtils_jni.h",
+ "base/base_jni_headers/StatisticsRecorderAndroid_jni.h",
+ "base/base_jni_headers/SysUtils_jni.h",
+ "base/base_jni_headers/TaskRunnerImpl_jni.h",
+ "base/base_jni_headers/ThreadUtils_jni.h",
+ "base/base_jni_headers/TimezoneUtils_jni.h",
+ "base/base_jni_headers/TraceEvent_jni.h",
+ "base/base_jni_headers/UnguessableToken_jni.h",
+ ],
+ tool_files: [
+ "base/android/jni_generator/jni_generator.py",
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/gn_helpers.py",
+ ],
+}
+
+// GN: //base:base_static
+cc_library_static {
+ name: "cronet_aml_base_base_static",
+ srcs: [
+ "base/base_switches.cc",
+ ],
+ generated_headers: [
+ "cronet_aml_build_chromeos_buildflags",
+ ],
+ export_generated_headers: [
+ "cronet_aml_build_chromeos_buildflags",
+ ],
+ defaults: [
+ "cronet_aml_defaults",
+ ],
+ cflags: [
+ "-DANDROID",
+ "-DANDROID_NDK_VERSION_ROLL=r23_1",
+ "-DCR_CLANG_REVISION=\"llvmorg-16-init-8697-g60809cd2-1\"",
+ "-DCR_LIBCXX_REVISION=47b31179d10646029c260702650a25d24f555acc",
+ "-DDCHECK_ALWAYS_ON=1",
+ "-DDYNAMIC_ANNOTATIONS_ENABLED=1",
+ "-DHAVE_SYS_UIO_H",
+ "-D_DEBUG",
+ "-D_GNU_SOURCE",
+ "-D_LIBCPP_AVAILABILITY_CUSTOM_VERBOSE_ABORT_PROVIDED=1",
+ "-D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS",
+ "-D_LIBCPP_ENABLE_ASSERTIONS_DEFAULT=1",
+ "-D_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS",
+ "-D__STDC_CONSTANT_MACROS",
+ "-D__STDC_FORMAT_MACROS",
+ ],
+ local_include_dirs: [
+ "./",
+ "buildtools/third_party/libc++/",
+ "buildtools/third_party/libc++/trunk/include",
+ "buildtools/third_party/libc++abi/trunk/include",
+ "third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include",
+ ],
+ cpp_std: "c++20",
+}
+
+// GN: //base:build_date
+genrule {
+ name: "cronet_aml_base_build_date",
+ cmd: "$(location build/write_build_date_header.py) $(out) " +
+ "1664686800",
+ out: [
+ "base/generated_build_date.h",
+ ],
+ tool_files: [
+ "build/write_build_date_header.py",
+ ],
+}
+
+// GN: //base:cfi_buildflags
+genrule {
+ name: "cronet_aml_base_cfi_buildflags",
+ cmd: "echo '--flags CFI_CAST_CHECK=\"false && false\" CFI_DIAG=\"false && false\" CFI_ICALL_CHECK=\"false && false\" CFI_ENFORCEMENT_TRAP=\"false && !false\" CFI_ENFORCEMENT_DIAGNOSTIC=\"false && false && !false\"' | " +
+ "$(location build/write_buildflag_header.py) --output " +
+ "$(out) " +
+ "--rulename " +
+ "//base:cfi_buildflags " +
+ "--gen-dir " +
+ ". " +
+ "--definitions " +
+ "/dev/stdin",
+ out: [
+ "base/cfi_buildflags.h",
+ ],
+ tool_files: [
+ "build/write_buildflag_header.py",
+ ],
+}
+
+// GN: //base:clang_profiling_buildflags
+genrule {
+ name: "cronet_aml_base_clang_profiling_buildflags",
+ cmd: "echo '--flags CLANG_PROFILING=\"false\" CLANG_PROFILING_INSIDE_SANDBOX=\"false\" USE_CLANG_COVERAGE=\"false\"' | " +
+ "$(location build/write_buildflag_header.py) --output " +
+ "$(out) " +
+ "--rulename " +
+ "//base:clang_profiling_buildflags " +
+ "--gen-dir " +
+ ". " +
+ "--definitions " +
+ "/dev/stdin",
+ out: [
+ "base/clang_profiling_buildflags.h",
+ ],
+ tool_files: [
+ "build/write_buildflag_header.py",
+ ],
+}
+
+// GN: //base:debugging_buildflags
+genrule {
+ name: "cronet_aml_base_debugging_buildflags",
+ cmd: "echo '--flags DCHECK_IS_CONFIGURABLE=\"false\" ENABLE_LOCATION_SOURCE=\"true\" ENABLE_PROFILING=\"false\" CAN_UNWIND_WITH_FRAME_POINTERS=\"false\" UNSAFE_DEVELOPER_BUILD=\"true\" CAN_UNWIND_WITH_CFI_TABLE=\"false\" EXCLUDE_UNWIND_TABLES=\"false\" ENABLE_GDBINIT_WARNING=\"true\" ENABLE_LLDBINIT_WARNING=\"false\" EXPENSIVE_DCHECKS_ARE_ON=\"true\" ENABLE_STACK_TRACE_LINE_NUMBERS=\"false\"' | " +
+ "$(location build/write_buildflag_header.py) --output " +
+ "$(out) " +
+ "--rulename " +
+ "//base:debugging_buildflags " +
+ "--gen-dir " +
+ ". " +
+ "--definitions " +
+ "/dev/stdin",
+ out: [
+ "base/debug/debugging_buildflags.h",
+ ],
+ tool_files: [
+ "build/write_buildflag_header.py",
+ ],
+}
+
+// GN: //base:feature_list_buildflags
+genrule {
+ name: "cronet_aml_base_feature_list_buildflags",
+ cmd: "echo '--flags ENABLE_BANNED_BASE_FEATURE_PREFIX=\"false\"' | " +
+ "$(location build/write_buildflag_header.py) --output " +
+ "$(out) " +
+ "--rulename " +
+ "//base:feature_list_buildflags " +
+ "--gen-dir " +
+ ". " +
+ "--definitions " +
+ "/dev/stdin",
+ out: [
+ "base/feature_list_buildflags.h",
+ ],
+ tool_files: [
+ "build/write_buildflag_header.py",
+ ],
+}
+
+// GN: //base:ios_cronet_buildflags
+genrule {
+ name: "cronet_aml_base_ios_cronet_buildflags",
+ cmd: "echo '--flags CRONET_BUILD=\"false\"' | " +
+ "$(location build/write_buildflag_header.py) --output " +
+ "$(out) " +
+ "--rulename " +
+ "//base:ios_cronet_buildflags " +
+ "--gen-dir " +
+ ". " +
+ "--definitions " +
+ "/dev/stdin",
+ out: [
+ "base/message_loop/ios_cronet_buildflags.h",
+ ],
+ tool_files: [
+ "build/write_buildflag_header.py",
+ ],
+}
+
+// GN: //base:jni_java__build_config_crbug_908819
+genrule {
+ name: "cronet_aml_base_jni_java__build_config_crbug_908819",
+ cmd: "$(location build/android/gyp/write_build_config.py) --type " +
+ "java_library " +
+ " " +
+ " " +
+ "--deps-configs " +
+ "[\"$(location build/android/build_java.build_config.json)\", \"$(location third_party/android_sdk/android_sdk_java.build_config.json)\"] " +
+ "--public-deps-configs " +
+ "[] " +
+ "--build-config " +
+ "$(genDir)/base/jni_java.build_config.json " +
+ "--gn-target " +
+ "//base:jni_java " +
+ "--device-jar-path " +
+ "$(location base/jni_java.processed.jar) " +
+ "--host-jar-path " +
+ "$(location lib.java/base/jni_java.jar) " +
+ "--unprocessed-jar-path " +
+ "$(location base/jni_java.processed.jar) " +
+ "--interface-jar-path " +
+ "$(location base/jni_java.turbine.jar) " +
+ "--dex-path " +
+ "obj/base/jni_java.dex.jar " +
+ "--supports-android " +
+ "--java-sources-file " +
+ "gen/base/jni_java.sources " +
+ "--bundled-srcjars " +
+ "[]",
+ out: [
+ "base/jni_java.build_config.json",
+ ],
+ tool_files: [
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/android/gyp/util/resource_utils.py",
+ "build/android/gyp/write_build_config.py",
+ "build/gn_helpers.py",
+ "third_party/jinja2/__init__.py",
+ "third_party/jinja2/_compat.py",
+ "third_party/jinja2/_identifier.py",
+ "third_party/jinja2/bccache.py",
+ "third_party/jinja2/compiler.py",
+ "third_party/jinja2/defaults.py",
+ "third_party/jinja2/environment.py",
+ "third_party/jinja2/exceptions.py",
+ "third_party/jinja2/filters.py",
+ "third_party/jinja2/idtracking.py",
+ "third_party/jinja2/lexer.py",
+ "third_party/jinja2/loaders.py",
+ "third_party/jinja2/nodes.py",
+ "third_party/jinja2/optimizer.py",
+ "third_party/jinja2/parser.py",
+ "third_party/jinja2/runtime.py",
+ "third_party/jinja2/tests.py",
+ "third_party/jinja2/utils.py",
+ "third_party/jinja2/visitor.py",
+ "third_party/markupsafe/__init__.py",
+ "third_party/markupsafe/_compat.py",
+ "third_party/markupsafe/_native.py",
+ ],
+}
+
+// GN: //base:jni_java__compile_java
+genrule {
+ name: "cronet_aml_base_jni_java__compile_java",
+ srcs: [
+ "base/android/java/src/org/chromium/base/JniException.java",
+ "base/android/java/src/org/chromium/base/JniStaticTestMocker.java",
+ "base/android/java/src/org/chromium/base/NativeLibraryLoadedStatus.java",
+ "base/android/java/src/org/chromium/base/annotations/AccessedByNative.java",
+ "base/android/java/src/org/chromium/base/annotations/CalledByNative.java",
+ "base/android/java/src/org/chromium/base/annotations/CalledByNativeForTesting.java",
+ "base/android/java/src/org/chromium/base/annotations/CalledByNativeUnchecked.java",
+ "base/android/java/src/org/chromium/base/annotations/JNIAdditionalImport.java",
+ "base/android/java/src/org/chromium/base/annotations/JNINamespace.java",
+ "base/android/java/src/org/chromium/base/annotations/JniIgnoreNatives.java",
+ "base/android/java/src/org/chromium/base/annotations/NativeClassQualifiedName.java",
+ "base/android/java/src/org/chromium/base/annotations/NativeMethods.java",
+ ],
+ cmd: "$(location build/android/gyp/compile_java.py) --depfile " +
+ "gen/base/jni_java__compile_java.d " +
+ "--generated-dir " +
+ "gen/base/jni_java/generated_java " +
+ "--jar-path " +
+ "obj/base/jni_java.processed.jar " +
+ "--java-srcjars " +
+ "[\"gen/base/jni_java.generated.srcjar\"] " +
+ "--target-name " +
+ "//base:jni_java__compile_java " +
+ "--header-jar " +
+ "obj/base/jni_java.turbine.jar " +
+ "--classpath " +
+ "[\"obj/base/jni_java.turbine.jar\"] " +
+ "--classpath " +
+ "@FileArg(gen/base/jni_java.build_config.json:deps_info:javac_full_interface_classpath) " +
+ "--chromium-code " +
+ "1 " +
+ "@gen/base/jni_java.sources",
+ out: [
+ "//out/test/obj/base/jni_java.processed.jar",
+ "//out/test/obj/base/jni_java.processed.jar.info",
+ ],
+ tool_files: [
+ "build/android/gyp/compile_java.py",
+ "build/android/gyp/javac_output_processor.py",
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/android/gyp/util/jar_info_utils.py",
+ "build/android/gyp/util/md5_check.py",
+ "build/android/gyp/util/server_utils.py",
+ "build/android/list_java_targets.py",
+ "build/android/pylib/__init__.py",
+ "build/android/pylib/constants/__init__.py",
+ "build/gn_helpers.py",
+ "build/print_python_deps.py",
+ "out/test/gen/base/jni_java.build_config.json",
+ "out/test/gen/base/jni_java.generated.srcjar",
+ "out/test/gen/base/jni_java.sources",
+ "out/test/obj/base/jni_java.turbine.jar",
+ "third_party/catapult/devil/devil/__init__.py",
+ "third_party/catapult/devil/devil/android/__init__.py",
+ "third_party/catapult/devil/devil/android/constants/__init__.py",
+ "third_party/catapult/devil/devil/android/constants/chrome.py",
+ "third_party/catapult/devil/devil/android/sdk/__init__.py",
+ "third_party/catapult/devil/devil/android/sdk/keyevent.py",
+ "third_party/catapult/devil/devil/android/sdk/version_codes.py",
+ "third_party/catapult/devil/devil/constants/__init__.py",
+ "third_party/catapult/devil/devil/constants/exit_codes.py",
+ "third_party/colorama/src/colorama/__init__.py",
+ "third_party/colorama/src/colorama/ansi.py",
+ "third_party/colorama/src/colorama/ansitowin32.py",
+ "third_party/colorama/src/colorama/initialise.py",
+ "third_party/colorama/src/colorama/win32.py",
+ "third_party/colorama/src/colorama/winterm.py",
+ "tools/android/modularization/convenience/lookup_dep.py",
+ ],
+}
+
+// GN: //base:jni_java__dex
+genrule {
+ name: "cronet_aml_base_jni_java__dex",
+ cmd: "$(location build/android/gyp/dex.py) --depfile " +
+ "gen/base/jni_java__dex.d " +
+ "--output " +
+ "obj/base/jni_java.dex.jar " +
+ "--min-api " +
+ "19 " +
+ "--r8-jar-path " +
+ "../../third_party/r8/lib/r8.jar " +
+ "--custom-d8-jar-path " +
+ "../../third_party/r8/custom_d8.jar " +
+ "--incremental-dir " +
+ "obj/base/jni_java__dex " +
+ "--library " +
+ "--class-inputs " +
+ "[\"obj/base/jni_java.processed.jar\"] " +
+ "--desugar " +
+ "--desugar-jdk-libs-json " +
+ "../../third_party/r8/desugar_jdk_libs.json " +
+ "--show-desugar-default-interface-warnings " +
+ "--classpath " +
+ "obj/base/jni_java.processed.jar " +
+ "--desugar-dependencies " +
+ "gen/base/jni_java__dex.desugardeps " +
+ "--bootclasspath " +
+ "@FileArg(gen/base/jni_java.build_config.json:android:sdk_jars) " +
+ "--classpath " +
+ "@FileArg(gen/base/jni_java.build_config.json:deps_info:javac_full_interface_classpath) " +
+ "--force-enable-assertions",
+ out: [
+ "//out/test/obj/base/jni_java.dex.jar",
+ ],
+ tool_files: [
+ "build/android/gyp/dex.py",
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/android/gyp/util/md5_check.py",
+ "build/android/gyp/util/zipalign.py",
+ "build/gn_helpers.py",
+ "build/print_python_deps.py",
+ "out/test/obj/base/jni_java.processed.jar",
+ "third_party/r8/custom_d8.jar",
+ "third_party/r8/d8/lib/r8.jar",
+ "third_party/r8/desugar_jdk_libs.json",
+ ],
+}
+
+// GN: //base:jni_java__errorprone
+genrule {
+ name: "cronet_aml_base_jni_java__errorprone",
+ srcs: [
+ "base/android/java/src/org/chromium/base/JniException.java",
+ "base/android/java/src/org/chromium/base/JniStaticTestMocker.java",
+ "base/android/java/src/org/chromium/base/NativeLibraryLoadedStatus.java",
+ "base/android/java/src/org/chromium/base/annotations/AccessedByNative.java",
+ "base/android/java/src/org/chromium/base/annotations/CalledByNative.java",
+ "base/android/java/src/org/chromium/base/annotations/CalledByNativeForTesting.java",
+ "base/android/java/src/org/chromium/base/annotations/CalledByNativeUnchecked.java",
+ "base/android/java/src/org/chromium/base/annotations/JNIAdditionalImport.java",
+ "base/android/java/src/org/chromium/base/annotations/JNINamespace.java",
+ "base/android/java/src/org/chromium/base/annotations/JniIgnoreNatives.java",
+ "base/android/java/src/org/chromium/base/annotations/NativeClassQualifiedName.java",
+ "base/android/java/src/org/chromium/base/annotations/NativeMethods.java",
+ ],
+ cmd: "$(location build/android/gyp/compile_java.py) --depfile " +
+ "gen/base/jni_java__errorprone.d " +
+ "--generated-dir " +
+ "gen/base/jni_java/generated_java " +
+ "--jar-path " +
+ "obj/base/jni_java__errorprone.errorprone.stamp " +
+ "--java-srcjars " +
+ "[\"gen/base/jni_java.generated.srcjar\"] " +
+ "--target-name " +
+ "//base:jni_java__errorprone " +
+ "--header-jar " +
+ "obj/base/jni_java.turbine.jar " +
+ "--classpath " +
+ "[\"obj/base/jni_java.turbine.jar\"] " +
+ "--classpath " +
+ "@FileArg(gen/base/jni_java.build_config.json:deps_info:javac_full_interface_classpath) " +
+ "--chromium-code " +
+ "1 " +
+ "--processorpath " +
+ "@FileArg(gen/tools/android/errorprone_plugin/errorprone_plugin.build_config.json:deps_info:host_classpath) " +
+ "--enable-errorprone " +
+ "@gen/base/jni_java.sources",
+ out: [
+ "//out/test/obj/base/jni_java__errorprone.errorprone.stamp",
+ ],
+ tool_files: [
+ "build/android/gyp/compile_java.py",
+ "build/android/gyp/javac_output_processor.py",
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/android/gyp/util/jar_info_utils.py",
+ "build/android/gyp/util/md5_check.py",
+ "build/android/gyp/util/server_utils.py",
+ "build/android/list_java_targets.py",
+ "build/android/pylib/__init__.py",
+ "build/android/pylib/constants/__init__.py",
+ "build/gn_helpers.py",
+ "build/print_python_deps.py",
+ "out/test/gen/base/jni_java.build_config.json",
+ "out/test/gen/base/jni_java.generated.srcjar",
+ "out/test/gen/base/jni_java.sources",
+ "out/test/obj/base/jni_java.turbine.jar",
+ "third_party/catapult/devil/devil/__init__.py",
+ "third_party/catapult/devil/devil/android/__init__.py",
+ "third_party/catapult/devil/devil/android/constants/__init__.py",
+ "third_party/catapult/devil/devil/android/constants/chrome.py",
+ "third_party/catapult/devil/devil/android/sdk/__init__.py",
+ "third_party/catapult/devil/devil/android/sdk/keyevent.py",
+ "third_party/catapult/devil/devil/android/sdk/version_codes.py",
+ "third_party/catapult/devil/devil/constants/__init__.py",
+ "third_party/catapult/devil/devil/constants/exit_codes.py",
+ "third_party/colorama/src/colorama/__init__.py",
+ "third_party/colorama/src/colorama/ansi.py",
+ "third_party/colorama/src/colorama/ansitowin32.py",
+ "third_party/colorama/src/colorama/initialise.py",
+ "third_party/colorama/src/colorama/win32.py",
+ "third_party/colorama/src/colorama/winterm.py",
+ "tools/android/modularization/convenience/lookup_dep.py",
+ ],
+}
+
+// GN: //base:jni_java__header
+genrule {
+ name: "cronet_aml_base_jni_java__header",
+ srcs: [
+ "base/android/java/src/org/chromium/base/JniException.java",
+ "base/android/java/src/org/chromium/base/JniStaticTestMocker.java",
+ "base/android/java/src/org/chromium/base/NativeLibraryLoadedStatus.java",
+ "base/android/java/src/org/chromium/base/annotations/AccessedByNative.java",
+ "base/android/java/src/org/chromium/base/annotations/CalledByNative.java",
+ "base/android/java/src/org/chromium/base/annotations/CalledByNativeForTesting.java",
+ "base/android/java/src/org/chromium/base/annotations/CalledByNativeUnchecked.java",
+ "base/android/java/src/org/chromium/base/annotations/JNIAdditionalImport.java",
+ "base/android/java/src/org/chromium/base/annotations/JNINamespace.java",
+ "base/android/java/src/org/chromium/base/annotations/JniIgnoreNatives.java",
+ "base/android/java/src/org/chromium/base/annotations/NativeClassQualifiedName.java",
+ "base/android/java/src/org/chromium/base/annotations/NativeMethods.java",
+ ],
+ cmd: "$(location build/android/gyp/turbine.py) --depfile " +
+ "gen/base/jni_java__header.d " +
+ "--generated-dir " +
+ "gen/base/jni_java/generated_java " +
+ "--jar-path " +
+ "obj/base/jni_java.turbine.jar " +
+ "--java-srcjars " +
+ "[] " +
+ "--target-name " +
+ "//base:jni_java__header " +
+ "--classpath " +
+ "@FileArg(gen/base/jni_java.build_config.json:javac:interface_classpath) " +
+ "--processorpath " +
+ "@FileArg(gen/base/jni_java.build_config.json:javac:processor_classpath) " +
+ "--processors " +
+ "@FileArg(gen/base/jni_java.build_config.json:javac:processor_classes) " +
+ "--turbine-jar-path " +
+ "../../third_party/turbine/turbine.jar " +
+ "--generated-jar-path " +
+ "gen/base/jni_java.generated.srcjar " +
+ "--chromium-code " +
+ "1 " +
+ "@gen/base/jni_java.sources",
+ out: [
+ "//out/test/obj/base/jni_java.turbine.jar",
+ "base/jni_java.generated.srcjar",
+ ],
+ tool_files: [
+ "build/android/gyp/javac_output_processor.py",
+ "build/android/gyp/turbine.py",
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/android/list_java_targets.py",
+ "build/android/pylib/__init__.py",
+ "build/android/pylib/constants/__init__.py",
+ "build/gn_helpers.py",
+ "out/test/gen/base/jni_java.build_config.json",
+ "out/test/gen/base/jni_java.sources",
+ "third_party/catapult/devil/devil/__init__.py",
+ "third_party/catapult/devil/devil/android/__init__.py",
+ "third_party/catapult/devil/devil/android/constants/__init__.py",
+ "third_party/catapult/devil/devil/android/constants/chrome.py",
+ "third_party/catapult/devil/devil/android/sdk/__init__.py",
+ "third_party/catapult/devil/devil/android/sdk/keyevent.py",
+ "third_party/catapult/devil/devil/android/sdk/version_codes.py",
+ "third_party/catapult/devil/devil/constants/__init__.py",
+ "third_party/catapult/devil/devil/constants/exit_codes.py",
+ "third_party/colorama/src/colorama/__init__.py",
+ "third_party/colorama/src/colorama/ansi.py",
+ "third_party/colorama/src/colorama/ansitowin32.py",
+ "third_party/colorama/src/colorama/initialise.py",
+ "third_party/colorama/src/colorama/win32.py",
+ "third_party/colorama/src/colorama/winterm.py",
+ "third_party/turbine/turbine.jar",
+ "tools/android/modularization/convenience/lookup_dep.py",
+ ],
+}
+
+// GN: //base:jni_java__host
+genrule {
+ name: "cronet_aml_base_jni_java__host",
+ cmd: "$(location build/android/gyp/filter_zip.py) --input " +
+ "obj/base/jni_java.processed.jar " +
+ "--output " +
+ "lib.java/base/jni_java.jar " +
+ "--exclude-globs " +
+ "[] " +
+ "--include-globs " +
+ "[]",
+ out: [
+ "//out/test/lib.java/base/jni_java.jar",
+ ],
+ tool_files: [
+ "build/android/gyp/filter_zip.py",
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/gn_helpers.py",
+ "out/test/obj/base/jni_java.processed.jar",
+ ],
+}
+
+// GN: //base:jni_java__validate
+genrule {
+ name: "cronet_aml_base_jni_java__validate",
+ cmd: "$(location build/android/gyp/bytecode_processor.py) --target-name " +
+ "//base:jni_java__validate " +
+ "--script " +
+ "bin/helper/bytecode_processor " +
+ "--gn-target " +
+ "//base:jni_java " +
+ "--input-jar " +
+ "obj/base/jni_java.processed.jar " +
+ "--stamp " +
+ "obj/base/jni_java__validate.bytecode.stamp " +
+ "--direct-classpath-jars " +
+ "@FileArg(gen/base/jni_java.build_config.json:javac:classpath) " +
+ "--full-classpath-jars " +
+ "@FileArg(gen/base/jni_java.build_config.json:deps_info:javac_full_classpath) " +
+ "--full-classpath-gn-targets " +
+ "@FileArg(gen/base/jni_java.build_config.json:deps_info:javac_full_classpath_targets)",
+ out: [
+ "//out/test/obj/base/jni_java__validate.bytecode.stamp",
+ ],
+ tool_files: [
+ "build/android/gyp/bytecode_processor.py",
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/android/gyp/util/server_utils.py",
+ "build/gn_helpers.py",
+ "out/test/bin/helper/bytecode_processor",
+ "out/test/gen/base/jni_java.build_config.json",
+ "out/test/obj/base/jni_java.processed.jar",
+ ],
+}
+
+// GN: //base:logging_buildflags
+genrule {
+ name: "cronet_aml_base_logging_buildflags",
+ cmd: "echo '--flags ENABLE_LOG_ERROR_NOT_REACHED=\"false\" USE_RUNTIME_VLOG=\"true\"' | " +
+ "$(location build/write_buildflag_header.py) --output " +
+ "$(out) " +
+ "--rulename " +
+ "//base:logging_buildflags " +
+ "--gen-dir " +
+ ". " +
+ "--definitions " +
+ "/dev/stdin",
+ out: [
+ "base/logging_buildflags.h",
+ ],
+ tool_files: [
+ "build/write_buildflag_header.py",
+ ],
+}
+
+// GN: //base:message_pump_buildflags
+genrule {
+ name: "cronet_aml_base_message_pump_buildflags",
+ cmd: "echo '--flags ENABLE_MESSAGE_PUMP_EPOLL=\"true\"' | " +
+ "$(location build/write_buildflag_header.py) --output " +
+ "$(out) " +
+ "--rulename " +
+ "//base:message_pump_buildflags " +
+ "--gen-dir " +
+ ". " +
+ "--definitions " +
+ "/dev/stdin",
+ out: [
+ "base/message_loop/message_pump_buildflags.h",
+ ],
+ tool_files: [
+ "build/write_buildflag_header.py",
+ ],
+}
+
+// GN: //base/numerics:base_numerics
+filegroup {
+ name: "cronet_aml_base_numerics_base_numerics",
+}
+
+// GN: //base:orderfile_buildflags
+genrule {
+ name: "cronet_aml_base_orderfile_buildflags",
+ cmd: "echo '--flags DEVTOOLS_INSTRUMENTATION_DUMPING=\"false\" ORDERFILE_INSTRUMENTATION=\"false\"' | " +
+ "$(location build/write_buildflag_header.py) --output " +
+ "$(out) " +
+ "--rulename " +
+ "//base:orderfile_buildflags " +
+ "--gen-dir " +
+ ". " +
+ "--definitions " +
+ "/dev/stdin",
+ out: [
+ "base/android/orderfile/orderfile_buildflags.h",
+ ],
+ tool_files: [
+ "build/write_buildflag_header.py",
+ ],
+}
+
+// GN: //base:parsing_buildflags
+genrule {
+ name: "cronet_aml_base_parsing_buildflags",
+ cmd: "echo '--flags BUILD_RUST_JSON_PARSER=\"false\"' | " +
+ "$(location build/write_buildflag_header.py) --output " +
+ "$(out) " +
+ "--rulename " +
+ "//base:parsing_buildflags " +
+ "--gen-dir " +
+ ". " +
+ "--definitions " +
+ "/dev/stdin",
+ out: [
+ "base/parsing_buildflags.h",
+ ],
+ tool_files: [
+ "build/write_buildflag_header.py",
+ ],
+}
+
+// GN: //base:power_monitor_buildflags
+genrule {
+ name: "cronet_aml_base_power_monitor_buildflags",
+ cmd: "echo '--flags HAS_BATTERY_LEVEL_PROVIDER_IMPL=\"false\"' | " +
+ "$(location build/write_buildflag_header.py) --output " +
+ "$(out) " +
+ "--rulename " +
+ "//base:power_monitor_buildflags " +
+ "--gen-dir " +
+ ". " +
+ "--definitions " +
+ "/dev/stdin",
+ out: [
+ "base/power_monitor/power_monitor_buildflags.h",
+ ],
+ tool_files: [
+ "build/write_buildflag_header.py",
+ ],
+}
+
+// GN: //base:profiler_buildflags
+genrule {
+ name: "cronet_aml_base_profiler_buildflags",
+ cmd: "echo '--flags ENABLE_ARM_CFI_TABLE=\"false\" IOS_STACK_PROFILER_ENABLED=\"true\" USE_ANDROID_UNWINDER_V2=\"true\"' | " +
+ "$(location build/write_buildflag_header.py) --output " +
+ "$(out) " +
+ "--rulename " +
+ "//base:profiler_buildflags " +
+ "--gen-dir " +
+ ". " +
+ "--definitions " +
+ "/dev/stdin",
+ out: [
+ "base/profiler/profiler_buildflags.h",
+ ],
+ tool_files: [
+ "build/write_buildflag_header.py",
+ ],
+}
+
+// GN: //base:sanitizer_buildflags
+genrule {
+ name: "cronet_aml_base_sanitizer_buildflags",
+ cmd: "echo '--flags IS_HWASAN=\"false\" USING_SANITIZER=\"false\"' | " +
+ "$(location build/write_buildflag_header.py) --output " +
+ "$(out) " +
+ "--rulename " +
+ "//base:sanitizer_buildflags " +
+ "--gen-dir " +
+ ". " +
+ "--definitions " +
+ "/dev/stdin",
+ out: [
+ "base/sanitizer_buildflags.h",
+ ],
+ tool_files: [
+ "build/write_buildflag_header.py",
+ ],
+}
+
+// GN: //base:synchronization_buildflags
+genrule {
+ name: "cronet_aml_base_synchronization_buildflags",
+ cmd: "echo '--flags ENABLE_MUTEX_PRIORITY_INHERITANCE=\"false\"' | " +
+ "$(location build/write_buildflag_header.py) --output " +
+ "$(out) " +
+ "--rulename " +
+ "//base:synchronization_buildflags " +
+ "--gen-dir " +
+ ". " +
+ "--definitions " +
+ "/dev/stdin",
+ out: [
+ "base/synchronization/synchronization_buildflags.h",
+ ],
+ tool_files: [
+ "build/write_buildflag_header.py",
+ ],
+}
+
+// GN: //base/third_party/double_conversion:double_conversion
+cc_library_static {
+ name: "cronet_aml_base_third_party_double_conversion_double_conversion",
+ srcs: [
+ "base/third_party/double_conversion/double-conversion/bignum-dtoa.cc",
+ "base/third_party/double_conversion/double-conversion/bignum.cc",
+ "base/third_party/double_conversion/double-conversion/cached-powers.cc",
+ "base/third_party/double_conversion/double-conversion/double-to-string.cc",
+ "base/third_party/double_conversion/double-conversion/fast-dtoa.cc",
+ "base/third_party/double_conversion/double-conversion/fixed-dtoa.cc",
+ "base/third_party/double_conversion/double-conversion/string-to-double.cc",
+ "base/third_party/double_conversion/double-conversion/strtod.cc",
+ ],
+ defaults: [
+ "cronet_aml_defaults",
+ ],
+ cflags: [
+ "-DANDROID",
+ "-DANDROID_NDK_VERSION_ROLL=r23_1",
+ "-DCR_CLANG_REVISION=\"llvmorg-16-init-8697-g60809cd2-1\"",
+ "-DCR_LIBCXX_REVISION=47b31179d10646029c260702650a25d24f555acc",
+ "-DDCHECK_ALWAYS_ON=1",
+ "-DDYNAMIC_ANNOTATIONS_ENABLED=1",
+ "-DHAVE_SYS_UIO_H",
+ "-D_DEBUG",
+ "-D_GNU_SOURCE",
+ "-D_LIBCPP_AVAILABILITY_CUSTOM_VERBOSE_ABORT_PROVIDED=1",
+ "-D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS",
+ "-D_LIBCPP_ENABLE_ASSERTIONS_DEFAULT=1",
+ "-D_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS",
+ "-D__STDC_CONSTANT_MACROS",
+ "-D__STDC_FORMAT_MACROS",
+ ],
+ local_include_dirs: [
+ "./",
+ "buildtools/third_party/libc++/",
+ "buildtools/third_party/libc++/trunk/include",
+ "buildtools/third_party/libc++abi/trunk/include",
+ "third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include",
+ ],
+ cpp_std: "c++20",
+}
+
+// GN: //base/third_party/dynamic_annotations:dynamic_annotations
+cc_library_static {
+ name: "cronet_aml_base_third_party_dynamic_annotations_dynamic_annotations",
+ srcs: [
+ "base/third_party/dynamic_annotations/dynamic_annotations.c",
+ ],
+ defaults: [
+ "cronet_aml_defaults",
+ ],
+ cflags: [
+ "-DANDROID",
+ "-DANDROID_NDK_VERSION_ROLL=r23_1",
+ "-DCR_CLANG_REVISION=\"llvmorg-16-init-8697-g60809cd2-1\"",
+ "-DCR_LIBCXX_REVISION=47b31179d10646029c260702650a25d24f555acc",
+ "-DDCHECK_ALWAYS_ON=1",
+ "-DDYNAMIC_ANNOTATIONS_ENABLED=1",
+ "-DHAVE_SYS_UIO_H",
+ "-D_DEBUG",
+ "-D_GNU_SOURCE",
+ "-D_LIBCPP_AVAILABILITY_CUSTOM_VERBOSE_ABORT_PROVIDED=1",
+ "-D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS",
+ "-D_LIBCPP_ENABLE_ASSERTIONS_DEFAULT=1",
+ "-D_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS",
+ ],
+ local_include_dirs: [
+ "./",
+ "buildtools/third_party/libc++/",
+ "buildtools/third_party/libc++/trunk/include",
+ "buildtools/third_party/libc++abi/trunk/include",
+ "third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include",
+ ],
+ cpp_std: "c++20",
+}
+
+// GN: //base:tracing_buildflags
+genrule {
+ name: "cronet_aml_base_tracing_buildflags",
+ cmd: "echo '--flags ENABLE_BASE_TRACING=\"false\" USE_PERFETTO_CLIENT_LIBRARY=\"false\" OPTIONAL_TRACE_EVENTS_ENABLED=\"false\"' | " +
+ "$(location build/write_buildflag_header.py) --output " +
+ "$(out) " +
+ "--rulename " +
+ "//base:tracing_buildflags " +
+ "--gen-dir " +
+ ". " +
+ "--definitions " +
+ "/dev/stdin",
+ out: [
+ "base/tracing_buildflags.h",
+ ],
+ tool_files: [
+ "build/write_buildflag_header.py",
+ ],
+}
+
+// GN: //build/android:build_config_gen
+genrule {
+ name: "cronet_aml_build_android_build_config_gen",
+ tools: [
+ "soong_zip",
+ ],
+ cmd: "echo " +
+ "\"package org.chromium.build;\n " +
+ "public class BuildConfig {\n " +
+ "public static boolean IS_MULTIDEX_ENABLED ;\n " +
+ "public static boolean ENABLE_ASSERTS = true;\n " +
+ "public static boolean IS_UBSAN ;\n " +
+ "public static boolean IS_CHROME_BRANDED ;\n " +
+ "public static int R_STRING_PRODUCT_VERSION ;\n " +
+ "public static int MIN_SDK_VERSION = 1;\n " +
+ "public static boolean BUNDLES_SUPPORTED ;\n " +
+ "public static boolean IS_INCREMENTAL_INSTALL ;\n " +
+ "public static boolean ISOLATED_SPLITS_ENABLED ;\n " +
+ "public static boolean IS_FOR_TEST ;\n " +
+ "}\n\" " +
+ "> $(genDir)/BuildConfig.java && " +
+ "$(location soong_zip) -o $(out) -srcjar -f $(genDir)/BuildConfig.java",
+ out: [
+ "build/android/build_config_gen.srcjar",
+ ],
+}
+
+// GN: //build/android:build_java__build_config_crbug_908819
+genrule {
+ name: "cronet_aml_build_android_build_java__build_config_crbug_908819",
+ cmd: "$(location build/android/gyp/write_build_config.py) --type " +
+ "java_library " +
+ " " +
+ " " +
+ "--deps-configs " +
+ "[\"$(location third_party/android_sdk/android_sdk_java.build_config.json)\"] " +
+ "--public-deps-configs " +
+ "[] " +
+ "--build-config " +
+ "$(genDir)/build/android/build_java.build_config.json " +
+ "--gn-target " +
+ "//build/android:build_java " +
+ "--device-jar-path " +
+ "$(location build/android/build_java.processed.jar) " +
+ "--host-jar-path " +
+ "$(location lib.java/build/android/build_java.jar) " +
+ "--unprocessed-jar-path " +
+ "$(location build/android/build_java.javac.jar) " +
+ "--interface-jar-path " +
+ "$(location build/android/build_java.turbine.jar) " +
+ "--dex-path " +
+ "obj/build/android/build_java.dex.jar " +
+ "--supports-android " +
+ "--java-sources-file " +
+ "gen/build/android/build_java.sources " +
+ "--bundled-srcjars " +
+ "[\"$(location build/android/build_config_gen.srcjar)\", \"$(location build/android/native_libraries_gen.srcjar)\"] " +
+ "--proguard-configs " +
+ "[$(location build/android/chromium_annotations.flags)]",
+ out: [
+ "build/android/build_java.build_config.json",
+ ],
+ tool_files: [
+ "build/android/chromium_annotations.flags",
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/android/gyp/util/resource_utils.py",
+ "build/android/gyp/write_build_config.py",
+ "build/gn_helpers.py",
+ "third_party/jinja2/__init__.py",
+ "third_party/jinja2/_compat.py",
+ "third_party/jinja2/_identifier.py",
+ "third_party/jinja2/bccache.py",
+ "third_party/jinja2/compiler.py",
+ "third_party/jinja2/defaults.py",
+ "third_party/jinja2/environment.py",
+ "third_party/jinja2/exceptions.py",
+ "third_party/jinja2/filters.py",
+ "third_party/jinja2/idtracking.py",
+ "third_party/jinja2/lexer.py",
+ "third_party/jinja2/loaders.py",
+ "third_party/jinja2/nodes.py",
+ "third_party/jinja2/optimizer.py",
+ "third_party/jinja2/parser.py",
+ "third_party/jinja2/runtime.py",
+ "third_party/jinja2/tests.py",
+ "third_party/jinja2/utils.py",
+ "third_party/jinja2/visitor.py",
+ "third_party/markupsafe/__init__.py",
+ "third_party/markupsafe/_compat.py",
+ "third_party/markupsafe/_native.py",
+ ],
+}
+
+// GN: //build/android:build_java__compile_java
+genrule {
+ name: "cronet_aml_build_android_build_java__compile_java",
+ srcs: [
+ "build/android/java/src/org/chromium/build/annotations/AlwaysInline.java",
+ "build/android/java/src/org/chromium/build/annotations/CheckDiscard.java",
+ "build/android/java/src/org/chromium/build/annotations/DoNotClassMerge.java",
+ "build/android/java/src/org/chromium/build/annotations/DoNotInline.java",
+ "build/android/java/src/org/chromium/build/annotations/IdentifierNameString.java",
+ "build/android/java/src/org/chromium/build/annotations/MainDex.java",
+ "build/android/java/src/org/chromium/build/annotations/MockedInTests.java",
+ "build/android/java/src/org/chromium/build/annotations/UsedByReflection.java",
+ ],
+ cmd: "$(location build/android/gyp/compile_java.py) --depfile " +
+ "gen/build/android/build_java__compile_java.d " +
+ "--generated-dir " +
+ "gen/build/android/build_java/generated_java " +
+ "--jar-path " +
+ "obj/build/android/build_java.javac.jar " +
+ "--java-srcjars " +
+ "[\"gen/build/android/build_config_gen.srcjar\", \"gen/build/android/native_libraries_gen.srcjar\", \"gen/build/android/build_java.generated.srcjar\"] " +
+ "--target-name " +
+ "//build/android:build_java__compile_java " +
+ "--header-jar " +
+ "obj/build/android/build_java.turbine.jar " +
+ "--classpath " +
+ "[\"obj/build/android/build_java.turbine.jar\"] " +
+ "--classpath " +
+ "@FileArg(gen/build/android/build_java.build_config.json:deps_info:javac_full_interface_classpath) " +
+ "--chromium-code " +
+ "1 " +
+ "--jar-info-exclude-globs " +
+ "[\"*/build/BuildConfig.class\", \"*/NativeLibraries.class\"] " +
+ "@gen/build/android/build_java.sources",
+ out: [
+ "//out/test/obj/build/android/build_java.javac.jar",
+ "//out/test/obj/build/android/build_java.javac.jar.info",
+ ],
+ tool_files: [
+ "build/android/gyp/compile_java.py",
+ "build/android/gyp/javac_output_processor.py",
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/android/gyp/util/jar_info_utils.py",
+ "build/android/gyp/util/md5_check.py",
+ "build/android/gyp/util/server_utils.py",
+ "build/android/list_java_targets.py",
+ "build/android/pylib/__init__.py",
+ "build/android/pylib/constants/__init__.py",
+ "build/gn_helpers.py",
+ "build/print_python_deps.py",
+ "out/test/gen/build/android/build_config_gen.srcjar",
+ "out/test/gen/build/android/build_java.build_config.json",
+ "out/test/gen/build/android/build_java.generated.srcjar",
+ "out/test/gen/build/android/build_java.sources",
+ "out/test/gen/build/android/native_libraries_gen.srcjar",
+ "out/test/obj/build/android/build_java.turbine.jar",
+ "third_party/catapult/devil/devil/__init__.py",
+ "third_party/catapult/devil/devil/android/__init__.py",
+ "third_party/catapult/devil/devil/android/constants/__init__.py",
+ "third_party/catapult/devil/devil/android/constants/chrome.py",
+ "third_party/catapult/devil/devil/android/sdk/__init__.py",
+ "third_party/catapult/devil/devil/android/sdk/keyevent.py",
+ "third_party/catapult/devil/devil/android/sdk/version_codes.py",
+ "third_party/catapult/devil/devil/constants/__init__.py",
+ "third_party/catapult/devil/devil/constants/exit_codes.py",
+ "third_party/colorama/src/colorama/__init__.py",
+ "third_party/colorama/src/colorama/ansi.py",
+ "third_party/colorama/src/colorama/ansitowin32.py",
+ "third_party/colorama/src/colorama/initialise.py",
+ "third_party/colorama/src/colorama/win32.py",
+ "third_party/colorama/src/colorama/winterm.py",
+ "tools/android/modularization/convenience/lookup_dep.py",
+ ],
+}
+
+// GN: //build/android:build_java__dex
+genrule {
+ name: "cronet_aml_build_android_build_java__dex",
+ cmd: "$(location build/android/gyp/dex.py) --depfile " +
+ "gen/build/android/build_java__dex.d " +
+ "--output " +
+ "obj/build/android/build_java.dex.jar " +
+ "--min-api " +
+ "19 " +
+ "--r8-jar-path " +
+ "../../third_party/r8/lib/r8.jar " +
+ "--custom-d8-jar-path " +
+ "../../third_party/r8/custom_d8.jar " +
+ "--incremental-dir " +
+ "obj/build/android/build_java__dex " +
+ "--library " +
+ "--class-inputs " +
+ "[\"obj/build/android/build_java.processed.jar\"] " +
+ "--desugar " +
+ "--desugar-jdk-libs-json " +
+ "../../third_party/r8/desugar_jdk_libs.json " +
+ "--show-desugar-default-interface-warnings " +
+ "--classpath " +
+ "obj/build/android/build_java.javac.jar " +
+ "--desugar-dependencies " +
+ "gen/build/android/build_java__dex.desugardeps " +
+ "--bootclasspath " +
+ "@FileArg(gen/build/android/build_java.build_config.json:android:sdk_jars) " +
+ "--classpath " +
+ "@FileArg(gen/build/android/build_java.build_config.json:deps_info:javac_full_interface_classpath) " +
+ "--force-enable-assertions",
+ out: [
+ "//out/test/obj/build/android/build_java.dex.jar",
+ ],
+ tool_files: [
+ "build/android/gyp/dex.py",
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/android/gyp/util/md5_check.py",
+ "build/android/gyp/util/zipalign.py",
+ "build/gn_helpers.py",
+ "build/print_python_deps.py",
+ "out/test/obj/build/android/build_java.javac.jar",
+ "out/test/obj/build/android/build_java.processed.jar",
+ "third_party/r8/custom_d8.jar",
+ "third_party/r8/d8/lib/r8.jar",
+ "third_party/r8/desugar_jdk_libs.json",
+ ],
+}
+
+// GN: //build/android:build_java__errorprone
+genrule {
+ name: "cronet_aml_build_android_build_java__errorprone",
+ srcs: [
+ "build/android/java/src/org/chromium/build/annotations/AlwaysInline.java",
+ "build/android/java/src/org/chromium/build/annotations/CheckDiscard.java",
+ "build/android/java/src/org/chromium/build/annotations/DoNotClassMerge.java",
+ "build/android/java/src/org/chromium/build/annotations/DoNotInline.java",
+ "build/android/java/src/org/chromium/build/annotations/IdentifierNameString.java",
+ "build/android/java/src/org/chromium/build/annotations/MainDex.java",
+ "build/android/java/src/org/chromium/build/annotations/MockedInTests.java",
+ "build/android/java/src/org/chromium/build/annotations/UsedByReflection.java",
+ ],
+ cmd: "$(location build/android/gyp/compile_java.py) --depfile " +
+ "gen/build/android/build_java__errorprone.d " +
+ "--generated-dir " +
+ "gen/build/android/build_java/generated_java " +
+ "--jar-path " +
+ "obj/build/android/build_java__errorprone.errorprone.stamp " +
+ "--java-srcjars " +
+ "[\"gen/build/android/build_java.generated.srcjar\"] " +
+ "--target-name " +
+ "//build/android:build_java__errorprone " +
+ "--header-jar " +
+ "obj/build/android/build_java.turbine.jar " +
+ "--classpath " +
+ "[\"obj/build/android/build_java.turbine.jar\"] " +
+ "--classpath " +
+ "@FileArg(gen/build/android/build_java.build_config.json:deps_info:javac_full_interface_classpath) " +
+ "--chromium-code " +
+ "1 " +
+ "--jar-info-exclude-globs " +
+ "[\"*/build/BuildConfig.class\", \"*/NativeLibraries.class\"] " +
+ "--processorpath " +
+ "@FileArg(gen/tools/android/errorprone_plugin/errorprone_plugin.build_config.json:deps_info:host_classpath) " +
+ "--enable-errorprone " +
+ "@gen/build/android/build_java.sources",
+ out: [
+ "//out/test/obj/build/android/build_java__errorprone.errorprone.stamp",
+ ],
+ tool_files: [
+ "build/android/gyp/compile_java.py",
+ "build/android/gyp/javac_output_processor.py",
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/android/gyp/util/jar_info_utils.py",
+ "build/android/gyp/util/md5_check.py",
+ "build/android/gyp/util/server_utils.py",
+ "build/android/list_java_targets.py",
+ "build/android/pylib/__init__.py",
+ "build/android/pylib/constants/__init__.py",
+ "build/gn_helpers.py",
+ "build/print_python_deps.py",
+ "out/test/gen/build/android/build_java.build_config.json",
+ "out/test/gen/build/android/build_java.generated.srcjar",
+ "out/test/gen/build/android/build_java.sources",
+ "out/test/obj/build/android/build_java.turbine.jar",
+ "third_party/catapult/devil/devil/__init__.py",
+ "third_party/catapult/devil/devil/android/__init__.py",
+ "third_party/catapult/devil/devil/android/constants/__init__.py",
+ "third_party/catapult/devil/devil/android/constants/chrome.py",
+ "third_party/catapult/devil/devil/android/sdk/__init__.py",
+ "third_party/catapult/devil/devil/android/sdk/keyevent.py",
+ "third_party/catapult/devil/devil/android/sdk/version_codes.py",
+ "third_party/catapult/devil/devil/constants/__init__.py",
+ "third_party/catapult/devil/devil/constants/exit_codes.py",
+ "third_party/colorama/src/colorama/__init__.py",
+ "third_party/colorama/src/colorama/ansi.py",
+ "third_party/colorama/src/colorama/ansitowin32.py",
+ "third_party/colorama/src/colorama/initialise.py",
+ "third_party/colorama/src/colorama/win32.py",
+ "third_party/colorama/src/colorama/winterm.py",
+ "tools/android/modularization/convenience/lookup_dep.py",
+ ],
+}
+
+// GN: //build/android:build_java__header
+genrule {
+ name: "cronet_aml_build_android_build_java__header",
+ srcs: [
+ "build/android/java/src/org/chromium/build/annotations/AlwaysInline.java",
+ "build/android/java/src/org/chromium/build/annotations/CheckDiscard.java",
+ "build/android/java/src/org/chromium/build/annotations/DoNotClassMerge.java",
+ "build/android/java/src/org/chromium/build/annotations/DoNotInline.java",
+ "build/android/java/src/org/chromium/build/annotations/IdentifierNameString.java",
+ "build/android/java/src/org/chromium/build/annotations/MainDex.java",
+ "build/android/java/src/org/chromium/build/annotations/MockedInTests.java",
+ "build/android/java/src/org/chromium/build/annotations/UsedByReflection.java",
+ ],
+ cmd: "$(location build/android/gyp/turbine.py) --depfile " +
+ "gen/build/android/build_java__header.d " +
+ "--generated-dir " +
+ "gen/build/android/build_java/generated_java " +
+ "--jar-path " +
+ "obj/build/android/build_java.turbine.jar " +
+ "--java-srcjars " +
+ "[\"gen/build/android/build_config_gen.srcjar\", \"gen/build/android/native_libraries_gen.srcjar\"] " +
+ "--target-name " +
+ "//build/android:build_java__header " +
+ "--classpath " +
+ "@FileArg(gen/build/android/build_java.build_config.json:javac:interface_classpath) " +
+ "--processorpath " +
+ "@FileArg(gen/build/android/build_java.build_config.json:javac:processor_classpath) " +
+ "--processors " +
+ "@FileArg(gen/build/android/build_java.build_config.json:javac:processor_classes) " +
+ "--turbine-jar-path " +
+ "../../third_party/turbine/turbine.jar " +
+ "--generated-jar-path " +
+ "gen/build/android/build_java.generated.srcjar " +
+ "--chromium-code " +
+ "1 " +
+ "--jar-info-exclude-globs " +
+ "[\"*/build/BuildConfig.class\", \"*/NativeLibraries.class\"] " +
+ "@gen/build/android/build_java.sources",
+ out: [
+ "//out/test/obj/build/android/build_java.turbine.jar",
+ "build/android/build_java.generated.srcjar",
+ ],
+ tool_files: [
+ "build/android/gyp/javac_output_processor.py",
+ "build/android/gyp/turbine.py",
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/android/list_java_targets.py",
+ "build/android/pylib/__init__.py",
+ "build/android/pylib/constants/__init__.py",
+ "build/gn_helpers.py",
+ "out/test/gen/build/android/build_config_gen.srcjar",
+ "out/test/gen/build/android/build_java.build_config.json",
+ "out/test/gen/build/android/build_java.sources",
+ "out/test/gen/build/android/native_libraries_gen.srcjar",
+ "third_party/catapult/devil/devil/__init__.py",
+ "third_party/catapult/devil/devil/android/__init__.py",
+ "third_party/catapult/devil/devil/android/constants/__init__.py",
+ "third_party/catapult/devil/devil/android/constants/chrome.py",
+ "third_party/catapult/devil/devil/android/sdk/__init__.py",
+ "third_party/catapult/devil/devil/android/sdk/keyevent.py",
+ "third_party/catapult/devil/devil/android/sdk/version_codes.py",
+ "third_party/catapult/devil/devil/constants/__init__.py",
+ "third_party/catapult/devil/devil/constants/exit_codes.py",
+ "third_party/colorama/src/colorama/__init__.py",
+ "third_party/colorama/src/colorama/ansi.py",
+ "third_party/colorama/src/colorama/ansitowin32.py",
+ "third_party/colorama/src/colorama/initialise.py",
+ "third_party/colorama/src/colorama/win32.py",
+ "third_party/colorama/src/colorama/winterm.py",
+ "third_party/turbine/turbine.jar",
+ "tools/android/modularization/convenience/lookup_dep.py",
+ ],
+}
+
+// GN: //build/android:build_java__host
+genrule {
+ name: "cronet_aml_build_android_build_java__host",
+ cmd: "$(location build/android/gyp/filter_zip.py) --input " +
+ "obj/build/android/build_java.javac.jar " +
+ "--output " +
+ "lib.java/build/android/build_java.jar " +
+ "--exclude-globs " +
+ "[\"*/build/BuildConfig.class\", \"*/NativeLibraries.class\"] " +
+ "--include-globs " +
+ "[]",
+ out: [
+ "//out/test/lib.java/build/android/build_java.jar",
+ ],
+ tool_files: [
+ "build/android/gyp/filter_zip.py",
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/gn_helpers.py",
+ "out/test/obj/build/android/build_java.javac.jar",
+ ],
+}
+
+// GN: //build/android:build_java__process_device
+genrule {
+ name: "cronet_aml_build_android_build_java__process_device",
+ cmd: "$(location build/android/gyp/filter_zip.py) --input " +
+ "obj/build/android/build_java.javac.jar " +
+ "--output " +
+ "obj/build/android/build_java.processed.jar " +
+ "--exclude-globs " +
+ "[\"*/build/BuildConfig.class\", \"*/NativeLibraries.class\"] " +
+ "--include-globs " +
+ "[]",
+ out: [
+ "//out/test/obj/build/android/build_java.processed.jar",
+ ],
+ tool_files: [
+ "build/android/gyp/filter_zip.py",
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/gn_helpers.py",
+ "out/test/obj/build/android/build_java.javac.jar",
+ ],
+}
+
+// GN: //build/android:build_java__validate
+genrule {
+ name: "cronet_aml_build_android_build_java__validate",
+ cmd: "$(location build/android/gyp/bytecode_processor.py) --target-name " +
+ "//build/android:build_java__validate " +
+ "--script " +
+ "bin/helper/bytecode_processor " +
+ "--gn-target " +
+ "//build/android:build_java " +
+ "--input-jar " +
+ "obj/build/android/build_java.javac.jar " +
+ "--stamp " +
+ "obj/build/android/build_java__validate.bytecode.stamp " +
+ "--direct-classpath-jars " +
+ "@FileArg(gen/build/android/build_java.build_config.json:javac:classpath) " +
+ "--full-classpath-jars " +
+ "@FileArg(gen/build/android/build_java.build_config.json:deps_info:javac_full_classpath) " +
+ "--full-classpath-gn-targets " +
+ "@FileArg(gen/build/android/build_java.build_config.json:deps_info:javac_full_classpath_targets)",
+ out: [
+ "//out/test/obj/build/android/build_java__validate.bytecode.stamp",
+ ],
+ tool_files: [
+ "build/android/gyp/bytecode_processor.py",
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/android/gyp/util/server_utils.py",
+ "build/gn_helpers.py",
+ "out/test/bin/helper/bytecode_processor",
+ "out/test/gen/build/android/build_java.build_config.json",
+ "out/test/obj/build/android/build_java.javac.jar",
+ ],
+}
+
+// GN: //build/android/bytecode:bytecode_processor__build_config_crbug_908819
+genrule {
+ name: "cronet_aml_build_android_bytecode_bytecode_processor__build_config_crbug_908819",
+ cmd: "$(location build/android/gyp/write_build_config.py) --type " +
+ "java_binary " +
+ " " +
+ " " +
+ "--deps-configs " +
+ "[\"$(location build/android/bytecode/bytecode_processor_java.build_config.json)\"] " +
+ "--public-deps-configs " +
+ "[] " +
+ "--build-config " +
+ "$(genDir)/build/android/bytecode/bytecode_processor.build_config.json " +
+ "--gn-target " +
+ "//build/android/bytecode:bytecode_processor " +
+ "--bundled-srcjars " +
+ "[] " +
+ "--main-class " +
+ "org.chromium.bytecode.ByteCodeProcessor",
+ out: [
+ "build/android/bytecode/bytecode_processor.build_config.json",
+ ],
+ tool_files: [
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/android/gyp/util/resource_utils.py",
+ "build/android/gyp/write_build_config.py",
+ "build/gn_helpers.py",
+ "third_party/jinja2/__init__.py",
+ "third_party/jinja2/_compat.py",
+ "third_party/jinja2/_identifier.py",
+ "third_party/jinja2/bccache.py",
+ "third_party/jinja2/compiler.py",
+ "third_party/jinja2/defaults.py",
+ "third_party/jinja2/environment.py",
+ "third_party/jinja2/exceptions.py",
+ "third_party/jinja2/filters.py",
+ "third_party/jinja2/idtracking.py",
+ "third_party/jinja2/lexer.py",
+ "third_party/jinja2/loaders.py",
+ "third_party/jinja2/nodes.py",
+ "third_party/jinja2/optimizer.py",
+ "third_party/jinja2/parser.py",
+ "third_party/jinja2/runtime.py",
+ "third_party/jinja2/tests.py",
+ "third_party/jinja2/utils.py",
+ "third_party/jinja2/visitor.py",
+ "third_party/markupsafe/__init__.py",
+ "third_party/markupsafe/_compat.py",
+ "third_party/markupsafe/_native.py",
+ ],
+}
+
+// GN: //build/android/bytecode:bytecode_processor__java_binary_script
+genrule {
+ name: "cronet_aml_build_android_bytecode_bytecode_processor__java_binary_script",
+ cmd: "$(location build/android/gyp/create_java_binary_script.py) --output " +
+ "bin/helper/bytecode_processor " +
+ "--main-class " +
+ "org.chromium.bytecode.ByteCodeProcessor " +
+ "--classpath " +
+ "@FileArg(gen/build/android/bytecode/bytecode_processor.build_config.json:deps_info:host_classpath) " +
+ "--noverify",
+ out: [
+ "//out/test/bin/helper/bytecode_processor",
+ ],
+ tool_files: [
+ "build/android/gyp/create_java_binary_script.py",
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/gn_helpers.py",
+ "out/test/gen/build/android/bytecode/bytecode_processor.build_config.json",
+ ],
+}
+
+// GN: //build/android/bytecode:bytecode_processor_java__build_config_crbug_908819
+genrule {
+ name: "cronet_aml_build_android_bytecode_bytecode_processor_java__build_config_crbug_908819",
+ cmd: "$(location build/android/gyp/write_build_config.py) --type " +
+ "java_library " +
+ " " +
+ " " +
+ "--deps-configs " +
+ "[\"$(location third_party/android_deps/org_ow2_asm_asm_java.build_config.json)\", \"$(location third_party/android_deps/org_ow2_asm_asm_util_java.build_config.json)\"] " +
+ "--public-deps-configs " +
+ "[] " +
+ "--build-config " +
+ "$(genDir)/build/android/bytecode/bytecode_processor_java.build_config.json " +
+ "--gn-target " +
+ "//build/android/bytecode:bytecode_processor_java " +
+ "--host-jar-path " +
+ "$(location lib.java/build/android/bytecode/bytecode_processor_java.jar) " +
+ "--unprocessed-jar-path " +
+ "$(location build/android/bytecode/bytecode_processor_java.javac.jar) " +
+ "--interface-jar-path " +
+ "$(location build/android/bytecode/bytecode_processor_java.turbine.jar) " +
+ "--java-sources-file " +
+ "gen/build/android/bytecode/bytecode_processor_java.sources " +
+ "--bundled-srcjars " +
+ "[]",
+ out: [
+ "build/android/bytecode/bytecode_processor_java.build_config.json",
+ ],
+ tool_files: [
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/android/gyp/util/resource_utils.py",
+ "build/android/gyp/write_build_config.py",
+ "build/gn_helpers.py",
+ "third_party/jinja2/__init__.py",
+ "third_party/jinja2/_compat.py",
+ "third_party/jinja2/_identifier.py",
+ "third_party/jinja2/bccache.py",
+ "third_party/jinja2/compiler.py",
+ "third_party/jinja2/defaults.py",
+ "third_party/jinja2/environment.py",
+ "third_party/jinja2/exceptions.py",
+ "third_party/jinja2/filters.py",
+ "third_party/jinja2/idtracking.py",
+ "third_party/jinja2/lexer.py",
+ "third_party/jinja2/loaders.py",
+ "third_party/jinja2/nodes.py",
+ "third_party/jinja2/optimizer.py",
+ "third_party/jinja2/parser.py",
+ "third_party/jinja2/runtime.py",
+ "third_party/jinja2/tests.py",
+ "third_party/jinja2/utils.py",
+ "third_party/jinja2/visitor.py",
+ "third_party/markupsafe/__init__.py",
+ "third_party/markupsafe/_compat.py",
+ "third_party/markupsafe/_native.py",
+ ],
+}
+
+// GN: //build/android/bytecode:bytecode_processor_java__compile_java
+genrule {
+ name: "cronet_aml_build_android_bytecode_bytecode_processor_java__compile_java",
+ srcs: [
+ "build/android/bytecode/java/org/chromium/bytecode/ByteCodeProcessor.java",
+ "build/android/bytecode/java/org/chromium/bytecode/ClassPathValidator.java",
+ "build/android/bytecode/java/org/chromium/bytecode/TypeUtils.java",
+ ],
+ cmd: "$(location build/android/gyp/compile_java.py) --depfile " +
+ "gen/build/android/bytecode/bytecode_processor_java__compile_java.d " +
+ "--generated-dir " +
+ "gen/build/android/bytecode/bytecode_processor_java/generated_java " +
+ "--jar-path " +
+ "obj/build/android/bytecode/bytecode_processor_java.javac.jar " +
+ "--java-srcjars " +
+ "[\"gen/build/android/bytecode/bytecode_processor_java.generated.srcjar\"] " +
+ "--target-name " +
+ "//build/android/bytecode:bytecode_processor_java__compile_java " +
+ "--header-jar " +
+ "obj/build/android/bytecode/bytecode_processor_java.turbine.jar " +
+ "--classpath " +
+ "[\"obj/build/android/bytecode/bytecode_processor_java.turbine.jar\"] " +
+ "--classpath " +
+ "@FileArg(gen/build/android/bytecode/bytecode_processor_java.build_config.json:deps_info:javac_full_interface_classpath) " +
+ "--chromium-code " +
+ "1 " +
+ "@gen/build/android/bytecode/bytecode_processor_java.sources",
+ out: [
+ "//out/test/obj/build/android/bytecode/bytecode_processor_java.javac.jar",
+ "//out/test/obj/build/android/bytecode/bytecode_processor_java.javac.jar.info",
+ ],
+ tool_files: [
+ "build/android/gyp/compile_java.py",
+ "build/android/gyp/javac_output_processor.py",
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/android/gyp/util/jar_info_utils.py",
+ "build/android/gyp/util/md5_check.py",
+ "build/android/gyp/util/server_utils.py",
+ "build/android/list_java_targets.py",
+ "build/android/pylib/__init__.py",
+ "build/android/pylib/constants/__init__.py",
+ "build/gn_helpers.py",
+ "build/print_python_deps.py",
+ "out/test/gen/build/android/bytecode/bytecode_processor_java.build_config.json",
+ "out/test/gen/build/android/bytecode/bytecode_processor_java.generated.srcjar",
+ "out/test/gen/build/android/bytecode/bytecode_processor_java.sources",
+ "out/test/obj/build/android/bytecode/bytecode_processor_java.turbine.jar",
+ "third_party/catapult/devil/devil/__init__.py",
+ "third_party/catapult/devil/devil/android/__init__.py",
+ "third_party/catapult/devil/devil/android/constants/__init__.py",
+ "third_party/catapult/devil/devil/android/constants/chrome.py",
+ "third_party/catapult/devil/devil/android/sdk/__init__.py",
+ "third_party/catapult/devil/devil/android/sdk/keyevent.py",
+ "third_party/catapult/devil/devil/android/sdk/version_codes.py",
+ "third_party/catapult/devil/devil/constants/__init__.py",
+ "third_party/catapult/devil/devil/constants/exit_codes.py",
+ "third_party/colorama/src/colorama/__init__.py",
+ "third_party/colorama/src/colorama/ansi.py",
+ "third_party/colorama/src/colorama/ansitowin32.py",
+ "third_party/colorama/src/colorama/initialise.py",
+ "third_party/colorama/src/colorama/win32.py",
+ "third_party/colorama/src/colorama/winterm.py",
+ "tools/android/modularization/convenience/lookup_dep.py",
+ ],
+}
+
+// GN: //build/android/bytecode:bytecode_processor_java__errorprone
+genrule {
+ name: "cronet_aml_build_android_bytecode_bytecode_processor_java__errorprone",
+ srcs: [
+ "build/android/bytecode/java/org/chromium/bytecode/ByteCodeProcessor.java",
+ "build/android/bytecode/java/org/chromium/bytecode/ClassPathValidator.java",
+ "build/android/bytecode/java/org/chromium/bytecode/TypeUtils.java",
+ ],
+ cmd: "$(location build/android/gyp/compile_java.py) --depfile " +
+ "gen/build/android/bytecode/bytecode_processor_java__errorprone.d " +
+ "--generated-dir " +
+ "gen/build/android/bytecode/bytecode_processor_java/generated_java " +
+ "--jar-path " +
+ "obj/build/android/bytecode/bytecode_processor_java__errorprone.errorprone.stamp " +
+ "--java-srcjars " +
+ "[\"gen/build/android/bytecode/bytecode_processor_java.generated.srcjar\"] " +
+ "--target-name " +
+ "//build/android/bytecode:bytecode_processor_java__errorprone " +
+ "--header-jar " +
+ "obj/build/android/bytecode/bytecode_processor_java.turbine.jar " +
+ "--classpath " +
+ "[\"obj/build/android/bytecode/bytecode_processor_java.turbine.jar\"] " +
+ "--classpath " +
+ "@FileArg(gen/build/android/bytecode/bytecode_processor_java.build_config.json:deps_info:javac_full_interface_classpath) " +
+ "--chromium-code " +
+ "1 " +
+ "--processorpath " +
+ "@FileArg(gen/tools/android/errorprone_plugin/errorprone_plugin.build_config.json:deps_info:host_classpath) " +
+ "--enable-errorprone " +
+ "@gen/build/android/bytecode/bytecode_processor_java.sources",
+ out: [
+ "//out/test/obj/build/android/bytecode/bytecode_processor_java__errorprone.errorprone.stamp",
+ ],
+ tool_files: [
+ "build/android/gyp/compile_java.py",
+ "build/android/gyp/javac_output_processor.py",
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/android/gyp/util/jar_info_utils.py",
+ "build/android/gyp/util/md5_check.py",
+ "build/android/gyp/util/server_utils.py",
+ "build/android/list_java_targets.py",
+ "build/android/pylib/__init__.py",
+ "build/android/pylib/constants/__init__.py",
+ "build/gn_helpers.py",
+ "build/print_python_deps.py",
+ "out/test/gen/build/android/bytecode/bytecode_processor_java.build_config.json",
+ "out/test/gen/build/android/bytecode/bytecode_processor_java.generated.srcjar",
+ "out/test/gen/build/android/bytecode/bytecode_processor_java.sources",
+ "out/test/obj/build/android/bytecode/bytecode_processor_java.turbine.jar",
+ "third_party/catapult/devil/devil/__init__.py",
+ "third_party/catapult/devil/devil/android/__init__.py",
+ "third_party/catapult/devil/devil/android/constants/__init__.py",
+ "third_party/catapult/devil/devil/android/constants/chrome.py",
+ "third_party/catapult/devil/devil/android/sdk/__init__.py",
+ "third_party/catapult/devil/devil/android/sdk/keyevent.py",
+ "third_party/catapult/devil/devil/android/sdk/version_codes.py",
+ "third_party/catapult/devil/devil/constants/__init__.py",
+ "third_party/catapult/devil/devil/constants/exit_codes.py",
+ "third_party/colorama/src/colorama/__init__.py",
+ "third_party/colorama/src/colorama/ansi.py",
+ "third_party/colorama/src/colorama/ansitowin32.py",
+ "third_party/colorama/src/colorama/initialise.py",
+ "third_party/colorama/src/colorama/win32.py",
+ "third_party/colorama/src/colorama/winterm.py",
+ "tools/android/modularization/convenience/lookup_dep.py",
+ ],
+}
+
+// GN: //build/android/bytecode:bytecode_processor_java__header
+genrule {
+ name: "cronet_aml_build_android_bytecode_bytecode_processor_java__header",
+ srcs: [
+ "build/android/bytecode/java/org/chromium/bytecode/ByteCodeProcessor.java",
+ "build/android/bytecode/java/org/chromium/bytecode/ClassPathValidator.java",
+ "build/android/bytecode/java/org/chromium/bytecode/TypeUtils.java",
+ ],
+ cmd: "$(location build/android/gyp/turbine.py) --depfile " +
+ "gen/build/android/bytecode/bytecode_processor_java__header.d " +
+ "--generated-dir " +
+ "gen/build/android/bytecode/bytecode_processor_java/generated_java " +
+ "--jar-path " +
+ "obj/build/android/bytecode/bytecode_processor_java.turbine.jar " +
+ "--java-srcjars " +
+ "[] " +
+ "--target-name " +
+ "//build/android/bytecode:bytecode_processor_java__header " +
+ "--classpath " +
+ "@FileArg(gen/build/android/bytecode/bytecode_processor_java.build_config.json:javac:interface_classpath) " +
+ "--processorpath " +
+ "@FileArg(gen/build/android/bytecode/bytecode_processor_java.build_config.json:javac:processor_classpath) " +
+ "--processors " +
+ "@FileArg(gen/build/android/bytecode/bytecode_processor_java.build_config.json:javac:processor_classes) " +
+ "--turbine-jar-path " +
+ "../../third_party/turbine/turbine.jar " +
+ "--generated-jar-path " +
+ "gen/build/android/bytecode/bytecode_processor_java.generated.srcjar " +
+ "--chromium-code " +
+ "1 " +
+ "@gen/build/android/bytecode/bytecode_processor_java.sources",
+ out: [
+ "//out/test/obj/build/android/bytecode/bytecode_processor_java.turbine.jar",
+ "build/android/bytecode/bytecode_processor_java.generated.srcjar",
+ ],
+ tool_files: [
+ "build/android/gyp/javac_output_processor.py",
+ "build/android/gyp/turbine.py",
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/android/list_java_targets.py",
+ "build/android/pylib/__init__.py",
+ "build/android/pylib/constants/__init__.py",
+ "build/gn_helpers.py",
+ "out/test/gen/build/android/bytecode/bytecode_processor_java.build_config.json",
+ "out/test/gen/build/android/bytecode/bytecode_processor_java.sources",
+ "third_party/catapult/devil/devil/__init__.py",
+ "third_party/catapult/devil/devil/android/__init__.py",
+ "third_party/catapult/devil/devil/android/constants/__init__.py",
+ "third_party/catapult/devil/devil/android/constants/chrome.py",
+ "third_party/catapult/devil/devil/android/sdk/__init__.py",
+ "third_party/catapult/devil/devil/android/sdk/keyevent.py",
+ "third_party/catapult/devil/devil/android/sdk/version_codes.py",
+ "third_party/catapult/devil/devil/constants/__init__.py",
+ "third_party/catapult/devil/devil/constants/exit_codes.py",
+ "third_party/colorama/src/colorama/__init__.py",
+ "third_party/colorama/src/colorama/ansi.py",
+ "third_party/colorama/src/colorama/ansitowin32.py",
+ "third_party/colorama/src/colorama/initialise.py",
+ "third_party/colorama/src/colorama/win32.py",
+ "third_party/colorama/src/colorama/winterm.py",
+ "third_party/turbine/turbine.jar",
+ "tools/android/modularization/convenience/lookup_dep.py",
+ ],
+}
+
+// GN: //build/android/bytecode:bytecode_processor_java__host
+genrule {
+ name: "cronet_aml_build_android_bytecode_bytecode_processor_java__host",
+ cmd: "$(location build/android/gyp/filter_zip.py) --input " +
+ "obj/build/android/bytecode/bytecode_processor_java.javac.jar " +
+ "--output " +
+ "lib.java/build/android/bytecode/bytecode_processor_java.jar " +
+ "--exclude-globs " +
+ "[] " +
+ "--include-globs " +
+ "[]",
+ out: [
+ "//out/test/lib.java/build/android/bytecode/bytecode_processor_java.jar",
+ ],
+ tool_files: [
+ "build/android/gyp/filter_zip.py",
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/gn_helpers.py",
+ "out/test/obj/build/android/bytecode/bytecode_processor_java.javac.jar",
+ ],
+}
+
+// GN: //build/android:native_libraries_gen
+genrule {
+ name: "cronet_aml_build_android_native_libraries_gen",
+ cmd: "$(location build/android/gyp/write_native_libraries_java.py) --output " +
+ "$(out) " +
+ "--cpu-family " +
+ "CPU_FAMILY_X86",
+ out: [
+ "build/android/native_libraries_gen.srcjar",
+ ],
+ tool_files: [
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/android/gyp/write_native_libraries_java.py",
+ "build/gn_helpers.py",
+ ],
+}
+
+// GN: //build:branding_buildflags
+genrule {
+ name: "cronet_aml_build_branding_buildflags",
+ cmd: "echo '--flags CHROMIUM_BRANDING=\"1\" GOOGLE_CHROME_BRANDING=\"0\"' | " +
+ "$(location build/write_buildflag_header.py) --output " +
+ "$(out) " +
+ "--rulename " +
+ "//build:branding_buildflags " +
+ "--gen-dir " +
+ ". " +
+ "--definitions " +
+ "/dev/stdin",
+ out: [
+ "build/branding_buildflags.h",
+ ],
+ tool_files: [
+ "build/write_buildflag_header.py",
+ ],
+}
+
+// GN: //build:buildflag_header_h
+filegroup {
+ name: "cronet_aml_build_buildflag_header_h",
+}
+
+// GN: //build:chromecast_buildflags
+genrule {
+ name: "cronet_aml_build_chromecast_buildflags",
+ cmd: "echo '--flags IS_CASTOS=\"false\" IS_CAST_ANDROID=\"false\" ENABLE_CAST_RECEIVER=\"false\" IS_CHROMECAST=\"false\"' | " +
+ "$(location build/write_buildflag_header.py) --output " +
+ "$(out) " +
+ "--rulename " +
+ "//build:chromecast_buildflags " +
+ "--gen-dir " +
+ ". " +
+ "--definitions " +
+ "/dev/stdin",
+ out: [
+ "build/chromecast_buildflags.h",
+ ],
+ tool_files: [
+ "build/write_buildflag_header.py",
+ ],
+}
+
+// GN: //build:chromeos_buildflags
+genrule {
+ name: "cronet_aml_build_chromeos_buildflags",
+ cmd: "echo '--flags IS_CHROMEOS_DEVICE=\"false\" IS_CHROMEOS_LACROS=\"false\" IS_CHROMEOS_ASH=\"false\" IS_CHROMEOS_WITH_HW_DETAILS=\"false\" IS_REVEN=\"false\"' | " +
+ "$(location build/write_buildflag_header.py) --output " +
+ "$(out) " +
+ "--rulename " +
+ "//build:chromeos_buildflags " +
+ "--gen-dir " +
+ ". " +
+ "--definitions " +
+ "/dev/stdin",
+ out: [
+ "build/chromeos_buildflags.h",
+ ],
+ tool_files: [
+ "build/write_buildflag_header.py",
+ ],
+}
+
+// GN: //build/config/compiler:compiler_buildflags
+genrule {
+ name: "cronet_aml_build_config_compiler_compiler_buildflags",
+ cmd: "echo '--flags CLANG_PGO=\"0\" SYMBOL_LEVEL=\"1\"' | " +
+ "$(location build/write_buildflag_header.py) --output " +
+ "$(out) " +
+ "--rulename " +
+ "//build/config/compiler:compiler_buildflags " +
+ "--gen-dir " +
+ ". " +
+ "--definitions " +
+ "/dev/stdin",
+ out: [
+ "build/config/compiler/compiler_buildflags.h",
+ ],
+ tool_files: [
+ "build/write_buildflag_header.py",
+ ],
+}
+
+// GN: //buildtools/third_party/libc++:libc++
+filegroup {
+ name: "cronet_aml_buildtools_third_party_libc___libc__",
+}
+
+// GN: //buildtools/third_party/libc++abi:libc++abi
+filegroup {
+ name: "cronet_aml_buildtools_third_party_libc__abi_libc__abi",
+}
+
+// GN: //crypto:buildflags
+genrule {
+ name: "cronet_aml_crypto_buildflags",
+ cmd: "echo '--flags USE_NSS_CERTS=\"false\"' | " +
+ "$(location build/write_buildflag_header.py) --output " +
+ "$(out) " +
+ "--rulename " +
+ "//crypto:buildflags " +
+ "--gen-dir " +
+ ". " +
+ "--definitions " +
+ "/dev/stdin",
+ out: [
+ "crypto/crypto_buildflags.h",
+ ],
+ tool_files: [
+ "build/write_buildflag_header.py",
+ ],
+}
+
+// GN: //crypto:crypto
+cc_library_static {
+ name: "cronet_aml_crypto_crypto",
+ srcs: [
+ "crypto/aead.cc",
+ "crypto/ec_private_key.cc",
+ "crypto/ec_signature_creator.cc",
+ "crypto/ec_signature_creator_impl.cc",
+ "crypto/encryptor.cc",
+ "crypto/hkdf.cc",
+ "crypto/hmac.cc",
+ "crypto/openssl_util.cc",
+ "crypto/p224_spake.cc",
+ "crypto/random.cc",
+ "crypto/rsa_private_key.cc",
+ "crypto/secure_hash.cc",
+ "crypto/secure_util.cc",
+ "crypto/sha2.cc",
+ "crypto/signature_creator.cc",
+ "crypto/signature_verifier.cc",
+ "crypto/symmetric_key.cc",
+ "crypto/unexportable_key.cc",
+ "crypto/unexportable_key_metrics.cc",
+ ],
+ shared_libs: [
+ "libandroid",
+ "liblog",
+ ],
+ static_libs: [
+ "cronet_aml_base_base",
+ "cronet_aml_base_third_party_dynamic_annotations_dynamic_annotations",
+ "cronet_aml_third_party_boringssl_boringssl",
+ ],
+ generated_headers: [
+ "cronet_aml_crypto_buildflags",
+ ],
+ export_generated_headers: [
+ "cronet_aml_crypto_buildflags",
+ ],
+ defaults: [
+ "cronet_aml_defaults",
+ ],
+ cflags: [
+ "-DANDROID",
+ "-DANDROID_NDK_VERSION_ROLL=r23_1",
+ "-DCRYPTO_IMPLEMENTATION",
+ "-DCR_CLANG_REVISION=\"llvmorg-16-init-8697-g60809cd2-1\"",
+ "-DCR_LIBCXX_REVISION=47b31179d10646029c260702650a25d24f555acc",
+ "-DDCHECK_ALWAYS_ON=1",
+ "-DDYNAMIC_ANNOTATIONS_ENABLED=1",
+ "-DHAVE_SYS_UIO_H",
+ "-D_DEBUG",
+ "-D_GNU_SOURCE",
+ "-D_LIBCPP_AVAILABILITY_CUSTOM_VERBOSE_ABORT_PROVIDED=1",
+ "-D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS",
+ "-D_LIBCPP_ENABLE_ASSERTIONS_DEFAULT=1",
+ "-D_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS",
+ "-D__STDC_CONSTANT_MACROS",
+ "-D__STDC_FORMAT_MACROS",
+ ],
+ local_include_dirs: [
+ "./",
+ "buildtools/third_party/libc++/",
+ "buildtools/third_party/libc++/trunk/include",
+ "buildtools/third_party/libc++abi/trunk/include",
+ "third_party/abseil-cpp/",
+ "third_party/boringssl/src/include/",
+ "third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include",
+ ],
+ cpp_std: "c++20",
+}
+
+// GN: //gn:default_deps
+cc_defaults {
+ name: "cronet_aml_defaults",
+ cflags: [
+ "-O2",
+ "-Wno-error=return-type",
+ "-Wno-missing-field-initializers",
+ "-Wno-non-virtual-dtor",
+ "-Wno-sign-compare",
+ "-Wno-sign-promo",
+ "-Wno-unused-parameter",
+ "-fvisibility=hidden",
+ ],
+ stl: "none",
+}
+
+// GN: //ipc:param_traits
+filegroup {
+ name: "cronet_aml_ipc_param_traits",
+}
+
+// GN: //net/base/registry_controlled_domains:registry_controlled_domains
+genrule {
+ name: "cronet_aml_net_base_registry_controlled_domains_registry_controlled_domains",
+ cmd: "$(location net/tools/dafsa/make_dafsa.py) --reverse " +
+ "$(location net/base/registry_controlled_domains/effective_tld_names.gperf) " +
+ "$(location net/base/registry_controlled_domains/effective_tld_names-reversed-inc.cc) " +
+ "&& python3 $(location net/tools/dafsa/make_dafsa.py) " +
+ "--reverse " +
+ "$(location net/base/registry_controlled_domains/effective_tld_names_unittest1.gperf) " +
+ "$(location net/base/registry_controlled_domains/effective_tld_names_unittest1-reversed-inc.cc) " +
+ "&& python3 $(location net/tools/dafsa/make_dafsa.py) " +
+ "--reverse " +
+ "$(location net/base/registry_controlled_domains/effective_tld_names_unittest2.gperf) " +
+ "$(location net/base/registry_controlled_domains/effective_tld_names_unittest2-reversed-inc.cc) " +
+ "&& python3 $(location net/tools/dafsa/make_dafsa.py) " +
+ "--reverse " +
+ "$(location net/base/registry_controlled_domains/effective_tld_names_unittest3.gperf) " +
+ "$(location net/base/registry_controlled_domains/effective_tld_names_unittest3-reversed-inc.cc) " +
+ "&& python3 $(location net/tools/dafsa/make_dafsa.py) " +
+ "--reverse " +
+ "$(location net/base/registry_controlled_domains/effective_tld_names_unittest4.gperf) " +
+ "$(location net/base/registry_controlled_domains/effective_tld_names_unittest4-reversed-inc.cc) " +
+ "&& python3 $(location net/tools/dafsa/make_dafsa.py) " +
+ "--reverse " +
+ "$(location net/base/registry_controlled_domains/effective_tld_names_unittest5.gperf) " +
+ "$(location net/base/registry_controlled_domains/effective_tld_names_unittest5-reversed-inc.cc) " +
+ "&& python3 $(location net/tools/dafsa/make_dafsa.py) " +
+ "--reverse " +
+ "$(location net/base/registry_controlled_domains/effective_tld_names_unittest6.gperf) " +
+ "$(location net/base/registry_controlled_domains/effective_tld_names_unittest6-reversed-inc.cc)",
+ out: [
+ "net/base/registry_controlled_domains/effective_tld_names-reversed-inc.cc",
+ "net/base/registry_controlled_domains/effective_tld_names_unittest1-reversed-inc.cc",
+ "net/base/registry_controlled_domains/effective_tld_names_unittest2-reversed-inc.cc",
+ "net/base/registry_controlled_domains/effective_tld_names_unittest3-reversed-inc.cc",
+ "net/base/registry_controlled_domains/effective_tld_names_unittest4-reversed-inc.cc",
+ "net/base/registry_controlled_domains/effective_tld_names_unittest5-reversed-inc.cc",
+ "net/base/registry_controlled_domains/effective_tld_names_unittest6-reversed-inc.cc",
+ ],
+ tool_files: [
+ "net/base/registry_controlled_domains/effective_tld_names.gperf",
+ "net/base/registry_controlled_domains/effective_tld_names_unittest1.gperf",
+ "net/base/registry_controlled_domains/effective_tld_names_unittest2.gperf",
+ "net/base/registry_controlled_domains/effective_tld_names_unittest3.gperf",
+ "net/base/registry_controlled_domains/effective_tld_names_unittest4.gperf",
+ "net/base/registry_controlled_domains/effective_tld_names_unittest5.gperf",
+ "net/base/registry_controlled_domains/effective_tld_names_unittest6.gperf",
+ "net/tools/dafsa/make_dafsa.py",
+ ],
+}
+
+// GN: //net:buildflags
+genrule {
+ name: "cronet_aml_net_buildflags",
+ cmd: "echo '--flags POSIX_BYPASS_MMAP=\"true\" DISABLE_FILE_SUPPORT=\"true\" ENABLE_MDNS=\"false\" ENABLE_REPORTING=\"true\" ENABLE_WEBSOCKETS=\"false\" INCLUDE_TRANSPORT_SECURITY_STATE_PRELOAD_LIST=\"false\" USE_KERBEROS=\"true\" USE_EXTERNAL_GSSAPI=\"false\" TRIAL_COMPARISON_CERT_VERIFIER_SUPPORTED=\"false\" CHROME_ROOT_STORE_SUPPORTED=\"false\"' | " +
+ "$(location build/write_buildflag_header.py) --output " +
+ "$(out) " +
+ "--rulename " +
+ "//net:buildflags " +
+ "--gen-dir " +
+ ". " +
+ "--definitions " +
+ "/dev/stdin",
+ out: [
+ "net/net_buildflags.h",
+ ],
+ tool_files: [
+ "build/write_buildflag_header.py",
+ ],
+}
+
+// GN: //net/cert:root_store_proto_full
+cc_library_static {
+ name: "cronet_aml_net_cert_root_store_proto_full",
+ srcs: [
+ "out/test/clang_x64/gen/net/cert/root_store_proto_full/root_store.pb.cc",
+ ],
+ static_libs: [
+ "cronet_aml_third_party_protobuf_protobuf_full",
+ ],
+ defaults: [
+ "cronet_aml_defaults",
+ ],
+ cflags: [
+ "-DCR_CLANG_REVISION=\"llvmorg-16-init-8697-g60809cd2-1\"",
+ "-DCR_LIBCXX_REVISION=47b31179d10646029c260702650a25d24f555acc",
+ "-DCR_SYSROOT_KEY=20220331T153654Z-0",
+ "-DDCHECK_ALWAYS_ON=1",
+ "-DDYNAMIC_ANNOTATIONS_ENABLED=1",
+ "-DGOOGLE_PROTOBUF_INTERNAL_DONATE_STEAL_INLINE=0",
+ "-DGOOGLE_PROTOBUF_NO_RTTI",
+ "-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER",
+ "-DHAVE_PTHREAD",
+ "-DUSE_AURA=1",
+ "-DUSE_OZONE=1",
+ "-DUSE_UDEV",
+ "-D_DEBUG",
+ "-D_FILE_OFFSET_BITS=64",
+ "-D_GNU_SOURCE",
+ "-D_LARGEFILE64_SOURCE",
+ "-D_LARGEFILE_SOURCE",
+ "-D_LIBCPP_AVAILABILITY_CUSTOM_VERBOSE_ABORT_PROVIDED=1",
+ "-D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS",
+ "-D_LIBCPP_ENABLE_ASSERTIONS_DEFAULT=1",
+ "-D_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS",
+ "-D__STDC_CONSTANT_MACROS",
+ "-D__STDC_FORMAT_MACROS",
+ ],
+ local_include_dirs: [
+ "./",
+ "buildtools/third_party/libc++/",
+ "buildtools/third_party/libc++/trunk/include",
+ "buildtools/third_party/libc++abi/trunk/include",
+ "third_party/protobuf/src/",
+ "build/linux/debian_bullseye_amd64-sysroot/usr/include",
+ ],
+ cpp_std: "c++20",
+}
+
+// GN: //net/cert:root_store_proto_full_gen
+genrule {
+ name: "cronet_aml_net_cert_root_store_proto_full_gen",
+ srcs: [
+ "net/cert/root_store.proto",
+ ],
+ tools: [
+ "aprotoc",
+ ],
+ cmd: "$(location tools/protoc_wrapper/protoc_wrapper.py) root_store.proto " +
+ "--protoc " +
+ "$(location aprotoc) " +
+ "--proto-in-dir " +
+ "`dirname $(location net/cert/root_store.proto)` " +
+ "--cc-out-dir " +
+ "clang_x64/gen/net/cert/root_store_proto_full/ " +
+ "--py-out-dir " +
+ "$(genDir)/clang_x64/pyproto/net/cert/root_store_proto_full/",
+ out: [
+ "clang_x64/pyproto/net/cert/root_store_proto_full/root_store_pb2.py",
+ "net/cert/root_store_proto_full/root_store.pb.cc",
+ "net/cert/root_store_proto_full/root_store.pb.h",
+ ],
+ tool_files: [
+ "tools/protoc_wrapper/protoc_wrapper.py",
+ ],
+}
+
+// GN: //net:constants
+filegroup {
+ name: "cronet_aml_net_constants",
+}
+
+// GN: //net/data/ssl/chrome_root_store:gen_root_store_inc
+genrule {
+ name: "cronet_aml_net_data_ssl_chrome_root_store_gen_root_store_inc",
+ cmd: "$(location build/gn_run_binary.py) clang_x64/root_store_tool " +
+ "--root-store " +
+ "../../net/data/ssl/chrome_root_store/root_store.textproto " +
+ "--certs " +
+ "../../net/data/ssl/chrome_root_store/root_store.certs " +
+ "--write-cpp-root-store " +
+ "gen/net/data/ssl/chrome_root_store/chrome-root-store-inc.cc " +
+ "--write-cpp-ev-roots " +
+ "gen/net/data/ssl/chrome_root_store/chrome-ev-roots-inc.cc",
+ out: [
+ "net/data/ssl/chrome_root_store/chrome-ev-roots-inc.cc",
+ "net/data/ssl/chrome_root_store/chrome-root-store-inc.cc",
+ ],
+ tool_files: [
+ "build/gn_run_binary.py",
+ "net/data/ssl/chrome_root_store/root_store.certs",
+ "net/data/ssl/chrome_root_store/root_store.textproto",
+ ],
+}
+
+// GN: //net/dns:dns
+filegroup {
+ name: "cronet_aml_net_dns_dns",
+ srcs: [
+ "net/dns/address_info.cc",
+ "net/dns/address_sorter_posix.cc",
+ "net/dns/context_host_resolver.cc",
+ "net/dns/dns_alias_utility.cc",
+ "net/dns/dns_client.cc",
+ "net/dns/dns_config.cc",
+ "net/dns/dns_config_service.cc",
+ "net/dns/dns_config_service_android.cc",
+ "net/dns/dns_hosts.cc",
+ "net/dns/dns_query.cc",
+ "net/dns/dns_reloader.cc",
+ "net/dns/dns_response.cc",
+ "net/dns/dns_response_result_extractor.cc",
+ "net/dns/dns_server_iterator.cc",
+ "net/dns/dns_session.cc",
+ "net/dns/dns_transaction.cc",
+ "net/dns/dns_udp_tracker.cc",
+ "net/dns/dns_util.cc",
+ "net/dns/host_cache.cc",
+ "net/dns/host_resolver.cc",
+ "net/dns/host_resolver_manager.cc",
+ "net/dns/host_resolver_mdns_listener_impl.cc",
+ "net/dns/host_resolver_mdns_task.cc",
+ "net/dns/host_resolver_nat64_task.cc",
+ "net/dns/host_resolver_proc.cc",
+ "net/dns/host_resolver_system_task.cc",
+ "net/dns/https_record_rdata.cc",
+ "net/dns/httpssvc_metrics.cc",
+ "net/dns/mapped_host_resolver.cc",
+ "net/dns/nsswitch_reader.cc",
+ "net/dns/opt_record_rdata.cc",
+ "net/dns/record_parsed.cc",
+ "net/dns/record_rdata.cc",
+ "net/dns/resolve_context.cc",
+ "net/dns/serial_worker.cc",
+ "net/dns/system_dns_config_change_notifier.cc",
+ "net/dns/test_dns_config_service.cc",
+ ],
+}
+
+// GN: //net/dns:dns_client
+filegroup {
+ name: "cronet_aml_net_dns_dns_client",
+}
+
+// GN: //net/dns:host_resolver
+filegroup {
+ name: "cronet_aml_net_dns_host_resolver",
+}
+
+// GN: //net/dns:host_resolver_manager
+filegroup {
+ name: "cronet_aml_net_dns_host_resolver_manager",
+}
+
+// GN: //net/dns:mdns_client
+filegroup {
+ name: "cronet_aml_net_dns_mdns_client",
+}
+
+// GN: //net/dns/public:public
+filegroup {
+ name: "cronet_aml_net_dns_public_public",
+ srcs: [
+ "net/dns/public/dns_config_overrides.cc",
+ "net/dns/public/dns_over_https_config.cc",
+ "net/dns/public/dns_over_https_server_config.cc",
+ "net/dns/public/dns_query_type.cc",
+ "net/dns/public/doh_provider_entry.cc",
+ "net/dns/public/host_resolver_results.cc",
+ "net/dns/public/resolve_error_info.cc",
+ "net/dns/public/util.cc",
+ ],
+}
+
+// GN: //net/http:transport_security_state_generated_files
+filegroup {
+ name: "cronet_aml_net_http_transport_security_state_generated_files",
+ srcs: [
+ "net/http/transport_security_state.cc",
+ ],
+}
+
+// GN: //net:ios_cronet_buildflags
+genrule {
+ name: "cronet_aml_net_ios_cronet_buildflags",
+ cmd: "echo '--flags CRONET_BUILD=\"false\"' | " +
+ "$(location build/write_buildflag_header.py) --output " +
+ "$(out) " +
+ "--rulename " +
+ "//net:ios_cronet_buildflags " +
+ "--gen-dir " +
+ ". " +
+ "--definitions " +
+ "/dev/stdin",
+ out: [
+ "net/socket/ios_cronet_buildflags.h",
+ ],
+ tool_files: [
+ "build/write_buildflag_header.py",
+ ],
+}
+
+// GN: //net:isolation_info_proto
+cc_library_static {
+ name: "cronet_aml_net_isolation_info_proto",
+ srcs: [
+ "out/test/gen/net/base/isolation_info.pb.cc",
+ ],
+ shared_libs: [
+ "liblog",
+ ],
+ static_libs: [
+ "cronet_aml_third_party_protobuf_protobuf_lite",
+ ],
+ defaults: [
+ "cronet_aml_defaults",
+ ],
+ cflags: [
+ "-DANDROID",
+ "-DANDROID_NDK_VERSION_ROLL=r23_1",
+ "-DCR_CLANG_REVISION=\"llvmorg-16-init-8697-g60809cd2-1\"",
+ "-DCR_LIBCXX_REVISION=47b31179d10646029c260702650a25d24f555acc",
+ "-DDCHECK_ALWAYS_ON=1",
+ "-DDYNAMIC_ANNOTATIONS_ENABLED=1",
+ "-DGOOGLE_PROTOBUF_INTERNAL_DONATE_STEAL_INLINE=0",
+ "-DGOOGLE_PROTOBUF_NO_RTTI",
+ "-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER",
+ "-DHAVE_PTHREAD",
+ "-DHAVE_SYS_UIO_H",
+ "-D_DEBUG",
+ "-D_GNU_SOURCE",
+ "-D_LIBCPP_AVAILABILITY_CUSTOM_VERBOSE_ABORT_PROVIDED=1",
+ "-D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS",
+ "-D_LIBCPP_ENABLE_ASSERTIONS_DEFAULT=1",
+ "-D_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS",
+ "-D__STDC_CONSTANT_MACROS",
+ "-D__STDC_FORMAT_MACROS",
+ ],
+ local_include_dirs: [
+ "./",
+ "buildtools/third_party/libc++/",
+ "buildtools/third_party/libc++/trunk/include",
+ "buildtools/third_party/libc++abi/trunk/include",
+ "third_party/protobuf/src/",
+ "third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include",
+ ],
+ cpp_std: "c++20",
+}
+
+// GN: //net:isolation_info_proto_gen
+genrule {
+ name: "cronet_aml_net_isolation_info_proto_gen",
+ srcs: [
+ "net/base/isolation_info.proto",
+ ],
+ tools: [
+ "aprotoc",
+ ],
+ cmd: "$(location tools/protoc_wrapper/protoc_wrapper.py) isolation_info.proto " +
+ "--protoc " +
+ "$(location aprotoc) " +
+ "--proto-in-dir " +
+ "`dirname $(location net/base/isolation_info.proto)` " +
+ "--cc-out-dir " +
+ "$(genDir)/net/base " +
+ "--py-out-dir " +
+ "$(genDir)/pyproto/net/base",
+ out: [
+ "net/base/isolation_info.pb.cc",
+ "net/base/isolation_info.pb.h",
+ "pyproto/net/base/isolation_info_pb2.py",
+ ],
+ tool_files: [
+ "tools/protoc_wrapper/protoc_wrapper.py",
+ ],
+}
+
+// GN: //net:net
+cc_library_static {
+ name: "cronet_aml_net_net",
+ srcs: [
+ ":cronet_aml_net_constants",
+ ":cronet_aml_net_dns_dns",
+ ":cronet_aml_net_dns_dns_client",
+ ":cronet_aml_net_dns_host_resolver",
+ ":cronet_aml_net_dns_host_resolver_manager",
+ ":cronet_aml_net_dns_mdns_client",
+ ":cronet_aml_net_dns_public_public",
+ ":cronet_aml_net_http_transport_security_state_generated_files",
+ ":cronet_aml_net_net_deps",
+ ":cronet_aml_net_net_export_header",
+ ":cronet_aml_net_net_public_deps",
+ ":cronet_aml_net_net_resources",
+ ":cronet_aml_net_traffic_annotation_traffic_annotation",
+ "net/android/android_http_util.cc",
+ "net/android/cert_verify_result_android.cc",
+ "net/android/gurl_utils.cc",
+ "net/android/http_auth_negotiate_android.cc",
+ "net/android/keystore.cc",
+ "net/android/network_change_notifier_android.cc",
+ "net/android/network_change_notifier_delegate_android.cc",
+ "net/android/network_change_notifier_factory_android.cc",
+ "net/android/network_library.cc",
+ "net/android/radio_activity_tracker.cc",
+ "net/android/traffic_stats.cc",
+ "net/base/address_family.cc",
+ "net/base/address_list.cc",
+ "net/base/address_tracker_linux.cc",
+ "net/base/auth.cc",
+ "net/base/backoff_entry.cc",
+ "net/base/backoff_entry_serializer.cc",
+ "net/base/cache_metrics.cc",
+ "net/base/chunked_upload_data_stream.cc",
+ "net/base/connection_endpoint_metadata.cc",
+ "net/base/data_url.cc",
+ "net/base/datagram_buffer.cc",
+ "net/base/elements_upload_data_stream.cc",
+ "net/base/features.cc",
+ "net/base/file_stream.cc",
+ "net/base/file_stream_context.cc",
+ "net/base/file_stream_context_posix.cc",
+ "net/base/filename_util.cc",
+ "net/base/filename_util_internal.cc",
+ "net/base/hash_value.cc",
+ "net/base/hex_utils.cc",
+ "net/base/host_mapping_rules.cc",
+ "net/base/host_port_pair.cc",
+ "net/base/io_buffer.cc",
+ "net/base/ip_address.cc",
+ "net/base/ip_endpoint.cc",
+ "net/base/isolation_info.cc",
+ "net/base/load_timing_info.cc",
+ "net/base/logging_network_change_observer.cc",
+ "net/base/lookup_string_in_fixed_set.cc",
+ "net/base/mime_sniffer.cc",
+ "net/base/mime_util.cc",
+ "net/base/net_errors.cc",
+ "net/base/net_errors_posix.cc",
+ "net/base/net_module.cc",
+ "net/base/net_string_util_icu_alternatives_android.cc",
+ "net/base/network_activity_monitor.cc",
+ "net/base/network_anonymization_key.cc",
+ "net/base/network_change_notifier.cc",
+ "net/base/network_change_notifier_posix.cc",
+ "net/base/network_delegate.cc",
+ "net/base/network_delegate_impl.cc",
+ "net/base/network_interfaces.cc",
+ "net/base/network_interfaces_getifaddrs.cc",
+ "net/base/network_interfaces_getifaddrs_android.cc",
+ "net/base/network_interfaces_linux.cc",
+ "net/base/network_interfaces_posix.cc",
+ "net/base/network_isolation_key.cc",
+ "net/base/parse_number.cc",
+ "net/base/platform_mime_util_linux.cc",
+ "net/base/port_util.cc",
+ "net/base/prioritized_dispatcher.cc",
+ "net/base/prioritized_task_runner.cc",
+ "net/base/privacy_mode.cc",
+ "net/base/proxy_server.cc",
+ "net/base/proxy_string_util.cc",
+ "net/base/registry_controlled_domains/registry_controlled_domain.cc",
+ "net/base/request_priority.cc",
+ "net/base/scheme_host_port_matcher.cc",
+ "net/base/scheme_host_port_matcher_rule.cc",
+ "net/base/schemeful_site.cc",
+ "net/base/sockaddr_storage.cc",
+ "net/base/sockaddr_util_posix.cc",
+ "net/base/transport_info.cc",
+ "net/base/upload_bytes_element_reader.cc",
+ "net/base/upload_data_stream.cc",
+ "net/base/upload_element_reader.cc",
+ "net/base/upload_file_element_reader.cc",
+ "net/base/url_util.cc",
+ "net/cert/asn1_util.cc",
+ "net/cert/caching_cert_verifier.cc",
+ "net/cert/cert_and_ct_verifier.cc",
+ "net/cert/cert_database.cc",
+ "net/cert/cert_status_flags.cc",
+ "net/cert/cert_verifier.cc",
+ "net/cert/cert_verify_proc.cc",
+ "net/cert/cert_verify_proc_android.cc",
+ "net/cert/cert_verify_proc_builtin.cc",
+ "net/cert/cert_verify_result.cc",
+ "net/cert/coalescing_cert_verifier.cc",
+ "net/cert/crl_set.cc",
+ "net/cert/ct_log_response_parser.cc",
+ "net/cert/ct_log_verifier.cc",
+ "net/cert/ct_log_verifier_util.cc",
+ "net/cert/ct_objects_extractor.cc",
+ "net/cert/ct_policy_enforcer.cc",
+ "net/cert/ct_sct_to_string.cc",
+ "net/cert/ct_serialization.cc",
+ "net/cert/ct_signed_certificate_timestamp_log_param.cc",
+ "net/cert/do_nothing_ct_verifier.cc",
+ "net/cert/ev_root_ca_metadata.cc",
+ "net/cert/internal/cert_issuer_source_aia.cc",
+ "net/cert/internal/revocation_checker.cc",
+ "net/cert/internal/system_trust_store.cc",
+ "net/cert/known_roots.cc",
+ "net/cert/merkle_audit_proof.cc",
+ "net/cert/merkle_consistency_proof.cc",
+ "net/cert/merkle_tree_leaf.cc",
+ "net/cert/multi_log_ct_verifier.cc",
+ "net/cert/multi_threaded_cert_verifier.cc",
+ "net/cert/ocsp_verify_result.cc",
+ "net/cert/pem.cc",
+ "net/cert/pki/cert_error_id.cc",
+ "net/cert/pki/cert_error_params.cc",
+ "net/cert/pki/cert_errors.cc",
+ "net/cert/pki/cert_issuer_source_static.cc",
+ "net/cert/pki/certificate_policies.cc",
+ "net/cert/pki/common_cert_errors.cc",
+ "net/cert/pki/crl.cc",
+ "net/cert/pki/extended_key_usage.cc",
+ "net/cert/pki/general_names.cc",
+ "net/cert/pki/name_constraints.cc",
+ "net/cert/pki/ocsp.cc",
+ "net/cert/pki/parse_certificate.cc",
+ "net/cert/pki/parse_name.cc",
+ "net/cert/pki/parsed_certificate.cc",
+ "net/cert/pki/path_builder.cc",
+ "net/cert/pki/revocation_util.cc",
+ "net/cert/pki/signature_algorithm.cc",
+ "net/cert/pki/simple_path_builder_delegate.cc",
+ "net/cert/pki/string_util.cc",
+ "net/cert/pki/trust_store.cc",
+ "net/cert/pki/trust_store_collection.cc",
+ "net/cert/pki/trust_store_in_memory.cc",
+ "net/cert/pki/verify_certificate_chain.cc",
+ "net/cert/pki/verify_name_match.cc",
+ "net/cert/pki/verify_signed_data.cc",
+ "net/cert/sct_status_flags.cc",
+ "net/cert/signed_certificate_timestamp.cc",
+ "net/cert/signed_certificate_timestamp_and_status.cc",
+ "net/cert/signed_tree_head.cc",
+ "net/cert/symantec_certs.cc",
+ "net/cert/test_root_certs.cc",
+ "net/cert/test_root_certs_android.cc",
+ "net/cert/trial_comparison_cert_verifier_util.cc",
+ "net/cert/x509_cert_types.cc",
+ "net/cert/x509_certificate.cc",
+ "net/cert/x509_certificate_net_log_param.cc",
+ "net/cert/x509_util.cc",
+ "net/cert/x509_util_android.cc",
+ "net/cert_net/cert_net_fetcher_url_request.cc",
+ "net/cookies/canonical_cookie.cc",
+ "net/cookies/cookie_access_delegate.cc",
+ "net/cookies/cookie_access_result.cc",
+ "net/cookies/cookie_change_dispatcher.cc",
+ "net/cookies/cookie_constants.cc",
+ "net/cookies/cookie_deletion_info.cc",
+ "net/cookies/cookie_inclusion_status.cc",
+ "net/cookies/cookie_monster.cc",
+ "net/cookies/cookie_monster_change_dispatcher.cc",
+ "net/cookies/cookie_monster_netlog_params.cc",
+ "net/cookies/cookie_options.cc",
+ "net/cookies/cookie_partition_key.cc",
+ "net/cookies/cookie_partition_key_collection.cc",
+ "net/cookies/cookie_store.cc",
+ "net/cookies/cookie_util.cc",
+ "net/cookies/parsed_cookie.cc",
+ "net/cookies/site_for_cookies.cc",
+ "net/cookies/static_cookie_policy.cc",
+ "net/der/encode_values.cc",
+ "net/der/input.cc",
+ "net/der/parse_values.cc",
+ "net/der/parser.cc",
+ "net/der/tag.cc",
+ "net/disk_cache/backend_cleanup_tracker.cc",
+ "net/disk_cache/blockfile/addr.cc",
+ "net/disk_cache/blockfile/backend_impl.cc",
+ "net/disk_cache/blockfile/bitmap.cc",
+ "net/disk_cache/blockfile/block_files.cc",
+ "net/disk_cache/blockfile/disk_format.cc",
+ "net/disk_cache/blockfile/entry_impl.cc",
+ "net/disk_cache/blockfile/eviction.cc",
+ "net/disk_cache/blockfile/file.cc",
+ "net/disk_cache/blockfile/file_lock.cc",
+ "net/disk_cache/blockfile/file_posix.cc",
+ "net/disk_cache/blockfile/in_flight_backend_io.cc",
+ "net/disk_cache/blockfile/in_flight_io.cc",
+ "net/disk_cache/blockfile/mapped_file.cc",
+ "net/disk_cache/blockfile/mapped_file_bypass_mmap_posix.cc",
+ "net/disk_cache/blockfile/rankings.cc",
+ "net/disk_cache/blockfile/sparse_control.cc",
+ "net/disk_cache/blockfile/stats.cc",
+ "net/disk_cache/cache_util.cc",
+ "net/disk_cache/cache_util_posix.cc",
+ "net/disk_cache/disk_cache.cc",
+ "net/disk_cache/memory/mem_backend_impl.cc",
+ "net/disk_cache/memory/mem_entry_impl.cc",
+ "net/disk_cache/net_log_parameters.cc",
+ "net/disk_cache/simple/post_doom_waiter.cc",
+ "net/disk_cache/simple/simple_backend_impl.cc",
+ "net/disk_cache/simple/simple_entry_format.cc",
+ "net/disk_cache/simple/simple_entry_impl.cc",
+ "net/disk_cache/simple/simple_entry_operation.cc",
+ "net/disk_cache/simple/simple_file_enumerator.cc",
+ "net/disk_cache/simple/simple_file_tracker.cc",
+ "net/disk_cache/simple/simple_index.cc",
+ "net/disk_cache/simple/simple_index_file.cc",
+ "net/disk_cache/simple/simple_net_log_parameters.cc",
+ "net/disk_cache/simple/simple_synchronous_entry.cc",
+ "net/disk_cache/simple/simple_util.cc",
+ "net/disk_cache/simple/simple_util_posix.cc",
+ "net/disk_cache/simple/simple_version_upgrade.cc",
+ "net/filter/brotli_source_stream.cc",
+ "net/filter/filter_source_stream.cc",
+ "net/filter/gzip_header.cc",
+ "net/filter/gzip_source_stream.cc",
+ "net/filter/source_stream.cc",
+ "net/first_party_sets/addition_overlaps_union_find.cc",
+ "net/first_party_sets/first_party_set_entry.cc",
+ "net/first_party_sets/first_party_set_metadata.cc",
+ "net/first_party_sets/first_party_sets_cache_filter.cc",
+ "net/first_party_sets/first_party_sets_context_config.cc",
+ "net/first_party_sets/global_first_party_sets.cc",
+ "net/first_party_sets/same_party_context.cc",
+ "net/http/alternative_service.cc",
+ "net/http/bidirectional_stream.cc",
+ "net/http/bidirectional_stream_impl.cc",
+ "net/http/bidirectional_stream_request_info.cc",
+ "net/http/broken_alternative_services.cc",
+ "net/http/http_auth.cc",
+ "net/http/http_auth_cache.cc",
+ "net/http/http_auth_challenge_tokenizer.cc",
+ "net/http/http_auth_controller.cc",
+ "net/http/http_auth_filter.cc",
+ "net/http/http_auth_handler.cc",
+ "net/http/http_auth_handler_basic.cc",
+ "net/http/http_auth_handler_digest.cc",
+ "net/http/http_auth_handler_factory.cc",
+ "net/http/http_auth_handler_negotiate.cc",
+ "net/http/http_auth_handler_ntlm.cc",
+ "net/http/http_auth_handler_ntlm_portable.cc",
+ "net/http/http_auth_multi_round_parse.cc",
+ "net/http/http_auth_ntlm_mechanism.cc",
+ "net/http/http_auth_preferences.cc",
+ "net/http/http_auth_scheme.cc",
+ "net/http/http_basic_state.cc",
+ "net/http/http_basic_stream.cc",
+ "net/http/http_byte_range.cc",
+ "net/http/http_cache.cc",
+ "net/http/http_cache_lookup_manager.cc",
+ "net/http/http_cache_transaction.cc",
+ "net/http/http_cache_writers.cc",
+ "net/http/http_chunked_decoder.cc",
+ "net/http/http_content_disposition.cc",
+ "net/http/http_log_util.cc",
+ "net/http/http_network_layer.cc",
+ "net/http/http_network_session.cc",
+ "net/http/http_network_session_peer.cc",
+ "net/http/http_network_transaction.cc",
+ "net/http/http_proxy_client_socket.cc",
+ "net/http/http_proxy_connect_job.cc",
+ "net/http/http_raw_request_headers.cc",
+ "net/http/http_request_headers.cc",
+ "net/http/http_request_info.cc",
+ "net/http/http_response_body_drainer.cc",
+ "net/http/http_response_headers.cc",
+ "net/http/http_response_info.cc",
+ "net/http/http_security_headers.cc",
+ "net/http/http_server_properties.cc",
+ "net/http/http_server_properties_manager.cc",
+ "net/http/http_status_code.cc",
+ "net/http/http_stream_factory.cc",
+ "net/http/http_stream_factory_job.cc",
+ "net/http/http_stream_factory_job_controller.cc",
+ "net/http/http_stream_parser.cc",
+ "net/http/http_stream_request.cc",
+ "net/http/http_util.cc",
+ "net/http/http_vary_data.cc",
+ "net/http/partial_data.cc",
+ "net/http/proxy_client_socket.cc",
+ "net/http/proxy_fallback.cc",
+ "net/http/transport_security_persister.cc",
+ "net/http/transport_security_state_source.cc",
+ "net/http/url_security_manager.cc",
+ "net/http/url_security_manager_posix.cc",
+ "net/http/webfonts_histogram.cc",
+ "net/log/file_net_log_observer.cc",
+ "net/log/net_log.cc",
+ "net/log/net_log_capture_mode.cc",
+ "net/log/net_log_entry.cc",
+ "net/log/net_log_event_type.cc",
+ "net/log/net_log_source.cc",
+ "net/log/net_log_util.cc",
+ "net/log/net_log_values.cc",
+ "net/log/net_log_with_source.cc",
+ "net/log/trace_net_log_observer.cc",
+ "net/network_error_logging/network_error_logging_service.cc",
+ "net/nqe/cached_network_quality.cc",
+ "net/nqe/effective_connection_type.cc",
+ "net/nqe/event_creator.cc",
+ "net/nqe/network_id.cc",
+ "net/nqe/network_qualities_prefs_manager.cc",
+ "net/nqe/network_quality.cc",
+ "net/nqe/network_quality_estimator.cc",
+ "net/nqe/network_quality_estimator_params.cc",
+ "net/nqe/network_quality_estimator_util.cc",
+ "net/nqe/network_quality_observation.cc",
+ "net/nqe/network_quality_store.cc",
+ "net/nqe/observation_buffer.cc",
+ "net/nqe/pref_names.cc",
+ "net/nqe/socket_watcher.cc",
+ "net/nqe/socket_watcher_factory.cc",
+ "net/nqe/throughput_analyzer.cc",
+ "net/ntlm/ntlm.cc",
+ "net/ntlm/ntlm_buffer_reader.cc",
+ "net/ntlm/ntlm_buffer_writer.cc",
+ "net/ntlm/ntlm_client.cc",
+ "net/ntlm/ntlm_constants.cc",
+ "net/proxy_resolution/configured_proxy_resolution_request.cc",
+ "net/proxy_resolution/configured_proxy_resolution_service.cc",
+ "net/proxy_resolution/dhcp_pac_file_fetcher.cc",
+ "net/proxy_resolution/multi_threaded_proxy_resolver.cc",
+ "net/proxy_resolution/network_delegate_error_observer.cc",
+ "net/proxy_resolution/pac_file_data.cc",
+ "net/proxy_resolution/pac_file_decider.cc",
+ "net/proxy_resolution/pac_file_fetcher.cc",
+ "net/proxy_resolution/pac_file_fetcher_impl.cc",
+ "net/proxy_resolution/polling_proxy_config_service.cc",
+ "net/proxy_resolution/proxy_bypass_rules.cc",
+ "net/proxy_resolution/proxy_config.cc",
+ "net/proxy_resolution/proxy_config_service.cc",
+ "net/proxy_resolution/proxy_config_service_android.cc",
+ "net/proxy_resolution/proxy_config_service_fixed.cc",
+ "net/proxy_resolution/proxy_config_with_annotation.cc",
+ "net/proxy_resolution/proxy_info.cc",
+ "net/proxy_resolution/proxy_list.cc",
+ "net/proxy_resolution/proxy_resolver_factory.cc",
+ "net/quic/bidirectional_stream_quic_impl.cc",
+ "net/quic/crypto/proof_source_chromium.cc",
+ "net/quic/crypto/proof_verifier_chromium.cc",
+ "net/quic/dedicated_web_transport_http3_client.cc",
+ "net/quic/network_connection.cc",
+ "net/quic/platform/impl/quic_chromium_clock.cc",
+ "net/quic/properties_based_quic_server_info.cc",
+ "net/quic/quic_address_mismatch.cc",
+ "net/quic/quic_chromium_alarm_factory.cc",
+ "net/quic/quic_chromium_client_session.cc",
+ "net/quic/quic_chromium_client_stream.cc",
+ "net/quic/quic_chromium_connection_helper.cc",
+ "net/quic/quic_chromium_packet_reader.cc",
+ "net/quic/quic_chromium_packet_writer.cc",
+ "net/quic/quic_clock_skew_detector.cc",
+ "net/quic/quic_connection_logger.cc",
+ "net/quic/quic_connectivity_monitor.cc",
+ "net/quic/quic_context.cc",
+ "net/quic/quic_crypto_client_config_handle.cc",
+ "net/quic/quic_crypto_client_stream_factory.cc",
+ "net/quic/quic_event_logger.cc",
+ "net/quic/quic_http3_logger.cc",
+ "net/quic/quic_http_stream.cc",
+ "net/quic/quic_http_utils.cc",
+ "net/quic/quic_proxy_client_socket.cc",
+ "net/quic/quic_server_info.cc",
+ "net/quic/quic_session_key.cc",
+ "net/quic/quic_stream_factory.cc",
+ "net/quic/set_quic_flag.cc",
+ "net/quic/web_transport_client.cc",
+ "net/quic/web_transport_error.cc",
+ "net/reporting/reporting_browsing_data_remover.cc",
+ "net/reporting/reporting_cache.cc",
+ "net/reporting/reporting_cache_impl.cc",
+ "net/reporting/reporting_cache_observer.cc",
+ "net/reporting/reporting_context.cc",
+ "net/reporting/reporting_delegate.cc",
+ "net/reporting/reporting_delivery_agent.cc",
+ "net/reporting/reporting_endpoint.cc",
+ "net/reporting/reporting_endpoint_manager.cc",
+ "net/reporting/reporting_garbage_collector.cc",
+ "net/reporting/reporting_header_parser.cc",
+ "net/reporting/reporting_network_change_observer.cc",
+ "net/reporting/reporting_policy.cc",
+ "net/reporting/reporting_report.cc",
+ "net/reporting/reporting_service.cc",
+ "net/reporting/reporting_uploader.cc",
+ "net/socket/client_socket_factory.cc",
+ "net/socket/client_socket_handle.cc",
+ "net/socket/client_socket_pool.cc",
+ "net/socket/client_socket_pool_manager.cc",
+ "net/socket/client_socket_pool_manager_impl.cc",
+ "net/socket/connect_job.cc",
+ "net/socket/connect_job_factory.cc",
+ "net/socket/network_binding_client_socket_factory.cc",
+ "net/socket/next_proto.cc",
+ "net/socket/server_socket.cc",
+ "net/socket/socket.cc",
+ "net/socket/socket_bio_adapter.cc",
+ "net/socket/socket_descriptor.cc",
+ "net/socket/socket_net_log_params.cc",
+ "net/socket/socket_options.cc",
+ "net/socket/socket_posix.cc",
+ "net/socket/socket_tag.cc",
+ "net/socket/socks5_client_socket.cc",
+ "net/socket/socks_client_socket.cc",
+ "net/socket/socks_connect_job.cc",
+ "net/socket/ssl_client_socket.cc",
+ "net/socket/ssl_client_socket_impl.cc",
+ "net/socket/ssl_connect_job.cc",
+ "net/socket/ssl_server_socket_impl.cc",
+ "net/socket/stream_socket.cc",
+ "net/socket/tcp_client_socket.cc",
+ "net/socket/tcp_server_socket.cc",
+ "net/socket/tcp_socket_posix.cc",
+ "net/socket/transport_client_socket.cc",
+ "net/socket/transport_client_socket_pool.cc",
+ "net/socket/transport_connect_job.cc",
+ "net/socket/transport_connect_sub_job.cc",
+ "net/socket/udp_client_socket.cc",
+ "net/socket/udp_net_log_parameters.cc",
+ "net/socket/udp_server_socket.cc",
+ "net/socket/udp_socket_global_limits.cc",
+ "net/socket/udp_socket_posix.cc",
+ "net/socket/unix_domain_client_socket_posix.cc",
+ "net/socket/unix_domain_server_socket_posix.cc",
+ "net/socket/websocket_endpoint_lock_manager.cc",
+ "net/socket/websocket_transport_client_socket_pool.cc",
+ "net/spdy/alps_decoder.cc",
+ "net/spdy/bidirectional_stream_spdy_impl.cc",
+ "net/spdy/buffered_spdy_framer.cc",
+ "net/spdy/header_coalescer.cc",
+ "net/spdy/http2_priority_dependencies.cc",
+ "net/spdy/http2_push_promise_index.cc",
+ "net/spdy/multiplexed_http_stream.cc",
+ "net/spdy/multiplexed_session.cc",
+ "net/spdy/spdy_buffer.cc",
+ "net/spdy/spdy_buffer_producer.cc",
+ "net/spdy/spdy_http_stream.cc",
+ "net/spdy/spdy_http_utils.cc",
+ "net/spdy/spdy_log_util.cc",
+ "net/spdy/spdy_proxy_client_socket.cc",
+ "net/spdy/spdy_read_queue.cc",
+ "net/spdy/spdy_session.cc",
+ "net/spdy/spdy_session_key.cc",
+ "net/spdy/spdy_session_pool.cc",
+ "net/spdy/spdy_stream.cc",
+ "net/spdy/spdy_write_queue.cc",
+ "net/ssl/cert_compression.cc",
+ "net/ssl/client_cert_identity.cc",
+ "net/ssl/openssl_ssl_util.cc",
+ "net/ssl/ssl_cert_request_info.cc",
+ "net/ssl/ssl_cipher_suite_names.cc",
+ "net/ssl/ssl_client_auth_cache.cc",
+ "net/ssl/ssl_client_session_cache.cc",
+ "net/ssl/ssl_config.cc",
+ "net/ssl/ssl_config_service.cc",
+ "net/ssl/ssl_config_service_defaults.cc",
+ "net/ssl/ssl_info.cc",
+ "net/ssl/ssl_key_logger.cc",
+ "net/ssl/ssl_key_logger_impl.cc",
+ "net/ssl/ssl_platform_key_android.cc",
+ "net/ssl/ssl_platform_key_util.cc",
+ "net/ssl/ssl_private_key.cc",
+ "net/ssl/ssl_server_config.cc",
+ "net/ssl/threaded_ssl_private_key.cc",
+ "net/url_request/redirect_info.cc",
+ "net/url_request/redirect_util.cc",
+ "net/url_request/report_sender.cc",
+ "net/url_request/static_http_user_agent_settings.cc",
+ "net/url_request/url_request.cc",
+ "net/url_request/url_request_context.cc",
+ "net/url_request/url_request_context_builder.cc",
+ "net/url_request/url_request_context_getter.cc",
+ "net/url_request/url_request_error_job.cc",
+ "net/url_request/url_request_filter.cc",
+ "net/url_request/url_request_http_job.cc",
+ "net/url_request/url_request_interceptor.cc",
+ "net/url_request/url_request_job.cc",
+ "net/url_request/url_request_job_factory.cc",
+ "net/url_request/url_request_netlog_params.cc",
+ "net/url_request/url_request_redirect_job.cc",
+ "net/url_request/url_request_throttler_entry.cc",
+ "net/url_request/url_request_throttler_manager.cc",
+ "net/url_request/view_cache_helper.cc",
+ "net/url_request/websocket_handshake_userdata_key.cc",
+ ],
+ shared_libs: [
+ "libandroid",
+ "liblog",
+ ],
+ static_libs: [
+ "cronet_aml_base_base",
+ "cronet_aml_base_third_party_dynamic_annotations_dynamic_annotations",
+ "cronet_aml_crypto_crypto",
+ "cronet_aml_net_isolation_info_proto",
+ "cronet_aml_net_net_nqe_proto",
+ "cronet_aml_net_preload_decoder",
+ "cronet_aml_net_third_party_quiche_net_quic_test_tools_proto",
+ "cronet_aml_net_third_party_quiche_quiche",
+ "cronet_aml_net_uri_template",
+ "cronet_aml_third_party_boringssl_boringssl",
+ "cronet_aml_third_party_brotli_dec",
+ "cronet_aml_third_party_protobuf_protobuf_lite",
+ "cronet_aml_third_party_zlib_zlib",
+ "cronet_aml_url_url",
+ ],
+ generated_headers: [
+ "cronet_aml_base_debugging_buildflags",
+ "cronet_aml_base_logging_buildflags",
+ "cronet_aml_build_branding_buildflags",
+ "cronet_aml_build_chromeos_buildflags",
+ "cronet_aml_net_buildflags",
+ "cronet_aml_net_ios_cronet_buildflags",
+ "cronet_aml_net_net_jni_headers",
+ "cronet_aml_tools_grit_grit_sources",
+ "cronet_aml_tools_gritsettings_default_resource_ids",
+ "cronet_aml_url_buildflags",
+ ],
+ export_generated_headers: [
+ "cronet_aml_base_debugging_buildflags",
+ "cronet_aml_base_logging_buildflags",
+ "cronet_aml_build_branding_buildflags",
+ "cronet_aml_build_chromeos_buildflags",
+ "cronet_aml_net_buildflags",
+ "cronet_aml_net_ios_cronet_buildflags",
+ "cronet_aml_net_net_jni_headers",
+ "cronet_aml_tools_grit_grit_sources",
+ "cronet_aml_tools_gritsettings_default_resource_ids",
+ "cronet_aml_url_buildflags",
+ ],
+ defaults: [
+ "cronet_aml_defaults",
+ ],
+ cflags: [
+ "-DANDROID",
+ "-DANDROID_NDK_VERSION_ROLL=r23_1",
+ "-DCR_CLANG_REVISION=\"llvmorg-16-init-8697-g60809cd2-1\"",
+ "-DCR_LIBCXX_REVISION=47b31179d10646029c260702650a25d24f555acc",
+ "-DDCHECK_ALWAYS_ON=1",
+ "-DDYNAMIC_ANNOTATIONS_ENABLED=1",
+ "-DENABLE_BUILT_IN_DNS",
+ "-DGOOGLE_PROTOBUF_INTERNAL_DONATE_STEAL_INLINE=0",
+ "-DGOOGLE_PROTOBUF_NO_RTTI",
+ "-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER",
+ "-DHAVE_PTHREAD",
+ "-DHAVE_SYS_UIO_H",
+ "-DNET_IMPLEMENTATION",
+ "-D_DEBUG",
+ "-D_GNU_SOURCE",
+ "-D_LIBCPP_AVAILABILITY_CUSTOM_VERBOSE_ABORT_PROVIDED=1",
+ "-D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS",
+ "-D_LIBCPP_ENABLE_ASSERTIONS_DEFAULT=1",
+ "-D_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS",
+ "-D__STDC_CONSTANT_MACROS",
+ "-D__STDC_FORMAT_MACROS",
+ ],
+ local_include_dirs: [
+ "./",
+ "buildtools/third_party/libc++/",
+ "buildtools/third_party/libc++/trunk/include",
+ "buildtools/third_party/libc++abi/trunk/include",
+ "net/third_party/quiche/overrides/",
+ "net/third_party/quiche/src/",
+ "net/third_party/quiche/src/quiche/common/platform/default/",
+ "third_party/abseil-cpp/",
+ "third_party/boringssl/src/include/",
+ "third_party/brotli/include/",
+ "third_party/protobuf/src/",
+ "third_party/zlib/",
+ "third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include",
+ ],
+ header_libs: [
+ "jni_headers",
+ ],
+ cpp_std: "c++20",
+}
+
+// GN: //net:net_deps
+filegroup {
+ name: "cronet_aml_net_net_deps",
+}
+
+// GN: //net:net_export_header
+filegroup {
+ name: "cronet_aml_net_net_export_header",
+}
+
+// GN: //net:net_jni_headers
+genrule {
+ name: "cronet_aml_net_net_jni_headers",
+ srcs: [
+ "net/android/java/src/org/chromium/net/AndroidCertVerifyResult.java",
+ "net/android/java/src/org/chromium/net/AndroidKeyStore.java",
+ "net/android/java/src/org/chromium/net/AndroidNetworkLibrary.java",
+ "net/android/java/src/org/chromium/net/AndroidTrafficStats.java",
+ "net/android/java/src/org/chromium/net/DnsStatus.java",
+ "net/android/java/src/org/chromium/net/GURLUtils.java",
+ "net/android/java/src/org/chromium/net/HttpNegotiateAuthenticator.java",
+ "net/android/java/src/org/chromium/net/HttpUtil.java",
+ "net/android/java/src/org/chromium/net/NetStringUtil.java",
+ "net/android/java/src/org/chromium/net/NetworkActiveNotifier.java",
+ "net/android/java/src/org/chromium/net/NetworkChangeNotifier.java",
+ "net/android/java/src/org/chromium/net/ProxyChangeListener.java",
+ "net/android/java/src/org/chromium/net/X509Util.java",
+ ],
+ cmd: "$(location base/android/jni_generator/jni_generator.py) --ptr_type " +
+ "long " +
+ " " +
+ " " +
+ "--output_dir " +
+ "$(genDir)/net/net_jni_headers " +
+ "--includes " +
+ "base/android/jni_generator/jni_generator_helper.h " +
+ "--use_proxy_hash " +
+ "--output_name " +
+ "AndroidCertVerifyResult_jni.h " +
+ "--output_name " +
+ "AndroidKeyStore_jni.h " +
+ "--output_name " +
+ "AndroidNetworkLibrary_jni.h " +
+ "--output_name " +
+ "AndroidTrafficStats_jni.h " +
+ "--output_name " +
+ "DnsStatus_jni.h " +
+ "--output_name " +
+ "GURLUtils_jni.h " +
+ "--output_name " +
+ "HttpNegotiateAuthenticator_jni.h " +
+ "--output_name " +
+ "HttpUtil_jni.h " +
+ "--output_name " +
+ "NetStringUtil_jni.h " +
+ "--output_name " +
+ "NetworkActiveNotifier_jni.h " +
+ "--output_name " +
+ "NetworkChangeNotifier_jni.h " +
+ "--output_name " +
+ "ProxyChangeListener_jni.h " +
+ "--output_name " +
+ "X509Util_jni.h " +
+ "--input_file " +
+ "$(location net/android/java/src/org/chromium/net/AndroidCertVerifyResult.java) " +
+ "--input_file " +
+ "$(location net/android/java/src/org/chromium/net/AndroidKeyStore.java) " +
+ "--input_file " +
+ "$(location net/android/java/src/org/chromium/net/AndroidNetworkLibrary.java) " +
+ "--input_file " +
+ "$(location net/android/java/src/org/chromium/net/AndroidTrafficStats.java) " +
+ "--input_file " +
+ "$(location net/android/java/src/org/chromium/net/DnsStatus.java) " +
+ "--input_file " +
+ "$(location net/android/java/src/org/chromium/net/GURLUtils.java) " +
+ "--input_file " +
+ "$(location net/android/java/src/org/chromium/net/HttpNegotiateAuthenticator.java) " +
+ "--input_file " +
+ "$(location net/android/java/src/org/chromium/net/HttpUtil.java) " +
+ "--input_file " +
+ "$(location net/android/java/src/org/chromium/net/NetStringUtil.java) " +
+ "--input_file " +
+ "$(location net/android/java/src/org/chromium/net/NetworkActiveNotifier.java) " +
+ "--input_file " +
+ "$(location net/android/java/src/org/chromium/net/NetworkChangeNotifier.java) " +
+ "--input_file " +
+ "$(location net/android/java/src/org/chromium/net/ProxyChangeListener.java) " +
+ "--input_file " +
+ "$(location net/android/java/src/org/chromium/net/X509Util.java)",
+ out: [
+ "net/net_jni_headers/AndroidCertVerifyResult_jni.h",
+ "net/net_jni_headers/AndroidKeyStore_jni.h",
+ "net/net_jni_headers/AndroidNetworkLibrary_jni.h",
+ "net/net_jni_headers/AndroidTrafficStats_jni.h",
+ "net/net_jni_headers/DnsStatus_jni.h",
+ "net/net_jni_headers/GURLUtils_jni.h",
+ "net/net_jni_headers/HttpNegotiateAuthenticator_jni.h",
+ "net/net_jni_headers/HttpUtil_jni.h",
+ "net/net_jni_headers/NetStringUtil_jni.h",
+ "net/net_jni_headers/NetworkActiveNotifier_jni.h",
+ "net/net_jni_headers/NetworkChangeNotifier_jni.h",
+ "net/net_jni_headers/ProxyChangeListener_jni.h",
+ "net/net_jni_headers/X509Util_jni.h",
+ ],
+ tool_files: [
+ "base/android/jni_generator/jni_generator.py",
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/gn_helpers.py",
+ ],
+}
+
+// GN: //net:net_nqe_proto
+cc_library_static {
+ name: "cronet_aml_net_net_nqe_proto",
+ srcs: [
+ ":cronet_aml_net_net_export_header",
+ "out/test/gen/net/nqe/proto/network_id_proto.pb.cc",
+ ],
+ shared_libs: [
+ "liblog",
+ ],
+ static_libs: [
+ "cronet_aml_third_party_protobuf_protobuf_lite",
+ ],
+ defaults: [
+ "cronet_aml_defaults",
+ ],
+ cflags: [
+ "-DANDROID",
+ "-DANDROID_NDK_VERSION_ROLL=r23_1",
+ "-DCR_CLANG_REVISION=\"llvmorg-16-init-8697-g60809cd2-1\"",
+ "-DCR_LIBCXX_REVISION=47b31179d10646029c260702650a25d24f555acc",
+ "-DDCHECK_ALWAYS_ON=1",
+ "-DDYNAMIC_ANNOTATIONS_ENABLED=1",
+ "-DGOOGLE_PROTOBUF_INTERNAL_DONATE_STEAL_INLINE=0",
+ "-DGOOGLE_PROTOBUF_NO_RTTI",
+ "-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER",
+ "-DHAVE_PTHREAD",
+ "-DHAVE_SYS_UIO_H",
+ "-DNET_IMPLEMENTATION",
+ "-D_DEBUG",
+ "-D_GNU_SOURCE",
+ "-D_LIBCPP_AVAILABILITY_CUSTOM_VERBOSE_ABORT_PROVIDED=1",
+ "-D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS",
+ "-D_LIBCPP_ENABLE_ASSERTIONS_DEFAULT=1",
+ "-D_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS",
+ "-D__STDC_CONSTANT_MACROS",
+ "-D__STDC_FORMAT_MACROS",
+ ],
+ local_include_dirs: [
+ "./",
+ "buildtools/third_party/libc++/",
+ "buildtools/third_party/libc++/trunk/include",
+ "buildtools/third_party/libc++abi/trunk/include",
+ "third_party/protobuf/src/",
+ "third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include",
+ ],
+ cpp_std: "c++20",
+}
+
+// GN: //net:net_nqe_proto_gen
+genrule {
+ name: "cronet_aml_net_net_nqe_proto_gen",
+ srcs: [
+ "net/base/net_export.h",
+ "net/nqe/proto/network_id_proto.proto",
+ ],
+ tools: [
+ "aprotoc",
+ ],
+ cmd: "$(location tools/protoc_wrapper/protoc_wrapper.py) network_id_proto.proto " +
+ "--protoc " +
+ "$(location aprotoc) " +
+ "--proto-in-dir " +
+ "`dirname $(location net/nqe/proto/network_id_proto.proto)` " +
+ "--cc-out-dir " +
+ "$(genDir)/net/nqe/proto " +
+ "--cc-options " +
+ "dllexport_decl=NET_EXPORT_PRIVATE: " +
+ " " +
+ "--include " +
+ "$(location net/base/net_export.h) " +
+ "--py-out-dir " +
+ "$(genDir)/pyproto/net/nqe/proto",
+ out: [
+ "net/nqe/proto/network_id_proto.pb.cc",
+ "net/nqe/proto/network_id_proto.pb.h",
+ "pyproto/net/nqe/proto/network_id_proto_pb2.py",
+ ],
+ tool_files: [
+ "tools/protoc_wrapper/protoc_wrapper.py",
+ ],
+}
+
+// GN: //net:net_public_deps
+filegroup {
+ name: "cronet_aml_net_net_public_deps",
+}
+
+// GN: //net:net_resources
+filegroup {
+ name: "cronet_aml_net_net_resources",
+}
+
+// GN: //net:net_resources_grit
+genrule {
+ name: "cronet_aml_net_net_resources_grit",
+ cmd: "$(location tools/grit/grit.py) -i " +
+ "../../net/base/net_resources.grd " +
+ "build " +
+ "-o " +
+ "gen/net " +
+ "--depdir " +
+ ". " +
+ "--depfile " +
+ "gen/net/net_resources_grit.d " +
+ "--write-only-new " +
+ "1 " +
+ "--depend-on-stamp " +
+ "-D " +
+ "DEVTOOLS_GRD_PATH " +
+ "gen/third_party/devtools-frontend/src/front_end/devtools_resources " +
+ "-D " +
+ "SHARED_INTERMEDIATE_DIR " +
+ "gen " +
+ "-D " +
+ "_google_chrome " +
+ "false " +
+ "-D " +
+ "_google_chrome_for_testing " +
+ "false " +
+ "-D " +
+ "chromeos_ash " +
+ "false " +
+ "-D " +
+ "chromeos_lacros " +
+ "false " +
+ "-D " +
+ "reven " +
+ "false " +
+ "-D " +
+ "toolkit_views " +
+ "false " +
+ "-D " +
+ "use_aura " +
+ "false " +
+ "-D " +
+ "use_ozone " +
+ "false " +
+ "-D " +
+ "use_titlecase " +
+ "false " +
+ "-E " +
+ "root_gen_dir " +
+ "gen " +
+ "-E " +
+ "root_src_dir " +
+ "../../ " +
+ "-E " +
+ "CHROMIUM_BUILD " +
+ "chromium " +
+ "-E " +
+ "ANDROID_JAVA_TAGGED_ONLY " +
+ "true " +
+ "-t " +
+ "android " +
+ "-f " +
+ "gen/tools/gritsettings/default_resource_ids " +
+ "--assert-file-list " +
+ "obj/net/net_resources_expected_outputs.txt",
+ out: [
+ "net/grit/net_resources.h",
+ "net/net_resources.pak",
+ "net/net_resources.pak.info",
+ "net/net_resources_grit.d.stamp",
+ ],
+ tool_files: [
+ "net/base/net_resources.grd",
+ "out/test/gen/tools/gritsettings/default_resource_ids",
+ "out/test/obj/net/net_resources_expected_outputs.txt",
+ "tools/grit/grit.py",
+ ],
+}
+
+// GN: //net:preload_decoder
+cc_library_static {
+ name: "cronet_aml_net_preload_decoder",
+ srcs: [
+ "net/extras/preload_data/decoder.cc",
+ ],
+ shared_libs: [
+ "libandroid",
+ "liblog",
+ ],
+ static_libs: [
+ "cronet_aml_base_base",
+ ],
+ defaults: [
+ "cronet_aml_defaults",
+ ],
+ cflags: [
+ "-DANDROID",
+ "-DANDROID_NDK_VERSION_ROLL=r23_1",
+ "-DCR_CLANG_REVISION=\"llvmorg-16-init-8697-g60809cd2-1\"",
+ "-DCR_LIBCXX_REVISION=47b31179d10646029c260702650a25d24f555acc",
+ "-DDCHECK_ALWAYS_ON=1",
+ "-DDYNAMIC_ANNOTATIONS_ENABLED=1",
+ "-DHAVE_SYS_UIO_H",
+ "-D_DEBUG",
+ "-D_GNU_SOURCE",
+ "-D_LIBCPP_AVAILABILITY_CUSTOM_VERBOSE_ABORT_PROVIDED=1",
+ "-D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS",
+ "-D_LIBCPP_ENABLE_ASSERTIONS_DEFAULT=1",
+ "-D_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS",
+ "-D__STDC_CONSTANT_MACROS",
+ "-D__STDC_FORMAT_MACROS",
+ ],
+ local_include_dirs: [
+ "./",
+ "buildtools/third_party/libc++/",
+ "buildtools/third_party/libc++/trunk/include",
+ "buildtools/third_party/libc++abi/trunk/include",
+ "third_party/abseil-cpp/",
+ "third_party/boringssl/src/include/",
+ "third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include",
+ ],
+ cpp_std: "c++20",
+}
+
+// GN: //net/third_party/quiche:net_quic_proto
+cc_library_static {
+ name: "cronet_aml_net_third_party_quiche_net_quic_proto",
+ srcs: [
+ "out/test/gen/net/third_party/quiche/src/quiche/quic/core/proto/cached_network_parameters.pb.cc",
+ "out/test/gen/net/third_party/quiche/src/quiche/quic/core/proto/crypto_server_config.pb.cc",
+ "out/test/gen/net/third_party/quiche/src/quiche/quic/core/proto/source_address_token.pb.cc",
+ ],
+ shared_libs: [
+ "libandroid",
+ "liblog",
+ ],
+ static_libs: [
+ "cronet_aml_base_base",
+ "cronet_aml_third_party_protobuf_protobuf_lite",
+ ],
+ defaults: [
+ "cronet_aml_defaults",
+ ],
+ cflags: [
+ "-DANDROID",
+ "-DANDROID_NDK_VERSION_ROLL=r23_1",
+ "-DCR_CLANG_REVISION=\"llvmorg-16-init-8697-g60809cd2-1\"",
+ "-DCR_LIBCXX_REVISION=47b31179d10646029c260702650a25d24f555acc",
+ "-DDCHECK_ALWAYS_ON=1",
+ "-DDYNAMIC_ANNOTATIONS_ENABLED=1",
+ "-DGOOGLE_PROTOBUF_INTERNAL_DONATE_STEAL_INLINE=0",
+ "-DGOOGLE_PROTOBUF_NO_RTTI",
+ "-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER",
+ "-DHAVE_PTHREAD",
+ "-DHAVE_SYS_UIO_H",
+ "-DIS_QUICHE_IMPL",
+ "-D_DEBUG",
+ "-D_GNU_SOURCE",
+ "-D_LIBCPP_AVAILABILITY_CUSTOM_VERBOSE_ABORT_PROVIDED=1",
+ "-D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS",
+ "-D_LIBCPP_ENABLE_ASSERTIONS_DEFAULT=1",
+ "-D_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS",
+ "-D__STDC_CONSTANT_MACROS",
+ "-D__STDC_FORMAT_MACROS",
+ ],
+ local_include_dirs: [
+ "./",
+ "buildtools/third_party/libc++/",
+ "buildtools/third_party/libc++/trunk/include",
+ "buildtools/third_party/libc++abi/trunk/include",
+ "third_party/abseil-cpp/",
+ "third_party/boringssl/src/include/",
+ "third_party/protobuf/src/",
+ "third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include",
+ ],
+ cpp_std: "c++20",
+}
+
+// GN: //net/third_party/quiche:net_quic_proto_gen
+genrule {
+ name: "cronet_aml_net_third_party_quiche_net_quic_proto_gen",
+ srcs: [
+ "base/component_export.h",
+ "net/third_party/quiche/src/quiche/quic/core/proto/cached_network_parameters.proto",
+ "net/third_party/quiche/src/quiche/quic/core/proto/crypto_server_config.proto",
+ "net/third_party/quiche/src/quiche/quic/core/proto/source_address_token.proto",
+ ],
+ tools: [
+ "aprotoc",
+ ],
+ cmd: "$(location tools/protoc_wrapper/protoc_wrapper.py) quiche/quic/core/proto/cached_network_parameters.proto " +
+ "quiche/quic/core/proto/crypto_server_config.proto " +
+ "quiche/quic/core/proto/source_address_token.proto " +
+ "--protoc " +
+ "$(location aprotoc) " +
+ "--proto-in-dir " +
+ "`dirname $(location net/third_party/quiche/src/quiche/quic/core/proto/cached_network_parameters.proto)`/../../../../ " +
+ "--cc-out-dir " +
+ "$(genDir)/net/third_party/quiche/src " +
+ "--cc-options " +
+ "dllexport_decl=COMPONENT_EXPORT(QUICHE): " +
+ " " +
+ "--include " +
+ "$(location base/component_export.h) " +
+ "--py-out-dir " +
+ "$(genDir)/pyproto/net/third_party/quiche/src",
+ out: [
+ "net/third_party/quiche/src/quiche/quic/core/proto/cached_network_parameters.pb.cc",
+ "net/third_party/quiche/src/quiche/quic/core/proto/cached_network_parameters.pb.h",
+ "net/third_party/quiche/src/quiche/quic/core/proto/crypto_server_config.pb.cc",
+ "net/third_party/quiche/src/quiche/quic/core/proto/crypto_server_config.pb.h",
+ "net/third_party/quiche/src/quiche/quic/core/proto/source_address_token.pb.cc",
+ "net/third_party/quiche/src/quiche/quic/core/proto/source_address_token.pb.h",
+ "pyproto/net/third_party/quiche/src/quiche/quic/core/proto/cached_network_parameters_pb2.py",
+ "pyproto/net/third_party/quiche/src/quiche/quic/core/proto/crypto_server_config_pb2.py",
+ "pyproto/net/third_party/quiche/src/quiche/quic/core/proto/source_address_token_pb2.py",
+ ],
+ tool_files: [
+ "tools/protoc_wrapper/protoc_wrapper.py",
+ ],
+}
+
+// GN: //net/third_party/quiche:net_quic_test_tools_proto
+cc_library_static {
+ name: "cronet_aml_net_third_party_quiche_net_quic_test_tools_proto",
+ srcs: [
+ ":cronet_aml_net_net_export_header",
+ "out/test/gen/net/third_party/quiche/src/quiche/quic/test_tools/send_algorithm_test_result.pb.cc",
+ ],
+ shared_libs: [
+ "liblog",
+ ],
+ static_libs: [
+ "cronet_aml_third_party_protobuf_protobuf_lite",
+ ],
+ defaults: [
+ "cronet_aml_defaults",
+ ],
+ cflags: [
+ "-DANDROID",
+ "-DANDROID_NDK_VERSION_ROLL=r23_1",
+ "-DCR_CLANG_REVISION=\"llvmorg-16-init-8697-g60809cd2-1\"",
+ "-DCR_LIBCXX_REVISION=47b31179d10646029c260702650a25d24f555acc",
+ "-DDCHECK_ALWAYS_ON=1",
+ "-DDYNAMIC_ANNOTATIONS_ENABLED=1",
+ "-DGOOGLE_PROTOBUF_INTERNAL_DONATE_STEAL_INLINE=0",
+ "-DGOOGLE_PROTOBUF_NO_RTTI",
+ "-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER",
+ "-DHAVE_PTHREAD",
+ "-DHAVE_SYS_UIO_H",
+ "-DNET_IMPLEMENTATION",
+ "-D_DEBUG",
+ "-D_GNU_SOURCE",
+ "-D_LIBCPP_AVAILABILITY_CUSTOM_VERBOSE_ABORT_PROVIDED=1",
+ "-D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS",
+ "-D_LIBCPP_ENABLE_ASSERTIONS_DEFAULT=1",
+ "-D_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS",
+ "-D__STDC_CONSTANT_MACROS",
+ "-D__STDC_FORMAT_MACROS",
+ ],
+ local_include_dirs: [
+ "./",
+ "buildtools/third_party/libc++/",
+ "buildtools/third_party/libc++/trunk/include",
+ "buildtools/third_party/libc++abi/trunk/include",
+ "third_party/protobuf/src/",
+ "third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include",
+ ],
+ cpp_std: "c++20",
+}
+
+// GN: //net/third_party/quiche:net_quic_test_tools_proto_gen
+genrule {
+ name: "cronet_aml_net_third_party_quiche_net_quic_test_tools_proto_gen",
+ srcs: [
+ "net/base/net_export.h",
+ "net/third_party/quiche/src/quiche/quic/test_tools/send_algorithm_test_result.proto",
+ ],
+ tools: [
+ "aprotoc",
+ ],
+ cmd: "$(location tools/protoc_wrapper/protoc_wrapper.py) send_algorithm_test_result.proto " +
+ "--protoc " +
+ "$(location aprotoc) " +
+ "--proto-in-dir " +
+ "`dirname $(location net/third_party/quiche/src/quiche/quic/test_tools/send_algorithm_test_result.proto)` " +
+ "--cc-out-dir " +
+ "$(genDir)/net/third_party/quiche/src/quiche/quic/test_tools " +
+ "--cc-options " +
+ "dllexport_decl=NET_EXPORT_PRIVATE: " +
+ " " +
+ "--include " +
+ "$(location net/base/net_export.h) " +
+ "--py-out-dir " +
+ "$(genDir)/pyproto/net/third_party/quiche/src/quiche/quic/test_tools",
+ out: [
+ "net/third_party/quiche/src/quiche/quic/test_tools/send_algorithm_test_result.pb.cc",
+ "net/third_party/quiche/src/quiche/quic/test_tools/send_algorithm_test_result.pb.h",
+ "pyproto/net/third_party/quiche/src/quiche/quic/test_tools/send_algorithm_test_result_pb2.py",
+ ],
+ tool_files: [
+ "tools/protoc_wrapper/protoc_wrapper.py",
+ ],
+}
+
+// GN: //net/third_party/quiche:quiche
+cc_library_static {
+ name: "cronet_aml_net_third_party_quiche_quiche",
+ srcs: [
+ ":cronet_aml_third_party_abseil_cpp_absl",
+ ":cronet_aml_third_party_abseil_cpp_absl_algorithm_algorithm",
+ ":cronet_aml_third_party_abseil_cpp_absl_algorithm_container",
+ ":cronet_aml_third_party_abseil_cpp_absl_base_atomic_hook",
+ ":cronet_aml_third_party_abseil_cpp_absl_base_base",
+ ":cronet_aml_third_party_abseil_cpp_absl_base_base_internal",
+ ":cronet_aml_third_party_abseil_cpp_absl_base_config",
+ ":cronet_aml_third_party_abseil_cpp_absl_base_core_headers",
+ ":cronet_aml_third_party_abseil_cpp_absl_base_cycleclock_internal",
+ ":cronet_aml_third_party_abseil_cpp_absl_base_dynamic_annotations",
+ ":cronet_aml_third_party_abseil_cpp_absl_base_endian",
+ ":cronet_aml_third_party_abseil_cpp_absl_base_errno_saver",
+ ":cronet_aml_third_party_abseil_cpp_absl_base_fast_type_id",
+ ":cronet_aml_third_party_abseil_cpp_absl_base_log_severity",
+ ":cronet_aml_third_party_abseil_cpp_absl_base_malloc_internal",
+ ":cronet_aml_third_party_abseil_cpp_absl_base_prefetch",
+ ":cronet_aml_third_party_abseil_cpp_absl_base_raw_logging_internal",
+ ":cronet_aml_third_party_abseil_cpp_absl_base_spinlock_wait",
+ ":cronet_aml_third_party_abseil_cpp_absl_base_strerror",
+ ":cronet_aml_third_party_abseil_cpp_absl_base_throw_delegate",
+ ":cronet_aml_third_party_abseil_cpp_absl_cleanup_cleanup",
+ ":cronet_aml_third_party_abseil_cpp_absl_cleanup_cleanup_internal",
+ ":cronet_aml_third_party_abseil_cpp_absl_container_btree",
+ ":cronet_aml_third_party_abseil_cpp_absl_container_common",
+ ":cronet_aml_third_party_abseil_cpp_absl_container_common_policy_traits",
+ ":cronet_aml_third_party_abseil_cpp_absl_container_compressed_tuple",
+ ":cronet_aml_third_party_abseil_cpp_absl_container_container_memory",
+ ":cronet_aml_third_party_abseil_cpp_absl_container_fixed_array",
+ ":cronet_aml_third_party_abseil_cpp_absl_container_flat_hash_map",
+ ":cronet_aml_third_party_abseil_cpp_absl_container_flat_hash_set",
+ ":cronet_aml_third_party_abseil_cpp_absl_container_hash_function_defaults",
+ ":cronet_aml_third_party_abseil_cpp_absl_container_hash_policy_traits",
+ ":cronet_aml_third_party_abseil_cpp_absl_container_hashtable_debug_hooks",
+ ":cronet_aml_third_party_abseil_cpp_absl_container_hashtablez_sampler",
+ ":cronet_aml_third_party_abseil_cpp_absl_container_inlined_vector",
+ ":cronet_aml_third_party_abseil_cpp_absl_container_inlined_vector_internal",
+ ":cronet_aml_third_party_abseil_cpp_absl_container_layout",
+ ":cronet_aml_third_party_abseil_cpp_absl_container_node_hash_map",
+ ":cronet_aml_third_party_abseil_cpp_absl_container_node_hash_set",
+ ":cronet_aml_third_party_abseil_cpp_absl_container_node_slot_policy",
+ ":cronet_aml_third_party_abseil_cpp_absl_container_raw_hash_map",
+ ":cronet_aml_third_party_abseil_cpp_absl_container_raw_hash_set",
+ ":cronet_aml_third_party_abseil_cpp_absl_debugging_debugging_internal",
+ ":cronet_aml_third_party_abseil_cpp_absl_debugging_demangle_internal",
+ ":cronet_aml_third_party_abseil_cpp_absl_debugging_examine_stack",
+ ":cronet_aml_third_party_abseil_cpp_absl_debugging_failure_signal_handler",
+ ":cronet_aml_third_party_abseil_cpp_absl_debugging_stacktrace",
+ ":cronet_aml_third_party_abseil_cpp_absl_debugging_symbolize",
+ ":cronet_aml_third_party_abseil_cpp_absl_functional_any_invocable",
+ ":cronet_aml_third_party_abseil_cpp_absl_functional_bind_front",
+ ":cronet_aml_third_party_abseil_cpp_absl_functional_function_ref",
+ ":cronet_aml_third_party_abseil_cpp_absl_hash_city",
+ ":cronet_aml_third_party_abseil_cpp_absl_hash_hash",
+ ":cronet_aml_third_party_abseil_cpp_absl_hash_low_level_hash",
+ ":cronet_aml_third_party_abseil_cpp_absl_memory_memory",
+ ":cronet_aml_third_party_abseil_cpp_absl_meta_type_traits",
+ ":cronet_aml_third_party_abseil_cpp_absl_numeric_bits",
+ ":cronet_aml_third_party_abseil_cpp_absl_numeric_int128",
+ ":cronet_aml_third_party_abseil_cpp_absl_numeric_representation",
+ ":cronet_aml_third_party_abseil_cpp_absl_profiling_exponential_biased",
+ ":cronet_aml_third_party_abseil_cpp_absl_profiling_sample_recorder",
+ ":cronet_aml_third_party_abseil_cpp_absl_random_distributions",
+ ":cronet_aml_third_party_abseil_cpp_absl_random_internal_distribution_caller",
+ ":cronet_aml_third_party_abseil_cpp_absl_random_internal_fast_uniform_bits",
+ ":cronet_aml_third_party_abseil_cpp_absl_random_internal_fastmath",
+ ":cronet_aml_third_party_abseil_cpp_absl_random_internal_generate_real",
+ ":cronet_aml_third_party_abseil_cpp_absl_random_internal_iostream_state_saver",
+ ":cronet_aml_third_party_abseil_cpp_absl_random_internal_nonsecure_base",
+ ":cronet_aml_third_party_abseil_cpp_absl_random_internal_pcg_engine",
+ ":cronet_aml_third_party_abseil_cpp_absl_random_internal_platform",
+ ":cronet_aml_third_party_abseil_cpp_absl_random_internal_pool_urbg",
+ ":cronet_aml_third_party_abseil_cpp_absl_random_internal_randen",
+ ":cronet_aml_third_party_abseil_cpp_absl_random_internal_randen_engine",
+ ":cronet_aml_third_party_abseil_cpp_absl_random_internal_randen_hwaes",
+ ":cronet_aml_third_party_abseil_cpp_absl_random_internal_randen_hwaes_impl",
+ ":cronet_aml_third_party_abseil_cpp_absl_random_internal_randen_slow",
+ ":cronet_aml_third_party_abseil_cpp_absl_random_internal_salted_seed_seq",
+ ":cronet_aml_third_party_abseil_cpp_absl_random_internal_seed_material",
+ ":cronet_aml_third_party_abseil_cpp_absl_random_internal_traits",
+ ":cronet_aml_third_party_abseil_cpp_absl_random_internal_uniform_helper",
+ ":cronet_aml_third_party_abseil_cpp_absl_random_internal_wide_multiply",
+ ":cronet_aml_third_party_abseil_cpp_absl_random_random",
+ ":cronet_aml_third_party_abseil_cpp_absl_random_seed_gen_exception",
+ ":cronet_aml_third_party_abseil_cpp_absl_random_seed_sequences",
+ ":cronet_aml_third_party_abseil_cpp_absl_status_status",
+ ":cronet_aml_third_party_abseil_cpp_absl_status_statusor",
+ ":cronet_aml_third_party_abseil_cpp_absl_strings_cord",
+ ":cronet_aml_third_party_abseil_cpp_absl_strings_cord_internal",
+ ":cronet_aml_third_party_abseil_cpp_absl_strings_cordz_functions",
+ ":cronet_aml_third_party_abseil_cpp_absl_strings_cordz_handle",
+ ":cronet_aml_third_party_abseil_cpp_absl_strings_cordz_info",
+ ":cronet_aml_third_party_abseil_cpp_absl_strings_cordz_statistics",
+ ":cronet_aml_third_party_abseil_cpp_absl_strings_cordz_update_scope",
+ ":cronet_aml_third_party_abseil_cpp_absl_strings_cordz_update_tracker",
+ ":cronet_aml_third_party_abseil_cpp_absl_strings_internal",
+ ":cronet_aml_third_party_abseil_cpp_absl_strings_str_format",
+ ":cronet_aml_third_party_abseil_cpp_absl_strings_str_format_internal",
+ ":cronet_aml_third_party_abseil_cpp_absl_strings_strings",
+ ":cronet_aml_third_party_abseil_cpp_absl_synchronization_graphcycles_internal",
+ ":cronet_aml_third_party_abseil_cpp_absl_synchronization_kernel_timeout_internal",
+ ":cronet_aml_third_party_abseil_cpp_absl_synchronization_synchronization",
+ ":cronet_aml_third_party_abseil_cpp_absl_time_internal_cctz_civil_time",
+ ":cronet_aml_third_party_abseil_cpp_absl_time_internal_cctz_time_zone",
+ ":cronet_aml_third_party_abseil_cpp_absl_time_time",
+ ":cronet_aml_third_party_abseil_cpp_absl_types_bad_optional_access",
+ ":cronet_aml_third_party_abseil_cpp_absl_types_bad_variant_access",
+ ":cronet_aml_third_party_abseil_cpp_absl_types_compare",
+ ":cronet_aml_third_party_abseil_cpp_absl_types_optional",
+ ":cronet_aml_third_party_abseil_cpp_absl_types_span",
+ ":cronet_aml_third_party_abseil_cpp_absl_types_variant",
+ ":cronet_aml_third_party_abseil_cpp_absl_utility_utility",
+ "net/third_party/quiche/overrides/quiche_platform_impl/quiche_mutex_impl.cc",
+ "net/third_party/quiche/overrides/quiche_platform_impl/quiche_time_utils_impl.cc",
+ "net/third_party/quiche/overrides/quiche_platform_impl/quiche_url_utils_impl.cc",
+ "net/third_party/quiche/src/quiche/common/platform/api/quiche_hostname_utils.cc",
+ "net/third_party/quiche/src/quiche/common/platform/api/quiche_mutex.cc",
+ "net/third_party/quiche/src/quiche/common/platform/default/quiche_platform_impl/quiche_flags_impl.cc",
+ "net/third_party/quiche/src/quiche/common/quiche_buffer_allocator.cc",
+ "net/third_party/quiche/src/quiche/common/quiche_crypto_logging.cc",
+ "net/third_party/quiche/src/quiche/common/quiche_data_reader.cc",
+ "net/third_party/quiche/src/quiche/common/quiche_data_writer.cc",
+ "net/third_party/quiche/src/quiche/common/quiche_ip_address.cc",
+ "net/third_party/quiche/src/quiche/common/quiche_ip_address_family.cc",
+ "net/third_party/quiche/src/quiche/common/quiche_mem_slice_storage.cc",
+ "net/third_party/quiche/src/quiche/common/quiche_random.cc",
+ "net/third_party/quiche/src/quiche/common/quiche_text_utils.cc",
+ "net/third_party/quiche/src/quiche/common/simple_buffer_allocator.cc",
+ "net/third_party/quiche/src/quiche/common/structured_headers.cc",
+ "net/third_party/quiche/src/quiche/http2/adapter/event_forwarder.cc",
+ "net/third_party/quiche/src/quiche/http2/adapter/header_validator.cc",
+ "net/third_party/quiche/src/quiche/http2/adapter/http2_protocol.cc",
+ "net/third_party/quiche/src/quiche/http2/adapter/http2_util.cc",
+ "net/third_party/quiche/src/quiche/http2/adapter/noop_header_validator.cc",
+ "net/third_party/quiche/src/quiche/http2/adapter/oghttp2_adapter.cc",
+ "net/third_party/quiche/src/quiche/http2/adapter/oghttp2_session.cc",
+ "net/third_party/quiche/src/quiche/http2/adapter/oghttp2_util.cc",
+ "net/third_party/quiche/src/quiche/http2/adapter/window_manager.cc",
+ "net/third_party/quiche/src/quiche/http2/core/http2_trace_logging.cc",
+ "net/third_party/quiche/src/quiche/http2/decoder/decode_buffer.cc",
+ "net/third_party/quiche/src/quiche/http2/decoder/decode_http2_structures.cc",
+ "net/third_party/quiche/src/quiche/http2/decoder/decode_status.cc",
+ "net/third_party/quiche/src/quiche/http2/decoder/frame_decoder_state.cc",
+ "net/third_party/quiche/src/quiche/http2/decoder/http2_frame_decoder.cc",
+ "net/third_party/quiche/src/quiche/http2/decoder/http2_frame_decoder_listener.cc",
+ "net/third_party/quiche/src/quiche/http2/decoder/http2_structure_decoder.cc",
+ "net/third_party/quiche/src/quiche/http2/decoder/payload_decoders/altsvc_payload_decoder.cc",
+ "net/third_party/quiche/src/quiche/http2/decoder/payload_decoders/continuation_payload_decoder.cc",
+ "net/third_party/quiche/src/quiche/http2/decoder/payload_decoders/data_payload_decoder.cc",
+ "net/third_party/quiche/src/quiche/http2/decoder/payload_decoders/goaway_payload_decoder.cc",
+ "net/third_party/quiche/src/quiche/http2/decoder/payload_decoders/headers_payload_decoder.cc",
+ "net/third_party/quiche/src/quiche/http2/decoder/payload_decoders/ping_payload_decoder.cc",
+ "net/third_party/quiche/src/quiche/http2/decoder/payload_decoders/priority_payload_decoder.cc",
+ "net/third_party/quiche/src/quiche/http2/decoder/payload_decoders/priority_update_payload_decoder.cc",
+ "net/third_party/quiche/src/quiche/http2/decoder/payload_decoders/push_promise_payload_decoder.cc",
+ "net/third_party/quiche/src/quiche/http2/decoder/payload_decoders/rst_stream_payload_decoder.cc",
+ "net/third_party/quiche/src/quiche/http2/decoder/payload_decoders/settings_payload_decoder.cc",
+ "net/third_party/quiche/src/quiche/http2/decoder/payload_decoders/unknown_payload_decoder.cc",
+ "net/third_party/quiche/src/quiche/http2/decoder/payload_decoders/window_update_payload_decoder.cc",
+ "net/third_party/quiche/src/quiche/http2/hpack/decoder/hpack_block_decoder.cc",
+ "net/third_party/quiche/src/quiche/http2/hpack/decoder/hpack_decoder.cc",
+ "net/third_party/quiche/src/quiche/http2/hpack/decoder/hpack_decoder_listener.cc",
+ "net/third_party/quiche/src/quiche/http2/hpack/decoder/hpack_decoder_state.cc",
+ "net/third_party/quiche/src/quiche/http2/hpack/decoder/hpack_decoder_string_buffer.cc",
+ "net/third_party/quiche/src/quiche/http2/hpack/decoder/hpack_decoder_tables.cc",
+ "net/third_party/quiche/src/quiche/http2/hpack/decoder/hpack_decoding_error.cc",
+ "net/third_party/quiche/src/quiche/http2/hpack/decoder/hpack_entry_decoder.cc",
+ "net/third_party/quiche/src/quiche/http2/hpack/decoder/hpack_entry_decoder_listener.cc",
+ "net/third_party/quiche/src/quiche/http2/hpack/decoder/hpack_entry_type_decoder.cc",
+ "net/third_party/quiche/src/quiche/http2/hpack/decoder/hpack_string_decoder.cc",
+ "net/third_party/quiche/src/quiche/http2/hpack/decoder/hpack_string_decoder_listener.cc",
+ "net/third_party/quiche/src/quiche/http2/hpack/decoder/hpack_whole_entry_buffer.cc",
+ "net/third_party/quiche/src/quiche/http2/hpack/decoder/hpack_whole_entry_listener.cc",
+ "net/third_party/quiche/src/quiche/http2/hpack/http2_hpack_constants.cc",
+ "net/third_party/quiche/src/quiche/http2/hpack/huffman/hpack_huffman_decoder.cc",
+ "net/third_party/quiche/src/quiche/http2/hpack/huffman/hpack_huffman_encoder.cc",
+ "net/third_party/quiche/src/quiche/http2/hpack/huffman/huffman_spec_tables.cc",
+ "net/third_party/quiche/src/quiche/http2/hpack/varint/hpack_varint_decoder.cc",
+ "net/third_party/quiche/src/quiche/http2/hpack/varint/hpack_varint_encoder.cc",
+ "net/third_party/quiche/src/quiche/http2/http2_constants.cc",
+ "net/third_party/quiche/src/quiche/http2/http2_structures.cc",
+ "net/third_party/quiche/src/quiche/quic/core/congestion_control/bandwidth_sampler.cc",
+ "net/third_party/quiche/src/quiche/quic/core/congestion_control/bbr2_drain.cc",
+ "net/third_party/quiche/src/quiche/quic/core/congestion_control/bbr2_misc.cc",
+ "net/third_party/quiche/src/quiche/quic/core/congestion_control/bbr2_probe_bw.cc",
+ "net/third_party/quiche/src/quiche/quic/core/congestion_control/bbr2_probe_rtt.cc",
+ "net/third_party/quiche/src/quiche/quic/core/congestion_control/bbr2_sender.cc",
+ "net/third_party/quiche/src/quiche/quic/core/congestion_control/bbr2_startup.cc",
+ "net/third_party/quiche/src/quiche/quic/core/congestion_control/bbr_sender.cc",
+ "net/third_party/quiche/src/quiche/quic/core/congestion_control/cubic_bytes.cc",
+ "net/third_party/quiche/src/quiche/quic/core/congestion_control/general_loss_algorithm.cc",
+ "net/third_party/quiche/src/quiche/quic/core/congestion_control/hybrid_slow_start.cc",
+ "net/third_party/quiche/src/quiche/quic/core/congestion_control/pacing_sender.cc",
+ "net/third_party/quiche/src/quiche/quic/core/congestion_control/prr_sender.cc",
+ "net/third_party/quiche/src/quiche/quic/core/congestion_control/rtt_stats.cc",
+ "net/third_party/quiche/src/quiche/quic/core/congestion_control/send_algorithm_interface.cc",
+ "net/third_party/quiche/src/quiche/quic/core/congestion_control/tcp_cubic_sender_bytes.cc",
+ "net/third_party/quiche/src/quiche/quic/core/congestion_control/uber_loss_algorithm.cc",
+ "net/third_party/quiche/src/quiche/quic/core/crypto/aead_base_decrypter.cc",
+ "net/third_party/quiche/src/quiche/quic/core/crypto/aead_base_encrypter.cc",
+ "net/third_party/quiche/src/quiche/quic/core/crypto/aes_128_gcm_12_decrypter.cc",
+ "net/third_party/quiche/src/quiche/quic/core/crypto/aes_128_gcm_12_encrypter.cc",
+ "net/third_party/quiche/src/quiche/quic/core/crypto/aes_128_gcm_decrypter.cc",
+ "net/third_party/quiche/src/quiche/quic/core/crypto/aes_128_gcm_encrypter.cc",
+ "net/third_party/quiche/src/quiche/quic/core/crypto/aes_256_gcm_decrypter.cc",
+ "net/third_party/quiche/src/quiche/quic/core/crypto/aes_256_gcm_encrypter.cc",
+ "net/third_party/quiche/src/quiche/quic/core/crypto/aes_base_decrypter.cc",
+ "net/third_party/quiche/src/quiche/quic/core/crypto/aes_base_encrypter.cc",
+ "net/third_party/quiche/src/quiche/quic/core/crypto/cert_compressor.cc",
+ "net/third_party/quiche/src/quiche/quic/core/crypto/certificate_util.cc",
+ "net/third_party/quiche/src/quiche/quic/core/crypto/certificate_view.cc",
+ "net/third_party/quiche/src/quiche/quic/core/crypto/chacha20_poly1305_decrypter.cc",
+ "net/third_party/quiche/src/quiche/quic/core/crypto/chacha20_poly1305_encrypter.cc",
+ "net/third_party/quiche/src/quiche/quic/core/crypto/chacha20_poly1305_tls_decrypter.cc",
+ "net/third_party/quiche/src/quiche/quic/core/crypto/chacha20_poly1305_tls_encrypter.cc",
+ "net/third_party/quiche/src/quiche/quic/core/crypto/chacha_base_decrypter.cc",
+ "net/third_party/quiche/src/quiche/quic/core/crypto/chacha_base_encrypter.cc",
+ "net/third_party/quiche/src/quiche/quic/core/crypto/channel_id.cc",
+ "net/third_party/quiche/src/quiche/quic/core/crypto/client_proof_source.cc",
+ "net/third_party/quiche/src/quiche/quic/core/crypto/crypto_framer.cc",
+ "net/third_party/quiche/src/quiche/quic/core/crypto/crypto_handshake.cc",
+ "net/third_party/quiche/src/quiche/quic/core/crypto/crypto_handshake_message.cc",
+ "net/third_party/quiche/src/quiche/quic/core/crypto/crypto_secret_boxer.cc",
+ "net/third_party/quiche/src/quiche/quic/core/crypto/crypto_utils.cc",
+ "net/third_party/quiche/src/quiche/quic/core/crypto/curve25519_key_exchange.cc",
+ "net/third_party/quiche/src/quiche/quic/core/crypto/key_exchange.cc",
+ "net/third_party/quiche/src/quiche/quic/core/crypto/null_decrypter.cc",
+ "net/third_party/quiche/src/quiche/quic/core/crypto/null_encrypter.cc",
+ "net/third_party/quiche/src/quiche/quic/core/crypto/p256_key_exchange.cc",
+ "net/third_party/quiche/src/quiche/quic/core/crypto/proof_source.cc",
+ "net/third_party/quiche/src/quiche/quic/core/crypto/proof_source_x509.cc",
+ "net/third_party/quiche/src/quiche/quic/core/crypto/quic_client_session_cache.cc",
+ "net/third_party/quiche/src/quiche/quic/core/crypto/quic_compressed_certs_cache.cc",
+ "net/third_party/quiche/src/quiche/quic/core/crypto/quic_crypter.cc",
+ "net/third_party/quiche/src/quiche/quic/core/crypto/quic_crypto_client_config.cc",
+ "net/third_party/quiche/src/quiche/quic/core/crypto/quic_crypto_proof.cc",
+ "net/third_party/quiche/src/quiche/quic/core/crypto/quic_crypto_server_config.cc",
+ "net/third_party/quiche/src/quiche/quic/core/crypto/quic_decrypter.cc",
+ "net/third_party/quiche/src/quiche/quic/core/crypto/quic_encrypter.cc",
+ "net/third_party/quiche/src/quiche/quic/core/crypto/quic_hkdf.cc",
+ "net/third_party/quiche/src/quiche/quic/core/crypto/tls_client_connection.cc",
+ "net/third_party/quiche/src/quiche/quic/core/crypto/tls_connection.cc",
+ "net/third_party/quiche/src/quiche/quic/core/crypto/tls_server_connection.cc",
+ "net/third_party/quiche/src/quiche/quic/core/crypto/transport_parameters.cc",
+ "net/third_party/quiche/src/quiche/quic/core/crypto/web_transport_fingerprint_proof_verifier.cc",
+ "net/third_party/quiche/src/quiche/quic/core/deterministic_connection_id_generator.cc",
+ "net/third_party/quiche/src/quiche/quic/core/frames/quic_ack_frame.cc",
+ "net/third_party/quiche/src/quiche/quic/core/frames/quic_ack_frequency_frame.cc",
+ "net/third_party/quiche/src/quiche/quic/core/frames/quic_blocked_frame.cc",
+ "net/third_party/quiche/src/quiche/quic/core/frames/quic_connection_close_frame.cc",
+ "net/third_party/quiche/src/quiche/quic/core/frames/quic_crypto_frame.cc",
+ "net/third_party/quiche/src/quiche/quic/core/frames/quic_frame.cc",
+ "net/third_party/quiche/src/quiche/quic/core/frames/quic_goaway_frame.cc",
+ "net/third_party/quiche/src/quiche/quic/core/frames/quic_handshake_done_frame.cc",
+ "net/third_party/quiche/src/quiche/quic/core/frames/quic_max_streams_frame.cc",
+ "net/third_party/quiche/src/quiche/quic/core/frames/quic_message_frame.cc",
+ "net/third_party/quiche/src/quiche/quic/core/frames/quic_new_connection_id_frame.cc",
+ "net/third_party/quiche/src/quiche/quic/core/frames/quic_new_token_frame.cc",
+ "net/third_party/quiche/src/quiche/quic/core/frames/quic_padding_frame.cc",
+ "net/third_party/quiche/src/quiche/quic/core/frames/quic_path_challenge_frame.cc",
+ "net/third_party/quiche/src/quiche/quic/core/frames/quic_path_response_frame.cc",
+ "net/third_party/quiche/src/quiche/quic/core/frames/quic_ping_frame.cc",
+ "net/third_party/quiche/src/quiche/quic/core/frames/quic_retire_connection_id_frame.cc",
+ "net/third_party/quiche/src/quiche/quic/core/frames/quic_rst_stream_frame.cc",
+ "net/third_party/quiche/src/quiche/quic/core/frames/quic_stop_sending_frame.cc",
+ "net/third_party/quiche/src/quiche/quic/core/frames/quic_stop_waiting_frame.cc",
+ "net/third_party/quiche/src/quiche/quic/core/frames/quic_stream_frame.cc",
+ "net/third_party/quiche/src/quiche/quic/core/frames/quic_streams_blocked_frame.cc",
+ "net/third_party/quiche/src/quiche/quic/core/frames/quic_window_update_frame.cc",
+ "net/third_party/quiche/src/quiche/quic/core/http/capsule.cc",
+ "net/third_party/quiche/src/quiche/quic/core/http/http_constants.cc",
+ "net/third_party/quiche/src/quiche/quic/core/http/http_decoder.cc",
+ "net/third_party/quiche/src/quiche/quic/core/http/http_encoder.cc",
+ "net/third_party/quiche/src/quiche/quic/core/http/quic_client_promised_info.cc",
+ "net/third_party/quiche/src/quiche/quic/core/http/quic_client_push_promise_index.cc",
+ "net/third_party/quiche/src/quiche/quic/core/http/quic_header_list.cc",
+ "net/third_party/quiche/src/quiche/quic/core/http/quic_headers_stream.cc",
+ "net/third_party/quiche/src/quiche/quic/core/http/quic_receive_control_stream.cc",
+ "net/third_party/quiche/src/quiche/quic/core/http/quic_send_control_stream.cc",
+ "net/third_party/quiche/src/quiche/quic/core/http/quic_server_initiated_spdy_stream.cc",
+ "net/third_party/quiche/src/quiche/quic/core/http/quic_server_session_base.cc",
+ "net/third_party/quiche/src/quiche/quic/core/http/quic_spdy_client_session.cc",
+ "net/third_party/quiche/src/quiche/quic/core/http/quic_spdy_client_session_base.cc",
+ "net/third_party/quiche/src/quiche/quic/core/http/quic_spdy_client_stream.cc",
+ "net/third_party/quiche/src/quiche/quic/core/http/quic_spdy_session.cc",
+ "net/third_party/quiche/src/quiche/quic/core/http/quic_spdy_stream.cc",
+ "net/third_party/quiche/src/quiche/quic/core/http/quic_spdy_stream_body_manager.cc",
+ "net/third_party/quiche/src/quiche/quic/core/http/spdy_server_push_utils.cc",
+ "net/third_party/quiche/src/quiche/quic/core/http/spdy_utils.cc",
+ "net/third_party/quiche/src/quiche/quic/core/http/web_transport_http3.cc",
+ "net/third_party/quiche/src/quiche/quic/core/http/web_transport_stream_adapter.cc",
+ "net/third_party/quiche/src/quiche/quic/core/legacy_quic_stream_id_manager.cc",
+ "net/third_party/quiche/src/quiche/quic/core/qpack/qpack_blocking_manager.cc",
+ "net/third_party/quiche/src/quiche/quic/core/qpack/qpack_decoded_headers_accumulator.cc",
+ "net/third_party/quiche/src/quiche/quic/core/qpack/qpack_decoder.cc",
+ "net/third_party/quiche/src/quiche/quic/core/qpack/qpack_decoder_stream_receiver.cc",
+ "net/third_party/quiche/src/quiche/quic/core/qpack/qpack_decoder_stream_sender.cc",
+ "net/third_party/quiche/src/quiche/quic/core/qpack/qpack_encoder.cc",
+ "net/third_party/quiche/src/quiche/quic/core/qpack/qpack_encoder_stream_receiver.cc",
+ "net/third_party/quiche/src/quiche/quic/core/qpack/qpack_encoder_stream_sender.cc",
+ "net/third_party/quiche/src/quiche/quic/core/qpack/qpack_header_table.cc",
+ "net/third_party/quiche/src/quiche/quic/core/qpack/qpack_index_conversions.cc",
+ "net/third_party/quiche/src/quiche/quic/core/qpack/qpack_instruction_decoder.cc",
+ "net/third_party/quiche/src/quiche/quic/core/qpack/qpack_instruction_encoder.cc",
+ "net/third_party/quiche/src/quiche/quic/core/qpack/qpack_instructions.cc",
+ "net/third_party/quiche/src/quiche/quic/core/qpack/qpack_progressive_decoder.cc",
+ "net/third_party/quiche/src/quiche/quic/core/qpack/qpack_receive_stream.cc",
+ "net/third_party/quiche/src/quiche/quic/core/qpack/qpack_required_insert_count.cc",
+ "net/third_party/quiche/src/quiche/quic/core/qpack/qpack_send_stream.cc",
+ "net/third_party/quiche/src/quiche/quic/core/qpack/qpack_static_table.cc",
+ "net/third_party/quiche/src/quiche/quic/core/qpack/value_splitting_header_list.cc",
+ "net/third_party/quiche/src/quiche/quic/core/quic_ack_listener_interface.cc",
+ "net/third_party/quiche/src/quiche/quic/core/quic_alarm.cc",
+ "net/third_party/quiche/src/quiche/quic/core/quic_bandwidth.cc",
+ "net/third_party/quiche/src/quiche/quic/core/quic_chaos_protector.cc",
+ "net/third_party/quiche/src/quiche/quic/core/quic_clock.cc",
+ "net/third_party/quiche/src/quiche/quic/core/quic_coalesced_packet.cc",
+ "net/third_party/quiche/src/quiche/quic/core/quic_config.cc",
+ "net/third_party/quiche/src/quiche/quic/core/quic_connection.cc",
+ "net/third_party/quiche/src/quiche/quic/core/quic_connection_context.cc",
+ "net/third_party/quiche/src/quiche/quic/core/quic_connection_id.cc",
+ "net/third_party/quiche/src/quiche/quic/core/quic_connection_id_manager.cc",
+ "net/third_party/quiche/src/quiche/quic/core/quic_connection_stats.cc",
+ "net/third_party/quiche/src/quiche/quic/core/quic_constants.cc",
+ "net/third_party/quiche/src/quiche/quic/core/quic_control_frame_manager.cc",
+ "net/third_party/quiche/src/quiche/quic/core/quic_crypto_client_handshaker.cc",
+ "net/third_party/quiche/src/quiche/quic/core/quic_crypto_client_stream.cc",
+ "net/third_party/quiche/src/quiche/quic/core/quic_crypto_handshaker.cc",
+ "net/third_party/quiche/src/quiche/quic/core/quic_crypto_server_stream.cc",
+ "net/third_party/quiche/src/quiche/quic/core/quic_crypto_server_stream_base.cc",
+ "net/third_party/quiche/src/quiche/quic/core/quic_crypto_stream.cc",
+ "net/third_party/quiche/src/quiche/quic/core/quic_data_reader.cc",
+ "net/third_party/quiche/src/quiche/quic/core/quic_data_writer.cc",
+ "net/third_party/quiche/src/quiche/quic/core/quic_datagram_queue.cc",
+ "net/third_party/quiche/src/quiche/quic/core/quic_error_codes.cc",
+ "net/third_party/quiche/src/quiche/quic/core/quic_flow_controller.cc",
+ "net/third_party/quiche/src/quiche/quic/core/quic_framer.cc",
+ "net/third_party/quiche/src/quiche/quic/core/quic_idle_network_detector.cc",
+ "net/third_party/quiche/src/quiche/quic/core/quic_mtu_discovery.cc",
+ "net/third_party/quiche/src/quiche/quic/core/quic_network_blackhole_detector.cc",
+ "net/third_party/quiche/src/quiche/quic/core/quic_packet_creator.cc",
+ "net/third_party/quiche/src/quiche/quic/core/quic_packet_number.cc",
+ "net/third_party/quiche/src/quiche/quic/core/quic_packets.cc",
+ "net/third_party/quiche/src/quiche/quic/core/quic_path_validator.cc",
+ "net/third_party/quiche/src/quiche/quic/core/quic_ping_manager.cc",
+ "net/third_party/quiche/src/quiche/quic/core/quic_received_packet_manager.cc",
+ "net/third_party/quiche/src/quiche/quic/core/quic_sent_packet_manager.cc",
+ "net/third_party/quiche/src/quiche/quic/core/quic_server_id.cc",
+ "net/third_party/quiche/src/quiche/quic/core/quic_session.cc",
+ "net/third_party/quiche/src/quiche/quic/core/quic_socket_address_coder.cc",
+ "net/third_party/quiche/src/quiche/quic/core/quic_stream.cc",
+ "net/third_party/quiche/src/quiche/quic/core/quic_stream_id_manager.cc",
+ "net/third_party/quiche/src/quiche/quic/core/quic_stream_send_buffer.cc",
+ "net/third_party/quiche/src/quiche/quic/core/quic_stream_sequencer.cc",
+ "net/third_party/quiche/src/quiche/quic/core/quic_stream_sequencer_buffer.cc",
+ "net/third_party/quiche/src/quiche/quic/core/quic_sustained_bandwidth_recorder.cc",
+ "net/third_party/quiche/src/quiche/quic/core/quic_tag.cc",
+ "net/third_party/quiche/src/quiche/quic/core/quic_time.cc",
+ "net/third_party/quiche/src/quiche/quic/core/quic_transmission_info.cc",
+ "net/third_party/quiche/src/quiche/quic/core/quic_types.cc",
+ "net/third_party/quiche/src/quiche/quic/core/quic_unacked_packet_map.cc",
+ "net/third_party/quiche/src/quiche/quic/core/quic_utils.cc",
+ "net/third_party/quiche/src/quiche/quic/core/quic_version_manager.cc",
+ "net/third_party/quiche/src/quiche/quic/core/quic_versions.cc",
+ "net/third_party/quiche/src/quiche/quic/core/quic_write_blocked_list.cc",
+ "net/third_party/quiche/src/quiche/quic/core/tls_client_handshaker.cc",
+ "net/third_party/quiche/src/quiche/quic/core/tls_handshaker.cc",
+ "net/third_party/quiche/src/quiche/quic/core/tls_server_handshaker.cc",
+ "net/third_party/quiche/src/quiche/quic/core/uber_quic_stream_id_manager.cc",
+ "net/third_party/quiche/src/quiche/quic/core/uber_received_packet_manager.cc",
+ "net/third_party/quiche/src/quiche/quic/platform/api/quic_socket_address.cc",
+ "net/third_party/quiche/src/quiche/spdy/core/array_output_buffer.cc",
+ "net/third_party/quiche/src/quiche/spdy/core/hpack/hpack_constants.cc",
+ "net/third_party/quiche/src/quiche/spdy/core/hpack/hpack_decoder_adapter.cc",
+ "net/third_party/quiche/src/quiche/spdy/core/hpack/hpack_encoder.cc",
+ "net/third_party/quiche/src/quiche/spdy/core/hpack/hpack_entry.cc",
+ "net/third_party/quiche/src/quiche/spdy/core/hpack/hpack_header_table.cc",
+ "net/third_party/quiche/src/quiche/spdy/core/hpack/hpack_output_stream.cc",
+ "net/third_party/quiche/src/quiche/spdy/core/hpack/hpack_static_table.cc",
+ "net/third_party/quiche/src/quiche/spdy/core/http2_frame_decoder_adapter.cc",
+ "net/third_party/quiche/src/quiche/spdy/core/http2_header_block.cc",
+ "net/third_party/quiche/src/quiche/spdy/core/http2_header_storage.cc",
+ "net/third_party/quiche/src/quiche/spdy/core/recording_headers_handler.cc",
+ "net/third_party/quiche/src/quiche/spdy/core/spdy_alt_svc_wire_format.cc",
+ "net/third_party/quiche/src/quiche/spdy/core/spdy_frame_builder.cc",
+ "net/third_party/quiche/src/quiche/spdy/core/spdy_framer.cc",
+ "net/third_party/quiche/src/quiche/spdy/core/spdy_no_op_visitor.cc",
+ "net/third_party/quiche/src/quiche/spdy/core/spdy_pinnable_buffer_piece.cc",
+ "net/third_party/quiche/src/quiche/spdy/core/spdy_prefixed_buffer_reader.cc",
+ "net/third_party/quiche/src/quiche/spdy/core/spdy_protocol.cc",
+ "net/third_party/quiche/src/quiche/spdy/core/spdy_simple_arena.cc",
+ ],
+ shared_libs: [
+ "libandroid",
+ "liblog",
+ ],
+ static_libs: [
+ "cronet_aml_base_base",
+ "cronet_aml_net_third_party_quiche_net_quic_proto",
+ "cronet_aml_net_uri_template",
+ "cronet_aml_third_party_boringssl_boringssl",
+ "cronet_aml_third_party_protobuf_protobuf_lite",
+ "cronet_aml_third_party_zlib_zlib",
+ "cronet_aml_url_url",
+ ],
+ generated_headers: [
+ "cronet_aml_build_chromeos_buildflags",
+ ],
+ export_generated_headers: [
+ "cronet_aml_build_chromeos_buildflags",
+ ],
+ defaults: [
+ "cronet_aml_defaults",
+ ],
+ cflags: [
+ "-DABSL_ALLOCATOR_NOTHROW=1",
+ "-DANDROID",
+ "-DANDROID_NDK_VERSION_ROLL=r23_1",
+ "-DCR_CLANG_REVISION=\"llvmorg-16-init-8697-g60809cd2-1\"",
+ "-DCR_LIBCXX_REVISION=47b31179d10646029c260702650a25d24f555acc",
+ "-DDCHECK_ALWAYS_ON=1",
+ "-DDYNAMIC_ANNOTATIONS_ENABLED=1",
+ "-DGOOGLE_PROTOBUF_INTERNAL_DONATE_STEAL_INLINE=0",
+ "-DGOOGLE_PROTOBUF_NO_RTTI",
+ "-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER",
+ "-DHAVE_PTHREAD",
+ "-DHAVE_SYS_UIO_H",
+ "-DIS_QUICHE_IMPL",
+ "-D_DEBUG",
+ "-D_GNU_SOURCE",
+ "-D_LIBCPP_AVAILABILITY_CUSTOM_VERBOSE_ABORT_PROVIDED=1",
+ "-D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS",
+ "-D_LIBCPP_ENABLE_ASSERTIONS_DEFAULT=1",
+ "-D_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS",
+ "-D__STDC_CONSTANT_MACROS",
+ "-D__STDC_FORMAT_MACROS",
+ ],
+ local_include_dirs: [
+ "./",
+ "buildtools/third_party/libc++/",
+ "buildtools/third_party/libc++/trunk/include",
+ "buildtools/third_party/libc++abi/trunk/include",
+ "net/third_party/quiche/overrides/",
+ "net/third_party/quiche/src/",
+ "net/third_party/quiche/src/quiche/common/platform/default/",
+ "third_party/abseil-cpp/",
+ "third_party/boringssl/src/include/",
+ "third_party/protobuf/src/",
+ "third_party/zlib/",
+ "third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include",
+ ],
+ cpp_std: "c++20",
+}
+
+// GN: //net/tools/root_store_tool:root_store_tool
+cc_binary {
+ name: "cronet_aml_net_tools_root_store_tool_root_store_tool",
+ srcs: [
+ ":cronet_aml_buildtools_third_party_libc___libc__",
+ ":cronet_aml_buildtools_third_party_libc__abi_libc__abi",
+ "net/tools/root_store_tool/root_store_tool.cc",
+ ],
+ static_libs: [
+ "cronet_aml_base_base",
+ "cronet_aml_crypto_crypto",
+ "cronet_aml_net_cert_root_store_proto_full",
+ "cronet_aml_third_party_boringssl_boringssl",
+ ],
+ defaults: [
+ "cronet_aml_defaults",
+ ],
+ cflags: [
+ "-DCR_CLANG_REVISION=\"llvmorg-16-init-8697-g60809cd2-1\"",
+ "-DCR_LIBCXX_REVISION=47b31179d10646029c260702650a25d24f555acc",
+ "-DCR_SYSROOT_KEY=20220331T153654Z-0",
+ "-DDCHECK_ALWAYS_ON=1",
+ "-DDYNAMIC_ANNOTATIONS_ENABLED=1",
+ "-DGOOGLE_PROTOBUF_INTERNAL_DONATE_STEAL_INLINE=0",
+ "-DGOOGLE_PROTOBUF_NO_RTTI",
+ "-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER",
+ "-DHAVE_PTHREAD",
+ "-DLIBCXXABI_SILENT_TERMINATE",
+ "-DLIBCXX_BUILDING_LIBCXXABI",
+ "-DUSE_AURA=1",
+ "-DUSE_OZONE=1",
+ "-DUSE_UDEV",
+ "-D_DEBUG",
+ "-D_FILE_OFFSET_BITS=64",
+ "-D_GNU_SOURCE",
+ "-D_LARGEFILE64_SOURCE",
+ "-D_LARGEFILE_SOURCE",
+ "-D_LIBCPP_AVAILABILITY_CUSTOM_VERBOSE_ABORT_PROVIDED=1",
+ "-D_LIBCPP_BUILDING_LIBRARY",
+ "-D_LIBCPP_CONSTINIT=constinit",
+ "-D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS",
+ "-D_LIBCPP_ENABLE_ASSERTIONS_DEFAULT=1",
+ "-D_LIBCPP_OVERRIDABLE_FUNC_VIS=__attribute__((__visibility__(\"default\")))",
+ "-D_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS",
+ "-D__STDC_CONSTANT_MACROS",
+ "-D__STDC_FORMAT_MACROS",
+ ],
+ local_include_dirs: [
+ "./",
+ "buildtools/third_party/libc++/",
+ "buildtools/third_party/libc++/trunk/include",
+ "buildtools/third_party/libc++/trunk/src/",
+ "buildtools/third_party/libc++abi/trunk/include",
+ "third_party/abseil-cpp/",
+ "third_party/boringssl/src/include/",
+ "third_party/protobuf/src/",
+ "build/linux/debian_bullseye_amd64-sysroot/usr/include",
+ ],
+ cpp_std: "c++20",
+}
+
+// GN: //net/traffic_annotation:traffic_annotation
+filegroup {
+ name: "cronet_aml_net_traffic_annotation_traffic_annotation",
+ srcs: [
+ "net/traffic_annotation/network_traffic_annotation_android.cc",
+ ],
+}
+
+// GN: //net:uri_template
+cc_library_static {
+ name: "cronet_aml_net_uri_template",
+ srcs: [
+ "net/third_party/uri_template/uri_template.cc",
+ ],
+ shared_libs: [
+ "libandroid",
+ "liblog",
+ ],
+ static_libs: [
+ "cronet_aml_base_base",
+ ],
+ defaults: [
+ "cronet_aml_defaults",
+ ],
+ cflags: [
+ "-DANDROID",
+ "-DANDROID_NDK_VERSION_ROLL=r23_1",
+ "-DCR_CLANG_REVISION=\"llvmorg-16-init-8697-g60809cd2-1\"",
+ "-DCR_LIBCXX_REVISION=47b31179d10646029c260702650a25d24f555acc",
+ "-DDCHECK_ALWAYS_ON=1",
+ "-DDYNAMIC_ANNOTATIONS_ENABLED=1",
+ "-DHAVE_SYS_UIO_H",
+ "-DIS_URI_TEMPLATE_IMPL",
+ "-D_DEBUG",
+ "-D_GNU_SOURCE",
+ "-D_LIBCPP_AVAILABILITY_CUSTOM_VERBOSE_ABORT_PROVIDED=1",
+ "-D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS",
+ "-D_LIBCPP_ENABLE_ASSERTIONS_DEFAULT=1",
+ "-D_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS",
+ "-D__STDC_CONSTANT_MACROS",
+ "-D__STDC_FORMAT_MACROS",
+ ],
+ local_include_dirs: [
+ "./",
+ "buildtools/third_party/libc++/",
+ "buildtools/third_party/libc++/trunk/include",
+ "buildtools/third_party/libc++abi/trunk/include",
+ "third_party/abseil-cpp/",
+ "third_party/boringssl/src/include/",
+ "third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include",
+ ],
+ cpp_std: "c++20",
+}
+
+// GN: //third_party/abseil-cpp:absl
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl",
+}
+
+// GN: //third_party/abseil-cpp/absl/algorithm:algorithm
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_algorithm_algorithm",
+}
+
+// GN: //third_party/abseil-cpp/absl/algorithm:container
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_algorithm_container",
+}
+
+// GN: //third_party/abseil-cpp/absl/base:atomic_hook
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_base_atomic_hook",
+}
+
+// GN: //third_party/abseil-cpp/absl/base:base
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_base_base",
+ srcs: [
+ "third_party/abseil-cpp/absl/base/internal/cycleclock.cc",
+ "third_party/abseil-cpp/absl/base/internal/spinlock.cc",
+ "third_party/abseil-cpp/absl/base/internal/sysinfo.cc",
+ "third_party/abseil-cpp/absl/base/internal/thread_identity.cc",
+ "third_party/abseil-cpp/absl/base/internal/unscaledcycleclock.cc",
+ ],
+}
+
+// GN: //third_party/abseil-cpp/absl/base:base_internal
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_base_base_internal",
+}
+
+// GN: //third_party/abseil-cpp/absl/base:config
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_base_config",
+}
+
+// GN: //third_party/abseil-cpp/absl/base:core_headers
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_base_core_headers",
+}
+
+// GN: //third_party/abseil-cpp/absl/base:cycleclock_internal
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_base_cycleclock_internal",
+}
+
+// GN: //third_party/abseil-cpp/absl/base:dynamic_annotations
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_base_dynamic_annotations",
+}
+
+// GN: //third_party/abseil-cpp/absl/base:endian
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_base_endian",
+}
+
+// GN: //third_party/abseil-cpp/absl/base:errno_saver
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_base_errno_saver",
+}
+
+// GN: //third_party/abseil-cpp/absl/base:fast_type_id
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_base_fast_type_id",
+}
+
+// GN: //third_party/abseil-cpp/absl/base:log_severity
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_base_log_severity",
+ srcs: [
+ "third_party/abseil-cpp/absl/base/log_severity.cc",
+ ],
+}
+
+// GN: //third_party/abseil-cpp/absl/base:malloc_internal
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_base_malloc_internal",
+ srcs: [
+ "third_party/abseil-cpp/absl/base/internal/low_level_alloc.cc",
+ ],
+}
+
+// GN: //third_party/abseil-cpp/absl/base:prefetch
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_base_prefetch",
+}
+
+// GN: //third_party/abseil-cpp/absl/base:raw_logging_internal
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_base_raw_logging_internal",
+ srcs: [
+ "third_party/abseil-cpp/absl/base/internal/raw_logging.cc",
+ ],
+}
+
+// GN: //third_party/abseil-cpp/absl/base:spinlock_wait
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_base_spinlock_wait",
+ srcs: [
+ "third_party/abseil-cpp/absl/base/internal/spinlock_wait.cc",
+ ],
+}
+
+// GN: //third_party/abseil-cpp/absl/base:strerror
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_base_strerror",
+ srcs: [
+ "third_party/abseil-cpp/absl/base/internal/strerror.cc",
+ ],
+}
+
+// GN: //third_party/abseil-cpp/absl/base:throw_delegate
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_base_throw_delegate",
+ srcs: [
+ "third_party/abseil-cpp/absl/base/internal/throw_delegate.cc",
+ ],
+}
+
+// GN: //third_party/abseil-cpp/absl/cleanup:cleanup
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_cleanup_cleanup",
+}
+
+// GN: //third_party/abseil-cpp/absl/cleanup:cleanup_internal
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_cleanup_cleanup_internal",
+}
+
+// GN: //third_party/abseil-cpp/absl/container:btree
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_container_btree",
+}
+
+// GN: //third_party/abseil-cpp/absl/container:common
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_container_common",
+}
+
+// GN: //third_party/abseil-cpp/absl/container:common_policy_traits
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_container_common_policy_traits",
+}
+
+// GN: //third_party/abseil-cpp/absl/container:compressed_tuple
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_container_compressed_tuple",
+}
+
+// GN: //third_party/abseil-cpp/absl/container:container_memory
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_container_container_memory",
+}
+
+// GN: //third_party/abseil-cpp/absl/container:fixed_array
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_container_fixed_array",
+}
+
+// GN: //third_party/abseil-cpp/absl/container:flat_hash_map
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_container_flat_hash_map",
+}
+
+// GN: //third_party/abseil-cpp/absl/container:flat_hash_set
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_container_flat_hash_set",
+}
+
+// GN: //third_party/abseil-cpp/absl/container:hash_function_defaults
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_container_hash_function_defaults",
+}
+
+// GN: //third_party/abseil-cpp/absl/container:hash_policy_traits
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_container_hash_policy_traits",
+}
+
+// GN: //third_party/abseil-cpp/absl/container:hashtable_debug_hooks
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_container_hashtable_debug_hooks",
+}
+
+// GN: //third_party/abseil-cpp/absl/container:hashtablez_sampler
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_container_hashtablez_sampler",
+ srcs: [
+ "third_party/abseil-cpp/absl/container/internal/hashtablez_sampler.cc",
+ "third_party/abseil-cpp/absl/container/internal/hashtablez_sampler_force_weak_definition.cc",
+ ],
+}
+
+// GN: //third_party/abseil-cpp/absl/container:inlined_vector
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_container_inlined_vector",
+}
+
+// GN: //third_party/abseil-cpp/absl/container:inlined_vector_internal
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_container_inlined_vector_internal",
+}
+
+// GN: //third_party/abseil-cpp/absl/container:layout
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_container_layout",
+}
+
+// GN: //third_party/abseil-cpp/absl/container:node_hash_map
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_container_node_hash_map",
+}
+
+// GN: //third_party/abseil-cpp/absl/container:node_hash_set
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_container_node_hash_set",
+}
+
+// GN: //third_party/abseil-cpp/absl/container:node_slot_policy
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_container_node_slot_policy",
+}
+
+// GN: //third_party/abseil-cpp/absl/container:raw_hash_map
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_container_raw_hash_map",
+}
+
+// GN: //third_party/abseil-cpp/absl/container:raw_hash_set
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_container_raw_hash_set",
+ srcs: [
+ "third_party/abseil-cpp/absl/container/internal/raw_hash_set.cc",
+ ],
+}
+
+// GN: //third_party/abseil-cpp/absl/debugging:debugging_internal
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_debugging_debugging_internal",
+ srcs: [
+ "third_party/abseil-cpp/absl/debugging/internal/address_is_readable.cc",
+ "third_party/abseil-cpp/absl/debugging/internal/elf_mem_image.cc",
+ "third_party/abseil-cpp/absl/debugging/internal/vdso_support.cc",
+ ],
+}
+
+// GN: //third_party/abseil-cpp/absl/debugging:demangle_internal
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_debugging_demangle_internal",
+ srcs: [
+ "third_party/abseil-cpp/absl/debugging/internal/demangle.cc",
+ ],
+}
+
+// GN: //third_party/abseil-cpp/absl/debugging:examine_stack
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_debugging_examine_stack",
+ srcs: [
+ "third_party/abseil-cpp/absl/debugging/internal/examine_stack.cc",
+ ],
+}
+
+// GN: //third_party/abseil-cpp/absl/debugging:failure_signal_handler
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_debugging_failure_signal_handler",
+ srcs: [
+ "third_party/abseil-cpp/absl/debugging/failure_signal_handler.cc",
+ ],
+}
+
+// GN: //third_party/abseil-cpp/absl/debugging:stacktrace
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_debugging_stacktrace",
+ srcs: [
+ "third_party/abseil-cpp/absl/debugging/stacktrace.cc",
+ ],
+}
+
+// GN: //third_party/abseil-cpp/absl/debugging:symbolize
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_debugging_symbolize",
+ srcs: [
+ "third_party/abseil-cpp/absl/debugging/symbolize.cc",
+ ],
+}
+
+// GN: //third_party/abseil-cpp/absl/functional:any_invocable
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_functional_any_invocable",
+}
+
+// GN: //third_party/abseil-cpp/absl/functional:bind_front
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_functional_bind_front",
+}
+
+// GN: //third_party/abseil-cpp/absl/functional:function_ref
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_functional_function_ref",
+}
+
+// GN: //third_party/abseil-cpp/absl/hash:city
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_hash_city",
+ srcs: [
+ "third_party/abseil-cpp/absl/hash/internal/city.cc",
+ ],
+}
+
+// GN: //third_party/abseil-cpp/absl/hash:hash
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_hash_hash",
+ srcs: [
+ "third_party/abseil-cpp/absl/hash/internal/hash.cc",
+ ],
+}
+
+// GN: //third_party/abseil-cpp/absl/hash:low_level_hash
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_hash_low_level_hash",
+ srcs: [
+ "third_party/abseil-cpp/absl/hash/internal/low_level_hash.cc",
+ ],
+}
+
+// GN: //third_party/abseil-cpp/absl/memory:memory
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_memory_memory",
+}
+
+// GN: //third_party/abseil-cpp/absl/meta:type_traits
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_meta_type_traits",
+}
+
+// GN: //third_party/abseil-cpp/absl/numeric:bits
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_numeric_bits",
+}
+
+// GN: //third_party/abseil-cpp/absl/numeric:int128
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_numeric_int128",
+ srcs: [
+ "third_party/abseil-cpp/absl/numeric/int128.cc",
+ ],
+}
+
+// GN: //third_party/abseil-cpp/absl/numeric:representation
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_numeric_representation",
+}
+
+// GN: //third_party/abseil-cpp/absl/profiling:exponential_biased
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_profiling_exponential_biased",
+ srcs: [
+ "third_party/abseil-cpp/absl/profiling/internal/exponential_biased.cc",
+ ],
+}
+
+// GN: //third_party/abseil-cpp/absl/profiling:sample_recorder
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_profiling_sample_recorder",
+}
+
+// GN: //third_party/abseil-cpp/absl/random:distributions
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_random_distributions",
+ srcs: [
+ "third_party/abseil-cpp/absl/random/discrete_distribution.cc",
+ "third_party/abseil-cpp/absl/random/gaussian_distribution.cc",
+ ],
+}
+
+// GN: //third_party/abseil-cpp/absl/random/internal:distribution_caller
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_random_internal_distribution_caller",
+}
+
+// GN: //third_party/abseil-cpp/absl/random/internal:fast_uniform_bits
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_random_internal_fast_uniform_bits",
+}
+
+// GN: //third_party/abseil-cpp/absl/random/internal:fastmath
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_random_internal_fastmath",
+}
+
+// GN: //third_party/abseil-cpp/absl/random/internal:generate_real
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_random_internal_generate_real",
+}
+
+// GN: //third_party/abseil-cpp/absl/random/internal:iostream_state_saver
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_random_internal_iostream_state_saver",
+}
+
+// GN: //third_party/abseil-cpp/absl/random/internal:nonsecure_base
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_random_internal_nonsecure_base",
+}
+
+// GN: //third_party/abseil-cpp/absl/random/internal:pcg_engine
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_random_internal_pcg_engine",
+}
+
+// GN: //third_party/abseil-cpp/absl/random/internal:platform
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_random_internal_platform",
+ srcs: [
+ "third_party/abseil-cpp/absl/random/internal/randen_round_keys.cc",
+ ],
+}
+
+// GN: //third_party/abseil-cpp/absl/random/internal:pool_urbg
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_random_internal_pool_urbg",
+ srcs: [
+ "third_party/abseil-cpp/absl/random/internal/pool_urbg.cc",
+ ],
+}
+
+// GN: //third_party/abseil-cpp/absl/random/internal:randen
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_random_internal_randen",
+ srcs: [
+ "third_party/abseil-cpp/absl/random/internal/randen.cc",
+ ],
+}
+
+// GN: //third_party/abseil-cpp/absl/random/internal:randen_engine
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_random_internal_randen_engine",
+}
+
+// GN: //third_party/abseil-cpp/absl/random/internal:randen_hwaes
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_random_internal_randen_hwaes",
+ srcs: [
+ "third_party/abseil-cpp/absl/random/internal/randen_detect.cc",
+ ],
+}
+
+// GN: //third_party/abseil-cpp/absl/random/internal:randen_hwaes_impl
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_random_internal_randen_hwaes_impl",
+ srcs: [
+ "third_party/abseil-cpp/absl/random/internal/randen_hwaes.cc",
+ ],
+}
+
+// GN: //third_party/abseil-cpp/absl/random/internal:randen_slow
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_random_internal_randen_slow",
+ srcs: [
+ "third_party/abseil-cpp/absl/random/internal/randen_slow.cc",
+ ],
+}
+
+// GN: //third_party/abseil-cpp/absl/random/internal:salted_seed_seq
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_random_internal_salted_seed_seq",
+}
+
+// GN: //third_party/abseil-cpp/absl/random/internal:seed_material
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_random_internal_seed_material",
+ srcs: [
+ "third_party/abseil-cpp/absl/random/internal/seed_material.cc",
+ ],
+}
+
+// GN: //third_party/abseil-cpp/absl/random/internal:traits
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_random_internal_traits",
+}
+
+// GN: //third_party/abseil-cpp/absl/random/internal:uniform_helper
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_random_internal_uniform_helper",
+}
+
+// GN: //third_party/abseil-cpp/absl/random/internal:wide_multiply
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_random_internal_wide_multiply",
+}
+
+// GN: //third_party/abseil-cpp/absl/random:random
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_random_random",
+}
+
+// GN: //third_party/abseil-cpp/absl/random:seed_gen_exception
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_random_seed_gen_exception",
+ srcs: [
+ "third_party/abseil-cpp/absl/random/seed_gen_exception.cc",
+ ],
+}
+
+// GN: //third_party/abseil-cpp/absl/random:seed_sequences
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_random_seed_sequences",
+ srcs: [
+ "third_party/abseil-cpp/absl/random/seed_sequences.cc",
+ ],
+}
+
+// GN: //third_party/abseil-cpp/absl/status:status
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_status_status",
+ srcs: [
+ "third_party/abseil-cpp/absl/status/status.cc",
+ "third_party/abseil-cpp/absl/status/status_payload_printer.cc",
+ ],
+}
+
+// GN: //third_party/abseil-cpp/absl/status:statusor
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_status_statusor",
+ srcs: [
+ "third_party/abseil-cpp/absl/status/statusor.cc",
+ ],
+}
+
+// GN: //third_party/abseil-cpp/absl/strings:cord
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_strings_cord",
+ srcs: [
+ "third_party/abseil-cpp/absl/strings/cord.cc",
+ "third_party/abseil-cpp/absl/strings/cord_analysis.cc",
+ "third_party/abseil-cpp/absl/strings/cord_buffer.cc",
+ ],
+}
+
+// GN: //third_party/abseil-cpp/absl/strings:cord_internal
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_strings_cord_internal",
+ srcs: [
+ "third_party/abseil-cpp/absl/strings/internal/cord_internal.cc",
+ "third_party/abseil-cpp/absl/strings/internal/cord_rep_btree.cc",
+ "third_party/abseil-cpp/absl/strings/internal/cord_rep_btree_navigator.cc",
+ "third_party/abseil-cpp/absl/strings/internal/cord_rep_btree_reader.cc",
+ "third_party/abseil-cpp/absl/strings/internal/cord_rep_consume.cc",
+ "third_party/abseil-cpp/absl/strings/internal/cord_rep_crc.cc",
+ "third_party/abseil-cpp/absl/strings/internal/cord_rep_ring.cc",
+ ],
+}
+
+// GN: //third_party/abseil-cpp/absl/strings:cordz_functions
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_strings_cordz_functions",
+ srcs: [
+ "third_party/abseil-cpp/absl/strings/internal/cordz_functions.cc",
+ ],
+}
+
+// GN: //third_party/abseil-cpp/absl/strings:cordz_handle
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_strings_cordz_handle",
+ srcs: [
+ "third_party/abseil-cpp/absl/strings/internal/cordz_handle.cc",
+ ],
+}
+
+// GN: //third_party/abseil-cpp/absl/strings:cordz_info
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_strings_cordz_info",
+ srcs: [
+ "third_party/abseil-cpp/absl/strings/internal/cordz_info.cc",
+ ],
+}
+
+// GN: //third_party/abseil-cpp/absl/strings:cordz_statistics
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_strings_cordz_statistics",
+}
+
+// GN: //third_party/abseil-cpp/absl/strings:cordz_update_scope
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_strings_cordz_update_scope",
+}
+
+// GN: //third_party/abseil-cpp/absl/strings:cordz_update_tracker
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_strings_cordz_update_tracker",
+}
+
+// GN: //third_party/abseil-cpp/absl/strings:internal
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_strings_internal",
+ srcs: [
+ "third_party/abseil-cpp/absl/strings/internal/escaping.cc",
+ "third_party/abseil-cpp/absl/strings/internal/ostringstream.cc",
+ "third_party/abseil-cpp/absl/strings/internal/utf8.cc",
+ ],
+}
+
+// GN: //third_party/abseil-cpp/absl/strings:str_format
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_strings_str_format",
+}
+
+// GN: //third_party/abseil-cpp/absl/strings:str_format_internal
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_strings_str_format_internal",
+ srcs: [
+ "third_party/abseil-cpp/absl/strings/internal/str_format/arg.cc",
+ "third_party/abseil-cpp/absl/strings/internal/str_format/bind.cc",
+ "third_party/abseil-cpp/absl/strings/internal/str_format/extension.cc",
+ "third_party/abseil-cpp/absl/strings/internal/str_format/float_conversion.cc",
+ "third_party/abseil-cpp/absl/strings/internal/str_format/output.cc",
+ "third_party/abseil-cpp/absl/strings/internal/str_format/parser.cc",
+ ],
+}
+
+// GN: //third_party/abseil-cpp/absl/strings:strings
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_strings_strings",
+ srcs: [
+ "third_party/abseil-cpp/absl/strings/ascii.cc",
+ "third_party/abseil-cpp/absl/strings/charconv.cc",
+ "third_party/abseil-cpp/absl/strings/escaping.cc",
+ "third_party/abseil-cpp/absl/strings/internal/charconv_bigint.cc",
+ "third_party/abseil-cpp/absl/strings/internal/charconv_parse.cc",
+ "third_party/abseil-cpp/absl/strings/internal/damerau_levenshtein_distance.cc",
+ "third_party/abseil-cpp/absl/strings/internal/memutil.cc",
+ "third_party/abseil-cpp/absl/strings/match.cc",
+ "third_party/abseil-cpp/absl/strings/numbers.cc",
+ "third_party/abseil-cpp/absl/strings/str_cat.cc",
+ "third_party/abseil-cpp/absl/strings/str_replace.cc",
+ "third_party/abseil-cpp/absl/strings/str_split.cc",
+ "third_party/abseil-cpp/absl/strings/string_view.cc",
+ "third_party/abseil-cpp/absl/strings/substitute.cc",
+ ],
+}
+
+// GN: //third_party/abseil-cpp/absl/synchronization:graphcycles_internal
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_synchronization_graphcycles_internal",
+ srcs: [
+ "third_party/abseil-cpp/absl/synchronization/internal/graphcycles.cc",
+ ],
+}
+
+// GN: //third_party/abseil-cpp/absl/synchronization:kernel_timeout_internal
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_synchronization_kernel_timeout_internal",
+}
+
+// GN: //third_party/abseil-cpp/absl/synchronization:synchronization
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_synchronization_synchronization",
+ srcs: [
+ "third_party/abseil-cpp/absl/synchronization/barrier.cc",
+ "third_party/abseil-cpp/absl/synchronization/blocking_counter.cc",
+ "third_party/abseil-cpp/absl/synchronization/internal/create_thread_identity.cc",
+ "third_party/abseil-cpp/absl/synchronization/internal/per_thread_sem.cc",
+ "third_party/abseil-cpp/absl/synchronization/internal/waiter.cc",
+ "third_party/abseil-cpp/absl/synchronization/mutex.cc",
+ "third_party/abseil-cpp/absl/synchronization/notification.cc",
+ ],
+}
+
+// GN: //third_party/abseil-cpp/absl/time/internal/cctz:civil_time
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_time_internal_cctz_civil_time",
+ srcs: [
+ "third_party/abseil-cpp/absl/time/internal/cctz/src/civil_time_detail.cc",
+ ],
+}
+
+// GN: //third_party/abseil-cpp/absl/time/internal/cctz:time_zone
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_time_internal_cctz_time_zone",
+ srcs: [
+ "third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_fixed.cc",
+ "third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_format.cc",
+ "third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_if.cc",
+ "third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_impl.cc",
+ "third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_info.cc",
+ "third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_libc.cc",
+ "third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_lookup.cc",
+ "third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_posix.cc",
+ "third_party/abseil-cpp/absl/time/internal/cctz/src/zone_info_source.cc",
+ ],
+}
+
+// GN: //third_party/abseil-cpp/absl/time:time
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_time_time",
+ srcs: [
+ "third_party/abseil-cpp/absl/time/civil_time.cc",
+ "third_party/abseil-cpp/absl/time/clock.cc",
+ "third_party/abseil-cpp/absl/time/duration.cc",
+ "third_party/abseil-cpp/absl/time/format.cc",
+ "third_party/abseil-cpp/absl/time/time.cc",
+ ],
+}
+
+// GN: //third_party/abseil-cpp/absl/types:bad_optional_access
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_types_bad_optional_access",
+ srcs: [
+ "third_party/abseil-cpp/absl/types/bad_optional_access.cc",
+ ],
+}
+
+// GN: //third_party/abseil-cpp/absl/types:bad_variant_access
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_types_bad_variant_access",
+ srcs: [
+ "third_party/abseil-cpp/absl/types/bad_variant_access.cc",
+ ],
+}
+
+// GN: //third_party/abseil-cpp/absl/types:compare
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_types_compare",
+}
+
+// GN: //third_party/abseil-cpp/absl/types:optional
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_types_optional",
+}
+
+// GN: //third_party/abseil-cpp/absl/types:span
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_types_span",
+}
+
+// GN: //third_party/abseil-cpp/absl/types:variant
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_types_variant",
+}
+
+// GN: //third_party/abseil-cpp/absl/utility:utility
+filegroup {
+ name: "cronet_aml_third_party_abseil_cpp_absl_utility_utility",
+}
+
+// GN: //third_party/android_deps:auto_service_processor__build_config_crbug_908819
+genrule {
+ name: "cronet_aml_third_party_android_deps_auto_service_processor__build_config_crbug_908819",
+ cmd: "$(location build/android/gyp/write_build_config.py) --type " +
+ "java_annotation_processor " +
+ " " +
+ " " +
+ "--deps-configs " +
+ "[\"$(location third_party/android_deps/com_google_auto_service_auto_service_java.build_config.json)\"] " +
+ "--public-deps-configs " +
+ "[] " +
+ "--build-config " +
+ "$(genDir)/third_party/android_deps/auto_service_processor.build_config.json " +
+ "--gn-target " +
+ "//third_party/android_deps:auto_service_processor " +
+ "--non-chromium-code " +
+ "--bundled-srcjars " +
+ "[] " +
+ "--main-class " +
+ "com.google.auto.service.processor.AutoServiceProcessor",
+ out: [
+ "third_party/android_deps/auto_service_processor.build_config.json",
+ ],
+ tool_files: [
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/android/gyp/util/resource_utils.py",
+ "build/android/gyp/write_build_config.py",
+ "build/gn_helpers.py",
+ "third_party/jinja2/__init__.py",
+ "third_party/jinja2/_compat.py",
+ "third_party/jinja2/_identifier.py",
+ "third_party/jinja2/bccache.py",
+ "third_party/jinja2/compiler.py",
+ "third_party/jinja2/defaults.py",
+ "third_party/jinja2/environment.py",
+ "third_party/jinja2/exceptions.py",
+ "third_party/jinja2/filters.py",
+ "third_party/jinja2/idtracking.py",
+ "third_party/jinja2/lexer.py",
+ "third_party/jinja2/loaders.py",
+ "third_party/jinja2/nodes.py",
+ "third_party/jinja2/optimizer.py",
+ "third_party/jinja2/parser.py",
+ "third_party/jinja2/runtime.py",
+ "third_party/jinja2/tests.py",
+ "third_party/jinja2/utils.py",
+ "third_party/jinja2/visitor.py",
+ "third_party/markupsafe/__init__.py",
+ "third_party/markupsafe/_compat.py",
+ "third_party/markupsafe/_native.py",
+ ],
+}
+
+// GN: //third_party/android_deps:com_github_ben_manes_caffeine_caffeine_java__build_config_crbug_908819
+genrule {
+ name: "cronet_aml_third_party_android_deps_com_github_ben_manes_caffeine_caffeine_java__build_config_crbug_908819",
+ cmd: "$(location build/android/gyp/write_build_config.py) --type " +
+ "java_library " +
+ " " +
+ " " +
+ "--deps-configs " +
+ "[\"$(location third_party/android_deps/com_google_errorprone_error_prone_annotations_java.build_config.json)\", \"$(location third_party/android_deps/org_checkerframework_checker_qual_java.build_config.json)\"] " +
+ "--public-deps-configs " +
+ "[] " +
+ "--build-config " +
+ "$(genDir)/third_party/android_deps/com_github_ben_manes_caffeine_caffeine_java.build_config.json " +
+ "--gn-target " +
+ "//third_party/android_deps:com_github_ben_manes_caffeine_caffeine_java " +
+ "--non-chromium-code " +
+ "--host-jar-path " +
+ "$(location lib.java/third_party/android_deps/com_github_ben_manes_caffeine_caffeine.jar) " +
+ "--unprocessed-jar-path " +
+ "$(location ../../third_party/android_deps/libs/com_github_ben_manes_caffeine_caffeine/caffeine-2.8.8.jar) " +
+ "--interface-jar-path " +
+ "$(location third_party/android_deps/com_github_ben_manes_caffeine_caffeine.ijar.jar) " +
+ "--is-prebuilt " +
+ "--bundled-srcjars " +
+ "[]",
+ out: [
+ "third_party/android_deps/com_github_ben_manes_caffeine_caffeine_java.build_config.json",
+ ],
+ tool_files: [
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/android/gyp/util/resource_utils.py",
+ "build/android/gyp/write_build_config.py",
+ "build/gn_helpers.py",
+ "third_party/jinja2/__init__.py",
+ "third_party/jinja2/_compat.py",
+ "third_party/jinja2/_identifier.py",
+ "third_party/jinja2/bccache.py",
+ "third_party/jinja2/compiler.py",
+ "third_party/jinja2/defaults.py",
+ "third_party/jinja2/environment.py",
+ "third_party/jinja2/exceptions.py",
+ "third_party/jinja2/filters.py",
+ "third_party/jinja2/idtracking.py",
+ "third_party/jinja2/lexer.py",
+ "third_party/jinja2/loaders.py",
+ "third_party/jinja2/nodes.py",
+ "third_party/jinja2/optimizer.py",
+ "third_party/jinja2/parser.py",
+ "third_party/jinja2/runtime.py",
+ "third_party/jinja2/tests.py",
+ "third_party/jinja2/utils.py",
+ "third_party/jinja2/visitor.py",
+ "third_party/markupsafe/__init__.py",
+ "third_party/markupsafe/_compat.py",
+ "third_party/markupsafe/_native.py",
+ ],
+}
+
+// GN: //third_party/android_deps:com_github_ben_manes_caffeine_caffeine_java__header
+genrule {
+ name: "cronet_aml_third_party_android_deps_com_github_ben_manes_caffeine_caffeine_java__header",
+ cmd: "$(location build/android/gyp/ijar.py) clang_x64/ijar " +
+ "../../third_party/android_deps/libs/com_github_ben_manes_caffeine_caffeine/caffeine-2.8.8.jar " +
+ "obj/third_party/android_deps/com_github_ben_manes_caffeine_caffeine.ijar.jar",
+ out: [
+ "//out/test/obj/third_party/android_deps/com_github_ben_manes_caffeine_caffeine.ijar.jar",
+ ],
+ tool_files: [
+ "build/android/gyp/ijar.py",
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/gn_helpers.py",
+ "out/test/clang_x64/ijar",
+ "third_party/android_deps/libs/com_github_ben_manes_caffeine_caffeine/caffeine-2.8.8.jar",
+ ],
+}
+
+// GN: //third_party/android_deps:com_github_ben_manes_caffeine_caffeine_java__host
+genrule {
+ name: "cronet_aml_third_party_android_deps_com_github_ben_manes_caffeine_caffeine_java__host",
+ cmd: "$(location build/android/gyp/filter_zip.py) --input " +
+ "../../third_party/android_deps/libs/com_github_ben_manes_caffeine_caffeine/caffeine-2.8.8.jar " +
+ "--output " +
+ "lib.java/third_party/android_deps/com_github_ben_manes_caffeine_caffeine.jar " +
+ "--exclude-globs " +
+ "[] " +
+ "--include-globs " +
+ "[]",
+ out: [
+ "//out/test/lib.java/third_party/android_deps/com_github_ben_manes_caffeine_caffeine.jar",
+ ],
+ tool_files: [
+ "build/android/gyp/filter_zip.py",
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/gn_helpers.py",
+ "third_party/android_deps/libs/com_github_ben_manes_caffeine_caffeine/caffeine-2.8.8.jar",
+ ],
+}
+
+// GN: //third_party/android_deps:com_github_kevinstern_software_and_algorithms_java__build_config_crbug_908819
+genrule {
+ name: "cronet_aml_third_party_android_deps_com_github_kevinstern_software_and_algorithms_java__build_config_crbug_908819",
+ cmd: "$(location build/android/gyp/write_build_config.py) --type " +
+ "java_library " +
+ " " +
+ " " +
+ "--deps-configs " +
+ "[] " +
+ "--public-deps-configs " +
+ "[] " +
+ "--build-config " +
+ "$(genDir)/third_party/android_deps/com_github_kevinstern_software_and_algorithms_java.build_config.json " +
+ "--gn-target " +
+ "//third_party/android_deps:com_github_kevinstern_software_and_algorithms_java " +
+ "--non-chromium-code " +
+ "--host-jar-path " +
+ "$(location lib.java/third_party/android_deps/com_github_kevinstern_software_and_algorithms.jar) " +
+ "--unprocessed-jar-path " +
+ "$(location ../../third_party/android_deps/libs/com_github_kevinstern_software_and_algorithms/software-and-algorithms-1.0.jar) " +
+ "--interface-jar-path " +
+ "$(location third_party/android_deps/com_github_kevinstern_software_and_algorithms.ijar.jar) " +
+ "--is-prebuilt " +
+ "--bundled-srcjars " +
+ "[]",
+ out: [
+ "third_party/android_deps/com_github_kevinstern_software_and_algorithms_java.build_config.json",
+ ],
+ tool_files: [
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/android/gyp/util/resource_utils.py",
+ "build/android/gyp/write_build_config.py",
+ "build/gn_helpers.py",
+ "third_party/jinja2/__init__.py",
+ "third_party/jinja2/_compat.py",
+ "third_party/jinja2/_identifier.py",
+ "third_party/jinja2/bccache.py",
+ "third_party/jinja2/compiler.py",
+ "third_party/jinja2/defaults.py",
+ "third_party/jinja2/environment.py",
+ "third_party/jinja2/exceptions.py",
+ "third_party/jinja2/filters.py",
+ "third_party/jinja2/idtracking.py",
+ "third_party/jinja2/lexer.py",
+ "third_party/jinja2/loaders.py",
+ "third_party/jinja2/nodes.py",
+ "third_party/jinja2/optimizer.py",
+ "third_party/jinja2/parser.py",
+ "third_party/jinja2/runtime.py",
+ "third_party/jinja2/tests.py",
+ "third_party/jinja2/utils.py",
+ "third_party/jinja2/visitor.py",
+ "third_party/markupsafe/__init__.py",
+ "third_party/markupsafe/_compat.py",
+ "third_party/markupsafe/_native.py",
+ ],
+}
+
+// GN: //third_party/android_deps:com_github_kevinstern_software_and_algorithms_java__header
+genrule {
+ name: "cronet_aml_third_party_android_deps_com_github_kevinstern_software_and_algorithms_java__header",
+ cmd: "$(location build/android/gyp/ijar.py) clang_x64/ijar " +
+ "../../third_party/android_deps/libs/com_github_kevinstern_software_and_algorithms/software-and-algorithms-1.0.jar " +
+ "obj/third_party/android_deps/com_github_kevinstern_software_and_algorithms.ijar.jar",
+ out: [
+ "//out/test/obj/third_party/android_deps/com_github_kevinstern_software_and_algorithms.ijar.jar",
+ ],
+ tool_files: [
+ "build/android/gyp/ijar.py",
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/gn_helpers.py",
+ "out/test/clang_x64/ijar",
+ "third_party/android_deps/libs/com_github_kevinstern_software_and_algorithms/software-and-algorithms-1.0.jar",
+ ],
+}
+
+// GN: //third_party/android_deps:com_github_kevinstern_software_and_algorithms_java__host
+genrule {
+ name: "cronet_aml_third_party_android_deps_com_github_kevinstern_software_and_algorithms_java__host",
+ cmd: "$(location build/android/gyp/filter_zip.py) --input " +
+ "../../third_party/android_deps/libs/com_github_kevinstern_software_and_algorithms/software-and-algorithms-1.0.jar " +
+ "--output " +
+ "lib.java/third_party/android_deps/com_github_kevinstern_software_and_algorithms.jar " +
+ "--exclude-globs " +
+ "[] " +
+ "--include-globs " +
+ "[]",
+ out: [
+ "//out/test/lib.java/third_party/android_deps/com_github_kevinstern_software_and_algorithms.jar",
+ ],
+ tool_files: [
+ "build/android/gyp/filter_zip.py",
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/gn_helpers.py",
+ "third_party/android_deps/libs/com_github_kevinstern_software_and_algorithms/software-and-algorithms-1.0.jar",
+ ],
+}
+
+// GN: //third_party/android_deps:com_google_auto_auto_common_java__build_config_crbug_908819
+genrule {
+ name: "cronet_aml_third_party_android_deps_com_google_auto_auto_common_java__build_config_crbug_908819",
+ cmd: "$(location build/android/gyp/write_build_config.py) --type " +
+ "java_library " +
+ " " +
+ " " +
+ "--deps-configs " +
+ "[\"$(location third_party/android_deps/com_google_guava_guava_java.build_config.json)\"] " +
+ "--public-deps-configs " +
+ "[] " +
+ "--build-config " +
+ "$(genDir)/third_party/android_deps/com_google_auto_auto_common_java.build_config.json " +
+ "--gn-target " +
+ "//third_party/android_deps:com_google_auto_auto_common_java " +
+ "--non-chromium-code " +
+ "--host-jar-path " +
+ "$(location lib.java/third_party/android_deps/com_google_auto_auto_common.jar) " +
+ "--unprocessed-jar-path " +
+ "$(location ../../third_party/android_deps/libs/com_google_auto_auto_common/auto-common-1.2.1.jar) " +
+ "--interface-jar-path " +
+ "$(location third_party/android_deps/com_google_auto_auto_common.ijar.jar) " +
+ "--is-prebuilt " +
+ "--bundled-srcjars " +
+ "[]",
+ out: [
+ "third_party/android_deps/com_google_auto_auto_common_java.build_config.json",
+ ],
+ tool_files: [
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/android/gyp/util/resource_utils.py",
+ "build/android/gyp/write_build_config.py",
+ "build/gn_helpers.py",
+ "third_party/jinja2/__init__.py",
+ "third_party/jinja2/_compat.py",
+ "third_party/jinja2/_identifier.py",
+ "third_party/jinja2/bccache.py",
+ "third_party/jinja2/compiler.py",
+ "third_party/jinja2/defaults.py",
+ "third_party/jinja2/environment.py",
+ "third_party/jinja2/exceptions.py",
+ "third_party/jinja2/filters.py",
+ "third_party/jinja2/idtracking.py",
+ "third_party/jinja2/lexer.py",
+ "third_party/jinja2/loaders.py",
+ "third_party/jinja2/nodes.py",
+ "third_party/jinja2/optimizer.py",
+ "third_party/jinja2/parser.py",
+ "third_party/jinja2/runtime.py",
+ "third_party/jinja2/tests.py",
+ "third_party/jinja2/utils.py",
+ "third_party/jinja2/visitor.py",
+ "third_party/markupsafe/__init__.py",
+ "third_party/markupsafe/_compat.py",
+ "third_party/markupsafe/_native.py",
+ ],
+}
+
+// GN: //third_party/android_deps:com_google_auto_auto_common_java__header
+genrule {
+ name: "cronet_aml_third_party_android_deps_com_google_auto_auto_common_java__header",
+ cmd: "$(location build/android/gyp/ijar.py) clang_x64/ijar " +
+ "../../third_party/android_deps/libs/com_google_auto_auto_common/auto-common-1.2.1.jar " +
+ "obj/third_party/android_deps/com_google_auto_auto_common.ijar.jar",
+ out: [
+ "//out/test/obj/third_party/android_deps/com_google_auto_auto_common.ijar.jar",
+ ],
+ tool_files: [
+ "build/android/gyp/ijar.py",
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/gn_helpers.py",
+ "out/test/clang_x64/ijar",
+ "third_party/android_deps/libs/com_google_auto_auto_common/auto-common-1.2.1.jar",
+ ],
+}
+
+// GN: //third_party/android_deps:com_google_auto_auto_common_java__host
+genrule {
+ name: "cronet_aml_third_party_android_deps_com_google_auto_auto_common_java__host",
+ cmd: "$(location build/android/gyp/filter_zip.py) --input " +
+ "../../third_party/android_deps/libs/com_google_auto_auto_common/auto-common-1.2.1.jar " +
+ "--output " +
+ "lib.java/third_party/android_deps/com_google_auto_auto_common.jar " +
+ "--exclude-globs " +
+ "[] " +
+ "--include-globs " +
+ "[]",
+ out: [
+ "//out/test/lib.java/third_party/android_deps/com_google_auto_auto_common.jar",
+ ],
+ tool_files: [
+ "build/android/gyp/filter_zip.py",
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/gn_helpers.py",
+ "third_party/android_deps/libs/com_google_auto_auto_common/auto-common-1.2.1.jar",
+ ],
+}
+
+// GN: //third_party/android_deps:com_google_auto_service_auto_service_annotations_java__build_config_crbug_908819
+genrule {
+ name: "cronet_aml_third_party_android_deps_com_google_auto_service_auto_service_annotations_java__build_config_crbug_908819",
+ cmd: "$(location build/android/gyp/write_build_config.py) --type " +
+ "java_library " +
+ " " +
+ " " +
+ "--deps-configs " +
+ "[] " +
+ "--public-deps-configs " +
+ "[] " +
+ "--build-config " +
+ "$(genDir)/third_party/android_deps/com_google_auto_service_auto_service_annotations_java.build_config.json " +
+ "--gn-target " +
+ "//third_party/android_deps:com_google_auto_service_auto_service_annotations_java " +
+ "--non-chromium-code " +
+ "--host-jar-path " +
+ "$(location lib.java/third_party/android_deps/com_google_auto_service_auto_service_annotations.jar) " +
+ "--unprocessed-jar-path " +
+ "$(location ../../third_party/android_deps/libs/com_google_auto_service_auto_service_annotations/auto-service-annotations-1.0-rc6.jar) " +
+ "--interface-jar-path " +
+ "$(location third_party/android_deps/com_google_auto_service_auto_service_annotations.ijar.jar) " +
+ "--is-prebuilt " +
+ "--bundled-srcjars " +
+ "[]",
+ out: [
+ "third_party/android_deps/com_google_auto_service_auto_service_annotations_java.build_config.json",
+ ],
+ tool_files: [
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/android/gyp/util/resource_utils.py",
+ "build/android/gyp/write_build_config.py",
+ "build/gn_helpers.py",
+ "third_party/jinja2/__init__.py",
+ "third_party/jinja2/_compat.py",
+ "third_party/jinja2/_identifier.py",
+ "third_party/jinja2/bccache.py",
+ "third_party/jinja2/compiler.py",
+ "third_party/jinja2/defaults.py",
+ "third_party/jinja2/environment.py",
+ "third_party/jinja2/exceptions.py",
+ "third_party/jinja2/filters.py",
+ "third_party/jinja2/idtracking.py",
+ "third_party/jinja2/lexer.py",
+ "third_party/jinja2/loaders.py",
+ "third_party/jinja2/nodes.py",
+ "third_party/jinja2/optimizer.py",
+ "third_party/jinja2/parser.py",
+ "third_party/jinja2/runtime.py",
+ "third_party/jinja2/tests.py",
+ "third_party/jinja2/utils.py",
+ "third_party/jinja2/visitor.py",
+ "third_party/markupsafe/__init__.py",
+ "third_party/markupsafe/_compat.py",
+ "third_party/markupsafe/_native.py",
+ ],
+}
+
+// GN: //third_party/android_deps:com_google_auto_service_auto_service_annotations_java__header
+genrule {
+ name: "cronet_aml_third_party_android_deps_com_google_auto_service_auto_service_annotations_java__header",
+ cmd: "$(location build/android/gyp/ijar.py) clang_x64/ijar " +
+ "../../third_party/android_deps/libs/com_google_auto_service_auto_service_annotations/auto-service-annotations-1.0-rc6.jar " +
+ "obj/third_party/android_deps/com_google_auto_service_auto_service_annotations.ijar.jar",
+ out: [
+ "//out/test/obj/third_party/android_deps/com_google_auto_service_auto_service_annotations.ijar.jar",
+ ],
+ tool_files: [
+ "build/android/gyp/ijar.py",
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/gn_helpers.py",
+ "out/test/clang_x64/ijar",
+ "third_party/android_deps/libs/com_google_auto_service_auto_service_annotations/auto-service-annotations-1.0-rc6.jar",
+ ],
+}
+
+// GN: //third_party/android_deps:com_google_auto_service_auto_service_annotations_java__host
+genrule {
+ name: "cronet_aml_third_party_android_deps_com_google_auto_service_auto_service_annotations_java__host",
+ cmd: "$(location build/android/gyp/filter_zip.py) --input " +
+ "../../third_party/android_deps/libs/com_google_auto_service_auto_service_annotations/auto-service-annotations-1.0-rc6.jar " +
+ "--output " +
+ "lib.java/third_party/android_deps/com_google_auto_service_auto_service_annotations.jar " +
+ "--exclude-globs " +
+ "[] " +
+ "--include-globs " +
+ "[]",
+ out: [
+ "//out/test/lib.java/third_party/android_deps/com_google_auto_service_auto_service_annotations.jar",
+ ],
+ tool_files: [
+ "build/android/gyp/filter_zip.py",
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/gn_helpers.py",
+ "third_party/android_deps/libs/com_google_auto_service_auto_service_annotations/auto-service-annotations-1.0-rc6.jar",
+ ],
+}
+
+// GN: //third_party/android_deps:com_google_auto_service_auto_service_java__build_config_crbug_908819
+genrule {
+ name: "cronet_aml_third_party_android_deps_com_google_auto_service_auto_service_java__build_config_crbug_908819",
+ cmd: "$(location build/android/gyp/write_build_config.py) --type " +
+ "java_library " +
+ " " +
+ " " +
+ "--deps-configs " +
+ "[\"$(location third_party/android_deps/com_google_auto_auto_common_java.build_config.json)\", \"$(location third_party/android_deps/com_google_auto_service_auto_service_annotations_java.build_config.json)\", \"$(location third_party/android_deps/com_google_guava_guava_java.build_config.json)\"] " +
+ "--public-deps-configs " +
+ "[] " +
+ "--build-config " +
+ "$(genDir)/third_party/android_deps/com_google_auto_service_auto_service_java.build_config.json " +
+ "--gn-target " +
+ "//third_party/android_deps:com_google_auto_service_auto_service_java " +
+ "--non-chromium-code " +
+ "--host-jar-path " +
+ "$(location lib.java/third_party/android_deps/com_google_auto_service_auto_service.jar) " +
+ "--unprocessed-jar-path " +
+ "$(location ../../third_party/android_deps/libs/com_google_auto_service_auto_service/auto-service-1.0-rc6.jar) " +
+ "--interface-jar-path " +
+ "$(location third_party/android_deps/com_google_auto_service_auto_service.ijar.jar) " +
+ "--is-prebuilt " +
+ "--bundled-srcjars " +
+ "[]",
+ out: [
+ "third_party/android_deps/com_google_auto_service_auto_service_java.build_config.json",
+ ],
+ tool_files: [
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/android/gyp/util/resource_utils.py",
+ "build/android/gyp/write_build_config.py",
+ "build/gn_helpers.py",
+ "third_party/jinja2/__init__.py",
+ "third_party/jinja2/_compat.py",
+ "third_party/jinja2/_identifier.py",
+ "third_party/jinja2/bccache.py",
+ "third_party/jinja2/compiler.py",
+ "third_party/jinja2/defaults.py",
+ "third_party/jinja2/environment.py",
+ "third_party/jinja2/exceptions.py",
+ "third_party/jinja2/filters.py",
+ "third_party/jinja2/idtracking.py",
+ "third_party/jinja2/lexer.py",
+ "third_party/jinja2/loaders.py",
+ "third_party/jinja2/nodes.py",
+ "third_party/jinja2/optimizer.py",
+ "third_party/jinja2/parser.py",
+ "third_party/jinja2/runtime.py",
+ "third_party/jinja2/tests.py",
+ "third_party/jinja2/utils.py",
+ "third_party/jinja2/visitor.py",
+ "third_party/markupsafe/__init__.py",
+ "third_party/markupsafe/_compat.py",
+ "third_party/markupsafe/_native.py",
+ ],
+}
+
+// GN: //third_party/android_deps:com_google_auto_service_auto_service_java__host
+genrule {
+ name: "cronet_aml_third_party_android_deps_com_google_auto_service_auto_service_java__host",
+ cmd: "$(location build/android/gyp/filter_zip.py) --input " +
+ "../../third_party/android_deps/libs/com_google_auto_service_auto_service/auto-service-1.0-rc6.jar " +
+ "--output " +
+ "lib.java/third_party/android_deps/com_google_auto_service_auto_service.jar " +
+ "--exclude-globs " +
+ "[] " +
+ "--include-globs " +
+ "[]",
+ out: [
+ "//out/test/lib.java/third_party/android_deps/com_google_auto_service_auto_service.jar",
+ ],
+ tool_files: [
+ "build/android/gyp/filter_zip.py",
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/gn_helpers.py",
+ "third_party/android_deps/libs/com_google_auto_service_auto_service/auto-service-1.0-rc6.jar",
+ ],
+}
+
+// GN: //third_party/android_deps:com_google_auto_value_auto_value_annotations_java__build_config_crbug_908819
+genrule {
+ name: "cronet_aml_third_party_android_deps_com_google_auto_value_auto_value_annotations_java__build_config_crbug_908819",
+ cmd: "$(location build/android/gyp/write_build_config.py) --type " +
+ "java_library " +
+ " " +
+ " " +
+ "--deps-configs " +
+ "[] " +
+ "--public-deps-configs " +
+ "[] " +
+ "--build-config " +
+ "$(genDir)/third_party/android_deps/com_google_auto_value_auto_value_annotations_java.build_config.json " +
+ "--gn-target " +
+ "//third_party/android_deps:com_google_auto_value_auto_value_annotations_java " +
+ "--non-chromium-code " +
+ "--host-jar-path " +
+ "$(location lib.java/third_party/android_deps/com_google_auto_value_auto_value_annotations.jar) " +
+ "--unprocessed-jar-path " +
+ "$(location ../../third_party/android_deps/libs/com_google_auto_value_auto_value_annotations/auto-value-annotations-1.9.jar) " +
+ "--interface-jar-path " +
+ "$(location third_party/android_deps/com_google_auto_value_auto_value_annotations.ijar.jar) " +
+ "--is-prebuilt " +
+ "--bundled-srcjars " +
+ "[]",
+ out: [
+ "third_party/android_deps/com_google_auto_value_auto_value_annotations_java.build_config.json",
+ ],
+ tool_files: [
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/android/gyp/util/resource_utils.py",
+ "build/android/gyp/write_build_config.py",
+ "build/gn_helpers.py",
+ "third_party/jinja2/__init__.py",
+ "third_party/jinja2/_compat.py",
+ "third_party/jinja2/_identifier.py",
+ "third_party/jinja2/bccache.py",
+ "third_party/jinja2/compiler.py",
+ "third_party/jinja2/defaults.py",
+ "third_party/jinja2/environment.py",
+ "third_party/jinja2/exceptions.py",
+ "third_party/jinja2/filters.py",
+ "third_party/jinja2/idtracking.py",
+ "third_party/jinja2/lexer.py",
+ "third_party/jinja2/loaders.py",
+ "third_party/jinja2/nodes.py",
+ "third_party/jinja2/optimizer.py",
+ "third_party/jinja2/parser.py",
+ "third_party/jinja2/runtime.py",
+ "third_party/jinja2/tests.py",
+ "third_party/jinja2/utils.py",
+ "third_party/jinja2/visitor.py",
+ "third_party/markupsafe/__init__.py",
+ "third_party/markupsafe/_compat.py",
+ "third_party/markupsafe/_native.py",
+ ],
+}
+
+// GN: //third_party/android_deps:com_google_auto_value_auto_value_annotations_java__header
+genrule {
+ name: "cronet_aml_third_party_android_deps_com_google_auto_value_auto_value_annotations_java__header",
+ cmd: "$(location build/android/gyp/ijar.py) clang_x64/ijar " +
+ "../../third_party/android_deps/libs/com_google_auto_value_auto_value_annotations/auto-value-annotations-1.9.jar " +
+ "obj/third_party/android_deps/com_google_auto_value_auto_value_annotations.ijar.jar",
+ out: [
+ "//out/test/obj/third_party/android_deps/com_google_auto_value_auto_value_annotations.ijar.jar",
+ ],
+ tool_files: [
+ "build/android/gyp/ijar.py",
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/gn_helpers.py",
+ "out/test/clang_x64/ijar",
+ "third_party/android_deps/libs/com_google_auto_value_auto_value_annotations/auto-value-annotations-1.9.jar",
+ ],
+}
+
+// GN: //third_party/android_deps:com_google_auto_value_auto_value_annotations_java__host
+genrule {
+ name: "cronet_aml_third_party_android_deps_com_google_auto_value_auto_value_annotations_java__host",
+ cmd: "$(location build/android/gyp/filter_zip.py) --input " +
+ "../../third_party/android_deps/libs/com_google_auto_value_auto_value_annotations/auto-value-annotations-1.9.jar " +
+ "--output " +
+ "lib.java/third_party/android_deps/com_google_auto_value_auto_value_annotations.jar " +
+ "--exclude-globs " +
+ "[] " +
+ "--include-globs " +
+ "[]",
+ out: [
+ "//out/test/lib.java/third_party/android_deps/com_google_auto_value_auto_value_annotations.jar",
+ ],
+ tool_files: [
+ "build/android/gyp/filter_zip.py",
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/gn_helpers.py",
+ "third_party/android_deps/libs/com_google_auto_value_auto_value_annotations/auto-value-annotations-1.9.jar",
+ ],
+}
+
+// GN: //third_party/android_deps:com_google_code_findbugs_jsr305_java__build_config_crbug_908819
+genrule {
+ name: "cronet_aml_third_party_android_deps_com_google_code_findbugs_jsr305_java__build_config_crbug_908819",
+ cmd: "$(location build/android/gyp/write_build_config.py) --type " +
+ "java_library " +
+ " " +
+ " " +
+ "--deps-configs " +
+ "[\"$(location third_party/android_sdk/android_sdk_java.build_config.json)\"] " +
+ "--public-deps-configs " +
+ "[] " +
+ "--build-config " +
+ "$(genDir)/third_party/android_deps/com_google_code_findbugs_jsr305_java.build_config.json " +
+ "--gn-target " +
+ "//third_party/android_deps:com_google_code_findbugs_jsr305_java " +
+ "--non-chromium-code " +
+ "--device-jar-path " +
+ "$(location ../../third_party/android_deps/libs/com_google_code_findbugs_jsr305/jsr305-3.0.2.jar) " +
+ "--host-jar-path " +
+ "$(location lib.java/third_party/android_deps/com_google_code_findbugs_jsr305.jar) " +
+ "--unprocessed-jar-path " +
+ "$(location ../../third_party/android_deps/libs/com_google_code_findbugs_jsr305/jsr305-3.0.2.jar) " +
+ "--interface-jar-path " +
+ "$(location third_party/android_deps/com_google_code_findbugs_jsr305.ijar.jar) " +
+ "--dex-path " +
+ "obj/third_party/android_deps/com_google_code_findbugs_jsr305_java.dex.jar " +
+ "--supports-android " +
+ "--is-prebuilt " +
+ "--bundled-srcjars " +
+ "[]",
+ out: [
+ "third_party/android_deps/com_google_code_findbugs_jsr305_java.build_config.json",
+ ],
+ tool_files: [
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/android/gyp/util/resource_utils.py",
+ "build/android/gyp/write_build_config.py",
+ "build/gn_helpers.py",
+ "third_party/jinja2/__init__.py",
+ "third_party/jinja2/_compat.py",
+ "third_party/jinja2/_identifier.py",
+ "third_party/jinja2/bccache.py",
+ "third_party/jinja2/compiler.py",
+ "third_party/jinja2/defaults.py",
+ "third_party/jinja2/environment.py",
+ "third_party/jinja2/exceptions.py",
+ "third_party/jinja2/filters.py",
+ "third_party/jinja2/idtracking.py",
+ "third_party/jinja2/lexer.py",
+ "third_party/jinja2/loaders.py",
+ "third_party/jinja2/nodes.py",
+ "third_party/jinja2/optimizer.py",
+ "third_party/jinja2/parser.py",
+ "third_party/jinja2/runtime.py",
+ "third_party/jinja2/tests.py",
+ "third_party/jinja2/utils.py",
+ "third_party/jinja2/visitor.py",
+ "third_party/markupsafe/__init__.py",
+ "third_party/markupsafe/_compat.py",
+ "third_party/markupsafe/_native.py",
+ ],
+}
+
+// GN: //third_party/android_deps:com_google_code_findbugs_jsr305_java__header
+genrule {
+ name: "cronet_aml_third_party_android_deps_com_google_code_findbugs_jsr305_java__header",
+ cmd: "$(location build/android/gyp/ijar.py) clang_x64/ijar " +
+ "../../third_party/android_deps/libs/com_google_code_findbugs_jsr305/jsr305-3.0.2.jar " +
+ "obj/third_party/android_deps/com_google_code_findbugs_jsr305.ijar.jar",
+ out: [
+ "//out/test/obj/third_party/android_deps/com_google_code_findbugs_jsr305.ijar.jar",
+ ],
+ tool_files: [
+ "build/android/gyp/ijar.py",
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/gn_helpers.py",
+ "out/test/clang_x64/ijar",
+ "third_party/android_deps/libs/com_google_code_findbugs_jsr305/jsr305-3.0.2.jar",
+ ],
+}
+
+// GN: //third_party/android_deps:com_google_code_findbugs_jsr305_java__host
+genrule {
+ name: "cronet_aml_third_party_android_deps_com_google_code_findbugs_jsr305_java__host",
+ cmd: "$(location build/android/gyp/filter_zip.py) --input " +
+ "../../third_party/android_deps/libs/com_google_code_findbugs_jsr305/jsr305-3.0.2.jar " +
+ "--output " +
+ "lib.java/third_party/android_deps/com_google_code_findbugs_jsr305.jar " +
+ "--exclude-globs " +
+ "[] " +
+ "--include-globs " +
+ "[]",
+ out: [
+ "//out/test/lib.java/third_party/android_deps/com_google_code_findbugs_jsr305.jar",
+ ],
+ tool_files: [
+ "build/android/gyp/filter_zip.py",
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/gn_helpers.py",
+ "third_party/android_deps/libs/com_google_code_findbugs_jsr305/jsr305-3.0.2.jar",
+ ],
+}
+
+// GN: //third_party/android_deps:com_google_errorprone_error_prone_annotation_java__build_config_crbug_908819
+genrule {
+ name: "cronet_aml_third_party_android_deps_com_google_errorprone_error_prone_annotation_java__build_config_crbug_908819",
+ cmd: "$(location build/android/gyp/write_build_config.py) --type " +
+ "java_library " +
+ " " +
+ " " +
+ "--deps-configs " +
+ "[\"$(location third_party/android_deps/com_google_guava_guava_java.build_config.json)\"] " +
+ "--public-deps-configs " +
+ "[] " +
+ "--build-config " +
+ "$(genDir)/third_party/android_deps/com_google_errorprone_error_prone_annotation_java.build_config.json " +
+ "--gn-target " +
+ "//third_party/android_deps:com_google_errorprone_error_prone_annotation_java " +
+ "--non-chromium-code " +
+ "--host-jar-path " +
+ "$(location lib.java/third_party/android_deps/com_google_errorprone_error_prone_annotation.jar) " +
+ "--unprocessed-jar-path " +
+ "$(location ../../third_party/android_deps/libs/com_google_errorprone_error_prone_annotation/error_prone_annotation-2.11.0.jar) " +
+ "--interface-jar-path " +
+ "$(location third_party/android_deps/com_google_errorprone_error_prone_annotation.ijar.jar) " +
+ "--is-prebuilt " +
+ "--bundled-srcjars " +
+ "[]",
+ out: [
+ "third_party/android_deps/com_google_errorprone_error_prone_annotation_java.build_config.json",
+ ],
+ tool_files: [
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/android/gyp/util/resource_utils.py",
+ "build/android/gyp/write_build_config.py",
+ "build/gn_helpers.py",
+ "third_party/jinja2/__init__.py",
+ "third_party/jinja2/_compat.py",
+ "third_party/jinja2/_identifier.py",
+ "third_party/jinja2/bccache.py",
+ "third_party/jinja2/compiler.py",
+ "third_party/jinja2/defaults.py",
+ "third_party/jinja2/environment.py",
+ "third_party/jinja2/exceptions.py",
+ "third_party/jinja2/filters.py",
+ "third_party/jinja2/idtracking.py",
+ "third_party/jinja2/lexer.py",
+ "third_party/jinja2/loaders.py",
+ "third_party/jinja2/nodes.py",
+ "third_party/jinja2/optimizer.py",
+ "third_party/jinja2/parser.py",
+ "third_party/jinja2/runtime.py",
+ "third_party/jinja2/tests.py",
+ "third_party/jinja2/utils.py",
+ "third_party/jinja2/visitor.py",
+ "third_party/markupsafe/__init__.py",
+ "third_party/markupsafe/_compat.py",
+ "third_party/markupsafe/_native.py",
+ ],
+}
+
+// GN: //third_party/android_deps:com_google_errorprone_error_prone_annotation_java__header
+genrule {
+ name: "cronet_aml_third_party_android_deps_com_google_errorprone_error_prone_annotation_java__header",
+ cmd: "$(location build/android/gyp/ijar.py) clang_x64/ijar " +
+ "../../third_party/android_deps/libs/com_google_errorprone_error_prone_annotation/error_prone_annotation-2.11.0.jar " +
+ "obj/third_party/android_deps/com_google_errorprone_error_prone_annotation.ijar.jar",
+ out: [
+ "//out/test/obj/third_party/android_deps/com_google_errorprone_error_prone_annotation.ijar.jar",
+ ],
+ tool_files: [
+ "build/android/gyp/ijar.py",
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/gn_helpers.py",
+ "out/test/clang_x64/ijar",
+ "third_party/android_deps/libs/com_google_errorprone_error_prone_annotation/error_prone_annotation-2.11.0.jar",
+ ],
+}
+
+// GN: //third_party/android_deps:com_google_errorprone_error_prone_annotation_java__host
+genrule {
+ name: "cronet_aml_third_party_android_deps_com_google_errorprone_error_prone_annotation_java__host",
+ cmd: "$(location build/android/gyp/filter_zip.py) --input " +
+ "../../third_party/android_deps/libs/com_google_errorprone_error_prone_annotation/error_prone_annotation-2.11.0.jar " +
+ "--output " +
+ "lib.java/third_party/android_deps/com_google_errorprone_error_prone_annotation.jar " +
+ "--exclude-globs " +
+ "[] " +
+ "--include-globs " +
+ "[]",
+ out: [
+ "//out/test/lib.java/third_party/android_deps/com_google_errorprone_error_prone_annotation.jar",
+ ],
+ tool_files: [
+ "build/android/gyp/filter_zip.py",
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/gn_helpers.py",
+ "third_party/android_deps/libs/com_google_errorprone_error_prone_annotation/error_prone_annotation-2.11.0.jar",
+ ],
+}
+
+// GN: //third_party/android_deps:com_google_errorprone_error_prone_annotations_java__build_config_crbug_908819
+genrule {
+ name: "cronet_aml_third_party_android_deps_com_google_errorprone_error_prone_annotations_java__build_config_crbug_908819",
+ cmd: "$(location build/android/gyp/write_build_config.py) --type " +
+ "java_library " +
+ " " +
+ " " +
+ "--deps-configs " +
+ "[\"$(location third_party/android_sdk/android_sdk_java.build_config.json)\"] " +
+ "--public-deps-configs " +
+ "[] " +
+ "--build-config " +
+ "$(genDir)/third_party/android_deps/com_google_errorprone_error_prone_annotations_java.build_config.json " +
+ "--gn-target " +
+ "//third_party/android_deps:com_google_errorprone_error_prone_annotations_java " +
+ "--non-chromium-code " +
+ "--device-jar-path " +
+ "$(location ../../third_party/android_deps/libs/com_google_errorprone_error_prone_annotations/error_prone_annotations-2.14.0.jar) " +
+ "--host-jar-path " +
+ "$(location lib.java/third_party/android_deps/com_google_errorprone_error_prone_annotations.jar) " +
+ "--unprocessed-jar-path " +
+ "$(location ../../third_party/android_deps/libs/com_google_errorprone_error_prone_annotations/error_prone_annotations-2.14.0.jar) " +
+ "--interface-jar-path " +
+ "$(location third_party/android_deps/com_google_errorprone_error_prone_annotations.ijar.jar) " +
+ "--dex-path " +
+ "obj/third_party/android_deps/com_google_errorprone_error_prone_annotations_java.dex.jar " +
+ "--supports-android " +
+ "--is-prebuilt " +
+ "--bundled-srcjars " +
+ "[]",
+ out: [
+ "third_party/android_deps/com_google_errorprone_error_prone_annotations_java.build_config.json",
+ ],
+ tool_files: [
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/android/gyp/util/resource_utils.py",
+ "build/android/gyp/write_build_config.py",
+ "build/gn_helpers.py",
+ "third_party/jinja2/__init__.py",
+ "third_party/jinja2/_compat.py",
+ "third_party/jinja2/_identifier.py",
+ "third_party/jinja2/bccache.py",
+ "third_party/jinja2/compiler.py",
+ "third_party/jinja2/defaults.py",
+ "third_party/jinja2/environment.py",
+ "third_party/jinja2/exceptions.py",
+ "third_party/jinja2/filters.py",
+ "third_party/jinja2/idtracking.py",
+ "third_party/jinja2/lexer.py",
+ "third_party/jinja2/loaders.py",
+ "third_party/jinja2/nodes.py",
+ "third_party/jinja2/optimizer.py",
+ "third_party/jinja2/parser.py",
+ "third_party/jinja2/runtime.py",
+ "third_party/jinja2/tests.py",
+ "third_party/jinja2/utils.py",
+ "third_party/jinja2/visitor.py",
+ "third_party/markupsafe/__init__.py",
+ "third_party/markupsafe/_compat.py",
+ "third_party/markupsafe/_native.py",
+ ],
+}
+
+// GN: //third_party/android_deps:com_google_errorprone_error_prone_annotations_java__header
+genrule {
+ name: "cronet_aml_third_party_android_deps_com_google_errorprone_error_prone_annotations_java__header",
+ cmd: "$(location build/android/gyp/ijar.py) clang_x64/ijar " +
+ "../../third_party/android_deps/libs/com_google_errorprone_error_prone_annotations/error_prone_annotations-2.14.0.jar " +
+ "obj/third_party/android_deps/com_google_errorprone_error_prone_annotations.ijar.jar",
+ out: [
+ "//out/test/obj/third_party/android_deps/com_google_errorprone_error_prone_annotations.ijar.jar",
+ ],
+ tool_files: [
+ "build/android/gyp/ijar.py",
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/gn_helpers.py",
+ "out/test/clang_x64/ijar",
+ "third_party/android_deps/libs/com_google_errorprone_error_prone_annotations/error_prone_annotations-2.14.0.jar",
+ ],
+}
+
+// GN: //third_party/android_deps:com_google_errorprone_error_prone_annotations_java__host
+genrule {
+ name: "cronet_aml_third_party_android_deps_com_google_errorprone_error_prone_annotations_java__host",
+ cmd: "$(location build/android/gyp/filter_zip.py) --input " +
+ "../../third_party/android_deps/libs/com_google_errorprone_error_prone_annotations/error_prone_annotations-2.14.0.jar " +
+ "--output " +
+ "lib.java/third_party/android_deps/com_google_errorprone_error_prone_annotations.jar " +
+ "--exclude-globs " +
+ "[] " +
+ "--include-globs " +
+ "[]",
+ out: [
+ "//out/test/lib.java/third_party/android_deps/com_google_errorprone_error_prone_annotations.jar",
+ ],
+ tool_files: [
+ "build/android/gyp/filter_zip.py",
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/gn_helpers.py",
+ "third_party/android_deps/libs/com_google_errorprone_error_prone_annotations/error_prone_annotations-2.14.0.jar",
+ ],
+}
+
+// GN: //third_party/android_deps:com_google_errorprone_error_prone_check_api_java__build_config_crbug_908819
+genrule {
+ name: "cronet_aml_third_party_android_deps_com_google_errorprone_error_prone_check_api_java__build_config_crbug_908819",
+ cmd: "$(location build/android/gyp/write_build_config.py) --type " +
+ "java_library " +
+ " " +
+ " " +
+ "--deps-configs " +
+ "[\"$(location third_party/android_deps/com_github_ben_manes_caffeine_caffeine_java.build_config.json)\", \"$(location third_party/android_deps/com_github_kevinstern_software_and_algorithms_java.build_config.json)\", \"$(location third_party/android_deps/com_google_auto_value_auto_value_annotations_java.build_config.json)\", \"$(location third_party/android_deps/com_google_code_findbugs_jsr305_java.build_config.json)\", \"$(location third_party/android_deps/com_google_errorprone_error_prone_annotation_java.build_config.json)\", \"$(location third_party/android_deps/com_google_errorprone_error_prone_annotations_java.build_config.json)\", \"$(location third_party/android_deps/io_github_java_diff_utils_java_diff_utils_java.build_config.json)\", \"$(location third_party/android_deps/org_checkerframework_dataflow_errorprone_java.build_config.json)\"] " +
+ "--public-deps-configs " +
+ "[] " +
+ "--build-config " +
+ "$(genDir)/third_party/android_deps/com_google_errorprone_error_prone_check_api_java.build_config.json " +
+ "--gn-target " +
+ "//third_party/android_deps:com_google_errorprone_error_prone_check_api_java " +
+ "--non-chromium-code " +
+ "--host-jar-path " +
+ "$(location lib.java/third_party/android_deps/com_google_errorprone_error_prone_check_api.jar) " +
+ "--unprocessed-jar-path " +
+ "$(location ../../third_party/android_deps/libs/com_google_errorprone_error_prone_check_api/error_prone_check_api-2.11.0.jar) " +
+ "--interface-jar-path " +
+ "$(location third_party/android_deps/com_google_errorprone_error_prone_check_api.ijar.jar) " +
+ "--is-prebuilt " +
+ "--bundled-srcjars " +
+ "[]",
+ out: [
+ "third_party/android_deps/com_google_errorprone_error_prone_check_api_java.build_config.json",
+ ],
+ tool_files: [
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/android/gyp/util/resource_utils.py",
+ "build/android/gyp/write_build_config.py",
+ "build/gn_helpers.py",
+ "third_party/jinja2/__init__.py",
+ "third_party/jinja2/_compat.py",
+ "third_party/jinja2/_identifier.py",
+ "third_party/jinja2/bccache.py",
+ "third_party/jinja2/compiler.py",
+ "third_party/jinja2/defaults.py",
+ "third_party/jinja2/environment.py",
+ "third_party/jinja2/exceptions.py",
+ "third_party/jinja2/filters.py",
+ "third_party/jinja2/idtracking.py",
+ "third_party/jinja2/lexer.py",
+ "third_party/jinja2/loaders.py",
+ "third_party/jinja2/nodes.py",
+ "third_party/jinja2/optimizer.py",
+ "third_party/jinja2/parser.py",
+ "third_party/jinja2/runtime.py",
+ "third_party/jinja2/tests.py",
+ "third_party/jinja2/utils.py",
+ "third_party/jinja2/visitor.py",
+ "third_party/markupsafe/__init__.py",
+ "third_party/markupsafe/_compat.py",
+ "third_party/markupsafe/_native.py",
+ ],
+}
+
+// GN: //third_party/android_deps:com_google_errorprone_error_prone_check_api_java__header
+genrule {
+ name: "cronet_aml_third_party_android_deps_com_google_errorprone_error_prone_check_api_java__header",
+ cmd: "$(location build/android/gyp/ijar.py) clang_x64/ijar " +
+ "../../third_party/android_deps/libs/com_google_errorprone_error_prone_check_api/error_prone_check_api-2.11.0.jar " +
+ "obj/third_party/android_deps/com_google_errorprone_error_prone_check_api.ijar.jar",
+ out: [
+ "//out/test/obj/third_party/android_deps/com_google_errorprone_error_prone_check_api.ijar.jar",
+ ],
+ tool_files: [
+ "build/android/gyp/ijar.py",
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/gn_helpers.py",
+ "out/test/clang_x64/ijar",
+ "third_party/android_deps/libs/com_google_errorprone_error_prone_check_api/error_prone_check_api-2.11.0.jar",
+ ],
+}
+
+// GN: //third_party/android_deps:com_google_errorprone_error_prone_check_api_java__host
+genrule {
+ name: "cronet_aml_third_party_android_deps_com_google_errorprone_error_prone_check_api_java__host",
+ cmd: "$(location build/android/gyp/filter_zip.py) --input " +
+ "../../third_party/android_deps/libs/com_google_errorprone_error_prone_check_api/error_prone_check_api-2.11.0.jar " +
+ "--output " +
+ "lib.java/third_party/android_deps/com_google_errorprone_error_prone_check_api.jar " +
+ "--exclude-globs " +
+ "[] " +
+ "--include-globs " +
+ "[]",
+ out: [
+ "//out/test/lib.java/third_party/android_deps/com_google_errorprone_error_prone_check_api.jar",
+ ],
+ tool_files: [
+ "build/android/gyp/filter_zip.py",
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/gn_helpers.py",
+ "third_party/android_deps/libs/com_google_errorprone_error_prone_check_api/error_prone_check_api-2.11.0.jar",
+ ],
+}
+
+// GN: //third_party/android_deps:com_google_errorprone_error_prone_core_java__build_config_crbug_908819
+genrule {
+ name: "cronet_aml_third_party_android_deps_com_google_errorprone_error_prone_core_java__build_config_crbug_908819",
+ cmd: "$(location build/android/gyp/write_build_config.py) --type " +
+ "java_library " +
+ " " +
+ " " +
+ "--deps-configs " +
+ "[\"$(location third_party/android_deps/com_google_auto_auto_common_java.build_config.json)\", \"$(location third_party/android_deps/com_google_auto_service_auto_service_annotations_java.build_config.json)\", \"$(location third_party/android_deps/com_google_auto_value_auto_value_annotations_java.build_config.json)\", \"$(location third_party/android_deps/com_google_code_findbugs_jsr305_java.build_config.json)\", \"$(location third_party/android_deps/com_google_errorprone_error_prone_annotation_java.build_config.json)\", \"$(location third_party/android_deps/com_google_errorprone_error_prone_annotations_java.build_config.json)\", \"$(location third_party/android_deps/com_google_errorprone_error_prone_check_api_java.build_config.json)\", \"$(location third_party/android_deps/com_google_errorprone_error_prone_type_annotations_java.build_config.json)\", \"$(location third_party/android_deps/com_google_guava_guava_java.build_config.json)\", \"$(location third_party/android_deps/com_google_protobuf_protobuf_java_java.build_config.json)\", \"$(location third_party/android_deps/org_checkerframework_dataflow_errorprone_java.build_config.json)\", \"$(location third_party/android_deps/org_pcollections_pcollections_java.build_config.json)\"] " +
+ "--public-deps-configs " +
+ "[] " +
+ "--build-config " +
+ "$(genDir)/third_party/android_deps/com_google_errorprone_error_prone_core_java.build_config.json " +
+ "--gn-target " +
+ "//third_party/android_deps:com_google_errorprone_error_prone_core_java " +
+ "--non-chromium-code " +
+ "--host-jar-path " +
+ "$(location lib.java/third_party/android_deps/com_google_errorprone_error_prone_core.jar) " +
+ "--unprocessed-jar-path " +
+ "$(location ../../third_party/android_deps/libs/com_google_errorprone_error_prone_core/error_prone_core-2.11.0.jar) " +
+ "--interface-jar-path " +
+ "$(location third_party/android_deps/com_google_errorprone_error_prone_core.ijar.jar) " +
+ "--is-prebuilt " +
+ "--bundled-srcjars " +
+ "[]",
+ out: [
+ "third_party/android_deps/com_google_errorprone_error_prone_core_java.build_config.json",
+ ],
+ tool_files: [
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/android/gyp/util/resource_utils.py",
+ "build/android/gyp/write_build_config.py",
+ "build/gn_helpers.py",
+ "third_party/jinja2/__init__.py",
+ "third_party/jinja2/_compat.py",
+ "third_party/jinja2/_identifier.py",
+ "third_party/jinja2/bccache.py",
+ "third_party/jinja2/compiler.py",
+ "third_party/jinja2/defaults.py",
+ "third_party/jinja2/environment.py",
+ "third_party/jinja2/exceptions.py",
+ "third_party/jinja2/filters.py",
+ "third_party/jinja2/idtracking.py",
+ "third_party/jinja2/lexer.py",
+ "third_party/jinja2/loaders.py",
+ "third_party/jinja2/nodes.py",
+ "third_party/jinja2/optimizer.py",
+ "third_party/jinja2/parser.py",
+ "third_party/jinja2/runtime.py",
+ "third_party/jinja2/tests.py",
+ "third_party/jinja2/utils.py",
+ "third_party/jinja2/visitor.py",
+ "third_party/markupsafe/__init__.py",
+ "third_party/markupsafe/_compat.py",
+ "third_party/markupsafe/_native.py",
+ ],
+}
+
+// GN: //third_party/android_deps:com_google_errorprone_error_prone_core_java__header
+genrule {
+ name: "cronet_aml_third_party_android_deps_com_google_errorprone_error_prone_core_java__header",
+ cmd: "$(location build/android/gyp/ijar.py) clang_x64/ijar " +
+ "../../third_party/android_deps/libs/com_google_errorprone_error_prone_core/error_prone_core-2.11.0.jar " +
+ "obj/third_party/android_deps/com_google_errorprone_error_prone_core.ijar.jar",
+ out: [
+ "//out/test/obj/third_party/android_deps/com_google_errorprone_error_prone_core.ijar.jar",
+ ],
+ tool_files: [
+ "build/android/gyp/ijar.py",
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/gn_helpers.py",
+ "out/test/clang_x64/ijar",
+ "third_party/android_deps/libs/com_google_errorprone_error_prone_core/error_prone_core-2.11.0.jar",
+ ],
+}
+
+// GN: //third_party/android_deps:com_google_errorprone_error_prone_core_java__host
+genrule {
+ name: "cronet_aml_third_party_android_deps_com_google_errorprone_error_prone_core_java__host",
+ cmd: "$(location build/android/gyp/filter_zip.py) --input " +
+ "../../third_party/android_deps/libs/com_google_errorprone_error_prone_core/error_prone_core-2.11.0.jar " +
+ "--output " +
+ "lib.java/third_party/android_deps/com_google_errorprone_error_prone_core.jar " +
+ "--exclude-globs " +
+ "[] " +
+ "--include-globs " +
+ "[]",
+ out: [
+ "//out/test/lib.java/third_party/android_deps/com_google_errorprone_error_prone_core.jar",
+ ],
+ tool_files: [
+ "build/android/gyp/filter_zip.py",
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/gn_helpers.py",
+ "third_party/android_deps/libs/com_google_errorprone_error_prone_core/error_prone_core-2.11.0.jar",
+ ],
+}
+
+// GN: //third_party/android_deps:com_google_errorprone_error_prone_type_annotations_java__build_config_crbug_908819
+genrule {
+ name: "cronet_aml_third_party_android_deps_com_google_errorprone_error_prone_type_annotations_java__build_config_crbug_908819",
+ cmd: "$(location build/android/gyp/write_build_config.py) --type " +
+ "java_library " +
+ " " +
+ " " +
+ "--deps-configs " +
+ "[] " +
+ "--public-deps-configs " +
+ "[] " +
+ "--build-config " +
+ "$(genDir)/third_party/android_deps/com_google_errorprone_error_prone_type_annotations_java.build_config.json " +
+ "--gn-target " +
+ "//third_party/android_deps:com_google_errorprone_error_prone_type_annotations_java " +
+ "--non-chromium-code " +
+ "--host-jar-path " +
+ "$(location lib.java/third_party/android_deps/com_google_errorprone_error_prone_type_annotations.jar) " +
+ "--unprocessed-jar-path " +
+ "$(location ../../third_party/android_deps/libs/com_google_errorprone_error_prone_type_annotations/error_prone_type_annotations-2.11.0.jar) " +
+ "--interface-jar-path " +
+ "$(location third_party/android_deps/com_google_errorprone_error_prone_type_annotations.ijar.jar) " +
+ "--is-prebuilt " +
+ "--bundled-srcjars " +
+ "[]",
+ out: [
+ "third_party/android_deps/com_google_errorprone_error_prone_type_annotations_java.build_config.json",
+ ],
+ tool_files: [
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/android/gyp/util/resource_utils.py",
+ "build/android/gyp/write_build_config.py",
+ "build/gn_helpers.py",
+ "third_party/jinja2/__init__.py",
+ "third_party/jinja2/_compat.py",
+ "third_party/jinja2/_identifier.py",
+ "third_party/jinja2/bccache.py",
+ "third_party/jinja2/compiler.py",
+ "third_party/jinja2/defaults.py",
+ "third_party/jinja2/environment.py",
+ "third_party/jinja2/exceptions.py",
+ "third_party/jinja2/filters.py",
+ "third_party/jinja2/idtracking.py",
+ "third_party/jinja2/lexer.py",
+ "third_party/jinja2/loaders.py",
+ "third_party/jinja2/nodes.py",
+ "third_party/jinja2/optimizer.py",
+ "third_party/jinja2/parser.py",
+ "third_party/jinja2/runtime.py",
+ "third_party/jinja2/tests.py",
+ "third_party/jinja2/utils.py",
+ "third_party/jinja2/visitor.py",
+ "third_party/markupsafe/__init__.py",
+ "third_party/markupsafe/_compat.py",
+ "third_party/markupsafe/_native.py",
+ ],
+}
+
+// GN: //third_party/android_deps:com_google_errorprone_error_prone_type_annotations_java__header
+genrule {
+ name: "cronet_aml_third_party_android_deps_com_google_errorprone_error_prone_type_annotations_java__header",
+ cmd: "$(location build/android/gyp/ijar.py) clang_x64/ijar " +
+ "../../third_party/android_deps/libs/com_google_errorprone_error_prone_type_annotations/error_prone_type_annotations-2.11.0.jar " +
+ "obj/third_party/android_deps/com_google_errorprone_error_prone_type_annotations.ijar.jar",
+ out: [
+ "//out/test/obj/third_party/android_deps/com_google_errorprone_error_prone_type_annotations.ijar.jar",
+ ],
+ tool_files: [
+ "build/android/gyp/ijar.py",
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/gn_helpers.py",
+ "out/test/clang_x64/ijar",
+ "third_party/android_deps/libs/com_google_errorprone_error_prone_type_annotations/error_prone_type_annotations-2.11.0.jar",
+ ],
+}
+
+// GN: //third_party/android_deps:com_google_errorprone_error_prone_type_annotations_java__host
+genrule {
+ name: "cronet_aml_third_party_android_deps_com_google_errorprone_error_prone_type_annotations_java__host",
+ cmd: "$(location build/android/gyp/filter_zip.py) --input " +
+ "../../third_party/android_deps/libs/com_google_errorprone_error_prone_type_annotations/error_prone_type_annotations-2.11.0.jar " +
+ "--output " +
+ "lib.java/third_party/android_deps/com_google_errorprone_error_prone_type_annotations.jar " +
+ "--exclude-globs " +
+ "[] " +
+ "--include-globs " +
+ "[]",
+ out: [
+ "//out/test/lib.java/third_party/android_deps/com_google_errorprone_error_prone_type_annotations.jar",
+ ],
+ tool_files: [
+ "build/android/gyp/filter_zip.py",
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/gn_helpers.py",
+ "third_party/android_deps/libs/com_google_errorprone_error_prone_type_annotations/error_prone_type_annotations-2.11.0.jar",
+ ],
+}
+
+// GN: //third_party/android_deps:com_google_errorprone_javac_java__build_config_crbug_908819
+genrule {
+ name: "cronet_aml_third_party_android_deps_com_google_errorprone_javac_java__build_config_crbug_908819",
+ cmd: "$(location build/android/gyp/write_build_config.py) --type " +
+ "java_library " +
+ " " +
+ " " +
+ "--deps-configs " +
+ "[] " +
+ "--public-deps-configs " +
+ "[] " +
+ "--build-config " +
+ "$(genDir)/third_party/android_deps/com_google_errorprone_javac_java.build_config.json " +
+ "--gn-target " +
+ "//third_party/android_deps:com_google_errorprone_javac_java " +
+ "--non-chromium-code " +
+ "--host-jar-path " +
+ "$(location lib.java/third_party/android_deps/com_google_errorprone_javac.jar) " +
+ "--unprocessed-jar-path " +
+ "$(location ../../third_party/android_deps/libs/com_google_errorprone_javac/javac-9+181-r4173-1.jar) " +
+ "--interface-jar-path " +
+ "$(location third_party/android_deps/com_google_errorprone_javac.ijar.jar) " +
+ "--is-prebuilt " +
+ "--bundled-srcjars " +
+ "[]",
+ out: [
+ "third_party/android_deps/com_google_errorprone_javac_java.build_config.json",
+ ],
+ tool_files: [
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/android/gyp/util/resource_utils.py",
+ "build/android/gyp/write_build_config.py",
+ "build/gn_helpers.py",
+ "third_party/jinja2/__init__.py",
+ "third_party/jinja2/_compat.py",
+ "third_party/jinja2/_identifier.py",
+ "third_party/jinja2/bccache.py",
+ "third_party/jinja2/compiler.py",
+ "third_party/jinja2/defaults.py",
+ "third_party/jinja2/environment.py",
+ "third_party/jinja2/exceptions.py",
+ "third_party/jinja2/filters.py",
+ "third_party/jinja2/idtracking.py",
+ "third_party/jinja2/lexer.py",
+ "third_party/jinja2/loaders.py",
+ "third_party/jinja2/nodes.py",
+ "third_party/jinja2/optimizer.py",
+ "third_party/jinja2/parser.py",
+ "third_party/jinja2/runtime.py",
+ "third_party/jinja2/tests.py",
+ "third_party/jinja2/utils.py",
+ "third_party/jinja2/visitor.py",
+ "third_party/markupsafe/__init__.py",
+ "third_party/markupsafe/_compat.py",
+ "third_party/markupsafe/_native.py",
+ ],
+}
+
+// GN: //third_party/android_deps:com_google_errorprone_javac_java__header
+genrule {
+ name: "cronet_aml_third_party_android_deps_com_google_errorprone_javac_java__header",
+ cmd: "$(location build/android/gyp/ijar.py) clang_x64/ijar " +
+ "../../third_party/android_deps/libs/com_google_errorprone_javac/javac-9+181-r4173-1.jar " +
+ "obj/third_party/android_deps/com_google_errorprone_javac.ijar.jar",
+ out: [
+ "//out/test/obj/third_party/android_deps/com_google_errorprone_javac.ijar.jar",
+ ],
+ tool_files: [
+ "build/android/gyp/ijar.py",
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/gn_helpers.py",
+ "out/test/clang_x64/ijar",
+ "third_party/android_deps/libs/com_google_errorprone_javac/javac-9+181-r4173-1.jar",
+ ],
+}
+
+// GN: //third_party/android_deps:com_google_errorprone_javac_java__host
+genrule {
+ name: "cronet_aml_third_party_android_deps_com_google_errorprone_javac_java__host",
+ cmd: "$(location build/android/gyp/filter_zip.py) --input " +
+ "../../third_party/android_deps/libs/com_google_errorprone_javac/javac-9+181-r4173-1.jar " +
+ "--output " +
+ "lib.java/third_party/android_deps/com_google_errorprone_javac.jar " +
+ "--exclude-globs " +
+ "[] " +
+ "--include-globs " +
+ "[]",
+ out: [
+ "//out/test/lib.java/third_party/android_deps/com_google_errorprone_javac.jar",
+ ],
+ tool_files: [
+ "build/android/gyp/filter_zip.py",
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/gn_helpers.py",
+ "third_party/android_deps/libs/com_google_errorprone_javac/javac-9+181-r4173-1.jar",
+ ],
+}
+
+// GN: //third_party/android_deps:com_google_guava_failureaccess_java__build_config_crbug_908819
+genrule {
+ name: "cronet_aml_third_party_android_deps_com_google_guava_failureaccess_java__build_config_crbug_908819",
+ cmd: "$(location build/android/gyp/write_build_config.py) --type " +
+ "java_library " +
+ " " +
+ " " +
+ "--deps-configs " +
+ "[\"$(location third_party/android_sdk/android_sdk_java.build_config.json)\"] " +
+ "--public-deps-configs " +
+ "[] " +
+ "--build-config " +
+ "$(genDir)/third_party/android_deps/com_google_guava_failureaccess_java.build_config.json " +
+ "--gn-target " +
+ "//third_party/android_deps:com_google_guava_failureaccess_java " +
+ "--non-chromium-code " +
+ "--device-jar-path " +
+ "$(location ../../third_party/android_deps/libs/com_google_guava_failureaccess/failureaccess-1.0.1.jar) " +
+ "--host-jar-path " +
+ "$(location lib.java/third_party/android_deps/com_google_guava_failureaccess.jar) " +
+ "--unprocessed-jar-path " +
+ "$(location ../../third_party/android_deps/libs/com_google_guava_failureaccess/failureaccess-1.0.1.jar) " +
+ "--interface-jar-path " +
+ "$(location third_party/android_deps/com_google_guava_failureaccess.ijar.jar) " +
+ "--dex-path " +
+ "obj/third_party/android_deps/com_google_guava_failureaccess_java.dex.jar " +
+ "--supports-android " +
+ "--is-prebuilt " +
+ "--bundled-srcjars " +
+ "[]",
+ out: [
+ "third_party/android_deps/com_google_guava_failureaccess_java.build_config.json",
+ ],
+ tool_files: [
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/android/gyp/util/resource_utils.py",
+ "build/android/gyp/write_build_config.py",
+ "build/gn_helpers.py",
+ "third_party/jinja2/__init__.py",
+ "third_party/jinja2/_compat.py",
+ "third_party/jinja2/_identifier.py",
+ "third_party/jinja2/bccache.py",
+ "third_party/jinja2/compiler.py",
+ "third_party/jinja2/defaults.py",
+ "third_party/jinja2/environment.py",
+ "third_party/jinja2/exceptions.py",
+ "third_party/jinja2/filters.py",
+ "third_party/jinja2/idtracking.py",
+ "third_party/jinja2/lexer.py",
+ "third_party/jinja2/loaders.py",
+ "third_party/jinja2/nodes.py",
+ "third_party/jinja2/optimizer.py",
+ "third_party/jinja2/parser.py",
+ "third_party/jinja2/runtime.py",
+ "third_party/jinja2/tests.py",
+ "third_party/jinja2/utils.py",
+ "third_party/jinja2/visitor.py",
+ "third_party/markupsafe/__init__.py",
+ "third_party/markupsafe/_compat.py",
+ "third_party/markupsafe/_native.py",
+ ],
+}
+
+// GN: //third_party/android_deps:com_google_guava_failureaccess_java__header
+genrule {
+ name: "cronet_aml_third_party_android_deps_com_google_guava_failureaccess_java__header",
+ cmd: "$(location build/android/gyp/ijar.py) clang_x64/ijar " +
+ "../../third_party/android_deps/libs/com_google_guava_failureaccess/failureaccess-1.0.1.jar " +
+ "obj/third_party/android_deps/com_google_guava_failureaccess.ijar.jar",
+ out: [
+ "//out/test/obj/third_party/android_deps/com_google_guava_failureaccess.ijar.jar",
+ ],
+ tool_files: [
+ "build/android/gyp/ijar.py",
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/gn_helpers.py",
+ "out/test/clang_x64/ijar",
+ "third_party/android_deps/libs/com_google_guava_failureaccess/failureaccess-1.0.1.jar",
+ ],
+}
+
+// GN: //third_party/android_deps:com_google_guava_failureaccess_java__host
+genrule {
+ name: "cronet_aml_third_party_android_deps_com_google_guava_failureaccess_java__host",
+ cmd: "$(location build/android/gyp/filter_zip.py) --input " +
+ "../../third_party/android_deps/libs/com_google_guava_failureaccess/failureaccess-1.0.1.jar " +
+ "--output " +
+ "lib.java/third_party/android_deps/com_google_guava_failureaccess.jar " +
+ "--exclude-globs " +
+ "[] " +
+ "--include-globs " +
+ "[]",
+ out: [
+ "//out/test/lib.java/third_party/android_deps/com_google_guava_failureaccess.jar",
+ ],
+ tool_files: [
+ "build/android/gyp/filter_zip.py",
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/gn_helpers.py",
+ "third_party/android_deps/libs/com_google_guava_failureaccess/failureaccess-1.0.1.jar",
+ ],
+}
+
+// GN: //third_party/android_deps:com_google_guava_guava_java__build_config_crbug_908819
+genrule {
+ name: "cronet_aml_third_party_android_deps_com_google_guava_guava_java__build_config_crbug_908819",
+ cmd: "$(location build/android/gyp/write_build_config.py) --type " +
+ "java_library " +
+ " " +
+ " " +
+ "--deps-configs " +
+ "[\"$(location third_party/android_deps/com_google_code_findbugs_jsr305_java.build_config.json)\", \"$(location third_party/android_deps/com_google_errorprone_error_prone_annotations_java.build_config.json)\", \"$(location third_party/android_deps/com_google_guava_failureaccess_java.build_config.json)\", \"$(location third_party/android_deps/com_google_guava_listenablefuture_java.build_config.json)\", \"$(location third_party/android_deps/com_google_j2objc_j2objc_annotations_java.build_config.json)\", \"$(location third_party/android_deps/org_checkerframework_checker_qual_java.build_config.json)\", \"$(location third_party/android_deps/com_google_guava_listenablefuture_java.build_config.json)\"] " +
+ "--public-deps-configs " +
+ "[] " +
+ "--build-config " +
+ "$(genDir)/third_party/android_deps/com_google_guava_guava_java.build_config.json " +
+ "--gn-target " +
+ "//third_party/android_deps:com_google_guava_guava_java " +
+ "--non-chromium-code " +
+ "--host-jar-path " +
+ "$(location lib.java/third_party/android_deps/com_google_guava_guava.jar) " +
+ "--unprocessed-jar-path " +
+ "$(location ../../third_party/android_deps/libs/com_google_guava_guava/guava-31.0.1-jre.jar) " +
+ "--interface-jar-path " +
+ "$(location third_party/android_deps/com_google_guava_guava.ijar.jar) " +
+ "--is-prebuilt " +
+ "--bundled-srcjars " +
+ "[]",
+ out: [
+ "third_party/android_deps/com_google_guava_guava_java.build_config.json",
+ ],
+ tool_files: [
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/android/gyp/util/resource_utils.py",
+ "build/android/gyp/write_build_config.py",
+ "build/gn_helpers.py",
+ "third_party/jinja2/__init__.py",
+ "third_party/jinja2/_compat.py",
+ "third_party/jinja2/_identifier.py",
+ "third_party/jinja2/bccache.py",
+ "third_party/jinja2/compiler.py",
+ "third_party/jinja2/defaults.py",
+ "third_party/jinja2/environment.py",
+ "third_party/jinja2/exceptions.py",
+ "third_party/jinja2/filters.py",
+ "third_party/jinja2/idtracking.py",
+ "third_party/jinja2/lexer.py",
+ "third_party/jinja2/loaders.py",
+ "third_party/jinja2/nodes.py",
+ "third_party/jinja2/optimizer.py",
+ "third_party/jinja2/parser.py",
+ "third_party/jinja2/runtime.py",
+ "third_party/jinja2/tests.py",
+ "third_party/jinja2/utils.py",
+ "third_party/jinja2/visitor.py",
+ "third_party/markupsafe/__init__.py",
+ "third_party/markupsafe/_compat.py",
+ "third_party/markupsafe/_native.py",
+ ],
+}
+
+// GN: //third_party/android_deps:com_google_guava_guava_java__header
+genrule {
+ name: "cronet_aml_third_party_android_deps_com_google_guava_guava_java__header",
+ cmd: "$(location build/android/gyp/ijar.py) clang_x64/ijar " +
+ "../../third_party/android_deps/libs/com_google_guava_guava/guava-31.0.1-jre.jar " +
+ "obj/third_party/android_deps/com_google_guava_guava.ijar.jar",
+ out: [
+ "//out/test/obj/third_party/android_deps/com_google_guava_guava.ijar.jar",
+ ],
+ tool_files: [
+ "build/android/gyp/ijar.py",
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/gn_helpers.py",
+ "out/test/clang_x64/ijar",
+ "third_party/android_deps/libs/com_google_guava_guava/guava-31.0.1-jre.jar",
+ ],
+}
+
+// GN: //third_party/android_deps:com_google_guava_guava_java__host
+genrule {
+ name: "cronet_aml_third_party_android_deps_com_google_guava_guava_java__host",
+ cmd: "$(location build/android/gyp/filter_zip.py) --input " +
+ "../../third_party/android_deps/libs/com_google_guava_guava/guava-31.0.1-jre.jar " +
+ "--output " +
+ "lib.java/third_party/android_deps/com_google_guava_guava.jar " +
+ "--exclude-globs " +
+ "[\"*/ListenableFuture.class\"] " +
+ "--include-globs " +
+ "[]",
+ out: [
+ "//out/test/lib.java/third_party/android_deps/com_google_guava_guava.jar",
+ ],
+ tool_files: [
+ "build/android/gyp/filter_zip.py",
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/gn_helpers.py",
+ "third_party/android_deps/libs/com_google_guava_guava/guava-31.0.1-jre.jar",
+ ],
+}
+
+// GN: //third_party/android_deps:com_google_guava_listenablefuture_java__build_config_crbug_908819
+genrule {
+ name: "cronet_aml_third_party_android_deps_com_google_guava_listenablefuture_java__build_config_crbug_908819",
+ cmd: "$(location build/android/gyp/write_build_config.py) --type " +
+ "java_library " +
+ " " +
+ " " +
+ "--deps-configs " +
+ "[\"$(location third_party/android_sdk/android_sdk_java.build_config.json)\"] " +
+ "--public-deps-configs " +
+ "[] " +
+ "--build-config " +
+ "$(genDir)/third_party/android_deps/com_google_guava_listenablefuture_java.build_config.json " +
+ "--gn-target " +
+ "//third_party/android_deps:com_google_guava_listenablefuture_java " +
+ "--non-chromium-code " +
+ "--device-jar-path " +
+ "$(location ../../third_party/android_deps/libs/com_google_guava_listenablefuture/listenablefuture-1.0.jar) " +
+ "--host-jar-path " +
+ "$(location lib.java/third_party/android_deps/com_google_guava_listenablefuture.jar) " +
+ "--unprocessed-jar-path " +
+ "$(location ../../third_party/android_deps/libs/com_google_guava_listenablefuture/listenablefuture-1.0.jar) " +
+ "--interface-jar-path " +
+ "$(location third_party/android_deps/com_google_guava_listenablefuture.ijar.jar) " +
+ "--dex-path " +
+ "obj/third_party/android_deps/com_google_guava_listenablefuture_java.dex.jar " +
+ "--supports-android " +
+ "--is-prebuilt " +
+ "--bundled-srcjars " +
+ "[]",
+ out: [
+ "third_party/android_deps/com_google_guava_listenablefuture_java.build_config.json",
+ ],
+ tool_files: [
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/android/gyp/util/resource_utils.py",
+ "build/android/gyp/write_build_config.py",
+ "build/gn_helpers.py",
+ "third_party/jinja2/__init__.py",
+ "third_party/jinja2/_compat.py",
+ "third_party/jinja2/_identifier.py",
+ "third_party/jinja2/bccache.py",
+ "third_party/jinja2/compiler.py",
+ "third_party/jinja2/defaults.py",
+ "third_party/jinja2/environment.py",
+ "third_party/jinja2/exceptions.py",
+ "third_party/jinja2/filters.py",
+ "third_party/jinja2/idtracking.py",
+ "third_party/jinja2/lexer.py",
+ "third_party/jinja2/loaders.py",
+ "third_party/jinja2/nodes.py",
+ "third_party/jinja2/optimizer.py",
+ "third_party/jinja2/parser.py",
+ "third_party/jinja2/runtime.py",
+ "third_party/jinja2/tests.py",
+ "third_party/jinja2/utils.py",
+ "third_party/jinja2/visitor.py",
+ "third_party/markupsafe/__init__.py",
+ "third_party/markupsafe/_compat.py",
+ "third_party/markupsafe/_native.py",
+ ],
+}
+
+// GN: //third_party/android_deps:com_google_guava_listenablefuture_java__header
+genrule {
+ name: "cronet_aml_third_party_android_deps_com_google_guava_listenablefuture_java__header",
+ cmd: "$(location build/android/gyp/ijar.py) clang_x64/ijar " +
+ "../../third_party/android_deps/libs/com_google_guava_listenablefuture/listenablefuture-1.0.jar " +
+ "obj/third_party/android_deps/com_google_guava_listenablefuture.ijar.jar",
+ out: [
+ "//out/test/obj/third_party/android_deps/com_google_guava_listenablefuture.ijar.jar",
+ ],
+ tool_files: [
+ "build/android/gyp/ijar.py",
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/gn_helpers.py",
+ "out/test/clang_x64/ijar",
+ "third_party/android_deps/libs/com_google_guava_listenablefuture/listenablefuture-1.0.jar",
+ ],
+}
+
+// GN: //third_party/android_deps:com_google_guava_listenablefuture_java__host
+genrule {
+ name: "cronet_aml_third_party_android_deps_com_google_guava_listenablefuture_java__host",
+ cmd: "$(location build/android/gyp/filter_zip.py) --input " +
+ "../../third_party/android_deps/libs/com_google_guava_listenablefuture/listenablefuture-1.0.jar " +
+ "--output " +
+ "lib.java/third_party/android_deps/com_google_guava_listenablefuture.jar " +
+ "--exclude-globs " +
+ "[] " +
+ "--include-globs " +
+ "[]",
+ out: [
+ "//out/test/lib.java/third_party/android_deps/com_google_guava_listenablefuture.jar",
+ ],
+ tool_files: [
+ "build/android/gyp/filter_zip.py",
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/gn_helpers.py",
+ "third_party/android_deps/libs/com_google_guava_listenablefuture/listenablefuture-1.0.jar",
+ ],
+}
+
+// GN: //third_party/android_deps:com_google_j2objc_j2objc_annotations_java__build_config_crbug_908819
+genrule {
+ name: "cronet_aml_third_party_android_deps_com_google_j2objc_j2objc_annotations_java__build_config_crbug_908819",
+ cmd: "$(location build/android/gyp/write_build_config.py) --type " +
+ "java_library " +
+ " " +
+ " " +
+ "--deps-configs " +
+ "[\"$(location third_party/android_sdk/android_sdk_java.build_config.json)\"] " +
+ "--public-deps-configs " +
+ "[] " +
+ "--build-config " +
+ "$(genDir)/third_party/android_deps/com_google_j2objc_j2objc_annotations_java.build_config.json " +
+ "--gn-target " +
+ "//third_party/android_deps:com_google_j2objc_j2objc_annotations_java " +
+ "--non-chromium-code " +
+ "--device-jar-path " +
+ "$(location ../../third_party/android_deps/libs/com_google_j2objc_j2objc_annotations/j2objc-annotations-1.3.jar) " +
+ "--host-jar-path " +
+ "$(location lib.java/third_party/android_deps/com_google_j2objc_j2objc_annotations.jar) " +
+ "--unprocessed-jar-path " +
+ "$(location ../../third_party/android_deps/libs/com_google_j2objc_j2objc_annotations/j2objc-annotations-1.3.jar) " +
+ "--interface-jar-path " +
+ "$(location third_party/android_deps/com_google_j2objc_j2objc_annotations.ijar.jar) " +
+ "--dex-path " +
+ "obj/third_party/android_deps/com_google_j2objc_j2objc_annotations_java.dex.jar " +
+ "--supports-android " +
+ "--is-prebuilt " +
+ "--bundled-srcjars " +
+ "[]",
+ out: [
+ "third_party/android_deps/com_google_j2objc_j2objc_annotations_java.build_config.json",
+ ],
+ tool_files: [
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/android/gyp/util/resource_utils.py",
+ "build/android/gyp/write_build_config.py",
+ "build/gn_helpers.py",
+ "third_party/jinja2/__init__.py",
+ "third_party/jinja2/_compat.py",
+ "third_party/jinja2/_identifier.py",
+ "third_party/jinja2/bccache.py",
+ "third_party/jinja2/compiler.py",
+ "third_party/jinja2/defaults.py",
+ "third_party/jinja2/environment.py",
+ "third_party/jinja2/exceptions.py",
+ "third_party/jinja2/filters.py",
+ "third_party/jinja2/idtracking.py",
+ "third_party/jinja2/lexer.py",
+ "third_party/jinja2/loaders.py",
+ "third_party/jinja2/nodes.py",
+ "third_party/jinja2/optimizer.py",
+ "third_party/jinja2/parser.py",
+ "third_party/jinja2/runtime.py",
+ "third_party/jinja2/tests.py",
+ "third_party/jinja2/utils.py",
+ "third_party/jinja2/visitor.py",
+ "third_party/markupsafe/__init__.py",
+ "third_party/markupsafe/_compat.py",
+ "third_party/markupsafe/_native.py",
+ ],
+}
+
+// GN: //third_party/android_deps:com_google_j2objc_j2objc_annotations_java__header
+genrule {
+ name: "cronet_aml_third_party_android_deps_com_google_j2objc_j2objc_annotations_java__header",
+ cmd: "$(location build/android/gyp/ijar.py) clang_x64/ijar " +
+ "../../third_party/android_deps/libs/com_google_j2objc_j2objc_annotations/j2objc-annotations-1.3.jar " +
+ "obj/third_party/android_deps/com_google_j2objc_j2objc_annotations.ijar.jar",
+ out: [
+ "//out/test/obj/third_party/android_deps/com_google_j2objc_j2objc_annotations.ijar.jar",
+ ],
+ tool_files: [
+ "build/android/gyp/ijar.py",
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/gn_helpers.py",
+ "out/test/clang_x64/ijar",
+ "third_party/android_deps/libs/com_google_j2objc_j2objc_annotations/j2objc-annotations-1.3.jar",
+ ],
+}
+
+// GN: //third_party/android_deps:com_google_j2objc_j2objc_annotations_java__host
+genrule {
+ name: "cronet_aml_third_party_android_deps_com_google_j2objc_j2objc_annotations_java__host",
+ cmd: "$(location build/android/gyp/filter_zip.py) --input " +
+ "../../third_party/android_deps/libs/com_google_j2objc_j2objc_annotations/j2objc-annotations-1.3.jar " +
+ "--output " +
+ "lib.java/third_party/android_deps/com_google_j2objc_j2objc_annotations.jar " +
+ "--exclude-globs " +
+ "[] " +
+ "--include-globs " +
+ "[]",
+ out: [
+ "//out/test/lib.java/third_party/android_deps/com_google_j2objc_j2objc_annotations.jar",
+ ],
+ tool_files: [
+ "build/android/gyp/filter_zip.py",
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/gn_helpers.py",
+ "third_party/android_deps/libs/com_google_j2objc_j2objc_annotations/j2objc-annotations-1.3.jar",
+ ],
+}
+
+// GN: //third_party/android_deps:com_google_protobuf_protobuf_java_java__build_config_crbug_908819
+genrule {
+ name: "cronet_aml_third_party_android_deps_com_google_protobuf_protobuf_java_java__build_config_crbug_908819",
+ cmd: "$(location build/android/gyp/write_build_config.py) --type " +
+ "java_library " +
+ " " +
+ " " +
+ "--deps-configs " +
+ "[] " +
+ "--public-deps-configs " +
+ "[] " +
+ "--build-config " +
+ "$(genDir)/third_party/android_deps/com_google_protobuf_protobuf_java_java.build_config.json " +
+ "--gn-target " +
+ "//third_party/android_deps:com_google_protobuf_protobuf_java_java " +
+ "--non-chromium-code " +
+ "--host-jar-path " +
+ "$(location lib.java/third_party/android_deps/com_google_protobuf_protobuf_java.jar) " +
+ "--unprocessed-jar-path " +
+ "$(location ../../third_party/android_deps/libs/com_google_protobuf_protobuf_java/protobuf-java-3.19.2.jar) " +
+ "--interface-jar-path " +
+ "$(location third_party/android_deps/com_google_protobuf_protobuf_java.ijar.jar) " +
+ "--is-prebuilt " +
+ "--bundled-srcjars " +
+ "[]",
+ out: [
+ "third_party/android_deps/com_google_protobuf_protobuf_java_java.build_config.json",
+ ],
+ tool_files: [
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/android/gyp/util/resource_utils.py",
+ "build/android/gyp/write_build_config.py",
+ "build/gn_helpers.py",
+ "third_party/jinja2/__init__.py",
+ "third_party/jinja2/_compat.py",
+ "third_party/jinja2/_identifier.py",
+ "third_party/jinja2/bccache.py",
+ "third_party/jinja2/compiler.py",
+ "third_party/jinja2/defaults.py",
+ "third_party/jinja2/environment.py",
+ "third_party/jinja2/exceptions.py",
+ "third_party/jinja2/filters.py",
+ "third_party/jinja2/idtracking.py",
+ "third_party/jinja2/lexer.py",
+ "third_party/jinja2/loaders.py",
+ "third_party/jinja2/nodes.py",
+ "third_party/jinja2/optimizer.py",
+ "third_party/jinja2/parser.py",
+ "third_party/jinja2/runtime.py",
+ "third_party/jinja2/tests.py",
+ "third_party/jinja2/utils.py",
+ "third_party/jinja2/visitor.py",
+ "third_party/markupsafe/__init__.py",
+ "third_party/markupsafe/_compat.py",
+ "third_party/markupsafe/_native.py",
+ ],
+}
+
+// GN: //third_party/android_deps:com_google_protobuf_protobuf_java_java__header
+genrule {
+ name: "cronet_aml_third_party_android_deps_com_google_protobuf_protobuf_java_java__header",
+ cmd: "$(location build/android/gyp/ijar.py) clang_x64/ijar " +
+ "../../third_party/android_deps/libs/com_google_protobuf_protobuf_java/protobuf-java-3.19.2.jar " +
+ "obj/third_party/android_deps/com_google_protobuf_protobuf_java.ijar.jar",
+ out: [
+ "//out/test/obj/third_party/android_deps/com_google_protobuf_protobuf_java.ijar.jar",
+ ],
+ tool_files: [
+ "build/android/gyp/ijar.py",
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/gn_helpers.py",
+ "out/test/clang_x64/ijar",
+ "third_party/android_deps/libs/com_google_protobuf_protobuf_java/protobuf-java-3.19.2.jar",
+ ],
+}
+
+// GN: //third_party/android_deps:com_google_protobuf_protobuf_java_java__host
+genrule {
+ name: "cronet_aml_third_party_android_deps_com_google_protobuf_protobuf_java_java__host",
+ cmd: "$(location build/android/gyp/filter_zip.py) --input " +
+ "../../third_party/android_deps/libs/com_google_protobuf_protobuf_java/protobuf-java-3.19.2.jar " +
+ "--output " +
+ "lib.java/third_party/android_deps/com_google_protobuf_protobuf_java.jar " +
+ "--exclude-globs " +
+ "[] " +
+ "--include-globs " +
+ "[]",
+ out: [
+ "//out/test/lib.java/third_party/android_deps/com_google_protobuf_protobuf_java.jar",
+ ],
+ tool_files: [
+ "build/android/gyp/filter_zip.py",
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/gn_helpers.py",
+ "third_party/android_deps/libs/com_google_protobuf_protobuf_java/protobuf-java-3.19.2.jar",
+ ],
+}
+
+// GN: //third_party/android_deps:io_github_java_diff_utils_java_diff_utils_java__build_config_crbug_908819
+genrule {
+ name: "cronet_aml_third_party_android_deps_io_github_java_diff_utils_java_diff_utils_java__build_config_crbug_908819",
+ cmd: "$(location build/android/gyp/write_build_config.py) --type " +
+ "java_library " +
+ " " +
+ " " +
+ "--deps-configs " +
+ "[\"$(location third_party/android_deps/org_eclipse_jgit_org_eclipse_jgit_java.build_config.json)\"] " +
+ "--public-deps-configs " +
+ "[] " +
+ "--build-config " +
+ "$(genDir)/third_party/android_deps/io_github_java_diff_utils_java_diff_utils_java.build_config.json " +
+ "--gn-target " +
+ "//third_party/android_deps:io_github_java_diff_utils_java_diff_utils_java " +
+ "--non-chromium-code " +
+ "--host-jar-path " +
+ "$(location lib.java/third_party/android_deps/io_github_java_diff_utils_java_diff_utils.jar) " +
+ "--unprocessed-jar-path " +
+ "$(location ../../third_party/android_deps/libs/io_github_java_diff_utils_java_diff_utils/java-diff-utils-4.0.jar) " +
+ "--interface-jar-path " +
+ "$(location third_party/android_deps/io_github_java_diff_utils_java_diff_utils.ijar.jar) " +
+ "--is-prebuilt " +
+ "--bundled-srcjars " +
+ "[]",
+ out: [
+ "third_party/android_deps/io_github_java_diff_utils_java_diff_utils_java.build_config.json",
+ ],
+ tool_files: [
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/android/gyp/util/resource_utils.py",
+ "build/android/gyp/write_build_config.py",
+ "build/gn_helpers.py",
+ "third_party/jinja2/__init__.py",
+ "third_party/jinja2/_compat.py",
+ "third_party/jinja2/_identifier.py",
+ "third_party/jinja2/bccache.py",
+ "third_party/jinja2/compiler.py",
+ "third_party/jinja2/defaults.py",
+ "third_party/jinja2/environment.py",
+ "third_party/jinja2/exceptions.py",
+ "third_party/jinja2/filters.py",
+ "third_party/jinja2/idtracking.py",
+ "third_party/jinja2/lexer.py",
+ "third_party/jinja2/loaders.py",
+ "third_party/jinja2/nodes.py",
+ "third_party/jinja2/optimizer.py",
+ "third_party/jinja2/parser.py",
+ "third_party/jinja2/runtime.py",
+ "third_party/jinja2/tests.py",
+ "third_party/jinja2/utils.py",
+ "third_party/jinja2/visitor.py",
+ "third_party/markupsafe/__init__.py",
+ "third_party/markupsafe/_compat.py",
+ "third_party/markupsafe/_native.py",
+ ],
+}
+
+// GN: //third_party/android_deps:io_github_java_diff_utils_java_diff_utils_java__header
+genrule {
+ name: "cronet_aml_third_party_android_deps_io_github_java_diff_utils_java_diff_utils_java__header",
+ cmd: "$(location build/android/gyp/ijar.py) clang_x64/ijar " +
+ "../../third_party/android_deps/libs/io_github_java_diff_utils_java_diff_utils/java-diff-utils-4.0.jar " +
+ "obj/third_party/android_deps/io_github_java_diff_utils_java_diff_utils.ijar.jar",
+ out: [
+ "//out/test/obj/third_party/android_deps/io_github_java_diff_utils_java_diff_utils.ijar.jar",
+ ],
+ tool_files: [
+ "build/android/gyp/ijar.py",
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/gn_helpers.py",
+ "out/test/clang_x64/ijar",
+ "third_party/android_deps/libs/io_github_java_diff_utils_java_diff_utils/java-diff-utils-4.0.jar",
+ ],
+}
+
+// GN: //third_party/android_deps:io_github_java_diff_utils_java_diff_utils_java__host
+genrule {
+ name: "cronet_aml_third_party_android_deps_io_github_java_diff_utils_java_diff_utils_java__host",
+ cmd: "$(location build/android/gyp/filter_zip.py) --input " +
+ "../../third_party/android_deps/libs/io_github_java_diff_utils_java_diff_utils/java-diff-utils-4.0.jar " +
+ "--output " +
+ "lib.java/third_party/android_deps/io_github_java_diff_utils_java_diff_utils.jar " +
+ "--exclude-globs " +
+ "[] " +
+ "--include-globs " +
+ "[]",
+ out: [
+ "//out/test/lib.java/third_party/android_deps/io_github_java_diff_utils_java_diff_utils.jar",
+ ],
+ tool_files: [
+ "build/android/gyp/filter_zip.py",
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/gn_helpers.py",
+ "third_party/android_deps/libs/io_github_java_diff_utils_java_diff_utils/java-diff-utils-4.0.jar",
+ ],
+}
+
+// GN: //third_party/android_deps:org_checkerframework_checker_qual_java__build_config_crbug_908819
+genrule {
+ name: "cronet_aml_third_party_android_deps_org_checkerframework_checker_qual_java__build_config_crbug_908819",
+ cmd: "$(location build/android/gyp/write_build_config.py) --type " +
+ "java_library " +
+ " " +
+ " " +
+ "--deps-configs " +
+ "[\"$(location third_party/android_sdk/android_sdk_java.build_config.json)\"] " +
+ "--public-deps-configs " +
+ "[] " +
+ "--build-config " +
+ "$(genDir)/third_party/android_deps/org_checkerframework_checker_qual_java.build_config.json " +
+ "--gn-target " +
+ "//third_party/android_deps:org_checkerframework_checker_qual_java " +
+ "--non-chromium-code " +
+ "--device-jar-path " +
+ "$(location ../../third_party/android_deps/libs/org_checkerframework_checker_qual/checker-qual-3.25.0.jar) " +
+ "--host-jar-path " +
+ "$(location lib.java/third_party/android_deps/org_checkerframework_checker_qual.jar) " +
+ "--unprocessed-jar-path " +
+ "$(location ../../third_party/android_deps/libs/org_checkerframework_checker_qual/checker-qual-3.25.0.jar) " +
+ "--interface-jar-path " +
+ "$(location third_party/android_deps/org_checkerframework_checker_qual.ijar.jar) " +
+ "--dex-path " +
+ "obj/third_party/android_deps/org_checkerframework_checker_qual_java.dex.jar " +
+ "--supports-android " +
+ "--is-prebuilt " +
+ "--bundled-srcjars " +
+ "[]",
+ out: [
+ "third_party/android_deps/org_checkerframework_checker_qual_java.build_config.json",
+ ],
+ tool_files: [
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/android/gyp/util/resource_utils.py",
+ "build/android/gyp/write_build_config.py",
+ "build/gn_helpers.py",
+ "third_party/jinja2/__init__.py",
+ "third_party/jinja2/_compat.py",
+ "third_party/jinja2/_identifier.py",
+ "third_party/jinja2/bccache.py",
+ "third_party/jinja2/compiler.py",
+ "third_party/jinja2/defaults.py",
+ "third_party/jinja2/environment.py",
+ "third_party/jinja2/exceptions.py",
+ "third_party/jinja2/filters.py",
+ "third_party/jinja2/idtracking.py",
+ "third_party/jinja2/lexer.py",
+ "third_party/jinja2/loaders.py",
+ "third_party/jinja2/nodes.py",
+ "third_party/jinja2/optimizer.py",
+ "third_party/jinja2/parser.py",
+ "third_party/jinja2/runtime.py",
+ "third_party/jinja2/tests.py",
+ "third_party/jinja2/utils.py",
+ "third_party/jinja2/visitor.py",
+ "third_party/markupsafe/__init__.py",
+ "third_party/markupsafe/_compat.py",
+ "third_party/markupsafe/_native.py",
+ ],
+}
+
+// GN: //third_party/android_deps:org_checkerframework_checker_qual_java__header
+genrule {
+ name: "cronet_aml_third_party_android_deps_org_checkerframework_checker_qual_java__header",
+ cmd: "$(location build/android/gyp/ijar.py) clang_x64/ijar " +
+ "../../third_party/android_deps/libs/org_checkerframework_checker_qual/checker-qual-3.25.0.jar " +
+ "obj/third_party/android_deps/org_checkerframework_checker_qual.ijar.jar",
+ out: [
+ "//out/test/obj/third_party/android_deps/org_checkerframework_checker_qual.ijar.jar",
+ ],
+ tool_files: [
+ "build/android/gyp/ijar.py",
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/gn_helpers.py",
+ "out/test/clang_x64/ijar",
+ "third_party/android_deps/libs/org_checkerframework_checker_qual/checker-qual-3.25.0.jar",
+ ],
+}
+
+// GN: //third_party/android_deps:org_checkerframework_checker_qual_java__host
+genrule {
+ name: "cronet_aml_third_party_android_deps_org_checkerframework_checker_qual_java__host",
+ cmd: "$(location build/android/gyp/filter_zip.py) --input " +
+ "../../third_party/android_deps/libs/org_checkerframework_checker_qual/checker-qual-3.25.0.jar " +
+ "--output " +
+ "lib.java/third_party/android_deps/org_checkerframework_checker_qual.jar " +
+ "--exclude-globs " +
+ "[] " +
+ "--include-globs " +
+ "[]",
+ out: [
+ "//out/test/lib.java/third_party/android_deps/org_checkerframework_checker_qual.jar",
+ ],
+ tool_files: [
+ "build/android/gyp/filter_zip.py",
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/gn_helpers.py",
+ "third_party/android_deps/libs/org_checkerframework_checker_qual/checker-qual-3.25.0.jar",
+ ],
+}
+
+// GN: //third_party/android_deps:org_checkerframework_dataflow_errorprone_java__build_config_crbug_908819
+genrule {
+ name: "cronet_aml_third_party_android_deps_org_checkerframework_dataflow_errorprone_java__build_config_crbug_908819",
+ cmd: "$(location build/android/gyp/write_build_config.py) --type " +
+ "java_library " +
+ " " +
+ " " +
+ "--deps-configs " +
+ "[] " +
+ "--public-deps-configs " +
+ "[] " +
+ "--build-config " +
+ "$(genDir)/third_party/android_deps/org_checkerframework_dataflow_errorprone_java.build_config.json " +
+ "--gn-target " +
+ "//third_party/android_deps:org_checkerframework_dataflow_errorprone_java " +
+ "--non-chromium-code " +
+ "--host-jar-path " +
+ "$(location lib.java/third_party/android_deps/org_checkerframework_dataflow_errorprone.jar) " +
+ "--unprocessed-jar-path " +
+ "$(location ../../third_party/android_deps/libs/org_checkerframework_dataflow_errorprone/dataflow-errorprone-3.15.0.jar) " +
+ "--interface-jar-path " +
+ "$(location third_party/android_deps/org_checkerframework_dataflow_errorprone.ijar.jar) " +
+ "--is-prebuilt " +
+ "--bundled-srcjars " +
+ "[]",
+ out: [
+ "third_party/android_deps/org_checkerframework_dataflow_errorprone_java.build_config.json",
+ ],
+ tool_files: [
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/android/gyp/util/resource_utils.py",
+ "build/android/gyp/write_build_config.py",
+ "build/gn_helpers.py",
+ "third_party/jinja2/__init__.py",
+ "third_party/jinja2/_compat.py",
+ "third_party/jinja2/_identifier.py",
+ "third_party/jinja2/bccache.py",
+ "third_party/jinja2/compiler.py",
+ "third_party/jinja2/defaults.py",
+ "third_party/jinja2/environment.py",
+ "third_party/jinja2/exceptions.py",
+ "third_party/jinja2/filters.py",
+ "third_party/jinja2/idtracking.py",
+ "third_party/jinja2/lexer.py",
+ "third_party/jinja2/loaders.py",
+ "third_party/jinja2/nodes.py",
+ "third_party/jinja2/optimizer.py",
+ "third_party/jinja2/parser.py",
+ "third_party/jinja2/runtime.py",
+ "third_party/jinja2/tests.py",
+ "third_party/jinja2/utils.py",
+ "third_party/jinja2/visitor.py",
+ "third_party/markupsafe/__init__.py",
+ "third_party/markupsafe/_compat.py",
+ "third_party/markupsafe/_native.py",
+ ],
+}
+
+// GN: //third_party/android_deps:org_checkerframework_dataflow_errorprone_java__header
+genrule {
+ name: "cronet_aml_third_party_android_deps_org_checkerframework_dataflow_errorprone_java__header",
+ cmd: "$(location build/android/gyp/ijar.py) clang_x64/ijar " +
+ "../../third_party/android_deps/libs/org_checkerframework_dataflow_errorprone/dataflow-errorprone-3.15.0.jar " +
+ "obj/third_party/android_deps/org_checkerframework_dataflow_errorprone.ijar.jar",
+ out: [
+ "//out/test/obj/third_party/android_deps/org_checkerframework_dataflow_errorprone.ijar.jar",
+ ],
+ tool_files: [
+ "build/android/gyp/ijar.py",
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/gn_helpers.py",
+ "out/test/clang_x64/ijar",
+ "third_party/android_deps/libs/org_checkerframework_dataflow_errorprone/dataflow-errorprone-3.15.0.jar",
+ ],
+}
+
+// GN: //third_party/android_deps:org_checkerframework_dataflow_errorprone_java__host
+genrule {
+ name: "cronet_aml_third_party_android_deps_org_checkerframework_dataflow_errorprone_java__host",
+ cmd: "$(location build/android/gyp/filter_zip.py) --input " +
+ "../../third_party/android_deps/libs/org_checkerframework_dataflow_errorprone/dataflow-errorprone-3.15.0.jar " +
+ "--output " +
+ "lib.java/third_party/android_deps/org_checkerframework_dataflow_errorprone.jar " +
+ "--exclude-globs " +
+ "[] " +
+ "--include-globs " +
+ "[]",
+ out: [
+ "//out/test/lib.java/third_party/android_deps/org_checkerframework_dataflow_errorprone.jar",
+ ],
+ tool_files: [
+ "build/android/gyp/filter_zip.py",
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/gn_helpers.py",
+ "third_party/android_deps/libs/org_checkerframework_dataflow_errorprone/dataflow-errorprone-3.15.0.jar",
+ ],
+}
+
+// GN: //third_party/android_deps:org_eclipse_jgit_org_eclipse_jgit_java__build_config_crbug_908819
+genrule {
+ name: "cronet_aml_third_party_android_deps_org_eclipse_jgit_org_eclipse_jgit_java__build_config_crbug_908819",
+ cmd: "$(location build/android/gyp/write_build_config.py) --type " +
+ "java_library " +
+ " " +
+ " " +
+ "--deps-configs " +
+ "[] " +
+ "--public-deps-configs " +
+ "[] " +
+ "--build-config " +
+ "$(genDir)/third_party/android_deps/org_eclipse_jgit_org_eclipse_jgit_java.build_config.json " +
+ "--gn-target " +
+ "//third_party/android_deps:org_eclipse_jgit_org_eclipse_jgit_java " +
+ "--non-chromium-code " +
+ "--host-jar-path " +
+ "$(location lib.java/third_party/android_deps/org_eclipse_jgit_org_eclipse_jgit.jar) " +
+ "--unprocessed-jar-path " +
+ "$(location ../../third_party/android_deps/libs/org_eclipse_jgit_org_eclipse_jgit/org.eclipse.jgit-4.4.1.201607150455-r.jar) " +
+ "--interface-jar-path " +
+ "$(location third_party/android_deps/org_eclipse_jgit_org_eclipse_jgit.ijar.jar) " +
+ "--is-prebuilt " +
+ "--bundled-srcjars " +
+ "[]",
+ out: [
+ "third_party/android_deps/org_eclipse_jgit_org_eclipse_jgit_java.build_config.json",
+ ],
+ tool_files: [
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/android/gyp/util/resource_utils.py",
+ "build/android/gyp/write_build_config.py",
+ "build/gn_helpers.py",
+ "third_party/jinja2/__init__.py",
+ "third_party/jinja2/_compat.py",
+ "third_party/jinja2/_identifier.py",
+ "third_party/jinja2/bccache.py",
+ "third_party/jinja2/compiler.py",
+ "third_party/jinja2/defaults.py",
+ "third_party/jinja2/environment.py",
+ "third_party/jinja2/exceptions.py",
+ "third_party/jinja2/filters.py",
+ "third_party/jinja2/idtracking.py",
+ "third_party/jinja2/lexer.py",
+ "third_party/jinja2/loaders.py",
+ "third_party/jinja2/nodes.py",
+ "third_party/jinja2/optimizer.py",
+ "third_party/jinja2/parser.py",
+ "third_party/jinja2/runtime.py",
+ "third_party/jinja2/tests.py",
+ "third_party/jinja2/utils.py",
+ "third_party/jinja2/visitor.py",
+ "third_party/markupsafe/__init__.py",
+ "third_party/markupsafe/_compat.py",
+ "third_party/markupsafe/_native.py",
+ ],
+}
+
+// GN: //third_party/android_deps:org_eclipse_jgit_org_eclipse_jgit_java__header
+genrule {
+ name: "cronet_aml_third_party_android_deps_org_eclipse_jgit_org_eclipse_jgit_java__header",
+ cmd: "$(location build/android/gyp/ijar.py) clang_x64/ijar " +
+ "../../third_party/android_deps/libs/org_eclipse_jgit_org_eclipse_jgit/org.eclipse.jgit-4.4.1.201607150455-r.jar " +
+ "obj/third_party/android_deps/org_eclipse_jgit_org_eclipse_jgit.ijar.jar",
+ out: [
+ "//out/test/obj/third_party/android_deps/org_eclipse_jgit_org_eclipse_jgit.ijar.jar",
+ ],
+ tool_files: [
+ "build/android/gyp/ijar.py",
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/gn_helpers.py",
+ "out/test/clang_x64/ijar",
+ "third_party/android_deps/libs/org_eclipse_jgit_org_eclipse_jgit/org.eclipse.jgit-4.4.1.201607150455-r.jar",
+ ],
+}
+
+// GN: //third_party/android_deps:org_eclipse_jgit_org_eclipse_jgit_java__host
+genrule {
+ name: "cronet_aml_third_party_android_deps_org_eclipse_jgit_org_eclipse_jgit_java__host",
+ cmd: "$(location build/android/gyp/filter_zip.py) --input " +
+ "../../third_party/android_deps/libs/org_eclipse_jgit_org_eclipse_jgit/org.eclipse.jgit-4.4.1.201607150455-r.jar " +
+ "--output " +
+ "lib.java/third_party/android_deps/org_eclipse_jgit_org_eclipse_jgit.jar " +
+ "--exclude-globs " +
+ "[] " +
+ "--include-globs " +
+ "[]",
+ out: [
+ "//out/test/lib.java/third_party/android_deps/org_eclipse_jgit_org_eclipse_jgit.jar",
+ ],
+ tool_files: [
+ "build/android/gyp/filter_zip.py",
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/gn_helpers.py",
+ "third_party/android_deps/libs/org_eclipse_jgit_org_eclipse_jgit/org.eclipse.jgit-4.4.1.201607150455-r.jar",
+ ],
+}
+
+// GN: //third_party/android_deps:org_ow2_asm_asm_analysis_java__build_config_crbug_908819
+genrule {
+ name: "cronet_aml_third_party_android_deps_org_ow2_asm_asm_analysis_java__build_config_crbug_908819",
+ cmd: "$(location build/android/gyp/write_build_config.py) --type " +
+ "java_library " +
+ " " +
+ " " +
+ "--deps-configs " +
+ "[\"$(location third_party/android_deps/org_ow2_asm_asm_tree_java.build_config.json)\"] " +
+ "--public-deps-configs " +
+ "[] " +
+ "--build-config " +
+ "$(genDir)/third_party/android_deps/org_ow2_asm_asm_analysis_java.build_config.json " +
+ "--gn-target " +
+ "//third_party/android_deps:org_ow2_asm_asm_analysis_java " +
+ "--non-chromium-code " +
+ "--host-jar-path " +
+ "$(location lib.java/third_party/android_deps/org_ow2_asm_asm_analysis.jar) " +
+ "--unprocessed-jar-path " +
+ "$(location ../../third_party/android_deps/libs/org_ow2_asm_asm_analysis/asm-analysis-9.2.jar) " +
+ "--interface-jar-path " +
+ "$(location third_party/android_deps/org_ow2_asm_asm_analysis.ijar.jar) " +
+ "--is-prebuilt " +
+ "--bundled-srcjars " +
+ "[]",
+ out: [
+ "third_party/android_deps/org_ow2_asm_asm_analysis_java.build_config.json",
+ ],
+ tool_files: [
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/android/gyp/util/resource_utils.py",
+ "build/android/gyp/write_build_config.py",
+ "build/gn_helpers.py",
+ "third_party/jinja2/__init__.py",
+ "third_party/jinja2/_compat.py",
+ "third_party/jinja2/_identifier.py",
+ "third_party/jinja2/bccache.py",
+ "third_party/jinja2/compiler.py",
+ "third_party/jinja2/defaults.py",
+ "third_party/jinja2/environment.py",
+ "third_party/jinja2/exceptions.py",
+ "third_party/jinja2/filters.py",
+ "third_party/jinja2/idtracking.py",
+ "third_party/jinja2/lexer.py",
+ "third_party/jinja2/loaders.py",
+ "third_party/jinja2/nodes.py",
+ "third_party/jinja2/optimizer.py",
+ "third_party/jinja2/parser.py",
+ "third_party/jinja2/runtime.py",
+ "third_party/jinja2/tests.py",
+ "third_party/jinja2/utils.py",
+ "third_party/jinja2/visitor.py",
+ "third_party/markupsafe/__init__.py",
+ "third_party/markupsafe/_compat.py",
+ "third_party/markupsafe/_native.py",
+ ],
+}
+
+// GN: //third_party/android_deps:org_ow2_asm_asm_analysis_java__header
+genrule {
+ name: "cronet_aml_third_party_android_deps_org_ow2_asm_asm_analysis_java__header",
+ cmd: "$(location build/android/gyp/ijar.py) clang_x64/ijar " +
+ "../../third_party/android_deps/libs/org_ow2_asm_asm_analysis/asm-analysis-9.2.jar " +
+ "obj/third_party/android_deps/org_ow2_asm_asm_analysis.ijar.jar",
+ out: [
+ "//out/test/obj/third_party/android_deps/org_ow2_asm_asm_analysis.ijar.jar",
+ ],
+ tool_files: [
+ "build/android/gyp/ijar.py",
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/gn_helpers.py",
+ "out/test/clang_x64/ijar",
+ "third_party/android_deps/libs/org_ow2_asm_asm_analysis/asm-analysis-9.2.jar",
+ ],
+}
+
+// GN: //third_party/android_deps:org_ow2_asm_asm_analysis_java__host
+genrule {
+ name: "cronet_aml_third_party_android_deps_org_ow2_asm_asm_analysis_java__host",
+ cmd: "$(location build/android/gyp/filter_zip.py) --input " +
+ "../../third_party/android_deps/libs/org_ow2_asm_asm_analysis/asm-analysis-9.2.jar " +
+ "--output " +
+ "lib.java/third_party/android_deps/org_ow2_asm_asm_analysis.jar " +
+ "--exclude-globs " +
+ "[] " +
+ "--include-globs " +
+ "[]",
+ out: [
+ "//out/test/lib.java/third_party/android_deps/org_ow2_asm_asm_analysis.jar",
+ ],
+ tool_files: [
+ "build/android/gyp/filter_zip.py",
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/gn_helpers.py",
+ "third_party/android_deps/libs/org_ow2_asm_asm_analysis/asm-analysis-9.2.jar",
+ ],
+}
+
+// GN: //third_party/android_deps:org_ow2_asm_asm_java__build_config_crbug_908819
+genrule {
+ name: "cronet_aml_third_party_android_deps_org_ow2_asm_asm_java__build_config_crbug_908819",
+ cmd: "$(location build/android/gyp/write_build_config.py) --type " +
+ "java_library " +
+ " " +
+ " " +
+ "--deps-configs " +
+ "[] " +
+ "--public-deps-configs " +
+ "[] " +
+ "--build-config " +
+ "$(genDir)/third_party/android_deps/org_ow2_asm_asm_java.build_config.json " +
+ "--gn-target " +
+ "//third_party/android_deps:org_ow2_asm_asm_java " +
+ "--non-chromium-code " +
+ "--host-jar-path " +
+ "$(location lib.java/third_party/android_deps/org_ow2_asm_asm.jar) " +
+ "--unprocessed-jar-path " +
+ "$(location ../../third_party/android_deps/libs/org_ow2_asm_asm/asm-9.2.jar) " +
+ "--interface-jar-path " +
+ "$(location third_party/android_deps/org_ow2_asm_asm.ijar.jar) " +
+ "--is-prebuilt " +
+ "--bundled-srcjars " +
+ "[]",
+ out: [
+ "third_party/android_deps/org_ow2_asm_asm_java.build_config.json",
+ ],
+ tool_files: [
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/android/gyp/util/resource_utils.py",
+ "build/android/gyp/write_build_config.py",
+ "build/gn_helpers.py",
+ "third_party/jinja2/__init__.py",
+ "third_party/jinja2/_compat.py",
+ "third_party/jinja2/_identifier.py",
+ "third_party/jinja2/bccache.py",
+ "third_party/jinja2/compiler.py",
+ "third_party/jinja2/defaults.py",
+ "third_party/jinja2/environment.py",
+ "third_party/jinja2/exceptions.py",
+ "third_party/jinja2/filters.py",
+ "third_party/jinja2/idtracking.py",
+ "third_party/jinja2/lexer.py",
+ "third_party/jinja2/loaders.py",
+ "third_party/jinja2/nodes.py",
+ "third_party/jinja2/optimizer.py",
+ "third_party/jinja2/parser.py",
+ "third_party/jinja2/runtime.py",
+ "third_party/jinja2/tests.py",
+ "third_party/jinja2/utils.py",
+ "third_party/jinja2/visitor.py",
+ "third_party/markupsafe/__init__.py",
+ "third_party/markupsafe/_compat.py",
+ "third_party/markupsafe/_native.py",
+ ],
+}
+
+// GN: //third_party/android_deps:org_ow2_asm_asm_java__header
+genrule {
+ name: "cronet_aml_third_party_android_deps_org_ow2_asm_asm_java__header",
+ cmd: "$(location build/android/gyp/ijar.py) clang_x64/ijar " +
+ "../../third_party/android_deps/libs/org_ow2_asm_asm/asm-9.2.jar " +
+ "obj/third_party/android_deps/org_ow2_asm_asm.ijar.jar",
+ out: [
+ "//out/test/obj/third_party/android_deps/org_ow2_asm_asm.ijar.jar",
+ ],
+ tool_files: [
+ "build/android/gyp/ijar.py",
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/gn_helpers.py",
+ "out/test/clang_x64/ijar",
+ "third_party/android_deps/libs/org_ow2_asm_asm/asm-9.2.jar",
+ ],
+}
+
+// GN: //third_party/android_deps:org_ow2_asm_asm_java__host
+genrule {
+ name: "cronet_aml_third_party_android_deps_org_ow2_asm_asm_java__host",
+ cmd: "$(location build/android/gyp/filter_zip.py) --input " +
+ "../../third_party/android_deps/libs/org_ow2_asm_asm/asm-9.2.jar " +
+ "--output " +
+ "lib.java/third_party/android_deps/org_ow2_asm_asm.jar " +
+ "--exclude-globs " +
+ "[] " +
+ "--include-globs " +
+ "[]",
+ out: [
+ "//out/test/lib.java/third_party/android_deps/org_ow2_asm_asm.jar",
+ ],
+ tool_files: [
+ "build/android/gyp/filter_zip.py",
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/gn_helpers.py",
+ "third_party/android_deps/libs/org_ow2_asm_asm/asm-9.2.jar",
+ ],
+}
+
+// GN: //third_party/android_deps:org_ow2_asm_asm_tree_java__build_config_crbug_908819
+genrule {
+ name: "cronet_aml_third_party_android_deps_org_ow2_asm_asm_tree_java__build_config_crbug_908819",
+ cmd: "$(location build/android/gyp/write_build_config.py) --type " +
+ "java_library " +
+ " " +
+ " " +
+ "--deps-configs " +
+ "[\"$(location third_party/android_deps/org_ow2_asm_asm_java.build_config.json)\"] " +
+ "--public-deps-configs " +
+ "[] " +
+ "--build-config " +
+ "$(genDir)/third_party/android_deps/org_ow2_asm_asm_tree_java.build_config.json " +
+ "--gn-target " +
+ "//third_party/android_deps:org_ow2_asm_asm_tree_java " +
+ "--non-chromium-code " +
+ "--host-jar-path " +
+ "$(location lib.java/third_party/android_deps/org_ow2_asm_asm_tree.jar) " +
+ "--unprocessed-jar-path " +
+ "$(location ../../third_party/android_deps/libs/org_ow2_asm_asm_tree/asm-tree-9.2.jar) " +
+ "--interface-jar-path " +
+ "$(location third_party/android_deps/org_ow2_asm_asm_tree.ijar.jar) " +
+ "--is-prebuilt " +
+ "--bundled-srcjars " +
+ "[]",
+ out: [
+ "third_party/android_deps/org_ow2_asm_asm_tree_java.build_config.json",
+ ],
+ tool_files: [
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/android/gyp/util/resource_utils.py",
+ "build/android/gyp/write_build_config.py",
+ "build/gn_helpers.py",
+ "third_party/jinja2/__init__.py",
+ "third_party/jinja2/_compat.py",
+ "third_party/jinja2/_identifier.py",
+ "third_party/jinja2/bccache.py",
+ "third_party/jinja2/compiler.py",
+ "third_party/jinja2/defaults.py",
+ "third_party/jinja2/environment.py",
+ "third_party/jinja2/exceptions.py",
+ "third_party/jinja2/filters.py",
+ "third_party/jinja2/idtracking.py",
+ "third_party/jinja2/lexer.py",
+ "third_party/jinja2/loaders.py",
+ "third_party/jinja2/nodes.py",
+ "third_party/jinja2/optimizer.py",
+ "third_party/jinja2/parser.py",
+ "third_party/jinja2/runtime.py",
+ "third_party/jinja2/tests.py",
+ "third_party/jinja2/utils.py",
+ "third_party/jinja2/visitor.py",
+ "third_party/markupsafe/__init__.py",
+ "third_party/markupsafe/_compat.py",
+ "third_party/markupsafe/_native.py",
+ ],
+}
+
+// GN: //third_party/android_deps:org_ow2_asm_asm_tree_java__header
+genrule {
+ name: "cronet_aml_third_party_android_deps_org_ow2_asm_asm_tree_java__header",
+ cmd: "$(location build/android/gyp/ijar.py) clang_x64/ijar " +
+ "../../third_party/android_deps/libs/org_ow2_asm_asm_tree/asm-tree-9.2.jar " +
+ "obj/third_party/android_deps/org_ow2_asm_asm_tree.ijar.jar",
+ out: [
+ "//out/test/obj/third_party/android_deps/org_ow2_asm_asm_tree.ijar.jar",
+ ],
+ tool_files: [
+ "build/android/gyp/ijar.py",
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/gn_helpers.py",
+ "out/test/clang_x64/ijar",
+ "third_party/android_deps/libs/org_ow2_asm_asm_tree/asm-tree-9.2.jar",
+ ],
+}
+
+// GN: //third_party/android_deps:org_ow2_asm_asm_tree_java__host
+genrule {
+ name: "cronet_aml_third_party_android_deps_org_ow2_asm_asm_tree_java__host",
+ cmd: "$(location build/android/gyp/filter_zip.py) --input " +
+ "../../third_party/android_deps/libs/org_ow2_asm_asm_tree/asm-tree-9.2.jar " +
+ "--output " +
+ "lib.java/third_party/android_deps/org_ow2_asm_asm_tree.jar " +
+ "--exclude-globs " +
+ "[] " +
+ "--include-globs " +
+ "[]",
+ out: [
+ "//out/test/lib.java/third_party/android_deps/org_ow2_asm_asm_tree.jar",
+ ],
+ tool_files: [
+ "build/android/gyp/filter_zip.py",
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/gn_helpers.py",
+ "third_party/android_deps/libs/org_ow2_asm_asm_tree/asm-tree-9.2.jar",
+ ],
+}
+
+// GN: //third_party/android_deps:org_ow2_asm_asm_util_java__build_config_crbug_908819
+genrule {
+ name: "cronet_aml_third_party_android_deps_org_ow2_asm_asm_util_java__build_config_crbug_908819",
+ cmd: "$(location build/android/gyp/write_build_config.py) --type " +
+ "java_library " +
+ " " +
+ " " +
+ "--deps-configs " +
+ "[\"$(location third_party/android_deps/org_ow2_asm_asm_analysis_java.build_config.json)\", \"$(location third_party/android_deps/org_ow2_asm_asm_java.build_config.json)\", \"$(location third_party/android_deps/org_ow2_asm_asm_tree_java.build_config.json)\"] " +
+ "--public-deps-configs " +
+ "[] " +
+ "--build-config " +
+ "$(genDir)/third_party/android_deps/org_ow2_asm_asm_util_java.build_config.json " +
+ "--gn-target " +
+ "//third_party/android_deps:org_ow2_asm_asm_util_java " +
+ "--non-chromium-code " +
+ "--host-jar-path " +
+ "$(location lib.java/third_party/android_deps/org_ow2_asm_asm_util.jar) " +
+ "--unprocessed-jar-path " +
+ "$(location ../../third_party/android_deps/libs/org_ow2_asm_asm_util/asm-util-9.2.jar) " +
+ "--interface-jar-path " +
+ "$(location third_party/android_deps/org_ow2_asm_asm_util.ijar.jar) " +
+ "--is-prebuilt " +
+ "--bundled-srcjars " +
+ "[]",
+ out: [
+ "third_party/android_deps/org_ow2_asm_asm_util_java.build_config.json",
+ ],
+ tool_files: [
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/android/gyp/util/resource_utils.py",
+ "build/android/gyp/write_build_config.py",
+ "build/gn_helpers.py",
+ "third_party/jinja2/__init__.py",
+ "third_party/jinja2/_compat.py",
+ "third_party/jinja2/_identifier.py",
+ "third_party/jinja2/bccache.py",
+ "third_party/jinja2/compiler.py",
+ "third_party/jinja2/defaults.py",
+ "third_party/jinja2/environment.py",
+ "third_party/jinja2/exceptions.py",
+ "third_party/jinja2/filters.py",
+ "third_party/jinja2/idtracking.py",
+ "third_party/jinja2/lexer.py",
+ "third_party/jinja2/loaders.py",
+ "third_party/jinja2/nodes.py",
+ "third_party/jinja2/optimizer.py",
+ "third_party/jinja2/parser.py",
+ "third_party/jinja2/runtime.py",
+ "third_party/jinja2/tests.py",
+ "third_party/jinja2/utils.py",
+ "third_party/jinja2/visitor.py",
+ "third_party/markupsafe/__init__.py",
+ "third_party/markupsafe/_compat.py",
+ "third_party/markupsafe/_native.py",
+ ],
+}
+
+// GN: //third_party/android_deps:org_ow2_asm_asm_util_java__header
+genrule {
+ name: "cronet_aml_third_party_android_deps_org_ow2_asm_asm_util_java__header",
+ cmd: "$(location build/android/gyp/ijar.py) clang_x64/ijar " +
+ "../../third_party/android_deps/libs/org_ow2_asm_asm_util/asm-util-9.2.jar " +
+ "obj/third_party/android_deps/org_ow2_asm_asm_util.ijar.jar",
+ out: [
+ "//out/test/obj/third_party/android_deps/org_ow2_asm_asm_util.ijar.jar",
+ ],
+ tool_files: [
+ "build/android/gyp/ijar.py",
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/gn_helpers.py",
+ "out/test/clang_x64/ijar",
+ "third_party/android_deps/libs/org_ow2_asm_asm_util/asm-util-9.2.jar",
+ ],
+}
+
+// GN: //third_party/android_deps:org_ow2_asm_asm_util_java__host
+genrule {
+ name: "cronet_aml_third_party_android_deps_org_ow2_asm_asm_util_java__host",
+ cmd: "$(location build/android/gyp/filter_zip.py) --input " +
+ "../../third_party/android_deps/libs/org_ow2_asm_asm_util/asm-util-9.2.jar " +
+ "--output " +
+ "lib.java/third_party/android_deps/org_ow2_asm_asm_util.jar " +
+ "--exclude-globs " +
+ "[] " +
+ "--include-globs " +
+ "[]",
+ out: [
+ "//out/test/lib.java/third_party/android_deps/org_ow2_asm_asm_util.jar",
+ ],
+ tool_files: [
+ "build/android/gyp/filter_zip.py",
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/gn_helpers.py",
+ "third_party/android_deps/libs/org_ow2_asm_asm_util/asm-util-9.2.jar",
+ ],
+}
+
+// GN: //third_party/android_deps:org_pcollections_pcollections_java__build_config_crbug_908819
+genrule {
+ name: "cronet_aml_third_party_android_deps_org_pcollections_pcollections_java__build_config_crbug_908819",
+ cmd: "$(location build/android/gyp/write_build_config.py) --type " +
+ "java_library " +
+ " " +
+ " " +
+ "--deps-configs " +
+ "[] " +
+ "--public-deps-configs " +
+ "[] " +
+ "--build-config " +
+ "$(genDir)/third_party/android_deps/org_pcollections_pcollections_java.build_config.json " +
+ "--gn-target " +
+ "//third_party/android_deps:org_pcollections_pcollections_java " +
+ "--non-chromium-code " +
+ "--host-jar-path " +
+ "$(location lib.java/third_party/android_deps/org_pcollections_pcollections.jar) " +
+ "--unprocessed-jar-path " +
+ "$(location ../../third_party/android_deps/libs/org_pcollections_pcollections/pcollections-3.1.4.jar) " +
+ "--interface-jar-path " +
+ "$(location third_party/android_deps/org_pcollections_pcollections.ijar.jar) " +
+ "--is-prebuilt " +
+ "--bundled-srcjars " +
+ "[]",
+ out: [
+ "third_party/android_deps/org_pcollections_pcollections_java.build_config.json",
+ ],
+ tool_files: [
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/android/gyp/util/resource_utils.py",
+ "build/android/gyp/write_build_config.py",
+ "build/gn_helpers.py",
+ "third_party/jinja2/__init__.py",
+ "third_party/jinja2/_compat.py",
+ "third_party/jinja2/_identifier.py",
+ "third_party/jinja2/bccache.py",
+ "third_party/jinja2/compiler.py",
+ "third_party/jinja2/defaults.py",
+ "third_party/jinja2/environment.py",
+ "third_party/jinja2/exceptions.py",
+ "third_party/jinja2/filters.py",
+ "third_party/jinja2/idtracking.py",
+ "third_party/jinja2/lexer.py",
+ "third_party/jinja2/loaders.py",
+ "third_party/jinja2/nodes.py",
+ "third_party/jinja2/optimizer.py",
+ "third_party/jinja2/parser.py",
+ "third_party/jinja2/runtime.py",
+ "third_party/jinja2/tests.py",
+ "third_party/jinja2/utils.py",
+ "third_party/jinja2/visitor.py",
+ "third_party/markupsafe/__init__.py",
+ "third_party/markupsafe/_compat.py",
+ "third_party/markupsafe/_native.py",
+ ],
+}
+
+// GN: //third_party/android_deps:org_pcollections_pcollections_java__header
+genrule {
+ name: "cronet_aml_third_party_android_deps_org_pcollections_pcollections_java__header",
+ cmd: "$(location build/android/gyp/ijar.py) clang_x64/ijar " +
+ "../../third_party/android_deps/libs/org_pcollections_pcollections/pcollections-3.1.4.jar " +
+ "obj/third_party/android_deps/org_pcollections_pcollections.ijar.jar",
+ out: [
+ "//out/test/obj/third_party/android_deps/org_pcollections_pcollections.ijar.jar",
+ ],
+ tool_files: [
+ "build/android/gyp/ijar.py",
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/gn_helpers.py",
+ "out/test/clang_x64/ijar",
+ "third_party/android_deps/libs/org_pcollections_pcollections/pcollections-3.1.4.jar",
+ ],
+}
+
+// GN: //third_party/android_deps:org_pcollections_pcollections_java__host
+genrule {
+ name: "cronet_aml_third_party_android_deps_org_pcollections_pcollections_java__host",
+ cmd: "$(location build/android/gyp/filter_zip.py) --input " +
+ "../../third_party/android_deps/libs/org_pcollections_pcollections/pcollections-3.1.4.jar " +
+ "--output " +
+ "lib.java/third_party/android_deps/org_pcollections_pcollections.jar " +
+ "--exclude-globs " +
+ "[] " +
+ "--include-globs " +
+ "[]",
+ out: [
+ "//out/test/lib.java/third_party/android_deps/org_pcollections_pcollections.jar",
+ ],
+ tool_files: [
+ "build/android/gyp/filter_zip.py",
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/gn_helpers.py",
+ "third_party/android_deps/libs/org_pcollections_pcollections/pcollections-3.1.4.jar",
+ ],
+}
+
+// GN: //third_party/android_ndk:cpu_features
+filegroup {
+ name: "cronet_aml_third_party_android_ndk_cpu_features",
+ srcs: [
+ "third_party/android_ndk/sources/android/cpufeatures/cpu-features.c",
+ ],
+}
+
+// GN: //third_party/android_sdk:android_sdk_java__build_config_crbug_908819
+genrule {
+ name: "cronet_aml_third_party_android_sdk_android_sdk_java__build_config_crbug_908819",
+ cmd: "$(location build/android/gyp/write_build_config.py) --type " +
+ "system_java_library " +
+ " " +
+ " " +
+ "--deps-configs " +
+ "[] " +
+ "--public-deps-configs " +
+ "[] " +
+ "--build-config " +
+ "$(genDir)/third_party/android_sdk/android_sdk_java.build_config.json " +
+ "--gn-target " +
+ "//third_party/android_sdk:android_sdk_java " +
+ "--non-chromium-code " +
+ "--unprocessed-jar-path " +
+ "$(location ../../third_party/android_sdk/public/platforms/android-33/android.jar) " +
+ "--interface-jar-path " +
+ "$(location third_party/android_sdk/android.ijar.jar) " +
+ "--supports-android " +
+ "--is-prebuilt " +
+ "--bundled-srcjars " +
+ "[]",
+ out: [
+ "third_party/android_sdk/android_sdk_java.build_config.json",
+ ],
+ tool_files: [
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/android/gyp/util/resource_utils.py",
+ "build/android/gyp/write_build_config.py",
+ "build/gn_helpers.py",
+ "third_party/jinja2/__init__.py",
+ "third_party/jinja2/_compat.py",
+ "third_party/jinja2/_identifier.py",
+ "third_party/jinja2/bccache.py",
+ "third_party/jinja2/compiler.py",
+ "third_party/jinja2/defaults.py",
+ "third_party/jinja2/environment.py",
+ "third_party/jinja2/exceptions.py",
+ "third_party/jinja2/filters.py",
+ "third_party/jinja2/idtracking.py",
+ "third_party/jinja2/lexer.py",
+ "third_party/jinja2/loaders.py",
+ "third_party/jinja2/nodes.py",
+ "third_party/jinja2/optimizer.py",
+ "third_party/jinja2/parser.py",
+ "third_party/jinja2/runtime.py",
+ "third_party/jinja2/tests.py",
+ "third_party/jinja2/utils.py",
+ "third_party/jinja2/visitor.py",
+ "third_party/markupsafe/__init__.py",
+ "third_party/markupsafe/_compat.py",
+ "third_party/markupsafe/_native.py",
+ ],
+}
+
+// GN: //third_party/android_sdk:android_sdk_java__header
+genrule {
+ name: "cronet_aml_third_party_android_sdk_android_sdk_java__header",
+ cmd: "$(location build/android/gyp/ijar.py) clang_x64/ijar " +
+ "../../third_party/android_sdk/public/platforms/android-33/android.jar " +
+ "obj/third_party/android_sdk/android.ijar.jar",
+ out: [
+ "//out/test/obj/third_party/android_sdk/android.ijar.jar",
+ ],
+ tool_files: [
+ "build/android/gyp/ijar.py",
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/gn_helpers.py",
+ "out/test/clang_x64/ijar",
+ "third_party/android_sdk/public/platforms/android-33/android.jar",
+ ],
+}
+
+// GN: //third_party/ashmem:ashmem
+filegroup {
+ name: "cronet_aml_third_party_ashmem_ashmem",
+ srcs: [
+ "third_party/ashmem/ashmem-dev.c",
+ ],
+}
+
+// GN: //third_party/boringssl:boringssl
+cc_library_static {
+ name: "cronet_aml_third_party_boringssl_boringssl",
+ srcs: [
+ ":cronet_aml_third_party_boringssl_boringssl_asm",
+ ":cronet_aml_third_party_boringssl_src_third_party_fiat_fiat_license",
+ "third_party/boringssl/err_data.c",
+ "third_party/boringssl/src/crypto/asn1/a_bitstr.c",
+ "third_party/boringssl/src/crypto/asn1/a_bool.c",
+ "third_party/boringssl/src/crypto/asn1/a_d2i_fp.c",
+ "third_party/boringssl/src/crypto/asn1/a_dup.c",
+ "third_party/boringssl/src/crypto/asn1/a_gentm.c",
+ "third_party/boringssl/src/crypto/asn1/a_i2d_fp.c",
+ "third_party/boringssl/src/crypto/asn1/a_int.c",
+ "third_party/boringssl/src/crypto/asn1/a_mbstr.c",
+ "third_party/boringssl/src/crypto/asn1/a_object.c",
+ "third_party/boringssl/src/crypto/asn1/a_octet.c",
+ "third_party/boringssl/src/crypto/asn1/a_print.c",
+ "third_party/boringssl/src/crypto/asn1/a_strex.c",
+ "third_party/boringssl/src/crypto/asn1/a_strnid.c",
+ "third_party/boringssl/src/crypto/asn1/a_time.c",
+ "third_party/boringssl/src/crypto/asn1/a_type.c",
+ "third_party/boringssl/src/crypto/asn1/a_utctm.c",
+ "third_party/boringssl/src/crypto/asn1/a_utf8.c",
+ "third_party/boringssl/src/crypto/asn1/asn1_lib.c",
+ "third_party/boringssl/src/crypto/asn1/asn1_par.c",
+ "third_party/boringssl/src/crypto/asn1/asn_pack.c",
+ "third_party/boringssl/src/crypto/asn1/f_int.c",
+ "third_party/boringssl/src/crypto/asn1/f_string.c",
+ "third_party/boringssl/src/crypto/asn1/posix_time.c",
+ "third_party/boringssl/src/crypto/asn1/tasn_dec.c",
+ "third_party/boringssl/src/crypto/asn1/tasn_enc.c",
+ "third_party/boringssl/src/crypto/asn1/tasn_fre.c",
+ "third_party/boringssl/src/crypto/asn1/tasn_new.c",
+ "third_party/boringssl/src/crypto/asn1/tasn_typ.c",
+ "third_party/boringssl/src/crypto/asn1/tasn_utl.c",
+ "third_party/boringssl/src/crypto/base64/base64.c",
+ "third_party/boringssl/src/crypto/bio/bio.c",
+ "third_party/boringssl/src/crypto/bio/bio_mem.c",
+ "third_party/boringssl/src/crypto/bio/connect.c",
+ "third_party/boringssl/src/crypto/bio/fd.c",
+ "third_party/boringssl/src/crypto/bio/file.c",
+ "third_party/boringssl/src/crypto/bio/hexdump.c",
+ "third_party/boringssl/src/crypto/bio/pair.c",
+ "third_party/boringssl/src/crypto/bio/printf.c",
+ "third_party/boringssl/src/crypto/bio/socket.c",
+ "third_party/boringssl/src/crypto/bio/socket_helper.c",
+ "third_party/boringssl/src/crypto/blake2/blake2.c",
+ "third_party/boringssl/src/crypto/bn_extra/bn_asn1.c",
+ "third_party/boringssl/src/crypto/bn_extra/convert.c",
+ "third_party/boringssl/src/crypto/buf/buf.c",
+ "third_party/boringssl/src/crypto/bytestring/asn1_compat.c",
+ "third_party/boringssl/src/crypto/bytestring/ber.c",
+ "third_party/boringssl/src/crypto/bytestring/cbb.c",
+ "third_party/boringssl/src/crypto/bytestring/cbs.c",
+ "third_party/boringssl/src/crypto/bytestring/unicode.c",
+ "third_party/boringssl/src/crypto/chacha/chacha.c",
+ "third_party/boringssl/src/crypto/cipher_extra/cipher_extra.c",
+ "third_party/boringssl/src/crypto/cipher_extra/derive_key.c",
+ "third_party/boringssl/src/crypto/cipher_extra/e_aesctrhmac.c",
+ "third_party/boringssl/src/crypto/cipher_extra/e_aesgcmsiv.c",
+ "third_party/boringssl/src/crypto/cipher_extra/e_chacha20poly1305.c",
+ "third_party/boringssl/src/crypto/cipher_extra/e_des.c",
+ "third_party/boringssl/src/crypto/cipher_extra/e_null.c",
+ "third_party/boringssl/src/crypto/cipher_extra/e_rc2.c",
+ "third_party/boringssl/src/crypto/cipher_extra/e_rc4.c",
+ "third_party/boringssl/src/crypto/cipher_extra/e_tls.c",
+ "third_party/boringssl/src/crypto/cipher_extra/tls_cbc.c",
+ "third_party/boringssl/src/crypto/conf/conf.c",
+ "third_party/boringssl/src/crypto/cpu_aarch64_apple.c",
+ "third_party/boringssl/src/crypto/cpu_aarch64_fuchsia.c",
+ "third_party/boringssl/src/crypto/cpu_aarch64_linux.c",
+ "third_party/boringssl/src/crypto/cpu_aarch64_win.c",
+ "third_party/boringssl/src/crypto/cpu_arm.c",
+ "third_party/boringssl/src/crypto/cpu_arm_linux.c",
+ "third_party/boringssl/src/crypto/cpu_intel.c",
+ "third_party/boringssl/src/crypto/cpu_ppc64le.c",
+ "third_party/boringssl/src/crypto/crypto.c",
+ "third_party/boringssl/src/crypto/curve25519/curve25519.c",
+ "third_party/boringssl/src/crypto/curve25519/spake25519.c",
+ "third_party/boringssl/src/crypto/des/des.c",
+ "third_party/boringssl/src/crypto/dh_extra/dh_asn1.c",
+ "third_party/boringssl/src/crypto/dh_extra/params.c",
+ "third_party/boringssl/src/crypto/digest_extra/digest_extra.c",
+ "third_party/boringssl/src/crypto/dsa/dsa.c",
+ "third_party/boringssl/src/crypto/dsa/dsa_asn1.c",
+ "third_party/boringssl/src/crypto/ec_extra/ec_asn1.c",
+ "third_party/boringssl/src/crypto/ec_extra/ec_derive.c",
+ "third_party/boringssl/src/crypto/ec_extra/hash_to_curve.c",
+ "third_party/boringssl/src/crypto/ecdh_extra/ecdh_extra.c",
+ "third_party/boringssl/src/crypto/ecdsa_extra/ecdsa_asn1.c",
+ "third_party/boringssl/src/crypto/engine/engine.c",
+ "third_party/boringssl/src/crypto/err/err.c",
+ "third_party/boringssl/src/crypto/evp/evp.c",
+ "third_party/boringssl/src/crypto/evp/evp_asn1.c",
+ "third_party/boringssl/src/crypto/evp/evp_ctx.c",
+ "third_party/boringssl/src/crypto/evp/p_dsa_asn1.c",
+ "third_party/boringssl/src/crypto/evp/p_ec.c",
+ "third_party/boringssl/src/crypto/evp/p_ec_asn1.c",
+ "third_party/boringssl/src/crypto/evp/p_ed25519.c",
+ "third_party/boringssl/src/crypto/evp/p_ed25519_asn1.c",
+ "third_party/boringssl/src/crypto/evp/p_hkdf.c",
+ "third_party/boringssl/src/crypto/evp/p_rsa.c",
+ "third_party/boringssl/src/crypto/evp/p_rsa_asn1.c",
+ "third_party/boringssl/src/crypto/evp/p_x25519.c",
+ "third_party/boringssl/src/crypto/evp/p_x25519_asn1.c",
+ "third_party/boringssl/src/crypto/evp/pbkdf.c",
+ "third_party/boringssl/src/crypto/evp/print.c",
+ "third_party/boringssl/src/crypto/evp/scrypt.c",
+ "third_party/boringssl/src/crypto/evp/sign.c",
+ "third_party/boringssl/src/crypto/ex_data.c",
+ "third_party/boringssl/src/crypto/fipsmodule/bcm.c",
+ "third_party/boringssl/src/crypto/fipsmodule/fips_shared_support.c",
+ "third_party/boringssl/src/crypto/hkdf/hkdf.c",
+ "third_party/boringssl/src/crypto/hpke/hpke.c",
+ "third_party/boringssl/src/crypto/hrss/hrss.c",
+ "third_party/boringssl/src/crypto/lhash/lhash.c",
+ "third_party/boringssl/src/crypto/mem.c",
+ "third_party/boringssl/src/crypto/obj/obj.c",
+ "third_party/boringssl/src/crypto/obj/obj_xref.c",
+ "third_party/boringssl/src/crypto/pem/pem_all.c",
+ "third_party/boringssl/src/crypto/pem/pem_info.c",
+ "third_party/boringssl/src/crypto/pem/pem_lib.c",
+ "third_party/boringssl/src/crypto/pem/pem_oth.c",
+ "third_party/boringssl/src/crypto/pem/pem_pk8.c",
+ "third_party/boringssl/src/crypto/pem/pem_pkey.c",
+ "third_party/boringssl/src/crypto/pem/pem_x509.c",
+ "third_party/boringssl/src/crypto/pem/pem_xaux.c",
+ "third_party/boringssl/src/crypto/pkcs7/pkcs7.c",
+ "third_party/boringssl/src/crypto/pkcs7/pkcs7_x509.c",
+ "third_party/boringssl/src/crypto/pkcs8/p5_pbev2.c",
+ "third_party/boringssl/src/crypto/pkcs8/pkcs8.c",
+ "third_party/boringssl/src/crypto/pkcs8/pkcs8_x509.c",
+ "third_party/boringssl/src/crypto/poly1305/poly1305.c",
+ "third_party/boringssl/src/crypto/poly1305/poly1305_arm.c",
+ "third_party/boringssl/src/crypto/poly1305/poly1305_vec.c",
+ "third_party/boringssl/src/crypto/pool/pool.c",
+ "third_party/boringssl/src/crypto/rand_extra/deterministic.c",
+ "third_party/boringssl/src/crypto/rand_extra/forkunsafe.c",
+ "third_party/boringssl/src/crypto/rand_extra/fuchsia.c",
+ "third_party/boringssl/src/crypto/rand_extra/passive.c",
+ "third_party/boringssl/src/crypto/rand_extra/rand_extra.c",
+ "third_party/boringssl/src/crypto/rand_extra/windows.c",
+ "third_party/boringssl/src/crypto/rc4/rc4.c",
+ "third_party/boringssl/src/crypto/refcount_c11.c",
+ "third_party/boringssl/src/crypto/refcount_lock.c",
+ "third_party/boringssl/src/crypto/rsa_extra/rsa_asn1.c",
+ "third_party/boringssl/src/crypto/rsa_extra/rsa_print.c",
+ "third_party/boringssl/src/crypto/siphash/siphash.c",
+ "third_party/boringssl/src/crypto/stack/stack.c",
+ "third_party/boringssl/src/crypto/thread.c",
+ "third_party/boringssl/src/crypto/thread_none.c",
+ "third_party/boringssl/src/crypto/thread_pthread.c",
+ "third_party/boringssl/src/crypto/thread_win.c",
+ "third_party/boringssl/src/crypto/trust_token/pmbtoken.c",
+ "third_party/boringssl/src/crypto/trust_token/trust_token.c",
+ "third_party/boringssl/src/crypto/trust_token/voprf.c",
+ "third_party/boringssl/src/crypto/x509/a_digest.c",
+ "third_party/boringssl/src/crypto/x509/a_sign.c",
+ "third_party/boringssl/src/crypto/x509/a_verify.c",
+ "third_party/boringssl/src/crypto/x509/algorithm.c",
+ "third_party/boringssl/src/crypto/x509/asn1_gen.c",
+ "third_party/boringssl/src/crypto/x509/by_dir.c",
+ "third_party/boringssl/src/crypto/x509/by_file.c",
+ "third_party/boringssl/src/crypto/x509/i2d_pr.c",
+ "third_party/boringssl/src/crypto/x509/name_print.c",
+ "third_party/boringssl/src/crypto/x509/rsa_pss.c",
+ "third_party/boringssl/src/crypto/x509/t_crl.c",
+ "third_party/boringssl/src/crypto/x509/t_req.c",
+ "third_party/boringssl/src/crypto/x509/t_x509.c",
+ "third_party/boringssl/src/crypto/x509/t_x509a.c",
+ "third_party/boringssl/src/crypto/x509/x509.c",
+ "third_party/boringssl/src/crypto/x509/x509_att.c",
+ "third_party/boringssl/src/crypto/x509/x509_cmp.c",
+ "third_party/boringssl/src/crypto/x509/x509_d2.c",
+ "third_party/boringssl/src/crypto/x509/x509_def.c",
+ "third_party/boringssl/src/crypto/x509/x509_ext.c",
+ "third_party/boringssl/src/crypto/x509/x509_lu.c",
+ "third_party/boringssl/src/crypto/x509/x509_obj.c",
+ "third_party/boringssl/src/crypto/x509/x509_req.c",
+ "third_party/boringssl/src/crypto/x509/x509_set.c",
+ "third_party/boringssl/src/crypto/x509/x509_trs.c",
+ "third_party/boringssl/src/crypto/x509/x509_txt.c",
+ "third_party/boringssl/src/crypto/x509/x509_v3.c",
+ "third_party/boringssl/src/crypto/x509/x509_vfy.c",
+ "third_party/boringssl/src/crypto/x509/x509_vpm.c",
+ "third_party/boringssl/src/crypto/x509/x509cset.c",
+ "third_party/boringssl/src/crypto/x509/x509name.c",
+ "third_party/boringssl/src/crypto/x509/x509rset.c",
+ "third_party/boringssl/src/crypto/x509/x509spki.c",
+ "third_party/boringssl/src/crypto/x509/x_algor.c",
+ "third_party/boringssl/src/crypto/x509/x_all.c",
+ "third_party/boringssl/src/crypto/x509/x_attrib.c",
+ "third_party/boringssl/src/crypto/x509/x_crl.c",
+ "third_party/boringssl/src/crypto/x509/x_exten.c",
+ "third_party/boringssl/src/crypto/x509/x_info.c",
+ "third_party/boringssl/src/crypto/x509/x_name.c",
+ "third_party/boringssl/src/crypto/x509/x_pkey.c",
+ "third_party/boringssl/src/crypto/x509/x_pubkey.c",
+ "third_party/boringssl/src/crypto/x509/x_req.c",
+ "third_party/boringssl/src/crypto/x509/x_sig.c",
+ "third_party/boringssl/src/crypto/x509/x_spki.c",
+ "third_party/boringssl/src/crypto/x509/x_val.c",
+ "third_party/boringssl/src/crypto/x509/x_x509.c",
+ "third_party/boringssl/src/crypto/x509/x_x509a.c",
+ "third_party/boringssl/src/crypto/x509v3/pcy_cache.c",
+ "third_party/boringssl/src/crypto/x509v3/pcy_data.c",
+ "third_party/boringssl/src/crypto/x509v3/pcy_map.c",
+ "third_party/boringssl/src/crypto/x509v3/pcy_node.c",
+ "third_party/boringssl/src/crypto/x509v3/pcy_tree.c",
+ "third_party/boringssl/src/crypto/x509v3/v3_akey.c",
+ "third_party/boringssl/src/crypto/x509v3/v3_akeya.c",
+ "third_party/boringssl/src/crypto/x509v3/v3_alt.c",
+ "third_party/boringssl/src/crypto/x509v3/v3_bcons.c",
+ "third_party/boringssl/src/crypto/x509v3/v3_bitst.c",
+ "third_party/boringssl/src/crypto/x509v3/v3_conf.c",
+ "third_party/boringssl/src/crypto/x509v3/v3_cpols.c",
+ "third_party/boringssl/src/crypto/x509v3/v3_crld.c",
+ "third_party/boringssl/src/crypto/x509v3/v3_enum.c",
+ "third_party/boringssl/src/crypto/x509v3/v3_extku.c",
+ "third_party/boringssl/src/crypto/x509v3/v3_genn.c",
+ "third_party/boringssl/src/crypto/x509v3/v3_ia5.c",
+ "third_party/boringssl/src/crypto/x509v3/v3_info.c",
+ "third_party/boringssl/src/crypto/x509v3/v3_int.c",
+ "third_party/boringssl/src/crypto/x509v3/v3_lib.c",
+ "third_party/boringssl/src/crypto/x509v3/v3_ncons.c",
+ "third_party/boringssl/src/crypto/x509v3/v3_ocsp.c",
+ "third_party/boringssl/src/crypto/x509v3/v3_pci.c",
+ "third_party/boringssl/src/crypto/x509v3/v3_pcia.c",
+ "third_party/boringssl/src/crypto/x509v3/v3_pcons.c",
+ "third_party/boringssl/src/crypto/x509v3/v3_pmaps.c",
+ "third_party/boringssl/src/crypto/x509v3/v3_prn.c",
+ "third_party/boringssl/src/crypto/x509v3/v3_purp.c",
+ "third_party/boringssl/src/crypto/x509v3/v3_skey.c",
+ "third_party/boringssl/src/crypto/x509v3/v3_utl.c",
+ "third_party/boringssl/src/ssl/bio_ssl.cc",
+ "third_party/boringssl/src/ssl/d1_both.cc",
+ "third_party/boringssl/src/ssl/d1_lib.cc",
+ "third_party/boringssl/src/ssl/d1_pkt.cc",
+ "third_party/boringssl/src/ssl/d1_srtp.cc",
+ "third_party/boringssl/src/ssl/dtls_method.cc",
+ "third_party/boringssl/src/ssl/dtls_record.cc",
+ "third_party/boringssl/src/ssl/encrypted_client_hello.cc",
+ "third_party/boringssl/src/ssl/extensions.cc",
+ "third_party/boringssl/src/ssl/handoff.cc",
+ "third_party/boringssl/src/ssl/handshake.cc",
+ "third_party/boringssl/src/ssl/handshake_client.cc",
+ "third_party/boringssl/src/ssl/handshake_server.cc",
+ "third_party/boringssl/src/ssl/s3_both.cc",
+ "third_party/boringssl/src/ssl/s3_lib.cc",
+ "third_party/boringssl/src/ssl/s3_pkt.cc",
+ "third_party/boringssl/src/ssl/ssl_aead_ctx.cc",
+ "third_party/boringssl/src/ssl/ssl_asn1.cc",
+ "third_party/boringssl/src/ssl/ssl_buffer.cc",
+ "third_party/boringssl/src/ssl/ssl_cert.cc",
+ "third_party/boringssl/src/ssl/ssl_cipher.cc",
+ "third_party/boringssl/src/ssl/ssl_file.cc",
+ "third_party/boringssl/src/ssl/ssl_key_share.cc",
+ "third_party/boringssl/src/ssl/ssl_lib.cc",
+ "third_party/boringssl/src/ssl/ssl_privkey.cc",
+ "third_party/boringssl/src/ssl/ssl_session.cc",
+ "third_party/boringssl/src/ssl/ssl_stat.cc",
+ "third_party/boringssl/src/ssl/ssl_transcript.cc",
+ "third_party/boringssl/src/ssl/ssl_versions.cc",
+ "third_party/boringssl/src/ssl/ssl_x509.cc",
+ "third_party/boringssl/src/ssl/t1_enc.cc",
+ "third_party/boringssl/src/ssl/tls13_both.cc",
+ "third_party/boringssl/src/ssl/tls13_client.cc",
+ "third_party/boringssl/src/ssl/tls13_enc.cc",
+ "third_party/boringssl/src/ssl/tls13_server.cc",
+ "third_party/boringssl/src/ssl/tls_method.cc",
+ "third_party/boringssl/src/ssl/tls_record.cc",
+ ],
+ defaults: [
+ "cronet_aml_defaults",
+ ],
+ cflags: [
+ "-DANDROID",
+ "-DANDROID_NDK_VERSION_ROLL=r23_1",
+ "-DBORINGSSL_ALLOW_CXX_RUNTIME",
+ "-DBORINGSSL_IMPLEMENTATION",
+ "-DBORINGSSL_NO_STATIC_INITIALIZER",
+ "-DCR_CLANG_REVISION=\"llvmorg-16-init-8697-g60809cd2-1\"",
+ "-DCR_LIBCXX_REVISION=47b31179d10646029c260702650a25d24f555acc",
+ "-DDCHECK_ALWAYS_ON=1",
+ "-DDYNAMIC_ANNOTATIONS_ENABLED=1",
+ "-DHAVE_SYS_UIO_H",
+ "-DOPENSSL_SMALL",
+ "-D_DEBUG",
+ "-D_GNU_SOURCE",
+ "-D_LIBCPP_AVAILABILITY_CUSTOM_VERBOSE_ABORT_PROVIDED=1",
+ "-D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS",
+ "-D_LIBCPP_ENABLE_ASSERTIONS_DEFAULT=1",
+ "-D_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS",
+ "-D__STDC_CONSTANT_MACROS",
+ "-D__STDC_FORMAT_MACROS",
+ ],
+ local_include_dirs: [
+ "./",
+ "buildtools/third_party/libc++/",
+ "buildtools/third_party/libc++/trunk/include",
+ "buildtools/third_party/libc++abi/trunk/include",
+ "third_party/boringssl/src/include/",
+ "third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include",
+ ],
+ cpp_std: "c++20",
+}
+
+// GN: //third_party/boringssl:boringssl_asm
+filegroup {
+ name: "cronet_aml_third_party_boringssl_boringssl_asm",
+}
+
+// GN: //third_party/boringssl/src/third_party/fiat:fiat_license
+filegroup {
+ name: "cronet_aml_third_party_boringssl_src_third_party_fiat_fiat_license",
+}
+
+// GN: //third_party/brotli:common
+cc_library_static {
+ name: "cronet_aml_third_party_brotli_common",
+ srcs: [
+ ":cronet_aml_third_party_brotli_headers",
+ "third_party/brotli/common/constants.c",
+ "third_party/brotli/common/context.c",
+ "third_party/brotli/common/dictionary.c",
+ "third_party/brotli/common/platform.c",
+ "third_party/brotli/common/shared_dictionary.c",
+ "third_party/brotli/common/transform.c",
+ ],
+ defaults: [
+ "cronet_aml_defaults",
+ ],
+ cflags: [
+ "-DANDROID",
+ "-DANDROID_NDK_VERSION_ROLL=r23_1",
+ "-DCR_CLANG_REVISION=\"llvmorg-16-init-8697-g60809cd2-1\"",
+ "-DCR_LIBCXX_REVISION=47b31179d10646029c260702650a25d24f555acc",
+ "-DDCHECK_ALWAYS_ON=1",
+ "-DDYNAMIC_ANNOTATIONS_ENABLED=1",
+ "-DHAVE_SYS_UIO_H",
+ "-D_DEBUG",
+ "-D_GNU_SOURCE",
+ "-D_LIBCPP_AVAILABILITY_CUSTOM_VERBOSE_ABORT_PROVIDED=1",
+ "-D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS",
+ "-D_LIBCPP_ENABLE_ASSERTIONS_DEFAULT=1",
+ "-D_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS",
+ "-D__STDC_CONSTANT_MACROS",
+ "-D__STDC_FORMAT_MACROS",
+ ],
+ local_include_dirs: [
+ "./",
+ "buildtools/third_party/libc++/",
+ "buildtools/third_party/libc++/trunk/include",
+ "buildtools/third_party/libc++abi/trunk/include",
+ "third_party/brotli/include/",
+ "third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include",
+ ],
+ cpp_std: "c++20",
+}
+
+// GN: //third_party/brotli:dec
+cc_library_static {
+ name: "cronet_aml_third_party_brotli_dec",
+ srcs: [
+ ":cronet_aml_third_party_brotli_headers",
+ "third_party/brotli/dec/bit_reader.c",
+ "third_party/brotli/dec/decode.c",
+ "third_party/brotli/dec/huffman.c",
+ "third_party/brotli/dec/state.c",
+ ],
+ static_libs: [
+ "cronet_aml_third_party_brotli_common",
+ ],
+ defaults: [
+ "cronet_aml_defaults",
+ ],
+ cflags: [
+ "-DANDROID",
+ "-DANDROID_NDK_VERSION_ROLL=r23_1",
+ "-DCR_CLANG_REVISION=\"llvmorg-16-init-8697-g60809cd2-1\"",
+ "-DCR_LIBCXX_REVISION=47b31179d10646029c260702650a25d24f555acc",
+ "-DDCHECK_ALWAYS_ON=1",
+ "-DDYNAMIC_ANNOTATIONS_ENABLED=1",
+ "-DHAVE_SYS_UIO_H",
+ "-D_DEBUG",
+ "-D_GNU_SOURCE",
+ "-D_LIBCPP_AVAILABILITY_CUSTOM_VERBOSE_ABORT_PROVIDED=1",
+ "-D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS",
+ "-D_LIBCPP_ENABLE_ASSERTIONS_DEFAULT=1",
+ "-D_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS",
+ "-D__STDC_CONSTANT_MACROS",
+ "-D__STDC_FORMAT_MACROS",
+ ],
+ local_include_dirs: [
+ "./",
+ "buildtools/third_party/libc++/",
+ "buildtools/third_party/libc++/trunk/include",
+ "buildtools/third_party/libc++abi/trunk/include",
+ "third_party/brotli/include/",
+ "third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include",
+ ],
+ cpp_std: "c++20",
+}
+
+// GN: //third_party/brotli:headers
+filegroup {
+ name: "cronet_aml_third_party_brotli_headers",
+}
+
+// GN: //third_party/icu:icui18n
+cc_library_static {
+ name: "cronet_aml_third_party_icu_icui18n",
+ static_libs: [
+ "cronet_aml_third_party_icu_icuuc_private",
+ ],
+ defaults: [
+ "cronet_aml_defaults",
+ ],
+ cflags: [
+ "-DANDROID",
+ "-DANDROID_NDK_VERSION_ROLL=r23_1",
+ "-DCR_CLANG_REVISION=\"llvmorg-16-init-8697-g60809cd2-1\"",
+ "-DCR_LIBCXX_REVISION=47b31179d10646029c260702650a25d24f555acc",
+ "-DDCHECK_ALWAYS_ON=1",
+ "-DDYNAMIC_ANNOTATIONS_ENABLED=1",
+ "-DHAVE_DLOPEN=0",
+ "-DHAVE_SYS_UIO_H",
+ "-DICU_UTIL_DATA_IMPL=ICU_UTIL_DATA_FILE",
+ "-DUCONFIG_ONLY_HTML_CONVERSION=1",
+ "-DUCONFIG_USE_WINDOWS_LCID_MAPPING_API=0",
+ "-DUSE_CHROMIUM_ICU=1",
+ "-DU_CHARSET_IS_UTF8=1",
+ "-DU_ENABLE_DYLOAD=0",
+ "-DU_ENABLE_RESOURCE_TRACING=0",
+ "-DU_ENABLE_TRACING=1",
+ "-DU_I18N_IMPLEMENTATION",
+ "-DU_STATIC_IMPLEMENTATION",
+ "-DU_USING_ICU_NAMESPACE=0",
+ "-D_DEBUG",
+ "-D_GNU_SOURCE",
+ "-D_LIBCPP_AVAILABILITY_CUSTOM_VERBOSE_ABORT_PROVIDED=1",
+ "-D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS",
+ "-D_LIBCPP_ENABLE_ASSERTIONS_DEFAULT=1",
+ "-D_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS",
+ ],
+ local_include_dirs: [
+ "./",
+ "buildtools/third_party/libc++/",
+ "buildtools/third_party/libc++/trunk/include",
+ "buildtools/third_party/libc++abi/trunk/include",
+ "third_party/icu/source/common/",
+ "third_party/icu/source/i18n/",
+ "third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include",
+ ],
+ cpp_std: "c++20",
+}
+
+// GN: //third_party/icu:icuuc_private
+cc_library_static {
+ name: "cronet_aml_third_party_icu_icuuc_private",
+ srcs: [
+ ":cronet_aml_third_party_icu_icuuc_public",
+ ],
+ defaults: [
+ "cronet_aml_defaults",
+ ],
+ cflags: [
+ "-DANDROID",
+ "-DANDROID_NDK_VERSION_ROLL=r23_1",
+ "-DCR_CLANG_REVISION=\"llvmorg-16-init-8697-g60809cd2-1\"",
+ "-DCR_LIBCXX_REVISION=47b31179d10646029c260702650a25d24f555acc",
+ "-DDCHECK_ALWAYS_ON=1",
+ "-DDYNAMIC_ANNOTATIONS_ENABLED=1",
+ "-DHAVE_DLOPEN=0",
+ "-DHAVE_SYS_UIO_H",
+ "-DICU_UTIL_DATA_IMPL=ICU_UTIL_DATA_FILE",
+ "-DUCONFIG_ONLY_HTML_CONVERSION=1",
+ "-DUCONFIG_USE_WINDOWS_LCID_MAPPING_API=0",
+ "-DUSE_CHROMIUM_ICU=1",
+ "-DU_CHARSET_IS_UTF8=1",
+ "-DU_COMMON_IMPLEMENTATION",
+ "-DU_ENABLE_DYLOAD=0",
+ "-DU_ENABLE_RESOURCE_TRACING=0",
+ "-DU_ENABLE_TRACING=1",
+ "-DU_ICUDATAENTRY_IN_COMMON",
+ "-DU_STATIC_IMPLEMENTATION",
+ "-DU_USING_ICU_NAMESPACE=0",
+ "-D_DEBUG",
+ "-D_GNU_SOURCE",
+ "-D_LIBCPP_AVAILABILITY_CUSTOM_VERBOSE_ABORT_PROVIDED=1",
+ "-D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS",
+ "-D_LIBCPP_ENABLE_ASSERTIONS_DEFAULT=1",
+ "-D_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS",
+ "-D__STDC_CONSTANT_MACROS",
+ "-D__STDC_FORMAT_MACROS",
+ ],
+ local_include_dirs: [
+ "./",
+ "buildtools/third_party/libc++/",
+ "buildtools/third_party/libc++/trunk/include",
+ "buildtools/third_party/libc++abi/trunk/include",
+ "third_party/icu/source/common/",
+ "third_party/icu/source/i18n/",
+ "third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include",
+ ],
+ cpp_std: "c++20",
+}
+
+// GN: //third_party/icu:icuuc_public
+filegroup {
+ name: "cronet_aml_third_party_icu_icuuc_public",
+}
+
+// GN: //third_party/ijar:ijar
+cc_binary {
+ name: "cronet_aml_third_party_ijar_ijar",
+ srcs: [
+ ":cronet_aml_buildtools_third_party_libc___libc__",
+ ":cronet_aml_buildtools_third_party_libc__abi_libc__abi",
+ "third_party/ijar/classfile.cc",
+ "third_party/ijar/ijar.cc",
+ "third_party/ijar/mapped_file_unix.cc",
+ "third_party/ijar/platform_utils.cc",
+ "third_party/ijar/zip.cc",
+ "third_party/ijar/zlib_client.cc",
+ ],
+ static_libs: [
+ "cronet_aml_third_party_zlib_zlib",
+ ],
+ defaults: [
+ "cronet_aml_defaults",
+ ],
+ cflags: [
+ "-DCR_CLANG_REVISION=\"llvmorg-16-init-8697-g60809cd2-1\"",
+ "-DCR_LIBCXX_REVISION=47b31179d10646029c260702650a25d24f555acc",
+ "-DCR_SYSROOT_KEY=20220331T153654Z-0",
+ "-DDCHECK_ALWAYS_ON=1",
+ "-DDYNAMIC_ANNOTATIONS_ENABLED=0",
+ "-DDYNAMIC_ANNOTATIONS_ENABLED=1",
+ "-DLIBCXXABI_SILENT_TERMINATE",
+ "-DLIBCXX_BUILDING_LIBCXXABI",
+ "-DNDEBUG",
+ "-DNVALGRIND",
+ "-DUSE_AURA=1",
+ "-DUSE_OZONE=1",
+ "-DUSE_UDEV",
+ "-D_DEBUG",
+ "-D_FILE_OFFSET_BITS=64",
+ "-D_GNU_SOURCE",
+ "-D_LARGEFILE64_SOURCE",
+ "-D_LARGEFILE_SOURCE",
+ "-D_LIBCPP_AVAILABILITY_CUSTOM_VERBOSE_ABORT_PROVIDED=1",
+ "-D_LIBCPP_BUILDING_LIBRARY",
+ "-D_LIBCPP_CONSTINIT=constinit",
+ "-D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS",
+ "-D_LIBCPP_ENABLE_ASSERTIONS_DEFAULT=1",
+ "-D_LIBCPP_OVERRIDABLE_FUNC_VIS=__attribute__((__visibility__(\"default\")))",
+ "-D_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS",
+ "-D__STDC_CONSTANT_MACROS",
+ "-D__STDC_FORMAT_MACROS",
+ ],
+ local_include_dirs: [
+ "./",
+ "buildtools/third_party/libc++/",
+ "buildtools/third_party/libc++/trunk/include",
+ "buildtools/third_party/libc++/trunk/src/",
+ "buildtools/third_party/libc++abi/trunk/include",
+ "third_party/zlib/",
+ "build/linux/debian_bullseye_amd64-sysroot/usr/include",
+ ],
+ cpp_std: "c++20",
+}
+
+// GN: //third_party/libevent:libevent
+cc_library_static {
+ name: "cronet_aml_third_party_libevent_libevent",
+ srcs: [
+ "third_party/libevent/buffer.c",
+ "third_party/libevent/epoll.c",
+ "third_party/libevent/evbuffer.c",
+ "third_party/libevent/evdns.c",
+ "third_party/libevent/event.c",
+ "third_party/libevent/event_tagging.c",
+ "third_party/libevent/evrpc.c",
+ "third_party/libevent/evutil.c",
+ "third_party/libevent/http.c",
+ "third_party/libevent/log.c",
+ "third_party/libevent/poll.c",
+ "third_party/libevent/select.c",
+ "third_party/libevent/signal.c",
+ "third_party/libevent/strlcpy.c",
+ ],
+ defaults: [
+ "cronet_aml_defaults",
+ ],
+ cflags: [
+ "-DANDROID",
+ "-DANDROID_NDK_VERSION_ROLL=r23_1",
+ "-DCR_CLANG_REVISION=\"llvmorg-16-init-8697-g60809cd2-1\"",
+ "-DCR_LIBCXX_REVISION=47b31179d10646029c260702650a25d24f555acc",
+ "-DDCHECK_ALWAYS_ON=1",
+ "-DDYNAMIC_ANNOTATIONS_ENABLED=1",
+ "-DHAVE_CONFIG_H",
+ "-DHAVE_SYS_UIO_H",
+ "-D_DEBUG",
+ "-D_GNU_SOURCE",
+ "-D_LIBCPP_AVAILABILITY_CUSTOM_VERBOSE_ABORT_PROVIDED=1",
+ "-D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS",
+ "-D_LIBCPP_ENABLE_ASSERTIONS_DEFAULT=1",
+ "-D_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS",
+ ],
+ local_include_dirs: [
+ "./",
+ "buildtools/third_party/libc++/",
+ "buildtools/third_party/libc++/trunk/include",
+ "buildtools/third_party/libc++abi/trunk/include",
+ "third_party/libevent/android/",
+ "third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include",
+ ],
+ cpp_std: "c++20",
+}
+
+// GN: //third_party/modp_b64:modp_b64
+cc_library_static {
+ name: "cronet_aml_third_party_modp_b64_modp_b64",
+ srcs: [
+ "third_party/modp_b64/modp_b64.cc",
+ ],
+ defaults: [
+ "cronet_aml_defaults",
+ ],
+ cflags: [
+ "-DANDROID",
+ "-DANDROID_NDK_VERSION_ROLL=r23_1",
+ "-DCR_CLANG_REVISION=\"llvmorg-16-init-8697-g60809cd2-1\"",
+ "-DCR_LIBCXX_REVISION=47b31179d10646029c260702650a25d24f555acc",
+ "-DDCHECK_ALWAYS_ON=1",
+ "-DDYNAMIC_ANNOTATIONS_ENABLED=1",
+ "-DHAVE_SYS_UIO_H",
+ "-D_DEBUG",
+ "-D_GNU_SOURCE",
+ "-D_LIBCPP_AVAILABILITY_CUSTOM_VERBOSE_ABORT_PROVIDED=1",
+ "-D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS",
+ "-D_LIBCPP_ENABLE_ASSERTIONS_DEFAULT=1",
+ "-D_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS",
+ "-D__STDC_CONSTANT_MACROS",
+ "-D__STDC_FORMAT_MACROS",
+ ],
+ local_include_dirs: [
+ "./",
+ "buildtools/third_party/libc++/",
+ "buildtools/third_party/libc++/trunk/include",
+ "buildtools/third_party/libc++abi/trunk/include",
+ "third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include",
+ ],
+ cpp_std: "c++20",
+}
+
+// GN: //third_party/protobuf:protobuf_full
+cc_library_static {
+ name: "cronet_aml_third_party_protobuf_protobuf_full",
+ srcs: [
+ "third_party/protobuf/src/google/protobuf/any.cc",
+ "third_party/protobuf/src/google/protobuf/any.pb.cc",
+ "third_party/protobuf/src/google/protobuf/any_lite.cc",
+ "third_party/protobuf/src/google/protobuf/api.pb.cc",
+ "third_party/protobuf/src/google/protobuf/arena.cc",
+ "third_party/protobuf/src/google/protobuf/arenastring.cc",
+ "third_party/protobuf/src/google/protobuf/arenaz_sampler.cc",
+ "third_party/protobuf/src/google/protobuf/compiler/importer.cc",
+ "third_party/protobuf/src/google/protobuf/compiler/parser.cc",
+ "third_party/protobuf/src/google/protobuf/descriptor.cc",
+ "third_party/protobuf/src/google/protobuf/descriptor.pb.cc",
+ "third_party/protobuf/src/google/protobuf/descriptor_database.cc",
+ "third_party/protobuf/src/google/protobuf/duration.pb.cc",
+ "third_party/protobuf/src/google/protobuf/dynamic_message.cc",
+ "third_party/protobuf/src/google/protobuf/empty.pb.cc",
+ "third_party/protobuf/src/google/protobuf/extension_set.cc",
+ "third_party/protobuf/src/google/protobuf/extension_set_heavy.cc",
+ "third_party/protobuf/src/google/protobuf/field_mask.pb.cc",
+ "third_party/protobuf/src/google/protobuf/generated_enum_util.cc",
+ "third_party/protobuf/src/google/protobuf/generated_message_bases.cc",
+ "third_party/protobuf/src/google/protobuf/generated_message_reflection.cc",
+ "third_party/protobuf/src/google/protobuf/generated_message_tctable_full.cc",
+ "third_party/protobuf/src/google/protobuf/generated_message_tctable_lite.cc",
+ "third_party/protobuf/src/google/protobuf/generated_message_util.cc",
+ "third_party/protobuf/src/google/protobuf/implicit_weak_message.cc",
+ "third_party/protobuf/src/google/protobuf/inlined_string_field.cc",
+ "third_party/protobuf/src/google/protobuf/io/coded_stream.cc",
+ "third_party/protobuf/src/google/protobuf/io/gzip_stream.cc",
+ "third_party/protobuf/src/google/protobuf/io/io_win32.cc",
+ "third_party/protobuf/src/google/protobuf/io/printer.cc",
+ "third_party/protobuf/src/google/protobuf/io/strtod.cc",
+ "third_party/protobuf/src/google/protobuf/io/tokenizer.cc",
+ "third_party/protobuf/src/google/protobuf/io/zero_copy_stream.cc",
+ "third_party/protobuf/src/google/protobuf/io/zero_copy_stream_impl.cc",
+ "third_party/protobuf/src/google/protobuf/io/zero_copy_stream_impl_lite.cc",
+ "third_party/protobuf/src/google/protobuf/map.cc",
+ "third_party/protobuf/src/google/protobuf/map_field.cc",
+ "third_party/protobuf/src/google/protobuf/message.cc",
+ "third_party/protobuf/src/google/protobuf/message_lite.cc",
+ "third_party/protobuf/src/google/protobuf/parse_context.cc",
+ "third_party/protobuf/src/google/protobuf/reflection_ops.cc",
+ "third_party/protobuf/src/google/protobuf/repeated_field.cc",
+ "third_party/protobuf/src/google/protobuf/repeated_ptr_field.cc",
+ "third_party/protobuf/src/google/protobuf/service.cc",
+ "third_party/protobuf/src/google/protobuf/source_context.pb.cc",
+ "third_party/protobuf/src/google/protobuf/struct.pb.cc",
+ "third_party/protobuf/src/google/protobuf/stubs/bytestream.cc",
+ "third_party/protobuf/src/google/protobuf/stubs/common.cc",
+ "third_party/protobuf/src/google/protobuf/stubs/int128.cc",
+ "third_party/protobuf/src/google/protobuf/stubs/status.cc",
+ "third_party/protobuf/src/google/protobuf/stubs/statusor.cc",
+ "third_party/protobuf/src/google/protobuf/stubs/stringpiece.cc",
+ "third_party/protobuf/src/google/protobuf/stubs/stringprintf.cc",
+ "third_party/protobuf/src/google/protobuf/stubs/structurally_valid.cc",
+ "third_party/protobuf/src/google/protobuf/stubs/strutil.cc",
+ "third_party/protobuf/src/google/protobuf/stubs/substitute.cc",
+ "third_party/protobuf/src/google/protobuf/stubs/time.cc",
+ "third_party/protobuf/src/google/protobuf/text_format.cc",
+ "third_party/protobuf/src/google/protobuf/timestamp.pb.cc",
+ "third_party/protobuf/src/google/protobuf/type.pb.cc",
+ "third_party/protobuf/src/google/protobuf/unknown_field_set.cc",
+ "third_party/protobuf/src/google/protobuf/util/delimited_message_util.cc",
+ "third_party/protobuf/src/google/protobuf/util/field_comparator.cc",
+ "third_party/protobuf/src/google/protobuf/util/field_mask_util.cc",
+ "third_party/protobuf/src/google/protobuf/util/internal/datapiece.cc",
+ "third_party/protobuf/src/google/protobuf/util/internal/default_value_objectwriter.cc",
+ "third_party/protobuf/src/google/protobuf/util/internal/error_listener.cc",
+ "third_party/protobuf/src/google/protobuf/util/internal/field_mask_utility.cc",
+ "third_party/protobuf/src/google/protobuf/util/internal/json_escaping.cc",
+ "third_party/protobuf/src/google/protobuf/util/internal/json_objectwriter.cc",
+ "third_party/protobuf/src/google/protobuf/util/internal/json_stream_parser.cc",
+ "third_party/protobuf/src/google/protobuf/util/internal/object_writer.cc",
+ "third_party/protobuf/src/google/protobuf/util/internal/proto_writer.cc",
+ "third_party/protobuf/src/google/protobuf/util/internal/protostream_objectsource.cc",
+ "third_party/protobuf/src/google/protobuf/util/internal/protostream_objectwriter.cc",
+ "third_party/protobuf/src/google/protobuf/util/internal/type_info.cc",
+ "third_party/protobuf/src/google/protobuf/util/internal/utility.cc",
+ "third_party/protobuf/src/google/protobuf/util/json_util.cc",
+ "third_party/protobuf/src/google/protobuf/util/message_differencer.cc",
+ "third_party/protobuf/src/google/protobuf/util/time_util.cc",
+ "third_party/protobuf/src/google/protobuf/util/type_resolver_util.cc",
+ "third_party/protobuf/src/google/protobuf/wire_format.cc",
+ "third_party/protobuf/src/google/protobuf/wire_format_lite.cc",
+ "third_party/protobuf/src/google/protobuf/wrappers.pb.cc",
+ ],
+ static_libs: [
+ "cronet_aml_third_party_zlib_zlib",
+ ],
+ defaults: [
+ "cronet_aml_defaults",
+ ],
+ cflags: [
+ "-DCR_CLANG_REVISION=\"llvmorg-16-init-8697-g60809cd2-1\"",
+ "-DCR_LIBCXX_REVISION=47b31179d10646029c260702650a25d24f555acc",
+ "-DCR_SYSROOT_KEY=20220331T153654Z-0",
+ "-DDCHECK_ALWAYS_ON=1",
+ "-DDYNAMIC_ANNOTATIONS_ENABLED=1",
+ "-DGOOGLE_PROTOBUF_INTERNAL_DONATE_STEAL_INLINE=0",
+ "-DGOOGLE_PROTOBUF_NO_RTTI",
+ "-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER",
+ "-DHAVE_PTHREAD",
+ "-DHAVE_ZLIB",
+ "-DUSE_AURA=1",
+ "-DUSE_OZONE=1",
+ "-DUSE_UDEV",
+ "-D_DEBUG",
+ "-D_FILE_OFFSET_BITS=64",
+ "-D_GNU_SOURCE",
+ "-D_LARGEFILE64_SOURCE",
+ "-D_LARGEFILE_SOURCE",
+ "-D_LIBCPP_AVAILABILITY_CUSTOM_VERBOSE_ABORT_PROVIDED=1",
+ "-D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS",
+ "-D_LIBCPP_ENABLE_ASSERTIONS_DEFAULT=1",
+ "-D_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS",
+ ],
+ local_include_dirs: [
+ "./",
+ "buildtools/third_party/libc++/",
+ "buildtools/third_party/libc++/trunk/include",
+ "buildtools/third_party/libc++abi/trunk/include",
+ "third_party/protobuf/src/",
+ "third_party/zlib/",
+ "build/linux/debian_bullseye_amd64-sysroot/usr/include",
+ ],
+ cpp_std: "c++20",
+}
+
+// GN: //third_party/protobuf:protobuf_lite
+cc_library_static {
+ name: "cronet_aml_third_party_protobuf_protobuf_lite",
+ srcs: [
+ "third_party/protobuf/src/google/protobuf/any_lite.cc",
+ "third_party/protobuf/src/google/protobuf/arena.cc",
+ "third_party/protobuf/src/google/protobuf/arenastring.cc",
+ "third_party/protobuf/src/google/protobuf/arenaz_sampler.cc",
+ "third_party/protobuf/src/google/protobuf/extension_set.cc",
+ "third_party/protobuf/src/google/protobuf/generated_enum_util.cc",
+ "third_party/protobuf/src/google/protobuf/generated_message_tctable_lite.cc",
+ "third_party/protobuf/src/google/protobuf/generated_message_util.cc",
+ "third_party/protobuf/src/google/protobuf/implicit_weak_message.cc",
+ "third_party/protobuf/src/google/protobuf/inlined_string_field.cc",
+ "third_party/protobuf/src/google/protobuf/io/coded_stream.cc",
+ "third_party/protobuf/src/google/protobuf/io/io_win32.cc",
+ "third_party/protobuf/src/google/protobuf/io/strtod.cc",
+ "third_party/protobuf/src/google/protobuf/io/zero_copy_stream.cc",
+ "third_party/protobuf/src/google/protobuf/io/zero_copy_stream_impl.cc",
+ "third_party/protobuf/src/google/protobuf/io/zero_copy_stream_impl_lite.cc",
+ "third_party/protobuf/src/google/protobuf/map.cc",
+ "third_party/protobuf/src/google/protobuf/message_lite.cc",
+ "third_party/protobuf/src/google/protobuf/parse_context.cc",
+ "third_party/protobuf/src/google/protobuf/repeated_field.cc",
+ "third_party/protobuf/src/google/protobuf/repeated_ptr_field.cc",
+ "third_party/protobuf/src/google/protobuf/stubs/bytestream.cc",
+ "third_party/protobuf/src/google/protobuf/stubs/common.cc",
+ "third_party/protobuf/src/google/protobuf/stubs/int128.cc",
+ "third_party/protobuf/src/google/protobuf/stubs/status.cc",
+ "third_party/protobuf/src/google/protobuf/stubs/statusor.cc",
+ "third_party/protobuf/src/google/protobuf/stubs/stringpiece.cc",
+ "third_party/protobuf/src/google/protobuf/stubs/stringprintf.cc",
+ "third_party/protobuf/src/google/protobuf/stubs/structurally_valid.cc",
+ "third_party/protobuf/src/google/protobuf/stubs/strutil.cc",
+ "third_party/protobuf/src/google/protobuf/stubs/time.cc",
+ "third_party/protobuf/src/google/protobuf/wire_format_lite.cc",
+ ],
+ shared_libs: [
+ "liblog",
+ ],
+ defaults: [
+ "cronet_aml_defaults",
+ ],
+ cflags: [
+ "-DANDROID",
+ "-DANDROID_NDK_VERSION_ROLL=r23_1",
+ "-DCR_CLANG_REVISION=\"llvmorg-16-init-8697-g60809cd2-1\"",
+ "-DCR_LIBCXX_REVISION=47b31179d10646029c260702650a25d24f555acc",
+ "-DDCHECK_ALWAYS_ON=1",
+ "-DDYNAMIC_ANNOTATIONS_ENABLED=1",
+ "-DGOOGLE_PROTOBUF_INTERNAL_DONATE_STEAL_INLINE=0",
+ "-DGOOGLE_PROTOBUF_NO_RTTI",
+ "-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER",
+ "-DHAVE_PTHREAD",
+ "-DHAVE_SYS_UIO_H",
+ "-D_DEBUG",
+ "-D_GNU_SOURCE",
+ "-D_LIBCPP_AVAILABILITY_CUSTOM_VERBOSE_ABORT_PROVIDED=1",
+ "-D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS",
+ "-D_LIBCPP_ENABLE_ASSERTIONS_DEFAULT=1",
+ "-D_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS",
+ ],
+ local_include_dirs: [
+ "./",
+ "buildtools/third_party/libc++/",
+ "buildtools/third_party/libc++/trunk/include",
+ "buildtools/third_party/libc++abi/trunk/include",
+ "third_party/protobuf/src/",
+ "third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include",
+ ],
+ cpp_std: "c++20",
+}
+
+// GN: //third_party/zlib:zlib
+cc_library_static {
+ name: "cronet_aml_third_party_zlib_zlib",
+ srcs: [
+ ":cronet_aml_third_party_zlib_zlib_adler32_simd",
+ ":cronet_aml_third_party_zlib_zlib_common_headers",
+ ":cronet_aml_third_party_zlib_zlib_crc32_simd",
+ ":cronet_aml_third_party_zlib_zlib_inflate_chunk_simd",
+ ":cronet_aml_third_party_zlib_zlib_slide_hash_simd",
+ "third_party/zlib/adler32.c",
+ "third_party/zlib/compress.c",
+ "third_party/zlib/cpu_features.c",
+ "third_party/zlib/crc32.c",
+ "third_party/zlib/deflate.c",
+ "third_party/zlib/gzclose.c",
+ "third_party/zlib/gzlib.c",
+ "third_party/zlib/gzread.c",
+ "third_party/zlib/gzwrite.c",
+ "third_party/zlib/infback.c",
+ "third_party/zlib/inffast.c",
+ "third_party/zlib/inftrees.c",
+ "third_party/zlib/trees.c",
+ "third_party/zlib/uncompr.c",
+ "third_party/zlib/zutil.c",
+ ],
+ defaults: [
+ "cronet_aml_defaults",
+ ],
+ cflags: [
+ "-DADLER32_SIMD_SSSE3",
+ "-DCRC32_SIMD_SSE42_PCLMUL",
+ "-DCR_CLANG_REVISION=\"llvmorg-16-init-8697-g60809cd2-1\"",
+ "-DCR_LIBCXX_REVISION=47b31179d10646029c260702650a25d24f555acc",
+ "-DCR_SYSROOT_KEY=20220331T153654Z-0",
+ "-DDCHECK_ALWAYS_ON=1",
+ "-DDEFLATE_SLIDE_HASH_SSE2",
+ "-DDYNAMIC_ANNOTATIONS_ENABLED=1",
+ "-DINFLATE_CHUNK_READ_64LE",
+ "-DINFLATE_CHUNK_SIMD_SSE2",
+ "-DUSE_AURA=1",
+ "-DUSE_OZONE=1",
+ "-DUSE_UDEV",
+ "-DX86_NOT_WINDOWS",
+ "-DZLIB_DEBUG",
+ "-DZLIB_IMPLEMENTATION",
+ "-D_DEBUG",
+ "-D_FILE_OFFSET_BITS=64",
+ "-D_GNU_SOURCE",
+ "-D_LARGEFILE64_SOURCE",
+ "-D_LARGEFILE_SOURCE",
+ "-D_LIBCPP_AVAILABILITY_CUSTOM_VERBOSE_ABORT_PROVIDED=1",
+ "-D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS",
+ "-D_LIBCPP_ENABLE_ASSERTIONS_DEFAULT=1",
+ "-D_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS",
+ "-D__STDC_CONSTANT_MACROS",
+ "-D__STDC_FORMAT_MACROS",
+ ],
+ local_include_dirs: [
+ "./",
+ "buildtools/third_party/libc++/",
+ "buildtools/third_party/libc++/trunk/include",
+ "buildtools/third_party/libc++abi/trunk/include",
+ "third_party/zlib/",
+ "build/linux/debian_bullseye_amd64-sysroot/usr/include",
+ ],
+ cpp_std: "c++20",
+}
+
+// GN: //third_party/zlib:zlib_adler32_simd
+filegroup {
+ name: "cronet_aml_third_party_zlib_zlib_adler32_simd",
+ srcs: [
+ "third_party/zlib/adler32_simd.c",
+ ],
+}
+
+// GN: //third_party/zlib:zlib_common_headers
+filegroup {
+ name: "cronet_aml_third_party_zlib_zlib_common_headers",
+}
+
+// GN: //third_party/zlib:zlib_crc32_simd
+filegroup {
+ name: "cronet_aml_third_party_zlib_zlib_crc32_simd",
+ srcs: [
+ "third_party/zlib/crc32_simd.c",
+ "third_party/zlib/crc_folding.c",
+ ],
+}
+
+// GN: //third_party/zlib:zlib_inflate_chunk_simd
+filegroup {
+ name: "cronet_aml_third_party_zlib_zlib_inflate_chunk_simd",
+ srcs: [
+ "third_party/zlib/contrib/optimizations/inffast_chunk.c",
+ "third_party/zlib/contrib/optimizations/inflate.c",
+ ],
+}
+
+// GN: //third_party/zlib:zlib_slide_hash_simd
+filegroup {
+ name: "cronet_aml_third_party_zlib_zlib_slide_hash_simd",
+}
+
+// GN: //tools/android/errorprone_plugin:errorprone_plugin__build_config_crbug_908819
+genrule {
+ name: "cronet_aml_tools_android_errorprone_plugin_errorprone_plugin__build_config_crbug_908819",
+ cmd: "$(location build/android/gyp/write_build_config.py) --type " +
+ "java_binary " +
+ " " +
+ " " +
+ "--deps-configs " +
+ "[\"$(location third_party/android_deps/com_google_auto_service_auto_service_annotations_java.build_config.json)\", \"$(location third_party/android_deps/com_google_errorprone_error_prone_annotation_java.build_config.json)\", \"$(location third_party/android_deps/com_google_errorprone_error_prone_check_api_java.build_config.json)\", \"$(location third_party/android_deps/com_google_errorprone_error_prone_core_java.build_config.json)\", \"$(location third_party/android_deps/com_google_errorprone_javac_java.build_config.json)\"] " +
+ "--public-deps-configs " +
+ "[] " +
+ "--build-config " +
+ "$(genDir)/tools/android/errorprone_plugin/errorprone_plugin.build_config.json " +
+ "--gn-target " +
+ "//tools/android/errorprone_plugin:errorprone_plugin " +
+ "--host-jar-path " +
+ "$(location lib.java/tools/android/errorprone_plugin/errorprone_plugin.jar) " +
+ "--unprocessed-jar-path " +
+ "$(location tools/android/errorprone_plugin/errorprone_plugin.javac.jar) " +
+ "--interface-jar-path " +
+ "$(location tools/android/errorprone_plugin/errorprone_plugin.turbine.jar) " +
+ "--annotation-processor-configs " +
+ "[\"gen/third_party/android_deps/auto_service_processor.build_config.json\"] " +
+ "--java-sources-file " +
+ "gen/tools/android/errorprone_plugin/errorprone_plugin.sources " +
+ "--bundled-srcjars " +
+ "[] " +
+ "--main-class " +
+ "<ignore>",
+ out: [
+ "tools/android/errorprone_plugin/errorprone_plugin.build_config.json",
+ ],
+ tool_files: [
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/android/gyp/util/resource_utils.py",
+ "build/android/gyp/write_build_config.py",
+ "build/gn_helpers.py",
+ "third_party/jinja2/__init__.py",
+ "third_party/jinja2/_compat.py",
+ "third_party/jinja2/_identifier.py",
+ "third_party/jinja2/bccache.py",
+ "third_party/jinja2/compiler.py",
+ "third_party/jinja2/defaults.py",
+ "third_party/jinja2/environment.py",
+ "third_party/jinja2/exceptions.py",
+ "third_party/jinja2/filters.py",
+ "third_party/jinja2/idtracking.py",
+ "third_party/jinja2/lexer.py",
+ "third_party/jinja2/loaders.py",
+ "third_party/jinja2/nodes.py",
+ "third_party/jinja2/optimizer.py",
+ "third_party/jinja2/parser.py",
+ "third_party/jinja2/runtime.py",
+ "third_party/jinja2/tests.py",
+ "third_party/jinja2/utils.py",
+ "third_party/jinja2/visitor.py",
+ "third_party/markupsafe/__init__.py",
+ "third_party/markupsafe/_compat.py",
+ "third_party/markupsafe/_native.py",
+ ],
+}
+
+// GN: //tools/android/errorprone_plugin:errorprone_plugin__compile_java
+genrule {
+ name: "cronet_aml_tools_android_errorprone_plugin_errorprone_plugin__compile_java",
+ srcs: [
+ "tools/android/errorprone_plugin/src/org/chromium/tools/errorprone/plugin/AndroidNullableCheck.java",
+ "tools/android/errorprone_plugin/src/org/chromium/tools/errorprone/plugin/NoAndroidAsyncTaskCheck.java",
+ "tools/android/errorprone_plugin/src/org/chromium/tools/errorprone/plugin/NoDynamicStringsInTraceEventCheck.java",
+ "tools/android/errorprone_plugin/src/org/chromium/tools/errorprone/plugin/NoRedundantFieldInitCheck.java",
+ "tools/android/errorprone_plugin/src/org/chromium/tools/errorprone/plugin/NoSynchronizedMethodCheck.java",
+ "tools/android/errorprone_plugin/src/org/chromium/tools/errorprone/plugin/NoSynchronizedThisCheck.java",
+ "tools/android/errorprone_plugin/src/org/chromium/tools/errorprone/plugin/TestClassNameCheck.java",
+ "tools/android/errorprone_plugin/src/org/chromium/tools/errorprone/plugin/UseNetworkAnnotations.java",
+ ],
+ cmd: "$(location build/android/gyp/compile_java.py) --depfile " +
+ "gen/tools/android/errorprone_plugin/errorprone_plugin__compile_java.d " +
+ "--generated-dir " +
+ "gen/tools/android/errorprone_plugin/errorprone_plugin/generated_java " +
+ "--jar-path " +
+ "obj/tools/android/errorprone_plugin/errorprone_plugin.javac.jar " +
+ "--java-srcjars " +
+ "[\"gen/tools/android/errorprone_plugin/errorprone_plugin.generated.srcjar\"] " +
+ "--target-name " +
+ "//tools/android/errorprone_plugin:errorprone_plugin__compile_java " +
+ "--header-jar " +
+ "obj/tools/android/errorprone_plugin/errorprone_plugin.turbine.jar " +
+ "--classpath " +
+ "[\"obj/tools/android/errorprone_plugin/errorprone_plugin.turbine.jar\"] " +
+ "--classpath " +
+ "@FileArg(gen/tools/android/errorprone_plugin/errorprone_plugin.build_config.json:deps_info:javac_full_interface_classpath) " +
+ "--chromium-code " +
+ "1 " +
+ "@gen/tools/android/errorprone_plugin/errorprone_plugin.sources",
+ out: [
+ "//out/test/obj/tools/android/errorprone_plugin/errorprone_plugin.javac.jar",
+ "//out/test/obj/tools/android/errorprone_plugin/errorprone_plugin.javac.jar.info",
+ ],
+ tool_files: [
+ "build/android/gyp/compile_java.py",
+ "build/android/gyp/javac_output_processor.py",
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/android/gyp/util/jar_info_utils.py",
+ "build/android/gyp/util/md5_check.py",
+ "build/android/gyp/util/server_utils.py",
+ "build/android/list_java_targets.py",
+ "build/android/pylib/__init__.py",
+ "build/android/pylib/constants/__init__.py",
+ "build/gn_helpers.py",
+ "build/print_python_deps.py",
+ "out/test/gen/tools/android/errorprone_plugin/errorprone_plugin.build_config.json",
+ "out/test/gen/tools/android/errorprone_plugin/errorprone_plugin.generated.srcjar",
+ "out/test/gen/tools/android/errorprone_plugin/errorprone_plugin.sources",
+ "out/test/obj/tools/android/errorprone_plugin/errorprone_plugin.turbine.jar",
+ "third_party/catapult/devil/devil/__init__.py",
+ "third_party/catapult/devil/devil/android/__init__.py",
+ "third_party/catapult/devil/devil/android/constants/__init__.py",
+ "third_party/catapult/devil/devil/android/constants/chrome.py",
+ "third_party/catapult/devil/devil/android/sdk/__init__.py",
+ "third_party/catapult/devil/devil/android/sdk/keyevent.py",
+ "third_party/catapult/devil/devil/android/sdk/version_codes.py",
+ "third_party/catapult/devil/devil/constants/__init__.py",
+ "third_party/catapult/devil/devil/constants/exit_codes.py",
+ "third_party/colorama/src/colorama/__init__.py",
+ "third_party/colorama/src/colorama/ansi.py",
+ "third_party/colorama/src/colorama/ansitowin32.py",
+ "third_party/colorama/src/colorama/initialise.py",
+ "third_party/colorama/src/colorama/win32.py",
+ "third_party/colorama/src/colorama/winterm.py",
+ "tools/android/modularization/convenience/lookup_dep.py",
+ ],
+}
+
+// GN: //tools/android/errorprone_plugin:errorprone_plugin__header
+genrule {
+ name: "cronet_aml_tools_android_errorprone_plugin_errorprone_plugin__header",
+ srcs: [
+ "tools/android/errorprone_plugin/src/org/chromium/tools/errorprone/plugin/AndroidNullableCheck.java",
+ "tools/android/errorprone_plugin/src/org/chromium/tools/errorprone/plugin/NoAndroidAsyncTaskCheck.java",
+ "tools/android/errorprone_plugin/src/org/chromium/tools/errorprone/plugin/NoDynamicStringsInTraceEventCheck.java",
+ "tools/android/errorprone_plugin/src/org/chromium/tools/errorprone/plugin/NoRedundantFieldInitCheck.java",
+ "tools/android/errorprone_plugin/src/org/chromium/tools/errorprone/plugin/NoSynchronizedMethodCheck.java",
+ "tools/android/errorprone_plugin/src/org/chromium/tools/errorprone/plugin/NoSynchronizedThisCheck.java",
+ "tools/android/errorprone_plugin/src/org/chromium/tools/errorprone/plugin/TestClassNameCheck.java",
+ "tools/android/errorprone_plugin/src/org/chromium/tools/errorprone/plugin/UseNetworkAnnotations.java",
+ ],
+ cmd: "$(location build/android/gyp/turbine.py) --depfile " +
+ "gen/tools/android/errorprone_plugin/errorprone_plugin__header.d " +
+ "--generated-dir " +
+ "gen/tools/android/errorprone_plugin/errorprone_plugin/generated_java " +
+ "--jar-path " +
+ "obj/tools/android/errorprone_plugin/errorprone_plugin.turbine.jar " +
+ "--java-srcjars " +
+ "[] " +
+ "--target-name " +
+ "//tools/android/errorprone_plugin:errorprone_plugin__header " +
+ "--classpath " +
+ "@FileArg(gen/tools/android/errorprone_plugin/errorprone_plugin.build_config.json:javac:interface_classpath) " +
+ "--processorpath " +
+ "@FileArg(gen/tools/android/errorprone_plugin/errorprone_plugin.build_config.json:javac:processor_classpath) " +
+ "--processors " +
+ "@FileArg(gen/tools/android/errorprone_plugin/errorprone_plugin.build_config.json:javac:processor_classes) " +
+ "--turbine-jar-path " +
+ "../../third_party/turbine/turbine.jar " +
+ "--generated-jar-path " +
+ "gen/tools/android/errorprone_plugin/errorprone_plugin.generated.srcjar " +
+ "--chromium-code " +
+ "1 " +
+ "@gen/tools/android/errorprone_plugin/errorprone_plugin.sources",
+ out: [
+ "//out/test/obj/tools/android/errorprone_plugin/errorprone_plugin.turbine.jar",
+ "tools/android/errorprone_plugin/errorprone_plugin.generated.srcjar",
+ ],
+ tool_files: [
+ "build/android/gyp/javac_output_processor.py",
+ "build/android/gyp/turbine.py",
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/android/list_java_targets.py",
+ "build/android/pylib/__init__.py",
+ "build/android/pylib/constants/__init__.py",
+ "build/gn_helpers.py",
+ "out/test/gen/tools/android/errorprone_plugin/errorprone_plugin.build_config.json",
+ "out/test/gen/tools/android/errorprone_plugin/errorprone_plugin.sources",
+ "third_party/catapult/devil/devil/__init__.py",
+ "third_party/catapult/devil/devil/android/__init__.py",
+ "third_party/catapult/devil/devil/android/constants/__init__.py",
+ "third_party/catapult/devil/devil/android/constants/chrome.py",
+ "third_party/catapult/devil/devil/android/sdk/__init__.py",
+ "third_party/catapult/devil/devil/android/sdk/keyevent.py",
+ "third_party/catapult/devil/devil/android/sdk/version_codes.py",
+ "third_party/catapult/devil/devil/constants/__init__.py",
+ "third_party/catapult/devil/devil/constants/exit_codes.py",
+ "third_party/colorama/src/colorama/__init__.py",
+ "third_party/colorama/src/colorama/ansi.py",
+ "third_party/colorama/src/colorama/ansitowin32.py",
+ "third_party/colorama/src/colorama/initialise.py",
+ "third_party/colorama/src/colorama/win32.py",
+ "third_party/colorama/src/colorama/winterm.py",
+ "third_party/turbine/turbine.jar",
+ "tools/android/modularization/convenience/lookup_dep.py",
+ ],
+}
+
+// GN: //tools/android/errorprone_plugin:errorprone_plugin__host
+genrule {
+ name: "cronet_aml_tools_android_errorprone_plugin_errorprone_plugin__host",
+ cmd: "$(location build/android/gyp/filter_zip.py) --input " +
+ "obj/tools/android/errorprone_plugin/errorprone_plugin.javac.jar " +
+ "--output " +
+ "lib.java/tools/android/errorprone_plugin/errorprone_plugin.jar " +
+ "--exclude-globs " +
+ "[] " +
+ "--include-globs " +
+ "[]",
+ out: [
+ "//out/test/lib.java/tools/android/errorprone_plugin/errorprone_plugin.jar",
+ ],
+ tool_files: [
+ "build/android/gyp/filter_zip.py",
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/gn_helpers.py",
+ "out/test/obj/tools/android/errorprone_plugin/errorprone_plugin.javac.jar",
+ ],
+}
+
+// GN: //tools/android/errorprone_plugin:errorprone_plugin__java_binary_script
+genrule {
+ name: "cronet_aml_tools_android_errorprone_plugin_errorprone_plugin__java_binary_script",
+ cmd: "$(location build/android/gyp/create_java_binary_script.py) --output " +
+ "bin/bin/helper/errorprone_plugin " +
+ "--main-class " +
+ "<ignore> " +
+ "--classpath " +
+ "@FileArg(gen/tools/android/errorprone_plugin/errorprone_plugin.build_config.json:deps_info:host_classpath) " +
+ "--noverify",
+ out: [
+ "//out/test/bin/bin/helper/errorprone_plugin",
+ ],
+ tool_files: [
+ "build/android/gyp/create_java_binary_script.py",
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/gn_helpers.py",
+ "out/test/gen/tools/android/errorprone_plugin/errorprone_plugin.build_config.json",
+ ],
+}
+
+// GN: //tools/grit:grit_sources
+genrule {
+ name: "cronet_aml_tools_grit_grit_sources",
+ cmd: "python $(location tools/grit/stamp_grit_sources.py) `dirname $(location tools/grit/grit.py)` " +
+ "$(out) " +
+ "$(genDir)/grit_sources.d",
+ out: [
+ "out/test/obj/tools/grit/grit_sources.script.stamp",
+ ],
+ tool_files: [
+ "tools/grit/grit.py",
+ "tools/grit/stamp_grit_sources.py",
+ ],
+}
+
+// GN: //tools/gritsettings:default_resource_ids
+genrule {
+ name: "cronet_aml_tools_gritsettings_default_resource_ids",
+ cmd: "$(location tools/grit/grit.py) update_resource_ids " +
+ "-o " +
+ "gen/tools/gritsettings/default_resource_ids " +
+ "--add-header " +
+ "--depfile " +
+ "gen/tools/gritsettings/default_resource_ids.d " +
+ "--input " +
+ "../../tools/gritsettings/resource_ids.spec",
+ out: [
+ "tools/gritsettings/default_resource_ids",
+ ],
+ tool_files: [
+ "tools/grit/grit.py",
+ "tools/gritsettings/resource_ids.spec",
+ ],
+}
+
+// GN: //url:buildflags
+genrule {
+ name: "cronet_aml_url_buildflags",
+ cmd: "echo '--flags USE_PLATFORM_ICU_ALTERNATIVES=\"true\"' | " +
+ "$(location build/write_buildflag_header.py) --output " +
+ "$(out) " +
+ "--rulename " +
+ "//url:buildflags " +
+ "--gen-dir " +
+ ". " +
+ "--definitions " +
+ "/dev/stdin",
+ out: [
+ "url/buildflags.h",
+ ],
+ tool_files: [
+ "build/write_buildflag_header.py",
+ ],
+}
+
+// GN: //url:url
+cc_library_static {
+ name: "cronet_aml_url_url",
+ srcs: [
+ ":cronet_aml_ipc_param_traits",
+ "url/gurl.cc",
+ "url/origin.cc",
+ "url/scheme_host_port.cc",
+ "url/third_party/mozilla/url_parse.cc",
+ "url/url_canon.cc",
+ "url/url_canon_etc.cc",
+ "url/url_canon_filesystemurl.cc",
+ "url/url_canon_fileurl.cc",
+ "url/url_canon_host.cc",
+ "url/url_canon_internal.cc",
+ "url/url_canon_ip.cc",
+ "url/url_canon_mailtourl.cc",
+ "url/url_canon_path.cc",
+ "url/url_canon_pathurl.cc",
+ "url/url_canon_query.cc",
+ "url/url_canon_relative.cc",
+ "url/url_canon_stdstring.cc",
+ "url/url_canon_stdurl.cc",
+ "url/url_constants.cc",
+ "url/url_idna_icu_alternatives_android.cc",
+ "url/url_parse_file.cc",
+ "url/url_util.cc",
+ ],
+ shared_libs: [
+ "libandroid",
+ "liblog",
+ ],
+ static_libs: [
+ "cronet_aml_base_base",
+ "cronet_aml_base_third_party_dynamic_annotations_dynamic_annotations",
+ ],
+ generated_headers: [
+ "cronet_aml_base_debugging_buildflags",
+ "cronet_aml_base_jni_java__build_config_crbug_908819",
+ "cronet_aml_base_jni_java__compile_java",
+ "cronet_aml_base_jni_java__errorprone",
+ "cronet_aml_base_jni_java__header",
+ "cronet_aml_base_jni_java__host",
+ "cronet_aml_base_jni_java__validate",
+ "cronet_aml_base_logging_buildflags",
+ "cronet_aml_build_android_build_config_gen",
+ "cronet_aml_build_android_build_java__build_config_crbug_908819",
+ "cronet_aml_build_android_build_java__compile_java",
+ "cronet_aml_build_android_build_java__errorprone",
+ "cronet_aml_build_android_build_java__header",
+ "cronet_aml_build_android_build_java__host",
+ "cronet_aml_build_android_build_java__process_device",
+ "cronet_aml_build_android_build_java__validate",
+ "cronet_aml_build_android_bytecode_bytecode_processor__build_config_crbug_908819",
+ "cronet_aml_build_android_bytecode_bytecode_processor__java_binary_script",
+ "cronet_aml_build_android_bytecode_bytecode_processor_java__build_config_crbug_908819",
+ "cronet_aml_build_android_bytecode_bytecode_processor_java__compile_java",
+ "cronet_aml_build_android_bytecode_bytecode_processor_java__errorprone",
+ "cronet_aml_build_android_bytecode_bytecode_processor_java__header",
+ "cronet_aml_build_android_bytecode_bytecode_processor_java__host",
+ "cronet_aml_build_android_native_libraries_gen",
+ "cronet_aml_build_chromeos_buildflags",
+ "cronet_aml_third_party_android_deps_auto_service_processor__build_config_crbug_908819",
+ "cronet_aml_third_party_android_deps_com_github_ben_manes_caffeine_caffeine_java__build_config_crbug_908819",
+ "cronet_aml_third_party_android_deps_com_github_ben_manes_caffeine_caffeine_java__header",
+ "cronet_aml_third_party_android_deps_com_github_ben_manes_caffeine_caffeine_java__host",
+ "cronet_aml_third_party_android_deps_com_github_kevinstern_software_and_algorithms_java__build_config_crbug_908819",
+ "cronet_aml_third_party_android_deps_com_github_kevinstern_software_and_algorithms_java__header",
+ "cronet_aml_third_party_android_deps_com_github_kevinstern_software_and_algorithms_java__host",
+ "cronet_aml_third_party_android_deps_com_google_auto_auto_common_java__build_config_crbug_908819",
+ "cronet_aml_third_party_android_deps_com_google_auto_auto_common_java__header",
+ "cronet_aml_third_party_android_deps_com_google_auto_auto_common_java__host",
+ "cronet_aml_third_party_android_deps_com_google_auto_service_auto_service_annotations_java__build_config_crbug_908819",
+ "cronet_aml_third_party_android_deps_com_google_auto_service_auto_service_annotations_java__header",
+ "cronet_aml_third_party_android_deps_com_google_auto_service_auto_service_annotations_java__host",
+ "cronet_aml_third_party_android_deps_com_google_auto_service_auto_service_java__build_config_crbug_908819",
+ "cronet_aml_third_party_android_deps_com_google_auto_service_auto_service_java__host",
+ "cronet_aml_third_party_android_deps_com_google_auto_value_auto_value_annotations_java__build_config_crbug_908819",
+ "cronet_aml_third_party_android_deps_com_google_auto_value_auto_value_annotations_java__header",
+ "cronet_aml_third_party_android_deps_com_google_auto_value_auto_value_annotations_java__host",
+ "cronet_aml_third_party_android_deps_com_google_code_findbugs_jsr305_java__build_config_crbug_908819",
+ "cronet_aml_third_party_android_deps_com_google_code_findbugs_jsr305_java__header",
+ "cronet_aml_third_party_android_deps_com_google_code_findbugs_jsr305_java__host",
+ "cronet_aml_third_party_android_deps_com_google_errorprone_error_prone_annotation_java__build_config_crbug_908819",
+ "cronet_aml_third_party_android_deps_com_google_errorprone_error_prone_annotation_java__header",
+ "cronet_aml_third_party_android_deps_com_google_errorprone_error_prone_annotation_java__host",
+ "cronet_aml_third_party_android_deps_com_google_errorprone_error_prone_annotations_java__build_config_crbug_908819",
+ "cronet_aml_third_party_android_deps_com_google_errorprone_error_prone_annotations_java__header",
+ "cronet_aml_third_party_android_deps_com_google_errorprone_error_prone_annotations_java__host",
+ "cronet_aml_third_party_android_deps_com_google_errorprone_error_prone_check_api_java__build_config_crbug_908819",
+ "cronet_aml_third_party_android_deps_com_google_errorprone_error_prone_check_api_java__header",
+ "cronet_aml_third_party_android_deps_com_google_errorprone_error_prone_check_api_java__host",
+ "cronet_aml_third_party_android_deps_com_google_errorprone_error_prone_core_java__build_config_crbug_908819",
+ "cronet_aml_third_party_android_deps_com_google_errorprone_error_prone_core_java__header",
+ "cronet_aml_third_party_android_deps_com_google_errorprone_error_prone_core_java__host",
+ "cronet_aml_third_party_android_deps_com_google_errorprone_error_prone_type_annotations_java__build_config_crbug_908819",
+ "cronet_aml_third_party_android_deps_com_google_errorprone_error_prone_type_annotations_java__header",
+ "cronet_aml_third_party_android_deps_com_google_errorprone_error_prone_type_annotations_java__host",
+ "cronet_aml_third_party_android_deps_com_google_errorprone_javac_java__build_config_crbug_908819",
+ "cronet_aml_third_party_android_deps_com_google_errorprone_javac_java__header",
+ "cronet_aml_third_party_android_deps_com_google_errorprone_javac_java__host",
+ "cronet_aml_third_party_android_deps_com_google_guava_failureaccess_java__build_config_crbug_908819",
+ "cronet_aml_third_party_android_deps_com_google_guava_failureaccess_java__header",
+ "cronet_aml_third_party_android_deps_com_google_guava_failureaccess_java__host",
+ "cronet_aml_third_party_android_deps_com_google_guava_guava_java__build_config_crbug_908819",
+ "cronet_aml_third_party_android_deps_com_google_guava_guava_java__header",
+ "cronet_aml_third_party_android_deps_com_google_guava_guava_java__host",
+ "cronet_aml_third_party_android_deps_com_google_guava_listenablefuture_java__build_config_crbug_908819",
+ "cronet_aml_third_party_android_deps_com_google_guava_listenablefuture_java__header",
+ "cronet_aml_third_party_android_deps_com_google_guava_listenablefuture_java__host",
+ "cronet_aml_third_party_android_deps_com_google_j2objc_j2objc_annotations_java__build_config_crbug_908819",
+ "cronet_aml_third_party_android_deps_com_google_j2objc_j2objc_annotations_java__header",
+ "cronet_aml_third_party_android_deps_com_google_j2objc_j2objc_annotations_java__host",
+ "cronet_aml_third_party_android_deps_com_google_protobuf_protobuf_java_java__build_config_crbug_908819",
+ "cronet_aml_third_party_android_deps_com_google_protobuf_protobuf_java_java__header",
+ "cronet_aml_third_party_android_deps_com_google_protobuf_protobuf_java_java__host",
+ "cronet_aml_third_party_android_deps_io_github_java_diff_utils_java_diff_utils_java__build_config_crbug_908819",
+ "cronet_aml_third_party_android_deps_io_github_java_diff_utils_java_diff_utils_java__header",
+ "cronet_aml_third_party_android_deps_io_github_java_diff_utils_java_diff_utils_java__host",
+ "cronet_aml_third_party_android_deps_org_checkerframework_checker_qual_java__build_config_crbug_908819",
+ "cronet_aml_third_party_android_deps_org_checkerframework_checker_qual_java__header",
+ "cronet_aml_third_party_android_deps_org_checkerframework_checker_qual_java__host",
+ "cronet_aml_third_party_android_deps_org_checkerframework_dataflow_errorprone_java__build_config_crbug_908819",
+ "cronet_aml_third_party_android_deps_org_checkerframework_dataflow_errorprone_java__header",
+ "cronet_aml_third_party_android_deps_org_checkerframework_dataflow_errorprone_java__host",
+ "cronet_aml_third_party_android_deps_org_eclipse_jgit_org_eclipse_jgit_java__build_config_crbug_908819",
+ "cronet_aml_third_party_android_deps_org_eclipse_jgit_org_eclipse_jgit_java__header",
+ "cronet_aml_third_party_android_deps_org_eclipse_jgit_org_eclipse_jgit_java__host",
+ "cronet_aml_third_party_android_deps_org_ow2_asm_asm_analysis_java__build_config_crbug_908819",
+ "cronet_aml_third_party_android_deps_org_ow2_asm_asm_analysis_java__header",
+ "cronet_aml_third_party_android_deps_org_ow2_asm_asm_analysis_java__host",
+ "cronet_aml_third_party_android_deps_org_ow2_asm_asm_java__build_config_crbug_908819",
+ "cronet_aml_third_party_android_deps_org_ow2_asm_asm_java__header",
+ "cronet_aml_third_party_android_deps_org_ow2_asm_asm_java__host",
+ "cronet_aml_third_party_android_deps_org_ow2_asm_asm_tree_java__build_config_crbug_908819",
+ "cronet_aml_third_party_android_deps_org_ow2_asm_asm_tree_java__header",
+ "cronet_aml_third_party_android_deps_org_ow2_asm_asm_tree_java__host",
+ "cronet_aml_third_party_android_deps_org_ow2_asm_asm_util_java__build_config_crbug_908819",
+ "cronet_aml_third_party_android_deps_org_ow2_asm_asm_util_java__header",
+ "cronet_aml_third_party_android_deps_org_ow2_asm_asm_util_java__host",
+ "cronet_aml_third_party_android_deps_org_pcollections_pcollections_java__build_config_crbug_908819",
+ "cronet_aml_third_party_android_deps_org_pcollections_pcollections_java__header",
+ "cronet_aml_third_party_android_deps_org_pcollections_pcollections_java__host",
+ "cronet_aml_third_party_android_sdk_android_sdk_java__build_config_crbug_908819",
+ "cronet_aml_third_party_android_sdk_android_sdk_java__header",
+ "cronet_aml_tools_android_errorprone_plugin_errorprone_plugin__build_config_crbug_908819",
+ "cronet_aml_tools_android_errorprone_plugin_errorprone_plugin__compile_java",
+ "cronet_aml_tools_android_errorprone_plugin_errorprone_plugin__header",
+ "cronet_aml_tools_android_errorprone_plugin_errorprone_plugin__host",
+ "cronet_aml_tools_android_errorprone_plugin_errorprone_plugin__java_binary_script",
+ "cronet_aml_url_buildflags",
+ "cronet_aml_url_url_java__build_config_crbug_908819",
+ "cronet_aml_url_url_java__compile_java",
+ "cronet_aml_url_url_java__errorprone",
+ "cronet_aml_url_url_java__header",
+ "cronet_aml_url_url_java__process_device",
+ "cronet_aml_url_url_jni_headers",
+ ],
+ export_generated_headers: [
+ "cronet_aml_base_debugging_buildflags",
+ "cronet_aml_base_jni_java__build_config_crbug_908819",
+ "cronet_aml_base_jni_java__compile_java",
+ "cronet_aml_base_jni_java__errorprone",
+ "cronet_aml_base_jni_java__header",
+ "cronet_aml_base_jni_java__host",
+ "cronet_aml_base_jni_java__validate",
+ "cronet_aml_base_logging_buildflags",
+ "cronet_aml_build_android_build_config_gen",
+ "cronet_aml_build_android_build_java__build_config_crbug_908819",
+ "cronet_aml_build_android_build_java__compile_java",
+ "cronet_aml_build_android_build_java__errorprone",
+ "cronet_aml_build_android_build_java__header",
+ "cronet_aml_build_android_build_java__host",
+ "cronet_aml_build_android_build_java__process_device",
+ "cronet_aml_build_android_build_java__validate",
+ "cronet_aml_build_android_bytecode_bytecode_processor__build_config_crbug_908819",
+ "cronet_aml_build_android_bytecode_bytecode_processor__java_binary_script",
+ "cronet_aml_build_android_bytecode_bytecode_processor_java__build_config_crbug_908819",
+ "cronet_aml_build_android_bytecode_bytecode_processor_java__compile_java",
+ "cronet_aml_build_android_bytecode_bytecode_processor_java__errorprone",
+ "cronet_aml_build_android_bytecode_bytecode_processor_java__header",
+ "cronet_aml_build_android_bytecode_bytecode_processor_java__host",
+ "cronet_aml_build_android_native_libraries_gen",
+ "cronet_aml_build_chromeos_buildflags",
+ "cronet_aml_third_party_android_deps_auto_service_processor__build_config_crbug_908819",
+ "cronet_aml_third_party_android_deps_com_github_ben_manes_caffeine_caffeine_java__build_config_crbug_908819",
+ "cronet_aml_third_party_android_deps_com_github_ben_manes_caffeine_caffeine_java__header",
+ "cronet_aml_third_party_android_deps_com_github_ben_manes_caffeine_caffeine_java__host",
+ "cronet_aml_third_party_android_deps_com_github_kevinstern_software_and_algorithms_java__build_config_crbug_908819",
+ "cronet_aml_third_party_android_deps_com_github_kevinstern_software_and_algorithms_java__header",
+ "cronet_aml_third_party_android_deps_com_github_kevinstern_software_and_algorithms_java__host",
+ "cronet_aml_third_party_android_deps_com_google_auto_auto_common_java__build_config_crbug_908819",
+ "cronet_aml_third_party_android_deps_com_google_auto_auto_common_java__header",
+ "cronet_aml_third_party_android_deps_com_google_auto_auto_common_java__host",
+ "cronet_aml_third_party_android_deps_com_google_auto_service_auto_service_annotations_java__build_config_crbug_908819",
+ "cronet_aml_third_party_android_deps_com_google_auto_service_auto_service_annotations_java__header",
+ "cronet_aml_third_party_android_deps_com_google_auto_service_auto_service_annotations_java__host",
+ "cronet_aml_third_party_android_deps_com_google_auto_service_auto_service_java__build_config_crbug_908819",
+ "cronet_aml_third_party_android_deps_com_google_auto_service_auto_service_java__host",
+ "cronet_aml_third_party_android_deps_com_google_auto_value_auto_value_annotations_java__build_config_crbug_908819",
+ "cronet_aml_third_party_android_deps_com_google_auto_value_auto_value_annotations_java__header",
+ "cronet_aml_third_party_android_deps_com_google_auto_value_auto_value_annotations_java__host",
+ "cronet_aml_third_party_android_deps_com_google_code_findbugs_jsr305_java__build_config_crbug_908819",
+ "cronet_aml_third_party_android_deps_com_google_code_findbugs_jsr305_java__header",
+ "cronet_aml_third_party_android_deps_com_google_code_findbugs_jsr305_java__host",
+ "cronet_aml_third_party_android_deps_com_google_errorprone_error_prone_annotation_java__build_config_crbug_908819",
+ "cronet_aml_third_party_android_deps_com_google_errorprone_error_prone_annotation_java__header",
+ "cronet_aml_third_party_android_deps_com_google_errorprone_error_prone_annotation_java__host",
+ "cronet_aml_third_party_android_deps_com_google_errorprone_error_prone_annotations_java__build_config_crbug_908819",
+ "cronet_aml_third_party_android_deps_com_google_errorprone_error_prone_annotations_java__header",
+ "cronet_aml_third_party_android_deps_com_google_errorprone_error_prone_annotations_java__host",
+ "cronet_aml_third_party_android_deps_com_google_errorprone_error_prone_check_api_java__build_config_crbug_908819",
+ "cronet_aml_third_party_android_deps_com_google_errorprone_error_prone_check_api_java__header",
+ "cronet_aml_third_party_android_deps_com_google_errorprone_error_prone_check_api_java__host",
+ "cronet_aml_third_party_android_deps_com_google_errorprone_error_prone_core_java__build_config_crbug_908819",
+ "cronet_aml_third_party_android_deps_com_google_errorprone_error_prone_core_java__header",
+ "cronet_aml_third_party_android_deps_com_google_errorprone_error_prone_core_java__host",
+ "cronet_aml_third_party_android_deps_com_google_errorprone_error_prone_type_annotations_java__build_config_crbug_908819",
+ "cronet_aml_third_party_android_deps_com_google_errorprone_error_prone_type_annotations_java__header",
+ "cronet_aml_third_party_android_deps_com_google_errorprone_error_prone_type_annotations_java__host",
+ "cronet_aml_third_party_android_deps_com_google_errorprone_javac_java__build_config_crbug_908819",
+ "cronet_aml_third_party_android_deps_com_google_errorprone_javac_java__header",
+ "cronet_aml_third_party_android_deps_com_google_errorprone_javac_java__host",
+ "cronet_aml_third_party_android_deps_com_google_guava_failureaccess_java__build_config_crbug_908819",
+ "cronet_aml_third_party_android_deps_com_google_guava_failureaccess_java__header",
+ "cronet_aml_third_party_android_deps_com_google_guava_failureaccess_java__host",
+ "cronet_aml_third_party_android_deps_com_google_guava_guava_java__build_config_crbug_908819",
+ "cronet_aml_third_party_android_deps_com_google_guava_guava_java__header",
+ "cronet_aml_third_party_android_deps_com_google_guava_guava_java__host",
+ "cronet_aml_third_party_android_deps_com_google_guava_listenablefuture_java__build_config_crbug_908819",
+ "cronet_aml_third_party_android_deps_com_google_guava_listenablefuture_java__header",
+ "cronet_aml_third_party_android_deps_com_google_guava_listenablefuture_java__host",
+ "cronet_aml_third_party_android_deps_com_google_j2objc_j2objc_annotations_java__build_config_crbug_908819",
+ "cronet_aml_third_party_android_deps_com_google_j2objc_j2objc_annotations_java__header",
+ "cronet_aml_third_party_android_deps_com_google_j2objc_j2objc_annotations_java__host",
+ "cronet_aml_third_party_android_deps_com_google_protobuf_protobuf_java_java__build_config_crbug_908819",
+ "cronet_aml_third_party_android_deps_com_google_protobuf_protobuf_java_java__header",
+ "cronet_aml_third_party_android_deps_com_google_protobuf_protobuf_java_java__host",
+ "cronet_aml_third_party_android_deps_io_github_java_diff_utils_java_diff_utils_java__build_config_crbug_908819",
+ "cronet_aml_third_party_android_deps_io_github_java_diff_utils_java_diff_utils_java__header",
+ "cronet_aml_third_party_android_deps_io_github_java_diff_utils_java_diff_utils_java__host",
+ "cronet_aml_third_party_android_deps_org_checkerframework_checker_qual_java__build_config_crbug_908819",
+ "cronet_aml_third_party_android_deps_org_checkerframework_checker_qual_java__header",
+ "cronet_aml_third_party_android_deps_org_checkerframework_checker_qual_java__host",
+ "cronet_aml_third_party_android_deps_org_checkerframework_dataflow_errorprone_java__build_config_crbug_908819",
+ "cronet_aml_third_party_android_deps_org_checkerframework_dataflow_errorprone_java__header",
+ "cronet_aml_third_party_android_deps_org_checkerframework_dataflow_errorprone_java__host",
+ "cronet_aml_third_party_android_deps_org_eclipse_jgit_org_eclipse_jgit_java__build_config_crbug_908819",
+ "cronet_aml_third_party_android_deps_org_eclipse_jgit_org_eclipse_jgit_java__header",
+ "cronet_aml_third_party_android_deps_org_eclipse_jgit_org_eclipse_jgit_java__host",
+ "cronet_aml_third_party_android_deps_org_ow2_asm_asm_analysis_java__build_config_crbug_908819",
+ "cronet_aml_third_party_android_deps_org_ow2_asm_asm_analysis_java__header",
+ "cronet_aml_third_party_android_deps_org_ow2_asm_asm_analysis_java__host",
+ "cronet_aml_third_party_android_deps_org_ow2_asm_asm_java__build_config_crbug_908819",
+ "cronet_aml_third_party_android_deps_org_ow2_asm_asm_java__header",
+ "cronet_aml_third_party_android_deps_org_ow2_asm_asm_java__host",
+ "cronet_aml_third_party_android_deps_org_ow2_asm_asm_tree_java__build_config_crbug_908819",
+ "cronet_aml_third_party_android_deps_org_ow2_asm_asm_tree_java__header",
+ "cronet_aml_third_party_android_deps_org_ow2_asm_asm_tree_java__host",
+ "cronet_aml_third_party_android_deps_org_ow2_asm_asm_util_java__build_config_crbug_908819",
+ "cronet_aml_third_party_android_deps_org_ow2_asm_asm_util_java__header",
+ "cronet_aml_third_party_android_deps_org_ow2_asm_asm_util_java__host",
+ "cronet_aml_third_party_android_deps_org_pcollections_pcollections_java__build_config_crbug_908819",
+ "cronet_aml_third_party_android_deps_org_pcollections_pcollections_java__header",
+ "cronet_aml_third_party_android_deps_org_pcollections_pcollections_java__host",
+ "cronet_aml_third_party_android_sdk_android_sdk_java__build_config_crbug_908819",
+ "cronet_aml_third_party_android_sdk_android_sdk_java__header",
+ "cronet_aml_tools_android_errorprone_plugin_errorprone_plugin__build_config_crbug_908819",
+ "cronet_aml_tools_android_errorprone_plugin_errorprone_plugin__compile_java",
+ "cronet_aml_tools_android_errorprone_plugin_errorprone_plugin__header",
+ "cronet_aml_tools_android_errorprone_plugin_errorprone_plugin__host",
+ "cronet_aml_tools_android_errorprone_plugin_errorprone_plugin__java_binary_script",
+ "cronet_aml_url_buildflags",
+ "cronet_aml_url_url_java__build_config_crbug_908819",
+ "cronet_aml_url_url_java__compile_java",
+ "cronet_aml_url_url_java__errorprone",
+ "cronet_aml_url_url_java__header",
+ "cronet_aml_url_url_java__process_device",
+ "cronet_aml_url_url_jni_headers",
+ ],
+ defaults: [
+ "cronet_aml_defaults",
+ ],
+ cflags: [
+ "-DANDROID",
+ "-DANDROID_NDK_VERSION_ROLL=r23_1",
+ "-DCR_CLANG_REVISION=\"llvmorg-16-init-8697-g60809cd2-1\"",
+ "-DCR_LIBCXX_REVISION=47b31179d10646029c260702650a25d24f555acc",
+ "-DDCHECK_ALWAYS_ON=1",
+ "-DDYNAMIC_ANNOTATIONS_ENABLED=1",
+ "-DHAVE_SYS_UIO_H",
+ "-DIS_URL_IMPL",
+ "-D_DEBUG",
+ "-D_GNU_SOURCE",
+ "-D_LIBCPP_AVAILABILITY_CUSTOM_VERBOSE_ABORT_PROVIDED=1",
+ "-D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS",
+ "-D_LIBCPP_ENABLE_ASSERTIONS_DEFAULT=1",
+ "-D_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS",
+ "-D__STDC_CONSTANT_MACROS",
+ "-D__STDC_FORMAT_MACROS",
+ ],
+ local_include_dirs: [
+ "./",
+ "buildtools/third_party/libc++/",
+ "buildtools/third_party/libc++/trunk/include",
+ "buildtools/third_party/libc++abi/trunk/include",
+ "third_party/abseil-cpp/",
+ "third_party/boringssl/src/include/",
+ "third_party/android_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include",
+ ],
+ header_libs: [
+ "jni_headers",
+ ],
+ cpp_std: "c++20",
+}
+
+// GN: //url:url_java__build_config_crbug_908819
+genrule {
+ name: "cronet_aml_url_url_java__build_config_crbug_908819",
+ cmd: "$(location build/android/gyp/write_build_config.py) --type " +
+ "java_library " +
+ " " +
+ " " +
+ "--deps-configs " +
+ "[\"$(location base/jni_java.build_config.json)\", \"$(location third_party/android_sdk/android_sdk_java.build_config.json)\"] " +
+ "--public-deps-configs " +
+ "[] " +
+ "--build-config " +
+ "$(genDir)/url/url_java.build_config.json " +
+ "--gn-target " +
+ "//url:url_java " +
+ "--device-jar-path " +
+ "$(location url/url_java.processed.jar) " +
+ "--host-jar-path " +
+ "$(location lib.java/url/url_java.jar) " +
+ "--unprocessed-jar-path " +
+ "$(location url/url_java.javac.jar) " +
+ "--interface-jar-path " +
+ "$(location url/url_java.turbine.jar) " +
+ "--dex-path " +
+ "obj/url/url_java.dex.jar " +
+ "--supports-android " +
+ "--requires-android " +
+ "--java-sources-file " +
+ "gen/url/url_java.sources " +
+ "--bundled-srcjars " +
+ "[]",
+ out: [
+ "url/url_java.build_config.json",
+ ],
+ tool_files: [
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/android/gyp/util/resource_utils.py",
+ "build/android/gyp/write_build_config.py",
+ "build/gn_helpers.py",
+ "third_party/jinja2/__init__.py",
+ "third_party/jinja2/_compat.py",
+ "third_party/jinja2/_identifier.py",
+ "third_party/jinja2/bccache.py",
+ "third_party/jinja2/compiler.py",
+ "third_party/jinja2/defaults.py",
+ "third_party/jinja2/environment.py",
+ "third_party/jinja2/exceptions.py",
+ "third_party/jinja2/filters.py",
+ "third_party/jinja2/idtracking.py",
+ "third_party/jinja2/lexer.py",
+ "third_party/jinja2/loaders.py",
+ "third_party/jinja2/nodes.py",
+ "third_party/jinja2/optimizer.py",
+ "third_party/jinja2/parser.py",
+ "third_party/jinja2/runtime.py",
+ "third_party/jinja2/tests.py",
+ "third_party/jinja2/utils.py",
+ "third_party/jinja2/visitor.py",
+ "third_party/markupsafe/__init__.py",
+ "third_party/markupsafe/_compat.py",
+ "third_party/markupsafe/_native.py",
+ ],
+}
+
+// GN: //url:url_java__compile_java
+genrule {
+ name: "cronet_aml_url_url_java__compile_java",
+ srcs: [
+ "url/android/java/src/org/chromium/url/IDNStringUtil.java",
+ ],
+ cmd: "$(location build/android/gyp/compile_java.py) --depfile " +
+ "gen/url/url_java__compile_java.d " +
+ "--generated-dir " +
+ "gen/url/url_java/generated_java " +
+ "--jar-path " +
+ "obj/url/url_java.javac.jar " +
+ "--java-srcjars " +
+ "[\"gen/url/url_java.generated.srcjar\"] " +
+ "--target-name " +
+ "//url:url_java__compile_java " +
+ "--classpath " +
+ "@FileArg(gen/url/url_java.build_config.json:android:sdk_interface_jars) " +
+ "--header-jar " +
+ "obj/url/url_java.turbine.jar " +
+ "--classpath " +
+ "[\"obj/url/url_java.turbine.jar\"] " +
+ "--classpath " +
+ "@FileArg(gen/url/url_java.build_config.json:deps_info:javac_full_interface_classpath) " +
+ "--chromium-code " +
+ "1 " +
+ "--jar-info-exclude-globs " +
+ "[\"*/R.class\", \"*/R\\$*.class\", \"*/Manifest.class\", \"*/Manifest\\$*.class\", \"*/GEN_JNI.class\"] " +
+ "@gen/url/url_java.sources",
+ out: [
+ "//out/test/obj/url/url_java.javac.jar",
+ "//out/test/obj/url/url_java.javac.jar.info",
+ ],
+ tool_files: [
+ "build/android/gyp/compile_java.py",
+ "build/android/gyp/javac_output_processor.py",
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/android/gyp/util/jar_info_utils.py",
+ "build/android/gyp/util/md5_check.py",
+ "build/android/gyp/util/server_utils.py",
+ "build/android/list_java_targets.py",
+ "build/android/pylib/__init__.py",
+ "build/android/pylib/constants/__init__.py",
+ "build/gn_helpers.py",
+ "build/print_python_deps.py",
+ "out/test/gen/url/url_java.build_config.json",
+ "out/test/gen/url/url_java.generated.srcjar",
+ "out/test/gen/url/url_java.sources",
+ "out/test/obj/url/url_java.turbine.jar",
+ "third_party/catapult/devil/devil/__init__.py",
+ "third_party/catapult/devil/devil/android/__init__.py",
+ "third_party/catapult/devil/devil/android/constants/__init__.py",
+ "third_party/catapult/devil/devil/android/constants/chrome.py",
+ "third_party/catapult/devil/devil/android/sdk/__init__.py",
+ "third_party/catapult/devil/devil/android/sdk/keyevent.py",
+ "third_party/catapult/devil/devil/android/sdk/version_codes.py",
+ "third_party/catapult/devil/devil/constants/__init__.py",
+ "third_party/catapult/devil/devil/constants/exit_codes.py",
+ "third_party/colorama/src/colorama/__init__.py",
+ "third_party/colorama/src/colorama/ansi.py",
+ "third_party/colorama/src/colorama/ansitowin32.py",
+ "third_party/colorama/src/colorama/initialise.py",
+ "third_party/colorama/src/colorama/win32.py",
+ "third_party/colorama/src/colorama/winterm.py",
+ "tools/android/modularization/convenience/lookup_dep.py",
+ ],
+}
+
+// GN: //url:url_java__dex
+genrule {
+ name: "cronet_aml_url_url_java__dex",
+ cmd: "$(location build/android/gyp/dex.py) --depfile " +
+ "gen/url/url_java__dex.d " +
+ "--output " +
+ "obj/url/url_java.dex.jar " +
+ "--min-api " +
+ "19 " +
+ "--r8-jar-path " +
+ "../../third_party/r8/lib/r8.jar " +
+ "--custom-d8-jar-path " +
+ "../../third_party/r8/custom_d8.jar " +
+ "--incremental-dir " +
+ "obj/url/url_java__dex " +
+ "--library " +
+ "--class-inputs " +
+ "[\"obj/url/url_java.processed.jar\"] " +
+ "--desugar " +
+ "--desugar-jdk-libs-json " +
+ "../../third_party/r8/desugar_jdk_libs.json " +
+ "--show-desugar-default-interface-warnings " +
+ "--classpath " +
+ "obj/url/url_java.javac.jar " +
+ "--desugar-dependencies " +
+ "gen/url/url_java__dex.desugardeps " +
+ "--bootclasspath " +
+ "@FileArg(gen/url/url_java.build_config.json:android:sdk_jars) " +
+ "--classpath " +
+ "@FileArg(gen/url/url_java.build_config.json:deps_info:javac_full_interface_classpath) " +
+ "--force-enable-assertions",
+ out: [
+ "//out/test/obj/url/url_java.dex.jar",
+ ],
+ tool_files: [
+ "build/android/gyp/dex.py",
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/android/gyp/util/md5_check.py",
+ "build/android/gyp/util/zipalign.py",
+ "build/gn_helpers.py",
+ "build/print_python_deps.py",
+ "out/test/obj/url/url_java.javac.jar",
+ "out/test/obj/url/url_java.processed.jar",
+ "third_party/r8/custom_d8.jar",
+ "third_party/r8/d8/lib/r8.jar",
+ "third_party/r8/desugar_jdk_libs.json",
+ ],
+}
+
+// GN: //url:url_java__errorprone
+genrule {
+ name: "cronet_aml_url_url_java__errorprone",
+ srcs: [
+ "url/android/java/src/org/chromium/url/IDNStringUtil.java",
+ ],
+ cmd: "$(location build/android/gyp/compile_java.py) --depfile " +
+ "gen/url/url_java__errorprone.d " +
+ "--generated-dir " +
+ "gen/url/url_java/generated_java " +
+ "--jar-path " +
+ "obj/url/url_java__errorprone.errorprone.stamp " +
+ "--java-srcjars " +
+ "[\"gen/url/url_java.generated.srcjar\"] " +
+ "--target-name " +
+ "//url:url_java__errorprone " +
+ "--classpath " +
+ "@FileArg(gen/url/url_java.build_config.json:android:sdk_interface_jars) " +
+ "--header-jar " +
+ "obj/url/url_java.turbine.jar " +
+ "--classpath " +
+ "[\"obj/url/url_java.turbine.jar\"] " +
+ "--classpath " +
+ "@FileArg(gen/url/url_java.build_config.json:deps_info:javac_full_interface_classpath) " +
+ "--chromium-code " +
+ "1 " +
+ "--jar-info-exclude-globs " +
+ "[\"*/R.class\", \"*/R\\$*.class\", \"*/Manifest.class\", \"*/Manifest\\$*.class\", \"*/GEN_JNI.class\"] " +
+ "--processorpath " +
+ "@FileArg(gen/tools/android/errorprone_plugin/errorprone_plugin.build_config.json:deps_info:host_classpath) " +
+ "--enable-errorprone " +
+ "@gen/url/url_java.sources",
+ out: [
+ "//out/test/obj/url/url_java__errorprone.errorprone.stamp",
+ ],
+ tool_files: [
+ "build/android/gyp/compile_java.py",
+ "build/android/gyp/javac_output_processor.py",
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/android/gyp/util/jar_info_utils.py",
+ "build/android/gyp/util/md5_check.py",
+ "build/android/gyp/util/server_utils.py",
+ "build/android/list_java_targets.py",
+ "build/android/pylib/__init__.py",
+ "build/android/pylib/constants/__init__.py",
+ "build/gn_helpers.py",
+ "build/print_python_deps.py",
+ "out/test/gen/url/url_java.build_config.json",
+ "out/test/gen/url/url_java.generated.srcjar",
+ "out/test/gen/url/url_java.sources",
+ "out/test/obj/url/url_java.turbine.jar",
+ "third_party/catapult/devil/devil/__init__.py",
+ "third_party/catapult/devil/devil/android/__init__.py",
+ "third_party/catapult/devil/devil/android/constants/__init__.py",
+ "third_party/catapult/devil/devil/android/constants/chrome.py",
+ "third_party/catapult/devil/devil/android/sdk/__init__.py",
+ "third_party/catapult/devil/devil/android/sdk/keyevent.py",
+ "third_party/catapult/devil/devil/android/sdk/version_codes.py",
+ "third_party/catapult/devil/devil/constants/__init__.py",
+ "third_party/catapult/devil/devil/constants/exit_codes.py",
+ "third_party/colorama/src/colorama/__init__.py",
+ "third_party/colorama/src/colorama/ansi.py",
+ "third_party/colorama/src/colorama/ansitowin32.py",
+ "third_party/colorama/src/colorama/initialise.py",
+ "third_party/colorama/src/colorama/win32.py",
+ "third_party/colorama/src/colorama/winterm.py",
+ "tools/android/modularization/convenience/lookup_dep.py",
+ ],
+}
+
+// GN: //url:url_java__header
+genrule {
+ name: "cronet_aml_url_url_java__header",
+ srcs: [
+ "url/android/java/src/org/chromium/url/IDNStringUtil.java",
+ ],
+ cmd: "$(location build/android/gyp/turbine.py) --depfile " +
+ "gen/url/url_java__header.d " +
+ "--generated-dir " +
+ "gen/url/url_java/generated_java " +
+ "--jar-path " +
+ "obj/url/url_java.turbine.jar " +
+ "--java-srcjars " +
+ "[] " +
+ "--target-name " +
+ "//url:url_java__header " +
+ "--classpath " +
+ "@FileArg(gen/url/url_java.build_config.json:android:sdk_interface_jars) " +
+ "--classpath " +
+ "@FileArg(gen/url/url_java.build_config.json:javac:interface_classpath) " +
+ "--processorpath " +
+ "@FileArg(gen/url/url_java.build_config.json:javac:processor_classpath) " +
+ "--processors " +
+ "@FileArg(gen/url/url_java.build_config.json:javac:processor_classes) " +
+ "--turbine-jar-path " +
+ "../../third_party/turbine/turbine.jar " +
+ "--generated-jar-path " +
+ "gen/url/url_java.generated.srcjar " +
+ "--chromium-code " +
+ "1 " +
+ "--jar-info-exclude-globs " +
+ "[\"*/R.class\", \"*/R\\$*.class\", \"*/Manifest.class\", \"*/Manifest\\$*.class\", \"*/GEN_JNI.class\"] " +
+ "@gen/url/url_java.sources",
+ out: [
+ "//out/test/obj/url/url_java.turbine.jar",
+ "url/url_java.generated.srcjar",
+ ],
+ tool_files: [
+ "build/android/gyp/javac_output_processor.py",
+ "build/android/gyp/turbine.py",
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/android/list_java_targets.py",
+ "build/android/pylib/__init__.py",
+ "build/android/pylib/constants/__init__.py",
+ "build/gn_helpers.py",
+ "out/test/gen/url/url_java.build_config.json",
+ "out/test/gen/url/url_java.sources",
+ "third_party/catapult/devil/devil/__init__.py",
+ "third_party/catapult/devil/devil/android/__init__.py",
+ "third_party/catapult/devil/devil/android/constants/__init__.py",
+ "third_party/catapult/devil/devil/android/constants/chrome.py",
+ "third_party/catapult/devil/devil/android/sdk/__init__.py",
+ "third_party/catapult/devil/devil/android/sdk/keyevent.py",
+ "third_party/catapult/devil/devil/android/sdk/version_codes.py",
+ "third_party/catapult/devil/devil/constants/__init__.py",
+ "third_party/catapult/devil/devil/constants/exit_codes.py",
+ "third_party/colorama/src/colorama/__init__.py",
+ "third_party/colorama/src/colorama/ansi.py",
+ "third_party/colorama/src/colorama/ansitowin32.py",
+ "third_party/colorama/src/colorama/initialise.py",
+ "third_party/colorama/src/colorama/win32.py",
+ "third_party/colorama/src/colorama/winterm.py",
+ "third_party/turbine/turbine.jar",
+ "tools/android/modularization/convenience/lookup_dep.py",
+ ],
+}
+
+// GN: //url:url_java__process_device
+genrule {
+ name: "cronet_aml_url_url_java__process_device",
+ cmd: "$(location build/android/gyp/filter_zip.py) --input " +
+ "obj/url/url_java.javac.jar " +
+ "--output " +
+ "obj/url/url_java.processed.jar " +
+ "--exclude-globs " +
+ "[\"*/R.class\", \"*/R\\$*.class\", \"*/Manifest.class\", \"*/Manifest\\$*.class\", \"*/GEN_JNI.class\"] " +
+ "--include-globs " +
+ "[]",
+ out: [
+ "//out/test/obj/url/url_java.processed.jar",
+ ],
+ tool_files: [
+ "build/android/gyp/filter_zip.py",
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/gn_helpers.py",
+ "out/test/obj/url/url_java.javac.jar",
+ ],
+}
+
+// GN: //url:url_java__validate
+genrule {
+ name: "cronet_aml_url_url_java__validate",
+ cmd: "$(location build/android/gyp/bytecode_processor.py) --target-name " +
+ "//url:url_java__validate " +
+ "--script " +
+ "bin/helper/bytecode_processor " +
+ "--gn-target " +
+ "//url:url_java " +
+ "--input-jar " +
+ "obj/url/url_java.javac.jar " +
+ "--stamp " +
+ "obj/url/url_java__validate.bytecode.stamp " +
+ "--direct-classpath-jars " +
+ "@FileArg(gen/url/url_java.build_config.json:javac:classpath) " +
+ "--full-classpath-jars " +
+ "@FileArg(gen/url/url_java.build_config.json:deps_info:javac_full_classpath) " +
+ "--full-classpath-gn-targets " +
+ "@FileArg(gen/url/url_java.build_config.json:deps_info:javac_full_classpath_targets) " +
+ "--sdk-classpath-jars " +
+ "@FileArg(gen/url/url_java.build_config.json:android:sdk_jars)",
+ out: [
+ "//out/test/obj/url/url_java__validate.bytecode.stamp",
+ ],
+ tool_files: [
+ "build/android/gyp/bytecode_processor.py",
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/android/gyp/util/server_utils.py",
+ "build/gn_helpers.py",
+ "out/test/bin/helper/bytecode_processor",
+ "out/test/gen/url/url_java.build_config.json",
+ "out/test/obj/url/url_java.javac.jar",
+ ],
+}
+
+// GN: //url:url_jni_headers
+genrule {
+ name: "cronet_aml_url_url_jni_headers",
+ srcs: [
+ "url/android/java/src/org/chromium/url/IDNStringUtil.java",
+ "url/android/java/src/org/chromium/url/Origin.java",
+ ],
+ cmd: "$(location base/android/jni_generator/jni_generator.py) --ptr_type " +
+ "long " +
+ " " +
+ " " +
+ "--output_dir " +
+ "$(genDir)/url/url_jni_headers " +
+ "--includes " +
+ "base/android/jni_generator/jni_generator_helper.h " +
+ "--use_proxy_hash " +
+ "--output_name " +
+ "IDNStringUtil_jni.h " +
+ "--output_name " +
+ "Origin_jni.h " +
+ "--input_file " +
+ "$(location url/android/java/src/org/chromium/url/IDNStringUtil.java) " +
+ "--input_file " +
+ "$(location url/android/java/src/org/chromium/url/Origin.java)",
+ out: [
+ "url/url_jni_headers/IDNStringUtil_jni.h",
+ "url/url_jni_headers/Origin_jni.h",
+ ],
+ tool_files: [
+ "base/android/jni_generator/jni_generator.py",
+ "build/android/gyp/util/__init__.py",
+ "build/android/gyp/util/build_utils.py",
+ "build/gn_helpers.py",
+ ],
+}
+
diff --git a/tools/gn2bp/desc.json b/tools/gn2bp/desc.json
new file mode 100644
index 0000000..0c51c3c
--- /dev/null
+++ b/tools/gn2bp/desc.json
Binary files differ
diff --git a/tools/gn2bp/gen_android_bp b/tools/gn2bp/gen_android_bp
new file mode 100755
index 0000000..f157b22
--- /dev/null
+++ b/tools/gn2bp/gen_android_bp
@@ -0,0 +1,1242 @@
+#!/usr/bin/env python3
+# 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.
+
+# This tool translates a collection of BUILD.gn files into a mostly equivalent
+# Android.bp file for the Android Soong build system. The input to the tool is a
+# JSON description of the GN build definition generated with the following
+# command:
+#
+# gn desc out --format=json --all-toolchains "//*" > desc.json
+#
+# The tool is then given a list of GN labels for which to generate Android.bp
+# build rules. The dependencies for the GN labels are squashed to the generated
+# Android.bp target, except for actions which get their own genrule. Some
+# libraries are also mapped to their Android equivalents -- see |builtin_deps|.
+
+import argparse
+import collections
+import json
+import logging as log
+import os
+import re
+import sys
+
+import gn_utils
+
+ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
+
+# Defines a custom init_rc argument to be applied to the corresponding output
+# blueprint target.
+target_initrc = {
+ # TODO: this can probably be removed.
+}
+
+target_host_supported = [
+ # TODO: remove if this is not useful for the cronet build.
+]
+
+# Proto target groups which will be made public.
+proto_groups = {
+ # TODO: remove if this is not used for the cronet build.
+}
+
+# All module names are prefixed with this string to avoid collisions.
+module_prefix = 'cronet_aml_'
+
+# Shared libraries which are directly translated to Android system equivalents.
+shared_library_allowlist = [
+ 'android',
+ 'android.hardware.atrace@1.0',
+ 'android.hardware.health@2.0',
+ 'android.hardware.health-V1-ndk',
+ 'android.hardware.power.stats@1.0',
+ "android.hardware.power.stats-V1-cpp",
+ 'base',
+ 'binder',
+ 'binder_ndk',
+ 'cutils',
+ 'hidlbase',
+ 'hidltransport',
+ 'hwbinder',
+ 'incident',
+ 'log',
+ 'services',
+ 'statssocket',
+ "tracingproxy",
+ 'utils',
+]
+
+# Static libraries which are directly translated to Android system equivalents.
+static_library_allowlist = [
+ 'statslog_perfetto',
+]
+
+# Name of the module which settings such as compiler flags for all other
+# modules.
+defaults_module = module_prefix + 'defaults'
+
+# Location of the project in the Android source tree.
+tree_path = 'external/perfetto'
+
+# Path for the protobuf sources in the standalone build.
+buildtools_protobuf_src = '//buildtools/protobuf/src'
+
+# Location of the protobuf src dir in the Android source tree.
+android_protobuf_src = 'external/protobuf/src'
+
+# Compiler flags which are passed through to the blueprint.
+cflag_allowlist = r'^-DPERFETTO.*$'
+
+# Additional arguments to apply to Android.bp rules.
+additional_args = {
+ # TODO: remove if this is not useful for the cronet build.
+ # Consider using additional_args for overriding the genrule cmd property for gn actions.
+}
+
+
+def enable_gtest_and_gmock(module):
+ module.static_libs.add('libgmock')
+ module.static_libs.add('libgtest')
+ if module.name != 'perfetto_gtest_logcat_printer':
+ module.whole_static_libs.add('perfetto_gtest_logcat_printer')
+
+
+def enable_protobuf_full(module):
+ if module.type == 'cc_binary_host':
+ module.static_libs.add('libprotobuf-cpp-full')
+ elif module.host_supported:
+ module.host.static_libs.add('libprotobuf-cpp-full')
+ module.android.shared_libs.add('libprotobuf-cpp-full')
+ else:
+ module.shared_libs.add('libprotobuf-cpp-full')
+
+
+def enable_protobuf_lite(module):
+ module.shared_libs.add('libprotobuf-cpp-lite')
+
+
+def enable_protoc_lib(module):
+ if module.type == 'cc_binary_host':
+ module.static_libs.add('libprotoc')
+ else:
+ module.shared_libs.add('libprotoc')
+
+
+def enable_libunwindstack(module):
+ if module.name != 'heapprofd_standalone_client':
+ module.shared_libs.add('libunwindstack')
+ module.shared_libs.add('libprocinfo')
+ module.shared_libs.add('libbase')
+ else:
+ module.static_libs.add('libunwindstack')
+ module.static_libs.add('libprocinfo')
+ module.static_libs.add('libbase')
+ module.static_libs.add('liblzma')
+ module.static_libs.add('libdexfile_support')
+ module.runtime_libs.add('libdexfile') # libdexfile_support dependency
+
+
+def enable_libunwind(module):
+ # libunwind is disabled on Darwin so we cannot depend on it.
+ pass
+
+
+def enable_sqlite(module):
+ if module.type == 'cc_binary_host':
+ module.static_libs.add('libsqlite')
+ module.static_libs.add('sqlite_ext_percentile')
+ elif module.host_supported:
+ # Copy what the sqlite3 command line tool does.
+ module.android.shared_libs.add('libsqlite')
+ module.android.shared_libs.add('libicu')
+ module.android.shared_libs.add('liblog')
+ module.android.shared_libs.add('libutils')
+ module.android.static_libs.add('sqlite_ext_percentile')
+ module.host.static_libs.add('libsqlite')
+ module.host.static_libs.add('sqlite_ext_percentile')
+ else:
+ module.shared_libs.add('libsqlite')
+ module.shared_libs.add('libicu')
+ module.shared_libs.add('liblog')
+ module.shared_libs.add('libutils')
+ module.static_libs.add('sqlite_ext_percentile')
+
+
+def enable_zlib(module):
+ if module.type == 'cc_binary_host':
+ module.static_libs.add('libz')
+ elif module.host_supported:
+ module.android.shared_libs.add('libz')
+ module.host.static_libs.add('libz')
+ else:
+ module.shared_libs.add('libz')
+
+
+def enable_uapi_headers(module):
+ module.include_dirs.add('bionic/libc/kernel')
+
+
+def enable_bionic_libc_platform_headers_on_android(module):
+ module.header_libs.add('bionic_libc_platform_headers')
+
+
+# Android equivalents for third-party libraries that the upstream project
+# depends on.
+builtin_deps = {
+ '//gn:default_deps':
+ lambda x: None,
+ '//gn:gtest_main':
+ lambda x: None,
+ '//gn:protoc':
+ lambda x: None,
+ '//gn:gtest_and_gmock':
+ enable_gtest_and_gmock,
+ '//gn:libunwind':
+ enable_libunwind,
+ '//gn:protobuf_full':
+ enable_protobuf_full,
+ '//gn:protobuf_lite':
+ enable_protobuf_lite,
+ '//gn:protoc_lib':
+ enable_protoc_lib,
+ '//gn:libunwindstack':
+ enable_libunwindstack,
+ '//gn:sqlite':
+ enable_sqlite,
+ '//gn:zlib':
+ enable_zlib,
+ '//gn:bionic_kernel_uapi_headers':
+ enable_uapi_headers,
+ '//src/profiling/memory:bionic_libc_platform_headers_on_android':
+ enable_bionic_libc_platform_headers_on_android,
+ '//third_party/protobuf:protoc':
+ lambda x: None,
+}
+
+# ----------------------------------------------------------------------------
+# End of configuration.
+# ----------------------------------------------------------------------------
+
+
+class Error(Exception):
+ pass
+
+
+class ThrowingArgumentParser(argparse.ArgumentParser):
+
+ def __init__(self, context):
+ super(ThrowingArgumentParser, self).__init__()
+ self.context = context
+
+ def error(self, message):
+ raise Error('%s: %s' % (self.context, message))
+
+
+def write_blueprint_key_value(output, name, value, sort=True):
+ """Writes a Blueprint key-value pair to the output"""
+
+ if isinstance(value, bool):
+ if value:
+ output.append(' %s: true,' % name)
+ else:
+ output.append(' %s: false,' % name)
+ return
+ if not value:
+ return
+ if isinstance(value, set):
+ value = sorted(value)
+ if isinstance(value, list):
+ output.append(' %s: [' % name)
+ for item in sorted(value) if sort else value:
+ output.append(' "%s",' % item)
+ output.append(' ],')
+ return
+ if isinstance(value, Target):
+ value.to_string(output)
+ return
+ if isinstance(value, dict):
+ kv_output = []
+ for k, v in value.items():
+ write_blueprint_key_value(kv_output, k, v)
+
+ output.append(' %s: {' % name)
+ for line in kv_output:
+ output.append(' %s' % line)
+ output.append(' },')
+ return
+ output.append(' %s: "%s",' % (name, value))
+
+
+class Target(object):
+ """A target-scoped part of a module"""
+
+ def __init__(self, name):
+ self.name = name
+ self.shared_libs = set()
+ self.static_libs = set()
+ self.whole_static_libs = set()
+ self.cflags = set()
+ self.dist = dict()
+ self.strip = dict()
+ self.stl = None
+
+ def to_string(self, output):
+ nested_out = []
+ self._output_field(nested_out, 'shared_libs')
+ self._output_field(nested_out, 'static_libs')
+ self._output_field(nested_out, 'whole_static_libs')
+ self._output_field(nested_out, 'cflags')
+ self._output_field(nested_out, 'stl')
+ self._output_field(nested_out, 'dist')
+ self._output_field(nested_out, 'strip')
+
+ if nested_out:
+ output.append(' %s: {' % self.name)
+ for line in nested_out:
+ output.append(' %s' % line)
+ output.append(' },')
+
+ def _output_field(self, output, name, sort=True):
+ value = getattr(self, name)
+ return write_blueprint_key_value(output, name, value, sort)
+
+
+class Module(object):
+ """A single module (e.g., cc_binary, cc_test) in a blueprint."""
+
+ def __init__(self, mod_type, name, gn_target):
+ self.type = mod_type
+ self.gn_target = gn_target
+ self.name = name
+ self.srcs = set()
+ self.comment = 'GN: ' + gn_utils.label_without_toolchain(gn_target)
+ self.shared_libs = set()
+ self.static_libs = set()
+ self.whole_static_libs = set()
+ self.runtime_libs = set()
+ self.tools = set()
+ self.cmd = None
+ self.host_supported = False
+ self.vendor_available = False
+ self.init_rc = set()
+ self.out = set()
+ self.export_include_dirs = set()
+ self.generated_headers = set()
+ self.export_generated_headers = set()
+ self.defaults = set()
+ self.cflags = set()
+ self.include_dirs = set()
+ self.local_include_dirs = []
+ self.header_libs = set()
+ self.required = set()
+ self.tool_files = set()
+ self.android = Target('android')
+ self.host = Target('host')
+ self.stl = None
+ self.cpp_std = None
+ self.dist = dict()
+ self.strip = dict()
+ self.data = set()
+ self.apex_available = set()
+ self.min_sdk_version = None
+ self.proto = dict()
+ # The genrule_XXX below are properties that must to be propagated back
+ # on the module(s) that depend on the genrule.
+ self.genrule_headers = set()
+ self.genrule_srcs = set()
+ self.genrule_shared_libs = set()
+ self.genrule_header_libs = set()
+ self.version_script = None
+ self.test_suites = set()
+ self.test_config = None
+ self.stubs = {}
+
+ def to_string(self, output):
+ if self.comment:
+ output.append('// %s' % self.comment)
+ output.append('%s {' % self.type)
+ self._output_field(output, 'name')
+ self._output_field(output, 'srcs')
+ self._output_field(output, 'shared_libs')
+ self._output_field(output, 'static_libs')
+ self._output_field(output, 'whole_static_libs')
+ self._output_field(output, 'runtime_libs')
+ self._output_field(output, 'tools')
+ self._output_field(output, 'cmd', sort=False)
+ if self.host_supported:
+ self._output_field(output, 'host_supported')
+ if self.vendor_available:
+ self._output_field(output, 'vendor_available')
+ self._output_field(output, 'init_rc')
+ self._output_field(output, 'out')
+ self._output_field(output, 'export_include_dirs')
+ self._output_field(output, 'generated_headers')
+ self._output_field(output, 'export_generated_headers')
+ self._output_field(output, 'defaults')
+ self._output_field(output, 'cflags')
+ self._output_field(output, 'include_dirs')
+ self._output_field(output, 'local_include_dirs', sort=False)
+ self._output_field(output, 'header_libs')
+ self._output_field(output, 'required')
+ self._output_field(output, 'dist')
+ self._output_field(output, 'strip')
+ self._output_field(output, 'tool_files')
+ self._output_field(output, 'data')
+ self._output_field(output, 'stl')
+ self._output_field(output, 'cpp_std')
+ self._output_field(output, 'apex_available')
+ self._output_field(output, 'min_sdk_version')
+ self._output_field(output, 'version_script')
+ self._output_field(output, 'test_suites')
+ self._output_field(output, 'test_config')
+ self._output_field(output, 'stubs')
+ self._output_field(output, 'proto')
+
+ target_out = []
+ self._output_field(target_out, 'android')
+ self._output_field(target_out, 'host')
+ if target_out:
+ output.append(' target: {')
+ for line in target_out:
+ output.append(' %s' % line)
+ output.append(' },')
+
+ output.append('}')
+ output.append('')
+
+ def add_android_static_lib(self, lib):
+ if self.type == 'cc_binary_host':
+ raise Exception('Adding Android static lib for host tool is unsupported')
+ elif self.host_supported:
+ self.android.static_libs.add(lib)
+ else:
+ self.static_libs.add(lib)
+
+ def add_android_shared_lib(self, lib):
+ if self.type == 'cc_binary_host':
+ raise Exception('Adding Android shared lib for host tool is unsupported')
+ elif self.host_supported:
+ self.android.shared_libs.add(lib)
+ else:
+ self.shared_libs.add(lib)
+
+ def _output_field(self, output, name, sort=True):
+ value = getattr(self, name)
+ return write_blueprint_key_value(output, name, value, sort)
+
+
+class Blueprint(object):
+ """In-memory representation of an Android.bp file."""
+
+ def __init__(self):
+ self.modules = {}
+
+ def add_module(self, module):
+ """Adds a new module to the blueprint, replacing any existing module
+ with the same name.
+
+ Args:
+ module: Module instance.
+ """
+ self.modules[module.name] = module
+
+ def to_string(self, output):
+ for m in sorted(self.modules.values(), key=lambda m: m.name):
+ m.to_string(output)
+
+
+def label_to_module_name(label):
+ """Turn a GN label (e.g., //:perfetto_tests) into a module name."""
+ # If the label is explicibly listed in the default target list, don't prefix
+ # its name and return just the target name. This is so tools like
+ # "traceconv" stay as such in the Android tree.
+ label_without_toolchain = gn_utils.label_without_toolchain(label)
+ module = re.sub(r'^//:?', '', label_without_toolchain)
+ module = re.sub(r'[^a-zA-Z0-9_]', '_', module)
+ if not module.startswith(module_prefix):
+ return module_prefix + module
+ return module
+
+
+def is_supported_source_file(name):
+ """Returns True if |name| can appear in a 'srcs' list."""
+ return os.path.splitext(name)[1] in ['.c', '.cc', '.java', '.proto']
+
+
+def create_proto_modules(blueprint, gn, target):
+ """Generate genrules for a proto GN target.
+
+ GN actions are used to dynamically generate files during the build. The
+ Soong equivalent is a genrule. This function turns a specific kind of
+ genrule which turns .proto files into source and header files into a pair
+ equivalent genrules.
+
+ Args:
+ blueprint: Blueprint instance which is being generated.
+ target: gn_utils.Target object.
+
+ Returns:
+ The source_genrule module.
+ """
+ assert (target.type == 'proto_library')
+
+ tools = {'aprotoc'}
+ cpp_out_dir = '$(genDir)/%s/' % tree_path
+ target_module_name = label_to_module_name(target.name)
+
+ # In GN builds the proto path is always relative to the output directory
+ # (out/tmp.xxx).
+ cmd = ['mkdir -p %s &&' % cpp_out_dir, '$(location aprotoc)']
+ cmd += ['--proto_path=%s' % tree_path]
+
+ if buildtools_protobuf_src in target.proto_paths:
+ cmd += ['--proto_path=%s' % android_protobuf_src]
+
+ # We don't generate any targets for source_set proto modules because
+ # they will be inlined into other modules if required.
+ if target.proto_plugin == 'source_set':
+ return None
+
+ # Descriptor targets only generate a single target.
+ if target.proto_plugin == 'descriptor':
+ out = '{}.bin'.format(target_module_name)
+
+ cmd += ['--descriptor_set_out=$(out)']
+ cmd += ['$(in)']
+
+ descriptor_module = Module('genrule', target_module_name, target.name)
+ descriptor_module.cmd = ' '.join(cmd)
+ descriptor_module.out = [out]
+ descriptor_module.tools = tools
+ blueprint.add_module(descriptor_module)
+
+ # Recursively extract the .proto files of all the dependencies and
+ # add them to srcs.
+ descriptor_module.srcs.update(
+ gn_utils.label_to_path(src) for src in target.sources)
+ for dep in target.transitive_proto_deps:
+ current_target = gn.get_target(dep)
+ descriptor_module.srcs.update(
+ gn_utils.label_to_path(src) for src in current_target.sources)
+
+ return descriptor_module
+
+ # We create two genrules for each proto target: one for the headers and
+ # another for the sources. This is because the module that depends on the
+ # generated files needs to declare two different types of dependencies --
+ # source files in 'srcs' and headers in 'generated_headers' -- and it's not
+ # valid to generate .h files from a source dependency and vice versa.
+ source_module_name = target_module_name + '_gen'
+ source_module = Module('genrule', source_module_name, target.name)
+ blueprint.add_module(source_module)
+ source_module.srcs.update(
+ gn_utils.label_to_path(src) for src in target.sources)
+
+ header_module = Module('genrule', source_module_name + '_headers',
+ target.name)
+ blueprint.add_module(header_module)
+ header_module.srcs = set(source_module.srcs)
+
+ # TODO(primiano): at some point we should remove this. This was introduced
+ # by aosp/1108421 when adding "protos/" to .proto include paths, in order to
+ # avoid doing multi-repo changes and allow old clients in the android tree
+ # to still do the old #include "perfetto/..." rather than
+ # #include "protos/perfetto/...".
+ header_module.export_include_dirs = {'.', 'protos'}
+
+ source_module.genrule_srcs.add(':' + source_module.name)
+ source_module.genrule_headers.add(header_module.name)
+
+ if target.proto_plugin == 'proto':
+ suffixes = ['pb']
+ source_module.genrule_shared_libs.add('libprotobuf-cpp-lite')
+ cmd += ['--cpp_out=lite=true:' + cpp_out_dir]
+ elif target.proto_plugin == 'protozero':
+ suffixes = ['pbzero']
+ plugin = create_modules_from_target(blueprint, gn, protozero_plugin)
+ tools.add(plugin.name)
+ cmd += ['--plugin=protoc-gen-plugin=$(location %s)' % plugin.name]
+ cmd += ['--plugin_out=wrapper_namespace=pbzero:' + cpp_out_dir]
+ elif target.proto_plugin == 'cppgen':
+ suffixes = ['gen']
+ plugin = create_modules_from_target(blueprint, gn, cppgen_plugin)
+ tools.add(plugin.name)
+ cmd += ['--plugin=protoc-gen-plugin=$(location %s)' % plugin.name]
+ cmd += ['--plugin_out=wrapper_namespace=gen:' + cpp_out_dir]
+ elif target.proto_plugin == 'ipc':
+ suffixes = ['ipc']
+ plugin = create_modules_from_target(blueprint, gn, ipc_plugin)
+ tools.add(plugin.name)
+ cmd += ['--plugin=protoc-gen-plugin=$(location %s)' % plugin.name]
+ cmd += ['--plugin_out=wrapper_namespace=gen:' + cpp_out_dir]
+ else:
+ raise Error('Unsupported proto plugin: %s' % target.proto_plugin)
+
+ cmd += ['$(in)']
+ source_module.cmd = ' '.join(cmd)
+ header_module.cmd = source_module.cmd
+ source_module.tools = tools
+ header_module.tools = tools
+
+ for sfx in suffixes:
+ source_module.out.update('%s/%s' %
+ (tree_path, src.replace('.proto', '.%s.cc' % sfx))
+ for src in source_module.srcs)
+ header_module.out.update('%s/%s' %
+ (tree_path, src.replace('.proto', '.%s.h' % sfx))
+ for src in header_module.srcs)
+ return source_module
+
+
+def create_amalgamated_sql_metrics_module(blueprint, target):
+ bp_module_name = label_to_module_name(target.name)
+ module = Module('genrule', bp_module_name, target.name)
+ module.tool_files.add('tools/gen_amalgamated_sql_metrics.py')
+ module.cmd = ' '.join([
+ '$(location tools/gen_amalgamated_sql_metrics.py)',
+ '--cpp_out=$(out)',
+ '$(in)',
+ ])
+ module.genrule_headers.add(module.name)
+ module.out.update(target.outputs)
+ module.srcs.update(gn_utils.label_to_path(src) for src in target.inputs)
+ blueprint.add_module(module)
+ return module
+
+
+def create_cc_proto_descriptor_module(blueprint, target):
+ bp_module_name = label_to_module_name(target.name)
+ module = Module('genrule', bp_module_name, target.name)
+ module.tool_files.add('tools/gen_cc_proto_descriptor.py')
+ module.cmd = ' '.join([
+ '$(location tools/gen_cc_proto_descriptor.py)', '--gen_dir=$(genDir)',
+ '--cpp_out=$(out)', '$(in)'
+ ])
+ module.genrule_headers.add(module.name)
+ module.srcs.update(
+ ':' + label_to_module_name(dep) for dep in target.proto_deps)
+ module.srcs.update(
+ gn_utils.label_to_path(src)
+ for src in target.inputs
+ if "tmp.gn_utils" not in src)
+ module.out.update(target.outputs)
+ blueprint.add_module(module)
+ return module
+
+
+def create_gen_version_module(blueprint, target, bp_module_name):
+ module = Module('genrule', bp_module_name, gn_utils.GEN_VERSION_TARGET)
+ script_path = gn_utils.label_to_path(target.script)
+ module.genrule_headers.add(bp_module_name)
+ module.tool_files.add(script_path)
+ module.out.update(target.outputs)
+ module.srcs.update(gn_utils.label_to_path(src) for src in target.inputs)
+ module.cmd = ' '.join([
+ 'python3 $(location %s)' % script_path, '--no_git',
+ '--changelog=$(location CHANGELOG)', '--cpp_out=$(out)'
+ ])
+ blueprint.add_module(module)
+ return module
+
+
+def create_proto_group_modules(blueprint, gn, module_name, target_names):
+ # TODO(lalitm): today, we're only adding a Java lite module because that's
+ # the only one used in practice. In the future, if we need other target types
+ # (e.g. C++, Java full etc.) add them here.
+ bp_module_name = label_to_module_name(module_name) + '_java_protos'
+ module = Module('java_library', bp_module_name, bp_module_name)
+ module.comment = f'''GN: [{', '.join(target_names)}]'''
+ module.proto = {'type': 'lite', 'canonical_path_from_root': False}
+
+ for name in target_names:
+ target = gn.get_target(name)
+ module.srcs.update(gn_utils.label_to_path(src) for src in target.sources)
+ for dep_label in target.transitive_proto_deps:
+ dep = gn.get_target(dep_label)
+ module.srcs.update(gn_utils.label_to_path(src) for src in dep.sources)
+
+ blueprint.add_module(module)
+
+# HACK: Need to support build_cofig_gen flexibly instead of hardcoding
+# build_config_gen generates srcjar by executing gcc via gcc_preprocess.py but gcc is not
+# available in genrule sandbox. Also gcc path is not configurable.
+# Under the //net:net, gcc_preprocess.py is only used for build_config_gen.
+# So, for now, hardcoding BuildConfig.java and generates srcjar by soong_zip.
+def override_build_config_gen(module):
+ module.tool_files.clear()
+ module.tools.add("soong_zip")
+ cmd = [
+ "echo",
+ "\\\"package org.chromium.build;\\n",
+ "public class BuildConfig {\\n",
+ "public static boolean IS_MULTIDEX_ENABLED ;\\n",
+ "public static boolean ENABLE_ASSERTS = true;\\n",
+ "public static boolean IS_UBSAN ;\\n",
+ "public static boolean IS_CHROME_BRANDED ;\\n",
+ "public static int R_STRING_PRODUCT_VERSION ;\\n",
+ "public static int MIN_SDK_VERSION = 1;\\n",
+ "public static boolean BUNDLES_SUPPORTED ;\\n",
+ "public static boolean IS_INCREMENTAL_INSTALL ;\\n",
+ "public static boolean ISOLATED_SPLITS_ENABLED ;\\n",
+ "public static boolean IS_FOR_TEST ;\\n",
+ "}\\n\\\"",
+ "> $(genDir)/BuildConfig.java &&",
+ "$(location soong_zip) -o $(out) -srcjar -f $(genDir)/BuildConfig.java"
+ ]
+ NEWLINE = ' " +\n "'
+ module.cmd = NEWLINE.join(cmd)
+ return module
+
+def create_action_foreach_modules(blueprint, target):
+ """ The following assumes that rebase_path exists in the args.
+ The args of an action_foreach contains hints about which output files are generated
+ by which source files.
+ This is copied directly from the args
+ "gen/net/base/registry_controlled_domains/{{source_name_part}}-reversed-inc.cc"
+ So each source file will generate an output whose name is the {source_name-reversed-inc.cc}
+ """
+ new_args = []
+ for i, src in enumerate(sorted(target.sources)):
+ # don't add script arg for the first source -- create_action_module
+ # already does this.
+ if i != 0:
+ new_args.append('&& python3 $(location %s)' %
+ gn_utils.label_to_path(target.script))
+ for arg in target.args:
+ if '{{source}}' in arg:
+ new_args.append('$(location %s)' % (gn_utils.label_to_path(src)))
+ elif '{{source_name_part}}' in arg:
+ source_name_part = src.split("/")[-1] # Get the file name only
+ source_name_part = source_name_part.split(".")[0] # Remove the extension (Ex: .cc)
+ file_name = arg.replace('{{source_name_part}}', source_name_part).split("/")[-1]
+ # file_name represent the output file name. But we need the whole path
+ # This can be found from target.outputs.
+ for out in target.outputs:
+ if out.endswith(file_name):
+ new_args.append('$(location %s)' % out)
+ else:
+ new_args.append(arg)
+
+ target.args = new_args
+ return create_action_module(blueprint, target)
+
+def create_action_module(blueprint, target):
+ bp_module_name = label_to_module_name(target.name)
+ module = Module('genrule', bp_module_name, target.name)
+
+ # Convert ['--param=value'] to ['--param', 'value'] for consistency.
+ # TODO: we may want to only do this for python scripts arguments. If argparse
+ # is used, this transformation is safe.
+ target.args = [str for it in target.args for str in it.split('=')]
+
+ if target.script == "//build/write_buildflag_header.py":
+ # write_buildflag_header.py writes result to args.genDir/args.output
+ # So, override args.genDir by '.' so that args.output=$(out) works
+ for i, val in enumerate(target.args):
+ if val == '--gen-dir':
+ target.args[i + 1] = '.'
+ elif val == '--output':
+ target.args[i + 1] = '$(out)'
+
+ elif target.script == '//build/write_build_date_header.py':
+ target.args[0] = '$(out)'
+
+ elif target.script == '//base/android/jni_generator/jni_generator.py':
+ # chromium builds against a prebuilt ndk that contains the jni_headers, so
+ # a dependency is never explicitly created.
+ module.genrule_header_libs.add('jni_headers')
+ needs_javap = False
+ for i, val in enumerate(target.args):
+ if val == '--output_dir':
+ # replace --output_dir gen/jni_headers/... with --output_dir $(genDir)/...
+ target.args[i + 1] = re.sub('^gen/jni_headers', '$(genDir)', target.args[i + 1])
+ elif val == '--input_file':
+ # --input_file supports both .class specifiers or source files as arguments.
+ # Only source files need to be wrapped inside a $(location <label>) tag.
+ if re.match('.*\.class$', target.args[i + 1]):
+ continue
+ # replace --input_file ../../... with --input_file $(location ...)
+ # TODO: put inside function
+ filename = re.sub('^\.\./\.\./', '', target.args[i + 1])
+ target.args[i + 1] = '$(location %s)' % filename
+ elif val == '--includes' and 'jni_generator_helper' in target.args[i + 1]:
+ # delete all leading ../
+ target.args[i + 1] = re.sub('^(\.\./)+', '', target.args[i + 1])
+ elif val == '--prev_output_dir':
+ # this is not needed for aosp builds.
+ target.args[i] = ''
+ target.args[i + 1] = ''
+ elif val == '--jar_file':
+ # delete leading ../../ and add path to javap
+ filename = re.sub('^\.\./\.\./', '', target.args[i + 1])
+ target.args[i + 1] = '$(location %s)' % filename
+ needs_javap = True
+
+ if needs_javap:
+ target.args.append('--javap')
+ target.args.append('$$(find out/.path -name javap)')
+ # fix target.output directory to match #include statements.
+ target.outputs = [re.sub('^jni_headers/', '', out) for out in target.outputs]
+
+ elif target.script == '//build/android/gyp/write_build_config.py':
+ for i, val in enumerate(target.args):
+ if val == '--depfile':
+ # Depfile is not used, so no need to generate it.
+ target.args[i] = ''
+ target.args[i + 1] = ''
+ elif val in ['--deps-configs', '--bundled-srcjars']:
+ args = target.args[i + 1]
+ if args == '[]':
+ continue
+ # strip surrounding [] and split by ", "
+ args = args.strip('[]').split(', ')
+ # strip surrounding ""
+ args = [arg.strip('"') for arg in args]
+ # remove leading gen/
+ args = [re.sub('^gen/', '', arg) for arg in args]
+ # wrap filename in \"$(location filename)\"
+ args = ['\"$(location %s)\"' % arg for arg in args]
+ # join args with ", " and wrap in []
+ target.args[i + 1] = '[%s]' % ', '.join(args)
+
+ elif val == '--public-deps-configs':
+ # TODO: implement.
+ pass
+
+ elif val == '--build-config':
+ # json output of this script
+ target.args[i + 1] = re.sub('^gen', '$(genDir)', target.args[i + 1])
+
+ elif val in ['--unprocessed-jar-path', '--interface-jar-path',
+ '--device-jar-path', '--host-jar-path']:
+ # jar path can be within sources (../../) or output generated by
+ # another genrule (obj/)
+ filename = re.sub('^\.\./\.\./', '', target.args[i + 1])
+ filename = re.sub('^obj/', '', target.args[i + 1])
+ target.args[i + 1] = '$(location %s)' % filename
+
+ elif val == '--proguard-configs':
+ args = target.args[i + 1]
+ if args == '[]':
+ continue
+ # TODO: consider adding helpers to deal with argument lists
+ # strip surrounding [] and split by ", ", then strip surrounding ""
+ args = args.strip('[]').split(', ')
+ args = [arg.strip('"') for arg in args]
+ # remove leading ../../
+ args = [re.sub('^\.\./\.\./', '', arg) for arg in args]
+ # add dependency on proguard config file, so a $(location) wrapper can be used.
+ module.tool_files.update(args)
+ # wrap filename in \"$(location filename)\"
+ args = ['$(location %s)' % arg for arg in args]
+ target.args[i + 1] = '[%s]' % ', '.join(args)
+ elif target.script == "//build/android/gyp/write_native_libraries_java.py":
+ for i, val in enumerate(target.args):
+ if val == '--output':
+ target.args[i + 1] = '$(out)'
+ elif target.script == "//tools/grit/stamp_grit_sources.py":
+ target.outputs = [re.sub('^\/\/', '', out) for out in target.outputs]
+ # Directory that contains grit scripts
+ target.args[0] = '`dirname $(location tools/grit/grit.py)`'
+ # Path to the stamp file
+ target.args[1] = '$(out)'
+ # Script tries to create args[2] file but this is not in the output.
+ # Specifying file under $(genDir) so that parent directory exists.
+ # If this file is used by other module, we may need to add this file to the outputs.
+ target.args[2] = '$(genDir)/' + target.args[2].split('/')[-1]
+ elif target.script == "//tools/protoc_wrapper/protoc_wrapper.py":
+ # Use protoc in the android
+ module.tools.add("aprotoc")
+ target.outputs = [re.sub('^//out/test/', '', out) for out in target.outputs]
+ for i, val in enumerate(target.args):
+ if val == '--protoc':
+ target.args[i + 1] = '$(location aprotoc)'
+ elif val == '--proto-in-dir':
+ # Proto files in the cmd is relative path from --proto-in-dir
+ # Proto files are specified as filenames without directory except net_quic_proto_gen
+ # So getting directory from source file
+ proto_file = gn_utils.label_to_path(sorted(list(target.sources))[0])
+ target.args[i + 1] = '`dirname $(location %s)`' % proto_file
+ # Adjusting path for net_quic_proto_gen
+ if target.name == "//net/third_party/quiche:net_quic_proto_gen":
+ target.args[i + 1] += '/../../../../'
+ elif val == '--cc-out-dir':
+ target.args[i + 1] = re.sub('^gen', '$(genDir)', target.args[i + 1])
+ elif val == 'dllexport_decl':
+ # Needs to be dllexport_decl=value format
+ target.args[i] += '=' + target.args[i+1]
+ target.args[i+1] = ''
+ elif val == '--include':
+ # This file can be got from filegroup this target depends on, but currently we don't add .h
+ # files to the srcs. So far this is the only case .h files need to be added to the srcs.
+ # So, for now, adding specific for this target.
+ module.srcs.add(target.args[i+1])
+ target.args[i + 1] = '$(location %s)' % target.args[i + 1]
+ elif val == "--py-out-dir":
+ target.args[i + 1] = '$(genDir)/' + target.args[i + 1]
+
+ script = gn_utils.label_to_path(target.script)
+ module.tool_files.add(script)
+
+ # Handle passing parameters via response file by piping them into the script
+ # and reading them from /dev/stdin.
+ response_file = '{{response_file_name}}'
+ use_response_file = response_file in target.args
+ if use_response_file:
+ # Replace {{response_file_contents}} with /dev/stdin
+ target.args = ['/dev/stdin' if it == response_file else it for it in target.args]
+
+ # escape " and \$ in target.args.
+ # once all actions are properly implemented, this may not be necessary anymore.
+ # TODO: is this the right place to do this?
+ target.args = [arg.replace('"', r'\"') for arg in target.args]
+ target.args = [arg.replace(r'\$', r'\\$') for arg in target.args]
+
+ # put all args on a new line for better diffs.
+ NEWLINE = ' " +\n "'
+ arg_string = NEWLINE.join(target.args)
+ module.cmd = '$(location %s) %s' % (script, arg_string)
+
+ if use_response_file:
+ # Pipe response file contents into script
+ module.cmd = 'echo \'%s\' |%s%s' % (target.response_file_contents, NEWLINE, module.cmd)
+
+ if all(os.path.splitext(it)[1] == '.h' for it in target.outputs):
+ module.genrule_headers.add(bp_module_name)
+
+ # gn treats inputs and sources for actions equally.
+ # soong only supports source files inside srcs, non-source files are added as
+ # tool_files dependency.
+ for it in target.sources or target.inputs:
+ if is_supported_source_file(it):
+ module.srcs.add(gn_utils.label_to_path(it))
+ else:
+ module.tool_files.add(gn_utils.label_to_path(it))
+
+ # Actions using template "action_with_pydeps" also put script inside inputs.
+ # TODO: it might make sense to filter inputs inside GnParser.
+ if script in module.srcs:
+ module.srcs.remove(script)
+
+ module.out.update(target.outputs)
+
+ if target.name == "//build/android:build_config_gen":
+ module = override_build_config_gen(module)
+ elif target.script == "//tools/grit/stamp_grit_sources.py":
+ # stamp_grit_sources.py is not executable
+ module.cmd = "python " + module.cmd
+
+ blueprint.add_module(module)
+ return module
+
+
+
+def _get_cflags(target):
+ cflags = {flag for flag in target.cflags if re.match(cflag_allowlist, flag)}
+ # Consider proper allowlist or denylist if needed
+ cflags |= set("-D%s" % define.replace("\"", "\\\"") for define in target.defines)
+ return cflags
+
+
+def create_modules_from_target(blueprint, gn, gn_target_name):
+ """Generate module(s) for a given GN target.
+
+ Given a GN target name, generate one or more corresponding modules into a
+ blueprint. The only case when this generates >1 module is proto libraries.
+
+ Args:
+ blueprint: Blueprint instance which is being generated.
+ gn: gn_utils.GnParser object.
+ gn_target_name: GN target for module generation.
+ """
+ bp_module_name = label_to_module_name(gn_target_name)
+ if bp_module_name in blueprint.modules:
+ return blueprint.modules[bp_module_name]
+ target = gn.get_target(gn_target_name)
+ log.info('create modules for %s (%s)', target.name, target.type)
+
+ name_without_toolchain = gn_utils.label_without_toolchain(target.name)
+ if target.type == 'executable':
+ if target.toolchain == gn_utils.HOST_TOOLCHAIN:
+ module_type = 'cc_binary_host'
+ elif target.testonly:
+ module_type = 'cc_test'
+ else:
+ module_type = 'cc_binary'
+ module = Module(module_type, bp_module_name, gn_target_name)
+ elif target.type == 'static_library':
+ module = Module('cc_library_static', bp_module_name, gn_target_name)
+ elif target.type == 'shared_library':
+ module = Module('cc_library_shared', bp_module_name, gn_target_name)
+ elif target.type == 'source_set':
+ module = Module('filegroup', bp_module_name, gn_target_name)
+ elif target.type == 'group':
+ # "group" targets are resolved recursively by gn_utils.get_target().
+ # There's nothing we need to do at this level for them.
+ return None
+ elif target.type == 'proto_library':
+ module = create_proto_modules(blueprint, gn, target)
+ if module is None:
+ return None
+ elif target.type == 'action':
+ if 'gen_amalgamated_sql_metrics' in target.name:
+ module = create_amalgamated_sql_metrics_module(blueprint, target)
+ elif re.match('.*gen_cc_.*_descriptor$', name_without_toolchain):
+ module = create_cc_proto_descriptor_module(blueprint, target)
+ elif target.type == 'action' and \
+ name_without_toolchain == gn_utils.GEN_VERSION_TARGET:
+ module = create_gen_version_module(blueprint, target, bp_module_name)
+ else:
+ module = create_action_module(blueprint, target)
+ elif target.type == 'action_foreach':
+ module = create_action_foreach_modules(blueprint, target)
+ elif target.type == 'copy':
+ # TODO: careful now! copy targets are not supported yet, but this will stop
+ # traversing the dependency tree. For //base:base, this is not a big
+ # problem as libicu contains the only copy target which happens to be a
+ # leaf node.
+ return None
+ else:
+ raise Error('Unknown target %s (%s)' % (target.name, target.type))
+
+ blueprint.add_module(module)
+ module.host_supported = (name_without_toolchain in target_host_supported)
+ module.init_rc = target_initrc.get(target.name, [])
+ module.srcs.update(
+ gn_utils.label_to_path(src)
+ for src in target.sources
+ if is_supported_source_file(src))
+
+ local_include_dirs_set = set()
+ if target.type in gn_utils.LINKER_UNIT_TYPES:
+ module.cflags.update(_get_cflags(target))
+ # TODO: implement proper cflag parsing.
+ for flag in target.cflags:
+ if '-std=' in flag:
+ module.cpp_std = flag[len('-std='):]
+ if '-isystem' in flag:
+ local_include_dirs_set.add(flag[len('-isystem../../'):])
+
+ # Adding local_include_dirs is necessary due to source_sets / filegroups
+ # which do not properly propagate include directories.
+ # Filter any directory inside //out as a) this directory does not exist for
+ # aosp / soong builds and b) the include directory should already be
+ # configured via library dependency.
+ local_include_dirs_set.update([gn_utils.label_to_path(d)
+ for d in target.include_dirs
+ if not re.match('^//out/.*', d)])
+ module.local_include_dirs = sorted(list(local_include_dirs_set))
+
+ # Order matters for some targets. For example, base/time/time_exploded_icu.cc
+ # in //base:base needs to have sysroot include after icu/source/common
+ # include. So adding sysroot include at the end.
+ for flag in target.cflags:
+ if '--sysroot' in flag:
+ module.local_include_dirs.append(flag[len('--sysroot=../../'):] + "/usr/include")
+
+ module_is_compiled = module.type not in ('genrule', 'filegroup')
+ if module_is_compiled:
+ # Don't try to inject library/source dependencies into genrules or
+ # filegroups because they are not compiled in the traditional sense.
+ module.defaults = [defaults_module]
+ for lib in target.libs:
+ # Generally library names should be mangled as 'libXXX', unless they
+ # are HAL libraries (e.g., android.hardware.health@2.0) or AIDL c++ / NDK
+ # libraries (e.g. "android.hardware.power.stats-V1-cpp")
+ android_lib = lib if '@' in lib or "-cpp" in lib or "-ndk" in lib \
+ else 'lib' + lib
+ if lib in shared_library_allowlist:
+ module.add_android_shared_lib(android_lib)
+ if lib in static_library_allowlist:
+ module.add_android_static_lib(android_lib)
+
+ # If the module is a static library, export all the generated headers.
+ if module.type == 'cc_library_static':
+ module.export_generated_headers = module.generated_headers
+
+ # Merge in additional hardcoded arguments.
+ for key, add_val in additional_args.get(module.name, []):
+ curr = getattr(module, key)
+ if add_val and isinstance(add_val, set) and isinstance(curr, set):
+ curr.update(add_val)
+ elif isinstance(add_val, str) and (not curr or isinstance(curr, str)):
+ setattr(module, key, add_val)
+ elif isinstance(add_val, bool) and (not curr or isinstance(curr, bool)):
+ setattr(module, key, add_val)
+ elif isinstance(add_val, dict) and isinstance(curr, dict):
+ curr.update(add_val)
+ elif isinstance(add_val, dict) and isinstance(curr, Target):
+ curr.__dict__.update(add_val)
+ else:
+ raise Error('Unimplemented type %r of additional_args: %r' %
+ (type(add_val), key))
+
+ # dep_name is an unmangled GN target name (e.g. //foo:bar(toolchain)).
+ all_deps = target.deps | target.source_set_deps | target.transitive_proto_deps
+ for dep_name in all_deps:
+ # |builtin_deps| override GN deps with Android-specific ones. See the
+ # config in the top of this file.
+ if gn_utils.label_without_toolchain(dep_name) in builtin_deps:
+ builtin_deps[gn_utils.label_without_toolchain(dep_name)](module)
+ continue
+
+ dep_module = create_modules_from_target(blueprint, gn, dep_name)
+
+ # TODO: Proper dependency check for genrule.
+ # Currently, only propagating genrule dependencies.
+ # Also, currently, all the dependencies are propagated upwards.
+ # in gn, public_deps should be propagated but deps should not.
+ # Not sure this information is available in the desc.json.
+ # Following rule works for adding android_runtime_jni_headers to base:base.
+ # If this doesn't work for other target, hardcoding for specific target
+ # might be better.
+ if module.type == "genrule" and dep_module.type == "genrule":
+ module.genrule_headers.add(dep_module.name)
+ module.genrule_headers.update(dep_module.genrule_headers)
+
+ # For filegroups and genrule, recurse but don't apply the deps.
+ if not module_is_compiled:
+ continue
+
+ if dep_module is None:
+ continue
+ if dep_module.type == 'cc_library_shared':
+ module.shared_libs.add(dep_module.name)
+ elif dep_module.type == 'cc_library_static':
+ module.static_libs.add(dep_module.name)
+ elif dep_module.type == 'filegroup':
+ module.srcs.add(':' + dep_module.name)
+ elif dep_module.type == 'genrule':
+ module.generated_headers.update(dep_module.genrule_headers)
+ module.srcs.update(dep_module.genrule_srcs)
+ module.shared_libs.update(dep_module.genrule_shared_libs)
+ module.header_libs.update(dep_module.genrule_header_libs)
+ elif dep_module.type == 'cc_binary':
+ continue # Ignore executables deps (used by cmdline integration tests).
+ else:
+ raise Error('Unknown dep %s (%s) for target %s' %
+ (dep_module.name, dep_module.type, module.name))
+
+ return module
+
+
+def create_blueprint_for_targets(gn, desc, targets):
+ """Generate a blueprint for a list of GN targets."""
+ blueprint = Blueprint()
+
+ # Default settings used by all modules.
+ defaults = Module('cc_defaults', defaults_module, '//gn:default_deps')
+ defaults.cflags = [
+ '-Wno-error=return-type',
+ '-Wno-non-virtual-dtor',
+ '-Wno-missing-field-initializers',
+ '-Wno-sign-compare',
+ '-Wno-sign-promo',
+ '-Wno-unused-parameter',
+ '-fvisibility=hidden',
+ '-O2',
+ ]
+ defaults.stl = 'none'
+ blueprint.add_module(defaults)
+
+ for target in targets:
+ create_modules_from_target(blueprint, gn, target)
+ return blueprint
+
+
+def main():
+ parser = argparse.ArgumentParser(
+ description='Generate Android.bp from a GN description.')
+ parser.add_argument(
+ '--desc',
+ help='GN description (e.g., gn desc out --format=json --all-toolchains "//*"',
+ required=True
+ )
+ parser.add_argument(
+ '--extras',
+ help='Extra targets to include at the end of the Blueprint file',
+ default=os.path.join(gn_utils.repo_root(), 'Android.bp.extras'),
+ )
+ parser.add_argument(
+ '--output',
+ help='Blueprint file to create',
+ default=os.path.join(gn_utils.repo_root(), 'Android.bp'),
+ )
+ parser.add_argument(
+ '-v',
+ '--verbose',
+ help='Print debug logs.',
+ action='store_true',
+ )
+ parser.add_argument(
+ 'targets',
+ nargs=argparse.REMAINDER,
+ help='Targets to include in the blueprint (e.g., "//:perfetto_tests")'
+ )
+ args = parser.parse_args()
+
+ if args.verbose:
+ log.basicConfig(format='%(levelname)s:%(funcName)s:%(message)s', level=log.DEBUG)
+
+ with open(args.desc) as f:
+ desc = json.load(f)
+
+ gn = gn_utils.GnParser(desc)
+ blueprint = create_blueprint_for_targets(gn, desc, args.targets)
+ project_root = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
+ tool_name = os.path.relpath(os.path.abspath(__file__), project_root)
+
+ # Add any proto groups to the blueprint.
+ for l_name, t_names in proto_groups.items():
+ create_proto_group_modules(blueprint, gn, l_name, t_names)
+
+ output = [
+ """// 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.
+//
+// This file is automatically generated by %s. Do not edit.
+""" % (tool_name)
+ ]
+ blueprint.to_string(output)
+ if os.path.exists(args.extras):
+ with open(args.extras, 'r') as r:
+ for line in r:
+ output.append(line.rstrip("\n\r"))
+
+ out_files = []
+
+ # Generate the Android.bp file.
+ out_files.append(args.output + '.swp')
+ with open(out_files[-1], 'w') as f:
+ f.write('\n'.join(output))
+ # Text files should have a trailing EOL.
+ f.write('\n')
+
+ return 0
+
+
+if __name__ == '__main__':
+ sys.exit(main())
diff --git a/tools/gn2bp/gn_utils.py b/tools/gn2bp/gn_utils.py
new file mode 100644
index 0000000..686003c
--- /dev/null
+++ b/tools/gn2bp/gn_utils.py
@@ -0,0 +1,335 @@
+# 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.
+
+# A collection of utilities for extracting build rule information from GN
+# projects.
+
+from __future__ import print_function
+import collections
+import errno
+import filecmp
+import json
+import os
+import re
+import shutil
+import subprocess
+import sys
+
+BUILDFLAGS_TARGET = '//gn:gen_buildflags'
+GEN_VERSION_TARGET = '//src/base:version_gen_h'
+TARGET_TOOLCHAIN = '//gn/standalone/toolchain:gcc_like_host'
+HOST_TOOLCHAIN = '//gn/standalone/toolchain:gcc_like_host'
+LINKER_UNIT_TYPES = ('executable', 'shared_library', 'static_library')
+
+# TODO(primiano): investigate these, they require further componentization.
+ODR_VIOLATION_IGNORE_TARGETS = {
+ '//test/cts:perfetto_cts_deps',
+ '//:perfetto_integrationtests',
+}
+
+
+def repo_root():
+ """Returns an absolute path to the repository root."""
+ return os.path.join(
+ os.path.realpath(os.path.dirname(__file__)), os.path.pardir)
+
+
+def label_to_path(label):
+ """Turn a GN output label (e.g., //some_dir/file.cc) into a path."""
+ assert label.startswith('//')
+ return label[2:] or "./"
+
+
+def label_without_toolchain(label):
+ """Strips the toolchain from a GN label.
+
+ Return a GN label (e.g //buildtools:protobuf(//gn/standalone/toolchain:
+ gcc_like_host) without the parenthesised toolchain part.
+ """
+ return label.split('(')[0]
+
+
+def label_to_target_name_with_path(label):
+ """
+ Turn a GN label into a target name involving the full path.
+ e.g., //src/perfetto:tests -> src_perfetto_tests
+ """
+ name = re.sub(r'^//:?', '', label)
+ name = re.sub(r'[^a-zA-Z0-9_]', '_', name)
+ return name
+
+
+class GnParser(object):
+ """A parser with some cleverness for GN json desc files
+
+ The main goals of this parser are:
+ 1) Deal with the fact that other build systems don't have an equivalent
+ notion to GN's source_set. Conversely to Bazel's and Soong's filegroups,
+ GN source_sets expect that dependencies, cflags and other source_set
+ properties propagate up to the linker unit (static_library, executable or
+ shared_library). This parser simulates the same behavior: when a
+ source_set is encountered, some of its variables (cflags and such) are
+ copied up to the dependent targets. This is to allow gen_xxx to create
+ one filegroup for each source_set and then squash all the other flags
+ onto the linker unit.
+ 2) Detect and special-case protobuf targets, figuring out the protoc-plugin
+ being used.
+ """
+
+ class Target(object):
+ """Reperesents A GN target.
+
+ Maked properties are propagated up the dependency chain when a
+ source_set dependency is encountered.
+ """
+
+ def __init__(self, name, type):
+ self.name = name # e.g. //src/ipc:ipc
+
+ VALID_TYPES = ('static_library', 'shared_library', 'executable', 'group',
+ 'action', 'source_set', 'proto_library', 'copy', 'action_foreach')
+ assert (type in VALID_TYPES)
+ self.type = type
+ self.testonly = False
+ self.toolchain = None
+
+ # These are valid only for type == proto_library.
+ # This is typically: 'proto', 'protozero', 'ipc'.
+ self.proto_plugin = None
+ self.proto_paths = set()
+ self.proto_exports = set()
+
+ self.sources = set()
+ # TODO(primiano): consider whether the public section should be part of
+ # bubbled-up sources.
+ self.public_headers = set() # 'public'
+
+ # These are valid only for type == 'action'
+ self.inputs = set()
+ self.outputs = set()
+ self.script = None
+ self.args = []
+ self.response_file_contents = None
+
+ # These variables are propagated up when encountering a dependency
+ # on a source_set target.
+ self.cflags = set()
+ self.defines = set()
+ self.deps = set()
+ self.libs = set()
+ self.include_dirs = set()
+ self.ldflags = set()
+ self.source_set_deps = set() # Transitive set of source_set deps.
+ self.proto_deps = set()
+ self.transitive_proto_deps = set()
+
+ # Deps on //gn:xxx have this flag set to True. These dependencies
+ # are special because they pull third_party code from buildtools/.
+ # We don't want to keep recursing into //buildtools in generators,
+ # this flag is used to stop the recursion and create an empty
+ # placeholder target once we hit //gn:protoc or similar.
+ self.is_third_party_dep_ = False
+
+ def __lt__(self, other):
+ if isinstance(other, self.__class__):
+ return self.name < other.name
+ raise TypeError(
+ '\'<\' not supported between instances of \'%s\' and \'%s\'' %
+ (type(self).__name__, type(other).__name__))
+
+ def __repr__(self):
+ return json.dumps({
+ k: (list(sorted(v)) if isinstance(v, set) else v)
+ for (k, v) in self.__dict__.items()
+ },
+ indent=4,
+ sort_keys=True)
+
+ def update(self, other):
+ for key in ('cflags', 'defines', 'deps', 'include_dirs', 'ldflags',
+ 'source_set_deps', 'proto_deps', 'transitive_proto_deps',
+ 'libs', 'proto_paths'):
+ self.__dict__[key].update(other.__dict__.get(key, []))
+
+ def __init__(self, gn_desc):
+ self.gn_desc_ = gn_desc
+ self.all_targets = {}
+ self.linker_units = {} # Executables, shared or static libraries.
+ self.source_sets = {}
+ self.actions = {}
+ self.proto_libs = {}
+
+ def _get_response_file_contents(self, action_desc):
+ # response_file_contents are formatted as:
+ # ['--flags', '--flag=true && false'] and need to be formatted as:
+ # '--flags --flag=\"true && false\"'
+ flags = action_desc.get('response_file_contents', [])
+ formatted_flags = []
+ for flag in flags:
+ if '=' in flag:
+ key, val = flag.split('=')
+ formatted_flags.append('%s=\\"%s\\"' % (key, val))
+ else:
+ formatted_flags.append(flag)
+
+ return ' '.join(formatted_flags)
+
+ def get_target(self, gn_target_name):
+ """Returns a Target object from the fully qualified GN target name.
+
+ It bubbles up variables from source_set dependencies as described in the
+ class-level comments.
+ """
+ target = self.all_targets.get(gn_target_name)
+ if target is not None:
+ return target # Target already processed.
+
+ desc = self.gn_desc_[gn_target_name]
+ target = GnParser.Target(gn_target_name, desc['type'])
+ target.testonly = desc.get('testonly', False)
+ target.toolchain = desc.get('toolchain', None)
+ self.all_targets[gn_target_name] = target
+
+ # TODO: determine if below comment should apply for cronet builds in Android.
+ # We should never have GN targets directly depend on buidtools. They
+ # should hop via //gn:xxx, so we can give generators an opportunity to
+ # override them.
+ # Specifically allow targets to depend on libc++ and libunwind.
+ if not any(match in gn_target_name for match in ['libc++', 'libunwind']):
+ assert (not gn_target_name.startswith('//buildtools'))
+
+
+ # Don't descend further into third_party targets. Genrators are supposed
+ # to either ignore them or route to other externally-provided targets.
+ if gn_target_name.startswith('//gn'):
+ target.is_third_party_dep_ = True
+ return target
+
+ proto_target_type, proto_desc = self.get_proto_target_type(target)
+ if proto_target_type is not None:
+ self.proto_libs[target.name] = target
+ target.type = 'proto_library'
+ target.proto_plugin = proto_target_type
+ target.proto_paths.update(self.get_proto_paths(proto_desc))
+ target.proto_exports.update(self.get_proto_exports(proto_desc))
+ target.sources.update(proto_desc.get('sources', []))
+ assert (all(x.endswith('.proto') for x in target.sources))
+ elif target.type == 'source_set':
+ self.source_sets[gn_target_name] = target
+ target.sources.update(desc.get('sources', []))
+ elif target.type in LINKER_UNIT_TYPES:
+ self.linker_units[gn_target_name] = target
+ target.sources.update(desc.get('sources', []))
+ elif target.type in ['action', 'action_foreach']:
+ self.actions[gn_target_name] = target
+ target.inputs.update(desc.get('inputs', []))
+ target.sources.update(desc.get('sources', []))
+ outs = [re.sub('^//out/.+?/gen/', '', x) for x in desc['outputs']]
+ target.outputs.update(outs)
+ target.script = desc['script']
+ target.args = desc['args']
+ target.response_file_contents = self._get_response_file_contents(desc)
+ elif target.type == 'copy':
+ # TODO: copy rules are not currently implemented.
+ self.actions[gn_target_name] = target
+
+ # Default for 'public' is //* - all headers in 'sources' are public.
+ # TODO(primiano): if a 'public' section is specified (even if empty), then
+ # the rest of 'sources' is considered inaccessible by gn. Consider
+ # emulating that, so that generated build files don't end up with overly
+ # accessible headers.
+ public_headers = [x for x in desc.get('public', []) if x != '*']
+ target.public_headers.update(public_headers)
+
+ target.cflags.update(desc.get('cflags', []) + desc.get('cflags_cc', []))
+ target.libs.update(desc.get('libs', []))
+ target.ldflags.update(desc.get('ldflags', []))
+ target.defines.update(desc.get('defines', []))
+ target.include_dirs.update(desc.get('include_dirs', []))
+
+ # Recurse in dependencies.
+ for dep_name in desc.get('deps', []):
+ dep = self.get_target(dep_name)
+ if dep.is_third_party_dep_:
+ target.deps.add(dep_name)
+ elif dep.type == 'proto_library':
+ target.proto_deps.add(dep_name)
+ target.transitive_proto_deps.add(dep_name)
+ target.proto_paths.update(dep.proto_paths)
+ target.transitive_proto_deps.update(dep.transitive_proto_deps)
+ elif dep.type == 'source_set':
+ target.source_set_deps.add(dep_name)
+ target.update(dep) # Bubble up source set's cflags/ldflags etc.
+ elif dep.type == 'group':
+ target.update(dep) # Bubble up groups's cflags/ldflags etc.
+ elif dep.type in ['action', 'action_foreach', 'copy']:
+ if proto_target_type is None:
+ target.deps.add(dep_name)
+ elif dep.type in LINKER_UNIT_TYPES:
+ target.deps.add(dep_name)
+
+ return target
+
+ def get_proto_exports(self, proto_desc):
+ # exports in metadata will be available for source_set targets.
+ metadata = proto_desc.get('metadata', {})
+ return metadata.get('exports', [])
+
+ def get_proto_paths(self, proto_desc):
+ # import_dirs in metadata will be available for source_set targets.
+ metadata = proto_desc.get('metadata', {})
+ return metadata.get('import_dirs', [])
+
+ def get_proto_target_type(self, target):
+ """ Checks if the target is a proto library and return the plugin.
+
+ Returns:
+ (None, None): if the target is not a proto library.
+ (plugin, proto_desc) where |plugin| is 'proto' in the default (lite)
+ case or 'protozero' or 'ipc' or 'descriptor'; |proto_desc| is the GN
+ json desc of the target with the .proto sources (_gen target for
+ non-descriptor types or the target itself for descriptor type).
+ """
+ parts = target.name.split('(', 1)
+ name = parts[0]
+ toolchain = '(' + parts[1] if len(parts) > 1 else ''
+
+ # Descriptor targets don't have a _gen target; instead we look for the
+ # characteristic flag in the args of the target itself.
+ desc = self.gn_desc_.get(target.name)
+ if '--descriptor_set_out' in desc.get('args', []):
+ return 'descriptor', desc
+
+ # Source set proto targets have a non-empty proto_library_sources in the
+ # metadata of the description.
+ metadata = desc.get('metadata', {})
+ if 'proto_library_sources' in metadata:
+ return 'source_set', desc
+
+ # In all other cases, we want to look at the _gen target as that has the
+ # important information.
+ gen_desc = self.gn_desc_.get('%s_gen%s' % (name, toolchain))
+ if gen_desc is None or gen_desc['type'] != 'action':
+ return None, None
+ args = gen_desc.get('args', [])
+ if '/protoc' not in args[0]:
+ return None, None
+ plugin = 'proto'
+ for arg in (arg for arg in args if arg.startswith('--plugin=')):
+ # |arg| at this point looks like:
+ # --plugin=protoc-gen-plugin=gcc_like_host/protozero_plugin
+ # or
+ # --plugin=protoc-gen-plugin=protozero_plugin
+ plugin = arg.split('=')[-1].split('/')[-1].replace('_plugin', '')
+ return plugin, gen_desc
diff --git a/tools/gn2bp/update_results.sh b/tools/gn2bp/update_results.sh
new file mode 100755
index 0000000..ad0277c
--- /dev/null
+++ b/tools/gn2bp/update_results.sh
@@ -0,0 +1,19 @@
+#!/bin/bash
+
+# This script is expected to run after gen_android_bp is modified.
+#
+# ./update_result.sh
+#
+# TARGETS contains targets which are supported by gen_android_bp and
+# this script generates Android.bp.swp from TARGETS.
+# This makes it easy to realize unintended impact/degression on
+# previously supported targets.
+
+set -eux
+
+TARGETS=(
+ "//net:net"
+)
+
+BASEDIR=$(dirname "$0")
+$BASEDIR/gen_android_bp --desc $BASEDIR/desc.json --out $BASEDIR/Android.bp ${TARGETS[@]}
diff --git a/tools/testdata/java/android/net/IpSecTransform.java b/tools/testdata/java/android/net/IpSecTransform.java
new file mode 100644
index 0000000..0140bc5
--- /dev/null
+++ b/tools/testdata/java/android/net/IpSecTransform.java
@@ -0,0 +1,23 @@
+/*
+ * 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 android.net;
+
+/**
+ * Test class with a name matching a public API in a secondary (framework-connectivity-t) stubs jar.
+ */
+public class IpSecTransform {
+}
diff --git a/tools/testdata/java/test/unsupportedappusage/OtherUnsupportedUsageClass.java b/tools/testdata/java/test/unsupportedappusage/OtherUnsupportedUsageClass.java
new file mode 100644
index 0000000..9d3ae2e0
--- /dev/null
+++ b/tools/testdata/java/test/unsupportedappusage/OtherUnsupportedUsageClass.java
@@ -0,0 +1,25 @@
+/*
+ * 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 test.unsupportedappusage;
+
+import android.compat.annotation.UnsupportedAppUsage;
+
+public class OtherUnsupportedUsageClass {
+ // The annotation is just for completeness, what matters is the unsupportedappusage.txt file
+ @UnsupportedAppUsage
+ public void testSecondMethod() {}
+}
diff --git a/tools/testdata/java/test/unsupportedappusage/TestUnsupportedAppUsageClass.java b/tools/testdata/java/test/unsupportedappusage/TestUnsupportedAppUsageClass.java
index 9d32296..460c91b 100644
--- a/tools/testdata/java/test/unsupportedappusage/TestUnsupportedAppUsageClass.java
+++ b/tools/testdata/java/test/unsupportedappusage/TestUnsupportedAppUsageClass.java
@@ -16,6 +16,11 @@
package test.unsupportedappusage;
+
+import android.compat.annotation.UnsupportedAppUsage;
+
public class TestUnsupportedAppUsageClass {
+ // The annotation is just for completeness, what matters is the unsupportedappusage.txt file
+ @UnsupportedAppUsage
public void testMethod() {}
}
diff --git a/tools/testdata/test-other-unsupportedappusage.txt b/tools/testdata/test-other-unsupportedappusage.txt
new file mode 100644
index 0000000..b7d74a4
--- /dev/null
+++ b/tools/testdata/test-other-unsupportedappusage.txt
@@ -0,0 +1 @@
+Ltest/unsupportedappusage/OtherUnsupportedUsageClass;->testSecondMethod()V
\ No newline at end of file