From 9dac660bf072fe0701228b731e376052ec773e7b Mon Sep 17 00:00:00 2001 From: Igor Chernyshev <igorc@google.com> Date: Tue, 13 Dec 2022 19:28:32 -0800 Subject: [PATCH] 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 --- Tethering/Android.bp | 1 + Tethering/apex/Android.bp | 1 + Tethering/common/TetheringLib/Android.bp | 19 ++----- .../wear/ICompanionDeviceManagerProxy.aidl | 24 ++++++++ .../wear/CompanionDeviceManagerProxy.java | 55 +++++++++++++++++++ framework/Android.bp | 29 +++++++++- .../src/android/net/ConnectivityManager.java | 9 +++ .../src/android/net/IConnectivityManager.aidl | 2 + .../TiramisuConnectivityInternalApiUtil.java | 48 ++++++++++++++++ service-t/Android.bp | 3 +- service/Android.bp | 7 ++- .../android/server/ConnectivityService.java | 14 +++++ .../CompanionDeviceManagerProxyService.java | 55 +++++++++++++++++++ 13 files changed, 248 insertions(+), 19 deletions(-) create mode 100644 Tethering/common/TetheringLib/src/android/net/wear/ICompanionDeviceManagerProxy.aidl create mode 100644 Tethering/src/com/android/networkstack/tethering/wear/CompanionDeviceManagerProxy.java create mode 100644 framework/src/android/net/connectivity/TiramisuConnectivityInternalApiUtil.java create mode 100644 service/src/com/android/server/connectivity/wear/CompanionDeviceManagerProxyService.java diff --git a/Tethering/Android.bp b/Tethering/Android.bp index 829e66a350..d2f6d154c7 100644 --- a/Tethering/Android.bp +++ b/Tethering/Android.bp @@ -34,6 +34,7 @@ java_defaults { // Libraries not including Tethering's own framework-tethering (different flavors of that one // are needed depending on the build rule) libs: [ + "connectivity-internal-api-util", "framework-configinfrastructure", "framework-connectivity.stubs.module_lib", "framework-connectivity-t.stubs.module_lib", diff --git a/Tethering/apex/Android.bp b/Tethering/apex/Android.bp index e59c8e4fdb..88403943b9 100644 --- a/Tethering/apex/Android.bp +++ b/Tethering/apex/Android.bp @@ -199,6 +199,7 @@ bootclasspath_fragment { "android.net.connectivity", "android.net.netstats.provider", "android.net.nsd", + "android.net.wear", ], }, } diff --git a/Tethering/common/TetheringLib/Android.bp b/Tethering/common/TetheringLib/Android.bp index 9ca3f14fee..481557b863 100644 --- a/Tethering/common/TetheringLib/Android.bp +++ b/Tethering/common/TetheringLib/Android.bp @@ -22,6 +22,10 @@ java_sdk_library { defaults: ["framework-module-defaults"], impl_library_visibility: [ "//packages/modules/Connectivity/Tethering:__subpackages__", + "//packages/modules/Connectivity/framework", + "//packages/modules/Connectivity/framework-t", + "//packages/modules/Connectivity/service", + "//packages/modules/Connectivity/service-t", // Using for test only "//cts/tests/netlegacy22.api", @@ -64,19 +68,8 @@ java_sdk_library { filegroup { name: "framework-tethering-srcs", srcs: [ - "src/android/net/TetheredClient.aidl", - "src/android/net/TetheredClient.java", - "src/android/net/TetheringManager.java", - "src/android/net/TetheringConstants.java", - "src/android/net/IIntResultListener.aidl", - "src/android/net/ITetheringEventCallback.aidl", - "src/android/net/ITetheringConnector.aidl", - "src/android/net/TetheringCallbackStartedParcel.aidl", - "src/android/net/TetheringConfigurationParcel.aidl", - "src/android/net/TetheringRequestParcel.aidl", - "src/android/net/TetherStatesParcel.aidl", - "src/android/net/TetheringInterface.aidl", - "src/android/net/TetheringInterface.java", + "src/**/*.aidl", + "src/**/*.java", ], path: "src" } diff --git a/Tethering/common/TetheringLib/src/android/net/wear/ICompanionDeviceManagerProxy.aidl b/Tethering/common/TetheringLib/src/android/net/wear/ICompanionDeviceManagerProxy.aidl new file mode 100644 index 0000000000..f8c39bfa15 --- /dev/null +++ b/Tethering/common/TetheringLib/src/android/net/wear/ICompanionDeviceManagerProxy.aidl @@ -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. + */ + +package android.net.wear; + +import android.companion.AssociationInfo; + +/** @hide */ +interface ICompanionDeviceManagerProxy { + List<AssociationInfo> getAllAssociations(); +} diff --git a/Tethering/src/com/android/networkstack/tethering/wear/CompanionDeviceManagerProxy.java b/Tethering/src/com/android/networkstack/tethering/wear/CompanionDeviceManagerProxy.java new file mode 100644 index 0000000000..e94febbcc7 --- /dev/null +++ b/Tethering/src/com/android/networkstack/tethering/wear/CompanionDeviceManagerProxy.java @@ -0,0 +1,55 @@ +/* + * 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.networkstack.tethering.wear; + +import android.companion.AssociationInfo; +import android.companion.CompanionDeviceManager; +import android.content.Context; +import android.net.connectivity.TiramisuConnectivityInternalApiUtil; +import android.net.wear.ICompanionDeviceManagerProxy; +import android.os.Build; +import android.os.RemoteException; + +import androidx.annotation.RequiresApi; + +import java.util.List; + +/** + * A proxy for {@link android.companion.CompanionDeviceManager}, allowing Tethering to call it with + * a different set of permissions. + * @hide + */ +public class CompanionDeviceManagerProxy { + private final ICompanionDeviceManagerProxy mService; + + @RequiresApi(Build.VERSION_CODES.TIRAMISU) + public CompanionDeviceManagerProxy(Context context) { + mService = ICompanionDeviceManagerProxy.Stub.asInterface( + TiramisuConnectivityInternalApiUtil.getCompanionDeviceManagerProxyService(context)); + } + + /** + * @see CompanionDeviceManager#getAllAssociations() + */ + public List<AssociationInfo> getAllAssociations() { + try { + return mService.getAllAssociations(); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } +} diff --git a/framework/Android.bp b/framework/Android.bp index 485961c8b4..3950dba276 100644 --- a/framework/Android.bp +++ b/framework/Android.bp @@ -80,7 +80,9 @@ java_defaults { "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 @@ java_library { 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 @@ java_genrule { "//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 39c5af20a1..1b4b42fbe3 100644 --- a/framework/src/android/net/ConnectivityManager.java +++ b/framework/src/android/net/ConnectivityManager.java @@ -5992,4 +5992,13 @@ public class ConnectivityManager { 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 29fea00ffa..43d2f07c7b 100644 --- a/framework/src/android/net/IConnectivityManager.aidl +++ b/framework/src/android/net/IConnectivityManager.aidl @@ -247,4 +247,6 @@ interface IConnectivityManager 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 0000000000..d65858f9ab --- /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(); + } +} diff --git a/service-t/Android.bp b/service-t/Android.bp index 2e7a4f3aac..d876166b5b 100644 --- a/service-t/Android.bp +++ b/service-t/Android.bp @@ -50,7 +50,8 @@ java_library { "framework-configinfrastructure", "framework-connectivity-pre-jarjar", "framework-connectivity-t-pre-jarjar", - "framework-tethering", + // TODO: use framework-tethering-pre-jarjar when it is separated from framework-tethering + "framework-tethering.impl", "service-connectivity-pre-jarjar", "service-nearby-pre-jarjar", "ServiceConnectivityResources", diff --git a/service/Android.bp b/service/Android.bp index 98bbbacb3e..224fa19bc1 100644 --- a/service/Android.bp +++ b/service/Android.bp @@ -157,7 +157,9 @@ java_library { // against the implementation because the two libraries are in the same // APEX. "framework-connectivity-t.stubs.module_lib", - "framework-tethering", + // TODO: figure out why just using "framework-tethering" uses the stubs, even though both + // service-connectivity and framework-tethering are in the same APEX. + "framework-tethering.impl", "framework-wifi", "unsupportedappusage", "ServiceConnectivityResources", @@ -166,6 +168,7 @@ java_library { static_libs: [ // Do not add libs here if they are already included // in framework-connectivity + "androidx.annotation_annotation", "connectivity-net-module-utils-bpf", "connectivity_native_aidl_interface-lateststable-java", "dnsresolver_aidl_interface-V9-java", @@ -258,7 +261,7 @@ java_defaults { "framework-annotations-lib", "framework-connectivity.impl", "framework-connectivity-t.impl", - "framework-tethering", + "framework-tethering.impl", "framework-wifi", "libprotobuf-java-nano", ], diff --git a/service/src/com/android/server/ConnectivityService.java b/service/src/com/android/server/ConnectivityService.java index d547d838ae..e3e12fd6b2 100755 --- a/service/src/com/android/server/ConnectivityService.java +++ b/service/src/com/android/server/ConnectivityService.java @@ -286,6 +286,7 @@ import com.android.server.connectivity.ProfileNetworkPreferenceInfo; import com.android.server.connectivity.ProxyTracker; import com.android.server.connectivity.QosCallbackTracker; import com.android.server.connectivity.UidRangeUtils; +import com.android.server.connectivity.wear.CompanionDeviceManagerProxyService; import libcore.io.IoUtils; @@ -435,6 +436,7 @@ public class ConnectivityService extends IConnectivityManager.Stub */ @GuardedBy("mTNSLock") private TestNetworkService mTNS; + private final CompanionDeviceManagerProxyService mCdmps; private final Object mTNSLock = new Object(); @@ -1586,6 +1588,12 @@ public class ConnectivityService extends IConnectivityManager.Stub mIngressRateLimit = ConnectivitySettingsManager.getIngressRateLimitInBytesPerSecond( mContext); + + if (SdkLevel.isAtLeastT()) { + mCdmps = new CompanionDeviceManagerProxyService(context); + } else { + mCdmps = null; + } } /** @@ -11491,4 +11499,10 @@ public class ConnectivityService extends IConnectivityManager.Stub mBpfNetMaps.replaceUidChain(chain, uids); } + + @Override + public IBinder getCompanionDeviceManagerProxyService() { + enforceNetworkStackPermission(mContext); + return mCdmps; + } } diff --git a/service/src/com/android/server/connectivity/wear/CompanionDeviceManagerProxyService.java b/service/src/com/android/server/connectivity/wear/CompanionDeviceManagerProxyService.java new file mode 100644 index 0000000000..7e1cf5c9c4 --- /dev/null +++ b/service/src/com/android/server/connectivity/wear/CompanionDeviceManagerProxyService.java @@ -0,0 +1,55 @@ +/* + * 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.wear; + +import android.companion.AssociationInfo; +import android.companion.CompanionDeviceManager; +import android.content.Context; +import android.net.wear.ICompanionDeviceManagerProxy; +import android.os.Binder; +import android.os.Build; + +import androidx.annotation.RequiresApi; + +import com.android.net.module.util.PermissionUtils; + +import java.util.List; + +/** + * A proxy for {@link CompanionDeviceManager}, for use by Tethering with NetworkStack permissions. + */ +public class CompanionDeviceManagerProxyService extends ICompanionDeviceManagerProxy.Stub { + private final Context mContext; + + @RequiresApi(Build.VERSION_CODES.TIRAMISU) + public CompanionDeviceManagerProxyService(Context context) { + mContext = context; + } + + @Override + public List<AssociationInfo> getAllAssociations() { + PermissionUtils.enforceNetworkStackPermission(mContext); + final long token = Binder.clearCallingIdentity(); + try { + final CompanionDeviceManager cdm = mContext.getSystemService( + CompanionDeviceManager.class); + return cdm.getAllAssociations(); + } finally { + Binder.restoreCallingIdentity(token); + } + } +} -- GitLab