Native Binder

以 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和传输参数等。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值