diff --git a/base/HidlSupport.cpp b/base/HidlSupport.cpp
index e97797d..91c9717 100644
--- a/base/HidlSupport.cpp
+++ b/base/HidlSupport.cpp
@@ -147,6 +147,7 @@
 }
 
 void hidl_handle::setTo(native_handle_t* handle, bool shouldOwn) {
+    freeHandle();
     mHandle = handle;
     mOwnsHandle = shouldOwn;
 }
diff --git a/manifest.xml b/manifest.xml
index 8f80d90..8dc9304 100644
--- a/manifest.xml
+++ b/manifest.xml
@@ -26,4 +26,13 @@
             <instance>ashmem</instance>
         </interface>
     </hal>
+    <hal>
+        <name>android.frameworks.sensorservice</name>
+        <transport>hwbinder</transport>
+        <version>1.0</version>
+        <interface>
+            <name>ISensorManager</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
 </manifest>
diff --git a/transport/Android.bp b/transport/Android.bp
index 1c1a310..f81d9c6 100644
--- a/transport/Android.bp
+++ b/transport/Android.bp
@@ -20,6 +20,7 @@
     "memory/1.0",
     "memory/1.0/default",
     "token/1.0",
+    "token/1.0/utils",
 ]
 
 cc_library_shared {
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
