Le framework Media Conditional Access Systems (Media CAS) fournit des API standards pour activer les services d'accès conditionnel (AC) sur une gamme de matériel de télévision numérique, y compris les systèmes de télévision par câble, par satellite, terrestre et IPTV. Le framework fonctionne avec le framework Android TV Input et le framework Android TV Tuner, et fournit des API Java appelées à partir de l'application TV Input Service (TIS).
Les principaux objectifs de Media CAS sont les suivants.
- Fournir une API Java publique et un framework de plug-in natif qui peuvent être utilisés par des développeurs tiers et des OEM pour prendre en charge l'AC pour la télévision hertzienne sur Android.
- Fournir un framework d'AC dans Android qui permet aux OEM ATV d'interagir avec différents fournisseurs d'AC de manière cohérente.
- Prendre en charge plusieurs fournisseurs d'AC tiers à l'aide de plug-ins natifs. Les plug-ins d'AC peuvent utiliser des protocoles réseau spécifiques au fournisseur, des formats de message de gestion des droits (EMM)/de message de contrôle des droits (ECM) et des désembrouilleurs.
- Prendre en charge la sécurité matérielle, comme les chaînes de clés.
- Prendre en charge les environnements d'exécution sécurisés (TEE), tels que TrustZone.
Configurations compatibles
Configuration du tuner matériel
Si le matériel est responsable du démultiplexage et du désembrouillage du flux de transport MPEG, le framework Tuner fournit des données d'informations spécifiques au programme (PSI) d'accès conditionnel à l' application TIS afin d'interagir avec les tuners TV matériels.
Les données PSI d'accès conditionnel incluent des descripteurs d'AC, des ECM et des EMM. Ces structures permettent au plug-in d'AC d'obtenir les clés nécessaires pour déchiffrer les flux de contenu.
Figure 1. Configuration du tuner matériel
La configuration matérielle peut comporter une couche TEE, telle que TrustZone, illustrée dans la figure 1. S'il n'y a pas de couche TEE, un plug-in client d'AC peut communiquer avec les services de chaîne de clés matérielles fournis par la plate-forme. En raison des variations spécifiques au fournisseur de ces interfaces, Media CAS ne les standardise pas.
Configuration du logiciel
Avant Android 11, le framework Media CAS pouvait toujours être utilisé pour traiter du contenu logiciel, tel que l'IPTV à partir de multidiffusion/unidiffusion IP. L'application TIS est chargée d'instancier et de provisionner correctement l'objet Java Media CAS.
L'application peut utiliser MediaExtractor ou d'autres analyseurs MPEG2-TS pour extraire les données PSI liées à l'AC, telles que les descripteurs d'AC, les ECM et les EMM. Si l'application utilise le framework MediaExtractor, elle peut déléguer la gestion de la session d'AC, comme l'ouverture d'une session et le traitement des EMM/ECM, au framework MediaExtractor. MediaExtractor configure ensuite la session d'AC directement à l'aide de l'API native.
Sinon, l'application est chargée d'extraire les données PSI liées à l'AC et de configurer la session d'AC à l'aide des API Java Media CAS (par exemple, lorsque l'application utilise son propre analyseur MPEG2-TS).
Figure 2. Configuration de l'entrée IPTV, de l'AC et du désembrouilleur à l'aide du framework MediaExtractor
Dans le scénario d'extracteur logiciel, l'extracteur nécessite un objet de désembrouillage logiciel ou matériel pour chaque piste brouillée, que la piste nécessite ou non des décodeurs sécurisés. Cela est dû aux éléments suivants.
- Si la piste ne nécessite pas de décodage sécurisé, l'extracteur désembrouille l'unité d'accès pour effacer les tampons et extrait les échantillons comme s'il s'agissait d'un flux clair. Ainsi,
MediaCodecn'a pas besoin d'être impliqué dans le désembrouillage. Si la piste nécessite un décodage sécurisé, l'extracteur peut toujours avoir besoin d'un désembrouilleur. Cela se produit lorsque le flux de transport est brouillé au niveau du paquet de transport, où l'en-tête du flux élémentaire par paquets (PES) est brouillé. L'extracteur doit accéder à l'en-tête PES pour transmettre certaines informations (par exemple, l'horodatage de présentation).
Le désembrouilleur n'est pas utilisé par l'extracteur si le flux de transport est brouillé au niveau du paquet PES, où l'en-tête PES est laissé clair. Toutefois, il n'est pas possible de confirmer quand le brouillage se produit tant que le paquet brouillé réel n'est pas arrivé. Par souci de simplicité, supposons qu'un désembrouilleur est utilisé si la piste est déterminée comme étant brouillée en fonction de la table de mappage de programme (PMT).
Limites de la configuration logicielle
Lorsque la piste nécessite un décodage sécurisé, le désembrouilleur doit faire attention lorsqu'il autorise une opération de désembrouillage dans des tampons clairs. Étant donné qu'un décodage audio non sécurisé est requis, si le décodage vidéo nécessite des décodeurs sécurisés, il doit être brouillé sur une session différente de l'audio. L'ECM de la session doit signaler au plug-in qu'un décodeur sécurisé est requis.
Le plug-in doit également être en mesure de lier de manière fiable une clé à sa stratégie de sécurité. Sinon, l'application peut facilement obtenir des images vidéo avec le désembrouilleur audio.
Même lorsque la session nécessite un décodeur sécurisé, il peut être demandé de générer une petite quantité de données pour effacer les tampons par l'extracteur afin de traiter l'en-tête PES. Pour empêcher une application malveillante de faire en sorte que le plug-in renvoie l'ensemble de l'unité d'accès, le plug-in doit analyser la charge utile de transport pour s'assurer qu'elle commence par un en-tête PES du type de flux approprié. Sinon, le plug-in doit refuser la requête.
Séquence de réglage de l'AC
Lors du réglage sur une nouvelle chaîne, le module TIS s'enregistre pour recevoir des descripteurs d'AC, des ECM et des EMM du framework PSI Tuner. Un descripteur d'AC contient l'ID du système d'AC, qui identifie de manière unique un fournisseur d'AC spécifique et d'autres données spécifiques au fournisseur. TIS interroge Media CAS pour déterminer s'il existe un plug-in d'AC capable de gérer le descripteur d'AC.
Figure 3. Réglage du contenu de l'AC
Si l'ID du système d'AC est compatible, une instance de Media CAS est créée et les données privées du fournisseur du descripteur d'AC sont fournies au plug-in. Ensuite, de nouvelles sessions sont ouvertes dans Media CAS pour gérer les flux audio et vidéo. Les sessions nouvellement ouvertes reçoivent des ECM et des EMM pour le plug-in.
Exemple de flux de plug-in d'AC
TIS fournit des ECM au plug-in d'AC à l'aide des API Media CAS. Un ECM contient le mot de contrôle chiffré, qui doit être déchiffré à l'aide des informations d'un EMM. Le plug-in d'AC détermine comment acquérir un EMM pour l'élément en fonction des informations spécifiques au fournisseur dans le descripteur d'AC, qui est fourni par la méthode setPrivateData().
Les EMM peuvent être fournis dans la bande du flux de contenu ou hors bande à l'aide d'une requête réseau initiée par le plug-in d'AC. TIS utilise la méthode processEMM() pour fournir tous les EMM dans la bande au plug-in d'AC.
Si une requête réseau est nécessaire pour obtenir un EMM, le plug-in d'AC est chargé d'effectuer la transaction réseau avec un serveur de licences.
Figure 4. Exemple de plug-in d'AC pour le traitement des EMM et des ECM
Lorsque l'EMM est reçu, le plug-in d'AC l'analyse pour obtenir la clé chiffrée permettant de déchiffrer le mot de contrôle. La clé EMM chiffrée et le mot de contrôle chiffré peuvent être chargés dans une chaîne de clés ou un environnement de confiance pour effectuer le déchiffrement du mot de contrôle et le désembrouillage ultérieur du flux de contenu.
API Java Media CAS
L'API Java Media CAS contient les méthodes suivantes.
Lister tous les plug-ins d'AC disponibles sur l'appareil.
class MediaCas.PluginDescriptor { public String getName(); public int getSystemId(); } static PluginDescriptor[] enumeratePlugins();Construire une instance Media CAS pour le système d'AC spécifié. Cela signifie que le framework Media CAS peut gérer plusieurs systèmes d'AC simultanément.
MediaCas(int CA_system_id); MediaCas(@NonNull Context context, int casSystemId, @Nullable String tvInputServiceSessionId, @PriorityHintUseCaseType int priorityHint);Enregistrer un écouteur d'événements et permettre à l'application de spécifier un gestionnaire dont le looper est utilisé.
interface MediaCas.EventListener { void onEvent(MediaCas, int event, int arg, byte[] data); void onSessionEvent(@NonNull MediaCas mediaCas, @NonNull Session session, int event, int arg, @Nullable byte[] data); void onPluginStatusUpdate(@NonNull MediaCas mediaCas, @PluginStatus int status, int arg); void onResourceLost(@NonNull MediaCas mediaCas); } void setEventListener(MediaCas.EventListener listener, Handler handler);Envoyer les données privées pour le système d'AC. Les données privées peuvent provenir du descripteur d'AC, de la table d'accès conditionnel ou de sources hors bande. Elles ne sont pas associées à une session particulière.
void setPrivateData(@NonNull byte[] data);Traiter un paquet EMM.
void processEmm(@NonNull byte[] data, int offset, int length);Envoyer un événement à un système d'AC. Le format de l'événement est spécifique au schéma et opaque au framework.
void sendEvent(int event, int arg, @Nullable byte[] data);Lancer une opération de provisionnement du type spécifié pour un système d'AC. Lorsqu'un appareil s'abonne à un service de télévision payante pour la première fois, il doit d'abord être provisionné sur le serveur d'AC. Fournir un ensemble de paramètres associés à l'appareil pour le provisionnement.
void provision(String provisionString);Déclencher une actualisation des droits d'accès. Lorsqu'un utilisateur s'abonne à une nouvelle chaîne (par exemple, en répondant à une publicité ou en ajoutant une chaîne dans le guide des programmes électronique (EPG)), l'application doit être en mesure d'indiquer aux clients d'AC d'actualiser les clés de droits d'accès.
void refreshEntitlements(int refreshType);Fermer l'objet Media CAS.
void close();Ouvrir une session.
Session openSession(); Session openSession(@SessionUsage int sessionUsage, @ScramblingMode int scramblingMode);Fermer une session précédemment ouverte.
void Session#close();Fournir les données privées d'AC à partir d'un descripteur d'AC dans la PMT, qui peut provenir de la section d'informations sur le programme ou d'informations ES, à une session d'AC.
void Session#setPrivateData(@NonNull byte[] sessionId, @NonNull byte[] data);Traiter un paquet ECM pour une session.
void Session#processEcm(@NonNull byte[] data, int offset, int length);Obtenir l'ID de session.
byte[] Session#getSessionId();Envoyer un événement de session à un système d'AC. Le format de l'événement est spécifique au schéma et opaque au framework.
void Session#sendSessionEvent(int event, int arg, @Nullable byte[] data);