Merge "Refine the ViewTranslationCallback usage." into sc-dev am: cee152ee43
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/14186069 Change-Id: Id288b5a1111f604cca9a79cb9b848a1487b43cc6
This commit is contained in:
@@ -3514,6 +3514,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
|
|||||||
* 11 PFLAG4_SCROLL_CAPTURE_HINT_MASK
|
* 11 PFLAG4_SCROLL_CAPTURE_HINT_MASK
|
||||||
* 1 PFLAG4_ALLOW_CLICK_WHEN_DISABLED
|
* 1 PFLAG4_ALLOW_CLICK_WHEN_DISABLED
|
||||||
* 1 PFLAG4_DETACHED
|
* 1 PFLAG4_DETACHED
|
||||||
|
* 1 PFLAG4_HAS_TRANSLATION_TRANSIENT_STATE
|
||||||
* |-------|-------|-------|-------|
|
* |-------|-------|-------|-------|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -3580,6 +3581,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
|
|||||||
*/
|
*/
|
||||||
private static final int PFLAG4_DETACHED = 0x000002000;
|
private static final int PFLAG4_DETACHED = 0x000002000;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates that the view has transient state because the system is translating it.
|
||||||
|
*/
|
||||||
|
private static final int PFLAG4_HAS_TRANSLATION_TRANSIENT_STATE = 0x000004000;
|
||||||
|
|
||||||
/* End of masks for mPrivateFlags4 */
|
/* End of masks for mPrivateFlags4 */
|
||||||
|
|
||||||
/** @hide */
|
/** @hide */
|
||||||
@@ -12270,6 +12276,30 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the view is tracking translation transient state. This flag is used to check if the view
|
||||||
|
* need to call setHasTransientState(false) to reset transient state that set when starting
|
||||||
|
* translation.
|
||||||
|
*
|
||||||
|
* @param hasTranslationTransientState true if this view has translation transient state
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public void setHasTranslationTransientState(boolean hasTranslationTransientState) {
|
||||||
|
if (hasTranslationTransientState) {
|
||||||
|
mPrivateFlags4 |= PFLAG4_HAS_TRANSLATION_TRANSIENT_STATE;
|
||||||
|
} else {
|
||||||
|
mPrivateFlags4 &= ~PFLAG4_HAS_TRANSLATION_TRANSIENT_STATE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public boolean hasTranslationTransientState() {
|
||||||
|
return (mPrivateFlags4 & PFLAG4_HAS_TRANSLATION_TRANSIENT_STATE)
|
||||||
|
== PFLAG4_HAS_TRANSLATION_TRANSIENT_STATE;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if this view is currently attached to a window.
|
* Returns true if this view is currently attached to a window.
|
||||||
*/
|
*/
|
||||||
@@ -30839,6 +30869,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Returns a {@link ViewTranslationCallback} that is used to display the translated information
|
||||||
|
* or {@code null} if this View doesn't support translation.
|
||||||
|
*
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
@@ -30925,7 +30958,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
|
|||||||
* view or calls {@link View#onVirtualViewTranslationResponses} for view contains virtual
|
* view or calls {@link View#onVirtualViewTranslationResponses} for view contains virtual
|
||||||
* children to build {@link ViewTranslationRequest} if the view should be translated.
|
* children to build {@link ViewTranslationRequest} if the view should be translated.
|
||||||
* The view is marked as having {@link #setHasTransientState(boolean) transient state} so that
|
* 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>
|
* recycling of views doesn't prevent the system from attaching the response to it. Therefore,
|
||||||
|
* if overriding this method, you should set or reset the transient state. </p>
|
||||||
*
|
*
|
||||||
* @param viewIds a map for the view's {@link AutofillId} and its virtual child ids or
|
* @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
|
* {@code null} if the view doesn't have virtual child that should be translated. The virtual
|
||||||
@@ -30975,10 +31009,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
|
|||||||
Log.v(CONTENT_CAPTURE_LOG_TAG, "Calling setHasTransientState(true) for "
|
Log.v(CONTENT_CAPTURE_LOG_TAG, "Calling setHasTransientState(true) for "
|
||||||
+ getAutofillId());
|
+ getAutofillId());
|
||||||
}
|
}
|
||||||
// TODO: Add a default ViewTranslationCallback for View that resets this in
|
|
||||||
// onClearTranslation(). Also update the javadoc for this method to mention
|
|
||||||
// that.
|
|
||||||
setHasTransientState(true);
|
setHasTransientState(true);
|
||||||
|
setHasTranslationTransientState(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,6 +43,8 @@ import android.view.ViewRootImpl;
|
|||||||
import android.view.WindowManagerGlobal;
|
import android.view.WindowManagerGlobal;
|
||||||
import android.view.autofill.AutofillId;
|
import android.view.autofill.AutofillId;
|
||||||
import android.view.translation.UiTranslationManager.UiTranslationState;
|
import android.view.translation.UiTranslationManager.UiTranslationState;
|
||||||
|
import android.widget.TextView;
|
||||||
|
import android.widget.TextViewTranslationCallback;
|
||||||
|
|
||||||
import com.android.internal.util.function.pooled.PooledLambda;
|
import com.android.internal.util.function.pooled.PooledLambda;
|
||||||
|
|
||||||
@@ -146,7 +148,13 @@ public class UiTranslationController {
|
|||||||
break;
|
break;
|
||||||
case STATE_UI_TRANSLATION_FINISHED:
|
case STATE_UI_TRANSLATION_FINISHED:
|
||||||
destroyTranslators();
|
destroyTranslators();
|
||||||
runForEachView((view, callback) -> callback.onClearTranslation(view));
|
runForEachView((view, callback) -> {
|
||||||
|
callback.onClearTranslation(view);
|
||||||
|
if (view.hasTranslationTransientState()) {
|
||||||
|
view.setHasTransientState(false);
|
||||||
|
view.setHasTranslationTransientState(false);
|
||||||
|
}
|
||||||
|
});
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
mViews.clear();
|
mViews.clear();
|
||||||
}
|
}
|
||||||
@@ -381,17 +389,23 @@ public class UiTranslationController {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
mActivity.runOnUiThread(() -> {
|
mActivity.runOnUiThread(() -> {
|
||||||
final ViewTranslationCallback callback = view.getViewTranslationCallback();
|
ViewTranslationCallback callback = view.getViewTranslationCallback();
|
||||||
if (callback == null) {
|
if (callback == null) {
|
||||||
|
if (view instanceof TextView) {
|
||||||
|
// developer doesn't provide their override, we set the default TextView
|
||||||
|
// implememtation.
|
||||||
|
callback = new TextViewTranslationCallback();
|
||||||
|
view.setViewTranslationCallback(callback);
|
||||||
|
if (mViewsToPadContent.contains(autofillId)) {
|
||||||
|
callback.enableContentPadding();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Log.d(TAG, view + " doesn't support showing translation because of "
|
Log.d(TAG, view + " doesn't support showing translation because of "
|
||||||
+ "null ViewTranslationCallback.");
|
+ "null ViewTranslationCallback.");
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mViewsToPadContent.contains(autofillId)) {
|
|
||||||
callback.enableContentPadding();
|
|
||||||
}
|
}
|
||||||
view.onViewTranslationResponse(response);
|
view.onViewTranslationResponse(response);
|
||||||
callback.onShowTranslation(view);
|
callback.onShowTranslation(view);
|
||||||
|
|||||||
@@ -740,7 +740,6 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
|||||||
private MovementMethod mMovement;
|
private MovementMethod mMovement;
|
||||||
|
|
||||||
private TransformationMethod mTransformation;
|
private TransformationMethod mTransformation;
|
||||||
private TextViewTranslationCallback mDefaultTranslationCallback;
|
|
||||||
@UnsupportedAppUsage
|
@UnsupportedAppUsage
|
||||||
private boolean mAllowTransformationLengthChange;
|
private boolean mAllowTransformationLengthChange;
|
||||||
@UnsupportedAppUsage
|
@UnsupportedAppUsage
|
||||||
@@ -2376,11 +2375,16 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
|||||||
@ViewDebug.CapturedViewProperty
|
@ViewDebug.CapturedViewProperty
|
||||||
@InspectableProperty
|
@InspectableProperty
|
||||||
public CharSequence getText() {
|
public CharSequence getText() {
|
||||||
if (mUseTextPaddingForUiTranslation
|
if (mUseTextPaddingForUiTranslation) {
|
||||||
&& mDefaultTranslationCallback != null
|
ViewTranslationCallback callback = getViewTranslationCallback();
|
||||||
&& mDefaultTranslationCallback.isTextPaddingEnabled()
|
if (callback != null && callback instanceof TextViewTranslationCallback) {
|
||||||
&& mDefaultTranslationCallback.isShowingTranslation()) {
|
TextViewTranslationCallback defaultCallback =
|
||||||
return mDefaultTranslationCallback.getPaddedText(mText, mTransformed);
|
(TextViewTranslationCallback) callback;
|
||||||
|
if (defaultCallback.isTextPaddingEnabled()
|
||||||
|
&& defaultCallback.isShowingTranslation()) {
|
||||||
|
return defaultCallback.getPaddedText(mText, mTransformed);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return mText;
|
return mText;
|
||||||
}
|
}
|
||||||
@@ -13932,30 +13936,6 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
|||||||
requestsCollector.accept(requestBuilder.build());
|
requestsCollector.accept(requestBuilder.build());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a {@link ViewTranslationCallback} that is used to display the translated information.
|
|
||||||
* The default implementation will use a {@link TransformationMethod} that allow to replace the
|
|
||||||
* current {@link TransformationMethod} to transform the original text to the translated text
|
|
||||||
* display.
|
|
||||||
*
|
|
||||||
* @return a {@link ViewTranslationCallback} that is used to control how to display the
|
|
||||||
* translated information or {@code null} if this View doesn't support translation.
|
|
||||||
*
|
|
||||||
* @hide
|
|
||||||
*/
|
|
||||||
@Nullable
|
|
||||||
@Override
|
|
||||||
public ViewTranslationCallback getViewTranslationCallback() {
|
|
||||||
return getDefaultViewTranslationCallback();
|
|
||||||
}
|
|
||||||
|
|
||||||
private ViewTranslationCallback getDefaultViewTranslationCallback() {
|
|
||||||
if (mDefaultTranslationCallback == null) {
|
|
||||||
mDefaultTranslationCallback = new TextViewTranslationCallback();
|
|
||||||
}
|
|
||||||
return mDefaultTranslationCallback;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Called when the content from {@link #onCreateViewTranslationRequest} had been translated by
|
* Called when the content from {@link #onCreateViewTranslationRequest} had been translated by
|
||||||
@@ -13969,17 +13949,19 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
|||||||
public void onViewTranslationResponse(@NonNull ViewTranslationResponse response) {
|
public void onViewTranslationResponse(@NonNull ViewTranslationResponse response) {
|
||||||
// set ViewTranslationResponse
|
// set ViewTranslationResponse
|
||||||
super.onViewTranslationResponse(response);
|
super.onViewTranslationResponse(response);
|
||||||
// TODO(b/183467275): Use the overridden ViewTranslationCallback instead of our default
|
// TODO(b/178353965): move to ViewTranslationCallback.onShow()
|
||||||
// implementation if the view has overridden getViewTranslationCallback.
|
ViewTranslationCallback callback = getViewTranslationCallback();
|
||||||
TextViewTranslationCallback callback =
|
if (callback instanceof TextViewTranslationCallback) {
|
||||||
(TextViewTranslationCallback) getDefaultViewTranslationCallback();
|
TextViewTranslationCallback textViewDefaultCallback =
|
||||||
|
(TextViewTranslationCallback) callback;
|
||||||
TranslationTransformationMethod oldTranslationMethod =
|
TranslationTransformationMethod oldTranslationMethod =
|
||||||
callback.getTranslationTransformation();
|
textViewDefaultCallback.getTranslationTransformation();
|
||||||
TransformationMethod originalTranslationMethod = oldTranslationMethod != null
|
TransformationMethod originalTranslationMethod = oldTranslationMethod != null
|
||||||
? oldTranslationMethod.getOriginalTransformationMethod() : mTransformation;
|
? oldTranslationMethod.getOriginalTransformationMethod() : mTransformation;
|
||||||
TranslationTransformationMethod newTranslationMethod =
|
TranslationTransformationMethod newTranslationMethod =
|
||||||
new TranslationTransformationMethod(response, originalTranslationMethod);
|
new TranslationTransformationMethod(response, originalTranslationMethod);
|
||||||
// TODO(b/178353965): well-handle setTransformationMethod.
|
// TODO(b/178353965): well-handle setTransformationMethod.
|
||||||
callback.setTranslationTransformation(newTranslationMethod);
|
textViewDefaultCallback.setTranslationTransformation(newTranslationMethod);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user