display_util.cc 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. // Copyright 2018 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. #include "ui/display/display_util.h"
  5. #include "build/build_config.h"
  6. #include "ui/display/display.h"
  7. #include "ui/display/screen.h"
  8. #include "ui/gfx/icc_profile.h"
  9. namespace display {
  10. // static
  11. void DisplayUtil::DisplayToScreenInfo(ScreenInfo* screen_info,
  12. const Display& display) {
  13. screen_info->rect = display.bounds();
  14. // TODO(husky): Remove any Android system controls from availableRect.
  15. screen_info->available_rect = display.work_area();
  16. screen_info->device_scale_factor = display.device_scale_factor();
  17. screen_info->display_color_spaces = display.color_spaces();
  18. screen_info->depth = display.color_depth();
  19. screen_info->depth_per_component = display.depth_per_component();
  20. screen_info->is_monochrome = display.is_monochrome();
  21. screen_info->display_frequency = display.display_frequency();
  22. // TODO(https://crbug.com/998131): Expose panel orientation via a proper web
  23. // API instead of window.screen.orientation.angle.
  24. screen_info->orientation_angle = display.PanelRotationAsDegree();
  25. #if defined(USE_AURA)
  26. // The Display rotation and the ScreenInfo orientation are not the same
  27. // angle. The former is the physical display rotation while the later is the
  28. // rotation required by the content to be shown properly on the screen, in
  29. // other words, relative to the physical display.
  30. // Spec: https://w3c.github.io/screen-orientation/#dom-screenorientation-angle
  31. // TODO(ccameron): Should this apply to macOS? Should this be reconciled at a
  32. // higher level (say, in conversion to ScreenInfo)?
  33. if (screen_info->orientation_angle == 90)
  34. screen_info->orientation_angle = 270;
  35. else if (screen_info->orientation_angle == 270)
  36. screen_info->orientation_angle = 90;
  37. #endif
  38. #if BUILDFLAG(IS_ANDROID)
  39. screen_info->orientation_type = GetOrientationTypeForMobile(display);
  40. #else
  41. screen_info->orientation_type = GetOrientationTypeForDesktop(display);
  42. #endif
  43. // TODO(crbug.com/1194700 and crbug.com/1182855): Use cross-process screen
  44. // info caches, not local-process info, for child frames and Mac's shim.
  45. auto* screen = Screen::GetScreen();
  46. // Some tests are run with no Screen initialized.
  47. screen_info->is_extended = screen && screen->GetNumDisplays() > 1;
  48. screen_info->is_primary =
  49. screen && (screen->GetPrimaryDisplay().id() == display.id());
  50. screen_info->is_internal = display.IsInternal();
  51. screen_info->display_id = display.id();
  52. screen_info->label = display.label();
  53. }
  54. // static
  55. void DisplayUtil::GetDefaultScreenInfo(ScreenInfo* screen_info) {
  56. return GetNativeViewScreenInfo(screen_info, nullptr);
  57. }
  58. // static
  59. void DisplayUtil::GetNativeViewScreenInfo(ScreenInfo* screen_info,
  60. gfx::NativeView native_view) {
  61. // Some tests are run with no Screen initialized.
  62. Screen* screen = Screen::GetScreen();
  63. if (!screen) {
  64. *screen_info = ScreenInfo();
  65. return;
  66. }
  67. Display display = native_view ? screen->GetDisplayNearestView(native_view)
  68. : screen->GetPrimaryDisplay();
  69. DisplayToScreenInfo(screen_info, display);
  70. }
  71. // static
  72. mojom::ScreenOrientation DisplayUtil::GetOrientationTypeForMobile(
  73. const Display& display) {
  74. int angle = display.PanelRotationAsDegree();
  75. const gfx::Rect& bounds = display.bounds();
  76. // Whether the device's natural orientation is portrait.
  77. bool natural_portrait = false;
  78. if (angle == 0 || angle == 180) // The device is in its natural orientation.
  79. natural_portrait = bounds.height() >= bounds.width();
  80. else
  81. natural_portrait = bounds.height() <= bounds.width();
  82. switch (angle) {
  83. case 0:
  84. return natural_portrait ? mojom::ScreenOrientation::kPortraitPrimary
  85. : mojom::ScreenOrientation::kLandscapePrimary;
  86. case 90:
  87. return natural_portrait ? mojom::ScreenOrientation::kLandscapePrimary
  88. : mojom::ScreenOrientation::kPortraitSecondary;
  89. case 180:
  90. return natural_portrait ? mojom::ScreenOrientation::kPortraitSecondary
  91. : mojom::ScreenOrientation::kLandscapeSecondary;
  92. case 270:
  93. return natural_portrait ? mojom::ScreenOrientation::kLandscapeSecondary
  94. : mojom::ScreenOrientation::kPortraitPrimary;
  95. default:
  96. NOTREACHED();
  97. return mojom::ScreenOrientation::kPortraitPrimary;
  98. }
  99. }
  100. // static
  101. mojom::ScreenOrientation DisplayUtil::GetOrientationTypeForDesktop(
  102. const Display& display) {
  103. static int primary_landscape_angle = -1;
  104. static int primary_portrait_angle = -1;
  105. int angle = display.PanelRotationAsDegree();
  106. const gfx::Rect& bounds = display.bounds();
  107. bool is_portrait = bounds.height() >= bounds.width();
  108. if (is_portrait && primary_portrait_angle == -1)
  109. primary_portrait_angle = angle;
  110. if (!is_portrait && primary_landscape_angle == -1)
  111. primary_landscape_angle = angle;
  112. if (is_portrait) {
  113. return primary_portrait_angle == angle
  114. ? mojom::ScreenOrientation::kPortraitPrimary
  115. : mojom::ScreenOrientation::kPortraitSecondary;
  116. }
  117. return primary_landscape_angle == angle
  118. ? mojom::ScreenOrientation::kLandscapePrimary
  119. : mojom::ScreenOrientation::kLandscapeSecondary;
  120. }
  121. } // namespace display