blob: 83fc3a9274559d52843bb0b53bad1357bc2d6d87 [file] [log] [blame]
// Copyright 2017 The Fuchsia 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 "src/ui/bin/root_presenter/displays/display_configuration.h"
#include <lib/syslog/cpp/macros.h>
#include "src/lib/files/file.h"
#include "src/lib/fxl/strings/trim.h"
namespace root_presenter {
namespace display_configuration {
void LogDisplayMetrics(const DisplayMetrics& metrics);
float LookupPixelDensityForDisplay(uint32_t width_in_px, uint32_t height_in_px);
fuchsia::ui::policy::DisplayUsage LookupDisplayUsageForDisplay(uint32_t width_in_px,
uint32_t height_in_px);
void InitializeModelForDisplay(uint32_t width_in_px, uint32_t height_in_px, DisplayModel* model) {
FX_DCHECK(width_in_px != 0u);
FX_DCHECK(height_in_px != 0u);
FX_DCHECK(model != nullptr);
model->display_info().width_in_px = width_in_px;
model->display_info().height_in_px = height_in_px;
model->display_info().density_in_px_per_mm =
LookupPixelDensityForDisplay(width_in_px, height_in_px);
model->environment_info().usage = LookupDisplayUsageForDisplay(width_in_px, height_in_px);
FX_DCHECK(model->display_info().density_in_px_per_mm != 0.f);
FX_DCHECK(model->environment_info().usage != fuchsia::ui::policy::DisplayUsage::kUnknown);
}
// Returns density_in_px_per_mm. This will be replaced by something that
// talks to the display API.
float LookupPixelDensityForDisplay(uint32_t width_in_px, uint32_t height_in_px) {
{
std::string pixel_density;
if (files::ReadFileToString("/config/data/display_pixel_density", &pixel_density)) {
auto pixel_density_value = atof(pixel_density.c_str());
if (pixel_density_value != 0.0) {
FX_LOGS(INFO) << "Display pixel density applied: " << pixel_density_value << " px/mm.";
return pixel_density_value;
} else {
FX_LOGS(WARNING) << "Invalid display pixel density in configuration: " << pixel_density
<< " px/mm.";
}
}
}
// TODO(fxbug.dev/23273): Need to have a database of devices and a more robust way
// of identifying and classifying them.
if (width_in_px == 2160 && height_in_px == 1440) {
// Assume that the device is an Acer Switch 12 Alpha.
FX_LOGS(INFO) << "RootPresenter: treating device as an Acer Switch 12 Alpha.";
return 8.5f;
} else if (width_in_px == 2400 && height_in_px == 1600) {
// Assume that the device is a Google Pixelbook.
FX_LOGS(INFO) << "RootPresenter: treating device as a Google Pixelbook.";
return 9.252f;
} else if (width_in_px == 3840 && height_in_px == 2160) {
// Assume the display is a 24in 4K monitor.
FX_LOGS(INFO) << "RootPresenter: treating display as a 24in 4K monitor.";
return 7.323761f;
} else if (width_in_px == 1920 && height_in_px == 1200) {
// Assume the display is a 24in HD monitor.
FX_LOGS(INFO) << "RootPresenter: treating display as a 24in monitor.";
return 4.16f;
} else if (width_in_px == 2560 && height_in_px == 1440) {
// TODO(fxbug.dev/42794): Allow Root Presenter clients to specify exact pixel ratio
// Assume display is a 27in 2K monitor.
FX_LOGS(INFO) << "RootPresenter: treating device as a 27in 2k monitor.";
return 5.22f;
} else {
// TODO(fxbug.dev/23621): Don't lie.
FX_LOGS(WARNING) << "RootPresenter: unrecognized display (width_in_px=" << width_in_px
<< " height_in_px=" << height_in_px << ").";
return 9.f;
}
}
fuchsia::ui::policy::DisplayUsage LookupDisplayUsageForDisplay(uint32_t width_in_px,
uint32_t height_in_px) {
// TODO(fxbug.dev/23273): Need to have a database of devices and a more robust way
// of identifying and classifying them.
{
std::string raw_display_usage;
if (files::ReadFileToString("/config/data/display_usage", &raw_display_usage)) {
std::string_view display_usage = fxl::TrimString(raw_display_usage, "\n ");
if (display_usage == "handheld") {
return fuchsia::ui::policy::DisplayUsage::kHandheld;
} else if (display_usage == "close") {
return fuchsia::ui::policy::DisplayUsage::kClose;
} else if (display_usage == "near") {
return fuchsia::ui::policy::DisplayUsage::kNear;
} else if (display_usage == "midrange") {
return fuchsia::ui::policy::DisplayUsage::kMidrange;
} else if (display_usage == "far") {
return fuchsia::ui::policy::DisplayUsage::kFar;
} else {
FX_LOGS(WARNING) << "Invalid display usage in configuration: " << display_usage << ".";
}
}
}
if (width_in_px == 2160 && height_in_px == 1440) {
// Assume that the device is an Acer Switch 12 Alpha.
return fuchsia::ui::policy::DisplayUsage::kClose;
} else if (width_in_px == 2400 && height_in_px == 1600) {
// Assume that the device is a Google Pixelbook.
return fuchsia::ui::policy::DisplayUsage::kClose;
} else if (width_in_px == 3840 && height_in_px == 2160) {
// Assume the display is a 24in 4K monitor.
return fuchsia::ui::policy::DisplayUsage::kNear;
} else if (width_in_px == 1920 && height_in_px == 1200) {
// Assume the display is a 24in monitor.
return fuchsia::ui::policy::DisplayUsage::kNear;
} else {
// TODO(fxbug.dev/23621): Don't lie.
return fuchsia::ui::policy::DisplayUsage::kClose;
}
}
void LogDisplayMetrics(const DisplayMetrics& metrics) {
FX_DLOGS(INFO) << "RootPresenter: Display metrics: "
<< "width_in_px=" << metrics.width_in_px()
<< ", height_in_px=" << metrics.height_in_px()
<< ", width_in_pp=" << metrics.width_in_pp()
<< ", height_in_pp=" << metrics.height_in_pp()
<< ", width_in_mm=" << metrics.width_in_mm()
<< ", height_in_mm=" << metrics.height_in_mm()
<< ", x_scale_in_px_per_pp=" << metrics.x_scale_in_px_per_pp()
<< ", y_scale_in_px_per_pp=" << metrics.y_scale_in_px_per_pp()
<< ", x_scale_in_pp_per_px=" << metrics.x_scale_in_pp_per_px()
<< ", y_scale_in_pp_per_px=" << metrics.y_scale_in_pp_per_px()
<< ", density_in_pp_per_mm=" << metrics.density_in_pp_per_mm()
<< ", density_in_mm_per_pp=" << metrics.density_in_mm_per_pp();
}
} // namespace display_configuration
} // namespace root_presenter