Merge "Add a parameter to allow EventFlag configuration."
diff --git a/base/Status.cpp b/base/Status.cpp
index f018918..4ce26ee 100644
--- a/base/Status.cpp
+++ b/base/Status.cpp
@@ -28,7 +28,7 @@
 }
 
 Status Status::fromExceptionCode(int32_t exceptionCode,
-                                 const String8& message) {
+                                 const char *message) {
     return Status(exceptionCode, OK, message);
 }
 
@@ -37,7 +37,7 @@
 }
 
 Status Status::fromServiceSpecificError(int32_t serviceSpecificErrorCode,
-                                        const String8& message) {
+                                        const char *message) {
     return Status(EX_SERVICE_SPECIFIC, serviceSpecificErrorCode, message);
 }
 
@@ -51,18 +51,18 @@
     : mException(exceptionCode),
       mErrorCode(errorCode) {}
 
-Status::Status(int32_t exceptionCode, int32_t errorCode, const String8& message)
+Status::Status(int32_t exceptionCode, int32_t errorCode, const char *message)
     : mException(exceptionCode),
       mErrorCode(errorCode),
       mMessage(message) {}
 
-void Status::setException(int32_t ex, const String8& message) {
+void Status::setException(int32_t ex, const char *message) {
     mException = ex;
     mErrorCode = NO_ERROR;  // an exception, not a transaction failure.
-    mMessage.setTo(message);
+    mMessage = message;
 }
 
-void Status::setServiceSpecificError(int32_t errorCode, const String8& message) {
+void Status::setServiceSpecificError(int32_t errorCode, const char *message) {
     setException(EX_SERVICE_SPECIFIC, message);
     mErrorCode = errorCode;
 }
@@ -73,24 +73,24 @@
     mMessage.clear();
 }
 
-String8 Status::toString8() const {
-    String8 ret;
-    if (mException == EX_NONE) {
-        ret.append("No error");
-    } else {
-        ret.appendFormat("Status(%d): '", mException);
-        if (mException == EX_SERVICE_SPECIFIC ||
-            mException == EX_TRANSACTION_FAILED) {
-            ret.appendFormat("%d: ", mErrorCode);
-        }
-        ret.append(String8(mMessage));
-        ret.append("'");
-    }
-    return ret;
+std::string Status::description() const {
+    std::ostringstream oss;
+    oss << (*this);
+    return oss.str();
 }
 
-std::stringstream& operator<< (std::stringstream& stream, const Status& s) {
-    stream << s.toString8().string();
+std::ostream& operator<< (std::ostream& stream, const Status& s) {
+    if (s.exceptionCode() == Status::EX_NONE) {
+        stream << "No error";
+    } else {
+        stream << "Status(" << s.exceptionCode() << "): '";
+        if (s.exceptionCode() == Status::EX_SERVICE_SPECIFIC) {
+            stream << s.serviceSpecificErrorCode() << ": ";
+        } else if (s.exceptionCode() == Status::EX_TRANSACTION_FAILED) {
+            stream << s.transactionError() << ": ";
+        }
+        stream << s.exceptionMessage() << "'";
+    }
     return stream;
 }
 
diff --git a/base/include/hidl/HidlSupport.h b/base/include/hidl/HidlSupport.h
index 0670dd9..1a4fd3c 100644
--- a/base/include/hidl/HidlSupport.h
+++ b/base/include/hidl/HidlSupport.h
@@ -38,7 +38,8 @@
 
 namespace android {
 
-// this file is included by all hidl interface, so we must forward declare the IMemory type.
+// this file is included by all hidl interface, so we must forward declare the
+// IMemory and IBase types.
 namespace hidl {
 namespace memory {
 namespace V1_0 {
@@ -47,8 +48,23 @@
 }; // namespace manager
 }; // namespace hidl
 
+namespace hidl {
+namespace base {
+namespace V1_0 {
+    struct IBase;
+}; // namespace V1_0
+}; // namespace base
+}; // namespace hidl
+
 namespace hardware {
 
+// hidl_death_recipient is a callback interfaced that can be used with
+// linkToDeath() / unlinkToDeath()
+struct hidl_death_recipient : public virtual RefBase {
+    virtual void serviceDied(uint64_t cookie,
+            const ::android::wp<::android::hidl::base::V1_0::IBase>& who) = 0;
+};
+
 // hidl_handle wraps a pointer to a native_handle_t in a hidl_pointer,
 // so that it can safely be transferred between 32-bit and 64-bit processes.
 struct hidl_handle {
@@ -271,8 +287,11 @@
     }
 
     hidl_vec(const std::initializer_list<T> list)
-            : mSize(list.size()),
-              mOwnsBuffer(true) {
+            : mOwnsBuffer(true) {
+        if (list.size() > UINT32_MAX) {
+            logAlwaysFatal("hidl_vec can't hold more than 2^32 elements.");
+        }
+        mSize = static_cast<uint32_t>(list.size());
         mBuffer = new T[mSize];
 
         size_t idx = 0;
@@ -742,15 +761,6 @@
 #define HAL_LIBRARY_PATH_ODM "/odm/lib/hw/"
 #endif
 
-#define DECLARE_SERVICE_MANAGER_INTERACTIONS(INTERFACE)                                  \
-    static ::android::sp<I##INTERFACE> getService(                                       \
-            const std::string &serviceName, bool getStub=false);                         \
-    ::android::status_t registerAsService(const std::string &serviceName);               \
-    static bool registerForNotifications(                                                \
-        const std::string &serviceName,                                                  \
-        const ::android::sp<::android::hidl::manager::V1_0::IServiceNotification>        \
-                  &notification);                                                        \
-
 // ----------------------------------------------------------------------
 // Class that provides Hidl instrumentation utilities.
 struct HidlInstrumentor {
diff --git a/base/include/hidl/Status.h b/base/include/hidl/Status.h
index cacaf08..c0edb84 100644
--- a/base/include/hidl/Status.h
+++ b/base/include/hidl/Status.h
@@ -22,7 +22,7 @@
 
 #include <android-base/macros.h>
 #include <hidl/HidlInternal.h>
-#include <utils/String8.h>
+#include <utils/Errors.h>
 
 namespace android {
 namespace hardware {
@@ -84,10 +84,10 @@
     //  Java clients.
     static Status fromExceptionCode(int32_t exceptionCode);
     static Status fromExceptionCode(int32_t exceptionCode,
-                                    const String8& message);
+                                    const char *message);
     static Status fromServiceSpecificError(int32_t serviceSpecificErrorCode);
     static Status fromServiceSpecificError(int32_t serviceSpecificErrorCode,
-                                           const String8& message);
+                                           const char *message);
     static Status fromStatusT(status_t status);
 
     Status() = default;
@@ -99,9 +99,9 @@
     Status& operator=(const Status& status) = default;
 
     // Set one of the pre-defined exception types defined above.
-    void setException(int32_t ex, const String8& message);
+    void setException(int32_t ex, const char *message);
     // Set a service specific exception with error code.
-    void setServiceSpecificError(int32_t errorCode, const String8& message);
+    void setServiceSpecificError(int32_t errorCode, const char *message);
     // Setting a |status| != OK causes generated code to return |status|
     // from Binder transactions, rather than writing an exception into the
     // reply Parcel.  This is the least preferable way of reporting errors.
@@ -109,7 +109,7 @@
 
     // Get information about an exception.
     int32_t exceptionCode() const  { return mException; }
-    const String8& exceptionMessage() const { return mMessage; }
+    const char *exceptionMessage() const { return mMessage.c_str(); }
     status_t transactionError() const {
         return mException == EX_TRANSACTION_FAILED ? mErrorCode : OK;
     }
@@ -119,12 +119,12 @@
 
     bool isOk() const { return mException == EX_NONE; }
 
-    // For logging.
-    String8 toString8() const;
+    // For debugging purposes only
+    std::string description() const;
 
 private:
     Status(int32_t exceptionCode, int32_t errorCode);
-    Status(int32_t exceptionCode, int32_t errorCode, const String8& message);
+    Status(int32_t exceptionCode, int32_t errorCode, const char *message);
 
     // If |mException| == EX_TRANSACTION_FAILED, generated code will return
     // |mErrorCode| as the result of the transaction rather than write an
@@ -135,11 +135,11 @@
     // If |mException| == EX_SERVICE_SPECIFIC we write |mErrorCode| as well.
     int32_t mException = EX_NONE;
     int32_t mErrorCode = 0;
-    String8 mMessage;
+    std::string mMessage;
 };  // class Status
 
 // For gtest output logging
-std::stringstream& operator<< (std::stringstream& stream, const Status& s);
+std::ostream& operator<< (std::ostream& stream, const Status& s);
 
 namespace details {
     class return_status : public details::hidl_log_base {
@@ -169,6 +169,12 @@
             mCheckedStatus = true;
             return mStatus;
         }
+
+        // For debugging purposes only
+        std::string description() const {
+            // Doesn't consider checked.
+            return mStatus.description();
+        }
     };
 }  // namespace details
 
diff --git a/transport/Android.bp b/transport/Android.bp
index 4f97ff6..9b0fe2c 100644
--- a/transport/Android.bp
+++ b/transport/Android.bp
@@ -13,10 +13,11 @@
 // limitations under the License.
 
 subdirs = [
+    "base/1.0",
     "manager/1.0",
     "memory/1.0",
     "memory/1.0/default",
-    "base/1.0"
+    "token/1.0",
 ]
 
 cc_library_shared {
@@ -52,6 +53,7 @@
 
     srcs: [
         "HidlBinderSupport.cpp",
+        "HidlPassthroughSupport.cpp",
         "ServiceManagement.cpp",
         "Static.cpp"
     ],
diff --git a/transport/HidlPassthroughSupport.cpp b/transport/HidlPassthroughSupport.cpp
new file mode 100644
index 0000000..9d4e2b4
--- /dev/null
+++ b/transport/HidlPassthroughSupport.cpp
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2016 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 <hidl/HidlPassthroughSupport.h>
+
+#include <hidl/HidlSupport.h>
+#include <hidl/Static.h>
+#include <hidl/HidlTransportUtils.h>
+
+namespace android {
+namespace hardware {
+
+sp<::android::hidl::base::V1_0::IBase> wrapPassthrough(
+        sp<::android::hidl::base::V1_0::IBase> iface) {
+    if (iface.get() == nullptr || iface->isRemote()) {
+        // doesn't know how to handle it.
+        return iface;
+    }
+    std::string myDescriptor = getDescriptor(iface.get());
+    if (myDescriptor.empty()) {
+        // interfaceChain fails
+        return nullptr;
+    }
+    auto iter = gBsConstructorMap.find(myDescriptor);
+    if (iter == gBsConstructorMap.end()) {
+        return nullptr;
+    }
+    return (iter->second)(reinterpret_cast<void *>(iface.get()));
+}
+
+
+}  // namespace hardware
+}  // namespace android
diff --git a/transport/Static.cpp b/transport/Static.cpp
index ddda712..4a140e5 100644
--- a/transport/Static.cpp
+++ b/transport/Static.cpp
@@ -25,7 +25,11 @@
 Mutex gDefaultServiceManagerLock;
 sp<android::hidl::manager::V1_0::IServiceManager> gDefaultServiceManager;
 
-std::map<std::string, std::function<sp<IBinder>(void*)>> gBnConstructorMap{};
+std::map<std::string, std::function<sp<IBinder>(void *)>>
+        gBnConstructorMap{};
+
+std::map<std::string, std::function<sp<::android::hidl::base::V1_0::IBase>(void *)>>
+        gBsConstructorMap;
 
 }   // namespace hardware
 }   // namespace android
diff --git a/transport/base/1.0/IBase.hal b/transport/base/1.0/IBase.hal
index 379213a..d696249 100644
--- a/transport/base/1.0/IBase.hal
+++ b/transport/base/1.0/IBase.hal
@@ -54,4 +54,21 @@
      * tags).
      */
     oneway notifySyspropsChanged();
+
+    /*
+     * Registers a death recipient, to be called when the process hosting this
+     * interface dies.
+     *
+     * @param recipient a hidl_death_recipient callback object
+     * @param cookie a cookie that must be returned with the callback
+     * @return success whether the death recipient was registered successfully.
+     */
+    linkToDeath(death_recipient recipient, uint64_t cookie) generates (bool success);
+
+    /*
+     * Unregisters a previously registered death recipient.
+     * @param recipient a previously registered hidl_death_recipient callback
+     * @return success whether the death recipient was unregistered successfully.
+     */
+    unlinkToDeath(death_recipient recipient) generates (bool success);
 };
diff --git a/transport/include/hidl/HidlBinderSupport.h b/transport/include/hidl/HidlBinderSupport.h
index f906ea4..13b67fd 100644
--- a/transport/include/hidl/HidlBinderSupport.h
+++ b/transport/include/hidl/HidlBinderSupport.h
@@ -17,6 +17,7 @@
 #ifndef ANDROID_HIDL_BINDER_SUPPORT_H
 #define ANDROID_HIDL_BINDER_SUPPORT_H
 
+#include <android/hidl/base/1.0/IBase.h>
 #include <hidl/HidlSupport.h>
 #include <hidl/HidlTransportUtils.h>
 #include <hidl/MQDescriptor.h>
@@ -30,6 +31,29 @@
 namespace android {
 namespace hardware {
 
+// hidl_binder_death_recipient wraps a transport-independent
+// hidl_death_recipient, and implements the binder-specific
+// DeathRecipient interface.
+struct hidl_binder_death_recipient : IBinder::DeathRecipient {
+    hidl_binder_death_recipient(const sp<hidl_death_recipient> &recipient,
+            uint64_t cookie, const sp<::android::hidl::base::V1_0::IBase> &base) :
+        mRecipient(recipient), mCookie(cookie), mBase(base) {
+    }
+    virtual void binderDied(const wp<IBinder>& /*who*/) {
+        sp<hidl_death_recipient> recipient = mRecipient.promote();
+        if (recipient != nullptr) {
+            recipient->serviceDied(mCookie, mBase);
+        }
+    }
+    wp<hidl_death_recipient> getRecipient() {
+        return mRecipient;
+    }
+private:
+    wp<hidl_death_recipient> mRecipient;
+    uint64_t mCookie;
+    wp<::android::hidl::base::V1_0::IBase> mBase;
+};
+
 // ---------------------- hidl_memory
 
 status_t readEmbeddedFromParcel(hidl_memory *memory,
@@ -296,12 +320,7 @@
     if (ifacePtr->isRemote()) {
         return ::android::hardware::IInterface::asBinder(static_cast<ProxyType *>(ifacePtr));
     } else {
-        std::string myDescriptor{};
-        ifacePtr->interfaceChain([&](const hidl_vec<hidl_string> &types) {
-            if (types.size() > 0) {
-                myDescriptor = types[0].c_str();
-            }
-        });
+        std::string myDescriptor = getDescriptor(ifacePtr);
         if (myDescriptor.empty()) {
             // interfaceChain fails
             return nullptr;
@@ -334,91 +353,6 @@
     }
 }
 
-#define IMPLEMENT_SERVICE_MANAGER_INTERACTIONS(INTERFACE, PACKAGE)                       \
-    ::android::sp<I##INTERFACE> I##INTERFACE::getService(                                \
-            const std::string &serviceName, bool getStub)                                \
-    {                                                                                    \
-        using ::android::sp;                                                             \
-        using ::android::hardware::defaultServiceManager;                                \
-        using ::android::hidl::manager::V1_0::IServiceManager;                           \
-        sp<I##INTERFACE> iface;                                                          \
-        const sp<IServiceManager> sm = defaultServiceManager();                          \
-        if (sm != nullptr && !getStub) {                                                 \
-            sp<::android::hidl::base::V1_0::IBase> base;                                 \
-            ::android::hardware::Return<void> ret =                                      \
-                sm->get(PACKAGE "::I" #INTERFACE, serviceName.c_str(),                   \
-                    [&base](sp<::android::hidl::base::V1_0::IBase> found) {              \
-                        base = found;                                                    \
-                    });                                                                  \
-            if (ret.getStatus().isOk()) {                                                \
-                iface = I##INTERFACE::castFrom(base);                                    \
-                if (iface != nullptr) {                                                  \
-                    return iface;                                                        \
-                }                                                                        \
-            }                                                                            \
-        }                                                                                \
-        int dlMode = RTLD_LAZY;                                                          \
-        void *handle = dlopen(HAL_LIBRARY_PATH_ODM PACKAGE "-impl.so", dlMode);          \
-        if (handle == nullptr) {                                                         \
-            handle = dlopen(HAL_LIBRARY_PATH_VENDOR PACKAGE "-impl.so", dlMode);         \
-        }                                                                                \
-        if (handle == nullptr) {                                                         \
-            handle = dlopen(HAL_LIBRARY_PATH_SYSTEM PACKAGE "-impl.so", dlMode);         \
-        }                                                                                \
-        if (handle == nullptr) {                                                         \
-            return iface;                                                                \
-        }                                                                                \
-        I##INTERFACE* (*generator)(const char* name);                                    \
-        *(void **)(&generator) = dlsym(handle, "HIDL_FETCH_I"#INTERFACE);                \
-        if (generator) {                                                                 \
-            iface = (*generator)(serviceName.c_str());                                   \
-            if (iface != nullptr) {                                                      \
-                iface = new Bs##INTERFACE(iface);                                        \
-            }                                                                            \
-        }                                                                                \
-        return iface;                                                                    \
-    }                                                                                    \
-    ::android::status_t I##INTERFACE::registerAsService(                                 \
-            const std::string &serviceName)                                              \
-    {                                                                                    \
-        using ::android::sp;                                                             \
-        using ::android::hardware::defaultServiceManager;                                \
-        using ::android::hidl::manager::V1_0::IServiceManager;                           \
-        const sp<IServiceManager> sm = defaultServiceManager();                          \
-        if (sm == nullptr) {                                                             \
-            return ::android::INVALID_OPERATION;                                         \
-        }                                                                                \
-        bool success = false;                                                            \
-        ::android::hardware::Return<void> ret =                                          \
-            this->interfaceChain(                                                        \
-                [&success, &sm, &serviceName, this](const auto &chain) {                 \
-                    ::android::hardware::Return<bool> addRet =                           \
-                            sm->add(chain, serviceName.c_str(), this);                   \
-                    success = addRet.isOk() && addRet;                                   \
-                });                                                                      \
-        success = success && ret.getStatus().isOk();                                     \
-        return success ? ::android::OK : ::android::UNKNOWN_ERROR;                       \
-    }                                                                                    \
-    bool I##INTERFACE::registerForNotifications(                                         \
-            const std::string &serviceName,                                              \
-            const ::android::sp<::android::hidl::manager::V1_0::IServiceNotification>    \
-                      &notification)                                                     \
-    {                                                                                    \
-        using ::android::sp;                                                             \
-        using ::android::hardware::defaultServiceManager;                                \
-        using ::android::hidl::manager::V1_0::IServiceManager;                           \
-        const sp<IServiceManager> sm = defaultServiceManager();                          \
-        if (sm == nullptr) {                                                             \
-            return false;                                                                \
-        }                                                                                \
-        ::android::hardware::Return<bool> success =                                      \
-                sm->registerForNotifications(PACKAGE "::I" #INTERFACE,                   \
-                                             serviceName,                                \
-                                             notification);                              \
-        return success.isOk() && success;                                                \
-    }
-
-
 }  // namespace hardware
 }  // namespace android
 
diff --git a/transport/include/hidl/HidlPassthroughSupport.h b/transport/include/hidl/HidlPassthroughSupport.h
new file mode 100644
index 0000000..2b2f86b
--- /dev/null
+++ b/transport/include/hidl/HidlPassthroughSupport.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#ifndef ANDROID_HIDL_PASSTHROUGH_SUPPORT_H
+#define ANDROID_HIDL_PASSTHROUGH_SUPPORT_H
+
+#include <android/hidl/base/1.0/IBase.h>
+
+namespace android {
+namespace hardware {
+
+/*
+ * Wrap the given interface with the smallest BsChild possible. Will return the
+ * argument directly if nullptr or isRemote().
+ */
+sp<::android::hidl::base::V1_0::IBase> wrapPassthrough(
+        sp<::android::hidl::base::V1_0::IBase> iface);
+
+}  // namespace hardware
+}  // namespace android
+
+
+#endif  // ANDROID_HIDL_PASSTHROUGH_SUPPORT_H
diff --git a/transport/include/hidl/HidlTransportUtils.h b/transport/include/hidl/HidlTransportUtils.h
index d890988..dc444dc 100644
--- a/transport/include/hidl/HidlTransportUtils.h
+++ b/transport/include/hidl/HidlTransportUtils.h
@@ -31,7 +31,7 @@
     }
 
     bool canCast = false;
-    interface->interfaceChain([&](const hidl_vec<hidl_string> &types) {
+    auto ret = interface->interfaceChain([&](const hidl_vec<hidl_string> &types) {
         for (size_t i = 0; i < types.size(); i++) {
             if (types[i] == castTo) {
                 canCast = true;
@@ -39,7 +39,17 @@
             }
         }
     });
-    return canCast;
+    return ret.isOk() && canCast;
+}
+
+inline std::string getDescriptor(::android::hidl::base::V1_0::IBase* interface) {
+    std::string myDescriptor{};
+    auto ret = interface->interfaceChain([&](const hidl_vec<hidl_string> &types) {
+        if (types.size() > 0) {
+            myDescriptor = types[0].c_str();
+        }
+    });
+    return ret.isOk() ? myDescriptor : "";
 }
 
 }   // namespace hardware
diff --git a/transport/include/hidl/Static.h b/transport/include/hidl/Static.h
index 2a40125..1f6fa9f 100644
--- a/transport/include/hidl/Static.h
+++ b/transport/include/hidl/Static.h
@@ -32,7 +32,14 @@
 // For HidlBinderSupport
 // value function receives reinterpret_cast<void *>(static_cast<IFoo *>(foo)),
 // returns sp<IBinder>
-extern std::map<std::string, std::function<sp<IBinder>(void*)>> gBnConstructorMap;
+extern std::map<std::string, std::function<sp<IBinder>(void *)>>
+        gBnConstructorMap;
+
+// For HidlPassthroughSupport
+// value function receives reinterpret_cast<void *>(static_cast<IFoo *>(foo)),
+// returns sp<IBase>
+extern std::map<std::string, std::function<sp<::android::hidl::base::V1_0::IBase>(void *)>>
+        gBsConstructorMap;
 
 }   // namespace hardware
 }   // namespace android
diff --git a/transport/memory/1.0/default/Android.bp b/transport/memory/1.0/default/Android.bp
index 4bc24a2..2b89f07 100644
--- a/transport/memory/1.0/default/Android.bp
+++ b/transport/memory/1.0/default/Android.bp
@@ -16,7 +16,6 @@
     name: "android.hidl.memory@1.0-impl",
     relative_install_path: "hw",
     srcs: [
-        "AshmemAllocator.cpp",
         "AshmemMapper.cpp",
         "AshmemMemory.cpp",
         "HidlFetch.cpp"
@@ -39,7 +38,10 @@
 cc_binary {
     name: "android.hidl.memory@1.0-service",
     relative_install_path: "hw",
-    srcs: ["service.cpp"],
+    srcs: [
+        "AshmemAllocator.cpp",
+        "service.cpp"
+    ],
     init_rc: ["android.hidl.memory@1.0-service.rc"],
 
     shared_libs: [
@@ -48,8 +50,10 @@
         "libhidlbase",
         "libhidltransport",
         "libhwbinder",
+        "libbase",
         "liblog",
         "libutils",
+        "libcutils",
     ],
 
     required: [
diff --git a/transport/memory/1.0/default/HidlFetch.cpp b/transport/memory/1.0/default/HidlFetch.cpp
index 8236055..adb55d3 100644
--- a/transport/memory/1.0/default/HidlFetch.cpp
+++ b/transport/memory/1.0/default/HidlFetch.cpp
@@ -27,14 +27,6 @@
 namespace V1_0 {
 namespace implementation {
 
-IAllocator* HIDL_FETCH_IAllocator(const char* name) {
-    if (name == kAshmemMemoryName) {
-        return new AshmemAllocator;
-    }
-
-    return nullptr;
-}
-
 IMapper* HIDL_FETCH_IMapper(const char* name) {
     if (name == kAshmemMemoryName) {
         return new AshmemMapper;
diff --git a/transport/memory/1.0/default/HidlFetch.h b/transport/memory/1.0/default/HidlFetch.h
index a9d366f..389ca30 100644
--- a/transport/memory/1.0/default/HidlFetch.h
+++ b/transport/memory/1.0/default/HidlFetch.h
@@ -26,9 +26,6 @@
 namespace V1_0 {
 namespace implementation {
 
-// TODO: disable passthrough allocator. It's much better if it's in a centralized location
-extern "C" IAllocator* HIDL_FETCH_IAllocator(const char* name);
-
 extern "C" IMapper* HIDL_FETCH_IMapper(const char* name);
 
 }  // namespace implementation
diff --git a/transport/memory/1.0/default/service.cpp b/transport/memory/1.0/default/service.cpp
index ff3a8e8..8ea8b8a 100644
--- a/transport/memory/1.0/default/service.cpp
+++ b/transport/memory/1.0/default/service.cpp
@@ -1,12 +1,31 @@
 #define LOG_TAG "android.hidl.memory@1.0-service"
 
+#include "AshmemAllocator.h"
+
+#include <android-base/logging.h>
 #include <android/hidl/memory/1.0/IAllocator.h>
+#include <hwbinder/IPCThreadState.h>
+#include <hwbinder/ProcessState.h>
 
-#include <hidl/LegacySupport.h>
-
+using android::hardware::IPCThreadState;
+using android::hardware::ProcessState;
 using android::hidl::memory::V1_0::IAllocator;
-using android::hardware::defaultPassthroughServiceImplementation;
+using android::hidl::memory::V1_0::implementation::AshmemAllocator;
+using android::sp;
+using android::status_t;
 
 int main() {
-    return defaultPassthroughServiceImplementation<IAllocator>("ashmem");
+    sp<IAllocator> allocator = new AshmemAllocator();
+
+    status_t status = allocator->registerAsService("ashmem");
+
+    if (android::OK != status) {
+        LOG(FATAL) << "Unable to register allocator service: " << status;
+    }
+
+    ProcessState::self()->setThreadPoolMaxThreadCount(0);
+    ProcessState::self()->startThreadPool();
+    IPCThreadState::self()->joinThreadPool();
+
+    return -1;
 }
diff --git a/transport/token/1.0/Android.bp b/transport/token/1.0/Android.bp
new file mode 100644
index 0000000..0ebe1e4
--- /dev/null
+++ b/transport/token/1.0/Android.bp
@@ -0,0 +1,52 @@
+// This file is autogenerated by hidl-gen. Do not edit manually.
+
+genrule {
+    name: "android.hidl.token@1.0_genc++",
+    tools: ["hidl-gen"],
+    cmd: "$(location hidl-gen) -o $(genDir) -Lc++ -randroid.hidl:system/libhidl/transport -randroid.hidl:system/libhidl/transport android.hidl.token@1.0",
+    srcs: [
+        "ITokenManager.hal",
+    ],
+    out: [
+        "android/hidl/token/1.0/TokenManagerAll.cpp",
+    ],
+}
+
+genrule {
+    name: "android.hidl.token@1.0_genc++_headers",
+    tools: ["hidl-gen"],
+    cmd: "$(location hidl-gen) -o $(genDir) -Lc++ -randroid.hidl:system/libhidl/transport -randroid.hidl:system/libhidl/transport android.hidl.token@1.0",
+    srcs: [
+        "ITokenManager.hal",
+    ],
+    out: [
+        "android/hidl/token/1.0/ITokenManager.h",
+        "android/hidl/token/1.0/IHwTokenManager.h",
+        "android/hidl/token/1.0/BnTokenManager.h",
+        "android/hidl/token/1.0/BpTokenManager.h",
+        "android/hidl/token/1.0/BsTokenManager.h",
+    ],
+}
+
+cc_library_shared {
+    name: "android.hidl.token@1.0",
+    generated_sources: ["android.hidl.token@1.0_genc++"],
+    generated_headers: ["android.hidl.token@1.0_genc++_headers"],
+    export_generated_headers: ["android.hidl.token@1.0_genc++_headers"],
+    shared_libs: [
+        "libhidlbase",
+        "libhidltransport",
+        "libhwbinder",
+        "liblog",
+        "libutils",
+        "libcutils",
+        "android.hidl.base@1.0",
+    ],
+    export_shared_lib_headers: [
+        "libhidlbase",
+        "libhidltransport",
+        "libhwbinder",
+        "libutils",
+        "android.hidl.base@1.0",
+    ],
+}
diff --git a/transport/token/1.0/Android.mk b/transport/token/1.0/Android.mk
new file mode 100644
index 0000000..3d07671
--- /dev/null
+++ b/transport/token/1.0/Android.mk
@@ -0,0 +1,76 @@
+# This file is autogenerated by hidl-gen. Do not edit manually.
+
+LOCAL_PATH := $(call my-dir)
+
+################################################################################
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := android.hidl.token@1.0-java
+LOCAL_MODULE_CLASS := JAVA_LIBRARIES
+
+intermediates := $(local-generated-sources-dir)
+
+HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
+
+LOCAL_JAVA_LIBRARIES := \
+    android.hidl.base@1.0-java \
+
+
+#
+# Build ITokenManager.hal
+#
+GEN := $(intermediates)/android/hidl/token/V1_0/ITokenManager.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/ITokenManager.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava \
+        -randroid.hidl:system/libhidl/transport \
+        -randroid.hidl:system/libhidl/transport \
+        android.hidl.token@1.0::ITokenManager
+
+$(GEN): $(LOCAL_PATH)/ITokenManager.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+include $(BUILD_JAVA_LIBRARY)
+
+
+################################################################################
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := android.hidl.token@1.0-java-static
+LOCAL_MODULE_CLASS := JAVA_LIBRARIES
+
+intermediates := $(local-generated-sources-dir)
+
+HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
+
+LOCAL_STATIC_JAVA_LIBRARIES := \
+    android.hidl.base@1.0-java-static \
+
+
+#
+# Build ITokenManager.hal
+#
+GEN := $(intermediates)/android/hidl/token/V1_0/ITokenManager.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/ITokenManager.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava \
+        -randroid.hidl:system/libhidl/transport \
+        -randroid.hidl:system/libhidl/transport \
+        android.hidl.token@1.0::ITokenManager
+
+$(GEN): $(LOCAL_PATH)/ITokenManager.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+include $(BUILD_STATIC_JAVA_LIBRARY)
+
+
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/transport/token/1.0/ITokenManager.hal b/transport/token/1.0/ITokenManager.hal
new file mode 100644
index 0000000..dc4134a
--- /dev/null
+++ b/transport/token/1.0/ITokenManager.hal
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+package android.hidl.token@1.0;
+
+/**
+ * This facilitates converting hidl interfaces into something that
+ * are more easily transferrable to other processes.
+ */
+interface ITokenManager {
+
+    /**
+     * Register an interface. The server must only keep a weak reference
+     * to the token. The lifetime of the token is thus linked to the
+     * lifetime of the stored interface.
+     *
+     * @param store Interface which can later be fetched with the returned token.
+     * @return token Opaque value which may be used as inputs to other functions.
+     */
+    createToken(interface store) generates (uint64_t token);
+
+    /**
+     * Explicitly unregister an interface. If the server still holds a weak reference
+     * to an interface, but that interface interface is deleted and the reference
+     * cannot be promoted, then success must be false.
+     *
+     * @param token Token recieved from createToken
+     * @return success Whether or not an interface was successfully unregistered.
+     */
+    unregister(uint64_t token) generates (bool success);
+
+    /**
+     * Fetches an interface from a provided token.
+     *
+     * @param token Token recieved from createToken
+     * @return store Interface registered with createToken and the corresponding
+     *               token or nullptr.
+     */
+    get(uint64_t token) generates (interface store);
+};
diff --git a/update-makefiles.sh b/update-makefiles.sh
index 6a77a7d..3cd1cd2 100755
--- a/update-makefiles.sh
+++ b/update-makefiles.sh
@@ -6,14 +6,15 @@
   exit 1;
 fi
 
-#base
-hidl-gen -Lmakefile -r android.hidl:system/libhidl/transport android.hidl.base@1.0
-hidl-gen -Landroidbp -r android.hidl:system/libhidl/transport android.hidl.base@1.0
+packages=(
+    android.hidl.base@1.0
+    android.hidl.manager@1.0
+    android.hidl.memory@1.0
+    android.hidl.token@1.0
+)
 
-#manager
-hidl-gen -Lmakefile -r android.hidl:system/libhidl/transport android.hidl.manager@1.0
-hidl-gen -Landroidbp -r android.hidl:system/libhidl/transport android.hidl.manager@1.0
-
-#memory
-hidl-gen -Lmakefile -r android.hidl:system/libhidl/transport android.hidl.memory@1.0
-hidl-gen -Landroidbp -r android.hidl:system/libhidl/transport android.hidl.memory@1.0
+for package in "${packages[@]}"; do
+    echo "Updating $package."
+    hidl-gen -Lmakefile -r android.hidl:system/libhidl/transport $package
+    hidl-gen -Landroidbp -r android.hidl:system/libhidl/transport $package
+done