From e52bb7df7c37c6ba33782e2b3fc04108c3024d87 Mon Sep 17 00:00:00 2001 From: Steven Moreland Date: Wed, 10 Oct 2018 11:24:58 -0700 Subject: [PATCH] JavaBBinder: implement getInterfaceDescriptor JavaBBinder previously only implemented transact (which works because it calls into Java and the Java binder will call checkInterface). However, when ibinderForJavaObject is used, the binder returned will not properly report its interface descriptor. In this CL, getInterfaceDescriptor is implemented so that this is reported correctly. Bug: 112664205 Test: atest android.binder.cts (fails without this) Change-Id: Ic8f7d202021688287edafdc27db25fc8ec2f075c --- core/jni/android_util_Binder.cpp | 37 +++++++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp index c3ba9ba828268..9341d9a48913c 100644 --- a/core/jni/android_util_Binder.cpp +++ b/core/jni/android_util_Binder.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -69,6 +70,7 @@ static struct bindernative_offsets_t // Class state. jclass mClass; jmethodID mExecTransact; + jmethodID mGetInterfaceDescriptor; // Object state. jfieldID mObject; @@ -328,8 +330,32 @@ protected: env->DeleteGlobalRef(mObject); } - virtual status_t onTransact( - uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0) + const String16& getInterfaceDescriptor() const override + { + call_once(mPopulateDescriptor, [this] { + JNIEnv* env = javavm_to_jnienv(mVM); + + ALOGV("getInterfaceDescriptor() on %p calling object %p in env %p vm %p\n", this, mObject, env, mVM); + + jstring descriptor = (jstring)env->CallObjectMethod(mObject, gBinderOffsets.mGetInterfaceDescriptor); + + if (descriptor == nullptr) { + return; + } + + static_assert(sizeof(jchar) == sizeof(char16_t), ""); + const jchar* descriptorChars = env->GetStringChars(descriptor, nullptr); + const char16_t* rawDescriptor = reinterpret_cast(descriptorChars); + jsize rawDescriptorLen = env->GetStringLength(descriptor); + mDescriptor = String16(rawDescriptor, rawDescriptorLen); + env->ReleaseStringChars(descriptor, descriptorChars); + }); + + return mDescriptor; + } + + status_t onTransact( + uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0) override { JNIEnv* env = javavm_to_jnienv(mVM); @@ -378,7 +404,7 @@ protected: return res != JNI_FALSE ? NO_ERROR : UNKNOWN_TRANSACTION; } - virtual status_t dump(int fd, const Vector& args) + status_t dump(int fd, const Vector& args) override { return 0; } @@ -386,6 +412,9 @@ protected: private: JavaVM* const mVM; jobject const mObject; // GlobalRef to Java Binder + + mutable std::once_flag mPopulateDescriptor; + mutable String16 mDescriptor; }; // ---------------------------------------------------------------------------- @@ -939,6 +968,8 @@ static int int_register_android_os_Binder(JNIEnv* env) gBinderOffsets.mClass = MakeGlobalRefOrDie(env, clazz); gBinderOffsets.mExecTransact = GetMethodIDOrDie(env, clazz, "execTransact", "(IJJI)Z"); + gBinderOffsets.mGetInterfaceDescriptor = GetMethodIDOrDie(env, clazz, "getInterfaceDescriptor", + "()Ljava/lang/String;"); gBinderOffsets.mObject = GetFieldIDOrDie(env, clazz, "mObject", "J"); return RegisterMethodsOrDie(