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 #include "media/remoting/remoting_source_impl.h" | |
6 | |
7 #include "base/bind.h" | |
8 #include "base/logging.h" | |
9 | |
10 namespace media { | |
11 | |
12 RemotingSourceImpl::RemotingSourceImpl( | |
13 mojom::RemotingSourceRequest source_request, | |
14 mojom::RemoterPtr remoter) | |
15 : binding_(this, std::move(source_request)), remoter_(std::move(remoter)) {} | |
16 | |
17 RemotingSourceImpl::~RemotingSourceImpl() { | |
18 DCHECK(thread_checker_.CalledOnValidThread()); | |
19 | |
20 if (!clients_.empty()) { | |
21 Shutdown(); | |
22 clients_.clear(); | |
23 } | |
24 } | |
25 | |
26 void RemotingSourceImpl::OnSinkAvailable() { | |
27 DCHECK(thread_checker_.CalledOnValidThread()); | |
28 | |
29 if (state_ == RemotingSessionState::SESSION_UNAVAILABLE) | |
30 UpdateAndNotifyState(RemotingSessionState::SESSION_CAN_START); | |
31 } | |
32 | |
33 void RemotingSourceImpl::OnSinkGone() { | |
34 DCHECK(thread_checker_.CalledOnValidThread()); | |
35 | |
36 if (state_ == RemotingSessionState::SESSION_PERMANENTLY_STOPPED) | |
37 return; | |
38 if (state_ == RemotingSessionState::SESSION_CAN_START) { | |
39 UpdateAndNotifyState(RemotingSessionState::SESSION_UNAVAILABLE); | |
40 return; | |
41 } | |
42 if (state_ == RemotingSessionState::SESSION_STARTED || | |
43 state_ == RemotingSessionState::SESSION_STARTING) { | |
44 VLOG(1) << "Sink is gone in a remoting session."; | |
45 // Remoting is being stopped by Remoter. | |
46 UpdateAndNotifyState(RemotingSessionState::SESSION_STOPPING); | |
47 } | |
48 } | |
49 | |
50 void RemotingSourceImpl::OnStarted() { | |
51 DCHECK(thread_checker_.CalledOnValidThread()); | |
52 | |
53 VLOG(1) << "Remoting started successively."; | |
54 if (clients_.empty() || | |
55 state_ == RemotingSessionState::SESSION_PERMANENTLY_STOPPED || | |
56 state_ == RemotingSessionState::SESSION_STOPPING) { | |
57 for (Client* client : clients_) | |
58 client->OnStarted(false); | |
59 return; | |
60 } | |
61 for (Client* client : clients_) | |
62 client->OnStarted(true); | |
xhwang
2016/11/01 08:21:29
Actually you notify all clients, so the comment is
xjz
2016/11/01 21:55:53
In general, no. Only when there are requests from
| |
63 state_ = RemotingSessionState::SESSION_STARTED; | |
64 } | |
65 | |
66 void RemotingSourceImpl::OnStartFailed(mojom::RemotingStartFailReason reason) { | |
67 DCHECK(thread_checker_.CalledOnValidThread()); | |
68 | |
69 VLOG(1) << "Failed to start remoting:" << reason; | |
70 for (Client* client : clients_) | |
71 client->OnStarted(false); | |
72 if (state_ == RemotingSessionState::SESSION_PERMANENTLY_STOPPED) | |
73 return; | |
74 state_ = RemotingSessionState::SESSION_UNAVAILABLE; | |
75 } | |
76 | |
77 void RemotingSourceImpl::OnStopped(mojom::RemotingStopReason reason) { | |
78 DCHECK(thread_checker_.CalledOnValidThread()); | |
79 | |
80 VLOG(1) << "Remoting stopped: " << reason; | |
81 if (state_ == RemotingSessionState::SESSION_PERMANENTLY_STOPPED) | |
82 return; | |
83 RemotingSessionState state = RemotingSessionState::SESSION_UNAVAILABLE; | |
84 UpdateAndNotifyState(state); | |
85 } | |
86 | |
87 void RemotingSourceImpl::OnMessageFromSink( | |
88 const std::vector<uint8_t>& message) { | |
89 DCHECK(thread_checker_.CalledOnValidThread()); | |
90 | |
91 // TODO(xjz): Merge with Eric's CL to handle the RPC messages here. | |
92 NOTIMPLEMENTED(); | |
93 } | |
94 | |
95 void RemotingSourceImpl::UpdateAndNotifyState(RemotingSessionState state) { | |
96 DCHECK(thread_checker_.CalledOnValidThread()); | |
97 | |
98 if (state_ == state) | |
99 return; | |
100 state_ = state; | |
101 for (Client* client : clients_) | |
102 client->OnSessionStateChanged(); | |
103 } | |
104 | |
105 void RemotingSourceImpl::StartRemoting(Client* client) { | |
106 DCHECK(std::find(clients_.begin(), clients_.end(), client) != clients_.end()); | |
107 | |
108 switch (state_) { | |
109 case SESSION_CAN_START: | |
110 remoter_->Start(); | |
111 UpdateAndNotifyState(RemotingSessionState::SESSION_STARTING); | |
112 break; | |
113 case SESSION_STARTING: | |
114 break; | |
115 case SESSION_STARTED: | |
116 client->OnStarted(true); | |
117 break; | |
118 case SESSION_STOPPING: | |
119 case SESSION_UNAVAILABLE: | |
120 case SESSION_PERMANENTLY_STOPPED: | |
121 client->OnStarted(false); | |
xhwang
2016/11/01 08:21:29
hmm, now I see why you have |client|...
Does it m
xjz
2016/11/01 21:55:53
That may make the switching logic more complicate.
| |
122 break; | |
123 } | |
124 } | |
125 | |
126 void RemotingSourceImpl::StopRemoting(Client* client) { | |
127 DCHECK(std::find(clients_.begin(), clients_.end(), client) != clients_.end()); | |
128 | |
129 VLOG(1) << "RemotingSourceImpl::StopRemoting: " << state_; | |
130 | |
131 if (state_ != RemotingSessionState::SESSION_STARTING && | |
132 state_ != RemotingSessionState::SESSION_STARTED) | |
133 return; | |
134 | |
135 remoter_->Stop(mojom::RemotingStopReason::LOCAL_PLAYBACK); | |
136 UpdateAndNotifyState(RemotingSessionState::SESSION_STOPPING); | |
137 } | |
138 | |
139 void RemotingSourceImpl::AddClient(Client* client) { | |
140 DCHECK(thread_checker_.CalledOnValidThread()); | |
141 | |
142 if (std::find(clients_.begin(), clients_.end(), client) != clients_.end()) | |
143 return; | |
xhwang
2016/11/01 08:21:29
If this happens, it'll be a programming error... D
xjz
2016/11/01 21:55:53
Done.
| |
144 clients_.push_back(client); | |
145 client->OnSessionStateChanged(); | |
146 } | |
147 | |
148 void RemotingSourceImpl::RemoveClient(Client* client) { | |
149 DCHECK(thread_checker_.CalledOnValidThread()); | |
150 | |
151 auto it = std::find(clients_.begin(), clients_.end(), client); | |
152 if (it == clients_.end()) | |
153 return; | |
xhwang
2016/11/01 08:21:29
ditto, DCHECK?
xjz
2016/11/01 21:55:53
Done.
| |
154 | |
155 clients_.erase(it); | |
156 if (clients_.empty() && (state_ == RemotingSessionState::SESSION_STARTED || | |
157 state_ == RemotingSessionState::SESSION_STARTING)) { | |
158 remoter_->Stop(mojom::RemotingStopReason::SOURCE_GONE); | |
159 state_ = RemotingSessionState::SESSION_STOPPING; | |
160 } | |
161 } | |
162 | |
163 void RemotingSourceImpl::Shutdown() { | |
164 DCHECK(thread_checker_.CalledOnValidThread()); | |
165 | |
166 if (state_ == RemotingSessionState::SESSION_STARTED || | |
167 state_ == RemotingSessionState::SESSION_STARTING) | |
168 remoter_->Stop(mojom::RemotingStopReason::UNEXPECTED_FAILURE); | |
169 UpdateAndNotifyState(RemotingSessionState::SESSION_PERMANENTLY_STOPPED); | |
170 } | |
171 | |
172 } // namespace media | |
OLD | NEW |