Line data Source code
1 : /* THIS FILE IS AUTOGENERATED FROM MediaDevices.webidl BY Codegen.py - DO NOT EDIT */
2 :
3 : #include "EventHandlerBinding.h"
4 : #include "EventTargetBinding.h"
5 : #include "MediaDevicesBinding.h"
6 : #include "MediaStreamBinding.h"
7 : #include "MediaTrackSupportedConstraintsBinding.h"
8 : #include "Navigator.h"
9 : #include "WrapperFactory.h"
10 : #include "mozilla/OwningNonNull.h"
11 : #include "mozilla/Preferences.h"
12 : #include "mozilla/dom/BindingUtils.h"
13 : #include "mozilla/dom/DOMJSClass.h"
14 : #include "mozilla/dom/MediaDevices.h"
15 : #include "mozilla/dom/NonRefcountedDOMObject.h"
16 : #include "mozilla/dom/Nullable.h"
17 : #include "mozilla/dom/Promise.h"
18 : #include "mozilla/dom/ToJSValue.h"
19 : #include "mozilla/dom/XrayExpandoClass.h"
20 : #include "nsContentUtils.h"
21 :
22 : namespace mozilla {
23 : namespace dom {
24 :
25 : namespace MediaDevicesBinding {
26 :
27 : static_assert(IsRefcounted<NativeType>::value == IsRefcounted<EventTargetBinding::NativeType>::value,
28 : "Can't inherit from an interface with a different ownership model.");
29 :
30 : static bool
31 0 : get_ondevicechange(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::MediaDevices* self, JSJitGetterCallArgs args)
32 : {
33 0 : RefPtr<EventHandlerNonNull> result(self->GetOndevicechange());
34 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
35 0 : if (result) {
36 0 : args.rval().setObjectOrNull(GetCallbackFromCallbackObject(result));
37 0 : if (!MaybeWrapObjectOrNullValue(cx, args.rval())) {
38 0 : return false;
39 : }
40 0 : return true;
41 : } else {
42 0 : args.rval().setNull();
43 0 : return true;
44 : }
45 : }
46 :
47 : static bool
48 0 : set_ondevicechange(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::MediaDevices* self, JSJitSetterCallArgs args)
49 : {
50 0 : RootedCallback<RefPtr<binding_detail::FastEventHandlerNonNull>> arg0(cx);
51 0 : if (args[0].isObject()) {
52 : { // scope for tempRoot
53 0 : JS::Rooted<JSObject*> tempRoot(cx, &args[0].toObject());
54 0 : arg0 = new binding_detail::FastEventHandlerNonNull(tempRoot);
55 : }
56 : } else {
57 0 : arg0 = nullptr;
58 : }
59 0 : self->SetOndevicechange(Constify(arg0));
60 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
61 :
62 0 : return true;
63 : }
64 :
65 : static const JSJitInfo ondevicechange_getterinfo = {
66 : { (JSJitGetterOp)get_ondevicechange },
67 : { prototypes::id::MediaDevices },
68 : { PrototypeTraits<prototypes::id::MediaDevices>::Depth },
69 : JSJitInfo::Getter,
70 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
71 : JSVAL_TYPE_UNKNOWN, /* returnType. Not relevant for setters. */
72 : false, /* isInfallible. False in setters. */
73 : false, /* isMovable. Not relevant for setters. */
74 : false, /* isEliminatable. Not relevant for setters. */
75 : false, /* isAlwaysInSlot. Only relevant for getters. */
76 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
77 : false, /* isTypedMethod. Only relevant for methods. */
78 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
79 : };
80 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
81 : static_assert(0 < 1, "There is no slot for us");
82 : static const JSJitInfo ondevicechange_setterinfo = {
83 : { (JSJitGetterOp)set_ondevicechange },
84 : { prototypes::id::MediaDevices },
85 : { PrototypeTraits<prototypes::id::MediaDevices>::Depth },
86 : JSJitInfo::Setter,
87 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
88 : JSVAL_TYPE_UNDEFINED, /* returnType. Not relevant for setters. */
89 : false, /* isInfallible. False in setters. */
90 : false, /* isMovable. Not relevant for setters. */
91 : false, /* isEliminatable. Not relevant for setters. */
92 : false, /* isAlwaysInSlot. Only relevant for getters. */
93 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
94 : false, /* isTypedMethod. Only relevant for methods. */
95 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
96 : };
97 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
98 : static_assert(0 < 1, "There is no slot for us");
99 :
100 : static bool
101 0 : getSupportedConstraints(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::MediaDevices* self, const JSJitMethodCallArgs& args)
102 : {
103 0 : MediaTrackSupportedConstraints result;
104 0 : self->GetSupportedConstraints(result);
105 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
106 0 : if (!result.ToObjectInternal(cx, args.rval())) {
107 0 : return false;
108 : }
109 0 : return true;
110 : }
111 :
112 : static const JSJitInfo getSupportedConstraints_methodinfo = {
113 : { (JSJitGetterOp)getSupportedConstraints },
114 : { prototypes::id::MediaDevices },
115 : { PrototypeTraits<prototypes::id::MediaDevices>::Depth },
116 : JSJitInfo::Method,
117 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
118 : JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
119 : false, /* isInfallible. False in setters. */
120 : false, /* isMovable. Not relevant for setters. */
121 : false, /* isEliminatable. Not relevant for setters. */
122 : false, /* isAlwaysInSlot. Only relevant for getters. */
123 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
124 : false, /* isTypedMethod. Only relevant for methods. */
125 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
126 : };
127 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
128 : static_assert(0 < 1, "There is no slot for us");
129 :
130 : static bool
131 0 : enumerateDevices(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::MediaDevices* self, const JSJitMethodCallArgs& args)
132 : {
133 0 : binding_detail::FastErrorResult rv;
134 0 : auto result(StrongOrRawPtr<Promise>(self->EnumerateDevices(rv)));
135 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
136 0 : return false;
137 : }
138 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
139 0 : if (!ToJSValue(cx, result, args.rval())) {
140 0 : return false;
141 : }
142 0 : return true;
143 : }
144 :
145 : static bool
146 0 : enumerateDevices_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::MediaDevices* self, const JSJitMethodCallArgs& args)
147 : {
148 : // Make sure to save the callee before someone maybe messes
149 : // with rval().
150 0 : JS::Rooted<JSObject*> callee(cx, &args.callee());
151 0 : bool ok = enumerateDevices(cx, obj, self, args);
152 0 : if (ok) {
153 0 : return true;
154 : }
155 0 : return ConvertExceptionToPromise(cx, xpc::XrayAwareCalleeGlobal(callee),
156 0 : args.rval());
157 : }
158 :
159 : static const JSJitInfo enumerateDevices_methodinfo = {
160 : { (JSJitGetterOp)enumerateDevices_promiseWrapper },
161 : { prototypes::id::MediaDevices },
162 : { PrototypeTraits<prototypes::id::MediaDevices>::Depth },
163 : JSJitInfo::Method,
164 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
165 : JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
166 : false, /* isInfallible. False in setters. */
167 : false, /* isMovable. Not relevant for setters. */
168 : false, /* isEliminatable. Not relevant for setters. */
169 : false, /* isAlwaysInSlot. Only relevant for getters. */
170 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
171 : false, /* isTypedMethod. Only relevant for methods. */
172 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
173 : };
174 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
175 : static_assert(0 < 1, "There is no slot for us");
176 :
177 : static bool
178 0 : getUserMedia(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::MediaDevices* self, const JSJitMethodCallArgs& args)
179 : {
180 0 : binding_detail::FastMediaStreamConstraints arg0;
181 0 : if (!arg0.Init(cx, (args.hasDefined(0)) ? args[0] : JS::NullHandleValue, "Argument 1 of MediaDevices.getUserMedia", false)) {
182 0 : return false;
183 : }
184 0 : binding_detail::FastErrorResult rv;
185 0 : auto result(StrongOrRawPtr<Promise>(self->GetUserMedia(Constify(arg0), nsContentUtils::IsSystemCaller(cx) ? CallerType::System : CallerType::NonSystem, rv)));
186 0 : if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
187 0 : return false;
188 : }
189 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
190 0 : if (!ToJSValue(cx, result, args.rval())) {
191 0 : return false;
192 : }
193 0 : return true;
194 : }
195 :
196 : static bool
197 0 : getUserMedia_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::MediaDevices* self, const JSJitMethodCallArgs& args)
198 : {
199 : // Make sure to save the callee before someone maybe messes
200 : // with rval().
201 0 : JS::Rooted<JSObject*> callee(cx, &args.callee());
202 0 : bool ok = getUserMedia(cx, obj, self, args);
203 0 : if (ok) {
204 0 : return true;
205 : }
206 0 : return ConvertExceptionToPromise(cx, xpc::XrayAwareCalleeGlobal(callee),
207 0 : args.rval());
208 : }
209 :
210 : static const JSJitInfo getUserMedia_methodinfo = {
211 : { (JSJitGetterOp)getUserMedia_promiseWrapper },
212 : { prototypes::id::MediaDevices },
213 : { PrototypeTraits<prototypes::id::MediaDevices>::Depth },
214 : JSJitInfo::Method,
215 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
216 : JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
217 : false, /* isInfallible. False in setters. */
218 : false, /* isMovable. Not relevant for setters. */
219 : false, /* isEliminatable. Not relevant for setters. */
220 : false, /* isAlwaysInSlot. Only relevant for getters. */
221 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
222 : false, /* isTypedMethod. Only relevant for methods. */
223 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
224 : };
225 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
226 : static_assert(0 < 1, "There is no slot for us");
227 :
228 : static bool
229 0 : _addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
230 : {
231 0 : mozilla::dom::MediaDevices* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::MediaDevices>(obj);
232 : // We don't want to preserve if we don't have a wrapper, and we
233 : // obviously can't preserve if we're not initialized.
234 0 : if (self && self->GetWrapperPreserveColor()) {
235 0 : PreserveWrapper(self);
236 : }
237 0 : return true;
238 : }
239 :
240 : static void
241 0 : _finalize(js::FreeOp* fop, JSObject* obj)
242 : {
243 0 : mozilla::dom::MediaDevices* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::MediaDevices>(obj);
244 0 : if (self) {
245 0 : ClearWrapper(self, self, obj);
246 0 : AddForDeferredFinalization<mozilla::dom::MediaDevices>(self);
247 : }
248 0 : }
249 :
250 : static void
251 0 : _objectMoved(JSObject* obj, const JSObject* old)
252 : {
253 0 : mozilla::dom::MediaDevices* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::MediaDevices>(obj);
254 0 : if (self) {
255 0 : UpdateWrapper(self, self, obj, old);
256 : }
257 0 : }
258 :
259 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
260 : #if defined(__clang__)
261 : #pragma clang diagnostic push
262 : #pragma clang diagnostic ignored "-Wmissing-braces"
263 : #endif
264 : static const JSFunctionSpec sMethods_specs[] = {
265 : JS_FNSPEC("getSupportedConstraints", GenericBindingMethod, reinterpret_cast<const JSJitInfo*>(&getSupportedConstraints_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
266 : JS_FNSPEC("enumerateDevices", GenericPromiseReturningBindingMethod, reinterpret_cast<const JSJitInfo*>(&enumerateDevices_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
267 : JS_FNSPEC("getUserMedia", GenericPromiseReturningBindingMethod, reinterpret_cast<const JSJitInfo*>(&getUserMedia_methodinfo), 0, JSPROP_ENUMERATE, nullptr),
268 : JS_FS_END
269 : };
270 : #if defined(__clang__)
271 : #pragma clang diagnostic pop
272 : #endif
273 :
274 :
275 : // Can't be const because the pref-enabled boolean needs to be writable
276 : static Prefable<const JSFunctionSpec> sMethods[] = {
277 : { nullptr, &sMethods_specs[0] },
278 : { nullptr, nullptr }
279 : };
280 :
281 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
282 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
283 : static_assert(3 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
284 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
285 :
286 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
287 : #if defined(__clang__)
288 : #pragma clang diagnostic push
289 : #pragma clang diagnostic ignored "-Wmissing-braces"
290 : #endif
291 : static const JSPropertySpec sAttributes_specs[] = {
292 : { "ondevicechange", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &ondevicechange_getterinfo, GenericBindingSetter, &ondevicechange_setterinfo },
293 : { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
294 : };
295 : #if defined(__clang__)
296 : #pragma clang diagnostic pop
297 : #endif
298 :
299 : static PrefableDisablers sAttributes_disablers0 = {
300 : true, false, 0, nullptr
301 : };
302 :
303 : // Can't be const because the pref-enabled boolean needs to be writable
304 : static Prefable<const JSPropertySpec> sAttributes[] = {
305 : { &sAttributes_disablers0, &sAttributes_specs[0] },
306 : { nullptr, nullptr }
307 : };
308 :
309 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
310 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
311 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
312 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
313 :
314 :
315 : static uint16_t sNativeProperties_sortedPropertyIndices[4];
316 : static PropertyInfo sNativeProperties_propertyInfos[4];
317 :
318 : static const NativePropertiesN<2> sNativeProperties = {
319 : false, 0,
320 : false, 0,
321 : true, 0 /* sMethods */,
322 : true, 1 /* sAttributes */,
323 : false, 0,
324 : false, 0,
325 : false, 0,
326 : -1,
327 : 4,
328 : sNativeProperties_sortedPropertyIndices,
329 : {
330 : { sMethods, &sNativeProperties_propertyInfos[0] },
331 : { sAttributes, &sNativeProperties_propertyInfos[3] }
332 : }
333 : };
334 : static_assert(4 < 1ull << CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount),
335 : "We have a property info count that is oversized");
336 :
337 : static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
338 : {
339 : "Function",
340 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
341 : &sBoringInterfaceObjectClassClassOps,
342 : JS_NULL_CLASS_SPEC,
343 : JS_NULL_CLASS_EXT,
344 : &sInterfaceObjectClassObjectOps
345 : },
346 : eInterface,
347 : true,
348 : prototypes::id::MediaDevices,
349 : PrototypeTraits<prototypes::id::MediaDevices>::Depth,
350 : sNativePropertyHooks,
351 : "function MediaDevices() {\n [native code]\n}",
352 : EventTargetBinding::GetConstructorObject
353 : };
354 :
355 : static const DOMIfaceAndProtoJSClass sPrototypeClass = {
356 : {
357 : "MediaDevicesPrototype",
358 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
359 : JS_NULL_CLASS_OPS,
360 : JS_NULL_CLASS_SPEC,
361 : JS_NULL_CLASS_EXT,
362 : JS_NULL_OBJECT_OPS
363 : },
364 : eInterfacePrototype,
365 : false,
366 : prototypes::id::MediaDevices,
367 : PrototypeTraits<prototypes::id::MediaDevices>::Depth,
368 : sNativePropertyHooks,
369 : "[object MediaDevicesPrototype]",
370 : EventTargetBinding::GetProtoObject
371 : };
372 :
373 : bool
374 0 : ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
375 : {
376 0 : return Navigator::HasUserMediaSupport(aCx, aObj);
377 : }
378 :
379 : JSObject*
380 0 : DefineDOMInterface(JSContext* aCx, JS::Handle<JSObject*> aGlobal, JS::Handle<jsid> id, bool aDefineOnGlobal)
381 : {
382 0 : return GetConstructorObjectHandle(aCx, aDefineOnGlobal);
383 : }
384 :
385 : static const js::ClassOps sClassOps = {
386 : _addProperty, /* addProperty */
387 : nullptr, /* delProperty */
388 : nullptr, /* getProperty */
389 : nullptr, /* setProperty */
390 : nullptr, /* enumerate */
391 : nullptr, /* newEnumerate */
392 : nullptr, /* resolve */
393 : nullptr, /* mayResolve */
394 : _finalize, /* finalize */
395 : nullptr, /* call */
396 : nullptr, /* hasInstance */
397 : nullptr, /* construct */
398 : nullptr, /* trace */
399 : };
400 :
401 : static const js::ClassExtension sClassExtension = {
402 : nullptr, /* weakmapKeyDelegateOp */
403 : _objectMoved /* objectMovedOp */
404 : };
405 :
406 : static const DOMJSClass sClass = {
407 : { "MediaDevices",
408 : JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
409 : &sClassOps,
410 : JS_NULL_CLASS_SPEC,
411 : &sClassExtension,
412 : JS_NULL_OBJECT_OPS
413 : },
414 : { prototypes::id::EventTarget, prototypes::id::MediaDevices, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
415 : IsBaseOf<nsISupports, mozilla::dom::MediaDevices >::value,
416 : sNativePropertyHooks,
417 : FindAssociatedGlobalForNative<mozilla::dom::MediaDevices>::Get,
418 : GetProtoObjectHandle,
419 : GetCCParticipant<mozilla::dom::MediaDevices>::Get()
420 : };
421 : static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
422 : "Must have the right minimal number of reserved slots.");
423 : static_assert(1 >= 1,
424 : "Must have enough reserved slots.");
425 :
426 : const JSClass*
427 0 : GetJSClass()
428 : {
429 0 : return sClass.ToJSClass();
430 : }
431 :
432 : bool
433 0 : Wrap(JSContext* aCx, mozilla::dom::MediaDevices* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
434 : {
435 : MOZ_ASSERT(static_cast<mozilla::dom::MediaDevices*>(aObject) ==
436 : reinterpret_cast<mozilla::dom::MediaDevices*>(aObject),
437 : "Multiple inheritance for mozilla::dom::MediaDevices is broken.");
438 : MOZ_ASSERT(static_cast<mozilla::dom::EventTarget*>(aObject) ==
439 : reinterpret_cast<mozilla::dom::EventTarget*>(aObject),
440 : "Multiple inheritance for mozilla::dom::EventTarget is broken.");
441 0 : MOZ_ASSERT(ToSupportsIsCorrect(aObject));
442 0 : MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
443 0 : MOZ_ASSERT(!aCache->GetWrapper(),
444 : "You should probably not be using Wrap() directly; use "
445 : "GetOrCreateDOMReflector instead");
446 :
447 0 : MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
448 : "nsISupports must be on our primary inheritance chain");
449 :
450 0 : JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
451 0 : if (!global) {
452 0 : return false;
453 : }
454 0 : MOZ_ASSERT(JS_IsGlobalObject(global));
455 0 : MOZ_ASSERT(JS::ObjectIsNotGray(global));
456 :
457 : // That might have ended up wrapping us already, due to the wonders
458 : // of XBL. Check for that, and bail out as needed.
459 0 : aReflector.set(aCache->GetWrapper());
460 0 : if (aReflector) {
461 : #ifdef DEBUG
462 0 : binding_detail::AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
463 : #endif // DEBUG
464 0 : return true;
465 : }
466 :
467 0 : JSAutoCompartment ac(aCx, global);
468 0 : JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
469 0 : if (!canonicalProto) {
470 0 : return false;
471 : }
472 0 : JS::Rooted<JSObject*> proto(aCx);
473 0 : if (aGivenProto) {
474 0 : proto = aGivenProto;
475 : // Unfortunately, while aGivenProto was in the compartment of aCx
476 : // coming in, we changed compartments to that of "parent" so may need
477 : // to wrap the proto here.
478 0 : if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
479 0 : if (!JS_WrapObject(aCx, &proto)) {
480 0 : return false;
481 : }
482 : }
483 : } else {
484 0 : proto = canonicalProto;
485 : }
486 :
487 0 : BindingJSObjectCreator<mozilla::dom::MediaDevices> creator(aCx);
488 0 : creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
489 0 : if (!aReflector) {
490 0 : return false;
491 : }
492 :
493 0 : aCache->SetWrapper(aReflector);
494 0 : creator.InitializationSucceeded();
495 :
496 0 : MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
497 : aCache->GetWrapperPreserveColor() == aReflector);
498 : // If proto != canonicalProto, we have to preserve our wrapper;
499 : // otherwise we won't be able to properly recreate it later, since
500 : // we won't know what proto to use. Note that we don't check
501 : // aGivenProto here, since it's entirely possible (and even
502 : // somewhat common) to have a non-null aGivenProto which is the
503 : // same as canonicalProto.
504 0 : if (proto != canonicalProto) {
505 0 : PreserveWrapper(aObject);
506 : }
507 :
508 0 : return true;
509 : }
510 :
511 : const NativePropertyHooks sNativePropertyHooks[] = { {
512 : nullptr,
513 : nullptr,
514 : nullptr,
515 : { sNativeProperties.Upcast(), nullptr },
516 : prototypes::id::MediaDevices,
517 : constructors::id::MediaDevices,
518 : EventTargetBinding::sNativePropertyHooks,
519 : &DefaultXrayExpandoObjectClass
520 : } };
521 :
522 : void
523 0 : CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
524 : {
525 0 : JS::Handle<JSObject*> parentProto(EventTargetBinding::GetProtoObjectHandle(aCx));
526 0 : if (!parentProto) {
527 0 : return;
528 : }
529 :
530 0 : JS::Handle<JSObject*> constructorProto(EventTargetBinding::GetConstructorObjectHandle(aCx));
531 0 : if (!constructorProto) {
532 0 : return;
533 : }
534 :
535 : static bool sIdsInited = false;
536 0 : if (!sIdsInited && NS_IsMainThread()) {
537 0 : if (!InitIds(aCx, sNativeProperties.Upcast())) {
538 0 : return;
539 : }
540 0 : sIdsInited = true;
541 : }
542 :
543 : static bool sPrefCachesInited = false;
544 0 : if (!sPrefCachesInited && NS_IsMainThread()) {
545 0 : sPrefCachesInited = true;
546 0 : Preferences::AddBoolVarCache(&sAttributes[0].disablers->enabled, "media.ondevicechange.enabled");
547 : }
548 :
549 0 : JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::MediaDevices);
550 0 : JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::MediaDevices);
551 0 : dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
552 : &sPrototypeClass.mBase, protoCache,
553 : constructorProto, &sInterfaceObjectClass.mBase, 0, nullptr,
554 : interfaceCache,
555 : sNativeProperties.Upcast(),
556 : nullptr,
557 : "MediaDevices", aDefineOnGlobal,
558 : nullptr,
559 0 : false);
560 : }
561 :
562 : JS::Handle<JSObject*>
563 0 : GetProtoObjectHandle(JSContext* aCx)
564 : {
565 : /* Get the interface prototype object for this class. This will create the
566 : object as needed. */
567 0 : bool aDefineOnGlobal = true;
568 :
569 : /* Make sure our global is sane. Hopefully we can remove this sometime */
570 0 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
571 0 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
572 0 : return nullptr;
573 : }
574 :
575 : /* Check to see whether the interface objects are already installed */
576 0 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
577 0 : if (!protoAndIfaceCache.HasEntryInSlot(prototypes::id::MediaDevices)) {
578 0 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
579 0 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
580 : }
581 :
582 : /*
583 : * The object might _still_ be null, but that's OK.
584 : *
585 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
586 : * traced by TraceProtoAndIfaceCache() and its contents are never
587 : * changed after they have been set.
588 : *
589 : * Calling address() avoids the read read barrier that does gray
590 : * unmarking, but it's not possible for the object to be gray here.
591 : */
592 :
593 0 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(prototypes::id::MediaDevices);
594 0 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
595 0 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
596 : }
597 :
598 : JS::Handle<JSObject*>
599 0 : GetConstructorObjectHandle(JSContext* aCx, bool aDefineOnGlobal)
600 : {
601 : /* Get the interface object for this class. This will create the object as
602 : needed. */
603 :
604 : /* Make sure our global is sane. Hopefully we can remove this sometime */
605 0 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
606 0 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
607 0 : return nullptr;
608 : }
609 :
610 : /* Check to see whether the interface objects are already installed */
611 0 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
612 0 : if (!protoAndIfaceCache.HasEntryInSlot(constructors::id::MediaDevices)) {
613 0 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
614 0 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
615 : }
616 :
617 : /*
618 : * The object might _still_ be null, but that's OK.
619 : *
620 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
621 : * traced by TraceProtoAndIfaceCache() and its contents are never
622 : * changed after they have been set.
623 : *
624 : * Calling address() avoids the read read barrier that does gray
625 : * unmarking, but it's not possible for the object to be gray here.
626 : */
627 :
628 0 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(constructors::id::MediaDevices);
629 0 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
630 0 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
631 : }
632 :
633 : JSObject*
634 0 : GetConstructorObject(JSContext* aCx)
635 : {
636 0 : return GetConstructorObjectHandle(aCx);
637 : }
638 :
639 : } // namespace MediaDevicesBinding
640 :
641 :
642 :
643 : } // namespace dom
644 : } // namespace mozilla
|