/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 |