Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/dom/base/nsObjectLoadingContent.h
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
3
/* This Source Code Form is subject to the terms of the Mozilla Public
4
 * License, v. 2.0. If a copy of the MPL was not distributed with this
5
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7
/*
8
 * A base class implementing nsIObjectLoadingContent for use by
9
 * various content nodes that want to provide plugin/document/image
10
 * loading functionality (eg <embed>, <object>, etc).
11
 */
12
13
#ifndef NSOBJECTLOADINGCONTENT_H_
14
#define NSOBJECTLOADINGCONTENT_H_
15
16
#include "mozilla/Attributes.h"
17
#include "mozilla/dom/BindingDeclarations.h"
18
#include "nsImageLoadingContent.h"
19
#include "nsIStreamListener.h"
20
#include "nsIChannelEventSink.h"
21
#include "nsIContentPolicy.h"
22
#include "nsIObjectLoadingContent.h"
23
#include "nsIRunnable.h"
24
#include "nsIThreadInternal.h"
25
#include "nsIFrame.h"
26
#include "nsIFrameLoaderOwner.h"
27
28
class nsAsyncInstantiateEvent;
29
class nsStopPluginRunnable;
30
class AutoSetInstantiatingToFalse;
31
class nsIPrincipal;
32
class nsFrameLoader;
33
class nsPluginFrame;
34
class nsPluginInstanceOwner;
35
36
namespace mozilla {
37
namespace dom {
38
template<typename T> class Sequence;
39
struct MozPluginParameter;
40
class HTMLIFrameElement;
41
class XULFrameElement;
42
} // namespace dom
43
} // namespace mozilla
44
45
class nsObjectLoadingContent : public nsImageLoadingContent
46
                             , public nsIStreamListener
47
                             , public nsIFrameLoaderOwner
48
                             , public nsIObjectLoadingContent
49
                             , public nsIChannelEventSink
50
{
51
  friend class AutoSetInstantiatingToFalse;
52
  friend class AutoSetLoadingToFalse;
53
  friend class CheckPluginStopEvent;
54
  friend class nsStopPluginRunnable;
55
  friend class nsAsyncInstantiateEvent;
56
57
  public:
58
    // This enum's values must be the same as the constants on
59
    // nsIObjectLoadingContent
60
    enum ObjectType {
61
      // Loading, type not yet known. We may be waiting for a channel to open.
62
      eType_Loading        = TYPE_LOADING,
63
      // Content is a *non-svg* image
64
      eType_Image          = TYPE_IMAGE,
65
      // Content is a plugin
66
      eType_Plugin         = TYPE_PLUGIN,
67
      // Content is a fake plugin, which loads as a document but behaves as a
68
      // plugin (see nsPluginHost::CreateFakePlugin)
69
      eType_FakePlugin     = TYPE_FAKE_PLUGIN,
70
      // Content is a subdocument, possibly SVG
71
      eType_Document       = TYPE_DOCUMENT,
72
      // No content loaded (fallback). May be showing alternate content or
73
      // a custom error handler - *including* click-to-play dialogs
74
      eType_Null           = TYPE_NULL
75
    };
76
77
    enum FallbackType {
78
      // The content type is not supported (e.g. plugin not installed)
79
      eFallbackUnsupported = nsIObjectLoadingContent::PLUGIN_UNSUPPORTED,
80
      // Showing alternate content
81
      eFallbackAlternate = nsIObjectLoadingContent::PLUGIN_ALTERNATE,
82
      // The plugin exists, but is disabled
83
      eFallbackDisabled = nsIObjectLoadingContent::PLUGIN_DISABLED,
84
      // The plugin is blocklisted and disabled
85
      eFallbackBlocklisted = nsIObjectLoadingContent::PLUGIN_BLOCKLISTED,
86
      // The plugin is considered outdated, but not disabled
87
      eFallbackOutdated = nsIObjectLoadingContent::PLUGIN_OUTDATED,
88
      // The plugin has crashed
89
      eFallbackCrashed = nsIObjectLoadingContent::PLUGIN_CRASHED,
90
      // Suppressed by security policy
91
      eFallbackSuppressed = nsIObjectLoadingContent::PLUGIN_SUPPRESSED,
92
      // Blocked by content policy
93
      eFallbackUserDisabled = nsIObjectLoadingContent::PLUGIN_USER_DISABLED,
94
      /// ** All values >= eFallbackClickToPlay are plugin placeholder types
95
      ///    that would be replaced by a real plugin if activated (PlayPlugin())
96
      /// ** Furthermore, values >= eFallbackClickToPlay and
97
      ///    <= eFallbackClickToPlayQuiet are click-to-play types.
98
      // The plugin is disabled until the user clicks on it
99
      eFallbackClickToPlay = nsIObjectLoadingContent::PLUGIN_CLICK_TO_PLAY,
100
      // The plugin is vulnerable (update available)
101
      eFallbackVulnerableUpdatable = nsIObjectLoadingContent::PLUGIN_VULNERABLE_UPDATABLE,
102
      // The plugin is vulnerable (no update available)
103
      eFallbackVulnerableNoUpdate = nsIObjectLoadingContent::PLUGIN_VULNERABLE_NO_UPDATE,
104
      // The plugin is click-to-play, but the user won't see overlays
105
      eFallbackClickToPlayQuiet = nsIObjectLoadingContent::PLUGIN_CLICK_TO_PLAY_QUIET,
106
    };
107
108
    nsObjectLoadingContent();
109
    virtual ~nsObjectLoadingContent();
110
111
    NS_DECL_NSIREQUESTOBSERVER
112
    NS_DECL_NSISTREAMLISTENER
113
    NS_DECL_NSIFRAMELOADEROWNER
114
    NS_DECL_NSIOBJECTLOADINGCONTENT
115
    NS_DECL_NSICHANNELEVENTSINK
116
117
    /**
118
     * Object state. This is a bitmask of NS_EVENT_STATEs epresenting the
119
     * current state of the object.
120
     */
121
    mozilla::EventStates ObjectState() const;
122
123
0
    ObjectType Type() const { return mType; }
124
125
    void SetIsNetworkCreated(bool aNetworkCreated)
126
0
    {
127
0
      mNetworkCreated = aNetworkCreated;
128
0
    }
129
130
    /**
131
     * When the object is loaded, the attributes and all nested <param>
132
     * elements are cached as name:value string pairs to be passed as
133
     * parameters when instantiating the plugin.
134
     *
135
     * Note: these cached values can be overriden for different quirk cases.
136
     */
137
    // Returns the cached attributes array.
138
    void GetPluginAttributes(nsTArray<mozilla::dom::MozPluginParameter>& aAttributes);
139
140
    // Returns the cached <param> array.
141
    void GetPluginParameters(nsTArray<mozilla::dom::MozPluginParameter>& aParameters);
142
143
    /**
144
     * Immediately instantiate a plugin instance. This is a no-op if mType !=
145
     * eType_Plugin or a plugin is already running.
146
     *
147
     * aIsLoading indicates that we are in the loading code, and we can bypass
148
     * the mIsLoading check.
149
     */
150
    nsresult InstantiatePluginInstance(bool aIsLoading = false);
151
152
    /**
153
     * Notify this class the document state has changed
154
     * Called by nsDocument so we may suspend plugins in inactive documents)
155
     */
156
    void NotifyOwnerDocumentActivityChanged();
157
158
    /**
159
     * When a plug-in is instantiated, it can create a scriptable
160
     * object that the page wants to interact with.  We expose this
161
     * object by placing it on the prototype chain of our element,
162
     * between the element itself and its most-derived DOM prototype.
163
     *
164
     * SetupProtoChain handles actually inserting the plug-in
165
     * scriptable object into the proto chain if needed.
166
     *
167
     * DoResolve is a hook that allows us to find out when the web
168
     * page is looking up a property name on our object and make sure
169
     * that our plug-in, if any, is instantiated.
170
     */
171
    // Helper for WebIDL node wrapping
172
    void SetupProtoChain(JSContext* aCx, JS::Handle<JSObject*> aObject);
173
174
    // Remove plugin from protochain
175
    void TeardownProtoChain();
176
177
    // Helper for WebIDL NeedResolve
178
    bool DoResolve(JSContext* aCx, JS::Handle<JSObject*> aObject,
179
                   JS::Handle<jsid> aId,
180
                   JS::MutableHandle<JS::PropertyDescriptor> aDesc);
181
    // The return value is whether DoResolve might end up resolving the given
182
    // id.  If in doubt, return true.
183
    static bool MayResolve(jsid aId);
184
185
    // Helper for WebIDL enumeration
186
    void GetOwnPropertyNames(JSContext* aCx, JS::AutoIdVector& /* unused */,
187
                             bool /* unused */, mozilla::ErrorResult& aRv);
188
189
    // WebIDL API
190
    nsIDocument* GetContentDocument(nsIPrincipal& aSubjectPrincipal);
191
    void GetActualType(nsAString& aType) const
192
0
    {
193
0
      CopyUTF8toUTF16(mContentType, aType);
194
0
    }
195
    uint32_t DisplayedType() const
196
0
    {
197
0
      return mType;
198
0
    }
199
    uint32_t GetContentTypeForMIMEType(const nsAString& aMIMEType)
200
0
    {
201
0
      return GetTypeOfContent(NS_ConvertUTF16toUTF8(aMIMEType), false);
202
0
    }
203
    void PlayPlugin(mozilla::dom::SystemCallerGuarantee,
204
                    mozilla::ErrorResult& aRv);
205
    void Reload(bool aClearActivation, mozilla::ErrorResult& aRv)
206
0
    {
207
0
      aRv = Reload(aClearActivation);
208
0
    }
209
    bool Activated() const
210
0
    {
211
0
      return mActivated;
212
0
    }
213
    nsIURI* GetSrcURI() const
214
0
    {
215
0
      return mURI;
216
0
    }
217
218
    /**
219
     * The default state that this plugin would be without manual activation.
220
     * @returns PLUGIN_ACTIVE if the default state would be active.
221
     */
222
    uint32_t DefaultFallbackType();
223
224
    uint32_t PluginFallbackType() const
225
0
    {
226
0
      return mFallbackType;
227
0
    }
228
    bool HasRunningPlugin() const
229
0
    {
230
0
      return !!mInstanceOwner;
231
0
    }
232
    // FIXME rename this
233
    void SkipFakePlugins(mozilla::ErrorResult& aRv)
234
0
    {
235
0
      aRv = SkipFakePlugins();
236
0
    }
237
    void SwapFrameLoaders(mozilla::dom::HTMLIFrameElement& aOtherLoaderOwner,
238
                          mozilla::ErrorResult& aRv)
239
0
    {
240
0
      aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
241
0
    }
242
    void SwapFrameLoaders(mozilla::dom::XULFrameElement& aOtherLoaderOwner,
243
                          mozilla::ErrorResult& aRv)
244
0
    {
245
0
      aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
246
0
    }
247
    void LegacyCall(JSContext* aCx, JS::Handle<JS::Value> aThisVal,
248
                    const mozilla::dom::Sequence<JS::Value>& aArguments,
249
                    JS::MutableHandle<JS::Value> aRetval,
250
                    mozilla::ErrorResult& aRv);
251
252
    uint32_t GetRunID(mozilla::dom::SystemCallerGuarantee,
253
                      mozilla::ErrorResult& aRv);
254
255
    bool IsRewrittenYoutubeEmbed() const
256
0
    {
257
0
      return mRewrittenYoutubeEmbed;
258
0
    }
259
260
    void PresetOpenerWindow(mozIDOMWindowProxy* aOpenerWindow, mozilla::ErrorResult& aRv);
261
262
  protected:
263
    /**
264
     * Begins loading the object when called
265
     *
266
     * Attributes of |this| QI'd to nsIContent will be inspected, depending on
267
     * the node type. This function currently assumes it is a <object> or
268
     * <embed> tag.
269
     *
270
     * The instantiated plugin depends on:
271
     * - The URI (<embed src>, <object data>)
272
     * - The type 'hint' (type attribute)
273
     * - The mime type returned by opening the URI
274
     * - Enabled plugins claiming the ultimate mime type
275
     * - The capabilities returned by GetCapabilities
276
     * - The classid attribute, if eFallbackIfClassIDPresent is among the capabilities
277
     *
278
     * If eAllowPluginSkipChannel is true, we may skip opening the URI if our
279
     * type hint points to a valid plugin, deferring that responsibility to the
280
     * plugin.
281
     * Similarly, if no URI is provided, but a type hint for a valid plugin is
282
     * present, that plugin will be instantiated
283
     *
284
     * Otherwise a request to that URI is made and the type sent by the server
285
     * is used to find a suitable handler, EXCEPT when:
286
     *  - The type hint refers to a *supported* plugin, in which case that
287
     *    plugin will be instantiated regardless of the server provided type
288
     *  - The server returns a binary-stream type, and our type hint refers to
289
     *    a valid non-document type, we will use the type hint
290
     *
291
     * @param aNotify    If we should send notifications. If false, content
292
     *                   loading may be deferred while appropriate frames are
293
     *                   created
294
     * @param aForceLoad If we should reload this content (and re-attempt the
295
     *                   channel open) even if our parameters did not change
296
     */
297
    nsresult LoadObject(bool aNotify,
298
                        bool aForceLoad = false);
299
300
    enum Capabilities {
301
      eSupportImages       = 1u << 0, // Images are supported (imgILoader)
302
      eSupportPlugins      = 1u << 1, // Plugins are supported (nsIPluginHost)
303
      eSupportDocuments    = 1u << 2, // Documents are supported
304
                                      // (nsIDocumentLoaderFactory)
305
                                      // This flag always includes SVG
306
307
      // Node supports class ID as an attribute, and should fallback if it is
308
      // present, as class IDs are not supported.
309
      eFallbackIfClassIDPresent = 1u << 3,
310
311
      // If possible to get a *plugin* type from the type attribute *or* file
312
      // extension, we can use that type and begin loading the plugin before
313
      // opening a channel.
314
      // A side effect of this is if the channel fails, the plugin is still
315
      // running.
316
      eAllowPluginSkipChannel  = 1u << 4
317
    };
318
319
    /**
320
     * Returns the list of capabilities this content node supports. This is a
321
     * bitmask consisting of flags from the Capabilities enum.
322
     *
323
     * The default implementation supports all types but not
324
     * eSupportClassID or eAllowPluginSkipChannel
325
     */
326
    virtual uint32_t GetCapabilities() const;
327
328
    /**
329
     * Destroys all loaded documents/plugins and releases references
330
     */
331
    void DestroyContent();
332
333
    static void Traverse(nsObjectLoadingContent *tmp,
334
                         nsCycleCollectionTraversalCallback &cb);
335
336
    void CreateStaticClone(nsObjectLoadingContent* aDest) const;
337
338
    void DoStopPlugin(nsPluginInstanceOwner* aInstanceOwner);
339
340
    nsresult BindToTree(nsIDocument* aDocument,
341
                        nsIContent* aParent,
342
                        nsIContent* aBindingParent);
343
    void UnbindFromTree(bool aDeep = true,
344
                        bool aNullParent = true);
345
346
    /**
347
     * Return the content policy type used for loading the element.
348
     */
349
    virtual nsContentPolicyType GetContentPolicyType() const = 0;
350
351
    /**
352
     * Decides whether we should load <embed>/<object> node content.
353
     *
354
     * If this is an <embed> or <object> node there are cases in which we should
355
     * not try to load the content:
356
     *
357
     * - If the node is the child of a media element
358
     * - If the node is the child of an <object> node that already has
359
     *   content being loaded.
360
     *
361
     * In these cases, this function will return false, which will cause
362
     * us to skip calling LoadObject.
363
     */
364
    bool BlockEmbedOrObjectContentLoading();
365
366
  private:
367
368
    // Object parameter changes returned by UpdateObjectParameters
369
    enum ParameterUpdateFlags {
370
      eParamNoChange           = 0,
371
      // Parameters that potentially affect the channel changed
372
      // - mOriginalURI, mOriginalContentType
373
      eParamChannelChanged     = 1u << 0,
374
      // Parameters that affect displayed content changed
375
      // - mURI, mContentType, mType, mBaseURI
376
      eParamStateChanged       = 1u << 1,
377
      // The effective content type changed, independant of object type. This
378
      // can happen when changing from Loading -> Final type, but doesn't
379
      // necessarily happen when changing between object types. E.g., if a PDF
380
      // handler was installed between the last load of this object and now, we
381
      // might change from eType_Document -> eType_Plugin without changing
382
      // ContentType
383
      eParamContentTypeChanged = 1u << 2
384
    };
385
386
    /**
387
     * Getter for child <param> elements that are not nested in another plugin
388
     * dom element.
389
     * This is an internal helper function and should not be used directly for
390
     * passing parameters to the plugin instance.
391
     *
392
     * See GetPluginParameters and GetPluginAttributes, which also handle
393
     * quirk-overrides.
394
     *
395
     * @param aParameters     The array containing pairs of name/value strings
396
     *                        from nested <param> objects.
397
     */
398
    void GetNestedParams(nsTArray<mozilla::dom::MozPluginParameter>& aParameters);
399
400
    MOZ_MUST_USE nsresult BuildParametersArray();
401
402
    /**
403
     * Loads fallback content with the specified FallbackType
404
     *
405
     * @param aType   FallbackType value for type of fallback we're loading
406
     * @param aNotify Send notifications and events. If false, caller is
407
     *                responsible for doing so
408
     */
409
    void LoadFallback(FallbackType aType, bool aNotify);
410
411
    /**
412
     * Internal version of LoadObject that should only be used by this class
413
     * aLoadingChannel is passed by the LoadObject call from OnStartRequest,
414
     * primarily for sanity-preservation
415
     */
416
    nsresult LoadObject(bool aNotify,
417
                        bool aForceLoad,
418
                        nsIRequest *aLoadingChannel);
419
420
    /**
421
     * Introspects the object and sets the following member variables:
422
     * - mOriginalContentType : This is the type attribute on the element
423
     * - mOriginalURI         : The src or data attribute on the element
424
     * - mURI                 : The final URI, considering mChannel if
425
     *                          mChannelLoaded is set
426
     * - mContentType         : The final content type, considering mChannel if
427
     *                          mChannelLoaded is set
428
     * - mBaseURI             : The object's base URI, which may be set by the
429
     *                          object
430
     * - mType                : The type the object is determined to be based
431
     *                          on the above
432
     *
433
     * NOTE The class assumes that mType is the currently loaded type at various
434
     *      points, so the caller of this function must take the appropriate
435
     *      actions to ensure this
436
     *
437
     * NOTE This function does not perform security checks, only determining the
438
     *      requested type and parameters of the object.
439
     *
440
     * @return Returns a bitmask of ParameterUpdateFlags values
441
     */
442
    ParameterUpdateFlags UpdateObjectParameters();
443
444
    /**
445
     * Queue a CheckPluginStopEvent and track it in mPendingCheckPluginStopEvent
446
     */
447
    void QueueCheckPluginStopEvent();
448
449
    void NotifyContentObjectWrapper();
450
451
    /**
452
     * Opens the channel pointed to by mURI into mChannel.
453
     */
454
    nsresult OpenChannel();
455
456
    /**
457
     * Closes and releases references to mChannel and, if opened, mFinalListener
458
     */
459
    nsresult CloseChannel();
460
461
    /**
462
     * If this object should be tested against blocking list.
463
     */
464
    bool ShouldBlockContent();
465
466
    /**
467
     * If this object is allowed to play plugin content, or if it would display
468
     * click-to-play instead.
469
     * NOTE that this does not actually check if the object is a loadable plugin
470
     * NOTE This ignores the current activated state. The caller should check
471
     *      this if appropriate.
472
     */
473
    bool ShouldPlay(FallbackType &aReason);
474
475
    /**
476
     * This method tells if the fallback content should be attempted to be used
477
     * over the original object content.
478
     * It will look at prefs and this plugin's CTP state to make a decision.
479
     *
480
     * NOTE that this doesn't say whether the fallback _will_ be used, only whether
481
     * we should look into it to possibly use it. The final answer will be
482
     * given by the PreferFallback method.
483
     *
484
     * @param aIsPluginClickToPlay Whether this object instance is CTP.
485
     */
486
    bool FavorFallbackMode(bool aIsPluginClickToPlay);
487
488
    /**
489
     * Whether the page has provided good fallback content to this object.
490
     */
491
    bool HasGoodFallback();
492
493
    /**
494
     * This method tells the final answer on whether this object's fallback
495
     * content should be used instead of the original plugin content.
496
     *
497
     * @param aIsPluginClickToPlay Whether this object instance is CTP.
498
     */
499
    bool PreferFallback(bool aIsPluginClickToPlay);
500
501
    /**
502
     * Helper to check if our current URI passes policy
503
     *
504
     * @param aContentPolicy [out] The result of the content policy decision
505
     *
506
     * @return true if call succeeded and NS_CP_ACCEPTED(*aContentPolicy)
507
     */
508
    bool CheckLoadPolicy(int16_t *aContentPolicy);
509
510
    /**
511
     * Helper to check if the object passes process policy. Assumes we have a
512
     * final determined type.
513
     *
514
     * @param aContentPolicy [out] The result of the content policy decision
515
     *
516
     * @return true if call succeeded and NS_CP_ACCEPTED(*aContentPolicy)
517
     */
518
    bool CheckProcessPolicy(int16_t *aContentPolicy);
519
520
    /**
521
     * Gets the plugin instance and creates a plugin stream listener, assigning
522
     * it to mFinalListener
523
     */
524
    bool MakePluginListener();
525
526
    void SetupFrameLoader(int32_t aJSPluginId);
527
528
    /**
529
     * Helper to spawn mFrameLoader and return a pointer to its docshell
530
     *
531
     * @param aURI URI we intend to load for the recursive load check (does not
532
     *             actually load anything)
533
     */
534
    already_AddRefed<nsIDocShell> SetupDocShell(nsIURI* aRecursionCheckURI);
535
536
    /**
537
     * Unloads all content and resets the object to a completely unloaded state
538
     *
539
     * NOTE Calls StopPluginInstance() and may spin the event loop
540
     *
541
     * @param aResetState Reset the object type to 'loading' and destroy channel
542
     *                    as well
543
     */
544
    void UnloadObject(bool aResetState = true);
545
546
    /**
547
     * Notifies document observes about a new type/state of this object.
548
     * Triggers frame construction as needed. mType must be set correctly when
549
     * this method is called. This method is cheap if the type and state didn't
550
     * actually change.
551
     *
552
     * @param aSync If a synchronous frame construction is required. If false,
553
     *              the construction may either be sync or async.
554
     * @param aNotify if false, only need to update the state of our element.
555
     */
556
    void NotifyStateChanged(ObjectType aOldType,
557
                            mozilla::EventStates aOldState,
558
                            bool aSync, bool aNotify);
559
560
    /**
561
     * Returns a ObjectType value corresponding to the type of content we would
562
     * support the given MIME type as, taking capabilities and plugin state
563
     * into account
564
     *
565
     * @param aNoFakePlugin Don't select a fake plugin handler as a valid type,
566
     *                      as when SkipFakePlugins() is called.
567
     * @return The ObjectType enum value that we would attempt to load
568
     *
569
     * NOTE this does not consider whether the content would be suppressed by
570
     *      click-to-play or other content policy checks
571
     */
572
    ObjectType GetTypeOfContent(const nsCString& aMIMEType, bool aNoFakePlugin);
573
574
    /**
575
     * Gets the frame that's associated with this content node.
576
     * Does not flush.
577
     */
578
    nsPluginFrame* GetExistingFrame();
579
580
    /**
581
     * Used for identifying whether we can rewrite a youtube flash embed to
582
     * possibly use HTML5 instead.
583
     *
584
     * Returns true if plugin.rewrite_youtube_embeds pref is true and the
585
     * element this nsObjectLoadingContent instance represents:
586
     *
587
     * - is an embed or object node
588
     * - has a URL pointing at the youtube.com domain, using "/v/" style video
589
     *   path reference.
590
     *
591
     * Having the enablejsapi flag means the document that contains the element
592
     * could possibly be manipulating the youtube video elsewhere on the page
593
     * via javascript. In the context of embed elements, this usage has been
594
     * deprecated by youtube, so we can just rewrite as normal.
595
     *
596
     * If we can rewrite the URL, we change the "/v/" to "/embed/", and change
597
     * our type to eType_Document so that we render similarly to an iframe
598
     * embed.
599
     */
600
    void MaybeRewriteYoutubeEmbed(nsIURI* aURI,
601
                                  nsIURI* aBaseURI,
602
                                  nsIURI** aRewrittenURI);
603
604
    // Helper class for SetupProtoChain
605
    class SetupProtoChainRunner final : public nsIRunnable
606
    {
607
0
      ~SetupProtoChainRunner() = default;
608
    public:
609
      NS_DECL_ISUPPORTS
610
611
      explicit SetupProtoChainRunner(nsObjectLoadingContent* aContent);
612
613
      NS_IMETHOD Run() override;
614
615
    private:
616
      // We store an nsIObjectLoadingContent because we can
617
      // unambiguously refcount that.
618
      RefPtr<nsIObjectLoadingContent> mContent;
619
    };
620
621
    // Utility getter for getting our nsNPAPIPluginInstance in a safe way.
622
    nsresult ScriptRequestPluginInstance(JSContext* aCx,
623
                                         nsNPAPIPluginInstance** aResult);
624
625
    // Utility method for getting our plugin JSObject
626
    static nsresult GetPluginJSObject(JSContext *cx,
627
                                      nsNPAPIPluginInstance *plugin_inst,
628
                                      JS::MutableHandle<JSObject*> plugin_obj,
629
                                      JS::MutableHandle<JSObject*> plugin_proto);
630
631
    // Utility for firing an error event, if we're an <object>.
632
    void MaybeFireErrorEvent();
633
634
    // The final listener for mChannel (uriloader, pluginstreamlistener, etc.)
635
    nsCOMPtr<nsIStreamListener> mFinalListener;
636
637
    // Frame loader, for content documents we load.
638
    RefPtr<nsFrameLoader>     mFrameLoader;
639
640
    // Track if we have a pending AsyncInstantiateEvent
641
    nsCOMPtr<nsIRunnable>       mPendingInstantiateEvent;
642
643
    // Tracks if we have a pending CheckPluginStopEvent
644
    nsCOMPtr<nsIRunnable>       mPendingCheckPluginStopEvent;
645
646
    // The content type of our current load target, updated by
647
    // UpdateObjectParameters(). Takes the channel's type into account once
648
    // opened.
649
    //
650
    // May change if a channel is opened, does not imply a loaded state
651
    nsCString                   mContentType;
652
653
    // The content type 'hint' provided by the element's type attribute. May
654
    // or may not be used as a final type
655
    nsCString                   mOriginalContentType;
656
657
    // The channel that's currently being loaded. If set, but mChannelLoaded is
658
    // false, has not yet reached OnStartRequest
659
    nsCOMPtr<nsIChannel>        mChannel;
660
661
    // The URI of the current content.
662
    // May change as we open channels and encounter redirects - does not imply
663
    // a loaded type
664
    nsCOMPtr<nsIURI>            mURI;
665
666
    // The original URI obtained from inspecting the element. May differ from
667
    // mURI due to redirects
668
    nsCOMPtr<nsIURI>            mOriginalURI;
669
670
    // The baseURI used for constructing mURI.
671
    nsCOMPtr<nsIURI>            mBaseURI;
672
673
674
675
    // Type of the currently-loaded content.
676
    ObjectType                  mType           : 8;
677
    // The type of fallback content we're showing (see ObjectState())
678
    FallbackType                mFallbackType : 8;
679
680
    uint32_t                    mRunID;
681
    bool                        mHasRunID : 1;
682
683
    // If true, we have opened a channel as the listener and it has reached
684
    // OnStartRequest. Does not get set for channels that are passed directly to
685
    // the plugin listener.
686
    bool                        mChannelLoaded    : 1;
687
688
    // Whether we are about to call instantiate on our frame. If we aren't,
689
    // SetFrame needs to asynchronously call Instantiate.
690
    bool                        mInstantiating : 1;
691
692
    // True when the object is created for an element which the parser has
693
    // created using NS_FROM_PARSER_NETWORK flag. If the element is modified,
694
    // it may lose the flag.
695
    bool                        mNetworkCreated : 1;
696
697
    // Used to keep track of whether or not a plugin has been explicitly
698
    // activated by PlayPlugin(). (see ShouldPlay())
699
    bool                        mActivated : 1;
700
701
    // Whether content blocking is enabled or not for this object.
702
    bool                        mContentBlockingEnabled : 1;
703
704
    // If we should not use fake plugins until the next type change
705
    bool                        mSkipFakePlugins : 1;
706
707
    // Protects DoStopPlugin from reentry (bug 724781).
708
    bool                        mIsStopping : 1;
709
710
    // Protects LoadObject from re-entry
711
    bool                        mIsLoading : 1;
712
713
    // For plugin stand-in types (click-to-play) tracks whether content js has
714
    // tried to access the plugin script object.
715
    bool                        mScriptRequested : 1;
716
717
    // True if object represents an object/embed tag pointing to a flash embed
718
    // for a youtube video. When possible (see IsRewritableYoutubeEmbed function
719
    // comments for details), we change these to try to load HTML5 versions of
720
    // videos.
721
    bool                        mRewrittenYoutubeEmbed : 1;
722
723
    // Cache the answer of PreferFallback() because ShouldPlay is called several
724
    // times during the load process.
725
    bool                        mPreferFallback : 1;
726
    bool                        mPreferFallbackKnown : 1;
727
728
    WeakFrame                   mPrintFrame;
729
730
    RefPtr<nsPluginInstanceOwner> mInstanceOwner;
731
    nsTArray<mozilla::dom::MozPluginParameter> mCachedAttributes;
732
    nsTArray<mozilla::dom::MozPluginParameter> mCachedParameters;
733
};
734
735
#endif