libbinder_ndk: allow disabling interface token

For compatibility with Java interfaces which don't use interface tokens.

Test: CtsNdkBinderTestCases
Bug: 188022639
Change-Id: I77642427993f37971b4b5b5928fc4a3688f17e42
diff --git a/libs/binder/ndk/ibinder.cpp b/libs/binder/ndk/ibinder.cpp
index 11e9fc5..23db59e 100644
--- a/libs/binder/ndk/ibinder.cpp
+++ b/libs/binder/ndk/ibinder.cpp
@@ -172,7 +172,7 @@
 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 @@
     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 @@
     *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) {