LCOV - code coverage report
Current view: directory - content/base/src - nsObjectLoadingContent.h (source / functions) Found Hit Coverage
Test: app.info Lines: 5 0 0.0 %
Date: 2012-06-02 Functions: 3 0 0.0 %

       1                 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2                 : // vim:set et cin sw=2 sts=2:
       3                 : /* ***** BEGIN LICENSE BLOCK *****
       4                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       5                 :  *
       6                 :  * The contents of this file are subject to the Mozilla Public License Version
       7                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       8                 :  * the License. You may obtain a copy of the License at
       9                 :  * http://www.mozilla.org/MPL/
      10                 :  *
      11                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      12                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      13                 :  * for the specific language governing rights and limitations under the
      14                 :  * License.
      15                 :  *
      16                 :  * The Original Code is Mozilla <object> loading code.
      17                 :  *
      18                 :  * The Initial Developer of the Original Code is
      19                 :  * Christian Biesinger <cbiesinger@web.de>.
      20                 :  * Portions created by the Initial Developer are Copyright (C) 2005
      21                 :  * the Initial Developer. All Rights Reserved.
      22                 :  *
      23                 :  * Contributor(s):
      24                 :  *
      25                 :  * Alternatively, the contents of this file may be used under the terms of
      26                 :  * either the GNU General Public License Version 2 or later (the "GPL"), or
      27                 :  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      28                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      29                 :  * of those above. If you wish to allow use of your version of this file only
      30                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      31                 :  * use your version of this file under the terms of the MPL, indicate your
      32                 :  * decision by deleting the provisions above and replace them with the notice
      33                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      34                 :  * the provisions above, a recipient may use your version of this file under
      35                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      36                 :  *
      37                 :  * ***** END LICENSE BLOCK ***** */
      38                 : 
      39                 : /*
      40                 :  * A base class implementing nsIObjectLoadingContent for use by
      41                 :  * various content nodes that want to provide plugin/document/image
      42                 :  * loading functionality (eg <embed>, <object>, <applet>, etc).
      43                 :  */
      44                 : 
      45                 : #ifndef NSOBJECTLOADINGCONTENT_H_
      46                 : #define NSOBJECTLOADINGCONTENT_H_
      47                 : 
      48                 : #include "nsImageLoadingContent.h"
      49                 : #include "nsIStreamListener.h"
      50                 : #include "nsFrameLoader.h"
      51                 : #include "nsIInterfaceRequestor.h"
      52                 : #include "nsIChannelEventSink.h"
      53                 : #include "nsIObjectLoadingContent.h"
      54                 : #include "nsIRunnable.h"
      55                 : #include "nsIFrame.h"
      56                 : #include "nsPluginInstanceOwner.h"
      57                 : #include "nsIThreadInternal.h"
      58                 : 
      59                 : class nsAsyncInstantiateEvent;
      60                 : class nsStopPluginRunnable;
      61                 : class AutoNotifier;
      62                 : class AutoFallback;
      63                 : class AutoSetInstantiatingToFalse;
      64                 : class nsObjectFrame;
      65                 : 
      66                 : enum PluginSupportState {
      67                 :   ePluginUnsupported,  // The plugin is not supported (e.g. not installed)
      68                 :   ePluginDisabled,     // The plugin has been explicitly disabled by the user
      69                 :   ePluginBlocklisted,  // The plugin is blocklisted and disabled
      70                 :   ePluginOutdated,     // The plugin is considered outdated, but not disabled
      71                 :   ePluginOtherState,   // Something else (e.g. uninitialized or not a plugin)
      72                 :   ePluginCrashed,
      73                 :   ePluginClickToPlay   // The plugin is disabled until the user clicks on it
      74                 : };
      75                 : 
      76                 : /**
      77                 :  * INVARIANTS OF THIS CLASS
      78                 :  * - mChannel is non-null between asyncOpen and onStopRequest (NOTE: Only needs
      79                 :  *   to be valid until onStopRequest is called on mFinalListener, not
      80                 :  *   necessarily until the channel calls onStopRequest on us)
      81                 :  * - mChannel corresponds to the channel that gets passed to the
      82                 :  *   nsIRequestObserver/nsIStreamListener methods
      83                 :  * - mChannel can be cancelled and ODA calls will stop
      84                 :  * - mFinalListener is non-null (only) after onStartRequest has been called on
      85                 :  *   it and before onStopRequest has been called on it
      86                 :  *   (i.e. calling onStopRequest doesn't violate the nsIRequestObserver
      87                 :  *   contract)
      88                 :  * - mFrameLoader is null while this node is not in a document (XXX this
      89                 :  *   invariant only exists due to nsFrameLoader suckage and needs to go away)
      90                 :  * - mInstantiating is true while in LoadObject (it may be true in other
      91                 :  *   cases as well). Only the function that set mInstantiating should trigger
      92                 :  *   frame construction or notifications like ContentStatesChanged or flushes.
      93                 :  */
      94                 : class nsObjectLoadingContent : public nsImageLoadingContent
      95                 :                              , public nsIStreamListener
      96                 :                              , public nsIFrameLoaderOwner
      97                 :                              , public nsIObjectLoadingContent
      98                 :                              , public nsIInterfaceRequestor
      99                 :                              , public nsIChannelEventSink
     100                 : {
     101                 :   friend class AutoNotifier;
     102                 :   friend class AutoFallback;
     103                 :   friend class AutoSetInstantiatingToFalse;
     104                 :   friend class nsStopPluginRunnable;
     105                 :   friend class nsAsyncInstantiateEvent;
     106                 : 
     107                 :   public:
     108                 :     // This enum's values must be the same as the constants on
     109                 :     // nsIObjectLoadingContent
     110                 :     enum ObjectType {
     111                 :       eType_Loading  = TYPE_LOADING,  ///< Type not yet known
     112                 :       eType_Image    = TYPE_IMAGE,    ///< This content is an image
     113                 :       eType_Plugin   = TYPE_PLUGIN,   ///< This content is a plugin
     114                 :       eType_Document = TYPE_DOCUMENT, ///< This is a document type (e.g. HTML)
     115                 :       eType_Null     = TYPE_NULL      ///< Type can't be handled
     116                 :     };
     117                 : 
     118                 :     nsObjectLoadingContent();
     119                 :     virtual ~nsObjectLoadingContent();
     120                 : 
     121                 :     NS_DECL_NSIREQUESTOBSERVER
     122                 :     NS_DECL_NSISTREAMLISTENER
     123                 :     NS_DECL_NSIFRAMELOADEROWNER
     124                 :     NS_DECL_NSIOBJECTLOADINGCONTENT
     125                 :     NS_DECL_NSIINTERFACEREQUESTOR
     126                 :     NS_DECL_NSICHANNELEVENTSINK
     127                 : 
     128                 : #ifdef HAVE_CPP_AMBIGUITY_RESOLVING_USING
     129                 :     // Fix gcc compile warnings
     130                 :     using nsImageLoadingContent::OnStartRequest;
     131                 :     using nsImageLoadingContent::OnDataAvailable;
     132                 :     using nsImageLoadingContent::OnStopRequest;
     133                 : #endif
     134                 : 
     135               0 :     ObjectType Type() { return mType; }
     136                 : 
     137                 :     /**
     138                 :      * Object state. This is a bitmask consisting of a subset of
     139                 :      * NS_EVENT_STATE_BROKEN, NS_EVENT_STATE_USERDISABLED and
     140                 :      * NS_EVENT_STATE_SUPPRESSED representing the current state of the object.
     141                 :      */
     142                 :     nsEventStates ObjectState() const;
     143                 : 
     144               0 :     void SetIsNetworkCreated(bool aNetworkCreated)
     145                 :     {
     146               0 :       mNetworkCreated = aNetworkCreated;
     147               0 :     }
     148                 : 
     149                 :     // Can flush layout.
     150                 :     nsresult InstantiatePluginInstance(const char* aMimeType, nsIURI* aURI);
     151                 : 
     152                 :     void NotifyOwnerDocumentActivityChanged();
     153                 : 
     154               0 :     bool SrcStreamLoading() { return mSrcStreamLoading; };
     155                 : 
     156                 :   protected:
     157                 :     /**
     158                 :      * Load the object from the given URI.
     159                 :      * @param aURI       The URI to load.
     160                 :      * @param aNotify If true, nsIDocumentObserver state change notifications
     161                 :      *                will be sent as needed.
     162                 :      * @param aTypeHint  MIME Type hint. Overridden by the server unless this
     163                 :      *                   class has the eOverrideServerType capability.
     164                 :      * @param aForceLoad If true, the object will be refetched even if the URI
     165                 :      *                   is the same as the currently-loaded object.
     166                 :      * @note Prefer the nsIURI-taking version of this function if a URI object
     167                 :      *       is already available.
     168                 :      * @see the URI-taking version of this function for a detailed description
     169                 :      *      of how a plugin will be found.
     170                 :      */
     171                 :     nsresult LoadObject(const nsAString& aURI,
     172                 :                         bool aNotify,
     173                 :                         const nsCString& aTypeHint = EmptyCString(),
     174                 :                         bool aForceLoad = false);
     175                 :     /**
     176                 :      * Loads the object from the given URI.
     177                 :      *
     178                 :      * The URI and type can both be null; if the URI is null a plugin will be
     179                 :      * instantiated in the hope that there is a <param> with a useful URI
     180                 :      * somewhere around. Other attributes of |this| QI'd to nsIContent will be
     181                 :      * inspected. This function attempts hard to find a suitable plugin.
     182                 :      *
     183                 :      * The instantiated plugin depends on three values:
     184                 :      * - The passed-in URI
     185                 :      * - The passed-in type hint
     186                 :      * - The classid attribute, if eSupportClassID is among the capabilities
     187                 :      *   and such an attribute is present..
     188                 :      *
     189                 :      * Supported class ID attributes override any other value.
     190                 :      *
     191                 :      * If no class ID is present and aForceType is true, the handler given by
     192                 :      * aTypeHint will be instantiated for this content.
     193                 :      * If the URI is null or not supported, and a type hint is given, the plugin
     194                 :      * corresponding to that type is instantiated.
     195                 :      *
     196                 :      * Otherwise a request to that URI is made and the type sent by the server
     197                 :      * is used to find a suitable handler.
     198                 :      *
     199                 :      * @param aForceLoad If true, the object will be refetched even if the URI
     200                 :      *                   is the same as the currently-loaded object.
     201                 :      */
     202                 :     nsresult LoadObject(nsIURI* aURI,
     203                 :                         bool aNotify,
     204                 :                         const nsCString& aTypeHint = EmptyCString(),
     205                 :                         bool aForceLoad = false);
     206                 : 
     207                 :     enum Capabilities {
     208                 :       eSupportImages    = PR_BIT(0), // Images are supported (imgILoader)
     209                 :       eSupportPlugins   = PR_BIT(1), // Plugins are supported (nsIPluginHost)
     210                 :       eSupportDocuments = PR_BIT(2), // Documents are supported
     211                 :                                      // (nsIDocumentLoaderFactory)
     212                 :                                      // This flag always includes SVG
     213                 :       eSupportSVG       = PR_BIT(3), // SVG is supported (image/svg+xml)
     214                 :       eSupportClassID   = PR_BIT(4), // The classid attribute is supported
     215                 :       eOverrideServerType = PR_BIT(5) // The server-sent MIME type is ignored
     216                 :                                       // (ignored if no type is specified)
     217                 :     };
     218                 : 
     219                 :     /**
     220                 :      * Returns the list of capabilities this content node supports. This is a
     221                 :      * bitmask consisting of flags from the Capabilities enum.
     222                 :      *
     223                 :      * The default implementation supports all types but no classids.
     224                 :      */
     225                 :     virtual PRUint32 GetCapabilities() const;
     226                 : 
     227                 :     /**
     228                 :      * Fall back to rendering the alternative content.
     229                 :      */
     230                 :     void Fallback(bool aNotify);
     231                 : 
     232                 :     /**
     233                 :      * Subclasses must call this function when they are removed from the
     234                 :      * document.
     235                 :      *
     236                 :      * XXX This is a temporary workaround for docshell suckyness
     237                 :      */
     238                 :     void RemovedFromDocument();
     239                 : 
     240                 :     static void Traverse(nsObjectLoadingContent *tmp,
     241                 :                          nsCycleCollectionTraversalCallback &cb);
     242                 : 
     243                 :     void CreateStaticClone(nsObjectLoadingContent* aDest) const;
     244                 : 
     245                 :     void DoStopPlugin(nsPluginInstanceOwner* aInstanceOwner, bool aDelayedStop,
     246                 :                       bool aForcedReentry = false);
     247                 : 
     248                 :   private:
     249                 : 
     250                 :     void NotifyContentObjectWrapper();
     251                 : 
     252                 :     /**
     253                 :      * Check whether the given request represents a successful load.
     254                 :      */
     255                 :     static bool IsSuccessfulRequest(nsIRequest* aRequest);
     256                 : 
     257                 :     /**
     258                 :      * Check whether the URI can be handled internally.
     259                 :      */
     260                 :     static bool CanHandleURI(nsIURI* aURI);
     261                 : 
     262                 :     /**
     263                 :      * Checks whether the given type is a supported document type.
     264                 :      */
     265                 :     bool IsSupportedDocument(const nsCString& aType);
     266                 : 
     267                 :     /**
     268                 :      * Unload the currently loaded content. This removes all state related to
     269                 :      * the displayed content and sets the type to eType_Null.
     270                 :      * Note: This does not send any notifications.
     271                 :      */
     272                 :     void UnloadContent();
     273                 : 
     274                 :     /**
     275                 :      * Notifies document observes about a new type/state of this object.
     276                 :      * Triggers frame construction as needed. mType must be set correctly when
     277                 :      * this method is called. This method is cheap if the type and state didn't
     278                 :      * actually change.
     279                 :      *
     280                 :      * @param aSync If a synchronous frame construction is required. If false,
     281                 :      *              the construction may either be sync or async.
     282                 :      * @param aNotify if false, only need to update the state of our element.
     283                 :      */
     284                 :     void NotifyStateChanged(ObjectType aOldType, nsEventStates aOldState,
     285                 :                             bool aSync, bool aNotify);
     286                 : 
     287                 :     /**
     288                 :      * Fires the "Plugin not found" event. This function doesn't do any checks
     289                 :      * whether it should be fired, the caller should do that.
     290                 :      */
     291                 :     static void FirePluginError(nsIContent* thisContent, PluginSupportState state);
     292                 : 
     293                 :     ObjectType GetTypeOfContent(const nsCString& aMIMEType);
     294                 : 
     295                 :     /**
     296                 :      * For a classid, returns the MIME type that can be used to instantiate
     297                 :      * a plugin for this ID.
     298                 :      *
     299                 :      * @return NS_ERROR_NOT_AVAILABLE Unsupported class ID.
     300                 :      */
     301                 :     nsresult TypeForClassID(const nsAString& aClassID, nsACString& aType);
     302                 : 
     303                 :     /**
     304                 :      * Gets the base URI to be used for this object. This differs from
     305                 :      * nsIContent::GetBaseURI in that it takes codebase attributes into
     306                 :      * account.
     307                 :      */
     308                 :     void GetObjectBaseURI(nsIContent* thisContent, nsIURI** aURI);
     309                 : 
     310                 : 
     311                 :     /**
     312                 :      * Gets the frame that's associated with this content node.
     313                 :      * Does not flush.
     314                 :      */
     315                 :     nsObjectFrame* GetExistingFrame();
     316                 : 
     317                 :     /**
     318                 :      * Handle being blocked by a content policy.  aStatus is the nsresult
     319                 :      * return value of the Should* call, while aRetval is what it returned in
     320                 :      * its out parameter.
     321                 :      */
     322                 :     void HandleBeingBlockedByContentPolicy(nsresult aStatus,
     323                 :                                            PRInt16 aRetval);
     324                 : 
     325                 :     /**
     326                 :      * Get the plugin support state for the given content node and MIME type.
     327                 :      * This is used for purposes of determining whether to fire PluginNotFound
     328                 :      * events etc.  aContentType is the MIME type we ended up with.
     329                 :      *
     330                 :      * This should only be called if the type of this content is eType_Null.
     331                 :      */
     332                 :     PluginSupportState GetPluginSupportState(nsIContent* aContent, const nsCString& aContentType);
     333                 : 
     334                 :     /**
     335                 :      * If the plugin for aContentType is disabled, return ePluginDisabled.
     336                 :      * Otherwise (including if there is no plugin for aContentType at all),
     337                 :      * return ePluginUnsupported.
     338                 :      *
     339                 :      * This should only be called if the type of this content is eType_Null.
     340                 :      */
     341                 :     PluginSupportState GetPluginDisabledState(const nsCString& aContentType);
     342                 : 
     343                 :     /**
     344                 :      * When there is no usable plugin available this will send UI events and
     345                 :      * update the AutoFallback object appropriate to the reason for there being
     346                 :      * no plugin available.
     347                 :      */
     348                 :     void UpdateFallbackState(nsIContent* aContent, AutoFallback& fallback, const nsCString& aTypeHint);
     349                 : 
     350                 :     nsresult IsPluginEnabledForType(const nsCString& aMIMEType);
     351                 :     bool IsPluginEnabledByExtension(nsIURI* uri, nsCString& mimeType);
     352                 : 
     353                 :     /**
     354                 :      * The final listener to ship the data to (imagelib, uriloader, etc)
     355                 :      */
     356                 :     nsCOMPtr<nsIStreamListener> mFinalListener;
     357                 : 
     358                 :     /**
     359                 :      * Frame loader, for content documents we load.
     360                 :      */
     361                 :     nsRefPtr<nsFrameLoader>     mFrameLoader;
     362                 : 
     363                 :     /**
     364                 :      * A pending nsAsyncInstantiateEvent (may be null).  This is a weak ref.
     365                 :      */
     366                 :     nsIRunnable                *mPendingInstantiateEvent;
     367                 : 
     368                 :     /**
     369                 :      * The content type of the resource we were last asked to load.
     370                 :      */
     371                 :     nsCString                   mContentType;
     372                 : 
     373                 :     /**
     374                 :      * The channel that's currently being loaded. This is a weak reference.
     375                 :      * Non-null between asyncOpen and onStopRequest.
     376                 :      */
     377                 :     nsIChannel*                 mChannel;
     378                 : 
     379                 :     // The data we were last asked to load
     380                 :     nsCOMPtr<nsIURI>            mURI;
     381                 : 
     382                 :     /**
     383                 :      * Type of the currently-loaded content.
     384                 :      */
     385                 :     ObjectType                  mType          : 16;
     386                 : 
     387                 :     /**
     388                 :      * Whether we are about to call instantiate on our frame. If we aren't,
     389                 :      * SetFrame needs to asynchronously call Instantiate.
     390                 :      */
     391                 :     bool                        mInstantiating : 1;
     392                 :     // Blocking status from content policy
     393                 :     bool                        mUserDisabled  : 1;
     394                 :     bool                        mSuppressed    : 1;
     395                 : 
     396                 :     // True when the object is created for an element which the parser has
     397                 :     // created using NS_FROM_PARSER_NETWORK flag. If the element is modified,
     398                 :     // it may lose the flag.
     399                 :     bool                        mNetworkCreated : 1;
     400                 : 
     401                 :     // Used to keep track of whether or not a plugin should be played.
     402                 :     // This is used for click-to-play plugins.
     403                 :     bool                        mShouldPlay : 1;
     404                 : 
     405                 :     // Protects DoStopPlugin from reentry (bug 724781).
     406                 :     bool                        mIsStopping : 1;
     407                 : 
     408                 :     // Used to track when we might try to instantiate a plugin instance based on
     409                 :     // a src data stream being delivered to this object. When this is true we don't
     410                 :     // want plugin instance instantiation code to attempt to load src data again or
     411                 :     // we'll deliver duplicate streams. Should be cleared when we are not loading
     412                 :     // src data.
     413                 :     bool mSrcStreamLoading;
     414                 : 
     415                 :     // A specific state that caused us to fallback
     416                 :     PluginSupportState          mFallbackReason;
     417                 : 
     418                 :     nsWeakFrame                 mPrintFrame;
     419                 : 
     420                 :     nsRefPtr<nsPluginInstanceOwner> mInstanceOwner;
     421                 : };
     422                 : 
     423                 : #endif

Generated by: LCOV version 1.7