OLD | NEW |
| (Empty) |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #ifndef MEDIA_REMOTING_REMOTING_SOURCE_IMPL_H_ | |
6 #define MEDIA_REMOTING_REMOTING_SOURCE_IMPL_H_ | |
7 | |
8 #include <vector> | |
9 #include "base/callback.h" | |
10 #include "base/memory/weak_ptr.h" | |
11 #include "base/threading/thread_checker.h" | |
12 #include "media/mojo/interfaces/remoting.mojom.h" | |
13 #include "media/remoting/rpc/rpc_broker.h" | |
14 #include "mojo/public/cpp/bindings/binding.h" | |
15 | |
16 namespace media { | |
17 | |
18 // State transition diagram: | |
19 // | |
20 // .--> SESSION_UNAVAILABLE | |
21 // | | ^ | |
22 // | V | | |
23 // | SESSION_CAN_START | |
24 // | | | |
25 // | V | |
26 // | .---SESSION_STARTING --. | |
27 // | | | | | |
28 // | | V | | |
29 // | | SESSION_STARTED----| | |
30 // | | | | | |
31 // | | V | | |
32 // | '-> SESSION_STOPPING | | |
33 // '-----' | | | |
34 // V V | |
35 // SESSION_PERMANENTLY_STOPPED | |
36 | |
37 enum RemotingSessionState { | |
38 // Remoting sink is not available. Can't start remoting. | |
39 SESSION_UNAVAILABLE, | |
40 // Remoting sink is available, Can start remoting. | |
41 SESSION_CAN_START, | |
42 // Starting a remoting session. | |
43 SESSION_STARTING, | |
44 // Remoting session is successively started. | |
45 SESSION_STARTED, | |
46 // Stopping the session. | |
47 SESSION_STOPPING, | |
48 // Remoting session is permanently stopped. This state indicates that the | |
49 // video stack cannot continue operation. For example, if a remoting session | |
50 // involving CDM content was stopped, there is no way to continue playback | |
51 // because the CDM is required but is no longer available. | |
52 SESSION_PERMANENTLY_STOPPED, | |
53 }; | |
54 | |
55 // Maintains a single remoting session for multiple clients. The session will | |
56 // start remoting when receiving the first request. Once remoting is started, | |
57 // it will be stopped when any of the following happens: | |
58 // 1) Receives the request from any client to stop remoting. | |
59 // 2) Remote sink is gone. | |
60 // 3) Any client requests to permanently terminate the session. | |
61 // 4) All clients are destroyed. | |
62 // | |
63 // This class is ref-counted because, in some cases, an instance will have | |
64 // shared ownership between RemotingRendererController and | |
65 // RemotingCdmController. | |
66 class RemotingSourceImpl final | |
67 : public mojom::RemotingSource, | |
68 public base::RefCountedThreadSafe<RemotingSourceImpl> { | |
69 public: | |
70 class Client { | |
71 public: | |
72 // Get notified whether the remoting session is successively started. | |
73 virtual void OnStarted(bool success) = 0; | |
74 // Get notified when session state changes. | |
75 virtual void OnSessionStateChanged() = 0; | |
76 }; | |
77 | |
78 RemotingSourceImpl(mojom::RemotingSourceRequest source_request, | |
79 mojom::RemoterPtr remoter); | |
80 | |
81 // Get the current session state. | |
82 RemotingSessionState state() const { | |
83 DCHECK(thread_checker_.CalledOnValidThread()); | |
84 return state_; | |
85 } | |
86 | |
87 mojom::RemotingSinkCapabilities sink_capabilities() const { | |
88 return sink_capabilities_; | |
89 } | |
90 | |
91 bool is_remote_decryption_available() const { | |
92 return sink_capabilities_ == | |
93 mojom::RemotingSinkCapabilities::CONTENT_DECRYPTION_AND_RENDERING; | |
94 } | |
95 | |
96 // RemotingSource implementations. | |
97 void OnSinkAvailable(mojom::RemotingSinkCapabilities capabilities) override; | |
98 void OnSinkGone() override; | |
99 void OnStarted() override; | |
100 void OnStartFailed(mojom::RemotingStartFailReason reason) override; | |
101 void OnMessageFromSink(const std::vector<uint8_t>& message) override; | |
102 void OnStopped(mojom::RemotingStopReason reason) override; | |
103 | |
104 using DataPipeStartCallback = | |
105 base::Callback<void(mojom::RemotingDataStreamSenderPtrInfo audio, | |
106 mojom::RemotingDataStreamSenderPtrInfo video, | |
107 mojo::ScopedDataPipeProducerHandle audio_handle, | |
108 mojo::ScopedDataPipeProducerHandle video_handle)>; | |
109 void StartDataPipe(std::unique_ptr<mojo::DataPipe> audio_data_pipe, | |
110 std::unique_ptr<mojo::DataPipe> video_data_pipe, | |
111 const DataPipeStartCallback& done_callback); | |
112 | |
113 // Requests to start remoting. Will try start a remoting session if not | |
114 // started yet. |client| will get informed whether the session is | |
115 // successifully started throught OnStarted(). | |
116 void StartRemoting(Client* client); | |
117 | |
118 // Requests to stop the current remoting session if started. When the session | |
119 // is stopping, all clients will get notified. | |
120 void StopRemoting(Client* client); | |
121 | |
122 // Permanently terminates the current remoting session. | |
123 void Shutdown(); | |
124 | |
125 // Add/remove a client to/from |clients_|. | |
126 // Note: Clients can only added/removed through these methods. | |
127 // Remoting session will be stopped if all clients are gone. | |
128 void AddClient(Client* client); | |
129 void RemoveClient(Client* client); | |
130 | |
131 remoting::RpcBroker* GetRpcBroker() const; | |
132 | |
133 private: | |
134 friend class base::RefCountedThreadSafe<RemotingSourceImpl>; | |
135 ~RemotingSourceImpl() override; | |
136 | |
137 // Updates the current session state and notifies all the clients if state | |
138 // changes. | |
139 void UpdateAndNotifyState(RemotingSessionState state); | |
140 | |
141 // Callback from RpcBroker when sending message to remote sink. | |
142 void SendMessageToSink(std::unique_ptr<std::vector<uint8_t>> message); | |
143 | |
144 // TODO(xjz): Might merge RpcBroker into RemotingSourceImpl. | |
145 // Handle incomging and outgoing RPC message. | |
146 remoting::RpcBroker rpc_broker_; | |
147 | |
148 const mojo::Binding<mojom::RemotingSource> binding_; | |
149 const mojom::RemoterPtr remoter_; | |
150 | |
151 // When the sink is available, this describes its capabilities. When not | |
152 // available, this is always NONE. Updated by OnSinkAvailable/Gone(). | |
153 mojom::RemotingSinkCapabilities sink_capabilities_ = | |
154 mojom::RemotingSinkCapabilities::NONE; | |
155 | |
156 // The current state. | |
157 RemotingSessionState state_ = RemotingSessionState::SESSION_UNAVAILABLE; | |
158 | |
159 // Clients are added/removed to/from this list by calling Add/RemoveClient(). | |
160 // All the clients are not belong to this class. They are supposed to call | |
161 // RemoveClient() before they are gone. | |
162 std::vector<Client*> clients_; | |
163 | |
164 // This is used to check all the methods are called on the current thread in | |
165 // debug builds. | |
166 base::ThreadChecker thread_checker_; | |
167 }; | |
168 | |
169 } // namespace media | |
170 | |
171 #endif // MEDIA_REMOTING_REMOTING_SOURCE_IMPL_H_ | |
OLD | NEW |