Merge "Bug fix: allow to create ViewTranslationRequest for virtual AutofillId." into sc-dev

This commit is contained in:
Joanne Chung
2021-03-31 03:41:39 +00:00
committed by Android (Google) Code Review
6 changed files with 104 additions and 86 deletions

View File

@@ -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 {

View File

@@ -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<android.view.translation.ViewTranslationRequest>);
method public default void onCreateTranslationRequests(@NonNull long[], @NonNull int[], @NonNull java.util.function.Consumer<android.view.translation.ViewTranslationRequest>);
method public void onDetachedFromWindow();
method public boolean onDragEvent(android.view.DragEvent);
method public void onDraw(android.graphics.Canvas);

View File

@@ -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.
*
* <p> The default implementation will call {@link View#onCreateTranslationRequest} to build
* {@link ViewTranslationRequest} if the view should be translated. </p>

View File

@@ -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<ViewTranslationResponse> viewsResult = new SparseArray<>();
final SparseArray<LongSparseArray<ViewTranslationResponse>> virtualViewsResult =
new SparseArray<>();
// TODO: use another structure to prevent autoboxing?
final List<Integer> 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<AutofillId, long[]> viewIds = new ArrayMap<>();
Map<AutofillId, Integer> 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<Integer> sourceViewIds) {
private void findViewsTraversalByAutofillIds(IntArray sourceViewIds) {
final ArrayList<ViewRootImpl> 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<Integer> 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<Integer> 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));
}
}

View File

@@ -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<String, TranslationRequestValue> value);
private @NonNull AutofillId mAutofillId;
private @NonNull Map<String, TranslationRequestValue> 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<String, TranslationRequestValue> 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<String,TranslationRequestValue> 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<String,TranslationRequestValue> 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<String,TranslationRequestValue> 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<java.lang.String,android.view.translation.TranslationRequestValue> mTranslationRequestValues\npublic @android.annotation.NonNull android.view.translation.TranslationRequestValue getValue(java.lang.String)\npublic @android.annotation.NonNull java.util.Set<java.lang.String> getKeys()\npublic @android.annotation.NonNull android.view.autofill.AutofillId getAutofillId()\nprivate static java.util.Map<java.lang.String,android.view.translation.TranslationRequestValue> defaultTranslationRequestValues()\nclass ViewTranslationRequest extends java.lang.Object implements [android.os.Parcelable]\nabstract android.view.translation.ViewTranslationRequest.Builder setTranslationRequestValues(java.util.Map<java.lang.String,android.view.translation.TranslationRequestValue>)\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<java.lang.String,android.view.translation.TranslationRequestValue>)\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<java.lang.String,android.view.translation.TranslationRequestValue> mTranslationRequestValues\npublic @android.annotation.NonNull android.view.translation.TranslationRequestValue getValue(java.lang.String)\npublic @android.annotation.NonNull java.util.Set<java.lang.String> getKeys()\npublic @android.annotation.NonNull android.view.autofill.AutofillId getAutofillId()\nprivate static java.util.Map<java.lang.String,android.view.translation.TranslationRequestValue> 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<java.lang.String,android.view.translation.TranslationRequestValue> 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<java.lang.String,android.view.translation.TranslationRequestValue>)\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() {}

View File

@@ -365,7 +365,6 @@ public interface WebViewProvider {
}
@SuppressLint("NullableCollection")
@Nullable
default void onCreateTranslationRequests(
@NonNull @SuppressWarnings("unused") long[] virtualChildIds,
@NonNull @SuppressWarnings("unused") @DataFormat int[] supportedFormats,