diff options
| author | 2019-10-11 18:40:48 -0700 | |
|---|---|---|
| committer | 2019-10-11 18:40:48 -0700 | |
| commit | 1dd86b40205be92663b300e30352e0ab049173fc (patch) | |
| tree | 65480e8dfad1e1fef15837e45ed198749d190674 | |
| parent | 280ea75aca065144650cd069a23997267a589b35 (diff) | |
| parent | 6fd2b9e8e5ba69e4413b15d4aa9257e68c3c9aba (diff) | |
Merge "Made libbinder's waitForService accessible in java" am: 3ef1b5e544 am: fa830219cd am: 6b8cef41e5
am: 6fd2b9e8e5
Change-Id: If28614029aa7ba2f5ce4358bcd47db3f316c236a
| -rw-r--r-- | core/java/android/os/Binder.java | 9 | ||||
| -rw-r--r-- | core/jni/android_util_Binder.cpp | 28 |
2 files changed, 36 insertions, 1 deletions
diff --git a/core/java/android/os/Binder.java b/core/java/android/os/Binder.java index 2c9333bc1a7c..ef3afabfe878 100644 --- a/core/java/android/os/Binder.java +++ b/core/java/android/os/Binder.java @@ -1085,4 +1085,13 @@ public class Binder implements IBinder { StrictMode.clearGatheredViolations(); return res; } + + /** + * Returns the specified service from servicemanager. If the service is not running, + * servicemanager will attempt to start it, and this function will wait for it to be ready. + * Returns nullptr only if there are permission problems or fatal errors. + * @hide + */ + public static final native @Nullable IBinder waitForService(@NonNull String serviceName) + throws RemoteException; } diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp index e406e2257c67..22323931e94c 100644 --- a/core/jni/android_util_Binder.cpp +++ b/core/jni/android_util_Binder.cpp @@ -992,6 +992,31 @@ static void android_os_Binder_blockUntilThreadAvailable(JNIEnv* env, jobject cla return IPCThreadState::self()->blockUntilThreadAvailable(); } +static jobject android_os_Binder_waitForService( + JNIEnv *env, + jclass /* clazzObj */, + jstring serviceNameObj) { + + const jchar* serviceName = env->GetStringCritical(serviceNameObj, nullptr); + if (!serviceName) { + signalExceptionForError(env, nullptr, BAD_VALUE, true /*canThrowRemoteException*/); + return nullptr; + } + String16 nameCopy = String16(reinterpret_cast<const char16_t *>(serviceName), + env->GetStringLength(serviceNameObj)); + env->ReleaseStringCritical(serviceNameObj, serviceName); + + auto sm = android::defaultServiceManager(); + sp<IBinder> service = sm->waitForService(nameCopy); + + if (!service) { + signalExceptionForError(env, nullptr, NAME_NOT_FOUND, true /*canThrowRemoteException*/); + return nullptr; + } + + return javaObjectForIBinder(env, service); +} + // ---------------------------------------------------------------------------- static const JNINativeMethod gBinderMethods[] = { @@ -1019,7 +1044,8 @@ static const JNINativeMethod gBinderMethods[] = { { "flushPendingCommands", "()V", (void*)android_os_Binder_flushPendingCommands }, { "getNativeBBinderHolder", "()J", (void*)android_os_Binder_getNativeBBinderHolder }, { "getNativeFinalizer", "()J", (void*)android_os_Binder_getNativeFinalizer }, - { "blockUntilThreadAvailable", "()V", (void*)android_os_Binder_blockUntilThreadAvailable } + { "blockUntilThreadAvailable", "()V", (void*)android_os_Binder_blockUntilThreadAvailable }, + { "waitForService", "(Ljava/lang/String;)Landroid/os/IBinder;", (void*)android_os_Binder_waitForService } }; const char* const kBinderPathName = "android/os/Binder"; |