From 192e4b0289521fbf39500faa98dd86461ad9438d Mon Sep 17 00:00:00 2001 From: Kangping Dong Date: Wed, 25 Oct 2023 20:34:21 +0800 Subject: [PATCH] [Thread] add ServiceManagerWrapper Add a JNI wrapper of the NDK version of the ServiceManager which allows us to retrieve the ot-daemon lazy service. Bug: 262683651 Test: atest CtsThreadNetworkTestCases Change-Id: I1d331d1ba06c2b88f156622d4ae864dae7b15dc3 --- service/Android.bp | 8 ++++ ...m_android_server_ServiceManagerWrapper.cpp | 48 +++++++++++++++++++ service/jni/onload.cpp | 5 ++ .../android/server/ServiceManagerWrapper.java | 46 ++++++++++++++++++ thread/service/Android.bp | 1 + 5 files changed, 108 insertions(+) create mode 100644 service/jni/com_android_server_ServiceManagerWrapper.cpp create mode 100644 service/src/com/android/server/ServiceManagerWrapper.java diff --git a/service/Android.bp b/service/Android.bp index 15ae501564..38c0110ae3 100644 --- a/service/Android.bp +++ b/service/Android.bp @@ -107,11 +107,16 @@ cc_library_shared { "-Werror", "-Wno-unused-parameter", "-Wthread-safety", + + // AServiceManager_waitForService is available on only 31+, but it's still safe for Thread + // service because it's enabled on only 34+ + "-Wno-unguarded-availability", ], srcs: [ ":services.connectivity-netstats-jni-sources", "jni/com_android_server_BpfNetMaps.cpp", "jni/com_android_server_connectivity_ClatCoordinator.cpp", + "jni/com_android_server_ServiceManagerWrapper.cpp", "jni/com_android_server_TestNetworkService.cpp", "jni/onload.cpp", ], @@ -128,6 +133,7 @@ cc_library_shared { ], shared_libs: [ "libbase", + "libbinder_ndk", "libcutils", "libnetdutils", "liblog", @@ -203,6 +209,8 @@ java_library { visibility: [ "//packages/modules/Connectivity/service-t", "//packages/modules/Connectivity/tests:__subpackages__", + "//packages/modules/Connectivity/thread/service:__subpackages__", + "//packages/modules/Connectivity/thread/tests:__subpackages__", ], } diff --git a/service/jni/com_android_server_ServiceManagerWrapper.cpp b/service/jni/com_android_server_ServiceManagerWrapper.cpp new file mode 100644 index 0000000000..0cd58f4ea4 --- /dev/null +++ b/service/jni/com_android_server_ServiceManagerWrapper.cpp @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2023 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 +#include +#include +#include "nativehelper/JNIHelp.h" +#include +#include + +namespace android { +static jobject com_android_server_ServiceManagerWrapper_waitForService( + JNIEnv* env, jobject clazz, jstring serviceName) { + ScopedUtfChars name(env, serviceName); + return AIBinder_toJavaBinder(env, AServiceManager_waitForService(name.c_str())); +} + +/* + * JNI registration. + */ + +static const JNINativeMethod gMethods[] = { + /* name, signature, funcPtr */ + {"nativeWaitForService", + "(Ljava/lang/String;)Landroid/os/IBinder;", + (void*)com_android_server_ServiceManagerWrapper_waitForService}, +}; + +int register_com_android_server_ServiceManagerWrapper(JNIEnv* env) { + return jniRegisterNativeMethods(env, + "android/net/connectivity/com/android/server/ServiceManagerWrapper", + gMethods, NELEM(gMethods)); +} + +}; // namespace android diff --git a/service/jni/onload.cpp b/service/jni/onload.cpp index ed744306da..5e89ad0c80 100644 --- a/service/jni/onload.cpp +++ b/service/jni/onload.cpp @@ -26,6 +26,7 @@ int register_com_android_server_BpfNetMaps(JNIEnv* env); int register_com_android_server_connectivity_ClatCoordinator(JNIEnv* env); int register_android_server_net_NetworkStatsFactory(JNIEnv* env); int register_android_server_net_NetworkStatsService(JNIEnv* env); +int register_com_android_server_ServiceManagerWrapper(JNIEnv* env); extern "C" jint JNI_OnLoad(JavaVM* vm, void*) { JNIEnv *env; @@ -38,6 +39,10 @@ extern "C" jint JNI_OnLoad(JavaVM* vm, void*) { return JNI_ERR; } + if (register_com_android_server_ServiceManagerWrapper(env) < 0) { + return JNI_ERR; + } + if (android::modules::sdklevel::IsAtLeastT()) { if (register_com_android_server_BpfNetMaps(env) < 0) { return JNI_ERR; diff --git a/service/src/com/android/server/ServiceManagerWrapper.java b/service/src/com/android/server/ServiceManagerWrapper.java new file mode 100644 index 0000000000..6d99f333e5 --- /dev/null +++ b/service/src/com/android/server/ServiceManagerWrapper.java @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2023 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; + +import android.annotation.RequiresApi; +import android.os.IBinder; +import android.os.Build; +import android.os.ServiceManager; + +/** Provides a way to access {@link ServiceManager#waitForService} API. */ +@RequiresApi(Build.VERSION_CODES.S) +public final class ServiceManagerWrapper { + static { + System.loadLibrary("service-connectivity"); + } + + private ServiceManagerWrapper() {} + + /** + * Returns the specified service from the service manager. + * + * If the service is not running, service manager will attempt to start it, and this function + * will wait for it to be ready. + * + * @return {@code null} only if there are permission problems or fatal errors + */ + public static IBinder waitForService(String serviceName) { + return nativeWaitForService(serviceName); + } + + private static native IBinder nativeWaitForService(String serviceName); +} diff --git a/thread/service/Android.bp b/thread/service/Android.bp index f1af653f1c..fcf9521807 100644 --- a/thread/service/Android.bp +++ b/thread/service/Android.bp @@ -34,6 +34,7 @@ java_library { srcs: [":service-thread-sources"], libs: [ "framework-connectivity-t-pre-jarjar", + "service-connectivity-pre-jarjar", ], static_libs: [ "net-utils-device-common",