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 "media/base/cdm_promise.h" 6 7#include "base/bind.h" 8#include "base/logging.h" 9#include "base/metrics/histogram.h" 10 11namespace media { 12 13template <typename T> 14struct CdmPromiseTraits {}; 15 16template <> 17struct CdmPromiseTraits<void> { 18 static const CdmPromise::ResolveParameterType kType = CdmPromise::VOID_TYPE; 19}; 20 21template <> 22struct CdmPromiseTraits<std::string> { 23 static const CdmPromise::ResolveParameterType kType = CdmPromise::STRING_TYPE; 24}; 25 26template <> 27struct CdmPromiseTraits<KeyIdsVector> { 28 static const CdmPromise::ResolveParameterType kType = 29 CdmPromise::KEY_IDS_VECTOR_TYPE; 30}; 31 32CdmPromise::CdmPromise(ResolveParameterType parameter_type) 33 : parameter_type_(parameter_type), is_pending_(true) { 34} 35 36CdmPromise::CdmPromise(ResolveParameterType parameter_type, 37 PromiseRejectedCB reject_cb) 38 : parameter_type_(parameter_type), 39 reject_cb_(reject_cb), 40 is_pending_(true) { 41 DCHECK(!reject_cb_.is_null()); 42} 43 44CdmPromise::CdmPromise(ResolveParameterType parameter_type, 45 PromiseRejectedCB reject_cb, 46 const std::string& uma_name) 47 : parameter_type_(parameter_type), 48 reject_cb_(reject_cb), 49 is_pending_(true), 50 uma_name_(uma_name) { 51 DCHECK(!reject_cb_.is_null()); 52 DCHECK(!uma_name_.empty()); 53} 54 55CdmPromise::~CdmPromise() { 56 DCHECK(!is_pending_); 57} 58 59static CdmPromise::ResultCodeForUMA ConvertExceptionToUMAResult( 60 MediaKeys::Exception exception_code) { 61 switch (exception_code) { 62 case MediaKeys::NOT_SUPPORTED_ERROR: 63 return CdmPromise::NOT_SUPPORTED_ERROR; 64 case MediaKeys::INVALID_STATE_ERROR: 65 return CdmPromise::INVALID_STATE_ERROR; 66 case MediaKeys::INVALID_ACCESS_ERROR: 67 return CdmPromise::INVALID_ACCESS_ERROR; 68 case MediaKeys::QUOTA_EXCEEDED_ERROR: 69 return CdmPromise::QUOTA_EXCEEDED_ERROR; 70 case MediaKeys::UNKNOWN_ERROR: 71 return CdmPromise::UNKNOWN_ERROR; 72 case MediaKeys::CLIENT_ERROR: 73 return CdmPromise::CLIENT_ERROR; 74 case MediaKeys::OUTPUT_ERROR: 75 return CdmPromise::OUTPUT_ERROR; 76 } 77 NOTREACHED(); 78 return CdmPromise::UNKNOWN_ERROR; 79} 80 81void CdmPromise::reject(MediaKeys::Exception exception_code, 82 uint32 system_code, 83 const std::string& error_message) { 84 ReportResultToUMA(ConvertExceptionToUMAResult(exception_code)); 85 reject_cb_.Run(exception_code, system_code, error_message); 86} 87 88void CdmPromise::ReportResultToUMA(ResultCodeForUMA result) { 89 DCHECK(is_pending_); 90 is_pending_ = false; 91 if (!uma_name_.empty()) { 92 base::LinearHistogram::FactoryGet( 93 uma_name_, 94 1, 95 NUM_RESULT_CODES, 96 NUM_RESULT_CODES + 1, 97 base::HistogramBase::kUmaTargetedHistogramFlag)->Add(result); 98 } 99} 100 101template <typename T> 102CdmPromiseTemplate<T>::CdmPromiseTemplate( 103 base::Callback<void(const T&)> resolve_cb, 104 PromiseRejectedCB reject_cb) 105 : CdmPromise(CdmPromiseTraits<T>::kType, reject_cb), 106 resolve_cb_(resolve_cb) { 107 DCHECK(!resolve_cb_.is_null()); 108} 109 110template <typename T> 111CdmPromiseTemplate<T>::CdmPromiseTemplate( 112 base::Callback<void(const T&)> resolve_cb, 113 PromiseRejectedCB reject_cb, 114 const std::string& uma_name) 115 : CdmPromise(CdmPromiseTraits<T>::kType, reject_cb, uma_name), 116 resolve_cb_(resolve_cb) { 117 DCHECK(!resolve_cb_.is_null()); 118} 119 120template <typename T> 121CdmPromiseTemplate<T>::CdmPromiseTemplate() 122 : CdmPromise(CdmPromiseTraits<T>::kType) { 123} 124 125template <typename T> 126void CdmPromiseTemplate<T>::resolve(const T& result) { 127 ReportResultToUMA(SUCCESS); 128 resolve_cb_.Run(result); 129} 130 131CdmPromiseTemplate<void>::CdmPromiseTemplate(base::Callback<void()> resolve_cb, 132 PromiseRejectedCB reject_cb) 133 : CdmPromise(CdmPromiseTraits<void>::kType, reject_cb), 134 resolve_cb_(resolve_cb) { 135 DCHECK(!resolve_cb_.is_null()); 136} 137 138CdmPromiseTemplate<void>::CdmPromiseTemplate(base::Callback<void()> resolve_cb, 139 PromiseRejectedCB reject_cb, 140 const std::string& uma_name) 141 : CdmPromise(CdmPromiseTraits<void>::kType, reject_cb, uma_name), 142 resolve_cb_(resolve_cb) { 143 DCHECK(!resolve_cb_.is_null()); 144 DCHECK(!uma_name_.empty()); 145} 146 147CdmPromiseTemplate<void>::CdmPromiseTemplate() 148 : CdmPromise(CdmPromiseTraits<void>::kType) { 149} 150 151void CdmPromiseTemplate<void>::resolve() { 152 ReportResultToUMA(SUCCESS); 153 resolve_cb_.Run(); 154} 155 156// Explicit template instantiation for the Promises needed. 157template class MEDIA_EXPORT CdmPromiseTemplate<std::string>; 158template class MEDIA_EXPORT CdmPromiseTemplate<KeyIdsVector>; 159 160} // namespace media 161