1010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
2d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// found in the LICENSE file.
4d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
5010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "components/cdm/browser/cdm_message_filter_android.h"
6d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
7d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include <string>
8f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include <vector>
9d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
10010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "components/cdm/common/cdm_messages_android.h"
11d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ipc/ipc_message_macros.h"
12d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "media/base/android/media_codec_bridge.h"
13d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "media/base/android/media_drm_bridge.h"
14d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
15d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)using content::BrowserThread;
165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuusing content::SupportedCodecs;
17d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)using media::MediaCodecBridge;
18d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)using media::MediaDrmBridge;
19d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
20010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)namespace cdm {
21d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
22a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)const size_t kMaxKeySystemLength = 256;
23a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochenum CodecType {
250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  CODEC_AUDIO,
260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  CODEC_VIDEO
270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch};
280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochstruct CodecInfo {
305c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  SupportedCodecs codec;
310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  CodecType codec_type;
320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  const char* codec_name;
330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  const char* container_mime_type;
340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch};
350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochconst CodecInfo kCodecsToQuery[] = {
375c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  {content::EME_CODEC_WEBM_VORBIS, CODEC_AUDIO, "vorbis", "video/webm"},
385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  {content::EME_CODEC_WEBM_VP8, CODEC_VIDEO, "vp8", "video/webm"},
395c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  {content::EME_CODEC_WEBM_VP9, CODEC_VIDEO, "vp9", "video/webm"},
400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#if defined(USE_PROPRIETARY_CODECS)
415c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  {content::EME_CODEC_MP4_AAC, CODEC_AUDIO, "mp4a", "video/mp4"},
425c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  {content::EME_CODEC_MP4_AVC1, CODEC_VIDEO, "avc1", "video/mp4"}
430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#endif  // defined(USE_PROPRIETARY_CODECS)
440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch};
450529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
465c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liustatic SupportedCodecs GetSupportedCodecs(
47c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    const SupportedKeySystemRequest& request,
48d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    bool video_must_be_compositable) {
49c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  const std::string& key_system = request.key_system;
505c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  SupportedCodecs supported_codecs = content::EME_CODEC_NONE;
510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  for (size_t i = 0; i < arraysize(kCodecsToQuery); ++i) {
530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const CodecInfo& info = kCodecsToQuery[i];
540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    // TODO(qinmin): Remove the composition logic when secure contents can be
550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    // composited.
560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    bool is_secure = (info.codec_type == CODEC_VIDEO)
570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                         ? (!video_must_be_compositable) : false;
580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    if ((request.codecs & info.codec) &&
590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        MediaDrmBridge::IsKeySystemSupportedWithType(
600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch            key_system, info.container_mime_type) &&
610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        MediaCodecBridge::CanDecode(info.codec_name, is_secure)) {
625c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      supported_codecs |= info.codec;
630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    }
64c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  }
65d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
66d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  return supported_codecs;
67d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
68d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
69010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)CdmMessageFilterAndroid::CdmMessageFilterAndroid()
705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    : BrowserMessageFilter(EncryptedMediaMsgStart) {}
71d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
72010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)CdmMessageFilterAndroid::~CdmMessageFilterAndroid() {}
73d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
74cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool CdmMessageFilterAndroid::OnMessageReceived(const IPC::Message& message) {
75d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  bool handled = true;
76cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  IPC_BEGIN_MESSAGE_MAP(CdmMessageFilterAndroid, message)
77f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    IPC_MESSAGE_HANDLER(ChromeViewHostMsg_QueryKeySystemSupport,
78f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                        OnQueryKeySystemSupport)
79f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    IPC_MESSAGE_HANDLER(ChromeViewHostMsg_GetPlatformKeySystemNames,
80f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                        OnGetPlatformKeySystemNames)
81d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    IPC_MESSAGE_UNHANDLED(handled = false)
82cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  IPC_END_MESSAGE_MAP()
83d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  return handled;
84d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
85d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
86010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void CdmMessageFilterAndroid::OverrideThreadForMessage(
87d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    const IPC::Message& message, BrowserThread::ID* thread) {
88d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // Move the IPC handling to FILE thread as it is not very cheap.
89f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (message.type() == ChromeViewHostMsg_QueryKeySystemSupport::ID)
90d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    *thread = BrowserThread::FILE;
91d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
92d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
93f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void CdmMessageFilterAndroid::OnQueryKeySystemSupport(
9468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    const SupportedKeySystemRequest& request,
9568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    SupportedKeySystemResponse* response) {
96a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!response) {
97a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    NOTREACHED() << "NULL response pointer provided.";
98d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    return;
99a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
100a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
101a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (request.key_system.size() > kMaxKeySystemLength) {
102a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    NOTREACHED() << "Invalid key system: " << request.key_system;
103a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return;
104a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
105d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
106c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (!MediaDrmBridge::IsKeySystemSupported(request.key_system))
107d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    return;
108d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
1095c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  DCHECK(request.codecs & content::EME_CODEC_ALL) << "unrecognized codec";
110a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  response->key_system = request.key_system;
111d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // TODO(qinmin): check composition is supported or not.
112c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  response->compositing_codecs = GetSupportedCodecs(request, true);
113c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  response->non_compositing_codecs = GetSupportedCodecs(request, false);
114d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
115d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
116f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void CdmMessageFilterAndroid::OnGetPlatformKeySystemNames(
117f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    std::vector<std::string>* key_systems) {
118f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  *key_systems = MediaDrmBridge::GetPlatformKeySystemNames();
119f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
120f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
121010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}  // namespace cdm
122