1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/dom/plugins/ipc/BrowserStreamChild.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,175 @@ 1.4 +/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#ifndef mozilla_plugins_BrowserStreamChild_h 1.10 +#define mozilla_plugins_BrowserStreamChild_h 1 1.11 + 1.12 +#include "mozilla/plugins/PBrowserStreamChild.h" 1.13 +#include "mozilla/plugins/AStream.h" 1.14 + 1.15 +namespace mozilla { 1.16 +namespace plugins { 1.17 + 1.18 +class PluginInstanceChild; 1.19 +class StreamNotifyChild; 1.20 + 1.21 +class BrowserStreamChild : public PBrowserStreamChild, public AStream 1.22 +{ 1.23 +public: 1.24 + BrowserStreamChild(PluginInstanceChild* instance, 1.25 + const nsCString& url, 1.26 + const uint32_t& length, 1.27 + const uint32_t& lastmodified, 1.28 + StreamNotifyChild* notifyData, 1.29 + const nsCString& headers, 1.30 + const nsCString& mimeType, 1.31 + const bool& seekable, 1.32 + NPError* rv, 1.33 + uint16_t* stype); 1.34 + virtual ~BrowserStreamChild(); 1.35 + 1.36 + virtual bool IsBrowserStream() MOZ_OVERRIDE { return true; } 1.37 + 1.38 + NPError StreamConstructed( 1.39 + const nsCString& mimeType, 1.40 + const bool& seekable, 1.41 + uint16_t* stype); 1.42 + 1.43 + virtual bool RecvWrite(const int32_t& offset, 1.44 + const Buffer& data, 1.45 + const uint32_t& newsize) MOZ_OVERRIDE; 1.46 + virtual bool RecvNPP_StreamAsFile(const nsCString& fname) MOZ_OVERRIDE; 1.47 + virtual bool RecvNPP_DestroyStream(const NPReason& reason) MOZ_OVERRIDE; 1.48 + virtual bool Recv__delete__() MOZ_OVERRIDE; 1.49 + 1.50 + void EnsureCorrectInstance(PluginInstanceChild* i) 1.51 + { 1.52 + if (i != mInstance) 1.53 + NS_RUNTIMEABORT("Incorrect stream instance"); 1.54 + } 1.55 + void EnsureCorrectStream(NPStream* s) 1.56 + { 1.57 + if (s != &mStream) 1.58 + NS_RUNTIMEABORT("Incorrect stream data"); 1.59 + } 1.60 + 1.61 + NPError NPN_RequestRead(NPByteRange* aRangeList); 1.62 + void NPN_DestroyStream(NPReason reason); 1.63 + 1.64 + void NotifyPending() { 1.65 + NS_ASSERTION(!mNotifyPending, "Pending twice?"); 1.66 + mNotifyPending = true; 1.67 + EnsureDeliveryPending(); 1.68 + } 1.69 + 1.70 + /** 1.71 + * During instance destruction, artificially cancel all outstanding streams. 1.72 + * 1.73 + * @return false if we are already in the DELETING state. 1.74 + */ 1.75 + bool InstanceDying() { 1.76 + if (DELETING == mState) 1.77 + return false; 1.78 + 1.79 + mInstanceDying = true; 1.80 + return true; 1.81 + } 1.82 + 1.83 + void FinishDelivery() { 1.84 + NS_ASSERTION(mInstanceDying, "Should only be called after InstanceDying"); 1.85 + NS_ASSERTION(DELETING != mState, "InstanceDying didn't work?"); 1.86 + mStreamStatus = NPRES_USER_BREAK; 1.87 + Deliver(); 1.88 + NS_ASSERTION(!mStreamNotify, "Didn't deliver NPN_URLNotify?"); 1.89 + } 1.90 + 1.91 +private: 1.92 + friend class StreamNotifyChild; 1.93 + using PBrowserStreamChild::SendNPN_DestroyStream; 1.94 + 1.95 + /** 1.96 + * Post an event to ensure delivery of pending data/destroy/urlnotify events 1.97 + * outside of the current RPC stack. 1.98 + */ 1.99 + void EnsureDeliveryPending(); 1.100 + 1.101 + /** 1.102 + * Deliver data, destruction, notify scheduling 1.103 + * or cancelling the suspended timer as needed. 1.104 + */ 1.105 + void Deliver(); 1.106 + 1.107 + /** 1.108 + * Deliver one chunk of pending data. 1.109 + * @return true if the plugin indicated a pause was necessary 1.110 + */ 1.111 + bool DeliverPendingData(); 1.112 + 1.113 + void SetSuspendedTimer(); 1.114 + void ClearSuspendedTimer(); 1.115 + 1.116 + PluginInstanceChild* mInstance; 1.117 + NPStream mStream; 1.118 + 1.119 + static const NPReason kStreamOpen = -1; 1.120 + 1.121 + /** 1.122 + * The plugin's notion of whether a stream has been "closed" (no more 1.123 + * data delivery) differs from the plugin host due to asynchronous delivery 1.124 + * of data and NPN_DestroyStream. While the plugin-visible stream is open, 1.125 + * mStreamStatus should be kStreamOpen (-1). mStreamStatus will be a 1.126 + * failure code if either the parent or child indicates stream failure. 1.127 + */ 1.128 + NPReason mStreamStatus; 1.129 + 1.130 + /** 1.131 + * Delivery of NPP_DestroyStream and NPP_URLNotify must be postponed until 1.132 + * all data has been delivered. 1.133 + */ 1.134 + enum { 1.135 + NOT_DESTROYED, // NPP_DestroyStream not yet received 1.136 + DESTROY_PENDING, // NPP_DestroyStream received, not yet delivered 1.137 + DESTROYED // NPP_DestroyStream delivered, NPP_URLNotify may still be pending 1.138 + } mDestroyPending; 1.139 + bool mNotifyPending; 1.140 + bool mStreamAsFilePending; 1.141 + nsCString mStreamAsFileName; 1.142 + 1.143 + // When NPP_Destroy is called for our instance (manager), this flag is set 1.144 + // cancels the stream and avoids sending StreamDestroyed. 1.145 + bool mInstanceDying; 1.146 + 1.147 + enum { 1.148 + CONSTRUCTING, 1.149 + ALIVE, 1.150 + DYING, 1.151 + DELETING 1.152 + } mState; 1.153 + nsCString mURL; 1.154 + nsCString mHeaders; 1.155 + StreamNotifyChild* mStreamNotify; 1.156 + 1.157 + struct PendingData 1.158 + { 1.159 + int32_t offset; 1.160 + Buffer data; 1.161 + int32_t curpos; 1.162 + }; 1.163 + nsTArray<PendingData> mPendingData; 1.164 + 1.165 + /** 1.166 + * Asynchronous RecvWrite messages are never delivered to the plugin 1.167 + * immediately, because that may be in the midst of an unexpected RPC 1.168 + * stack frame. It instead posts a runnable using this tracker to cancel 1.169 + * in case we are destroyed. 1.170 + */ 1.171 + ScopedRunnableMethodFactory<BrowserStreamChild> mDeliveryTracker; 1.172 + base::RepeatingTimer<BrowserStreamChild> mSuspendedTimer; 1.173 +}; 1.174 + 1.175 +} // namespace plugins 1.176 +} // namespace mozilla 1.177 + 1.178 +#endif /* mozilla_plugins_BrowserStreamChild_h */