blob: 79be2a8e0479b332c6a9190b44300888b1ae0d29 [file] [log] [blame]
// Copyright 2021 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package arc
import (
"context"
"math"
"time"
"chromiumos/tast/local/arc"
"chromiumos/tast/local/chrome/display"
"chromiumos/tast/testing"
)
func init() {
testing.AddTest(&testing.Test{
Func: DefaultDisplayDensity,
Desc: "Checks that the default density is calculated correctly for various boards",
Contacts: []string{"prabirmsp@chromium.org", "arc-framework+tast@google.com"},
Attr: []string{"group:mainline", "informational"},
SoftwareDeps: []string{"android_vm", "chrome"},
Timeout: 4 * time.Minute,
Fixture: "arcBooted",
})
}
func DefaultDisplayDensity(ctx context.Context, s *testing.State) {
const (
// The ratio between Chrome's scale and Android's scale.
ChromeScaleToAndroidScaleRatio = 0.75
// The Uniform Scale Factor (USF) that is used by default on ARC++ R and later.
UniformScaleFactor = 1.20
)
cr := s.FixtValue().(*arc.PreData).Chrome
a := s.FixtValue().(*arc.PreData).ARC
tconn, err := cr.TestAPIConn(ctx)
if err != nil {
s.Fatal("Failed to create Test API connection: ", err)
}
var defaultDeviceScaleFactor float64
dispInfo, err := display.GetInternalInfo(ctx, tconn)
if err != nil {
// An internal display was not found. Use a device scale factor of 1.0.
defaultDeviceScaleFactor = 1.0
} else {
// An internal display is present. Assume that it is using the default zoom factor on boot.
if dispInfo.DisplayZoomFactor != 1.0 {
s.Fatalf("The internal display is configured with a non-default zoom factor %f", dispInfo.DisplayZoomFactor)
}
defaultDeviceScaleFactor, err = dispInfo.GetEffectiveDeviceScaleFactor()
if err != nil {
s.Fatal("Failed to get the effective device scale factor: ", err)
}
}
// The Android density DPI is calculated from Chrome's device scale factor. For low-density devices, we ensure that
// the chosen density does not fall below DefaultDensityDPI, because using lower density values can cause performance
// and compatibility issues.
calculatedDPI := math.Max(1.0, defaultDeviceScaleFactor*ChromeScaleToAndroidScaleRatio*UniformScaleFactor) * arc.DefaultDensityDPI
expectedDPI := closestCTSApprovedDensityDPI(calculatedDPI)
d, err := arc.NewDisplay(a, arc.DefaultDisplayID)
if err != nil {
s.Fatal("Failed to create new arc display: ", err)
}
dpi, err := d.OverrideDensityDPI(ctx)
if err != nil {
s.Fatal("Failed to get override display density: ", err)
}
if expectedDPI != dpi {
s.Fatalf("The default density was not set correctly: got: %d want: %d", dpi, expectedDPI)
}
}
// closestCTSApprovedDensityDPI returns the density DPI that is approved by the Android CDD that is closest to
// the provided density. Android CDD requires that devices must use one of the approved density DPI by default.
// If provided density falls exactly in the middle of two values, we pick the larger value.
func closestCTSApprovedDensityDPI(dpi float64) (bestDPI int) {
// These are the list of approved density values reported in the Android CDD.
// Source: https://source.android.com/compatibility/android-cdd#7_1_1_3_screen_density
var ctsDensityBuckets = [...]int{120, 140, 160, 180, 200, 213, 220, 240, 260, 280, 300, 320, 340, 360, 400, 420, 480, 560, 640}
minDiff := math.MaxFloat64
for _, d := range ctsDensityBuckets {
diff := math.Abs(float64(d) - dpi)
if diff > minDiff {
break
}
minDiff = diff
bestDPI = d
}
return bestDPI
}