blob: 7d0d3d89f5d198485931a961ab09b81a490c36a3 [file] [log] [blame]
// 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