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