diff options
Diffstat (limited to 'core/java/android')
| -rw-r--r-- | core/java/android/view/View.java | 43 | ||||
| -rw-r--r-- | core/java/android/view/ViewGroup.java | 11 | ||||
| -rw-r--r-- | core/java/android/view/translation/UiTranslationController.java | 2 | ||||
| -rw-r--r-- | core/java/android/widget/AbsListView.java | 3 |
4 files changed, 56 insertions, 3 deletions
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 1e2b2aedfc08..e7542ee70aef 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -9285,6 +9285,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * parentView.addView(reusableView); * </pre> * + * <p>NOTE: If this view is a descendant of an {@link android.widget.AdapterView}, the system + * may reset its autofill id when this view is recycled. If the autofill ids need to be stable, + * they should be set again in + * {@link android.widget.Adapter#getView(int, android.view.View, android.view.ViewGroup)}. + * * @param id an autofill ID that is unique in the {@link android.app.Activity} hosting the view, * or {@code null} to reset it. Usually it's an id previously allocated to another view (and * obtained through {@link #getAutofillId()}), or a new value obtained through @@ -9321,6 +9326,30 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } /** + * Forces a reset of the autofill ids of the subtree rooted at this view. Like calling + * {@link #setAutofillId(AutofillId) setAutofillId(null)} for each view, but works even if the + * views are attached to a window. + * + * <p>This is useful if the views are being recycled, since an autofill id should uniquely + * identify a particular piece of content. + * + * @hide + */ + public void resetSubtreeAutofillIds() { + if (mAutofillViewId == NO_ID) { + return; + } + if (Log.isLoggable(CONTENT_CAPTURE_LOG_TAG, Log.VERBOSE)) { + Log.v(CONTENT_CAPTURE_LOG_TAG, "resetAutofillId() for " + mAutofillViewId); + } else if (Log.isLoggable(AUTOFILL_LOG_TAG, Log.VERBOSE)) { + Log.v(AUTOFILL_LOG_TAG, "resetAutofillId() for " + mAutofillViewId); + } + mAutofillId = null; + mAutofillViewId = NO_ID; + mPrivateFlags3 &= ~PFLAG3_AUTOFILLID_EXPLICITLY_SET; + } + + /** * Describes the autofill type of this view, so an * {@link android.service.autofill.AutofillService} can create the proper {@link AutofillValue} * when autofilling the view. @@ -30838,8 +30867,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * {@link android.view.translation.Translator} to translate the requests. All the * {@link ViewTranslationRequest}s must be added when the traversal is done. * - * <p> The default implementation will call {@link View#onCreateTranslationRequest} to build - * {@link ViewTranslationRequest} if the view should be translated. </p> + * <p> The default implementation calls {@link View#onCreateTranslationRequest} to build + * {@link ViewTranslationRequest} if the view should be translated. The view is marked as having + * {@link #setHasTransientState(boolean) transient state} so that recycling of views doesn't + * prevent the system from attaching the response to it.</p> * * @param viewIds a map for the view's {@link AutofillId} and its virtual child ids or * {@code null} if the view doesn't have virtual child that should be translated. The virtual @@ -30860,6 +30891,14 @@ public class View implements Drawable.Callback, KeyEvent.Callback, ViewTranslationRequest request = onCreateTranslationRequest(supportedFormats); if (request != null && request.getKeys().size() > 0) { requests.add(request); + if (Log.isLoggable(CONTENT_CAPTURE_LOG_TAG, Log.VERBOSE)) { + Log.v(CONTENT_CAPTURE_LOG_TAG, "Calling setHasTransientState(true) for " + + autofillId); + } + // TODO: Add a default ViewTranslationCallback for View that resets this in + // onClearTranslation(). Also update the javadoc for this method to mention + // that. + setHasTransientState(true); } } else { onCreateTranslationRequests(viewIds.get(autofillId), supportedFormats, request -> { diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java index 5b695f4c425a..04e2cdee56a0 100644 --- a/core/java/android/view/ViewGroup.java +++ b/core/java/android/view/ViewGroup.java @@ -3773,6 +3773,17 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager /** @hide */ @Override + public void resetSubtreeAutofillIds() { + super.resetSubtreeAutofillIds(); + View[] children = mChildren; + final int childCount = mChildrenCount; + for (int i = 0; i < childCount; i++) { + children[i].resetSubtreeAutofillIds(); + } + } + + /** @hide */ + @Override @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) public void onInitializeAccessibilityNodeInfoInternal(AccessibilityNodeInfo info) { super.onInitializeAccessibilityNodeInfoInternal(info); diff --git a/core/java/android/view/translation/UiTranslationController.java b/core/java/android/view/translation/UiTranslationController.java index 53e354f8200e..f4fdf35fb50f 100644 --- a/core/java/android/view/translation/UiTranslationController.java +++ b/core/java/android/view/translation/UiTranslationController.java @@ -388,7 +388,7 @@ public class UiTranslationController { private void sendTranslationRequest(Translator translator, List<ViewTranslationRequest> requests) { if (requests.size() == 0) { - Log.wtf(TAG, "No ViewTranslationRequest was collected."); + Log.w(TAG, "No ViewTranslationRequest was collected."); return; } final TranslationRequest request = new TranslationRequest.Builder() diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java index 94a0790c86a2..eb16cef15248 100644 --- a/core/java/android/widget/AbsListView.java +++ b/core/java/android/widget/AbsListView.java @@ -6425,6 +6425,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te if (lp != null && mRecycler.shouldRecycleViewType(lp.viewType)) { views.add(child); child.setAccessibilityDelegate(null); + child.resetSubtreeAutofillIds(); if (listener != null) { // Pretend they went through the scrap heap listener.onMovedToScrapHeap(child); @@ -7365,10 +7366,12 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te private void clearScrapForRebind(View view) { view.clearAccessibilityFocus(); view.setAccessibilityDelegate(null); + view.resetSubtreeAutofillIds(); } private void removeDetachedView(View child, boolean animate) { child.setAccessibilityDelegate(null); + child.resetSubtreeAutofillIds(); AbsListView.this.removeDetachedView(child, animate); } } |
