2007-03-22 10:30:00 -07:00
|
|
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
|
|
|
*
|
2012-05-21 04:12:37 -07:00
|
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
#include "imgRequestProxy.h"
|
|
|
|
|
|
|
|
#include "nsIInputStream.h"
|
|
|
|
#include "nsIComponentManager.h"
|
|
|
|
#include "nsIServiceManager.h"
|
|
|
|
#include "nsIMultiPartChannel.h"
|
|
|
|
|
|
|
|
#include "nsString.h"
|
|
|
|
#include "nsXPIDLString.h"
|
|
|
|
#include "nsReadableUtils.h"
|
|
|
|
#include "nsCRT.h"
|
|
|
|
|
2010-08-13 21:09:48 -07:00
|
|
|
#include "Image.h"
|
2007-03-22 10:30:00 -07:00
|
|
|
#include "ImageErrors.h"
|
|
|
|
#include "ImageLogging.h"
|
|
|
|
|
|
|
|
#include "nspr.h"
|
|
|
|
|
2012-01-06 08:02:27 -08:00
|
|
|
using namespace mozilla::image;
|
2010-08-13 21:09:48 -07:00
|
|
|
|
2011-06-09 14:11:57 -07:00
|
|
|
NS_IMPL_ADDREF(imgRequestProxy)
|
|
|
|
NS_IMPL_RELEASE(imgRequestProxy)
|
|
|
|
|
|
|
|
NS_INTERFACE_MAP_BEGIN(imgRequestProxy)
|
|
|
|
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, imgIRequest)
|
|
|
|
NS_INTERFACE_MAP_ENTRY(imgIRequest)
|
|
|
|
NS_INTERFACE_MAP_ENTRY(nsIRequest)
|
|
|
|
NS_INTERFACE_MAP_ENTRY(nsISupportsPriority)
|
|
|
|
NS_INTERFACE_MAP_ENTRY(nsISecurityInfoProvider)
|
2012-07-30 07:20:58 -07:00
|
|
|
NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsITimedChannel, TimedChannel() != nullptr)
|
2011-06-09 14:11:57 -07:00
|
|
|
NS_INTERFACE_MAP_END
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
imgRequestProxy::imgRequestProxy() :
|
2012-07-30 07:20:58 -07:00
|
|
|
mOwner(nullptr),
|
|
|
|
mURI(nullptr),
|
|
|
|
mImage(nullptr),
|
|
|
|
mPrincipal(nullptr),
|
|
|
|
mListener(nullptr),
|
2007-03-22 10:30:00 -07:00
|
|
|
mLoadFlags(nsIRequest::LOAD_NORMAL),
|
2010-08-25 23:21:34 -07:00
|
|
|
mLockCount(0),
|
2010-09-07 17:33:02 -07:00
|
|
|
mAnimationConsumers(0),
|
2011-10-17 07:59:28 -07:00
|
|
|
mCanceled(false),
|
|
|
|
mIsInLoadGroup(false),
|
|
|
|
mListenerIsStrongRef(false),
|
|
|
|
mDecodeRequested(false),
|
|
|
|
mDeferNotifications(false),
|
|
|
|
mSentStartContainer(false)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
/* member initializers and constructor code */
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
imgRequestProxy::~imgRequestProxy()
|
|
|
|
{
|
|
|
|
/* destructor code */
|
|
|
|
NS_PRECONDITION(!mListener, "Someone forgot to properly cancel this request!");
|
2008-12-19 14:35:50 -08:00
|
|
|
|
2009-09-15 17:33:14 -07:00
|
|
|
// Unlock the image the proper number of times if we're holding locks on it.
|
2010-08-25 23:21:34 -07:00
|
|
|
// Note that UnlockImage() decrements mLockCount each time it's called.
|
|
|
|
while (mLockCount)
|
2010-05-14 13:47:59 -07:00
|
|
|
UnlockImage();
|
2009-09-12 15:44:18 -07:00
|
|
|
|
2010-09-07 17:33:02 -07:00
|
|
|
ClearAnimationConsumers();
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
// Explicitly set mListener to null to ensure that the RemoveProxy
|
|
|
|
// call below can't send |this| to an arbitrary listener while |this|
|
2008-03-19 12:07:59 -07:00
|
|
|
// is being destroyed. This is all belt-and-suspenders in view of the
|
|
|
|
// above assert.
|
|
|
|
NullOutListener();
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
if (mOwner) {
|
|
|
|
if (!mCanceled) {
|
2011-10-17 07:59:28 -07:00
|
|
|
mCanceled = true;
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
/* Call RemoveProxy with a successful status. This will keep the
|
|
|
|
channel, if still downloading data, from being canceled if 'this' is
|
|
|
|
the last observer. This allows the image to continue to download and
|
|
|
|
be cached even if no one is using it currently.
|
|
|
|
|
|
|
|
Passing false to aNotify means that we will still get
|
|
|
|
OnStopRequest, if needed.
|
|
|
|
*/
|
2011-10-17 07:59:28 -07:00
|
|
|
mOwner->RemoveProxy(this, NS_OK, false);
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-08-13 21:09:48 -07:00
|
|
|
nsresult imgRequestProxy::Init(imgRequest* request, nsILoadGroup* aLoadGroup, Image* aImage,
|
2010-05-14 13:47:59 -07:00
|
|
|
nsIURI* aURI, imgIDecoderObserver* aObserver)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
2007-09-22 12:40:57 -07:00
|
|
|
NS_PRECONDITION(!mOwner && !mListener, "imgRequestProxy is already initialized");
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
LOG_SCOPE_WITH_PARAM(gImgLog, "imgRequestProxy::Init", "request", request);
|
|
|
|
|
2010-09-07 17:33:02 -07:00
|
|
|
NS_ABORT_IF_FALSE(mAnimationConsumers == 0, "Cannot have animation before Init");
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
mOwner = request;
|
|
|
|
mListener = aObserver;
|
2008-03-19 12:07:59 -07:00
|
|
|
// Make sure to addref mListener before the AddProxy call below, since
|
|
|
|
// that call might well want to release it if the imgRequest has
|
|
|
|
// already seen OnStopRequest.
|
|
|
|
if (mListener) {
|
2011-10-17 07:59:28 -07:00
|
|
|
mListenerIsStrongRef = true;
|
2008-03-19 12:07:59 -07:00
|
|
|
NS_ADDREF(mListener);
|
|
|
|
}
|
2007-03-22 10:30:00 -07:00
|
|
|
mLoadGroup = aLoadGroup;
|
2010-05-14 13:47:59 -07:00
|
|
|
mImage = aImage;
|
2010-05-10 20:27:41 -07:00
|
|
|
mURI = aURI;
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2009-01-11 00:06:41 -08:00
|
|
|
// Note: AddProxy won't send all the On* notifications immediately
|
2010-05-14 13:47:59 -07:00
|
|
|
if (mOwner)
|
|
|
|
mOwner->AddProxy(this);
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult imgRequestProxy::ChangeOwner(imgRequest *aNewOwner)
|
|
|
|
{
|
2010-05-10 20:27:41 -07:00
|
|
|
NS_PRECONDITION(mOwner, "Cannot ChangeOwner on a proxy without an owner!");
|
|
|
|
|
2010-05-14 13:47:59 -07:00
|
|
|
// If we're holding locks, unlock the old image.
|
2010-08-25 23:21:34 -07:00
|
|
|
// Note that UnlockImage decrements mLockCount each time it's called.
|
|
|
|
PRUint32 oldLockCount = mLockCount;
|
|
|
|
while (mLockCount)
|
2010-05-14 13:47:59 -07:00
|
|
|
UnlockImage();
|
|
|
|
|
2010-09-07 17:33:02 -07:00
|
|
|
// If we're holding animation requests, undo them.
|
|
|
|
PRUint32 oldAnimationConsumers = mAnimationConsumers;
|
|
|
|
ClearAnimationConsumers();
|
|
|
|
|
2010-05-14 13:47:59 -07:00
|
|
|
// Even if we are cancelled, we MUST change our image, because the image
|
|
|
|
// holds our status, and the status must always be correct.
|
|
|
|
mImage = aNewOwner->mImage;
|
|
|
|
|
|
|
|
// If we were locked, apply the locks here
|
|
|
|
for (PRUint32 i = 0; i < oldLockCount; i++)
|
|
|
|
LockImage();
|
|
|
|
|
2011-01-26 10:52:42 -08:00
|
|
|
if (mCanceled) {
|
|
|
|
// If we had animation requests, restore them before exiting
|
|
|
|
// (otherwise we restore them later below)
|
|
|
|
for (PRUint32 i = 0; i < oldAnimationConsumers; i++)
|
|
|
|
IncrementAnimationConsumers();
|
2010-09-07 17:33:02 -07:00
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
return NS_OK;
|
2011-01-26 10:52:42 -08:00
|
|
|
}
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2009-09-12 15:44:18 -07:00
|
|
|
// Were we decoded before?
|
2011-09-28 23:19:26 -07:00
|
|
|
bool wasDecoded = false;
|
2010-08-23 15:44:07 -07:00
|
|
|
if (mImage &&
|
|
|
|
(mImage->GetStatusTracker().GetImageStatus() &
|
|
|
|
imgIRequest::STATUS_FRAME_COMPLETE)) {
|
2011-10-17 07:59:28 -07:00
|
|
|
wasDecoded = true;
|
2010-08-23 15:44:07 -07:00
|
|
|
}
|
2009-09-12 15:44:18 -07:00
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
// Passing false to aNotify means that mListener will still get
|
|
|
|
// OnStopRequest, if needed.
|
2011-10-17 07:59:28 -07:00
|
|
|
mOwner->RemoveProxy(this, NS_IMAGELIB_CHANGING_OWNER, false);
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2011-01-26 10:52:42 -08:00
|
|
|
// If we had animation requests, restore them here. Note that we
|
|
|
|
// do this *after* RemoveProxy, which clears out animation consumers
|
|
|
|
// (see bug 601723).
|
|
|
|
for (PRUint32 i = 0; i < oldAnimationConsumers; i++)
|
|
|
|
IncrementAnimationConsumers();
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
mOwner = aNewOwner;
|
|
|
|
|
2007-09-22 12:40:57 -07:00
|
|
|
mOwner->AddProxy(this);
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2009-09-15 17:33:14 -07:00
|
|
|
// If we were decoded, or if we'd previously requested a decode, request a
|
|
|
|
// decode on the new image
|
|
|
|
if (wasDecoded || mDecodeRequested)
|
|
|
|
mOwner->RequestDecode();
|
2009-09-12 15:44:18 -07:00
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
void imgRequestProxy::AddToLoadGroup()
|
|
|
|
{
|
|
|
|
NS_ASSERTION(!mIsInLoadGroup, "Whaa, we're already in the loadgroup!");
|
|
|
|
|
|
|
|
if (!mIsInLoadGroup && mLoadGroup) {
|
2012-07-30 07:20:58 -07:00
|
|
|
mLoadGroup->AddRequest(this, nullptr);
|
2011-10-17 07:59:28 -07:00
|
|
|
mIsInLoadGroup = true;
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-09-28 23:19:26 -07:00
|
|
|
void imgRequestProxy::RemoveFromLoadGroup(bool releaseLoadGroup)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
if (!mIsInLoadGroup)
|
|
|
|
return;
|
|
|
|
|
|
|
|
/* calling RemoveFromLoadGroup may cause the document to finish
|
|
|
|
loading, which could result in our death. We need to make sure
|
|
|
|
that we stay alive long enough to fight another battle... at
|
|
|
|
least until we exit this function.
|
|
|
|
*/
|
|
|
|
nsCOMPtr<imgIRequest> kungFuDeathGrip(this);
|
|
|
|
|
2012-07-30 07:20:58 -07:00
|
|
|
mLoadGroup->RemoveRequest(this, nullptr, NS_OK);
|
2011-10-17 07:59:28 -07:00
|
|
|
mIsInLoadGroup = false;
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
if (releaseLoadGroup) {
|
|
|
|
// We're done with the loadgroup, release it.
|
2012-07-30 07:20:58 -07:00
|
|
|
mLoadGroup = nullptr;
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/** nsIRequest / imgIRequest methods **/
|
|
|
|
|
|
|
|
/* readonly attribute wstring name; */
|
|
|
|
NS_IMETHODIMP imgRequestProxy::GetName(nsACString &aName)
|
|
|
|
{
|
|
|
|
aName.Truncate();
|
2010-05-10 20:27:41 -07:00
|
|
|
|
|
|
|
if (mURI)
|
|
|
|
mURI->GetSpec(aName);
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* boolean isPending (); */
|
2011-09-28 23:19:26 -07:00
|
|
|
NS_IMETHODIMP imgRequestProxy::IsPending(bool *_retval)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* readonly attribute nsresult status; */
|
|
|
|
NS_IMETHODIMP imgRequestProxy::GetStatus(nsresult *aStatus)
|
|
|
|
{
|
2009-01-30 11:13:52 -08:00
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
/* void cancel (in nsresult status); */
|
|
|
|
NS_IMETHODIMP imgRequestProxy::Cancel(nsresult status)
|
|
|
|
{
|
2010-05-14 13:47:59 -07:00
|
|
|
if (mCanceled)
|
2007-03-22 10:30:00 -07:00
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
LOG_SCOPE(gImgLog, "imgRequestProxy::Cancel");
|
|
|
|
|
2011-10-17 07:59:28 -07:00
|
|
|
mCanceled = true;
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2008-12-19 14:35:50 -08:00
|
|
|
nsCOMPtr<nsIRunnable> ev = new imgCancelRunnable(this, status);
|
|
|
|
return NS_DispatchToCurrentThread(ev);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
imgRequestProxy::DoCancel(nsresult status)
|
|
|
|
{
|
2007-03-22 10:30:00 -07:00
|
|
|
// Passing false to aNotify means that mListener will still get
|
|
|
|
// OnStopRequest, if needed.
|
2010-05-14 13:47:59 -07:00
|
|
|
if (mOwner)
|
2011-10-17 07:59:28 -07:00
|
|
|
mOwner->RemoveProxy(this, status, false);
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2008-03-19 12:07:59 -07:00
|
|
|
NullOutListener();
|
2008-12-19 14:35:50 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
/* void cancelAndForgetObserver (in nsresult aStatus); */
|
|
|
|
NS_IMETHODIMP imgRequestProxy::CancelAndForgetObserver(nsresult aStatus)
|
|
|
|
{
|
2011-10-14 13:15:56 -07:00
|
|
|
// If mCanceled is true but mListener is non-null, that means
|
|
|
|
// someone called Cancel() on us but the imgCancelRunnable is still
|
|
|
|
// pending. We still need to null out mListener before returning
|
|
|
|
// from this function in this case. That means we want to do the
|
|
|
|
// RemoveProxy call right now, because we need to deliver the
|
|
|
|
// onStopRequest.
|
|
|
|
if (mCanceled && !mListener)
|
2008-12-19 14:35:50 -08:00
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
LOG_SCOPE(gImgLog, "imgRequestProxy::CancelAndForgetObserver");
|
|
|
|
|
2011-10-17 07:59:28 -07:00
|
|
|
mCanceled = true;
|
2008-12-19 14:35:50 -08:00
|
|
|
|
2010-03-08 11:34:52 -08:00
|
|
|
// Now cheat and make sure our removal from loadgroup happens async
|
2011-09-28 23:19:26 -07:00
|
|
|
bool oldIsInLoadGroup = mIsInLoadGroup;
|
2011-10-17 07:59:28 -07:00
|
|
|
mIsInLoadGroup = false;
|
2010-05-14 13:47:59 -07:00
|
|
|
|
2008-12-19 14:35:50 -08:00
|
|
|
// Passing false to aNotify means that mListener will still get
|
|
|
|
// OnStopRequest, if needed.
|
2010-05-14 13:47:59 -07:00
|
|
|
if (mOwner)
|
2011-10-17 07:59:28 -07:00
|
|
|
mOwner->RemoveProxy(this, aStatus, false);
|
2008-12-19 14:35:50 -08:00
|
|
|
|
2010-03-08 11:34:52 -08:00
|
|
|
mIsInLoadGroup = oldIsInLoadGroup;
|
|
|
|
|
|
|
|
if (mIsInLoadGroup) {
|
|
|
|
nsCOMPtr<nsIRunnable> ev =
|
2010-04-20 16:21:35 -07:00
|
|
|
NS_NewRunnableMethod(this, &imgRequestProxy::DoRemoveFromLoadGroup);
|
2010-03-08 11:34:52 -08:00
|
|
|
NS_DispatchToCurrentThread(ev);
|
|
|
|
}
|
|
|
|
|
2008-12-19 14:35:50 -08:00
|
|
|
NullOutListener();
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2009-09-12 15:44:18 -07:00
|
|
|
/* void requestDecode (); */
|
|
|
|
NS_IMETHODIMP
|
|
|
|
imgRequestProxy::RequestDecode()
|
|
|
|
{
|
|
|
|
if (!mOwner)
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
2009-09-15 17:33:14 -07:00
|
|
|
// Flag this, so we know to transfer the request if our owner changes
|
2011-10-17 07:59:28 -07:00
|
|
|
mDecodeRequested = true;
|
2009-09-12 15:44:18 -07:00
|
|
|
|
2009-09-15 17:33:14 -07:00
|
|
|
// Forward the request
|
|
|
|
return mOwner->RequestDecode();
|
2009-09-12 15:44:18 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
/* void lockImage (); */
|
|
|
|
NS_IMETHODIMP
|
|
|
|
imgRequestProxy::LockImage()
|
|
|
|
{
|
2010-08-25 23:21:34 -07:00
|
|
|
mLockCount++;
|
|
|
|
if (mImage)
|
|
|
|
return mImage->LockImage();
|
|
|
|
return NS_OK;
|
2009-09-12 15:44:18 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
/* void unlockImage (); */
|
|
|
|
NS_IMETHODIMP
|
|
|
|
imgRequestProxy::UnlockImage()
|
|
|
|
{
|
2010-08-25 23:21:34 -07:00
|
|
|
NS_ABORT_IF_FALSE(mLockCount > 0, "calling unlock but no locks!");
|
2010-05-14 13:47:59 -07:00
|
|
|
|
2010-08-25 23:21:34 -07:00
|
|
|
mLockCount--;
|
|
|
|
if (mImage)
|
|
|
|
return mImage->UnlockImage();
|
|
|
|
return NS_OK;
|
2009-09-12 15:44:18 -07:00
|
|
|
}
|
|
|
|
|
2012-03-09 22:29:28 -08:00
|
|
|
/* void requestDiscard (); */
|
|
|
|
NS_IMETHODIMP
|
|
|
|
imgRequestProxy::RequestDiscard()
|
|
|
|
{
|
|
|
|
if (mImage) {
|
|
|
|
return mImage->RequestDiscard();
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2010-09-07 17:33:02 -07:00
|
|
|
NS_IMETHODIMP
|
|
|
|
imgRequestProxy::IncrementAnimationConsumers()
|
|
|
|
{
|
|
|
|
mAnimationConsumers++;
|
|
|
|
if (mImage)
|
|
|
|
mImage->IncrementAnimationConsumers();
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
imgRequestProxy::DecrementAnimationConsumers()
|
|
|
|
{
|
|
|
|
// We may get here if some responsible code called Increment,
|
|
|
|
// then called us, but we have meanwhile called ClearAnimationConsumers
|
|
|
|
// because we needed to get rid of them earlier (see
|
|
|
|
// imgRequest::RemoveProxy), and hence have nothing left to
|
|
|
|
// decrement. (In such a case we got rid of the animation consumers
|
|
|
|
// early, but not the observer.)
|
|
|
|
if (mAnimationConsumers > 0) {
|
|
|
|
mAnimationConsumers--;
|
|
|
|
if (mImage)
|
|
|
|
mImage->DecrementAnimationConsumers();
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
imgRequestProxy::ClearAnimationConsumers()
|
|
|
|
{
|
|
|
|
while (mAnimationConsumers > 0)
|
|
|
|
DecrementAnimationConsumers();
|
|
|
|
}
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
/* void suspend (); */
|
|
|
|
NS_IMETHODIMP imgRequestProxy::Suspend()
|
|
|
|
{
|
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* void resume (); */
|
|
|
|
NS_IMETHODIMP imgRequestProxy::Resume()
|
|
|
|
{
|
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* attribute nsILoadGroup loadGroup */
|
|
|
|
NS_IMETHODIMP imgRequestProxy::GetLoadGroup(nsILoadGroup **loadGroup)
|
|
|
|
{
|
|
|
|
NS_IF_ADDREF(*loadGroup = mLoadGroup.get());
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
NS_IMETHODIMP imgRequestProxy::SetLoadGroup(nsILoadGroup *loadGroup)
|
|
|
|
{
|
|
|
|
mLoadGroup = loadGroup;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* attribute nsLoadFlags loadFlags */
|
|
|
|
NS_IMETHODIMP imgRequestProxy::GetLoadFlags(nsLoadFlags *flags)
|
|
|
|
{
|
|
|
|
*flags = mLoadFlags;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
NS_IMETHODIMP imgRequestProxy::SetLoadFlags(nsLoadFlags flags)
|
|
|
|
{
|
|
|
|
mLoadFlags = flags;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/** imgIRequest methods **/
|
|
|
|
|
|
|
|
/* attribute imgIContainer image; */
|
|
|
|
NS_IMETHODIMP imgRequestProxy::GetImage(imgIContainer * *aImage)
|
|
|
|
{
|
2010-08-23 15:44:07 -07:00
|
|
|
// It's possible that our owner has an image but hasn't notified us of it -
|
|
|
|
// that'll happen if we get Canceled before the owner instantiates its image
|
|
|
|
// (because Canceling unregisters us as a listener on mOwner). If we're
|
|
|
|
// in that situation, just grab the image off of mOwner.
|
|
|
|
imgIContainer* imageToReturn = mImage ? mImage : mOwner->mImage;
|
|
|
|
|
|
|
|
if (!imageToReturn)
|
2007-03-22 10:30:00 -07:00
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
2010-08-23 15:44:07 -07:00
|
|
|
NS_ADDREF(*aImage = imageToReturn);
|
2010-05-10 20:27:41 -07:00
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* readonly attribute unsigned long imageStatus; */
|
|
|
|
NS_IMETHODIMP imgRequestProxy::GetImageStatus(PRUint32 *aStatus)
|
|
|
|
{
|
2010-08-23 15:44:07 -07:00
|
|
|
*aStatus = GetStatusTracker().GetImageStatus();
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* readonly attribute nsIURI URI; */
|
|
|
|
NS_IMETHODIMP imgRequestProxy::GetURI(nsIURI **aURI)
|
|
|
|
{
|
2010-05-10 20:27:41 -07:00
|
|
|
if (!mURI)
|
2007-03-22 10:30:00 -07:00
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
2010-05-10 20:27:41 -07:00
|
|
|
NS_ADDREF(*aURI = mURI);
|
|
|
|
|
|
|
|
return NS_OK;
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
/* readonly attribute imgIDecoderObserver decoderObserver; */
|
|
|
|
NS_IMETHODIMP imgRequestProxy::GetDecoderObserver(imgIDecoderObserver **aDecoderObserver)
|
|
|
|
{
|
|
|
|
*aDecoderObserver = mListener;
|
|
|
|
NS_IF_ADDREF(*aDecoderObserver);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* readonly attribute string mimeType; */
|
|
|
|
NS_IMETHODIMP imgRequestProxy::GetMimeType(char **aMimeType)
|
|
|
|
{
|
|
|
|
if (!mOwner)
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
const char *type = mOwner->GetMimeType();
|
|
|
|
if (!type)
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
2009-03-29 04:46:12 -07:00
|
|
|
*aMimeType = NS_strdup(type);
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP imgRequestProxy::Clone(imgIDecoderObserver* aObserver,
|
|
|
|
imgIRequest** aClone)
|
|
|
|
{
|
|
|
|
NS_PRECONDITION(aClone, "Null out param");
|
2010-05-14 13:47:59 -07:00
|
|
|
|
|
|
|
LOG_SCOPE(gImgLog, "imgRequestProxy::Clone");
|
|
|
|
|
2012-07-30 07:20:58 -07:00
|
|
|
*aClone = nullptr;
|
2010-05-10 20:27:41 -07:00
|
|
|
nsRefPtr<imgRequestProxy> clone = new imgRequestProxy();
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
// It is important to call |SetLoadFlags()| before calling |Init()| because
|
|
|
|
// |Init()| adds the request to the loadgroup.
|
|
|
|
// When a request is added to a loadgroup, its load flags are merged
|
|
|
|
// with the load flags of the loadgroup.
|
|
|
|
// XXXldb That's not true anymore. Stuff from imgLoader adds the
|
|
|
|
// request to the loadgroup.
|
|
|
|
clone->SetLoadFlags(mLoadFlags);
|
2010-08-23 15:44:07 -07:00
|
|
|
nsresult rv = clone->Init(mOwner, mLoadGroup,
|
|
|
|
mImage ? mImage : mOwner->mImage,
|
|
|
|
mURI, aObserver);
|
2010-05-10 20:27:41 -07:00
|
|
|
if (NS_FAILED(rv))
|
2007-03-22 10:30:00 -07:00
|
|
|
return rv;
|
|
|
|
|
2010-05-10 20:27:41 -07:00
|
|
|
clone->SetPrincipal(mPrincipal);
|
|
|
|
|
|
|
|
// Assign to *aClone before calling Notify so that if the caller expects to
|
|
|
|
// only be notified for requests it's already holding pointers to it won't be
|
|
|
|
// surprised.
|
2010-05-14 13:47:59 -07:00
|
|
|
NS_ADDREF(*aClone = clone);
|
2007-03-22 10:30:00 -07:00
|
|
|
|
2010-07-28 14:52:14 -07:00
|
|
|
// This is wrong!!! We need to notify asynchronously, but there's code that
|
|
|
|
// assumes that we don't. This will be fixed in bug 580466.
|
|
|
|
clone->SyncNotifyListener();
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2007-11-08 18:55:41 -08:00
|
|
|
/* readonly attribute nsIPrincipal imagePrincipal; */
|
|
|
|
NS_IMETHODIMP imgRequestProxy::GetImagePrincipal(nsIPrincipal **aPrincipal)
|
|
|
|
{
|
2010-05-10 20:27:41 -07:00
|
|
|
if (!mPrincipal)
|
2007-11-08 18:55:41 -08:00
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
2010-05-10 20:27:41 -07:00
|
|
|
NS_ADDREF(*aPrincipal = mPrincipal);
|
|
|
|
|
|
|
|
return NS_OK;
|
2007-11-08 18:55:41 -08:00
|
|
|
}
|
|
|
|
|
2012-05-19 12:32:37 -07:00
|
|
|
/* readonly attribute bool multipart; */
|
|
|
|
NS_IMETHODIMP imgRequestProxy::GetMultipart(bool *aMultipart)
|
|
|
|
{
|
|
|
|
if (!mOwner)
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
*aMultipart = mOwner->GetMultipart();
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2011-07-14 11:47:34 -07:00
|
|
|
/* readonly attribute PRInt32 CORSMode; */
|
|
|
|
NS_IMETHODIMP imgRequestProxy::GetCORSMode(PRInt32* aCorsMode)
|
|
|
|
{
|
|
|
|
if (!mOwner)
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
*aCorsMode = mOwner->GetCORSMode();
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
/** nsISupportsPriority methods **/
|
|
|
|
|
|
|
|
NS_IMETHODIMP imgRequestProxy::GetPriority(PRInt32 *priority)
|
|
|
|
{
|
|
|
|
NS_ENSURE_STATE(mOwner);
|
|
|
|
*priority = mOwner->Priority();
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP imgRequestProxy::SetPriority(PRInt32 priority)
|
|
|
|
{
|
|
|
|
NS_ENSURE_STATE(mOwner && !mCanceled);
|
|
|
|
mOwner->AdjustPriority(this, priority - mOwner->Priority());
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP imgRequestProxy::AdjustPriority(PRInt32 priority)
|
|
|
|
{
|
|
|
|
NS_ENSURE_STATE(mOwner && !mCanceled);
|
|
|
|
mOwner->AdjustPriority(this, priority);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2008-09-01 13:53:59 -07:00
|
|
|
/** nsISecurityInfoProvider methods **/
|
|
|
|
|
|
|
|
NS_IMETHODIMP imgRequestProxy::GetSecurityInfo(nsISupports** _retval)
|
|
|
|
{
|
|
|
|
if (mOwner)
|
|
|
|
return mOwner->GetSecurityInfo(_retval);
|
|
|
|
|
2012-07-30 07:20:58 -07:00
|
|
|
*_retval = nullptr;
|
2008-09-01 13:53:59 -07:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2011-09-28 23:19:26 -07:00
|
|
|
NS_IMETHODIMP imgRequestProxy::GetHasTransferredData(bool* hasData)
|
2009-02-16 06:11:30 -08:00
|
|
|
{
|
|
|
|
if (mOwner) {
|
|
|
|
*hasData = mOwner->HasTransferredData();
|
|
|
|
} else {
|
|
|
|
// The safe thing to do is to claim we have data
|
2011-10-17 07:59:28 -07:00
|
|
|
*hasData = true;
|
2009-02-16 06:11:30 -08:00
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
/** imgIContainerObserver methods **/
|
|
|
|
|
2010-08-13 21:09:48 -07:00
|
|
|
void imgRequestProxy::FrameChanged(imgIContainer *container,
|
|
|
|
const nsIntRect *dirtyRect)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
LOG_FUNC(gImgLog, "imgRequestProxy::FrameChanged");
|
|
|
|
|
2008-12-19 14:35:50 -08:00
|
|
|
if (mListener && !mCanceled) {
|
2007-03-22 10:30:00 -07:00
|
|
|
// Hold a ref to the listener while we call it, just in case.
|
|
|
|
nsCOMPtr<imgIDecoderObserver> kungFuDeathGrip(mListener);
|
2012-01-06 04:32:38 -08:00
|
|
|
mListener->FrameChanged(this, container, dirtyRect);
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/** imgIDecoderObserver methods **/
|
|
|
|
|
|
|
|
void imgRequestProxy::OnStartDecode()
|
|
|
|
{
|
|
|
|
LOG_FUNC(gImgLog, "imgRequestProxy::OnStartDecode");
|
|
|
|
|
2008-12-19 14:35:50 -08:00
|
|
|
if (mListener && !mCanceled) {
|
2007-03-22 10:30:00 -07:00
|
|
|
// Hold a ref to the listener while we call it, just in case.
|
|
|
|
nsCOMPtr<imgIDecoderObserver> kungFuDeathGrip(mListener);
|
|
|
|
mListener->OnStartDecode(this);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void imgRequestProxy::OnStartContainer(imgIContainer *image)
|
|
|
|
{
|
|
|
|
LOG_FUNC(gImgLog, "imgRequestProxy::OnStartContainer");
|
|
|
|
|
2010-08-12 08:59:37 -07:00
|
|
|
if (mListener && !mCanceled && !mSentStartContainer) {
|
2007-03-22 10:30:00 -07:00
|
|
|
// Hold a ref to the listener while we call it, just in case.
|
|
|
|
nsCOMPtr<imgIDecoderObserver> kungFuDeathGrip(mListener);
|
|
|
|
mListener->OnStartContainer(this, image);
|
2011-10-17 07:59:28 -07:00
|
|
|
mSentStartContainer = true;
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Bug 753 - Remove nsIImage, gfxIImageFrame, and their implementations, and expose an equivalent api on imgIContainer. r=roc,josh,bz,longsonr,vlad,karlt,jimm,bsmedberg,mfinkle,peterw,peterv sr=vlad,roc
--HG--
rename : gfx/src/shared/gfxImageFrame.cpp => modules/libpr0n/src/imgFrame.cpp
rename : gfx/src/shared/gfxImageFrame.h => modules/libpr0n/src/imgFrame.h
2009-07-20 18:50:15 -07:00
|
|
|
void imgRequestProxy::OnStartFrame(PRUint32 frame)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
LOG_FUNC(gImgLog, "imgRequestProxy::OnStartFrame");
|
|
|
|
|
2008-12-19 14:35:50 -08:00
|
|
|
if (mListener && !mCanceled) {
|
2007-03-22 10:30:00 -07:00
|
|
|
// Hold a ref to the listener while we call it, just in case.
|
|
|
|
nsCOMPtr<imgIDecoderObserver> kungFuDeathGrip(mListener);
|
|
|
|
mListener->OnStartFrame(this, frame);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-09-28 23:19:26 -07:00
|
|
|
void imgRequestProxy::OnDataAvailable(bool aCurrentFrame, const nsIntRect * rect)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
LOG_FUNC(gImgLog, "imgRequestProxy::OnDataAvailable");
|
|
|
|
|
2008-12-19 14:35:50 -08:00
|
|
|
if (mListener && !mCanceled) {
|
2007-03-22 10:30:00 -07:00
|
|
|
// Hold a ref to the listener while we call it, just in case.
|
|
|
|
nsCOMPtr<imgIDecoderObserver> kungFuDeathGrip(mListener);
|
Bug 753 - Remove nsIImage, gfxIImageFrame, and their implementations, and expose an equivalent api on imgIContainer. r=roc,josh,bz,longsonr,vlad,karlt,jimm,bsmedberg,mfinkle,peterw,peterv sr=vlad,roc
--HG--
rename : gfx/src/shared/gfxImageFrame.cpp => modules/libpr0n/src/imgFrame.cpp
rename : gfx/src/shared/gfxImageFrame.h => modules/libpr0n/src/imgFrame.h
2009-07-20 18:50:15 -07:00
|
|
|
mListener->OnDataAvailable(this, aCurrentFrame, rect);
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Bug 753 - Remove nsIImage, gfxIImageFrame, and their implementations, and expose an equivalent api on imgIContainer. r=roc,josh,bz,longsonr,vlad,karlt,jimm,bsmedberg,mfinkle,peterw,peterv sr=vlad,roc
--HG--
rename : gfx/src/shared/gfxImageFrame.cpp => modules/libpr0n/src/imgFrame.cpp
rename : gfx/src/shared/gfxImageFrame.h => modules/libpr0n/src/imgFrame.h
2009-07-20 18:50:15 -07:00
|
|
|
void imgRequestProxy::OnStopFrame(PRUint32 frame)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
LOG_FUNC(gImgLog, "imgRequestProxy::OnStopFrame");
|
|
|
|
|
2008-12-19 14:35:50 -08:00
|
|
|
if (mListener && !mCanceled) {
|
2007-03-22 10:30:00 -07:00
|
|
|
// Hold a ref to the listener while we call it, just in case.
|
|
|
|
nsCOMPtr<imgIDecoderObserver> kungFuDeathGrip(mListener);
|
|
|
|
mListener->OnStopFrame(this, frame);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void imgRequestProxy::OnStopContainer(imgIContainer *image)
|
|
|
|
{
|
|
|
|
LOG_FUNC(gImgLog, "imgRequestProxy::OnStopContainer");
|
|
|
|
|
2008-12-19 14:35:50 -08:00
|
|
|
if (mListener && !mCanceled) {
|
2007-03-22 10:30:00 -07:00
|
|
|
// Hold a ref to the listener while we call it, just in case.
|
|
|
|
nsCOMPtr<imgIDecoderObserver> kungFuDeathGrip(mListener);
|
|
|
|
mListener->OnStopContainer(this, image);
|
|
|
|
}
|
2012-05-19 12:32:37 -07:00
|
|
|
|
|
|
|
// Multipart needs reset for next OnStartContainer
|
|
|
|
if (mOwner && mOwner->GetMultipart())
|
|
|
|
mSentStartContainer = false;
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void imgRequestProxy::OnStopDecode(nsresult status, const PRUnichar *statusArg)
|
|
|
|
{
|
|
|
|
LOG_FUNC(gImgLog, "imgRequestProxy::OnStopDecode");
|
|
|
|
|
2008-12-19 14:35:50 -08:00
|
|
|
if (mListener && !mCanceled) {
|
2007-03-22 10:30:00 -07:00
|
|
|
// Hold a ref to the listener while we call it, just in case.
|
|
|
|
nsCOMPtr<imgIDecoderObserver> kungFuDeathGrip(mListener);
|
|
|
|
mListener->OnStopDecode(this, status, statusArg);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-09-12 15:44:18 -07:00
|
|
|
void imgRequestProxy::OnDiscard()
|
|
|
|
{
|
|
|
|
LOG_FUNC(gImgLog, "imgRequestProxy::OnDiscard");
|
|
|
|
|
|
|
|
if (mListener && !mCanceled) {
|
|
|
|
// Hold a ref to the listener while we call it, just in case.
|
|
|
|
nsCOMPtr<imgIDecoderObserver> kungFuDeathGrip(mListener);
|
|
|
|
mListener->OnDiscard(this);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-11-09 13:39:15 -08:00
|
|
|
void imgRequestProxy::OnImageIsAnimated()
|
|
|
|
{
|
|
|
|
LOG_FUNC(gImgLog, "imgRequestProxy::OnImageIsAnimated");
|
|
|
|
if (mListener && !mCanceled) {
|
|
|
|
// Hold a ref to the listener while we call it, just in case.
|
|
|
|
nsCOMPtr<imgIDecoderObserver> kungFuDeathGrip(mListener);
|
|
|
|
mListener->OnImageIsAnimated(this);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-05-10 20:25:11 -07:00
|
|
|
void imgRequestProxy::OnStartRequest()
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
#ifdef PR_LOGGING
|
|
|
|
nsCAutoString name;
|
|
|
|
GetName(name);
|
|
|
|
LOG_FUNC_WITH_PARAM(gImgLog, "imgRequestProxy::OnStartRequest", "name", name.get());
|
|
|
|
#endif
|
|
|
|
|
2008-12-19 14:35:50 -08:00
|
|
|
// Notify even if mCanceled, since OnStartRequest is guaranteed by the
|
|
|
|
// nsIStreamListener contract so it makes sense to do the same here.
|
2007-03-22 10:30:00 -07:00
|
|
|
if (mListener) {
|
|
|
|
// Hold a ref to the listener while we call it, just in case.
|
|
|
|
nsCOMPtr<imgIDecoderObserver> kungFuDeathGrip(mListener);
|
|
|
|
mListener->OnStartRequest(this);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-09-28 23:19:26 -07:00
|
|
|
void imgRequestProxy::OnStopRequest(bool lastPart)
|
2007-03-22 10:30:00 -07:00
|
|
|
{
|
|
|
|
#ifdef PR_LOGGING
|
|
|
|
nsCAutoString name;
|
|
|
|
GetName(name);
|
|
|
|
LOG_FUNC_WITH_PARAM(gImgLog, "imgRequestProxy::OnStopRequest", "name", name.get());
|
|
|
|
#endif
|
2008-03-20 23:13:11 -07:00
|
|
|
// There's all sorts of stuff here that could kill us (the OnStopRequest call
|
|
|
|
// on the listener, the removal from the loadgroup, the release of the
|
|
|
|
// listener, etc). Don't let them do it.
|
|
|
|
nsCOMPtr<imgIRequest> kungFuDeathGrip(this);
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
if (mListener) {
|
|
|
|
// Hold a ref to the listener while we call it, just in case.
|
|
|
|
nsCOMPtr<imgIDecoderObserver> kungFuDeathGrip(mListener);
|
|
|
|
mListener->OnStopRequest(this, lastPart);
|
|
|
|
}
|
|
|
|
|
|
|
|
// If we're expecting more data from a multipart channel, re-add ourself
|
|
|
|
// to the loadgroup so that the document doesn't lose track of the load.
|
|
|
|
// If the request is already a background request and there's more data
|
|
|
|
// coming, we can just leave the request in the loadgroup as-is.
|
|
|
|
if (lastPart || (mLoadFlags & nsIRequest::LOAD_BACKGROUND) == 0) {
|
|
|
|
RemoveFromLoadGroup(lastPart);
|
|
|
|
// More data is coming, so change the request to be a background request
|
|
|
|
// and put it back in the loadgroup.
|
|
|
|
if (!lastPart) {
|
|
|
|
mLoadFlags |= nsIRequest::LOAD_BACKGROUND;
|
|
|
|
AddToLoadGroup();
|
|
|
|
}
|
|
|
|
}
|
2008-03-19 12:07:59 -07:00
|
|
|
|
|
|
|
if (mListenerIsStrongRef) {
|
|
|
|
NS_PRECONDITION(mListener, "How did that happen?");
|
|
|
|
// Drop our strong ref to the listener now that we're done with
|
|
|
|
// everything. Note that this can cancel us and other fun things
|
|
|
|
// like that. Don't add anything in this method after this point.
|
|
|
|
imgIDecoderObserver* obs = mListener;
|
2011-10-17 07:59:28 -07:00
|
|
|
mListenerIsStrongRef = false;
|
2008-03-19 12:07:59 -07:00
|
|
|
NS_RELEASE(obs);
|
|
|
|
}
|
2007-03-22 10:30:00 -07:00
|
|
|
}
|
|
|
|
|
2008-03-19 12:07:59 -07:00
|
|
|
void imgRequestProxy::NullOutListener()
|
|
|
|
{
|
2010-09-07 17:33:02 -07:00
|
|
|
// If we have animation consumers, then they don't matter anymore
|
|
|
|
if (mListener)
|
|
|
|
ClearAnimationConsumers();
|
|
|
|
|
2008-03-19 12:07:59 -07:00
|
|
|
if (mListenerIsStrongRef) {
|
|
|
|
// Releasing could do weird reentery stuff, so just play it super-safe
|
|
|
|
nsCOMPtr<imgIDecoderObserver> obs;
|
|
|
|
obs.swap(mListener);
|
2011-10-17 07:59:28 -07:00
|
|
|
mListenerIsStrongRef = false;
|
2008-03-19 12:07:59 -07:00
|
|
|
} else {
|
2012-07-30 07:20:58 -07:00
|
|
|
mListener = nullptr;
|
2008-03-19 12:07:59 -07:00
|
|
|
}
|
|
|
|
}
|
2009-12-10 20:02:13 -08:00
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
imgRequestProxy::GetStaticRequest(imgIRequest** aReturn)
|
|
|
|
{
|
2012-07-30 07:20:58 -07:00
|
|
|
*aReturn = nullptr;
|
2010-05-10 20:27:41 -07:00
|
|
|
|
2011-09-28 23:19:26 -07:00
|
|
|
bool animated;
|
2010-08-26 13:47:20 -07:00
|
|
|
if (!mImage || (NS_SUCCEEDED(mImage->GetAnimated(&animated)) && !animated)) {
|
2010-05-10 20:27:41 -07:00
|
|
|
// Early exit - we're not animated, so we don't have to do anything.
|
|
|
|
NS_ADDREF(*aReturn = this);
|
|
|
|
return NS_OK;
|
2009-12-10 20:02:13 -08:00
|
|
|
}
|
|
|
|
|
2010-05-14 13:47:59 -07:00
|
|
|
// We are animated. We need to extract the current frame from this image.
|
|
|
|
PRInt32 w = 0;
|
|
|
|
PRInt32 h = 0;
|
|
|
|
mImage->GetWidth(&w);
|
|
|
|
mImage->GetHeight(&h);
|
|
|
|
nsIntRect rect(0, 0, w, h);
|
|
|
|
nsCOMPtr<imgIContainer> currentFrame;
|
|
|
|
nsresult rv = mImage->ExtractFrame(imgIContainer::FRAME_CURRENT, rect,
|
|
|
|
imgIContainer::FLAG_SYNC_DECODE,
|
|
|
|
getter_AddRefs(currentFrame));
|
|
|
|
if (NS_FAILED(rv))
|
|
|
|
return rv;
|
|
|
|
|
2010-08-13 21:09:48 -07:00
|
|
|
nsRefPtr<Image> frame = static_cast<Image*>(currentFrame.get());
|
2010-05-10 20:27:41 -07:00
|
|
|
|
2010-05-14 13:47:59 -07:00
|
|
|
// Create a static imgRequestProxy with our new extracted frame.
|
|
|
|
nsRefPtr<imgRequestProxy> req = new imgRequestProxy();
|
2012-07-30 07:20:58 -07:00
|
|
|
req->Init(nullptr, nullptr, frame, mURI, nullptr);
|
2010-05-10 20:27:41 -07:00
|
|
|
req->SetPrincipal(mPrincipal);
|
|
|
|
|
2009-12-10 20:02:13 -08:00
|
|
|
NS_ADDREF(*aReturn = req);
|
2010-05-10 20:27:41 -07:00
|
|
|
|
2009-12-10 20:02:13 -08:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2010-05-10 20:27:41 -07:00
|
|
|
void imgRequestProxy::SetPrincipal(nsIPrincipal *aPrincipal)
|
|
|
|
{
|
|
|
|
mPrincipal = aPrincipal;
|
|
|
|
}
|
|
|
|
|
2010-05-14 13:47:59 -07:00
|
|
|
void imgRequestProxy::NotifyListener()
|
2010-05-10 20:27:41 -07:00
|
|
|
{
|
2010-07-28 14:52:14 -07:00
|
|
|
// It would be nice to notify the observer directly in the status tracker
|
|
|
|
// instead of through the proxy, but there are several places we do extra
|
|
|
|
// processing when we receive notifications (like OnStopRequest()), and we
|
|
|
|
// need to check mCanceled everywhere too.
|
2010-05-10 20:27:41 -07:00
|
|
|
|
2010-07-28 14:52:14 -07:00
|
|
|
if (mOwner) {
|
|
|
|
// Send the notifications to our listener asynchronously.
|
2010-08-23 15:44:07 -07:00
|
|
|
GetStatusTracker().Notify(mOwner, this);
|
2010-07-28 14:52:14 -07:00
|
|
|
} else {
|
|
|
|
// We don't have an imgRequest, so we can only notify the clone of our
|
|
|
|
// current state, but we still have to do that asynchronously.
|
2010-08-23 15:44:07 -07:00
|
|
|
NS_ABORT_IF_FALSE(mImage,
|
|
|
|
"if we have no imgRequest, we should have an Image");
|
2010-07-28 14:52:14 -07:00
|
|
|
mImage->GetStatusTracker().NotifyCurrentState(this);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void imgRequestProxy::SyncNotifyListener()
|
|
|
|
{
|
|
|
|
// It would be nice to notify the observer directly in the status tracker
|
|
|
|
// instead of through the proxy, but there are several places we do extra
|
|
|
|
// processing when we receive notifications (like OnStopRequest()), and we
|
|
|
|
// need to check mCanceled everywhere too.
|
|
|
|
|
2010-08-23 15:44:07 -07:00
|
|
|
GetStatusTracker().SyncNotify(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
imgRequestProxy::SetImage(Image* aImage)
|
|
|
|
{
|
2010-08-26 13:47:20 -07:00
|
|
|
NS_ABORT_IF_FALSE(aImage, "Setting null image");
|
2012-05-19 12:32:37 -07:00
|
|
|
NS_ABORT_IF_FALSE(!mImage || mOwner->GetMultipart(),
|
|
|
|
"Setting image when we already have one");
|
2010-08-23 15:44:07 -07:00
|
|
|
|
|
|
|
mImage = aImage;
|
|
|
|
|
2010-08-25 23:21:34 -07:00
|
|
|
// Apply any locks we have
|
|
|
|
for (PRUint32 i = 0; i < mLockCount; ++i)
|
2010-08-23 15:44:07 -07:00
|
|
|
mImage->LockImage();
|
2010-09-07 17:33:02 -07:00
|
|
|
|
|
|
|
// Apply any animation consumers we have
|
|
|
|
for (PRUint32 i = 0; i < mAnimationConsumers; i++)
|
|
|
|
mImage->IncrementAnimationConsumers();
|
2010-08-23 15:44:07 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
imgStatusTracker&
|
|
|
|
imgRequestProxy::GetStatusTracker()
|
|
|
|
{
|
|
|
|
// NOTE: It's possible that our mOwner has an Image that it didn't notify
|
|
|
|
// us about, if we were Canceled before its Image was constructed.
|
|
|
|
// (Canceling removes us as an observer, so mOwner has no way to notify us).
|
|
|
|
// That's why this method uses mOwner->GetStatusTracker() instead of just
|
|
|
|
// mOwner->mStatusTracker -- we might have a null mImage and yet have an
|
|
|
|
// mOwner with a non-null mImage (and a null mStatusTracker pointer).
|
|
|
|
return mImage ? mImage->GetStatusTracker() : mOwner->GetStatusTracker();
|
2010-05-10 20:27:41 -07:00
|
|
|
}
|