11320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Copyright 2014 The Chromium Authors. All rights reserved.
21320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Use of this source code is governed by a BSD-style license that can be
31320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// found in the LICENSE file.
41320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
51320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "content/renderer/media/crypto/encrypted_media_player_support_impl.h"
61320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
71320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include <string>
81320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
91320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/bind.h"
101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/callback_helpers.h"
111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/metrics/histogram.h"
121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/strings/string_number_conversions.h"
131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/strings/string_util.h"
141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/strings/utf_string_conversions.h"
151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "content/renderer/media/crypto/key_systems.h"
161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "content/renderer/media/webcontentdecryptionmodule_impl.h"
171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "content/renderer/pepper/pepper_webplugin_impl.h"
181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "media/base/bind_to_current_loop.h"
191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "media/blink/encrypted_media_player_support.h"
201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "third_party/WebKit/public/platform/WebContentDecryptionModule.h"
211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "third_party/WebKit/public/platform/WebContentDecryptionModuleResult.h"
221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "third_party/WebKit/public/platform/WebMediaPlayerClient.h"
231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "third_party/WebKit/public/web/WebDocument.h"
241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "third_party/WebKit/public/web/WebLocalFrame.h"
251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "third_party/WebKit/public/web/WebRuntimeFeatures.h"
261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#if defined(ENABLE_PEPPER_CDMS)
281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "content/renderer/media/crypto/pepper_cdm_wrapper_impl.h"
291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#endif
301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciusing blink::WebMediaPlayer;
321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciusing blink::WebMediaPlayerClient;
331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciusing blink::WebString;
341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccinamespace content {
361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#define BIND_TO_RENDER_LOOP(function)            \
381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  (media::BindToCurrentLoop(base::Bind(function, AsWeakPtr())))
391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#define BIND_TO_RENDER_LOOP1(function, arg1)     \
411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  (media::BindToCurrentLoop(base::Bind(function, AsWeakPtr(), arg1)))
421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Prefix for histograms related to Encrypted Media Extensions.
451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccistatic const char* kMediaEme = "Media.EME.";
461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Used for calls to decryptor_ready_cb where the result can be ignored.
481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccistatic void DoNothing(bool success) {
491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Convert a WebString to ASCII, falling back on an empty string in the case
521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// of a non-ASCII string.
531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccistatic std::string ToASCIIOrEmpty(const WebString& string) {
541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return base::IsStringASCII(string) ? base::UTF16ToASCII(string)
551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                     : std::string();
561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Helper functions to report media EME related stats to UMA. They follow the
591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// convention of more commonly used macros UMA_HISTOGRAM_ENUMERATION and
601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// UMA_HISTOGRAM_COUNTS. The reason that we cannot use those macros directly is
611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// that UMA_* macros require the names to be constant throughout the process'
621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// lifetime.
631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccistatic void EmeUMAHistogramEnumeration(const std::string& key_system,
641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                       const std::string& method,
651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                       int sample,
661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                       int boundary_value) {
671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::LinearHistogram::FactoryGet(
681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      kMediaEme + KeySystemNameForUMA(key_system) + "." + method,
691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      1, boundary_value, boundary_value + 1,
701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      base::Histogram::kUmaTargetedHistogramFlag)->Add(sample);
711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccistatic void EmeUMAHistogramCounts(const std::string& key_system,
741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                  const std::string& method,
751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                  int sample) {
761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Use the same parameters as UMA_HISTOGRAM_COUNTS.
771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::Histogram::FactoryGet(
781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      kMediaEme + KeySystemNameForUMA(key_system) + "." + method,
791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      1, 1000000, 50, base::Histogram::kUmaTargetedHistogramFlag)->Add(sample);
801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Helper enum for reporting generateKeyRequest/addKey histograms.
831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccienum MediaKeyException {
841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  kUnknownResultId,
851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  kSuccess,
861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  kKeySystemNotSupported,
871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  kInvalidPlayerState,
881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  kMaxMediaKeyException
891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci};
901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccistatic MediaKeyException MediaKeyExceptionForUMA(
921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    WebMediaPlayer::MediaKeyException e) {
931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  switch (e) {
941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    case WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported:
951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      return kKeySystemNotSupported;
961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    case WebMediaPlayer::MediaKeyExceptionInvalidPlayerState:
971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      return kInvalidPlayerState;
981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    case WebMediaPlayer::MediaKeyExceptionNoError:
991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      return kSuccess;
1001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    default:
1011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      return kUnknownResultId;
1021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Helper for converting |key_system| name and exception |e| to a pair of enum
1061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// values from above, for reporting to UMA.
1071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccistatic void ReportMediaKeyExceptionToUMA(const std::string& method,
1081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                         const std::string& key_system,
1091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                         WebMediaPlayer::MediaKeyException e) {
1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  MediaKeyException result_id = MediaKeyExceptionForUMA(e);
1111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK_NE(result_id, kUnknownResultId) << e;
1121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EmeUMAHistogramEnumeration(
1131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      key_system, method, result_id, kMaxMediaKeyException);
1141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Guess the type of |init_data|. This is only used to handle some corner cases
1171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// so we keep it as simple as possible without breaking major use cases.
1181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccistatic std::string GuessInitDataType(const unsigned char* init_data,
1191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                     unsigned init_data_length) {
1201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Most WebM files use KeyId of 16 bytes. MP4 init data are always >16 bytes.
1211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (init_data_length == 16)
1221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return "video/webm";
1231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return "video/mp4";
1251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciscoped_ptr<media::EncryptedMediaPlayerSupport>
1281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciEncryptedMediaPlayerSupportImpl::Create(blink::WebMediaPlayerClient* client) {
1291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return scoped_ptr<EncryptedMediaPlayerSupport>(
1301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new EncryptedMediaPlayerSupportImpl(client));
1311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciEncryptedMediaPlayerSupportImpl::EncryptedMediaPlayerSupportImpl(
1341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    blink::WebMediaPlayerClient* client)
1351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    : client_(client),
1361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      web_cdm_(NULL) {
1371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciEncryptedMediaPlayerSupportImpl::~EncryptedMediaPlayerSupportImpl() {
1401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciWebMediaPlayer::MediaKeyException
1431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciEncryptedMediaPlayerSupportImpl::GenerateKeyRequest(
1441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    blink::WebLocalFrame* frame,
1451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const WebString& key_system,
1461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const unsigned char* init_data,
1471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    unsigned init_data_length) {
1481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DVLOG(1) << "generateKeyRequest: " << base::string16(key_system) << ": "
1491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci           << std::string(reinterpret_cast<const char*>(init_data),
1501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                          static_cast<size_t>(init_data_length));
1511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::string ascii_key_system =
1531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      GetUnprefixedKeySystemName(ToASCIIOrEmpty(key_system));
1541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  WebMediaPlayer::MediaKeyException e =
1561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      GenerateKeyRequestInternal(frame, ascii_key_system, init_data,
1571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                 init_data_length);
1581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ReportMediaKeyExceptionToUMA("generateKeyRequest", ascii_key_system, e);
1591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return e;
1601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciWebMediaPlayer::MediaKeyException
1641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciEncryptedMediaPlayerSupportImpl::GenerateKeyRequestInternal(
1651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    blink::WebLocalFrame* frame,
1661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const std::string& key_system,
1671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const unsigned char* init_data,
1681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    unsigned init_data_length) {
1691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!IsConcreteSupportedKeySystem(key_system))
1701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported;
1711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // We do not support run-time switching between key systems for now.
1731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (current_key_system_.empty()) {
1741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (!proxy_decryptor_) {
1751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      proxy_decryptor_.reset(new ProxyDecryptor(
1761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#if defined(ENABLE_PEPPER_CDMS)
1771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          // Create() must be called synchronously as |frame| may not be
1781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          // valid afterwards.
1791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          base::Bind(&PepperCdmWrapperImpl::Create, frame),
1801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#elif defined(ENABLE_BROWSER_CDMS)
1811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#error Browser side CDM in WMPI for prefixed EME API not supported yet.
1821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#endif
1831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          BIND_TO_RENDER_LOOP(&EncryptedMediaPlayerSupportImpl::OnKeyAdded),
1841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          BIND_TO_RENDER_LOOP(&EncryptedMediaPlayerSupportImpl::OnKeyError),
1851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          BIND_TO_RENDER_LOOP(&EncryptedMediaPlayerSupportImpl::OnKeyMessage)));
1861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }
1871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    GURL security_origin(frame->document().securityOrigin().toString());
1891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (!proxy_decryptor_->InitializeCDM(key_system, security_origin))
1901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      return WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported;
1911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (proxy_decryptor_ && !decryptor_ready_cb_.is_null()) {
1931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      base::ResetAndReturn(&decryptor_ready_cb_)
1941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          .Run(proxy_decryptor_->GetDecryptor(), base::Bind(DoNothing));
1951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }
1961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    current_key_system_ = key_system;
1981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  } else if (key_system != current_key_system_) {
1991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return WebMediaPlayer::MediaKeyExceptionInvalidPlayerState;
2001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
2011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::string init_data_type = init_data_type_;
2031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (init_data_type.empty())
2041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    init_data_type = GuessInitDataType(init_data, init_data_length);
2051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // TODO(xhwang): We assume all streams are from the same container (thus have
2071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // the same "type") for now. In the future, the "type" should be passed down
2081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // from the application.
2091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!proxy_decryptor_->GenerateKeyRequest(
2101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci           init_data_type, init_data, init_data_length)) {
2111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    current_key_system_.clear();
2121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported;
2131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
2141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return WebMediaPlayer::MediaKeyExceptionNoError;
2161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciWebMediaPlayer::MediaKeyException EncryptedMediaPlayerSupportImpl::AddKey(
2191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const WebString& key_system,
2201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const unsigned char* key,
2211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    unsigned key_length,
2221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const unsigned char* init_data,
2231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    unsigned init_data_length,
2241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const WebString& session_id) {
2251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DVLOG(1) << "addKey: " << base::string16(key_system) << ": "
2261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci           << std::string(reinterpret_cast<const char*>(key),
2271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                          static_cast<size_t>(key_length)) << ", "
2281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci           << std::string(reinterpret_cast<const char*>(init_data),
2291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                          static_cast<size_t>(init_data_length)) << " ["
2301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci           << base::string16(session_id) << "]";
2311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::string ascii_key_system =
2331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      GetUnprefixedKeySystemName(ToASCIIOrEmpty(key_system));
2341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::string ascii_session_id = ToASCIIOrEmpty(session_id);
2351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  WebMediaPlayer::MediaKeyException e = AddKeyInternal(ascii_key_system,
2371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                                       key,
2381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                                       key_length,
2391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                                       init_data,
2401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                                       init_data_length,
2411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                                       ascii_session_id);
2421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ReportMediaKeyExceptionToUMA("addKey", ascii_key_system, e);
2431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return e;
2441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciWebMediaPlayer::MediaKeyException
2471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciEncryptedMediaPlayerSupportImpl::AddKeyInternal(
2481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const std::string& key_system,
2491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const unsigned char* key,
2501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    unsigned key_length,
2511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const unsigned char* init_data,
2521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    unsigned init_data_length,
2531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const std::string& session_id) {
2541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(key);
2551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK_GT(key_length, 0u);
2561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!IsConcreteSupportedKeySystem(key_system))
2581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported;
2591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (current_key_system_.empty() || key_system != current_key_system_)
2611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return WebMediaPlayer::MediaKeyExceptionInvalidPlayerState;
2621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  proxy_decryptor_->AddKey(
2641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      key, key_length, init_data, init_data_length, session_id);
2651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return WebMediaPlayer::MediaKeyExceptionNoError;
2661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciWebMediaPlayer::MediaKeyException
2691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciEncryptedMediaPlayerSupportImpl::CancelKeyRequest(
2701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const WebString& key_system,
2711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const WebString& session_id) {
2721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DVLOG(1) << "cancelKeyRequest: " << base::string16(key_system) << ": "
2731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci           << " [" << base::string16(session_id) << "]";
2741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::string ascii_key_system =
2761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      GetUnprefixedKeySystemName(ToASCIIOrEmpty(key_system));
2771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::string ascii_session_id = ToASCIIOrEmpty(session_id);
2781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  WebMediaPlayer::MediaKeyException e =
2801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      CancelKeyRequestInternal(ascii_key_system, ascii_session_id);
2811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ReportMediaKeyExceptionToUMA("cancelKeyRequest", ascii_key_system, e);
2821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return e;
2831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciWebMediaPlayer::MediaKeyException
2861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciEncryptedMediaPlayerSupportImpl::CancelKeyRequestInternal(
2871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const std::string& key_system,
2881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const std::string& session_id) {
2891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!IsConcreteSupportedKeySystem(key_system))
2901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return WebMediaPlayer::MediaKeyExceptionKeySystemNotSupported;
2911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (current_key_system_.empty() || key_system != current_key_system_)
2931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return WebMediaPlayer::MediaKeyExceptionInvalidPlayerState;
2941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  proxy_decryptor_->CancelKeyRequest(session_id);
2961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return WebMediaPlayer::MediaKeyExceptionNoError;
2971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid EncryptedMediaPlayerSupportImpl::SetInitialContentDecryptionModule(
3001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    blink::WebContentDecryptionModule* initial_cdm) {
3011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Used when loading media and no pipeline/decoder attached yet.
3021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(decryptor_ready_cb_.is_null());
3031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  web_cdm_ = ToWebContentDecryptionModuleImpl(initial_cdm);
3051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
3061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid EncryptedMediaPlayerSupportImpl::SetContentDecryptionModule(
3081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    blink::WebContentDecryptionModule* cdm) {
3091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // TODO(xhwang): Support setMediaKeys(0) if necessary: http://crbug.com/330324
3101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!cdm)
3111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
3121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  web_cdm_ = ToWebContentDecryptionModuleImpl(cdm);
3141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (web_cdm_ && !decryptor_ready_cb_.is_null())
3161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    base::ResetAndReturn(&decryptor_ready_cb_)
3171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        .Run(web_cdm_->GetDecryptor(), base::Bind(DoNothing));
3181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
3191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid EncryptedMediaPlayerSupportImpl::SetContentDecryptionModule(
3211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    blink::WebContentDecryptionModule* cdm,
3221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    blink::WebContentDecryptionModuleResult result) {
3231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // TODO(xhwang): Support setMediaKeys(0) if necessary: http://crbug.com/330324
3241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!cdm) {
3251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    result.completeWithError(
3261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        blink::WebContentDecryptionModuleExceptionNotSupportedError,
3271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        0,
3281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        "Null MediaKeys object is not supported.");
3291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
3301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
3311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  web_cdm_ = ToWebContentDecryptionModuleImpl(cdm);
3331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (web_cdm_ && !decryptor_ready_cb_.is_null()) {
3351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    base::ResetAndReturn(&decryptor_ready_cb_)
3361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        .Run(web_cdm_->GetDecryptor(), BIND_TO_RENDER_LOOP1(
3371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            &EncryptedMediaPlayerSupportImpl::ContentDecryptionModuleAttached,
3381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            result));
3391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  } else {
3401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // No pipeline/decoder connected, so resolve the promise. When something
3411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // is connected, setting the CDM will happen in SetDecryptorReadyCB().
3421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ContentDecryptionModuleAttached(result, true);
3431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
3441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
3451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid EncryptedMediaPlayerSupportImpl::ContentDecryptionModuleAttached(
3471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    blink::WebContentDecryptionModuleResult result,
3481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    bool success) {
3491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (success) {
3501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    result.complete();
3511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
3521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
3531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  result.completeWithError(
3551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      blink::WebContentDecryptionModuleExceptionNotSupportedError,
3561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      0,
3571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "Unable to set MediaKeys object");
3581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
3591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccimedia::SetDecryptorReadyCB
3611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciEncryptedMediaPlayerSupportImpl::CreateSetDecryptorReadyCB() {
3621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return BIND_TO_RENDER_LOOP(
3631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      &EncryptedMediaPlayerSupportImpl::SetDecryptorReadyCB);
3641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
3651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccimedia::Demuxer::NeedKeyCB
3671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciEncryptedMediaPlayerSupportImpl::CreateNeedKeyCB() {
3681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return BIND_TO_RENDER_LOOP(&EncryptedMediaPlayerSupportImpl::OnNeedKey);
3691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
3701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid EncryptedMediaPlayerSupportImpl::OnPipelineDecryptError() {
3721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EmeUMAHistogramCounts(current_key_system_, "DecryptError", 1);
3731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
3741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid EncryptedMediaPlayerSupportImpl::OnNeedKey(const std::string& type,
3761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                   const std::vector<uint8>& init_data) {
3771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Do not fire NeedKey event if encrypted media is not enabled.
3781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!blink::WebRuntimeFeatures::isPrefixedEncryptedMediaEnabled() &&
3791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      !blink::WebRuntimeFeatures::isEncryptedMediaEnabled()) {
3801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
3811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
3821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  UMA_HISTOGRAM_COUNTS(kMediaEme + std::string("NeedKey"), 1);
3841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(init_data_type_.empty() || type.empty() || type == init_data_type_);
3861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (init_data_type_.empty())
3871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    init_data_type_ = type;
3881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const uint8* init_data_ptr = init_data.empty() ? NULL : &init_data[0];
3901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  client_->keyNeeded(
3911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      WebString::fromUTF8(type), init_data_ptr, init_data.size());
3921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
3931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid EncryptedMediaPlayerSupportImpl::OnKeyAdded(
3951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const std::string& session_id) {
3961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EmeUMAHistogramCounts(current_key_system_, "KeyAdded", 1);
3971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  client_->keyAdded(
3981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      WebString::fromUTF8(GetPrefixedKeySystemName(current_key_system_)),
3991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      WebString::fromUTF8(session_id));
4001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
4011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid EncryptedMediaPlayerSupportImpl::OnKeyError(const std::string& session_id,
4031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                    media::MediaKeys::KeyError error_code,
4041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                    uint32 system_code) {
4051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EmeUMAHistogramEnumeration(current_key_system_, "KeyError",
4061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                             error_code, media::MediaKeys::kMaxKeyError);
4071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  uint16 short_system_code = 0;
4091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (system_code > std::numeric_limits<uint16>::max()) {
4101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    LOG(WARNING) << "system_code exceeds unsigned short limit.";
4111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    short_system_code = std::numeric_limits<uint16>::max();
4121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  } else {
4131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    short_system_code = static_cast<uint16>(system_code);
4141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
4151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  client_->keyError(
4171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      WebString::fromUTF8(GetPrefixedKeySystemName(current_key_system_)),
4181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      WebString::fromUTF8(session_id),
4191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      static_cast<WebMediaPlayerClient::MediaKeyErrorCode>(error_code),
4201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      short_system_code);
4211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
4221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid EncryptedMediaPlayerSupportImpl::OnKeyMessage(
4241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const std::string& session_id,
4251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const std::vector<uint8>& message,
4261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const GURL& destination_url) {
4271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(destination_url.is_empty() || destination_url.is_valid());
4281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  client_->keyMessage(
4301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      WebString::fromUTF8(GetPrefixedKeySystemName(current_key_system_)),
4311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      WebString::fromUTF8(session_id),
4321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      message.empty() ? NULL : &message[0],
4331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      message.size(),
4341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      destination_url);
4351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
4361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid EncryptedMediaPlayerSupportImpl::SetDecryptorReadyCB(
4381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci     const media::DecryptorReadyCB& decryptor_ready_cb) {
4391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Cancels the previous decryptor request.
4401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (decryptor_ready_cb.is_null()) {
4411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (!decryptor_ready_cb_.is_null()) {
4421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      base::ResetAndReturn(&decryptor_ready_cb_)
4431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          .Run(NULL, base::Bind(DoNothing));
4441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }
4451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
4461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
4471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // TODO(xhwang): Support multiple decryptor notification request (e.g. from
4491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // video and audio). The current implementation is okay for the current
4501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // media pipeline since we initialize audio and video decoders in sequence.
4511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // But WebMediaPlayerImpl should not depend on media pipeline's implementation
4521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // detail.
4531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(decryptor_ready_cb_.is_null());
4541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Mixed use of prefixed and unprefixed EME APIs is disallowed by Blink.
4561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(!proxy_decryptor_ || !web_cdm_);
4571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (proxy_decryptor_) {
4591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    decryptor_ready_cb.Run(proxy_decryptor_->GetDecryptor(),
4601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                           base::Bind(DoNothing));
4611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
4621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
4631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (web_cdm_) {
4651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    decryptor_ready_cb.Run(web_cdm_->GetDecryptor(), base::Bind(DoNothing));
4661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
4671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
4681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  decryptor_ready_cb_ = decryptor_ready_cb;
4701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
4711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}  // namespace content
473