diff options
| -rw-r--r-- | core/java/android/os/HwBinder.java | 7 | ||||
| -rw-r--r-- | core/jni/android_os_HwBinder.cpp | 114 |
2 files changed, 64 insertions, 57 deletions
diff --git a/core/java/android/os/HwBinder.java b/core/java/android/os/HwBinder.java index 0e7da63a2215..481b2dc096d5 100644 --- a/core/java/android/os/HwBinder.java +++ b/core/java/android/os/HwBinder.java @@ -16,6 +16,7 @@ package android.os; +import java.util.ArrayList; import libcore.util.NativeAllocationRegistry; /** @hide */ @@ -39,10 +40,12 @@ public abstract class HwBinder implements IHwBinder { int code, HwParcel request, HwParcel reply, int flags); public native final void registerService( - String serviceName, int versionMajor, int versionMinor); + ArrayList<String> interfaceChain, + String serviceName); public static native final IHwBinder getService( - String serviceName, int versionMajor, int versionMinor); + String iface, + String serviceName); // Returns address of the "freeFunction". private static native final long native_init(); diff --git a/core/jni/android_os_HwBinder.cpp b/core/jni/android_os_HwBinder.cpp index 1a33d9111fdb..10090a1f6942 100644 --- a/core/jni/android_os_HwBinder.cpp +++ b/core/jni/android_os_HwBinder.cpp @@ -34,6 +34,8 @@ #include "core_jni_helpers.h" using android::AndroidRuntime; +using android::hardware::hidl_vec; +using android::hardware::hidl_string; #define PACKAGE_PATH "android/os" #define CLASS_NAME "HwBinder" @@ -41,10 +43,15 @@ using android::AndroidRuntime; namespace android { +static jclass gArrayListClass; +static struct { + jmethodID size; + jmethodID get; +} gArrayListMethods; + static struct fields_t { jfieldID contextID; jmethodID onTransactID; - } gFields; // static @@ -199,45 +206,46 @@ static void JHwBinder_native_transact( static void JHwBinder_native_registerService( JNIEnv *env, jobject thiz, - jstring serviceNameObj, - jint versionMajor, - jint versionMinor) { + jobject interfaceChainArrayList, + jstring serviceNameObj) { if (serviceNameObj == NULL) { jniThrowException(env, "java/lang/NullPointerException", NULL); return; } - if (versionMajor < 0 - || versionMajor > 65535 - || versionMinor < 0 - || versionMinor > 65535) { - jniThrowException(env, "java/lang/IllegalArgumentException", NULL); - return; - } - - const jchar *serviceName = env->GetStringCritical(serviceNameObj, NULL); - + const char *serviceName = env->GetStringUTFChars(serviceNameObj, NULL); if (serviceName == NULL) { return; // XXX exception already pending? } - using android::hidl::manager::V1_0::IServiceManager; + jint numInterfaces = env->CallIntMethod(interfaceChainArrayList, + gArrayListMethods.size); + hidl_string *strings = new hidl_string[numInterfaces]; + + for (jint i = 0; i < numInterfaces; i++) { + jstring strObj = static_cast<jstring>( + env->CallObjectMethod(interfaceChainArrayList, + gArrayListMethods.get, + i) + ); + const char * str = env->GetStringUTFChars(strObj, nullptr); + strings[i] = hidl_string(str); + env->ReleaseStringUTFChars(strObj, str); + } - const IServiceManager::Version kVersion { - .major = static_cast<uint16_t>(versionMajor), - .minor = static_cast<uint16_t>(versionMinor), - }; + hidl_vec<hidl_string> interfaceChain; + interfaceChain.setToExternal(strings, numInterfaces, true /* shouldOwn */); + + using android::hidl::manager::V1_0::IServiceManager; sp<hardware::IBinder> binder = JHwBinder::GetNativeContext(env, thiz); bool ok = hardware::defaultServiceManager()->add( - String8(String16( - reinterpret_cast<const char16_t *>(serviceName), - env->GetStringLength(serviceNameObj))).string(), - binder, - kVersion); + interfaceChain, + serviceName, + binder); - env->ReleaseStringCritical(serviceNameObj, serviceName); + env->ReleaseStringUTFChars(serviceNameObj, serviceName); serviceName = NULL; if (ok) { @@ -251,52 +259,43 @@ static void JHwBinder_native_registerService( static jobject JHwBinder_native_getService( JNIEnv *env, jclass /* clazzObj */, - jstring serviceNameObj, - jint versionMajor, - jint versionMinor) { - if (serviceNameObj == NULL) { + jstring ifaceNameObj, + jstring serviceNameObj) { + + if (ifaceNameObj == NULL) { jniThrowException(env, "java/lang/NullPointerException", NULL); return NULL; } - - if (versionMajor < 0 - || versionMajor > 65535 - || versionMinor < 0 - || versionMinor > 65535) { - jniThrowException(env, "java/lang/IllegalArgumentException", NULL); + if (serviceNameObj == NULL) { + jniThrowException(env, "java/lang/NullPointerException", NULL); return NULL; } - const jchar *serviceName = env->GetStringCritical(serviceNameObj, NULL); - + const char *ifaceName = env->GetStringUTFChars(ifaceNameObj, NULL); + if (ifaceName == NULL) { + return NULL; // XXX exception already pending? + } + const char *serviceName = env->GetStringUTFChars(serviceNameObj, NULL); if (serviceName == NULL) { - return NULL; // XXX exception already pending? + env->ReleaseStringUTFChars(ifaceNameObj, ifaceName); + return NULL; // XXX exception already pending? } - using android::hidl::manager::V1_0::IServiceManager; - - const IServiceManager::Version kVersion { - .major = static_cast<uint16_t>(versionMajor), - .minor = static_cast<uint16_t>(versionMinor), - }; - LOG(INFO) << "looking for service '" - << String8(String16( - reinterpret_cast<const char16_t *>(serviceName), - env->GetStringLength(serviceNameObj))).string() + << serviceName << "'"; sp<hardware::IBinder> service; hardware::defaultServiceManager()->get( - String8(String16( - reinterpret_cast<const char16_t *>(serviceName), - env->GetStringLength(serviceNameObj))).string(), - kVersion, + ifaceName, + serviceName, [&service](sp<hardware::IBinder> out) { service = out; }); - env->ReleaseStringCritical(serviceNameObj, serviceName); + env->ReleaseStringUTFChars(ifaceNameObj, ifaceName); + ifaceName = NULL; + env->ReleaseStringUTFChars(serviceNameObj, serviceName); serviceName = NULL; if (service == NULL) { @@ -318,16 +317,21 @@ static JNINativeMethod gMethods[] = { "(IL" PACKAGE_PATH "/HwParcel;L" PACKAGE_PATH "/HwParcel;I)V", (void *)JHwBinder_native_transact }, - { "registerService", "(Ljava/lang/String;II)V", + { "registerService", "(Ljava/util/ArrayList;Ljava/lang/String;)V", (void *)JHwBinder_native_registerService }, - { "getService", "(Ljava/lang/String;II)L" PACKAGE_PATH "/IHwBinder;", + { "getService", "(Ljava/lang/String;Ljava/lang/String;)L" PACKAGE_PATH "/IHwBinder;", (void *)JHwBinder_native_getService }, }; namespace android { int register_android_os_HwBinder(JNIEnv *env) { + jclass arrayListClass = FindClassOrDie(env, "java/util/ArrayList"); + gArrayListClass = MakeGlobalRefOrDie(env, arrayListClass); + gArrayListMethods.size = GetMethodIDOrDie(env, arrayListClass, "size", "()I"); + gArrayListMethods.get = GetMethodIDOrDie(env, arrayListClass, "get", "(I)Ljava/lang/Object;"); + return RegisterMethodsOrDie(env, CLASS_PATH, gMethods, NELEM(gMethods)); } |