/* * Copyright (C) 2018 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_CAMERA_HYBRIDINTERFACE_H #define ANDROID_CAMERA_HYBRIDINTERFACE_H #include #include #include #include namespace android { namespace camerahybrid { typedef ::android::hidl::base::V1_0::IBase HInterface; template < typename HINTERFACE, typename INTERFACE, typename BNINTERFACE > class H2BConverter : public BNINTERFACE { public: typedef H2BConverter CBase; // Converter Base typedef INTERFACE BaseInterface; typedef HINTERFACE HalInterface; H2BConverter(const sp& base) : mBase(base) {} virtual sp getHalInterface() { return mBase; } virtual status_t linkToDeath( const sp& recipient, void* cookie = nullptr, uint32_t flags = 0); virtual status_t unlinkToDeath( const wp& recipient, void* cookie = nullptr, uint32_t flags = 0, wp* outRecipient = nullptr); protected: sp mBase; struct Obituary : public hardware::hidl_death_recipient { wp recipient; void* cookie; uint32_t flags; wp who; Obituary( const wp& r, void* c, uint32_t f, const wp& 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&) override { sp dr = recipient.promote(); if (dr != nullptr) { dr->binderDied(who); } } }; std::mutex mObituariesLock; std::vector > mObituaries; }; template < typename HINTERFACE, typename INTERFACE, typename BNINTERFACE> status_t H2BConverter:: linkToDeath( const sp& recipient, void* cookie, uint32_t flags) { LOG_ALWAYS_FATAL_IF(recipient == nullptr, "linkToDeath(): recipient must be non-nullptr"); { std::lock_guard 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> status_t H2BConverter:: unlinkToDeath( const wp& recipient, void* cookie, uint32_t flags, wp* outRecipient) { std::lock_guard 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; } } // namespace camerahybrid } // namespace android #endif // ANDROID_CAMERA_HYBRIDINTERFACE_H