1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "components/cdm/browser/cdm_message_filter_android.h"
9 #include "components/cdm/common/cdm_messages_android.h"
10 #include "ipc/ipc_message_macros.h"
11 #include "media/base/android/media_codec_bridge.h"
12 #include "media/base/android/media_drm_bridge.h"
14 using content::BrowserThread;
15 using content::SupportedCodecs;
16 using media::MediaCodecBridge;
17 using media::MediaDrmBridge;
21 const size_t kMaxKeySystemLength = 256;
29 SupportedCodecs codec;
31 const char* codec_name;
32 const char* container_mime_type;
35 const CodecInfo kCodecsToQuery[] = {
36 {content::EME_CODEC_WEBM_VORBIS, CODEC_AUDIO, "vorbis", "video/webm"},
37 {content::EME_CODEC_WEBM_VP8, CODEC_VIDEO, "vp8", "video/webm"},
38 {content::EME_CODEC_WEBM_VP9, CODEC_VIDEO, "vp9", "video/webm"},
39 #if defined(USE_PROPRIETARY_CODECS)
40 {content::EME_CODEC_MP4_AAC, CODEC_AUDIO, "mp4a", "video/mp4"},
41 {content::EME_CODEC_MP4_AVC1, CODEC_VIDEO, "avc1", "video/mp4"}
42 #endif // defined(USE_PROPRIETARY_CODECS)
45 static SupportedCodecs GetSupportedCodecs(
46 const SupportedKeySystemRequest& request,
47 bool video_must_be_compositable) {
48 const std::string& key_system = request.key_system;
49 SupportedCodecs supported_codecs = content::EME_CODEC_NONE;
51 for (size_t i = 0; i < arraysize(kCodecsToQuery); ++i) {
52 const CodecInfo& info = kCodecsToQuery[i];
53 // TODO(qinmin): Remove the composition logic when secure contents can be
55 bool is_secure = (info.codec_type == CODEC_VIDEO)
56 ? (!video_must_be_compositable) : false;
57 if ((request.codecs & info.codec) &&
58 MediaDrmBridge::IsKeySystemSupportedWithType(
59 key_system, info.container_mime_type) &&
60 MediaCodecBridge::CanDecode(info.codec_name, is_secure)) {
61 supported_codecs |= info.codec;
65 return supported_codecs;
68 CdmMessageFilterAndroid::CdmMessageFilterAndroid()
69 : BrowserMessageFilter(EncryptedMediaMsgStart) {}
71 CdmMessageFilterAndroid::~CdmMessageFilterAndroid() {}
73 bool CdmMessageFilterAndroid::OnMessageReceived(
74 const IPC::Message& message, bool* message_was_ok) {
76 IPC_BEGIN_MESSAGE_MAP_EX(
77 CdmMessageFilterAndroid, message, *message_was_ok)
78 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_GetSupportedKeySystems,
79 OnGetSupportedKeySystems)
80 IPC_MESSAGE_UNHANDLED(handled = false)
81 IPC_END_MESSAGE_MAP_EX()
85 void CdmMessageFilterAndroid::OverrideThreadForMessage(
86 const IPC::Message& message, BrowserThread::ID* thread) {
87 // Move the IPC handling to FILE thread as it is not very cheap.
88 if (message.type() == ChromeViewHostMsg_GetSupportedKeySystems::ID)
89 *thread = BrowserThread::FILE;
92 void CdmMessageFilterAndroid::OnGetSupportedKeySystems(
93 const SupportedKeySystemRequest& request,
94 SupportedKeySystemResponse* response) {
96 NOTREACHED() << "NULL response pointer provided.";
100 if (request.key_system.size() > kMaxKeySystemLength) {
101 NOTREACHED() << "Invalid key system: " << request.key_system;
105 if (!MediaDrmBridge::IsKeySystemSupported(request.key_system))
108 DCHECK(request.codecs & content::EME_CODEC_ALL) << "unrecognized codec";
109 response->key_system = request.key_system;
110 // TODO(qinmin): check composition is supported or not.
111 response->compositing_codecs = GetSupportedCodecs(request, true);
112 response->non_compositing_codecs = GetSupportedCodecs(request, false);