Android Audio底层原理(二)

1. Hal层类关系图

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

2. IMediaPlayerService.h

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

class IMediaPlayerService: public IInterface {

   public:
      DECLARE_META_INTERFACE(MediaPlayerService);
      ... ...

      virtual sp<IMediaPlayer> create(const sp<IMediaPlayerClient>& client, audio_session_t audioSessionIdAUDIO_SESSION_ALLOCATE) = 0;

virtual sp<IOMX> getOMX() = 0;

       virtual sp<IHDCP> makeHDCP(bool createEncryptionModule) = 0;

       virtual sp<IMediaCodecList> getCodecList() const = 0; };


class BnMediaPlayerService: public BnInterface<IMediaPlayerService> {

   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<typename INTERFACE>
  class BnInterface : public INTERFACE, public BBinder
  {
      public:
         virtual sp<IInterface>      queryLocalInterface(const String16& _descriptor);
         virtual const String16&     getInterfaceDescriptor() const;

      protected:
         virtual IBinder*            onAsBinder();
   };

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

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

template<typename INTERFACE>

class BpInterface : public INTERFACE, public BpRefBase {

     public:

           explicit     BpInterface(const sp<IBinder>& 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<I##INTERFACE> 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<IMediaPlayerService> asInterface( const ::android::sp<::android::IBinder>& obj);

      virtual const ::android::String16& getInterfaceDescriptor() const;
      IMediaPlayerService();
      virtual ~IMediaPlayerService();                                  //释放IMediaPlayerService对象

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

         (1) sp<IMediaPlayer> create(...)       //纯虚函数

         (2) sp<IOMX> getOMX()                    //纯虚函数

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

      (4) sp<IMediaCodecList> getCodecList() const   //纯虚函数

3. IMediaPlayerService.cpp

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

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

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

class BpMediaPlayerService: public BpInterface<IMediaPlayerService> {

    public:

        explicit     BpMediaPlayerService(const sp<IBinder>& impl):BpInterface<IMediaPlayerService>(impl){ }

        ... ...

        virtual sp<IMediaPlayer> create(const sp<IMediaPlayerClient>& client, audio_session_t, audioSessionId) {

                Parcel data, reply;
                data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());

                data.writeStrongBinder(IInterface::asBinder(client));

                data.writeInt32(audioSessionId); remote()->transact(CREATE, data, &reply);

                return interface_cast<IMediaPlayer>(reply.readStrongBinder());
         }

         virtual sp<IOMX> getOMX() {

                Parcel data, reply;

                data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());

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

                return interface_cast<IOMX>(reply.readStrongBinder());

         }

         virtual sp<IHDCP> makeHDCP(bool createEncryptionModule) {

               Parcel data, reply;

               data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());

               data.writeInt32(createEncryptionModule);

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

               return interface_cast<IHDCP>(reply.readStrongBinder());          

         }

         ... ...

          virtual sp<IRemoteDisplay> listenForRemoteDisplay(const String16 &opPackageName, const sp<IRemoteDisplayClient>& client, const String8& iface){

               Parcel data, reply;

               data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());                  

               data.writeString16(opPackageName);

               data.writeStrongBinder(IInterface::asBinder(client));

               data.writeString8(iface);                 

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

               return interface_cast<IRemoteDisplay>(reply.readStrongBinder());

          }

          virtual sp<IMediaCodecList> getCodecList() const {

                Parcel data, reply;

                data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());

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

                return interface_cast<IMediaCodecList>(reply.readStrongBinder());

           }

  };

       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<IMediaPlayerClient> client =interface_cast<IMediaPlayerClient(data.readStrongBinder()); audio_session_t audioSessionId = (audio_session_t) data.readInt32();

             sp<IMediaPlayer> player = create(client, audioSessionId);

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

             return NO_ERROR;

    } break;

    ... ...

    case GET_OMX: {

           CHECK_INTERFACE(IMediaPlayerService, data, reply);

           sp<IOMX> omx = getOMX();

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

           return NO_ERROR;

     } break;

    case MAKE_HDCP: {

           CHECK_INTERFACE(IMediaPlayerService, data, reply);

           bool createEncryptionModule = data.readInt32();

          sp<IHDCP> 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<IRemoteDisplayClient> client(interface_cast<IRemoteDisplayClient>(data.readStrongBinder()));

          if (client == NULL) {

               reply->writeStrongBinder(NULL);

               return NO_ERROR;

            }

           String8 iface(data.readString8());

           sp<IRemoteDisplay> display(listenForRemoteDisplay(opPackageName, client, iface));                 

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

           return NO_ERROR;

       } break;

       case GET_CODEC_LIST: {

            CHECK_INTERFACE(IMediaPlayerService, data, reply);

            sp<IMediaCodecList> 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,则执行

writeStrongBinder(IInterface::asBinder(mcl))

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

猜你喜欢

转载自blog.csdn.net/zxy1198186906/article/details/81665018
今日推荐