diff options
| author | Joanne Chung <joannechung@google.com> | 2020-12-30 00:05:02 +0800 |
|---|---|---|
| committer | Joanne Chung <joannechung@google.com> | 2021-01-25 18:57:14 +0800 |
| commit | a5fa9bc0f7d861b9a083aab3a43b60da1e19b9af (patch) | |
| tree | 186c1a440f880d71d91146fbb6c3a54397072faf /core/java/android/widget/TextView.java | |
| parent | d9e22f9ac96610cb2b4780c1615a2b262abe7d63 (diff) | |
Add initial View's APIs for auto translation
The initial APIs for auto translation flow. The implementation of
sending request and dealing spans will on the follow up changes.
Bug: 172969740
Test: manual build pass. Use a sample app to call api get expected
result.
Change-Id: Ief45190026e6205ff18366c1aaba8f424a4df00c
Diffstat (limited to 'core/java/android/widget/TextView.java')
| -rw-r--r-- | core/java/android/widget/TextView.java | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index b8660255acc1..8cfbca88c596 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -129,6 +129,7 @@ import android.text.method.TextKeyListener; import android.text.method.TimeKeyListener; import android.text.method.TransformationMethod; import android.text.method.TransformationMethod2; +import android.text.method.TranslationTransformationMethod; import android.text.method.WordIterator; import android.text.style.CharacterStyle; import android.text.style.ClickableSpan; @@ -193,6 +194,7 @@ import android.view.textclassifier.TextClassifier; import android.view.textclassifier.TextLinks; import android.view.textservice.SpellCheckerSubtype; import android.view.textservice.TextServicesManager; +import android.view.translation.TranslationRequest; import android.widget.RemoteViews.RemoteView; import com.android.internal.annotations.VisibleForTesting; @@ -732,6 +734,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener private MovementMethod mMovement; private TransformationMethod mTransformation; + private TranslationTransformationMethod mTranslationTransformation; @UnsupportedAppUsage private boolean mAllowTransformationLengthChange; @UnsupportedAppUsage @@ -13814,4 +13817,121 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener Log.d(LOG_TAG, location + ": " + String.format(msgFormat, msgArgs)); } } + + /** + * Provides a {@link TranslationRequest} that represents the content to be translated via + * translation service. + * + * <p>NOTE: When overriding the method, it should not translate the password. We also suggest + * that not translating the text is selectable or editable. We use the transformation method to + * implement showing the translated text. The TextView does not support the transformation + * method text length change. If the text is selectable or editable, it will crash while + * selecting the text. To support it, it needs broader changes to text APIs, we only allow to + * translate non selectable and editable text now. + * + * @hide + */ + @Nullable + @Override + public TranslationRequest onCreateTranslationRequest() { + if (mText == null || mText.length() == 0) { + return null; + } + // Not translate password, editable text and not important for translation + // TODO(b/177214256): support selectable text translation. It needs to broader changes to + // text selection apis, not support in S. + boolean isPassword = isAnyPasswordInputType() || hasPasswordTransformationMethod(); + if (isTextEditable() || isPassword || isTextSelectable()) { + return null; + } + // TODO(b/176488462): apply the view's important for translation property + // TODO(b/174283799): remove the spans from the mText and save the spans informatopn + TranslationRequest request = + new TranslationRequest.Builder() + .setAutofillId(getAutofillId()) + .setTranslationText(mText) + .build(); + return request; + } + + /** + * Provides the implementation that pauses the ongoing Ui translation, it will show the original + * text instead of the translated text and restore the original transformation method. + * + * <p>NOTE: If this method is overridden, other translation related methods such as + * {@link onRestoreUiTranslation}, {@link onFinishUiTranslation}, {@link onTranslationComplete} + * should also be overridden. + * + * @hide + */ + @Override + public void onPauseUiTranslation() { + // Restore to original text content. + if (mTranslationTransformation != null) { + setTransformationMethod(mTranslationTransformation.getOriginalTransformationMethod()); + } + } + + /** + * Provides the implementation that restoes the paused Ui translation, it will show the + * translated text again if the text had been translated. This method will replace the current + * tansformation method with {@link TranslationTransformationMethod}. + * + * <p>NOTE: If this method is overridden, other translation related methods such as + * {@link onPauseUiTranslation}, {@link onFinishUiTranslation}, {@link onTranslationComplete} + * should also be overridden. + * + * @hide + */ + @Override + public void onRestoreUiTranslation() { + if (mTranslationTransformation != null) { + setTransformationMethod(mTranslationTransformation); + } else { + Log.w(LOG_TAG, "onResumeTranslatedText(): no translated text."); + } + } + + /** + * Provides the implementation that finishes the current Ui translation and it's no longer to + * show the translated text. This method restores the original transformation method and resets + * the saved {@link TranslationTransformationMethod}. + * + * <p>NOTE: If this method is overridden, other translation related methods such as + * {@link onPauseUiTranslation}, {@link onRestoreUiTranslation}, {@link onTranslationComplete} + * should also be overridden. + * + * @hide + */ + @Override + public void onFinishUiTranslation() { + // Restore to original text content and clear TranslationTransformation + if (mTranslationTransformation != null) { + setTransformationMethod(mTranslationTransformation.getOriginalTransformationMethod()); + mTranslationTransformation = null; + } + } + + /** + * Default {@link TextView} implementation after the translation request is done by the + * translation service, it's ok to show the translated text. This method will save the original + * transformation method and replace the current transformation method with + * {@link TranslationTransformationMethod}. + * + * <p>NOTE: If this method is overridden, other translation related methods such as + * {@link onPauseUiTranslation}, {@link onRestoreUiTranslation}, {@link onFinishUiTranslation} + * should also be overridden. + * + * @hide + */ + @Override + public void onTranslationComplete(@NonNull TranslationRequest data) { + // Show the translated text. + TransformationMethod originalTranslationMethod = mTranslationTransformation != null + ? mTranslationTransformation.getOriginalTransformationMethod() : mTransformation; + mTranslationTransformation = + new TranslationTransformationMethod(data, originalTranslationMethod); + // TODO(b/178353965): well-handle setTransformationMethod. + setTransformationMethod(mTranslationTransformation); + } } |
