电视输入框架

Android TV HAL 图标

Android TV 输入框架 (TIF) 简化了向 Android TV 传输直播内容的过程。 Android TIF 为制造商提供标准 API 以创建用于控制 Android TV 的输入模块,并通过 TV Input 发布的元数据启用直播电视搜索和推荐。

该框架不寻求实施电视标准或区域要求,但确实使设备制造商更容易满足区域数字电视广播标准而无需重新实施。本节中的文档也可能对想要创建自定义 TV 输入的第三方应用程序开发人员有用。

成分

Android TV Input Framework 实现包括一个 TV Input Manager。 TIF 可与第三方应用程序无法替代的系统应用程序 TV 应用程序配合使用,以访问内置和 IP 调谐器频道。 TV App 通过 TV Input Manager 与设备制造商或其他方提供的 TV Input 模块进行通信。

TV 输入框架包括:

  • TV Provider ( com.android.providers.tv.TvProvider ):频道、节目和相关权限的数据库
  • TV App ( com.android.tv.TvActivity ):处理用户交互的应用
  • TV Input Manager ( android.media.tv.TvInputManager ):允许 TV Inputs 与 TV App 通信
  • TV Input:代表物理或虚拟调谐器和输入端口的应用程序
  • TV Input HAL( tv_input模块):允许系统 TV Input 在实现时访问 TV 特定硬件的硬件定义
  • 家长控制:允许阻止频道和节目的技术
  • HDMI-CEC:允许通过 HDMI 远程控制各种设备的技术
  • Tuner Framework:内置调谐器电视输入的框架
  • MediaCas:条件访问框架
  • 调谐器资源管理器:用于管理电视输入、MediaCas 和内置调谐器输入的硬件资源的服务

下面将详细介绍这些组件。有关 Android TV 输入框架架构的详细视图,请参见下图。

Android TIF 架构概述
图 1. Android TV 输入框架 (TIF) 架构

流动

以下是架构的实施方式:

  1. 用户看到 TV 应用程序并与之交互,这是一个第三方应用程序无法替代的系统应用程序。
  2. TV App 显示来自 TV Input 的 AV 内容。
  3. TV 应用程序无法直接与 TV Inputs 对话。 TV Input Manager 识别 TV 应用程序的 TV Input 状态。有关这些限制的更多详细信息,请参阅下面的TV Input Manager

权限

  • 只有signatureOrSystem TV Inputs 和 TV App 可以完全访问 TV Provider 数据库并能够接收 KeyEvent。
  • 只有系统 TV Input 可以通过 TV Input Manager 服务访问 TV Input HAL。通过 TV Input Manager 会话一对一地访问 TV Input。
  • 第三方 TV 输入具有对 TV Provider 数据库的包锁定访问权限,并且只能对匹配的包行进行读/写。
  • 第三方电视输入既可以显示自己的内容,也可以显示来自设备制造商的直通电视输入的内容,例如 HDMI1。它们无法显示来自非直通电视输入的内容,例如内置或 IPTV 调谐器。
  • 硬件 TV Input 应用程序的TV_INPUT_HARDWARE权限向 TV Input Manager Service 发出信号,通知 TV Input 服务在启动时调用 TV Input Manager Service 并添加其 TV Input。此权限允许硬件 TV Input 应用程序支持每个 TV Input 服务的多个 TV Input,以及能够动态添加和删除其支持的 TV Input。

电视提供商

TV Provider 数据库存储来自 TV Inputs 的频道和节目。 TV Provider 还发布和管理相关权限,以便 TV Input 只能看到他们自己的记录。例如,特定的 TV Input 只能看到它提供的频道和节目,并且被禁止访问任何其他 TV Input 的频道和节目。

电视提供商在内部将“广播类型”映射到“规范类型”。 TV Inputs 负责使用基础广播标准中的值填充“广播类型”,并且“规范类型”字段将自动填充来自android.provider.TvContract.Genres的正确关联类型。例如,对于广播标准 ATSC A/65 和类型为 0x25(意为“体育”)的节目,电视输入将使用字符串“体育”填充“广播类型”,而电视提供商将使用“规范类型”字段填充映射值android.provider.TvContract.Genres.SPORTS

有关 TV Provider 的详细视图,请参见下图。

安卓电视提供商
图 2. Android TV 提供商

只有特权系统分区中的应用程序才能读取整个 TV Provider 数据库。

直通电视输入不存储频道和节目。

除了频道和节目的标准字段外,TV Provider 数据库还在每个表中提供了一个 BLOB 类型字段COLUMN_INTERNAL_PROVIDER_DATA ,TV Inputs 可以使用它来存储任意数据。该 BLOB 数据可以包括自定义信息,例如相关调谐器的频率,并且可以在协议缓冲区或其他形式中提供。可搜索字段可用于使某些频道在搜索中不可用(例如满足特定国家/地区的内容保护要求)。

数据库字段示例

TV Provider 支持频道 ( android.provider.TvContract.Channels ) 和节目 ( android.provider.TvContract.Programs ) 表中的结构化数据。这些表格由 TV 输入和系统应用程序(如 TV 应用程序)填充和访问。这些表有四种类型的字段:

  • 显示:显示字段包含应用程序可能希望用户看到的信息,例如频道名称 ( COLUMN_DISPLAY_NAME ) 或编号 ( COLUMN_DISPLAY_NUMBER ),或正在观看的节目的标题。
  • 元数据:根据相关标准,用于识别内容的三个字段,如通道的传输流 ID( COLUMN_TRANSPORT_STREAM_ID )、原始网络 ID( COLUMN_ORIGINAL_NETWORK_ID )和服务 ID( COLUMN_SERVICE_ID )。
  • 内部数据:用于自定义使用 TV 输入的字段。
    某些字段,例如COLUMN_INTERNAL_PROVIDER_DATA ,是可自定义的 BLOB 字段,电视输入可以在其中存储有关其频道或节目的任意元数据。
  • 标志:标志字段表示是否应限制频道搜索​​、浏览或查看。这只能在通道级别设置。所有节目均以频道设置为准。
    • COLUMN_SEARCHABLE :在某些地区可能需要限制某些频道的搜索。 COLUMN_SEARCHABLE = 0表示频道不应出现在搜索结果中。
    • COLUMN_BROWSABLE :仅对系统应用程序可见。限制频道被应用程序浏览。 COLUMN_BROWSABLE = 0表示频道不应包含在频道列表中。
    • COLUMN_LOCKED :仅对系统应用程序可见。限制不输入PIN码的无效帐户查看频道。 COLUMN_LOCKED = 1表示频道应受家长控制保护。

有关更详尽的字段列表,请参阅android/frameworks/base/media/java/android/media/tv/TvContract.java

权限和访问控制

任何有权访问相应行的人都可以看到所有字段。用户无法直接访问任何字段;他们只能看到 TV 应用、系统应用或 TV 输入显示的内容。

  • 每行都有PACKAGE_NAME ,即拥有该行的包(应用程序),通过 TvProvider.java 对 Query、Insert、Update 进行了检查。 TV Input 只能访问它编写的信息,并与其他 TV Input 提供的信息隔离开来。
  • 通过 AndroidManifest.xml 读取、写入权限(需要用户同意)以确定可用频道。
  • 只有signatureOrSystem应用程序可以获得访问整个数据库的ACCESS_ALL_EPG_DATA权限。

电视输入管理器

TV Input Manager 为整个 Android TV Input Framework 提供了一个中央系统 API。它仲裁应用程序和电视输入之间的交互,并提供家长控制功能。 TV Input Manager 会话必须与 TV Input 一对一地创建。 TV Input Manager 允许访问已安装的 TV Input,因此应用可以:

  • 列出电视输入并检查其状态
  • 创建会话和管理监听器

对于会话,TV 应用程序只能将 TV 输入调整到它已添加到 TV Provider 数据库的 URI,但可以使用TvContract.buildChannelUriForPassthroughInput()调整到的直通 TV 输入除外。 TV Input 也可以设置其音量。由设备制造商(签名应用程序)或安装在系统分区中的其他应用程序提供和签名的 TV Input 将有权访问整个 TV Provider 数据库。此访问权限可用于构建应用程序以浏览和搜索所有可用的电视频道和节目。

应用可以创建并注册TvInputCallbackandroid.media.tv.TvInputManager以在 TV Input 的状态更改或添加或删除 TV Input 时回调。例如,TV 应用程序可以在 TV Input 断开连接时做出反应,将其显示为断开连接并阻止其选择。

TV Input Manager 抽象了 TV App 和 TV Inputs 之间的通信。 TV Input Manager 和 TV Input 的标准界面允许多个设备制造商创建自己的 TV 应用程序,同时帮助所有第三方 TV Inputs 在所有 TV 应用程序上工作。

电视输入

TV Input 是 Android 应用,因为它们具有 AndroidManifest.xml 并已安装(通过 Play、预安装或旁加载)。 Android TV 支持预装系统应用、设备制造商签名的应用和第三方 TV Input。

有些输入,如 HDMI 输入或内置调谐器输入,只能由制造商提供,因为它们直接与底层硬件对话。其他的,例如 IPTV、位置转换和外部 STB,可以由第三方在 Google Play 商店中以 APK 的形式提供。下载并安装后,可以在 TV App 中选择新的输入。

直通输入示例

Android TV 系统输入
图 3. Android TV 系统输入

在此示例中,设备制造商提供的 TV Input 是受信任的,并且可以完全访问 TV Provider。作为直通 TV Input,它不会向 TV Provider 注册任何频道或节目。要获取用于引用直通输入的 URI,请使用android.media.tv.TvContract实用程序方法buildChannelUriForPassthroughInput(String inputId) 。 TV App 与 TV Input Manager 通信以访问 HDMI TV Input。

内置调谐器示例

Android TV 内置调谐器输入
图 4. Android TV 内置调谐器输入

在此示例中,设备制造商提供的内置调谐器 TV Input 是受信任的,并且可以完全访问 TV Provider。

第三方输入示例

Android TV 第三方输入
图 5. Android TV 第三方输入

在此示例中,外部 STB TV Input 由第三方提供。由于该 TV Input 无法直接访问传入的 HDMI 视频源,因此它必须通过 TV Input Manager 并使用设备制造商提供的 HDMI TV Input。

通过 TV Input Manager,外部 STB TV Input 可以与 HDMI TV Input 对话,并要求它在 HDMI1 上显示视频。因此,STB TV Input 可以控制电视,而制造商提供的 HDMI TV Input 可以渲染视频。

画中画 (PIP) 示例

Android TV 按键事件
图 6. Android TV 按键事件

上图显示了遥控器上的按钮如何传递到特定的电视输入以实现画中画 (PIP) 显示。这些按钮按下由设备制造商提供的硬件驱动程序解释,将硬件扫描码转换为 Android 键码,并将它们作为KeyEvents传递给标准 Android输入管道InputReaderInputDispatcher函数。如果 TV App 处于焦点位置,这些反过来会触发 TV App 上的事件。

只有系统 TV 输入才有资格接收InputEvents ,并且只有它们具有RECEIVE_INPUT_EVENT系统权限。 TV Input 负责确定要使用哪些 InputEvents,并应允许 TV App 处理它不需要使用的键。

TV App 负责了解哪个系统 TV Input 处于活动状态,即用户选择的意思,并消除传入KeyEvents的歧义并将它们路由到正确的 TV Input Manager 会话,调用dispatchInputEvent()将事件传递给关联的 TV Input .

MHEG-5 输入示例

下图显示了如何通过 Android TIF 路由KeyEvents的更详细视图。

Android TV 红色按钮示例
图 7. Android TV 红色按钮示例

它描绘了一个红色按钮应用程序的流程,该应用程序在欧洲很常见,用于让用户在他们的电视上访问交互式应用程序。可以通过此传输流交付应用程序。单击该按钮时,它可以让用户与这些广播应用程序进行交互。例如,您可能会使用这些广播应用程序来访问相关网页或体育赛事比分。

请参阅广播应用部分以了解广播应用如何与 TV 应用交互。

在这个例子中:

  1. TV 应用程序处于焦点位置并接收所有键。
  2. KeyEvents (例如红色按钮)作为InputEvents.
  3. 系统 TV Input 与 MHEG-5 堆栈集成,具有RECEIVE_INPUT_EVENT系统权限。
  4. 在接收到激活键码(例如红色按钮)时,TV Input 会激活广播应用程序。
  5. TV 输入将KeyEvents作为InputEvents使用,广播应用程序是焦点并处理InputEvents直到被解雇。

注意:第三方电视输入从不接收密钥。

电视输入 HAL

电视输入 HAL 有助于开发电视输入以访问电视特定的硬件。与其他 Android HAL 一样,电视输入 HAL ( tv_input ) 在 AOSP 源代码树中可用,并且供应商会开发其实现。

电视应用

系统TV App向用户呈现直播电视内容。参考 TV App(Live TV)与 Android 平台一起提供,可以由设备制造商按原样使用、定制、扩展或替换。源代码可在 Android 开源项目中获得,您可以在参考 TV 应用文章中开始使用它。

设备制造商可以扩展其 TV 应用程序以实现设备制造商或特定国家/地区的功能,但这不在 TIF 或参考 TV 应用程序的范围内。

系统 TV App 至少需要处理以下任务:

设置和配置

  • 自动检测电视输入
  • 让 TV Inputs 启动频道设置
  • 控制家长设置
  • 编辑频道

查看

  • 访问和浏览所有电视频道
  • 进入电视节目信息栏
  • 显示电子节目指南 (EPG) 数据
  • 支持多个音轨和字幕轨
  • 提供家长控制 PIN 挑战
  • 允许 TV 标准(HbbTV 等)的 TV Input UI 覆盖
  • 填充电视频道和节目的搜索结果
  • 显示应用关联卡片
  • 支持时移 API
  • 处理 DVR 功能并支持电视录制 API

此功能集将随着平台 TIF API 扩展的新 Android 版本而增加。 CTS Verifier 提供兼容性测试覆盖率。

支持第三方电视输入

Android TV 为第三方 TV 输入提供开发者 API,使已安装的应用能够将软件频道传送到直播电视体验中。为确保兼容的 Android 设备实施,系统 TV 应用在向用户显示第三方 TV 输入和频道方面有一些责任。参考直播电视应用程序提供了兼容的实现;如果更换系统 TV App,设备制造商必须确保他们自己的应用程序提供类似的兼容性,以满足开发者对所有 Android TV 设备的期望。

系统 TV 应用程序必须在设备的默认直播电视服务旁边显示第三方输入。开发人员 API 的承诺是用户将能够在其标准电视体验中找到频道(一旦安装)。

内置频道和第三方频道之间的视觉区分是允许的,如 Android CDD 的 TV 应用部分中所定义。

以下部分显示了直播电视应用程序如何满足 CDD 要求。

新频道设置

添加新的第三方输入/频道开始于用户从应用商店(例如 Google Play)查找并安装 TV Input。

一些第三方电视输入会自动将频道添加到 TvProvider 数据库。然而,大多数将提供一个设置活动,使用户能够设置他们的频道、提供登录详细信息和其他操作。系统 TV App 需要确保用户可以激活此 Setup 活动,这就是 CDD 要求第三方输入是远离主 TV App 的最小导航操作的原因。

参考直播电视应用程序提供了用于访问输入的频道源菜单。

前往设置
图 8.转到设置

转到设置中的频道来源
图 9.转到设置中的频道来源

从列表中选择您的来源。
图 10.从列表中选择您的源。

从您的来源添加频道
图 11.从您的来源添加频道。

此外,在安装新的 TvInput 后​​,TV App 菜单顶部会显示通知卡,以将用户直接带到设置:

显示新频道来源的通知可用。
图 12.显示新频道来源可用的通知。

如果用户通过通知采取行动,他们可以选择设置他们的来源,如图 10 所示。

请参阅定义您的电视输入服务以了解开发人员在此领域的期望。

自定义频道列表

设备制造商可能会提供一个 UI 来隐藏某些频道并使用户能够管理他们自己的 EPG。直播电视包括此设施。

在“设置”中打开频道列表。
图 13.设置中打开频道列表。

自定义您的频道列表。
图 14.自定义您的频道列表。

电子节目表

第三方输入开发人员需要确信用户可以在所有兼容的 Android TV 设备上在一般使用期间轻松导航到他们的频道。

来自第三方输入的频道必须作为设备标准直播电视体验 EPG 的一部分呈现。可以使用第三方频道的视觉分离或单独的类别(请参阅 Android CDD 的 TV 应用部分)——关键是用户能够找到他们已安装的频道。

制造商必须实施 TV 应用程序以包含全球搜索请求的搜索结果,以确保最佳用户体验。 Live TV 提供了一个实现(参见com.android.tv.search.TvProviderSearch ),它提供来自第三方输入(平台兼容性所需)以及内置输入的结果。

时移

对于 Android 6.0 及更高版本的设备,TV App 必须支持 Android 框架时移 API 。此外,制造商必须在 TV App 中实现播放控件,允许用户暂停、恢复、倒带和快进播放。

对于支持时移的 TV Input,TV App 需要显示播放控件。

播放控制
图 15.播放控件

硬盘录像机

对于 Android 7.0 及以上版本的设备,TV App 必须支持 Android 框架TV 录制 API ,才能支持、列出和播放录制的节目。

这允许设备制造商将其 DVR 子系统插入 TIF,并显着减少在电视设备上启用或集成 DVR 功能所需的集成工作。它还使第三方能够提供可插入 Android TV 设备的售后 DVR 系统。

除了录制直播内容,TV App 还处理资源冲突。例如,如果设备有两个调谐器,它可以同时录制两个节目。如果用户要求录制三个,则 TV App 必须处理冲突,并且应该显示通知或请求用户为这些请求安排优先级。

TV 应用程序还可以实现更复杂的逻辑,例如在用户请求录制一集时询问他们是否愿意录制系列中的所有未来剧集。

请参阅下图,了解 Android TV 中可能的 DVR 实现。

Android TV 中的数字视频录制
图 16. Android TV 中的数字视频录制

  1. TV Input Service 告诉 TV App 有多少调谐器可用,以便 TV App 可以处理可能的资源冲突。
  2. TV App 接收用户发起的录制电视节目的请求。
  3. TV App 将录制时间表存储在其内部数据库中。
  4. 到了录制时间时,TV 应用程序会传递一个请求以调谐到与录制相关的频道。
  5. TV Input Service 接收到这个请求,响应是否有合适的资源,并调谐到频道。
  6. 然后 TV 应用程序将开始录制的请求传递给 TV Input Manager。
  7. TV Input Service 收到此请求并开始录制。
  8. TV Input Service 将实际视频数据存储在其存储中,该存储可以是外部存储或云存储。
  9. 当需要完成录制时,TV App 会将停止录制请求传递给 TV Input Manager。
  10. 一旦 TV Input Service 收到请求,它就会停止录制并将其关联的元数据添加到 TV Provider,以便 TV App 可以在请求时向用户显示录制内容。

有关在 TV Input 服务中实现录制功能的更多信息,请参阅此TV Recording文章。

有用的资源

  • Android CDD和记录在案的开发人员 API 是权威参考。
  • CTS 验证程序将 API 用作兼容性测试程序的一部分。对直播电视运行此操作可能是在第三方输入的上下文中查看 EPG、搜索、家长控制和其他要求的有用方法。
  • 请参阅定义您的电视输入服务以了解开发人员在此领域的期望。

家长控制

家长控制允许用户阻止不需要的频道和节目,但通过输入 PIN 码绕过阻止。

TV App、TV Input Manager 服务、TV Provider 和 TV Input 共同负责家长控制功能。

家长控制是强制性的,并且由 CTS 验证程序覆盖。

许多国家/地区已经定义了 TV Inputs 可以通过TVContentRating API使用的分级系统。此外,TV Inputs 可以注册他们自己的自定义评级系统,如 CTS 验证器测试所示,该测试引入了“虚假”评级。对于存在标准评级系统的国家/地区,鼓励设备制造商将 TV Input Framework 家长控制与他们可能包含的任何其他机制结合起来。

电视提供商

每个频道行都有一个COLUMN_LOCKED字段,用于在不输入 PIN 码的情况下锁定特定频道的观看。程序字段COLUMN_CONTENT_RATING用于显示,不用于强制家长控制。

电视输入管理器

TV Input Manager 存储每个被阻止TvContentRating并响应isRatingBlocked()来建议是否应该阻止具有给定评级的内容。

电视输入

当显示内容的等级发生变化(在节目或频道更改时)或家长控制设置已更改(在ACTION_BLOCKED_RATINGS_CHANGEDACTION_PARENTAL_CONTROLS_ENABLED_CHANGED上)时,TV Input 检查是否应阻止当前内容,方法是在 TV Input Manager 上调用isRatingBlocked() ) .如果内容应该被阻止,TV Input 会禁用音频和视频,并通过调用notifyContentBlocked(TvContentRating)通知 TV 应用当前内容被阻止。如果不应阻止内容,则 TV Input 会启用音频和视频,并通过调用notifyContentAllowed()通知 TV App 当前内容允许。

电视应用

为了尊重家长控制 API,从而创建一个兼容的平台,系统 TV App 需要为用户提供一种管理家长控制的方式,包括特定应用程序注册的任何自定义评级。

当 TV Input 通知当前内容已被阻止或用户尝试查看被阻止的频道时,TV 应用会显示 PIN 码 UI。

TV App 不直接存储家长控制设置。当用户更改家长控制设置时,每个被屏蔽的TvContentRating都由 TV Input Manager 存储,而被屏蔽的频道则由 TV Provider 存储。

TV App 需要声明权限android.permission.MODIFY_PARENTAL_CONTROLS才能更改家长控制设置。

鼓励设备制造商:

  • 针对参考直播电视应用程序执行 CTS 验证程序家长控制测试,以演示兼容性要求。
  • 使用 Live TV 应用程序作为他们自己的 TV 应用程序的参考:特别是查看ContentRatingsManagerRatingSystemsFragment源,以及它们如何处理自定义评级。

HDMI-CEC

HDMI-CEC 允许一个设备控制另一个设备,从而使单个遥控器能够控制家庭影院中的多个设备。 Android TV 使用它来加速设置并允许通过中央 TV 应用程序远程控制各种 TV 输入。例如,它可以切换输入、开启或关闭设备等等。

Android TIF 将 HDMI-CEC 实现为 HDMI 控制服务,因此设备制造商只需开发与轻量级 Android TV HAL 交互的低级驱动程序,跳过更复杂的业务逻辑。在提供标准实现时,Android 试图通过减少碎片化实现和选择性功能支持来缓解兼容性问题。 HDMI 控制服务使用现有的 Android 服务,包括输入和电源。

这意味着现有的 HDMI-CEC 实现将需要重新设计以与 Android TIF 互操作。我们建议硬件平台包含一个微处理器来接收 CEC 开机和其他命令。

Android TV 上的 CEC 集成
图 17. Android TV 上的 CEC 集成

  1. CEC 总线从当前活动的源接收命令以切换到不同的源。
  2. 驱动程序将命令传递给 HDMI-CEC HAL。
  3. HAL 通知所有ActiveSourceChangeListeners
  4. HDMI 控制服务通过ActiveSourceChangeListener通知源更改。
  5. TV Input Manager 服务为 TV 应用程序生成切换源的意图。
  6. 然后,TV 应用程序为要切换到的 TV Input 创建一个 TV Input Manager 会话,并在该会话上调用setMain
  7. TV Input Manager 会话将此信息传递给 HDMI TV Input。
  8. HDMI 电视输入请求设置边带表面。
  9. 设置表面时,TV Input Manager Service 会生成相应的路由控制命令返回 HDMI Control Service。

电视集成指南

广播应用

由于每个国家/地区都有特定于广播的要求(MHEG、Teletext、HbbTV 等),因此制造商应为广播应用程序提供自己的解决方案,例如:

  • MHEG:本机堆栈
  • 图文电视:本机堆栈
  • HbbTV:来自 Vewd Software 的 HbbTV 解决方案

在 Android L 版本中,Android TV 期望设备制造商使用系统集成商或针对区域 TV 堆栈的 Android 解决方案,将表面传递给 TV 软件堆栈,或传递必要的关键代码以与旧堆栈交互。

以下是广播应用程序和电视应用程序的交互方式:

  1. 电视应用程序处于焦点,接收所有键。
  2. TV App 将按键(例如红色按钮)传递给 TV Input 设备。
  3. TV Input 设备在内部与传统 TV 堆栈集成。
  4. 在接收到激活键码(例如红色按钮)后,TV Input 设备会激活广播应用程序。
  5. 广播应用程序关注 TV 应用程序并处理用户操作。

对于语音搜索/推荐,广播应用可能支持语音搜索的应用内搜索。