summaryrefslogtreecommitdiff
path: root/dom/plugins/ipc/BrowserStreamChild.h
diff options
context:
space:
mode:
Diffstat (limited to 'dom/plugins/ipc/BrowserStreamChild.h')
-rw-r--r--dom/plugins/ipc/BrowserStreamChild.h173
1 files changed, 173 insertions, 0 deletions
diff --git a/dom/plugins/ipc/BrowserStreamChild.h b/dom/plugins/ipc/BrowserStreamChild.h
new file mode 100644
index 000000000..ad334e4a3
--- /dev/null
+++ b/dom/plugins/ipc/BrowserStreamChild.h
@@ -0,0 +1,173 @@
+/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */
+/* 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/. */
+
+#ifndef mozilla_plugins_BrowserStreamChild_h
+#define mozilla_plugins_BrowserStreamChild_h 1
+
+#include "mozilla/plugins/PBrowserStreamChild.h"
+#include "mozilla/plugins/AStream.h"
+#include "base/task.h"
+#include "base/timer.h"
+
+namespace mozilla {
+namespace plugins {
+
+class PluginInstanceChild;
+class StreamNotifyChild;
+
+class BrowserStreamChild : public PBrowserStreamChild, public AStream
+{
+public:
+ BrowserStreamChild(PluginInstanceChild* instance,
+ const nsCString& url,
+ const uint32_t& length,
+ const uint32_t& lastmodified,
+ StreamNotifyChild* notifyData,
+ const nsCString& headers);
+ virtual ~BrowserStreamChild();
+
+ virtual bool IsBrowserStream() override { return true; }
+
+ NPError StreamConstructed(
+ const nsCString& mimeType,
+ const bool& seekable,
+ uint16_t* stype);
+
+ virtual bool RecvWrite(const int32_t& offset,
+ const uint32_t& newsize,
+ const Buffer& data) override;
+ virtual bool RecvNPP_StreamAsFile(const nsCString& fname) override;
+ virtual bool RecvNPP_DestroyStream(const NPReason& reason) override;
+ virtual bool Recv__delete__() override;
+
+ void EnsureCorrectInstance(PluginInstanceChild* i)
+ {
+ if (i != mInstance)
+ NS_RUNTIMEABORT("Incorrect stream instance");
+ }
+ void EnsureCorrectStream(NPStream* s)
+ {
+ if (s != &mStream)
+ NS_RUNTIMEABORT("Incorrect stream data");
+ }
+
+ NPError NPN_RequestRead(NPByteRange* aRangeList);
+ void NPN_DestroyStream(NPReason reason);
+
+ void NotifyPending() {
+ NS_ASSERTION(!mNotifyPending, "Pending twice?");
+ mNotifyPending = true;
+ EnsureDeliveryPending();
+ }
+
+ /**
+ * During instance destruction, artificially cancel all outstanding streams.
+ *
+ * @return false if we are already in the DELETING state.
+ */
+ bool InstanceDying() {
+ if (DELETING == mState)
+ return false;
+
+ mInstanceDying = true;
+ return true;
+ }
+
+ void FinishDelivery() {
+ NS_ASSERTION(mInstanceDying, "Should only be called after InstanceDying");
+ NS_ASSERTION(DELETING != mState, "InstanceDying didn't work?");
+ mStreamStatus = NPRES_USER_BREAK;
+ Deliver();
+ NS_ASSERTION(!mStreamNotify, "Didn't deliver NPN_URLNotify?");
+ }
+
+private:
+ friend class StreamNotifyChild;
+ using PBrowserStreamChild::SendNPN_DestroyStream;
+
+ /**
+ * Post an event to ensure delivery of pending data/destroy/urlnotify events
+ * outside of the current RPC stack.
+ */
+ void EnsureDeliveryPending();
+
+ /**
+ * Deliver data, destruction, notify scheduling
+ * or cancelling the suspended timer as needed.
+ */
+ void Deliver();
+
+ /**
+ * Deliver one chunk of pending data.
+ * @return true if the plugin indicated a pause was necessary
+ */
+ bool DeliverPendingData();
+
+ void SetSuspendedTimer();
+ void ClearSuspendedTimer();
+
+ PluginInstanceChild* mInstance;
+ NPStream mStream;
+
+ static const NPReason kStreamOpen = -1;
+
+ /**
+ * The plugin's notion of whether a stream has been "closed" (no more
+ * data delivery) differs from the plugin host due to asynchronous delivery
+ * of data and NPN_DestroyStream. While the plugin-visible stream is open,
+ * mStreamStatus should be kStreamOpen (-1). mStreamStatus will be a
+ * failure code if either the parent or child indicates stream failure.
+ */
+ NPReason mStreamStatus;
+
+ /**
+ * Delivery of NPP_DestroyStream and NPP_URLNotify must be postponed until
+ * 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,
+ DYING,
+ DELETING
+ } mState;
+ nsCString mURL;
+ nsCString mHeaders;
+ StreamNotifyChild* mStreamNotify;
+
+ struct PendingData
+ {
+ int32_t offset;
+ Buffer data;
+ int32_t curpos;
+ };
+ nsTArray<PendingData> mPendingData;
+
+ /**
+ * Asynchronous RecvWrite messages are never delivered to the plugin
+ * immediately, because that may be in the midst of an unexpected RPC
+ * stack frame. It instead posts a runnable using this tracker to cancel
+ * in case we are destroyed.
+ */
+ ScopedRunnableMethodFactory<BrowserStreamChild> mDeliveryTracker;
+ base::RepeatingTimer<BrowserStreamChild> mSuspendedTimer;
+};
+
+} // namespace plugins
+} // namespace mozilla
+
+#endif /* mozilla_plugins_BrowserStreamChild_h */