forked from koush/android_system_core
-
Notifications
You must be signed in to change notification settings - Fork 530
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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
- Loading branch information
Daniel Erat
committed
Sep 9, 2015
1 parent
da0b011
commit be43a39
Showing
9 changed files
with
638 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
/* | ||
* 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_INCLUDE_BINDERWRAPPER_BINDER_TEST_BASE_H_ | ||
#define SYSTEM_CORE_INCLUDE_BINDERWRAPPER_BINDER_TEST_BASE_H_ | ||
|
||
#include <base/macros.h> | ||
#include <gtest/gtest.h> | ||
|
||
namespace android { | ||
|
||
class StubBinderWrapper; | ||
|
||
// Class that can be inherited from (or aliased via typedef/using) when writing | ||
// tests that use StubBinderManager. | ||
class BinderTestBase : public ::testing::Test { | ||
public: | ||
BinderTestBase(); | ||
~BinderTestBase() override; | ||
|
||
StubBinderWrapper* binder_wrapper() { return binder_wrapper_; } | ||
|
||
protected: | ||
StubBinderWrapper* binder_wrapper_; // Not owned. | ||
|
||
private: | ||
DISALLOW_COPY_AND_ASSIGN(BinderTestBase); | ||
}; | ||
|
||
} // namespace android | ||
|
||
#endif // SYSTEM_CORE_INCLUDE_BINDERWRAPPER_BINDER_TEST_BASE_H_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
/* | ||
* 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_INCLUDE_BINDERWRAPPER_BINDER_WRAPPER_H_ | ||
#define SYSTEM_CORE_INCLUDE_BINDERWRAPPER_BINDER_WRAPPER_H_ | ||
|
||
#include <string> | ||
|
||
#include <base/callback.h> | ||
#include <utils/StrongPointer.h> | ||
|
||
namespace android { | ||
|
||
class BBinder; | ||
class IBinder; | ||
|
||
// Wraps libbinder to make it testable. | ||
class BinderWrapper { | ||
public: | ||
virtual ~BinderWrapper() {} | ||
|
||
// Creates and initializes the singleton (using a wrapper that communicates | ||
// with the real binder system). | ||
static void Create(); | ||
|
||
// Initializes |wrapper| as the singleton, taking ownership of it. Tests that | ||
// want to inject their own wrappers should call this instead of Create(). | ||
static void InitForTesting(BinderWrapper* wrapper); | ||
|
||
// Destroys the singleton. Must be called before calling Create() or | ||
// InitForTesting() a second time. | ||
static void Destroy(); | ||
|
||
// Returns the singleton instance previously created by Create() or set by | ||
// InitForTesting(). | ||
static BinderWrapper* Get(); | ||
|
||
// Gets the binder for communicating with the service identified by | ||
// |service_name|, returning null immediately if it doesn't exist. | ||
virtual sp<IBinder> GetService(const std::string& service_name) = 0; | ||
|
||
// Registers |binder| as |service_name| with the service manager. | ||
virtual bool RegisterService(const std::string& service_name, | ||
const sp<IBinder>& binder) = 0; | ||
|
||
// Creates a local binder object. | ||
virtual sp<BBinder> CreateLocalBinder() = 0; | ||
|
||
// Registers |callback| to be invoked when |binder| dies. If another callback | ||
// is currently registered for |binder|, it will be replaced. | ||
virtual bool RegisterForDeathNotifications( | ||
const sp<IBinder>& binder, | ||
const base::Closure& callback) = 0; | ||
|
||
// Unregisters the callback, if any, for |binder|. | ||
virtual bool UnregisterForDeathNotifications(const sp<IBinder>& binder) = 0; | ||
|
||
private: | ||
static BinderWrapper* instance_; | ||
}; | ||
|
||
} // namespace android | ||
|
||
#endif // SYSTEM_CORE_INCLUDE_BINDERWRAPPER_BINDER_WRAPPER_H_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
/* | ||
* 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_INCLUDE_BINDERWRAPPER_STUB_BINDER_WRAPPER_H_ | ||
#define SYSTEM_CORE_INCLUDE_BINDERWRAPPER_STUB_BINDER_WRAPPER_H_ | ||
|
||
#include <map> | ||
#include <string> | ||
#include <vector> | ||
|
||
#include <base/macros.h> | ||
#include <binder/Binder.h> | ||
#include <binder/IBinder.h> | ||
#include <binderwrapper/binder_wrapper.h> | ||
|
||
namespace android { | ||
|
||
// Stub implementation of BinderWrapper for testing. | ||
// | ||
// Example usage: | ||
// | ||
// First, assuming a base IFoo binder interface, create a stub class that | ||
// derives from BnFoo to implement the receiver side of the communication: | ||
// | ||
// class StubFoo : public BnFoo { | ||
// public: | ||
// ... | ||
// status_t doSomething(int arg) override { | ||
// // e.g. save passed-in value for later inspection by tests. | ||
// return OK; | ||
// } | ||
// }; | ||
// | ||
// Next, from your test code, inject a StubBinderManager either directly or by | ||
// inheriting from the BinderTestBase class: | ||
// | ||
// StubBinderWrapper* wrapper = new StubBinderWrapper(); | ||
// BinderWrapper::InitForTesting(wrapper); // Takes ownership. | ||
// | ||
// Also from your test, create a StubFoo and register it with the wrapper: | ||
// | ||
// StubFoo* foo = new StubFoo(); | ||
// sp<IBinder> binder(foo); | ||
// wrapper->SetBinderForService("foo", binder); | ||
// | ||
// The code being tested can now use the wrapper to get the stub and call it: | ||
// | ||
// sp<IBinder> binder = BinderWrapper::Get()->GetService("foo"); | ||
// CHECK(binder.get()); | ||
// sp<IFoo> foo = interface_cast<IFoo>(binder); | ||
// CHECK_EQ(foo->doSomething(3), OK); | ||
// | ||
// To create a local BBinder object, production code can call | ||
// CreateLocalBinder(). Then, a test can get the BBinder's address via | ||
// local_binders() to check that they're passed as expected in binder calls. | ||
// | ||
class StubBinderWrapper : public BinderWrapper { | ||
public: | ||
StubBinderWrapper(); | ||
~StubBinderWrapper() override; | ||
|
||
const std::vector<sp<BBinder>>& local_binders() const { | ||
return local_binders_; | ||
} | ||
void clear_local_binders() { local_binders_.clear(); } | ||
|
||
// Sets the binder to return when |service_name| is passed to GetService() or | ||
// WaitForService(). | ||
void SetBinderForService(const std::string& service_name, | ||
const sp<IBinder>& binder); | ||
|
||
// Returns the binder previously registered for |service_name| via | ||
// RegisterService(), or null if the service hasn't been registered. | ||
sp<IBinder> GetRegisteredService(const std::string& service_name) const; | ||
|
||
// Run the calback in |death_callbacks_| corresponding to |binder|. | ||
void NotifyAboutBinderDeath(const sp<IBinder>& binder); | ||
|
||
// 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: | ||
using ServiceMap = std::map<std::string, sp<IBinder>>; | ||
|
||
// Map from service name to associated binder handle. Used by GetService() and | ||
// WaitForService(). | ||
ServiceMap services_to_return_; | ||
|
||
// Map from service name to associated binder handle. Updated by | ||
// RegisterService(). | ||
ServiceMap registered_services_; | ||
|
||
// Local binders returned by CreateLocalBinder(). | ||
std::vector<sp<BBinder>> local_binders_; | ||
|
||
// Map from binder handle to the callback that should be invoked on binder | ||
// death. | ||
std::map<sp<IBinder>, base::Closure> death_callbacks_; | ||
|
||
DISALLOW_COPY_AND_ASSIGN(StubBinderWrapper); | ||
}; | ||
|
||
} // namespace android | ||
|
||
#endif // SYSTEM_CORE_INCLUDE_BINDERWRAPPER_STUB_BINDER_WRAPPER_H_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
Oops, something went wrong.