Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 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 "config.h" | |
| 6 #include "modules/encryptedmedia/NavigatorRequestMediaKeySystemAccess.h" | |
| 7 | |
| 8 #include "bindings/core/v8/ScriptPromiseResolver.h" | |
| 9 #include "bindings/core/v8/ScriptState.h" | |
| 10 #include "core/dom/DOMException.h" | |
| 11 #include "core/dom/ExceptionCode.h" | |
| 12 #include "modules/encryptedmedia/MediaKeySystemAccess.h" | |
| 13 #include "platform/ContentType.h" | |
| 14 #include "platform/Logging.h" | |
| 15 #include "platform/MIMETypeRegistry.h" | |
| 16 | |
| 17 namespace blink { | |
| 18 | |
| 19 static bool isKeySystemSupportedWithContentType(const String& keySystem, const S tring& contentType) | |
| 20 { | |
| 21 ASSERT(!keySystem.isEmpty()); | |
| 22 | |
| 23 ContentType type(contentType); | |
| 24 String codecs = type.parameter("codecs"); | |
| 25 return MIMETypeRegistry::isSupportedEncryptedMediaMIMEType(keySystem, type.t ype(), codecs); | |
| 26 } | |
| 27 | |
| 28 // This class allows a MediaKeySystemAccess object to be created asynchronously. | |
|
ddorwin
2014/10/22 22:18:54
allows capabilities to be checked and... ?
jrummell
2014/10/23 01:20:03
Done.
| |
| 29 class MediaKeySystemAccessInitializer : public ScriptPromiseResolver { | |
|
ddorwin
2014/10/22 22:18:54
We should consider somehow avoiding the boilerplat
jrummell
2014/10/23 01:20:03
Acknowledged.
| |
| 30 WTF_MAKE_NONCOPYABLE(MediaKeySystemAccessInitializer); | |
| 31 | |
| 32 public: | |
| 33 static ScriptPromise create(ScriptState*, const String& keySystem, const Vec tor<MediaKeySystemOptions>& supportedConfigurations); | |
| 34 virtual ~MediaKeySystemAccessInitializer(); | |
| 35 | |
| 36 private: | |
| 37 MediaKeySystemAccessInitializer(ScriptState*, const String& keySystem, const Vector<MediaKeySystemOptions>& supportedConfigurations); | |
| 38 void timerFired(Timer<MediaKeySystemAccessInitializer>*); | |
| 39 | |
| 40 const String m_keySystem; | |
| 41 const Vector<MediaKeySystemOptions> m_supportedConfigurations; | |
| 42 Timer<MediaKeySystemAccessInitializer> m_timer; | |
| 43 }; | |
| 44 | |
| 45 ScriptPromise MediaKeySystemAccessInitializer::create(ScriptState* scriptState, const String& keySystem, const Vector<MediaKeySystemOptions>& supportedConfigura tions) | |
| 46 { | |
| 47 RefPtr<MediaKeySystemAccessInitializer> initializer = adoptRef(new MediaKeyS ystemAccessInitializer(scriptState, keySystem, supportedConfigurations)); | |
| 48 initializer->suspendIfNeeded(); | |
| 49 initializer->keepAliveWhilePending(); | |
| 50 return initializer->promise(); | |
| 51 } | |
| 52 | |
| 53 MediaKeySystemAccessInitializer::MediaKeySystemAccessInitializer(ScriptState* sc riptState, const String& keySystem, const Vector<MediaKeySystemOptions>& support edConfigurations) | |
| 54 : ScriptPromiseResolver(scriptState) | |
| 55 , m_keySystem(keySystem) | |
| 56 , m_supportedConfigurations(supportedConfigurations) | |
| 57 , m_timer(this, &MediaKeySystemAccessInitializer::timerFired) | |
| 58 { | |
| 59 WTF_LOG(Media, "MediaKeySystemAccessInitializer::MediaKeySystemAccessInitial izer"); | |
| 60 // Start the timer so that MediaKeySystemAccess can be created asynchronousl y. | |
| 61 m_timer.startOneShot(0, FROM_HERE); | |
| 62 } | |
| 63 | |
| 64 MediaKeySystemAccessInitializer::~MediaKeySystemAccessInitializer() | |
| 65 { | |
| 66 WTF_LOG(Media, "MediaKeySystemAccessInitializer::~MediaKeySystemAccessInitia lizer"); | |
| 67 } | |
| 68 | |
| 69 void MediaKeySystemAccessInitializer::timerFired(Timer<MediaKeySystemAccessIniti alizer>*) | |
| 70 { | |
| 71 WTF_LOG(Media, "MediaKeySystemAccessInitializer::timerFired"); | |
| 72 | |
| 73 // Continued from requestMediaKeySystemAccess(). | |
| 74 // 5.1 If keySystem is not supported or not allowed in the origin of the | |
| 75 // calling context's Document, return a promise rejected with a new | |
| 76 // DOMException whose name is NotSupportedError. | |
|
ddorwin
2014/10/22 22:18:54
(Handled by Chromium.)
jrummell
2014/10/23 01:20:03
Done.
| |
| 77 | |
| 78 // 5.2 If supportedConfigurations was not provided, resolve the promise | |
| 79 // with a new MediaKeySystemAccess object, execute the following steps: | |
| 80 if (!m_supportedConfigurations.size()) { | |
| 81 // 5.2.1 Let access be a new MediaKeySystemAccess object, and initialize | |
| 82 // it as follows: | |
| 83 // 5.2.1.1 Set the keySystem attribute to keySystem. | |
| 84 MediaKeySystemAccess* access = new MediaKeySystemAccess(m_keySystem); | |
| 85 | |
| 86 // 5.2.2 Resolve promise with access and abort these steps. | |
| 87 resolve(access); | |
| 88 return; | |
| 89 } | |
| 90 | |
| 91 // 5.3 For each element of supportedConfigurations: | |
| 92 // 5.3.1 Let combination be the element. | |
| 93 // 5.3.2 For each dictionary member in combination: | |
| 94 for (const auto& combination : m_supportedConfigurations) { | |
| 95 // 5.3.2.1 If the member's value cannot be satisfied together in | |
| 96 // combination with the previous members, continue to the next | |
| 97 // iteration of the loop. | |
| 98 // 5.3.3 If keySystem is supported and allowed in the origin of the | |
| 99 // calling context's Document in the configuration specified by | |
| 100 // the combination of the values in combination, execute the | |
| 101 // following steps: | |
| 102 // FIXME: This test needs to be enhanced to use more values from | |
| 103 // combination. | |
| 104 if (isKeySystemSupportedWithContentType(m_keySystem, combination.initDat aType())) { | |
| 105 // 5.3.3.1 Let access be a new MediaKeySystemAccess object, and | |
| 106 // initialize it as follows: | |
| 107 // 5.3.3.1.1 Set the keySystem attribute to keySystem. | |
| 108 MediaKeySystemAccess* access = new MediaKeySystemAccess(m_keySystem) ; | |
| 109 | |
| 110 // 5.3.3.2 Resolve promise with access and abort these steps. | |
| 111 resolve(access); | |
| 112 return; | |
| 113 } | |
| 114 } | |
| 115 | |
| 116 // 5.4 Reject promise with a new DOMException whose name is | |
| 117 // NotSupportedError. | |
| 118 reject(DOMException::create(NotSupportedError, "There were no supported comb inations in supportedConfigurations.")); | |
| 119 } | |
| 120 | |
| 121 NavigatorRequestMediaKeySystemAccess::NavigatorRequestMediaKeySystemAccess() | |
| 122 { | |
| 123 } | |
| 124 | |
| 125 NavigatorRequestMediaKeySystemAccess::~NavigatorRequestMediaKeySystemAccess() | |
| 126 { | |
| 127 } | |
| 128 | |
| 129 NavigatorRequestMediaKeySystemAccess& NavigatorRequestMediaKeySystemAccess::from (Navigator& navigator) | |
| 130 { | |
| 131 NavigatorRequestMediaKeySystemAccess* supplement = static_cast<NavigatorRequ estMediaKeySystemAccess*>(WillBeHeapSupplement<Navigator>::from(navigator, suppl ementName())); | |
| 132 if (!supplement) { | |
| 133 supplement = new NavigatorRequestMediaKeySystemAccess(); | |
| 134 provideTo(navigator, supplementName(), adoptPtrWillBeNoop(supplement)); | |
| 135 } | |
| 136 return *supplement; | |
| 137 } | |
| 138 | |
| 139 ScriptPromise NavigatorRequestMediaKeySystemAccess::requestMediaKeySystemAccess( | |
| 140 ScriptState* scriptState, | |
| 141 Navigator& navigator, | |
| 142 const String& keySystem) | |
| 143 { | |
| 144 // From https://dvcs.w3.org/hg/html-media/raw-file/default/encrypted-media/e ncrypted-media.html#requestmediakeysystemaccess | |
| 145 // When this method is invoked, the user agent must run the following steps: | |
| 146 // 1. If keySystem is an empty string, return a promise rejected with a | |
| 147 // new DOMException whose name is InvalidAccessError. | |
| 148 if (keySystem.isEmpty()) { | |
| 149 return ScriptPromise::rejectWithDOMException( | |
| 150 scriptState, DOMException::create(InvalidAccessError, "The keySystem parameter is empty.")); | |
| 151 } | |
| 152 | |
| 153 // 2. If supportedConfigurations was provided and is empty, return a | |
| 154 // promise rejected with a new DOMException whose name is | |
| 155 // InvalidAccessError. | |
| 156 // (no supportedConfigurations provided.) | |
| 157 | |
| 158 // Remainder of steps handled in common routine below. | |
| 159 Vector<MediaKeySystemOptions> supportedConfigurations; | |
|
ddorwin
2014/10/22 22:18:54
nit: Can you do this inline below?
jrummell
2014/10/23 01:20:03
Done.
| |
| 160 return NavigatorRequestMediaKeySystemAccess::from(navigator).requestMediaKey SystemAccess(scriptState, keySystem, supportedConfigurations); | |
| 161 } | |
| 162 | |
| 163 ScriptPromise NavigatorRequestMediaKeySystemAccess::requestMediaKeySystemAccess( | |
| 164 ScriptState* scriptState, | |
| 165 Navigator& navigator, | |
| 166 const String& keySystem, | |
| 167 const Vector<MediaKeySystemOptions>& supportedConfigurations) | |
| 168 { | |
| 169 // From https://dvcs.w3.org/hg/html-media/raw-file/default/encrypted-media/e ncrypted-media.html#requestmediakeysystemaccess | |
| 170 // When this method is invoked, the user agent must run the following steps: | |
| 171 // 1. If keySystem is an empty string, return a promise rejected with a | |
| 172 // new DOMException whose name is InvalidAccessError. | |
| 173 if (keySystem.isEmpty()) { | |
| 174 return ScriptPromise::rejectWithDOMException( | |
| 175 scriptState, DOMException::create(InvalidAccessError, "The keySystem parameter is empty.")); | |
| 176 } | |
| 177 | |
| 178 // 2. If supportedConfigurations was provided and is empty, return a | |
| 179 // promise rejected with a new DOMException whose name is | |
| 180 // InvalidAccessError. | |
| 181 if (!supportedConfigurations.size()) { | |
| 182 return ScriptPromise::rejectWithDOMException( | |
| 183 scriptState, DOMException::create(InvalidAccessError, "The supported Configurations parameter is empty.")); | |
| 184 } | |
| 185 | |
| 186 // Remainder of steps handled in common routine below. | |
| 187 return NavigatorRequestMediaKeySystemAccess::from(navigator).requestMediaKey SystemAccess( | |
| 188 scriptState, keySystem, supportedConfigurations); | |
| 189 } | |
| 190 | |
| 191 ScriptPromise NavigatorRequestMediaKeySystemAccess::requestMediaKeySystemAccess( | |
| 192 ScriptState* scriptState, | |
| 193 const String& keySystem, | |
| 194 const Vector<MediaKeySystemOptions>& supportedConfigurations) | |
| 195 { | |
| 196 // Continued from above. | |
| 197 // 3. If keySystem is not one of the Key Systems supported by the user | |
| 198 // agent, return a promise rejected with a new DOMException whose name | |
| 199 // is NotSupportedError. String comparison is case-sensitive. | |
| 200 if (!isKeySystemSupportedWithContentType(keySystem, "")) { | |
| 201 return ScriptPromise::rejectWithDOMException( | |
| 202 scriptState, DOMException::create(NotSupportedError, "The key system specified is not supported.")); | |
| 203 } | |
| 204 | |
| 205 // 4. Let promise be a new promise. | |
| 206 // 5. Asynchronously create and initialize the MediaKeySystemAccess object. | |
|
ddorwin
2014/10/22 22:18:54
It's really determine support and ....
jrummell
2014/10/23 01:20:03
Done.
| |
| 207 // 6. Return promise. | |
| 208 return MediaKeySystemAccessInitializer::create(scriptState, keySystem, suppo rtedConfigurations); | |
| 209 } | |
| 210 | |
| 211 const char* NavigatorRequestMediaKeySystemAccess::supplementName() | |
| 212 { | |
| 213 return "RequestMediaKeySystemAccess"; | |
| 214 } | |
| 215 | |
| 216 void NavigatorRequestMediaKeySystemAccess::trace(Visitor* visitor) | |
| 217 { | |
| 218 WillBeHeapSupplement<Navigator>::trace(visitor); | |
| 219 } | |
| 220 | |
| 221 } // namespace blink | |
| OLD | NEW |