Android Audio底层原理(二)

1. Hal层类关系图

以MediaPlayer功能为例,我们可以根据Android 8.1 (Oreo)源代码绘制出其类图

Android Audio底层原理(二)_第1张图片


2. IMediaPlayerService.h

     定义相关API,方便binder进程调用。IMediaPlayerService理论上是MediaPlayerService的接口,故只定义API而把API具体实现都放在class MediaPlayerService中。

class IMediaPlayerService: public IInterface {

   public:
      DECLARE_META_INTERFACE(MediaPlayerService);
      ... ...
      virtual sp create(const sp& client, audio_session_taudioSessionId = AUDIO_SESSION_ALLOCATE) = 0;

      virtual sp getOMX() = 0;

      virtual sp makeHDCP(bool createEncryptionModule) = 0;

      virtual sp getCodecList() const = 0; };


class BnMediaPlayerService: public BnInterface {

   public:
       virtual status_t onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0);

};

      2.1   BnMediaPlayerService

      IMediaPlayerService主要有两个子类,一个是BpMediaPlayerServcie类,另一个是BnMediaPlayerService类。

      IMediaPlayerService.h中,可以看到BnMediaPlayerService继承模板类BnInterface。在IInterface.h中可看到BnInterface的定义如下:

template
  class BnInterface : public INTERFACE, public BBinder
  {
      public:
         virtual sp  queryLocalInterface(const String16& _descriptor);
         virtual const String16&  getInterfaceDescriptor() const;

      protected:
         virtual IBinder* onAsBinder();
   };

 根据模板类的概念,BnMediaPlayerService相当于继承IMediaPlayerService和BBinder。

        同理,BpMediaPlayerService类相当于继承了IMediaPlayerService和BpRefBase类。

template

class BpInterface : public INTERFACE, public BpRefBase {
     public:
           explicit BpInterface(const sp& remote);

     protected:
            virtual IBinder* onAsBinder();

 };

2.2  DECLARE_META_INTERFACE( )
          DECLARE_META_INTERFACE( )同样位于IInterface.h,同样是一个模板函数。

#define DECLARE_META_INTERFACE(INTERFACE)
      static const ::android::String16 descriptor;
      static ::android::sp asInterface(const::android::sp<::android::IBinder>& obj);
      virtual const ::android::String16& getInterfaceDescriptor() const;
      I##INTERFACE();
      virtual ~I##INTERFACE();

则DECLARE_META_INTERFACE( MediaPlayerService)可以翻译为:

static const ::android::String16 descriptor;
      static ::android::sp asInterface(const::android::sp<::android::IBinder>& obj);
      virtual const ::android::String16& getInterfaceDescriptor() const;
      IMediaPlayerService();
      virtual ~IMediaPlayerService();      //析构IMediaPlayerService对象

 可以总结为IMediaPlayerService主要包含了以下几个虚函数,待子类 class MediaPlayerService实现。、

         (1) sp create(...)       //纯虚函数

         (2) sp getOMX()                    //纯虚函数

         (3) sp makeHDCP(bool createEncryptionModule)   //纯虚函数

      (4) sp getCodecList() const   //纯虚函数


3. IMediaPlayerService.cpp

    IMediaPlayer.cpp包含了class BpMediaPlayerService和class BnMediaPlayerService。

    BpMediaPlayerService的主要设计满足代理模式(proxy),可以视为代理类,隔断客户端(访问对象)和服务端(被访问对象)。客户端对象必须通过代理类才能访问到BnMediaPlayerService中对象。

Android Audio底层原理(二)_第2张图片

     BpMediaPlayerService代理类的主要代码如下,主要作用是remote->transact( )调用。通知服务端具体调用。

status_t BnMediaPlayerService::onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
   switch (code) {
        case CREATE: {
            CHECK_INTERFACE(IMediaPlayerService, data, reply);
            sp client=interface_cast player = create(client, audioSessionId);
             reply->writeStrongBinder(IInterface::asBinder(player));
             return NO_ERROR;

    } break;

    ... ...

    case GET_OMX: {
           CHECK_INTERFACE(IMediaPlayerService, data, reply);
           sp omx = getOMX();
           reply->writeStrongBinder(IInterface::asBinder(omx));
           return NO_ERROR;
     } break;

    case MAKE_HDCP: {
           CHECK_INTERFACE(IMediaPlayerService, data, reply);
           bool createEncryptionModule = data.readInt32();
           sp hdcp = makeHDCP(createEncryptionModule);
           reply->writeStrongBinder(IInterface::asBinder(hdcp));
           return NO_ERROR;
      } break;

      ... ...
     case LISTEN_FOR_REMOTE_DISPLAY: {
          CHECK_INTERFACE(IMediaPlayerService, data, reply);
          const String16 opPackageName = data.readString16();
          sp client(interface_cast(data.readStrongBinder()));
          if (client == NULL) {
               reply->writeStrongBinder(NULL);
               return NO_ERROR;
            }
           String8 iface(data.readString8());
           sp display(listenForRemoteDisplay(opPackageName, client,iface));                 
           reply->writeStrongBinder(IInterface::asBinder(display));
           return NO_ERROR;

       } break;

       case GET_CODEC_LIST: {
            CHECK_INTERFACE(IMediaPlayerService, data, reply);
            sp mcl = getCodecList();
            reply->writeStrongBinder(IInterface::asBinder(mcl));
            return NO_ERROR;
        } break;

        default:
            return BBinder::onTransact(code, data, reply, flags);
        }

 }

       BnMediaPlayerService作为实现类,重写onTransact( )函数,处理proxy发来的函数调用。

status_t BnMediaPlayerService::onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {

   switch (code) {

        case CREATE: {

            CHECK_INTERFACE(IMediaPlayerService, data, reply);

            sp client =interface_cast player = create(client, audioSessionId);

             reply->writeStrongBinder(IInterface::asBinder(player));

             return NO_ERROR;

    } break;

    ... ...

    case GET_OMX: {

           CHECK_INTERFACE(IMediaPlayerService, data, reply);

           sp omx = getOMX();

           reply->writeStrongBinder(IInterface::asBinder(omx));

           return NO_ERROR;

     } break;

    case MAKE_HDCP: {

           CHECK_INTERFACE(IMediaPlayerService, data, reply);

           bool createEncryptionModule = data.readInt32();

          sp hdcp = makeHDCP(createEncryptionModule);

          reply->writeStrongBinder(IInterface::asBinder(hdcp));

          return NO_ERROR;

      } break;

      ... ...
     case LISTEN_FOR_REMOTE_DISPLAY: {

          CHECK_INTERFACE(IMediaPlayerService, data, reply);

          const String16 opPackageName = data.readString16();

          sp client(interface_cast(data.readStrongBinder()));

          if (client == NULL) {

               reply->writeStrongBinder(NULL);

               return NO_ERROR;

            }

           String8 iface(data.readString8());

           sp display(listenForRemoteDisplay(opPackageName, client, iface));                 

           reply->writeStrongBinder(IInterface::asBinder(display));

           return NO_ERROR;

       } break;

       case GET_CODEC_LIST: {

            CHECK_INTERFACE(IMediaPlayerService, data, reply);

            sp mcl = getCodecList();

            reply->writeStrongBinder(IInterface::asBinder(mcl));

            return NO_ERROR;

        } break;

        default:

            return BBinder::onTransact(code, data, reply, flags);

        }

 }

  例如,当proxy发来调用服务端的getCodecList( )函数(getCodecList()函数为获取编码器列表)。则调用

 remote()->transact(GET_CODEC_LIST,data,&reply);

经过binder驱动,会回调至onTransact( ),处理客户端需求。如GET_CODEC_LIST满足case GET_CODEC_LIST,则执行

     而IMediaPlayerService类中的create( ),makeDHCP( ),getCodecList( )具体实现不在IMediaPlayerService类中。

writeStrongBinder(IInterface::asBinder(mcl))

 

你可能感兴趣的:(Android)