13bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa/*
23bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa * Copyright (C) 2017 The Android Open Source Project
33bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa *
43bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa * Licensed under the Apache License, Version 2.0 (the "License");
53bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa * you may not use this file except in compliance with the License.
63bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa * You may obtain a copy of the License at
73bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa *
83bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa *      http://www.apache.org/licenses/LICENSE-2.0
93bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa *
103bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa * Unless required by applicable law or agreed to in writing, software
113bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa * distributed under the License is distributed on an "AS IS" BASIS,
123bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa * See the License for the specific language governing permissions and
143bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa * limitations under the License.
153bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa */
163bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa
173bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa#ifndef ANDROID_HYBRIDINTERFACE_H
183bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa#define ANDROID_HYBRIDINTERFACE_H
193bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa
203bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa#include <vector>
213bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa#include <mutex>
223bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa
233bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa#include <binder/Parcel.h>
243bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa#include <hidl/HidlSupport.h>
253bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa
263bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa/**
273bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa * Hybrid Interfaces
283bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa * =================
293bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa *
303bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa * A hybrid interface is a binder interface that
313bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa * 1. is implemented both traditionally and as a wrapper around a hidl
323bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa *    interface, and allows querying whether the underlying instance comes from
333bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa *    a hidl interface or not; and
343bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa * 2. allows efficient calls to a hidl interface (if the underlying instance
353bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa *    comes from a hidl interface) by automatically creating the wrapper in the
363bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa *    process that calls it.
373bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa *
383bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa * Terminology:
393bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa * - `HalToken`: The type for a "token" of a hidl interface. This is defined to
403bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa *   be compatible with `ITokenManager.hal`.
413bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa * - `HInterface`: The base type for a hidl interface. Currently, it is defined
423bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa *   as `::android::hidl::base::V1_0::IBase`.
433bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa * - `HALINTERFACE`: The hidl interface that will be sent through binders.
443bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa * - `INTERFACE`: The binder interface that will be the wrapper of
453bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa *   `HALINTERFACE`. `INTERFACE` is supposed to be somewhat similar to
463bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa *   `HALINTERFACE`.
473bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa *
483bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa * To demonstrate how this is done, here is an example. Suppose `INTERFACE` is
493bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa * `IFoo` and `HALINTERFACE` is `HFoo`. The required steps are:
503bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa * 1. Use DECLARE_HYBRID_META_INTERFACE instead of DECLARE_META_INTERFACE in the
513bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa *    definition of `IFoo`. The usage is
523bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa *        DECLARE_HYBRID_META_INTERFACE(IFoo, HFoo)
533bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa *    inside the body of `IFoo`.
543bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa * 2. Create a converter class that derives from
553bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa *    `H2BConverter<HFoo, IFoo, BnFoo>`. Let us call this `H2BFoo`.
563bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa * 3. Add the following constructor in `H2BFoo` that call the corresponding
573bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa *    constructors in `H2BConverter`:
583bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa *        H2BFoo(const sp<HalInterface>& base) : CBase(base) {}
593bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa *    Note: `CBase = H2BConverter<HFoo, IFoo, BnFoo>` and `HalInterface = HFoo`
603bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa *    are member typedefs of `H2BConverter<HFoo, IFoo, BnFoo>`, so the above
613bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa *    line can be copied into `H2BFoo`.
623bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa * 4. Implement `IFoo` in `H2BFoo` on top of `HFoo`. `H2BConverter` provides a
633bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa *    protected `mBase` of type `sp<HFoo>` that can be used to access the `HFoo`
643bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa *    instance. (There is also a public function named `getHalInterface()` that
653bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa *    returns `mBase`.)
663bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa * 5. Create a hardware proxy class that derives from
673bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa *    `HpInterface<BpFoo, H2BFoo>`. Name this class `HpFoo`. (This name cannot
683bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa *    deviate. See step 8 below.)
693bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa * 6. Add the following constructor to `HpFoo`:
703bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa *        HpFoo(const sp<IBinder>& base): PBase(base) {}
713bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa *    Note: `PBase` a member typedef of `HpInterface<BpFoo, H2BFoo>` that is
723bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa *    equal to `HpInterface<BpFoo, H2BFoo>` itself, so the above line can be
733bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa *    copied verbatim into `HpFoo`.
743bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa * 7. Delegate all functions in `HpFoo` that come from `IFoo` except
753bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa *    `getHalInterface` to the protected member `mBase`,
763bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa *    which is defined in `HpInterface<BpFoo, H2BFoo>` (hence in `HpFoo`) with
773bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa *    type `IFoo`. (There is also a public function named `getBaseInterface()`
783bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa *    that returns `mBase`.)
793bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa * 8. Replace the existing `IMPLEMENT_META_INTERFACE` for INTERFACE by
803bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa *    `IMPLEMENT_HYBRID_META_INTERFACE`. Note that this macro relies on the
813bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa *    exact naming of `HpFoo`, where `Foo` comes from the interface name `IFoo`.
823bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa *    An example usage is
833bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa *        IMPLEMENT_HYBRID_META_INTERFACE(IFoo, HFoo, "example.interface.foo");
843bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa *
853bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa * `GETTOKEN` Template Argument
863bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa * ============================
873bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa *
883bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa * Following the instructions above, `H2BConverter` and `HpInterface` would use
893bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa * `transact()` to send over tokens, with `code` (the first argument of
903bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa * `transact()`) equal to `DEFAULT_GET_HAL_TOKEN_TRANSACTION_CODE`. If this
913bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa * value clashes with other values already in use in the `Bp` class, it can be
923bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa * changed by supplying the last optional template argument to `H2BConverter`
933bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa * and `HpInterface`.
943bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa *
953bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa */
963bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa
973bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasanamespace android {
983bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa
9915716d525cff9487897e0841fa47092a30293d92Steven Morelandtypedef ::android::hardware::hidl_vec<uint8_t> HalToken;
1003bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasatypedef ::android::hidl::base::V1_0::IBase HInterface;
1013bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa
1023bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasaconstexpr uint32_t DEFAULT_GET_HAL_TOKEN_TRANSACTION_CODE =
1033bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa        B_PACK_CHARS('_', 'G', 'H', 'T');
1043bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa
1053bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasasp<HInterface> retrieveHalInterface(const HalToken& token);
1063bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasabool createHalToken(const sp<HInterface>& interface, HalToken* token);
1073bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasabool deleteHalToken(const HalToken& token);
1083bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa
1093bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasatemplate <
1103bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa        typename HINTERFACE,
1113bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa        typename INTERFACE,
1123bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa        typename BNINTERFACE,
1133bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa        uint32_t GETTOKEN = DEFAULT_GET_HAL_TOKEN_TRANSACTION_CODE>
1143bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasaclass H2BConverter : public BNINTERFACE {
1153bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasapublic:
1163bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa    typedef H2BConverter<HINTERFACE, INTERFACE, BNINTERFACE, GETTOKEN> CBase; // Converter Base
1173bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa    typedef INTERFACE BaseInterface;
1183bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa    typedef HINTERFACE HalInterface;
1193bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa    static constexpr uint32_t GET_HAL_TOKEN = GETTOKEN;
1203bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa
1213bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa    H2BConverter(const sp<HalInterface>& base) : mBase(base) {}
1223bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa    virtual status_t onTransact(uint32_t code,
1233bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa            const Parcel& data, Parcel* reply, uint32_t flags = 0);
1243bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa    virtual sp<HalInterface> getHalInterface() { return mBase; }
1253bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa    HalInterface* getBaseInterface() { return mBase.get(); }
1263bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa    virtual status_t linkToDeath(
1273bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa            const sp<IBinder::DeathRecipient>& recipient,
1283bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa            void* cookie = NULL,
1293bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa            uint32_t flags = 0);
1303bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa    virtual status_t unlinkToDeath(
1313bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa            const wp<IBinder::DeathRecipient>& recipient,
1323bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa            void* cookie = NULL,
1333bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa            uint32_t flags = 0,
1343bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa            wp<IBinder::DeathRecipient>* outRecipient = NULL);
1353bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa
1363bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasaprotected:
1373bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa    sp<HalInterface> mBase;
1383bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa    struct Obituary : public hardware::hidl_death_recipient {
1393bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa        wp<IBinder::DeathRecipient> recipient;
1403bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa        void* cookie;
1413bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa        uint32_t flags;
1423bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa        wp<IBinder> who;
1433bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa        Obituary(
1443bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa                const wp<IBinder::DeathRecipient>& r,
1453bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa                void* c, uint32_t f,
1463bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa                const wp<IBinder>& w) :
1473bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa            recipient(r), cookie(c), flags(f), who(w) {
1483bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa        }
1493bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa        Obituary(const Obituary& o) :
1503bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa            recipient(o.recipient),
1513bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa            cookie(o.cookie),
1523bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa            flags(o.flags),
1533bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa            who(o.who) {
1543bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa        }
1553bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa        Obituary& operator=(const Obituary& o) {
1563bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa            recipient = o.recipient;
1573bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa            cookie = o.cookie;
1583bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa            flags = o.flags;
1593bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa            who = o.who;
1603bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa            return *this;
1613bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa        }
1623bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa        void serviceDied(uint64_t, const wp<HInterface>&) override {
1633bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa            sp<IBinder::DeathRecipient> dr = recipient.promote();
1643bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa            if (dr != nullptr) {
1653bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa                dr->binderDied(who);
1663bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa            }
1673bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa        }
1683bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa    };
1693bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa    std::mutex mObituariesLock;
1703bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa    std::vector<sp<Obituary> > mObituaries;
1713bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa};
1723bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa
1733bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasatemplate <
1743bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa        typename BPINTERFACE,
1753bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa        typename CONVERTER,
1763bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa        uint32_t GETTOKEN = DEFAULT_GET_HAL_TOKEN_TRANSACTION_CODE>
1773bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasaclass HpInterface : public CONVERTER::BaseInterface {
1783bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasapublic:
1793bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa    typedef HpInterface<BPINTERFACE, CONVERTER, GETTOKEN> PBase; // Proxy Base
1803bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa    typedef typename CONVERTER::BaseInterface BaseInterface;
1813bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa    typedef typename CONVERTER::HalInterface HalInterface;
1823bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa    static constexpr uint32_t GET_HAL_TOKEN = GETTOKEN;
1833bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa
1843bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa    explicit HpInterface(const sp<IBinder>& impl);
1853bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa    virtual sp<HalInterface> getHalInterface() { return mHal; }
1863bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa    BaseInterface* getBaseInterface() { return mBase.get(); }
1873bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa
1883bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasaprotected:
1893bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa    IBinder* mImpl;
1903bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa    sp<BPINTERFACE> mBp;
1913bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa    sp<BaseInterface> mBase;
1923bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa    sp<HalInterface> mHal;
1933bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa    IBinder* onAsBinder() override { return mImpl; }
1943bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa};
1953bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa
1963bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa// ----------------------------------------------------------------------
1973bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa
1983bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa#define DECLARE_HYBRID_META_INTERFACE(INTERFACE, HAL)                   \
1993bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa    static const ::android::String16 descriptor;                        \
2003bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa    static ::android::sp<I##INTERFACE> asInterface(                     \
2013bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa            const ::android::sp<::android::IBinder>& obj);              \
2023bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa    virtual const ::android::String16& getInterfaceDescriptor() const;  \
2033bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa    I##INTERFACE();                                                     \
2043bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa    virtual ~I##INTERFACE();                                            \
2053bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa    virtual sp<HAL> getHalInterface();                                  \
2063bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa
2073bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa
2083bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa#define IMPLEMENT_HYBRID_META_INTERFACE(INTERFACE, HAL, NAME)           \
2093bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa    const ::android::String16 I##INTERFACE::descriptor(NAME);           \
2103bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa    const ::android::String16&                                          \
2113bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa            I##INTERFACE::getInterfaceDescriptor() const {              \
2123bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa        return I##INTERFACE::descriptor;                                \
2133bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa    }                                                                   \
2143bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa    ::android::sp<I##INTERFACE> I##INTERFACE::asInterface(              \
2153bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa            const ::android::sp<::android::IBinder>& obj)               \
2163bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa    {                                                                   \
2173bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa        ::android::sp<I##INTERFACE> intr;                               \
2183bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa        if (obj != NULL) {                                              \
2193bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa            intr = static_cast<I##INTERFACE*>(                          \
2203bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa                obj->queryLocalInterface(                               \
2213bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa                        I##INTERFACE::descriptor).get());               \
2223bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa            if (intr == NULL) {                                         \
2233bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa                intr = new Hp##INTERFACE(obj);                          \
2243bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa            }                                                           \
2253bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa        }                                                               \
2263bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa        return intr;                                                    \
2273bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa    }                                                                   \
2283bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa    I##INTERFACE::I##INTERFACE() { }                                    \
2293bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa    I##INTERFACE::~I##INTERFACE() { }                                   \
2303bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa    sp<HAL> I##INTERFACE::getHalInterface() { return nullptr; }         \
2313bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa
2323bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa// ----------------------------------------------------------------------
2333bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa
2343bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasatemplate <
2353bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa        typename HINTERFACE,
2363bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa        typename INTERFACE,
2373bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa        typename BNINTERFACE,
2383bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa        uint32_t GETTOKEN>
2393bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasastatus_t H2BConverter<HINTERFACE, INTERFACE, BNINTERFACE, GETTOKEN>::
2403bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa        onTransact(
2413bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa        uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
2423bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa    if (code == GET_HAL_TOKEN) {
2433bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa        HalToken token;
2443bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa        bool result;
2453bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa        result = createHalToken(mBase, &token);
2463bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa        if (!result) {
2473bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa            ALOGE("H2BConverter: Failed to create HAL token.");
2483bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa        }
2493bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa        reply->writeBool(result);
25015716d525cff9487897e0841fa47092a30293d92Steven Moreland        reply->writeByteArray(token.size(), token.data());
2513bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa        return NO_ERROR;
2523bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa    }
2533bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa    return BNINTERFACE::onTransact(code, data, reply, flags);
2543bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa}
2553bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa
2563bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasatemplate <
2573bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa        typename HINTERFACE,
2583bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa        typename INTERFACE,
2593bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa        typename BNINTERFACE,
2603bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa        uint32_t GETTOKEN>
2613bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasastatus_t H2BConverter<HINTERFACE, INTERFACE, BNINTERFACE, GETTOKEN>::
2623bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa        linkToDeath(
2633bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa        const sp<IBinder::DeathRecipient>& recipient,
2643bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa        void* cookie, uint32_t flags) {
2653bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa    LOG_ALWAYS_FATAL_IF(recipient == NULL,
2663bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa            "linkToDeath(): recipient must be non-NULL");
2673bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa    {
2683bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa        std::lock_guard<std::mutex> lock(mObituariesLock);
2693bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa        mObituaries.push_back(new Obituary(recipient, cookie, flags, this));
2703bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa        if (!mBase->linkToDeath(mObituaries.back(), 0)) {
2713bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa           return DEAD_OBJECT;
2723bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa        }
2733bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa    }
2743bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa    return NO_ERROR;
2753bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa}
2763bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa
2773bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasatemplate <
2783bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa        typename HINTERFACE,
2793bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa        typename INTERFACE,
2803bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa        typename BNINTERFACE,
2813bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa        uint32_t GETTOKEN>
2823bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasastatus_t H2BConverter<HINTERFACE, INTERFACE, BNINTERFACE, GETTOKEN>::
2833bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa        unlinkToDeath(
2843bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa        const wp<IBinder::DeathRecipient>& recipient,
2853bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa        void* cookie, uint32_t flags,
2863bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa        wp<IBinder::DeathRecipient>* outRecipient) {
2873bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa    std::lock_guard<std::mutex> lock(mObituariesLock);
2883bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa    for (auto i = mObituaries.begin(); i != mObituaries.end(); ++i) {
2893bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa        if ((flags = (*i)->flags) && (
2903bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa                (recipient == (*i)->recipient) ||
2913bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa                ((recipient == nullptr) && (cookie == (*i)->cookie)))) {
2923bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa            if (outRecipient != nullptr) {
2933bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa                *outRecipient = (*i)->recipient;
2943bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa            }
2953bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa            bool success = mBase->unlinkToDeath(*i);
2963bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa            mObituaries.erase(i);
2973bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa            return success ? NO_ERROR : DEAD_OBJECT;
2983bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa        }
2993bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa    }
3003bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa    return NAME_NOT_FOUND;
3013bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa}
3023bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa
3033bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasatemplate <typename BPINTERFACE, typename CONVERTER, uint32_t GETTOKEN>
3043bfdaf1353af049316e57685c20e4f724037ce8ePawin VongmasaHpInterface<BPINTERFACE, CONVERTER, GETTOKEN>::HpInterface(
3053bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa        const sp<IBinder>& impl) :
3063bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa    mImpl(impl.get()),
3073bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa    mBp(new BPINTERFACE(impl)) {
3083bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa    mBase = mBp;
3093bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa    if (mImpl->remoteBinder() == nullptr) {
3103bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa        return;
3113bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa    }
3123bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa    Parcel data, reply;
3133bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa    data.writeInterfaceToken(BaseInterface::getInterfaceDescriptor());
3143bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa    if (mImpl->transact(GET_HAL_TOKEN, data, &reply) == NO_ERROR) {
3153bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa        bool tokenCreated = reply.readBool();
31615716d525cff9487897e0841fa47092a30293d92Steven Moreland
31715716d525cff9487897e0841fa47092a30293d92Steven Moreland        std::vector<uint8_t> tokenVector;
31815716d525cff9487897e0841fa47092a30293d92Steven Moreland        reply.readByteVector(&tokenVector);
31915716d525cff9487897e0841fa47092a30293d92Steven Moreland        HalToken token = HalToken(tokenVector);
32015716d525cff9487897e0841fa47092a30293d92Steven Moreland
3213bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa        if (tokenCreated) {
3223bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa            sp<HInterface> hBase = retrieveHalInterface(token);
3233bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa            if (hBase != nullptr) {
3243bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa                mHal = HalInterface::castFrom(hBase);
3253bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa                if (mHal != nullptr) {
3263bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa                    mBase = new CONVERTER(mHal);
3273bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa                } else {
3283bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa                    ALOGE("HpInterface: Wrong interface type.");
3293bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa                }
3303bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa            } else {
3313bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa                ALOGE("HpInterface: Invalid HAL token.");
3323bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa            }
3333bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa            deleteHalToken(token);
3343bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa        }
3353bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa    }
3363bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa}
3373bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa
3383bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa// ----------------------------------------------------------------------
3393bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa
3403bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa}; // namespace android
3413bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa
3423bfdaf1353af049316e57685c20e4f724037ce8ePawin Vongmasa#endif // ANDROID_HYBRIDINTERFACE_H
343