Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(33)

Side by Side Diff: chrome/browser/media/router/offscreen_presentation_manager.cc

Issue 1314413005: [Presentation API] 1-UA presentation support + presenter APIs. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 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 "chrome/browser/media/router/offscreen_presentation_manager.h"
6
7 #include "base/memory/ptr_util.h"
8 #include "content/public/browser/render_frame_host.h"
9 #include "content/public/browser/render_process_host.h"
10 #include "content/public/browser/web_contents.h"
11
12 namespace media_router {
13
14 // OffscreenPresentationConnection implementation.
15 // ////////////////////////////////
16
17 OffscreenPresentationManager::OffscreenPresentationConnection::
18 OffscreenPresentationConnection(
19 OffscreenPresentationManager::OffscreenPresentationSession* session)
20 : session_(session) {
21 DCHECK(session_);
22 }
23
24 OffscreenPresentationManager::OffscreenPresentationConnection::
25 ~OffscreenPresentationConnection() {
26 if (session_) {
27 content::PresentationConnectionStateChangeInfo remove_reason(
28 content::PRESENTATION_CONNECTION_STATE_CLOSED);
29 remove_reason.close_reason =
30 content::PRESENTATION_CONNECTION_CLOSE_REASON_WENT_AWAY;
31 session_->RemoveConnection(this, remove_reason);
32 }
33 }
34
35 void OffscreenPresentationManager::OffscreenPresentationConnection::SendMessage(
36 std::unique_ptr<content::PresentationSessionMessage> message,
37 const content::SendMessageCallback& callback) {
38 if (!session_) {
39 callback.Run(false);
40 return;
41 }
42
43 session_->SendMessageFrom(this, std::move(message), callback);
44 }
45
46 void OffscreenPresentationManager::OffscreenPresentationConnection::
47 ListenForMessages(
48 const content::PresentationSessionMessageCallback& callback) {
49 DCHECK(messages_callback_.is_null());
50 DCHECK(!callback.is_null());
51 messages_callback_ = callback;
52 }
53
54 void OffscreenPresentationManager::OffscreenPresentationConnection::
55 ListenForStateChange(
56 const content::PresentationConnectionStateChangedCallback& callback) {
57 DCHECK(state_change_callback_.is_null());
58 DCHECK(!state_change_callback_.is_null());
59 state_change_callback_ = callback;
60 }
61
62 void OffscreenPresentationManager::OffscreenPresentationConnection::
63 RemoveFromPresentation(
64 const content::PresentationConnectionStateChangeInfo& remove_reason) {
65 if (session_) {
66 session_->RemoveConnection(this, remove_reason);
67 session_ = nullptr;
68 }
69 }
70
71 void OffscreenPresentationManager::OffscreenPresentationConnection::
72 OnConnectionStateChanged(
73 const content::PresentationConnectionStateChangeInfo& info) {
74 if (!state_change_callback_.is_null())
75 state_change_callback_.Run(info);
76
77 if (info.state == content::PRESENTATION_CONNECTION_STATE_CLOSED ||
78 info.state == content::PRESENTATION_CONNECTION_STATE_TERMINATED) {
79 session_ = nullptr;
80 }
81 }
82
83 void OffscreenPresentationManager::OffscreenPresentationConnection::
84 OnMessageReceived(
85 std::unique_ptr<content::PresentationSessionMessage> message) {
86 if (messages_callback_.is_null())
87 return;
88
89 // TODO(imcheng): Implement message queueing/batching.
90 ScopedVector<content::PresentationSessionMessage> messages;
91 messages.push_back(std::move(message));
92 messages_callback_.Run(messages, true);
93 }
94
95 // OffscreenPresentationManager implementation. ////////////////////////////////
96
97 OffscreenPresentationManager::~OffscreenPresentationManager() {}
98
99 void OffscreenPresentationManager::RegisterOffscreenPresentationReceiver(
100 const std::string& presentation_id,
101 const ReceiverConnectionAvailableCallback& receiver_available_callback) {
102 DCHECK(!ContainsKey(offscreen_presentations_, presentation_id));
103
104 offscreen_presentations_.insert(
105 std::make_pair(presentation_id,
106 base::WrapUnique(new OffscreenPresentation(
107 presentation_id, receiver_available_callback, this))));
108 }
109
110 void OffscreenPresentationManager::UnregisterOffscreenPresentationReceiver(
111 const std::string& presentation_id) {
112 DCHECK(ContainsKey(offscreen_presentations_, presentation_id));
113 offscreen_presentations_.erase(presentation_id);
114 }
115
116 std::unique_ptr<OffscreenPresentationManager::OffscreenPresentationConnection>
117 OffscreenPresentationManager::ConnectToOffscreenPresentation(
118 const std::string& presentation_id,
119 const RenderFrameHostId& controller_frame_id) {
120 auto it = offscreen_presentations_.find(presentation_id);
121 if (it == offscreen_presentations_.end())
122 return std::unique_ptr<OffscreenPresentationConnection>();
123
124 return it->second->AddSession(controller_frame_id);
125 }
126
127 OffscreenPresentationManager::OffscreenPresentationManager() {}
128
129 // OffscreenPresentationSession implementation. /////////////////////////////
130
131 OffscreenPresentationManager::OffscreenPresentationSession::
132 OffscreenPresentationSession(const RenderFrameHostId& controller_frame_id,
133 OffscreenPresentation* presentation)
134 : controller_frame_id_(controller_frame_id),
135 presentation_(presentation),
136 controller_(nullptr),
137 receiver_(nullptr) {
138 DCHECK(presentation_);
139 }
140
141 void OffscreenPresentationManager::OffscreenPresentationSession::Init(
142 OffscreenPresentationManager::OffscreenPresentationConnection* controller,
143 OffscreenPresentationManager::OffscreenPresentationConnection* receiver) {
144 DCHECK(!controller_);
145 DCHECK(!receiver_);
146 DCHECK(controller);
147 DCHECK(receiver);
148 controller_ = controller;
149 receiver_ = receiver;
150 }
151
152 OffscreenPresentationManager::OffscreenPresentationSession::
153 ~OffscreenPresentationSession() {
154 DCHECK(!controller_ || !receiver_);
155 }
156
157 void OffscreenPresentationManager::OffscreenPresentationSession::
158 RemoveConnection(
159 OffscreenPresentationConnection* connection,
160 const content::PresentationConnectionStateChangeInfo& remove_reason) {
161 DCHECK(connection);
162 OffscreenPresentationConnection* other_connection = nullptr;
163 if (connection == controller_) {
164 controller_ = nullptr;
165 other_connection = receiver_;
166 } else {
167 DCHECK(connection == receiver_);
168 receiver_ = nullptr;
169 other_connection = controller_;
170 }
171
172 DCHECK(other_connection);
173 other_connection->OnConnectionStateChanged(remove_reason);
174 presentation_->RemoveSession(controller_frame_id_);
175 // |this| is deleted beyond this point.
176 }
177
178 void OffscreenPresentationManager::OffscreenPresentationSession::
179 SendMessageFrom(
180 OffscreenPresentationConnection* connection,
181 std::unique_ptr<content::PresentationSessionMessage> message,
182 const content::SendMessageCallback& callback) {
183 OffscreenPresentationConnection* other_connection =
184 connection == controller_ ? receiver_ : controller_;
185 DCHECK(other_connection);
186
187 other_connection->OnMessageReceived(std::move(message));
188 callback.Run(true);
189 }
190
191 // OffscreenPresentation implementation. ///////////////////////////////////////
192
193 OffscreenPresentationManager::OffscreenPresentation::OffscreenPresentation(
194 const std::string& presentation_id,
195 const ReceiverConnectionAvailableCallback& receiver_available_callback,
196 OffscreenPresentationManager* manager)
197 : presentation_id_(presentation_id),
198 receiver_available_callback_(receiver_available_callback),
199 manager_(manager) {
200 DCHECK(!receiver_available_callback_.is_null());
201 DCHECK(manager_);
202 }
203
204 OffscreenPresentationManager::OffscreenPresentation::~OffscreenPresentation() {
205 // The receiver must have destroyed all connections before unregistration.
206 DCHECK(sessions_.empty());
207 }
208
209 std::unique_ptr<OffscreenPresentationManager::OffscreenPresentationConnection>
210 OffscreenPresentationManager::OffscreenPresentation::AddSession(
211 const RenderFrameHostId& controller_frame_id) {
212 if (ContainsKey(sessions_, controller_frame_id)) {
213 DLOG(ERROR) << "Frame " << controller_frame_id.first << ", "
214 << controller_frame_id.second << " already registered as a "
215 << "controller for presentation " << presentation_id_;
216 return std::unique_ptr<OffscreenPresentationConnection>();
217 }
218
219 std::unique_ptr<OffscreenPresentationSession> session(
220 new OffscreenPresentationSession(controller_frame_id, this));
221 std::unique_ptr<OffscreenPresentationConnection> controller_connection(
222 new OffscreenPresentationConnection(session.get()));
223 std::unique_ptr<OffscreenPresentationConnection> receiver_connection(
224 new OffscreenPresentationConnection(session.get()));
225
226 session->Init(controller_connection.get(), receiver_connection.get());
227 sessions_.insert(std::make_pair(controller_frame_id, std::move(session)));
228 receiver_available_callback_.Run(std::move(receiver_connection));
229 return controller_connection;
230 }
231
232 void OffscreenPresentationManager::OffscreenPresentation::RemoveSession(
233 const RenderFrameHostId& controller_frame_id) {
234 DCHECK(ContainsKey(sessions_, controller_frame_id));
235 sessions_.erase(controller_frame_id);
236 }
237
238 } // namespace media_router
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698