зеркало из https://github.com/mozilla/gecko-dev.git
Bug 687610 - QuickTime can't play media from the network cache when running OOP. r=bsmedberg
This commit is contained in:
Родитель
2f1612e0e6
Коммит
e7fcaffff2
|
@ -578,6 +578,29 @@ nsNPAPIPlugin::Shutdown()
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsNPAPIPlugin::RetainStream(NPStream *pstream, nsISupports **aRetainedPeer)
|
||||
{
|
||||
if (!aRetainedPeer)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
*aRetainedPeer = NULL;
|
||||
|
||||
if (!pstream || !pstream->ndata)
|
||||
return NPERR_INVALID_PARAM;
|
||||
|
||||
nsNPAPIPluginStreamListener* listener =
|
||||
static_cast<nsNPAPIPluginStreamListener*>(pstream->ndata);
|
||||
nsPluginStreamListenerPeer* peer = listener->GetStreamListenerPeer();
|
||||
|
||||
if (!peer)
|
||||
return NPERR_GENERIC_ERROR;
|
||||
|
||||
*aRetainedPeer = (nsISupports*) peer;
|
||||
NS_ADDREF(*aRetainedPeer);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Create a new NPP GET or POST (given in the type argument) url
|
||||
// stream that may have a notify callback
|
||||
NPError
|
||||
|
|
|
@ -106,6 +106,8 @@ public:
|
|||
nsresult CreatePluginInstance(nsNPAPIPluginInstance **aResult);
|
||||
nsresult Shutdown();
|
||||
|
||||
static nsresult RetainStream(NPStream *pstream, nsISupports **aRetainedPeer);
|
||||
|
||||
protected:
|
||||
NPPluginFuncs mPluginFuncs;
|
||||
PluginLibrary* mLibrary;
|
||||
|
|
|
@ -56,6 +56,7 @@ BrowserStreamChild::BrowserStreamChild(PluginInstanceChild* instance,
|
|||
, mStreamStatus(kStreamOpen)
|
||||
, mDestroyPending(NOT_DESTROYED)
|
||||
, mNotifyPending(false)
|
||||
, mStreamAsFilePending(false)
|
||||
, mInstanceDying(false)
|
||||
, mState(CONSTRUCTING)
|
||||
, mURL(url)
|
||||
|
@ -140,7 +141,7 @@ BrowserStreamChild::RecvWrite(const int32_t& offset,
|
|||
}
|
||||
|
||||
bool
|
||||
BrowserStreamChild::AnswerNPP_StreamAsFile(const nsCString& fname)
|
||||
BrowserStreamChild::RecvNPP_StreamAsFile(const nsCString& fname)
|
||||
{
|
||||
PLUGIN_LOG_DEBUG(("%s (fname=%s)", FULLFUNCTION, fname.get()));
|
||||
|
||||
|
@ -152,8 +153,10 @@ BrowserStreamChild::AnswerNPP_StreamAsFile(const nsCString& fname)
|
|||
if (kStreamOpen != mStreamStatus)
|
||||
return true;
|
||||
|
||||
mInstance->mPluginIface->asfile(&mInstance->mData, &mStream,
|
||||
fname.get());
|
||||
mStreamAsFilePending = true;
|
||||
mStreamAsFileName = fname;
|
||||
EnsureDeliveryPending();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -238,6 +241,19 @@ BrowserStreamChild::Deliver()
|
|||
"Exit out of the data-delivery loop with pending data");
|
||||
mPendingData.Clear();
|
||||
|
||||
// NPP_StreamAsFile() is documented (at MDN) to be called "when the stream
|
||||
// is complete" -- i.e. after all calls to NPP_WriteReady() and NPP_Write()
|
||||
// have finished. We make these calls asynchronously (from
|
||||
// DeliverPendingData()). So we need to make sure all the "pending data"
|
||||
// has been "delivered" before calling NPP_StreamAsFile() (also
|
||||
// asynchronously). Doing this resolves bug 687610, bug 670036 and possibly
|
||||
// also other bugs.
|
||||
if (mStreamAsFilePending) {
|
||||
mInstance->mPluginIface->asfile(&mInstance->mData, &mStream,
|
||||
mStreamAsFileName.get());
|
||||
mStreamAsFilePending = false;
|
||||
}
|
||||
|
||||
if (DESTROY_PENDING == mDestroyPending) {
|
||||
mDestroyPending = DESTROYED;
|
||||
if (mState != DYING)
|
||||
|
|
|
@ -72,7 +72,7 @@ public:
|
|||
virtual bool RecvWrite(const int32_t& offset,
|
||||
const Buffer& data,
|
||||
const uint32_t& newsize);
|
||||
virtual bool AnswerNPP_StreamAsFile(const nsCString& fname);
|
||||
virtual bool RecvNPP_StreamAsFile(const nsCString& fname);
|
||||
virtual bool RecvNPP_DestroyStream(const NPReason& reason);
|
||||
virtual bool Recv__delete__();
|
||||
|
||||
|
@ -166,6 +166,8 @@ private:
|
|||
DESTROYED // NPP_DestroyStream delivered, NPP_URLNotify may still be pending
|
||||
} mDestroyPending;
|
||||
bool mNotifyPending;
|
||||
bool mStreamAsFilePending;
|
||||
nsCString mStreamAsFileName;
|
||||
|
||||
// When NPP_Destroy is called for our instance (manager), this flag is set
|
||||
// cancels the stream and avoids sending StreamDestroyed.
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include "BrowserStreamParent.h"
|
||||
#include "PluginInstanceParent.h"
|
||||
#include "nsNPAPIPlugin.h"
|
||||
|
||||
#include "mozilla/unused.h"
|
||||
|
||||
|
@ -97,6 +98,8 @@ BrowserStreamParent::RecvStreamDestroyed()
|
|||
return false;
|
||||
}
|
||||
|
||||
mStreamPeer = NULL;
|
||||
|
||||
mState = DELETING;
|
||||
return Send__delete__(this);
|
||||
}
|
||||
|
@ -134,7 +137,15 @@ BrowserStreamParent::StreamAsFile(const char* fname)
|
|||
NS_ASSERTION(ALIVE == mState,
|
||||
"Calling streamasfile after NPP_DestroyStream?");
|
||||
|
||||
unused << CallNPP_StreamAsFile(nsCString(fname));
|
||||
// Make sure our stream survives until the plugin process tells us we've
|
||||
// been destroyed (until RecvStreamDestroyed() is called). Since we retain
|
||||
// mStreamPeer at most once, we won't get in trouble if StreamAsFile() is
|
||||
// called more than once.
|
||||
if (!mStreamPeer) {
|
||||
nsNPAPIPlugin::RetainStream(mStream, getter_AddRefs(mStreamPeer));
|
||||
}
|
||||
|
||||
unused << SendNPP_StreamAsFile(nsCString(fname));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -76,6 +76,7 @@ private:
|
|||
|
||||
PluginInstanceParent* mNPP;
|
||||
NPStream* mStream;
|
||||
nsCOMPtr<nsISupports> mStreamPeer;
|
||||
|
||||
enum {
|
||||
ALIVE,
|
||||
|
|
|
@ -59,7 +59,7 @@ rpc protocol PBrowserStream
|
|||
child:
|
||||
async Write(int32_t offset, Buffer data,
|
||||
uint32_t newlength);
|
||||
rpc NPP_StreamAsFile(nsCString fname);
|
||||
async NPP_StreamAsFile(nsCString fname);
|
||||
|
||||
/**
|
||||
* NPP_DestroyStream may race with other messages: the child acknowledges
|
||||
|
|
Загрузка…
Ссылка в новой задаче