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

Commit d62a86e6 authored by Abodunrinwa Toki's avatar Abodunrinwa Toki
Browse files

Fix smart selection logging bugs.

- Fix count with selection start index inside a word
- Properly handle whitespace characters
- Set the model version tag

Bug: 64914512
Test: bit FrameworksCoreTests:android.widget.TextViewActivityTest
Test: bit CtsWidgetTestCases:android.widget.cts.TextViewTest
Test: Manually tested that logs are correct. Will follow up with automated tests.
Change-Id: Ib73b52ebce999f2cb6e5734e556cd09e47c89a29
parent 75a353ed
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -261,7 +261,7 @@ public final class TextClassification {
         * @hide
         */
        Builder setVersionInfo(@NonNull String versionInfo) {
            mVersionInfo = Preconditions.checkNotNull(mVersionInfo);
            mVersionInfo = Preconditions.checkNotNull(versionInfo);
            return this;
        }

+1 −1
Original line number Diff line number Diff line
@@ -169,7 +169,7 @@ public final class TextSelection {
         * @hide
         */
        Builder setVersionInfo(@NonNull String versionInfo) {
            mVersionInfo = Preconditions.checkNotNull(mVersionInfo);
            mVersionInfo = Preconditions.checkNotNull(versionInfo);
            return this;
        }

+3 −3
Original line number Diff line number Diff line
@@ -253,6 +253,7 @@ public final class SmartSelectionEventTracker {
    private static void debugLog(LogMaker log) {
        if (!DEBUG_LOG_ENABLED) return;

        final String tag = Objects.toString(log.getTaggedData(TAG), "tag");
        final int index = Integer.parseInt(Objects.toString(log.getTaggedData(INDEX), ZERO));

        final String event;
@@ -291,7 +292,6 @@ public final class SmartSelectionEventTracker {
                event = "RESET";
                break;
            case SelectionEvent.EventType.SELECTION_STARTED:
                final String tag = Objects.toString(log.getTaggedData(TAG), "tag");
                String sessionId = Objects.toString(log.getTaggedData(SESSION_ID), "");
                sessionId = sessionId.substring(sessionId.lastIndexOf("-") + 1);
                Log.d(LOG_TAG, String.format("New selection session: %s(%s)", tag, sessionId));
@@ -326,8 +326,8 @@ public final class SmartSelectionEventTracker {
        final String entity = Objects.toString(
                log.getTaggedData(ENTITY_TYPE), TextClassifier.TYPE_UNKNOWN);

        Log.d(LOG_TAG, String.format("%2d: %s, context=%d,%d - old=%d,%d [%s]",
                index, event, eventStart, eventEnd, smartStart, smartEnd, entity));
        Log.d(LOG_TAG, String.format("%2d: %s, context=%d,%d - old=%d,%d [%s] (%s)",
                index, event, eventStart, eventEnd, smartStart, smartEnd, entity, tag));
    }

    /**
+28 −25
Original line number Diff line number Diff line
@@ -20,7 +20,6 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UiThread;
import android.annotation.WorkerThread;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.PointF;
import android.graphics.RectF;
@@ -48,6 +47,7 @@ import java.util.List;
import java.util.Objects;
import java.util.function.Consumer;
import java.util.function.Supplier;
import java.util.regex.Pattern;

/**
 * Helper class for starting selection action mode
@@ -85,8 +85,7 @@ final class SelectionActionModeHelper {
        mTextClassificationHelper = new TextClassificationHelper(
                mTextView.getTextClassifier(), mTextView.getText(),
                0, 1, mTextView.getTextLocales());
        mSelectionTracker =
                new SelectionTracker(mTextView.getContext(), mTextView.isTextEditable());
        mSelectionTracker = new SelectionTracker(mTextView);

        if (SMART_SELECT_ANIMATION_ENABLED) {
            mSmartSelectSprite = new SmartSelectSprite(mTextView.getContext(),
@@ -337,7 +336,7 @@ final class SelectionActionModeHelper {
     */
    private static final class SelectionTracker {

        private final Context mContext;
        private final TextView mTextView;
        private SelectionMetricsLogger mLogger;

        private int mOriginalStart;
@@ -347,9 +346,9 @@ final class SelectionActionModeHelper {
        private boolean mSelectionStarted;
        private boolean mAllowReset;

        SelectionTracker(Context context, boolean editable) {
            mContext = Preconditions.checkNotNull(context);
            mLogger = new SelectionMetricsLogger(context, editable);
        SelectionTracker(TextView textView) {
            mTextView = Preconditions.checkNotNull(textView);
            mLogger = new SelectionMetricsLogger(textView);
        }

        /**
@@ -361,7 +360,7 @@ final class SelectionActionModeHelper {
            mOriginalEnd = selectionEnd;
            mSelectionStarted = true;
            mAllowReset = false;
            maybeInvalidateLogger(editableText);
            maybeInvalidateLogger();
            mLogger.logSelectionStarted(text, selectionStart);
        }

@@ -438,9 +437,9 @@ final class SelectionActionModeHelper {
            return false;
        }

        private void maybeInvalidateLogger(boolean editableText) {
            if (mLogger.isEditTextLogger() != editableText) {
                mLogger = new SelectionMetricsLogger(mContext, editableText);
        private void maybeInvalidateLogger() {
            if (mLogger.isEditTextLogger() != mTextView.isTextEditable()) {
                mLogger = new SelectionMetricsLogger(mTextView);
            }
        }
    }
@@ -462,20 +461,22 @@ final class SelectionActionModeHelper {
    private static final class SelectionMetricsLogger {

        private static final String LOG_TAG = "SelectionMetricsLogger";
        private static final Pattern PATTERN_WHITESPACE = Pattern.compile("\\s+");

        private final SmartSelectionEventTracker mDelegate;
        private final boolean mEditTextLogger;
        private final BreakIterator mWordIterator = BreakIterator.getWordInstance();
        private final BreakIterator mWordIterator;
        private int mStartIndex;
        private int mEndIndex;
        private String mText;

        SelectionMetricsLogger(Context context, boolean editable) {
            final @SmartSelectionEventTracker.WidgetType int widgetType = editable
        SelectionMetricsLogger(TextView textView) {
            Preconditions.checkNotNull(textView);
            final @SmartSelectionEventTracker.WidgetType int widgetType = textView.isTextEditable()
                    ? SmartSelectionEventTracker.WidgetType.EDITTEXT
                    : SmartSelectionEventTracker.WidgetType.TEXTVIEW;
            mDelegate = new SmartSelectionEventTracker(context, widgetType);
            mEditTextLogger = editable;
            mDelegate = new SmartSelectionEventTracker(textView.getContext(), widgetType);
            mEditTextLogger = textView.isTextEditable();
            mWordIterator = BreakIterator.getWordInstance(textView.getTextLocale());
        }

        public void logSelectionStarted(CharSequence text, int index) {
@@ -487,7 +488,6 @@ final class SelectionActionModeHelper {
                }
                mWordIterator.setText(mText);
                mStartIndex = index;
                mEndIndex = mWordIterator.following(index);
                mDelegate.logEvent(SelectionEvent.selectionStarted(0));
            } catch (Exception e) {
                // Avoid crashes due to logging.
@@ -550,12 +550,15 @@ final class SelectionActionModeHelper {
            } else if (start < mStartIndex) {
                wordIndices[0] = -countWordsForward(start);
            } else {  // start > mStartIndex
                if (mStartIndex < start && start < mEndIndex) {
                    // If the new selection did not move past the original word,
                    // assume it has not moved.
                    wordIndices[0] = 0;
                } else {
                wordIndices[0] = countWordsBackward(start);

                // For the selection start index, avoid counting a partial word backwards.
                if (!mWordIterator.isBoundary(start)
                        && !isWhitespace(
                        mWordIterator.preceding(start),
                        mWordIterator.following(start))) {
                    // We counted a partial word. Remove it.
                    wordIndices[0]--;
                }
            }

@@ -599,7 +602,7 @@ final class SelectionActionModeHelper {
        }

        private boolean isWhitespace(int start, int end) {
            return mText.substring(start, end).trim().isEmpty();
            return PATTERN_WHITESPACE.matcher(mText.substring(start, end)).matches();
        }
    }