diff options
| author | 2019-10-09 17:23:00 -0700 | |
|---|---|---|
| committer | 2019-10-11 15:15:02 -0700 | |
| commit | 9e45fde5e98aea91465e0e7e2b64ec5afa535f6b (patch) | |
| tree | de9fd5b5993646c4acb7acd54641b68faf7e3a0b | |
| parent | 685d950fdfb3c7a270e47fe03c5dc68607f2ce5c (diff) | |
Made libbinder's waitForService accessible in java
waitForService is used to lazily start AIDL services
Bug: 138756857
Test: Manual (tested starting gsiservice with this function)
Change-Id: I7ff16b014052d3845bd4b1baa8fc9843e7975a16
| -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 6178b2bf5817..357c0c97b22c 100644 --- a/core/java/android/os/Binder.java +++ b/core/java/android/os/Binder.java @@ -1063,4 +1063,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 0afbaa0e174c..fe7e508872ab 100644 --- a/core/jni/android_util_Binder.cpp +++ b/core/jni/android_util_Binder.cpp @@ -989,6 +989,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[] = { @@ -1016,7 +1041,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"; |