Add CDM dependency in Tethering

This change introduces a limited library for dependencies on
framework-connectivity from Tethering,
connectivity-internal-api-util, where all classes are annotated with
@RequiresApi(S) to ensure proper API checks are done before usage.

Bug: 245972418

Change-Id: I82bafd9063341adc71d07f0858e6d68283d081f0
diff --git a/framework/Android.bp b/framework/Android.bp
index 485961c..3950dba 100644
--- a/framework/Android.bp
+++ b/framework/Android.bp
@@ -80,7 +80,9 @@
         "framework-connectivity-t.stubs.module_lib",
     ],
     impl_only_libs: [
-        "framework-tethering.stubs.module_lib",
+        // TODO: figure out why just using "framework-tethering" uses the stubs, even though both
+        // framework-connectivity and framework-tethering are in the same APEX.
+        "framework-tethering.impl",
         "framework-wifi.stubs.module_lib",
         "net-utils-device-common",
     ],
@@ -109,9 +111,9 @@
     libs: [
         // This cannot be in the defaults clause above because if it were, it would be used
         // to generate the connectivity stubs. That would create a circular dependency
-        // because the tethering stubs depend on the connectivity stubs (e.g.,
+        // because the tethering impl depend on the connectivity stubs (e.g.,
         // TetheringRequest depends on LinkAddress).
-        "framework-tethering.stubs.module_lib",
+        "framework-tethering.impl",
         "framework-wifi.stubs.module_lib",
     ],
     visibility: ["//packages/modules/Connectivity:__subpackages__"]
@@ -243,3 +245,24 @@
         "//packages/modules/Connectivity/service",
     ],
 }
+
+// Library providing limited APIs within the connectivity module, so that R+ components like
+// Tethering have a controlled way to depend on newer components like framework-connectivity that
+// are not loaded on R.
+java_library {
+    name: "connectivity-internal-api-util",
+    sdk_version: "module_current",
+    libs: [
+        "androidx.annotation_annotation",
+        "framework-connectivity.impl",
+    ],
+    jarjar_rules: ":framework-connectivity-jarjar-rules",
+    srcs: [
+        // Files listed here MUST all be annotated with @RequiresApi(Build.VERSION_CODES.TIRAMISU),
+        // so that API checks are enforced for R+ users of this library
+        "src/android/net/connectivity/TiramisuConnectivityInternalApiUtil.java",
+    ],
+    visibility: [
+        "//packages/modules/Connectivity/Tethering:__subpackages__",
+    ],
+}
diff --git a/framework/src/android/net/ConnectivityManager.java b/framework/src/android/net/ConnectivityManager.java
index 39c5af2..1b4b42f 100644
--- a/framework/src/android/net/ConnectivityManager.java
+++ b/framework/src/android/net/ConnectivityManager.java
@@ -5992,4 +5992,13 @@
             throw e.rethrowFromSystemServer();
         }
     }
+
+    /** @hide */
+    public IBinder getCompanionDeviceManagerProxyService() {
+        try {
+            return mService.getCompanionDeviceManagerProxyService();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
 }
diff --git a/framework/src/android/net/IConnectivityManager.aidl b/framework/src/android/net/IConnectivityManager.aidl
index 29fea00..43d2f07 100644
--- a/framework/src/android/net/IConnectivityManager.aidl
+++ b/framework/src/android/net/IConnectivityManager.aidl
@@ -247,4 +247,6 @@
     boolean getFirewallChainEnabled(int chain);
 
     void replaceFirewallChain(int chain, in int[] uids);
+
+    IBinder getCompanionDeviceManagerProxyService();
 }
diff --git a/framework/src/android/net/connectivity/TiramisuConnectivityInternalApiUtil.java b/framework/src/android/net/connectivity/TiramisuConnectivityInternalApiUtil.java
new file mode 100644
index 0000000..d65858f
--- /dev/null
+++ b/framework/src/android/net/connectivity/TiramisuConnectivityInternalApiUtil.java
@@ -0,0 +1,48 @@
+/*
+ * 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.connectivity;
+
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.os.Build;
+import android.os.IBinder;
+
+import androidx.annotation.RequiresApi;
+
+/**
+ * Utility providing limited access to module-internal APIs which are only available on Android T+,
+ * as this class is only in the bootclasspath on T+ as part of framework-connectivity.
+ *
+ * R+ module components like Tethering cannot depend on all hidden symbols from
+ * framework-connectivity. They only have access to stable API stubs where newer APIs can be
+ * accessed after an API level check (enforced by the linter), or to limited hidden symbols in this
+ * class which is also annotated with @RequiresApi (so API level checks are also enforced by the
+ * linter).
+ * @hide
+ */
+@RequiresApi(Build.VERSION_CODES.TIRAMISU)
+public class TiramisuConnectivityInternalApiUtil {
+
+    /**
+     * Get a service binder token for
+     * {@link com.android.server.connectivity.wear.CompanionDeviceManagerProxyService}.
+     */
+    public static IBinder getCompanionDeviceManagerProxyService(Context ctx) {
+        final ConnectivityManager cm = ctx.getSystemService(ConnectivityManager.class);
+        return cm.getCompanionDeviceManagerProxyService();
+    }
+}