Merge "Update for namespaced services in hwservicemanager."

This commit is contained in:
Treehugger Robot
2016-11-08 21:10:06 +00:00
committed by Gerrit Code Review
2 changed files with 64 additions and 57 deletions

View File

@@ -16,6 +16,7 @@
package android.os; package android.os;
import java.util.ArrayList;
import libcore.util.NativeAllocationRegistry; import libcore.util.NativeAllocationRegistry;
/** @hide */ /** @hide */
@@ -39,10 +40,12 @@ public abstract class HwBinder implements IHwBinder {
int code, HwParcel request, HwParcel reply, int flags); int code, HwParcel request, HwParcel reply, int flags);
public native final void registerService( public native final void registerService(
String serviceName, int versionMajor, int versionMinor); ArrayList<String> interfaceChain,
String serviceName);
public static native final IHwBinder getService( public static native final IHwBinder getService(
String serviceName, int versionMajor, int versionMinor); String iface,
String serviceName);
// Returns address of the "freeFunction". // Returns address of the "freeFunction".
private static native final long native_init(); private static native final long native_init();

View File

@@ -34,6 +34,8 @@
#include "core_jni_helpers.h" #include "core_jni_helpers.h"
using android::AndroidRuntime; using android::AndroidRuntime;
using android::hardware::hidl_vec;
using android::hardware::hidl_string;
#define PACKAGE_PATH "android/os" #define PACKAGE_PATH "android/os"
#define CLASS_NAME "HwBinder" #define CLASS_NAME "HwBinder"
@@ -41,10 +43,15 @@ using android::AndroidRuntime;
namespace android { namespace android {
static jclass gArrayListClass;
static struct {
jmethodID size;
jmethodID get;
} gArrayListMethods;
static struct fields_t { static struct fields_t {
jfieldID contextID; jfieldID contextID;
jmethodID onTransactID; jmethodID onTransactID;
} gFields; } gFields;
// static // static
@@ -199,45 +206,46 @@ static void JHwBinder_native_transact(
static void JHwBinder_native_registerService( static void JHwBinder_native_registerService(
JNIEnv *env, JNIEnv *env,
jobject thiz, jobject thiz,
jstring serviceNameObj, jobject interfaceChainArrayList,
jint versionMajor, jstring serviceNameObj) {
jint versionMinor) {
if (serviceNameObj == NULL) { if (serviceNameObj == NULL) {
jniThrowException(env, "java/lang/NullPointerException", NULL); jniThrowException(env, "java/lang/NullPointerException", NULL);
return; return;
} }
if (versionMajor < 0 const char *serviceName = env->GetStringUTFChars(serviceNameObj, NULL);
|| versionMajor > 65535
|| versionMinor < 0
|| versionMinor > 65535) {
jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
return;
}
const jchar *serviceName = env->GetStringCritical(serviceNameObj, NULL);
if (serviceName == NULL) { if (serviceName == NULL) {
return; // XXX exception already pending? 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];
const IServiceManager::Version kVersion { for (jint i = 0; i < numInterfaces; i++) {
.major = static_cast<uint16_t>(versionMajor), jstring strObj = static_cast<jstring>(
.minor = static_cast<uint16_t>(versionMinor), env->CallObjectMethod(interfaceChainArrayList,
}; gArrayListMethods.get,
i)
);
const char * str = env->GetStringUTFChars(strObj, nullptr);
strings[i] = hidl_string(str);
env->ReleaseStringUTFChars(strObj, str);
}
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); sp<hardware::IBinder> binder = JHwBinder::GetNativeContext(env, thiz);
bool ok = hardware::defaultServiceManager()->add( bool ok = hardware::defaultServiceManager()->add(
String8(String16( interfaceChain,
reinterpret_cast<const char16_t *>(serviceName), serviceName,
env->GetStringLength(serviceNameObj))).string(), binder);
binder,
kVersion);
env->ReleaseStringCritical(serviceNameObj, serviceName); env->ReleaseStringUTFChars(serviceNameObj, serviceName);
serviceName = NULL; serviceName = NULL;
if (ok) { if (ok) {
@@ -251,52 +259,43 @@ static void JHwBinder_native_registerService(
static jobject JHwBinder_native_getService( static jobject JHwBinder_native_getService(
JNIEnv *env, JNIEnv *env,
jclass /* clazzObj */, jclass /* clazzObj */,
jstring serviceNameObj, jstring ifaceNameObj,
jint versionMajor, jstring serviceNameObj) {
jint versionMinor) {
if (ifaceNameObj == NULL) {
jniThrowException(env, "java/lang/NullPointerException", NULL);
return NULL;
}
if (serviceNameObj == NULL) { if (serviceNameObj == NULL) {
jniThrowException(env, "java/lang/NullPointerException", NULL); jniThrowException(env, "java/lang/NullPointerException", NULL);
return NULL; return NULL;
} }
if (versionMajor < 0 const char *ifaceName = env->GetStringUTFChars(ifaceNameObj, NULL);
|| versionMajor > 65535 if (ifaceName == NULL) {
|| versionMinor < 0 return NULL; // XXX exception already pending?
|| versionMinor > 65535) {
jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
return NULL;
} }
const char *serviceName = env->GetStringUTFChars(serviceNameObj, NULL);
const jchar *serviceName = env->GetStringCritical(serviceNameObj, NULL);
if (serviceName == NULL) { if (serviceName == NULL) {
env->ReleaseStringUTFChars(ifaceNameObj, ifaceName);
return NULL; // XXX exception already pending? 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 '" LOG(INFO) << "looking for service '"
<< String8(String16( << serviceName
reinterpret_cast<const char16_t *>(serviceName),
env->GetStringLength(serviceNameObj))).string()
<< "'"; << "'";
sp<hardware::IBinder> service; sp<hardware::IBinder> service;
hardware::defaultServiceManager()->get( hardware::defaultServiceManager()->get(
String8(String16( ifaceName,
reinterpret_cast<const char16_t *>(serviceName), serviceName,
env->GetStringLength(serviceNameObj))).string(),
kVersion,
[&service](sp<hardware::IBinder> out) { [&service](sp<hardware::IBinder> out) {
service = out; service = out;
}); });
env->ReleaseStringCritical(serviceNameObj, serviceName); env->ReleaseStringUTFChars(ifaceNameObj, ifaceName);
ifaceName = NULL;
env->ReleaseStringUTFChars(serviceNameObj, serviceName);
serviceName = NULL; serviceName = NULL;
if (service == NULL) { if (service == NULL) {
@@ -318,16 +317,21 @@ static JNINativeMethod gMethods[] = {
"(IL" PACKAGE_PATH "/HwParcel;L" PACKAGE_PATH "/HwParcel;I)V", "(IL" PACKAGE_PATH "/HwParcel;L" PACKAGE_PATH "/HwParcel;I)V",
(void *)JHwBinder_native_transact }, (void *)JHwBinder_native_transact },
{ "registerService", "(Ljava/lang/String;II)V", { "registerService", "(Ljava/util/ArrayList;Ljava/lang/String;)V",
(void *)JHwBinder_native_registerService }, (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 }, (void *)JHwBinder_native_getService },
}; };
namespace android { namespace android {
int register_android_os_HwBinder(JNIEnv *env) { 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)); return RegisterMethodsOrDie(env, CLASS_PATH, gMethods, NELEM(gMethods));
} }