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 11 namespace media { 12 13 template <typename T> 14 struct CdmPromiseTraits {}; 15 16 template <> 17 struct CdmPromiseTraits<void> { 18 static const CdmPromise::ResolveParameterType kType = CdmPromise::VOID_TYPE; 19 }; 20 21 template <> 22 struct CdmPromiseTraits<std::string> { 23 static const CdmPromise::ResolveParameterType kType = CdmPromise::STRING_TYPE; 24 }; 25 26 template <> 27 struct CdmPromiseTraits<KeyIdsVector> { 28 static const CdmPromise::ResolveParameterType kType = 29 CdmPromise::KEY_IDS_VECTOR_TYPE; 30 }; 31 32 CdmPromise::CdmPromise(ResolveParameterType parameter_type) 33 : parameter_type_(parameter_type), is_pending_(true) { 34 } 35 36 CdmPromise::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 44 CdmPromise::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 55 CdmPromise::~CdmPromise() { 56 DCHECK(!is_pending_); 57 } 58 59 static 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 81 void 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 88 void 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 101 template <typename T> 102 CdmPromiseTemplate<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 110 template <typename T> 111 CdmPromiseTemplate<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 120 template <typename T> 121 CdmPromiseTemplate<T>::CdmPromiseTemplate() 122 : CdmPromise(CdmPromiseTraits<T>::kType) { 123 } 124 125 template <typename T> 126 void CdmPromiseTemplate<T>::resolve(const T& result) { 127 ReportResultToUMA(SUCCESS); 128 resolve_cb_.Run(result); 129 } 130 131 CdmPromiseTemplate<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 138 CdmPromiseTemplate<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 147 CdmPromiseTemplate<void>::CdmPromiseTemplate() 148 : CdmPromise(CdmPromiseTraits<void>::kType) { 149 } 150 151 void CdmPromiseTemplate<void>::resolve() { 152 ReportResultToUMA(SUCCESS); 153 resolve_cb_.Run(); 154 } 155 156 // Explicit template instantiation for the Promises needed. 157 template class MEDIA_EXPORT CdmPromiseTemplate<std::string>; 158 template class MEDIA_EXPORT CdmPromiseTemplate<KeyIdsVector>; 159 160 } // namespace media 161