| // Copyright 2018 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "content/browser/renderer_host/display_util.h" |
| |
| #include "build/build_config.h" |
| #include "content/browser/renderer_host/render_widget_host_view_base.h" |
| #include "content/public/common/screen_info.h" |
| #include "ui/display/display.h" |
| #include "ui/display/screen.h" |
| #include "ui/gfx/icc_profile.h" |
| |
| namespace content { |
| |
| // static |
| void DisplayUtil::DisplayToScreenInfo(ScreenInfo* screen_info, |
| const display::Display& display) { |
| screen_info->rect = display.bounds(); |
| // TODO(husky): Remove any Android system controls from availableRect. |
| screen_info->available_rect = display.work_area(); |
| screen_info->device_scale_factor = display.device_scale_factor(); |
| screen_info->color_space = display.color_space(); |
| screen_info->depth = display.color_depth(); |
| screen_info->depth_per_component = display.depth_per_component(); |
| screen_info->is_monochrome = display.is_monochrome(); |
| |
| screen_info->orientation_angle = display.RotationAsDegree(); |
| #if defined(USE_AURA) |
| // The Display rotation and the ScreenInfo orientation are not the same |
| // angle. The former is the physical display rotation while the later is the |
| // rotation required by the content to be shown properly on the screen, in |
| // other words, relative to the physical display. |
| // TODO(ccameron): Should this apply to macOS? Should this be reconciled at a |
| // higher level (say, in conversion to WebScreenInfo)? |
| if (screen_info->orientation_angle == 90) |
| screen_info->orientation_angle = 270; |
| else if (screen_info->orientation_angle == 270) |
| screen_info->orientation_angle = 90; |
| #endif |
| |
| #if defined(OS_ANDROID) |
| screen_info->orientation_type = GetOrientationTypeForMobile(display); |
| #else |
| screen_info->orientation_type = GetOrientationTypeForDesktop(display); |
| #endif |
| } |
| |
| // static |
| void DisplayUtil::GetDefaultScreenInfo(ScreenInfo* screen_info) { |
| // Some tests are run with no Screen initialized. |
| display::Screen* screen = display::Screen::GetScreen(); |
| if (!screen) { |
| *screen_info = ScreenInfo(); |
| return; |
| } |
| #if defined(USE_AURA) |
| // This behavior difference between Aura and other platforms may or may not |
| // be intentional, and may or may not have any effect. |
| gfx::NativeView null_native_view = nullptr; |
| display::Display display = screen->GetDisplayNearestView(null_native_view); |
| #else |
| display::Display display = screen->GetPrimaryDisplay(); |
| #endif |
| DisplayToScreenInfo(screen_info, display); |
| } |
| |
| // static |
| void DisplayUtil::GetNativeViewScreenInfo(ScreenInfo* screen_info, |
| gfx::NativeView native_view) { |
| // Some tests are run with no Screen initialized. |
| display::Screen* screen = display::Screen::GetScreen(); |
| if (!screen) { |
| *screen_info = ScreenInfo(); |
| return; |
| } |
| display::Display display = native_view |
| ? screen->GetDisplayNearestView(native_view) |
| : screen->GetPrimaryDisplay(); |
| DisplayToScreenInfo(screen_info, display); |
| } |
| |
| // static |
| ScreenOrientationValues DisplayUtil::GetOrientationTypeForMobile( |
| const display::Display& display) { |
| int angle = display.RotationAsDegree(); |
| const gfx::Rect& bounds = display.bounds(); |
| |
| // Whether the device's natural orientation is portrait. |
| bool natural_portrait = false; |
| if (angle == 0 || angle == 180) // The device is in its natural orientation. |
| natural_portrait = bounds.height() >= bounds.width(); |
| else |
| natural_portrait = bounds.height() <= bounds.width(); |
| |
| switch (angle) { |
| case 0: |
| return natural_portrait ? SCREEN_ORIENTATION_VALUES_PORTRAIT_PRIMARY |
| : SCREEN_ORIENTATION_VALUES_LANDSCAPE_PRIMARY; |
| case 90: |
| return natural_portrait ? SCREEN_ORIENTATION_VALUES_LANDSCAPE_PRIMARY |
| : SCREEN_ORIENTATION_VALUES_PORTRAIT_SECONDARY; |
| case 180: |
| return natural_portrait ? SCREEN_ORIENTATION_VALUES_PORTRAIT_SECONDARY |
| : SCREEN_ORIENTATION_VALUES_LANDSCAPE_SECONDARY; |
| case 270: |
| return natural_portrait ? SCREEN_ORIENTATION_VALUES_LANDSCAPE_SECONDARY |
| : SCREEN_ORIENTATION_VALUES_PORTRAIT_PRIMARY; |
| default: |
| NOTREACHED(); |
| return SCREEN_ORIENTATION_VALUES_PORTRAIT_PRIMARY; |
| } |
| } |
| |
| // static |
| ScreenOrientationValues DisplayUtil::GetOrientationTypeForDesktop( |
| const display::Display& display) { |
| static int primary_landscape_angle = -1; |
| static int primary_portrait_angle = -1; |
| |
| int angle = display.RotationAsDegree(); |
| const gfx::Rect& bounds = display.bounds(); |
| bool is_portrait = bounds.height() >= bounds.width(); |
| |
| if (is_portrait && primary_portrait_angle == -1) |
| primary_portrait_angle = angle; |
| |
| if (!is_portrait && primary_landscape_angle == -1) |
| primary_landscape_angle = angle; |
| |
| if (is_portrait) { |
| return primary_portrait_angle == angle |
| ? SCREEN_ORIENTATION_VALUES_PORTRAIT_PRIMARY |
| : SCREEN_ORIENTATION_VALUES_PORTRAIT_SECONDARY; |
| } |
| |
| return primary_landscape_angle == angle |
| ? SCREEN_ORIENTATION_VALUES_LANDSCAPE_PRIMARY |
| : SCREEN_ORIENTATION_VALUES_LANDSCAPE_SECONDARY; |
| } |
| |
| } // namespace content |