美文网首页
Android 源码学习 -- 隐藏api实现

Android 源码学习 -- 隐藏api实现

作者: 打出了枫采 | 来源:发表于2022-05-02 06:59 被阅读0次
    隐藏api内部实现细节的两种方式:
    • 头文件 + shared library

      下面引用Android Framwork层 Bluetooth service 如何获取Native层 BT Statck api Interface示例 (做了部分删减)来说明:
    // in com_android_bluetooth_btservice_AdapterService.cpp
    int hal_util_load_bt_library(const bt_interface_t** interface) {
      const char* sym = BLUETOOTH_INTERFACE_STRING; //"bluetoothInterface"
      bt_interface_t* itf = nullptr;
    
      // The library name is not set by default, so the preset library name is used.
      void* handle = dlopen("libbluetooth.so", RTLD_NOW);
    
      // Get the address of the bt_interface_t.
      itf = (bt_interface_t*)dlsym(handle, sym);
    
      // Success.
      ALOGI("%s: loaded Bluetooth library successfully", __func__);
      *interface = itf;
      return 0;
    

    上面这段代码通过dlopen加载Shared libbluetooth.so,然后通过dlsym 获取bluetoothInterface

    下面接着看看bluetoothInterface 的类型声明和定义实现

    // in bluetooth.h
    /** Represents the standard Bluetooth DM interface. */
    typedef struct {
      /** set to sizeof(bt_interface_t) */
      size_t size;
    
      int (*init)(bt_callbacks_t* callbacks, bool guest_mode,
                  bool is_common_criteria_mode, int config_compare_result,
                  const char** init_flags, bool is_atv);
    
      /** Enable Bluetooth. */
      int (*enable)();
    
      /** Disable Bluetooth. */
      int (*disable)(void);
    
      /** Closes the interface. */
      void (*cleanup)(void);
      ......
      ......
      ......
      int (*config_clear)(void);
      void (*interop_database_clear)(void);
      void (*interop_database_add)(uint16_t feature, const RawAddress* addr,
                                   size_t len);
      bluetooth::avrcp::ServiceInterface* (*get_avrcp_service)(void);
      std::string (*obfuscate_address)(const RawAddress& address);
      int (*get_metric_id)(const RawAddress& address);
      int (*set_dynamic_audio_buffer_size)(int codec, int size);
      int (*generate_local_oob_data)(tBT_TRANSPORT transport);
      bool (*allow_low_latency_audio)(bool allowed, const RawAddress& address);
      int (*clear_event_filter)();
    } bt_interface_t;
    
    // in bluetooth_interface.cc
    EXPORT_SYMBOL bt_interface_t bluetoothInterface = {
        sizeof(bluetoothInterface),
        init,
        enable,
        disable,
        cleanup,
        get_adapter_properties,
        get_adapter_property,
        set_adapter_property,
        get_remote_device_properties,
        get_remote_device_property,
        set_remote_device_property,
        nullptr,
        get_remote_services,
        ......
        ......
        interop_database_clear,
        interop_database_add,
        get_avrcp_service,
        obfuscate_address,
        get_metric_id,
        set_dynamic_audio_buffer_size,
        generate_local_oob_data,
        allow_low_latency_audio
    };
    

    可以看到后续所有api 都是通过bluetoothInterface来获取,仅提供so和头文件供使用者调用就可以实现具体实现的隐藏。

    • 类接口的抽象封装

    头文件中暴露的是基类接口声明,实现在具体实现类,使用的地方不会明显看到实现细节

    对外暴露的接口类声明

    // 接口类
    class HearingAid {
     public:
      virtual ~HearingAid() = default;
    
      static void Initialize(bluetooth::hearing_aid::HearingAidCallbacks* callbacks,
                             base::Closure initCb);
      static void CleanUp();
      static bool IsHearingAidRunning();
      static HearingAid* Get();
      static void DebugDump(int fd);
    
      static void AddFromStorage(const HearingDevice& dev_info,
                                 uint16_t is_acceptlisted);
    
      static int GetDeviceCount();
    
      virtual void Connect(const RawAddress& address) = 0;
      virtual void Disconnect(const RawAddress& address) = 0;
      virtual void AddToAcceptlist(const RawAddress& address) = 0;
      virtual void SetVolume(int8_t volume) = 0;
    };
    

    具体实现类

    // 具体实现类
    class HearingAidImpl : public HearingAid {
    ......
    }
    

    抽象类 与 实现类 方法关联:
    通过instance来完成,静态方法可以从下面定义中明显看出由instance的实现完成;
    动态方法调用,借由Get方法来获取隐藏的实现类的示例instance,动态绑定逻辑

    // 抽象类 与 实现类 方法关联
    void HearingAid::Initialize(
        bluetooth::hearing_aid::HearingAidCallbacks* callbacks, Closure initCb) {
      if (instance) {
        LOG(ERROR) << "Already initialized!";
      }
    
      audioReceiver = &audioReceiverImpl;
      instance = new HearingAidImpl(callbacks, initCb);
      HearingAidAudioSource::Initialize();
    }
    
    bool HearingAid::IsHearingAidRunning() { return instance; }
    
    HearingAid* HearingAid::Get() {
      CHECK(instance);
      return instance;
    };
    
    void HearingAid::AddFromStorage(const HearingDevice& dev_info,
                                    uint16_t is_acceptlisted) {
      if (!instance) {
        LOG(ERROR) << "Not initialized yet";
      }
    
      instance->AddFromStorage(dev_info, is_acceptlisted);
    };
    

    调用的地方

    // 直接调用HearingAid的静态方法Initialize
      void Init(HearingAidCallbacks* callbacks) override {
        DVLOG(2) << __func__;
        this->callbacks = callbacks;
        do_in_main_thread(
            FROM_HERE,
            Bind(&HearingAid::Initialize, this,
                 jni_thread_wrapper(FROM_HERE,
                                    Bind(&btif_storage_load_bonded_hearing_aids))));
      }
    
    // 调用 HearingAid动态方法Connect,通过Get获取出来的instance 实际是HearingAid 的基类HearingAidImpl,由动态方法绑定关系,最终运行时调用的就是实现类示例instance的Connect
      void Connect(const RawAddress& address) override {
        DVLOG(2) << __func__ << " address: " << address;
        do_in_main_thread(FROM_HERE, Bind(&HearingAid::Connect,
                                          Unretained(HearingAid::Get()), address));
      }
    

    关于动态绑定的理解可以看看 C++ Primer Plus Chapter 13 中Static and Dynamic Binding内容

    上面do_in_main_thread,Bind等功能,属于chromium,android底层很多地方使用了这个库的函数功能,多线程task ,threadloop机制等,也是一种巧妙的设计,后面再研究下其源码细节进行说明。

    附:上面源码下载方式
    git clone "https://mirrors.tuna.tsinghua.edu.cn/git/AOSP/platform/packages/modules/Bluetooth"

    相关文章

      网友评论

          本文标题:Android 源码学习 -- 隐藏api实现

          本文链接:https://www.haomeiwen.com/subject/tnxyyrtx.html