Merge "Add InputConnection app and service dump"
This commit is contained in:
committed by
Android (Google) Code Review
commit
0612ad7955
@@ -199,10 +199,11 @@ public abstract class AbstractInputMethodService extends Service
|
||||
* Dumps the internal state of IME to a protocol buffer output stream.
|
||||
*
|
||||
* @param proto ProtoOutputStream to dump data to.
|
||||
* @param icProto {@link InputConnection} call data in proto format.
|
||||
* @hide
|
||||
*/
|
||||
@SuppressWarnings("HiddenAbstractMethod")
|
||||
public abstract void dumpProtoInternal(ProtoOutputStream proto);
|
||||
public abstract void dumpProtoInternal(ProtoOutputStream proto, ProtoOutputStream icProto);
|
||||
|
||||
/**
|
||||
* Implement this to handle {@link android.os.Binder#dump Binder.dump()}
|
||||
|
||||
@@ -25,6 +25,7 @@ import static android.inputmethodservice.InputMethodServiceProto.EXTRACTED_TOKEN
|
||||
import static android.inputmethodservice.InputMethodServiceProto.EXTRACT_VIEW_HIDDEN;
|
||||
import static android.inputmethodservice.InputMethodServiceProto.FULLSCREEN_APPLIED;
|
||||
import static android.inputmethodservice.InputMethodServiceProto.INPUT_BINDING;
|
||||
import static android.inputmethodservice.InputMethodServiceProto.INPUT_CONNECTION_CALL;
|
||||
import static android.inputmethodservice.InputMethodServiceProto.INPUT_EDITOR_INFO;
|
||||
import static android.inputmethodservice.InputMethodServiceProto.INPUT_STARTED;
|
||||
import static android.inputmethodservice.InputMethodServiceProto.INPUT_VIEW_STARTED;
|
||||
@@ -742,7 +743,8 @@ public class InputMethodService extends AbstractInputMethodService {
|
||||
return;
|
||||
}
|
||||
ImeTracing.getInstance().triggerServiceDump(
|
||||
"InputMethodService.InputMethodImpl#hideSoftInput", InputMethodService.this);
|
||||
"InputMethodService.InputMethodImpl#hideSoftInput", InputMethodService.this,
|
||||
null /* icProto */);
|
||||
final boolean wasVisible = isInputViewShown();
|
||||
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMS.hideSoftInput");
|
||||
|
||||
@@ -798,7 +800,8 @@ public class InputMethodService extends AbstractInputMethodService {
|
||||
}
|
||||
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMS.showSoftInput");
|
||||
ImeTracing.getInstance().triggerServiceDump(
|
||||
"InputMethodService.InputMethodImpl#showSoftInput", InputMethodService.this);
|
||||
"InputMethodService.InputMethodImpl#showSoftInput", InputMethodService.this,
|
||||
null /* icProto */);
|
||||
final boolean wasVisible = isInputViewShown();
|
||||
if (dispatchOnShowInputRequested(flags, false)) {
|
||||
|
||||
@@ -2182,7 +2185,8 @@ public class InputMethodService extends AbstractInputMethodService {
|
||||
return;
|
||||
}
|
||||
|
||||
ImeTracing.getInstance().triggerServiceDump("InputMethodService#showWindow", this);
|
||||
ImeTracing.getInstance().triggerServiceDump("InputMethodService#showWindow", this,
|
||||
null /* icProto */);
|
||||
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMS.showWindow");
|
||||
mDecorViewWasVisible = mDecorViewVisible;
|
||||
mInShowWindow = true;
|
||||
@@ -2260,7 +2264,8 @@ public class InputMethodService extends AbstractInputMethodService {
|
||||
*/
|
||||
private void applyVisibilityInInsetsConsumerIfNecessary(boolean setVisible) {
|
||||
ImeTracing.getInstance().triggerServiceDump(
|
||||
"InputMethodService#applyVisibilityInInsetsConsumerIfNecessary", this);
|
||||
"InputMethodService#applyVisibilityInInsetsConsumerIfNecessary", this,
|
||||
null /* icProto */);
|
||||
mPrivOps.applyImeVisibility(setVisible
|
||||
? mCurShowInputToken : mCurHideInputToken, setVisible);
|
||||
}
|
||||
@@ -2285,7 +2290,8 @@ public class InputMethodService extends AbstractInputMethodService {
|
||||
|
||||
public void hideWindow() {
|
||||
if (DEBUG) Log.v(TAG, "CALL: hideWindow");
|
||||
ImeTracing.getInstance().triggerServiceDump("InputMethodService#hideWindow", this);
|
||||
ImeTracing.getInstance().triggerServiceDump("InputMethodService#hideWindow", this,
|
||||
null /* icProto */);
|
||||
mWindowVisible = false;
|
||||
finishViews(false /* finishingInput */);
|
||||
if (mDecorViewVisible) {
|
||||
@@ -2356,7 +2362,8 @@ public class InputMethodService extends AbstractInputMethodService {
|
||||
|
||||
void doFinishInput() {
|
||||
if (DEBUG) Log.v(TAG, "CALL: doFinishInput");
|
||||
ImeTracing.getInstance().triggerServiceDump("InputMethodService#doFinishInput", this);
|
||||
ImeTracing.getInstance().triggerServiceDump("InputMethodService#doFinishInput", this,
|
||||
null /* icProto */);
|
||||
finishViews(true /* finishingInput */);
|
||||
if (mInputStarted) {
|
||||
mInlineSuggestionSessionController.notifyOnFinishInput();
|
||||
@@ -2372,7 +2379,8 @@ public class InputMethodService extends AbstractInputMethodService {
|
||||
if (!restarting && mInputStarted) {
|
||||
doFinishInput();
|
||||
}
|
||||
ImeTracing.getInstance().triggerServiceDump("InputMethodService#doStartInput", this);
|
||||
ImeTracing.getInstance().triggerServiceDump("InputMethodService#doStartInput", this,
|
||||
null /* icProto */);
|
||||
mInputStarted = true;
|
||||
mStartedInputConnection = ic;
|
||||
mInputEditorInfo = attribute;
|
||||
@@ -2531,7 +2539,8 @@ public class InputMethodService extends AbstractInputMethodService {
|
||||
* @param flags Provides additional operating flags.
|
||||
*/
|
||||
public void requestHideSelf(int flags) {
|
||||
ImeTracing.getInstance().triggerServiceDump("InputMethodService#requestHideSelf", this);
|
||||
ImeTracing.getInstance().triggerServiceDump("InputMethodService#requestHideSelf", this,
|
||||
null /* icProto */);
|
||||
mPrivOps.hideMySoftInput(flags);
|
||||
}
|
||||
|
||||
@@ -2544,7 +2553,8 @@ public class InputMethodService extends AbstractInputMethodService {
|
||||
* @param flags Provides additional operating flags.
|
||||
*/
|
||||
public final void requestShowSelf(int flags) {
|
||||
ImeTracing.getInstance().triggerServiceDump("InputMethodService#requestShowSelf", this);
|
||||
ImeTracing.getInstance().triggerServiceDump("InputMethodService#requestShowSelf", this,
|
||||
null /* icProto */);
|
||||
mPrivOps.showMySoftInput(flags);
|
||||
}
|
||||
|
||||
@@ -3364,7 +3374,7 @@ public class InputMethodService extends AbstractInputMethodService {
|
||||
* @hide
|
||||
*/
|
||||
@Override
|
||||
public final void dumpProtoInternal(ProtoOutputStream proto) {
|
||||
public final void dumpProtoInternal(ProtoOutputStream proto, ProtoOutputStream icProto) {
|
||||
final long token = proto.start(InputMethodServiceTraceProto.INPUT_METHOD_SERVICE);
|
||||
mWindow.dumpDebug(proto, SOFT_INPUT_WINDOW);
|
||||
proto.write(VIEWS_CREATED, mViewsCreated);
|
||||
@@ -3393,6 +3403,9 @@ public class InputMethodService extends AbstractInputMethodService {
|
||||
proto.write(STATUS_ICON, mStatusIcon);
|
||||
mTmpInsets.dumpDebug(proto, LAST_COMPUTED_INSETS);
|
||||
proto.write(SETTINGS_OBSERVER, Objects.toString(mSettingsObserver));
|
||||
if (icProto != null) {
|
||||
proto.write(INPUT_CONNECTION_CALL, icProto.getBytes());
|
||||
}
|
||||
proto.end(token);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,15 +110,20 @@ public abstract class ImeTracing {
|
||||
*
|
||||
* @param where Place where the trace was triggered.
|
||||
* @param immInstance The {@link InputMethodManager} instance to dump.
|
||||
* @param icProto {@link android.view.inputmethod.InputConnection} call data in proto format.
|
||||
*/
|
||||
public abstract void triggerClientDump(String where, InputMethodManager immInstance);
|
||||
public abstract void triggerClientDump(String where, InputMethodManager immInstance,
|
||||
ProtoOutputStream icProto);
|
||||
|
||||
/**
|
||||
* Starts a proto dump of the currently connected InputMethodService information.
|
||||
*
|
||||
* @param where Place where the trace was triggered.
|
||||
* @param service The {@link android.inputmethodservice.InputMethodService} to be dumped.
|
||||
* @param icProto {@link android.view.inputmethod.InputConnection} call data in proto format.
|
||||
*/
|
||||
public abstract void triggerServiceDump(String where, AbstractInputMethodService service);
|
||||
public abstract void triggerServiceDump(String where, AbstractInputMethodService service,
|
||||
ProtoOutputStream icProto);
|
||||
|
||||
/**
|
||||
* Starts a proto dump of the InputMethodManagerService information.
|
||||
|
||||
@@ -45,7 +45,8 @@ class ImeTracingClientImpl extends ImeTracing {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void triggerClientDump(String where, @NonNull InputMethodManager immInstance) {
|
||||
public void triggerClientDump(String where, @NonNull InputMethodManager immInstance,
|
||||
ProtoOutputStream icProto) {
|
||||
if (!isEnabled() || !isAvailable()) {
|
||||
return;
|
||||
}
|
||||
@@ -59,7 +60,7 @@ class ImeTracingClientImpl extends ImeTracing {
|
||||
|
||||
try {
|
||||
ProtoOutputStream proto = new ProtoOutputStream();
|
||||
immInstance.dumpDebug(proto);
|
||||
immInstance.dumpDebug(proto, icProto);
|
||||
sendToService(proto.getBytes(), IME_TRACING_FROM_CLIENT, where);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Exception while sending ime-related client dump to server", e);
|
||||
@@ -69,7 +70,8 @@ class ImeTracingClientImpl extends ImeTracing {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void triggerServiceDump(String where, @NonNull AbstractInputMethodService service) {
|
||||
public void triggerServiceDump(String where, @NonNull AbstractInputMethodService service,
|
||||
ProtoOutputStream icProto) {
|
||||
if (!isEnabled() || !isAvailable()) {
|
||||
return;
|
||||
}
|
||||
@@ -83,7 +85,7 @@ class ImeTracingClientImpl extends ImeTracing {
|
||||
|
||||
try {
|
||||
ProtoOutputStream proto = new ProtoOutputStream();
|
||||
service.dumpProtoInternal(proto);
|
||||
service.dumpProtoInternal(proto, icProto);
|
||||
sendToService(proto.getBytes(), IME_TRACING_FROM_IMS, where);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Exception while sending ime-related service dump to server", e);
|
||||
|
||||
@@ -133,12 +133,14 @@ class ImeTracingServerImpl extends ImeTracing {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void triggerClientDump(String where, InputMethodManager immInstance) {
|
||||
public void triggerClientDump(String where, InputMethodManager immInstance,
|
||||
ProtoOutputStream icProto) {
|
||||
// Intentionally left empty, this is implemented in ImeTracingClientImpl
|
||||
}
|
||||
|
||||
@Override
|
||||
public void triggerServiceDump(String where, AbstractInputMethodService service) {
|
||||
public void triggerServiceDump(String where, AbstractInputMethodService service,
|
||||
ProtoOutputStream icProto) {
|
||||
// Intentionally left empty, this is implemented in ImeTracingClientImpl
|
||||
}
|
||||
|
||||
|
||||
231
core/java/android/util/imetracing/InputConnectionHelper.java
Normal file
231
core/java/android/util/imetracing/InputConnectionHelper.java
Normal file
@@ -0,0 +1,231 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.util.imetracing;
|
||||
|
||||
import static android.view.inputmethod.InputConnectionCallProto.GET_CURSOR_CAPS_MODE;
|
||||
import static android.view.inputmethod.InputConnectionCallProto.GET_EXTRACTED_TEXT;
|
||||
import static android.view.inputmethod.InputConnectionCallProto.GET_SELECTED_TEXT;
|
||||
import static android.view.inputmethod.InputConnectionCallProto.GET_SURROUNDING_TEXT;
|
||||
import static android.view.inputmethod.InputConnectionCallProto.GET_TEXT_AFTER_CURSOR;
|
||||
import static android.view.inputmethod.InputConnectionCallProto.GET_TEXT_BEFORE_CURSOR;
|
||||
import static android.view.inputmethod.InputConnectionCallProto.GetExtractedText.REQUEST;
|
||||
|
||||
import android.annotation.IntRange;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.util.proto.ProtoOutputStream;
|
||||
import android.view.inputmethod.ExtractedText;
|
||||
import android.view.inputmethod.ExtractedTextRequest;
|
||||
import android.view.inputmethod.InputConnectionCallProto.GetCursorCapsMode;
|
||||
import android.view.inputmethod.InputConnectionCallProto.GetExtractedText;
|
||||
import android.view.inputmethod.InputConnectionCallProto.GetSelectedText;
|
||||
import android.view.inputmethod.InputConnectionCallProto.GetSurroundingText;
|
||||
import android.view.inputmethod.InputConnectionCallProto.GetTextAfterCursor;
|
||||
import android.view.inputmethod.InputConnectionCallProto.GetTextBeforeCursor;
|
||||
import android.view.inputmethod.SurroundingText;
|
||||
|
||||
/**
|
||||
* Helper class for constructing {@link android.view.inputmethod.InputConnection} dumps, which are
|
||||
* integrated into {@link ImeTracing}.
|
||||
* @hide
|
||||
*/
|
||||
public class InputConnectionHelper {
|
||||
static final String TAG = "InputConnectionHelper";
|
||||
public static final boolean DUMP_TEXT = false;
|
||||
|
||||
private InputConnectionHelper() {}
|
||||
|
||||
/**
|
||||
* Builder for InputConnectionCallProto to hold
|
||||
* {@link android.view.inputmethod.InputConnection#getTextAfterCursor(int, int)} data.
|
||||
*
|
||||
* @param length The expected length of the text. This must be non-negative.
|
||||
* @param flags Supplies additional options controlling how the text is
|
||||
* returned. May be either {@code 0} or
|
||||
* {@link android.view.inputmethod.InputConnection#GET_TEXT_WITH_STYLES}.
|
||||
* @param result The text after the cursor position; the length of the
|
||||
* returned text might be less than <var>length</var>.
|
||||
* @return ProtoOutputStream holding the InputConnectionCallProto data.
|
||||
*/
|
||||
public static ProtoOutputStream buildGetTextAfterCursorProto(@IntRange(from = 0) int length,
|
||||
int flags, @Nullable CharSequence result) {
|
||||
ProtoOutputStream proto = new ProtoOutputStream();
|
||||
final long token = proto.start(GET_TEXT_AFTER_CURSOR);
|
||||
proto.write(GetTextAfterCursor.LENGTH, length);
|
||||
proto.write(GetTextAfterCursor.FLAGS, flags);
|
||||
if (result == null) {
|
||||
proto.write(GetTextAfterCursor.RESULT, "null result");
|
||||
} else if (DUMP_TEXT) {
|
||||
proto.write(GetTextAfterCursor.RESULT, result.toString());
|
||||
}
|
||||
proto.end(token);
|
||||
return proto;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder for InputConnectionCallProto to hold
|
||||
* {@link android.view.inputmethod.InputConnection#getTextBeforeCursor(int, int)} data.
|
||||
*
|
||||
* @param length The expected length of the text. This must be non-negative.
|
||||
* @param flags Supplies additional options controlling how the text is
|
||||
* returned. May be either {@code 0} or
|
||||
* {@link android.view.inputmethod.InputConnection#GET_TEXT_WITH_STYLES}.
|
||||
* @param result The text before the cursor position; the length of the
|
||||
* returned text might be less than <var>length</var>.
|
||||
* @return ProtoOutputStream holding the InputConnectionCallProto data.
|
||||
*/
|
||||
public static ProtoOutputStream buildGetTextBeforeCursorProto(@IntRange(from = 0) int length,
|
||||
int flags, @Nullable CharSequence result) {
|
||||
ProtoOutputStream proto = new ProtoOutputStream();
|
||||
final long token = proto.start(GET_TEXT_BEFORE_CURSOR);
|
||||
proto.write(GetTextBeforeCursor.LENGTH, length);
|
||||
proto.write(GetTextBeforeCursor.FLAGS, flags);
|
||||
if (result == null) {
|
||||
proto.write(GetTextBeforeCursor.RESULT, "null result");
|
||||
} else if (DUMP_TEXT) {
|
||||
proto.write(GetTextBeforeCursor.RESULT, result.toString());
|
||||
}
|
||||
proto.end(token);
|
||||
return proto;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder for InputConnectionCallProto to hold
|
||||
* {@link android.view.inputmethod.InputConnection#getSelectedText(int)} data.
|
||||
*
|
||||
* @param flags Supplies additional options controlling how the text is
|
||||
* returned. May be either {@code 0} or
|
||||
* {@link android.view.inputmethod.InputConnection#GET_TEXT_WITH_STYLES}.
|
||||
* @param result the text that is currently selected, if any, or null if
|
||||
* no text is selected. In {@link android.os.Build.VERSION_CODES#N} and
|
||||
* later, returns false when the target application does not implement
|
||||
* this method.
|
||||
* @return ProtoOutputStream holding the InputConnectionCallProto data.
|
||||
*/
|
||||
public static ProtoOutputStream buildGetSelectedTextProto(int flags,
|
||||
@Nullable CharSequence result) {
|
||||
ProtoOutputStream proto = new ProtoOutputStream();
|
||||
final long token = proto.start(GET_SELECTED_TEXT);
|
||||
proto.write(GetSelectedText.FLAGS, flags);
|
||||
if (result == null) {
|
||||
proto.write(GetSelectedText.RESULT, "null result");
|
||||
} else if (DUMP_TEXT) {
|
||||
proto.write(GetSelectedText.RESULT, result.toString());
|
||||
}
|
||||
proto.end(token);
|
||||
return proto;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder for InputConnectionCallProto to hold
|
||||
* {@link android.view.inputmethod.InputConnection#getSurroundingText(int, int, int)} data.
|
||||
*
|
||||
* @param beforeLength The expected length of the text before the cursor.
|
||||
* @param afterLength The expected length of the text after the cursor.
|
||||
* @param flags Supplies additional options controlling how the text is
|
||||
* returned. May be either {@code 0} or
|
||||
* {@link android.view.inputmethod.InputConnection#GET_TEXT_WITH_STYLES}.
|
||||
* @param result an {@link android.view.inputmethod.SurroundingText} object describing the
|
||||
* surrounding text and state of selection, or null if the input connection is no longer valid,
|
||||
* or the editor can't comply with the request for some reason, or the application does not
|
||||
* implement this method. The length of the returned text might be less than the sum of
|
||||
* <var>beforeLength</var> and <var>afterLength</var> .
|
||||
* @return ProtoOutputStream holding the InputConnectionCallProto data.
|
||||
*/
|
||||
public static ProtoOutputStream buildGetSurroundingTextProto(@IntRange(from = 0)
|
||||
int beforeLength, @IntRange(from = 0) int afterLength, int flags,
|
||||
@Nullable SurroundingText result) {
|
||||
ProtoOutputStream proto = new ProtoOutputStream();
|
||||
final long token = proto.start(GET_SURROUNDING_TEXT);
|
||||
proto.write(GetSurroundingText.BEFORE_LENGTH, beforeLength);
|
||||
proto.write(GetSurroundingText.AFTER_LENGTH, afterLength);
|
||||
proto.write(GetSurroundingText.FLAGS, flags);
|
||||
if (result == null) {
|
||||
final long token_result = proto.start(GetSurroundingText.RESULT);
|
||||
proto.write(GetSurroundingText.SurroundingText.TEXT, "null result");
|
||||
proto.end(token_result);
|
||||
} else if (DUMP_TEXT) {
|
||||
final long token_result = proto.start(GetSurroundingText.RESULT);
|
||||
proto.write(GetSurroundingText.SurroundingText.TEXT, result.getText().toString());
|
||||
proto.write(GetSurroundingText.SurroundingText.SELECTION_START,
|
||||
result.getSelectionStart());
|
||||
proto.write(GetSurroundingText.SurroundingText.SELECTION_END,
|
||||
result.getSelectionEnd());
|
||||
proto.write(GetSurroundingText.SurroundingText.OFFSET, result.getOffset());
|
||||
proto.end(token_result);
|
||||
}
|
||||
proto.end(token);
|
||||
return proto;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder for InputConnectionCallProto to hold
|
||||
* {@link android.view.inputmethod.InputConnection#getCursorCapsMode(int)} data.
|
||||
*
|
||||
* @param reqModes The desired modes to retrieve, as defined by
|
||||
* {@link android.text.TextUtils#getCapsMode TextUtils.getCapsMode}.
|
||||
* @param result the caps mode flags that are in effect at the current
|
||||
* cursor position. See TYPE_TEXT_FLAG_CAPS_* in {@link android.text.InputType}.
|
||||
* @return ProtoOutputStream holding the InputConnectionCallProto data.
|
||||
*/
|
||||
public static ProtoOutputStream buildGetCursorCapsModeProto(int reqModes, int result) {
|
||||
ProtoOutputStream proto = new ProtoOutputStream();
|
||||
final long token = proto.start(GET_CURSOR_CAPS_MODE);
|
||||
proto.write(GetCursorCapsMode.REQ_MODES, reqModes);
|
||||
if (DUMP_TEXT) {
|
||||
proto.write(GetCursorCapsMode.RESULT, result);
|
||||
}
|
||||
proto.end(token);
|
||||
return proto;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder for InputConnectionCallProto to hold
|
||||
* {@link android.view.inputmethod.InputConnection#getExtractedText(ExtractedTextRequest, int)}
|
||||
* data.
|
||||
*
|
||||
* @param request Description of how the text should be returned.
|
||||
* {@link android.view.inputmethod.ExtractedTextRequest}
|
||||
* @param flags Additional options to control the client, either {@code 0} or
|
||||
* {@link android.view.inputmethod.InputConnection#GET_EXTRACTED_TEXT_MONITOR}.
|
||||
* @param result an {@link android.view.inputmethod.ExtractedText}
|
||||
* object describing the state of the text view and containing the
|
||||
* extracted text itself, or null if the input connection is no
|
||||
* longer valid of the editor can't comply with the request for
|
||||
* some reason.
|
||||
* @return ProtoOutputStream holding the InputConnectionCallProto data.
|
||||
*/
|
||||
public static ProtoOutputStream buildGetExtractedTextProto(@NonNull ExtractedTextRequest
|
||||
request, int flags, @Nullable ExtractedText result) {
|
||||
ProtoOutputStream proto = new ProtoOutputStream();
|
||||
final long token = proto.start(GET_EXTRACTED_TEXT);
|
||||
final long token_request = proto.start(REQUEST);
|
||||
proto.write(GetExtractedText.ExtractedTextRequest.TOKEN, request.token);
|
||||
proto.write(GetExtractedText.ExtractedTextRequest.FLAGS, request.flags);
|
||||
proto.write(GetExtractedText.ExtractedTextRequest.HINT_MAX_LINES, request.hintMaxLines);
|
||||
proto.write(GetExtractedText.ExtractedTextRequest.HINT_MAX_CHARS, request.hintMaxChars);
|
||||
proto.end(token_request);
|
||||
proto.write(GetExtractedText.FLAGS, flags);
|
||||
if (result == null) {
|
||||
proto.write(GetExtractedText.RESULT, "null result");
|
||||
} else if (DUMP_TEXT) {
|
||||
proto.write(GetExtractedText.RESULT, result.text.toString());
|
||||
}
|
||||
proto.end(token);
|
||||
return proto;
|
||||
}
|
||||
}
|
||||
@@ -829,7 +829,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
|
||||
}
|
||||
if (fromIme) {
|
||||
ImeTracing.getInstance().triggerClientDump("InsetsController#show",
|
||||
mHost.getInputMethodManager());
|
||||
mHost.getInputMethodManager(), null /* icProto */);
|
||||
Trace.asyncTraceEnd(TRACE_TAG_VIEW, "IC.showRequestFromApiToImeReady", 0);
|
||||
Trace.asyncTraceBegin(TRACE_TAG_VIEW, "IC.showRequestFromIme", 0);
|
||||
} else {
|
||||
@@ -886,7 +886,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
|
||||
void hide(@InsetsType int types, boolean fromIme) {
|
||||
if (fromIme) {
|
||||
ImeTracing.getInstance().triggerClientDump("InsetsController#hide",
|
||||
mHost.getInputMethodManager());
|
||||
mHost.getInputMethodManager(), null /* icProto */);
|
||||
Trace.asyncTraceBegin(TRACE_TAG_VIEW, "IC.hideRequestFromIme", 0);
|
||||
} else {
|
||||
Trace.asyncTraceBegin(TRACE_TAG_VIEW, "IC.hideRequestFromApi", 0);
|
||||
@@ -928,7 +928,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
|
||||
if (fromIme) {
|
||||
ImeTracing.getInstance().triggerClientDump(
|
||||
"InsetsController#controlWindowInsetsAnimation",
|
||||
mHost.getInputMethodManager());
|
||||
mHost.getInputMethodManager(), null /* icProto */);
|
||||
}
|
||||
|
||||
controlAnimationUnchecked(types, cancellationSignal, listener, mFrame, fromIme, durationMs,
|
||||
@@ -1022,7 +1022,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
|
||||
animationType, mHost.getTranslator());
|
||||
if ((typesReady & WindowInsets.Type.ime()) != 0) {
|
||||
ImeTracing.getInstance().triggerClientDump("InsetsAnimationControlImpl",
|
||||
mHost.getInputMethodManager());
|
||||
mHost.getInputMethodManager(), null /* icProto */);
|
||||
}
|
||||
mRunningAnimations.add(new RunningAnimation(runner, animationType));
|
||||
if (DEBUG) Log.d(TAG, "Animation added to runner. useInsetsAnimationThread: "
|
||||
@@ -1200,7 +1200,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
|
||||
if (types.valueAt(j) == ITYPE_IME) {
|
||||
ImeTracing.getInstance().triggerClientDump(
|
||||
"InsetsSourceConsumer#notifyAnimationFinished",
|
||||
mHost.getInputMethodManager());
|
||||
mHost.getInputMethodManager(), null /* icProto */);
|
||||
}
|
||||
stateChanged |= getSourceConsumer(types.valueAt(j)).notifyAnimationFinished();
|
||||
}
|
||||
@@ -1345,7 +1345,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
|
||||
boolean fromIme) {
|
||||
if ((types & ime()) != 0) {
|
||||
ImeTracing.getInstance().triggerClientDump("InsetsController#hideDirectly",
|
||||
mHost.getInputMethodManager());
|
||||
mHost.getInputMethodManager(), null /* icProto */);
|
||||
}
|
||||
final ArraySet<Integer> internalTypes = InsetsState.toInternalType(types);
|
||||
for (int i = internalTypes.size() - 1; i >= 0; i--) {
|
||||
@@ -1361,7 +1361,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
|
||||
private void showDirectly(@InsetsType int types, boolean fromIme) {
|
||||
if ((types & ime()) != 0) {
|
||||
ImeTracing.getInstance().triggerClientDump("InsetsController#showDirectly",
|
||||
mHost.getInputMethodManager());
|
||||
mHost.getInputMethodManager(), null /* icProto */);
|
||||
}
|
||||
final ArraySet<Integer> internalTypes = InsetsState.toInternalType(types);
|
||||
for (int i = internalTypes.size() - 1; i >= 0; i--) {
|
||||
|
||||
@@ -9225,7 +9225,8 @@ public final class ViewRootImpl implements ViewParent,
|
||||
final ViewRootImpl viewAncestor = mViewAncestor.get();
|
||||
if (fromIme) {
|
||||
ImeTracing.getInstance().triggerClientDump("ViewRootImpl.W#showInsets",
|
||||
viewAncestor.getInsetsController().getHost().getInputMethodManager());
|
||||
viewAncestor.getInsetsController().getHost().getInputMethodManager(),
|
||||
null /* icProto */);
|
||||
}
|
||||
if (viewAncestor != null) {
|
||||
viewAncestor.showInsets(types, fromIme);
|
||||
@@ -9238,7 +9239,8 @@ public final class ViewRootImpl implements ViewParent,
|
||||
final ViewRootImpl viewAncestor = mViewAncestor.get();
|
||||
if (fromIme) {
|
||||
ImeTracing.getInstance().triggerClientDump("ViewRootImpl.W#hideInsets",
|
||||
viewAncestor.getInsetsController().getHost().getInputMethodManager());
|
||||
viewAncestor.getInsetsController().getHost().getInputMethodManager(),
|
||||
null /* icProto */);
|
||||
}
|
||||
if (viewAncestor != null) {
|
||||
viewAncestor.hideInsets(types, fromIme);
|
||||
|
||||
@@ -23,6 +23,7 @@ import static android.view.inputmethod.InputMethodEditorTraceProto.InputMethodCl
|
||||
import static android.view.inputmethod.InputMethodEditorTraceProto.InputMethodClientsTraceProto.ClientSideProto.EDITOR_INFO;
|
||||
import static android.view.inputmethod.InputMethodEditorTraceProto.InputMethodClientsTraceProto.ClientSideProto.IME_INSETS_SOURCE_CONSUMER;
|
||||
import static android.view.inputmethod.InputMethodEditorTraceProto.InputMethodClientsTraceProto.ClientSideProto.INPUT_CONNECTION;
|
||||
import static android.view.inputmethod.InputMethodEditorTraceProto.InputMethodClientsTraceProto.ClientSideProto.INPUT_CONNECTION_CALL;
|
||||
import static android.view.inputmethod.InputMethodEditorTraceProto.InputMethodClientsTraceProto.ClientSideProto.INPUT_METHOD_MANAGER;
|
||||
import static android.view.inputmethod.InputMethodEditorTraceProto.InputMethodClientsTraceProto.ClientSideProto.VIEW_ROOT_IMPL;
|
||||
import static android.view.inputmethod.InputMethodManagerProto.ACTIVE;
|
||||
@@ -579,7 +580,8 @@ public final class InputMethodManager {
|
||||
int windowFlags) {
|
||||
final View servedView;
|
||||
ImeTracing.getInstance().triggerClientDump(
|
||||
"InputMethodManager.DelegateImpl#startInput", InputMethodManager.this);
|
||||
"InputMethodManager.DelegateImpl#startInput", InputMethodManager.this,
|
||||
null /* icProto */);
|
||||
synchronized (mH) {
|
||||
mCurrentTextBoxAttribute = null;
|
||||
mCompletions = null;
|
||||
@@ -1016,6 +1018,11 @@ public final class InputMethodManager {
|
||||
return mParentInputMethodManager.mActive && !isFinished();
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputMethodManager getIMM() {
|
||||
return mParentInputMethodManager;
|
||||
}
|
||||
|
||||
void deactivate() {
|
||||
if (isFinished()) {
|
||||
// This is a small performance optimization. Still only the 1st call of
|
||||
@@ -1713,7 +1720,8 @@ public final class InputMethodManager {
|
||||
* {@link #RESULT_HIDDEN}.
|
||||
*/
|
||||
public boolean showSoftInput(View view, int flags, ResultReceiver resultReceiver) {
|
||||
ImeTracing.getInstance().triggerClientDump("InputMethodManager#showSoftInput", this);
|
||||
ImeTracing.getInstance().triggerClientDump("InputMethodManager#showSoftInput", this,
|
||||
null /* icProto */);
|
||||
// Re-dispatch if there is a context mismatch.
|
||||
final InputMethodManager fallbackImm = getFallbackInputMethodManagerIfNecessary(view);
|
||||
if (fallbackImm != null) {
|
||||
@@ -1822,7 +1830,7 @@ public final class InputMethodManager {
|
||||
public boolean hideSoftInputFromWindow(IBinder windowToken, int flags,
|
||||
ResultReceiver resultReceiver) {
|
||||
ImeTracing.getInstance().triggerClientDump("InputMethodManager#hideSoftInputFromWindow",
|
||||
this);
|
||||
this, null /* icProto */);
|
||||
checkFocus();
|
||||
synchronized (mH) {
|
||||
final View servedView = getServedViewLocked();
|
||||
@@ -2228,7 +2236,8 @@ public final class InputMethodManager {
|
||||
* @hide
|
||||
*/
|
||||
public void notifyImeHidden(IBinder windowToken) {
|
||||
ImeTracing.getInstance().triggerClientDump("InputMethodManager#notifyImeHidden", this);
|
||||
ImeTracing.getInstance().triggerClientDump("InputMethodManager#notifyImeHidden", this,
|
||||
null /* icProto */);
|
||||
synchronized (mH) {
|
||||
try {
|
||||
if (mCurMethod != null && mCurRootView != null
|
||||
@@ -3296,7 +3305,7 @@ public final class InputMethodManager {
|
||||
for (String arg : args) {
|
||||
if (arg.equals(PROTO_ARG)) {
|
||||
final ProtoOutputStream proto = new ProtoOutputStream(fd);
|
||||
dumpDebug(proto);
|
||||
dumpDebug(proto, null /* icProto */);
|
||||
proto.flush();
|
||||
return true;
|
||||
}
|
||||
@@ -3309,10 +3318,11 @@ public final class InputMethodManager {
|
||||
* {@link ProtoOutputStream}.
|
||||
*
|
||||
* @param proto The proto stream to which the dumps are written.
|
||||
* @param icProto {@link InputConnection} call data in proto format.
|
||||
* @hide
|
||||
*/
|
||||
@GuardedBy("mH")
|
||||
public void dumpDebug(ProtoOutputStream proto) {
|
||||
public void dumpDebug(ProtoOutputStream proto, ProtoOutputStream icProto) {
|
||||
if (mCurMethod == null) {
|
||||
return;
|
||||
}
|
||||
@@ -3337,6 +3347,9 @@ public final class InputMethodManager {
|
||||
if (mServedInputConnectionWrapper != null) {
|
||||
mServedInputConnectionWrapper.dumpDebug(proto, INPUT_CONNECTION);
|
||||
}
|
||||
if (icProto != null) {
|
||||
proto.write(INPUT_CONNECTION_CALL, icProto.getBytes());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,9 @@ import android.os.Message;
|
||||
import android.os.RemoteException;
|
||||
import android.os.Trace;
|
||||
import android.util.Log;
|
||||
import android.util.imetracing.ImeTracing;
|
||||
import android.util.imetracing.InputConnectionHelper;
|
||||
import android.util.proto.ProtoOutputStream;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.inputmethod.CompletionInfo;
|
||||
import android.view.inputmethod.CorrectionInfo;
|
||||
@@ -36,6 +39,7 @@ import android.view.inputmethod.InputConnection;
|
||||
import android.view.inputmethod.InputConnectionInspector;
|
||||
import android.view.inputmethod.InputConnectionInspector.MissingMethodFlags;
|
||||
import android.view.inputmethod.InputContentInfo;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.view.inputmethod.SurroundingText;
|
||||
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
@@ -124,7 +128,9 @@ public abstract class IInputConnectionWrapper extends IInputContext.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
abstract protected boolean isActive();
|
||||
protected abstract boolean isActive();
|
||||
|
||||
protected abstract InputMethodManager getIMM();
|
||||
|
||||
public void getTextAfterCursor(int length, int flags, ICharSequenceResultCallback callback) {
|
||||
dispatchMessage(mH.obtainMessage(DO_GET_TEXT_AFTER_CURSOR, length, flags, callback));
|
||||
@@ -264,6 +270,7 @@ public abstract class IInputConnectionWrapper extends IInputContext.Stub {
|
||||
}
|
||||
|
||||
void executeMessage(Message msg) {
|
||||
ProtoOutputStream icProto;
|
||||
switch (msg.what) {
|
||||
case DO_GET_TEXT_AFTER_CURSOR: {
|
||||
Trace.traceBegin(Trace.TRACE_TAG_INPUT, "InputConnection#getTextAfterCursor");
|
||||
@@ -278,6 +285,12 @@ public abstract class IInputConnectionWrapper extends IInputContext.Stub {
|
||||
} else {
|
||||
result = ic.getTextAfterCursor(msg.arg1, msg.arg2);
|
||||
}
|
||||
if (ImeTracing.getInstance().isEnabled()) {
|
||||
icProto = InputConnectionHelper.buildGetTextAfterCursorProto(msg.arg1,
|
||||
msg.arg2, result);
|
||||
ImeTracing.getInstance().triggerClientDump(
|
||||
TAG + "#getTextAfterCursor", getIMM(), icProto);
|
||||
}
|
||||
try {
|
||||
callback.onResult(result);
|
||||
} catch (RemoteException e) {
|
||||
@@ -302,6 +315,12 @@ public abstract class IInputConnectionWrapper extends IInputContext.Stub {
|
||||
} else {
|
||||
result = ic.getTextBeforeCursor(msg.arg1, msg.arg2);
|
||||
}
|
||||
if (ImeTracing.getInstance().isEnabled()) {
|
||||
icProto = InputConnectionHelper.buildGetTextBeforeCursorProto(msg.arg1,
|
||||
msg.arg2, result);
|
||||
ImeTracing.getInstance().triggerClientDump(
|
||||
TAG + "#getTextBeforeCursor", getIMM(), icProto);
|
||||
}
|
||||
try {
|
||||
callback.onResult(result);
|
||||
} catch (RemoteException e) {
|
||||
@@ -326,6 +345,11 @@ public abstract class IInputConnectionWrapper extends IInputContext.Stub {
|
||||
} else {
|
||||
result = ic.getSelectedText(msg.arg1);
|
||||
}
|
||||
if (ImeTracing.getInstance().isEnabled()) {
|
||||
icProto = InputConnectionHelper.buildGetSelectedTextProto(msg.arg1, result);
|
||||
ImeTracing.getInstance().triggerClientDump(
|
||||
TAG + "#getSelectedText", getIMM(), icProto);
|
||||
}
|
||||
try {
|
||||
callback.onResult(result);
|
||||
} catch (RemoteException e) {
|
||||
@@ -354,6 +378,12 @@ public abstract class IInputConnectionWrapper extends IInputContext.Stub {
|
||||
} else {
|
||||
result = ic.getSurroundingText(beforeLength, afterLength, flags);
|
||||
}
|
||||
if (ImeTracing.getInstance().isEnabled()) {
|
||||
icProto = InputConnectionHelper.buildGetSurroundingTextProto(beforeLength,
|
||||
afterLength, flags, result);
|
||||
ImeTracing.getInstance().triggerClientDump(
|
||||
TAG + "#getSurroundingText", getIMM(), icProto);
|
||||
}
|
||||
try {
|
||||
callback.onResult(result);
|
||||
} catch (RemoteException e) {
|
||||
@@ -378,6 +408,12 @@ public abstract class IInputConnectionWrapper extends IInputContext.Stub {
|
||||
} else {
|
||||
result = ic.getCursorCapsMode(msg.arg1);
|
||||
}
|
||||
if (ImeTracing.getInstance().isEnabled()) {
|
||||
icProto = InputConnectionHelper.buildGetCursorCapsModeProto(msg.arg1,
|
||||
result);
|
||||
ImeTracing.getInstance().triggerClientDump(
|
||||
TAG + "#getCursorCapsMode", getIMM(), icProto);
|
||||
}
|
||||
try {
|
||||
callback.onResult(result);
|
||||
} catch (RemoteException e) {
|
||||
@@ -404,6 +440,12 @@ public abstract class IInputConnectionWrapper extends IInputContext.Stub {
|
||||
} else {
|
||||
result = ic.getExtractedText(request, msg.arg1);
|
||||
}
|
||||
if (ImeTracing.getInstance().isEnabled()) {
|
||||
icProto = InputConnectionHelper.buildGetExtractedTextProto(request,
|
||||
msg.arg1, result);
|
||||
ImeTracing.getInstance().triggerClientDump(
|
||||
TAG + "#getExtractedText", getIMM(), icProto);
|
||||
}
|
||||
try {
|
||||
callback.onResult(result);
|
||||
} catch (RemoteException e) {
|
||||
|
||||
@@ -24,6 +24,9 @@ import android.inputmethodservice.AbstractInputMethodService;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.RemoteException;
|
||||
import android.util.imetracing.ImeTracing;
|
||||
import android.util.imetracing.InputConnectionHelper;
|
||||
import android.util.proto.ProtoOutputStream;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.inputmethod.CompletionInfo;
|
||||
import android.view.inputmethod.CorrectionInfo;
|
||||
@@ -87,8 +90,18 @@ public class InputConnectionWrapper implements InputConnection {
|
||||
} catch (RemoteException e) {
|
||||
return null;
|
||||
}
|
||||
return Completable.getResultOrNull(
|
||||
CharSequence result = Completable.getResultOrNull(
|
||||
value, TAG, "getTextAfterCursor()", mCancellationGroup, MAX_WAIT_TIME_MILLIS);
|
||||
|
||||
final AbstractInputMethodService inputMethodService = mInputMethodService.get();
|
||||
if (inputMethodService != null && ImeTracing.getInstance().isEnabled()) {
|
||||
ProtoOutputStream icProto = InputConnectionHelper.buildGetTextAfterCursorProto(length,
|
||||
flags, result);
|
||||
ImeTracing.getInstance().triggerServiceDump(TAG + "#getTextAfterCursor",
|
||||
inputMethodService, icProto);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -107,8 +120,18 @@ public class InputConnectionWrapper implements InputConnection {
|
||||
} catch (RemoteException e) {
|
||||
return null;
|
||||
}
|
||||
return Completable.getResultOrNull(
|
||||
CharSequence result = Completable.getResultOrNull(
|
||||
value, TAG, "getTextBeforeCursor()", mCancellationGroup, MAX_WAIT_TIME_MILLIS);
|
||||
|
||||
final AbstractInputMethodService inputMethodService = mInputMethodService.get();
|
||||
if (inputMethodService != null && ImeTracing.getInstance().isEnabled()) {
|
||||
ProtoOutputStream icProto = InputConnectionHelper.buildGetTextBeforeCursorProto(length,
|
||||
flags, result);
|
||||
ImeTracing.getInstance().triggerServiceDump(TAG + "#getTextBeforeCursor",
|
||||
inputMethodService, icProto);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@AnyThread
|
||||
@@ -127,8 +150,18 @@ public class InputConnectionWrapper implements InputConnection {
|
||||
} catch (RemoteException e) {
|
||||
return null;
|
||||
}
|
||||
return Completable.getResultOrNull(
|
||||
CharSequence result = Completable.getResultOrNull(
|
||||
value, TAG, "getSelectedText()", mCancellationGroup, MAX_WAIT_TIME_MILLIS);
|
||||
|
||||
final AbstractInputMethodService inputMethodService = mInputMethodService.get();
|
||||
if (inputMethodService != null && ImeTracing.getInstance().isEnabled()) {
|
||||
ProtoOutputStream icProto = InputConnectionHelper.buildGetSelectedTextProto(flags,
|
||||
result);
|
||||
ImeTracing.getInstance().triggerServiceDump(TAG + "#getSelectedText",
|
||||
inputMethodService, icProto);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -161,8 +194,18 @@ public class InputConnectionWrapper implements InputConnection {
|
||||
} catch (RemoteException e) {
|
||||
return null;
|
||||
}
|
||||
return Completable.getResultOrNull(
|
||||
SurroundingText result = Completable.getResultOrNull(
|
||||
value, TAG, "getSurroundingText()", mCancellationGroup, MAX_WAIT_TIME_MILLIS);
|
||||
|
||||
final AbstractInputMethodService inputMethodService = mInputMethodService.get();
|
||||
if (inputMethodService != null && ImeTracing.getInstance().isEnabled()) {
|
||||
ProtoOutputStream icProto = InputConnectionHelper.buildGetSurroundingTextProto(
|
||||
beforeLength, afterLength, flags, result);
|
||||
ImeTracing.getInstance().triggerServiceDump(TAG + "#getSurroundingText",
|
||||
inputMethodService, icProto);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@AnyThread
|
||||
@@ -177,8 +220,18 @@ public class InputConnectionWrapper implements InputConnection {
|
||||
} catch (RemoteException e) {
|
||||
return 0;
|
||||
}
|
||||
return Completable.getResultOrZero(
|
||||
int result = Completable.getResultOrZero(
|
||||
value, TAG, "getCursorCapsMode()", mCancellationGroup, MAX_WAIT_TIME_MILLIS);
|
||||
|
||||
final AbstractInputMethodService inputMethodService = mInputMethodService.get();
|
||||
if (inputMethodService != null && ImeTracing.getInstance().isEnabled()) {
|
||||
ProtoOutputStream icProto = InputConnectionHelper.buildGetCursorCapsModeProto(
|
||||
reqModes, result);
|
||||
ImeTracing.getInstance().triggerServiceDump(TAG + "#getCursorCapsMode",
|
||||
inputMethodService, icProto);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@AnyThread
|
||||
@@ -193,8 +246,18 @@ public class InputConnectionWrapper implements InputConnection {
|
||||
} catch (RemoteException e) {
|
||||
return null;
|
||||
}
|
||||
return Completable.getResultOrNull(
|
||||
ExtractedText result = Completable.getResultOrNull(
|
||||
value, TAG, "getExtractedText()", mCancellationGroup, MAX_WAIT_TIME_MILLIS);
|
||||
|
||||
final AbstractInputMethodService inputMethodService = mInputMethodService.get();
|
||||
if (inputMethodService != null && ImeTracing.getInstance().isEnabled()) {
|
||||
ProtoOutputStream icProto = InputConnectionHelper.buildGetExtractedTextProto(
|
||||
request, flags, result);
|
||||
ImeTracing.getInstance().triggerServiceDump(TAG + "#getExtractedText",
|
||||
inputMethodService, icProto);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@AnyThread
|
||||
|
||||
@@ -28,6 +28,7 @@ import android.text.Editable;
|
||||
import android.text.Selection;
|
||||
import android.text.method.KeyListener;
|
||||
import android.util.Log;
|
||||
import android.util.imetracing.InputConnectionHelper;
|
||||
import android.util.proto.ProtoOutputStream;
|
||||
import android.view.inputmethod.BaseInputConnection;
|
||||
import android.view.inputmethod.CompletionInfo;
|
||||
@@ -45,7 +46,6 @@ import android.widget.TextView;
|
||||
public class EditableInputConnection extends BaseInputConnection
|
||||
implements DumpableInputConnection {
|
||||
private static final boolean DEBUG = false;
|
||||
private static final boolean DUMP_TEXT = false;
|
||||
private static final String TAG = "EditableInputConnection";
|
||||
|
||||
private final TextView mTextView;
|
||||
@@ -243,7 +243,7 @@ public class EditableInputConnection extends BaseInputConnection
|
||||
final long token = proto.start(fieldId);
|
||||
CharSequence editableText = mTextView.getText();
|
||||
CharSequence selectedText = getSelectedText(0 /* flags */);
|
||||
if (DUMP_TEXT) {
|
||||
if (InputConnectionHelper.DUMP_TEXT) {
|
||||
if (editableText != null) {
|
||||
proto.write(EDITABLE_TEXT, editableText.toString());
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ syntax = "proto2";
|
||||
|
||||
import "frameworks/base/core/proto/android/inputmethodservice/softinputwindow.proto";
|
||||
import "frameworks/base/core/proto/android/view/inputmethod/editorinfo.proto";
|
||||
import "frameworks/base/core/proto/android/view/inputmethod/inputconnection.proto";
|
||||
|
||||
package android.inputmethodservice;
|
||||
|
||||
@@ -51,6 +52,7 @@ message InputMethodServiceProto {
|
||||
optional int32 status_icon = 25;
|
||||
optional InsetsProto last_computed_insets = 26;
|
||||
optional string settings_observer = 27;
|
||||
optional .android.view.inputmethod.InputConnectionCallProto input_connection_call = 28;
|
||||
|
||||
message InsetsProto {
|
||||
optional int32 content_top_insets = 1;
|
||||
|
||||
@@ -31,4 +31,68 @@ message InputConnectionProto {
|
||||
optional int32 selected_text_start = 3;
|
||||
optional int32 selected_text_end = 4;
|
||||
optional int32 cursor_caps_mode = 5;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows information about parameters and result for method calls to
|
||||
* {@link android.view.inputmethod.InputConnection}.
|
||||
*/
|
||||
message InputConnectionCallProto {
|
||||
oneof method_call {
|
||||
GetTextBeforeCursor get_text_before_cursor = 1;
|
||||
GetTextAfterCursor get_text_after_cursor = 2;
|
||||
GetSelectedText get_selected_text = 3;
|
||||
GetSurroundingText get_surrounding_text = 4;
|
||||
GetCursorCapsMode get_cursor_caps_mode = 5;
|
||||
GetExtractedText get_extracted_text = 6;
|
||||
}
|
||||
|
||||
message GetTextBeforeCursor {
|
||||
optional int32 length = 1;
|
||||
optional int32 flags = 2;
|
||||
optional string result = 3 [(.android.privacy).dest = DEST_LOCAL];
|
||||
}
|
||||
|
||||
message GetTextAfterCursor {
|
||||
optional int32 length = 1;
|
||||
optional int32 flags = 2;
|
||||
optional string result = 3 [(.android.privacy).dest = DEST_LOCAL];
|
||||
}
|
||||
|
||||
message GetSelectedText {
|
||||
optional int32 flags = 1;
|
||||
optional string result = 2 [(.android.privacy).dest = DEST_LOCAL];
|
||||
}
|
||||
|
||||
message GetSurroundingText {
|
||||
optional int32 before_length = 1;
|
||||
optional int32 after_length = 2;
|
||||
optional int32 flags = 3;
|
||||
optional SurroundingText result = 4;
|
||||
|
||||
message SurroundingText {
|
||||
optional string text = 1 [(.android.privacy).dest = DEST_LOCAL];
|
||||
optional int32 selection_start = 2;
|
||||
optional int32 selection_end = 3;
|
||||
optional int32 offset = 4;
|
||||
}
|
||||
}
|
||||
|
||||
message GetCursorCapsMode {
|
||||
optional int32 req_modes = 1;
|
||||
optional int32 result = 2;
|
||||
}
|
||||
|
||||
message GetExtractedText {
|
||||
optional ExtractedTextRequest request = 1;
|
||||
optional int32 flags = 2;
|
||||
optional string result = 3 [(.android.privacy).dest = DEST_LOCAL];
|
||||
|
||||
message ExtractedTextRequest {
|
||||
optional int32 token = 1;
|
||||
optional int32 flags = 2;
|
||||
optional int32 hint_max_lines = 3;
|
||||
optional int32 hint_max_chars = 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -72,6 +72,7 @@ message InputMethodClientsTraceProto {
|
||||
optional EditorInfoProto editor_info = 6;
|
||||
optional ImeFocusControllerProto ime_focus_controller = 7;
|
||||
optional InputConnectionProto input_connection = 8;
|
||||
optional InputConnectionCallProto input_connection_call = 9;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user