| /* |
| * 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 <base/logging.h> |
| #include <binder/Binder.h> |
| #include <binder/IBinder.h> |
| #include <binder/IPCThreadState.h> |
| #include <binder/IServiceManager.h> |
| |
| 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<IBinder>& 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<IBinder> RealBinderWrapper::GetService(const std::string& service_name) { |
| sp<IServiceManager> service_manager = defaultServiceManager(); |
| if (!service_manager.get()) { |
| LOG(ERROR) << "Unable to get service manager"; |
| return sp<IBinder>(); |
| } |
| sp<IBinder> 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<IBinder>& binder) { |
| sp<IServiceManager> 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<BBinder> RealBinderWrapper::CreateLocalBinder() { |
| return sp<BBinder>(new BBinder()); |
| } |
| |
| bool RealBinderWrapper::RegisterForDeathNotifications( |
| const sp<IBinder>& binder, |
| const ::base::Closure& callback) { |
| sp<DeathRecipient> 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<IBinder>& 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 |