Merge "Fix UiTranslation for ListView." into sc-dev
This commit is contained in:
@@ -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
|
||||
@@ -9320,6 +9325,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}
|
||||
@@ -30843,8 +30872,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
|
||||
@@ -30865,6 +30896,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 -> {
|
||||
|
||||
@@ -3771,6 +3771,17 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
|
||||
return child;
|
||||
}
|
||||
|
||||
/** @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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user