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 3fe38e7..c4fd16f 100644
--- a/manifest.xml
+++ b/manifest.xml
@@ -35,4 +35,13 @@
             <instance>default</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
