Chromium Code Reviews| OLD | NEW |
|---|---|
| 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_webui_message_handle r.h" | 5 #include "chrome/browser/ui/webui/media_router/media_router_webui_message_handle r.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/metrics/histogram_macros.h" | 10 #include "base/metrics/histogram_macros.h" |
| 11 #include "base/strings/stringprintf.h" | 11 #include "base/strings/stringprintf.h" |
| 12 #include "chrome/browser/media/router/issue.h" | 12 #include "chrome/browser/media/router/issue.h" |
| 13 #include "chrome/browser/ui/webui/media_router/media_router_ui.h" | 13 #include "chrome/browser/ui/webui/media_router/media_router_ui.h" |
| 14 #include "chrome/grit/generated_resources.h" | 14 #include "chrome/grit/generated_resources.h" |
| 15 #include "extensions/common/constants.h" | 15 #include "extensions/common/constants.h" |
| 16 #include "ui/base/l10n/l10n_util.h" | 16 #include "ui/base/l10n/l10n_util.h" |
| 17 | 17 |
| 18 namespace media_router { | 18 namespace media_router { |
| 19 | 19 |
| 20 namespace { | 20 namespace { |
| 21 | 21 |
| 22 const char kHelpPageUrlPrefix[] = | 22 const char kHelpPageUrlPrefix[] = |
| 23 "https://support.google.com/chromecast/answer/%d"; | 23 "https://support.google.com/chromecast/answer/%d"; |
| 24 | 24 |
| 25 // Message names. | 25 // Message names. |
| 26 const char kRequestInitialData[] = "requestInitialData"; | 26 const char kRequestInitialData[] = "requestInitialData"; |
| 27 const char kCreateRoute[] = "requestRoute"; | 27 const char kCreateRoute[] = "requestRoute"; |
| 28 const char kActOnIssue[] = "actOnIssue"; | 28 const char kActOnIssue[] = "actOnIssue"; |
| 29 const char kCloseRoute[] = "closeRoute"; | 29 const char kCloseRoute[] = "closeRoute"; |
| 30 const char kJoinRoute[] = "joinRoute"; | |
| 30 const char kCloseDialog[] = "closeDialog"; | 31 const char kCloseDialog[] = "closeDialog"; |
| 31 const char kReportSinkCount[] = "reportSinkCount"; | 32 const char kReportSinkCount[] = "reportSinkCount"; |
| 32 const char kOnInitialDataReceived[] = "onInitialDataReceived"; | 33 const char kOnInitialDataReceived[] = "onInitialDataReceived"; |
| 33 | 34 |
| 34 // JS function names. | 35 // JS function names. |
| 35 const char kSetInitialData[] = "media_router.ui.setInitialData"; | 36 const char kSetInitialData[] = "media_router.ui.setInitialData"; |
| 36 const char kNotifyRouteCreationTimeout[] = | 37 const char kNotifyRouteCreationTimeout[] = |
| 37 "media_router.ui.onNotifyRouteCreationTimeout"; | 38 "media_router.ui.onNotifyRouteCreationTimeout"; |
| 38 const char kOnCreateRouteResponseReceived[] = | 39 const char kOnCreateRouteResponseReceived[] = |
| 39 "media_router.ui.onCreateRouteResponseReceived"; | 40 "media_router.ui.onCreateRouteResponseReceived"; |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 62 cast_mode_bits |= cast_mode; | 63 cast_mode_bits |= cast_mode; |
| 63 | 64 |
| 64 sink_val->SetInteger("castModes", cast_mode_bits); | 65 sink_val->SetInteger("castModes", cast_mode_bits); |
| 65 value->Append(sink_val.release()); | 66 value->Append(sink_val.release()); |
| 66 } | 67 } |
| 67 | 68 |
| 68 return value.Pass(); | 69 return value.Pass(); |
| 69 } | 70 } |
| 70 | 71 |
| 71 scoped_ptr<base::DictionaryValue> RouteToValue( | 72 scoped_ptr<base::DictionaryValue> RouteToValue( |
| 72 const MediaRoute& route, const std::string& extension_id) { | 73 const MediaRoute& route, bool canJoin, const std::string& extension_id) { |
| 73 scoped_ptr<base::DictionaryValue> dictionary(new base::DictionaryValue); | 74 scoped_ptr<base::DictionaryValue> dictionary(new base::DictionaryValue); |
| 74 dictionary->SetString("id", route.media_route_id()); | 75 dictionary->SetString("id", route.media_route_id()); |
| 75 dictionary->SetString("sinkId", route.media_sink_id()); | 76 dictionary->SetString("sinkId", route.media_sink_id()); |
| 76 dictionary->SetString("description", route.description()); | 77 dictionary->SetString("description", route.description()); |
| 77 dictionary->SetBoolean("isLocal", route.is_local()); | 78 dictionary->SetBoolean("isLocal", route.is_local()); |
| 79 dictionary->SetBoolean("canJoin", canJoin); | |
| 78 | 80 |
| 79 const std::string& custom_path = route.custom_controller_path(); | 81 const std::string& custom_path = route.custom_controller_path(); |
| 80 if (!custom_path.empty()) { | 82 if (!custom_path.empty()) { |
| 81 std::string full_custom_controller_path = base::StringPrintf("%s://%s/%s", | 83 std::string full_custom_controller_path = base::StringPrintf("%s://%s/%s", |
| 82 extensions::kExtensionScheme, extension_id.c_str(), | 84 extensions::kExtensionScheme, extension_id.c_str(), |
| 83 custom_path.c_str()); | 85 custom_path.c_str()); |
| 84 DCHECK(GURL(full_custom_controller_path).is_valid()); | 86 DCHECK(GURL(full_custom_controller_path).is_valid()); |
| 85 dictionary->SetString("customControllerPath", | 87 dictionary->SetString("customControllerPath", |
| 86 full_custom_controller_path); | 88 full_custom_controller_path); |
| 87 } | 89 } |
| 88 | 90 |
| 89 return dictionary.Pass(); | 91 return dictionary.Pass(); |
| 90 } | 92 } |
| 91 | 93 |
| 92 scoped_ptr<base::ListValue> RoutesToValue( | 94 scoped_ptr<base::ListValue> RoutesToValue( |
| 93 const std::vector<MediaRoute>& routes, const std::string& extension_id) { | 95 const std::vector<MediaRoute>& routes, |
| 96 const std::vector<MediaRoute::Id>& joinable_route_ids, | |
| 97 const std::string& extension_id) { | |
| 94 scoped_ptr<base::ListValue> value(new base::ListValue); | 98 scoped_ptr<base::ListValue> value(new base::ListValue); |
| 95 | 99 |
| 96 for (const MediaRoute& route : routes) { | 100 for (const MediaRoute& route : routes) { |
| 101 bool canJoin = ContainsValue(joinable_route_ids, route.media_route_id()); | |
| 97 scoped_ptr<base::DictionaryValue> route_val(RouteToValue(route, | 102 scoped_ptr<base::DictionaryValue> route_val(RouteToValue(route, |
| 98 extension_id)); | 103 canJoin, extension_id)); |
| 99 value->Append(route_val.release()); | 104 value->Append(route_val.release()); |
| 100 } | 105 } |
| 101 | 106 |
| 102 return value.Pass(); | 107 return value.Pass(); |
| 103 } | 108 } |
| 104 | 109 |
| 105 scoped_ptr<base::ListValue> CastModesToValue(const CastModeSet& cast_modes, | 110 scoped_ptr<base::ListValue> CastModesToValue(const CastModeSet& cast_modes, |
| 106 const std::string& source_host) { | 111 const std::string& source_host) { |
| 107 scoped_ptr<base::ListValue> value(new base::ListValue); | 112 scoped_ptr<base::ListValue> value(new base::ListValue); |
| 108 | 113 |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 173 } | 178 } |
| 174 | 179 |
| 175 void MediaRouterWebUIMessageHandler::UpdateSinks( | 180 void MediaRouterWebUIMessageHandler::UpdateSinks( |
| 176 const std::vector<MediaSinkWithCastModes>& sinks) { | 181 const std::vector<MediaSinkWithCastModes>& sinks) { |
| 177 DVLOG(2) << "UpdateSinks"; | 182 DVLOG(2) << "UpdateSinks"; |
| 178 scoped_ptr<base::ListValue> sinks_val(SinksToValue(sinks)); | 183 scoped_ptr<base::ListValue> sinks_val(SinksToValue(sinks)); |
| 179 web_ui()->CallJavascriptFunction(kSetSinkList, *sinks_val); | 184 web_ui()->CallJavascriptFunction(kSetSinkList, *sinks_val); |
| 180 } | 185 } |
| 181 | 186 |
| 182 void MediaRouterWebUIMessageHandler::UpdateRoutes( | 187 void MediaRouterWebUIMessageHandler::UpdateRoutes( |
| 183 const std::vector<MediaRoute>& routes) { | 188 const std::vector<MediaRoute>& routes, |
| 184 DVLOG(2) << "UpdateRoutes"; | 189 const std::vector<MediaRoute::Id>& joinable_route_ids) { |
| 185 scoped_ptr<base::ListValue> routes_val(RoutesToValue(routes, | 190 scoped_ptr<base::ListValue> routes_val(RoutesToValue(routes, |
| 191 joinable_route_ids, | |
| 186 media_router_ui_->GetRouteProviderExtensionId())); | 192 media_router_ui_->GetRouteProviderExtensionId())); |
| 187 web_ui()->CallJavascriptFunction(kSetRouteList, *routes_val); | 193 web_ui()->CallJavascriptFunction(kSetRouteList, *routes_val); |
| 188 } | 194 } |
| 189 | 195 |
| 190 void MediaRouterWebUIMessageHandler::UpdateCastModes( | 196 void MediaRouterWebUIMessageHandler::UpdateCastModes( |
| 191 const CastModeSet& cast_modes, | 197 const CastModeSet& cast_modes, |
| 192 const std::string& source_host) { | 198 const std::string& source_host) { |
| 193 DVLOG(2) << "UpdateCastModes"; | 199 DVLOG(2) << "UpdateCastModes"; |
| 194 scoped_ptr<base::ListValue> cast_modes_val( | 200 scoped_ptr<base::ListValue> cast_modes_val( |
| 195 CastModesToValue(cast_modes, source_host)); | 201 CastModesToValue(cast_modes, source_host)); |
| 196 web_ui()->CallJavascriptFunction(kSetCastModeList, *cast_modes_val); | 202 web_ui()->CallJavascriptFunction(kSetCastModeList, *cast_modes_val); |
| 197 } | 203 } |
| 198 | 204 |
| 199 void MediaRouterWebUIMessageHandler::OnCreateRouteResponseReceived( | 205 void MediaRouterWebUIMessageHandler::OnCreateRouteResponseReceived( |
| 200 const MediaSink::Id& sink_id, | 206 const MediaSink::Id& sink_id, |
| 201 const MediaRoute* route) { | 207 const MediaRoute* route) { |
| 202 DVLOG(2) << "OnCreateRouteResponseReceived"; | 208 DVLOG(2) << "OnCreateRouteResponseReceived"; |
| 203 if (route) { | 209 if (route) { |
| 204 scoped_ptr<base::DictionaryValue> route_value(RouteToValue(*route, | 210 scoped_ptr<base::DictionaryValue> route_value(RouteToValue(*route, false, |
| 205 media_router_ui_->GetRouteProviderExtensionId())); | 211 media_router_ui_->GetRouteProviderExtensionId())); |
| 206 web_ui()->CallJavascriptFunction(kOnCreateRouteResponseReceived, | 212 web_ui()->CallJavascriptFunction(kOnCreateRouteResponseReceived, |
| 207 base::StringValue(sink_id), *route_value); | 213 base::StringValue(sink_id), *route_value); |
| 208 UMA_HISTOGRAM_BOOLEAN("MediaRouter.Ui.Action.StartLocalSessionSuccessful", | 214 UMA_HISTOGRAM_BOOLEAN("MediaRouter.Ui.Action.StartLocalSessionSuccessful", |
| 209 true); | 215 true); |
| 210 } else { | 216 } else { |
| 211 web_ui()->CallJavascriptFunction(kOnCreateRouteResponseReceived, | 217 web_ui()->CallJavascriptFunction(kOnCreateRouteResponseReceived, |
| 212 base::StringValue(sink_id), | 218 base::StringValue(sink_id), |
| 213 *base::Value::CreateNullValue()); | 219 *base::Value::CreateNullValue()); |
| 214 UMA_HISTOGRAM_BOOLEAN("MediaRouter.Ui.Action.StartLocalSessionSuccessful", | 220 UMA_HISTOGRAM_BOOLEAN("MediaRouter.Ui.Action.StartLocalSessionSuccessful", |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 243 base::Unretained(this))); | 249 base::Unretained(this))); |
| 244 web_ui()->RegisterMessageCallback( | 250 web_ui()->RegisterMessageCallback( |
| 245 kActOnIssue, | 251 kActOnIssue, |
| 246 base::Bind(&MediaRouterWebUIMessageHandler::OnActOnIssue, | 252 base::Bind(&MediaRouterWebUIMessageHandler::OnActOnIssue, |
| 247 base::Unretained(this))); | 253 base::Unretained(this))); |
| 248 web_ui()->RegisterMessageCallback( | 254 web_ui()->RegisterMessageCallback( |
| 249 kCloseRoute, | 255 kCloseRoute, |
| 250 base::Bind(&MediaRouterWebUIMessageHandler::OnCloseRoute, | 256 base::Bind(&MediaRouterWebUIMessageHandler::OnCloseRoute, |
| 251 base::Unretained(this))); | 257 base::Unretained(this))); |
| 252 web_ui()->RegisterMessageCallback( | 258 web_ui()->RegisterMessageCallback( |
| 259 kJoinRoute, | |
| 260 base::Bind(&MediaRouterWebUIMessageHandler::OnJoinRoute, | |
| 261 base::Unretained(this))); | |
| 262 web_ui()->RegisterMessageCallback( | |
| 253 kCloseDialog, | 263 kCloseDialog, |
| 254 base::Bind(&MediaRouterWebUIMessageHandler::OnCloseDialog, | 264 base::Bind(&MediaRouterWebUIMessageHandler::OnCloseDialog, |
| 255 base::Unretained(this))); | 265 base::Unretained(this))); |
| 256 web_ui()->RegisterMessageCallback( | 266 web_ui()->RegisterMessageCallback( |
| 257 kReportSinkCount, | 267 kReportSinkCount, |
| 258 base::Bind(&MediaRouterWebUIMessageHandler::OnReportSinkCount, | 268 base::Bind(&MediaRouterWebUIMessageHandler::OnReportSinkCount, |
| 259 base::Unretained(this))); | 269 base::Unretained(this))); |
| 260 web_ui()->RegisterMessageCallback( | 270 web_ui()->RegisterMessageCallback( |
| 261 kOnInitialDataReceived, | 271 kOnInitialDataReceived, |
| 262 base::Bind(&MediaRouterWebUIMessageHandler::OnInitialDataReceived, | 272 base::Bind(&MediaRouterWebUIMessageHandler::OnInitialDataReceived, |
| 263 base::Unretained(this))); | 273 base::Unretained(this))); |
| 264 } | 274 } |
| 265 | 275 |
| 266 void MediaRouterWebUIMessageHandler::OnRequestInitialData( | 276 void MediaRouterWebUIMessageHandler::OnRequestInitialData( |
| 267 const base::ListValue* args) { | 277 const base::ListValue* args) { |
| 268 DVLOG(1) << "OnRequestInitialData"; | 278 DVLOG(1) << "OnRequestInitialData"; |
| 269 media_router_ui_->OnUIInitiallyLoaded(); | 279 media_router_ui_->OnUIInitiallyLoaded(); |
| 270 base::DictionaryValue initial_data; | 280 base::DictionaryValue initial_data; |
| 271 | 281 |
| 272 // "No Cast devices found?" Chromecast help center page. | 282 // "No Cast devices found?" Chromecast help center page. |
| 273 initial_data.SetString("deviceMissingUrl", | 283 initial_data.SetString("deviceMissingUrl", |
| 274 base::StringPrintf(kHelpPageUrlPrefix, 3249268)); | 284 base::StringPrintf(kHelpPageUrlPrefix, 3249268)); |
| 275 | 285 |
| 276 scoped_ptr<base::ListValue> sinks(SinksToValue(media_router_ui_->sinks())); | 286 scoped_ptr<base::ListValue> sinks(SinksToValue(media_router_ui_->sinks())); |
| 277 initial_data.Set("sinks", sinks.release()); | 287 initial_data.Set("sinks", sinks.release()); |
| 278 | 288 |
| 279 scoped_ptr<base::ListValue> routes(RoutesToValue(media_router_ui_->routes(), | 289 scoped_ptr<base::ListValue> routes(RoutesToValue(media_router_ui_->routes(), |
| 290 media_router_ui_->joinable_route_ids(), | |
| 280 media_router_ui_->GetRouteProviderExtensionId())); | 291 media_router_ui_->GetRouteProviderExtensionId())); |
| 281 initial_data.Set("routes", routes.release()); | 292 initial_data.Set("routes", routes.release()); |
| 282 | 293 |
| 283 const std::set<MediaCastMode> cast_modes = media_router_ui_->cast_modes(); | 294 const std::set<MediaCastMode> cast_modes = media_router_ui_->cast_modes(); |
| 284 scoped_ptr<base::ListValue> cast_modes_list( | 295 scoped_ptr<base::ListValue> cast_modes_list( |
| 285 CastModesToValue(cast_modes, | 296 CastModesToValue(cast_modes, |
| 286 media_router_ui_->GetPresentationRequestSourceName())); | 297 media_router_ui_->GetPresentationRequestSourceName())); |
| 287 initial_data.Set("castModes", cast_modes_list.release()); | 298 initial_data.Set("castModes", cast_modes_list.release()); |
| 288 | 299 |
| 289 web_ui()->CallJavascriptFunction(kSetInitialData, initial_data); | 300 web_ui()->CallJavascriptFunction(kSetInitialData, initial_data); |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 357 DVLOG(1) << "Invalid action type: " << action_type_num; | 368 DVLOG(1) << "Invalid action type: " << action_type_num; |
| 358 return; | 369 return; |
| 359 } | 370 } |
| 360 IssueAction::Type action_type = | 371 IssueAction::Type action_type = |
| 361 static_cast<IssueAction::Type>(action_type_num); | 372 static_cast<IssueAction::Type>(action_type_num); |
| 362 if (ActOnIssueType(action_type, args_dict)) | 373 if (ActOnIssueType(action_type, args_dict)) |
| 363 DVLOG(1) << "ActOnIssueType failed for Issue ID " << issue_id; | 374 DVLOG(1) << "ActOnIssueType failed for Issue ID " << issue_id; |
| 364 media_router_ui_->ClearIssue(issue_id); | 375 media_router_ui_->ClearIssue(issue_id); |
| 365 } | 376 } |
| 366 | 377 |
| 367 void MediaRouterWebUIMessageHandler::OnCloseRoute( | 378 void MediaRouterWebUIMessageHandler::OnJoinRoute(const base::ListValue* args) { |
| 368 const base::ListValue* args) { | 379 DVLOG(1) << "OnJoinRoute"; |
| 380 const base::DictionaryValue* args_dict = nullptr; | |
| 381 std::string route_id; | |
| 382 std::string sink_id; | |
| 383 if (!args->GetDictionary(0, &args_dict) || | |
| 384 !args_dict->GetString("sinkId", &sink_id) || | |
| 385 !args_dict->GetString("routeId", &route_id)) { | |
| 386 DVLOG(1) << "Unable to extract args."; | |
| 387 return; | |
| 388 } | |
| 389 | |
| 390 if (sink_id.empty()) { | |
| 391 DVLOG(1) << "Media Route UI did not respond with a " | |
| 392 << "valid sink ID. Aborting."; | |
| 393 return; | |
| 394 } | |
| 395 | |
| 396 if (route_id.empty()) { | |
| 397 DVLOG(1) << "Media Route UI did not respond with a " | |
| 398 << "valid route ID. Aborting."; | |
| 399 return; | |
| 400 } | |
| 401 | |
| 402 MediaRouterUI* media_router_ui = | |
| 403 static_cast<MediaRouterUI*>(web_ui()->GetController()); | |
| 404 if (media_router_ui->HasPendingRouteRequest()) { | |
| 405 DVLOG(1) << "UI already has pending route request. Ignoring."; | |
| 406 Issue issue( | |
| 407 l10n_util::GetStringUTF8(IDS_MEDIA_ROUTER_ISSUE_PENDING_ROUTE), | |
| 408 std::string(), IssueAction(IssueAction::TYPE_DISMISS), | |
| 409 std::vector<IssueAction>(), std::string(), Issue::NOTIFICATION, | |
| 410 false, std::string()); | |
| 411 media_router_ui_->AddIssue(issue); | |
| 412 return; | |
| 413 } | |
| 414 | |
| 415 DVLOG(2) << __FUNCTION__ << ": sink id: " << sink_id | |
| 416 << ", route id: " << route_id; | |
| 417 | |
| 418 if (!media_router_ui_->ConnectRemoteRoute(sink_id, route_id)) { | |
|
imcheng
2015/12/29 00:24:42
on naming: Is there logic in the WebUI that restri
matt.boetger
2016/01/05 00:19:48
No, there is currently nothing preventing a provid
imcheng
2016/01/05 02:12:47
Well I think it's reasonable to allow join to loca
matt.boetger
2016/01/06 22:49:07
Done.
| |
| 419 // TODO(boetger): Need to add an issue if failed to initiate a JoinRoute | |
| 420 // request. | |
| 421 DVLOG(1) << "Error initiating route join request."; | |
| 422 } | |
| 423 } | |
| 424 | |
| 425 void MediaRouterWebUIMessageHandler::OnCloseRoute(const base::ListValue* args) { | |
| 369 DVLOG(1) << "OnCloseRoute"; | 426 DVLOG(1) << "OnCloseRoute"; |
| 370 const base::DictionaryValue* args_dict = nullptr; | 427 const base::DictionaryValue* args_dict = nullptr; |
| 371 std::string route_id; | 428 std::string route_id; |
| 372 if (!args->GetDictionary(0, &args_dict) || | 429 if (!args->GetDictionary(0, &args_dict) || |
| 373 !args_dict->GetString("routeId", &route_id)) { | 430 !args_dict->GetString("routeId", &route_id)) { |
| 374 DVLOG(1) << "Unable to extract args."; | 431 DVLOG(1) << "Unable to extract args."; |
| 375 return; | 432 return; |
| 376 } | 433 } |
| 377 media_router_ui_->CloseRoute(route_id); | 434 media_router_ui_->CloseRoute(route_id); |
| 378 } | 435 } |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 415 open_args->AppendString(learn_more_url); | 472 open_args->AppendString(learn_more_url); |
| 416 web_ui()->CallJavascriptFunction(kWindowOpen, *open_args); | 473 web_ui()->CallJavascriptFunction(kWindowOpen, *open_args); |
| 417 return true; | 474 return true; |
| 418 } else { | 475 } else { |
| 419 // Do nothing; no other issue action types require any other action. | 476 // Do nothing; no other issue action types require any other action. |
| 420 return true; | 477 return true; |
| 421 } | 478 } |
| 422 } | 479 } |
| 423 | 480 |
| 424 } // namespace media_router | 481 } // namespace media_router |
| OLD | NEW |