TIF是Tv Input Framework的简称,是Android在5.0后加入的tv框架,为了支持android tv功能。
1 TvInputManagerService启动流程
TvInputManagerService在TIF框架结构中扮演Java service层的角色,向java api提供接口实现。
在SystemServer的Main Thread里面,执行run函数时,回去启动各种services :
startBootstrapServices();
startCoreServices();
startOtherServices();
startCoreServices();
startOtherServices();
在startOtherServices()函数里会去启动TvInputManagerService服务:
if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_LIVE_TV)) {
mSystemServiceManager.startService(TvInputManagerService.class);
}
mSystemServiceManager.startService(TvInputManagerService.class);
}
支持TIF,平台需要配置feature PackageManager.FEATURE_LIVE_TV,否则无法启动TvInputManagerService.
startService函数会做下面几件事情:
1)TvInputManagerService注册到SystemService
// Register it.
mServices.add(service);
mServices.add(service);
2)通过反射获取TvInputManagerService实例
public TvInputManagerService(Context context) {
super(context);
mContext = context;
mWatchLogHandler = new WatchLogHandler(mContext.getContentResolver(),
IoThread.get().getLooper());
mTvInputHardwareManager = new TvInputHardwareManager(context, new HardwareListener());
synchronized (mLock) {
getOrCreateUserStateLocked(mCurrentUserId);
}
}
主要实例化TvInputHardwareManager,TvInputHardwareManager辅助TvInputManagerService管理Tv Input device,包含Tv Input Device Status变化等。
WatchLogHandler是一个Handler,用于处理watch事件,对于这个handler的解释如下:
// There are only two kinds of watch events that can happen on the system:
// 1. The current TV input session is tuned to a new channel.
// 2. The session is released for some reason.
// 1. The current TV input session is tuned to a new channel.
// 2. The session is released for some reason.
看实现是有一个db去保存watch 状态,可以控制start watch或end watch.
Handler使用的Looper不是System Server Main thread Looper,所以不会卡System Server Main Thread.
3)调用TvInputManagerService onStart函数
@Override
public void onStart() {
publishBinderService(Context.TV_INPUT_SERVICE, new BinderService());
}
将ITvInputManager service注册到ServiceManager,在BinderService类中实现ITvInputManager的aidl接口,这个实现代码很长,也是TvInputManagerService主要业务,java api层的接口实现就是在BinderService。
4)调用TvInputManagerService onBootPhase函数
在TvInputManagerService启动时,会call到如下函数:
@Override
public void onBootPhase(int phase) {
if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
registerBroadcastReceivers();
} else if (phase == SystemService.PHASE_THIRD_PARTY_APPS_CAN_START) {
synchronized (mLock) {
buildTvInputListLocked(mCurrentUserId, null);
buildTvContentRatingSystemListLocked(mCurrentUserId);
}
}
mTvInputHardwareManager.onBootPhase(phase);
}
对于phase的两种事件解释如下:
/**
* After receiving this boot phase, services can safely call into core system services
* such as the PowerManager or PackageManager.
*/
public static final int PHASE_SYSTEM_SERVICES_READY = 500;
/**
* After receiving this boot phase, services can start/bind to third party apps.
* Apps will be able to make Binder calls into services at this point.
*/
public static final int PHASE_THIRD_PARTY_APPS_CAN_START = 600;
看起来是TvInputManagerService在启动时,有两个启动完毕时间点,一个是可以被core service call,另外一种是被third party apps start/bind
在收到PHASE_SYSTEM_SERVICES_READY event后,会去注册广播接收器:
private void registerBroadcastReceivers() {
PackageMonitor monitor = new PackageMonitor() {
这里有一个内部类PackageMonitor,有很多的call back接口,以及内部接口:
private void buildTvInputList(String[] packages) {
synchronized (mLock) {
buildTvInputListLocked(getChangingUserId(), packages);
buildTvContentRatingSystemListLocked(getChangingUserId());
}
}
call back接口主要为:
public void onPackageUpdateFinished(String packageName, int uid)
public void onPackagesAvailable(String[] packages)
public void onPackagesUnavailable(String[] packages)
public void onSomePackagesChanged()
public boolean onPackageChanged(String packageName, int uid, String[] components)
public void