电视输入框架

Android TV HAL 图标

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

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

成分

Android TV 输入框架实现包括 TV 输入管理器。 TIF 与 TV 应用程序(无法被第三方应用程序替代的系统应用程序)配合使用,以访问内置频道和 IP 调谐器频道。电视应用程序通过电视输入管理器与设备制造商或其他方提供的电视输入模块进行通信。

电视输入框架包括:

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

下面详细介绍这些组件。请参阅下图,了解 Android TV 输入框架架构的详细视图。

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

流动

以下是该架构的运用方式:

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

权限

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

电视提供商

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

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

有关电视提供商的详细视图,请参见下图。

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

只有特权系统分区中的应用程序才能读取整个电视提供商数据库。

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

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

数据库字段示例

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

  • 显示:显示字段包含应用程序可能希望用户可见的信息,例如频道名称 ( COLUMN_DISPLAY_NAME ) 或编号 ( COLUMN_DISPLAY_NUMBER ),或者正在观看的节目的标题。
  • 元数据:根据相关标准,有三个字段用于标识内容,例如频道的传输流ID( COLUMN_TRANSPORT_STREAM_ID )、原始网络ID( COLUMN_ORIGINAL_NETWORK_ID )和服务ID( COLUMN_SERVICE_ID )。
  • 内部数据:供电视输入自定义使用的字段。
    某些字段(例如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

权限和访问控制

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

  • 每行都有PACKAGE_NAME ,即拥有该行的包(应用程序),通过 TvProvider.java 检查查询、插入、更新。电视输入只能访问其写入的信息,并且与其他电视输入提供的信息隔离开来。
  • 通过 AndroidManifest.xml 读取、写入权限(需要用户同意)以确定可用通道。
  • 只有signatureOrSystem应用程序可以获得ACCESS_ALL_EPG_DATA权限来访问整个数据库。

电视输入管理器

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

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

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

应用程序可以使用android.media.tv.TvInputManager创建和注册TvInputCallback ,以便在电视输入的状态更改或添加或删除电视输入时进行回调。例如,电视应用程序可以在电视输入断开连接时做出反应,将其显示为已断开连接并阻止其选择。

电视输入管理器抽象了电视应用程序和电视输入之间的通信。电视输入管理器和电视输入的标准接口允许多个设备制造商创建自己的电视应用程序,同时帮助所有第三方电视输入在所有电视应用程序上工作。

电视输入

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

某些输入(例如 HDMI 输入或内置调谐器输入)只能由制造商提供,因为它们直接与底层硬件通信。其他功能,例如 IPTV、异地移位和外部 STB,可以由第三方在 Google Play 商店上以 APK 形式提供。下载并安装后,可以在电视应用程序中选择新的输入。

直通输入示例

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

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

内置调谐器示例

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

在此示例中,设备制造商提供的内置调谐器电视输入受到信任,并且具有对电视提供商的完全访问权限。

第三方输入示例

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

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

通过电视输入管理器,外部机顶盒电视输入可以与 HDMI 电视输入对话并要求其在 HDMI1 上显示视频。因此,STB 电视输入可以控制电视,而制造商提供的 HDMI 电视输入则可以渲染视频。

画中画 (PIP) 示例

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

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

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

TV 应用程序负责了解哪个系统 TV 输入处于活动状态(即由用户选择),并消除传入的KeyEvents并将它们路由到正确的 TV 输入管理器会话,调用dispatchInputEvent()将事件传递到关联的 TV 输入。

MHEG-5 输入示例

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

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

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

请参阅广播应用程序部分,了解广播应用程序如何与电视应用程序交互。

在这个例子中:

  1. 电视应用程序处于焦点并接收所有按键。
  2. KeyEvents (例如红色按钮)作为InputEvents.
  3. 系统 TV Input 与 MHEG-5 堆栈集成,并具有RECEIVE_INPUT_EVENT系统权限。
  4. 收到激活键码(例如红色按钮)后,电视输入将激活广播应用程序。
  5. 电视输入将KeyEvents作为InputEvents进行消费,广播应用程序是焦点并处理InputEvents直到被关闭。

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

电视输入 HAL

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

注意:从 Android 14 开始,TV 输入 HAL 接口使用AIDL定义。

电视应用程序

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

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

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

设置和配置

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

观看

  • 访问和导航所有电视频道
  • 访问电视节目信息栏
  • 显示电子节目指南 (EPG) 数据
  • 支持多种音轨和字幕轨
  • 提供家长控制 PIN 码挑战
  • 允许电视输入 UI 覆盖电视标准(HbbTV 等)
  • 填充电视频道和节目的搜索结果
  • 显示应用程序链接卡
  • 支持时移API
  • 处理 DVR 功能并支持电视录制 API

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

支持第三方电视输入

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

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

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

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

新频道设置

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

某些第三方电视输入会自动将频道添加到 TvProvider 数据库。不过,大多数都会提供设置活动,以使用户能够设置其频道、提供登录详细信息和其他操作。系统电视应用程序需要确保用户可以激活此设置活动,这就是为什么 CDD 要求第三方输入是远离主电视应用程序的最少导航操作。

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

前往设置
图 8.转到“设置”

转到“设置”中的“频道源”
图 9.转到“设置”中的“通道源”

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

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

此外,安装新的 TvInput 后​​,电视应用程序菜单顶部会显示通知卡,以便用户直接进入设置:

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

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

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

自定义频道列表

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

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

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

电子节目指南

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

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

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

时移

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

对于支持时移的电视输入,电视应用程序需要显示播放控件。

播放控制
图 15.播放控件

硬盘录像机

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

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

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

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

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

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

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

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

有用的资源

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

家长控制

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

家长控制功能的责任由电视应用程序、电视输入管理器服务、电视提供商和电视输入共同承担。

家长控制是强制性的,并且由 CTS Verifier 涵盖。

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

电视提供商

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

电视输入管理器

TV 输入管理器存储每个被阻止的TvContentRating并响应isRatingBlocked()以建议是否应阻止具有给定评级的内容。

电视输入

当显示内容的分级已更改(节目或频道更改时)或家长控制设置已更改(在ACTION_BLOCKED_RATINGS_CHANGEDACTION_PARENTAL_CONTROLS_ENABLED_CHANGED上)时,电视输入会检查是否应通过在电视输入管理器上调用isRatingBlocked()来阻止当前内容。如果内容应该被阻止,电视输入会禁用音频和视频,并通过调用notifyContentBlocked(TvContentRating)通知电视应用当前内容被阻止。如果内容不应被阻止,电视输入将启用音频和视频,并通过调用notifyContentAllowed()通知电视应用当前内容已被允许。

电视应用程序

为了遵守家长控制 API 并因此创建兼容平台,系统 TV 应用程序需要为用户提供一种管理家长控制的方法,包括特定应用程序注册的任何自定义收视率。

当电视输入通知当前内容被阻止或用户尝试观看被阻止的频道时,电视应用程序会显示 PIN 码 UI。

TV 应用程序不直接存储家长控制设置。当用户更改家长控制设置时,每个被阻止的TvContentRating由电视输入管理器存储,并且被阻止的频道由电视提供商存储。

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

鼓励设备制造商:

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

HDMI-CEC

HDMI-CEC 允许一台设备控制另一台设备,从而使单个遥控器能够控制家庭影院中的多个设备。 Android 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 输入管理器服务生成电视应用程序切换源的意图。
  6. 然后,电视应用程序为要切换到的电视输入创建一个电视输入管理器会话,并在该会话上调用setMain
  7. 电视输入管理器会话将此信息传递到 HDMI 电视输入。
  8. HDMI TV 输入请求设置边带表面。
  9. 设置表面时,电视输入管理器服务会生成相应的路由控制命令返回 HDMI 控制服务。

电视集成指南

广播应用程序

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

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

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

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

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

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