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