1// Copyright 2013 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 "ash/system/chromeos/tray_display.h"
6
7#include "ash/display/display_manager.h"
8#include "ash/root_window_controller.h"
9#include "ash/screen_util.h"
10#include "ash/shell.h"
11#include "ash/system/tray/system_tray.h"
12#include "ash/test/ash_test_base.h"
13#include "ash/test/test_system_tray_delegate.h"
14#include "base/strings/string16.h"
15#include "base/strings/utf_string_conversions.h"
16#include "grit/ash_strings.h"
17#include "ui/accessibility/ax_view_state.h"
18#include "ui/base/l10n/l10n_util.h"
19#include "ui/gfx/display.h"
20#include "ui/message_center/message_center.h"
21#include "ui/message_center/notification.h"
22#include "ui/message_center/notification_list.h"
23#include "ui/views/controls/label.h"
24
25namespace ash {
26
27base::string16 GetTooltipText(const base::string16& headline,
28                              const base::string16& name1,
29                              const std::string& data1,
30                              const base::string16& name2,
31                              const std::string& data2) {
32  std::vector<base::string16> lines;
33  lines.push_back(headline);
34  if (data1.empty()) {
35    lines.push_back(name1);
36  } else {
37    lines.push_back(l10n_util::GetStringFUTF16(
38        IDS_ASH_STATUS_TRAY_DISPLAY_SINGLE_DISPLAY,
39        name1, base::UTF8ToUTF16(data1)));
40  }
41  if (!name2.empty()) {
42    lines.push_back(l10n_util::GetStringFUTF16(
43        IDS_ASH_STATUS_TRAY_DISPLAY_SINGLE_DISPLAY,
44        name2, base::UTF8ToUTF16(data2)));
45  }
46  return JoinString(lines, '\n');
47}
48
49base::string16 GetMirroredTooltipText(const base::string16& headline,
50                                      const base::string16& name,
51                                      const std::string& data) {
52  return GetTooltipText(headline, name, data, base::string16(), "");
53}
54
55base::string16 GetFirstDisplayName() {
56  DisplayManager* display_manager = Shell::GetInstance()->display_manager();
57  return base::UTF8ToUTF16(display_manager->GetDisplayNameForId(
58      display_manager->first_display_id()));
59}
60
61base::string16 GetSecondDisplayName() {
62  return base::UTF8ToUTF16(
63      Shell::GetInstance()->display_manager()->GetDisplayNameForId(
64          ScreenUtil::GetSecondaryDisplay().id()));
65}
66
67base::string16 GetMirroredDisplayName() {
68  DisplayManager* display_manager = Shell::GetInstance()->display_manager();
69  return base::UTF8ToUTF16(display_manager->GetDisplayNameForId(
70      display_manager->mirrored_display_id()));
71}
72
73class TrayDisplayTest : public ash::test::AshTestBase {
74 public:
75  TrayDisplayTest();
76  virtual ~TrayDisplayTest();
77
78  virtual void SetUp() OVERRIDE;
79
80 protected:
81  SystemTray* tray() { return tray_; }
82  TrayDisplay* tray_display() { return tray_display_; }
83
84  void CloseNotification();
85  bool IsDisplayVisibleInTray() const;
86  base::string16 GetTrayDisplayText() const;
87  void CheckAccessibleName() const;
88  base::string16 GetTrayDisplayTooltipText() const;
89  base::string16 GetDisplayNotificationText() const;
90  base::string16 GetDisplayNotificationAdditionalText() const;
91
92 private:
93  const message_center::Notification* GetDisplayNotification() const;
94
95  // Weak reference, owned by Shell.
96  SystemTray* tray_;
97
98  // Weak reference, owned by |tray_|.
99  TrayDisplay* tray_display_;
100
101  DISALLOW_COPY_AND_ASSIGN(TrayDisplayTest);
102};
103
104TrayDisplayTest::TrayDisplayTest() : tray_(NULL), tray_display_(NULL) {
105}
106
107TrayDisplayTest::~TrayDisplayTest() {
108}
109
110void TrayDisplayTest::SetUp() {
111  ash::test::AshTestBase::SetUp();
112  tray_ = Shell::GetPrimaryRootWindowController()->GetSystemTray();
113  tray_display_ = new TrayDisplay(tray_);
114  tray_->AddTrayItem(tray_display_);
115}
116
117void TrayDisplayTest::CloseNotification() {
118  message_center::MessageCenter::Get()->RemoveNotification(
119      TrayDisplay::kNotificationId, false);
120  RunAllPendingInMessageLoop();
121}
122
123bool TrayDisplayTest::IsDisplayVisibleInTray() const {
124  return tray_->HasSystemBubble() &&
125      tray_display_->default_view() &&
126      tray_display_->default_view()->visible();
127}
128
129base::string16 TrayDisplayTest::GetTrayDisplayText() const {
130  return tray_display_->GetDefaultViewMessage();
131}
132
133void TrayDisplayTest::CheckAccessibleName() const {
134  ui::AXViewState state;
135  if (tray_display_->GetAccessibleStateForTesting(&state)) {
136    base::string16 expected = tray_display_->GetDefaultViewMessage();
137    EXPECT_EQ(expected, state.name);
138  }
139}
140
141base::string16 TrayDisplayTest::GetTrayDisplayTooltipText() const {
142  if (!tray_display_->default_view())
143    return base::string16();
144
145  base::string16 tooltip;
146  if (!tray_display_->default_view()->GetTooltipText(gfx::Point(), &tooltip))
147    return base::string16();
148  return tooltip;
149}
150
151base::string16 TrayDisplayTest::GetDisplayNotificationText() const {
152  const message_center::Notification* notification = GetDisplayNotification();
153  return notification ? notification->title() : base::string16();
154}
155
156base::string16 TrayDisplayTest::GetDisplayNotificationAdditionalText() const {
157  const message_center::Notification* notification = GetDisplayNotification();
158  return notification ? notification->message() : base::string16();
159}
160
161const message_center::Notification* TrayDisplayTest::GetDisplayNotification()
162    const {
163  const message_center::NotificationList::Notifications notifications =
164      message_center::MessageCenter::Get()->GetVisibleNotifications();
165  for (message_center::NotificationList::Notifications::const_iterator iter =
166           notifications.begin(); iter != notifications.end(); ++iter) {
167    if ((*iter)->id() == TrayDisplay::kNotificationId)
168      return *iter;
169  }
170
171  return NULL;
172}
173
174TEST_F(TrayDisplayTest, NoInternalDisplay) {
175  UpdateDisplay("400x400");
176  tray()->ShowDefaultView(BUBBLE_USE_EXISTING);
177  EXPECT_FALSE(IsDisplayVisibleInTray());
178
179  UpdateDisplay("400x400,200x200");
180  tray()->ShowDefaultView(BUBBLE_USE_EXISTING);
181  EXPECT_TRUE(IsDisplayVisibleInTray());
182  base::string16 expected = l10n_util::GetStringUTF16(
183      IDS_ASH_STATUS_TRAY_DISPLAY_EXTENDED_NO_INTERNAL);
184  base::string16 first_name = GetFirstDisplayName();
185  EXPECT_EQ(expected, GetTrayDisplayText());
186  EXPECT_EQ(GetTooltipText(expected, GetFirstDisplayName(), "400x400",
187                           GetSecondDisplayName(), "200x200"),
188            GetTrayDisplayTooltipText());
189  CheckAccessibleName();
190
191  // mirroring
192  Shell::GetInstance()->display_manager()->SetSoftwareMirroring(true);
193  UpdateDisplay("400x400,200x200");
194  tray()->ShowDefaultView(BUBBLE_USE_EXISTING);
195  EXPECT_TRUE(IsDisplayVisibleInTray());
196  expected = l10n_util::GetStringUTF16(
197      IDS_ASH_STATUS_TRAY_DISPLAY_MIRRORING_NO_INTERNAL);
198  EXPECT_EQ(expected, GetTrayDisplayText());
199  EXPECT_EQ(GetMirroredTooltipText(expected, GetFirstDisplayName(), "400x400"),
200            GetTrayDisplayTooltipText());
201  CheckAccessibleName();
202}
203
204TEST_F(TrayDisplayTest, InternalDisplay) {
205  UpdateDisplay("400x400");
206  DisplayManager* display_manager = Shell::GetInstance()->display_manager();
207  gfx::Display::SetInternalDisplayId(display_manager->first_display_id());
208
209  tray()->ShowDefaultView(BUBBLE_USE_EXISTING);
210  EXPECT_FALSE(IsDisplayVisibleInTray());
211
212  // Extended
213  UpdateDisplay("400x400,200x200");
214  base::string16 expected = l10n_util::GetStringFUTF16(
215      IDS_ASH_STATUS_TRAY_DISPLAY_EXTENDED, GetSecondDisplayName());
216  tray()->ShowDefaultView(BUBBLE_USE_EXISTING);
217  EXPECT_TRUE(IsDisplayVisibleInTray());
218  EXPECT_EQ(expected, GetTrayDisplayText());
219  EXPECT_EQ(GetTooltipText(expected, GetFirstDisplayName(), "400x400",
220                           GetSecondDisplayName(), "200x200"),
221            GetTrayDisplayTooltipText());
222  CheckAccessibleName();
223
224  // Mirroring
225  display_manager->SetSoftwareMirroring(true);
226  UpdateDisplay("400x400,200x200");
227  tray()->ShowDefaultView(BUBBLE_USE_EXISTING);
228  EXPECT_TRUE(IsDisplayVisibleInTray());
229
230  expected = l10n_util::GetStringFUTF16(
231      IDS_ASH_STATUS_TRAY_DISPLAY_MIRRORING, GetMirroredDisplayName());
232  EXPECT_EQ(expected, GetTrayDisplayText());
233  EXPECT_EQ(GetMirroredTooltipText(expected, GetFirstDisplayName(), "400x400"),
234            GetTrayDisplayTooltipText());
235  CheckAccessibleName();
236}
237
238TEST_F(TrayDisplayTest, InternalDisplayResized) {
239  UpdateDisplay("400x400@1.5");
240  DisplayManager* display_manager = Shell::GetInstance()->display_manager();
241  gfx::Display::SetInternalDisplayId(display_manager->first_display_id());
242
243  // Shows the tray_display even though there's a single-display.
244  tray()->ShowDefaultView(BUBBLE_USE_EXISTING);
245  EXPECT_TRUE(IsDisplayVisibleInTray());
246  base::string16 internal_info = l10n_util::GetStringFUTF16(
247      IDS_ASH_STATUS_TRAY_DISPLAY_SINGLE_DISPLAY,
248      GetFirstDisplayName(), base::UTF8ToUTF16("600x600"));
249  EXPECT_EQ(internal_info, GetTrayDisplayText());
250  EXPECT_EQ(GetTooltipText(base::string16(), GetFirstDisplayName(), "600x600",
251                           base::string16(), std::string()),
252            GetTrayDisplayTooltipText());
253  CheckAccessibleName();
254
255  // Extended
256  UpdateDisplay("400x400@1.5,200x200");
257  tray()->ShowDefaultView(BUBBLE_USE_EXISTING);
258  EXPECT_TRUE(IsDisplayVisibleInTray());
259  base::string16 expected = l10n_util::GetStringFUTF16(
260      IDS_ASH_STATUS_TRAY_DISPLAY_EXTENDED, GetSecondDisplayName());
261  EXPECT_EQ(expected, GetTrayDisplayText());
262  EXPECT_EQ(GetTooltipText(expected, GetFirstDisplayName(), "600x600",
263                           GetSecondDisplayName(), "200x200"),
264            GetTrayDisplayTooltipText());
265  CheckAccessibleName();
266
267  // Mirroring
268  display_manager->SetSoftwareMirroring(true);
269  UpdateDisplay("400x400@1.5,200x200");
270  tray()->ShowDefaultView(BUBBLE_USE_EXISTING);
271  EXPECT_TRUE(IsDisplayVisibleInTray());
272  expected = l10n_util::GetStringFUTF16(
273      IDS_ASH_STATUS_TRAY_DISPLAY_MIRRORING, GetMirroredDisplayName());
274  EXPECT_EQ(expected, GetTrayDisplayText());
275  EXPECT_EQ(GetMirroredTooltipText(expected, GetFirstDisplayName(), "600x600"),
276            GetTrayDisplayTooltipText());
277  CheckAccessibleName();
278
279  // Closed lid mode.
280  display_manager->SetSoftwareMirroring(false);
281  UpdateDisplay("400x400@1.5,200x200");
282  gfx::Display::SetInternalDisplayId(ScreenUtil::GetSecondaryDisplay().id());
283  UpdateDisplay("400x400@1.5");
284  tray()->ShowDefaultView(BUBBLE_USE_EXISTING);
285  EXPECT_TRUE(IsDisplayVisibleInTray());
286  expected = l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_DISPLAY_DOCKED);
287  EXPECT_EQ(expected, GetTrayDisplayText());
288  EXPECT_EQ(
289      GetTooltipText(
290          expected, GetFirstDisplayName(), "600x600", base::string16(), ""),
291      GetTrayDisplayTooltipText());
292  CheckAccessibleName();
293}
294
295TEST_F(TrayDisplayTest, ExternalDisplayResized) {
296  UpdateDisplay("400x400");
297  DisplayManager* display_manager = Shell::GetInstance()->display_manager();
298  gfx::Display::SetInternalDisplayId(display_manager->first_display_id());
299
300  // Shows the tray_display even though there's a single-display.
301  tray()->ShowDefaultView(BUBBLE_USE_EXISTING);
302  EXPECT_FALSE(IsDisplayVisibleInTray());
303
304  // Extended
305  UpdateDisplay("400x400,200x200@1.5");
306  const gfx::Display& secondary_display = ScreenUtil::GetSecondaryDisplay();
307
308  tray()->ShowDefaultView(BUBBLE_USE_EXISTING);
309  EXPECT_TRUE(IsDisplayVisibleInTray());
310  base::string16 expected = l10n_util::GetStringFUTF16(
311      IDS_ASH_STATUS_TRAY_DISPLAY_EXTENDED,
312      l10n_util::GetStringFUTF16(
313          IDS_ASH_STATUS_TRAY_DISPLAY_ANNOTATED_NAME,
314          GetSecondDisplayName(),
315          base::UTF8ToUTF16(secondary_display.size().ToString())));
316  EXPECT_EQ(expected, GetTrayDisplayText());
317  EXPECT_EQ(GetTooltipText(expected, GetFirstDisplayName(), "400x400",
318                           GetSecondDisplayName(), "300x300"),
319            GetTrayDisplayTooltipText());
320  CheckAccessibleName();
321
322  // Mirroring
323  display_manager->SetSoftwareMirroring(true);
324  UpdateDisplay("400x400,200x200@1.5");
325  tray()->ShowDefaultView(BUBBLE_USE_EXISTING);
326  EXPECT_TRUE(IsDisplayVisibleInTray());
327  expected = l10n_util::GetStringFUTF16(
328      IDS_ASH_STATUS_TRAY_DISPLAY_MIRRORING, GetMirroredDisplayName());
329  EXPECT_EQ(expected, GetTrayDisplayText());
330  EXPECT_EQ(GetMirroredTooltipText(expected, GetFirstDisplayName(), "400x400"),
331            GetTrayDisplayTooltipText());
332  CheckAccessibleName();
333}
334
335TEST_F(TrayDisplayTest, OverscanDisplay) {
336  UpdateDisplay("400x400,300x300/o");
337  DisplayManager* display_manager = Shell::GetInstance()->display_manager();
338  gfx::Display::SetInternalDisplayId(display_manager->first_display_id());
339
340  tray()->ShowDefaultView(BUBBLE_USE_EXISTING);
341  EXPECT_TRUE(IsDisplayVisibleInTray());
342
343  // /o creates the default overscan, and if overscan is set, the annotation
344  // should be the size.
345  base::string16 overscan = l10n_util::GetStringUTF16(
346      IDS_ASH_STATUS_TRAY_DISPLAY_ANNOTATION_OVERSCAN);
347  base::string16 headline = l10n_util::GetStringFUTF16(
348      IDS_ASH_STATUS_TRAY_DISPLAY_EXTENDED,
349      l10n_util::GetStringFUTF16(
350          IDS_ASH_STATUS_TRAY_DISPLAY_ANNOTATED_NAME,
351          GetSecondDisplayName(), base::UTF8ToUTF16("286x286")));
352  std::string second_data = l10n_util::GetStringFUTF8(
353      IDS_ASH_STATUS_TRAY_DISPLAY_ANNOTATION,
354      base::UTF8ToUTF16("286x286"), overscan);
355  EXPECT_EQ(GetTooltipText(headline, GetFirstDisplayName(), "400x400",
356                           GetSecondDisplayName(), second_data),
357            GetTrayDisplayTooltipText());
358
359  // reset the overscan.
360  display_manager->SetOverscanInsets(
361      ScreenUtil::GetSecondaryDisplay().id(), gfx::Insets());
362  headline = l10n_util::GetStringFUTF16(
363      IDS_ASH_STATUS_TRAY_DISPLAY_EXTENDED,
364      l10n_util::GetStringFUTF16(
365          IDS_ASH_STATUS_TRAY_DISPLAY_ANNOTATED_NAME,
366          GetSecondDisplayName(), overscan));
367  second_data = l10n_util::GetStringFUTF8(
368      IDS_ASH_STATUS_TRAY_DISPLAY_ANNOTATION,
369      base::UTF8ToUTF16("300x300"), overscan);
370  EXPECT_EQ(GetTooltipText(headline, GetFirstDisplayName(), "400x400",
371                           GetSecondDisplayName(), second_data),
372            GetTrayDisplayTooltipText());
373}
374
375TEST_F(TrayDisplayTest, UpdateDuringDisplayConfigurationChange) {
376  tray()->ShowDefaultView(BUBBLE_USE_EXISTING);
377  EXPECT_FALSE(IsDisplayVisibleInTray());
378
379  UpdateDisplay("400x400@1.5");
380  EXPECT_TRUE(tray()->HasSystemBubble());
381  EXPECT_TRUE(IsDisplayVisibleInTray());
382  base::string16 internal_info = l10n_util::GetStringFUTF16(
383      IDS_ASH_STATUS_TRAY_DISPLAY_SINGLE_DISPLAY,
384      GetFirstDisplayName(), base::UTF8ToUTF16("600x600"));
385  EXPECT_EQ(internal_info, GetTrayDisplayText());
386  EXPECT_EQ(GetTooltipText(base::string16(), GetFirstDisplayName(), "600x600",
387                           base::string16(), std::string()),
388            GetTrayDisplayTooltipText());
389  CheckAccessibleName();
390
391  UpdateDisplay("400x400,200x200");
392  EXPECT_TRUE(tray()->HasSystemBubble());
393  EXPECT_TRUE(IsDisplayVisibleInTray());
394  base::string16 expected = l10n_util::GetStringUTF16(
395      IDS_ASH_STATUS_TRAY_DISPLAY_EXTENDED_NO_INTERNAL);
396  base::string16 first_name = GetFirstDisplayName();
397  EXPECT_EQ(expected, GetTrayDisplayText());
398  EXPECT_EQ(GetTooltipText(expected, GetFirstDisplayName(), "400x400",
399                           GetSecondDisplayName(), "200x200"),
400            GetTrayDisplayTooltipText());
401  CheckAccessibleName();
402
403  UpdateDisplay("400x400@1.5");
404  tray()->ShowDefaultView(BUBBLE_USE_EXISTING);
405
406  // Back to the default state, the display tray item should disappear.
407  UpdateDisplay("400x400");
408  EXPECT_TRUE(tray()->HasSystemBubble());
409  EXPECT_FALSE(IsDisplayVisibleInTray());
410}
411
412TEST_F(TrayDisplayTest, DisplayNotifications) {
413  test::TestSystemTrayDelegate* tray_delegate =
414      static_cast<test::TestSystemTrayDelegate*>(
415          Shell::GetInstance()->system_tray_delegate());
416  tray_delegate->set_should_show_display_notification(true);
417
418  UpdateDisplay("400x400");
419  DisplayManager* display_manager = Shell::GetInstance()->display_manager();
420  gfx::Display::SetInternalDisplayId(display_manager->first_display_id());
421  EXPECT_TRUE(GetDisplayNotificationText().empty());
422
423  // rotation.
424  UpdateDisplay("400x400/r");
425  EXPECT_EQ(
426      l10n_util::GetStringFUTF16(
427          IDS_ASH_STATUS_TRAY_DISPLAY_ROTATED, GetFirstDisplayName(),
428          l10n_util::GetStringUTF16(
429              IDS_ASH_STATUS_TRAY_DISPLAY_ORIENTATION_90)),
430      GetDisplayNotificationText());
431  EXPECT_TRUE(GetDisplayNotificationAdditionalText().empty());
432
433  CloseNotification();
434  UpdateDisplay("400x400");
435  EXPECT_EQ(
436      l10n_util::GetStringFUTF16(
437          IDS_ASH_STATUS_TRAY_DISPLAY_ROTATED, GetFirstDisplayName(),
438          l10n_util::GetStringUTF16(
439              IDS_ASH_STATUS_TRAY_DISPLAY_STANDARD_ORIENTATION)),
440      GetDisplayNotificationText());
441  EXPECT_TRUE(GetDisplayNotificationAdditionalText().empty());
442
443  // UI-scale
444  CloseNotification();
445  UpdateDisplay("400x400@1.5");
446  EXPECT_EQ(
447      l10n_util::GetStringFUTF16(
448          IDS_ASH_STATUS_TRAY_DISPLAY_RESOLUTION_CHANGED,
449          GetFirstDisplayName(), base::UTF8ToUTF16("600x600")),
450      GetDisplayNotificationText());
451  EXPECT_TRUE(GetDisplayNotificationAdditionalText().empty());
452
453  // UI-scale to 1.0
454  CloseNotification();
455  UpdateDisplay("400x400");
456  EXPECT_EQ(
457      l10n_util::GetStringFUTF16(
458          IDS_ASH_STATUS_TRAY_DISPLAY_RESOLUTION_CHANGED,
459          GetFirstDisplayName(), base::UTF8ToUTF16("400x400")),
460      GetDisplayNotificationText());
461  EXPECT_TRUE(GetDisplayNotificationAdditionalText().empty());
462
463  // No-update
464  CloseNotification();
465  UpdateDisplay("400x400");
466  EXPECT_TRUE(GetDisplayNotificationText().empty());
467  EXPECT_TRUE(GetDisplayNotificationAdditionalText().empty());
468
469  // Extended.
470  CloseNotification();
471  UpdateDisplay("400x400,200x200");
472  EXPECT_EQ(
473      l10n_util::GetStringFUTF16(
474          IDS_ASH_STATUS_TRAY_DISPLAY_EXTENDED, GetSecondDisplayName()),
475      GetDisplayNotificationText());
476  EXPECT_TRUE(GetDisplayNotificationAdditionalText().empty());
477
478  // Mirroring.
479  CloseNotification();
480  display_manager->SetSoftwareMirroring(true);
481  UpdateDisplay("400x400,200x200");
482  EXPECT_EQ(
483      l10n_util::GetStringFUTF16(
484          IDS_ASH_STATUS_TRAY_DISPLAY_MIRRORING, GetMirroredDisplayName()),
485      GetDisplayNotificationText());
486  EXPECT_TRUE(GetDisplayNotificationAdditionalText().empty());
487
488  // Back to extended.
489  CloseNotification();
490  display_manager->SetSoftwareMirroring(false);
491  UpdateDisplay("400x400,200x200");
492  EXPECT_EQ(
493      l10n_util::GetStringFUTF16(
494          IDS_ASH_STATUS_TRAY_DISPLAY_EXTENDED, GetSecondDisplayName()),
495      GetDisplayNotificationText());
496  EXPECT_TRUE(GetDisplayNotificationAdditionalText().empty());
497
498  // Resize the first display.
499  UpdateDisplay("400x400@1.5,200x200");
500  EXPECT_EQ(
501      l10n_util::GetStringFUTF16(
502          IDS_ASH_STATUS_TRAY_DISPLAY_RESOLUTION_CHANGED,
503          GetFirstDisplayName(), base::UTF8ToUTF16("600x600")),
504      GetDisplayNotificationText());
505  EXPECT_TRUE(GetDisplayNotificationAdditionalText().empty());
506
507  // Rotate the second.
508  UpdateDisplay("400x400@1.5,200x200/r");
509  EXPECT_EQ(
510      l10n_util::GetStringFUTF16(
511          IDS_ASH_STATUS_TRAY_DISPLAY_ROTATED,
512          GetSecondDisplayName(),
513          l10n_util::GetStringUTF16(
514              IDS_ASH_STATUS_TRAY_DISPLAY_ORIENTATION_90)),
515      GetDisplayNotificationText());
516  EXPECT_TRUE(GetDisplayNotificationAdditionalText().empty());
517
518  // Enters closed lid mode.
519  UpdateDisplay("400x400@1.5,200x200");
520  gfx::Display::SetInternalDisplayId(ScreenUtil::GetSecondaryDisplay().id());
521  UpdateDisplay("400x400@1.5");
522  EXPECT_EQ(l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_DISPLAY_DOCKED),
523            GetDisplayNotificationText());
524  EXPECT_EQ(
525      l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_DISPLAY_DOCKED_DESCRIPTION),
526      GetDisplayNotificationAdditionalText());
527}
528
529TEST_F(TrayDisplayTest, DisplayConfigurationChangedTwice) {
530  test::TestSystemTrayDelegate* tray_delegate =
531      static_cast<test::TestSystemTrayDelegate*>(
532          Shell::GetInstance()->system_tray_delegate());
533  tray_delegate->set_should_show_display_notification(true);
534
535  UpdateDisplay("400x400,200x200");
536  EXPECT_EQ(
537      l10n_util::GetStringUTF16(
538          IDS_ASH_STATUS_TRAY_DISPLAY_EXTENDED_NO_INTERNAL),
539      GetDisplayNotificationText());
540
541  // OnDisplayConfigurationChanged() may be called more than once for a single
542  // update display in case of primary is swapped or recovered from dock mode.
543  // Should not remove the notification in such case.
544  tray_display()->OnDisplayConfigurationChanged();
545  EXPECT_EQ(
546      l10n_util::GetStringUTF16(
547          IDS_ASH_STATUS_TRAY_DISPLAY_EXTENDED_NO_INTERNAL),
548      GetDisplayNotificationText());
549
550  // Back to the single display. It SHOULD remove the notification since the
551  // information is stale.
552  UpdateDisplay("400x400");
553  EXPECT_TRUE(GetDisplayNotificationText().empty());
554}
555
556TEST_F(TrayDisplayTest, UpdateAfterSuppressDisplayNotification) {
557  UpdateDisplay("400x400,200x200");
558
559  test::TestSystemTrayDelegate* tray_delegate =
560      static_cast<test::TestSystemTrayDelegate*>(
561          Shell::GetInstance()->system_tray_delegate());
562  tray_delegate->set_should_show_display_notification(true);
563
564  // rotate the second.
565  UpdateDisplay("400x400,200x200/r");
566  EXPECT_EQ(
567      l10n_util::GetStringFUTF16(
568          IDS_ASH_STATUS_TRAY_DISPLAY_ROTATED,
569          GetSecondDisplayName(),
570          l10n_util::GetStringUTF16(
571              IDS_ASH_STATUS_TRAY_DISPLAY_ORIENTATION_90)),
572      GetDisplayNotificationText());
573}
574
575}  // namespace ash
576