Add InputConnection debug information
Add InputConnection information to IME tracing. This change adds
only information about the text associated with an
EditableInputConnection instance: editable text, selected text, text
before and after the cursor (for a preset length) and cursor caps mode.
Test: flash a device
start IME tracing with `adb shell ime tracing start`
stop IME tracing with `adb shell ime tracing stop`
visualise the traces in Winscope and see the inputConnection information
Change-Id: I4dc6147fb7baa2cea413d2c44226e8c84c056c37
This commit is contained in:
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* 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.view.inputmethod;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.util.proto.ProtoOutputStream;
|
||||
|
||||
/** @hide */
|
||||
public interface DumpableInputConnection {
|
||||
|
||||
/**
|
||||
* Method used to dump state of InputConnection implementations of interest.
|
||||
*
|
||||
* @param proto Stream to write the state to
|
||||
* @param fieldId FieldId of DumpableInputConnection as defined in the parent message
|
||||
*/
|
||||
void dumpDebug(@NonNull ProtoOutputStream proto, long fieldId);
|
||||
}
|
||||
@@ -22,6 +22,7 @@ import static android.util.imetracing.ImeTracing.PROTO_ARG;
|
||||
import static android.view.inputmethod.InputMethodEditorTraceProto.InputMethodClientsTraceProto.ClientSideProto.DISPLAY_ID;
|
||||
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_METHOD_MANAGER;
|
||||
import static android.view.inputmethod.InputMethodEditorTraceProto.InputMethodClientsTraceProto.ClientSideProto.VIEW_ROOT_IMPL;
|
||||
import static android.view.inputmethod.InputMethodManagerProto.ACTIVE;
|
||||
@@ -998,9 +999,9 @@ public final class InputMethodManager {
|
||||
private final InputMethodManager mParentInputMethodManager;
|
||||
private final WeakReference<View> mServedView;
|
||||
|
||||
ControlledInputConnectionWrapper(Looper mainLooper, InputConnection conn,
|
||||
ControlledInputConnectionWrapper(Looper icLooper, InputConnection conn,
|
||||
InputMethodManager inputMethodManager, View servedView) {
|
||||
super(mainLooper, conn);
|
||||
super(icLooper, conn);
|
||||
mParentInputMethodManager = inputMethodManager;
|
||||
mServedView = new WeakReference<>(servedView);
|
||||
}
|
||||
@@ -1046,6 +1047,18 @@ public final class InputMethodManager {
|
||||
+ " mServedView=" + mServedView.get()
|
||||
+ "}";
|
||||
}
|
||||
|
||||
void dumpDebug(ProtoOutputStream proto, long fieldId) {
|
||||
// Check that the call is initiated in the main thread of the current InputConnection
|
||||
// {@link InputConnection#getHandler} since the messages to IInputConnectionWrapper are
|
||||
// executed on this thread. Otherwise the messages are dispatched to the correct thread
|
||||
// in IInputConnectionWrapper, but this is not wanted while dumpng, for performance
|
||||
// reasons.
|
||||
if (getInputConnection() instanceof DumpableInputConnection && Looper.myLooper()
|
||||
== getLooper()) {
|
||||
((DumpableInputConnection) getInputConnection()).dumpDebug(proto, fieldId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class ImeThreadFactory implements ThreadFactory {
|
||||
@@ -2207,6 +2220,7 @@ public final class InputMethodManager {
|
||||
* @hide
|
||||
*/
|
||||
public void notifyImeHidden(IBinder windowToken) {
|
||||
ImeTracing.getInstance().triggerClientDump("InputMethodManager#notifyImeHidden", this);
|
||||
synchronized (mH) {
|
||||
try {
|
||||
if (mCurMethod != null && mCurRootView != null
|
||||
@@ -3312,6 +3326,9 @@ public final class InputMethodManager {
|
||||
if (mImeInsetsConsumer != null) {
|
||||
mImeInsetsConsumer.dumpDebug(proto, IME_INSETS_SOURCE_CONSUMER);
|
||||
}
|
||||
if (mServedInputConnectionWrapper != null) {
|
||||
mServedInputConnectionWrapper.dumpDebug(proto, INPUT_CONNECTION);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,6 +111,12 @@ public abstract class IInputConnectionWrapper extends IInputContext.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
protected Looper getLooper() {
|
||||
synchronized (mMainLooper) {
|
||||
return mMainLooper;
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean isFinished() {
|
||||
synchronized (mLock) {
|
||||
return mFinished;
|
||||
|
||||
@@ -16,21 +16,36 @@
|
||||
|
||||
package com.android.internal.widget;
|
||||
|
||||
import static android.view.inputmethod.InputConnectionProto.CURSOR_CAPS_MODE;
|
||||
import static android.view.inputmethod.InputConnectionProto.EDITABLE_TEXT;
|
||||
import static android.view.inputmethod.InputConnectionProto.SELECTED_TEXT;
|
||||
import static android.view.inputmethod.InputConnectionProto.SELECTED_TEXT_END;
|
||||
import static android.view.inputmethod.InputConnectionProto.SELECTED_TEXT_START;
|
||||
|
||||
import android.compat.annotation.UnsupportedAppUsage;
|
||||
import android.os.Bundle;
|
||||
import android.text.Editable;
|
||||
import android.text.Selection;
|
||||
import android.text.method.KeyListener;
|
||||
import android.util.Log;
|
||||
import android.util.proto.ProtoOutputStream;
|
||||
import android.view.inputmethod.BaseInputConnection;
|
||||
import android.view.inputmethod.CompletionInfo;
|
||||
import android.view.inputmethod.CorrectionInfo;
|
||||
import android.view.inputmethod.DumpableInputConnection;
|
||||
import android.view.inputmethod.ExtractedText;
|
||||
import android.view.inputmethod.ExtractedTextRequest;
|
||||
import android.view.inputmethod.InputConnection;
|
||||
import android.widget.TextView;
|
||||
|
||||
public class EditableInputConnection extends BaseInputConnection {
|
||||
/**
|
||||
* Base class for an editable InputConnection instance. This is created by {@link TextView} or
|
||||
* {@link EditText}.
|
||||
*/
|
||||
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;
|
||||
@@ -222,4 +237,28 @@ public class EditableInputConnection extends BaseInputConnection {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dumpDebug(ProtoOutputStream proto, long fieldId) {
|
||||
final long token = proto.start(fieldId);
|
||||
CharSequence editableText = mTextView.getText();
|
||||
CharSequence selectedText = getSelectedText(0 /* flags */);
|
||||
if (DUMP_TEXT) {
|
||||
if (editableText != null) {
|
||||
proto.write(EDITABLE_TEXT, editableText.toString());
|
||||
}
|
||||
if (selectedText != null) {
|
||||
proto.write(SELECTED_TEXT, selectedText.toString());
|
||||
}
|
||||
}
|
||||
final Editable content = getEditable();
|
||||
if (content != null) {
|
||||
int start = Selection.getSelectionStart(content);
|
||||
int end = Selection.getSelectionEnd(content);
|
||||
proto.write(SELECTED_TEXT_START, start);
|
||||
proto.write(SELECTED_TEXT_END, end);
|
||||
}
|
||||
proto.write(CURSOR_CAPS_MODE, getCursorCapsMode(0));
|
||||
proto.end(token);
|
||||
}
|
||||
}
|
||||
|
||||
34
core/proto/android/view/inputmethod/inputconnection.proto
Normal file
34
core/proto/android/view/inputmethod/inputconnection.proto
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
syntax = "proto2";
|
||||
|
||||
import "frameworks/base/core/proto/android/privacy.proto";
|
||||
|
||||
package android.view.inputmethod;
|
||||
|
||||
option java_multiple_files = true;
|
||||
|
||||
/**
|
||||
* Represents a {@link android.view.inputmethod.InputConnection} object.
|
||||
*/
|
||||
message InputConnectionProto {
|
||||
optional string editable_text = 1 [(.android.privacy).dest = DEST_LOCAL];
|
||||
optional string selected_text = 2 [(.android.privacy).dest = DEST_LOCAL];
|
||||
optional int32 selected_text_start = 3;
|
||||
optional int32 selected_text_end = 4;
|
||||
optional int32 cursor_caps_mode = 5;
|
||||
}
|
||||
@@ -24,6 +24,7 @@ import "frameworks/base/core/proto/android/view/viewrootimpl.proto";
|
||||
import "frameworks/base/core/proto/android/view/insetscontroller.proto";
|
||||
import "frameworks/base/core/proto/android/view/imeinsetssourceconsumer.proto";
|
||||
import "frameworks/base/core/proto/android/view/inputmethod/editorinfo.proto";
|
||||
import "frameworks/base/core/proto/android/view/inputmethod/inputconnection.proto";
|
||||
import "frameworks/base/core/proto/android/view/imefocuscontroller.proto";
|
||||
|
||||
import "frameworks/base/core/proto/android/server/inputmethod/inputmethodmanagerservice.proto";
|
||||
@@ -70,6 +71,7 @@ message InputMethodClientsTraceProto {
|
||||
optional ImeInsetsSourceConsumerProto ime_insets_source_consumer = 5;
|
||||
optional EditorInfoProto editor_info = 6;
|
||||
optional ImeFocusControllerProto ime_focus_controller = 7;
|
||||
optional InputConnectionProto input_connection = 8;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user