Thu, 22 Jan 2015 13:21:57 +0100
Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6
1 /* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #ifndef mozilla_plugins_BrowserStreamChild_h
7 #define mozilla_plugins_BrowserStreamChild_h 1
9 #include "mozilla/plugins/PBrowserStreamChild.h"
10 #include "mozilla/plugins/AStream.h"
12 namespace mozilla {
13 namespace plugins {
15 class PluginInstanceChild;
16 class StreamNotifyChild;
18 class BrowserStreamChild : public PBrowserStreamChild, public AStream
19 {
20 public:
21 BrowserStreamChild(PluginInstanceChild* instance,
22 const nsCString& url,
23 const uint32_t& length,
24 const uint32_t& lastmodified,
25 StreamNotifyChild* notifyData,
26 const nsCString& headers,
27 const nsCString& mimeType,
28 const bool& seekable,
29 NPError* rv,
30 uint16_t* stype);
31 virtual ~BrowserStreamChild();
33 virtual bool IsBrowserStream() MOZ_OVERRIDE { return true; }
35 NPError StreamConstructed(
36 const nsCString& mimeType,
37 const bool& seekable,
38 uint16_t* stype);
40 virtual bool RecvWrite(const int32_t& offset,
41 const Buffer& data,
42 const uint32_t& newsize) MOZ_OVERRIDE;
43 virtual bool RecvNPP_StreamAsFile(const nsCString& fname) MOZ_OVERRIDE;
44 virtual bool RecvNPP_DestroyStream(const NPReason& reason) MOZ_OVERRIDE;
45 virtual bool Recv__delete__() MOZ_OVERRIDE;
47 void EnsureCorrectInstance(PluginInstanceChild* i)
48 {
49 if (i != mInstance)
50 NS_RUNTIMEABORT("Incorrect stream instance");
51 }
52 void EnsureCorrectStream(NPStream* s)
53 {
54 if (s != &mStream)
55 NS_RUNTIMEABORT("Incorrect stream data");
56 }
58 NPError NPN_RequestRead(NPByteRange* aRangeList);
59 void NPN_DestroyStream(NPReason reason);
61 void NotifyPending() {
62 NS_ASSERTION(!mNotifyPending, "Pending twice?");
63 mNotifyPending = true;
64 EnsureDeliveryPending();
65 }
67 /**
68 * During instance destruction, artificially cancel all outstanding streams.
69 *
70 * @return false if we are already in the DELETING state.
71 */
72 bool InstanceDying() {
73 if (DELETING == mState)
74 return false;
76 mInstanceDying = true;
77 return true;
78 }
80 void FinishDelivery() {
81 NS_ASSERTION(mInstanceDying, "Should only be called after InstanceDying");
82 NS_ASSERTION(DELETING != mState, "InstanceDying didn't work?");
83 mStreamStatus = NPRES_USER_BREAK;
84 Deliver();
85 NS_ASSERTION(!mStreamNotify, "Didn't deliver NPN_URLNotify?");
86 }
88 private:
89 friend class StreamNotifyChild;
90 using PBrowserStreamChild::SendNPN_DestroyStream;
92 /**
93 * Post an event to ensure delivery of pending data/destroy/urlnotify events
94 * outside of the current RPC stack.
95 */
96 void EnsureDeliveryPending();
98 /**
99 * Deliver data, destruction, notify scheduling
100 * or cancelling the suspended timer as needed.
101 */
102 void Deliver();
104 /**
105 * Deliver one chunk of pending data.
106 * @return true if the plugin indicated a pause was necessary
107 */
108 bool DeliverPendingData();
110 void SetSuspendedTimer();
111 void ClearSuspendedTimer();
113 PluginInstanceChild* mInstance;
114 NPStream mStream;
116 static const NPReason kStreamOpen = -1;
118 /**
119 * The plugin's notion of whether a stream has been "closed" (no more
120 * data delivery) differs from the plugin host due to asynchronous delivery
121 * of data and NPN_DestroyStream. While the plugin-visible stream is open,
122 * mStreamStatus should be kStreamOpen (-1). mStreamStatus will be a
123 * failure code if either the parent or child indicates stream failure.
124 */
125 NPReason mStreamStatus;
127 /**
128 * Delivery of NPP_DestroyStream and NPP_URLNotify must be postponed until
129 * all data has been delivered.
130 */
131 enum {
132 NOT_DESTROYED, // NPP_DestroyStream not yet received
133 DESTROY_PENDING, // NPP_DestroyStream received, not yet delivered
134 DESTROYED // NPP_DestroyStream delivered, NPP_URLNotify may still be pending
135 } mDestroyPending;
136 bool mNotifyPending;
137 bool mStreamAsFilePending;
138 nsCString mStreamAsFileName;
140 // When NPP_Destroy is called for our instance (manager), this flag is set
141 // cancels the stream and avoids sending StreamDestroyed.
142 bool mInstanceDying;
144 enum {
145 CONSTRUCTING,
146 ALIVE,
147 DYING,
148 DELETING
149 } mState;
150 nsCString mURL;
151 nsCString mHeaders;
152 StreamNotifyChild* mStreamNotify;
154 struct PendingData
155 {
156 int32_t offset;
157 Buffer data;
158 int32_t curpos;
159 };
160 nsTArray<PendingData> mPendingData;
162 /**
163 * Asynchronous RecvWrite messages are never delivered to the plugin
164 * immediately, because that may be in the midst of an unexpected RPC
165 * stack frame. It instead posts a runnable using this tracker to cancel
166 * in case we are destroyed.
167 */
168 ScopedRunnableMethodFactory<BrowserStreamChild> mDeliveryTracker;
169 base::RepeatingTimer<BrowserStreamChild> mSuspendedTimer;
170 };
172 } // namespace plugins
173 } // namespace mozilla
175 #endif /* mozilla_plugins_BrowserStreamChild_h */