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

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: addressed yuri's comments #16 Created 5 years, 2 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 "content/public/browser/presentation_session_state_listener.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 OffscreenPresentationManager::OffscreenPresentationSession::
15 OffscreenPresentationSession(
16 OffscreenPresentationManager::OffscreenPresentationConnection*
17 connection)
18 : state_change_listener_(nullptr), connection_(connection) {
19 DCHECK(connection_);
20 }
21
22 OffscreenPresentationManager::OffscreenPresentationSession::
23 ~OffscreenPresentationSession() {
24 if (connection_)
25 connection_->RemoveSession(this);
26 }
27
28 void OffscreenPresentationManager::OffscreenPresentationSession::SendMessage(
29 scoped_ptr<content::PresentationSessionMessage> message,
30 const content::SendMessageCallback& callback) {
31 if (!connection_) {
32 callback.Run(false);
33 return;
34 }
35
36 connection_->SendMessageFrom(this, message.Pass(), callback);
37 }
38
39 void OffscreenPresentationManager::OffscreenPresentationSession::
40 ListenForMessages(
41 const content::PresentationSessionMessageCallback& callback) {
42 DCHECK(messages_callback_.is_null());
43 messages_callback_ = callback;
44 }
45
46 void OffscreenPresentationManager::OffscreenPresentationSession::
47 ListenForStateChanges(content::PresentationSessionStateListener* listener) {
48 DCHECK(!state_change_listener_);
49 state_change_listener_ = listener;
whywhat 2015/10/13 15:21:30 nit: DCHECK(listener);
imcheng 2015/10/17 01:00:23 Done.
50 }
51
52 void OffscreenPresentationManager::OffscreenPresentationSession::
53 OnSessionStateChanged(content::PresentationSessionState state) {
54 if (state_change_listener_)
whywhat 2015/10/13 15:21:30 Shouldn't be a DCHECK rather so we always have a l
imcheng 2015/10/17 01:00:23 I wouldn't expect a listener to always exist when
55 state_change_listener_->OnSessionStateChanged(state);
56
57 if (state == content::PRESENTATION_SESSION_STATE_DISCONNECTED)
58 connection_ = nullptr;
59 }
60
61 void OffscreenPresentationManager::OffscreenPresentationSession::
62 OnMessageReceived(scoped_ptr<content::PresentationSessionMessage> message) {
63 if (!messages_callback_.is_null()) {
whywhat 2015/10/13 15:21:30 nit: Seems like the inverse condition would be mor
imcheng 2015/10/17 01:00:23 Done. For queueing, it can be done along with batc
64 ScopedVector<content::PresentationSessionMessage> messages;
mark a. foltz 2015/10/12 21:56:10 Please add a TODO to handle multiple messages at o
imcheng 2015/10/17 01:00:23 Moved comment from OffscreenPresentationConnection
65 messages.push_back(message.release());
66 messages_callback_.Run(messages.Pass(), true);
67 }
68 }
69
70 OffscreenPresentationManager::~OffscreenPresentationManager() {}
71
72 void OffscreenPresentationManager::RegisterOffscreenPresentationReceiver(
73 const std::string& presentation_id,
74 const ReceiverSessionAvailableCallback& receiver_available_callback) {
75 DCHECK(!ContainsKey(offscreen_presentations_, presentation_id));
mark a. foltz 2015/10/12 21:56:10 How do you intend to handle this case in release b
imcheng 2015/10/17 01:00:23 This is a "can't happen" situation since the prese
76
77 offscreen_presentations_.insert(
78 presentation_id,
79 make_scoped_ptr(new OffscreenPresentation(
80 presentation_id, receiver_available_callback, this)));
81 }
82
83 void OffscreenPresentationManager::UnregisterOffscreenPresentationReceiver(
84 const std::string& presentation_id) {
85 DCHECK(ContainsKey(offscreen_presentations_, presentation_id));
mark a. foltz 2015/10/12 21:56:10 Similar comments
imcheng 2015/10/17 01:00:23 Ditto.
86 offscreen_presentations_.erase(presentation_id);
87 }
88
89 scoped_ptr<OffscreenPresentationManager::OffscreenPresentationSession>
90 OffscreenPresentationManager::ConnectToOffscreenPresentation(
91 const std::string& presentation_id,
92 const RenderFrameHostId& controller_frame_id) {
93 auto it = offscreen_presentations_.find(presentation_id);
94 if (it == offscreen_presentations_.end())
95 return scoped_ptr<OffscreenPresentationSession>();
96
97 return it->second->AddConnection(controller_frame_id);
98 }
99
100 OffscreenPresentationManager::OffscreenPresentationManager() {}
101
102 OffscreenPresentationManager::OffscreenPresentationConnection::
103 OffscreenPresentationConnection(
104 const RenderFrameHostId& controller_frame_id,
105 OffscreenPresentation* presentation)
106 : controller_frame_id_(controller_frame_id),
107 presentation_(presentation),
108 controller_(nullptr),
109 receiver_(nullptr) {
110 DCHECK(presentation_);
111 }
112
113 void OffscreenPresentationManager::OffscreenPresentationConnection::Init(
114 OffscreenPresentationManager::OffscreenPresentationSession* controller,
115 OffscreenPresentationManager::OffscreenPresentationSession* receiver) {
116 DCHECK(!controller_);
117 DCHECK(!receiver_);
118 DCHECK(controller);
119 DCHECK(receiver);
120 controller_ = controller;
121 receiver_ = receiver;
122 }
123
124 OffscreenPresentationManager::OffscreenPresentationConnection::
125 ~OffscreenPresentationConnection() {
126 DCHECK(!controller_ || !receiver_);
127 }
128
129 void OffscreenPresentationManager::OffscreenPresentationConnection::
130 RemoveSession(OffscreenPresentationSession* session) {
131 DCHECK(session);
132 OffscreenPresentationManager::OffscreenPresentationSession* other_session =
133 nullptr;
134 if (session == controller_) {
135 controller_ = nullptr;
136 other_session = receiver_;
137 } else {
138 DCHECK(session == receiver_);
139 receiver_ = nullptr;
140 other_session = controller_;
141 }
142
143 DCHECK(other_session);
144 other_session->OnSessionStateChanged(
145 content::PRESENTATION_SESSION_STATE_DISCONNECTED);
146 presentation_->RemoveConnection(controller_frame_id_);
147 // |this| is deleted beyond this point.
148 }
149
150 void OffscreenPresentationManager::OffscreenPresentationConnection::
151 SendMessageFrom(OffscreenPresentationSession* session,
152 scoped_ptr<content::PresentationSessionMessage> message,
153 const content::SendMessageCallback& callback) {
154 OffscreenPresentationManager::OffscreenPresentationSession* other_session =
155 session == controller_ ? receiver_ : controller_;
156 DCHECK(other_session);
157
158 // TODO(imcheng): Implement message batching.
159 session->OnMessageReceived(message.Pass());
whywhat 2015/10/13 15:21:30 Did you mean other_session?
imcheng 2015/10/17 01:00:23 Done. Good catch, thanks!
160 callback.Run(true);
161 }
162
163 OffscreenPresentationManager::OffscreenPresentation::OffscreenPresentation(
164 const std::string& presentation_id,
165 const ReceiverSessionAvailableCallback& receiver_available_callback,
166 OffscreenPresentationManager* manager)
167 : presentation_id_(presentation_id),
168 receiver_available_callback_(receiver_available_callback),
169 manager_(manager) {
170 DCHECK(!receiver_available_callback_.is_null());
171 DCHECK(manager_);
172 }
173
174 OffscreenPresentationManager::OffscreenPresentation::~OffscreenPresentation() {
175 // The receiver must have destroyed all connections before unregistration.
mark a. foltz 2015/10/12 21:56:10 Can unregistration do this as a side effect? It w
imcheng 2015/10/17 01:00:23 All of the scenarios should already be covered by
176 DCHECK(connections_.empty());
177 }
178
179 scoped_ptr<OffscreenPresentationManager::OffscreenPresentationSession>
180 OffscreenPresentationManager::OffscreenPresentation::AddConnection(
181 const RenderFrameHostId& controller_frame_id) {
182 DCHECK(!ContainsKey(connections_, controller_frame_id));
mark a. foltz 2015/10/12 21:56:10 Behavior in release builds?
imcheng 2015/10/17 01:00:23 Changed this to LOG(ERROR) and return nullptr. In
183
184 scoped_ptr<OffscreenPresentationConnection> connection(
185 new OffscreenPresentationConnection(controller_frame_id, this));
186 scoped_ptr<OffscreenPresentationSession> controller_session(
187 new OffscreenPresentationSession(connection.get()));
188 scoped_ptr<OffscreenPresentationSession> receiver_session(
189 new OffscreenPresentationSession(connection.get()));
190
191 connection->Init(controller_session.get(), receiver_session.get());
192 connections_.insert(controller_frame_id, connection.Pass());
193 receiver_available_callback_.Run(receiver_session.Pass());
194 return controller_session.Pass();
195 }
196
197 void OffscreenPresentationManager::OffscreenPresentation::RemoveConnection(
198 const RenderFrameHostId& controller_frame_id) {
199 DCHECK(ContainsKey(connections_, controller_frame_id));
mark a. foltz 2015/10/12 21:56:10 Ditto
imcheng 2015/10/17 01:00:23 erase() is no-op is key is not found so we should
200 connections_.erase(controller_frame_id);
201 }
202
203 } // namespace media_router
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698