зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1768726 - Make RemoteAccessibleBase::BoundsWithOffset thread safe for Android. r=morgan
In Android we need to keep the remote accessible methods thread safe. That means no direct references to local accessibles, or anything DOM or layout. We have the advantage of always being remote except for a 0 offset browser element, and no support for full page zoom. Also removed the visual/layout viewport offset in the bounds method since the top level doc will always have its visual and layout viewport match. Differential Revision: https://phabricator.services.mozilla.com/D146006
This commit is contained in:
Родитель
780d656a9c
Коммит
7e7246091a
|
@ -396,6 +396,7 @@ LayoutDeviceIntRect RemoteAccessibleBase<Derived>::BoundsWithOffset(
|
|||
Maybe<nsRect> maybeBounds = RetrieveCachedBounds();
|
||||
if (maybeBounds) {
|
||||
nsRect bounds = *maybeBounds;
|
||||
#if !defined(ANDROID)
|
||||
dom::CanonicalBrowsingContext* cbc =
|
||||
static_cast<dom::BrowserParent*>(mDoc->Manager())
|
||||
->GetBrowsingContext()
|
||||
|
@ -403,6 +404,11 @@ LayoutDeviceIntRect RemoteAccessibleBase<Derived>::BoundsWithOffset(
|
|||
dom::BrowserParent* bp = cbc->GetBrowserParent();
|
||||
nsPresContext* presContext =
|
||||
bp->GetOwnerElement()->OwnerDoc()->GetPresContext();
|
||||
float fullZoom = cbc->GetFullZoom();
|
||||
#else
|
||||
// In Android the FullZoom is always 1.0 since we use APZ/resolution zoom.
|
||||
float fullZoom = 1.0;
|
||||
#endif
|
||||
|
||||
if (aOffset.isSome()) {
|
||||
// The rect we've passed in is in app units, so no conversion needed.
|
||||
|
@ -411,7 +417,7 @@ LayoutDeviceIntRect RemoteAccessibleBase<Derived>::BoundsWithOffset(
|
|||
// text bounds, which already have their zoom level
|
||||
// applied. Remove it, because we'll multiply it back
|
||||
// in later on.
|
||||
internalRect.ScaleRoundOut(1 / cbc->GetFullZoom());
|
||||
internalRect.ScaleRoundOut(1 / fullZoom);
|
||||
bounds.SetRectX(bounds.x + internalRect.x, internalRect.width);
|
||||
bounds.SetRectY(bounds.y + internalRect.y, internalRect.height);
|
||||
}
|
||||
|
@ -421,29 +427,7 @@ LayoutDeviceIntRect RemoteAccessibleBase<Derived>::BoundsWithOffset(
|
|||
LayoutDeviceIntRect devPxBounds;
|
||||
const Accessible* acc = Parent();
|
||||
|
||||
while (acc) {
|
||||
if (LocalAccessible* localAcc =
|
||||
const_cast<Accessible*>(acc)->AsLocal()) {
|
||||
// LocalAccessible::Bounds returns screen-relative bounds in
|
||||
// dev pixels.
|
||||
LayoutDeviceIntRect localBounds = localAcc->Bounds();
|
||||
|
||||
// Convert our existing `bounds` rect from app units to dev pixels
|
||||
devPxBounds = LayoutDeviceIntRect::FromAppUnitsToNearest(
|
||||
bounds, presContext->AppUnitsPerDevPixel());
|
||||
|
||||
// We factor in our zoom level before offsetting by
|
||||
// `localBounds`, which has already taken zoom into account.
|
||||
devPxBounds.ScaleRoundOut(cbc->GetFullZoom());
|
||||
|
||||
// The root document will always have an APZ resolution of 1,
|
||||
// so we don't factor in its scale here. We also don't scale
|
||||
// by GetFullZoom because LocalAccessible::Bounds already does
|
||||
// that.
|
||||
devPxBounds.MoveBy(localBounds.X(), localBounds.Y());
|
||||
break;
|
||||
}
|
||||
|
||||
while (acc && acc->IsRemote()) {
|
||||
RemoteAccessible* remoteAcc = const_cast<Accessible*>(acc)->AsRemote();
|
||||
|
||||
if (Maybe<nsRect> maybeRemoteBounds =
|
||||
|
@ -484,15 +468,31 @@ LayoutDeviceIntRect RemoteAccessibleBase<Derived>::BoundsWithOffset(
|
|||
acc = acc->Parent();
|
||||
}
|
||||
|
||||
PresShell* presShell = presContext->PresShell();
|
||||
#if !defined(ANDROID)
|
||||
// This block is not thread safe because it queries a LocalAccessible,
|
||||
// the BrowsingContext, PresContext, etc. It is also not needed in
|
||||
// Android since the only local accessible is the outer doc browser that
|
||||
// has an offset of 0 and a FullZoom value of 1.0.
|
||||
if (LocalAccessible* localAcc = const_cast<Accessible*>(acc)->AsLocal()) {
|
||||
// LocalAccessible::Bounds returns screen-relative bounds in
|
||||
// dev pixels.
|
||||
LayoutDeviceIntRect localBounds = localAcc->Bounds();
|
||||
|
||||
// Our relative bounds are pulled from the coordinate space of the layout
|
||||
// viewport, but we need them to be in the coordinate space of the visual
|
||||
// viewport. We calculate the difference and translate our bounds here.
|
||||
nsPoint viewportOffset = presShell->GetVisualViewportOffset() -
|
||||
presShell->GetLayoutViewportOffset();
|
||||
devPxBounds.MoveBy(-(LayoutDeviceIntPoint::FromAppUnitsToNearest(
|
||||
viewportOffset, presContext->AppUnitsPerDevPixel())));
|
||||
// Convert our existing `bounds` rect from app units to dev pixels
|
||||
devPxBounds = LayoutDeviceIntRect::FromAppUnitsToNearest(
|
||||
bounds, presContext->AppUnitsPerDevPixel());
|
||||
|
||||
// We factor in our zoom level before offsetting by
|
||||
// `localBounds`, which has already taken zoom into account.
|
||||
devPxBounds.ScaleRoundOut(fullZoom);
|
||||
|
||||
// The root document will always have an APZ resolution of 1,
|
||||
// so we don't factor in its scale here. We also don't scale
|
||||
// by GetFullZoom because LocalAccessible::Bounds already does
|
||||
// that.
|
||||
devPxBounds.MoveBy(localBounds.X(), localBounds.Y());
|
||||
}
|
||||
#endif
|
||||
|
||||
return devPxBounds;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче