Commit 97c6f75e authored by Jared Wein's avatar Jared Wein
Browse files

Bug 730318 - Implement a way for chrome js to enumerate the plugin objects on...

Bug 730318 - Implement a way for chrome js to enumerate the plugin objects on a page for activation. r=khuey
parent b7fa0f7a
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -111,6 +111,7 @@ class imgIRequest;
class nsISHEntry;
class nsDOMNavigationTiming;
class nsWindowSizes;
class nsIObjectLoadingContent;

namespace mozilla {
namespace css {
@@ -1566,6 +1567,10 @@ public:
  // state is unlocked/false.
  virtual nsresult SetImageLockingState(bool aLocked) = 0;

  virtual nsresult AddPlugin(nsIObjectLoadingContent* aPlugin) = 0;
  virtual void RemovePlugin(nsIObjectLoadingContent* aPlugin) = 0;
  virtual void GetPlugins(nsTArray<nsIObjectLoadingContent*>& aPlugins) = 0;

  virtual nsresult GetStateObject(nsIVariant** aResult) = 0;

  virtual nsDOMNavigationTiming* GetNavigationTiming() const = 0;
+7 −1
Original line number Diff line number Diff line
@@ -52,7 +52,7 @@ interface nsIURI;
/**
 * This interface represents a content node that loads objects.
 */
[scriptable, uuid(3FF07AB3-5BAC-4D98-9549-5BD15CCEBCD3)]
[scriptable, uuid(fd56fda8-d3c3-4368-8cf3-67dbc992aec9)]
interface nsIObjectLoadingContent : nsISupports
{
  const unsigned long TYPE_LOADING  = 0;
@@ -125,6 +125,12 @@ interface nsIObjectLoadingContent : nsISupports
   */
  void playPlugin();

  /**
   * This attribute will return true if the plugin has been activated
   * and false if the plugin is still in the click-to-play state.
   */
  readonly attribute boolean activated;

  [noscript] void stopPluginInstance();

  [noscript] void syncStartPluginInstance();
+49 −1
Original line number Diff line number Diff line
@@ -1673,6 +1673,8 @@ nsDocument::~nsDocument()
  // unlocked state, and then clear the table.
  SetImageLockingState(false);
  mImageTracker.Clear();

  mPlugins.Clear();
}

NS_IMPL_CYCLE_COLLECTION_CLASS(nsDocument)
@@ -2023,7 +2025,8 @@ nsDocument::Init()
  mScriptLoader = new nsScriptLoader(this);
  NS_ENSURE_TRUE(mScriptLoader, NS_ERROR_OUT_OF_MEMORY);

  if (!mImageTracker.Init()) {
  if (!mImageTracker.Init() ||
      !mPlugins.Init()) {
    return NS_ERROR_OUT_OF_MEMORY;
  }

@@ -8354,6 +8357,51 @@ nsDocument::RemoveImage(imgIRequest* aImage)
  return rv;
}

nsresult
nsDocument::AddPlugin(nsIObjectLoadingContent* aPlugin)
{
  MOZ_ASSERT(aPlugin);
  if (!mPlugins.PutEntry(aPlugin)) {
    return NS_ERROR_OUT_OF_MEMORY;
  }
  return NS_OK;
}

void
nsDocument::RemovePlugin(nsIObjectLoadingContent* aPlugin)
{
  MOZ_ASSERT(aPlugin);
  mPlugins.RemoveEntry(aPlugin);
}

static bool
AllSubDocumentPluginEnum(nsIDocument* aDocument, void* userArg)
{
  nsTArray<nsIObjectLoadingContent*>* plugins =
    reinterpret_cast< nsTArray<nsIObjectLoadingContent*>* >(userArg);
  MOZ_ASSERT(plugins);
  aDocument->GetPlugins(*plugins);
  return true;
}

static PLDHashOperator
AllPluginEnum(nsPtrHashKey<nsIObjectLoadingContent>* aPlugin, void* userArg)
{
  nsTArray<nsIObjectLoadingContent*>* allPlugins =
    reinterpret_cast< nsTArray<nsIObjectLoadingContent*>* >(userArg);
  MOZ_ASSERT(allPlugins);
  allPlugins->AppendElement(aPlugin->GetKey());
  return PL_DHASH_NEXT;
}

void
nsDocument::GetPlugins(nsTArray<nsIObjectLoadingContent*>& aPlugins)
{
  aPlugins.SetCapacity(aPlugins.Length() + mPlugins.Count());
  mPlugins.EnumerateEntries(AllPluginEnum, &aPlugins);
  EnumerateSubDocuments(AllSubDocumentPluginEnum, &aPlugins);
}

PLDHashOperator LockEnumerator(imgIRequest* aKey,
                               PRUint32 aData,
                               void*    userArg)
+13 −0
Original line number Diff line number Diff line
@@ -934,6 +934,16 @@ public:
  virtual NS_HIDDEN_(nsresult) RemoveImage(imgIRequest* aImage);
  virtual NS_HIDDEN_(nsresult) SetImageLockingState(bool aLocked);

  // AddPlugin adds a plugin-related element to mPlugins when the element is
  // added to the tree.
  virtual nsresult AddPlugin(nsIObjectLoadingContent* aPlugin);
  // RemovePlugin removes a plugin-related element to mPlugins when the
  // element is removed from the tree.
  virtual void RemovePlugin(nsIObjectLoadingContent* aPlugin);
  // GetPlugins returns the plugin-related elements from
  // the frame and any subframes.
  virtual void GetPlugins(nsTArray<nsIObjectLoadingContent*>& aPlugins);

  virtual nsresult GetStateObject(nsIVariant** aResult);

  virtual nsDOMNavigationTiming* GetNavigationTiming() const;
@@ -1298,6 +1308,9 @@ private:
  // Tracking for images in the document.
  nsDataHashtable< nsPtrHashKey<imgIRequest>, PRUint32> mImageTracker;

  // Tracking for plugins in the document.
  nsTHashtable< nsPtrHashKey<nsIObjectLoadingContent> > mPlugins;

  VisibilityState mVisibilityState;

#ifdef DEBUG
+44 −2
Original line number Diff line number Diff line
@@ -115,6 +115,18 @@ static PRLogModuleInfo* gObjectLog = PR_NewLogModule("objlc");

#include "mozilla/Preferences.h"

static bool gClickToPlayPlugins = false;

static void
InitPrefCache()
{
  static bool initializedPrefCache = false;
  if (!initializedPrefCache) {
    mozilla::Preferences::AddBoolVarCache(&gClickToPlayPlugins, "plugins.click_to_play");
  }
  initializedPrefCache = true;
}

class nsAsyncInstantiateEvent : public nsRunnable {
public:
  nsObjectLoadingContent *mContent;
@@ -546,6 +558,25 @@ bool nsObjectLoadingContent::IsPluginEnabledByExtension(nsIURI* uri, nsCString&
  return false;
}

nsresult
nsObjectLoadingContent::BindToTree(nsIDocument* aDocument, nsIContent* /*aParent*/,
                                   nsIContent* /*aBindingParent*/,
                                   bool /*aCompileEventHandlers*/)
{
  if (aDocument)
    return aDocument->AddPlugin(this);
  return NS_OK;
}

void
nsObjectLoadingContent::UnbindFromTree(bool /*aDeep*/, bool /*aNullParent*/)
{
  nsCOMPtr<nsIContent> thisContent = do_QueryInterface(static_cast<nsIObjectLoadingContent*>(this));
  MOZ_ASSERT(thisContent);
  nsIDocument* ownerDoc = thisContent->OwnerDoc();
  ownerDoc->RemovePlugin(this);
}

nsObjectLoadingContent::nsObjectLoadingContent()
  : mPendingInstantiateEvent(nsnull)
  , mChannel(nsnull)
@@ -554,11 +585,14 @@ nsObjectLoadingContent::nsObjectLoadingContent()
  , mUserDisabled(false)
  , mSuppressed(false)
  , mNetworkCreated(true)
  // If plugins.click_to_play is false, plugins should always play
  , mShouldPlay(!mozilla::Preferences::GetBool("plugins.click_to_play", false))
  , mSrcStreamLoading(false)
  , mFallbackReason(ePluginOtherState)
{
  InitPrefCache();
  // If plugins.click_to_play is false, plugins should always play
  mShouldPlay = !gClickToPlayPlugins;
  // If plugins.click_to_play is true, track the activated state of plugins.
  mActivated = !gClickToPlayPlugins;
}

nsObjectLoadingContent::~nsObjectLoadingContent()
@@ -2205,5 +2239,13 @@ nsObjectLoadingContent::PlayPlugin()
    return NS_OK;

  mShouldPlay = true;
  mActivated = true;
  return LoadObject(mURI, true, mContentType, true);
}

NS_IMETHODIMP
nsObjectLoadingContent::GetActivated(bool* aActivated)
{
  *aActivated = mActivated;
  return NS_OK;
}
Loading