summaryrefslogtreecommitdiffstats
path: root/components/cdm/browser/cdm_message_filter_android.cc
blob: 82dac5e1ac0f39e2d32b6bd2b991da443162e07a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "components/cdm/browser/cdm_message_filter_android.h"

#include <string>

#include "components/cdm/common/cdm_messages_android.h"
#include "ipc/ipc_message_macros.h"
#include "media/base/android/media_codec_bridge.h"
#include "media/base/android/media_drm_bridge.h"

using content::BrowserThread;
using content::SupportedCodecs;
using media::MediaCodecBridge;
using media::MediaDrmBridge;

namespace cdm {

const size_t kMaxKeySystemLength = 256;

enum CodecType {
  CODEC_AUDIO,
  CODEC_VIDEO
};

struct CodecInfo {
  SupportedCodecs codec;
  CodecType codec_type;
  const char* codec_name;
  const char* container_mime_type;
};

const CodecInfo kCodecsToQuery[] = {
  {content::EME_CODEC_WEBM_VORBIS, CODEC_AUDIO, "vorbis", "video/webm"},
  {content::EME_CODEC_WEBM_VP8, CODEC_VIDEO, "vp8", "video/webm"},
  {content::EME_CODEC_WEBM_VP9, CODEC_VIDEO, "vp9", "video/webm"},
#if defined(USE_PROPRIETARY_CODECS)
  {content::EME_CODEC_MP4_AAC, CODEC_AUDIO, "mp4a", "video/mp4"},
  {content::EME_CODEC_MP4_AVC1, CODEC_VIDEO, "avc1", "video/mp4"}
#endif  // defined(USE_PROPRIETARY_CODECS)
};

static SupportedCodecs GetSupportedCodecs(
    const SupportedKeySystemRequest& request,
    bool video_must_be_compositable) {
  const std::string& key_system = request.key_system;
  SupportedCodecs supported_codecs = content::EME_CODEC_NONE;

  for (size_t i = 0; i < arraysize(kCodecsToQuery); ++i) {
    const CodecInfo& info = kCodecsToQuery[i];
    // TODO(qinmin): Remove the composition logic when secure contents can be
    // composited.
    bool is_secure = (info.codec_type == CODEC_VIDEO)
                         ? (!video_must_be_compositable) : false;
    if ((request.codecs & info.codec) &&
        MediaDrmBridge::IsKeySystemSupportedWithType(
            key_system, info.container_mime_type) &&
        MediaCodecBridge::CanDecode(info.codec_name, is_secure)) {
      supported_codecs |= info.codec;
    }
  }

  return supported_codecs;
}

CdmMessageFilterAndroid::CdmMessageFilterAndroid()
    : BrowserMessageFilter(EncryptedMediaMsgStart) {}

CdmMessageFilterAndroid::~CdmMessageFilterAndroid() {}

bool CdmMessageFilterAndroid::OnMessageReceived(
    const IPC::Message& message, bool* message_was_ok) {
  bool handled = true;
  IPC_BEGIN_MESSAGE_MAP_EX(
      CdmMessageFilterAndroid, message, *message_was_ok)
    IPC_MESSAGE_HANDLER(ChromeViewHostMsg_GetSupportedKeySystems,
                        OnGetSupportedKeySystems)
    IPC_MESSAGE_UNHANDLED(handled = false)
  IPC_END_MESSAGE_MAP_EX()
  return handled;
}

void CdmMessageFilterAndroid::OverrideThreadForMessage(
    const IPC::Message& message, BrowserThread::ID* thread) {
  // Move the IPC handling to FILE thread as it is not very cheap.
  if (message.type() == ChromeViewHostMsg_GetSupportedKeySystems::ID)
    *thread = BrowserThread::FILE;
}

void CdmMessageFilterAndroid::OnGetSupportedKeySystems(
    const SupportedKeySystemRequest& request,
    SupportedKeySystemResponse* response) {
  if (!response) {
    NOTREACHED() << "NULL response pointer provided.";
    return;
  }

  if (request.key_system.size() > kMaxKeySystemLength) {
    NOTREACHED() << "Invalid key system: " << request.key_system;
    return;
  }

  if (!MediaDrmBridge::IsKeySystemSupported(request.key_system))
    return;

  DCHECK(request.codecs & content::EME_CODEC_ALL) << "unrecognized codec";
  response->key_system = request.key_system;
  // TODO(qinmin): check composition is supported or not.
  response->compositing_codecs = GetSupportedCodecs(request, true);
  response->non_compositing_codecs = GetSupportedCodecs(request, false);
}

}  // namespace cdm