Merge changes from topic "b127336441"

* changes:
  libbinder_ndk: Fix 'isRemote' value for Bn*.
  libbinder_ndk: define userdata class in headers
diff --git a/libs/binder/ndk/include_ndk/android/binder_interface_utils.h b/libs/binder/ndk/include_ndk/android/binder_interface_utils.h
index b82141c..83a1048 100644
--- a/libs/binder/ndk/include_ndk/android/binder_interface_utils.h
+++ b/libs/binder/ndk/include_ndk/android/binder_interface_utils.h
@@ -106,28 +106,37 @@
     virtual bool isRemote() = 0;
 
     /**
-     * Dumps information about the interface.
+     * Dumps information about the interface. By default, dumps nothing.
      */
-    virtual binder_status_t dump(int /*fd*/, const char** /*args*/, uint32_t /*numArgs*/) {
-        return STATUS_OK;
-    }
+    virtual inline binder_status_t dump(int /*fd*/, const char** /*args*/, uint32_t /*numArgs*/);
+
+    /**
+     * Interprets this binder as this underlying interface if this has stored an ICInterface in the
+     * binder's user data.
+     *
+     * This does not do type checking and should only be used when the binder is known to originate
+     * from ICInterface. Most likely, you want to use I*::fromBinder.
+     */
+    static inline std::shared_ptr<ICInterface> asInterface(AIBinder* binder);
 
     /**
      * Helper method to create a class
      */
-    static AIBinder_Class* defineClass(const char* interfaceDescriptor,
-                                       AIBinder_Class_onCreate onCreate,
-                                       AIBinder_Class_onDestroy onDestroy,
-                                       AIBinder_Class_onTransact onTransact,
-                                       AIBinder_onDump onDump = nullptr) {
-        AIBinder_Class* clazz =
-                AIBinder_Class_define(interfaceDescriptor, onCreate, onDestroy, onTransact);
-        if (clazz == nullptr) {
-            return nullptr;
-        }
-        AIBinder_Class_setOnDump(clazz, onDump);
-        return clazz;
-    }
+    static inline AIBinder_Class* defineClass(const char* interfaceDescriptor,
+                                              AIBinder_Class_onTransact onTransact);
+
+   private:
+    class ICInterfaceData {
+       public:
+        std::shared_ptr<ICInterface> interface;
+
+        static inline std::shared_ptr<ICInterface> getInterface(AIBinder* binder);
+
+        static inline void* onCreate(void* args);
+        static inline void onDestroy(void* userData);
+        static inline binder_status_t onDump(AIBinder* binder, int fd, const char** args,
+                                             uint32_t numArgs);
+    };
 };
 
 /**
@@ -141,7 +150,7 @@
 
     SpAIBinder asBinder() override;
 
-    bool isRemote() override { return true; }
+    bool isRemote() override { return false; }
 
    protected:
     /**
@@ -176,6 +185,55 @@
     SpAIBinder mBinder;
 };
 
+// END OF CLASS DECLARATIONS
+
+binder_status_t ICInterface::dump(int /*fd*/, const char** /*args*/, uint32_t /*numArgs*/) {
+    return STATUS_OK;
+}
+
+std::shared_ptr<ICInterface> ICInterface::asInterface(AIBinder* binder) {
+    return ICInterfaceData::getInterface(binder);
+}
+
+AIBinder_Class* ICInterface::defineClass(const char* interfaceDescriptor,
+                                         AIBinder_Class_onTransact onTransact) {
+    AIBinder_Class* clazz = AIBinder_Class_define(interfaceDescriptor, ICInterfaceData::onCreate,
+                                                  ICInterfaceData::onDestroy, onTransact);
+    if (clazz == nullptr) {
+        return nullptr;
+    }
+
+    // We can't know if this method is overriden by a subclass interface, so we must register
+    // ourselves. The default (nothing to dump) is harmless.
+    AIBinder_Class_setOnDump(clazz, ICInterfaceData::onDump);
+    return clazz;
+}
+
+std::shared_ptr<ICInterface> ICInterface::ICInterfaceData::getInterface(AIBinder* binder) {
+    if (binder == nullptr) return nullptr;
+
+    void* userData = AIBinder_getUserData(binder);
+    if (userData == nullptr) return nullptr;
+
+    return static_cast<ICInterfaceData*>(userData)->interface;
+}
+
+void* ICInterface::ICInterfaceData::onCreate(void* args) {
+    std::shared_ptr<ICInterface> interface = static_cast<ICInterface*>(args)->ref<ICInterface>();
+    ICInterfaceData* data = new ICInterfaceData{interface};
+    return static_cast<void*>(data);
+}
+
+void ICInterface::ICInterfaceData::onDestroy(void* userData) {
+    delete static_cast<ICInterfaceData*>(userData);
+}
+
+binder_status_t ICInterface::ICInterfaceData::onDump(AIBinder* binder, int fd, const char** args,
+                                                     uint32_t numArgs) {
+    std::shared_ptr<ICInterface> interface = getInterface(binder);
+    return interface->dump(fd, args, numArgs);
+}
+
 template <typename INTERFACE>
 SpAIBinder BnCInterface<INTERFACE>::asBinder() {
     std::lock_guard<std::mutex> l(mMutex);