| Index: chrome/browser/ui/webui/media_router/media_router_dialog_controller.cc
|
| diff --git a/chrome/browser/ui/webui/media_router/media_router_dialog_controller.cc b/chrome/browser/ui/webui/media_router/media_router_dialog_controller.cc
|
| index 392ebfc891d04c8db732f31a3a90a99b26a880db..0f142c2f650555c34e90eb7f1cddcc9b2ef8425a 100644
|
| --- a/chrome/browser/ui/webui/media_router/media_router_dialog_controller.cc
|
| +++ b/chrome/browser/ui/webui/media_router/media_router_dialog_controller.cc
|
| @@ -170,6 +170,85 @@ class MediaRouterDialogController::InitiatorWebContentsObserver
|
| MediaRouterDialogController* const dialog_controller_;
|
| };
|
|
|
| +MediaRouterDialogCallbacks::MediaRouterDialogCallbacks(
|
| + const base::WeakPtr<PresentationServiceDelegateImpl>& delegate)
|
| + : MediaRouterDialogCallbacks(nullptr, delegate) {
|
| +}
|
| +
|
| +MediaRouterDialogCallbacks::MediaRouterDialogCallbacks(
|
| + scoped_ptr<CreateSessionRequest> presentation_request,
|
| + const base::WeakPtr<PresentationServiceDelegateImpl>& delegate)
|
| + : presentation_request_(presentation_request.Pass()),
|
| + pending_presentation_response_after_dialog_destroyed_(false),
|
| + presentation_service_delegate_(delegate),
|
| + weak_factory_(this) {
|
| +}
|
| +
|
| +MediaRouterDialogCallbacks::~MediaRouterDialogCallbacks() {
|
| + if (presentation_request_) {
|
| + presentation_request_->MaybeInvokeErrorCallback(content::PresentationError(
|
| + content::PRESENTATION_ERROR_UNKNOWN, "Unknown error."));
|
| + }
|
| +}
|
| +
|
| +void MediaRouterDialogCallbacks::OnRouteResponseReceived(
|
| + bool is_presentation,
|
| + scoped_ptr<MediaRoute> route,
|
| + const std::string& error) {
|
| + if (is_presentation) {
|
| + if (presentation_request_) {
|
| + // Remove the presentation request after responding. Subsequent
|
| + // responses from the same dialog will be treated as if they came from
|
| + // browser-initiated requests.
|
| + HandleRouteResponseForPresentation(route.get(), error);
|
| + presentation_request_.reset();
|
| + } else if (route && presentation_service_delegate_) {
|
| + // Response was due to a browser-initiated request. Let
|
| + // PresentationServiceDelegateImpl perform the match against the default
|
| + // presentation URL.
|
| + presentation_service_delegate_->OnRouteCreated(*route);
|
| + }
|
| + }
|
| +
|
| + if (!route_response_cb_.is_null())
|
| + route_response_cb_.Run(route.get(), error);
|
| +
|
| + if (pending_presentation_response_after_dialog_destroyed_)
|
| + delete this;
|
| +}
|
| +
|
| +void MediaRouterDialogCallbacks::HandleRouteResponseForPresentation(
|
| + const MediaRoute* route,
|
| + const std::string& error) {
|
| + if (!route) {
|
| + presentation_request_->MaybeInvokeErrorCallback(
|
| + content::PresentationError(content::PRESENTATION_ERROR_UNKNOWN, error));
|
| + } else {
|
| + presentation_request_->MaybeInvokeSuccessCallback(route->media_route_id());
|
| + }
|
| +}
|
| +
|
| +void MediaRouterDialogCallbacks::OnDialogDestroyed(
|
| + bool has_pending_presentation_response) {
|
| + if (has_pending_presentation_response) {
|
| + pending_presentation_response_after_dialog_destroyed_ = true;
|
| + } else {
|
| + if (presentation_request_) {
|
| + presentation_request_->MaybeInvokeErrorCallback(
|
| + content::PresentationError(
|
| + content::PRESENTATION_ERROR_SESSION_REQUEST_CANCELLED,
|
| + "Dialog closed."));
|
| + presentation_request_.reset();
|
| + }
|
| + delete this;
|
| + }
|
| +}
|
| +
|
| +base::WeakPtr<MediaRouterDialogCallbacks>
|
| +MediaRouterDialogCallbacks::GetWeakPtr() {
|
| + return weak_factory_.GetWeakPtr();
|
| +}
|
| +
|
| MediaRouterDialogController::MediaRouterDialogController(
|
| WebContents* web_contents)
|
| : initiator_(web_contents),
|
| @@ -331,15 +410,22 @@ void MediaRouterDialogController::PopulateDialog(
|
| return;
|
| }
|
|
|
| + base::WeakPtr<PresentationServiceDelegateImpl> delegate =
|
| + PresentationServiceDelegateImpl::GetOrCreateForWebContents(initiator)
|
| + ->GetWeakPtr();
|
| + CHECK(delegate);
|
| + // TODO(imcheng): Currently it is assumed that MediaRouter requests will
|
| + // always be eventually resolved, but this may not be true due to
|
| + // implementation errors, in which case DialogCallbacks objects may be leaked.
|
| + // We should have some timeout mechanism to make sure they self-destruct
|
| + // after certain conditions and timeout are met.
|
| if (!presentation_request_.get()) {
|
| - PresentationServiceDelegateImpl::CreateForWebContents(initiator);
|
| - PresentationServiceDelegateImpl* delegate =
|
| - PresentationServiceDelegateImpl::FromWebContents(initiator);
|
| - CHECK(delegate);
|
| - media_router_ui->InitWithDefaultMediaSource(delegate);
|
| + media_router_ui->InitWithDefaultMediaSource(
|
| + delegate,
|
| + new MediaRouterDialogCallbacks(presentation_request_.Pass(), delegate));
|
| } else {
|
| media_router_ui->InitWithPresentationSessionRequest(
|
| - initiator, presentation_request_.Pass());
|
| + initiator, new MediaRouterDialogCallbacks(delegate));
|
| }
|
| }
|
|
|
|
|