Commit 96979774 authored by Hiroki Sato's avatar Hiroki Sato Committed by Commit Bot

arc-a11y: Use correct scale factor for ARC R

Starting ARC R, ARC natively supports display density. As a result, when
the client is ARC P, the bounds are always scaled by the default device
scale factor, and when the client is ARC R and later, the bounds are
always scaled by the screen scale of the display, which matches the
browser behavior.

This CL addresses the above change in accessibility layer.

AX-Relnotes: n/a. (a part of preparation for ARC R)
Bug: b:17251157
Test: manual. Open PlayStore and change scale factor by ctrl+shift+(+/-) with P and R.
Change-Id: Iae39adaed7b3fc7a00962edc9da617b89dea7202
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2540266
Commit-Queue: Hiroki Sato <hirokisato@chromium.org>
Reviewed-by: default avatarDavid Tseng <dtseng@chromium.org>
Reviewed-by: default avatarSara Kato <sarakato@chromium.org>
Cr-Commit-Position: refs/heads/master@{#829057}
parent 2b5b4772
......@@ -35,9 +35,9 @@ void AccessibilityInfoDataWrapper::PopulateBounds(
tree_source_->is_input_method_window() || root->GetId() != GetId()) {
// By default, populate the bounds relative to the tree root.
const gfx::Rect& root_bounds = root->GetBounds();
info_data_bounds.Offset(-1 * root_bounds.x(), -1 * root_bounds.y());
out_bounds = ToChromeScale(info_data_bounds);
out_bounds = ScaleAndroidPxToChromePx(info_data_bounds, window);
out_data->relative_bounds.offset_container_id = root->GetId();
} else {
// For the root node of application tree, populate the bounds to be
......@@ -46,17 +46,21 @@ void AccessibilityInfoDataWrapper::PopulateBounds(
DCHECK(widget);
DCHECK(widget->widget_delegate());
DCHECK(widget->widget_delegate()->GetContentsView());
const gfx::Rect& root_bounds =
widget->widget_delegate()->GetContentsView()->GetBoundsInScreen();
gfx::PointF root_origin = gfx::PointF(widget->widget_delegate()
->GetContentsView()
->GetBoundsInScreen()
.origin());
out_bounds = ToChromeBounds(info_data_bounds, widget);
out_bounds.Offset(-1 * root_bounds.x(), -1 * root_bounds.y());
}
// Adjust the origin because a maximized window has an offset in Android.
root_origin.Offset(0, -1 * GetChromeWindowHeightOffsetInDip(window));
// |out_bounds| is in Chrome DPI here. As ARC is considered the same as web
// in Chrome automation, scale the bounds by device scale factor.
out_bounds.Scale(
// Scale to Chrome pixels.
root_origin.Scale(
window->GetToplevelWindow()->layer()->device_scale_factor());
out_bounds = ScaleAndroidPxToChromePx(info_data_bounds, window);
out_bounds.Offset(-1 * root_origin.x(), -1 * root_origin.y());
}
} else {
// We cannot compute global bounds, so use the raw bounds.
out_bounds.SetRect(info_data_bounds.x(), info_data_bounds.y(),
......
......@@ -93,9 +93,14 @@ void DispatchFocusChange(arc::mojom::AccessibilityNodeInfoData* node_data,
if (!active_window)
return;
gfx::Rect bounds_in_screen = gfx::ToEnclosingRect(arc::ToChromeBounds(
// Convert bounds from Android pixels to Chrome DIP, and adjust coordinate to
// Chrome's screen coordinate.
gfx::Rect bounds_in_screen = gfx::ScaleToEnclosingRect(
node_data->bounds_in_screen,
views::Widget::GetWidgetForNativeView(active_window)));
1.0f / exo::WMHelper::GetInstance()->GetDeviceScaleFactorForWindow(
active_window));
bounds_in_screen.Offset(0,
arc::GetChromeWindowHeightOffsetInDip(active_window));
bool is_editable = arc::GetBooleanProperty(
node_data, arc::mojom::AccessibilityBooleanProperty::EDITABLE);
......@@ -677,8 +682,8 @@ ArcAccessibilityHelperBridge::OnGetTextLocationDataResultInternal(
if (!active_window)
return base::nullopt;
gfx::RectF rect_f = arc::ToChromeScale(*result_rect);
rect_f.Scale(DeviceScaleFactorFromWindow(active_window));
const gfx::RectF& rect_f =
ScaleAndroidPxToChromePx(result_rect.value(), active_window);
return gfx::ToEnclosingRect(rect_f);
}
......
......@@ -14,28 +14,32 @@
#include "ui/views/widget/widget.h"
namespace arc {
gfx::RectF ToChromeScale(const gfx::Rect& bounds) {
gfx::RectF ScaleAndroidPxToChromePx(const gfx::Rect& android_bounds,
aura::Window* window) {
DCHECK(exo::WMHelper::HasInstance());
gfx::RectF bounds_f(bounds);
bounds_f.Scale(1.0f /
exo::WMHelper::GetInstance()->GetDefaultDeviceScaleFactor());
return bounds_f;
}
DCHECK(window);
gfx::RectF ToChromeBounds(const gfx::Rect& bounds, views::Widget* widget) {
DCHECK(widget);
gfx::RectF chrome_bounds = ToChromeScale(bounds);
const float chrome_dsf =
window->GetToplevelWindow()->layer()->device_scale_factor();
const float android_dsf =
exo::WMHelper::GetInstance()->GetDeviceScaleFactorForWindow(window);
if (chrome_dsf == android_dsf)
return gfx::RectF(android_bounds);
gfx::RectF chrome_bounds(android_bounds);
chrome_bounds.Scale(chrome_dsf / android_dsf);
return chrome_bounds;
}
int GetChromeWindowHeightOffsetInDip(aura::Window* window) {
// On Android side, content is rendered without considering height of
// caption bar, e.g. Content is rendered at y:0 instead of y:32 where 32 is
// height of caption bar. Add back height of caption bar here.
if (widget->IsMaximized()) {
chrome_bounds.Offset(
0,
widget->non_client_view()->frame_view()->GetBoundsForClientView().y());
}
// caption bar when it's maximized, e.g. Content is rendered at y:0 instead of
// y:32 where 32 is height of caption bar.
views::Widget* widget = views::Widget::GetWidgetForNativeView(window);
if (!widget->IsMaximized())
return 0;
return chrome_bounds;
return widget->non_client_view()->frame_view()->GetBoundsForClientView().y();
}
} // namespace arc
......
......@@ -11,18 +11,19 @@ namespace gfx {
class RectF;
}
namespace views {
class Widget;
namespace aura {
class Window;
}
namespace arc {
// Given ARC pixels, returns DIPs in Chrome OS main display.
// This function only scales the bounds.
gfx::RectF ToChromeScale(const gfx::Rect& rect);
// Given a rect in Android pixels, returns a scaled rectangle in Chrome pixels.
// This only scales the given bounds.
gfx::RectF ScaleAndroidPxToChromePx(const gfx::Rect& android_bounds,
aura::Window* window);
// Given ARC pixels in screen coordinate, returns DIPs in Chrome OS main
// display. This function adjusts differences between ARC and Chrome.
gfx::RectF ToChromeBounds(const gfx::Rect& rect, views::Widget* widget);
// Returns an difference of y coordinate in DIP between Android internal bounds
// and what Chrome actually renders in the screen.
int GetChromeWindowHeightOffsetInDip(aura::Window* window);
} // namespace arc
#endif // CHROME_BROWSER_CHROMEOS_ARC_ACCESSIBILITY_GEOMETRY_UTIL_H_
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment