diff --git a/core/api/current.txt b/core/api/current.txt index dc0f9722bc1e1..a30191ce63a76 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -52923,8 +52923,9 @@ package android.view.translation { public static final class ViewTranslationRequest.Builder { ctor public ViewTranslationRequest.Builder(@NonNull android.view.autofill.AutofillId); + ctor public ViewTranslationRequest.Builder(@NonNull android.view.autofill.AutofillId, long); method @NonNull public android.view.translation.ViewTranslationRequest build(); - method public android.view.translation.ViewTranslationRequest.Builder setValue(String, android.view.translation.TranslationRequestValue); + method @NonNull public android.view.translation.ViewTranslationRequest.Builder setValue(@NonNull String, @NonNull android.view.translation.TranslationRequestValue); } public final class ViewTranslationResponse implements android.os.Parcelable { diff --git a/core/api/system-current.txt b/core/api/system-current.txt index 4fa1dbabb5d2e..2d9c6687c0cdc 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -14752,7 +14752,7 @@ package android.webkit { method public default boolean onCheckIsTextEditor(); method public void onConfigurationChanged(android.content.res.Configuration); method public android.view.inputmethod.InputConnection onCreateInputConnection(android.view.inputmethod.EditorInfo); - method @Nullable public default void onCreateTranslationRequests(@NonNull long[], @NonNull int[], @NonNull java.util.function.Consumer); + method public default void onCreateTranslationRequests(@NonNull long[], @NonNull int[], @NonNull java.util.function.Consumer); method public void onDetachedFromWindow(); method public boolean onDragEvent(android.view.DragEvent); method public void onDraw(android.graphics.Canvas); diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 61d74a40bee57..fd3254e47f108 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -30759,10 +30759,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * view. * @param supportedFormats the supported translation formats. For now, the only possible value * is the {@link android.view.translation.TranslationSpec#DATA_FORMAT_TEXT}. - * @param requestsCollector a {@link ViewTranslationRequest} collector that will be called + * @param requestsCollector a {@link ViewTranslationRequest} collector that can be called * multiple times to collect the information to be translated in the virtual view. One * {@link ViewTranslationRequest} per virtual child. The {@link ViewTranslationRequest} must - * contains the {@link AutofillId} corresponding to the virtualChildIds. + * contains the {@link AutofillId} corresponding to the virtualChildIds. Do not keep this + * Consumer after the method returns. */ @SuppressLint("NullableCollection") public void onCreateTranslationRequests(@NonNull long[] virtualChildIds, @@ -30835,7 +30836,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * ui translation, the system will call this method to traverse the view hierarchy to call * {@link View#onCreateTranslationRequest} to build {@link ViewTranslationRequest}s and create a * {@link android.view.translation.Translator} to translate the requests. All the - * {@link ViewTranslationRequest}s will be added when the traversal is done. + * {@link ViewTranslationRequest}s must be added when the traversal is done. * *

The default implementation will call {@link View#onCreateTranslationRequest} to build * {@link ViewTranslationRequest} if the view should be translated.

diff --git a/core/java/android/view/translation/UiTranslationController.java b/core/java/android/view/translation/UiTranslationController.java index 0fa6e16b2e038..7d1df9cd51b8f 100644 --- a/core/java/android/view/translation/UiTranslationController.java +++ b/core/java/android/view/translation/UiTranslationController.java @@ -30,6 +30,7 @@ import android.os.Handler; import android.os.HandlerThread; import android.os.Process; import android.util.ArrayMap; +import android.util.IntArray; import android.util.Log; import android.util.LongSparseArray; import android.util.Pair; @@ -241,13 +242,11 @@ public class UiTranslationController { final SparseArray viewsResult = new SparseArray<>(); final SparseArray> virtualViewsResult = new SparseArray<>(); - // TODO: use another structure to prevent autoboxing? - final List viewIds = new ArrayList<>(); - + final IntArray viewIds = new IntArray(1); for (int i = 0; i < translatedResult.size(); i++) { final ViewTranslationResponse result = translatedResult.valueAt(i); final AutofillId autofillId = result.getAutofillId(); - if (!viewIds.contains(autofillId.getViewId())) { + if (viewIds.indexOf(autofillId.getViewId()) < 0) { viewIds.add(autofillId.getViewId()); } if (autofillId.isNonVirtual()) { @@ -405,23 +404,29 @@ public class UiTranslationController { // Filter the request views's AutofillId SparseIntArray virtualViewChildCount = getRequestVirtualViewChildCount(views); Map viewIds = new ArrayMap<>(); + Map unusedIndices = null; for (int i = 0; i < views.size(); i++) { AutofillId autofillId = views.get(i); if (autofillId.isNonVirtual()) { viewIds.put(autofillId, null); } else { + if (unusedIndices == null) { + unusedIndices = new ArrayMap<>(); + } // The virtual id get from content capture is long, see getVirtualChildLongId() // e.g. 1001, 1001:2, 1002:1 -> 1001, <1,2>; 1002, <1> AutofillId virtualViewAutofillId = new AutofillId(autofillId.getViewId()); long[] childs; + int end = 0; if (viewIds.containsKey(virtualViewAutofillId)) { childs = viewIds.get(virtualViewAutofillId); + end = unusedIndices.get(virtualViewAutofillId); } else { int childCount = virtualViewChildCount.get(autofillId.getViewId()); childs = new long[childCount]; viewIds.put(virtualViewAutofillId, childs); } - int end = childs.length - 1; + unusedIndices.put(virtualViewAutofillId, end + 1); childs[end] = autofillId.getVirtualChildLongId(); } } @@ -465,7 +470,7 @@ public class UiTranslationController { return new int[] {TranslationSpec.DATA_FORMAT_TEXT}; } - private void findViewsTraversalByAutofillIds(List sourceViewIds) { + private void findViewsTraversalByAutofillIds(IntArray sourceViewIds) { final ArrayList roots = WindowManagerGlobal.getInstance().getRootViews(mActivity.getActivityToken()); for (int rootNum = 0; rootNum < roots.size(); rootNum++) { @@ -479,7 +484,7 @@ public class UiTranslationController { } private void findViewsTraversalByAutofillIds(ViewGroup viewGroup, - List sourceViewIds) { + IntArray sourceViewIds) { final int childCount = viewGroup.getChildCount(); for (int i = 0; i < childCount; ++i) { final View child = viewGroup.getChildAt(i); @@ -491,9 +496,10 @@ public class UiTranslationController { } } - private void addViewIfNeeded(List sourceViewIds, View view) { + private void addViewIfNeeded(IntArray sourceViewIds, View view) { final AutofillId autofillId = view.getAutofillId(); - if (sourceViewIds.contains(autofillId.getViewId()) && !mViews.containsKey(autofillId)) { + if ((sourceViewIds.indexOf(autofillId.getViewId()) >= 0) + && !mViews.containsKey(autofillId)) { mViews.put(autofillId, new WeakReference<>(view)); } } diff --git a/core/java/android/view/translation/ViewTranslationRequest.java b/core/java/android/view/translation/ViewTranslationRequest.java index 180b1c2c166a9..4d8fb99023c9d 100644 --- a/core/java/android/view/translation/ViewTranslationRequest.java +++ b/core/java/android/view/translation/ViewTranslationRequest.java @@ -35,7 +35,8 @@ import java.util.Set; * Wrapper class representing a translation request associated with a {@link android.view.View} to * be used by {@link android.service.translation.TranslationService}. */ -@DataClass(genBuilder = true, genToString = true, genEqualsHashCode = true, genGetters = false) +@DataClass(genBuilder = false, genToString = true, genEqualsHashCode = true, genGetters = false, + genHiddenConstructor = true) public final class ViewTranslationRequest implements Parcelable { /** @@ -91,10 +92,39 @@ public final class ViewTranslationRequest implements Parcelable { return Collections.emptyMap(); } - @DataClass.Suppress({"addTranslationRequestValue", "setAutofillId"}) - abstract static class BaseBuilder { + /** + * A builder for building ViewTranslationRequest. + */ + public static final class Builder { - abstract Builder setTranslationRequestValues(Map value); + private @NonNull AutofillId mAutofillId; + private @NonNull Map mTranslationRequestValues; + + private long mBuilderFieldsSet = 0L; + + /** + * Creates a new Builder. + * + * @param autofillId The {@link AutofillId} of the view associated with this request. + */ + public Builder(@NonNull AutofillId autofillId) { + mAutofillId = autofillId; + com.android.internal.util.AnnotationValidations.validate( + NonNull.class, null, mAutofillId); + } + + /** + * Creates a new Builder. + * + * @param autofillId the {@link AutofillId} of the non-virtual view hosting the virtual view + * hierarchy associated with this request. + * @param virtualChildId the id of the virtual child, relative to the parent. + */ + public Builder(@NonNull AutofillId autofillId, long virtualChildId) { + mAutofillId = new AutofillId(autofillId, virtualChildId, AutofillId.NO_SESSION); + com.android.internal.util.AnnotationValidations.validate( + NonNull.class, null, mAutofillId); + } /** * Sets the corresponding {@link TranslationRequestValue} for the provided key. @@ -104,20 +134,50 @@ public final class ViewTranslationRequest implements Parcelable { * @return this builder. */ @SuppressLint("MissingGetterMatchingBuilder") - public Builder setValue(String key, - TranslationRequestValue value) { - final Builder builder = (Builder) this; - if (builder.mTranslationRequestValues == null) { + @NonNull + public Builder setValue(@NonNull String key, @NonNull TranslationRequestValue value) { + if (mTranslationRequestValues == null) { setTranslationRequestValues(new ArrayMap<>()); } - builder.mTranslationRequestValues.put(key, value); - return builder; + mTranslationRequestValues.put(key, value); + return this; + } + + /** + * Builds the instance. This builder should not be touched after calling this! + */ + @NonNull + public ViewTranslationRequest build() { + checkNotUsed(); + mBuilderFieldsSet |= 0x4; // Mark builder used + + if ((mBuilderFieldsSet & 0x2) == 0) { + mTranslationRequestValues = defaultTranslationRequestValues(); + } + ViewTranslationRequest o = new ViewTranslationRequest( + mAutofillId, + mTranslationRequestValues); + return o; + } + + Builder setTranslationRequestValues(@NonNull Map value) { + checkNotUsed(); + mBuilderFieldsSet |= 0x2; + mTranslationRequestValues = value; + return this; + } + + private void checkNotUsed() { + if ((mBuilderFieldsSet & 0x4) != 0) { + throw new IllegalStateException( + "This Builder should not be reused. Use a new Builder instance instead"); + } } } - // Code below generated by codegen v1.0.22. + // Code below generated by codegen v1.0.23. // // DO NOT MODIFY! // CHECKSTYLE:OFF Generated code @@ -130,8 +190,15 @@ public final class ViewTranslationRequest implements Parcelable { //@formatter:off + /** + * Creates a new ViewTranslationRequest. + * + * @param autofillId + * The {@link AutofillId} of the view associated with this request. + * @hide + */ @DataClass.Generated.Member - /* package-private */ ViewTranslationRequest( + public ViewTranslationRequest( @NonNull AutofillId autofillId, @NonNull Map translationRequestValues) { this.mAutofillId = autofillId; @@ -234,67 +301,11 @@ public final class ViewTranslationRequest implements Parcelable { } }; - /** - * A builder for {@link ViewTranslationRequest} - */ - @SuppressWarnings("WeakerAccess") - @DataClass.Generated.Member - public static final class Builder extends BaseBuilder { - - private @NonNull AutofillId mAutofillId; - private @NonNull Map mTranslationRequestValues; - - private long mBuilderFieldsSet = 0L; - - /** - * Creates a new Builder. - * - * @param autofillId - * The {@link AutofillId} of the view associated with this request. - */ - public Builder( - @NonNull AutofillId autofillId) { - mAutofillId = autofillId; - com.android.internal.util.AnnotationValidations.validate( - NonNull.class, null, mAutofillId); - } - - @DataClass.Generated.Member - @Override - @NonNull Builder setTranslationRequestValues(@NonNull Map value) { - checkNotUsed(); - mBuilderFieldsSet |= 0x2; - mTranslationRequestValues = value; - return this; - } - - /** Builds the instance. This builder should not be touched after calling this! */ - public @NonNull ViewTranslationRequest build() { - checkNotUsed(); - mBuilderFieldsSet |= 0x4; // Mark builder used - - if ((mBuilderFieldsSet & 0x2) == 0) { - mTranslationRequestValues = defaultTranslationRequestValues(); - } - ViewTranslationRequest o = new ViewTranslationRequest( - mAutofillId, - mTranslationRequestValues); - return o; - } - - private void checkNotUsed() { - if ((mBuilderFieldsSet & 0x4) != 0) { - throw new IllegalStateException( - "This Builder should not be reused. Use a new Builder instance instead"); - } - } - } - @DataClass.Generated( - time = 1614992269658L, - codegenVersion = "1.0.22", + time = 1617119791798L, + codegenVersion = "1.0.23", sourceFile = "frameworks/base/core/java/android/view/translation/ViewTranslationRequest.java", - inputSignatures = "public static final java.lang.String ID_TEXT\nprivate final @android.annotation.NonNull android.view.autofill.AutofillId mAutofillId\nprivate final @android.annotation.NonNull @com.android.internal.util.DataClass.PluralOf(\"translationRequestValue\") java.util.Map mTranslationRequestValues\npublic @android.annotation.NonNull android.view.translation.TranslationRequestValue getValue(java.lang.String)\npublic @android.annotation.NonNull java.util.Set getKeys()\npublic @android.annotation.NonNull android.view.autofill.AutofillId getAutofillId()\nprivate static java.util.Map defaultTranslationRequestValues()\nclass ViewTranslationRequest extends java.lang.Object implements [android.os.Parcelable]\nabstract android.view.translation.ViewTranslationRequest.Builder setTranslationRequestValues(java.util.Map)\npublic @android.annotation.SuppressLint android.view.translation.ViewTranslationRequest.Builder setValue(java.lang.String,android.view.translation.TranslationRequestValue)\nclass BaseBuilder extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genBuilder=true, genToString=true, genEqualsHashCode=true, genGetters=false)\nabstract android.view.translation.ViewTranslationRequest.Builder setTranslationRequestValues(java.util.Map)\npublic @android.annotation.SuppressLint android.view.translation.ViewTranslationRequest.Builder setValue(java.lang.String,android.view.translation.TranslationRequestValue)\nclass BaseBuilder extends java.lang.Object implements []") + inputSignatures = "public static final java.lang.String ID_TEXT\nprivate final @android.annotation.NonNull android.view.autofill.AutofillId mAutofillId\nprivate final @android.annotation.NonNull @com.android.internal.util.DataClass.PluralOf(\"translationRequestValue\") java.util.Map mTranslationRequestValues\npublic @android.annotation.NonNull android.view.translation.TranslationRequestValue getValue(java.lang.String)\npublic @android.annotation.NonNull java.util.Set getKeys()\npublic @android.annotation.NonNull android.view.autofill.AutofillId getAutofillId()\nprivate static java.util.Map defaultTranslationRequestValues()\nclass ViewTranslationRequest extends java.lang.Object implements [android.os.Parcelable]\nprivate @android.annotation.NonNull android.view.autofill.AutofillId mAutofillId\nprivate @android.annotation.NonNull java.util.Map mTranslationRequestValues\nprivate long mBuilderFieldsSet\npublic @android.annotation.SuppressLint @android.annotation.NonNull android.view.translation.ViewTranslationRequest.Builder setValue(java.lang.String,android.view.translation.TranslationRequestValue)\npublic @android.annotation.NonNull android.view.translation.ViewTranslationRequest build()\n android.view.translation.ViewTranslationRequest.Builder setTranslationRequestValues(java.util.Map)\nprivate void checkNotUsed()\nclass Builder extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genBuilder=false, genToString=true, genEqualsHashCode=true, genGetters=false, genHiddenConstructor=true)") @Deprecated private void __metadata() {} diff --git a/core/java/android/webkit/WebViewProvider.java b/core/java/android/webkit/WebViewProvider.java index 264736008782d..770a1568241cc 100644 --- a/core/java/android/webkit/WebViewProvider.java +++ b/core/java/android/webkit/WebViewProvider.java @@ -365,7 +365,6 @@ public interface WebViewProvider { } @SuppressLint("NullableCollection") - @Nullable default void onCreateTranslationRequests( @NonNull @SuppressWarnings("unused") long[] virtualChildIds, @NonNull @SuppressWarnings("unused") @DataFormat int[] supportedFormats,