普通文本  |  161行  |  4.75 KB

// 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 "media/base/cdm_promise.h"

#include "base/bind.h"
#include "base/logging.h"
#include "base/metrics/histogram.h"

namespace media {

template <typename T>
struct CdmPromiseTraits {};

template <>
struct CdmPromiseTraits<void> {
  static const CdmPromise::ResolveParameterType kType = CdmPromise::VOID_TYPE;
};

template <>
struct CdmPromiseTraits<std::string> {
  static const CdmPromise::ResolveParameterType kType = CdmPromise::STRING_TYPE;
};

template <>
struct CdmPromiseTraits<KeyIdsVector> {
  static const CdmPromise::ResolveParameterType kType =
      CdmPromise::KEY_IDS_VECTOR_TYPE;
};

CdmPromise::CdmPromise(ResolveParameterType parameter_type)
    : parameter_type_(parameter_type), is_pending_(true) {
}

CdmPromise::CdmPromise(ResolveParameterType parameter_type,
                       PromiseRejectedCB reject_cb)
    : parameter_type_(parameter_type),
      reject_cb_(reject_cb),
      is_pending_(true) {
  DCHECK(!reject_cb_.is_null());
}

CdmPromise::CdmPromise(ResolveParameterType parameter_type,
                       PromiseRejectedCB reject_cb,
                       const std::string& uma_name)
    : parameter_type_(parameter_type),
      reject_cb_(reject_cb),
      is_pending_(true),
      uma_name_(uma_name) {
  DCHECK(!reject_cb_.is_null());
  DCHECK(!uma_name_.empty());
}

CdmPromise::~CdmPromise() {
  DCHECK(!is_pending_);
}

static CdmPromise::ResultCodeForUMA ConvertExceptionToUMAResult(
    MediaKeys::Exception exception_code) {
  switch (exception_code) {
    case MediaKeys::NOT_SUPPORTED_ERROR:
      return CdmPromise::NOT_SUPPORTED_ERROR;
    case MediaKeys::INVALID_STATE_ERROR:
      return CdmPromise::INVALID_STATE_ERROR;
    case MediaKeys::INVALID_ACCESS_ERROR:
      return CdmPromise::INVALID_ACCESS_ERROR;
    case MediaKeys::QUOTA_EXCEEDED_ERROR:
      return CdmPromise::QUOTA_EXCEEDED_ERROR;
    case MediaKeys::UNKNOWN_ERROR:
      return CdmPromise::UNKNOWN_ERROR;
    case MediaKeys::CLIENT_ERROR:
      return CdmPromise::CLIENT_ERROR;
    case MediaKeys::OUTPUT_ERROR:
      return CdmPromise::OUTPUT_ERROR;
  }
  NOTREACHED();
  return CdmPromise::UNKNOWN_ERROR;
}

void CdmPromise::reject(MediaKeys::Exception exception_code,
                        uint32 system_code,
                        const std::string& error_message) {
  ReportResultToUMA(ConvertExceptionToUMAResult(exception_code));
  reject_cb_.Run(exception_code, system_code, error_message);
}

void CdmPromise::ReportResultToUMA(ResultCodeForUMA result) {
  DCHECK(is_pending_);
  is_pending_ = false;
  if (!uma_name_.empty()) {
    base::LinearHistogram::FactoryGet(
        uma_name_,
        1,
        NUM_RESULT_CODES,
        NUM_RESULT_CODES + 1,
        base::HistogramBase::kUmaTargetedHistogramFlag)->Add(result);
  }
}

template <typename T>
CdmPromiseTemplate<T>::CdmPromiseTemplate(
    base::Callback<void(const T&)> resolve_cb,
    PromiseRejectedCB reject_cb)
    : CdmPromise(CdmPromiseTraits<T>::kType, reject_cb),
      resolve_cb_(resolve_cb) {
  DCHECK(!resolve_cb_.is_null());
}

template <typename T>
CdmPromiseTemplate<T>::CdmPromiseTemplate(
    base::Callback<void(const T&)> resolve_cb,
    PromiseRejectedCB reject_cb,
    const std::string& uma_name)
    : CdmPromise(CdmPromiseTraits<T>::kType, reject_cb, uma_name),
      resolve_cb_(resolve_cb) {
  DCHECK(!resolve_cb_.is_null());
}

template <typename T>
CdmPromiseTemplate<T>::CdmPromiseTemplate()
    : CdmPromise(CdmPromiseTraits<T>::kType) {
}

template <typename T>
void CdmPromiseTemplate<T>::resolve(const T& result) {
  ReportResultToUMA(SUCCESS);
  resolve_cb_.Run(result);
}

CdmPromiseTemplate<void>::CdmPromiseTemplate(base::Callback<void()> resolve_cb,
                                             PromiseRejectedCB reject_cb)
    : CdmPromise(CdmPromiseTraits<void>::kType, reject_cb),
      resolve_cb_(resolve_cb) {
  DCHECK(!resolve_cb_.is_null());
}

CdmPromiseTemplate<void>::CdmPromiseTemplate(base::Callback<void()> resolve_cb,
                                             PromiseRejectedCB reject_cb,
                                             const std::string& uma_name)
    : CdmPromise(CdmPromiseTraits<void>::kType, reject_cb, uma_name),
      resolve_cb_(resolve_cb) {
  DCHECK(!resolve_cb_.is_null());
  DCHECK(!uma_name_.empty());
}

CdmPromiseTemplate<void>::CdmPromiseTemplate()
    : CdmPromise(CdmPromiseTraits<void>::kType) {
}

void CdmPromiseTemplate<void>::resolve() {
  ReportResultToUMA(SUCCESS);
  resolve_cb_.Run();
}

// Explicit template instantiation for the Promises needed.
template class MEDIA_EXPORT CdmPromiseTemplate<std::string>;
template class MEDIA_EXPORT CdmPromiseTemplate<KeyIdsVector>;

}  // namespace media