diff --git a/core/java/android/inputmethodservice/AbstractInputMethodService.java b/core/java/android/inputmethodservice/AbstractInputMethodService.java index d7ca63a549879..3ca5207d867c1 100644 --- a/core/java/android/inputmethodservice/AbstractInputMethodService.java +++ b/core/java/android/inputmethodservice/AbstractInputMethodService.java @@ -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. diff --git a/core/java/android/inputmethodservice/IInputMethodWrapper.java b/core/java/android/inputmethodservice/IInputMethodWrapper.java index a298c856a0fba..0512305e71a20 100644 --- a/core/java/android/inputmethodservice/IInputMethodWrapper.java +++ b/core/java/android/inputmethodservice/IInputMethodWrapper.java @@ -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); } diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java index d62d1e1e57754..78cc71a782a59 100644 --- a/core/java/android/inputmethodservice/InputMethodService.java +++ b/core/java/android/inputmethodservice/InputMethodService.java @@ -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(); + } } diff --git a/core/java/android/inputmethodservice/SoftInputWindow.java b/core/java/android/inputmethodservice/SoftInputWindow.java index 6efd03c44b9f9..bc0b37ed626d4 100644 --- a/core/java/android/inputmethodservice/SoftInputWindow.java +++ b/core/java/android/inputmethodservice/SoftInputWindow.java @@ -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); + } } diff --git a/core/java/android/view/InsetsSource.java b/core/java/android/view/InsetsSource.java index 41cc8459a266f..ec54007e99793 100644 --- a/core/java/android/view/InsetsSource.java +++ b/core/java/android/view/InsetsSource.java @@ -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); diff --git a/core/java/android/view/InsetsSourceControl.java b/core/java/android/view/InsetsSourceControl.java index b45bd3869f64a..5ddbd029f1134 100644 --- a/core/java/android/view/InsetsSourceControl.java +++ b/core/java/android/view/InsetsSourceControl.java @@ -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)); diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java index 4e735e228c12b..e7e5f9de095fe 100644 --- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java +++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java @@ -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) { diff --git a/services/core/java/com/android/server/inputmethod/InputMethodMenuController.java b/services/core/java/com/android/server/inputmethod/InputMethodMenuController.java index d94d78e7bbaf7..7b29e5bcebb85 100644 --- a/services/core/java/com/android/server/inputmethod/InputMethodMenuController.java +++ b/services/core/java/com/android/server/inputmethod/InputMethodMenuController.java @@ -280,6 +280,10 @@ public class InputMethodMenuController { return mSwitchingDialog; } + boolean getShowImeWithHardKeyboard() { + return mShowImeWithHardKeyboard; + } + boolean isisInputMethodPickerShownForTestLocked() { if (mSwitchingDialog == null) { return false; diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index 4b2c41ddecec9..c5b45c529daba 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -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); } diff --git a/services/core/java/com/android/server/wm/DisplayFrames.java b/services/core/java/com/android/server/wm/DisplayFrames.java index f8495b5abdf57..d67f3f967e66a 100644 --- a/services/core/java/com/android/server/wm/DisplayFrames.java +++ b/services/core/java/com/android/server/wm/DisplayFrames.java @@ -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); } diff --git a/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java b/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java index 1d8cdf7e773c9..0813b4f9efe0f 100644 --- a/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java +++ b/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java @@ -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); + } } diff --git a/services/core/java/com/android/server/wm/InsetsSourceProvider.java b/services/core/java/com/android/server/wm/InsetsSourceProvider.java index 5bed1862a6298..7defc5ddb3f44 100644 --- a/services/core/java/com/android/server/wm/InsetsSourceProvider.java +++ b/services/core/java/com/android/server/wm/InsetsSourceProvider.java @@ -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; diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 366cf945db82a..404cee435148d 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -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,