Merge "Initial C library for libbinder."
diff --git a/libs/binder/ndk/ABinderProcess.cpp b/libs/binder/ndk/ABinderProcess.cpp
new file mode 100644
index 0000000..c89caaf
--- /dev/null
+++ b/libs/binder/ndk/ABinderProcess.cpp
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+
+#include <android/binder_process.h>
+
+#include <mutex>
+
+#include <android-base/logging.h>
+#include <binder/IPCThreadState.h>
+
+using ::android::IPCThreadState;
+using ::android::ProcessState;
+
+void ABinderProcess_startThreadPool() {
+    ProcessState::self()->startThreadPool();
+    ProcessState::self()->giveThreadPoolName();
+}
+bool ABinderProcess_setThreadPoolMaxThreadCount(uint32_t numThreads) {
+    return ProcessState::self()->setThreadPoolMaxThreadCount(numThreads) == 0;
+}
+void ABinderProcess_joinThreadPool() {
+    IPCThreadState::self()->joinThreadPool();
+}
diff --git a/libs/binder/ndk/AIBinder.cpp b/libs/binder/ndk/AIBinder.cpp
new file mode 100644
index 0000000..d0ce98d
--- /dev/null
+++ b/libs/binder/ndk/AIBinder.cpp
@@ -0,0 +1,345 @@
+/*
+ * 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.
+ */
+
+#include <android/binder_ibinder.h>
+#include "AIBinder_internal.h"
+
+#include <android/binder_status.h>
+#include "AParcel_internal.h"
+
+#include <android-base/logging.h>
+
+using ::android::IBinder;
+using ::android::Parcel;
+using ::android::sp;
+using ::android::String16;
+using ::android::wp;
+
+AIBinder::AIBinder(const AIBinder_Class* clazz) : mClazz(clazz) {}
+AIBinder::~AIBinder() {}
+
+sp<AIBinder> AIBinder::associateClass(const AIBinder_Class* clazz) {
+    using ::android::String8;
+
+    if (clazz == nullptr) return nullptr;
+    if (mClazz == clazz) return this;
+
+    String8 newDescriptor(clazz->getInterfaceDescriptor());
+
+    if (mClazz != nullptr) {
+        String8 currentDescriptor(mClazz->getInterfaceDescriptor());
+        if (newDescriptor == currentDescriptor) {
+            LOG(ERROR) << __func__ << ": Class descriptors '" << currentDescriptor
+                       << "' match during associateClass, but they are different class objects. "
+                          "Class descriptor collision?";
+            return nullptr;
+        }
+
+        LOG(ERROR) << __func__
+                   << ": Class cannot be associated on object which already has a class. Trying to "
+                      "associate to '"
+                   << newDescriptor.c_str() << "' but already set to '" << currentDescriptor.c_str()
+                   << "'.";
+        return nullptr;
+    }
+
+    String8 descriptor(getBinder()->getInterfaceDescriptor());
+    if (descriptor != newDescriptor) {
+        LOG(ERROR) << __func__ << ": Expecting binder to have class '" << newDescriptor.c_str()
+                   << "' but descriptor is actually '" << descriptor.c_str() << "'.";
+        return nullptr;
+    }
+
+    // The descriptor matches, so if it is local, this is guaranteed to be the libbinder_ndk class.
+    // An error here can occur if there is a conflict between descriptors (two unrelated classes
+    // define the same descriptor), but this should never happen.
+
+    // if this is a local ABBinder, mClazz should be non-null
+    CHECK(asABBinder() == nullptr);
+    CHECK(asABpBinder() != nullptr);
+
+    if (!isRemote()) {
+        // ABpBinder but proxy to a local object. Therefore that local object must be an ABBinder.
+        ABBinder* binder = static_cast<ABBinder*>(getBinder().get());
+        return binder;
+    }
+
+    // This is a remote object
+    mClazz = clazz;
+
+    return this;
+}
+
+ABBinder::ABBinder(const AIBinder_Class* clazz, void* userData)
+      : AIBinder(clazz), BBinder(), mUserData(userData) {
+    CHECK(clazz != nullptr);
+}
+ABBinder::~ABBinder() {
+    getClass()->onDestroy(mUserData);
+}
+
+const String16& ABBinder::getInterfaceDescriptor() const {
+    return getClass()->getInterfaceDescriptor();
+}
+
+binder_status_t ABBinder::onTransact(transaction_code_t code, const Parcel& data, Parcel* reply,
+                                     binder_flags_t flags) {
+    if (isUserCommand(code)) {
+        if (!data.checkInterface(this)) {
+            return EX_ILLEGAL_STATE;
+        }
+
+        const AParcel in = AParcel::readOnly(this, &data);
+        AParcel out = AParcel(this, reply, false /*owns*/);
+
+        return getClass()->onTransact(this, code, &in, &out);
+    } else {
+        return BBinder::onTransact(code, data, reply, flags);
+    }
+}
+
+ABpBinder::ABpBinder(::android::sp<::android::IBinder> binder)
+      : AIBinder(nullptr /*clazz*/), BpRefBase(binder) {
+    CHECK(binder != nullptr);
+}
+ABpBinder::~ABpBinder() {}
+
+struct AIBinder_Weak {
+    wp<AIBinder> binder;
+};
+AIBinder_Weak* AIBinder_Weak_new(AIBinder* binder) {
+    if (binder == nullptr) return nullptr;
+    return new AIBinder_Weak{wp<AIBinder>(binder)};
+}
+void AIBinder_Weak_delete(AIBinder_Weak* weakBinder) {
+    delete weakBinder;
+}
+AIBinder* AIBinder_Weak_promote(AIBinder_Weak* weakBinder) {
+    if (weakBinder == nullptr) return nullptr;
+    sp<AIBinder> binder = weakBinder->binder.promote();
+    AIBinder_incStrong(binder.get());
+    return binder.get();
+}
+
+AIBinder_Class::AIBinder_Class(const char* interfaceDescriptor, AIBinder_Class_onCreate onCreate,
+                               AIBinder_Class_onDestroy onDestroy,
+                               AIBinder_Class_onTransact onTransact)
+      : onCreate(onCreate),
+        onDestroy(onDestroy),
+        onTransact(onTransact),
+        mInterfaceDescriptor(interfaceDescriptor) {}
+
+AIBinder_Class* AIBinder_Class_define(const char* interfaceDescriptor,
+                                      AIBinder_Class_onCreate onCreate,
+                                      AIBinder_Class_onDestroy onDestroy,
+                                      AIBinder_Class_onTransact onTransact) {
+    if (interfaceDescriptor == nullptr || onCreate == nullptr || onDestroy == nullptr ||
+        onTransact == nullptr) {
+        return nullptr;
+    }
+
+    return new AIBinder_Class(interfaceDescriptor, onCreate, onDestroy, onTransact);
+}
+
+AIBinder* AIBinder_new(const AIBinder_Class* clazz, void* args) {
+    if (clazz == nullptr) {
+        LOG(ERROR) << __func__ << ": Must provide class to construct local binder.";
+        return nullptr;
+    }
+
+    void* userData = clazz->onCreate(args);
+
+    AIBinder* ret = new ABBinder(clazz, userData);
+    AIBinder_incStrong(ret);
+    return ret;
+}
+
+bool AIBinder_isRemote(AIBinder* binder) {
+    if (binder == nullptr) {
+        return true;
+    }
+
+    return binder->isRemote();
+}
+
+void AIBinder_incStrong(AIBinder* binder) {
+    if (binder == nullptr) {
+        LOG(ERROR) << __func__ << ": on null binder";
+        return;
+    }
+
+    binder->incStrong(nullptr);
+}
+void AIBinder_decStrong(AIBinder* binder) {
+    if (binder == nullptr) {
+        LOG(ERROR) << __func__ << ": on null binder";
+        return;
+    }
+
+    binder->decStrong(nullptr);
+}
+int32_t AIBinder_debugGetRefCount(AIBinder* binder) {
+    if (binder == nullptr) {
+        LOG(ERROR) << __func__ << ": on null binder";
+        return -1;
+    }
+
+    return binder->getStrongCount();
+}
+
+void AIBinder_associateClass(AIBinder** binder, const AIBinder_Class* clazz) {
+    if (binder == nullptr || *binder == nullptr) {
+        return;
+    }
+
+    sp<AIBinder> result = (*binder)->associateClass(clazz);
+
+    // This function takes one refcount of 'binder' and delivers one refcount of 'result' to the
+    // callee. First we give the callee their refcount and then take it away from binder. This is
+    // done in this order in order to handle the case that the result and the binder are the same
+    // object.
+    if (result != nullptr) {
+        AIBinder_incStrong(result.get());
+    }
+    AIBinder_decStrong(*binder);
+
+    *binder = result.get(); // Maybe no-op
+}
+
+const AIBinder_Class* AIBinder_getClass(AIBinder* binder) {
+    if (binder == nullptr) {
+        return nullptr;
+    }
+
+    return binder->getClass();
+}
+
+void* AIBinder_getUserData(AIBinder* binder) {
+    if (binder == nullptr) {
+        return nullptr;
+    }
+
+    ABBinder* bBinder = binder->asABBinder();
+    if (bBinder == nullptr) {
+        return nullptr;
+    }
+
+    return bBinder->getUserData();
+}
+
+binder_status_t AIBinder_prepareTransaction(AIBinder* binder, AParcel** in) {
+    if (binder == nullptr || in == nullptr) {
+        LOG(ERROR) << __func__ << ": requires non-null parameters.";
+        return EX_NULL_POINTER;
+    }
+    const AIBinder_Class* clazz = binder->getClass();
+    if (clazz == nullptr) {
+        LOG(ERROR) << __func__
+                   << ": Class must be defined for a remote binder transaction. See "
+                      "AIBinder_associateClass.";
+        return EX_ILLEGAL_STATE;
+    }
+
+    *in = new AParcel(binder);
+    binder_status_t status = (**in)->writeInterfaceToken(clazz->getInterfaceDescriptor());
+    if (status != EX_NONE) {
+        delete *in;
+        *in = nullptr;
+    }
+
+    return status;
+}
+
+using AutoParcelDestroyer = std::unique_ptr<AParcel*, void (*)(AParcel**)>;
+static void destroy_parcel(AParcel** parcel) {
+    delete *parcel;
+    *parcel = nullptr;
+}
+
+binder_status_t AIBinder_transact(AIBinder* binder, transaction_code_t code, AParcel** in,
+                                  AParcel** out, binder_flags_t flags) {
+    if (in == nullptr) {
+        LOG(ERROR) << __func__ << ": requires non-null in parameter";
+        return EX_NULL_POINTER;
+    }
+
+    // This object is the input to the transaction. This function takes ownership of it and deletes
+    // it.
+    AutoParcelDestroyer forIn(in, destroy_parcel);
+
+    if (!isUserCommand(code)) {
+        LOG(ERROR) << __func__ << ": Only user-defined transactions can be made from the NDK.";
+        return EX_UNSUPPORTED_OPERATION;
+    }
+
+    if ((flags & ~FLAG_ONEWAY) != 0) {
+        LOG(ERROR) << __func__ << ": Unrecognized flags sent: " << flags;
+        return EX_ILLEGAL_ARGUMENT;
+    }
+
+    if (binder == nullptr || *in == nullptr || out == nullptr) {
+        LOG(ERROR) << __func__ << ": requires non-null parameters.";
+        return EX_NULL_POINTER;
+    }
+
+    if ((*in)->getBinder() != binder) {
+        LOG(ERROR) << __func__ << ": parcel is associated with binder object " << binder
+                   << " but called with " << (*in)->getBinder();
+        return EX_ILLEGAL_STATE;
+    }
+
+    *out = new AParcel(binder);
+
+    binder_status_t parcelStatus =
+            binder->getBinder()->transact(code, *(*in)->operator->(), (*out)->operator->(), flags);
+
+    if (parcelStatus != EX_NONE) {
+        delete *out;
+        *out = nullptr;
+    }
+
+    return parcelStatus;
+}
+
+binder_status_t AIBinder_finalizeTransaction(AIBinder* binder, AParcel** out) {
+    if (out == nullptr) {
+        LOG(ERROR) << __func__ << ": requires non-null out parameter";
+        return EX_NULL_POINTER;
+    }
+
+    // This object is the input to the transaction. This function takes ownership of it and deletes
+    // it.
+    AutoParcelDestroyer forOut(out, destroy_parcel);
+
+    if (binder == nullptr || *out == nullptr) {
+        LOG(ERROR) << __func__ << ": requires non-null parameters.";
+        return EX_NULL_POINTER;
+    }
+
+    if ((*out)->getBinder() != binder) {
+        LOG(ERROR) << __func__ << ": parcel is associated with binder object " << binder
+                   << " but called with " << (*out)->getBinder();
+        return EX_ILLEGAL_STATE;
+    }
+
+    if ((**out)->dataAvail() != 0) {
+        LOG(ERROR) << __func__
+                   << ": Only part of this transaction was read. There is remaining data left.";
+        return EX_ILLEGAL_STATE;
+    }
+
+    return EX_NONE;
+}
diff --git a/libs/binder/ndk/AIBinder_internal.h b/libs/binder/ndk/AIBinder_internal.h
new file mode 100644
index 0000000..d44b937
--- /dev/null
+++ b/libs/binder/ndk/AIBinder_internal.h
@@ -0,0 +1,109 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <android/binder_ibinder.h>
+#include "AIBinder_internal.h"
+
+#include <atomic>
+
+#include <binder/Binder.h>
+#include <binder/IBinder.h>
+
+inline bool isUserCommand(transaction_code_t code) {
+    return code >= FIRST_CALL_TRANSACTION && code <= LAST_CALL_TRANSACTION;
+}
+
+struct ABBinder;
+struct ABpBinder;
+
+struct AIBinder : public virtual ::android::RefBase {
+    AIBinder(const AIBinder_Class* clazz);
+    virtual ~AIBinder();
+
+    // This returns an AIBinder object with this class associated. If the class is already
+    // associated, 'this' will be returned. If there is a local AIBinder implementation, that will
+    // be returned. If this is a remote object, the class will be associated and this will be ready
+    // to be used for transactions.
+    ::android::sp<AIBinder> associateClass(const AIBinder_Class* clazz);
+    const AIBinder_Class* getClass() const { return mClazz; }
+
+    // This does not create the binder if it does not exist in the process.
+    virtual ::android::sp<::android::IBinder> getBinder() = 0;
+    virtual ABBinder* asABBinder() { return nullptr; }
+    virtual ABpBinder* asABpBinder() { return nullptr; }
+
+    bool isRemote() {
+        auto binder = getBinder();
+        // if the binder is nullptr, then it is a local object which hasn't been sent out of process
+        // yet.
+        return binder != nullptr && binder->remoteBinder() != nullptr;
+    }
+
+private:
+    // AIBinder instance is instance of this class for a local object. In order to transact on a
+    // remote object, this also must be set for simplicity (although right now, only the
+    // interfaceDescriptor from it is used).
+    const AIBinder_Class* mClazz;
+};
+
+// This is a local AIBinder object with a known class.
+struct ABBinder : public AIBinder, public ::android::BBinder {
+    ABBinder(const AIBinder_Class* clazz, void* userData);
+    virtual ~ABBinder();
+
+    void* getUserData() { return mUserData; }
+
+    ::android::sp<::android::IBinder> getBinder() override { return this; }
+    ABBinder* asABBinder() override { return this; }
+
+    const ::android::String16& getInterfaceDescriptor() const override;
+    binder_status_t onTransact(uint32_t code, const ::android::Parcel& data,
+                               ::android::Parcel* reply, binder_flags_t flags) override;
+
+private:
+    // Can contain implementation if this is a local binder. This can still be nullptr for a local
+    // binder. If it is nullptr, the implication is the implementation state is entirely external to
+    // this object and the functionality provided in the AIBinder_Class is sufficient.
+    void* mUserData;
+};
+
+// This binder object may be remote or local (even though it is 'Bp'). It is not yet associated with
+// a class.
+struct ABpBinder : public AIBinder, public ::android::BpRefBase {
+    ABpBinder(::android::sp<::android::IBinder> binder);
+    virtual ~ABpBinder();
+
+    ::android::sp<::android::IBinder> getBinder() override { return remote(); }
+    ABpBinder* asABpBinder() override { return this; }
+};
+
+struct AIBinder_Class {
+    AIBinder_Class(const char* interfaceDescriptor, AIBinder_Class_onCreate onCreate,
+                   AIBinder_Class_onDestroy onDestroy, AIBinder_Class_onTransact onTransact);
+
+    const ::android::String16& getInterfaceDescriptor() const { return mInterfaceDescriptor; }
+
+    const AIBinder_Class_onCreate onCreate;
+    const AIBinder_Class_onDestroy onDestroy;
+    const AIBinder_Class_onTransact onTransact;
+
+private:
+    // This must be a String16 since BBinder virtual getInterfaceDescriptor returns a reference to
+    // one.
+    const ::android::String16 mInterfaceDescriptor;
+};
diff --git a/libs/binder/ndk/AParcel.cpp b/libs/binder/ndk/AParcel.cpp
new file mode 100644
index 0000000..b63b138
--- /dev/null
+++ b/libs/binder/ndk/AParcel.cpp
@@ -0,0 +1,127 @@
+/*
+ * 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.
+ */
+
+#include <android/binder_parcel.h>
+#include "AParcel_internal.h"
+
+#include "AIBinder_internal.h"
+
+#include <binder/Parcel.h>
+
+using ::android::IBinder;
+using ::android::Parcel;
+using ::android::sp;
+
+binder_status_t AParcel_writeStrongBinder(AParcel* parcel, AIBinder* binder) {
+    return (*parcel)->writeStrongBinder(binder->getBinder());
+}
+binder_status_t AParcel_readStrongBinder(const AParcel* parcel, AIBinder** binder) {
+    sp<IBinder> readBinder = nullptr;
+    binder_status_t status = (*parcel)->readStrongBinder(&readBinder);
+    if (status != EX_NONE) {
+        return status;
+    }
+    *binder = new ABpBinder(readBinder);
+    AIBinder_incStrong(*binder);
+    return status;
+}
+binder_status_t AParcel_readNullableStrongBinder(const AParcel* parcel, AIBinder** binder) {
+    sp<IBinder> readBinder = nullptr;
+    binder_status_t status = (*parcel)->readNullableStrongBinder(&readBinder);
+    if (status != EX_NONE) {
+        return status;
+    }
+    *binder = new ABpBinder(readBinder);
+    AIBinder_incStrong(*binder);
+    return status;
+}
+
+// See gen_parcel_helper.py. These auto-generated read/write methods use the same types for
+// libbinder and this library.
+// @START
+binder_status_t AParcel_writeInt32(AParcel* parcel, int32_t value) {
+    return (*parcel)->writeInt32(value);
+}
+
+binder_status_t AParcel_writeUint32(AParcel* parcel, uint32_t value) {
+    return (*parcel)->writeUint32(value);
+}
+
+binder_status_t AParcel_writeInt64(AParcel* parcel, int64_t value) {
+    return (*parcel)->writeInt64(value);
+}
+
+binder_status_t AParcel_writeUint64(AParcel* parcel, uint64_t value) {
+    return (*parcel)->writeUint64(value);
+}
+
+binder_status_t AParcel_writeFloat(AParcel* parcel, float value) {
+    return (*parcel)->writeFloat(value);
+}
+
+binder_status_t AParcel_writeDouble(AParcel* parcel, double value) {
+    return (*parcel)->writeDouble(value);
+}
+
+binder_status_t AParcel_writeBool(AParcel* parcel, bool value) {
+    return (*parcel)->writeBool(value);
+}
+
+binder_status_t AParcel_writeChar(AParcel* parcel, char16_t value) {
+    return (*parcel)->writeChar(value);
+}
+
+binder_status_t AParcel_writeByte(AParcel* parcel, int8_t value) {
+    return (*parcel)->writeByte(value);
+}
+
+binder_status_t AParcel_readInt32(const AParcel* parcel, int32_t* value) {
+    return (*parcel)->readInt32(value);
+}
+
+binder_status_t AParcel_readUint32(const AParcel* parcel, uint32_t* value) {
+    return (*parcel)->readUint32(value);
+}
+
+binder_status_t AParcel_readInt64(const AParcel* parcel, int64_t* value) {
+    return (*parcel)->readInt64(value);
+}
+
+binder_status_t AParcel_readUint64(const AParcel* parcel, uint64_t* value) {
+    return (*parcel)->readUint64(value);
+}
+
+binder_status_t AParcel_readFloat(const AParcel* parcel, float* value) {
+    return (*parcel)->readFloat(value);
+}
+
+binder_status_t AParcel_readDouble(const AParcel* parcel, double* value) {
+    return (*parcel)->readDouble(value);
+}
+
+binder_status_t AParcel_readBool(const AParcel* parcel, bool* value) {
+    return (*parcel)->readBool(value);
+}
+
+binder_status_t AParcel_readChar(const AParcel* parcel, char16_t* value) {
+    return (*parcel)->readChar(value);
+}
+
+binder_status_t AParcel_readByte(const AParcel* parcel, int8_t* value) {
+    return (*parcel)->readByte(value);
+}
+
+// @END
diff --git a/libs/binder/ndk/AParcel_internal.h b/libs/binder/ndk/AParcel_internal.h
new file mode 100644
index 0000000..9f30a2f
--- /dev/null
+++ b/libs/binder/ndk/AParcel_internal.h
@@ -0,0 +1,53 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <android/binder_parcel.h>
+
+#include <sys/cdefs.h>
+
+#include <binder/Parcel.h>
+#include "AIBinder_internal.h"
+
+struct AParcel {
+    const ::android::Parcel* operator->() const { return mParcel; }
+    ::android::Parcel* operator->() { return mParcel; }
+
+    AParcel(const AIBinder* binder) : AParcel(binder, new ::android::Parcel, true /*owns*/) {}
+    AParcel(const AIBinder* binder, ::android::Parcel* parcel, bool owns)
+          : mBinder(binder), mParcel(parcel), mOwns(owns) {}
+
+    ~AParcel() {
+        if (mOwns) {
+            delete mParcel;
+        }
+    }
+
+    static const AParcel readOnly(const AIBinder* binder, const ::android::Parcel* parcel) {
+        return AParcel(binder, const_cast<::android::Parcel*>(parcel), false);
+    }
+
+    const AIBinder* getBinder() { return mBinder; }
+
+private:
+    // This object is associated with a calls to a specific AIBinder object. This is used for sanity
+    // checking to make sure that a parcel is one that is expected.
+    const AIBinder* mBinder;
+
+    ::android::Parcel* mParcel;
+    bool mOwns;
+};
diff --git a/libs/binder/ndk/AServiceManager.cpp b/libs/binder/ndk/AServiceManager.cpp
new file mode 100644
index 0000000..f61b914
--- /dev/null
+++ b/libs/binder/ndk/AServiceManager.cpp
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+
+#include <android/binder_manager.h>
+#include "AIBinder_internal.h"
+
+#include <binder/IServiceManager.h>
+
+using ::android::defaultServiceManager;
+using ::android::IBinder;
+using ::android::IServiceManager;
+using ::android::sp;
+using ::android::String16;
+
+binder_status_t AServiceManager_addService(AIBinder* binder, const char* instance) {
+    if (binder == nullptr || instance == nullptr) {
+        return EX_NULL_POINTER;
+    }
+
+    sp<IServiceManager> sm = defaultServiceManager();
+    return sm->addService(String16(instance), binder->getBinder());
+}
+AIBinder* AServiceManager_getService(const char* instance) {
+    if (instance == nullptr) {
+        return nullptr;
+    }
+
+    sp<IServiceManager> sm = defaultServiceManager();
+    sp<IBinder> binder = sm->getService(String16(instance));
+
+    AIBinder* ret = new ABpBinder(binder);
+    AIBinder_incStrong(ret);
+    return ret;
+}
diff --git a/libs/binder/ndk/Android.bp b/libs/binder/ndk/Android.bp
new file mode 100644
index 0000000..76d5a73
--- /dev/null
+++ b/libs/binder/ndk/Android.bp
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+cc_library {
+    name: "libbinder_ndk",
+    vendor_available: false,
+
+    export_include_dirs: [
+        "include_ndk",
+        "include_apex",
+    ],
+
+    srcs: [
+        "ABinderProcess.cpp",
+        "AIBinder.cpp",
+        "AParcel.cpp",
+        "AServiceManager.cpp",
+    ],
+
+    shared_libs: [
+        "libbase",
+        "libbinder",
+        "libutils",
+    ],
+}
diff --git a/libs/binder/ndk/include_apex/android/binder_manager.h b/libs/binder/ndk/include_apex/android/binder_manager.h
new file mode 100644
index 0000000..b8f38ba
--- /dev/null
+++ b/libs/binder/ndk/include_apex/android/binder_manager.h
@@ -0,0 +1,35 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <android/binder_ibinder.h>
+
+__BEGIN_DECLS
+
+/**
+ * This registers the service with the default service manager under this instance name.
+ */
+binder_status_t AServiceManager_addService(AIBinder* binder, const char* instance);
+
+/**
+ * Gets a binder object with this specific instance name. Blocks for a couple of seconds waiting on
+ * it. This also implicitly calls AIBinder_incStrong (so the caller of this function is responsible
+ * for calling AIBinder_decStrong).
+ */
+__attribute__((warn_unused_result)) AIBinder* AServiceManager_getService(const char* instance);
+
+__END_DECLS
diff --git a/libs/binder/ndk/include_apex/android/binder_process.h b/libs/binder/ndk/include_apex/android/binder_process.h
new file mode 100644
index 0000000..69e6387
--- /dev/null
+++ b/libs/binder/ndk/include_apex/android/binder_process.h
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <stdint.h>
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+
+/**
+ * This creates a threadpool for incoming binder transactions if it has not already been created.
+ */
+void ABinderProcess_startThreadPool();
+/**
+ * This sets the maximum number of threads that can be started in the threadpool. By default, after
+ * startThreadPool is called, this is one. If it is called additional times, it will only prevent
+ * the kernel from starting new threads and will not delete already existing threads.
+ */
+bool ABinderProcess_setThreadPoolMaxThreadCount(uint32_t numThreads);
+/**
+ * This adds the current thread to the threadpool. This may cause the threadpool to exceed the
+ * maximum size.
+ */
+void ABinderProcess_joinThreadPool();
+
+__END_DECLS
diff --git a/libs/binder/ndk/include_ndk/android/binder_ibinder.h b/libs/binder/ndk/include_ndk/android/binder_ibinder.h
new file mode 100644
index 0000000..23136a2
--- /dev/null
+++ b/libs/binder/ndk/include_ndk/android/binder_ibinder.h
@@ -0,0 +1,247 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <stdint.h>
+#include <sys/cdefs.h>
+
+#include <android/binder_parcel.h>
+#include <android/binder_status.h>
+
+__BEGIN_DECLS
+
+// Also see TF_* in kernel's binder.h
+typedef uint32_t binder_flags_t;
+enum {
+    /**
+     * The transaction will be dispatched and then returned to the caller. The outgoing process
+     * cannot block a call made by this, and execution of the call will not be waited on. An error
+     * can still be returned if the call is unable to be processed by the binder driver. All oneway
+     * calls are guaranteed to be ordered if they are sent on the same AIBinder object.
+     */
+    FLAG_ONEWAY = 0x01,
+};
+
+// Also see IBinder.h in libbinder
+typedef uint32_t transaction_code_t;
+enum {
+    /**
+     * The first transaction code available for user commands (inclusive).
+     */
+    FIRST_CALL_TRANSACTION = 0x00000001,
+    /**
+     * The last transaction code available for user commands (inclusive).
+     */
+    LAST_CALL_TRANSACTION = 0x00ffffff,
+};
+
+/**
+ * Represents a type of AIBinder object which can be sent out.
+ */
+struct AIBinder_Class;
+typedef struct AIBinder_Class AIBinder_Class;
+
+/**
+ * Represents a local or remote object which can be used for IPC or which can itself be sent.
+ *
+ * This object has a refcount associated with it and will be deleted when its refcount reaches zero.
+ * How methods interactive with this refcount is described below. When using this API, it is
+ * intended for a client of a service to hold a strong reference to that service. This also means
+ * that user data typically should hold a strong reference to a local AIBinder object. A remote
+ * AIBinder object automatically holds a strong reference to the AIBinder object in the server's
+ * process. A typically memory layout looks like this:
+ *
+ * Key:
+ *   --->         Ownership/a strong reference
+ *   ...>         A weak reference
+ *
+ *                         (process boundary)
+ *                                 |
+ * MyInterface ---> AIBinder_Weak  |  ProxyForMyInterface
+ *      ^                .         |          |
+ *      |                .         |          |
+ *      |                v         |          v
+ *   UserData  <---   AIBinder   <-|-      AIBinder
+ *                                 |
+ *
+ * In this way, you'll notice that a proxy for the interface holds a strong reference to the
+ * implementation and that in the server process, the AIBinder object which was sent can be resent
+ * so that the same AIBinder object always represents the same object. This allows, for instance, an
+ * implementation (usually a callback) to transfer all ownership to a remote process and
+ * automatically be deleted when the remote process is done with it or dies. Other memory models are
+ * possible, but this is the standard one.
+ */
+struct AIBinder;
+typedef struct AIBinder AIBinder;
+
+/**
+ * The AIBinder object associated with this can be retrieved if it is still alive so that it can be
+ * re-used. The intention of this is to enable the same AIBinder object to always represent the same
+ * object.
+ */
+struct AIBinder_Weak;
+typedef struct AIBinder_Weak AIBinder_Weak;
+
+/**
+ * This is called whenever a new AIBinder object is needed of a specific class.
+ *
+ * These arguments are passed from AIBinder_new. The return value is stored and can be retrieved
+ * using AIBinder_getUserData.
+ */
+typedef void* (*AIBinder_Class_onCreate)(void* args);
+
+/**
+ * This is called whenever an AIBinder object is no longer referenced and needs destroyed.
+ *
+ * Typically, this just deletes whatever the implementation is.
+ */
+typedef void (*AIBinder_Class_onDestroy)(void* userData);
+
+/**
+ * This is called whenever a transaction needs to be processed by a local implementation.
+ */
+typedef binder_status_t (*AIBinder_Class_onTransact)(AIBinder* binder, transaction_code_t code,
+                                                     const AParcel* in, AParcel* out);
+
+/**
+ * An interfaceDescriptor uniquely identifies the type of object that is being created. This is used
+ * internally for sanity checks on transactions.
+ *
+ * None of these parameters can be nullptr.
+ *
+ * This is created one time during library initialization and cleaned up when the process exits or
+ * execs.
+ */
+__attribute__((warn_unused_result)) AIBinder_Class* AIBinder_Class_define(
+        const char* interfaceDescriptor, AIBinder_Class_onCreate onCreate,
+        AIBinder_Class_onDestroy onDestroy, AIBinder_Class_onTransact onTransact);
+
+/**
+ * Creates a new binder object of the appropriate class.
+ *
+ * Ownership of args is passed to this object. The lifecycle is implemented with AIBinder_incStrong
+ * and AIBinder_decStrong. When the reference count reaches zero, onDestroy is called.
+ *
+ * When this is called, the refcount is implicitly 1. So, calling decStrong exactly one time is
+ * required to delete this object.
+ */
+__attribute__((warn_unused_result)) AIBinder* AIBinder_new(const AIBinder_Class* clazz, void* args);
+
+/**
+ * If this is hosted in a process other than the current one.
+ */
+bool AIBinder_isRemote(AIBinder* binder);
+
+/**
+ * This can only be called if a strong reference to this object already exists in process.
+ */
+void AIBinder_incStrong(AIBinder* binder);
+
+/**
+ * This will delete the object and call onDestroy once the refcount reaches zero.
+ */
+void AIBinder_decStrong(AIBinder* binder);
+
+/**
+ * For debugging only!
+ */
+int32_t AIBinder_debugGetRefCount(AIBinder* binder);
+
+/**
+ * This sets the class of an AIBinder object. This checks to make sure the remote object is of
+ * the expected class. A class must be set in order to use transactions on an AIBinder object.
+ * However, if an object is just intended to be passed through to another process or used as a
+ * handle this need not be called.
+ *
+ * The binder parameter may or may not be updated. If it is updated, the ownership of the original
+ * object is transferred to the new object. If the class association fails, ownership of the binder
+ * is lost, and it is set to nullptr.
+ */
+void AIBinder_associateClass(AIBinder** binder, const AIBinder_Class* clazz);
+
+/*
+ * Returns the class that this binder was constructed with or associated with.
+ */
+const AIBinder_Class* AIBinder_getClass(AIBinder* binder);
+
+/**
+ * Value returned by onCreate for a local binder. For stateless classes (if onCreate returns
+ * nullptr), this also returns nullptr. For a remote binder, this will always return nullptr.
+ */
+void* AIBinder_getUserData(AIBinder* binder);
+
+/**
+ * A transaction is a series of calls to these functions which looks this
+ * - call AIBinder_prepareTransaction
+ * - fill out parcel with in parameters (lifetime of the 'in' variable)
+ * - call AIBinder_transact
+ * - fill out parcel with out parameters (lifetime of the 'out' variable)
+ * - call AIBinder_finalizeTransaction
+ */
+
+/**
+ * Creates a parcel to start filling out for a transaction. This may add data to the parcel for
+ * security, debugging, or other purposes. This parcel is to be sent via AIBinder_transact and it
+ * represents the input data to the transaction. It is recommended to check if the object is local
+ * and call directly into its user data before calling this as the parceling and unparceling cost
+ * can be avoided. This AIBinder must be either built with a class or associated with a class before
+ * using this API.
+ *
+ * This does not affect the ownership of binder.
+ */
+binder_status_t AIBinder_prepareTransaction(AIBinder* binder, AParcel** in);
+
+/**
+ * Transact using a parcel created from AIBinder_prepareTransaction. This actually communicates with
+ * the object representing this binder object. This also passes out a parcel to be used for the
+ * return transaction. This takes ownership of the in parcel and automatically deletes it after it
+ * is sent to the remote process. The output parcel is the result of the transaction. If the
+ * transaction has FLAG_ONEWAY, the out parcel will be empty. Otherwise, this will block until the
+ * remote process has processed the transaction, and the out parcel will contain the output data
+ * from transaction.
+ *
+ * This does not affect the ownership of binder.
+ */
+binder_status_t AIBinder_transact(AIBinder* binder, transaction_code_t code, AParcel** in,
+                                  AParcel** out, binder_flags_t flags);
+
+/**
+ * This takes ownership of the out parcel and automatically deletes it. Additional checks for
+ * security or debugging maybe performed internally.
+ *
+ * This does not affect the ownership of binder.
+ */
+binder_status_t AIBinder_finalizeTransaction(AIBinder* binder, AParcel** out);
+
+/*
+ * This does not take any ownership of the input binder, but it can be used to retrieve it if
+ * something else in some process still holds a reference to it.
+ */
+__attribute__((warn_unused_result)) AIBinder_Weak* AIBinder_Weak_new(AIBinder* binder);
+
+/*
+ * Deletes the weak reference. This will have no impact on the lifetime of the binder.
+ */
+void AIBinder_Weak_delete(AIBinder_Weak* weakBinder);
+
+/**
+ * If promotion succeeds, result will have one strong refcount added to it. Otherwise, this returns
+ * nullptr.
+ */
+__attribute__((warn_unused_result)) AIBinder* AIBinder_Weak_promote(AIBinder_Weak* weakBinder);
+
+__END_DECLS
diff --git a/libs/binder/ndk/include_ndk/android/binder_parcel.h b/libs/binder/ndk/include_ndk/android/binder_parcel.h
new file mode 100644
index 0000000..091ae8e
--- /dev/null
+++ b/libs/binder/ndk/include_ndk/android/binder_parcel.h
@@ -0,0 +1,147 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <sys/cdefs.h>
+
+#include <android/binder_status.h>
+
+struct AIBinder;
+typedef struct AIBinder AIBinder;
+
+__BEGIN_DECLS
+
+/**
+ * This object represents a package of data that can be sent between processes. When transacting, an
+ * instance of it is automatically created to be used for the transaction. When two processes use
+ * binder to communicate, they must agree on a format of this parcel to be used in order to transfer
+ * data. This is usually done in an IDL (see AIDL, specificially).
+ */
+struct AParcel;
+typedef struct AParcel AParcel;
+
+/**
+ * Writes an AIBinder to the next location in a non-null parcel. Can be null.
+ */
+binder_status_t AParcel_writeStrongBinder(AParcel* parcel, AIBinder* binder);
+
+/**
+ * Reads an AIBinder from the next location in a non-null parcel. This will fail if the binder is
+ * non-null. One strong ref-count of ownership is passed to the caller of this function.
+ */
+binder_status_t AParcel_readStrongBinder(const AParcel* parcel, AIBinder** binder);
+
+/**
+ * Reads an AIBinder from the next location in a non-null parcel. This may read a null. One strong
+ * ref-count of ownership is passed to the caller of this function.
+ */
+binder_status_t AParcel_readNullableStrongBinder(const AParcel* parcel, AIBinder** binder);
+
+// @START
+/**
+ * Writes int32_t value to the next location in a non-null parcel.
+ */
+binder_status_t AParcel_writeInt32(AParcel* parcel, int32_t value);
+
+/**
+ * Writes uint32_t value to the next location in a non-null parcel.
+ */
+binder_status_t AParcel_writeUint32(AParcel* parcel, uint32_t value);
+
+/**
+ * Writes int64_t value to the next location in a non-null parcel.
+ */
+binder_status_t AParcel_writeInt64(AParcel* parcel, int64_t value);
+
+/**
+ * Writes uint64_t value to the next location in a non-null parcel.
+ */
+binder_status_t AParcel_writeUint64(AParcel* parcel, uint64_t value);
+
+/**
+ * Writes float value to the next location in a non-null parcel.
+ */
+binder_status_t AParcel_writeFloat(AParcel* parcel, float value);
+
+/**
+ * Writes double value to the next location in a non-null parcel.
+ */
+binder_status_t AParcel_writeDouble(AParcel* parcel, double value);
+
+/**
+ * Writes bool value to the next location in a non-null parcel.
+ */
+binder_status_t AParcel_writeBool(AParcel* parcel, bool value);
+
+/**
+ * Writes char16_t value to the next location in a non-null parcel.
+ */
+binder_status_t AParcel_writeChar(AParcel* parcel, char16_t value);
+
+/**
+ * Writes int8_t value to the next location in a non-null parcel.
+ */
+binder_status_t AParcel_writeByte(AParcel* parcel, int8_t value);
+
+/**
+ * Reads into int32_t value from the next location in a non-null parcel.
+ */
+binder_status_t AParcel_readInt32(const AParcel* parcel, int32_t* value);
+
+/**
+ * Reads into uint32_t value from the next location in a non-null parcel.
+ */
+binder_status_t AParcel_readUint32(const AParcel* parcel, uint32_t* value);
+
+/**
+ * Reads into int64_t value from the next location in a non-null parcel.
+ */
+binder_status_t AParcel_readInt64(const AParcel* parcel, int64_t* value);
+
+/**
+ * Reads into uint64_t value from the next location in a non-null parcel.
+ */
+binder_status_t AParcel_readUint64(const AParcel* parcel, uint64_t* value);
+
+/**
+ * Reads into float value from the next location in a non-null parcel.
+ */
+binder_status_t AParcel_readFloat(const AParcel* parcel, float* value);
+
+/**
+ * Reads into double value from the next location in a non-null parcel.
+ */
+binder_status_t AParcel_readDouble(const AParcel* parcel, double* value);
+
+/**
+ * Reads into bool value from the next location in a non-null parcel.
+ */
+binder_status_t AParcel_readBool(const AParcel* parcel, bool* value);
+
+/**
+ * Reads into char16_t value from the next location in a non-null parcel.
+ */
+binder_status_t AParcel_readChar(const AParcel* parcel, char16_t* value);
+
+/**
+ * Reads into int8_t value from the next location in a non-null parcel.
+ */
+binder_status_t AParcel_readByte(const AParcel* parcel, int8_t* value);
+
+// @END
+
+__END_DECLS
diff --git a/libs/binder/ndk/include_ndk/android/binder_status.h b/libs/binder/ndk/include_ndk/android/binder_status.h
new file mode 100644
index 0000000..d414c99
--- /dev/null
+++ b/libs/binder/ndk/include_ndk/android/binder_status.h
@@ -0,0 +1,56 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <stdint.h>
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+
+// Keep the exception codes in sync with android/os/Parcel.java.
+enum {
+    EX_NONE = 0,
+    EX_SECURITY = -1,
+    EX_BAD_PARCELABLE = -2,
+    EX_ILLEGAL_ARGUMENT = -3,
+    EX_NULL_POINTER = -4,
+    EX_ILLEGAL_STATE = -5,
+    EX_NETWORK_MAIN_THREAD = -6,
+    EX_UNSUPPORTED_OPERATION = -7,
+    EX_SERVICE_SPECIFIC = -8,
+    EX_PARCELABLE = -9,
+
+    /**
+     * This is special and Java specific; see Parcel.java.
+     * This should be considered a success, and the next readInt32 bytes can be ignored.
+     */
+    EX_HAS_REPLY_HEADER = -128,
+
+    /**
+     * This is special, and indicates to native binder proxies that the
+     * transaction has failed at a low level.
+     */
+    EX_TRANSACTION_FAILED = -129,
+};
+
+/**
+ * One of the above values or -errno.
+ * By convention, positive values are considered to mean service-specific exceptions.
+ */
+typedef int32_t binder_status_t;
+
+__END_DECLS
diff --git a/libs/binder/ndk/runtests.sh b/libs/binder/ndk/runtests.sh
new file mode 100755
index 0000000..6c8527d
--- /dev/null
+++ b/libs/binder/ndk/runtests.sh
@@ -0,0 +1,40 @@
+#!/usr/bin/env bash
+
+# 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.
+
+if [ -z $ANDROID_BUILD_TOP ]; then
+  echo "You need to source and lunch before you can use this script"
+  exit 1
+fi
+
+set -ex
+
+function run_libbinder_ndk_test() {
+	adb shell /data/nativetest64/libbinder_ndk_test_server/libbinder_ndk_test_server &
+	local pid=$!
+	trap "kill $pid" ERR
+	adb shell /data/nativetest64/libbinder_ndk_test_client/libbinder_ndk_test_client
+	trap '' ERR
+	kill $pid
+}
+
+[ "$1" != "--skip-build" ] && $ANDROID_BUILD_TOP/build/soong/soong_ui.bash --make-mode \
+    MODULES-IN-frameworks-native-libs-binder-ndk
+
+adb root
+adb wait-for-device
+adb sync data
+
+run_libbinder_ndk_test
diff --git a/libs/binder/ndk/scripts/format.sh b/libs/binder/ndk/scripts/format.sh
new file mode 100755
index 0000000..698d291
--- /dev/null
+++ b/libs/binder/ndk/scripts/format.sh
@@ -0,0 +1,22 @@
+#!/usr/bin/env bash
+
+# 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.
+
+set -e
+
+echo "Formatting code"
+
+bpfmt -w $(find $ANDROID_BUILD_TOP/frameworks/native/libs/binder/ndk/ -name "Android.bp")
+clang-format -i $(find $ANDROID_BUILD_TOP/frameworks/native/libs/binder/ndk/ -\( -name "*.cpp" -o -name "*.h" -\))
diff --git a/libs/binder/ndk/scripts/gen_parcel_helper.py b/libs/binder/ndk/scripts/gen_parcel_helper.py
new file mode 100755
index 0000000..5c0b936
--- /dev/null
+++ b/libs/binder/ndk/scripts/gen_parcel_helper.py
@@ -0,0 +1,89 @@
+#!/usr/bin/env python3
+
+# 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.
+
+import os
+import sys
+
+# list (pretty, cpp)
+data_types = [
+    ("Int32", "int32_t"),
+    ("Uint32", "uint32_t"),
+    ("Int64", "int64_t"),
+    ("Uint64", "uint64_t"),
+    ("Float", "float"),
+    ("Double", "double"),
+    ("Bool", "bool"),
+    ("Char", "char16_t"),
+    ("Byte", "int8_t"),
+]
+
+def replaceFileTags(path, content):
+    print("Updating", path)
+    with open(path, "r+") as f:
+        lines = f.readlines()
+
+        start = lines.index("// @START\n")
+        end = lines.index("// @END\n")
+
+        if end <= start or start < 0 or end < 0:
+            print("Failed to find tags in", path)
+            exit(1)
+
+        f.seek(0)
+        f.write("".join(lines[:start+1]) + content + "".join(lines[end:]))
+        f.truncate()
+
+def main():
+    if len(sys.argv) != 1:
+        print("No arguments.")
+        exit(1)
+
+    ABT = os.environ.get('ANDROID_BUILD_TOP', None)
+    if ABT is None:
+        print("Can't get ANDROID_BUILD_TOP. Lunch?")
+        exit(1)
+    ROOT = ABT + "/frameworks/native/libs/binder/ndk/"
+
+    print("Updating auto-generated code")
+
+    header = ""
+    source = ""
+
+    for pretty, cpp in data_types:
+        header += "/**\n"
+        header += " * Writes " + cpp + " value to the next location in a non-null parcel.\n"
+        header += " */\n"
+        header += "binder_status_t AParcel_write" + pretty + "(AParcel* parcel, " + cpp + " value);\n\n"
+        source += "binder_status_t AParcel_write" + pretty + "(AParcel* parcel, " + cpp + " value) {\n"
+        source += "    return (*parcel)->write" + pretty + "(value);\n"
+        source += "}\n\n"
+
+    for pretty, cpp in data_types:
+        header += "/**\n"
+        header += " * Reads into " + cpp + " value from the next location in a non-null parcel.\n"
+        header += " */\n"
+        header += "binder_status_t AParcel_read" + pretty + "(const AParcel* parcel, " + cpp + "* value);\n\n"
+        source += "binder_status_t AParcel_read" + pretty + "(const AParcel* parcel, " + cpp + "* value) {\n"
+        source += "    return (*parcel)->read" + pretty + "(value);\n"
+        source += "}\n\n"
+
+    replaceFileTags(ROOT + "include_ndk/android/binder_parcel.h", header)
+    replaceFileTags(ROOT + "AParcel.cpp", source)
+
+    print("Updating DONE.")
+
+if __name__ == "__main__":
+    main()
diff --git a/libs/binder/ndk/test/Android.bp b/libs/binder/ndk/test/Android.bp
new file mode 100644
index 0000000..d242138
--- /dev/null
+++ b/libs/binder/ndk/test/Android.bp
@@ -0,0 +1,68 @@
+/*
+ * 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.
+ */
+
+// This test is a unit test of the low-level API that is presented here.
+// Actual users should use AIDL to generate these complicated stubs.
+
+cc_defaults {
+    name: "test_libbinder_ndk_defaults",
+    shared_libs: [
+        "libbase",
+    ],
+    strip: {
+        none: true,
+    },
+    cflags: [
+        "-O0",
+        "-g",
+    ],
+}
+
+cc_library_static {
+    name: "test_libbinder_ndk_library",
+    defaults: ["test_libbinder_ndk_defaults"],
+    export_include_dirs: ["include"],
+    shared_libs: ["libbinder_ndk"],
+    export_shared_lib_headers: ["libbinder_ndk"],
+    srcs: ["iface.cpp"],
+}
+
+cc_defaults {
+    name: "test_libbinder_ndk_test_defaults",
+    defaults: ["test_libbinder_ndk_defaults"],
+    shared_libs: [
+        "libbase",
+        "libbinder",
+        "libutils",
+    ],
+    static_libs: [
+        "libbinder_ndk",
+        "test_libbinder_ndk_library",
+    ],
+}
+
+cc_test {
+    name: "libbinder_ndk_test_client",
+    defaults: ["test_libbinder_ndk_test_defaults"],
+    srcs: ["main_client.cpp"],
+}
+
+cc_test {
+    name: "libbinder_ndk_test_server",
+    defaults: ["test_libbinder_ndk_test_defaults"],
+    srcs: ["main_server.cpp"],
+    gtest: false,
+}
diff --git a/libs/binder/ndk/test/iface.cpp b/libs/binder/ndk/test/iface.cpp
new file mode 100644
index 0000000..eed09f0
--- /dev/null
+++ b/libs/binder/ndk/test/iface.cpp
@@ -0,0 +1,145 @@
+/*
+ * 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.
+ */
+
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <iface/iface.h>
+
+using ::android::sp;
+using ::android::wp;
+
+const char* IFoo::kSomeInstanceName = "libbinder_ndk-test-IFoo";
+const char* kIFooDescriptor = "my-special-IFoo-class";
+
+struct IFoo_Class_Data {
+    sp<IFoo> foo;
+};
+
+void* IFoo_Class_onCreate(void* args) {
+    IFoo_Class_Data* foo = static_cast<IFoo_Class_Data*>(args);
+    // This is a foo, but we're currently not verifying that. So, the method newLocalBinder is
+    // coupled with this.
+    return static_cast<void*>(foo);
+}
+
+void IFoo_Class_onDestroy(void* userData) {
+    delete static_cast<IFoo_Class_Data*>(userData);
+}
+
+binder_status_t IFoo_Class_onTransact(AIBinder* binder, transaction_code_t code, const AParcel* in,
+                                      AParcel* out) {
+    binder_status_t stat = EX_UNSUPPORTED_OPERATION;
+
+    sp<IFoo> foo = static_cast<IFoo_Class_Data*>(AIBinder_getUserData(binder))->foo;
+    CHECK(foo != nullptr) << "Transaction made on already deleted object";
+
+    switch (code) {
+        case IFoo::DOFOO: {
+            int32_t valueIn;
+            stat = AParcel_readInt32(in, &valueIn);
+            if (stat != EX_NONE) break;
+            int32_t valueOut = foo->doubleNumber(valueIn);
+            stat = AParcel_writeInt32(out, valueOut);
+            break;
+        }
+    }
+
+    return stat;
+}
+
+AIBinder_Class* IFoo::kClass = AIBinder_Class_define(kIFooDescriptor, IFoo_Class_onCreate,
+                                                     IFoo_Class_onDestroy, IFoo_Class_onTransact);
+
+class BpFoo : public IFoo {
+public:
+    BpFoo(AIBinder* binder) : mBinder(binder) {}
+    virtual ~BpFoo() { AIBinder_decStrong(mBinder); }
+
+    virtual int32_t doubleNumber(int32_t in) {
+        AParcel* parcelIn;
+        CHECK(EX_NONE == AIBinder_prepareTransaction(mBinder, &parcelIn));
+
+        CHECK(EX_NONE == AParcel_writeInt32(parcelIn, in));
+
+        AParcel* parcelOut;
+        CHECK(EX_NONE ==
+              AIBinder_transact(mBinder, IFoo::DOFOO, &parcelIn, &parcelOut, 0 /*flags*/));
+
+        int32_t out;
+        CHECK(EX_NONE == AParcel_readInt32(parcelOut, &out));
+
+        CHECK(EX_NONE == AIBinder_finalizeTransaction(mBinder, &parcelOut));
+        return out;
+    }
+
+private:
+    // Always assumes one refcount
+    AIBinder* mBinder;
+};
+
+IFoo::~IFoo() {
+    AIBinder_Weak_delete(mWeakBinder);
+}
+
+binder_status_t IFoo::addService(const char* instance) {
+    AIBinder* binder = nullptr;
+
+    if (mWeakBinder != nullptr) {
+        // one strong ref count of binder
+        binder = AIBinder_Weak_promote(mWeakBinder);
+    }
+    if (binder == nullptr) {
+        // or one strong refcount here
+        binder = AIBinder_new(IFoo::kClass, static_cast<void*>(new IFoo_Class_Data{this}));
+        if (mWeakBinder != nullptr) {
+            AIBinder_Weak_delete(mWeakBinder);
+        }
+        mWeakBinder = AIBinder_Weak_new(binder);
+    }
+
+    binder_status_t status = AServiceManager_addService(binder, instance);
+    // Strong references we care about kept by remote process
+    AIBinder_decStrong(binder);
+    return status;
+}
+
+sp<IFoo> IFoo::getService(const char* instance) {
+    AIBinder* binder = AServiceManager_getService(instance); // maybe nullptr
+    AIBinder_associateClass(&binder, IFoo::kClass);
+
+    if (binder == nullptr) {
+        return nullptr;
+    }
+
+    if (AIBinder_isRemote(binder)) {
+        sp<IFoo> ret = new BpFoo(binder); // takes ownership of binder
+        return ret;
+    }
+
+    IFoo_Class_Data* data = static_cast<IFoo_Class_Data*>(AIBinder_getUserData(binder));
+
+    CHECK(data != nullptr); // always created with non-null data
+
+    sp<IFoo> ret = data->foo;
+
+    AIBinder* held = AIBinder_Weak_promote(ret->mWeakBinder);
+    CHECK(held == binder);
+    AIBinder_decStrong(held);
+
+    // IFoo only keeps a weak reference to AIBinder, so we can drop this
+    AIBinder_decStrong(binder);
+    return ret;
+}
diff --git a/libs/binder/ndk/test/include/iface/iface.h b/libs/binder/ndk/test/include/iface/iface.h
new file mode 100644
index 0000000..4c61e9d
--- /dev/null
+++ b/libs/binder/ndk/test/include/iface/iface.h
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <android/binder_ibinder.h>
+#include <utils/RefBase.h>
+
+class IFoo : public virtual ::android::RefBase {
+public:
+    static const char* kSomeInstanceName;
+    static AIBinder_Class* kClass;
+
+    // Takes ownership of IFoo
+    binder_status_t addService(const char* instance);
+    static ::android::sp<IFoo> getService(const char* instance);
+
+    enum Call {
+        DOFOO = FIRST_CALL_TRANSACTION + 0,
+    };
+
+    virtual ~IFoo();
+    virtual int32_t doubleNumber(int32_t in) = 0;
+
+private:
+    AIBinder_Weak* mWeakBinder = nullptr; // maybe owns AIBinder
+};
diff --git a/libs/binder/ndk/test/main_client.cpp b/libs/binder/ndk/test/main_client.cpp
new file mode 100644
index 0000000..7c53e51
--- /dev/null
+++ b/libs/binder/ndk/test/main_client.cpp
@@ -0,0 +1,70 @@
+/*
+ * 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.
+ */
+
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <gtest/gtest.h>
+#include <iface/iface.h>
+
+using ::android::sp;
+
+constexpr char kExistingNonNdkService[] = "SurfaceFlinger";
+
+// This is too slow
+// TEST(NdkBinder, GetServiceThatDoesntExist) {
+//     sp<IFoo> foo = IFoo::getService("asdfghkl;");
+//     EXPECT_EQ(nullptr, foo.get());
+// }
+
+TEST(NdkBinder, DoubleNumber) {
+    sp<IFoo> foo = IFoo::getService(IFoo::kSomeInstanceName);
+    ASSERT_NE(foo, nullptr);
+    EXPECT_EQ(2, foo->doubleNumber(1));
+}
+
+TEST(NdkBinder, RetrieveNonNdkService) {
+    AIBinder* binder = AServiceManager_getService(kExistingNonNdkService);
+    ASSERT_NE(nullptr, binder);
+    AIBinder_decStrong(binder);
+}
+
+class MyTestFoo : public IFoo {
+    int32_t doubleNumber(int32_t in) override {
+        LOG(INFO) << "doubleNumber " << in;
+        return 2 * in;
+    }
+};
+
+TEST(NdkBinder, GetServiceInProcess) {
+    static const char* kInstanceName = "test-get-service-in-process";
+
+    sp<IFoo> foo = new MyTestFoo;
+    EXPECT_EQ(EX_NONE, foo->addService(kInstanceName));
+
+    sp<IFoo> getFoo = IFoo::getService(kInstanceName);
+    EXPECT_EQ(foo.get(), getFoo.get());
+
+    EXPECT_EQ(2, getFoo->doubleNumber(1));
+}
+
+TEST(NdkBinder, AddServiceMultipleTimes) {
+    static const char* kInstanceName1 = "test-multi-1";
+    static const char* kInstanceName2 = "test-multi-2";
+    sp<IFoo> foo = new MyTestFoo;
+    EXPECT_EQ(EX_NONE, foo->addService(kInstanceName1));
+    EXPECT_EQ(EX_NONE, foo->addService(kInstanceName2));
+    EXPECT_EQ(IFoo::getService(kInstanceName1), IFoo::getService(kInstanceName2));
+}
diff --git a/libs/binder/ndk/test/main_server.cpp b/libs/binder/ndk/test/main_server.cpp
new file mode 100644
index 0000000..f3da7da
--- /dev/null
+++ b/libs/binder/ndk/test/main_server.cpp
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+#include <android-base/logging.h>
+#include <android/binder_process.h>
+#include <iface/iface.h>
+
+using ::android::sp;
+
+class MyFoo : public IFoo {
+    int32_t doubleNumber(int32_t in) override {
+        LOG(INFO) << "doubling " << in;
+        return 2 * in;
+    }
+};
+
+int main() {
+    ABinderProcess_setThreadPoolMaxThreadCount(0);
+
+    // Strong reference to MyFoo kept by service manager.
+    binder_status_t status = (new MyFoo)->addService(IFoo::kSomeInstanceName);
+
+    if (status != EX_NONE) {
+        LOG(FATAL) << "Could not register: " << status;
+    }
+
+    ABinderProcess_joinThreadPool();
+
+    return 1;
+}
diff --git a/libs/binder/ndk/update.sh b/libs/binder/ndk/update.sh
new file mode 100755
index 0000000..1eba892
--- /dev/null
+++ b/libs/binder/ndk/update.sh
@@ -0,0 +1,22 @@
+#!/usr/bin/env bash
+
+# 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.
+
+
+set -ex
+
+# This script makes sure that the source code is in sync with the various scripts
+./scripts/gen_parcel_helper.py
+./scripts/format.sh