TvServer Architecture

1: TvServer架构。

TvServer 作为一个系统service注册到servicemanager,编译成libmiddleware.so && tvserver.so两个library库,通过TvServerService来加载。通过暴露的tvjar为上层app提供服务,

主要包括,SI/PSI table的解析,Tuner Play,TimeShift、parent control,OAD,subtitle

1.1:TvServerService

Tvserver与上层app之间的关系

1.1.1: TvServerService.java

加载*.so

Public class TvServerService extends Service {

      ……

      Private native void startTvServer

      Static {

           try {

                 System.loadLibrary("TvMiddlewareCore");

                 System.loadLibrary("tvserver");

           } catch (UnsatisfiedLinkError e) {

                 Log.e(TAG, "cannot load library due to " + e.getLocalizedMessage());

           }

}

      ……

}

1.1.2:  Native 端 tvserver.cpp

extern "C" {

      void Java_org_droidtv_tvserver_TvServerService_startTvServer(JNIEnv *env, jobject  obj);

}

 

void Java_org_droidtv_tvserver_TvServerService_startTvServer(JNIEnv *env, jobject  obj)

{

LogPrint("starting TvServer");

    TvServerService::instantiate();

}

1.1.3:tvserverservice 服务端的实现

类图

其中最为核心的一个类,当属TvMediaResource,它管理者Tvserver内部众多Media,通过该Binder接口,可以获取tvserver服务接口,如OAD,MediaControl,MediaStream等。

1):定义相关的头文件

A:ITvServerService.h

class ITvServerService:public IInterface {

    public:

        DECLARE_META_INTERFACE(TvServerService);

        virtual sp<IBinder> createTvMediaResource(int tokenId)=0;

           virtual sp<IBinder> getTvServerConfigInstance() = 0;

           virtual void destroy(int tokenId)=0;

           virtual void destroyNativeMediaplayerSurface (void) = 0;

};

B:BnTvServerService.h

class BnTvServerService : public BnInterface<ITvServerService> {

      public :

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

};

C:BpTvServerService.h

class BpTvServerService : public BpInterface<ITvServerService> {

      public :

           BpTvServerService (const sp<IBinder>& impl) : BpInterface<ITvServerService>(impl) {}

           virtual ~BpTvServerService();

           virtual sp<IBinder> createTvMediaResource(int tokenId);

           virtual sp<IBinder> getTvServerConfigInstance();

           virtual void destroy(int tokenId);

           virtual void destroyNativeMediaplayerSurface (void);

};

D: TvServerService.h

class TvServerService : public BnTvServerService {

    private:

        sp<ITvMediaResource> iTvMediaResource;

        sp<ITvServerConfig> iTvServerConfig;

        int tokenId;

        NativeMediaPlayer *tunerMediaPlayerInstance;

        KeyedVector< int, sp<IBinder> > strongInstanceMap;

        KeyedVector< int, wp<ITvMediaResource> > weakInstanceMap;

        char fileName[128];

        TvServerPowerManager *tvServerPowerManager;

        void createRootTvMediaResource(void);

        void playTunerMediaPlayer(void);

        void playExtensionMediaPlayer(void);

        int getsource(int extid);

        bool isWowLanWakeup;

             static bool mStartAVStatus;

    public:

        NativeMediaPlayer *extensionsMediaPlayerInstance;

        uriValues persistentUri;

        TvServerService();

        virtual ~TvServerService() {};

        static void instantiate();

        virtual sp<IBinder> createTvMediaResource(int tokenId);

        virtual sp<IBinder> getTvServerConfigInstance();

        virtual void destroy(int tokenId);

        sp<ITvMediaResource> getTvMediaResource();

        void destroyNativeMediaplayerSurface (void);

        void destroyRootPlayer(void);

        static void muteStartUpAV(bool muteStatus);

             static bool getStartUpAVStatus(void);

};

2):Bn/Bp端的实现 ITvServerService.cpp

enum {

      CREATETVMEDIARESOURCE=IBinder::FIRST_CALL_TRANSACTION,

      GETTVSERVERCONFIGINSTANCE,

      DESTROY,

      DESTROYMEDIAPLAYERSURFACE

};

 

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

{

      switch (code){

           case CREATETVMEDIARESOURCE: {

           CHECK_INTERFACE(ITvServerService, data, reply);

           int tokenId=data.readInt32();

           sp<IBinder> retval = createTvMediaResource(tokenId);

           reply->writeNoException();

           reply->writeStrongBinder(retval);

           return OK;                        

           }break;

          

           case GETTVSERVERCONFIGINSTANCE:{

           CHECK_INTERFACE(ITvServerService, data, reply);

           sp<IBinder> retval = getTvServerConfigInstance();

           reply->writeNoException();

           reply->writeStrongBinder(retval);

           return OK;                        

           }break;

 

           case DESTROY: {

           CHECK_INTERFACE(ITvServerService, data, reply);

           int tokenId=data.readInt32();

           destroy(tokenId);

           reply->writeNoException();

           return OK;

           }break;

          

           case DESTROYMEDIAPLAYERSURFACE: {

           CHECK_INTERFACE(ITvServerService, data, reply);

           ;

           int tokenId=data.readInt32();

           destroyNativeMediaplayerSurface();

           reply->writeNoException();

           return OK;

           }break;          

      }

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

}

 

BpTvServerService::~BpTvServerService() {

}

     

sp<IBinder> BpTvServerService::createTvMediaResource(int tokenId) {

      sp<IBinder> itssinterface;

      Parcel data, reply;

      data.writeInterfaceToken (ITvServerService::descriptor);

      status_t status = remote ()->transact (CREATETVMEDIARESOURCE, data, &reply);

      itssinterface=reply.readStrongBinder();

      return itssinterface;  

}

 

sp<IBinder> BpTvServerService::getTvServerConfigInstance() {

      sp<IBinder> itscinterface;

      Parcel data, reply;

      //data.writeInterfaceToken(string16("com.tpvision.TvServerService"));

      data.writeInterfaceToken (ITvServerService::descriptor);

      status_t status = remote ()->transact (GETTVSERVERCONFIGINSTANCE, data, &reply);

      itscinterface=reply.readStrongBinder();

      return itscinterface;  

}

……

IMPLEMENT_META_INTERFACE(TvServerService, "org.droidtv.tv.media.TvServerService");

3):TvServerService服务端 TvServerService.cpp

  1. 将tvserver添加到serviceManager

void TvServerService::instantiate ()

{

      if (tvServerServiceInstance == NULL)

      {

           ExtensionsPlayed = false;

           tvServerServiceInstance = new TvServerService();

           defaultServiceManager()->addService(String16("tvserver"), tvServerServiceInstance);

      }

}

  1. 实现服务端的接口,如createTvMediaResource

sp<IBinder> TvServerService::createTvMediaResource(int tokenId)

{

      int cur_index;

    //add mutex to avoid new TvMediaResource with the same tokenId, which may cause TvMw init twice.

      pthread_mutex_lock(&mMutex);

      if ((tokenId == TOKEN_ROOT_TUNER) || (tokenId == TOKEN_ROOT_EXTENSIONS) || (tokenId == TOKEN_AUX_TUNER))

      {

           if((strongInstanceMap.indexOfKey(tokenId))<0)

           {

          ALOGE("%s, %d\r\n",__FUNCTION__, __LINE__);

                 iTvMediaResource = new TvMediaResource(tokenId);

                 strongInstanceMap.add(tokenId ,iTvMediaResource->asBinder());

             pthread_mutex_unlock(&mMutex);

                 return iTvMediaResource->asBinder();

           }

          pthread_mutex_unlock(&mMutex);

           return strongInstanceMap.valueFor(tokenId);

      }

}

1.1.4:TvServerService提供的binder接口

  1. TvMediaPayer继承MediaPayer,作为tvjar提供给app的接口,提供TvPayer类型,如IPVODMediaPayer,TunerMediaPayer,ExtensionMediaPayer,AuxMediaPayer;
  2. TvMediaPayerImpl 继承TvMediaPayer,实现TvMediaPayer的接口方法,其中最为主要的一个方法是去new 一个TvMediaPayerContext(token);既是TvMediaPayer传下来的payer类型。
  3. TvMediaPayerContext,从serviceManager中去获取tvserver的服务,同时根据token类型,创建相应的TVMediaResource,获取binder端。另外TvMediaPayerContext实现ITvMediaPayerContext定义的接口方法。
  4. ITvServerService,作为TvServer的服务端,其中主要的一个方法是去createTvMediaResourcee。
  5. ITvMediaResource,则是管理和提供TvServer暴露给App的接口,相当于一个binder poo,向外提供不同类型的binder接口。

App 获取服务的流程

  1. 先获取一个tvmediaplayer的实例,如TunerMediaPlayer,ExtensionMediaPlayer等,tvMediaPlayer = new TvMediaPlayerImpl(ROOT_TUNER);
  2. 通过tvMediaPlayer获取TvMediaPlayerContext实例,tvMediaPlayer.getTvMediaPlayerContext();
  3. 通过TvMediaPlayerContext获取tvserver的接口

1.2:TvMediaResource

类图如下,像TvServerService一样,也会定义一些头文件,如ITvMediaResource,BnTvMediaResource,BpTvMediaResouce,TvMediaResource,ITvMediaResource.cpp,TvMediaResource.cpp;

在这里就只介绍服务端的实现。

TvMediaResource::TvMediaResource(int token)
{
    tvServerContext = new TvServerContext(token);

……
      iTvMediaCI=new TvMediaCI(tvServerContext);
      iTvMediaStream = new TvMediaStream(tvServerContext);
      iVsecureManager = new VsecureManager(tvServerContext);
      iTvMediaControl = new TvMediaControl(tvServerContext);
      iSubtitles = new Subtitles(tvServerContext);
      iTvMediaRecordControl = new TvMediaRecordControl(tvServerContext);
      iTvOADControl = new TvOADControl(tvServerContext);
      iTvMediaAmmi = new TvMediaAmmi(tvServerContext);
      iTvMediaMultiFeed = new TvMediaMultiFeed(tvServerContext);
      iTvMediaOp=new TvMediaOp(tvServerContext);
      tvServerContext->setTvMediaCIInstance(iTvMediaCI);
      tvServerContext->setTvMediaStreamInstance(iTvMediaStream);
      tvServerContext->setVsecureManagerInstance(iVsecureManager);
      tvServerContext->setTvMediaControlInstance(iTvMediaControl);
      tvServerContext->setTvSubtitleInstance(iSubtitles);
      tvServerContext->setTvMediaRecordControlInstance(iTvMediaRecordControl);
      tvServerContext->setTvOADInstance(iTvOADControl);
      tvServerContext->setTvMediaAmmiInstance(iTvMediaAmmi);
      tvServerContext->setTvMediaMultiFeedInstance(iTvMediaMultiFeed);
      tvServerContext->setTvMediaOpInstance(iTvMediaOp);

           initTvMW();//create tvserver mw comp

}

在TvMediaResource的构造函数中,会创建一个servercontext,并创建每个comp对应的实例,然后将该实例保存在servercontext->setTv**Instance中,当app需要使用某个comp时,必须通过servercontext->getMWInstane来获取对应的实例。这样ap才可以使用到该comp实例中的功能

后续tvmw中各个comp的功能实现,暂不介绍,这篇文章主要介绍如何实现本地服务,如何通过tvjar暴露本地服务的接口,以及如何管理本地服务组件。

 

TunerService继承TvInputService,实现一路输入源为TV_INPUT_TYPE_TUNER,实现onCreatSession方法并返回一个TvInputService.Session对象,即TunerSession,当其他app通过TIF创建session typeTuner,即返回TunerSession,透过TunerSession,返回TunerService返回的一些服务,

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值