Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/renderer/media/webcontentdecryptionmodulesession_impl.h" | 5 #include "content/renderer/media/webcontentdecryptionmodulesession_impl.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/callback_helpers.h" | 8 #include "base/callback_helpers.h" |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/strings/string_util.h" | 10 #include "base/strings/string_util.h" |
| 11 #include "base/strings/utf_string_conversions.h" | 11 #include "base/strings/utf_string_conversions.h" |
| 12 #include "content/renderer/media/cdm_result_promise.h" | |
| 12 #include "content/renderer/media/cdm_session_adapter.h" | 13 #include "content/renderer/media/cdm_session_adapter.h" |
| 13 #include "media/base/cdm_promise.h" | 14 #include "media/base/cdm_promise.h" |
| 14 #include "third_party/WebKit/public/platform/WebURL.h" | 15 #include "third_party/WebKit/public/platform/WebURL.h" |
| 15 | 16 |
| 16 namespace content { | 17 namespace content { |
| 17 | 18 |
| 18 const char kCreateSessionUMAName[] = "CreateSession"; | 19 const char kCreateSessionUMAName[] = "CreateSession"; |
| 19 | 20 |
| 20 // For backwards compatibility with blink not using | 21 typedef base::Callback<blink::WebContentDecryptionModuleResult::SessionStatus( |
| 21 // WebContentDecryptionModuleResult, reserve an index for |outstanding_results_| | 22 const std::string& web_session_id)> SessionInitializedCB; |
| 22 // that will not be used when adding a WebContentDecryptionModuleResult. | |
| 23 // TODO(jrummell): Remove once blink always uses | |
| 24 // WebContentDecryptionModuleResult. | |
| 25 const uint32 kReservedIndex = 0; | |
| 26 | 23 |
| 27 static blink::WebContentDecryptionModuleException ConvertException( | 24 class NewSessionCdmResultPromise : public CdmResultPromise<std::string> { |
| 28 media::MediaKeys::Exception exception_code) { | 25 public: |
| 29 switch (exception_code) { | 26 NewSessionCdmResultPromise(blink::WebContentDecryptionModuleResult result, |
| 30 case media::MediaKeys::NOT_SUPPORTED_ERROR: | 27 std::string uma_name, |
| 31 return blink::WebContentDecryptionModuleExceptionNotSupportedError; | 28 const SessionInitializedCB& new_session_created_cb) |
| 32 case media::MediaKeys::INVALID_STATE_ERROR: | 29 : CdmResultPromise<std::string>(result, uma_name), |
| 33 return blink::WebContentDecryptionModuleExceptionInvalidStateError; | 30 new_session_created_cb_(new_session_created_cb) {} |
| 34 case media::MediaKeys::INVALID_ACCESS_ERROR: | 31 |
| 35 return blink::WebContentDecryptionModuleExceptionInvalidAccessError; | 32 protected: |
| 36 case media::MediaKeys::QUOTA_EXCEEDED_ERROR: | 33 virtual void OnResolve(const std::string& web_session_id) OVERRIDE { |
| 37 return blink::WebContentDecryptionModuleExceptionQuotaExceededError; | 34 blink::WebContentDecryptionModuleResult::SessionStatus status = |
| 38 case media::MediaKeys::UNKNOWN_ERROR: | 35 new_session_created_cb_.Run(web_session_id); |
| 39 return blink::WebContentDecryptionModuleExceptionUnknownError; | 36 webCDMResult_.completeWithSession(status); |
| 40 case media::MediaKeys::CLIENT_ERROR: | |
| 41 return blink::WebContentDecryptionModuleExceptionClientError; | |
| 42 case media::MediaKeys::OUTPUT_ERROR: | |
| 43 return blink::WebContentDecryptionModuleExceptionOutputError; | |
| 44 default: | |
| 45 NOTREACHED(); | |
| 46 return blink::WebContentDecryptionModuleExceptionUnknownError; | |
| 47 } | 37 } |
| 48 } | 38 |
| 39 private: | |
| 40 SessionInitializedCB new_session_created_cb_; | |
| 41 }; | |
| 49 | 42 |
| 50 WebContentDecryptionModuleSessionImpl::WebContentDecryptionModuleSessionImpl( | 43 WebContentDecryptionModuleSessionImpl::WebContentDecryptionModuleSessionImpl( |
| 51 const scoped_refptr<CdmSessionAdapter>& adapter) | 44 const scoped_refptr<CdmSessionAdapter>& adapter) |
| 52 : adapter_(adapter), | 45 : adapter_(adapter), |
| 53 is_closed_(false), | 46 is_closed_(false), |
| 54 next_available_result_index_(1), | |
| 55 weak_ptr_factory_(this) { | 47 weak_ptr_factory_(this) { |
| 56 } | 48 } |
| 57 | 49 |
| 58 WebContentDecryptionModuleSessionImpl:: | 50 WebContentDecryptionModuleSessionImpl:: |
| 59 ~WebContentDecryptionModuleSessionImpl() { | 51 ~WebContentDecryptionModuleSessionImpl() { |
| 60 if (!web_session_id_.empty()) | 52 if (!web_session_id_.empty()) |
| 61 adapter_->RemoveSession(web_session_id_); | 53 adapter_->UnregisterSession(web_session_id_); |
| 62 | |
| 63 // Release any WebContentDecryptionModuleResult objects that are left. Their | |
| 64 // index will have been passed down via a CdmPromise, but it uses a WeakPtr. | |
| 65 DLOG_IF(WARNING, outstanding_results_.size() > 0) | |
| 66 << "Clearing " << outstanding_results_.size() << " results"; | |
| 67 for (ResultMap::iterator it = outstanding_results_.begin(); | |
| 68 it != outstanding_results_.end(); | |
| 69 ++it) { | |
| 70 it->second.completeWithError( | |
| 71 blink::WebContentDecryptionModuleExceptionInvalidStateError, | |
| 72 0, | |
| 73 "Outstanding request being cancelled."); | |
| 74 } | |
| 75 outstanding_results_.clear(); | |
| 76 } | 54 } |
| 77 | 55 |
| 78 void WebContentDecryptionModuleSessionImpl::setClientInterface(Client* client) { | 56 void WebContentDecryptionModuleSessionImpl::setClientInterface(Client* client) { |
| 79 client_ = client; | 57 client_ = client; |
| 80 } | 58 } |
| 81 | 59 |
| 82 blink::WebString WebContentDecryptionModuleSessionImpl::sessionId() const { | 60 blink::WebString WebContentDecryptionModuleSessionImpl::sessionId() const { |
| 83 return blink::WebString::fromUTF8(web_session_id_); | 61 return blink::WebString::fromUTF8(web_session_id_); |
| 84 } | 62 } |
| 85 | 63 |
| 86 void WebContentDecryptionModuleSessionImpl::initializeNewSession( | 64 void WebContentDecryptionModuleSessionImpl::initializeNewSession( |
| 87 const blink::WebString& init_data_type, | 65 const blink::WebString& init_data_type, |
| 88 const uint8* init_data, | 66 const uint8* init_data, |
| 89 size_t init_data_length) { | 67 size_t init_data_length) { |
| 90 DCHECK(base::IsStringASCII(init_data_type)); | 68 NOTREACHED(); |
|
xhwang
2014/09/25 05:11:47
Will these be removed? Add a comment?
jrummell
2014/09/25 20:33:25
Comment in the header, but copied here.
| |
| 91 | |
| 92 std::string init_data_type_as_ascii = base::UTF16ToASCII(init_data_type); | |
| 93 DLOG_IF(WARNING, init_data_type_as_ascii.find('/') != std::string::npos) | |
| 94 << "init_data_type '" << init_data_type_as_ascii | |
| 95 << "' may be a MIME type"; | |
| 96 | |
| 97 // Attempt to translate content types. | |
| 98 // TODO(sandersd): Remove once tests stop using content types. | |
| 99 // http://crbug.com/385874 | |
| 100 std::string content_type = base::StringToLowerASCII(init_data_type_as_ascii); | |
| 101 if (content_type == "audio/mp4" || content_type == "video/mp4") { | |
| 102 init_data_type_as_ascii = "cenc"; | |
| 103 } else if (content_type == "audio/webm" || content_type == "video/webm") { | |
| 104 init_data_type_as_ascii = "webm"; | |
| 105 } | |
| 106 | |
| 107 scoped_ptr<media::NewSessionCdmPromise> promise( | |
| 108 new media::NewSessionCdmPromise( | |
| 109 base::Bind(&WebContentDecryptionModuleSessionImpl::SessionCreated, | |
| 110 weak_ptr_factory_.GetWeakPtr(), | |
| 111 kReservedIndex), | |
| 112 base::Bind(&WebContentDecryptionModuleSessionImpl::OnSessionError, | |
| 113 weak_ptr_factory_.GetWeakPtr()), | |
| 114 adapter_->GetKeySystemUMAPrefix() + kCreateSessionUMAName)); | |
| 115 adapter_->InitializeNewSession(init_data_type_as_ascii, | |
| 116 init_data, | |
| 117 init_data_length, | |
| 118 media::MediaKeys::TEMPORARY_SESSION, | |
| 119 promise.Pass()); | |
| 120 } | 69 } |
| 121 | 70 |
| 122 void WebContentDecryptionModuleSessionImpl::update(const uint8* response, | 71 void WebContentDecryptionModuleSessionImpl::update(const uint8* response, |
| 123 size_t response_length) { | 72 size_t response_length) { |
| 124 DCHECK(response); | 73 NOTREACHED(); |
| 125 scoped_ptr<media::SimpleCdmPromise> promise(new media::SimpleCdmPromise( | |
| 126 base::Bind(&WebContentDecryptionModuleSessionImpl::OnSessionReady, | |
| 127 weak_ptr_factory_.GetWeakPtr()), | |
| 128 base::Bind(&WebContentDecryptionModuleSessionImpl::OnSessionError, | |
| 129 weak_ptr_factory_.GetWeakPtr()))); | |
| 130 adapter_->UpdateSession( | |
| 131 web_session_id_, response, response_length, promise.Pass()); | |
| 132 } | 74 } |
| 133 | 75 |
| 134 void WebContentDecryptionModuleSessionImpl::release() { | 76 void WebContentDecryptionModuleSessionImpl::release() { |
| 135 scoped_ptr<media::SimpleCdmPromise> promise(new media::SimpleCdmPromise( | 77 NOTREACHED(); |
| 136 base::Bind(&WebContentDecryptionModuleSessionImpl::OnSessionClosed, | |
| 137 weak_ptr_factory_.GetWeakPtr()), | |
| 138 base::Bind(&WebContentDecryptionModuleSessionImpl::OnSessionError, | |
| 139 weak_ptr_factory_.GetWeakPtr()))); | |
| 140 adapter_->ReleaseSession(web_session_id_, promise.Pass()); | |
| 141 } | 78 } |
| 142 | 79 |
| 143 void WebContentDecryptionModuleSessionImpl::initializeNewSession( | 80 void WebContentDecryptionModuleSessionImpl::initializeNewSession( |
| 144 const blink::WebString& init_data_type, | 81 const blink::WebString& init_data_type, |
| 145 const uint8* init_data, | 82 const uint8* init_data, |
| 146 size_t init_data_length, | 83 size_t init_data_length, |
| 147 const blink::WebString& session_type, | 84 const blink::WebString& session_type, |
| 148 blink::WebContentDecryptionModuleResult result) { | 85 blink::WebContentDecryptionModuleResult result) { |
| 149 uint32 result_index = AddResult(result); | |
| 150 | 86 |
| 151 // TODO(ddorwin): Guard against this in supported types check and remove this. | 87 // TODO(ddorwin): Guard against this in supported types check and remove this. |
| 152 // Chromium only supports ASCII MIME types. | 88 // Chromium only supports ASCII MIME types. |
| 153 if (!base::IsStringASCII(init_data_type)) { | 89 if (!base::IsStringASCII(init_data_type)) { |
| 154 NOTREACHED(); | 90 NOTREACHED(); |
| 155 SessionError(result_index, | 91 std::string message = "The initialization data type " + |
| 156 media::MediaKeys::NOT_SUPPORTED_ERROR, | 92 init_data_type.utf8() + |
| 157 0, | 93 " is not supported by the key system."; |
| 158 "The initialization data type " + init_data_type.utf8() + | 94 result.completeWithError( |
| 159 " is not supported by the key system."); | 95 blink::WebContentDecryptionModuleExceptionNotSupportedError, |
| 96 0, | |
| 97 blink::WebString::fromUTF8(message)); | |
| 160 return; | 98 return; |
| 161 } | 99 } |
| 162 | 100 |
| 163 std::string init_data_type_as_ascii = base::UTF16ToASCII(init_data_type); | 101 std::string init_data_type_as_ascii = base::UTF16ToASCII(init_data_type); |
| 164 DLOG_IF(WARNING, init_data_type_as_ascii.find('/') != std::string::npos) | 102 DLOG_IF(WARNING, init_data_type_as_ascii.find('/') != std::string::npos) |
| 165 << "init_data_type '" << init_data_type_as_ascii | 103 << "init_data_type '" << init_data_type_as_ascii |
| 166 << "' may be a MIME type"; | 104 << "' may be a MIME type"; |
| 167 | 105 |
| 168 scoped_ptr<media::NewSessionCdmPromise> promise( | 106 adapter_->InitializeNewSession( |
| 169 new media::NewSessionCdmPromise( | 107 init_data_type_as_ascii, |
| 170 base::Bind(&WebContentDecryptionModuleSessionImpl::SessionCreated, | 108 init_data, |
| 171 weak_ptr_factory_.GetWeakPtr(), | 109 init_data_length, |
| 172 result_index), | 110 media::MediaKeys::TEMPORARY_SESSION, |
| 173 base::Bind(&WebContentDecryptionModuleSessionImpl::SessionError, | 111 scoped_ptr<media::NewSessionCdmPromise>(new NewSessionCdmResultPromise( |
| 174 weak_ptr_factory_.GetWeakPtr(), | 112 result, |
| 175 result_index), | 113 adapter_->GetKeySystemUMAPrefix() + kCreateSessionUMAName, |
| 176 adapter_->GetKeySystemUMAPrefix() + kCreateSessionUMAName)); | 114 base::Bind( |
| 177 adapter_->InitializeNewSession(init_data_type_as_ascii, | 115 &WebContentDecryptionModuleSessionImpl::OnSessionInitialized, |
| 178 init_data, | 116 base::Unretained(this))))); |
| 179 init_data_length, | |
| 180 media::MediaKeys::TEMPORARY_SESSION, | |
| 181 promise.Pass()); | |
| 182 } | 117 } |
| 183 | 118 |
| 184 void WebContentDecryptionModuleSessionImpl::update( | 119 void WebContentDecryptionModuleSessionImpl::update( |
| 185 const uint8* response, | 120 const uint8* response, |
| 186 size_t response_length, | 121 size_t response_length, |
| 187 blink::WebContentDecryptionModuleResult result) { | 122 blink::WebContentDecryptionModuleResult result) { |
| 188 DCHECK(response); | 123 DCHECK(response); |
| 189 uint32 result_index = AddResult(result); | 124 DCHECK(!web_session_id_.empty()); |
| 190 scoped_ptr<media::SimpleCdmPromise> promise(new media::SimpleCdmPromise( | |
| 191 base::Bind( | |
| 192 &WebContentDecryptionModuleSessionImpl::SessionUpdatedOrReleased, | |
| 193 weak_ptr_factory_.GetWeakPtr(), | |
| 194 result_index), | |
| 195 base::Bind(&WebContentDecryptionModuleSessionImpl::SessionError, | |
| 196 weak_ptr_factory_.GetWeakPtr(), | |
| 197 result_index))); | |
| 198 adapter_->UpdateSession( | 125 adapter_->UpdateSession( |
| 199 web_session_id_, response, response_length, promise.Pass()); | 126 web_session_id_, |
| 127 response, | |
| 128 response_length, | |
| 129 scoped_ptr<media::SimpleCdmPromise>(new SimpleCdmResultPromise(result))); | |
| 130 } | |
| 131 | |
| 132 void WebContentDecryptionModuleSessionImpl::close( | |
| 133 blink::WebContentDecryptionModuleResult result) { | |
| 134 DCHECK(!web_session_id_.empty()); | |
| 135 adapter_->CloseSession( | |
| 136 web_session_id_, | |
| 137 scoped_ptr<media::SimpleCdmPromise>(new SimpleCdmResultPromise(result))); | |
| 138 } | |
| 139 | |
| 140 void WebContentDecryptionModuleSessionImpl::remove( | |
| 141 blink::WebContentDecryptionModuleResult result) { | |
| 142 DCHECK(!web_session_id_.empty()); | |
| 143 adapter_->RemoveSession( | |
| 144 web_session_id_, | |
| 145 scoped_ptr<media::SimpleCdmPromise>(new SimpleCdmResultPromise(result))); | |
| 146 } | |
| 147 | |
| 148 void WebContentDecryptionModuleSessionImpl::getUsableKeyIds( | |
| 149 blink::WebContentDecryptionModuleResult result) { | |
| 150 DCHECK(!web_session_id_.empty()); | |
| 151 adapter_->GetUsableKeyIds( | |
| 152 web_session_id_, | |
| 153 scoped_ptr<media::KeyIdsPromise>(new KeyIdsCdmResultPromise(result))); | |
| 200 } | 154 } |
| 201 | 155 |
| 202 void WebContentDecryptionModuleSessionImpl::release( | 156 void WebContentDecryptionModuleSessionImpl::release( |
| 203 blink::WebContentDecryptionModuleResult result) { | 157 blink::WebContentDecryptionModuleResult result) { |
| 204 uint32 result_index = AddResult(result); | 158 close(result); |
| 205 scoped_ptr<media::SimpleCdmPromise> promise(new media::SimpleCdmPromise( | |
| 206 base::Bind( | |
| 207 &WebContentDecryptionModuleSessionImpl::SessionUpdatedOrReleased, | |
| 208 weak_ptr_factory_.GetWeakPtr(), | |
| 209 result_index), | |
| 210 base::Bind(&WebContentDecryptionModuleSessionImpl::SessionError, | |
| 211 weak_ptr_factory_.GetWeakPtr(), | |
| 212 result_index))); | |
| 213 adapter_->ReleaseSession(web_session_id_, promise.Pass()); | |
| 214 } | 159 } |
| 215 | 160 |
| 216 void WebContentDecryptionModuleSessionImpl::OnSessionMessage( | 161 void WebContentDecryptionModuleSessionImpl::OnSessionMessage( |
| 217 const std::vector<uint8>& message, | 162 const std::vector<uint8>& message, |
| 218 const GURL& destination_url) { | 163 const GURL& destination_url) { |
| 219 DCHECK(client_) << "Client not set before message event"; | 164 DCHECK(client_) << "Client not set before message event"; |
| 220 client_->message( | 165 client_->message( |
| 221 message.empty() ? NULL : &message[0], message.size(), destination_url); | 166 message.empty() ? NULL : &message[0], message.size(), destination_url); |
| 222 } | 167 } |
| 223 | 168 |
| 169 void WebContentDecryptionModuleSessionImpl::OnSessionKeysChange( | |
| 170 bool has_additional_usable_key) { | |
| 171 // TODO(jrummell): Update this once Blink client supports this. | |
| 172 } | |
| 173 | |
| 174 void WebContentDecryptionModuleSessionImpl::OnSessionExpirationChange( | |
| 175 double new_expiry_time) { | |
| 176 // TODO(jrummell): Update this once Blink client supports this. | |
| 177 } | |
| 178 | |
| 224 void WebContentDecryptionModuleSessionImpl::OnSessionReady() { | 179 void WebContentDecryptionModuleSessionImpl::OnSessionReady() { |
| 225 client_->ready(); | 180 client_->ready(); |
| 226 } | 181 } |
| 227 | 182 |
| 228 void WebContentDecryptionModuleSessionImpl::OnSessionClosed() { | 183 void WebContentDecryptionModuleSessionImpl::OnSessionClosed() { |
| 229 if (!is_closed_) { | 184 if (!is_closed_) { |
| 230 is_closed_ = true; | 185 is_closed_ = true; |
| 231 client_->close(); | 186 client_->close(); |
| 232 } | 187 } |
| 233 } | 188 } |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 244 client_->error(Client::MediaKeyErrorCodeClient, system_code); | 199 client_->error(Client::MediaKeyErrorCodeClient, system_code); |
| 245 break; | 200 break; |
| 246 default: | 201 default: |
| 247 // This will include all other CDM4 errors and any error generated | 202 // This will include all other CDM4 errors and any error generated |
| 248 // by CDM5 or later. | 203 // by CDM5 or later. |
| 249 client_->error(Client::MediaKeyErrorCodeUnknown, system_code); | 204 client_->error(Client::MediaKeyErrorCodeUnknown, system_code); |
| 250 break; | 205 break; |
| 251 } | 206 } |
| 252 } | 207 } |
| 253 | 208 |
| 254 void WebContentDecryptionModuleSessionImpl::SessionCreated( | 209 blink::WebContentDecryptionModuleResult::SessionStatus |
| 255 uint32 result_index, | 210 WebContentDecryptionModuleSessionImpl::OnSessionInitialized( |
| 256 const std::string& web_session_id) { | 211 const std::string& web_session_id) { |
| 257 blink::WebContentDecryptionModuleResult::SessionStatus status; | 212 // CDM will return NULL if the session to be loaded can't be found. |
| 213 if (web_session_id.empty()) | |
| 214 return blink::WebContentDecryptionModuleResult::SessionNotFound; | |
| 258 | 215 |
| 259 // CDM will return NULL if the session to be loaded can't be found. | 216 DCHECK(web_session_id_.empty()) << "Session ID may not be changed once set."; |
| 260 if (web_session_id.empty()) { | 217 web_session_id_ = web_session_id; |
| 261 status = blink::WebContentDecryptionModuleResult::SessionNotFound; | 218 return adapter_->RegisterSession(web_session_id_, |
| 262 } else { | 219 weak_ptr_factory_.GetWeakPtr()) |
| 263 DCHECK(web_session_id_.empty()) | 220 ? blink::WebContentDecryptionModuleResult::NewSession |
| 264 << "Session ID may not be changed once set."; | 221 : blink::WebContentDecryptionModuleResult::SessionAlreadyExists; |
| 265 web_session_id_ = web_session_id; | |
| 266 status = | |
| 267 adapter_->RegisterSession(web_session_id_, | |
| 268 weak_ptr_factory_.GetWeakPtr()) | |
| 269 ? blink::WebContentDecryptionModuleResult::NewSession | |
| 270 : blink::WebContentDecryptionModuleResult::SessionAlreadyExists; | |
| 271 } | |
| 272 | |
| 273 ResultMap::iterator it = outstanding_results_.find(result_index); | |
| 274 if (it != outstanding_results_.end()) { | |
| 275 blink::WebContentDecryptionModuleResult& result = it->second; | |
| 276 result.completeWithSession(status); | |
| 277 outstanding_results_.erase(result_index); | |
| 278 } | |
| 279 } | |
| 280 | |
| 281 void WebContentDecryptionModuleSessionImpl::SessionUpdatedOrReleased( | |
| 282 uint32 result_index) { | |
| 283 ResultMap::iterator it = outstanding_results_.find(result_index); | |
| 284 DCHECK(it != outstanding_results_.end()); | |
| 285 blink::WebContentDecryptionModuleResult& result = it->second; | |
| 286 result.complete(); | |
| 287 outstanding_results_.erase(it); | |
| 288 } | |
| 289 | |
| 290 void WebContentDecryptionModuleSessionImpl::SessionError( | |
| 291 uint32 result_index, | |
| 292 media::MediaKeys::Exception exception_code, | |
| 293 uint32 system_code, | |
| 294 const std::string& error_message) { | |
| 295 ResultMap::iterator it = outstanding_results_.find(result_index); | |
| 296 DCHECK(it != outstanding_results_.end()); | |
| 297 blink::WebContentDecryptionModuleResult& result = it->second; | |
| 298 result.completeWithError(ConvertException(exception_code), | |
| 299 system_code, | |
| 300 blink::WebString::fromUTF8(error_message)); | |
| 301 outstanding_results_.erase(it); | |
| 302 } | |
| 303 | |
| 304 uint32 WebContentDecryptionModuleSessionImpl::AddResult( | |
| 305 blink::WebContentDecryptionModuleResult result) { | |
| 306 uint32 result_index = next_available_result_index_++; | |
| 307 DCHECK(result_index != kReservedIndex); | |
| 308 outstanding_results_.insert(std::make_pair(result_index, result)); | |
| 309 return result_index; | |
| 310 } | 222 } |
| 311 | 223 |
| 312 } // namespace content | 224 } // namespace content |
| OLD | NEW |