1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
5  * You can obtain one at http://mozilla.org/MPL/2.0/. */
6 
7 #ifndef mozilla_extensions_StreamFilterChild_h
8 #define mozilla_extensions_StreamFilterChild_h
9 
10 #include "StreamFilterBase.h"
11 #include "mozilla/extensions/PStreamFilterChild.h"
12 #include "mozilla/extensions/StreamFilter.h"
13 
14 #include "mozilla/LinkedList.h"
15 #include "mozilla/dom/StreamFilterBinding.h"
16 #include "nsISupportsImpl.h"
17 
18 namespace mozilla {
19 class ErrorResult;
20 
21 namespace extensions {
22 
23 using mozilla::dom::StreamFilterStatus;
24 using mozilla::ipc::IPCResult;
25 
26 class StreamFilter;
27 
28 class StreamFilterChild final : public PStreamFilterChild,
29                                 public StreamFilterBase {
30   friend class StreamFilter;
31   friend class PStreamFilterChild;
32 
33  public:
NS_INLINE_DECL_REFCOUNTING(StreamFilterChild)34   NS_INLINE_DECL_REFCOUNTING(StreamFilterChild)
35 
36   StreamFilterChild() : mState(State::Uninitialized), mReceivedOnStop(false) {}
37 
38   enum class State {
39     // Uninitialized, waiting for constructor response from parent.
40     Uninitialized,
41     // Initialized, but channel has not begun transferring data.
42     Initialized,
43     // The stream's OnStartRequest event has been dispatched, and the channel is
44     // transferring data.
45     TransferringData,
46     // The channel's OnStopRequest event has been dispatched, and the channel is
47     // no longer transferring data. Data may still be written to the output
48     // stream listener.
49     FinishedTransferringData,
50     // The channel is being suspended, and we're waiting for confirmation of
51     // suspension from the parent.
52     Suspending,
53     // The channel has been suspended in the parent. Data may still be written
54     // to the output stream listener in this state.
55     Suspended,
56     // The channel is suspended. Resume has been called, and we are waiting for
57     // confirmation of resumption from the parent.
58     Resuming,
59     // The close() method has been called, and no further output may be written.
60     // We are waiting for confirmation from the parent.
61     Closing,
62     // The close() method has been called, and we have been disconnected from
63     // our parent.
64     Closed,
65     // The channel is being disconnected from the parent, and all further events
66     // and data will pass unfiltered. Data received by the child in this state
67     // will be automatically written to the output stream listener. No data may
68     // be explicitly written.
69     Disconnecting,
70     // The channel has been disconnected from the parent, and all further data
71     // and events will be transparently passed to the output stream listener
72     // without passing through the child.
73     Disconnected,
74     // An error has occurred and the child is disconnected from the parent.
75     Error,
76   };
77 
78   void Suspend(ErrorResult& aRv);
79   void Resume(ErrorResult& aRv);
80   void Disconnect(ErrorResult& aRv);
81   void Close(ErrorResult& aRv);
82   void Cleanup();
83 
84   void Write(Data&& aData, ErrorResult& aRv);
85 
GetState()86   State GetState() const { return mState; }
87 
88   StreamFilterStatus Status() const;
89 
90   void RecvInitialized(bool aSuccess);
91 
92  protected:
93   IPCResult RecvStartRequest();
94   IPCResult RecvData(Data&& data);
95   IPCResult RecvStopRequest(const nsresult& aStatus);
96   IPCResult RecvError(const nsCString& aError);
97 
98   IPCResult RecvClosed();
99   IPCResult RecvSuspended();
100   IPCResult RecvResumed();
101   IPCResult RecvFlushData();
102 
103   virtual void ActorDealloc() override;
104 
SetStreamFilter(StreamFilter * aStreamFilter)105   void SetStreamFilter(StreamFilter* aStreamFilter) {
106     mStreamFilter = aStreamFilter;
107   }
108 
109  private:
110   ~StreamFilterChild() = default;
111 
112   void SetNextState();
113 
114   void MaybeStopRequest();
115 
116   void EmitData(const Data& aData);
117 
CanFlushData()118   bool CanFlushData() {
119     return (mState == State::TransferringData || mState == State::Resuming);
120   }
121 
122   void FlushBufferedData();
123   void WriteBufferedData();
124 
125   virtual void ActorDestroy(ActorDestroyReason aWhy) override;
126 
127   State mState;
128   State mNextState;
129   bool mReceivedOnStop;
130 
131   RefPtr<StreamFilter> mStreamFilter;
132 };
133 
134 }  // namespace extensions
135 }  // namespace mozilla
136 
137 #endif  // mozilla_extensions_StreamFilterChild_h
138