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
This commit is contained in:
@@ -23,6 +23,7 @@
|
||||
#include <atomic>
|
||||
#include <fcntl.h>
|
||||
#include <inttypes.h>
|
||||
#include <mutex>
|
||||
#include <stdio.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
@@ -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<const char16_t*>(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<String16>& args)
|
||||
status_t dump(int fd, const Vector<String16>& 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(
|
||||
|
||||
Reference in New Issue
Block a user