summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Jon Spivack <spivack@google.com> 2019-10-09 17:23:00 -0700
committer Jon Spivack <spivack@google.com> 2019-10-11 15:15:02 -0700
commit9e45fde5e98aea91465e0e7e2b64ec5afa535f6b (patch)
treede9fd5b5993646c4acb7acd54641b68faf7e3a0b
parent685d950fdfb3c7a270e47fe03c5dc68607f2ce5c (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.java9
-rw-r--r--core/jni/android_util_Binder.cpp28
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";