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