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

Side by Side Diff: ash/common/system/cast/tray_cast.cc

Issue 2424183002: Remove Chromecast extension support from cast system tray menu. (Closed)
Patch Set: Initial patch Created 4 years, 1 month 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 "ash/common/system/cast/tray_cast.h" 5 #include "ash/common/system/cast/tray_cast.h"
6 6
7 #include "ash/common/material_design/material_design_controller.h" 7 #include "ash/common/material_design/material_design_controller.h"
8 #include "ash/common/session/session_state_delegate.h" 8 #include "ash/common/session/session_state_delegate.h"
9 #include "ash/common/shelf/wm_shelf_util.h" 9 #include "ash/common/shelf/wm_shelf_util.h"
10 #include "ash/common/system/chromeos/screen_security/screen_tray_item.h" 10 #include "ash/common/system/chromeos/screen_security/screen_tray_item.h"
(...skipping 27 matching lines...) Expand all
38 38
39 namespace ash { 39 namespace ash {
40 40
41 namespace { 41 namespace {
42 42
43 const size_t kMaximumStatusStringLength = 100; 43 const size_t kMaximumStatusStringLength = 100;
44 const int kStopButtonRightPadding = 18; 44 const int kStopButtonRightPadding = 18;
45 45
46 // Returns the active CastConfigDelegate instance. 46 // Returns the active CastConfigDelegate instance.
47 CastConfigDelegate* GetCastConfigDelegate() { 47 CastConfigDelegate* GetCastConfigDelegate() {
48 return WmShell::Get()->system_tray_delegate()->GetCastConfigDelegate(); 48 ash::SystemTrayDelegate* delegate = WmShell::Get()->system_tray_delegate();
49 if (!delegate)
achuithb 2016/10/27 19:38:59 Seems like a good place for the ternary operator:
jdufault 2016/10/31 21:12:08 Done.
50 return nullptr;
51 return delegate->GetCastConfigDelegate();
49 } 52 }
50 53
51 // Helper method to elide the given string to the maximum length. If a string is 54 // Helper method to elide the given string to the maximum length. If a string is
52 // contains user-input and is displayed, we should elide it. 55 // contains user-input and is displayed, we should elide it.
53 // TODO(jdufault): This does not properly trim unicode characters. We should 56 // TODO(jdufault): This does not properly trim unicode characters. We should
54 // implement this properly by using views::Label::SetElideBehavior(...). See 57 // implement this properly by using views::Label::SetElideBehavior(...). See
55 // crbug.com/532496. 58 // crbug.com/532496.
56 base::string16 ElideString(const base::string16& text) { 59 base::string16 ElideString(const base::string16& text) {
57 base::string16 elided; 60 base::string16 elided;
58 gfx::ElideString(text, kMaximumStatusStringLength, &elided); 61 gfx::ElideString(text, kMaximumStatusStringLength, &elided);
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
106 // the user to easily stop casting. It fully replaces the 109 // the user to easily stop casting. It fully replaces the
107 // |CastSelectDefaultView| view inside of the |CastDuplexView|. 110 // |CastSelectDefaultView| view inside of the |CastDuplexView|.
108 class CastCastView : public views::View, public views::ButtonListener { 111 class CastCastView : public views::View, public views::ButtonListener {
109 public: 112 public:
110 CastCastView(); 113 CastCastView();
111 ~CastCastView() override; 114 ~CastCastView() override;
112 115
113 void StopCasting(); 116 void StopCasting();
114 117
115 const std::string& displayed_activity_id() const { 118 const std::string& displayed_activity_id() const {
116 return displayed_activity_id_; 119 return displayed_route_.id;
117 } 120 }
118 121
119 // Updates the label for the stop view to include information about the 122 // Updates the label for the stop view to include information about the
120 // current device that is being casted. 123 // current device that is being casted.
121 void UpdateLabel( 124 void UpdateLabel(const CastConfigDelegate::SinksAndRoutes& sinks_routes);
122 const CastConfigDelegate::ReceiversAndActivities& receivers_activities);
123 125
124 private: 126 private:
125 // Overridden from views::View. 127 // Overridden from views::View.
126 int GetHeightForWidth(int width) const override; 128 int GetHeightForWidth(int width) const override;
127 void Layout() override; 129 void Layout() override;
128 130
129 // Overridden from views::ButtonListener. 131 // Overridden from views::ButtonListener.
130 void ButtonPressed(views::Button* sender, const ui::Event& event) override; 132 void ButtonPressed(views::Button* sender, const ui::Event& event) override;
131 133
132 // The cast activity id that we are displaying. If the user stops a cast, we 134 // The cast activity id that we are displaying. If the user stops a cast, we
133 // send this value to the config delegate so that we stop the right cast. 135 // send this value to the config delegate so that we stop the right cast.
134 std::string displayed_activity_id_; 136 CastConfigDelegate::Route displayed_route_;
135 137
136 views::ImageView* icon_; 138 views::ImageView* icon_;
137 views::Label* label_; 139 views::Label* label_;
138 TrayPopupLabelButton* stop_button_; 140 TrayPopupLabelButton* stop_button_;
139 141
140 DISALLOW_COPY_AND_ASSIGN(CastCastView); 142 DISALLOW_COPY_AND_ASSIGN(CastCastView);
141 }; 143 };
142 144
143 CastCastView::CastCastView() { 145 CastCastView::CastCastView() {
144 // We will initialize the primary tray view which shows a stop button here. 146 // We will initialize the primary tray view which shows a stop button here.
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
202 // Adjust the label's bounds in case it got cut off by |stop_button_|. 204 // Adjust the label's bounds in case it got cut off by |stop_button_|.
203 if (label_->bounds().Intersects(stop_button_->bounds())) { 205 if (label_->bounds().Intersects(stop_button_->bounds())) {
204 gfx::Rect label_bounds = label_->bounds(); 206 gfx::Rect label_bounds = label_->bounds();
205 label_bounds.set_width(stop_button_->x() - kTrayPopupPaddingBetweenItems - 207 label_bounds.set_width(stop_button_->x() - kTrayPopupPaddingBetweenItems -
206 label_->x()); 208 label_->x());
207 label_->SetBoundsRect(label_bounds); 209 label_->SetBoundsRect(label_bounds);
208 } 210 }
209 } 211 }
210 212
211 void CastCastView::StopCasting() { 213 void CastCastView::StopCasting() {
212 GetCastConfigDelegate()->StopCasting(displayed_activity_id_); 214 GetCastConfigDelegate()->StopCasting(displayed_route_);
213 WmShell::Get()->RecordUserMetricsAction(UMA_STATUS_AREA_CAST_STOP_CAST); 215 WmShell::Get()->RecordUserMetricsAction(UMA_STATUS_AREA_CAST_STOP_CAST);
214 } 216 }
215 217
216 void CastCastView::UpdateLabel( 218 void CastCastView::UpdateLabel(
217 const CastConfigDelegate::ReceiversAndActivities& receivers_activities) { 219 const CastConfigDelegate::SinksAndRoutes& sinks_routes) {
218 for (auto& i : receivers_activities) { 220 for (auto& i : sinks_routes) {
219 const CastConfigDelegate::Receiver& receiver = i.receiver; 221 const CastConfigDelegate::Sink& sink = i.sink;
220 const CastConfigDelegate::Activity& activity = i.activity; 222 const CastConfigDelegate::Route& route = i.route;
221 223
222 if (!activity.id.empty()) { 224 if (!route.id.empty()) {
223 displayed_activity_id_ = activity.id; 225 displayed_route_ = route;
224 226
225 // We want to display different labels inside of the title depending on 227 // We want to display different labels inside of the title depending on
226 // what we are actually casting - either the desktop, a tab, or a fallback 228 // what we are actually casting - either the desktop, a tab, or a fallback
227 // that catches everything else (ie, an extension tab). 229 // that catches everything else (ie, an extension tab).
228 if (activity.tab_id == CastConfigDelegate::Activity::TabId::DESKTOP) { 230 switch (route.content_source) {
229 label_->SetText(ElideString(l10n_util::GetStringFUTF16( 231 case CastConfigDelegate::Route::ContentSource::UNKNOWN:
230 IDS_ASH_STATUS_TRAY_CAST_CAST_DESKTOP, receiver.name))); 232 label_->SetText(
231 } else if (activity.tab_id >= 0) { 233 l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_CAST_CAST_UNKNOWN));
232 label_->SetText(ElideString(l10n_util::GetStringFUTF16( 234 break;
233 IDS_ASH_STATUS_TRAY_CAST_CAST_TAB, activity.title, receiver.name))); 235 case CastConfigDelegate::Route::ContentSource::TAB:
234 } else { 236 label_->SetText(ElideString(l10n_util::GetStringFUTF16(
235 label_->SetText( 237 IDS_ASH_STATUS_TRAY_CAST_CAST_TAB, route.title, sink.name)));
236 l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_CAST_CAST_UNKNOWN)); 238 break;
239 case CastConfigDelegate::Route::ContentSource::DESKTOP:
240 label_->SetText(ElideString(l10n_util::GetStringFUTF16(
241 IDS_ASH_STATUS_TRAY_CAST_CAST_DESKTOP, sink.name)));
242 break;
achuithb 2016/10/27 19:38:59 I believe default: NOTREACHED() << "unhandled s
jdufault 2016/10/31 21:12:07 Not having default means the compiler will emit a
237 } 243 }
238 244
239 PreferredSizeChanged(); 245 PreferredSizeChanged();
240 Layout(); 246 Layout();
241 247
242 // If this machine is the source of the activity, then we want to display 248 // If this machine is the source of the activity, then we want to display
243 // it over any other activity. There can be multiple activities if other 249 // it over any other activity. There can be multiple activities if other
244 // devices on the network are casting at the same time. 250 // devices on the network are casting at the same time.
245 if (activity.is_local_source) 251 if (route.is_local_source)
246 break; 252 break;
247 } 253 }
248 } 254 }
249 } 255 }
250 256
251 void CastCastView::ButtonPressed(views::Button* sender, 257 void CastCastView::ButtonPressed(views::Button* sender,
252 const ui::Event& event) { 258 const ui::Event& event) {
253 DCHECK(sender == stop_button_); 259 DCHECK(sender == stop_button_);
254 StopCasting(); 260 StopCasting();
255 } 261 }
256 262
257 // This view by itself does very little. It acts as a front-end for managing 263 // This view by itself does very little. It acts as a front-end for managing
258 // which of the two child views (|CastSelectDefaultView| and |CastCastView|) 264 // which of the two child views (|CastSelectDefaultView| and |CastCastView|)
259 // is active. 265 // is active.
260 class CastDuplexView : public views::View { 266 class CastDuplexView : public views::View {
261 public: 267 public:
262 CastDuplexView( 268 CastDuplexView(SystemTrayItem* owner,
263 SystemTrayItem* owner, 269 bool show_more,
264 bool show_more, 270 const CastConfigDelegate::SinksAndRoutes& sinks_routes);
265 const CastConfigDelegate::ReceiversAndActivities& receivers_activities);
266 ~CastDuplexView() override; 271 ~CastDuplexView() override;
267 272
268 // Activate either the casting or select view. 273 // Activate either the casting or select view.
269 void ActivateCastView(); 274 void ActivateCastView();
270 void ActivateSelectView(); 275 void ActivateSelectView();
271 276
272 CastSelectDefaultView* select_view() { return select_view_; } 277 CastSelectDefaultView* select_view() { return select_view_; }
273 CastCastView* cast_view() { return cast_view_; } 278 CastCastView* cast_view() { return cast_view_; }
274 279
275 private: 280 private:
276 // Overridden from views::View. 281 // Overridden from views::View.
277 void ChildPreferredSizeChanged(views::View* child) override; 282 void ChildPreferredSizeChanged(views::View* child) override;
278 void Layout() override; 283 void Layout() override;
279 284
280 // Only one of |select_view_| or |cast_view_| will be displayed at any given 285 // Only one of |select_view_| or |cast_view_| will be displayed at any given
281 // time. This will return the view is being displayed. 286 // time. This will return the view is being displayed.
282 views::View* ActiveChildView(); 287 views::View* ActiveChildView();
283 288
284 CastSelectDefaultView* select_view_; 289 CastSelectDefaultView* select_view_;
285 CastCastView* cast_view_; 290 CastCastView* cast_view_;
286 291
287 DISALLOW_COPY_AND_ASSIGN(CastDuplexView); 292 DISALLOW_COPY_AND_ASSIGN(CastDuplexView);
288 }; 293 };
289 294
290 CastDuplexView::CastDuplexView( 295 CastDuplexView::CastDuplexView(
291 SystemTrayItem* owner, 296 SystemTrayItem* owner,
292 bool show_more, 297 bool show_more,
293 const CastConfigDelegate::ReceiversAndActivities& receivers_activities) { 298 const CastConfigDelegate::SinksAndRoutes& sinks_routes) {
294 select_view_ = new CastSelectDefaultView(owner, show_more); 299 select_view_ = new CastSelectDefaultView(owner, show_more);
295 cast_view_ = new CastCastView(); 300 cast_view_ = new CastCastView();
296 cast_view_->UpdateLabel(receivers_activities); 301 cast_view_->UpdateLabel(sinks_routes);
297 SetLayoutManager(new views::FillLayout()); 302 SetLayoutManager(new views::FillLayout());
298 303
299 ActivateSelectView(); 304 ActivateSelectView();
300 } 305 }
301 306
302 CastDuplexView::~CastDuplexView() { 307 CastDuplexView::~CastDuplexView() {
303 RemoveChildView(ActiveChildView()); 308 RemoveChildView(ActiveChildView());
304 delete select_view_; 309 delete select_view_;
305 delete cast_view_; 310 delete cast_view_;
306 } 311 }
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
379 SetLayoutManager(new views::BoxLayout(layout, 0, 0, 0)); 384 SetLayoutManager(new views::BoxLayout(layout, 0, 0, 0));
380 Layout(); 385 Layout();
381 } 386 }
382 387
383 // This view displays a list of cast receivers that can be clicked on and casted 388 // This view displays a list of cast receivers that can be clicked on and casted
384 // to. It is activated by clicking on the chevron inside of 389 // to. It is activated by clicking on the chevron inside of
385 // |CastSelectDefaultView|. 390 // |CastSelectDefaultView|.
386 class CastDetailedView : public TrayDetailsView { 391 class CastDetailedView : public TrayDetailsView {
387 public: 392 public:
388 CastDetailedView(SystemTrayItem* owner, 393 CastDetailedView(SystemTrayItem* owner,
389 LoginStatus login, 394 const CastConfigDelegate::SinksAndRoutes& sinks_routes);
390 const CastConfigDelegate::ReceiversAndActivities&
391 receivers_and_activities);
392 ~CastDetailedView() override; 395 ~CastDetailedView() override;
393 396
394 // Makes the detail view think the view associated with the given receiver_id 397 // Makes the detail view think the view associated with the given receiver_id
395 // was clicked. This will start a cast. 398 // was clicked. This will start a cast.
396 void SimulateViewClickedForTest(const std::string& receiver_id); 399 void SimulateViewClickedForTest(const std::string& receiver_id);
397 400
398 // Updates the list of available receivers. 401 // Updates the list of available receivers.
399 void UpdateReceiverList(const CastConfigDelegate::ReceiversAndActivities& 402 void UpdateReceiverList(
400 new_receivers_and_activities); 403 const CastConfigDelegate::SinksAndRoutes& sinks_routes);
401 404
402 private: 405 private:
403 void CreateItems(); 406 void CreateItems();
404 407
405 void UpdateReceiverListFromCachedData(); 408 void UpdateReceiverListFromCachedData();
406 views::View* AddToReceiverList( 409 views::View* AddToReceiverList(
407 const CastConfigDelegate::ReceiverAndActivity& receiverActivity); 410 const CastConfigDelegate::SinkAndRoute& sink_route);
408
409 void AppendSettingsEntries();
410 411
411 // TrayDetailsView: 412 // TrayDetailsView:
412 void HandleViewClicked(views::View* view) override; 413 void HandleViewClicked(views::View* view) override;
413 414
414 LoginStatus login_;
415 views::View* options_ = nullptr;
416 // A mapping from the receiver id to the receiver/activity data. 415 // A mapping from the receiver id to the receiver/activity data.
417 std::map<std::string, CastConfigDelegate::ReceiverAndActivity> 416 std::map<std::string, CastConfigDelegate::SinkAndRoute> sinks_and_routes_;
418 receivers_and_activities_;
419 // A mapping from the view pointer to the associated activity id. 417 // A mapping from the view pointer to the associated activity id.
420 std::map<views::View*, std::string> receiver_activity_map_; 418 std::map<views::View*, CastConfigDelegate::Sink> view_to_sink_map_;
421 419
422 DISALLOW_COPY_AND_ASSIGN(CastDetailedView); 420 DISALLOW_COPY_AND_ASSIGN(CastDetailedView);
423 }; 421 };
424 422
425 CastDetailedView::CastDetailedView( 423 CastDetailedView::CastDetailedView(
426 SystemTrayItem* owner, 424 SystemTrayItem* owner,
427 LoginStatus login, 425 const CastConfigDelegate::SinksAndRoutes& sinks_routes)
428 const CastConfigDelegate::ReceiversAndActivities& receivers_and_activities) 426 : TrayDetailsView(owner) {
429 : TrayDetailsView(owner), login_(login) {
430 CreateItems(); 427 CreateItems();
431 UpdateReceiverList(receivers_and_activities); 428 UpdateReceiverList(sinks_routes);
432 } 429 }
433 430
434 CastDetailedView::~CastDetailedView() {} 431 CastDetailedView::~CastDetailedView() {}
435 432
436 void CastDetailedView::SimulateViewClickedForTest( 433 void CastDetailedView::SimulateViewClickedForTest(
437 const std::string& receiver_id) { 434 const std::string& receiver_id) {
438 for (auto& it : receiver_activity_map_) { 435 for (const auto& it : view_to_sink_map_) {
439 if (it.second == receiver_id) { 436 if (it.second.id == receiver_id) {
440 HandleViewClicked(it.first); 437 HandleViewClicked(it.first);
441 break; 438 break;
442 } 439 }
443 } 440 }
444 } 441 }
445 442
446 void CastDetailedView::CreateItems() { 443 void CastDetailedView::CreateItems() {
447 CreateScrollableList(); 444 CreateScrollableList();
448 if (GetCastConfigDelegate()->HasOptions())
449 AppendSettingsEntries();
450 CreateTitleRow(IDS_ASH_STATUS_TRAY_CAST); 445 CreateTitleRow(IDS_ASH_STATUS_TRAY_CAST);
451 } 446 }
452 447
453 void CastDetailedView::UpdateReceiverList( 448 void CastDetailedView::UpdateReceiverList(
454 const CastConfigDelegate::ReceiversAndActivities& 449 const CastConfigDelegate::SinksAndRoutes& sinks_routes) {
455 new_receivers_and_activities) {
456 // Add/update existing. 450 // Add/update existing.
457 for (auto i = new_receivers_and_activities.begin(); 451 for (const auto& it : sinks_routes) {
458 i != new_receivers_and_activities.end(); ++i) { 452 sinks_and_routes_[it.sink.id] = it;
459 receivers_and_activities_[i->receiver.id] = *i;
460 } 453 }
461 454
462 // Remove non-existent receivers. Removing an element invalidates all existing 455 // Remove non-existent receivers. Removing an element invalidates all existing
463 // iterators. 456 // iterators.
464 auto i = receivers_and_activities_.begin(); 457 auto i = sinks_and_routes_.begin();
465 while (i != receivers_and_activities_.end()) { 458 while (i != sinks_and_routes_.end()) {
466 bool has_receiver = false; 459 bool has_receiver = false;
467 for (auto receiver : new_receivers_and_activities) { 460 for (auto receiver : sinks_routes) {
468 if (i->first == receiver.receiver.id) 461 if (i->first == receiver.sink.id)
469 has_receiver = true; 462 has_receiver = true;
470 } 463 }
471 464
472 if (has_receiver) 465 if (has_receiver)
473 ++i; 466 ++i;
474 else 467 else
475 i = receivers_and_activities_.erase(i); 468 i = sinks_and_routes_.erase(i);
476 } 469 }
477 470
478 // Update UI. 471 // Update UI.
479 UpdateReceiverListFromCachedData(); 472 UpdateReceiverListFromCachedData();
480 Layout(); 473 Layout();
481 } 474 }
482 475
483 void CastDetailedView::UpdateReceiverListFromCachedData() { 476 void CastDetailedView::UpdateReceiverListFromCachedData() {
484 // Remove all of the existing views. 477 // Remove all of the existing views.
485 receiver_activity_map_.clear(); 478 view_to_sink_map_.clear();
486 scroll_content()->RemoveAllChildViews(true); 479 scroll_content()->RemoveAllChildViews(true);
487 480
488 // Add a view for each receiver. 481 // Add a view for each receiver.
489 for (auto& it : receivers_and_activities_) { 482 for (auto& it : sinks_and_routes_) {
490 const CastConfigDelegate::ReceiverAndActivity& receiver_activity = 483 const CastConfigDelegate::SinkAndRoute& sink_route = it.second;
491 it.second; 484 views::View* container = AddToReceiverList(sink_route);
492 views::View* container = AddToReceiverList(receiver_activity); 485 view_to_sink_map_[container] = sink_route.sink;
493 receiver_activity_map_[container] = it.first;
494 } 486 }
495 487
496 scroll_content()->SizeToPreferredSize(); 488 scroll_content()->SizeToPreferredSize();
497 static_cast<views::View*>(scroller())->Layout(); 489 static_cast<views::View*>(scroller())->Layout();
498 } 490 }
499 491
500 views::View* CastDetailedView::AddToReceiverList( 492 views::View* CastDetailedView::AddToReceiverList(
501 const CastConfigDelegate::ReceiverAndActivity& receiverActivity) { 493 const CastConfigDelegate::SinkAndRoute& sink_route) {
502 HoverHighlightView* container = new HoverHighlightView(this);
503
504 const gfx::ImageSkia* image = 494 const gfx::ImageSkia* image =
505 ui::ResourceBundle::GetSharedInstance() 495 ui::ResourceBundle::GetSharedInstance()
506 .GetImageNamed(IDR_AURA_UBER_TRAY_CAST_DEVICE_ICON) 496 .GetImageNamed(IDR_AURA_UBER_TRAY_CAST_DEVICE_ICON)
507 .ToImageSkia(); 497 .ToImageSkia();
508 const base::string16& name = receiverActivity.receiver.name; 498 HoverHighlightView* container = new HoverHighlightView(this);
509 container->AddIconAndLabelCustomSize( 499 container->AddIconAndLabelCustomSize(
510 *image, name, false, kTrayPopupDetailsIconWidth, 500 *image, sink_route.sink.name, false, kTrayPopupDetailsIconWidth,
511 kTrayPopupPaddingHorizontal, kTrayPopupPaddingBetweenItems); 501 kTrayPopupPaddingHorizontal, kTrayPopupPaddingBetweenItems);
512 502
513 scroll_content()->AddChildView(container); 503 scroll_content()->AddChildView(container);
514 return container; 504 return container;
515 } 505 }
516 506
517 void CastDetailedView::AppendSettingsEntries() {
518 if (MaterialDesignController::IsSystemTrayMenuMaterial())
519 return;
520
521 // Settings requires a browser window, hide it for non logged in user.
522 if (login_ == LoginStatus::NOT_LOGGED_IN || login_ == LoginStatus::LOCKED ||
523 WmShell::Get()->GetSessionStateDelegate()->IsInSecondaryLoginScreen()) {
524 return;
525 }
526
527 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
528 HoverHighlightView* container = new HoverHighlightView(this);
529 container->AddLabel(rb.GetLocalizedString(IDS_ASH_STATUS_TRAY_CAST_OPTIONS),
530 gfx::ALIGN_LEFT, false /* highlight */);
531
532 AddChildView(container);
533 options_ = container;
534 }
535
536 void CastDetailedView::HandleViewClicked(views::View* view) { 507 void CastDetailedView::HandleViewClicked(views::View* view) {
537 if (view == options_) {
538 GetCastConfigDelegate()->LaunchCastOptions();
539 return;
540 }
541
542 // Find the receiver we are going to cast to. 508 // Find the receiver we are going to cast to.
543 auto it = receiver_activity_map_.find(view); 509 auto it = view_to_sink_map_.find(view);
544 if (it != receiver_activity_map_.end()) { 510 if (it != view_to_sink_map_.end()) {
545 GetCastConfigDelegate()->CastToReceiver(it->second); 511 GetCastConfigDelegate()->CastToReceiver(it->second);
546 WmShell::Get()->RecordUserMetricsAction( 512 WmShell::Get()->RecordUserMetricsAction(
547 UMA_STATUS_AREA_DETAILED_CAST_VIEW_LAUNCH_CAST); 513 UMA_STATUS_AREA_DETAILED_CAST_VIEW_LAUNCH_CAST);
548 } 514 }
549 } 515 }
550 516
551 } // namespace tray 517 } // namespace tray
552 518
553 TrayCast::TrayCast(SystemTray* system_tray) 519 TrayCast::TrayCast(SystemTray* system_tray)
554 : SystemTrayItem(system_tray, UMA_CAST) { 520 : SystemTrayItem(system_tray, UMA_CAST) {
555 WmShell::Get()->AddShellObserver(this); 521 WmShell::Get()->AddShellObserver(this);
522
523 CastConfigDelegate* cast_config_delegate = GetCastConfigDelegate();
524 if (cast_config_delegate) {
achuithb 2016/10/27 19:38:59 When is this not true?
jdufault 2016/10/31 21:12:08 Some unrelated tests do not fully initialize every
525 cast_config_delegate->AddObserver(this);
526 cast_config_delegate->RequestDeviceRefresh();
527 }
556 } 528 }
557 529
558 TrayCast::~TrayCast() { 530 TrayCast::~TrayCast() {
531 CastConfigDelegate* cast_config_delegate = GetCastConfigDelegate();
532 if (cast_config_delegate)
533 cast_config_delegate->RemoveObserver(this);
534
559 WmShell::Get()->RemoveShellObserver(this); 535 WmShell::Get()->RemoveShellObserver(this);
560 if (added_observer_)
561 GetCastConfigDelegate()->RemoveObserver(this);
562 } 536 }
563 537
564 void TrayCast::StartCastForTest(const std::string& receiver_id) { 538 void TrayCast::StartCastForTest(const std::string& receiver_id) {
565 if (detailed_ != nullptr) 539 if (detailed_ != nullptr)
566 detailed_->SimulateViewClickedForTest(receiver_id); 540 detailed_->SimulateViewClickedForTest(receiver_id);
567 } 541 }
568 542
569 void TrayCast::StopCastForTest() { 543 void TrayCast::StopCastForTest() {
570 default_->cast_view()->StopCasting(); 544 default_->cast_view()->StopCasting();
571 } 545 }
572 546
573 const std::string& TrayCast::GetDisplayedCastId() { 547 const std::string& TrayCast::GetDisplayedCastId() {
574 return default_->cast_view()->displayed_activity_id(); 548 return default_->cast_view()->displayed_activity_id();
575 } 549 }
576 550
577 const views::View* TrayCast::GetDefaultView() const { 551 const views::View* TrayCast::GetDefaultView() const {
578 return default_; 552 return default_;
579 } 553 }
580 554
581 views::View* TrayCast::CreateTrayView(LoginStatus status) { 555 views::View* TrayCast::CreateTrayView(LoginStatus status) {
582 CHECK(tray_ == nullptr); 556 CHECK(tray_ == nullptr);
583 tray_ = new tray::CastTrayView(this); 557 tray_ = new tray::CastTrayView(this);
584 tray_->SetVisible(is_casting_); 558 tray_->SetVisible(HasActiveRoute());
585 return tray_; 559 return tray_;
586 } 560 }
587 561
588 views::View* TrayCast::CreateDefaultView(LoginStatus status) { 562 views::View* TrayCast::CreateDefaultView(LoginStatus status) {
589 CHECK(default_ == nullptr); 563 CHECK(default_ == nullptr);
590 564
591 if (HasCastExtension()) {
592 CastConfigDelegate* cast_config_delegate = GetCastConfigDelegate();
593
594 // Add the cast observer here instead of the ctor for two reasons:
595 // - The ctor gets called too early in the initialization cycle (at least
596 // for the tests); the correct profile hasn't been setup yet.
597 // - If we're using the cast extension backend (media router is disabled),
598 // then the user can install the extension at any point in time. The
599 // return value of HasCastExtension() can change, so only checking it in
600 // the ctor isn't enough.
601 if (!added_observer_) {
602 cast_config_delegate->AddObserver(this);
603 added_observer_ = true;
604 }
605
606 // The extension updates its view model whenever the popup is opened, so we
607 // probably should as well.
608 cast_config_delegate->RequestDeviceRefresh();
609 }
610
611 default_ = new tray::CastDuplexView(this, status != LoginStatus::LOCKED, 565 default_ = new tray::CastDuplexView(this, status != LoginStatus::LOCKED,
612 receivers_and_activities_); 566 sinks_and_routes_);
613 default_->set_id(TRAY_VIEW); 567 default_->set_id(TRAY_VIEW);
614 default_->select_view()->set_id(SELECT_VIEW); 568 default_->select_view()->set_id(SELECT_VIEW);
615 default_->cast_view()->set_id(CAST_VIEW); 569 default_->cast_view()->set_id(CAST_VIEW);
616 570
617 UpdatePrimaryView(); 571 UpdatePrimaryView();
618 return default_; 572 return default_;
619 } 573 }
620 574
621 views::View* TrayCast::CreateDetailedView(LoginStatus status) { 575 views::View* TrayCast::CreateDetailedView(LoginStatus status) {
622 WmShell::Get()->RecordUserMetricsAction(UMA_STATUS_AREA_DETAILED_CAST_VIEW); 576 WmShell::Get()->RecordUserMetricsAction(UMA_STATUS_AREA_DETAILED_CAST_VIEW);
623 CHECK(detailed_ == nullptr); 577 CHECK(detailed_ == nullptr);
624 detailed_ = 578 detailed_ = new tray::CastDetailedView(this, sinks_and_routes_);
625 new tray::CastDetailedView(this, status, receivers_and_activities_);
626 return detailed_; 579 return detailed_;
627 } 580 }
628 581
629 void TrayCast::DestroyTrayView() { 582 void TrayCast::DestroyTrayView() {
630 tray_ = nullptr; 583 tray_ = nullptr;
631 } 584 }
632 585
633 void TrayCast::DestroyDefaultView() { 586 void TrayCast::DestroyDefaultView() {
634 default_ = nullptr; 587 default_ = nullptr;
635 } 588 }
636 589
637 void TrayCast::DestroyDetailedView() { 590 void TrayCast::DestroyDetailedView() {
638 detailed_ = nullptr; 591 detailed_ = nullptr;
639 } 592 }
640 593
641 bool TrayCast::HasCastExtension() {
642 CastConfigDelegate* cast_config_delegate = GetCastConfigDelegate();
643 return cast_config_delegate != nullptr &&
644 cast_config_delegate->HasCastExtension();
645 }
646
647 void TrayCast::OnDevicesUpdated( 594 void TrayCast::OnDevicesUpdated(
648 const CastConfigDelegate::ReceiversAndActivities& receivers_activities) { 595 const CastConfigDelegate::SinksAndRoutes& sinks_routes) {
649 receivers_and_activities_ = receivers_activities; 596 sinks_and_routes_ = sinks_routes;
597 UpdatePrimaryView();
650 598
651 if (default_) { 599 if (default_) {
652 bool has_receivers = !receivers_and_activities_.empty(); 600 bool has_receivers = !sinks_and_routes_.empty();
653 default_->SetVisible(has_receivers); 601 default_->SetVisible(has_receivers);
654 default_->cast_view()->UpdateLabel(receivers_and_activities_); 602 default_->cast_view()->UpdateLabel(sinks_and_routes_);
655 } 603 }
656 if (detailed_) 604 if (detailed_)
657 detailed_->UpdateReceiverList(receivers_and_activities_); 605 detailed_->UpdateReceiverList(sinks_and_routes_);
658 } 606 }
659 607
660 void TrayCast::UpdatePrimaryView() { 608 void TrayCast::UpdatePrimaryView() {
661 if (HasCastExtension() && !receivers_and_activities_.empty()) { 609 if (!sinks_and_routes_.empty()) {
662 if (default_) { 610 if (default_) {
663 if (is_casting_) 611 if (HasActiveRoute())
664 default_->ActivateCastView(); 612 default_->ActivateCastView();
665 else 613 else
666 default_->ActivateSelectView(); 614 default_->ActivateSelectView();
667 } 615 }
668 616
669 if (tray_) 617 if (tray_)
670 tray_->SetVisible(is_casting_); 618 tray_->SetVisible(is_mirror_casting_);
671 } else { 619 } else {
672 if (default_) 620 if (default_)
673 default_->SetVisible(false); 621 default_->SetVisible(false);
674 if (tray_) 622 if (tray_)
675 tray_->SetVisible(false); 623 tray_->SetVisible(false);
676 } 624 }
677 } 625 }
678 626
627 bool TrayCast::HasActiveRoute() {
628 if (is_mirror_casting_)
629 return true;
630
631 for (const auto& sr : sinks_and_routes_) {
632 if (!sr.route.title.empty())
633 return true;
634 }
635
636 return false;
637 }
638
679 void TrayCast::OnCastingSessionStartedOrStopped(bool started) { 639 void TrayCast::OnCastingSessionStartedOrStopped(bool started) {
680 is_casting_ = started; 640 is_mirror_casting_ = started;
681 UpdatePrimaryView(); 641 UpdatePrimaryView();
682 } 642 }
683 643
684 void TrayCast::UpdateAfterShelfAlignmentChange(ShelfAlignment alignment) { 644 void TrayCast::UpdateAfterShelfAlignmentChange(ShelfAlignment alignment) {
685 if (tray_) 645 if (tray_)
686 tray_->UpdateAlignment(alignment); 646 tray_->UpdateAlignment(alignment);
687 } 647 }
688 648
689 } // namespace ash 649 } // namespace ash
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698