以 IAudioPolicyService为例,展示基于C/S 结构的Binder的实现,传输层和协议层各类的关系。
传输层 IBinder, BBinder, BpBinder, 传输层不关心传输的具体内容;
协议层 IAudioPolicyService, BpInterface, BnInterface 和传输层不同,协议层和具体的接口相关,为实现为统一的接口使用了 模板和宏定义的方法。
sp<>, wp<> 是什么
system/core/include/utils/RefBase.h
// This provides primarily wp<> weak pointer types and RefBase, which work
// together with sp<> from <StrongPointer.h>.
// sp<> (and wp<>) are a type of smart pointer that use a well defined protocol
// to operate. As long as the object they are templated with implements that
// protocol, these smart pointers work.
// RefBase is such an implementation and it supports strong pointers, weak
// pointers and some magic features for the binder.
// So, when using RefBase objects, you have the ability to use strong and weak
// pointers through sp<> and wp<>.
// Normally, when the last strong pointer goes away, the object is destroyed,
// i.e. it's destructor is called. HOWEVER, parts of its associated memory is not
// freed until the last weak pointer is released.
// Weak pointers are essentially "safe" pointers. They are always safe to
// access through promote(). They may return nullptr if the object was
// destroyed because it ran out of strong pointers. This makes them good candidates
// for keys in a cache for instance.
How is this supposed / intended to be used?
什么场景使用 sp<>: 一个对象拥有另个对象: has a , 另外函数的参数已使用 sp
// Our recommendation is to use strong references (sp<>) when there is an
// ownership relation. e.g. when an object "owns" another one, use a strong
// ref. And of course use strong refs as arguments of functions (it's extremely
// rare that a function will take a wp<>).
// Typically a newly allocated object will immediately be used to initialize
// a strong pointer, which may then be used to construct or assign to other
// strong and weak pointers.
什么场景使用 wp: no ownership relation
// Use weak references when there are no ownership relation. e.g. the keys in a
// cache (you cannot use plain pointers because there is no safe way to acquire
// a strong reference from a vanilla pointer).
// This implies that two objects should never (or very rarely) have sp<> on
// each other, because they can't both own each other.
// Do not construct a strong pointer to "this" in an object's constructor.
// The onFirstRef() callback would be made on an incompletely constructed
// object.
IBinder
frameworks/native/libs/binder/include/binder/IBinder.h
/**
* Base class and low-level protocol for a remotable object.
* You can derive from this class to create an object for which other
* processes can hold references to it. Communication between processes
* (method calls, property get and set) is down through a low-level
* protocol implemented on top of the transact() API.
*/
IInterface
frameworks/native/libs/binder/include/binder/IInterface.h
#define DECLARE_META_INTERFACE(INTERFACE) \
public: \
static const ::android::String16 descriptor; \
static ::android::sp<I##INTERFACE> asInterface( \
const ::android::sp<::android::IBinder>& obj); \
virtual const ::android::String16& getInterfaceDescriptor() const; \
I##INTERFACE(); \
virtual ~I##INTERFACE(); \
static bool setDefaultImpl(std::unique_ptr<I##INTERFACE> impl); \
static const std::unique_ptr<I##INTERFACE>& getDefaultImpl(); \
private: \
static std::unique_ptr<I##INTERFACE> default_impl; \
public: \
#define IMPLEMENT_META_INTERFACE(INTERFACE, NAME) \
DO_NOT_DIRECTLY_USE_ME_IMPLEMENT_META_INTERFACE(INTERFACE, NAME) \
#define DO_NOT_DIRECTLY_USE_ME_IMPLEMENT_META_INTERFACE(INTERFACE, NAME)\
const ::android::StaticString16 \
I##INTERFACE##_descriptor_static_str16(__IINTF_CONCAT(u, NAME));\
const ::android::String16 I##INTERFACE::descriptor( \
I##INTERFACE##_descriptor_static_str16); \
const ::android::String16& \
I##INTERFACE::getInterfaceDescriptor() const { \
return I##INTERFACE::descriptor; \
} \
::android::sp<I##INTERFACE> I##INTERFACE::asInterface( \
const ::android::sp<::android::IBinder>& obj) \
{ \
::android::sp<I##INTERFACE> intr; \
if (obj != nullptr) { \
intr = static_cast<I##INTERFACE*>( \
obj->queryLocalInterface( \
I##INTERFACE::descriptor).get()); \
if (intr == nullptr) { \
intr = new Bp##INTERFACE(obj); \
} \
} \
return intr; \
} \
std::unique_ptr<I##INTERFACE> I##INTERFACE::default_impl; \
bool I##INTERFACE::setDefaultImpl(std::unique_ptr<I##INTERFACE> impl)\
{ \
/* Only one user of this interface can use this function */ \
/* at a time. This is a heuristic to detect if two different */ \
/* users in the same process use this function. */ \
assert(!I##INTERFACE::default_impl); \
if (impl) { \
I##INTERFACE::default_impl = std::move(impl); \
return true; \
} \
return false; \
} \
const std::unique_ptr<I##INTERFACE>& I##INTERFACE::getDefaultImpl() \
{ \
return I##INTERFACE::default_impl; \
} \
I##INTERFACE::I##INTERFACE() { } \
I##INTERFACE::~I##INTERFACE() { } \
怎么展开上面的宏
主要功能是定义接口描述符(和service的名字一致吗?不一致)
media.audio_policy(service name): [android.media.IAudioPolicyService] (接口描述符)
frameworks/native/include/binder/IInterface.h
有两个macro: 声明接口和实现接口,展开后是什么样子?
#define DECLARE_META_INTERFACE(INTERFACE) #define IMPLEMENT_META_INTERFACE(INTERFACE, NAME)
使用预编译命令 gcc -E xxx.c -o xxx.i, 展开后的文件宏是在同一个行里,需要格式化
clang-format -i hello.i
DECLARE_META_INTERFACE(AudioPolicyService);
public:
static const ::android::String16 descriptor;
static ::android::sp<IAudioPolicyService> asInterface(
const ::android::sp<::android::IBinder> &obj);
virtual const ::android::String16 &getInterfaceDescriptor() const;
IAudioPolicyService();
virtual ~IAudioPolicyService();
static bool setDefaultImpl(std::unique_ptr<IAudioPolicyService> impl);
static const std::unique_ptr<IAudioPolicyService> &getDefaultImpl();
private:
static std::unique_ptr<IAudioPolicyService> default_impl;
public:
;
IMPLEMENT_META_INTERFACE(AudioPolicyService, "android.media.IAudioPolicyService")
获得接口描述符
const ::android::StaticString16 IAudioPolicyService_descriptor_static_str16(
(u"android.media.IAudioPolicyService"));
const ::android::String16 IAudioPolicyService::descriptor(
IAudioPolicyService_descriptor_static_str16);
const ::android::String16 &IAudioPolicyService::getInterfaceDescriptor()
const {
return IAudioPolicyService::descriptor;
}
通过Binder得到Interface
::android::sp<IAudioPolicyService> IAudioPolicyService::asInterface(
const ::android::sp<::android::IBinder> &obj) {
::android::sp<IAudioPolicyService> intr;
if (obj != nullptr) {
intr = static_cast<IAudioPolicyService *>(//server端,Binder已经存在
obj->queryLocalInterface(IAudioPolicyService::descriptor).get());
if (intr == nullptr) {
intr = new BpAudioPolicyService(obj);
}
}
return intr;
}
std::unique_ptr<IAudioPolicyService> IAudioPolicyService::default_impl;
bool IAudioPolicyService::setDefaultImpl(
std::unique_ptr<IAudioPolicyService> impl) {
assert(!IAudioPolicyService::default_impl);
if (impl) {
IAudioPolicyService::default_impl = std::move(impl);
return true;
}
return false;
}
const std::unique_ptr<IAudioPolicyService>
&IAudioPolicyService::getDefaultImpl() {
return IAudioPolicyService::default_impl;
}
IAudioPolicyService::IAudioPolicyService() {}
IAudioPolicyService::~IAudioPolicyService(){};
使用方法
client 端 获得 service的代理,代理和server的接口是一样的虽然内容不同,也就是说client得到IServicePolicy就可以使用server提供的服务了,其底层传输过程需要opCode和传输参数等。