display_manager_test_api.cc 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. // Copyright (c) 2012 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/test/display_manager_test_api.h"
  5. #include <cstdarg>
  6. #include <vector>
  7. #include "base/logging.h"
  8. #include "base/strings/string_split.h"
  9. #include "build/chromeos_buildflags.h"
  10. #include "ui/display/display_layout_builder.h"
  11. #include "ui/display/manager/display_manager.h"
  12. #include "ui/display/manager/display_manager_utilities.h"
  13. #include "ui/display/manager/managed_display_info.h"
  14. #include "ui/display/screen.h"
  15. #include "ui/display/util/display_util.h"
  16. namespace display {
  17. namespace test {
  18. namespace {
  19. // Indicates the default maximum of displays that chrome device can support.
  20. constexpr size_t kDefaultMaxSupportDisplayTest = 10;
  21. DisplayInfoList CreateDisplayInfoListFromString(
  22. const std::string specs,
  23. DisplayManager* display_manager) {
  24. DisplayInfoList display_info_list;
  25. std::vector<std::string> parts = base::SplitString(
  26. specs, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
  27. size_t index = 0;
  28. Displays list = display_manager->IsInUnifiedMode()
  29. ? display_manager->software_mirroring_display_list()
  30. : display_manager->active_display_list();
  31. for (std::vector<std::string>::const_iterator iter = parts.begin();
  32. iter != parts.end(); ++iter, ++index) {
  33. int64_t id = (index < list.size()) ? list[index].id() : kInvalidDisplayId;
  34. display_info_list.push_back(
  35. ManagedDisplayInfo::CreateFromSpecWithID(*iter, id));
  36. }
  37. return display_info_list;
  38. }
  39. // Gets the display |mode| for |resolution|. Returns false if no display
  40. // mode matches the resolution, or the display is an internal display.
  41. bool GetDisplayModeForResolution(const ManagedDisplayInfo& info,
  42. const gfx::Size& resolution,
  43. ManagedDisplayMode* mode) {
  44. if (IsInternalDisplayId(info.id()))
  45. return false;
  46. const ManagedDisplayInfo::ManagedDisplayModeList& modes =
  47. info.display_modes();
  48. DCHECK_NE(0u, modes.size());
  49. auto iter = std::find_if(modes.begin(), modes.end(),
  50. [resolution](const ManagedDisplayMode& mode) {
  51. return mode.size() == resolution;
  52. });
  53. if (iter == modes.end()) {
  54. DLOG(WARNING) << "Unsupported resolution was requested:"
  55. << resolution.ToString();
  56. return false;
  57. }
  58. *mode = *iter;
  59. return true;
  60. }
  61. } // namespace
  62. size_t DisplayManagerTestApi::maximum_support_display_ =
  63. kDefaultMaxSupportDisplayTest;
  64. DisplayManagerTestApi::DisplayManagerTestApi(DisplayManager* display_manager)
  65. : display_manager_(display_manager) {
  66. DCHECK(display_manager);
  67. }
  68. DisplayManagerTestApi::~DisplayManagerTestApi() {}
  69. void DisplayManagerTestApi::ResetMaximumDisplay() {
  70. maximum_support_display_ = kDefaultMaxSupportDisplayTest;
  71. }
  72. void DisplayManagerTestApi::UpdateDisplay(const std::string& display_specs) {
  73. DisplayInfoList display_info_list =
  74. CreateDisplayInfoListFromString(display_specs, display_manager_);
  75. #if BUILDFLAG(IS_CHROMEOS_ASH)
  76. if (display_info_list.size() > maximum_support_display_) {
  77. display_manager_->configurator()->has_unassociated_display_ = true;
  78. while (display_info_list.size() > maximum_support_display_)
  79. display_info_list.pop_back();
  80. } else {
  81. display_manager_->configurator()->has_unassociated_display_ = false;
  82. }
  83. #endif
  84. bool is_host_origin_set = false;
  85. for (const ManagedDisplayInfo& display_info : display_info_list) {
  86. if (display_info.bounds_in_native().origin() != gfx::Point(0, 0)) {
  87. is_host_origin_set = true;
  88. break;
  89. }
  90. }
  91. // Start from (1,1) so that windows won't overlap with native mouse cursor.
  92. // See |AshTestBase::SetUp()|.
  93. int next_y = 1;
  94. for (auto& info : display_info_list) {
  95. // On non-testing environment, when a secondary display is connected, a new
  96. // native (i.e. X) window for the display is always created below the
  97. // previous one for GPU performance reasons. Try to emulate the behavior
  98. // unless host origins are explicitly set.
  99. if (!is_host_origin_set) {
  100. gfx::Rect bounds(info.bounds_in_native().size());
  101. bounds.set_x(1);
  102. bounds.set_y(next_y);
  103. next_y += bounds.height();
  104. info.SetBounds(bounds);
  105. }
  106. // Overcan and native resolution are excluded for now as they require
  107. // special handing (has_overscan flag. resolution change makes sense
  108. // only on external).
  109. display_manager_->RegisterDisplayProperty(
  110. info.id(), info.GetRotation(Display::RotationSource::USER),
  111. /*overscan_insets=*/nullptr,
  112. /*native_resolution=*/gfx::Size(), info.device_scale_factor(),
  113. info.zoom_factor(), info.refresh_rate(), info.is_interlaced());
  114. }
  115. display_manager_->OnNativeDisplaysChanged(display_info_list);
  116. display_manager_->UpdateInternalManagedDisplayModeListForTest();
  117. display_manager_->RunPendingTasksForTest();
  118. }
  119. int64_t DisplayManagerTestApi::SetFirstDisplayAsInternalDisplay() {
  120. const Display& internal = display_manager_->active_display_list_[0];
  121. SetInternalDisplayIds({internal.id()});
  122. return Display::InternalDisplayId();
  123. }
  124. void DisplayManagerTestApi::SetInternalDisplayId(int64_t id) {
  125. SetInternalDisplayIds({id});
  126. display_manager_->UpdateInternalManagedDisplayModeListForTest();
  127. }
  128. void DisplayManagerTestApi::DisableChangeDisplayUponHostResize() {
  129. display_manager_->set_change_display_upon_host_resize(false);
  130. }
  131. const ManagedDisplayInfo& DisplayManagerTestApi::GetInternalManagedDisplayInfo(
  132. int64_t display_id) {
  133. return display_manager_->display_info_[display_id];
  134. }
  135. void DisplayManagerTestApi::SetTouchSupport(
  136. int64_t display_id,
  137. Display::TouchSupport touch_support) {
  138. display_manager_->FindDisplayForId(display_id)
  139. ->set_touch_support(touch_support);
  140. }
  141. const Display& DisplayManagerTestApi::GetSecondaryDisplay() const {
  142. CHECK_GE(display_manager_->GetNumDisplays(), 2U);
  143. const int64_t primary_display_id =
  144. Screen::GetScreen()->GetPrimaryDisplay().id();
  145. auto primary_display_iter =
  146. std::find_if(display_manager_->active_display_list_.begin(),
  147. display_manager_->active_display_list_.end(),
  148. [id = primary_display_id](const Display& display) {
  149. return display.id() == id;
  150. });
  151. DCHECK(primary_display_iter != display_manager_->active_display_list_.end());
  152. ++primary_display_iter;
  153. // If we've reach the end of |active_display_list_|, wrap back around to the
  154. // front.
  155. if (primary_display_iter == display_manager_->active_display_list_.end())
  156. return *display_manager_->active_display_list_.begin();
  157. return *primary_display_iter;
  158. }
  159. ScopedSetInternalDisplayId::ScopedSetInternalDisplayId(
  160. DisplayManager* display_manager,
  161. int64_t id) {
  162. DisplayManagerTestApi(display_manager).SetInternalDisplayId(id);
  163. }
  164. ScopedSetInternalDisplayId::~ScopedSetInternalDisplayId() {
  165. SetInternalDisplayIds({});
  166. }
  167. bool SetDisplayResolution(DisplayManager* display_manager,
  168. int64_t display_id,
  169. const gfx::Size& resolution) {
  170. const ManagedDisplayInfo& info = display_manager->GetDisplayInfo(display_id);
  171. ManagedDisplayMode mode;
  172. if (!GetDisplayModeForResolution(info, resolution, &mode))
  173. return false;
  174. return display_manager->SetDisplayMode(display_id, mode);
  175. }
  176. std::unique_ptr<DisplayLayout> CreateDisplayLayout(
  177. DisplayManager* display_manager,
  178. DisplayPlacement::Position position,
  179. int offset) {
  180. DisplayLayoutBuilder builder(Screen::GetScreen()->GetPrimaryDisplay().id());
  181. builder.SetSecondaryPlacement(
  182. DisplayManagerTestApi(display_manager).GetSecondaryDisplay().id(),
  183. position, offset);
  184. return builder.Build();
  185. }
  186. DisplayIdList CreateDisplayIdList2(int64_t id1, int64_t id2) {
  187. DisplayIdList list;
  188. list.push_back(id1);
  189. list.push_back(id2);
  190. SortDisplayIdList(&list);
  191. return list;
  192. }
  193. DisplayIdList CreateDisplayIdListN(int64_t start_id, size_t count) {
  194. DisplayIdList list;
  195. list.push_back(start_id);
  196. int64_t id = start_id;
  197. size_t N = count;
  198. while (count-- > 1) {
  199. id = display::GetNextSynthesizedDisplayId(id);
  200. list.push_back(id);
  201. }
  202. SortDisplayIdList(&list);
  203. DCHECK_EQ(N, list.size());
  204. return list;
  205. }
  206. } // namespace test
  207. } // namespace display