• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
GetSupportedCodecs(const SupportedKeySystemRequest & request,bool video_must_be_compositable)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 
CdmMessageFilterAndroid()69 CdmMessageFilterAndroid::CdmMessageFilterAndroid()
70     : BrowserMessageFilter(EncryptedMediaMsgStart) {}
71 
~CdmMessageFilterAndroid()72 CdmMessageFilterAndroid::~CdmMessageFilterAndroid() {}
73 
OnMessageReceived(const IPC::Message & message)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 
OverrideThreadForMessage(const IPC::Message & message,BrowserThread::ID * thread)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 
OnQueryKeySystemSupport(const SupportedKeySystemRequest & request,SupportedKeySystemResponse * response)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 
OnGetPlatformKeySystemNames(std::vector<std::string> * key_systems)116 void CdmMessageFilterAndroid::OnGetPlatformKeySystemNames(
117     std::vector<std::string>* key_systems) {
118   *key_systems = MediaDrmBridge::GetPlatformKeySystemNames();
119 }
120 
121 }  // namespace cdm
122