Merge "Make ContentCapture event contains parcelable span" into sc-dev am: 3009984d65
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/14819344 Change-Id: I5f7981101e83975bb0c78224513f763c1a5c3900
This commit is contained in:
@@ -44,8 +44,9 @@ import android.os.IBinder;
|
|||||||
import android.os.IBinder.DeathRecipient;
|
import android.os.IBinder.DeathRecipient;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.text.Spannable;
|
import android.text.Spannable;
|
||||||
|
import android.text.SpannableString;
|
||||||
|
import android.text.Spanned;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.ArrayMap;
|
|
||||||
import android.util.LocalLog;
|
import android.util.LocalLog;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.util.TimeUtils;
|
import android.util.TimeUtils;
|
||||||
@@ -60,7 +61,6 @@ import java.lang.ref.WeakReference;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -150,12 +150,6 @@ public final class MainContentCaptureSession extends ContentCaptureSession {
|
|||||||
@Nullable
|
@Nullable
|
||||||
private final LocalLog mFlushHistory;
|
private final LocalLog mFlushHistory;
|
||||||
|
|
||||||
/**
|
|
||||||
* If the event in the buffer is of type {@link TYPE_VIEW_TEXT_CHANGED}, this value
|
|
||||||
* indicates whether the event has composing span or not.
|
|
||||||
*/
|
|
||||||
private final Map<AutofillId, Boolean> mLastComposingSpan = new ArrayMap<>();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Binder object used to update the session state.
|
* Binder object used to update the session state.
|
||||||
*/
|
*/
|
||||||
@@ -352,40 +346,34 @@ public final class MainContentCaptureSession extends ContentCaptureSession {
|
|||||||
// 2.1 either last or current text is empty: add.
|
// 2.1 either last or current text is empty: add.
|
||||||
// 2.2 last event doesn't have composing span: add.
|
// 2.2 last event doesn't have composing span: add.
|
||||||
// Otherwise, merge.
|
// Otherwise, merge.
|
||||||
|
|
||||||
final CharSequence text = event.getText();
|
final CharSequence text = event.getText();
|
||||||
final boolean textHasComposingSpan = event.getTextHasComposingSpan();
|
final boolean textHasComposingSpan = event.getTextHasComposingSpan();
|
||||||
|
if (textHasComposingSpan) {
|
||||||
if (textHasComposingSpan && !mLastComposingSpan.isEmpty()) {
|
ContentCaptureEvent lastEvent = null;
|
||||||
final Boolean lastEventHasComposingSpan = mLastComposingSpan.get(event.getId());
|
for (int index = mEvents.size() - 1; index >= 0; index--) {
|
||||||
if (lastEventHasComposingSpan != null && lastEventHasComposingSpan.booleanValue()) {
|
final ContentCaptureEvent tmpEvent = mEvents.get(index);
|
||||||
ContentCaptureEvent lastEvent = null;
|
if (event.getId().equals(tmpEvent.getId())) {
|
||||||
for (int index = mEvents.size() - 1; index >= 0; index--) {
|
lastEvent = tmpEvent;
|
||||||
final ContentCaptureEvent tmpEvent = mEvents.get(index);
|
break;
|
||||||
if (event.getId().equals(tmpEvent.getId())) {
|
|
||||||
lastEvent = tmpEvent;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (lastEvent != null) {
|
}
|
||||||
final CharSequence lastText = lastEvent.getText();
|
if (lastEvent != null && lastEvent.getTextHasComposingSpan()) {
|
||||||
final boolean bothNonEmpty = !TextUtils.isEmpty(lastText)
|
final CharSequence lastText = lastEvent.getText();
|
||||||
&& !TextUtils.isEmpty(text);
|
final boolean bothNonEmpty = !TextUtils.isEmpty(lastText)
|
||||||
boolean equalContent = TextUtils.equals(lastText, text);
|
&& !TextUtils.isEmpty(text);
|
||||||
if (equalContent) {
|
boolean equalContent = TextUtils.equals(lastText, text);
|
||||||
addEvent = false;
|
if (equalContent) {
|
||||||
} else if (bothNonEmpty && lastEventHasComposingSpan) {
|
addEvent = false;
|
||||||
lastEvent.mergeEvent(event);
|
} else if (bothNonEmpty) {
|
||||||
addEvent = false;
|
lastEvent.mergeEvent(event);
|
||||||
}
|
addEvent = false;
|
||||||
if (!addEvent && sVerbose) {
|
}
|
||||||
Log.v(TAG, "Buffering VIEW_TEXT_CHANGED event, updated text="
|
if (!addEvent && sVerbose) {
|
||||||
+ getSanitizedString(text));
|
Log.v(TAG, "Buffering VIEW_TEXT_CHANGED event, updated text="
|
||||||
}
|
+ getSanitizedString(text));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mLastComposingSpan.put(event.getId(), textHasComposingSpan);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mEvents.isEmpty() && eventType == TYPE_VIEW_DISAPPEARED) {
|
if (!mEvents.isEmpty() && eventType == TYPE_VIEW_DISAPPEARED) {
|
||||||
@@ -586,7 +574,6 @@ public final class MainContentCaptureSession extends ContentCaptureSession {
|
|||||||
? Collections.EMPTY_LIST
|
? Collections.EMPTY_LIST
|
||||||
: new ArrayList<>(mEvents);
|
: new ArrayList<>(mEvents);
|
||||||
mEvents.clear();
|
mEvents.clear();
|
||||||
mLastComposingSpan.clear();
|
|
||||||
return new ParceledListSlice<>(events);
|
return new ParceledListSlice<>(events);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -717,7 +704,7 @@ public final class MainContentCaptureSession extends ContentCaptureSession {
|
|||||||
// Since the same CharSequence instance may be reused in the TextView, we need to make
|
// Since the same CharSequence instance may be reused in the TextView, we need to make
|
||||||
// a copy of its content so that its value will not be changed by subsequent updates
|
// a copy of its content so that its value will not be changed by subsequent updates
|
||||||
// in the TextView.
|
// in the TextView.
|
||||||
final String eventText = text == null ? null : text.toString();
|
final CharSequence eventText = stringOrSpannedStringWithoutNoCopySpans(text);
|
||||||
final boolean textHasComposingSpan =
|
final boolean textHasComposingSpan =
|
||||||
text instanceof Spannable && BaseInputConnection.getComposingSpanStart(
|
text instanceof Spannable && BaseInputConnection.getComposingSpanStart(
|
||||||
(Spannable) text) >= 0;
|
(Spannable) text) >= 0;
|
||||||
@@ -726,6 +713,16 @@ public final class MainContentCaptureSession extends ContentCaptureSession {
|
|||||||
.setAutofillId(id).setText(eventText, textHasComposingSpan)));
|
.setAutofillId(id).setText(eventText, textHasComposingSpan)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private CharSequence stringOrSpannedStringWithoutNoCopySpans(CharSequence source) {
|
||||||
|
if (source == null) {
|
||||||
|
return null;
|
||||||
|
} else if (source instanceof Spanned) {
|
||||||
|
return new SpannableString(source, /* ignoreNoCopySpan= */ true);
|
||||||
|
} else {
|
||||||
|
return source.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** Public because is also used by ViewRootImpl */
|
/** Public because is also used by ViewRootImpl */
|
||||||
public void notifyViewInsetsChanged(int sessionId, @NonNull Insets viewInsets) {
|
public void notifyViewInsetsChanged(int sessionId, @NonNull Insets viewInsets) {
|
||||||
mHandler.post(() -> sendEvent(new ContentCaptureEvent(sessionId, TYPE_VIEW_INSETS_CHANGED)
|
mHandler.post(() -> sendEvent(new ContentCaptureEvent(sessionId, TYPE_VIEW_INSETS_CHANGED)
|
||||||
|
|||||||
Reference in New Issue
Block a user