1*ec779b8eSAndroid Build Coastguard Worker /* 2*ec779b8eSAndroid Build Coastguard Worker * Copyright (C) 2019 The Android Open Source Project 3*ec779b8eSAndroid Build Coastguard Worker * 4*ec779b8eSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*ec779b8eSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*ec779b8eSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*ec779b8eSAndroid Build Coastguard Worker * 8*ec779b8eSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*ec779b8eSAndroid Build Coastguard Worker * 10*ec779b8eSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*ec779b8eSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*ec779b8eSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*ec779b8eSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*ec779b8eSAndroid Build Coastguard Worker * limitations under the License. 15*ec779b8eSAndroid Build Coastguard Worker */ 16*ec779b8eSAndroid Build Coastguard Worker 17*ec779b8eSAndroid Build Coastguard Worker #pragma once 18*ec779b8eSAndroid Build Coastguard Worker 19*ec779b8eSAndroid Build Coastguard Worker #include <mutex> 20*ec779b8eSAndroid Build Coastguard Worker #include <type_traits> 21*ec779b8eSAndroid Build Coastguard Worker #include <binder/IInterface.h> 22*ec779b8eSAndroid Build Coastguard Worker #include <binder/IServiceManager.h> 23*ec779b8eSAndroid Build Coastguard Worker #include <utils/Log.h> 24*ec779b8eSAndroid Build Coastguard Worker 25*ec779b8eSAndroid Build Coastguard Worker namespace android { 26*ec779b8eSAndroid Build Coastguard Worker 27*ec779b8eSAndroid Build Coastguard Worker // A simple utility that caches a proxy for a service and handles death notification. 28*ec779b8eSAndroid Build Coastguard Worker // Typically, intended to be used as a static-lifetime object. 29*ec779b8eSAndroid Build Coastguard Worker // 30*ec779b8eSAndroid Build Coastguard Worker // Example usage: 31*ec779b8eSAndroid Build Coastguard Worker // static BinderProxy<IMyInterface> myInterface("my_interface_svc"); 32*ec779b8eSAndroid Build Coastguard Worker // ... 33*ec779b8eSAndroid Build Coastguard Worker // myInterface.waitServiceOrDie()->doSomething(); 34*ec779b8eSAndroid Build Coastguard Worker // 35*ec779b8eSAndroid Build Coastguard Worker // If the service is unavailable, will wait until it becomes available. 36*ec779b8eSAndroid Build Coastguard Worker // Will die if the service doesn't implement the requested interface, or cannot be used for 37*ec779b8eSAndroid Build Coastguard Worker // permission reasons. 38*ec779b8eSAndroid Build Coastguard Worker template<typename ServiceType> 39*ec779b8eSAndroid Build Coastguard Worker class BinderProxy { 40*ec779b8eSAndroid Build Coastguard Worker public: 41*ec779b8eSAndroid Build Coastguard Worker static_assert(std::is_base_of_v<IInterface, ServiceType>, 42*ec779b8eSAndroid Build Coastguard Worker "Service type must be a sub-type of IInterface."); 43*ec779b8eSAndroid Build Coastguard Worker BinderProxy(std::string_view serviceName)44*ec779b8eSAndroid Build Coastguard Worker explicit BinderProxy(std::string_view serviceName) 45*ec779b8eSAndroid Build Coastguard Worker : mServiceName(serviceName), mDeathRecipient(new DeathRecipient(this)) {} 46*ec779b8eSAndroid Build Coastguard Worker ~BinderProxy()47*ec779b8eSAndroid Build Coastguard Worker ~BinderProxy() { 48*ec779b8eSAndroid Build Coastguard Worker if (mDelegate != nullptr) { 49*ec779b8eSAndroid Build Coastguard Worker sp<IBinder> binder = IInterface::asBinder(mDelegate); 50*ec779b8eSAndroid Build Coastguard Worker if (binder != nullptr) { 51*ec779b8eSAndroid Build Coastguard Worker binder->unlinkToDeath(mDeathRecipient); 52*ec779b8eSAndroid Build Coastguard Worker } 53*ec779b8eSAndroid Build Coastguard Worker } 54*ec779b8eSAndroid Build Coastguard Worker } 55*ec779b8eSAndroid Build Coastguard Worker waitServiceOrDie()56*ec779b8eSAndroid Build Coastguard Worker sp<ServiceType> waitServiceOrDie() { 57*ec779b8eSAndroid Build Coastguard Worker std::lock_guard<std::mutex> _l(mDelegateMutex); 58*ec779b8eSAndroid Build Coastguard Worker if (mDelegate == nullptr) { 59*ec779b8eSAndroid Build Coastguard Worker mDelegate = waitForService<ServiceType>(String16(mServiceName.c_str())); 60*ec779b8eSAndroid Build Coastguard Worker LOG_ALWAYS_FATAL_IF(mDelegate == nullptr, 61*ec779b8eSAndroid Build Coastguard Worker "Service %s doesn't implement the required interface.", 62*ec779b8eSAndroid Build Coastguard Worker mServiceName.c_str()); 63*ec779b8eSAndroid Build Coastguard Worker sp<IBinder> binder = IInterface::asBinder(mDelegate); 64*ec779b8eSAndroid Build Coastguard Worker if (binder != nullptr) { 65*ec779b8eSAndroid Build Coastguard Worker binder->linkToDeath(mDeathRecipient); 66*ec779b8eSAndroid Build Coastguard Worker } 67*ec779b8eSAndroid Build Coastguard Worker } 68*ec779b8eSAndroid Build Coastguard Worker return mDelegate; 69*ec779b8eSAndroid Build Coastguard Worker } 70*ec779b8eSAndroid Build Coastguard Worker 71*ec779b8eSAndroid Build Coastguard Worker private: 72*ec779b8eSAndroid Build Coastguard Worker sp<ServiceType> mDelegate; 73*ec779b8eSAndroid Build Coastguard Worker std::mutex mDelegateMutex; 74*ec779b8eSAndroid Build Coastguard Worker const std::string mServiceName; 75*ec779b8eSAndroid Build Coastguard Worker sp<IBinder::DeathRecipient> mDeathRecipient; 76*ec779b8eSAndroid Build Coastguard Worker 77*ec779b8eSAndroid Build Coastguard Worker class DeathRecipient : public IBinder::DeathRecipient { 78*ec779b8eSAndroid Build Coastguard Worker public: DeathRecipient(BinderProxy * proxy)79*ec779b8eSAndroid Build Coastguard Worker DeathRecipient(BinderProxy* proxy) : mProxy(proxy) {} 80*ec779b8eSAndroid Build Coastguard Worker binderDied(const wp<IBinder> &)81*ec779b8eSAndroid Build Coastguard Worker void binderDied(const wp<IBinder>&) override { 82*ec779b8eSAndroid Build Coastguard Worker mProxy->binderDied(); 83*ec779b8eSAndroid Build Coastguard Worker } 84*ec779b8eSAndroid Build Coastguard Worker 85*ec779b8eSAndroid Build Coastguard Worker private: 86*ec779b8eSAndroid Build Coastguard Worker BinderProxy* const mProxy; 87*ec779b8eSAndroid Build Coastguard Worker }; 88*ec779b8eSAndroid Build Coastguard Worker binderDied()89*ec779b8eSAndroid Build Coastguard Worker void binderDied() { 90*ec779b8eSAndroid Build Coastguard Worker std::lock_guard<std::mutex> _l(mDelegateMutex); 91*ec779b8eSAndroid Build Coastguard Worker mDelegate.clear(); 92*ec779b8eSAndroid Build Coastguard Worker ALOGW("Binder died: %s", mServiceName.c_str()); 93*ec779b8eSAndroid Build Coastguard Worker } 94*ec779b8eSAndroid Build Coastguard Worker }; 95*ec779b8eSAndroid Build Coastguard Worker 96*ec779b8eSAndroid Build Coastguard Worker } // namespace android 97