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

Unified Diff: ash/system/chromeos/screen_layout_observer.cc

Issue 2644593003: Fix bugs in the display notification (Closed)
Patch Set: Adding 2 more test stories Created 3 years, 11 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 side-by-side diff with in-line comments
Download patch
Index: ash/system/chromeos/screen_layout_observer.cc
diff --git a/ash/system/chromeos/screen_layout_observer.cc b/ash/system/chromeos/screen_layout_observer.cc
index a804840a608cd2997d88037dd5b4147f31a05400..602c4af53e7b8fce9763c8524566fa4a745396d9 100644
--- a/ash/system/chromeos/screen_layout_observer.cc
+++ b/ash/system/chromeos/screen_layout_observer.cc
@@ -102,35 +102,29 @@ void OpenSettingsFromNotification() {
}
}
-// Returns the name of the currently connected external display. This should not
-// be used when the external display is used for mirroring.
-base::string16 GetExternalDisplayName() {
+// Returns the name of the currently connected external display whose ID is
+// |external_display_id|. This should not be used when the external display is
+// used for mirroring.
+base::string16 GetExternalDisplayName(int64_t external_display_id) {
+ DCHECK(!display::Display::IsInternalDisplayId(external_display_id));
+
display::DisplayManager* display_manager = GetDisplayManager();
DCHECK(!display_manager->IsInMirrorMode());
- int64_t external_id = display::kInvalidDisplayId;
- for (size_t i = 0; i < display_manager->GetNumDisplays(); ++i) {
- int64_t id = display_manager->GetDisplayAt(i).id();
- if (!display::Display::IsInternalDisplayId(id)) {
- external_id = id;
- break;
- }
- }
-
- if (external_id == display::kInvalidDisplayId)
+ if (external_display_id == display::kInvalidDisplayId)
return l10n_util::GetStringUTF16(IDS_DISPLAY_NAME_UNKNOWN);
// The external display name may have an annotation of "(width x height)" in
// case that the display is rotated or its resolution is changed.
- base::string16 name = GetDisplayName(external_id);
+ base::string16 name = GetDisplayName(external_display_id);
const display::ManagedDisplayInfo& display_info =
- display_manager->GetDisplayInfo(external_id);
+ display_manager->GetDisplayInfo(external_display_id);
if (display_info.GetActiveRotation() != display::Display::ROTATE_0 ||
display_info.configured_ui_scale() != 1.0f ||
!display_info.overscan_insets_in_dip().IsEmpty()) {
name =
l10n_util::GetStringFUTF16(IDS_ASH_STATUS_TRAY_DISPLAY_ANNOTATED_NAME,
- name, GetDisplaySize(external_id));
+ name, GetDisplaySize(external_display_id));
} else if (display_info.overscan_insets_in_dip().IsEmpty() &&
display_info.has_overscan()) {
name = l10n_util::GetStringFUTF16(
@@ -142,41 +136,121 @@ base::string16 GetExternalDisplayName() {
return name;
}
-base::string16 GetDisplayMessage(base::string16* additional_message_out) {
+// Returns true if docked mode is currently enabled.
+bool IsDockedModeEnabled() {
display::DisplayManager* display_manager = GetDisplayManager();
- if (display_manager->GetNumDisplays() > 1) {
- if (display::Display::HasInternalDisplay()) {
- return l10n_util::GetStringFUTF16(IDS_ASH_STATUS_TRAY_DISPLAY_EXTENDED,
- GetExternalDisplayName());
+ if (display::Display::HasInternalDisplay()) {
+ // We have an internal display but it's not one of the active displays.
+ for (size_t i = 0; i < display_manager->GetNumDisplays(); ++i) {
+ if (display::Display::IsInternalDisplayId(
+ display_manager->GetDisplayAt(i).id())) {
+ return false;
+ }
+
+ return true;
}
- return l10n_util::GetStringUTF16(
- IDS_ASH_STATUS_TRAY_DISPLAY_EXTENDED_NO_INTERNAL);
}
- if (display_manager->IsInMirrorMode()) {
+ return false;
+}
+
+// Returns the notification message that should be shown to the user when the
+// docked mode is entered.
+base::string16 GetDockedModeEnabledMessage(
+ base::string16* out_additional_message) {
+ DCHECK(IsDockedModeEnabled());
+
+ if (out_additional_message) {
oshima 2017/01/24 17:49:41 can this be null?
afakhry 2017/01/24 22:13:22 No. Replaced with a DCHECK
+ *out_additional_message = ash::SubstituteChromeOSDeviceType(
+ IDS_ASH_STATUS_TRAY_DISPLAY_DOCKED_DESCRIPTION);
+ }
+
+ return l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_DISPLAY_DOCKED);
+}
+
+// Fills |out_message| with the appropriate notification message the should be
+// shown to the user when the status of the mirror mode is changed, and return
+// true. Otherwise, returns false and |out_message| is not modified.
+bool GetMirrorModeChangedMessage(bool current_mirror_mode,
+ base::string16* out_message,
+ base::string16* out_additional_message) {
oshima 2017/01/24 17:49:41 It's better to separate to GetExit/EnterMirrorMod
afakhry 2017/01/24 22:13:22 Done.
+ display::DisplayManager* display_manager = GetDisplayManager();
+ if (current_mirror_mode) {
if (display::Display::HasInternalDisplay()) {
- return l10n_util::GetStringFUTF16(
+ *out_message = l10n_util::GetStringFUTF16(
IDS_ASH_STATUS_TRAY_DISPLAY_MIRRORING,
GetDisplayName(display_manager->mirroring_display_id()));
+ } else {
+ *out_message = l10n_util::GetStringUTF16(
+ IDS_ASH_STATUS_TRAY_DISPLAY_MIRRORING_NO_INTERNAL);
}
- return l10n_util::GetStringUTF16(
- IDS_ASH_STATUS_TRAY_DISPLAY_MIRRORING_NO_INTERNAL);
+
+ return true;
}
- if (display_manager->IsInUnifiedMode())
- return l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_DISPLAY_UNIFIED);
+ // Handle disabling mirror mode as a result of going to docked mode when we
+ // only have a single display (this means we actually have two physical
+ // displays, one of which is the internal display, but they were in mirror
+ // mode, and hence considered as one. Closing the internal display disables
+ // mirror mode and we still have a single active display).
+ // Also make sure we're not in unified mode as this is also considered as
+ // a single display.
+ if (IsDockedModeEnabled() && display_manager->GetNumDisplays() == 1 &&
+ !display_manager->IsInUnifiedMode()) {
+ *out_message = GetDockedModeEnabledMessage(out_additional_message);
+ return true;
+ }
- int64_t primary_id = display::Screen::GetScreen()->GetPrimaryDisplay().id();
- if (display::Display::HasInternalDisplay() &&
- !(display::Display::IsInternalDisplayId(primary_id))) {
- if (additional_message_out) {
- *additional_message_out = ash::SubstituteChromeOSDeviceType(
- IDS_ASH_STATUS_TRAY_DISPLAY_DOCKED_DESCRIPTION);
- }
- return l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_DISPLAY_DOCKED);
+ if (display_manager->GetNumDisplays() > 2) {
+ // Mirror mode was turned off due to having more than two displays. Show
+ // a message that mirror mode for 3+ displays is not supported.
+ *out_message =
+ l10n_util::GetStringUTF16(IDS_ASH_DISPLAY_MIRRORING_NOT_SUPPORTED);
+ return true;
}
- return base::string16();
+ // Mirror mode was turned off; other messages should be shown e.g. extended
+ // mode is on, ... etc.
+ return false;
+}
+
+// Returns the notification message that should be shown to the user when there
+// is a change in the unified mode status.
+base::string16 GetUnifiedModeChangedMessage(bool current_unified_mode) {
+ return l10n_util::GetStringUTF16(
+ current_unified_mode ? IDS_ASH_STATUS_TRAY_DISPLAY_UNIFIED
+ : IDS_ASH_STATUS_TRAY_DISPLAY_UNIFIED_EXITING);
+}
+
+base::string16 GetDisplayRemovedMessage(
+ const display::ManagedDisplayInfo& removed_display_info,
+ base::string16* out_additional_message) {
+ // Removing the internal display means entering docked mode.
+ if (display::Display::IsInternalDisplayId(removed_display_info.id()))
+ return GetDockedModeEnabledMessage(out_additional_message);
+
+ return l10n_util::GetStringFUTF16(
+ IDS_ASH_STATUS_TRAY_DISPLAY_REMOVED,
+ base::UTF8ToUTF16(removed_display_info.name()));
+}
+
+base::string16 GetDisplayAddedMessage(int64_t added_display_id,
+ base::string16* additional_message_out) {
+ if (!display::Display::HasInternalDisplay()) {
+ return l10n_util::GetStringUTF16(
+ IDS_ASH_STATUS_TRAY_DISPLAY_EXTENDED_NO_INTERNAL);
+ }
+
+ if (display::Display::IsInternalDisplayId(added_display_id)) {
+ // Adding the internal display means exiting docked mode (IFF we are not
+ // exiting unified mode. This case should have already been handled by the
+ // time this function is called).
+ return l10n_util::GetStringUTF16(
+ IDS_ASH_STATUS_TRAY_DISPLAY_DOCKED_EXITING);
+ }
+
+ return l10n_util::GetStringFUTF16(IDS_ASH_STATUS_TRAY_DISPLAY_EXTENDED,
+ GetExternalDisplayName(added_display_id));
}
} // namespace
@@ -210,35 +284,62 @@ bool ScreenLayoutObserver::GetDisplayMessageForNotification(
const ScreenLayoutObserver::DisplayInfoMap& old_info,
base::string16* message_out,
base::string16* additional_message_out) {
- // Display is added or removed. Use the same message as the one in
- // the system tray.
- if (display_info_.size() != old_info.size()) {
- *message_out = GetDisplayMessage(additional_message_out);
+ // Detect changes in the mirror mode status.
+ if (old_is_in_mirrored_mode_ != current_is_in_mirrored_mode_ &&
+ GetMirrorModeChangedMessage(current_is_in_mirrored_mode_, message_out,
+ additional_message_out)) {
return true;
}
- for (DisplayInfoMap::const_iterator iter = display_info_.begin();
- iter != display_info_.end(); ++iter) {
- DisplayInfoMap::const_iterator old_iter = old_info.find(iter->first);
- // The display's number is same but different displays. This happens
- // for the transition between docked mode and mirrored display. Falls back
- // to GetDisplayMessage().
- if (old_iter == old_info.end()) {
- *message_out = GetDisplayMessage(additional_message_out);
+ // Detect changes in the unified mode.
+ if (old_is_in_unified_mode_ != current_is_in_unified_mode_) {
+ *message_out = GetUnifiedModeChangedMessage(current_is_in_unified_mode_);
+ return true;
+ }
+
+ // Displays are added or removed.
+ if (display_info_.size() < old_info.size()) {
+ // A display has been removed.
+ for (const auto& iter : old_info) {
+ if (display_info_.count(iter.first))
+ continue;
+
+ *message_out =
+ GetDisplayRemovedMessage(iter.second, additional_message_out);
+ return true;
+ }
+ } else if (display_info_.size() > old_info.size()) {
+ // A display has been added.
+ for (const auto& iter : display_info_) {
+ if (old_info.count(iter.first))
+ continue;
+
+ *message_out = GetDisplayAddedMessage(iter.first, additional_message_out);
return true;
}
+ }
- if (iter->second.configured_ui_scale() !=
+ for (const auto& iter : display_info_) {
+ DisplayInfoMap::const_iterator old_iter = old_info.find(iter.first);
+ if (old_iter == old_info.end()) {
+ // The display's number is same but different displays. This happens
+ // for the transition between docked mode and mirrored display.
+ // This condition can never be reached here, since it is handled above.
+ NOTREACHED();
+ return false;
+ }
+
+ if (iter.second.configured_ui_scale() !=
old_iter->second.configured_ui_scale()) {
*additional_message_out = l10n_util::GetStringFUTF16(
IDS_ASH_STATUS_TRAY_DISPLAY_RESOLUTION_CHANGED,
- GetDisplayName(iter->first), GetDisplaySize(iter->first));
+ GetDisplayName(iter.first), GetDisplaySize(iter.first));
return true;
}
- if (iter->second.GetActiveRotation() !=
+ if (iter.second.GetActiveRotation() !=
old_iter->second.GetActiveRotation()) {
int rotation_text_id = 0;
- switch (iter->second.GetActiveRotation()) {
+ switch (iter.second.GetActiveRotation()) {
case display::Display::ROTATE_0:
rotation_text_id = IDS_ASH_STATUS_TRAY_DISPLAY_STANDARD_ORIENTATION;
break;
@@ -253,7 +354,7 @@ bool ScreenLayoutObserver::GetDisplayMessageForNotification(
break;
}
*additional_message_out = l10n_util::GetStringFUTF16(
- IDS_ASH_STATUS_TRAY_DISPLAY_ROTATED, GetDisplayName(iter->first),
+ IDS_ASH_STATUS_TRAY_DISPLAY_ROTATED, GetDisplayName(iter.first),
l10n_util::GetStringUTF16(rotation_text_id));
return true;
}
@@ -304,6 +405,12 @@ void ScreenLayoutObserver::OnDisplayConfigurationChanged() {
DisplayInfoMap old_info;
UpdateDisplayInfo(&old_info);
+ old_is_in_mirrored_mode_ = current_is_in_mirrored_mode_;
+ current_is_in_mirrored_mode_ = GetDisplayManager()->IsInMirrorMode();
+
+ old_is_in_unified_mode_ = current_is_in_unified_mode_;
+ current_is_in_unified_mode_ = GetDisplayManager()->IsInUnifiedMode();
+
if (!show_notifications_for_testing)
return;

Powered by Google App Engine
This is Rietveld 408576698