summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteven Moreland <smoreland@google.com>2021-08-27 14:31:14 -0700
committerSteven Moreland <smoreland@google.com>2021-08-30 10:06:05 -0700
commitf3ed806737b67d1220944145f458eb364d47bacc (patch)
treeb6b1a771f1f9cee232b843fcf0d2828e9d2c37c4
parentf3af176ff16d9faf0e5198d55f0fa7c9c9daf372 (diff)
downloadnative-f3ed806737b67d1220944145f458eb364d47bacc.tar.gz
libbinder_ndk: allow disabling interface token
For compatibility with Java interfaces which don't use interface tokens. Test: CtsNdkBinderTestCases Bug: 188022639 Change-Id: I77642427993f37971b4b5b5928fc4a3688f17e42
-rw-r--r--libs/binder/ndk/ibinder.cpp13
-rw-r--r--libs/binder/ndk/ibinder_internal.h3
-rw-r--r--libs/binder/ndk/include_ndk/android/binder_ibinder.h15
-rw-r--r--libs/binder/ndk/libbinder_ndk.map.txt5
4 files changed, 34 insertions, 2 deletions
diff --git a/libs/binder/ndk/ibinder.cpp b/libs/binder/ndk/ibinder.cpp
index 11e9fc5d7b..23db59e238 100644
--- a/libs/binder/ndk/ibinder.cpp
+++ b/libs/binder/ndk/ibinder.cpp
@@ -172,7 +172,7 @@ status_t ABBinder::dump(int fd, const ::android::Vector<String16>& args) {
status_t ABBinder::onTransact(transaction_code_t code, const Parcel& data, Parcel* reply,
binder_flags_t flags) {
if (isUserCommand(code)) {
- if (!data.checkInterface(this)) {
+ if (getClass()->writeHeader && !data.checkInterface(this)) {
return STATUS_BAD_TYPE;
}
@@ -354,6 +354,12 @@ void AIBinder_Class_setOnDump(AIBinder_Class* clazz, AIBinder_onDump onDump) {
clazz->onDump = onDump;
}
+void AIBinder_Class_disableInterfaceTokenHeader(AIBinder_Class* clazz) {
+ CHECK(clazz != nullptr) << "disableInterfaceTokenHeader requires non-null clazz";
+
+ clazz->writeHeader = false;
+}
+
void AIBinder_Class_setHandleShellCommand(AIBinder_Class* clazz,
AIBinder_handleShellCommand handleShellCommand) {
CHECK(clazz != nullptr) << "setHandleShellCommand requires non-null clazz";
@@ -606,7 +612,10 @@ binder_status_t AIBinder_prepareTransaction(AIBinder* binder, AParcel** in) {
*in = new AParcel(binder);
(*in)->get()->markForBinder(binder->getBinder());
- status_t status = (*in)->get()->writeInterfaceToken(clazz->getInterfaceDescriptor());
+ status_t status = android::OK;
+ if (clazz->writeHeader) {
+ status = (*in)->get()->writeInterfaceToken(clazz->getInterfaceDescriptor());
+ }
binder_status_t ret = PruneStatusT(status);
if (ret != STATUS_OK) {
diff --git a/libs/binder/ndk/ibinder_internal.h b/libs/binder/ndk/ibinder_internal.h
index f2c69b3191..6509545da1 100644
--- a/libs/binder/ndk/ibinder_internal.h
+++ b/libs/binder/ndk/ibinder_internal.h
@@ -116,6 +116,9 @@ struct AIBinder_Class {
const ::android::String16& getInterfaceDescriptor() const { return mWideInterfaceDescriptor; }
const char* getInterfaceDescriptorUtf8() const { return mInterfaceDescriptor.c_str(); }
+ // whether a transaction header should be written
+ bool writeHeader = true;
+
// required to be non-null, implemented for every class
const AIBinder_Class_onCreate onCreate;
const AIBinder_Class_onDestroy onDestroy;
diff --git a/libs/binder/ndk/include_ndk/android/binder_ibinder.h b/libs/binder/ndk/include_ndk/android/binder_ibinder.h
index 78f2d3af14..c82df8319a 100644
--- a/libs/binder/ndk/include_ndk/android/binder_ibinder.h
+++ b/libs/binder/ndk/include_ndk/android/binder_ibinder.h
@@ -219,6 +219,21 @@ typedef binder_status_t (*AIBinder_onDump)(AIBinder* binder, int fd, const char*
void AIBinder_Class_setOnDump(AIBinder_Class* clazz, AIBinder_onDump onDump) __INTRODUCED_IN(29);
/**
+ * This tells users of this class not to use a transaction header. By default, libbinder_ndk users
+ * read/write transaction headers implicitly (in the SDK, this must be manually written by
+ * android.os.Parcel#writeInterfaceToken, and it is read/checked with
+ * android.os.Parcel#enforceInterface). This method is provided in order to talk to legacy code
+ * which does not write an interface token. When this is disabled, type safety is reduced, so you
+ * must have a separate way of determining the binder you are talking to is the right type. Must
+ * be called before any instance of the class is created.
+ *
+ * Available since API level 32.
+ *
+ * \param clazz class to disable interface header on.
+ */
+void AIBinder_Class_disableInterfaceTokenHeader(AIBinder_Class* clazz) __INTRODUCED_IN(32);
+
+/**
* Creates a new binder object of the appropriate class.
*
* Ownership of args is passed to this object. The lifecycle is implemented with AIBinder_incStrong
diff --git a/libs/binder/ndk/libbinder_ndk.map.txt b/libs/binder/ndk/libbinder_ndk.map.txt
index 685ebb5023..1975bdc52c 100644
--- a/libs/binder/ndk/libbinder_ndk.map.txt
+++ b/libs/binder/ndk/libbinder_ndk.map.txt
@@ -141,6 +141,11 @@ LIBBINDER_NDK31 { # introduced=31
AParcel_reset;
};
+LIBBINDER_NDK32 { # introduced=32
+ global:
+ AIBinder_Class_disableInterfaceTokenHeader;
+};
+
LIBBINDER_NDK_PLATFORM {
global:
AParcel_getAllowFds;