diff --git a/transport/token/1.0/utils/Android.bp b/transport/token/1.0/utils/Android.bp
new file mode 100644
index 0000000..0360d99
--- /dev/null
+++ b/transport/token/1.0/utils/Android.bp
@@ -0,0 +1,41 @@
+// Copyright (C) 2017 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: "android.hidl.token@1.0-utils",
+
+    srcs: [
+        "HybridInterface.cpp",
+    ],
+
+    shared_libs: [
+        "libutils",
+        "libbinder",
+        "liblog",
+        "libhidlbase",
+        "android.hidl.token@1.0",
+    ],
+
+    export_shared_lib_headers: [
+        "libbinder",
+        "libhidlbase",
+    ],
+
+    export_include_dirs: [
+        "include"
+    ],
+
+    clang: true,
+}
+
diff --git a/transport/token/1.0/utils/HybridInterface.cpp b/transport/token/1.0/utils/HybridInterface.cpp
new file mode 100644
index 0000000..f28446e
--- /dev/null
+++ b/transport/token/1.0/utils/HybridInterface.cpp
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#define LOG_TAG "HybridInterface"
+
+#include <utils/Log.h>
+#include <hidl/HybridInterface.h>
+#include <hidl/HidlSupport.h>
+#include <android/hidl/token/1.0/ITokenManager.h>
+
+namespace android {
+
+using ::android::hidl::token::V1_0::ITokenManager;
+
+namespace {
+
+std::mutex gTokenManagerLock;
+sp<ITokenManager> gTokenManager = nullptr;
+
+struct TokenManagerDeathRecipient : public hardware::hidl_death_recipient {
+    void serviceDied(uint64_t, const wp<HInterface>&) {
+        std::lock_guard<std::mutex> lock(gTokenManagerLock);
+        gTokenManager = nullptr;
+    }
+};
+
+sp<TokenManagerDeathRecipient> gTokenManagerDeathRecipient =
+    new TokenManagerDeathRecipient();
+
+bool isBadTokenManager() {
+    if (gTokenManager != nullptr) {
+        return false;
+    }
+    gTokenManager = ITokenManager::getService();
+    if (gTokenManager == nullptr) {
+        ALOGE("Cannot retrieve TokenManager.");
+        return true;
+    }
+    auto transaction = gTokenManager->linkToDeath(
+            gTokenManagerDeathRecipient, 0);
+    if (!transaction.isOk()) {
+        ALOGE("Cannot observe TokenManager's death.");
+        gTokenManager = nullptr;
+        return true;
+    }
+    return false;
+}
+
+template <typename ReturnType>
+bool isBadTransaction(hardware::Return<ReturnType>& transaction) {
+    if (transaction.isOk()) {
+        return false;
+    }
+    ALOGE("TokenManager's transaction error: %s",
+            transaction.description().c_str());
+    gTokenManager->unlinkToDeath(gTokenManagerDeathRecipient).isOk();
+    gTokenManager = nullptr;
+    return true;
+}
+
+} // unnamed namespace
+
+sp<HInterface> retrieveHalInterface(const HalToken& token) {
+    hardware::Return<sp<HInterface> > transaction(nullptr);
+    {
+        std::lock_guard<std::mutex> lock(gTokenManagerLock);
+        if (isBadTokenManager()) {
+            return nullptr;
+        }
+        transaction = gTokenManager->get(token);
+        if (isBadTransaction(transaction)) {
+            return nullptr;
+        }
+    }
+    return static_cast<sp<HInterface> >(transaction);
+}
+
+bool createHalToken(const sp<HInterface>& interface, HalToken* token) {
+    hardware::Return<HalToken> transaction(false);
+    {
+        std::lock_guard<std::mutex> lock(gTokenManagerLock);
+        if (isBadTokenManager()) {
+            return false;
+        }
+        transaction = gTokenManager->createToken(interface);
+        if (isBadTransaction(transaction)) {
+            return false;
+        }
+    }
+    *token = static_cast<HalToken>(transaction);
+    return true;
+}
+
+bool deleteHalToken(const HalToken& token) {
+    hardware::Return<bool> transaction(false);
+    {
+        std::lock_guard<std::mutex> lock(gTokenManagerLock);
+        if (isBadTokenManager()) {
+            return false;
+        }
+        transaction = gTokenManager->unregister(token);
+        if (isBadTransaction(transaction)) {
+            return false;
+        }
+    }
+    return static_cast<bool>(transaction);
+}
+
+}; // namespace android
+
diff --git a/transport/token/1.0/utils/include/hidl/HybridInterface.h b/transport/token/1.0/utils/include/hidl/HybridInterface.h
new file mode 100644
index 0000000..42d3734
--- /dev/null
+++ b/transport/token/1.0/utils/include/hidl/HybridInterface.h
@@ -0,0 +1,338 @@
+/*
+ * Copyright (C) 2017 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_HYBRIDINTERFACE_H
+#define ANDROID_HYBRIDINTERFACE_H
+
+#include <vector>
+#include <mutex>
+
+#include <binder/Parcel.h>
+#include <hidl/HidlSupport.h>
+
+/**
+ * Hybrid Interfaces
+ * =================
+ *
+ * A hybrid interface is a binder interface that
+ * 1. is implemented both traditionally and as a wrapper around a hidl
+ *    interface, and allows querying whether the underlying instance comes from
+ *    a hidl interface or not; and
+ * 2. allows efficient calls to a hidl interface (if the underlying instance
+ *    comes from a hidl interface) by automatically creating the wrapper in the
+ *    process that calls it.
+ *
+ * Terminology:
+ * - `HalToken`: The type for a "token" of a hidl interface. This is defined to
+ *   be compatible with `ITokenManager.hal`.
+ * - `HInterface`: The base type for a hidl interface. Currently, it is defined
+ *   as `::android::hidl::base::V1_0::IBase`.
+ * - `HALINTERFACE`: The hidl interface that will be sent through binders.
+ * - `INTERFACE`: The binder interface that will be the wrapper of
+ *   `HALINTERFACE`. `INTERFACE` is supposed to be somewhat similar to
+ *   `HALINTERFACE`.
+ *
+ * To demonstrate how this is done, here is an example. Suppose `INTERFACE` is
+ * `IFoo` and `HALINTERFACE` is `HFoo`. The required steps are:
+ * 1. Use DECLARE_HYBRID_META_INTERFACE instead of DECLARE_META_INTERFACE in the
+ *    definition of `IFoo`. The usage is
+ *        DECLARE_HYBRID_META_INTERFACE(IFoo, HFoo)
+ *    inside the body of `IFoo`.
+ * 2. Create a converter class that derives from
+ *    `H2BConverter<HFoo, IFoo, BnFoo>`. Let us call this `H2BFoo`.
+ * 3. Add the following constructor in `H2BFoo` that call the corresponding
+ *    constructors in `H2BConverter`:
+ *        H2BFoo(const sp<HalInterface>& base) : CBase(base) {}
+ *    Note: `CBase = H2BConverter<HFoo, IFoo, BnFoo>` and `HalInterface = HFoo`
+ *    are member typedefs of `H2BConverter<HFoo, IFoo, BnFoo>`, so the above
+ *    line can be copied into `H2BFoo`.
+ * 4. Implement `IFoo` in `H2BFoo` on top of `HFoo`. `H2BConverter` provides a
+ *    protected `mBase` of type `sp<HFoo>` that can be used to access the `HFoo`
+ *    instance. (There is also a public function named `getHalInterface()` that
+ *    returns `mBase`.)
+ * 5. Create a hardware proxy class that derives from
+ *    `HpInterface<BpFoo, H2BFoo>`. Name this class `HpFoo`. (This name cannot
+ *    deviate. See step 8 below.)
+ * 6. Add the following constructor to `HpFoo`:
+ *        HpFoo(const sp<IBinder>& base): PBase(base) {}
+ *    Note: `PBase` a member typedef of `HpInterface<BpFoo, H2BFoo>` that is
+ *    equal to `HpInterface<BpFoo, H2BFoo>` itself, so the above line can be
+ *    copied verbatim into `HpFoo`.
+ * 7. Delegate all functions in `HpFoo` that come from `IFoo` except
+ *    `getHalInterface` to the protected member `mBase`,
+ *    which is defined in `HpInterface<BpFoo, H2BFoo>` (hence in `HpFoo`) with
+ *    type `IFoo`. (There is also a public function named `getBaseInterface()`
+ *    that returns `mBase`.)
+ * 8. Replace the existing `IMPLEMENT_META_INTERFACE` for INTERFACE by
+ *    `IMPLEMENT_HYBRID_META_INTERFACE`. Note that this macro relies on the
+ *    exact naming of `HpFoo`, where `Foo` comes from the interface name `IFoo`.
+ *    An example usage is
+ *        IMPLEMENT_HYBRID_META_INTERFACE(IFoo, HFoo, "example.interface.foo");
+ *
+ * `GETTOKEN` Template Argument
+ * ============================
+ *
+ * Following the instructions above, `H2BConverter` and `HpInterface` would use
+ * `transact()` to send over tokens, with `code` (the first argument of
+ * `transact()`) equal to `DEFAULT_GET_HAL_TOKEN_TRANSACTION_CODE`. If this
+ * value clashes with other values already in use in the `Bp` class, it can be
+ * changed by supplying the last optional template argument to `H2BConverter`
+ * and `HpInterface`.
+ *
+ */
+
+namespace android {
+
+typedef uint64_t HalToken;
+typedef ::android::hidl::base::V1_0::IBase HInterface;
+
+constexpr uint32_t DEFAULT_GET_HAL_TOKEN_TRANSACTION_CODE =
+        B_PACK_CHARS('_', 'G', 'H', 'T');
+
+sp<HInterface> retrieveHalInterface(const HalToken& token);
+bool createHalToken(const sp<HInterface>& interface, HalToken* token);
+bool deleteHalToken(const HalToken& token);
+
+template <
+        typename HINTERFACE,
+        typename INTERFACE,
+        typename BNINTERFACE,
+        uint32_t GETTOKEN = DEFAULT_GET_HAL_TOKEN_TRANSACTION_CODE>
+class H2BConverter : public BNINTERFACE {
+public:
+    typedef H2BConverter<HINTERFACE, INTERFACE, BNINTERFACE, GETTOKEN> CBase; // Converter Base
+    typedef INTERFACE BaseInterface;
+    typedef HINTERFACE HalInterface;
+    static constexpr uint32_t GET_HAL_TOKEN = GETTOKEN;
+
+    H2BConverter(const sp<HalInterface>& base) : mBase(base) {}
+    virtual status_t onTransact(uint32_t code,
+            const Parcel& data, Parcel* reply, uint32_t flags = 0);
+    virtual sp<HalInterface> getHalInterface() { return mBase; }
+    HalInterface* getBaseInterface() { return mBase.get(); }
+    virtual status_t linkToDeath(
+            const sp<IBinder::DeathRecipient>& recipient,
+            void* cookie = NULL,
+            uint32_t flags = 0);
+    virtual status_t unlinkToDeath(
+            const wp<IBinder::DeathRecipient>& recipient,
+            void* cookie = NULL,
+            uint32_t flags = 0,
+            wp<IBinder::DeathRecipient>* outRecipient = NULL);
+
+protected:
+    sp<HalInterface> mBase;
+    struct Obituary : public hardware::hidl_death_recipient {
+        wp<IBinder::DeathRecipient> recipient;
+        void* cookie;
+        uint32_t flags;
+        wp<IBinder> who;
+        Obituary(
+                const wp<IBinder::DeathRecipient>& r,
+                void* c, uint32_t f,
+                const wp<IBinder>& w) :
+            recipient(r), cookie(c), flags(f), who(w) {
+        }
+        Obituary(const Obituary& o) :
+            recipient(o.recipient),
+            cookie(o.cookie),
+            flags(o.flags),
+            who(o.who) {
+        }
+        Obituary& operator=(const Obituary& o) {
+            recipient = o.recipient;
+            cookie = o.cookie;
+            flags = o.flags;
+            who = o.who;
+            return *this;
+        }
+        void serviceDied(uint64_t, const wp<HInterface>&) override {
+            sp<IBinder::DeathRecipient> dr = recipient.promote();
+            if (dr != nullptr) {
+                dr->binderDied(who);
+            }
+        }
+    };
+    std::mutex mObituariesLock;
+    std::vector<sp<Obituary> > mObituaries;
+};
+
+template <
+        typename BPINTERFACE,
+        typename CONVERTER,
+        uint32_t GETTOKEN = DEFAULT_GET_HAL_TOKEN_TRANSACTION_CODE>
+class HpInterface : public CONVERTER::BaseInterface {
+public:
+    typedef HpInterface<BPINTERFACE, CONVERTER, GETTOKEN> PBase; // Proxy Base
+    typedef typename CONVERTER::BaseInterface BaseInterface;
+    typedef typename CONVERTER::HalInterface HalInterface;
+    static constexpr uint32_t GET_HAL_TOKEN = GETTOKEN;
+
+    explicit HpInterface(const sp<IBinder>& impl);
+    virtual sp<HalInterface> getHalInterface() { return mHal; }
+    BaseInterface* getBaseInterface() { return mBase.get(); }
+
+protected:
+    IBinder* mImpl;
+    sp<BPINTERFACE> mBp;
+    sp<BaseInterface> mBase;
+    sp<HalInterface> mHal;
+    IBinder* onAsBinder() override { return mImpl; }
+};
+
+// ----------------------------------------------------------------------
+
+#define DECLARE_HYBRID_META_INTERFACE(INTERFACE, HAL)                   \
+    static const ::android::String16 descriptor;                        \
+    static ::android::sp<I##INTERFACE> asInterface(                     \
+            const ::android::sp<::android::IBinder>& obj);              \
+    virtual const ::android::String16& getInterfaceDescriptor() const;  \
+    I##INTERFACE();                                                     \
+    virtual ~I##INTERFACE();                                            \
+    virtual sp<HAL> getHalInterface();                                  \
+
+
+#define IMPLEMENT_HYBRID_META_INTERFACE(INTERFACE, HAL, NAME)           \
+    const ::android::String16 I##INTERFACE::descriptor(NAME);           \
+    const ::android::String16&                                          \
+            I##INTERFACE::getInterfaceDescriptor() const {              \
+        return I##INTERFACE::descriptor;                                \
+    }                                                                   \
+    ::android::sp<I##INTERFACE> I##INTERFACE::asInterface(              \
+            const ::android::sp<::android::IBinder>& obj)               \
+    {                                                                   \
+        ::android::sp<I##INTERFACE> intr;                               \
+        if (obj != NULL) {                                              \
+            intr = static_cast<I##INTERFACE*>(                          \
+                obj->queryLocalInterface(                               \
+                        I##INTERFACE::descriptor).get());               \
+            if (intr == NULL) {                                         \
+                intr = new Hp##INTERFACE(obj);                          \
+            }                                                           \
+        }                                                               \
+        return intr;                                                    \
+    }                                                                   \
+    I##INTERFACE::I##INTERFACE() { }                                    \
+    I##INTERFACE::~I##INTERFACE() { }                                   \
+    sp<HAL> I##INTERFACE::getHalInterface() { return nullptr; }         \
+
+// ----------------------------------------------------------------------
+
+template <
+        typename HINTERFACE,
+        typename INTERFACE,
+        typename BNINTERFACE,
+        uint32_t GETTOKEN>
+status_t H2BConverter<HINTERFACE, INTERFACE, BNINTERFACE, GETTOKEN>::
+        onTransact(
+        uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
+    if (code == GET_HAL_TOKEN) {
+        HalToken token;
+        bool result;
+        result = createHalToken(mBase, &token);
+        if (!result) {
+            ALOGE("H2BConverter: Failed to create HAL token.");
+        }
+        reply->writeBool(result);
+        reply->writeUint64(token);
+        return NO_ERROR;
+    }
+    return BNINTERFACE::onTransact(code, data, reply, flags);
+}
+
+template <
+        typename HINTERFACE,
+        typename INTERFACE,
+        typename BNINTERFACE,
+        uint32_t GETTOKEN>
+status_t H2BConverter<HINTERFACE, INTERFACE, BNINTERFACE, GETTOKEN>::
+        linkToDeath(
+        const sp<IBinder::DeathRecipient>& recipient,
+        void* cookie, uint32_t flags) {
+    LOG_ALWAYS_FATAL_IF(recipient == NULL,
+            "linkToDeath(): recipient must be non-NULL");
+    {
+        std::lock_guard<std::mutex> lock(mObituariesLock);
+        mObituaries.push_back(new Obituary(recipient, cookie, flags, this));
+        if (!mBase->linkToDeath(mObituaries.back(), 0)) {
+           return DEAD_OBJECT;
+        }
+    }
+    return NO_ERROR;
+}
+
+template <
+        typename HINTERFACE,
+        typename INTERFACE,
+        typename BNINTERFACE,
+        uint32_t GETTOKEN>
+status_t H2BConverter<HINTERFACE, INTERFACE, BNINTERFACE, GETTOKEN>::
+        unlinkToDeath(
+        const wp<IBinder::DeathRecipient>& recipient,
+        void* cookie, uint32_t flags,
+        wp<IBinder::DeathRecipient>* outRecipient) {
+    std::lock_guard<std::mutex> lock(mObituariesLock);
+    for (auto i = mObituaries.begin(); i != mObituaries.end(); ++i) {
+        if ((flags = (*i)->flags) && (
+                (recipient == (*i)->recipient) ||
+                ((recipient == nullptr) && (cookie == (*i)->cookie)))) {
+            if (outRecipient != nullptr) {
+                *outRecipient = (*i)->recipient;
+            }
+            bool success = mBase->unlinkToDeath(*i);
+            mObituaries.erase(i);
+            return success ? NO_ERROR : DEAD_OBJECT;
+        }
+    }
+    return NAME_NOT_FOUND;
+}
+
+template <typename BPINTERFACE, typename CONVERTER, uint32_t GETTOKEN>
+HpInterface<BPINTERFACE, CONVERTER, GETTOKEN>::HpInterface(
+        const sp<IBinder>& impl) :
+    mImpl(impl.get()),
+    mBp(new BPINTERFACE(impl)) {
+    mBase = mBp;
+    if (mImpl->remoteBinder() == nullptr) {
+        return;
+    }
+    Parcel data, reply;
+    data.writeInterfaceToken(BaseInterface::getInterfaceDescriptor());
+    if (mImpl->transact(GET_HAL_TOKEN, data, &reply) == NO_ERROR) {
+        bool tokenCreated = reply.readBool();
+        HalToken token = reply.readUint64();
+        if (tokenCreated) {
+            sp<HInterface> hBase = retrieveHalInterface(token);
+            if (hBase != nullptr) {
+                mHal = HalInterface::castFrom(hBase);
+                if (mHal != nullptr) {
+                    mBase = new CONVERTER(mHal);
+                } else {
+                    ALOGE("HpInterface: Wrong interface type.");
+                }
+            } else {
+                ALOGE("HpInterface: Invalid HAL token.");
+            }
+            deleteHalToken(token);
+        }
+    }
+}
+
+// ----------------------------------------------------------------------
+
+}; // namespace android
+
+#endif // ANDROID_HYBRIDINTERFACE_H
