1 /* 2 * Copyright (C) 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef ANDROID_CAMERA_HYBRIDINTERFACE_H 18 #define ANDROID_CAMERA_HYBRIDINTERFACE_H 19 20 #include <vector> 21 #include <mutex> 22 23 #include <binder/Parcel.h> 24 #include <hidl/HidlSupport.h> 25 26 namespace android { 27 namespace camerahybrid { 28 typedef ::android::hidl::base::V1_0::IBase HInterface; 29 30 template < 31 typename HINTERFACE, 32 typename INTERFACE, 33 typename BNINTERFACE > 34 class H2BConverter : public BNINTERFACE { 35 public: 36 typedef H2BConverter<HINTERFACE, INTERFACE, BNINTERFACE> CBase; // Converter Base 37 typedef INTERFACE BaseInterface; 38 typedef HINTERFACE HalInterface; 39 H2BConverter(const sp<HalInterface> & base)40 H2BConverter(const sp<HalInterface>& base) : mBase(base) {} getHalInterface()41 virtual sp<HalInterface> getHalInterface() { return mBase; } 42 virtual status_t linkToDeath( 43 const sp<IBinder::DeathRecipient>& recipient, 44 void* cookie = nullptr, 45 uint32_t flags = 0); 46 virtual status_t unlinkToDeath( 47 const wp<IBinder::DeathRecipient>& recipient, 48 void* cookie = nullptr, 49 uint32_t flags = 0, 50 wp<IBinder::DeathRecipient>* outRecipient = nullptr); 51 52 protected: 53 sp<HalInterface> mBase; 54 struct Obituary : public hardware::hidl_death_recipient { 55 wp<IBinder::DeathRecipient> recipient; 56 void* cookie; 57 uint32_t flags; 58 wp<IBinder> who; ObituaryObituary59 Obituary( 60 const wp<IBinder::DeathRecipient>& r, 61 void* c, uint32_t f, 62 const wp<IBinder>& w) : 63 recipient(r), cookie(c), flags(f), who(w) { 64 } ObituaryObituary65 Obituary(const Obituary& o) : 66 recipient(o.recipient), 67 cookie(o.cookie), 68 flags(o.flags), 69 who(o.who) { 70 } 71 Obituary& operator=(const Obituary& o) { 72 recipient = o.recipient; 73 cookie = o.cookie; 74 flags = o.flags; 75 who = o.who; 76 return *this; 77 } serviceDiedObituary78 void serviceDied(uint64_t, const wp<HInterface>&) override { 79 sp<IBinder::DeathRecipient> dr = recipient.promote(); 80 if (dr != nullptr) { 81 dr->binderDied(who); 82 } 83 } 84 }; 85 std::mutex mObituariesLock; 86 std::vector<sp<Obituary> > mObituaries; 87 }; 88 89 template < 90 typename HINTERFACE, 91 typename INTERFACE, 92 typename BNINTERFACE> 93 status_t H2BConverter<HINTERFACE, INTERFACE, BNINTERFACE>:: linkToDeath(const sp<IBinder::DeathRecipient> & recipient,void * cookie,uint32_t flags)94 linkToDeath( 95 const sp<IBinder::DeathRecipient>& recipient, 96 void* cookie, uint32_t flags) { 97 LOG_ALWAYS_FATAL_IF(recipient == nullptr, 98 "linkToDeath(): recipient must be non-nullptr"); 99 { 100 std::lock_guard<std::mutex> lock(mObituariesLock); 101 mObituaries.push_back(new Obituary(recipient, cookie, flags, this)); 102 if (!mBase->linkToDeath(mObituaries.back(), 0)) { 103 return DEAD_OBJECT; 104 } 105 } 106 return NO_ERROR; 107 } 108 109 template < 110 typename HINTERFACE, 111 typename INTERFACE, 112 typename BNINTERFACE> 113 status_t H2BConverter<HINTERFACE, INTERFACE, BNINTERFACE>:: unlinkToDeath(const wp<IBinder::DeathRecipient> & recipient,void * cookie,uint32_t flags,wp<IBinder::DeathRecipient> * outRecipient)114 unlinkToDeath( 115 const wp<IBinder::DeathRecipient>& recipient, 116 void* cookie, uint32_t flags, 117 wp<IBinder::DeathRecipient>* outRecipient) { 118 std::lock_guard<std::mutex> lock(mObituariesLock); 119 for (auto i = mObituaries.begin(); i != mObituaries.end(); ++i) { 120 if ((flags = (*i)->flags) && ( 121 (recipient == (*i)->recipient) || 122 ((recipient == nullptr) && (cookie == (*i)->cookie)))) { 123 if (outRecipient != nullptr) { 124 *outRecipient = (*i)->recipient; 125 } 126 bool success = mBase->unlinkToDeath(*i); 127 mObituaries.erase(i); 128 return success ? NO_ERROR : DEAD_OBJECT; 129 } 130 } 131 return NAME_NOT_FOUND; 132 } 133 134 } // namespace camerahybrid 135 } // namespace android 136 137 #endif // ANDROID_CAMERA_HYBRIDINTERFACE_H 138 139