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

Side by Side Diff: chrome/browser/ui/webui/media_router/media_router_ui.cc

Issue 1224093004: [Media Router] 2nd take on fix route response callback lifetime in UI. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 5 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
1 // Copyright 2015 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/ui/webui/media_router/media_router_ui.h" 5 #include "chrome/browser/ui/webui/media_router/media_router_ui.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "base/strings/string_util.h" 9 #include "base/strings/string_util.h"
10 #include "chrome/browser/media/router/create_session_request.h"
11 #include "chrome/browser/media/router/issue.h" 10 #include "chrome/browser/media/router/issue.h"
12 #include "chrome/browser/media/router/issues_observer.h" 11 #include "chrome/browser/media/router/issues_observer.h"
13 #include "chrome/browser/media/router/media_route.h" 12 #include "chrome/browser/media/router/media_route.h"
14 #include "chrome/browser/media/router/media_router.h" 13 #include "chrome/browser/media/router/media_router.h"
15 #include "chrome/browser/media/router/media_router_mojo_impl.h" 14 #include "chrome/browser/media/router/media_router_mojo_impl.h"
16 #include "chrome/browser/media/router/media_router_mojo_impl_factory.h" 15 #include "chrome/browser/media/router/media_router_mojo_impl_factory.h"
17 #include "chrome/browser/media/router/media_routes_observer.h" 16 #include "chrome/browser/media/router/media_routes_observer.h"
18 #include "chrome/browser/media/router/media_sink.h" 17 #include "chrome/browser/media/router/media_sink.h"
19 #include "chrome/browser/media/router/media_sinks_observer.h" 18 #include "chrome/browser/media/router/media_sinks_observer.h"
20 #include "chrome/browser/media/router/media_source.h" 19 #include "chrome/browser/media/router/media_source.h"
21 #include "chrome/browser/media/router/media_source_helper.h" 20 #include "chrome/browser/media/router/media_source_helper.h"
22 #include "chrome/browser/media/router/presentation_service_delegate_impl.h" 21 #include "chrome/browser/media/router/presentation_service_delegate_impl.h"
23 #include "chrome/browser/profiles/profile.h" 22 #include "chrome/browser/profiles/profile.h"
24 #include "chrome/browser/sessions/session_tab_helper.h" 23 #include "chrome/browser/sessions/session_tab_helper.h"
24 #include "chrome/browser/ui/webui/media_router/media_router_dialog_controller.h"
25 #include "chrome/browser/ui/webui/media_router/media_router_localized_strings_pr ovider.h" 25 #include "chrome/browser/ui/webui/media_router/media_router_localized_strings_pr ovider.h"
26 #include "chrome/browser/ui/webui/media_router/media_router_resources_provider.h " 26 #include "chrome/browser/ui/webui/media_router/media_router_resources_provider.h "
27 #include "chrome/browser/ui/webui/media_router/media_router_webui_message_handle r.h" 27 #include "chrome/browser/ui/webui/media_router/media_router_webui_message_handle r.h"
28 #include "chrome/common/url_constants.h" 28 #include "chrome/common/url_constants.h"
29 #include "content/public/browser/web_contents.h" 29 #include "content/public/browser/web_contents.h"
30 #include "content/public/browser/web_ui.h" 30 #include "content/public/browser/web_ui.h"
31 #include "content/public/browser/web_ui_data_source.h" 31 #include "content/public/browser/web_ui_data_source.h"
32 #include "ui/web_dialogs/web_dialog_delegate.h" 32 #include "ui/web_dialogs/web_dialog_delegate.h"
33 33
34 namespace media_router { 34 namespace media_router {
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
84 84
85 DISALLOW_COPY_AND_ASSIGN(UIMediaRoutesObserver); 85 DISALLOW_COPY_AND_ASSIGN(UIMediaRoutesObserver);
86 }; 86 };
87 87
88 MediaRouterUI::MediaRouterUI(content::WebUI* web_ui) 88 MediaRouterUI::MediaRouterUI(content::WebUI* web_ui)
89 : ConstrainedWebDialogUI(web_ui), 89 : ConstrainedWebDialogUI(web_ui),
90 handler_(new MediaRouterWebUIMessageHandler()), 90 handler_(new MediaRouterWebUIMessageHandler()),
91 ui_initialized_(false), 91 ui_initialized_(false),
92 has_pending_route_request_(false), 92 has_pending_route_request_(false),
93 requesting_route_for_default_source_(false), 93 requesting_route_for_default_source_(false),
94 dialog_callbacks_(nullptr),
94 initiator_(nullptr), 95 initiator_(nullptr),
95 router_(nullptr), 96 router_(nullptr),
96 weak_factory_(this) { 97 weak_factory_(this) {
97 // Create a WebUIDataSource containing the chrome://media-router page's 98 // Create a WebUIDataSource containing the chrome://media-router page's
98 // content. 99 // content.
99 scoped_ptr<content::WebUIDataSource> html_source( 100 scoped_ptr<content::WebUIDataSource> html_source(
100 content::WebUIDataSource::Create(chrome::kChromeUIMediaRouterHost)); 101 content::WebUIDataSource::Create(chrome::kChromeUIMediaRouterHost));
101 102
102 content::WebContents* wc = web_ui->GetWebContents(); 103 content::WebContents* wc = web_ui->GetWebContents();
103 DCHECK(wc); 104 DCHECK(wc);
(...skipping 10 matching lines...) Expand all
114 115
115 // Ownership of |handler_| is transferred to |web_ui|. 116 // Ownership of |handler_| is transferred to |web_ui|.
116 web_ui->AddMessageHandler(handler_); 117 web_ui->AddMessageHandler(handler_);
117 } 118 }
118 119
119 MediaRouterUI::~MediaRouterUI() { 120 MediaRouterUI::~MediaRouterUI() {
120 if (query_result_manager_.get()) 121 if (query_result_manager_.get())
121 query_result_manager_->RemoveObserver(this); 122 query_result_manager_->RemoveObserver(this);
122 if (presentation_service_delegate_.get()) 123 if (presentation_service_delegate_.get())
123 presentation_service_delegate_->RemoveDefaultMediaSourceObserver(this); 124 presentation_service_delegate_->RemoveDefaultMediaSourceObserver(this);
125 if (dialog_callbacks_)
126 dialog_callbacks_->OnDialogDestroyed(requesting_route_for_default_source_);
124 } 127 }
125 128
126 void MediaRouterUI::InitWithDefaultMediaSource( 129 void MediaRouterUI::InitWithDefaultMediaSource(
127 PresentationServiceDelegateImpl* delegate) { 130 const base::WeakPtr<PresentationServiceDelegateImpl>& delegate,
131 MediaRouterDialogCallbacks* dialog_callbacks) {
128 DCHECK(delegate); 132 DCHECK(delegate);
133 DCHECK(dialog_callbacks);
129 DCHECK(!presentation_service_delegate_); 134 DCHECK(!presentation_service_delegate_);
130 DCHECK(!query_result_manager_.get()); 135 DCHECK(!query_result_manager_.get());
131 136
132 presentation_service_delegate_ = delegate->GetWeakPtr(); 137 presentation_service_delegate_ = delegate;
133 presentation_service_delegate_->AddDefaultMediaSourceObserver(this); 138 presentation_service_delegate_->AddDefaultMediaSourceObserver(this);
134 InitCommon(presentation_service_delegate_->web_contents(), 139 InitCommon(presentation_service_delegate_->web_contents(),
135 presentation_service_delegate_->default_source(), 140 presentation_service_delegate_->default_source(),
136 presentation_service_delegate_->default_frame_url()); 141 presentation_service_delegate_->default_frame_url(),
142 dialog_callbacks);
137 } 143 }
138 144
139 void MediaRouterUI::InitWithPresentationSessionRequest( 145 void MediaRouterUI::InitWithPresentationSessionRequest(
140 const content::WebContents* initiator, 146 const content::WebContents* initiator,
141 scoped_ptr<CreateSessionRequest> request) { 147 MediaRouterDialogCallbacks* dialog_callbacks) {
142 DCHECK(request.get()); 148 DCHECK(initiator);
143 DCHECK(!presentation_session_request_.get()); 149 DCHECK(dialog_callbacks);
144 DCHECK(!query_result_manager_.get()); 150 DCHECK(!query_result_manager_.get());
145 151
146 presentation_session_request_ = request.Pass(); 152 const CreateSessionRequest* presentation_request =
147 InitCommon(initiator, presentation_session_request_->GetMediaSource(), 153 dialog_callbacks->presentation_request();
148 presentation_session_request_->frame_url()); 154 DCHECK(presentation_request);
155 InitCommon(initiator, presentation_request->GetMediaSource(),
156 presentation_request->frame_url(), dialog_callbacks);
149 } 157 }
150 158
151 void MediaRouterUI::InitCommon(const content::WebContents* initiator, 159 void MediaRouterUI::InitCommon(const content::WebContents* initiator,
152 const MediaSource& default_source, 160 const MediaSource& default_source,
153 const GURL& default_frame_url) { 161 const GURL& default_frame_url,
162 MediaRouterDialogCallbacks* dialog_callbacks) {
154 DCHECK(initiator); 163 DCHECK(initiator);
164 DCHECK(dialog_callbacks);
165
166 dialog_callbacks_ = dialog_callbacks;
167 dialog_callbacks_->set_route_response_cb(base::Bind(
168 &MediaRouterUI::OnRouteResponseReceived, weak_factory_.GetWeakPtr()));
155 169
156 // Register for Issue and MediaRoute updates. 170 // Register for Issue and MediaRoute updates.
157 issues_observer_.reset(new UIIssuesObserver(router_, this)); 171 issues_observer_.reset(new UIIssuesObserver(router_, this));
158 routes_observer_.reset(new UIMediaRoutesObserver(router_, this)); 172 routes_observer_.reset(new UIMediaRoutesObserver(router_, this));
159 173
160 query_result_manager_.reset(new QueryResultManager(router_)); 174 query_result_manager_.reset(new QueryResultManager(router_));
161 query_result_manager_->AddObserver(this); 175 query_result_manager_->AddObserver(this);
162 176
163 // These modes are always available. 177 // These modes are always available.
164 // Use the same MediaSource for all mirroring modes for now. 178 // Use the same MediaSource for all mirroring modes for now.
(...skipping 14 matching lines...) Expand all
179 void MediaRouterUI::OnDefaultMediaSourceChanged(const MediaSource& source, 193 void MediaRouterUI::OnDefaultMediaSourceChanged(const MediaSource& source,
180 const GURL& frame_url) { 194 const GURL& frame_url) {
181 if (source.Empty()) { 195 if (source.Empty()) {
182 query_result_manager_->StopSinksQuery(MediaCastMode::DEFAULT); 196 query_result_manager_->StopSinksQuery(MediaCastMode::DEFAULT);
183 } else { 197 } else {
184 query_result_manager_->StartSinksQuery(MediaCastMode::DEFAULT, source); 198 query_result_manager_->StartSinksQuery(MediaCastMode::DEFAULT, source);
185 } 199 }
186 UpdateSourceHostAndCastModes(frame_url); 200 UpdateSourceHostAndCastModes(frame_url);
187 } 201 }
188 202
189 void MediaRouterUI::HandleRouteResponseForPresentation(
190 const MediaRoute* route,
191 const std::string& error) {
192 if (!route) {
193 presentation_session_request_->MaybeInvokeErrorCallback(
194 content::PresentationError(content::PRESENTATION_ERROR_UNKNOWN, error));
195 } else {
196 // TODO(imcheng): Presentation ID should come from the response
197 // as the IDs might not be the same.
198 presentation_session_request_->MaybeInvokeSuccessCallback(
199 route->media_route_id());
200 }
201 }
202
203 void MediaRouterUI::UpdateSourceHostAndCastModes(const GURL& frame_url) { 203 void MediaRouterUI::UpdateSourceHostAndCastModes(const GURL& frame_url) {
204 DCHECK(query_result_manager_); 204 DCHECK(query_result_manager_);
205 frame_url_ = frame_url; 205 frame_url_ = frame_url;
206 query_result_manager_->GetSupportedCastModes(&cast_modes_); 206 query_result_manager_->GetSupportedCastModes(&cast_modes_);
207 if (ui_initialized_) 207 if (ui_initialized_)
208 handler_->UpdateCastModes(cast_modes_, GetHostFromURL(frame_url_)); 208 handler_->UpdateCastModes(cast_modes_, GetHostFromURL(frame_url_));
209 } 209 }
210 210
211 void MediaRouterUI::Close() { 211 void MediaRouterUI::Close() {
212 if (presentation_session_request_.get()) {
213 presentation_session_request_->MaybeInvokeErrorCallback(
214 content::PresentationError(
215 content::PRESENTATION_ERROR_SESSION_REQUEST_CANCELLED,
216 "Dialog closed."));
217 }
218
219 ConstrainedWebDialogDelegate* delegate = GetConstrainedDelegate(); 212 ConstrainedWebDialogDelegate* delegate = GetConstrainedDelegate();
220 if (delegate) { 213 if (delegate) {
221 delegate->GetWebDialogDelegate()->OnDialogClosed(std::string()); 214 delegate->GetWebDialogDelegate()->OnDialogClosed(std::string());
222 delegate->OnDialogCloseFromWebUI(); 215 delegate->OnDialogCloseFromWebUI();
223 } 216 }
224 } 217 }
225 218
226 void MediaRouterUI::UIInitialized() { 219 void MediaRouterUI::UIInitialized() {
227 ui_initialized_ = true; 220 ui_initialized_ = true;
228 } 221 }
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
266 if (ui_initialized_) 259 if (ui_initialized_)
267 handler_->UpdateIssue(issue); 260 handler_->UpdateIssue(issue);
268 } 261 }
269 262
270 void MediaRouterUI::OnRoutesUpdated(const std::vector<MediaRoute>& routes) { 263 void MediaRouterUI::OnRoutesUpdated(const std::vector<MediaRoute>& routes) {
271 routes_ = routes; 264 routes_ = routes;
272 if (ui_initialized_) 265 if (ui_initialized_)
273 handler_->UpdateRoutes(routes_); 266 handler_->UpdateRoutes(routes_);
274 } 267 }
275 268
276 void MediaRouterUI::OnRouteResponseReceived(scoped_ptr<MediaRoute> route, 269 void MediaRouterUI::OnRouteResponseReceived(const MediaRoute* route,
277 const std::string& error) { 270 const std::string& error) {
278 DVLOG(1) << "OnRouteResponseReceived"; 271 DVLOG(1) << "OnRouteResponseReceived";
279 // TODO(imcheng): Display error in UI. (crbug.com/490372) 272 // TODO(imcheng): Display error in UI. (crbug.com/490372)
280 if (!route) 273 if (!route)
281 LOG(ERROR) << "MediaRouteResponse returned error: " << error; 274 LOG(ERROR) << "MediaRouteResponse returned error: " << error;
282 else 275 else
283 handler_->AddRoute(*route); 276 handler_->AddRoute(*route);
284 277
285 if (requesting_route_for_default_source_) {
286 if (presentation_session_request_.get()) {
287 HandleRouteResponseForPresentation(route.get(), error);
288 } else {
289 // Dialog initiated via browser action. Let
290 // PresentationServiceDelegateImpl perform the match against the default
291 // presentation URL.
292 if (route && presentation_service_delegate_.get())
293 presentation_service_delegate_->OnRouteCreated(*route);
294 }
295 }
296
297 has_pending_route_request_ = false; 278 has_pending_route_request_ = false;
298 requesting_route_for_default_source_ = false; 279 requesting_route_for_default_source_ = false;
299 } 280 }
300 281
301 bool MediaRouterUI::DoCreateRoute(const MediaSink::Id& sink_id, 282 bool MediaRouterUI::DoCreateRoute(const MediaSink::Id& sink_id,
302 MediaCastMode cast_mode) { 283 MediaCastMode cast_mode) {
303 DCHECK(query_result_manager_.get()); 284 DCHECK(query_result_manager_.get());
285 DCHECK(dialog_callbacks_);
304 DCHECK(initiator_); 286 DCHECK(initiator_);
305 287
306 // Note that there is a rarely-encountered bug, where the MediaCastMode to 288 // Note that there is a rarely-encountered bug, where the MediaCastMode to
307 // MediaSource mapping could have been updated, between when the user 289 // MediaSource mapping could have been updated, between when the user
308 // clicked on the UI to start a create route request, 290 // clicked on the UI to start a create route request,
309 // and when this function is called. 291 // and when this function is called.
310 // However, since the user does not have visibility into the MediaSource, and 292 // However, since the user does not have visibility into the MediaSource, and
311 // that it occurs very rarely in practice, we leave it as-is for now. 293 // that it occurs very rarely in practice, we leave it as-is for now.
312 MediaSource source = query_result_manager_->GetSourceForCastMode(cast_mode); 294 MediaSource source = query_result_manager_->GetSourceForCastMode(cast_mode);
313 if (source.Empty()) { 295 if (source.Empty()) {
314 LOG(ERROR) << "No corresponding MediaSource for cast mode " << cast_mode; 296 LOG(ERROR) << "No corresponding MediaSource for cast mode " << cast_mode;
315 return false; 297 return false;
316 } 298 }
317 299
318 has_pending_route_request_ = true; 300 has_pending_route_request_ = true;
319 requesting_route_for_default_source_ = cast_mode == MediaCastMode::DEFAULT; 301 requesting_route_for_default_source_ = cast_mode == MediaCastMode::DEFAULT;
320 GURL origin; 302 GURL origin;
321 // TODO(imcheng): What is the origin if not creating route in DEFAULT mode? 303 // TODO(imcheng): What is the origin if not creating route in DEFAULT mode?
322 if (requesting_route_for_default_source_) { 304 if (requesting_route_for_default_source_) {
323 origin = frame_url_.GetOrigin(); 305 origin = frame_url_.GetOrigin();
324 } else { 306 } else {
325 // Requesting route for mirroring. Use a placeholder URL as origin. 307 // Requesting route for mirroring. Use a placeholder URL as origin.
326 origin = GURL(chrome::kChromeUIMediaRouterURL); 308 origin = GURL(chrome::kChromeUIMediaRouterURL);
327 } 309 }
328 DCHECK(origin.is_valid()); 310 DCHECK(origin.is_valid());
329 311
330 DVLOG(1) << "DoCreateRoute: origin: " << origin; 312 DVLOG(1) << "DoCreateRoute: origin: " << origin;
331 313
332 router_->CreateRoute(source.id(), sink_id, origin, 314 router_->CreateRoute(
333 SessionTabHelper::IdForTab(initiator_), 315 source.id(), sink_id, origin, SessionTabHelper::IdForTab(initiator_),
334 base::Bind(&MediaRouterUI::OnRouteResponseReceived, 316 base::Bind(&MediaRouterDialogCallbacks::OnRouteResponseReceived,
335 weak_factory_.GetWeakPtr())); 317 dialog_callbacks_->GetWeakPtr(),
318 requesting_route_for_default_source_));
336 return true; 319 return true;
337 } 320 }
338 321
339 std::string MediaRouterUI::GetFrameURLHost() const { 322 std::string MediaRouterUI::GetFrameURLHost() const {
340 return GetHostFromURL(frame_url_); 323 return GetHostFromURL(frame_url_);
341 } 324 }
342 325
343 } // namespace media_router 326 } // namespace media_router
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698