Add proto-based InputMethodService and server side dumping for IME
This CL implements a mechanism to dump InputMethodService and IME
related server states into a proto file which can later be imported
to Winscope to allow easy debugging.
The Design Doc for the IME tracing project is: go/ime-tracing
Bug: 154348613
Test: start trace by calling "adb shell ime tracing start"
end trace by calling "adb shell ime tracing stop"
pull trace using "adb pull /data/misc/wmtrace/ime_trace.pb ime_trace.pb"
Change-Id: Icbfb8c11e882f29eb45dea9d4c23315c48e9d619
This commit is contained in:
committed by
Ioana Stefan
parent
48acf101c3
commit
5e68eeac86
@@ -193,7 +193,17 @@ public abstract class AbstractInputMethodService extends Service
|
||||
* needed for a new client of the input method.
|
||||
*/
|
||||
public abstract AbstractInputMethodSessionImpl onCreateInputMethodSessionInterface();
|
||||
|
||||
|
||||
/**
|
||||
* Dumps the internal state of IME to a protocol buffer output stream initialized using the
|
||||
* given {@link FileDescriptor}.
|
||||
*
|
||||
* @param fd The file descriptor to which proto dump should be written.
|
||||
* @param args The arguments passed to the dump method.
|
||||
* @hide
|
||||
*/
|
||||
abstract void dumpProtoInternal(FileDescriptor fd, String[] args);
|
||||
|
||||
/**
|
||||
* Implement this to handle {@link android.os.Binder#dump Binder.dump()}
|
||||
* calls on your input method.
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package android.inputmethodservice;
|
||||
|
||||
import static android.util.imetracing.ImeTracing.PROTO_ARG;
|
||||
|
||||
import android.annotation.BinderThread;
|
||||
import android.annotation.MainThread;
|
||||
import android.annotation.Nullable;
|
||||
@@ -37,8 +39,8 @@ import android.view.inputmethod.InputMethod;
|
||||
import android.view.inputmethod.InputMethodSession;
|
||||
import android.view.inputmethod.InputMethodSubtype;
|
||||
|
||||
import com.android.internal.inputmethod.IInputMethodPrivilegedOperations;
|
||||
import com.android.internal.inputmethod.CancellationGroup;
|
||||
import com.android.internal.inputmethod.IInputMethodPrivilegedOperations;
|
||||
import com.android.internal.os.HandlerCaller;
|
||||
import com.android.internal.os.SomeArgs;
|
||||
import com.android.internal.view.IInlineSuggestionsRequestCallback;
|
||||
@@ -155,9 +157,20 @@ class IInputMethodWrapper extends IInputMethod.Stub
|
||||
return;
|
||||
}
|
||||
SomeArgs args = (SomeArgs)msg.obj;
|
||||
String[] dumpArgs = (String[]) args.arg3;
|
||||
boolean protoDumpRequested = false;
|
||||
for (String arg : dumpArgs) {
|
||||
if (arg.equals(PROTO_ARG)) {
|
||||
protoDumpRequested = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
try {
|
||||
target.dump((FileDescriptor)args.arg1,
|
||||
(PrintWriter)args.arg2, (String[])args.arg3);
|
||||
if (protoDumpRequested) {
|
||||
target.dumpProtoInternal((FileDescriptor) args.arg1, dumpArgs);
|
||||
} else {
|
||||
target.dump((FileDescriptor) args.arg1, (PrintWriter) args.arg2, dumpArgs);
|
||||
}
|
||||
} catch (RuntimeException e) {
|
||||
((PrintWriter)args.arg2).println("Exception: " + e);
|
||||
}
|
||||
|
||||
@@ -17,6 +17,37 @@
|
||||
package android.inputmethodservice;
|
||||
|
||||
import static android.graphics.Color.TRANSPARENT;
|
||||
import static android.inputmethodservice.InputMethodServiceProto.CANDIDATES_VIEW_STARTED;
|
||||
import static android.inputmethodservice.InputMethodServiceProto.CANDIDATES_VISIBILITY;
|
||||
import static android.inputmethodservice.InputMethodServiceProto.CAN_PRE_RENDER;
|
||||
import static android.inputmethodservice.InputMethodServiceProto.CONFIGURATION;
|
||||
import static android.inputmethodservice.InputMethodServiceProto.DECOR_VIEW_VISIBLE;
|
||||
import static android.inputmethodservice.InputMethodServiceProto.DECOR_VIEW_WAS_VISIBLE;
|
||||
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_EDITOR_INFO;
|
||||
import static android.inputmethodservice.InputMethodServiceProto.INPUT_STARTED;
|
||||
import static android.inputmethodservice.InputMethodServiceProto.INPUT_VIEW_STARTED;
|
||||
import static android.inputmethodservice.InputMethodServiceProto.IN_SHOW_WINDOW;
|
||||
import static android.inputmethodservice.InputMethodServiceProto.IS_FULLSCREEN;
|
||||
import static android.inputmethodservice.InputMethodServiceProto.IS_INPUT_VIEW_SHOWN;
|
||||
import static android.inputmethodservice.InputMethodServiceProto.IS_PRE_RENDERED;
|
||||
import static android.inputmethodservice.InputMethodServiceProto.InsetsProto.CONTENT_TOP_INSETS;
|
||||
import static android.inputmethodservice.InputMethodServiceProto.InsetsProto.TOUCHABLE_INSETS;
|
||||
import static android.inputmethodservice.InputMethodServiceProto.InsetsProto.TOUCHABLE_REGION;
|
||||
import static android.inputmethodservice.InputMethodServiceProto.InsetsProto.VISIBLE_TOP_INSETS;
|
||||
import static android.inputmethodservice.InputMethodServiceProto.LAST_COMPUTED_INSETS;
|
||||
import static android.inputmethodservice.InputMethodServiceProto.LAST_SHOW_INPUT_REQUESTED;
|
||||
import static android.inputmethodservice.InputMethodServiceProto.SETTINGS_OBSERVER;
|
||||
import static android.inputmethodservice.InputMethodServiceProto.SHOW_INPUT_FLAGS;
|
||||
import static android.inputmethodservice.InputMethodServiceProto.SHOW_INPUT_REQUESTED;
|
||||
import static android.inputmethodservice.InputMethodServiceProto.SOFT_INPUT_WINDOW;
|
||||
import static android.inputmethodservice.InputMethodServiceProto.STATUS_ICON;
|
||||
import static android.inputmethodservice.InputMethodServiceProto.TOKEN;
|
||||
import static android.inputmethodservice.InputMethodServiceProto.VIEWS_CREATED;
|
||||
import static android.inputmethodservice.InputMethodServiceProto.WINDOW_VISIBLE;
|
||||
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
|
||||
import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
|
||||
import static android.view.WindowInsets.Type.navigationBars;
|
||||
@@ -59,6 +90,7 @@ import android.text.method.MovementMethod;
|
||||
import android.util.Log;
|
||||
import android.util.PrintWriterPrinter;
|
||||
import android.util.Printer;
|
||||
import android.util.proto.ProtoOutputStream;
|
||||
import android.view.Gravity;
|
||||
import android.view.KeyCharacterMap;
|
||||
import android.view.KeyEvent;
|
||||
@@ -104,6 +136,7 @@ import java.io.PrintWriter;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.Collections;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* InputMethodService provides a standard implementation of an InputMethod,
|
||||
@@ -1041,6 +1074,15 @@ public class InputMethodService extends AbstractInputMethodService {
|
||||
* or {@link #TOUCHABLE_INSETS_REGION}.
|
||||
*/
|
||||
public int touchableInsets;
|
||||
|
||||
private void dumpDebug(ProtoOutputStream proto, long fieldId) {
|
||||
final long token = proto.start(fieldId);
|
||||
proto.write(CONTENT_TOP_INSETS, contentTopInsets);
|
||||
proto.write(VISIBLE_TOP_INSETS, visibleTopInsets);
|
||||
proto.write(TOUCHABLE_INSETS, touchableInsets);
|
||||
proto.write(TOUCHABLE_REGION, touchableRegion.toString());
|
||||
proto.end(token);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1380,7 +1422,7 @@ public class InputMethodService extends AbstractInputMethodService {
|
||||
public AbstractInputMethodSessionImpl onCreateInputMethodSessionInterface() {
|
||||
return new InputMethodSessionImpl();
|
||||
}
|
||||
|
||||
|
||||
public LayoutInflater getLayoutInflater() {
|
||||
return mInflater;
|
||||
}
|
||||
@@ -3294,7 +3336,7 @@ public class InputMethodService extends AbstractInputMethodService {
|
||||
} else {
|
||||
p.println(" mInputEditorInfo: null");
|
||||
}
|
||||
|
||||
|
||||
p.println(" mShowInputRequested=" + mShowInputRequested
|
||||
+ " mLastShowInputRequested=" + mLastShowInputRequested
|
||||
+ " mCanPreRender=" + mCanPreRender
|
||||
@@ -3304,7 +3346,7 @@ public class InputMethodService extends AbstractInputMethodService {
|
||||
+ " mFullscreenApplied=" + mFullscreenApplied
|
||||
+ " mIsFullscreen=" + mIsFullscreen
|
||||
+ " mExtractViewHidden=" + mExtractViewHidden);
|
||||
|
||||
|
||||
if (mExtractedText != null) {
|
||||
p.println(" mExtractedText:");
|
||||
p.println(" text=" + mExtractedText.text.length() + " chars"
|
||||
@@ -3325,4 +3367,42 @@ public class InputMethodService extends AbstractInputMethodService {
|
||||
+ " touchableRegion=" + mTmpInsets.touchableRegion);
|
||||
p.println(" mSettingsObserver=" + mSettingsObserver);
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
@Override
|
||||
final void dumpProtoInternal(FileDescriptor fd, String[] args) {
|
||||
final ProtoOutputStream proto = new ProtoOutputStream(fd);
|
||||
mWindow.dumpDebug(proto, SOFT_INPUT_WINDOW);
|
||||
proto.write(VIEWS_CREATED, mViewsCreated);
|
||||
proto.write(DECOR_VIEW_VISIBLE, mDecorViewVisible);
|
||||
proto.write(DECOR_VIEW_WAS_VISIBLE, mDecorViewWasVisible);
|
||||
proto.write(WINDOW_VISIBLE, mWindowVisible);
|
||||
proto.write(IN_SHOW_WINDOW, mInShowWindow);
|
||||
proto.write(CONFIGURATION, getResources().getConfiguration().toString());
|
||||
proto.write(TOKEN, Objects.toString(mToken));
|
||||
proto.write(INPUT_BINDING, Objects.toString(mInputBinding));
|
||||
proto.write(INPUT_STARTED, mInputStarted);
|
||||
proto.write(INPUT_VIEW_STARTED, mInputViewStarted);
|
||||
proto.write(CANDIDATES_VIEW_STARTED, mCandidatesViewStarted);
|
||||
if (mInputEditorInfo != null) {
|
||||
mInputEditorInfo.dumpDebug(proto, INPUT_EDITOR_INFO);
|
||||
}
|
||||
proto.write(SHOW_INPUT_REQUESTED, mShowInputRequested);
|
||||
proto.write(LAST_SHOW_INPUT_REQUESTED, mLastShowInputRequested);
|
||||
proto.write(CAN_PRE_RENDER, mCanPreRender);
|
||||
proto.write(IS_PRE_RENDERED, mIsPreRendered);
|
||||
proto.write(SHOW_INPUT_FLAGS, mShowInputFlags);
|
||||
proto.write(CANDIDATES_VISIBILITY, mCandidatesVisibility);
|
||||
proto.write(FULLSCREEN_APPLIED, mFullscreenApplied);
|
||||
proto.write(IS_FULLSCREEN, mIsFullscreen);
|
||||
proto.write(EXTRACT_VIEW_HIDDEN, mExtractViewHidden);
|
||||
proto.write(EXTRACTED_TOKEN, mExtractedToken);
|
||||
proto.write(IS_INPUT_VIEW_SHOWN, mIsInputViewShown);
|
||||
proto.write(STATUS_ICON, mStatusIcon);
|
||||
mTmpInsets.dumpDebug(proto, LAST_COMPUTED_INSETS);
|
||||
proto.write(SETTINGS_OBSERVER, Objects.toString(mSettingsObserver));
|
||||
proto.flush();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,13 @@
|
||||
|
||||
package android.inputmethodservice;
|
||||
|
||||
import static android.inputmethodservice.SoftInputWindowProto.BOUNDS;
|
||||
import static android.inputmethodservice.SoftInputWindowProto.GRAVITY;
|
||||
import static android.inputmethodservice.SoftInputWindowProto.NAME;
|
||||
import static android.inputmethodservice.SoftInputWindowProto.TAKES_FOCUS;
|
||||
import static android.inputmethodservice.SoftInputWindowProto.WINDOW_STATE;
|
||||
import static android.inputmethodservice.SoftInputWindowProto.WINDOW_TYPE;
|
||||
|
||||
import static java.lang.annotation.RetentionPolicy.SOURCE;
|
||||
|
||||
import android.annotation.IntDef;
|
||||
@@ -25,6 +32,7 @@ import android.graphics.Rect;
|
||||
import android.os.Debug;
|
||||
import android.os.IBinder;
|
||||
import android.util.Log;
|
||||
import android.util.proto.ProtoOutputStream;
|
||||
import android.view.Gravity;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.MotionEvent;
|
||||
@@ -362,4 +370,15 @@ public class SoftInputWindow extends Dialog {
|
||||
throw new IllegalStateException("Unknown state=" + state);
|
||||
}
|
||||
}
|
||||
|
||||
void dumpDebug(ProtoOutputStream proto, long fieldId) {
|
||||
final long token = proto.start(fieldId);
|
||||
proto.write(NAME, mName);
|
||||
proto.write(WINDOW_TYPE, mWindowType);
|
||||
proto.write(GRAVITY, mGravity);
|
||||
proto.write(TAKES_FOCUS, mTakesFocus);
|
||||
mBounds.dumpDebug(proto, BOUNDS);
|
||||
proto.write(WINDOW_STATE, mWindowState);
|
||||
proto.end(token);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -188,7 +188,13 @@ public class InsetsSource implements Parcelable {
|
||||
return false;
|
||||
}
|
||||
|
||||
void dumpDebug(ProtoOutputStream proto, long fieldId) {
|
||||
/**
|
||||
* Export the state of {@link InsetsSource} into a protocol buffer output stream.
|
||||
*
|
||||
* @param proto Stream to write the state to
|
||||
* @param fieldId FieldId of InsetsSource as defined in the parent message
|
||||
*/
|
||||
public void dumpDebug(ProtoOutputStream proto, long fieldId) {
|
||||
final long token = proto.start(fieldId);
|
||||
proto.write(TYPE, InsetsState.typeToString(mType));
|
||||
mFrame.dumpDebug(proto, FRAME);
|
||||
|
||||
@@ -128,7 +128,13 @@ public class InsetsSourceControl implements Parcelable {
|
||||
}
|
||||
};
|
||||
|
||||
void dumpDebug(ProtoOutputStream proto, long fieldId) {
|
||||
/**
|
||||
* Export the state of {@link InsetsSourceControl} into a protocol buffer output stream.
|
||||
*
|
||||
* @param proto Stream to write the state to
|
||||
* @param fieldId FieldId of InsetsSource as defined in the parent message
|
||||
*/
|
||||
public void dumpDebug(ProtoOutputStream proto, long fieldId) {
|
||||
final long token = proto.start(fieldId);
|
||||
proto.write(TYPE, InsetsState.typeToString(mType));
|
||||
|
||||
|
||||
@@ -15,10 +15,36 @@
|
||||
|
||||
package com.android.server.inputmethod;
|
||||
|
||||
import static android.server.inputmethod.InputMethodManagerServiceProto.ACCESSIBILITY_REQUESTING_NO_SOFT_KEYBOARD;
|
||||
import static android.server.inputmethod.InputMethodManagerServiceProto.BACK_DISPOSITION;
|
||||
import static android.server.inputmethod.InputMethodManagerServiceProto.BOUND_TO_METHOD;
|
||||
import static android.server.inputmethod.InputMethodManagerServiceProto.CUR_ATTRIBUTE;
|
||||
import static android.server.inputmethod.InputMethodManagerServiceProto.CUR_CLIENT;
|
||||
import static android.server.inputmethod.InputMethodManagerServiceProto.CUR_FOCUSED_WINDOW_NAME;
|
||||
import static android.server.inputmethod.InputMethodManagerServiceProto.CUR_FOCUSED_WINDOW_SOFT_INPUT_MODE;
|
||||
import static android.server.inputmethod.InputMethodManagerServiceProto.CUR_ID;
|
||||
import static android.server.inputmethod.InputMethodManagerServiceProto.CUR_METHOD_ID;
|
||||
import static android.server.inputmethod.InputMethodManagerServiceProto.CUR_SEQ;
|
||||
import static android.server.inputmethod.InputMethodManagerServiceProto.CUR_TOKEN;
|
||||
import static android.server.inputmethod.InputMethodManagerServiceProto.CUR_TOKEN_DISPLAY_ID;
|
||||
import static android.server.inputmethod.InputMethodManagerServiceProto.HAVE_CONNECTION;
|
||||
import static android.server.inputmethod.InputMethodManagerServiceProto.IME_WINDOW_VISIBILITY;
|
||||
import static android.server.inputmethod.InputMethodManagerServiceProto.INPUT_SHOWN;
|
||||
import static android.server.inputmethod.InputMethodManagerServiceProto.IN_FULLSCREEN_MODE;
|
||||
import static android.server.inputmethod.InputMethodManagerServiceProto.IS_INTERACTIVE;
|
||||
import static android.server.inputmethod.InputMethodManagerServiceProto.LAST_IME_TARGET_WINDOW_NAME;
|
||||
import static android.server.inputmethod.InputMethodManagerServiceProto.LAST_SWITCH_USER_ID;
|
||||
import static android.server.inputmethod.InputMethodManagerServiceProto.SHOW_EXPLICITLY_REQUESTED;
|
||||
import static android.server.inputmethod.InputMethodManagerServiceProto.SHOW_FORCED;
|
||||
import static android.server.inputmethod.InputMethodManagerServiceProto.SHOW_IME_WITH_HARD_KEYBOARD;
|
||||
import static android.server.inputmethod.InputMethodManagerServiceProto.SHOW_REQUESTED;
|
||||
import static android.server.inputmethod.InputMethodManagerServiceProto.SYSTEM_READY;
|
||||
import static android.view.Display.DEFAULT_DISPLAY;
|
||||
import static android.view.Display.INVALID_DISPLAY;
|
||||
import static android.view.inputmethod.InputMethodEditorTraceProto.InputMethodEditorProto.CLIENTS;
|
||||
import static android.view.inputmethod.InputMethodEditorTraceProto.InputMethodEditorProto.ELAPSED_REALTIME_NANOS;
|
||||
import static android.view.inputmethod.InputMethodEditorTraceProto.InputMethodEditorProto.INPUT_METHOD_MANAGER_SERVICE;
|
||||
import static android.view.inputmethod.InputMethodEditorTraceProto.InputMethodEditorProto.INPUT_METHOD_SERVICE;
|
||||
import static android.view.inputmethod.InputMethodEditorTraceProto.InputMethodEditorTraceFileProto.ENTRY;
|
||||
|
||||
import static java.lang.annotation.RetentionPolicy.SOURCE;
|
||||
@@ -70,6 +96,7 @@ import android.os.Binder;
|
||||
import android.os.Bundle;
|
||||
import android.os.Debug;
|
||||
import android.os.Handler;
|
||||
import android.os.HandlerThread;
|
||||
import android.os.IBinder;
|
||||
import android.os.IInterface;
|
||||
import android.os.LocaleList;
|
||||
@@ -712,6 +739,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
|
||||
private final IPackageManager mIPackageManager;
|
||||
private final String mSlotIme;
|
||||
|
||||
private HandlerThread mTracingThread;
|
||||
|
||||
/**
|
||||
* Registered {@link InputMethodListListener}.
|
||||
* This variable can be accessed from both of MainThread and BinderThread.
|
||||
@@ -1683,6 +1712,9 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
|
||||
mSwitchingController = InputMethodSubtypeSwitchingController.createInstanceLocked(
|
||||
mSettings, context);
|
||||
mMenuController = new InputMethodMenuController(this);
|
||||
|
||||
mTracingThread = new HandlerThread("android.tracing", Process.THREAD_PRIORITY_BACKGROUND);
|
||||
mTracingThread.start();
|
||||
}
|
||||
|
||||
private void resetDefaultImeLocked(Context context) {
|
||||
@@ -3989,40 +4021,59 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
|
||||
*/
|
||||
@BinderThread
|
||||
@Override
|
||||
@GuardedBy("mMethodMap")
|
||||
public void startProtoDump(byte[] clientProtoDump) {
|
||||
if (!ImeTracing.getInstance().isAvailable() || !ImeTracing.getInstance().isEnabled()) {
|
||||
return;
|
||||
}
|
||||
if (clientProtoDump == null && mCurClient == null) {
|
||||
return;
|
||||
}
|
||||
mTracingThread.getThreadHandler().post(() -> {
|
||||
if (!ImeTracing.getInstance().isAvailable() || !ImeTracing.getInstance().isEnabled()) {
|
||||
return;
|
||||
}
|
||||
if (clientProtoDump == null && mCurClient == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
ProtoOutputStream proto = new ProtoOutputStream();
|
||||
final long token = proto.start(ENTRY);
|
||||
proto.write(ELAPSED_REALTIME_NANOS, SystemClock.elapsedRealtimeNanos());
|
||||
// TODO: get server side dump
|
||||
if (clientProtoDump != null) {
|
||||
proto.write(CLIENTS, clientProtoDump);
|
||||
} else {
|
||||
IBinder client = null;
|
||||
ProtoOutputStream proto = new ProtoOutputStream();
|
||||
final long token = proto.start(ENTRY);
|
||||
proto.write(ELAPSED_REALTIME_NANOS, SystemClock.elapsedRealtimeNanos());
|
||||
dumpDebug(proto, INPUT_METHOD_MANAGER_SERVICE);
|
||||
|
||||
IBinder service = null;
|
||||
synchronized (mMethodMap) {
|
||||
if (mCurClient != null && mCurClient.client != null) {
|
||||
client = mCurClient.client.asBinder();
|
||||
if (mCurMethod != null) {
|
||||
service = mCurMethod.asBinder();
|
||||
}
|
||||
}
|
||||
|
||||
if (client != null) {
|
||||
if (service != null) {
|
||||
try {
|
||||
proto.write(CLIENTS,
|
||||
TransferPipe.dumpAsync(client, ImeTracing.PROTO_ARG));
|
||||
proto.write(INPUT_METHOD_SERVICE,
|
||||
TransferPipe.dumpAsync(service, ImeTracing.PROTO_ARG));
|
||||
} catch (IOException | RemoteException e) {
|
||||
Log.e(TAG, "Exception while collecting client side ime dump", e);
|
||||
Log.e(TAG, "Exception while collecting ime process dump", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
proto.end(token);
|
||||
ImeTracing.getInstance().addToBuffer(proto);
|
||||
|
||||
if (clientProtoDump != null) {
|
||||
proto.write(CLIENTS, clientProtoDump);
|
||||
} else {
|
||||
IBinder client = null;
|
||||
synchronized (mMethodMap) {
|
||||
if (mCurClient != null && mCurClient.client != null) {
|
||||
client = mCurClient.client.asBinder();
|
||||
}
|
||||
}
|
||||
|
||||
if (client != null) {
|
||||
try {
|
||||
proto.write(CLIENTS,
|
||||
TransferPipe.dumpAsync(client, ImeTracing.PROTO_ARG));
|
||||
} catch (IOException | RemoteException e) {
|
||||
Log.e(TAG, "Exception while collecting client side ime dump", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
proto.end(token);
|
||||
ImeTracing.getInstance().addToBuffer(proto);
|
||||
});
|
||||
}
|
||||
|
||||
@BinderThread
|
||||
@@ -4031,6 +4082,44 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
|
||||
return ImeTracing.getInstance().isEnabled();
|
||||
}
|
||||
|
||||
@GuardedBy("mMethodMap")
|
||||
private void dumpDebug(ProtoOutputStream proto, long fieldId) {
|
||||
synchronized (mMethodMap) {
|
||||
final long token = proto.start(fieldId);
|
||||
proto.write(CUR_METHOD_ID, mCurMethodId);
|
||||
proto.write(CUR_SEQ, mCurSeq);
|
||||
proto.write(CUR_CLIENT, Objects.toString(mCurClient));
|
||||
proto.write(CUR_FOCUSED_WINDOW_NAME,
|
||||
mWindowManagerInternal.getWindowName(mCurFocusedWindow));
|
||||
proto.write(LAST_IME_TARGET_WINDOW_NAME,
|
||||
mWindowManagerInternal.getWindowName(mLastImeTargetWindow));
|
||||
proto.write(CUR_FOCUSED_WINDOW_SOFT_INPUT_MODE,
|
||||
InputMethodDebug.softInputModeToString(mCurFocusedWindowSoftInputMode));
|
||||
if (mCurAttribute != null) {
|
||||
mCurAttribute.dumpDebug(proto, CUR_ATTRIBUTE);
|
||||
}
|
||||
proto.write(CUR_ID, mCurId);
|
||||
proto.write(SHOW_REQUESTED, mShowRequested);
|
||||
proto.write(SHOW_EXPLICITLY_REQUESTED, mShowExplicitlyRequested);
|
||||
proto.write(SHOW_FORCED, mShowForced);
|
||||
proto.write(INPUT_SHOWN, mInputShown);
|
||||
proto.write(IN_FULLSCREEN_MODE, mInFullscreenMode);
|
||||
proto.write(CUR_TOKEN, Objects.toString(mCurToken));
|
||||
proto.write(CUR_TOKEN_DISPLAY_ID, mCurTokenDisplayId);
|
||||
proto.write(SYSTEM_READY, mSystemReady);
|
||||
proto.write(LAST_SWITCH_USER_ID, mLastSwitchUserId);
|
||||
proto.write(HAVE_CONNECTION, mHaveConnection);
|
||||
proto.write(BOUND_TO_METHOD, mBoundToMethod);
|
||||
proto.write(IS_INTERACTIVE, mIsInteractive);
|
||||
proto.write(BACK_DISPOSITION, mBackDisposition);
|
||||
proto.write(IME_WINDOW_VISIBILITY, mImeWindowVis);
|
||||
proto.write(SHOW_IME_WITH_HARD_KEYBOARD, mMenuController.getShowImeWithHardKeyboard());
|
||||
proto.write(ACCESSIBILITY_REQUESTING_NO_SOFT_KEYBOARD,
|
||||
mAccessibilityRequestingNoSoftKeyboard);
|
||||
proto.end(token);
|
||||
}
|
||||
}
|
||||
|
||||
@BinderThread
|
||||
private void notifyUserAction(@NonNull IBinder token) {
|
||||
if (DEBUG) {
|
||||
|
||||
@@ -280,6 +280,10 @@ public class InputMethodMenuController {
|
||||
return mSwitchingDialog;
|
||||
}
|
||||
|
||||
boolean getShowImeWithHardKeyboard() {
|
||||
return mShowImeWithHardKeyboard;
|
||||
}
|
||||
|
||||
boolean isisInputMethodPickerShownForTestLocked() {
|
||||
if (mSwitchingDialog == null) {
|
||||
return false;
|
||||
|
||||
@@ -90,7 +90,9 @@ import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_L
|
||||
import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
|
||||
import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_STACK;
|
||||
import static com.android.server.wm.DisplayContentProto.APP_TRANSITION;
|
||||
import static com.android.server.wm.DisplayContentProto.CAN_SHOW_IME;
|
||||
import static com.android.server.wm.DisplayContentProto.CLOSING_APPS;
|
||||
import static com.android.server.wm.DisplayContentProto.CURRENT_FOCUS;
|
||||
import static com.android.server.wm.DisplayContentProto.DISPLAY_FRAMES;
|
||||
import static com.android.server.wm.DisplayContentProto.DISPLAY_INFO;
|
||||
import static com.android.server.wm.DisplayContentProto.DISPLAY_READY;
|
||||
@@ -98,6 +100,10 @@ import static com.android.server.wm.DisplayContentProto.DPI;
|
||||
import static com.android.server.wm.DisplayContentProto.FOCUSED_APP;
|
||||
import static com.android.server.wm.DisplayContentProto.FOCUSED_ROOT_TASK_ID;
|
||||
import static com.android.server.wm.DisplayContentProto.ID;
|
||||
import static com.android.server.wm.DisplayContentProto.IME_INSETS_SOURCE_PROVIDER;
|
||||
import static com.android.server.wm.DisplayContentProto.INPUT_METHOD_CONTROL_TARGET;
|
||||
import static com.android.server.wm.DisplayContentProto.INPUT_METHOD_INPUT_TARGET;
|
||||
import static com.android.server.wm.DisplayContentProto.INPUT_METHOD_TARGET;
|
||||
import static com.android.server.wm.DisplayContentProto.OPENING_APPS;
|
||||
import static com.android.server.wm.DisplayContentProto.RESUMED_ACTIVITY;
|
||||
import static com.android.server.wm.DisplayContentProto.ROOT_DISPLAY_AREA;
|
||||
@@ -2864,7 +2870,26 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
|
||||
proto.write(FOCUSED_ROOT_TASK_ID, INVALID_TASK_ID);
|
||||
}
|
||||
proto.write(DISPLAY_READY, isReady());
|
||||
|
||||
if (mInputMethodTarget != null) {
|
||||
mInputMethodTarget.dumpDebug(proto, INPUT_METHOD_TARGET, logLevel);
|
||||
}
|
||||
if (mInputMethodInputTarget != null) {
|
||||
mInputMethodInputTarget.dumpDebug(proto, INPUT_METHOD_INPUT_TARGET, logLevel);
|
||||
}
|
||||
if (mInputMethodControlTarget != null
|
||||
&& mInputMethodControlTarget.getWindow() != null) {
|
||||
mInputMethodControlTarget.getWindow().dumpDebug(proto, INPUT_METHOD_CONTROL_TARGET,
|
||||
logLevel);
|
||||
}
|
||||
if (mCurrentFocus != null) {
|
||||
mCurrentFocus.dumpDebug(proto, CURRENT_FOCUS, logLevel);
|
||||
}
|
||||
if (mInsetsStateController != null
|
||||
&& mInsetsStateController.getImeSourceProvider() != null) {
|
||||
mInsetsStateController.getImeSourceProvider().dumpDebug(proto,
|
||||
IME_INSETS_SOURCE_PROVIDER, logLevel);
|
||||
}
|
||||
proto.write(CAN_SHOW_IME, canShowIme());
|
||||
proto.end(token);
|
||||
}
|
||||
|
||||
|
||||
@@ -16,9 +16,8 @@
|
||||
|
||||
package com.android.server.wm;
|
||||
|
||||
import static android.view.Surface.ROTATION_180;
|
||||
import static android.view.Surface.ROTATION_270;
|
||||
import static android.view.Surface.ROTATION_90;
|
||||
import static com.android.server.wm.DisplayFramesProto.CURRENT;
|
||||
import static com.android.server.wm.DisplayFramesProto.DOCK;
|
||||
import static com.android.server.wm.DisplayFramesProto.STABLE_BOUNDS;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
@@ -155,6 +154,8 @@ public class DisplayFrames {
|
||||
public void dumpDebug(ProtoOutputStream proto, long fieldId) {
|
||||
final long token = proto.start(fieldId);
|
||||
mStable.dumpDebug(proto, STABLE_BOUNDS);
|
||||
mDock.dumpDebug(proto, DOCK);
|
||||
mCurrent.dumpDebug(proto, CURRENT);
|
||||
proto.end(token);
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,11 @@
|
||||
package com.android.server.wm;
|
||||
|
||||
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_IME;
|
||||
import static com.android.server.wm.ImeInsetsSourceProviderProto.IME_TARGET_FROM_IME;
|
||||
import static com.android.server.wm.ImeInsetsSourceProviderProto.INSETS_SOURCE_PROVIDER;
|
||||
import static com.android.server.wm.ImeInsetsSourceProviderProto.IS_IME_LAYOUT_DRAWN;
|
||||
|
||||
import android.util.proto.ProtoOutputStream;
|
||||
import android.view.InsetsSource;
|
||||
import android.view.WindowInsets;
|
||||
|
||||
@@ -154,4 +158,15 @@ class ImeInsetsSourceProvider extends InsetsSourceProvider {
|
||||
pw.println();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
void dumpDebug(ProtoOutputStream proto, long fieldId, @WindowTraceLogLevel int logLevel) {
|
||||
final long token = proto.start(fieldId);
|
||||
super.dumpDebug(proto, INSETS_SOURCE_PROVIDER, logLevel);
|
||||
if (mImeTargetFromIme != null) {
|
||||
mImeTargetFromIme.getWindow().dumpDebug(proto, IME_TARGET_FROM_IME, logLevel);
|
||||
}
|
||||
proto.write(IS_IME_LAYOUT_DRAWN, mIsImeLayoutDrawn);
|
||||
proto.end(token);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,21 @@ import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
|
||||
import static android.view.InsetsState.ITYPE_STATUS_BAR;
|
||||
|
||||
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_IME;
|
||||
import static com.android.server.wm.InsetsSourceProviderProto.CAPTURED_LEASH;
|
||||
import static com.android.server.wm.InsetsSourceProviderProto.CLIENT_VISIBLE;
|
||||
import static com.android.server.wm.InsetsSourceProviderProto.CONTROL;
|
||||
import static com.android.server.wm.InsetsSourceProviderProto.CONTROLLABLE;
|
||||
import static com.android.server.wm.InsetsSourceProviderProto.CONTROL_TARGET;
|
||||
import static com.android.server.wm.InsetsSourceProviderProto.FAKE_CONTROL;
|
||||
import static com.android.server.wm.InsetsSourceProviderProto.FAKE_CONTROL_TARGET;
|
||||
import static com.android.server.wm.InsetsSourceProviderProto.FINISH_SEAMLESS_ROTATE_FRAME_NUMBER;
|
||||
import static com.android.server.wm.InsetsSourceProviderProto.FRAME;
|
||||
import static com.android.server.wm.InsetsSourceProviderProto.IME_OVERRIDDEN_FRAME;
|
||||
import static com.android.server.wm.InsetsSourceProviderProto.IS_LEASH_READY_FOR_DISPATCHING;
|
||||
import static com.android.server.wm.InsetsSourceProviderProto.PENDING_CONTROL_TARGET;
|
||||
import static com.android.server.wm.InsetsSourceProviderProto.SEAMLESS_ROTATING;
|
||||
import static com.android.server.wm.InsetsSourceProviderProto.SERVER_VISIBLE;
|
||||
import static com.android.server.wm.InsetsSourceProviderProto.SOURCE;
|
||||
import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_INSETS_CONTROL;
|
||||
import static com.android.server.wm.WindowManagerService.H.LAYOUT_AND_ASSIGN_WINDOW_LAYERS_IF_NEEDED;
|
||||
|
||||
@@ -452,6 +467,36 @@ class InsetsSourceProvider {
|
||||
}
|
||||
}
|
||||
|
||||
void dumpDebug(ProtoOutputStream proto, long fieldId, @WindowTraceLogLevel int logLevel) {
|
||||
final long token = proto.start(fieldId);
|
||||
mSource.dumpDebug(proto, SOURCE);
|
||||
mTmpRect.dumpDebug(proto, FRAME);
|
||||
mFakeControl.dumpDebug(proto, FAKE_CONTROL);
|
||||
if (mControl != null) {
|
||||
mControl.dumpDebug(proto, CONTROL);
|
||||
}
|
||||
if (mControlTarget != null && mControlTarget.getWindow() != null) {
|
||||
mControlTarget.getWindow().dumpDebug(proto, CONTROL_TARGET, logLevel);
|
||||
}
|
||||
if (mPendingControlTarget != null && mPendingControlTarget.getWindow() != null) {
|
||||
mPendingControlTarget.getWindow().dumpDebug(proto, PENDING_CONTROL_TARGET, logLevel);
|
||||
}
|
||||
if (mFakeControlTarget != null && mFakeControlTarget.getWindow() != null) {
|
||||
mFakeControlTarget.getWindow().dumpDebug(proto, FAKE_CONTROL_TARGET, logLevel);
|
||||
}
|
||||
if (mAdapter != null && mAdapter.mCapturedLeash != null) {
|
||||
mAdapter.mCapturedLeash.dumpDebug(proto, CAPTURED_LEASH);
|
||||
}
|
||||
mImeOverrideFrame.dumpDebug(proto, IME_OVERRIDDEN_FRAME);
|
||||
proto.write(IS_LEASH_READY_FOR_DISPATCHING, mIsLeashReadyForDispatching);
|
||||
proto.write(CLIENT_VISIBLE, mClientVisible);
|
||||
proto.write(SERVER_VISIBLE, mServerVisible);
|
||||
proto.write(SEAMLESS_ROTATING, mSeamlessRotating);
|
||||
proto.write(FINISH_SEAMLESS_ROTATE_FRAME_NUMBER, mFinishSeamlessRotateFrameNumber);
|
||||
proto.write(CONTROLLABLE, mControllable);
|
||||
proto.end(token);
|
||||
}
|
||||
|
||||
private class ControlAdapter implements AnimationAdapter {
|
||||
|
||||
private SurfaceControl mCapturedLeash;
|
||||
|
||||
@@ -120,6 +120,7 @@ import static com.android.server.wm.WindowManagerServiceDumpProto.DISPLAY_FROZEN
|
||||
import static com.android.server.wm.WindowManagerServiceDumpProto.FOCUSED_APP;
|
||||
import static com.android.server.wm.WindowManagerServiceDumpProto.FOCUSED_DISPLAY_ID;
|
||||
import static com.android.server.wm.WindowManagerServiceDumpProto.FOCUSED_WINDOW;
|
||||
import static com.android.server.wm.WindowManagerServiceDumpProto.HARD_KEYBOARD_AVAILABLE;
|
||||
import static com.android.server.wm.WindowManagerServiceDumpProto.INPUT_METHOD_WINDOW;
|
||||
import static com.android.server.wm.WindowManagerServiceDumpProto.LAST_ORIENTATION;
|
||||
import static com.android.server.wm.WindowManagerServiceDumpProto.POLICY;
|
||||
@@ -6000,6 +6001,7 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
proto.write(ROTATION, defaultDisplayContent.getRotation());
|
||||
proto.write(LAST_ORIENTATION, defaultDisplayContent.getLastOrientation());
|
||||
proto.write(FOCUSED_DISPLAY_ID, topFocusedDisplayContent.getDisplayId());
|
||||
proto.write(HARD_KEYBOARD_AVAILABLE, mHardKeyboardAvailable);
|
||||
}
|
||||
|
||||
private void dumpWindowsLocked(PrintWriter pw, boolean dumpAll,
|
||||
|
||||
Reference in New Issue
Block a user