Merge changes I545be996,I2bef893e,I8c026cd2

* changes:
  gn2bp: create single java library from all sources
  gn2bp: collect java sources
  gn2bp: be explicit about dropping java_group dependencies
diff --git a/Tethering/apex/Android.bp b/Tethering/apex/Android.bp
index c590850..e59c8e4 100644
--- a/Tethering/apex/Android.bp
+++ b/Tethering/apex/Android.bp
@@ -70,7 +70,10 @@
                 "libservice-connectivity",
                 "libandroid_net_connectivity_com_android_net_module_util_jni",
             ],
-            native_shared_libs: ["libnetd_updatable"],
+            native_shared_libs: [
+                "libcom.android.tethering.connectivity_native",
+                "libnetd_updatable",
+            ],
         },
         both: {
             jni_libs: [
diff --git a/service/Android.bp b/service/Android.bp
index d850015..326f91b 100644
--- a/service/Android.bp
+++ b/service/Android.bp
@@ -22,7 +22,6 @@
 aidl_interface {
     name: "connectivity_native_aidl_interface",
     local_include_dir: "binder",
-    vendor_available: true,
     srcs: [
         "binder/android/net/connectivity/aidl/*.aidl",
     ],
@@ -179,6 +178,7 @@
         "networkstack-client",
         "PlatformProperties",
         "service-connectivity-protos",
+        "service-connectivity-stats-protos",
         "NetworkStackApiStableShims",
     ],
     apex_available: [
@@ -290,6 +290,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"],
diff --git a/service/libconnectivity/Android.bp b/service/libconnectivity/Android.bp
new file mode 100644
index 0000000..391ceac
--- /dev/null
+++ b/service/libconnectivity/Android.bp
@@ -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 {
+    // See: http://go/android-license-faq
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_library_shared {
+    name: "libcom.android.tethering.connectivity_native",
+    srcs: [
+        "src/**/*.cpp",
+    ],
+    min_sdk_version: "30",
+    static_libs: [
+        "connectivity_native_aidl_interface-V1-ndk",
+    ],
+    export_include_dirs: ["include"],
+    cflags: [
+        "-Wall",
+        "-Werror",
+        "-Wno-error=deprecated-declarations",
+    ],
+
+    shared_libs: [
+        "libbinder_ndk",
+    ],
+    llndk: {
+        symbol_file: "libconnectivity_native.map.txt",
+    },
+    stubs: {
+        symbol_file: "libconnectivity_native.map.txt",
+        versions: [
+            "current",
+        ],
+    },
+    header_abi_checker: {
+        enabled: true,
+        symbol_file: "libconnectivity_native.map.txt",
+    },
+    apex_available: [
+        "com.android.tethering",
+    ],
+}
diff --git a/service/libconnectivity/include/connectivity_native.h b/service/libconnectivity/include/connectivity_native.h
new file mode 100644
index 0000000..5a2509a
--- /dev/null
+++ b/service/libconnectivity/include/connectivity_native.h
@@ -0,0 +1,87 @@
+/*
+ * 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.
+ */
+
+#ifndef LIBCONNECTIVITY_CONNECTIVITY_NATIVE_H_
+#define LIBCONNECTIVITY_CONNECTIVITY_NATIVE_H_
+
+#include <sys/cdefs.h>
+#include <netinet/in.h>
+
+// For branches that do not yet have __ANDROID_API_U__ defined, like module
+// release branches.
+#ifndef __ANDROID_API_U__
+#define __ANDROID_API_U__ 34
+#endif
+
+__BEGIN_DECLS
+
+/**
+ * Blocks a port from being assigned during bind(). The caller is responsible for updating
+ * /proc/sys/net/ipv4/ip_local_port_range with the port being blocked so that calls to connect()
+ * will not automatically assign one of the blocked ports.
+ * Will return success even if port was already blocked.
+ *
+ * Returns 0 on success, or a POSIX error code (see errno.h) on failure:
+ *  - EINVAL for invalid port number
+ *  - EPERM if the UID of the client doesn't have network stack permission
+ *  - Other errors as per https://man7.org/linux/man-pages/man2/bpf.2.html
+ *
+ * @param port Int corresponding to port number.
+ */
+int AConnectivityNative_blockPortForBind(in_port_t port) __INTRODUCED_IN(__ANDROID_API_U__);
+
+/**
+ * Unblocks a port that has previously been blocked.
+ * Will return success even if port was already unblocked.
+ *
+ * Returns 0 on success, or a POSIX error code (see errno.h) on failure:
+ *  - EINVAL for invalid port number
+ *  - EPERM if the UID of the client doesn't have network stack permission
+ *  - Other errors as per https://man7.org/linux/man-pages/man2/bpf.2.html
+ *
+ * @param port Int corresponding to port number.
+ */
+int AConnectivityNative_unblockPortForBind(in_port_t port) __INTRODUCED_IN(__ANDROID_API_U__);
+
+/**
+ * Unblocks all ports that have previously been blocked.
+ *
+ * Returns 0 on success, or a POSIX error code (see errno.h) on failure:
+ *  - EINVAL for invalid port number
+ *  - EPERM if the UID of the client doesn't have network stack permission
+ *  - Other errors as per https://man7.org/linux/man-pages/man2/bpf.2.html
+ */
+int AConnectivityNative_unblockAllPortsForBind() __INTRODUCED_IN(__ANDROID_API_U__);
+
+/**
+ * Gets the list of ports that have been blocked.
+ *
+ * Returns 0 on success, or a POSIX error code (see errno.h) on failure:
+ *  - EINVAL for invalid port number
+ *  - EPERM if the UID of the client doesn't have network stack permission
+ *  - Other errors as per https://man7.org/linux/man-pages/man2/bpf.2.html
+ *
+ * @param ports Array of ports that will be filled with the port numbers.
+ * @param count Pointer to the size of the ports array; the value will be set to the total number of
+ *              blocked ports, which may be larger than the ports array that was filled.
+ */
+int AConnectivityNative_getPortsBlockedForBind(in_port_t *ports, size_t *count)
+    __INTRODUCED_IN(__ANDROID_API_U__);
+
+__END_DECLS
+
+
+#endif
diff --git a/service/libconnectivity/libconnectivity_native.map.txt b/service/libconnectivity/libconnectivity_native.map.txt
new file mode 100644
index 0000000..19b1074
--- /dev/null
+++ b/service/libconnectivity/libconnectivity_native.map.txt
@@ -0,0 +1,24 @@
+#
+# 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.
+#
+LIBCONNECTIVITY_NATIVE {
+  global:
+    AConnectivityNative_blockPortForBind; # apex llndk
+    AConnectivityNative_getPortsBlockedForBind; # apex llndk
+    AConnectivityNative_unblockPortForBind; # apex llndk
+    AConnectivityNative_unblockAllPortsForBind; # apex llndk
+  local:
+    *;
+};
diff --git a/service/libconnectivity/src/connectivity_native.cpp b/service/libconnectivity/src/connectivity_native.cpp
new file mode 100644
index 0000000..9545ed1
--- /dev/null
+++ b/service/libconnectivity/src/connectivity_native.cpp
@@ -0,0 +1,74 @@
+/*
+ * 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.
+ */
+
+#include "connectivity_native.h"
+
+#include <android/binder_manager.h>
+#include <aidl/android/net/connectivity/aidl/ConnectivityNative.h>
+
+using aidl::android::net::connectivity::aidl::IConnectivityNative;
+
+
+static std::shared_ptr<IConnectivityNative> getBinder() {
+    static ndk::SpAIBinder sBinder = ndk::SpAIBinder(reinterpret_cast<AIBinder*>(
+        AServiceManager_getService("connectivity_native")));
+    return aidl::android::net::connectivity::aidl::IConnectivityNative::fromBinder(sBinder);
+}
+
+static int getErrno(const ::ndk::ScopedAStatus& status) {
+    switch (status.getExceptionCode()) {
+        case EX_NONE:
+            return 0;
+        case EX_ILLEGAL_ARGUMENT:
+            return EINVAL;
+        case EX_SECURITY:
+            return EPERM;
+        case EX_SERVICE_SPECIFIC:
+            return status.getServiceSpecificError();
+        default:
+            return EPROTO;
+    }
+}
+
+int AConnectivityNative_blockPortForBind(in_port_t port) {
+    std::shared_ptr<IConnectivityNative> c = getBinder();
+    return getErrno(c->blockPortForBind(port));
+}
+
+int AConnectivityNative_unblockPortForBind(in_port_t port) {
+    std::shared_ptr<IConnectivityNative> c = getBinder();
+    return getErrno(c->unblockPortForBind(port));
+}
+
+int AConnectivityNative_unblockAllPortsForBind() {
+    std::shared_ptr<IConnectivityNative> c = getBinder();
+    return getErrno(c->unblockAllPortsForBind());
+}
+
+int AConnectivityNative_getPortsBlockedForBind(in_port_t *ports, size_t *count) {
+    std::shared_ptr<IConnectivityNative> c = getBinder();
+    std::vector<int32_t> actualBlockedPorts;
+    int err = getErrno(c->getPortsBlockedForBind(&actualBlockedPorts));
+    if (err) {
+        return err;
+    }
+
+    for (int i = 0; i < *count && i < actualBlockedPorts.size(); i++) {
+        ports[i] = actualBlockedPorts[i];
+    }
+    *count = actualBlockedPorts.size();
+    return 0;
+}
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/connectivity/PermissionMonitor.java b/service/src/com/android/server/connectivity/PermissionMonitor.java
index fd1ed60..aeca717 100755
--- a/service/src/com/android/server/connectivity/PermissionMonitor.java
+++ b/service/src/com/android/server/connectivity/PermissionMonitor.java
@@ -758,7 +758,8 @@
      *
      * @hide
      */
-    public synchronized void onPackageAdded(@NonNull final String packageName, final int uid) {
+    @VisibleForTesting
+    synchronized void onPackageAdded(@NonNull final String packageName, final int uid) {
         // Update uid permission.
         updateAppIdTrafficPermission(uid);
         // Get the appId permission from all users then send the latest permission to netd.
@@ -821,7 +822,8 @@
      *
      * @hide
      */
-    public synchronized void onPackageRemoved(@NonNull final String packageName, final int uid) {
+    @VisibleForTesting
+    synchronized void onPackageRemoved(@NonNull final String packageName, final int uid) {
         // Update uid permission.
         updateAppIdTrafficPermission(uid);
         // Get the appId permission from all users then send the latest permission to netd.
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/native/connectivity_native_test/Android.bp b/tests/native/connectivity_native_test/Android.bp
index 7d43aa8..8825aa4 100644
--- a/tests/native/connectivity_native_test/Android.bp
+++ b/tests/native/connectivity_native_test/Android.bp
@@ -10,7 +10,7 @@
         "vts",
     ],
     test_config_template: "AndroidTestTemplate.xml",
-    min_sdk_version: "31",
+    min_sdk_version: "34",
     tidy: false,
     srcs: [
         "connectivity_native_test.cpp",
diff --git a/tests/native/connectivity_native_test/connectivity_native_test.cpp b/tests/native/connectivity_native_test/connectivity_native_test.cpp
index 3db5265..27a9d35 100644
--- a/tests/native/connectivity_native_test/connectivity_native_test.cpp
+++ b/tests/native/connectivity_native_test/connectivity_native_test.cpp
@@ -14,62 +14,81 @@
  * limitations under the License.
  */
 
-#include <aidl/android/net/connectivity/aidl/ConnectivityNative.h>
 #include <android/binder_manager.h>
 #include <android/binder_process.h>
 #include <android-modules-utils/sdk_level.h>
 #include <cutils/misc.h>  // FIRST_APPLICATION_UID
+#include <dlfcn.h>
 #include <gtest/gtest.h>
 #include <netinet/in.h>
 
 #include "bpf/BpfUtils.h"
 
-using aidl::android::net::connectivity::aidl::IConnectivityNative;
+typedef int (*GetPortsBlockedForBind)(in_port_t*, size_t*);
+GetPortsBlockedForBind getPortsBlockedForBind;
+typedef int (*BlockPortForBind)(in_port_t);
+BlockPortForBind blockPortForBind;
+typedef int (*UnblockPortForBind)(in_port_t);
+UnblockPortForBind unblockPortForBind;
+typedef int (*UnblockAllPortsForBind)();
+UnblockAllPortsForBind unblockAllPortsForBind;
 
 class ConnectivityNativeBinderTest : public ::testing::Test {
   public:
-    std::vector<int32_t> mActualBlockedPorts;
-
-    ConnectivityNativeBinderTest() {
-        AIBinder* binder = AServiceManager_getService("connectivity_native");
-        ndk::SpAIBinder sBinder = ndk::SpAIBinder(binder);
-        mService = aidl::android::net::connectivity::aidl::IConnectivityNative::fromBinder(sBinder);
-    }
+    in_port_t mActualBlockedPorts[65535];
+    size_t mActualBlockedPortsCount = 65535;
+    bool restoreBlockedPorts;
 
     void SetUp() override {
-        // Skip test case if not on T.
-        if (!android::modules::sdklevel::IsAtLeastT()) GTEST_SKIP() <<
+        restoreBlockedPorts = false;
+        // Skip test case if not on U.
+        if (!android::modules::sdklevel::IsAtLeastU()) GTEST_SKIP() <<
                 "Should be at least T device.";
 
         // Skip test case if not on 5.4 kernel which is required by bpf prog.
         if (!android::bpf::isAtLeastKernelVersion(5, 4, 0)) GTEST_SKIP() <<
                 "Kernel should be at least 5.4.";
 
-        ASSERT_NE(nullptr, mService.get());
+        // Necessary to use dlopen/dlsym since the lib is only available on U and there
+        // is no Sdk34ModuleController in tradefed yet.
+        // TODO: link against the library directly and add Sdk34ModuleController to
+        // AndroidTest.txml when available.
+        void* nativeLib = dlopen("libcom.android.tethering.connectivity_native.so", RTLD_NOW);
+        ASSERT_NE(nullptr, nativeLib);
+        getPortsBlockedForBind = reinterpret_cast<GetPortsBlockedForBind>(
+                dlsym(nativeLib, "AConnectivityNative_getPortsBlockedForBind"));
+        ASSERT_NE(nullptr, getPortsBlockedForBind);
+        blockPortForBind = reinterpret_cast<BlockPortForBind>(
+                dlsym(nativeLib, "AConnectivityNative_blockPortForBind"));
+        ASSERT_NE(nullptr, blockPortForBind);
+        unblockPortForBind = reinterpret_cast<UnblockPortForBind>(
+                dlsym(nativeLib, "AConnectivityNative_unblockPortForBind"));
+        ASSERT_NE(nullptr, unblockPortForBind);
+        unblockAllPortsForBind = reinterpret_cast<UnblockAllPortsForBind>(
+                dlsym(nativeLib, "AConnectivityNative_unblockAllPortsForBind"));
+        ASSERT_NE(nullptr, unblockAllPortsForBind);
 
         // If there are already ports being blocked on device unblockAllPortsForBind() store
         // the currently blocked ports and add them back at the end of the test. Do this for
         // every test case so additional test cases do not forget to add ports back.
-        ndk::ScopedAStatus status = mService->getPortsBlockedForBind(&mActualBlockedPorts);
-        EXPECT_TRUE(status.isOk()) << status.getDescription ();
-
+        int err = getPortsBlockedForBind(mActualBlockedPorts, &mActualBlockedPortsCount);
+        EXPECT_EQ(err, 0);
+        restoreBlockedPorts = true;
     }
 
     void TearDown() override {
-        ndk::ScopedAStatus status;
-        if (mActualBlockedPorts.size() > 0) {
-            for (int i : mActualBlockedPorts) {
-                mService->blockPortForBind(i);
-                EXPECT_TRUE(status.isOk()) << status.getDescription ();
+        int err;
+        if (mActualBlockedPortsCount > 0 && restoreBlockedPorts) {
+            for (int i=0; i < mActualBlockedPortsCount; i++) {
+                err = blockPortForBind(mActualBlockedPorts[i]);
+                EXPECT_EQ(err, 0);
             }
         }
     }
 
   protected:
-    std::shared_ptr<IConnectivityNative> mService;
-
     void runSocketTest (sa_family_t family, const int type, bool blockPort) {
-        ndk::ScopedAStatus status;
+        int err;
         in_port_t port = 0;
         int sock, sock2;
         // Open two sockets with SO_REUSEADDR and expect they can both bind to port.
@@ -79,16 +98,16 @@
         int blockedPort = 0;
         if (blockPort) {
             blockedPort = ntohs(port);
-            status = mService->blockPortForBind(blockedPort);
-            EXPECT_TRUE(status.isOk()) << status.getDescription ();
+            err = blockPortForBind(blockedPort);
+            EXPECT_EQ(err, 0);
         }
 
         int sock3 = openSocket(&port, family, type, blockPort /* expectBindFail */);
 
         if (blockPort) {
             EXPECT_EQ(-1, sock3);
-            status = mService->unblockPortForBind(blockedPort);
-            EXPECT_TRUE(status.isOk()) << status.getDescription ();
+            err = unblockPortForBind(blockedPort);
+            EXPECT_EQ(err, 0);
         } else {
             EXPECT_NE(-1, sock3);
         }
@@ -177,110 +196,74 @@
 }
 
 TEST_F(ConnectivityNativeBinderTest, BlockPortTwice) {
-    ndk::ScopedAStatus status = mService->blockPortForBind(5555);
-    EXPECT_TRUE(status.isOk()) << status.getDescription ();
-    status = mService->blockPortForBind(5555);
-    EXPECT_TRUE(status.isOk()) << status.getDescription ();
-    status = mService->unblockPortForBind(5555);
-    EXPECT_TRUE(status.isOk()) << status.getDescription ();
+    int err = blockPortForBind(5555);
+    EXPECT_EQ(err, 0);
+    err = blockPortForBind(5555);
+    EXPECT_EQ(err, 0);
+    err = unblockPortForBind(5555);
+    EXPECT_EQ(err, 0);
 }
 
 TEST_F(ConnectivityNativeBinderTest, GetBlockedPorts) {
-    ndk::ScopedAStatus status;
-    std::vector<int> blockedPorts{1, 100, 1220, 1333, 2700, 5555, 5600, 65000};
-    for (int i : blockedPorts) {
-        status = mService->blockPortForBind(i);
-        EXPECT_TRUE(status.isOk()) << status.getDescription ();
+    int err;
+    in_port_t blockedPorts[8] = {1, 100, 1220, 1333, 2700, 5555, 5600, 65000};
+
+    if (mActualBlockedPortsCount > 0) {
+        err = unblockAllPortsForBind();
     }
-    std::vector<int32_t> actualBlockedPorts;
-    status = mService->getPortsBlockedForBind(&actualBlockedPorts);
-    EXPECT_TRUE(status.isOk()) << status.getDescription ();
-    EXPECT_FALSE(actualBlockedPorts.empty());
-    EXPECT_EQ(blockedPorts, actualBlockedPorts);
+
+    for (int i : blockedPorts) {
+        err = blockPortForBind(i);
+        EXPECT_EQ(err, 0);
+    }
+    size_t actualBlockedPortsCount = 8;
+    in_port_t actualBlockedPorts[actualBlockedPortsCount];
+    err = getPortsBlockedForBind((in_port_t*) actualBlockedPorts, &actualBlockedPortsCount);
+    EXPECT_EQ(err, 0);
+    EXPECT_NE(actualBlockedPortsCount, 0);
+    for (int i=0; i < actualBlockedPortsCount; i++) {
+        EXPECT_EQ(blockedPorts[i], actualBlockedPorts[i]);
+    }
 
     // Remove the ports we added.
-    status = mService->unblockAllPortsForBind();
-    EXPECT_TRUE(status.isOk()) << status.getDescription ();
-    status = mService->getPortsBlockedForBind(&actualBlockedPorts);
-    EXPECT_TRUE(status.isOk()) << status.getDescription ();
-    EXPECT_TRUE(actualBlockedPorts.empty());
+    err = unblockAllPortsForBind();
+    EXPECT_EQ(err, 0);
+    err = getPortsBlockedForBind(actualBlockedPorts, &actualBlockedPortsCount);
+    EXPECT_EQ(err, 0);
+    EXPECT_EQ(actualBlockedPortsCount, 0);
 }
 
 TEST_F(ConnectivityNativeBinderTest, UnblockAllPorts) {
-    ndk::ScopedAStatus status;
-    std::vector<int> blockedPorts{1, 100, 1220, 1333, 2700, 5555, 5600, 65000};
+    int err;
+    in_port_t blockedPorts[8] = {1, 100, 1220, 1333, 2700, 5555, 5600, 65000};
 
-    if (mActualBlockedPorts.size() > 0) {
-        status = mService->unblockAllPortsForBind();
+    if (mActualBlockedPortsCount > 0) {
+        err = unblockAllPortsForBind();
     }
 
     for (int i : blockedPorts) {
-        status = mService->blockPortForBind(i);
-        EXPECT_TRUE(status.isOk()) << status.getDescription ();
+        err = blockPortForBind(i);
+        EXPECT_EQ(err, 0);
     }
 
-    std::vector<int32_t> actualBlockedPorts;
-    status = mService->getPortsBlockedForBind(&actualBlockedPorts);
-    EXPECT_TRUE(status.isOk()) << status.getDescription ();
-    EXPECT_FALSE(actualBlockedPorts.empty());
+    size_t actualBlockedPortsCount = 8;
+    in_port_t actualBlockedPorts[actualBlockedPortsCount];
+    err = getPortsBlockedForBind((in_port_t*) actualBlockedPorts, &actualBlockedPortsCount);
+    EXPECT_EQ(err, 0);
+    EXPECT_EQ(actualBlockedPortsCount, 8);
 
-    status = mService->unblockAllPortsForBind();
-    EXPECT_TRUE(status.isOk()) << status.getDescription ();
-    status = mService->getPortsBlockedForBind(&actualBlockedPorts);
-    EXPECT_TRUE(status.isOk()) << status.getDescription ();
-    EXPECT_TRUE(actualBlockedPorts.empty());
+    err = unblockAllPortsForBind();
+    EXPECT_EQ(err, 0);
+    err = getPortsBlockedForBind((in_port_t*) actualBlockedPorts, &actualBlockedPortsCount);
+    EXPECT_EQ(err, 0);
+    EXPECT_EQ(actualBlockedPortsCount, 0);
     // If mActualBlockedPorts is not empty, ports will be added back in teardown.
 }
 
-TEST_F(ConnectivityNativeBinderTest, BlockNegativePort) {
-    int retry = 0;
-    ndk::ScopedAStatus status;
-    do {
-        status = mService->blockPortForBind(-1);
-        // TODO: find out why transaction failed is being thrown on the first attempt.
-    } while (status.getExceptionCode() == EX_TRANSACTION_FAILED && retry++ < 5);
-    EXPECT_EQ(EX_ILLEGAL_ARGUMENT, status.getExceptionCode());
-}
-
-TEST_F(ConnectivityNativeBinderTest, UnblockNegativePort) {
-    int retry = 0;
-    ndk::ScopedAStatus status;
-    do {
-        status = mService->unblockPortForBind(-1);
-        // TODO: find out why transaction failed is being thrown on the first attempt.
-    } while (status.getExceptionCode() == EX_TRANSACTION_FAILED && retry++ < 5);
-    EXPECT_EQ(EX_ILLEGAL_ARGUMENT, status.getExceptionCode());
-}
-
-TEST_F(ConnectivityNativeBinderTest, BlockMaxPort) {
-    int retry = 0;
-    ndk::ScopedAStatus status;
-    do {
-        status = mService->blockPortForBind(65536);
-        // TODO: find out why transaction failed is being thrown on the first attempt.
-    } while (status.getExceptionCode() == EX_TRANSACTION_FAILED && retry++ < 5);
-    EXPECT_EQ(EX_ILLEGAL_ARGUMENT, status.getExceptionCode());
-}
-
-TEST_F(ConnectivityNativeBinderTest, UnblockMaxPort) {
-    int retry = 0;
-    ndk::ScopedAStatus status;
-    do {
-        status = mService->unblockPortForBind(65536);
-        // TODO: find out why transaction failed is being thrown on the first attempt.
-    } while (status.getExceptionCode() == EX_TRANSACTION_FAILED && retry++ < 5);
-    EXPECT_EQ(EX_ILLEGAL_ARGUMENT, status.getExceptionCode());
-}
-
 TEST_F(ConnectivityNativeBinderTest, CheckPermission) {
-    int retry = 0;
     int curUid = getuid();
     EXPECT_EQ(0, seteuid(FIRST_APPLICATION_UID + 2000)) << "seteuid failed: " << strerror(errno);
-    ndk::ScopedAStatus status;
-    do {
-        status = mService->blockPortForBind(5555);
-        // TODO: find out why transaction failed is being thrown on the first attempt.
-    } while (status.getExceptionCode() == EX_TRANSACTION_FAILED && retry++ < 5);
-    EXPECT_EQ(EX_SECURITY, status.getExceptionCode());
+    int err = blockPortForBind((in_port_t) 5555);
+    EXPECT_EQ(EPERM, err);
     EXPECT_EQ(0, seteuid(curUid)) << "seteuid failed: " << strerror(errno);
 }
diff --git a/tests/unit/java/com/android/server/ConnectivityServiceTest.java b/tests/unit/java/com/android/server/ConnectivityServiceTest.java
index 2d35330..083f34d 100755
--- a/tests/unit/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/unit/java/com/android/server/ConnectivityServiceTest.java
@@ -3477,7 +3477,12 @@
             final int uid, final String packageName) throws Exception {
         doReturn(buildPackageInfo(true /* hasSystemPermission */, uid)).when(mPackageManager)
                 .getPackageInfo(eq(packageName), eq(GET_PERMISSIONS));
-        mService.mPermissionMonitor.onPackageAdded(packageName, uid);
+
+        // Send a broadcast indicating a package was installed.
+        final Intent addedIntent = new Intent(ACTION_PACKAGE_ADDED);
+        addedIntent.putExtra(Intent.EXTRA_UID, uid);
+        addedIntent.setData(Uri.parse("package:" + packageName));
+        processBroadcast(addedIntent);
     }
 
     @Test