/* * Copyright (C) 2015 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. */ #include "real_binder_wrapper.h" #include #include #include #include #include namespace android { // Class that handles binder death notifications. libbinder wants the recipient // to be wrapped in sp<>, so registering RealBinderWrapper as a recipient would // be awkward. class RealBinderWrapper::DeathRecipient : public IBinder::DeathRecipient { public: explicit DeathRecipient(const ::base::Closure& callback) : callback_(callback) {} ~DeathRecipient() = default; // IBinder::DeathRecipient: void binderDied(const wp& who) override { callback_.Run(); } private: // Callback to run in response to binder death. ::base::Closure callback_; DISALLOW_COPY_AND_ASSIGN(DeathRecipient); }; RealBinderWrapper::RealBinderWrapper() = default; RealBinderWrapper::~RealBinderWrapper() = default; sp RealBinderWrapper::GetService(const std::string& service_name) { sp service_manager = defaultServiceManager(); if (!service_manager.get()) { LOG(ERROR) << "Unable to get service manager"; return sp(); } sp binder = service_manager->checkService(String16(service_name.c_str())); if (!binder.get()) LOG(ERROR) << "Unable to get \"" << service_name << "\" service"; return binder; } bool RealBinderWrapper::RegisterService(const std::string& service_name, const sp& binder) { sp service_manager = defaultServiceManager(); if (!service_manager.get()) { LOG(ERROR) << "Unable to get service manager"; return false; } status_t status = defaultServiceManager()->addService( String16(service_name.c_str()), binder); if (status != OK) { LOG(ERROR) << "Failed to register \"" << service_name << "\" with service " << "manager"; return false; } return true; } sp RealBinderWrapper::CreateLocalBinder() { return sp(new BBinder()); } bool RealBinderWrapper::RegisterForDeathNotifications( const sp& binder, const ::base::Closure& callback) { sp recipient(new DeathRecipient(callback)); if (binder->linkToDeath(recipient) != OK) { LOG(ERROR) << "Failed to register for death notifications on " << binder.get(); return false; } death_recipients_[binder] = recipient; return true; } bool RealBinderWrapper::UnregisterForDeathNotifications( const sp& binder) { auto it = death_recipients_.find(binder); if (it == death_recipients_.end()) { LOG(ERROR) << "Not registered for death notifications on " << binder.get(); return false; } if (binder->unlinkToDeath(it->second) != OK) { LOG(ERROR) << "Failed to unregister for death notifications on " << binder.get(); return false; } death_recipients_.erase(it); return true; } uid_t RealBinderWrapper::GetCallingUid() { return IPCThreadState::self()->getCallingUid(); } pid_t RealBinderWrapper::GetCallingPid() { return IPCThreadState::self()->getCallingPid(); } } // namespace android