Bug 1352567 - Remove plugin IPC code to support stream types other than NP_NORMAL (seekable and/or file streams), r=jimm
authorBenjamin Smedberg <benjamin@smedbergs.us>
Mon, 02 Oct 2017 12:49:15 -0700
changeset 426609 0dfd227a6a20a7eec7c41b84381e63e8718fd861
parent 426608 989ab34fd26da1673f0c1c03e5f555ecfdba6976
child 426610 3eca597f346fda5899c7da9237b1b35327b312d0
push id97
push userfmarier@mozilla.com
push dateSat, 14 Oct 2017 01:12:59 +0000
reviewersjimm
bugs1352567
milestone58.0a1
Bug 1352567 - Remove plugin IPC code to support stream types other than NP_NORMAL (seekable and/or file streams), r=jimm MozReview-Commit-ID: FWl2gcpKy6D
dom/plugins/ipc/BrowserStreamChild.cpp
dom/plugins/ipc/BrowserStreamChild.h
dom/plugins/ipc/BrowserStreamParent.cpp
dom/plugins/ipc/BrowserStreamParent.h
dom/plugins/ipc/PBrowserStream.ipdl
dom/plugins/ipc/PluginModuleChild.cpp
dom/plugins/ipc/PluginModuleParent.cpp
dom/plugins/ipc/PluginModuleParent.h
ipc/ipdl/sync-messages.ini
--- a/dom/plugins/ipc/BrowserStreamChild.cpp
+++ b/dom/plugins/ipc/BrowserStreamChild.cpp
@@ -17,17 +17,16 @@ BrowserStreamChild::BrowserStreamChild(P
                                        const uint32_t& length,
                                        const uint32_t& lastmodified,
                                        StreamNotifyChild* notifyData,
                                        const nsCString& headers)
   : mInstance(instance)
   , mStreamStatus(kStreamOpen)
   , mDestroyPending(NOT_DESTROYED)
   , mNotifyPending(false)
-  , mStreamAsFilePending(false)
   , mInstanceDying(false)
   , mState(CONSTRUCTING)
   , mURL(url)
   , mHeaders(headers)
   , mStreamNotify(notifyData)
   , mDeliveryTracker(this)
 {
   PLUGIN_LOG_DEBUG(("%s (%s, %i, %i, %p, %s)", FULLFUNCTION,
@@ -55,16 +54,25 @@ BrowserStreamChild::StreamConstructed(
             uint16_t* stype)
 {
   NPError rv = NPERR_NO_ERROR;
 
   *stype = NP_NORMAL;
   rv = mInstance->mPluginIface->newstream(
     &mInstance->mData, const_cast<char*>(NullableStringGet(mimeType)),
     &mStream, seekable, stype);
+
+  // NP_NORMAL is the only permissible stream type
+  if (*stype != NP_NORMAL) {
+    rv = NPERR_INVALID_PARAM;
+    // The plugin thinks the stream is alive, so we kill it explicitly
+    (void) mInstance->mPluginIface
+      ->destroystream(&mInstance->mData, &mStream, NPRES_NETWORK_ERR);
+  }
+
   if (rv != NPERR_NO_ERROR) {
     mState = DELETING;
     if (mStreamNotify) {
       mStreamNotify->SetAssociatedStream(nullptr);
       mStreamNotify = nullptr;
     }
   }
   else {
@@ -104,36 +112,16 @@ BrowserStreamChild::RecvWrite(const int3
   newdata->curpos = 0;
 
   EnsureDeliveryPending();
 
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
-BrowserStreamChild::RecvNPP_StreamAsFile(const nsCString& fname)
-{
-  PLUGIN_LOG_DEBUG(("%s (fname=%s)", FULLFUNCTION, fname.get()));
-
-  AssertPluginThread();
-
-  if (ALIVE != mState)
-    MOZ_CRASH("Unexpected state: received file after NPP_DestroyStream?");
-
-  if (kStreamOpen != mStreamStatus)
-    return IPC_OK();
-
-  mStreamAsFilePending = true;
-  mStreamAsFileName = fname;
-  EnsureDeliveryPending();
-
-  return IPC_OK();
-}
-
-mozilla::ipc::IPCResult
 BrowserStreamChild::RecvNPP_DestroyStream(const NPReason& reason)
 {
   PLUGIN_LOG_DEBUG_METHOD;
 
   if (ALIVE != mState)
     MOZ_CRASH("Unexpected state: recevied NPP_DestroyStream twice?");
 
   mState = DYING;
@@ -151,37 +139,16 @@ BrowserStreamChild::Recv__delete__()
   AssertPluginThread();
 
   if (DELETING != mState)
     MOZ_CRASH("Bad state, not DELETING");
 
   return IPC_OK();
 }
 
-NPError
-BrowserStreamChild::NPN_RequestRead(NPByteRange* aRangeList)
-{
-  PLUGIN_LOG_DEBUG_FUNCTION;
-
-  AssertPluginThread();
-
-  if (ALIVE != mState || kStreamOpen != mStreamStatus)
-    return NPERR_GENERIC_ERROR;
-
-  IPCByteRanges ranges;
-  for (; aRangeList; aRangeList = aRangeList->next) {
-    IPCByteRange br = {aRangeList->offset, aRangeList->length};
-    ranges.AppendElement(br);
-  }
-
-  NPError result;
-  CallNPN_RequestRead(ranges, &result);
-  return result;
-}
-
 void
 BrowserStreamChild::EnsureDeliveryPending()
 {
   MessageLoop::current()->PostTask(
     mDeliveryTracker.NewRunnableMethod(&BrowserStreamChild::Deliver));
 }
 
 void
@@ -194,30 +161,16 @@ BrowserStreamChild::Deliver()
     }
   }
   ClearSuspendedTimer();
 
   NS_ASSERTION(kStreamOpen != mStreamStatus || 0 == mPendingData.Length(),
                "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) {
-    if (mStreamStatus == kStreamOpen)
-      mInstance->mPluginIface->asfile(&mInstance->mData, &mStream,
-                                      mStreamAsFileName.get());
-    mStreamAsFilePending = false;
-  }
-
   if (DESTROY_PENDING == mDestroyPending) {
     mDestroyPending = DESTROYED;
     if (mState != DYING)
       MOZ_CRASH("mDestroyPending but state not DYING");
 
     NS_ASSERTION(NPRES_DONE != mStreamStatus, "Success status set too early!");
     if (kStreamOpen == mStreamStatus)
       mStreamStatus = NPRES_DONE;
--- a/dom/plugins/ipc/BrowserStreamChild.h
+++ b/dom/plugins/ipc/BrowserStreamChild.h
@@ -33,33 +33,30 @@ public:
   NPError StreamConstructed(
             const nsCString& mimeType,
             const bool& seekable,
             uint16_t* stype);
 
   virtual mozilla::ipc::IPCResult RecvWrite(const int32_t& offset,
                                             const uint32_t& newsize,
                                             const Buffer& data) override;
-  virtual mozilla::ipc::IPCResult RecvNPP_StreamAsFile(const nsCString& fname) override;
   virtual mozilla::ipc::IPCResult RecvNPP_DestroyStream(const NPReason& reason) override;
   virtual mozilla::ipc::IPCResult Recv__delete__() override;
 
   void EnsureCorrectInstance(PluginInstanceChild* i)
   {
     if (i != mInstance)
       MOZ_CRASH("Incorrect stream instance");
   }
   void EnsureCorrectStream(NPStream* s)
   {
     if (s != &mStream)
       MOZ_CRASH("Incorrect stream data");
   }
 
-  NPError NPN_RequestRead(NPByteRange* aRangeList);
-
   void NotifyPending() {
     NS_ASSERTION(!mNotifyPending, "Pending twice?");
     mNotifyPending = true;
     EnsureDeliveryPending();
   }
 
   /**
    * During instance destruction, artificially cancel all outstanding streams.
@@ -125,18 +122,16 @@ private:
    * all data has been delivered.
    */
   enum {
     NOT_DESTROYED, // NPP_DestroyStream not yet received
     DESTROY_PENDING, // NPP_DestroyStream received, not yet delivered
     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.
   bool mInstanceDying;
 
   enum {
     CONSTRUCTING,
     ALIVE,
--- a/dom/plugins/ipc/BrowserStreamParent.cpp
+++ b/dom/plugins/ipc/BrowserStreamParent.cpp
@@ -38,58 +38,16 @@ BrowserStreamParent::~BrowserStreamParen
 }
 
 void
 BrowserStreamParent::ActorDestroy(ActorDestroyReason aWhy)
 {
   // Implement me! Bug 1005159
 }
 
-mozilla::ipc::IPCResult
-BrowserStreamParent::AnswerNPN_RequestRead(const IPCByteRanges& ranges,
-                                           NPError* result)
-{
-  PLUGIN_LOG_DEBUG_FUNCTION;
-
-  switch (mState) {
-  case INITIALIZING:
-    NS_ERROR("Requesting a read before initialization has completed");
-    *result = NPERR_GENERIC_ERROR;
-    return IPC_FAIL_NO_REASON(this);
-
-  case ALIVE:
-    break;
-
-  case DYING:
-    *result = NPERR_GENERIC_ERROR;
-    return IPC_OK();
-
-  default:
-    NS_ERROR("Unexpected state");
-    return IPC_FAIL_NO_REASON(this);
-  }
-
-  if (!mStream)
-    return IPC_FAIL_NO_REASON(this);
-
-  if (ranges.Length() > INT32_MAX)
-    return IPC_FAIL_NO_REASON(this);
-
-  UniquePtr<NPByteRange[]> rp(new NPByteRange[ranges.Length()]);
-  for (uint32_t i = 0; i < ranges.Length(); ++i) {
-    rp[i].offset = ranges[i].offset;
-    rp[i].length = ranges[i].length;
-    rp[i].next = &rp[i + 1];
-  }
-  rp[ranges.Length() - 1].next = nullptr;
-
-  *result = mNPP->mNPNIface->requestread(mStream, rp.get());
-  return IPC_OK();
-}
-
 void
 BrowserStreamParent::NPP_DestroyStream(NPReason reason)
 {
   NS_ASSERTION(ALIVE == mState || INITIALIZING == mState,
                "NPP_DestroyStream called twice?");
   bool stillInitializing = INITIALIZING == mState;
   if (stillInitializing) {
     mState = DEFERRING_DESTROY;
@@ -140,29 +98,10 @@ BrowserStreamParent::Write(int32_t offse
     len = kSendDataChunk;
 
   return SendWrite(offset,
                    mStream->end,
                    nsCString(static_cast<char*>(buffer), len)) ?
     len : -1;
 }
 
-void
-BrowserStreamParent::StreamAsFile(const char* fname)
-{
-  PLUGIN_LOG_DEBUG_FUNCTION;
-
-  NS_ASSERTION(ALIVE == mState,
-               "Calling streamasfile after NPP_DestroyStream?");
-
-  // 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));
-}
-
 } // namespace plugins
 } // namespace mozilla
--- a/dom/plugins/ipc/BrowserStreamParent.h
+++ b/dom/plugins/ipc/BrowserStreamParent.h
@@ -25,24 +25,20 @@ public:
   BrowserStreamParent(PluginInstanceParent* npp,
                       NPStream* stream);
   virtual ~BrowserStreamParent();
 
   virtual bool IsBrowserStream() override { return true; }
 
   virtual void ActorDestroy(ActorDestroyReason aWhy) override;
 
-  virtual mozilla::ipc::IPCResult AnswerNPN_RequestRead(const IPCByteRanges& ranges,
-                                                        NPError* result) override;
-
   virtual mozilla::ipc::IPCResult RecvStreamDestroyed() override;
 
   int32_t WriteReady();
   int32_t Write(int32_t offset, int32_t len, void* buffer);
-  void StreamAsFile(const char* fname);
 
   void NPP_DestroyStream(NPReason reason);
 
   void SetAlive()
   {
     if (mState == INITIALIZING) {
       mState = ALIVE;
     }
--- a/dom/plugins/ipc/PBrowserStream.ipdl
+++ b/dom/plugins/ipc/PBrowserStream.ipdl
@@ -21,47 +21,22 @@ namespace plugins {
 
 intr protocol PBrowserStream
 {
   manager PPluginInstance;
 
 child:
   async Write(int32_t offset, uint32_t newlength,
               Buffer data);
-  async NPP_StreamAsFile(nsCString fname);
 
   /**
    * NPP_DestroyStream may race with other messages: the child acknowledges
    * the message with StreamDestroyed before this actor is deleted.
    */
   async NPP_DestroyStream(NPReason reason);
   async __delete__();
 
 parent:
-  intr NPN_RequestRead(IPCByteRanges ranges)
-    returns (NPError result);
   async StreamDestroyed();
-
-/*
-  TODO: turn on state machine.
-
-  // need configurable start state: if the constructor
-  // returns an error in result, start state should
-  // be DELETING.
-start state ALIVE:
-  send Write goto ALIVE;
-  call NPP_StreamAsFile goto ALIVE;
-  send NPP_DestroyStream goto ALIVE;
-  answer NPN_RequestRead goto ALIVE;
-  recv NPN_DestroyStream goto DYING;
-
-state DYING:
-  answer NPN_RequestRead goto DYING;
-  recv NPN_DestroyStream goto DYING;
-  recv StreamDestroyed goto DELETING;
-
-state DELETING:
-  send __delete__;
-*/
 };
 
 } // namespace plugins
 } // namespace mozilla
--- a/dom/plugins/ipc/PluginModuleChild.cpp
+++ b/dom/plugins/ipc/PluginModuleChild.cpp
@@ -1040,23 +1040,17 @@ InstCast(NPP aNPP)
 namespace mozilla {
 namespace plugins {
 namespace child {
 
 NPError
 _requestread(NPStream* aStream,
              NPByteRange* aRangeList)
 {
-    PLUGIN_LOG_DEBUG_FUNCTION;
-    ENSURE_PLUGIN_THREAD(NPERR_INVALID_PARAM);
-
-    BrowserStreamChild* bs =
-        static_cast<BrowserStreamChild*>(static_cast<AStream*>(aStream->ndata));
-    bs->EnsureCorrectStream(aStream);
-    return bs->NPN_RequestRead(aRangeList);
+    return NPERR_STREAM_NOT_SEEKABLE;
 }
 
 NPError
 _geturlnotify(NPP aNPP,
               const char* aRelativeURL,
               const char* aTarget,
               void* aNotifyData)
 {
--- a/dom/plugins/ipc/PluginModuleParent.cpp
+++ b/dom/plugins/ipc/PluginModuleParent.cpp
@@ -1693,17 +1693,16 @@ PluginModuleParent::SetPluginFuncs(NPPlu
     aFuncs->newp = nullptr;
     aFuncs->clearsitedata = nullptr;
     aFuncs->getsiteswithdata = nullptr;
 
     aFuncs->destroy = NPP_Destroy;
     aFuncs->setwindow = NPP_SetWindow;
     aFuncs->newstream = NPP_NewStream;
     aFuncs->destroystream = NPP_DestroyStream;
-    aFuncs->asfile = NPP_StreamAsFile;
     aFuncs->writeready = NPP_WriteReady;
     aFuncs->write = NPP_Write;
     aFuncs->print = NPP_Print;
     aFuncs->event = NPP_HandleEvent;
     aFuncs->urlnotify = NPP_URLNotify;
     aFuncs->getvalue = NPP_GetValue;
     aFuncs->setvalue = NPP_SetValue;
     aFuncs->gotfocus = nullptr;
@@ -1789,28 +1788,16 @@ PluginModuleParent::NPP_Write(NPP instan
     BrowserStreamParent* s = StreamCast(instance, stream);
     if (!s)
         return -1;
 
     return s->Write(offset, len, buffer);
 }
 
 void
-PluginModuleParent::NPP_StreamAsFile(NPP instance,
-                                     NPStream* stream,
-                                     const char* fname)
-{
-    BrowserStreamParent* s = StreamCast(instance, stream);
-    if (!s)
-        return;
-
-    s->StreamAsFile(fname);
-}
-
-void
 PluginModuleParent::NPP_Print(NPP instance, NPPrint* platformPrint)
 {
 
     PluginInstanceParent* pip = PluginInstanceParent::Cast(instance);
     return pip ? pip->NPP_Print(platformPrint) : (void)0;
 }
 
 int16_t
--- a/dom/plugins/ipc/PluginModuleParent.h
+++ b/dom/plugins/ipc/PluginModuleParent.h
@@ -217,18 +217,16 @@ protected:
     static NPError NPP_SetWindow(NPP instance, NPWindow* window);
     static NPError NPP_NewStream(NPP instance, NPMIMEType type, NPStream* stream,
                                  NPBool seekable, uint16_t* stype);
     static NPError NPP_DestroyStream(NPP instance,
                                      NPStream* stream, NPReason reason);
     static int32_t NPP_WriteReady(NPP instance, NPStream* stream);
     static int32_t NPP_Write(NPP instance, NPStream* stream,
                              int32_t offset, int32_t len, void* buffer);
-    static void NPP_StreamAsFile(NPP instance,
-                                 NPStream* stream, const char* fname);
     static void NPP_Print(NPP instance, NPPrint* platformPrint);
     static int16_t NPP_HandleEvent(NPP instance, void* event);
     static void NPP_URLNotify(NPP instance, const char* url,
                               NPReason reason, void* notifyData);
     static NPError NPP_GetValue(NPP instance,
                                 NPPVariable variable, void *ret_value);
     static NPError NPP_SetValue(NPP instance, NPNVariable variable,
                                 void *value);
--- a/ipc/ipdl/sync-messages.ini
+++ b/ipc/ipdl/sync-messages.ini
@@ -913,18 +913,16 @@ description =
 [PGMPVideoDecoder::NeedShmem]
 description =
 [PGMPVideoEncoder::NeedShmem]
 description =
 [PVideoDecoderManager::PVideoDecoder]
 description =
 [PVideoDecoderManager::Readback]
 description =
-[PBrowserStream::NPN_RequestRead]
-description =
 [PBackgroundStorage::Preload]
 description =
 [PRemoteSpellcheckEngine::Check]
 description =
 [PRemoteSpellcheckEngine::CheckAndSuggest]
 description =
 [PRemoteSpellcheckEngine::SetDictionary]
 description =