diff options
| author | Daniel Erat <derat@google.com> | 2015-09-08 13:20:02 -0600 |
|---|---|---|
| committer | Daniel Erat <derat@google.com> | 2015-09-09 14:21:28 -0600 |
| commit | be43a39ff56ca8840ccfed048f75633adc535e92 (patch) | |
| tree | e63ac1efe6f9ccadd15bce351bc819842950af5e /libbinderwrapper | |
| parent | da0b0116ba676203328906608a78dd240e0fea48 (diff) | |
| download | system_core-be43a39ff56ca8840ccfed048f75633adc535e92.tar.gz system_core-be43a39ff56ca8840ccfed048f75633adc535e92.tar.bz2 system_core-be43a39ff56ca8840ccfed048f75633adc535e92.zip | |
Add libbinderwrapper.
Add a library that wraps libbinder to make it possible to
write tests for native code that communicates via binder.
Bug: 23791723
Change-Id: I3c842413e0f07dc252040c042d664031b0354353
Diffstat (limited to 'libbinderwrapper')
| -rw-r--r-- | libbinderwrapper/Android.mk | 62 | ||||
| -rw-r--r-- | libbinderwrapper/binder_test_base.cc | 33 | ||||
| -rw-r--r-- | libbinderwrapper/binder_wrapper.cc | 53 | ||||
| -rw-r--r-- | libbinderwrapper/real_binder_wrapper.cc | 114 | ||||
| -rw-r--r-- | libbinderwrapper/real_binder_wrapper.h | 54 | ||||
| -rw-r--r-- | libbinderwrapper/stub_binder_wrapper.cc | 76 |
6 files changed, 392 insertions, 0 deletions
diff --git a/libbinderwrapper/Android.mk b/libbinderwrapper/Android.mk new file mode 100644 index 000000000..23c2246da --- /dev/null +++ b/libbinderwrapper/Android.mk @@ -0,0 +1,62 @@ +# +# 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. +# + +LOCAL_PATH := $(call my-dir) + +binderwrapperCommonCFlags := -Wall -Werror -Wno-unused-parameter +binderwrapperCommonCFlags += -Wno-sign-promo # for libchrome +binderwrapperCommonExportCIncludeDirs := $(LOCAL_PATH)/../include +binderwrapperCommonCIncludes := $(LOCAL_PATH)/../include +binderwrapperCommonSharedLibraries := \ + libbinder \ + libchrome \ + libutils \ + +# libbinderwrapper shared library +# ======================================================== + +include $(CLEAR_VARS) +LOCAL_MODULE := libbinderwrapper +LOCAL_CPP_EXTENSION := .cc +LOCAL_CFLAGS := $(binderwrapperCommonCFlags) +LOCAL_EXPORT_C_INCLUDE_DIRS := $(binderwrapperCommonExportCIncludeDirs) +LOCAL_C_INCLUDES := $(binderwrapperCommonCIncludes) +LOCAL_SHARED_LIBRARIES := $(binderwrapperCommonSharedLibraries) +LOCAL_SRC_FILES := \ + binder_wrapper.cc \ + real_binder_wrapper.cc \ + +include $(BUILD_SHARED_LIBRARY) + +# libbinderwrapper_test_support shared library +# ======================================================== + +include $(CLEAR_VARS) +LOCAL_MODULE := libbinderwrapper_test_support +LOCAL_CPP_EXTENSION := .cc +LOCAL_CFLAGS := $(binderwrapperCommonCFlags) +LOCAL_EXPORT_C_INCLUDE_DIRS := $(binderwrapperCommonExportCIncludeDirs) +LOCAL_C_INCLUDES := $(binderwrapperCommonCIncludes) +LOCAL_STATIC_LIBRARIES := libgtest +LOCAL_SHARED_LIBRARIES := \ + $(binderwrapperCommonSharedLibraries) \ + libbinderwrapper \ + +LOCAL_SRC_FILES := \ + binder_test_base.cc \ + stub_binder_wrapper.cc \ + +include $(BUILD_SHARED_LIBRARY) diff --git a/libbinderwrapper/binder_test_base.cc b/libbinderwrapper/binder_test_base.cc new file mode 100644 index 000000000..af93a04d9 --- /dev/null +++ b/libbinderwrapper/binder_test_base.cc @@ -0,0 +1,33 @@ +/* + * 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 <binderwrapper/binder_test_base.h> + +#include <binderwrapper/binder_wrapper.h> +#include <binderwrapper/stub_binder_wrapper.h> + +namespace android { + +BinderTestBase::BinderTestBase() : binder_wrapper_(new StubBinderWrapper()) { + // Pass ownership. + BinderWrapper::InitForTesting(binder_wrapper_); +} + +BinderTestBase::~BinderTestBase() { + BinderWrapper::Destroy(); +} + +} // namespace android diff --git a/libbinderwrapper/binder_wrapper.cc b/libbinderwrapper/binder_wrapper.cc new file mode 100644 index 000000000..0b5ff9612 --- /dev/null +++ b/libbinderwrapper/binder_wrapper.cc @@ -0,0 +1,53 @@ +/* + * 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 <binderwrapper/binder_wrapper.h> + +#include <base/logging.h> + +#include "real_binder_wrapper.h" + +namespace android { + +// Singleton instance. +BinderWrapper* BinderWrapper::instance_ = nullptr; + +// static +void BinderWrapper::Create() { + CHECK(!instance_) << "Already initialized; missing call to Destroy()?"; + instance_ = new RealBinderWrapper(); +} + +// static +void BinderWrapper::InitForTesting(BinderWrapper* wrapper) { + CHECK(!instance_) << "Already initialized; missing call to Destroy()?"; + instance_ = wrapper; +} + +// static +void BinderWrapper::Destroy() { + CHECK(instance_) << "Not initialized; missing call to Create()?"; + delete instance_; + instance_ = nullptr; +} + +// static +BinderWrapper* BinderWrapper::Get() { + CHECK(instance_) << "Not initialized; missing call to Create()?"; + return instance_; +} + +} // namespace android diff --git a/libbinderwrapper/real_binder_wrapper.cc b/libbinderwrapper/real_binder_wrapper.cc new file mode 100644 index 000000000..adff19bed --- /dev/null +++ b/libbinderwrapper/real_binder_wrapper.cc @@ -0,0 +1,114 @@ +/* + * 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/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; +} + +} // namespace android diff --git a/libbinderwrapper/real_binder_wrapper.h b/libbinderwrapper/real_binder_wrapper.h new file mode 100644 index 000000000..8e281f2f8 --- /dev/null +++ b/libbinderwrapper/real_binder_wrapper.h @@ -0,0 +1,54 @@ +/* + * 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. + */ + +#ifndef SYSTEM_CORE_LIBBINDERWRAPPER_REAL_BINDER_WRAPPER_H_ +#define SYSTEM_CORE_LIBBINDERWRAPPER_REAL_BINDER_WRAPPER_H_ + +#include <base/macros.h> +#include <binderwrapper/binder_wrapper.h> + +namespace android { + +class IBinder; + +// Real implementation of BinderWrapper. +class RealBinderWrapper : public BinderWrapper { + public: + RealBinderWrapper(); + ~RealBinderWrapper() override; + + // BinderWrapper: + sp<IBinder> GetService(const std::string& service_name) override; + bool RegisterService(const std::string& service_name, + const sp<IBinder>& binder) override; + sp<BBinder> CreateLocalBinder() override; + bool RegisterForDeathNotifications(const sp<IBinder>& binder, + const base::Closure& callback) override; + bool UnregisterForDeathNotifications(const sp<IBinder>& binder) override; + + private: + class DeathRecipient; + + // Map from binder handle to object that should be notified of the binder's + // death. + std::map<sp<IBinder>, sp<DeathRecipient>> death_recipients_; + + DISALLOW_COPY_AND_ASSIGN(RealBinderWrapper); +}; + +} // namespace android + +#endif // SYSTEM_CORE_LIBBINDER_WRAPPER_REAL_BINDER_WRAPPER_H_ diff --git a/libbinderwrapper/stub_binder_wrapper.cc b/libbinderwrapper/stub_binder_wrapper.cc new file mode 100644 index 000000000..1d2468101 --- /dev/null +++ b/libbinderwrapper/stub_binder_wrapper.cc @@ -0,0 +1,76 @@ +/* + * 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 <binderwrapper/stub_binder_wrapper.h> + +#include <base/logging.h> +#include <binder/Binder.h> +#include <binder/IBinder.h> + +namespace android { + +StubBinderWrapper::StubBinderWrapper() = default; + +StubBinderWrapper::~StubBinderWrapper() = default; + +void StubBinderWrapper::SetBinderForService(const std::string& service_name, + const sp<IBinder>& binder) { + services_to_return_[service_name] = binder; +} + +sp<IBinder> StubBinderWrapper::GetRegisteredService( + const std::string& service_name) const { + const auto it = registered_services_.find(service_name); + return it != registered_services_.end() ? it->second : sp<IBinder>(); +} + +void StubBinderWrapper::NotifyAboutBinderDeath(const sp<IBinder>& binder) { + const auto it = death_callbacks_.find(binder); + if (it != death_callbacks_.end()) + it->second.Run(); +} + +sp<IBinder> StubBinderWrapper::GetService(const std::string& service_name) { + const auto it = services_to_return_.find(service_name); + return it != services_to_return_.end() ? it->second : sp<IBinder>(); +} + +bool StubBinderWrapper::RegisterService(const std::string& service_name, + const sp<IBinder>& binder) { + registered_services_[service_name] = binder; + return true; +} + +sp<BBinder> StubBinderWrapper::CreateLocalBinder() { + sp<BBinder> binder(new BBinder()); + local_binders_.push_back(binder); + return binder; +} + +bool StubBinderWrapper::RegisterForDeathNotifications( + const sp<IBinder>& binder, + const base::Closure& callback) { + death_callbacks_[binder] = callback; + return true; +} + +bool StubBinderWrapper::UnregisterForDeathNotifications( + const sp<IBinder>& binder) { + death_callbacks_.erase(binder); + return true; +} + +} // namespace android |
