Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit dbecc1a2 authored by Ahaan Ugale's avatar Ahaan Ugale Committed by Automerger Merge Worker
Browse files

Merge "AutoTranslate: Pad view text for compatibility reasons." into sc-dev am: 1281143a

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/14206887

Change-Id: I7958851096e91784f49463c04f238b5a3af54c56
parents 3497128f 1281143a
Loading
Loading
Loading
Loading
+0 −13
Original line number Original line Diff line number Diff line
@@ -78,24 +78,11 @@ public class TranslationTransformationMethod implements TransformationMethod2 {
        if (TextUtils.isEmpty(translatedText) || isWhitespace(translatedText.toString())) {
        if (TextUtils.isEmpty(translatedText) || isWhitespace(translatedText.toString())) {
            return source;
            return source;
        } else {
        } else {
            // TODO(b/179693024): Remove this once we have the fix to pad the view text instead.
            translatedText = ellipsize(translatedText, ((TextView) view).getText().length());
            // TODO(b/174283799): apply the spans to the text
            // TODO(b/174283799): apply the spans to the text
            return translatedText;
            return translatedText;
        }
        }
    }
    }


    private static CharSequence ellipsize(CharSequence text, int newLength) {
        if (text.length() <= newLength) {
            return text;
        }
        String ellipsis = String.valueOf('\u2026');
        if (newLength == 1) {
            return ellipsis;
        }
        return TextUtils.concat(TextUtils.trimToSize(text, newLength - 1), ellipsis);
    }

    @Override
    @Override
    public void onFocusChanged(View view, CharSequence sourceText,
    public void onFocusChanged(View view, CharSequence sourceText,
            boolean focused, int direction,
            boolean focused, int direction,
+7 −4
Original line number Original line Diff line number Diff line
@@ -362,17 +362,20 @@ public class UiTranslationController {
                    continue;
                    continue;
                }
                }
                mActivity.runOnUiThread(() -> {
                mActivity.runOnUiThread(() -> {
                    if (view.getViewTranslationCallback() == null) {
                    final ViewTranslationCallback callback = view.getViewTranslationCallback();
                    if (callback == null) {
                        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;
                    }
                    }

                    // TODO: Do this for specific views on request only.
                    callback.enableContentPadding();

                    view.onTranslationResponse(response);
                    view.onTranslationResponse(response);
                    if (view.getViewTranslationCallback() != null) {
                    callback.onShowTranslation(view);
                        view.getViewTranslationCallback().onShowTranslation(view);
                    }
                });
                });
            }
            }
        }
        }
+12 −0
Original line number Original line Diff line number Diff line
@@ -48,4 +48,16 @@ public interface ViewTranslationCallback {
     * @return {@code true} if the View handles clearing the translation.
     * @return {@code true} if the View handles clearing the translation.
     */
     */
    boolean onClearTranslation(@NonNull View view);
    boolean onClearTranslation(@NonNull View view);

    /**
     * Enables padding on the view's original content.
     * <p>
     * This is useful when we do not modify the content directly, rather use a mechanism like
     * {@link android.text.method.TransformationMethod}. If the app misbehaves when the displayed
     * translation and the underlying content have different sizes, the platform intelligence can
     * request that the original content be padded to make the sizes match.
     *
     * @hide
     */
    default void enableContentPadding() {}
}
}
+10 −0
Original line number Original line Diff line number Diff line
@@ -770,6 +770,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
    private final boolean mUseInternationalizedInput;
    private final boolean mUseInternationalizedInput;
    // True if fallback fonts that end up getting used should be allowed to affect line spacing.
    // True if fallback fonts that end up getting used should be allowed to affect line spacing.
    /* package */ boolean mUseFallbackLineSpacing;
    /* package */ boolean mUseFallbackLineSpacing;
    // True if the view text can be padded for compat reasons, when the view is translated.
    private final boolean mUseTextPaddingForUiTranslation;
    @ViewDebug.ExportedProperty(category = "text")
    @ViewDebug.ExportedProperty(category = "text")
    @UnsupportedAppUsage
    @UnsupportedAppUsage
@@ -1480,6 +1482,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
        final int targetSdkVersion = context.getApplicationInfo().targetSdkVersion;
        final int targetSdkVersion = context.getApplicationInfo().targetSdkVersion;
        mUseInternationalizedInput = targetSdkVersion >= VERSION_CODES.O;
        mUseInternationalizedInput = targetSdkVersion >= VERSION_CODES.O;
        mUseFallbackLineSpacing = targetSdkVersion >= VERSION_CODES.P;
        mUseFallbackLineSpacing = targetSdkVersion >= VERSION_CODES.P;
        // TODO(b/179693024): Use a ChangeId instead.
        mUseTextPaddingForUiTranslation = targetSdkVersion <= Build.VERSION_CODES.R;
        if (inputMethod != null) {
        if (inputMethod != null) {
            Class<?> c;
            Class<?> c;
@@ -2372,6 +2376,12 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
    @ViewDebug.CapturedViewProperty
    @ViewDebug.CapturedViewProperty
    @InspectableProperty
    @InspectableProperty
    public CharSequence getText() {
    public CharSequence getText() {
        if (mUseTextPaddingForUiTranslation
                && mDefaultTranslationCallback != null
                && mDefaultTranslationCallback.isTextPaddingEnabled()
                && mDefaultTranslationCallback.isShowingTranslation()) {
            return mDefaultTranslationCallback.getPaddedText(mText, mTransformed);
        }
        return mText;
        return mText;
    }
    }
+64 −3
Original line number Original line Diff line number Diff line
@@ -17,6 +17,7 @@
package android.widget;
package android.widget;


import android.annotation.NonNull;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.os.Build;
import android.os.Build;
import android.text.method.TranslationTransformationMethod;
import android.text.method.TranslationTransformationMethod;
import android.util.Log;
import android.util.Log;
@@ -33,7 +34,7 @@ import android.view.translation.ViewTranslationResponse;
 */
 */
public class TextViewTranslationCallback implements ViewTranslationCallback {
public class TextViewTranslationCallback implements ViewTranslationCallback {


    private static final String TAG = "TextViewTranslationCallback";
    private static final String TAG = "TextViewTranslationCb";


    // TODO(b/182433547): remove Build.IS_DEBUGGABLE before ship. Enable the logging in debug build
    // TODO(b/182433547): remove Build.IS_DEBUGGABLE before ship. Enable the logging in debug build
    //  to help the debug during the development phase
    //  to help the debug during the development phase
@@ -41,6 +42,9 @@ public class TextViewTranslationCallback implements ViewTranslationCallback {
            || Build.IS_DEBUGGABLE;
            || Build.IS_DEBUGGABLE;


    private TranslationTransformationMethod mTranslationTransformation;
    private TranslationTransformationMethod mTranslationTransformation;
    private boolean mIsShowingTranslation = false;
    private boolean mIsTextPaddingEnabled = false;
    private CharSequence mPaddedText;


    /**
    /**
     * Invoked by the platform when receiving the successful {@link ViewTranslationResponse} for the
     * Invoked by the platform when receiving the successful {@link ViewTranslationResponse} for the
@@ -74,6 +78,7 @@ public class TextViewTranslationCallback implements ViewTranslationCallback {
     */
     */
    @Override
    @Override
    public boolean onShowTranslation(@NonNull View view) {
    public boolean onShowTranslation(@NonNull View view) {
        mIsShowingTranslation = true;
        if (mTranslationTransformation != null) {
        if (mTranslationTransformation != null) {
            ((TextView) view).setTransformationMethod(mTranslationTransformation);
            ((TextView) view).setTransformationMethod(mTranslationTransformation);
        } else {
        } else {
@@ -90,6 +95,7 @@ public class TextViewTranslationCallback implements ViewTranslationCallback {
     */
     */
    @Override
    @Override
    public boolean onHideTranslation(@NonNull View view) {
    public boolean onHideTranslation(@NonNull View view) {
        mIsShowingTranslation = false;
        // Restore to original text content.
        // Restore to original text content.
        if (mTranslationTransformation != null) {
        if (mTranslationTransformation != null) {
            ((TextView) view).setTransformationMethod(
            ((TextView) view).setTransformationMethod(
@@ -110,9 +116,9 @@ public class TextViewTranslationCallback implements ViewTranslationCallback {
    public boolean onClearTranslation(@NonNull View view) {
    public boolean onClearTranslation(@NonNull View view) {
        // Restore to original text content and clear TranslationTransformation
        // Restore to original text content and clear TranslationTransformation
        if (mTranslationTransformation != null) {
        if (mTranslationTransformation != null) {
            ((TextView) view).setTransformationMethod(
            onHideTranslation(view);
                    mTranslationTransformation.getOriginalTransformationMethod());
            clearTranslationTransformation();
            clearTranslationTransformation();
            mPaddedText = null;
        } else {
        } else {
            if (DEBUG) {
            if (DEBUG) {
                // TODO(b/182433547): remove before S release
                // TODO(b/182433547): remove before S release
@@ -121,4 +127,59 @@ public class TextViewTranslationCallback implements ViewTranslationCallback {
        }
        }
        return true;
        return true;
    }
    }

    boolean isShowingTranslation() {
        return mIsShowingTranslation;
    }

    @Override
    public void enableContentPadding() {
        mIsTextPaddingEnabled = true;
    }

    /**
     * Returns whether readers of the view text should receive padded text for compatibility
     * reasons. The view's original text will be padded to match the length of the translated text.
     */
    boolean isTextPaddingEnabled() {
        return mIsTextPaddingEnabled;
    }

    /**
     * Returns the view's original text with padding added. If the translated text isn't longer than
     * the original text, returns the original text itself.
     *
     * @param text the view's original text
     * @param translatedText the view's translated text
     * @see #isTextPaddingEnabled()
     */
    @Nullable
    CharSequence getPaddedText(CharSequence text, CharSequence translatedText) {
        if (text == null) {
            return null;
        }
        if (mPaddedText == null) {
            mPaddedText = computePaddedText(text, translatedText);
        }
        return mPaddedText;
    }

    @NonNull
    private CharSequence computePaddedText(CharSequence text, CharSequence translatedText) {
        if (translatedText == null) {
            return text;
        }
        int newLength = translatedText.length();
        if (newLength <= text.length()) {
            return text;
        }
        StringBuilder sb = new StringBuilder(newLength);
        sb.append(text);
        for (int i = text.length(); i < newLength; i++) {
            sb.append(COMPAT_PAD_CHARACTER);
        }
        return sb;
    }

    private static final char COMPAT_PAD_CHARACTER = '\u2002';
}
}