libbinder_ndk: Add C++ wrapper code.

This library wraps libbinder_ndk with types similar to those found in
libbinder. This makes implementations more familiar and reduces the
amount of auto-generated code that has to be repeated in AIDL.

In order to simplify the distribution of the this code, it is
header-only in the NDK headers. This allows NDK users to use AIDL
against the NDK with no additional dependencies.

Bug: 112664205
Test: atest android.binder.cts

Change-Id: I6e6ef646226d474d538639f740e340c4e37fa7f7
diff --git a/libs/binder/ndk/include_ndk/android/binder_auto_utils.h b/libs/binder/ndk/include_ndk/android/binder_auto_utils.h
new file mode 100644
index 0000000..11b1e8e
--- /dev/null
+++ b/libs/binder/ndk/include_ndk/android/binder_auto_utils.h
@@ -0,0 +1,234 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @addtogroup NdkBinder
+ * @{
+ */
+
+/**
+ * @file binder_auto_utils.h
+ * @brief These objects provide a more C++-like thin interface to the .
+ */
+
+#pragma once
+
+#include <android/binder_ibinder.h>
+#include <android/binder_parcel.h>
+#include <android/binder_status.h>
+
+#ifdef __cplusplus
+
+#include <cstddef>
+
+namespace android {
+
+/**
+ * Represents one strong pointer to an AIBinder object.
+ */
+class AutoAIBinder {
+public:
+    /**
+     * Takes ownership of one strong refcount of binder.
+     */
+    explicit AutoAIBinder(AIBinder* binder = nullptr) : mBinder(binder) {}
+
+    /**
+     * Convenience operator for implicitly constructing an AutoAIBinder from nullptr. This is not
+     * explicit because it is not taking ownership of anything.
+     */
+    AutoAIBinder(std::nullptr_t) : AutoAIBinder() {}
+
+    /**
+     * This will delete the underlying object if it exists. See operator=.
+     */
+    AutoAIBinder(const AutoAIBinder& other) { *this = other; }
+
+    /**
+     * This deletes the underlying object if it exists. See set.
+     */
+    ~AutoAIBinder() { set(nullptr); }
+
+    /**
+     * This takes ownership of a binder from another AIBinder object but it does not affect the
+     * ownership of that other object.
+     */
+    AutoAIBinder& operator=(const AutoAIBinder& other) {
+        AIBinder_incStrong(other.mBinder);
+        set(other.mBinder);
+        return *this;
+    }
+
+    /**
+     * Takes ownership of one strong refcount of binder
+     */
+    void set(AIBinder* binder) {
+        if (mBinder != nullptr) AIBinder_decStrong(mBinder);
+        mBinder = binder;
+    }
+
+    /**
+     * This returns the underlying binder object for transactions. If it is used to create another
+     * AutoAIBinder object, it should first be incremented.
+     */
+    AIBinder* get() const { return mBinder; }
+
+    /**
+     * This allows the value in this class to be set from beneath it. If you call this method and
+     * then change the value of T*, you must take ownership of the value you are replacing and add
+     * ownership to the object that is put in here.
+     *
+     * Recommended use is like this:
+     *   AutoAIBinder a;  // will be nullptr
+     *   SomeInitFunction(a.getR());  // value is initialized with refcount
+     *
+     * Other usecases are discouraged.
+     *
+     */
+    AIBinder** getR() { return &mBinder; }
+
+private:
+    AIBinder* mBinder = nullptr;
+};
+
+/**
+ * This baseclass owns a single object, used to make various classes RAII.
+ */
+template <typename T, void (*Destroy)(T*)>
+class AutoA {
+public:
+    /**
+     * Takes ownership of t.
+     */
+    explicit AutoA(T* t = nullptr) : mT(t) {}
+
+    /**
+     * This deletes the underlying object if it exists. See set.
+     */
+    ~AutoA() { set(nullptr); }
+
+    /**
+     * Takes ownership of t.
+     */
+    void set(T* t) {
+        Destroy(mT);
+        mT = t;
+    }
+
+    /**
+     * This returns the underlying object to be modified but does not affect ownership.
+     */
+    T* get() { return mT; }
+
+    /**
+     * This returns the const underlying object but does not affect ownership.
+     */
+    const T* get() const { return mT; }
+
+    /**
+     * This allows the value in this class to be set from beneath it. If you call this method and
+     * then change the value of T*, you must take ownership of the value you are replacing and add
+     * ownership to the object that is put in here.
+     *
+     * Recommended use is like this:
+     *   AutoA<T> a; // will be nullptr
+     *   SomeInitFunction(a.getR()); // value is initialized with refcount
+     *
+     * Other usecases are discouraged.
+     *
+     */
+    T** getR() { return &mT; }
+
+    // copy-constructing, or move/copy assignment is disallowed
+    AutoA(const AutoA&) = delete;
+    AutoA& operator=(const AutoA&) = delete;
+    AutoA& operator=(AutoA&&) = delete;
+
+    // move-constructing is okay
+    AutoA(AutoA&&) = default;
+
+private:
+    T* mT;
+};
+
+/**
+ * Convenience wrapper. See AParcel.
+ */
+class AutoAParcel : public AutoA<AParcel, AParcel_delete> {
+public:
+    /**
+     * Takes ownership of a.
+     */
+    explicit AutoAParcel(AParcel* a = nullptr) : AutoA(a) {}
+    ~AutoAParcel() {}
+    AutoAParcel(AutoAParcel&&) = default;
+};
+
+/**
+ * Convenience wrapper. See AStatus.
+ */
+class AutoAStatus : public AutoA<AStatus, AStatus_delete> {
+public:
+    /**
+     * Takes ownership of a.
+     */
+    explicit AutoAStatus(AStatus* a = nullptr) : AutoA(a) {}
+    ~AutoAStatus() {}
+    AutoAStatus(AutoAStatus&&) = default;
+
+    /**
+     * See AStatus_isOk.
+     */
+    bool isOk() { return get() != nullptr && AStatus_isOk(get()); }
+};
+
+/**
+ * Convenience wrapper. See AIBinder_DeathRecipient.
+ */
+class AutoAIBinder_DeathRecipient
+      : public AutoA<AIBinder_DeathRecipient, AIBinder_DeathRecipient_delete> {
+public:
+    /**
+     * Takes ownership of a.
+     */
+    explicit AutoAIBinder_DeathRecipient(AIBinder_DeathRecipient* a = nullptr) : AutoA(a) {}
+    ~AutoAIBinder_DeathRecipient() {}
+    AutoAIBinder_DeathRecipient(AutoAIBinder_DeathRecipient&&) = default;
+};
+
+/**
+ * Convenience wrapper. See AIBinder_Weak.
+ */
+class AutoAIBinder_Weak : public AutoA<AIBinder_Weak, AIBinder_Weak_delete> {
+public:
+    /**
+     * Takes ownership of a.
+     */
+    explicit AutoAIBinder_Weak(AIBinder_Weak* a = nullptr) : AutoA(a) {}
+    ~AutoAIBinder_Weak() {}
+    AutoAIBinder_Weak(AutoAIBinder_Weak&&) = default;
+
+    /**
+     * See AIBinder_Weak_promote.
+     */
+    AutoAIBinder promote() { return AutoAIBinder(AIBinder_Weak_promote(get())); }
+};
+
+} // namespace android
+
+#endif // __cplusplus
+
+/** @} */
diff --git a/libs/binder/ndk/include_ndk/android/binder_interface_utils.h b/libs/binder/ndk/include_ndk/android/binder_interface_utils.h
new file mode 100644
index 0000000..d7e1566
--- /dev/null
+++ b/libs/binder/ndk/include_ndk/android/binder_interface_utils.h
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @addtogroup NdkBinder
+ * @{
+ */
+
+/**
+ * @file binder_interface_utils.h
+ * @brief This provides common C++ classes for common operations and as base classes for C++
+ * interfaces.
+ */
+
+#pragma once
+
+#include <android/binder_auto_utils.h>
+#include <android/binder_ibinder.h>
+
+#ifdef __cplusplus
+
+#include <memory>
+#include <mutex>
+
+namespace android {
+
+// analog using std::shared_ptr for RefBase-like semantics
+class SharedRefBase {
+public:
+    SharedRefBase() {}
+    virtual ~SharedRefBase() {}
+
+    std::shared_ptr<SharedRefBase> ref() {
+        std::shared_ptr<SharedRefBase> thiz = mThis.lock();
+
+        std::call_once(mFlagThis, [&]() { mThis = thiz = std::shared_ptr<SharedRefBase>(this); });
+
+        return thiz;
+    }
+
+    template <typename CHILD>
+    std::shared_ptr<CHILD> ref() {
+        return std::static_pointer_cast<CHILD>(ref());
+    }
+
+private:
+    std::once_flag mFlagThis;
+    std::weak_ptr<SharedRefBase> mThis;
+};
+
+// wrapper analog to IInterface
+class ICInterface : public SharedRefBase {
+public:
+    ICInterface() {}
+    virtual ~ICInterface() {}
+
+    // This either returns the single existing implementation or creates a new implementation.
+    virtual AutoAIBinder asBinder() = 0;
+};
+
+// wrapper analog to BnInterface
+template <typename INTERFACE>
+class BnCInterface : public INTERFACE {
+public:
+    BnCInterface() {}
+    virtual ~BnCInterface() {}
+
+    AutoAIBinder asBinder() override;
+
+protected:
+    // This function should only be called by asBinder. Otherwise, there is a possibility of
+    // multiple AIBinder* objects being created for the same instance of an object.
+    virtual AutoAIBinder createBinder() = 0;
+
+private:
+    std::mutex mMutex; // for asBinder
+    AutoAIBinder_Weak mWeakBinder;
+};
+
+// wrapper analog to BpInterfae
+template <typename INTERFACE>
+class BpCInterface : public INTERFACE {
+public:
+    BpCInterface(const AutoAIBinder& binder) : mBinder(binder) {}
+    virtual ~BpCInterface() {}
+
+    AutoAIBinder asBinder() override;
+
+private:
+    AutoAIBinder mBinder;
+};
+
+template <typename INTERFACE>
+AutoAIBinder BnCInterface<INTERFACE>::asBinder() {
+    std::lock_guard<std::mutex> l(mMutex);
+
+    AutoAIBinder binder;
+    if (mWeakBinder.get() != nullptr) {
+        binder.set(AIBinder_Weak_promote(mWeakBinder.get()));
+    }
+    if (binder.get() == nullptr) {
+        binder = createBinder();
+        mWeakBinder.set(AIBinder_Weak_new(binder.get()));
+    }
+
+    return binder;
+}
+
+template <typename INTERFACE>
+AutoAIBinder BpCInterface<INTERFACE>::asBinder() {
+    return mBinder;
+}
+
+#endif // __cplusplus
+
+} // namespace android
+
+/** @} */
diff --git a/libs/binder/ndk/test/main_client.cpp b/libs/binder/ndk/test/main_client.cpp
index 3fc096a..22bf1e5 100644
--- a/libs/binder/ndk/test/main_client.cpp
+++ b/libs/binder/ndk/test/main_client.cpp
@@ -131,3 +131,6 @@
     EXPECT_EQ(STATUS_OK, foo->addService(kInstanceName2));
     EXPECT_EQ(IFoo::getService(kInstanceName1), IFoo::getService(kInstanceName2));
 }
+
+#include <android/binder_auto_utils.h>
+#include <android/binder_interface_utils.h>