diff options
| author | 2024-09-24 11:11:45 +0800 | |
|---|---|---|
| committer | 2024-10-18 21:29:46 -0700 | |
| commit | 213dd25ea8c14ce16a32dc9eb6581a9bc2ea09d1 (patch) | |
| tree | b23b8fb87c4142eb800c3a63c6f343810d962123 | |
| parent | 88d3e14f3034424e477023a6167efb1227f15b83 (diff) | |
Set view bounds in parent by diff'ing the bounds in screen with parent.
The getBoundsInParent() has been deprecated, the getBoundsInScreen() is the recommended alternative for this. The Jetpack compose only sets the boundary via setBoundsInScreen() (given it's the new API), thus the getBoundsInParent() is always returning 0. Literally the bounding boxes of the AssistStructure are broken with Jetpack compose.
Now update the code to use the recommended alternatives.
Flag: android.view.flags.calculate_bounds_in_parent_from_bounds_in_screen
Bug: 366131857
Test: atest CtsAutoFillServiceTestCases
dump Assist Structure view hierarchy and check for bounds.
Change-Id: I78717c5d2faff06b9303adcfd8af1c8eeddf11fe
| -rw-r--r-- | core/java/android/view/View.java | 45 |
1 files changed, 41 insertions, 4 deletions
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 1b62cfdf5dcb..241ac435c18b 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -40,6 +40,7 @@ import static android.view.displayhash.DisplayHashResultCallback.EXTRA_DISPLAY_H import static android.view.flags.Flags.FLAG_SENSITIVE_CONTENT_APP_PROTECTION_API; import static android.view.flags.Flags.FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY; import static android.view.flags.Flags.FLAG_VIEW_VELOCITY_API; +import static android.view.flags.Flags.calculateBoundsInParentFromBoundsInScreen; import static android.view.flags.Flags.enableUseMeasureCacheDuringForceLayout; import static android.view.flags.Flags.sensitiveContentAppProtection; import static android.view.flags.Flags.toolkitFrameRateAnimationBugfix25q1; @@ -967,6 +968,13 @@ public class View implements Drawable.Callback, KeyEvent.Callback, private static boolean sAlwaysRemeasureExactly = false; /** + * When true calculates the bounds in parent from bounds in screen relative to its parents. + * This addresses the deprecated API (setBoundsInParent) in Compose, which causes empty + * getBoundsInParent call for Compose apps. + */ + private static boolean sCalculateBoundsInParentFromBoundsInScreenFlagValue = false; + + /** * When true makes it possible to use onMeasure caches also when the force layout flag is * enabled. This helps avoiding multiple measures in the same frame with the same dimensions. */ @@ -2556,6 +2564,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, sToolkitSetFrameRateReadOnlyFlagValue = toolkitSetFrameRateReadOnly(); sToolkitMetricsForFrameRateDecisionFlagValue = toolkitMetricsForFrameRateDecision(); + sCalculateBoundsInParentFromBoundsInScreenFlagValue = + calculateBoundsInParentFromBoundsInScreen(); sUseMeasureCacheDuringForceLayoutFlagValue = enableUseMeasureCacheDuringForceLayout(); } @@ -9776,7 +9786,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, structure.setChildCount(1); final ViewStructure root = structure.newChild(0); if (info != null) { - populateVirtualStructure(root, provider, info, forAutofill); + populateVirtualStructure(root, provider, info, null, forAutofill); info.recycle(); } else { Log.w(AUTOFILL_LOG_TAG, "AccessibilityNodeInfo is null."); @@ -11075,11 +11085,19 @@ public class View implements Drawable.Callback, KeyEvent.Callback, private void populateVirtualStructure(ViewStructure structure, AccessibilityNodeProvider provider, AccessibilityNodeInfo info, - boolean forAutofill) { + @Nullable AccessibilityNodeInfo parentInfo, boolean forAutofill) { structure.setId(AccessibilityNodeInfo.getVirtualDescendantId(info.getSourceNodeId()), null, null, info.getViewIdResourceName()); Rect rect = structure.getTempRect(); - info.getBoundsInParent(rect); + // The bounds in parent for Jetpack Compose views aren't set as setBoundsInParent is + // deprecated, and only setBoundsInScreen is called. + // The bounds in parent can be calculated by diff'ing the child view's bounds in screen with + // the parent's. + if (sCalculateBoundsInParentFromBoundsInScreenFlagValue) { + getBoundsInParent(info, parentInfo, rect); + } else { + info.getBoundsInParent(rect); + } structure.setDimens(rect.left, rect.top, 0, 0, rect.width(), rect.height()); structure.setVisibility(VISIBLE); structure.setEnabled(info.isEnabled()); @@ -11163,13 +11181,32 @@ public class View implements Drawable.Callback, KeyEvent.Callback, AccessibilityNodeInfo.getVirtualDescendantId(info.getChildId(i))); if (cinfo != null) { ViewStructure child = structure.newChild(i); - populateVirtualStructure(child, provider, cinfo, forAutofill); + populateVirtualStructure(child, provider, cinfo, info, forAutofill); cinfo.recycle(); } } } } + private void getBoundsInParent(@NonNull AccessibilityNodeInfo info, + @Nullable AccessibilityNodeInfo parentInfo, @NonNull Rect rect) { + info.getBoundsInParent(rect); + // Fallback to calculate bounds in parent by diffing the bounds in + // screen if it's all 0. + if ((rect.left | rect.top | rect.right | rect.bottom) == 0) { + if (parentInfo != null) { + Rect parentBoundsInScreen = parentInfo.getBoundsInScreen(); + Rect boundsInScreen = info.getBoundsInScreen(); + rect.set(boundsInScreen.left - parentBoundsInScreen.left, + boundsInScreen.top - parentBoundsInScreen.top, + boundsInScreen.right - parentBoundsInScreen.left, + boundsInScreen.bottom - parentBoundsInScreen.top); + } else { + info.getBoundsInScreen(rect); + } + } + } + /** * Dispatch creation of {@link ViewStructure} down the hierarchy. The default * implementation calls {@link #onProvideStructure} and |