1 /* 2 * Copyright (C) 2019 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 #pragma once 18 19 #include <mutex> 20 #include <type_traits> 21 #include <binder/IInterface.h> 22 #include <binder/IServiceManager.h> 23 #include <utils/Log.h> 24 25 namespace android { 26 27 // A simple utility that caches a proxy for a service and handles death notification. 28 // Typically, intended to be used as a static-lifetime object. 29 // 30 // Example usage: 31 // static BinderProxy<IMyInterface> myInterface("my_interface_svc"); 32 // ... 33 // myInterface.waitServiceOrDie()->doSomething(); 34 // 35 // If the service is unavailable, will wait until it becomes available. 36 // Will die if the service doesn't implement the requested interface, or cannot be used for 37 // permission reasons. 38 template<typename ServiceType> 39 class BinderProxy { 40 public: 41 static_assert(std::is_base_of_v<IInterface, ServiceType>, 42 "Service type must be a sub-type of IInterface."); 43 BinderProxy(std::string_view serviceName)44 explicit BinderProxy(std::string_view serviceName) 45 : mServiceName(serviceName), mDeathRecipient(new DeathRecipient(this)) {} 46 ~BinderProxy()47 ~BinderProxy() { 48 if (mDelegate != nullptr) { 49 sp<IBinder> binder = IInterface::asBinder(mDelegate); 50 if (binder != nullptr) { 51 binder->unlinkToDeath(mDeathRecipient); 52 } 53 } 54 } 55 waitServiceOrDie()56 sp<ServiceType> waitServiceOrDie() { 57 std::lock_guard<std::mutex> _l(mDelegateMutex); 58 if (mDelegate == nullptr) { 59 mDelegate = waitForService<ServiceType>(String16(mServiceName.c_str())); 60 LOG_ALWAYS_FATAL_IF(mDelegate == nullptr, 61 "Service %s doesn't implement the required interface.", 62 mServiceName.c_str()); 63 sp<IBinder> binder = IInterface::asBinder(mDelegate); 64 if (binder != nullptr) { 65 binder->linkToDeath(mDeathRecipient); 66 } 67 } 68 return mDelegate; 69 } 70 71 private: 72 sp<ServiceType> mDelegate; 73 std::mutex mDelegateMutex; 74 const std::string mServiceName; 75 sp<IBinder::DeathRecipient> mDeathRecipient; 76 77 class DeathRecipient : public IBinder::DeathRecipient { 78 public: DeathRecipient(BinderProxy * proxy)79 DeathRecipient(BinderProxy* proxy) : mProxy(proxy) {} 80 binderDied(const wp<IBinder> &)81 void binderDied(const wp<IBinder>&) override { 82 mProxy->binderDied(); 83 } 84 85 private: 86 BinderProxy* const mProxy; 87 }; 88 binderDied()89 void binderDied() { 90 std::lock_guard<std::mutex> _l(mDelegateMutex); 91 mDelegate.clear(); 92 ALOGW("Binder died: %s", mServiceName.c_str()); 93 } 94 }; 95 96 } // namespace android 97