diff options
29 files changed, 513 insertions, 118 deletions
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java index da7997d6cc65..fe14d4570e9e 100644 --- a/core/java/android/inputmethodservice/InputMethodService.java +++ b/core/java/android/inputmethodservice/InputMethodService.java @@ -974,6 +974,11 @@ public class InputMethodService extends AbstractInputMethodService { : InputMethodManager.RESULT_UNCHANGED_HIDDEN), null); } Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); + if (android.view.inputmethod.Flags.refactorInsetsController()) { + // The hide request first finishes the animation and then proceeds to the server + // side, finally reaching here, marking this the end state. + ImeTracker.forLogging().onHidden(statsToken); + } } /** @@ -3104,6 +3109,13 @@ public class InputMethodService extends AbstractInputMethodService { ImeTracker.forLogging().onProgress(statsToken, ImeTracker.PHASE_IME_SHOW_WINDOW); + if (android.view.inputmethod.Flags.refactorInsetsController()) { + // The ImeInsetsSourceProvider need the statsToken when dispatching the control + // (whenever the IME has drawn and its window is visible). Therefore, sending the + // statsToken here first. + notifyPreImeWindowVisibilityChanged(true /* visible */, statsToken); + } + ImeTracing.getInstance().triggerServiceDump("InputMethodService#showWindow", mDumper, null /* icProto */); Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMS.showWindow"); @@ -3127,7 +3139,9 @@ public class InputMethodService extends AbstractInputMethodService { if (DEBUG) Log.v(TAG, "showWindow: draw decorView!"); mWindow.show(); mDecorViewWasVisible = true; - applyVisibilityInInsetsConsumerIfNecessary(true /* setVisible */, statsToken); + if (!android.view.inputmethod.Flags.refactorInsetsController()) { + applyVisibilityInInsetsConsumerIfNecessary(true /* setVisible */, statsToken); + } cancelImeSurfaceRemoval(); mInShowWindow = false; Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); @@ -3238,6 +3252,20 @@ public class InputMethodService extends AbstractInputMethodService { ? mCurShowInputToken : mCurHideInputToken, setVisible, statsToken); } + /** + * Notifies the ImeInsetsSourceProvider before the IME visibility changes. + * + * @param visible {@code true} if it became visible, {@code false} otherwise. + * @param statsToken the token tracking the current IME request. + */ + private void notifyPreImeWindowVisibilityChanged(boolean visible, + @NonNull ImeTracker.Token statsToken) { + final var viewRootImpl = getWindow().getWindow().getDecorView().getViewRootImpl(); + if (viewRootImpl != null) { + viewRootImpl.notifyImeVisibilityChanged(visible, statsToken); + } + } + private void finishViews(boolean finishingInput) { if (mInputViewStarted) { if (DEBUG) Log.v(TAG, "CALL: onFinishInputView"); @@ -3279,7 +3307,13 @@ public class InputMethodService extends AbstractInputMethodService { ImeTracing.getInstance().triggerServiceDump("InputMethodService#hideWindow", mDumper, null /* icProto */); setImeWindowStatus(0, mBackDisposition); - applyVisibilityInInsetsConsumerIfNecessary(false /* setVisible */, statsToken); + if (android.view.inputmethod.Flags.refactorInsetsController()) { + // The ImeInsetsSourceProvider need the statsToken when dispatching the control. We + // send the token here, so that another request in the provider can be cancelled. + notifyPreImeWindowVisibilityChanged(false /* visible */, statsToken); + } else { + applyVisibilityInInsetsConsumerIfNecessary(false /* setVisible */, statsToken); + } mWindowVisible = false; finishViews(false /* finishingInput */); if (mDecorViewVisible) { diff --git a/core/java/android/view/IWindowSession.aidl b/core/java/android/view/IWindowSession.aidl index 14407ca32388..762a302e8170 100644 --- a/core/java/android/view/IWindowSession.aidl +++ b/core/java/android/view/IWindowSession.aidl @@ -30,6 +30,7 @@ import android.view.IWindow; import android.view.IWindowId; import android.view.MotionEvent; import android.view.WindowManager; +import android.view.inputmethod.ImeTracker; import android.view.InsetsSourceControl; import android.view.InsetsState; import android.view.Surface; @@ -276,7 +277,8 @@ interface IWindowSession { /** * Updates the requested visible types of insets. */ - oneway void updateRequestedVisibleTypes(IWindow window, int requestedVisibleTypes); + oneway void updateRequestedVisibleTypes(IWindow window, int requestedVisibleTypes, + in @nullable ImeTracker.Token imeStatsToken); /** * Called when the system gesture exclusion has changed. @@ -369,4 +371,14 @@ interface IWindowSession { * @return {@code true} if the focus changes. Otherwise, {@code false}. */ boolean moveFocusToAdjacentWindow(IWindow fromWindow, int direction); + + /** + * Notifies the statsToken and IME visibility to the ImeInsetsSourceProvider. + * + * @param window The window that is used to get the ImeInsetsSourceProvider. + * @param visible {@code true} to make it visible, {@code false} to hide it. + * @param statsToken the token tracking the current IME request. + */ + oneway void notifyImeWindowVisibilityChangedFromClient(IWindow window, boolean visible, + in ImeTracker.Token statsToken); } diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java index f166b89a1d13..d83f34436b1b 100644 --- a/core/java/android/view/InsetsController.java +++ b/core/java/android/view/InsetsController.java @@ -121,8 +121,10 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation * The visibilities should be reported back to WM. * * @param types Bitwise flags of types requested visible. + * @param statsToken the token tracking the current IME request or {@code null} otherwise. */ - void updateRequestedVisibleTypes(@InsetsType int types); + void updateRequestedVisibleTypes(@InsetsType int types, + @Nullable ImeTracker.Token statsToken); /** * @return Whether the host has any callbacks it wants to synchronize the animations with. @@ -974,6 +976,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation int consumedControlCount = 0; final @InsetsType int[] showTypes = new int[1]; final @InsetsType int[] hideTypes = new int[1]; + ImeTracker.Token statsToken = null; // Ensure to update all existing source consumers for (int i = mSourceConsumers.size() - 1; i >= 0; i--) { @@ -988,6 +991,12 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation if (control != null) { controllableTypes |= control.getType(); consumedControlCount++; + + if (Flags.refactorInsetsController()) { + if (control.getId() == ID_IME) { + statsToken = control.getImeStatsToken(); + } + } } // control may be null, but we still need to update the control to null if it got @@ -1021,34 +1030,31 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation if (Flags.refactorInsetsController()) { if (mPendingImeControlRequest != null && getImeSourceConsumer().getControl() != null && getImeSourceConsumer().getControl().getLeash() != null) { - // TODO we need to pass the statsToken - handlePendingControlRequest(null); + handlePendingControlRequest(statsToken); } else { if (showTypes[0] != 0) { - applyAnimation(showTypes[0], true /* show */, false /* fromIme */, - null /* statsToken */); + applyAnimation(showTypes[0], true /* show */, false /* fromIme */, statsToken); } if (hideTypes[0] != 0) { - applyAnimation(hideTypes[0], false /* show */, false /* fromIme */, - null /* statsToken */); + applyAnimation(hideTypes[0], false /* show */, false /* fromIme */, statsToken); } } } else { if (showTypes[0] != 0) { - final var statsToken = + final var newStatsToken = (showTypes[0] & ime()) == 0 ? null : ImeTracker.forLogging().onStart( ImeTracker.TYPE_SHOW, ImeTracker.ORIGIN_CLIENT, SoftInputShowHideReason.CONTROLS_CHANGED, mHost.isHandlingPointerEvent() /* fromUser */); - applyAnimation(showTypes[0], true /* show */, false /* fromIme */, statsToken); + applyAnimation(showTypes[0], true /* show */, false /* fromIme */, newStatsToken); } if (hideTypes[0] != 0) { - final var statsToken = + final var newStatsToken = (hideTypes[0] & ime()) == 0 ? null : ImeTracker.forLogging().onStart( ImeTracker.TYPE_HIDE, ImeTracker.ORIGIN_CLIENT, SoftInputShowHideReason.CONTROLS_CHANGED, mHost.isHandlingPointerEvent() /* fromUser */); - applyAnimation(hideTypes[0], false /* show */, false /* fromIme */, statsToken); + applyAnimation(hideTypes[0], false /* show */, false /* fromIme */, newStatsToken); } } @@ -1065,7 +1071,9 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation } // InsetsSourceConsumer#setControl might change the requested visibility. - reportRequestedVisibleTypes(); + // TODO(b/353463205) check this: if the requestedVisibleTypes for the IME were already + // sent, the request would fail. Therefore, don't send the statsToken here. + reportRequestedVisibleTypes(null /* statsToken */); } @VisibleForTesting(visibility = PACKAGE) @@ -1176,6 +1184,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation } if (DEBUG) Log.d(TAG, "show typesReady: " + typesReady); if ((Flags.refactorInsetsController() || fromIme) && (typesReady & Type.ime()) != 0) { + // TODO(b/353463205) check if this is needed here ImeTracker.forLatency().onShown(statsToken, ActivityThread::currentApplication); } applyAnimation(typesReady, true /* show */, fromIme, statsToken); @@ -1243,6 +1252,8 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation // an animation again (mRequestedVisibleTypes are reported at the end of the IME // hide animation but set at the beginning) if ((mRequestedVisibleTypes & ime()) == 0) { + ImeTracker.forLogging().onCancelled(statsToken, + ImeTracker.PHASE_CLIENT_ALREADY_HIDDEN); continue; } } @@ -1346,7 +1357,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation // We are finishing setting the requested visible types. Report them to the server // and/or the app. - reportRequestedVisibleTypes(); + reportRequestedVisibleTypes(statsToken); } private void controlAnimationUncheckedInner(@InsetsType int types, @@ -1396,8 +1407,8 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation // Ime will not be contained in typesReady nor in controls, if we don't have a leash Pair<Integer, Integer> typesReadyPair = collectSourceControlsV2(types, controls); typesReady = typesReadyPair.first; - @InsetsType int typesWithoutLeash = typesReadyPair.second; if (animationType == ANIMATION_TYPE_USER) { + @InsetsType int typesWithoutLeash = typesReadyPair.second; // When using an app-driven animation, the IME won't have a leash (because the // window isn't created yet). If we have a control, but no leash, defers the // request until the leash gets created. @@ -1431,6 +1442,11 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation } // We need to wait until all types are ready if (typesReady != types) { + if (DEBUG) { + Log.d(TAG, TextUtils.formatSimple( + "not all types are ready yet, waiting. typesReady: %s, types: %s", + typesReady, types)); + } return; } } @@ -1728,9 +1744,13 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation } else { ImeTracker.forLogging().onProgress(statsToken, ImeTracker.PHASE_CLIENT_ANIMATION_FINISHED_HIDE); - ImeTracker.forLogging().onHidden(statsToken); + // The requestedVisibleTypes are only send at the end of the hide animation. + // Therefore, the requested is not finished at this point. + if (!Flags.refactorInsetsController()) { + ImeTracker.forLogging().onHidden(statsToken); + } } - reportRequestedVisibleTypes(); + reportRequestedVisibleTypes(shown ? null : runner.getStatsToken()); } @Override @@ -1787,7 +1807,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation if (mHost != null) { // if the (hide) animation is cancelled, the // requestedVisibleTypes should be reported at this point. - reportRequestedVisibleTypes(); + reportRequestedVisibleTypes(control.getStatsToken()); mHost.getInputMethodManager().removeImeSurface( mHost.getWindowToken()); } @@ -1923,8 +1943,10 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation /** * Called when finishing setting requested visible types or finishing setting controls. + * + * @param statsToken the token tracking the current IME request or {@code null} otherwise. */ - private void reportRequestedVisibleTypes() { + private void reportRequestedVisibleTypes(@Nullable ImeTracker.Token statsToken) { final @InsetsType int typesToReport; if (Flags.refactorInsetsController()) { // If the IME is currently animating out, it is still visible, therefore we only @@ -1941,8 +1963,23 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation if (WindowInsets.Type.hasCompatSystemBars(diff)) { mCompatSysUiVisibilityStaled = true; } + if (Flags.refactorInsetsController()) { + ImeTracker.forLogging().onProgress(statsToken, + ImeTracker.PHASE_CLIENT_REPORT_REQUESTED_VISIBLE_TYPES); + } mReportedRequestedVisibleTypes = mRequestedVisibleTypes; - mHost.updateRequestedVisibleTypes(mReportedRequestedVisibleTypes); + mHost.updateRequestedVisibleTypes(mReportedRequestedVisibleTypes, statsToken); + } else if (Flags.refactorInsetsController()) { + if ((typesToReport & ime()) != 0 && mImeSourceConsumer != null) { + InsetsSourceControl control = mImeSourceConsumer.getControl(); + if (control != null && control.getLeash() == null) { + // If the IME was requested twice, and we didn't receive the controls + // yet, this request will not continue. It should be cancelled here, as + // it would time out otherwise. + ImeTracker.forLogging().onCancelled(statsToken, + ImeTracker.PHASE_CLIENT_REPORT_REQUESTED_VISIBLE_TYPES); + } + } } updateCompatSysUiVisibility(); } diff --git a/core/java/android/view/InsetsSourceControl.java b/core/java/android/view/InsetsSourceControl.java index 2efa647d3169..78773529294a 100644 --- a/core/java/android/view/InsetsSourceControl.java +++ b/core/java/android/view/InsetsSourceControl.java @@ -31,6 +31,7 @@ import android.os.Parcel; import android.os.Parcelable; import android.util.proto.ProtoOutputStream; import android.view.WindowInsets.Type.InsetsType; +import android.view.inputmethod.ImeTracker; import java.io.PrintWriter; import java.util.Arrays; @@ -56,6 +57,9 @@ public class InsetsSourceControl implements Parcelable { private boolean mSkipAnimationOnce; private int mParcelableFlags; + /** The token tracking the current IME request */ + private @Nullable ImeTracker.Token mImeStatsToken; + public InsetsSourceControl(int id, @InsetsType int type, @Nullable SurfaceControl leash, boolean initiallyVisible, Point surfacePosition, Insets insetsHint) { mId = id; @@ -78,6 +82,7 @@ public class InsetsSourceControl implements Parcelable { mSurfacePosition = new Point(other.mSurfacePosition); mInsetsHint = other.mInsetsHint; mSkipAnimationOnce = other.getAndClearSkipAnimationOnce(); + mImeStatsToken = other.getImeStatsToken(); } public InsetsSourceControl(Parcel in) { @@ -88,6 +93,7 @@ public class InsetsSourceControl implements Parcelable { mSurfacePosition = in.readTypedObject(Point.CREATOR); mInsetsHint = in.readTypedObject(Insets.CREATOR); mSkipAnimationOnce = in.readBoolean(); + mImeStatsToken = in.readTypedObject(ImeTracker.Token.CREATOR); } public int getId() { @@ -153,6 +159,15 @@ public class InsetsSourceControl implements Parcelable { return result; } + @Nullable + public ImeTracker.Token getImeStatsToken() { + return mImeStatsToken; + } + + public void setImeStatsToken(@Nullable ImeTracker.Token imeStatsToken) { + mImeStatsToken = imeStatsToken; + } + public void setParcelableFlags(int parcelableFlags) { mParcelableFlags = parcelableFlags; } @@ -171,6 +186,7 @@ public class InsetsSourceControl implements Parcelable { dest.writeTypedObject(mSurfacePosition, mParcelableFlags); dest.writeTypedObject(mInsetsHint, mParcelableFlags); dest.writeBoolean(mSkipAnimationOnce); + dest.writeTypedObject(mImeStatsToken, mParcelableFlags); } public void release(Consumer<SurfaceControl> surfaceReleaseConsumer) { @@ -196,13 +212,14 @@ public class InsetsSourceControl implements Parcelable { && mInitiallyVisible == that.mInitiallyVisible && mSurfacePosition.equals(that.mSurfacePosition) && mInsetsHint.equals(that.mInsetsHint) - && mSkipAnimationOnce == that.mSkipAnimationOnce; + && mSkipAnimationOnce == that.mSkipAnimationOnce + && Objects.equals(mImeStatsToken, that.mImeStatsToken); } @Override public int hashCode() { return Objects.hash(mId, mType, mLeash, mInitiallyVisible, mSurfacePosition, mInsetsHint, - mSkipAnimationOnce); + mSkipAnimationOnce, mImeStatsToken); } @Override @@ -225,6 +242,7 @@ public class InsetsSourceControl implements Parcelable { pw.print(" mSurfacePosition="); pw.print(mSurfacePosition); pw.print(" mInsetsHint="); pw.print(mInsetsHint); pw.print(" mSkipAnimationOnce="); pw.print(mSkipAnimationOnce); + pw.print(" mImeStatsToken="); pw.print(mImeStatsToken); pw.println(); } diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 2f204f9b1be9..37d52206ff5c 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -10057,6 +10057,24 @@ public final class ViewRootImpl implements ViewParent, } /** + * Dispatches the statsToken and IME visibility to the ImeInsetsSourceProvider. + * + * @param visible {@code true} if it became visible, {@code false} otherwise. + * @param statsToken the token tracking the current IME request. + * + * @hide + */ + public void notifyImeVisibilityChanged(boolean visible, @NonNull ImeTracker.Token statsToken) { + ImeTracker.forLogging().onProgress(statsToken, + ImeTracker.PHASE_CLIENT_NOTIFY_IME_VISIBILITY_CHANGED); + try { + mWindowSession.notifyImeWindowVisibilityChangedFromClient(mWindow, visible, statsToken); + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + } + } + + /** * Represents a pending input event that is waiting in a queue. * * Input events are processed in serial order by the timestamp specified by diff --git a/core/java/android/view/ViewRootInsetsControllerHost.java b/core/java/android/view/ViewRootInsetsControllerHost.java index b66c59aae899..889acca4b8b1 100644 --- a/core/java/android/view/ViewRootInsetsControllerHost.java +++ b/core/java/android/view/ViewRootInsetsControllerHost.java @@ -19,12 +19,14 @@ package android.view; import static android.view.InsetsController.DEBUG; import android.annotation.NonNull; +import android.annotation.Nullable; import android.content.Context; import android.content.res.CompatibilityInfo; import android.os.Handler; import android.os.IBinder; import android.os.RemoteException; import android.util.Log; +import android.view.inputmethod.ImeTracker; import android.view.inputmethod.InputMethodManager; import java.util.List; @@ -151,10 +153,17 @@ public class ViewRootInsetsControllerHost implements InsetsController.Host { } @Override - public void updateRequestedVisibleTypes(@WindowInsets.Type.InsetsType int types) { + public void updateRequestedVisibleTypes(@WindowInsets.Type.InsetsType int types, + @Nullable ImeTracker.Token statsToken) { try { if (mViewRoot.mAdded) { - mViewRoot.mWindowSession.updateRequestedVisibleTypes(mViewRoot.mWindow, types); + ImeTracker.forLogging().onProgress(statsToken, + ImeTracker.PHASE_CLIENT_UPDATE_REQUESTED_VISIBLE_TYPES); + mViewRoot.mWindowSession.updateRequestedVisibleTypes(mViewRoot.mWindow, types, + statsToken); + } else { + ImeTracker.forLogging().onFailed(statsToken, + ImeTracker.PHASE_CLIENT_UPDATE_REQUESTED_VISIBLE_TYPES); } } catch (RemoteException e) { Log.e(TAG, "Failed to call insetsModified", e); diff --git a/core/java/android/view/WindowlessWindowManager.java b/core/java/android/view/WindowlessWindowManager.java index 78718586329e..0d027f107a02 100644 --- a/core/java/android/view/WindowlessWindowManager.java +++ b/core/java/android/view/WindowlessWindowManager.java @@ -30,6 +30,7 @@ import android.util.Log; import android.util.MergedConfiguration; import android.view.View.FocusDirection; import android.view.WindowInsets.Type.InsetsType; +import android.view.inputmethod.ImeTracker; import android.window.ClientWindowFrames; import android.window.InputTransferToken; import android.window.OnBackInvokedCallbackInfo; @@ -596,7 +597,7 @@ public class WindowlessWindowManager implements IWindowSession { @Override public void updateRequestedVisibleTypes(IWindow window, - @InsetsType int requestedVisibleTypes) { + @InsetsType int requestedVisibleTypes, @Nullable ImeTracker.Token imeStatsToken) { } @Override @@ -677,6 +678,11 @@ public class WindowlessWindowManager implements IWindowSession { return false; } + @Override + public void notifyImeWindowVisibilityChangedFromClient(IWindow window, boolean visible, + @NonNull ImeTracker.Token statsToken) { + } + void setParentInterface(@Nullable ISurfaceControlViewHostParent parentInterface) { IBinder oldInterface = mParentInterface == null ? null : mParentInterface.asBinder(); IBinder newInterface = parentInterface == null ? null : parentInterface.asBinder(); diff --git a/core/java/android/view/inputmethod/ImeTracker.java b/core/java/android/view/inputmethod/ImeTracker.java index edc99218c71e..b9751c8cab52 100644 --- a/core/java/android/view/inputmethod/ImeTracker.java +++ b/core/java/android/view/inputmethod/ImeTracker.java @@ -202,6 +202,24 @@ public interface ImeTracker { PHASE_IME_HIDE_WINDOW, PHASE_IME_PRIVILEGED_OPERATIONS, PHASE_SERVER_CURRENT_ACTIVE_IME, + PHASE_CLIENT_REPORT_REQUESTED_VISIBLE_TYPES, + PHASE_WM_SET_REMOTE_TARGET_IME_VISIBILITY, + PHASE_WM_POST_LAYOUT_NOTIFY_CONTROLS_CHANGED, + PHASE_CLIENT_HANDLE_DISPATCH_IME_VISIBILITY_CHANGED, + PHASE_CLIENT_NOTIFY_IME_VISIBILITY_CHANGED, + PHASE_CLIENT_UPDATE_REQUESTED_VISIBLE_TYPES, + PHASE_WM_REMOTE_INSETS_CONTROL_TARGET_SET_REQUESTED_VISIBILITY, + PHASE_WM_GET_CONTROL_WITH_LEASH, + PHASE_WM_UPDATE_REQUESTED_VISIBLE_TYPES, + PHASE_SERVER_SET_VISIBILITY_ON_FOCUSED_WINDOW, + PHASE_CLIENT_HANDLE_SET_IME_VISIBILITY, + PHASE_CLIENT_SET_IME_VISIBILITY, + PHASE_WM_DISPATCH_IME_REQUESTED_CHANGED, + PHASE_CLIENT_NO_ONGOING_USER_ANIMATION, + PHASE_WM_NOTIFY_IME_VISIBILITY_CHANGED_FROM_CLIENT, + PHASE_WM_POSTING_CHANGED_IME_VISIBILITY, + PHASE_WM_INVOKING_IME_REQUESTED_LISTENER, + PHASE_CLIENT_ALREADY_HIDDEN, }) @Retention(RetentionPolicy.SOURCE) @interface Phase {} @@ -351,6 +369,62 @@ public interface ImeTracker { /** Checked that the calling IME is the currently active IME. */ int PHASE_SERVER_CURRENT_ACTIVE_IME = ImeProtoEnums.PHASE_SERVER_CURRENT_ACTIVE_IME; + /** Reporting the new requested visible types. */ + int PHASE_CLIENT_REPORT_REQUESTED_VISIBLE_TYPES = + ImeProtoEnums.PHASE_CLIENT_REPORT_REQUESTED_VISIBLE_TYPES; + /** Setting the IME visibility for the RemoteInsetsControlTarget. */ + int PHASE_WM_SET_REMOTE_TARGET_IME_VISIBILITY = + ImeProtoEnums.PHASE_WM_SET_REMOTE_TARGET_IME_VISIBILITY; + /** IME has no insets pending and is server visible. Notify about changed controls. */ + int PHASE_WM_POST_LAYOUT_NOTIFY_CONTROLS_CHANGED = + ImeProtoEnums.PHASE_WM_POST_LAYOUT_NOTIFY_CONTROLS_CHANGED; + /** Handling the dispatch of the IME visibility change. */ + int PHASE_CLIENT_HANDLE_DISPATCH_IME_VISIBILITY_CHANGED = + ImeProtoEnums.PHASE_CLIENT_HANDLE_DISPATCH_IME_VISIBILITY_CHANGED; + /** Dispatching the IME visibility change. */ + int PHASE_CLIENT_NOTIFY_IME_VISIBILITY_CHANGED = + ImeProtoEnums.PHASE_CLIENT_NOTIFY_IME_VISIBILITY_CHANGED; + /** Updating the requested visible types. */ + int PHASE_CLIENT_UPDATE_REQUESTED_VISIBLE_TYPES = + ImeProtoEnums.PHASE_CLIENT_UPDATE_REQUESTED_VISIBLE_TYPES; + /** Reached the remote insets control target's setImeInputTargetRequestedVisibility method. */ + int PHASE_WM_REMOTE_INSETS_CONTROL_TARGET_SET_REQUESTED_VISIBILITY = + ImeProtoEnums.PHASE_WM_REMOTE_INSETS_CONTROL_TARGET_SET_REQUESTED_VISIBILITY; + /** Received a new insets source control with a leash. */ + int PHASE_WM_GET_CONTROL_WITH_LEASH = + ImeProtoEnums.PHASE_WM_GET_CONTROL_WITH_LEASH; + /** + * Updating the requested visible types in the WindowState and sending them to state + * controller. + */ + int PHASE_WM_UPDATE_REQUESTED_VISIBLE_TYPES = + ImeProtoEnums.PHASE_WM_UPDATE_REQUESTED_VISIBLE_TYPES; + /** Setting the requested IME visibility of a window. */ + int PHASE_SERVER_SET_VISIBILITY_ON_FOCUSED_WINDOW = + ImeProtoEnums.PHASE_SERVER_SET_VISIBILITY_ON_FOCUSED_WINDOW; + /** Reached the redirect of InputMethodManager to InsetsController show/hide. */ + int PHASE_CLIENT_HANDLE_SET_IME_VISIBILITY = + ImeProtoEnums.PHASE_CLIENT_HANDLE_SET_IME_VISIBILITY; + /** Reached the InputMethodManager Handler call to send the visibility. */ + int PHASE_CLIENT_SET_IME_VISIBILITY = ImeProtoEnums.PHASE_CLIENT_SET_IME_VISIBILITY; + /** Calling into the listener to show/hide the IME from the ImeInsetsSourceProvider. */ + int PHASE_WM_DISPATCH_IME_REQUESTED_CHANGED = + ImeProtoEnums.PHASE_WM_DISPATCH_IME_REQUESTED_CHANGED; + /** An ongoing user animation will not be interrupted by a IMM#showSoftInput. */ + int PHASE_CLIENT_NO_ONGOING_USER_ANIMATION = + ImeProtoEnums.PHASE_CLIENT_NO_ONGOING_USER_ANIMATION; + /** Dispatching the token to the ImeInsetsSourceProvider. */ + int PHASE_WM_NOTIFY_IME_VISIBILITY_CHANGED_FROM_CLIENT = + ImeProtoEnums.PHASE_WM_NOTIFY_IME_VISIBILITY_CHANGED_FROM_CLIENT; + /** Now posting the IME visibility to the WMS handler. */ + int PHASE_WM_POSTING_CHANGED_IME_VISIBILITY = + ImeProtoEnums.PHASE_WM_POSTING_CHANGED_IME_VISIBILITY; + /** Inside the WMS handler calling into the listener that calls into IMMS show/hide. */ + int PHASE_WM_INVOKING_IME_REQUESTED_LISTENER = + ImeProtoEnums.PHASE_WM_INVOKING_IME_REQUESTED_LISTENER; + /** IME is requested to be hidden, but already hidden. Don't hide to avoid another animation. */ + int PHASE_CLIENT_ALREADY_HIDDEN = ImeProtoEnums.PHASE_CLIENT_ALREADY_HIDDEN; + /** * Called when an IME request is started. * diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java index fed8eea97688..d40b72c0914f 100644 --- a/core/java/android/view/inputmethod/InputMethodManager.java +++ b/core/java/android/view/inputmethod/InputMethodManager.java @@ -1350,11 +1350,15 @@ public final class InputMethodManager { return; } case MSG_SET_VISIBILITY: - final boolean visible = msg.arg1 != 0; + final SomeArgs args = (SomeArgs) msg.obj; + final boolean visible = (boolean) args.arg1; + final ImeTracker.Token statsToken = (ImeTracker.Token) args.arg2; synchronized (mH) { if (mCurRootView != null) { final var insetsController = mCurRootView.getInsetsController(); if (insetsController != null) { + ImeTracker.forLogging().onProgress(statsToken, + ImeTracker.PHASE_CLIENT_HANDLE_SET_IME_VISIBILITY); if (visible) { insetsController.show(WindowInsets.Type.ime(), false /* fromIme */, null /* statsToken */); @@ -1363,6 +1367,9 @@ public final class InputMethodManager { false /* fromIme */, null /* statsToken */); } } + } else { + ImeTracker.forLogging().onFailed(statsToken, + ImeTracker.PHASE_CLIENT_HANDLE_SET_IME_VISIBILITY); } } break; @@ -1463,8 +1470,13 @@ public final class InputMethodManager { } @Override - public void setImeVisibility(boolean visible) { - mH.obtainMessage(MSG_SET_VISIBILITY, visible ? 1 : 0, 0).sendToTarget(); + public void setImeVisibility(boolean visible, @Nullable ImeTracker.Token statsToken) { + final SomeArgs args = SomeArgs.obtain(); + args.arg1 = visible; + args.arg2 = statsToken; + ImeTracker.forLogging().onProgress(statsToken, + ImeTracker.PHASE_CLIENT_SET_IME_VISIBILITY); + mH.obtainMessage(MSG_SET_VISIBILITY, args).sendToTarget(); } @Override @@ -2344,11 +2356,15 @@ public final class InputMethodManager { if (viewRootImpl != null && (viewRootImpl.getInsetsController().computeUserAnimatingTypes() & WindowInsets.Type.ime()) == 0) { + ImeTracker.forLogging().onProgress(statsToken, + ImeTracker.PHASE_CLIENT_NO_ONGOING_USER_ANIMATION); // TODO(b/322992891) handle case of SHOW_IMPLICIT viewRootImpl.getInsetsController().show(WindowInsets.Type.ime(), false /* fromIme */, statsToken); return true; } + ImeTracker.forLogging().onCancelled(statsToken, + ImeTracker.PHASE_CLIENT_NO_ONGOING_USER_ANIMATION); return false; } else { // Makes sure to call ImeInsetsSourceConsumer#onShowRequested on the UI thread. diff --git a/core/java/com/android/internal/inputmethod/IInputMethodClient.aidl b/core/java/com/android/internal/inputmethod/IInputMethodClient.aidl index 6a7fa99f1caf..6eb9d2e0c02e 100644 --- a/core/java/com/android/internal/inputmethod/IInputMethodClient.aidl +++ b/core/java/com/android/internal/inputmethod/IInputMethodClient.aidl @@ -16,6 +16,7 @@ package com.android.internal.inputmethod; +import android.view.inputmethod.ImeTracker; import com.android.internal.inputmethod.InputBindResult; /** @@ -30,7 +31,7 @@ oneway interface IInputMethodClient { void onUnbindAccessibilityService(int sequence, int id); void setActive(boolean active, boolean fullscreen); void setInteractive(boolean active, boolean fullscreen); - void setImeVisibility(boolean visible); + void setImeVisibility(boolean visible, in @nullable ImeTracker.Token statsToken); void scheduleStartInputIfNecessary(boolean fullscreen); void reportFullscreenMode(boolean fullscreen); void setImeTraceEnabled(boolean enabled); diff --git a/core/tests/coretests/src/android/view/InsetsControllerTest.java b/core/tests/coretests/src/android/view/InsetsControllerTest.java index ae7f465baa87..7bc0d2f2fcd3 100644 --- a/core/tests/coretests/src/android/view/InsetsControllerTest.java +++ b/core/tests/coretests/src/android/view/InsetsControllerTest.java @@ -56,6 +56,7 @@ import static org.mockito.Mockito.verify; import static java.util.concurrent.TimeUnit.SECONDS; import android.annotation.NonNull; +import android.annotation.Nullable; import android.content.Context; import android.graphics.Insets; import android.graphics.Point; @@ -1095,9 +1096,10 @@ public class InsetsControllerTest { } @Override - public void updateRequestedVisibleTypes(@InsetsType int requestedVisibleTypes) { + public void updateRequestedVisibleTypes(@InsetsType int requestedVisibleTypes, + @Nullable ImeTracker.Token statsToken) { mRequestedVisibleTypes = requestedVisibleTypes; - super.updateRequestedVisibleTypes(requestedVisibleTypes); + super.updateRequestedVisibleTypes(requestedVisibleTypes, statsToken); } public boolean isRequestedVisible(@InsetsType int types) { diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java index f4ac5f260fcd..4fbb5744b64b 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java @@ -344,8 +344,7 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged if (android.view.inputmethod.Flags.refactorInsetsController()) { if (pendingImeStartAnimation) { - startAnimation(true, true /* forceRestart */, - null /* statsToken */); + startAnimation(true, true /* forceRestart */); } } } @@ -398,8 +397,7 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged // already (e.g., when focussing an editText in activity B, while and editText in // activity A is focussed), we will not get a call of #insetsControlChanged, and // therefore have to start the show animation from here - startAnimation(mImeRequestedVisible /* show */, false /* forceRestart */, - null /* TODO statsToken */); + startAnimation(mImeRequestedVisible /* show */, false /* forceRestart */); } } @@ -436,16 +434,31 @@ public class DisplayImeController implements DisplayController.OnDisplaysChanged .navBarFrameHeight(); } + private void startAnimation(final boolean show, final boolean forceRestart) { + final var imeSource = mInsetsState.peekSource(InsetsSource.ID_IME); + if (imeSource == null || mImeSourceControl == null) { + return; + } + final var statsToken = mImeSourceControl.getImeStatsToken(); + + startAnimation(show, forceRestart, statsToken); + } + private void startAnimation(final boolean show, final boolean forceRestart, @SoftInputShowHideReason int reason) { final var imeSource = mInsetsState.peekSource(InsetsSource.ID_IME); if (imeSource == null || mImeSourceControl == null) { return; } - final var statsToken = ImeTracker.forLogging().onStart( - show ? ImeTracker.TYPE_SHOW : ImeTracker.TYPE_HIDE, ImeTracker.ORIGIN_WM_SHELL, - reason, false /* fromUser */); - + final ImeTracker.Token statsToken; + if (android.view.inputmethod.Flags.refactorInsetsController() + && mImeSourceControl.getImeStatsToken() != null) { + statsToken = mImeSourceControl.getImeStatsToken(); + } else { + statsToken = ImeTracker.forLogging().onStart( + show ? ImeTracker.TYPE_SHOW : ImeTracker.TYPE_HIDE, + ImeTracker.ORIGIN_WM_SHELL, reason, false /* fromUser */); + } startAnimation(show, forceRestart, statsToken); } diff --git a/services/core/java/com/android/server/inputmethod/DefaultImeVisibilityApplier.java b/services/core/java/com/android/server/inputmethod/DefaultImeVisibilityApplier.java index 7c93c8b80897..5c939bc14ec7 100644 --- a/services/core/java/com/android/server/inputmethod/DefaultImeVisibilityApplier.java +++ b/services/core/java/com/android/server/inputmethod/DefaultImeVisibilityApplier.java @@ -202,7 +202,7 @@ final class DefaultImeVisibilityApplier { break; case STATE_HIDE_IME_EXPLICIT: if (Flags.refactorInsetsController()) { - setImeVisibilityOnFocusedWindowClient(false, userId); + setImeVisibilityOnFocusedWindowClient(false, userId, statsToken); } else { mService.hideCurrentInputLocked(windowToken, statsToken, 0 /* flags */, null /* resultReceiver */, reason, userId); @@ -210,7 +210,7 @@ final class DefaultImeVisibilityApplier { break; case STATE_HIDE_IME_NOT_ALWAYS: if (Flags.refactorInsetsController()) { - setImeVisibilityOnFocusedWindowClient(false, userId); + setImeVisibilityOnFocusedWindowClient(false, userId, statsToken); } else { mService.hideCurrentInputLocked(windowToken, statsToken, InputMethodManager.HIDE_NOT_ALWAYS, null /* resultReceiver */, reason, @@ -221,7 +221,7 @@ final class DefaultImeVisibilityApplier { if (Flags.refactorInsetsController()) { // This can be triggered by IMMS#startInputOrWindowGainedFocus. We need to // set the requestedVisibleTypes in InsetsController first, before applying it. - setImeVisibilityOnFocusedWindowClient(true, userId); + setImeVisibilityOnFocusedWindowClient(true, userId, statsToken); } else { mService.showCurrentInputLocked(windowToken, statsToken, InputMethodManager.SHOW_IMPLICIT, MotionEvent.TOOL_TYPE_UNKNOWN, @@ -278,14 +278,17 @@ final class DefaultImeVisibilityApplier { } @GuardedBy("ImfLock.class") - private void setImeVisibilityOnFocusedWindowClient(boolean visibility, @UserIdInt int userId) { + private void setImeVisibilityOnFocusedWindowClient(boolean visibility, @UserIdInt int userId, + @NonNull ImeTracker.Token statsToken) { final var userData = mService.getUserData(userId); if (userData.mImeBindingState != null && userData.mImeBindingState.mFocusedWindowClient != null && userData.mImeBindingState.mFocusedWindowClient.mClient != null) { - userData.mImeBindingState.mFocusedWindowClient.mClient.setImeVisibility(visibility); + userData.mImeBindingState.mFocusedWindowClient.mClient.setImeVisibility(visibility, + statsToken); } else { - // TODO(b/329229469): ImeTracker? + ImeTracker.forLogging().onFailed(statsToken, + ImeTracker.PHASE_SERVER_SET_VISIBILITY_ON_FOCUSED_WINDOW); } } } diff --git a/services/core/java/com/android/server/inputmethod/IInputMethodClientInvoker.java b/services/core/java/com/android/server/inputmethod/IInputMethodClientInvoker.java index eada2882e410..650ea605d391 100644 --- a/services/core/java/com/android/server/inputmethod/IInputMethodClientInvoker.java +++ b/services/core/java/com/android/server/inputmethod/IInputMethodClientInvoker.java @@ -25,6 +25,7 @@ import android.os.Handler; import android.os.IBinder; import android.os.RemoteException; import android.util.Slog; +import android.view.inputmethod.ImeTracker; import com.android.internal.inputmethod.IInputMethodClient; import com.android.internal.inputmethod.InputBindResult; @@ -250,18 +251,18 @@ final class IInputMethodClientInvoker { } @AnyThread - void setImeVisibility(boolean visible) { + void setImeVisibility(boolean visible, @Nullable ImeTracker.Token statsToken) { if (mIsProxy) { - setImeVisibilityInternal(visible); + setImeVisibilityInternal(visible, statsToken); } else { - mHandler.post(() -> setImeVisibilityInternal(visible)); + mHandler.post(() -> setImeVisibilityInternal(visible, statsToken)); } } @AnyThread - private void setImeVisibilityInternal(boolean visible) { + private void setImeVisibilityInternal(boolean visible, @Nullable ImeTracker.Token statsToken) { try { - mTarget.setImeVisibility(visible); + mTarget.setImeVisibility(visible, statsToken); } catch (RemoteException e) { logRemoteException(e); } diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java index a9723ccc2576..f93e458c0283 100644 --- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java +++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java @@ -1429,12 +1429,12 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl. void registerImeRequestedChangedListener() { mWindowManagerInternal.setOnImeRequestedChangedListener( - (windowToken, imeVisible) -> { + (windowToken, imeVisible, statsToken) -> { if (Flags.refactorInsetsController()) { if (imeVisible) { - showCurrentInputInternal(windowToken); + showCurrentInputInternal(windowToken, statsToken); } else { - hideCurrentInputInternal(windowToken); + hideCurrentInputInternal(windowToken, statsToken); } } }); @@ -1887,7 +1887,12 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl. if (Flags.refactorInsetsController()) { if (isShowRequestedForCurrentWindow(userId) && userData.mImeBindingState != null && userData.mImeBindingState.mFocusedWindow != null) { - showCurrentInputInternal(userData.mImeBindingState.mFocusedWindow); + // Re-use current statsToken, if it exists. + final var statsToken = userData.mCurStatsToken != null ? userData.mCurStatsToken + : createStatsTokenForFocusedClient(true /* show */, + SoftInputShowHideReason.ATTACH_NEW_INPUT, userId); + userData.mCurStatsToken = null; + showCurrentInputInternal(userData.mImeBindingState.mFocusedWindow, statsToken); } } else { if (isShowRequestedForCurrentWindow(userId)) { @@ -3099,7 +3104,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl. && userData.mImeBindingState.mFocusedWindowClient != null && userData.mImeBindingState.mFocusedWindowClient.mClient != null) { userData.mImeBindingState.mFocusedWindowClient.mClient - .setImeVisibility(true); + .setImeVisibility(true, statsToken); if (resultReceiver != null) { resultReceiver.send( wasVisible ? InputMethodManager.RESULT_UNCHANGED_SHOWN @@ -3119,7 +3124,8 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl. } } - boolean showCurrentInputInternal(IBinder windowToken) { + // TODO(b/353463205) check callers to see if we can make statsToken @NonNull + boolean showCurrentInputInternal(IBinder windowToken, @Nullable ImeTracker.Token statsToken) { Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMMS.showCurrentInputInternal"); ImeTracing.getInstance().triggerManagerServiceDump( "InputMethodManagerService#showSoftInput", mDumper); @@ -3129,7 +3135,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl. final long ident = Binder.clearCallingIdentity(); try { if (DEBUG) Slog.v(TAG, "Client requesting input be shown"); - return showCurrentInputLocked(windowToken, null /* statsToken */, 0 /* flags */, + return showCurrentInputLocked(windowToken, statsToken, 0 /* flags */, 0 /* lastClickTooType */, null /* resultReceiver */, SoftInputShowHideReason.SHOW_SOFT_INPUT, userId); } finally { @@ -3139,7 +3145,8 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl. } } - boolean hideCurrentInputInternal(IBinder windowToken) { + // TODO(b/353463205) check callers to see if we can make statsToken @NonNull + boolean hideCurrentInputInternal(IBinder windowToken, @Nullable ImeTracker.Token statsToken) { Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMMS.hideCurrentInputInternal"); ImeTracing.getInstance().triggerManagerServiceDump( "InputMethodManagerService#hideSoftInput", mDumper); @@ -3149,7 +3156,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl. final long ident = Binder.clearCallingIdentity(); try { if (DEBUG) Slog.v(TAG, "Client requesting input be hidden"); - return hideCurrentInputLocked(windowToken, null /* statsToken */, 0 /* flags */, + return hideCurrentInputLocked(windowToken, statsToken, 0 /* flags */, null /* resultReceiver */, SoftInputShowHideReason.HIDE_SOFT_INPUT, userId); } finally { @@ -3536,7 +3543,7 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl. boolean wasVisible = isInputShownLocked(); // TODO add windowToken to interface userData.mImeBindingState.mFocusedWindowClient.mClient - .setImeVisibility(false); + .setImeVisibility(false, statsToken); if (resultReceiver != null) { resultReceiver.send(wasVisible ? InputMethodManager.RESULT_HIDDEN : InputMethodManager.RESULT_UNCHANGED_HIDDEN, null); @@ -4855,13 +4862,13 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl. final long ident = Binder.clearCallingIdentity(); try { if (Flags.refactorInsetsController()) { - userData.mCurClient.mClient.setImeVisibility(false); + userData.mCurClient.mClient.setImeVisibility(false, statsToken); // TODO we will loose the flags here if (userData.mImeBindingState != null && userData.mImeBindingState.mFocusedWindowClient != null && userData.mImeBindingState.mFocusedWindowClient.mClient != null) { userData.mImeBindingState.mFocusedWindowClient.mClient - .setImeVisibility(false); + .setImeVisibility(false, statsToken); } } else { hideCurrentInputLocked(mLastImeTargetWindow, statsToken, flags, @@ -4894,13 +4901,13 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl. final long ident = Binder.clearCallingIdentity(); try { if (Flags.refactorInsetsController()) { - userData.mCurClient.mClient.setImeVisibility(false); + userData.mCurClient.mClient.setImeVisibility(false, statsToken); // TODO we will loose the flags here if (userData.mImeBindingState != null && userData.mImeBindingState.mFocusedWindowClient != null && userData.mImeBindingState.mFocusedWindowClient.mClient != null) { userData.mImeBindingState.mFocusedWindowClient.mClient - .setImeVisibility(true); + .setImeVisibility(true, statsToken); } } else { showCurrentInputLocked(mLastImeTargetWindow, statsToken, flags, @@ -5074,7 +5081,8 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl. && userData.mImeBindingState.mFocusedWindowClient != null && userData.mImeBindingState.mFocusedWindowClient.mClient != null) { userData.mImeBindingState.mFocusedWindowClient.mClient - .setImeVisibility(false); + .setImeVisibility(false, + null /* TODO(b329229469) check statsToken */); } } else { @SoftInputShowHideReason final int reason = (int) msg.obj; @@ -6822,7 +6830,8 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl. && userData.mImeBindingState.mFocusedWindowClient.mClient != null) { userData.mImeBindingState.mFocusedWindowClient.mClient - .setImeVisibility(false); + .setImeVisibility(false, + null /* TODO(b329229469) initialize statsToken here? */); } else { // TODO(b329229469): ImeTracker? } diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index f22e654ac07e..1efb3ef144d9 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -7180,8 +7180,8 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp @Override public void setImeInputTargetRequestedVisibility(boolean visible) { if (android.view.inputmethod.Flags.refactorInsetsController()) { + // TODO(b/329229469) we won't have the statsToken in all cases, but should still log try { - // TODO stats token mRemoteInsetsController.setImeInputTargetRequestedVisibility(visible); } catch (RemoteException e) { Slog.w(TAG, "Failed to deliver setImeInputTargetRequestedVisibility", e); diff --git a/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java b/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java index 91c61b1bd550..4f4daa132859 100644 --- a/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java +++ b/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java @@ -89,6 +89,7 @@ final class ImeInsetsSourceProvider extends InsetsSourceProvider { @Override void onPostLayout() { + boolean wasServerVisible = mServerVisible; super.onPostLayout(); if (android.view.inputmethod.Flags.refactorInsetsController()) { @@ -101,11 +102,32 @@ final class ImeInsetsSourceProvider extends InsetsSourceProvider { // again, so that the control with leash can be eventually dispatched if (!mGivenInsetsReady && mServerVisible && !givenInsetsPending) { mGivenInsetsReady = true; + ImeTracker.forLogging().onProgress(mStatsToken, + ImeTracker.PHASE_WM_POST_LAYOUT_NOTIFY_CONTROLS_CHANGED); mStateController.notifyControlChanged(mControlTarget); + } else if (wasServerVisible && mServerVisible && mGivenInsetsReady + && givenInsetsPending) { + // If the server visibility didn't change (still visible), and mGivenInsetsReady + // is set, we won't call into notifyControlChanged. Therefore, we can reset the + // statsToken, if available. + ImeTracker.forLogging().onCancelled(mStatsToken, + ImeTracker.PHASE_WM_POST_LAYOUT_NOTIFY_CONTROLS_CHANGED); + mStatsToken = null; } } } + @Nullable + ImeTracker.Token getAndClearStatsToken() { + if (android.view.inputmethod.Flags.refactorInsetsController()) { + ImeTracker.Token statsToken = mStatsToken; + mStatsToken = null; + return statsToken; + } else { + return null; + } + } + @Override protected boolean isLeashReadyForDispatching() { if (android.view.inputmethod.Flags.refactorInsetsController()) { @@ -142,6 +164,14 @@ final class ImeInsetsSourceProvider extends InsetsSourceProvider { } control.setSkipAnimationOnce(startingData != null && startingData.hasImeSurface()); } + if (android.view.inputmethod.Flags.refactorInsetsController()) { + if (control != null && control.getLeash() != null) { + ImeTracker.Token statsToken = getAndClearStatsToken(); + ImeTracker.forLogging().onProgress(statsToken, + ImeTracker.PHASE_WM_GET_CONTROL_WITH_LEASH); + control.setImeStatsToken(statsToken); + } + } return control; } @@ -168,7 +198,7 @@ final class ImeInsetsSourceProvider extends InsetsSourceProvider { if (android.view.inputmethod.Flags.refactorInsetsController()) { if (!serverVisible && !mFrozen) { mGivenInsetsReady = false; - updateControlForTarget(mControlTarget, true /* force */); + updateControlForTarget(mControlTarget, true /* force */, null /* statsToken */); } } } @@ -214,22 +244,29 @@ final class ImeInsetsSourceProvider extends InsetsSourceProvider { } @Override - void updateControlForTarget(@Nullable InsetsControlTarget target, boolean force) { + void updateControlForTarget(@Nullable InsetsControlTarget target, boolean force, + @NonNull ImeTracker.Token statsToken) { if (target != null && target.getWindow() != null) { // ime control target could be a different window. // Refer WindowState#getImeControlTarget(). target = target.getWindow().getImeControlTarget(); } - super.updateControlForTarget(target, force); + // TODO(b/329229469) make sure that the statsToken of all callers is non-null (currently + // not the case) + super.updateControlForTarget(target, force, statsToken); if (Flags.refactorInsetsController()) { + // TODO(b/353463205) investigate if we should fail the statsToken, or if it's only + // temporary null. if (target != null) { - invokeOnImeRequestedChangedListener(target.getWindow()); + invokeOnImeRequestedChangedListener(target.getWindow(), statsToken); } } } + // TODO(b/353463205) change statsToken to be NonNull, after the flag is permanently enabled @Override - protected boolean updateClientVisibility(InsetsControlTarget caller) { + protected boolean updateClientVisibility(InsetsControlTarget caller, + @Nullable ImeTracker.Token statsToken) { InsetsControlTarget controlTarget = getControlTarget(); if (caller != controlTarget) { if (Flags.refactorInsetsController()) { @@ -240,6 +277,8 @@ final class ImeInsetsSourceProvider extends InsetsSourceProvider { // its new requested visibility for the IME boolean imeVisible = caller.isRequestedVisible(WindowInsets.Type.ime()); if (controlTarget != null) { + ImeTracker.forLogging().onProgress(statsToken, + ImeTracker.PHASE_WM_SET_REMOTE_TARGET_IME_VISIBILITY); controlTarget.setImeInputTargetRequestedVisibility(imeVisible); } else { // In case of a virtual display that cannot show the IME, the @@ -249,17 +288,24 @@ final class ImeInsetsSourceProvider extends InsetsSourceProvider { controlTarget = mDisplayContent.getImeHostOrFallback(caller.getWindow()); if (controlTarget != caller) { + ImeTracker.forLogging().onProgress(statsToken, + ImeTracker.PHASE_WM_SET_REMOTE_TARGET_IME_VISIBILITY); controlTarget.setImeInputTargetRequestedVisibility(imeVisible); + } else { + ImeTracker.forLogging().onFailed(statsToken, + ImeTracker.PHASE_WM_SET_REMOTE_TARGET_IME_VISIBILITY); } } WindowState windowState = caller.getWindow(); - invokeOnImeRequestedChangedListener(windowState); + invokeOnImeRequestedChangedListener(windowState, statsToken); + } else { + // TODO(b/353463205) add ImeTracker? } } return false; } - boolean changed = super.updateClientVisibility(caller); + boolean changed = super.updateClientVisibility(caller, statsToken); if (!Flags.refactorInsetsController()) { if (changed && caller.isRequestedVisible(mSource.getType())) { reportImeDrawnForOrganizerIfNeeded(caller); @@ -273,7 +319,11 @@ final class ImeInsetsSourceProvider extends InsetsSourceProvider { WindowState windowState = caller.getWindow() != null ? caller.getWindow() : ((mDisplayContent.getImeInputTarget() != null) ? mDisplayContent.getImeInputTarget().getWindowState() : null); - invokeOnImeRequestedChangedListener(windowState); + invokeOnImeRequestedChangedListener(windowState, statsToken); + } else { + // TODO(b/329229469) change phase and check cancelled / failed + ImeTracker.forLogging().onCancelled(statsToken, + ImeTracker.PHASE_CLIENT_REPORT_REQUESTED_VISIBLE_TYPES); } } return changed; @@ -288,22 +338,34 @@ final class ImeInsetsSourceProvider extends InsetsSourceProvider { // know about the new requestedVisibleTypes for the IME. if (imeControlTarget != null) { imeControlTarget.setImeInputTargetRequestedVisibility( - (targetWin.getRequestedVisibleTypes() - & WindowInsets.Type.ime()) != 0); + (targetWin.getRequestedVisibleTypes() & WindowInsets.Type.ime()) != 0); } } } } - private void invokeOnImeRequestedChangedListener(WindowState windowState) { + // TODO(b/353463205) check callers to see if we can make statsToken @NonNull + private void invokeOnImeRequestedChangedListener(WindowState windowState, + @Nullable ImeTracker.Token statsToken) { final var imeListener = mDisplayContent.mWmService.mOnImeRequestedChangedListener; if (imeListener != null) { if (windowState != null) { + ImeTracker.forLogging().onProgress(statsToken, + ImeTracker.PHASE_WM_POSTING_CHANGED_IME_VISIBILITY); mDisplayContent.mWmService.mH.post(() -> { + ImeTracker.forLogging().onProgress(statsToken, + ImeTracker.PHASE_WM_INVOKING_IME_REQUESTED_LISTENER); imeListener.onImeRequestedChanged(windowState.mClient.asBinder(), - windowState.isRequestedVisible(WindowInsets.Type.ime())); + windowState.isRequestedVisible(WindowInsets.Type.ime()), statsToken); }); + } else { + ImeTracker.forLogging().onFailed(statsToken, + ImeTracker.PHASE_WM_POSTING_CHANGED_IME_VISIBILITY); } + } else { + // TODO(b/353463205) We could combine the upper if's and remove the additional phase. + ImeTracker.forLogging().onFailed(statsToken, + ImeTracker.PHASE_WM_DISPATCH_IME_REQUESTED_CHANGED); } } @@ -399,9 +461,9 @@ final class ImeInsetsSourceProvider extends InsetsSourceProvider { // This can later become ready, so we don't want to cancel the pending request here. return; } + // TODO(b/329229469) check if this is still triggered, as we don't go into STATE_SHOW_IME + // (DefaultImeVisibilityApplier) if (android.view.inputmethod.Flags.refactorInsetsController()) { - // Clear token here so we don't report an error in abortShowImePostLayout(). - abortShowImePostLayout(); // The IME is drawn, so call into {@link WindowState#notifyInsetsControlChanged} // if we have a leash if (mControl != null && mControl.getLeash() != null @@ -517,6 +579,33 @@ final class ImeInsetsSourceProvider extends InsetsSourceProvider { } /** + * Sets the statsToken before the IMS was shown/hidden. + * @param visible {@code true} to make it visible, false to hide it. + * @param statsToken the token tracking the current IME request. + */ + void receiveImeStatsToken(boolean visible, + @NonNull ImeTracker.Token statsToken) { + if (!android.view.inputmethod.Flags.refactorInsetsController()) { + return; + } + + if (mStatsToken != null) { + // We have an ongoing show request will be cancelled by the newly received show + // request (cancelling the initial show) or hide request (aborting the initial show). + logIsScheduledAndReadyToShowIme(!visible /* aborted */); + } + if (visible) { + ImeTracker.forLogging().onCancelled( + mStatsToken, ImeTracker.PHASE_WM_ABORT_SHOW_IME_POST_LAYOUT); + mStatsToken = statsToken; + } else { + ImeTracker.forLogging().onFailed( + mStatsToken, ImeTracker.PHASE_WM_ABORT_SHOW_IME_POST_LAYOUT); + mStatsToken = null; + } + } + + /** * Logs the current state that can be checked by {@link #isScheduledAndReadyToShowIme}. * * @param aborted whether the scheduled show IME request was aborted or cancelled. diff --git a/services/core/java/com/android/server/wm/InsetsPolicy.java b/services/core/java/com/android/server/wm/InsetsPolicy.java index 6288a429af81..62bef743a354 100644 --- a/services/core/java/com/android/server/wm/InsetsPolicy.java +++ b/services/core/java/com/android/server/wm/InsetsPolicy.java @@ -47,6 +47,7 @@ import android.view.WindowInsets.Type.InsetsType; import android.view.WindowInsetsAnimation; import android.view.WindowInsetsAnimation.Bounds; import android.view.WindowManager; +import android.view.inputmethod.ImeTracker; import android.view.inputmethod.InputMethodManager; import com.android.internal.R; @@ -433,8 +434,9 @@ class InsetsPolicy { return originalState; } - void onRequestedVisibleTypesChanged(InsetsControlTarget caller) { - mStateController.onRequestedVisibleTypesChanged(caller); + void onRequestedVisibleTypesChanged(InsetsControlTarget caller, + @Nullable ImeTracker.Token statsToken) { + mStateController.onRequestedVisibleTypesChanged(caller, statsToken); checkAbortTransient(caller); updateBarControlTarget(mFocusedWin); } @@ -803,7 +805,8 @@ class InsetsPolicy { } @Override - public void updateRequestedVisibleTypes(int types) { } + public void updateRequestedVisibleTypes(int types, @Nullable ImeTracker.Token statsToken) { + } @Override public boolean hasAnimationCallbacks() { diff --git a/services/core/java/com/android/server/wm/InsetsSourceProvider.java b/services/core/java/com/android/server/wm/InsetsSourceProvider.java index 33dea54574e6..f5c92f60b26a 100644 --- a/services/core/java/com/android/server/wm/InsetsSourceProvider.java +++ b/services/core/java/com/android/server/wm/InsetsSourceProvider.java @@ -46,6 +46,7 @@ import android.view.InsetsSourceControl; import android.view.SurfaceControl; import android.view.SurfaceControl.Transaction; import android.view.WindowInsets; +import android.view.inputmethod.ImeTracker; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.protolog.ProtoLog; @@ -498,7 +499,8 @@ class InsetsSourceProvider { ); } - void updateControlForTarget(@Nullable InsetsControlTarget target, boolean force) { + void updateControlForTarget(@Nullable InsetsControlTarget target, boolean force, + @Nullable ImeTracker.Token statsToken) { if (mSeamlessRotating) { // We are un-rotating the window against the display rotation. We don't want the target // to control the window for now. @@ -570,7 +572,8 @@ class InsetsSourceProvider { mSeamlessRotating = false; } - boolean updateClientVisibility(InsetsControlTarget caller) { + boolean updateClientVisibility(InsetsControlTarget caller, + @Nullable ImeTracker.Token statsToken) { final boolean requestedVisible = caller.isRequestedVisible(mSource.getType()); if (caller != mControlTarget || requestedVisible == mClientVisible) { return false; diff --git a/services/core/java/com/android/server/wm/InsetsStateController.java b/services/core/java/com/android/server/wm/InsetsStateController.java index dcadb0f31085..9c2a8def4d56 100644 --- a/services/core/java/com/android/server/wm/InsetsStateController.java +++ b/services/core/java/com/android/server/wm/InsetsStateController.java @@ -40,6 +40,7 @@ import android.view.InsetsSourceControl; import android.view.InsetsState; import android.view.WindowInsets; import android.view.WindowInsets.Type.InsetsType; +import android.view.inputmethod.ImeTracker; import com.android.internal.protolog.ProtoLog; import com.android.server.inputmethod.InputMethodManagerInternal; @@ -216,10 +217,14 @@ class InsetsStateController { } } - void onRequestedVisibleTypesChanged(InsetsControlTarget caller) { + void onRequestedVisibleTypesChanged(InsetsControlTarget caller, + @Nullable ImeTracker.Token statsToken) { boolean changed = false; for (int i = mProviders.size() - 1; i >= 0; i--) { - changed |= mProviders.valueAt(i).updateClientVisibility(caller); + final InsetsSourceProvider provider = mProviders.valueAt(i); + final boolean isImeProvider = provider.getSource().getType() == WindowInsets.Type.ime(); + changed |= provider.updateClientVisibility(caller, + isImeProvider ? statsToken : null); } if (!android.view.inputmethod.Flags.refactorInsetsController()) { if (changed) { @@ -310,7 +315,9 @@ class InsetsStateController { // aborted. provider.updateFakeControlTarget(target); } else { - provider.updateControlForTarget(target, false /* force */); + // TODO(b/329229469) if the IME controlTarget changes, any pending requests should fail + provider.updateControlForTarget(target, false /* force */, + null /* TODO(b/329229469) check if needed here */); // Get control target again in case the provider didn't accept the one we passed to it. target = provider.getControlTarget(); @@ -394,7 +401,9 @@ class InsetsStateController { // to the clients, so that the clients can change the current visibilities to the // requested visibilities with animations. for (int i = newControlTargets.size() - 1; i >= 0; i--) { - onRequestedVisibleTypesChanged(newControlTargets.valueAt(i)); + // TODO(b/353463205) the statsToken shouldn't be null as it is used later in the + // IME provider. Check if we have to create a new request here + onRequestedVisibleTypesChanged(newControlTargets.valueAt(i), null /* statsToken */); } newControlTargets.clear(); if (!android.view.inputmethod.Flags.refactorInsetsController()) { diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java index cc95518cce39..32ec020580d9 100644 --- a/services/core/java/com/android/server/wm/Session.java +++ b/services/core/java/com/android/server/wm/Session.java @@ -37,6 +37,7 @@ import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; import static android.view.WindowManager.LayoutParams.isSystemAlertWindowType; +import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_IME; import static com.android.internal.protolog.ProtoLogGroup.WM_SHOW_TRANSACTIONS; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; @@ -78,6 +79,7 @@ import android.view.WindowInsets; import android.view.WindowInsets.Type.InsetsType; import android.view.WindowManager; import android.view.WindowRelayoutResult; +import android.view.inputmethod.ImeTracker; import android.window.InputTransferToken; import android.window.OnBackInvokedCallbackInfo; @@ -710,13 +712,20 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient { } @Override - public void updateRequestedVisibleTypes(IWindow window, @InsetsType int requestedVisibleTypes) { + public void updateRequestedVisibleTypes(IWindow window, @InsetsType int requestedVisibleTypes, + @Nullable ImeTracker.Token imeStatsToken) { synchronized (mService.mGlobalLock) { final WindowState win = mService.windowForClientLocked(this, window, false /* throwOnError */); if (win != null) { + ImeTracker.forLogging().onProgress(imeStatsToken, + ImeTracker.PHASE_WM_UPDATE_REQUESTED_VISIBLE_TYPES); win.setRequestedVisibleTypes(requestedVisibleTypes); - win.getDisplayContent().getInsetsPolicy().onRequestedVisibleTypesChanged(win); + win.getDisplayContent().getInsetsPolicy().onRequestedVisibleTypesChanged(win, + imeStatsToken); + } else { + ImeTracker.forLogging().onFailed(imeStatsToken, + ImeTracker.PHASE_WM_UPDATE_REQUESTED_VISIBLE_TYPES); } } } @@ -985,4 +994,28 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient { } } } + + @Override + public void notifyImeWindowVisibilityChangedFromClient(IWindow window, boolean visible, + @NonNull ImeTracker.Token statsToken) { + synchronized (mService.mGlobalLock) { + // TODO(b/353463205) check if we can use mService.getDefaultDisplayContentLocked() + // instead of window + final WindowState win = mService.windowForClientLocked(this, window, + false /* throwOnError */); + if (win != null) { + final InsetsStateController insetsStateController = + win.getDisplayContent().getInsetsStateController(); + ProtoLog.d(WM_DEBUG_IME, "notifyImeWindowVisibilityChangedFromClient: %s", + insetsStateController.getImeSourceProvider()); + ImeTracker.forLogging().onProgress(statsToken, + ImeTracker.PHASE_WM_NOTIFY_IME_VISIBILITY_CHANGED_FROM_CLIENT); + insetsStateController.getImeSourceProvider().receiveImeStatsToken(visible, + statsToken); + } else { + ImeTracker.forLogging().onFailed(statsToken, + ImeTracker.PHASE_WM_NOTIFY_IME_VISIBILITY_CHANGED_FROM_CLIENT); + } + } + } } diff --git a/services/core/java/com/android/server/wm/WindowManagerInternal.java b/services/core/java/com/android/server/wm/WindowManagerInternal.java index 50611331619b..8ae1cf0e0709 100644 --- a/services/core/java/com/android/server/wm/WindowManagerInternal.java +++ b/services/core/java/com/android/server/wm/WindowManagerInternal.java @@ -365,8 +365,10 @@ public abstract class WindowManagerInternal { * * @param windowToken The window token * @param imeVisible {@code true} if the IME should be shown, {@code false} to hide + * @param statsToken the token tracking the current IME request. */ - void onImeRequestedChanged(IBinder windowToken, boolean imeVisible); + void onImeRequestedChanged(IBinder windowToken, boolean imeVisible, + @Nullable ImeTracker.Token statsToken); } /** diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index f65eea0797bf..a21806819d80 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -4717,8 +4717,10 @@ public class WindowManagerService extends IWindowManager.Stub return; } dc.mRemoteInsetsControlTarget.setRequestedVisibleTypes(requestedVisibleTypes); + // TODO(b/353463205) the statsToken shouldn't be null as it is used later in the + // IME provider. Check if we have to create a new request here dc.getInsetsStateController().onRequestedVisibleTypesChanged( - dc.mRemoteInsetsControlTarget); + dc.mRemoteInsetsControlTarget, null /* statsToken */); } } finally { Binder.restoreCallingIdentity(origId); diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java index 24fc7ee0c392..421bbae6fb14 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java @@ -3354,7 +3354,8 @@ public class ActivityRecordTests extends WindowTestsBase { // app1 requests IME visible. app1.setRequestedVisibleTypes(ime(), ime()); - mDisplayContent.getInsetsStateController().onRequestedVisibleTypesChanged(app1); + mDisplayContent.getInsetsStateController().onRequestedVisibleTypesChanged(app1, + null /* statsToken */); // Verify app1's IME insets is visible and app2's IME insets frozen flag set. assertTrue(app1.getInsetsState().peekSource(ID_IME).isVisible()); @@ -3425,7 +3426,7 @@ public class ActivityRecordTests extends WindowTestsBase { assertFalse(activity2.mImeInsetsFrozenUntilStartInput); app1.setRequestedVisibleTypes(ime()); - controller.onRequestedVisibleTypesChanged(app1); + controller.onRequestedVisibleTypesChanged(app1, null /* statsToken */); // Expect all activities in split-screen will get IME insets visible state assertTrue(app1.getInsetsState().peekSource(ID_IME).isVisible()); diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java index c77a4d650bb5..caeb41c78967 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java @@ -554,7 +554,7 @@ public class DisplayPolicyTests extends WindowTestsBase { final DisplayPolicy displayPolicy = mDisplayContent.getDisplayPolicy(); displayPolicy.addWindowLw(mNavBarWindow, mNavBarWindow.mAttrs); final InsetsSourceProvider navBarProvider = mNavBarWindow.getControllableInsetProvider(); - navBarProvider.updateControlForTarget(mAppWindow, false); + navBarProvider.updateControlForTarget(mAppWindow, false, null /* statsToken */); navBarProvider.getSource().setVisible(false); displayPolicy.setCanSystemBarsBeShownByUser(false); @@ -579,7 +579,7 @@ public class DisplayPolicyTests extends WindowTestsBase { final DisplayPolicy displayPolicy = mDisplayContent.getDisplayPolicy(); displayPolicy.addWindowLw(mNavBarWindow, mNavBarWindow.mAttrs); final InsetsSourceProvider navBarProvider = mNavBarWindow.getControllableInsetProvider(); - navBarProvider.updateControlForTarget(win, false); + navBarProvider.updateControlForTarget(win, false, null /* statsToken */); navBarProvider.getSource().setVisible(false); displayPolicy.setCanSystemBarsBeShownByUser(true); diff --git a/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java b/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java index eeec54fdc99a..b26c267768a7 100644 --- a/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java @@ -361,7 +361,7 @@ public class InsetsPolicyTest extends WindowTestsBase { mAppWindow.setRequestedVisibleTypes( navigationBars() | statusBars(), navigationBars() | statusBars()); - policy.onRequestedVisibleTypesChanged(mAppWindow); + policy.onRequestedVisibleTypesChanged(mAppWindow, null /* statsToken */); waitUntilWindowAnimatorIdle(); controls = mDisplayContent.getInsetsStateController().getControlsForDispatch(mAppWindow); diff --git a/services/tests/wmtests/src/com/android/server/wm/InsetsSourceProviderTest.java b/services/tests/wmtests/src/com/android/server/wm/InsetsSourceProviderTest.java index 2a025cd721b0..619080770f1e 100644 --- a/services/tests/wmtests/src/com/android/server/wm/InsetsSourceProviderTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/InsetsSourceProviderTest.java @@ -112,13 +112,13 @@ public class InsetsSourceProviderTest extends WindowTestsBase { statusBar.getFrame().set(0, 0, 500, 100); // We must not have control or control target before we have the insets source window. - mProvider.updateControlForTarget(target, true /* force */); + mProvider.updateControlForTarget(target, true /* force */, null /* statsToken */); assertNull(mProvider.getControl(target)); assertNull(mProvider.getControlTarget()); // We can have the control or the control target after we have the insets source window. mProvider.setWindowContainer(statusBar, null, null); - mProvider.updateControlForTarget(target, false /* force */); + mProvider.updateControlForTarget(target, false /* force */, null /* statsToken */); assertNotNull(mProvider.getControl(target)); assertNotNull(mProvider.getControlTarget()); @@ -127,25 +127,25 @@ public class InsetsSourceProviderTest extends WindowTestsBase { mProvider.startSeamlessRotation(); assertNull(mProvider.getControl(target)); assertNull(mProvider.getControlTarget()); - mProvider.updateControlForTarget(target, true /* force */); + mProvider.updateControlForTarget(target, true /* force */, null /* statsToken */); assertNull(mProvider.getControl(target)); assertNull(mProvider.getControlTarget()); // We can have the control and the control target after seamless rotation. mProvider.finishSeamlessRotation(); - mProvider.updateControlForTarget(target, false /* force */); + mProvider.updateControlForTarget(target, false /* force */, null /* statsToken */); assertNotNull(mProvider.getControl(target)); assertNotNull(mProvider.getControlTarget()); // We can clear the control and the control target. - mProvider.updateControlForTarget(null, false /* force */); + mProvider.updateControlForTarget(null, false /* force */, null /* statsToken */); assertNull(mProvider.getControl(target)); assertNull(mProvider.getControlTarget()); // We must not have control or control target if the insets source window doesn't have a // surface. statusBar.setSurfaceControl(null); - mProvider.updateControlForTarget(target, true /* force */); + mProvider.updateControlForTarget(target, true /* force */, null /* statsToken */); assertNull(mProvider.getControl(target)); assertNull(mProvider.getControlTarget()); } @@ -173,7 +173,7 @@ public class InsetsSourceProviderTest extends WindowTestsBase { // We must not have control or control target before we have the insets source window, // so also no leash. - mProvider.updateControlForTarget(target, true /* force */); + mProvider.updateControlForTarget(target, true /* force */, null /* statsToken */); assertNull(mProvider.getControl(target)); assertNull(mProvider.getControlTarget()); assertNull(mProvider.getLeash(target)); @@ -181,7 +181,7 @@ public class InsetsSourceProviderTest extends WindowTestsBase { // We can have the control or the control target after we have the insets source window, // but no leash as this is not yet ready for dispatching. mProvider.setWindowContainer(statusBar, null, null); - mProvider.updateControlForTarget(target, false /* force */); + mProvider.updateControlForTarget(target, false /* force */, null /* statsToken */); assertNotNull(mProvider.getControl(target)); assertNotNull(mProvider.getControlTarget()); assertEquals(mProvider.getControlTarget(), target); @@ -265,9 +265,9 @@ public class InsetsSourceProviderTest extends WindowTestsBase { final WindowState target = createWindow(null, TYPE_APPLICATION, "target"); statusBar.getFrame().set(0, 0, 500, 100); mProvider.setWindowContainer(statusBar, null, null); - mProvider.updateControlForTarget(target, false /* force */); + mProvider.updateControlForTarget(target, false /* force */, null /* statsToken */); target.setRequestedVisibleTypes(0, statusBars()); - mProvider.updateClientVisibility(target); + mProvider.updateClientVisibility(target, null /* statsToken */); assertFalse(mSource.isVisible()); } @@ -278,7 +278,7 @@ public class InsetsSourceProviderTest extends WindowTestsBase { statusBar.getFrame().set(0, 0, 500, 100); mProvider.setWindowContainer(statusBar, null, null); target.setRequestedVisibleTypes(0, statusBars()); - mProvider.updateClientVisibility(target); + mProvider.updateClientVisibility(target, null /* statsToken */); assertTrue(mSource.isVisible()); } diff --git a/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java index c69faede7580..0dc56f8afc53 100644 --- a/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java @@ -201,7 +201,7 @@ public class InsetsStateControllerTest extends WindowTestsBase { .setWindowContainer(mImeWindow, null, null); getController().onImeControlTargetChanged(base); base.setRequestedVisibleTypes(ime(), ime()); - getController().onRequestedVisibleTypesChanged(base); + getController().onRequestedVisibleTypesChanged(base, null /* statsToken */); // Send our spy window (app) into the system so that we can detect the invocation. final WindowState win = createWindow(null, TYPE_APPLICATION, "app"); @@ -445,7 +445,7 @@ public class InsetsStateControllerTest extends WindowTestsBase { waitUntilHandlersIdle(); clearInvocations(mDisplayContent); - imeSourceProvider.updateControlForTarget(app, false /* force */); + imeSourceProvider.updateControlForTarget(app, false /* force */, null /* statsToken */); imeSourceProvider.setClientVisible(true); verify(mDisplayContent).assignWindowLayers(anyBoolean()); waitUntilHandlersIdle(); @@ -497,7 +497,7 @@ public class InsetsStateControllerTest extends WindowTestsBase { mDisplayContent.updateImeInputAndControlTarget(app); app.setRequestedVisibleTypes(ime(), ime()); - getController().onRequestedVisibleTypesChanged(app); + getController().onRequestedVisibleTypesChanged(app, null /* statsToken */); assertTrue(ime.getControllableInsetProvider().getSource().isVisible()); getController().updateAboveInsetsState(true /* notifyInsetsChange */); @@ -544,7 +544,7 @@ public class InsetsStateControllerTest extends WindowTestsBase { imeInsetsProvider.setWindowContainer(mImeWindow, null, null); imeInsetsProvider.updateSourceFrame(mImeWindow.getFrame()); - imeInsetsProvider.updateControlForTarget(app1, false); + imeInsetsProvider.updateControlForTarget(app1, false, null /* statsToken */); imeInsetsProvider.onPostLayout(); final InsetsSourceControl control1 = imeInsetsProvider.getControl(app1); assertNotNull(control1); @@ -553,7 +553,7 @@ public class InsetsStateControllerTest extends WindowTestsBase { // Simulate the IME control target updated from app1 to app2 when IME insets was invisible. imeInsetsProvider.setServerVisible(false); - imeInsetsProvider.updateControlForTarget(app2, false); + imeInsetsProvider.updateControlForTarget(app2, false, null /* statsToken */); // Verify insetsHint of the new control is same as last IME source frame after the layout. imeInsetsProvider.onPostLayout(); diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java index e13376b34e7b..b46189c1704a 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java @@ -472,7 +472,7 @@ public class WindowStateTests extends WindowTestsBase { app.setRequestedVisibleTypes(0, statusBars()); mDisplayContent.getInsetsStateController() .getOrCreateSourceProvider(statusBarId, statusBars()) - .updateClientVisibility(app); + .updateClientVisibility(app, null /* statsToken */); waitUntilHandlersIdle(); assertFalse(statusBar.isVisible()); } |