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. 4 5 #include "components/cdm/browser/cdm_message_filter_android.h" 6 7 #include <string> 8 #include <vector> 9 10 #include "components/cdm/common/cdm_messages_android.h" 11 #include "ipc/ipc_message_macros.h" 12 #include "media/base/android/media_codec_bridge.h" 13 #include "media/base/android/media_drm_bridge.h" 14 15 using content::BrowserThread; 16 using content::SupportedCodecs; 17 using media::MediaCodecBridge; 18 using media::MediaDrmBridge; 19 20 namespace cdm { 21 22 const size_t kMaxKeySystemLength = 256; 23 24 enum CodecType { 25 CODEC_AUDIO, 26 CODEC_VIDEO 27 }; 28 29 struct CodecInfo { 30 SupportedCodecs codec; 31 CodecType codec_type; 32 const char* codec_name; 33 const char* container_mime_type; 34 }; 35 36 const CodecInfo kCodecsToQuery[] = { 37 {content::EME_CODEC_WEBM_VORBIS, CODEC_AUDIO, "vorbis", "video/webm"}, 38 {content::EME_CODEC_WEBM_VP8, CODEC_VIDEO, "vp8", "video/webm"}, 39 {content::EME_CODEC_WEBM_VP9, CODEC_VIDEO, "vp9", "video/webm"}, 40 #if defined(USE_PROPRIETARY_CODECS) 41 {content::EME_CODEC_MP4_AAC, CODEC_AUDIO, "mp4a", "video/mp4"}, 42 {content::EME_CODEC_MP4_AVC1, CODEC_VIDEO, "avc1", "video/mp4"} 43 #endif // defined(USE_PROPRIETARY_CODECS) 44 }; 45 46 static SupportedCodecs GetSupportedCodecs( 47 const SupportedKeySystemRequest& request, 48 bool video_must_be_compositable) { 49 const std::string& key_system = request.key_system; 50 SupportedCodecs supported_codecs = content::EME_CODEC_NONE; 51 52 for (size_t i = 0; i < arraysize(kCodecsToQuery); ++i) { 53 const CodecInfo& info = kCodecsToQuery[i]; 54 // TODO(qinmin): Remove the composition logic when secure contents can be 55 // composited. 56 bool is_secure = (info.codec_type == CODEC_VIDEO) 57 ? (!video_must_be_compositable) : false; 58 if ((request.codecs & info.codec) && 59 MediaDrmBridge::IsKeySystemSupportedWithType( 60 key_system, info.container_mime_type) && 61 MediaCodecBridge::CanDecode(info.codec_name, is_secure)) { 62 supported_codecs |= info.codec; 63 } 64 } 65 66 return supported_codecs; 67 } 68 69 CdmMessageFilterAndroid::CdmMessageFilterAndroid() 70 : BrowserMessageFilter(EncryptedMediaMsgStart) {} 71 72 CdmMessageFilterAndroid::~CdmMessageFilterAndroid() {} 73 74 bool CdmMessageFilterAndroid::OnMessageReceived(const IPC::Message& message) { 75 bool handled = true; 76 IPC_BEGIN_MESSAGE_MAP(CdmMessageFilterAndroid, message) 77 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_QueryKeySystemSupport, 78 OnQueryKeySystemSupport) 79 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_GetPlatformKeySystemNames, 80 OnGetPlatformKeySystemNames) 81 IPC_MESSAGE_UNHANDLED(handled = false) 82 IPC_END_MESSAGE_MAP() 83 return handled; 84 } 85 86 void CdmMessageFilterAndroid::OverrideThreadForMessage( 87 const IPC::Message& message, BrowserThread::ID* thread) { 88 // Move the IPC handling to FILE thread as it is not very cheap. 89 if (message.type() == ChromeViewHostMsg_QueryKeySystemSupport::ID) 90 *thread = BrowserThread::FILE; 91 } 92 93 void CdmMessageFilterAndroid::OnQueryKeySystemSupport( 94 const SupportedKeySystemRequest& request, 95 SupportedKeySystemResponse* response) { 96 if (!response) { 97 NOTREACHED() << "NULL response pointer provided."; 98 return; 99 } 100 101 if (request.key_system.size() > kMaxKeySystemLength) { 102 NOTREACHED() << "Invalid key system: " << request.key_system; 103 return; 104 } 105 106 if (!MediaDrmBridge::IsKeySystemSupported(request.key_system)) 107 return; 108 109 DCHECK(request.codecs & content::EME_CODEC_ALL) << "unrecognized codec"; 110 response->key_system = request.key_system; 111 // TODO(qinmin): check composition is supported or not. 112 response->compositing_codecs = GetSupportedCodecs(request, true); 113 response->non_compositing_codecs = GetSupportedCodecs(request, false); 114 } 115 116 void CdmMessageFilterAndroid::OnGetPlatformKeySystemNames( 117 std::vector<std::string>* key_systems) { 118 *key_systems = MediaDrmBridge::GetPlatformKeySystemNames(); 119 } 120 121 } // namespace cdm 122