Merge changes Icd842479,I2206a846
* changes:
Add MdnsInterfaceSocket and MdnsSocketProvider
Put the Network info in MdnsServiceInfo
diff --git a/Tethering/jni/com_android_networkstack_tethering_BpfCoordinator.cpp b/Tethering/jni/com_android_networkstack_tethering_BpfCoordinator.cpp
index 27357f8..c8c86bc 100644
--- a/Tethering/jni/com_android_networkstack_tethering_BpfCoordinator.cpp
+++ b/Tethering/jni/com_android_networkstack_tethering_BpfCoordinator.cpp
@@ -17,7 +17,7 @@
#include <jni.h>
#include <nativehelper/JNIHelp.h>
-#include "bpf_tethering.h"
+#include "offload.h"
namespace android {
diff --git a/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java b/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java
index 6a5089d..51c7c9c 100644
--- a/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java
+++ b/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java
@@ -126,7 +126,7 @@
private static final String DUMPSYS_RAWMAP_ARG_STATS = "--stats";
private static final String DUMPSYS_RAWMAP_ARG_UPSTREAM4 = "--upstream4";
- /** The names of all the BPF counters defined in bpf_tethering.h. */
+ /** The names of all the BPF counters defined in offload.h. */
public static final String[] sBpfCounterNames = getBpfCounterNames();
private static String makeMapPath(String which) {
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 225fed7..53984a8 100644
--- a/Tethering/tests/unit/src/com/android/networkstack/tethering/BpfCoordinatorTest.java
+++ b/Tethering/tests/unit/src/com/android/networkstack/tethering/BpfCoordinatorTest.java
@@ -2180,7 +2180,7 @@
new TetherDevValue(UPSTREAM_IFINDEX));
// dumpCounters
- // The error code is defined in packages/modules/Connectivity/bpf_progs/bpf_tethering.h.
+ // The error code is defined in packages/modules/Connectivity/bpf_progs/offload.h.
mBpfErrorMap.insertEntry(
new S32(0 /* INVALID_IPV4_VERSION */),
new S32(1000 /* count */));
diff --git a/bpf_progs/bpf_shared.h b/bpf_progs/bpf_shared.h
index 7b1106a..cc88680 100644
--- a/bpf_progs/bpf_shared.h
+++ b/bpf_progs/bpf_shared.h
@@ -196,32 +196,4 @@
// Entry in the configuration map that stores which stats map is currently in use.
#define CURRENT_STATS_MAP_CONFIGURATION_KEY 1
-typedef struct {
- uint32_t iif; // The input interface index
- struct in6_addr pfx96; // The source /96 nat64 prefix, bottom 32 bits must be 0
- struct in6_addr local6; // The full 128-bits of the destination IPv6 address
-} ClatIngress6Key;
-STRUCT_SIZE(ClatIngress6Key, 4 + 2 * 16); // 36
-
-typedef struct {
- uint32_t oif; // The output interface to redirect to (0 means don't redirect)
- struct in_addr local4; // The destination IPv4 address
-} ClatIngress6Value;
-STRUCT_SIZE(ClatIngress6Value, 4 + 4); // 8
-
-typedef struct {
- uint32_t iif; // The input interface index
- struct in_addr local4; // The source IPv4 address
-} ClatEgress4Key;
-STRUCT_SIZE(ClatEgress4Key, 4 + 4); // 8
-
-typedef struct {
- uint32_t oif; // The output interface to redirect to
- struct in6_addr local6; // The full 128-bits of the source IPv6 address
- struct in6_addr pfx96; // The destination /96 nat64 prefix, bottom 32 bits must be 0
- bool oifIsEthernet; // Whether the output interface requires ethernet header
- uint8_t pad[3];
-} ClatEgress4Value;
-STRUCT_SIZE(ClatEgress4Value, 4 + 2 * 16 + 1 + 3); // 40
-
#undef STRUCT_SIZE
diff --git a/bpf_progs/clatd.c b/bpf_progs/clatd.c
index fc10d09..14cddf6 100644
--- a/bpf_progs/clatd.c
+++ b/bpf_progs/clatd.c
@@ -35,7 +35,7 @@
#include "bpf_helpers.h"
#include "bpf_net_helpers.h"
-#include "bpf_shared.h"
+#include "clatd.h"
#include "clat_mark.h"
// IP flags. (from kernel's include/net/ip.h)
diff --git a/bpf_progs/clatd.h b/bpf_progs/clatd.h
new file mode 100644
index 0000000..b5f1cdc
--- /dev/null
+++ b/bpf_progs/clatd.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <linux/in.h>
+#include <linux/in6.h>
+
+#include <stdbool.h>
+#include <stdint.h>
+
+// This header file is shared by eBPF kernel programs (C) and netd (C++) and
+// some of the maps are also accessed directly from Java mainline module code.
+//
+// Hence: explicitly pad all relevant structures and assert that their size
+// is the sum of the sizes of their fields.
+#define STRUCT_SIZE(name, size) _Static_assert(sizeof(name) == (size), "Incorrect struct size.")
+
+typedef struct {
+ uint32_t iif; // The input interface index
+ struct in6_addr pfx96; // The source /96 nat64 prefix, bottom 32 bits must be 0
+ struct in6_addr local6; // The full 128-bits of the destination IPv6 address
+} ClatIngress6Key;
+STRUCT_SIZE(ClatIngress6Key, 4 + 2 * 16); // 36
+
+typedef struct {
+ uint32_t oif; // The output interface to redirect to (0 means don't redirect)
+ struct in_addr local4; // The destination IPv4 address
+} ClatIngress6Value;
+STRUCT_SIZE(ClatIngress6Value, 4 + 4); // 8
+
+typedef struct {
+ uint32_t iif; // The input interface index
+ struct in_addr local4; // The source IPv4 address
+} ClatEgress4Key;
+STRUCT_SIZE(ClatEgress4Key, 4 + 4); // 8
+
+typedef struct {
+ uint32_t oif; // The output interface to redirect to
+ struct in6_addr local6; // The full 128-bits of the source IPv6 address
+ struct in6_addr pfx96; // The destination /96 nat64 prefix, bottom 32 bits must be 0
+ bool oifIsEthernet; // Whether the output interface requires ethernet header
+ uint8_t pad[3];
+} ClatEgress4Value;
+STRUCT_SIZE(ClatEgress4Value, 4 + 2 * 16 + 1 + 3); // 40
+
+#undef STRUCT_SIZE
diff --git a/bpf_progs/offload.c b/bpf_progs/offload.c
index e211d68..a8612df 100644
--- a/bpf_progs/offload.c
+++ b/bpf_progs/offload.c
@@ -48,7 +48,7 @@
#include "bpf_helpers.h"
#include "bpf_net_helpers.h"
-#include "bpf_tethering.h"
+#include "offload.h"
// From kernel:include/net/ip.h
#define IP_DF 0x4000 // Flag: "Don't Fragment"
diff --git a/bpf_progs/bpf_tethering.h b/bpf_progs/offload.h
similarity index 100%
rename from bpf_progs/bpf_tethering.h
rename to bpf_progs/offload.h
diff --git a/bpf_progs/test.c b/bpf_progs/test.c
index c11c358..d1f780f 100644
--- a/bpf_progs/test.c
+++ b/bpf_progs/test.c
@@ -46,7 +46,7 @@
#include "bpf_helpers.h"
#include "bpf_net_helpers.h"
-#include "bpf_tethering.h"
+#include "offload.h"
// Used only by TetheringPrivilegedTests, not by production code.
DEFINE_BPF_MAP_GRW(tether_downstream6_map, HASH, TetherDownstream6Key, Tether6Value, 16,
diff --git a/service/src/com/android/server/ConnectivityService.java b/service/src/com/android/server/ConnectivityService.java
index 4c9e3a3..a44494c 100755
--- a/service/src/com/android/server/ConnectivityService.java
+++ b/service/src/com/android/server/ConnectivityService.java
@@ -738,6 +738,12 @@
private static final int EVENT_INITIAL_EVALUATION_TIMEOUT = 57;
/**
+ * Used internally when the user does not want the network from captive portal app.
+ * obj = Network
+ */
+ private static final int EVENT_USER_DOES_NOT_WANT = 58;
+
+ /**
* Argument for {@link #EVENT_PROVISIONING_NOTIFICATION} to indicate that the notification
* should be shown.
*/
@@ -5065,6 +5071,10 @@
public void appResponse(final int response) {
if (response == CaptivePortal.APP_RETURN_WANTED_AS_IS) {
enforceSettingsPermission();
+ } else if (response == CaptivePortal.APP_RETURN_UNWANTED) {
+ mHandler.sendMessage(mHandler.obtainMessage(EVENT_USER_DOES_NOT_WANT, mNetwork));
+ // Since the network will be disconnected, skip notifying NetworkMonitor
+ return;
}
final NetworkMonitorManager nm = getNetworkMonitorManager(mNetwork);
@@ -5508,6 +5518,12 @@
case EVENT_INGRESS_RATE_LIMIT_CHANGED:
handleIngressRateLimitChanged();
break;
+ case EVENT_USER_DOES_NOT_WANT:
+ final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork((Network) msg.obj);
+ if (nai == null) break;
+ nai.onPreventAutomaticReconnect();
+ nai.disconnect();
+ break;
}
}
}
diff --git a/tests/unit/java/com/android/server/ConnectivityServiceTest.java b/tests/unit/java/com/android/server/ConnectivityServiceTest.java
index 67cc7bd..07d3d95 100755
--- a/tests/unit/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/unit/java/com/android/server/ConnectivityServiceTest.java
@@ -228,6 +228,7 @@
import android.content.pm.UserInfo;
import android.content.res.Resources;
import android.location.LocationManager;
+import android.net.CaptivePortal;
import android.net.CaptivePortalData;
import android.net.ConnectionInfo;
import android.net.ConnectivityDiagnosticsManager.DataStallReport;
@@ -4440,6 +4441,27 @@
validatedCallback.expect(CallbackEntry.LOST, mWiFiNetworkAgent);
}
+ private Intent startCaptivePortalApp(TestNetworkAgentWrapper networkAgent) throws Exception {
+ Network network = networkAgent.getNetwork();
+ // Check that startCaptivePortalApp sends the expected command to NetworkMonitor.
+ mCm.startCaptivePortalApp(network);
+ waitForIdle();
+ verify(networkAgent.mNetworkMonitor).launchCaptivePortalApp();
+
+ // NetworkMonitor uses startCaptivePortal(Network, Bundle) (startCaptivePortalAppInternal)
+ final Bundle testBundle = new Bundle();
+ final String testKey = "testkey";
+ final String testValue = "testvalue";
+ testBundle.putString(testKey, testValue);
+ mServiceContext.setPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
+ PERMISSION_GRANTED);
+ mCm.startCaptivePortalApp(network, testBundle);
+ final Intent signInIntent = mServiceContext.expectStartActivityIntent(TIMEOUT_MS);
+ assertEquals(ACTION_CAPTIVE_PORTAL_SIGN_IN, signInIntent.getAction());
+ assertEquals(testValue, signInIntent.getStringExtra(testKey));
+ return signInIntent;
+ }
+
@Test
public void testCaptivePortalApp() throws Exception {
final TestNetworkCallback captivePortalCallback = new TestNetworkCallback();
@@ -4476,22 +4498,7 @@
captivePortalCallback.expect(CallbackEntry.NETWORK_CAPS_UPDATED,
mWiFiNetworkAgent);
- // Check that startCaptivePortalApp sends the expected command to NetworkMonitor.
- mCm.startCaptivePortalApp(wifiNetwork);
- waitForIdle();
- verify(mWiFiNetworkAgent.mNetworkMonitor).launchCaptivePortalApp();
-
- // NetworkMonitor uses startCaptivePortal(Network, Bundle) (startCaptivePortalAppInternal)
- final Bundle testBundle = new Bundle();
- final String testKey = "testkey";
- final String testValue = "testvalue";
- testBundle.putString(testKey, testValue);
- mServiceContext.setPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
- PERMISSION_GRANTED);
- mCm.startCaptivePortalApp(wifiNetwork, testBundle);
- final Intent signInIntent = mServiceContext.expectStartActivityIntent(TIMEOUT_MS);
- assertEquals(ACTION_CAPTIVE_PORTAL_SIGN_IN, signInIntent.getAction());
- assertEquals(testValue, signInIntent.getStringExtra(testKey));
+ startCaptivePortalApp(mWiFiNetworkAgent);
// Report that the captive portal is dismissed, and check that callbacks are fired
mWiFiNetworkAgent.setNetworkValid(false /* isStrictMode */);
@@ -4504,6 +4511,37 @@
}
@Test
+ public void testCaptivePortalApp_IgnoreNetwork() throws Exception {
+ final TestNetworkCallback captivePortalCallback = new TestNetworkCallback();
+ final NetworkRequest captivePortalRequest = new NetworkRequest.Builder()
+ .addCapability(NET_CAPABILITY_CAPTIVE_PORTAL).build();
+ mCm.registerNetworkCallback(captivePortalRequest, captivePortalCallback);
+
+ mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
+ mWiFiNetworkAgent.connectWithCaptivePortal(TEST_REDIRECT_URL, false);
+ captivePortalCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
+
+ final Intent signInIntent = startCaptivePortalApp(mWiFiNetworkAgent);
+ final CaptivePortal captivePortal = signInIntent
+ .getParcelableExtra(ConnectivityManager.EXTRA_CAPTIVE_PORTAL);
+
+ captivePortal.ignoreNetwork();
+ waitForIdle();
+
+ // Since network will disconnect, ensure no notification of response to NetworkMonitor
+ verify(mWiFiNetworkAgent.mNetworkMonitor, never())
+ .notifyCaptivePortalAppFinished(CaptivePortal.APP_RETURN_UNWANTED);
+
+ // Report that the network is disconnected
+ mWiFiNetworkAgent.expectDisconnected();
+ mWiFiNetworkAgent.expectPreventReconnectReceived();
+ verify(mWiFiNetworkAgent.mNetworkMonitor).notifyNetworkDisconnected();
+ captivePortalCallback.expect(CallbackEntry.LOST, mWiFiNetworkAgent);
+
+ mCm.unregisterNetworkCallback(captivePortalCallback);
+ }
+
+ @Test
public void testAvoidOrIgnoreCaptivePortals() throws Exception {
final TestNetworkCallback captivePortalCallback = new TestNetworkCallback();
final NetworkRequest captivePortalRequest = new NetworkRequest.Builder()
diff --git a/tools/gn2bp/Android.bp.swp b/tools/gn2bp/Android.bp.swp
index 4d0ed32..0b0ad9e 100644
--- a/tools/gn2bp/Android.bp.swp
+++ b/tools/gn2bp/Android.bp.swp
@@ -9848,6 +9848,56 @@
"net/android/java/src/org/chromium/net/X509Util.java",
"url/android/java/src/org/chromium/url/IDNStringUtil.java",
],
+ apex_available: [
+ "//apex_available:platform",
+ "com.android.tethering",
+ ],
+ libs: [
+ "android-support-multidex",
+ "androidx.annotation_annotation",
+ "androidx.annotation_annotation-experimental-nodeps",
+ "androidx.collection_collection",
+ "androidx.core_core-nodeps",
+ "framework-connectivity-t.stubs.module_lib",
+ "framework-connectivity.stubs.module_lib",
+ "framework-mediaprovider.stubs.module_lib",
+ "framework-tethering.stubs.module_lib",
+ "framework-wifi.stubs.module_lib",
+ "jsr305",
+ ],
+ aidl: {
+ include_dirs: [
+ "frameworks/base/core/java/",
+ ],
+ local_include_dirs: [
+ "base/android/java/src/",
+ ],
+ },
+ plugins: [
+ "cronet_aml_java_jni_annotation_preprocessor",
+ ],
+ sdk_version: "module_current",
+}
+
+// GN: //base/android/jni_generator:jni_processor
+java_plugin {
+ name: "cronet_aml_java_jni_annotation_preprocessor",
+ srcs: [
+ ":cronet_aml_build_android_build_config_gen",
+ "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/NativeMethods.java",
+ "base/android/jni_generator/java/src/org/chromium/jni_generator/JniProcessor.java",
+ "build/android/java/src/org/chromium/build/annotations/CheckDiscard.java",
+ "build/android/java/src/org/chromium/build/annotations/MainDex.java",
+ ],
+ static_libs: [
+ "auto_service_annotations",
+ "guava",
+ "javapoet",
+ ],
+ processor_class: "org.chromium.jni_generator.JniProcessor",
}
// GN: //net/android:net_android_java_enums_srcjar
diff --git a/tools/gn2bp/gen_android_bp b/tools/gn2bp/gen_android_bp
index 42cb494..46918c6 100755
--- a/tools/gn2bp/gen_android_bp
+++ b/tools/gn2bp/gen_android_bp
@@ -314,8 +314,13 @@
self.cppflags = set()
self.rtti = False
# Name of the output. Used for setting .so file name for libcronet
+ self.libs = set()
self.stem = None
self.compile_multilib = None
+ self.aidl = dict()
+ self.plugins = set()
+ self.processor_class = None
+ self.sdk_version = None
def to_string(self, output):
if self.comment:
@@ -362,8 +367,13 @@
self._output_field(output, 'proto')
self._output_field(output, 'linker_scripts')
self._output_field(output, 'cppflags')
+ self._output_field(output, 'libs')
self._output_field(output, 'stem')
self._output_field(output, 'compile_multilib')
+ self._output_field(output, 'aidl')
+ self._output_field(output, 'plugins')
+ self._output_field(output, 'processor_class')
+ self._output_field(output, 'sdk_version')
if self.rtti:
self._output_field(output, 'rtti')
@@ -1298,16 +1308,62 @@
(dep_module.name, target.name, dep_module.type))
return module
+def create_java_jni_preprocessor(blueprint):
+ bp_module_name = module_prefix + 'java_jni_annotation_preprocessor'
+ module = Module('java_plugin', bp_module_name, '//base/android/jni_generator:jni_processor')
+ module.srcs.update(
+ [
+ "base/android/jni_generator/java/src/org/chromium/jni_generator/JniProcessor.java",
+ # Avoids a circular dependency with base:base_java. This is okay because
+ # no target should ever expect to package an annotation processor.
+ "build/android/java/src/org/chromium/build/annotations/CheckDiscard.java",
+ "build/android/java/src/org/chromium/build/annotations/MainDex.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/NativeMethods.java",
+ "base/android/java/src/org/chromium/base/JniException.java",
+ ":cronet_aml_build_android_build_config_gen",
+ ])
+ module.static_libs.update({
+ "javapoet",
+ "guava",
+ "auto_service_annotations",
+ })
+ module.processor_class = "org.chromium.jni_generator.JniProcessor"
+ blueprint.add_module(module)
+ return module
+
def create_java_module(blueprint, gn):
bp_module_name = module_prefix + 'java'
module = Module('java_library', bp_module_name, '//gn:java')
module.srcs.update([gn_utils.label_to_path(source) for source in gn.java_sources])
+ module.libs = {
+ "androidx.annotation_annotation",
+ "jsr305",
+ "androidx.core_core-nodeps",
+ "androidx.collection_collection",
+ "androidx.annotation_annotation-experimental-nodeps",
+ "android-support-multidex",
+ "framework-connectivity.stubs.module_lib",
+ "framework-connectivity-t.stubs.module_lib",
+ "framework-tethering.stubs.module_lib",
+ "framework-wifi.stubs.module_lib",
+ "framework-mediaprovider.stubs.module_lib",
+ }
+ module.aidl["include_dirs"] = {"frameworks/base/core/java/"}
+ module.aidl["local_include_dirs"] = {"base/android/java/src/"}
+ module.sdk_version = "module_current"
+ module.apex_available.add(tethering_apex)
+ # TODO: remove following workaround required to make this module visible to make (b/203203405)
+ module.apex_available.add("//apex_available:platform")
for dep in gn.java_actions:
target = gn.get_target(dep)
if target.script == '//build/android/gyp/gcc_preprocess.py':
module.srcs.add(':' + create_gcc_preprocess_modules(blueprint, target).name)
else:
module.srcs.add(':' + create_action_module(blueprint, target, 'java_genrule').name)
+ preprocessor_module = create_java_jni_preprocessor(blueprint)
+ module.plugins.add(preprocessor_module.name)
blueprint.add_module(module)
def update_jni_registration_module(module, gn):