OSDN Git Service

Update for namespaced services in hwservicemanager.
authorSteven Moreland <smoreland@google.com>
Thu, 3 Nov 2016 22:17:04 +0000 (15:17 -0700)
committerSteven Moreland <smoreland@google.com>
Tue, 8 Nov 2016 16:53:16 +0000 (08:53 -0800)
Test: end to end, hidl_test_java
Bug: 31861268
Change-Id: I3e91cf8a87f9345d4ae0650e521414407c7fc780

core/java/android/os/HwBinder.java
core/jni/android_os_HwBinder.cpp

index 0e7da63..481b2dc 100644 (file)
@@ -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();
index 1a33d91..10090a1 100644 (file)
@@ -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));
 }