1 /* 2 * Copyright (C) 2017 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 HIDL_CALLBACK_UTIL_H_ 18 #define HIDL_CALLBACK_UTIL_H_ 19 20 #include <set> 21 22 #include <hidl/HidlSupport.h> 23 #include <hidl/HidlTransportSupport.h> 24 25 namespace { 26 // Type of callback invoked by the death handler. 27 using on_death_cb_function = std::function<void(uint64_t)>; 28 29 // Private class used to keep track of death of individual 30 // callbacks stored in HidlCallbackHandler. 31 template <typename CallbackType> 32 class HidlDeathHandler : public android::hardware::hidl_death_recipient { 33 public: HidlDeathHandler(const on_death_cb_function & user_cb_function)34 HidlDeathHandler(const on_death_cb_function& user_cb_function) 35 : cb_function_(user_cb_function) {} 36 ~HidlDeathHandler() = default; 37 38 // Death notification for callbacks. serviceDied(uint64_t cookie,const android::wp<android::hidl::base::V1_0::IBase> &)39 void serviceDied(uint64_t cookie, 40 const android::wp<android::hidl::base::V1_0::IBase>& /* who */) override { 41 cb_function_(cookie); 42 } 43 44 private: 45 on_death_cb_function cb_function_; 46 47 DISALLOW_COPY_AND_ASSIGN(HidlDeathHandler); 48 }; 49 } // namespace 50 51 namespace android { 52 namespace hardware { 53 namespace wifi { 54 namespace V1_6 { 55 namespace implementation { 56 namespace hidl_callback_util { 57 template <typename CallbackType> 58 // Provides a class to manage callbacks for the various HIDL interfaces and 59 // handle the death of the process hosting each callback. 60 class HidlCallbackHandler { 61 public: HidlCallbackHandler()62 HidlCallbackHandler() 63 : death_handler_(new HidlDeathHandler<CallbackType>( 64 std::bind(&HidlCallbackHandler::onObjectDeath, this, std::placeholders::_1))) {} 65 ~HidlCallbackHandler() = default; 66 addCallback(const sp<CallbackType> & cb)67 bool addCallback(const sp<CallbackType>& cb) { 68 // TODO(b/33818800): Can't compare proxies yet. So, use the cookie 69 // (callback proxy's raw pointer) to track the death of individual 70 // clients. 71 uint64_t cookie = reinterpret_cast<uint64_t>(cb.get()); 72 for (const auto& s : cb_set_) { 73 if (interfacesEqual(cb, s)) { 74 LOG(ERROR) << "Duplicate death notification registration"; 75 return true; 76 } 77 } 78 if (!cb->linkToDeath(death_handler_, cookie)) { 79 LOG(ERROR) << "Failed to register death notification"; 80 return false; 81 } 82 cb_set_.insert(cb); 83 return true; 84 } 85 getCallbacks()86 const std::set<android::sp<CallbackType>>& getCallbacks() { return cb_set_; } 87 88 // Death notification for callbacks. onObjectDeath(uint64_t cookie)89 void onObjectDeath(uint64_t cookie) { 90 CallbackType* cb = reinterpret_cast<CallbackType*>(cookie); 91 const auto& iter = cb_set_.find(cb); 92 if (iter == cb_set_.end()) { 93 LOG(ERROR) << "Unknown callback death notification received"; 94 return; 95 } 96 cb_set_.erase(iter); 97 LOG(DEBUG) << "Dead callback removed from list"; 98 } 99 invalidate()100 void invalidate() { 101 for (const sp<CallbackType>& cb : cb_set_) { 102 if (!cb->unlinkToDeath(death_handler_)) { 103 LOG(ERROR) << "Failed to deregister death notification"; 104 } 105 } 106 cb_set_.clear(); 107 } 108 109 private: 110 std::set<sp<CallbackType>> cb_set_; 111 sp<HidlDeathHandler<CallbackType>> death_handler_; 112 113 DISALLOW_COPY_AND_ASSIGN(HidlCallbackHandler); 114 }; 115 116 } // namespace hidl_callback_util 117 } // namespace implementation 118 } // namespace V1_6 119 } // namespace wifi 120 } // namespace hardware 121 } // namespace android 122 #endif // HIDL_CALLBACK_UTIL_H_ 123