diff options
| author | 2020-05-07 14:45:34 -0700 | |
|---|---|---|
| committer | 2020-05-27 15:12:07 +0000 | |
| commit | 85661e3f9e53919e1aa351b221cd6115f9a6f0ac (patch) | |
| tree | 38a7ba5f898ce8d3823f7bfc6a60618ba1a7706b | |
| parent | 45150144692a5bc30ee390b10c3e7452e0b9dcbd (diff) | |
Add Insets dumps and IME debug logs
Add more dumps and logs to better help debug IME insets better
Logging can be enabled by setting InsetsController.DEBUG to true.
Bug: 154348613
Test: manually build and flash.
Verify showing and hiding IME shows logs.
verify adb shell dumpsys window windows has new dumps
Change-Id: Iad0a21d81a22d6acfaaf5c5ca8b5131eec411e79
15 files changed, 305 insertions, 16 deletions
diff --git a/core/java/android/view/InsetsAnimationControlImpl.java b/core/java/android/view/InsetsAnimationControlImpl.java index 05abc6032116..cd56ca9251ab 100644 --- a/core/java/android/view/InsetsAnimationControlImpl.java +++ b/core/java/android/view/InsetsAnimationControlImpl.java @@ -17,6 +17,7 @@ package android.view; import static android.view.InsetsController.AnimationType; +import static android.view.InsetsController.DEBUG; import static android.view.InsetsState.ISIDE_BOTTOM; import static android.view.InsetsState.ISIDE_FLOATING; import static android.view.InsetsState.ISIDE_LEFT; @@ -30,6 +31,7 @@ import android.graphics.Insets; import android.graphics.Matrix; import android.graphics.Rect; import android.util.ArraySet; +import android.util.Log; import android.util.SparseArray; import android.util.SparseIntArray; import android.util.SparseSetArray; @@ -52,6 +54,8 @@ import java.util.ArrayList; public class InsetsAnimationControlImpl implements WindowInsetsAnimationController, InsetsAnimationControlRunner { + private static final String TAG = "InsetsAnimationCtrlImpl"; + private final Rect mTmpFrame = new Rect(); private final WindowInsetsAnimationControlListener mListener; @@ -165,6 +169,7 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll */ public boolean applyChangeInsets(InsetsState state) { if (mCancelled) { + if (DEBUG) Log.d(TAG, "applyChangeInsets canceled"); return false; } final Insets offset = Insets.subtract(mShownInsets, mPendingInsets); @@ -186,9 +191,13 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll mCurrentAlpha = mPendingAlpha; mAnimation.setAlpha(mPendingAlpha); if (mFinished) { + if (DEBUG) Log.d(TAG, String.format( + "notifyFinished shown: %s, currentAlpha: %f, currentInsets: %s", + mShownOnFinish, mCurrentAlpha, mCurrentInsets)); mController.notifyFinished(this, mShownOnFinish); releaseLeashes(); } + if (DEBUG) Log.d(TAG, "Animation finished abruptly."); return mFinished; } @@ -203,12 +212,15 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll @Override public void finish(boolean shown) { if (mCancelled || mFinished) { + if (DEBUG) Log.d(TAG, "Animation already canceled or finished, not notifying."); return; } mShownOnFinish = shown; mFinished = true; setInsetsAndAlpha(shown ? mShownInsets : mHiddenInsets, 1f /* alpha */, 1f /* fraction */, true /* allowWhenFinished */); + + if (DEBUG) Log.d(TAG, "notify control request finished for types: " + mTypes); mListener.onFinished(this); } @@ -225,6 +237,7 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll } mCancelled = true; mListener.onCancelled(mReadyDispatched ? this : null); + if (DEBUG) Log.d(TAG, "notify Control request cancelled for types: " + mTypes); releaseLeashes(); } diff --git a/core/java/android/view/InsetsAnimationThreadControlRunner.java b/core/java/android/view/InsetsAnimationThreadControlRunner.java index 3215b7c89b83..0e71b7643b7d 100644 --- a/core/java/android/view/InsetsAnimationThreadControlRunner.java +++ b/core/java/android/view/InsetsAnimationThreadControlRunner.java @@ -16,12 +16,14 @@ package android.view; +import static android.view.InsetsController.DEBUG; import static android.view.SyncRtSurfaceTransactionApplier.applyParams; import android.annotation.UiThread; import android.graphics.Rect; import android.os.Handler; import android.os.Trace; +import android.util.Log; import android.util.SparseArray; import android.view.InsetsController.AnimationType; import android.view.SyncRtSurfaceTransactionApplier.SurfaceParams; @@ -37,6 +39,7 @@ import android.view.animation.Interpolator; */ public class InsetsAnimationThreadControlRunner implements InsetsAnimationControlRunner { + private static final String TAG = "InsetsAnimThreadRunner"; private final InsetsAnimationControlImpl mControl; private final InsetsAnimationControlCallbacks mOuterCallbacks; private final Handler mMainThreadHandler; @@ -71,6 +74,7 @@ public class InsetsAnimationThreadControlRunner implements InsetsAnimationContro @Override public void applySurfaceParams(SurfaceParams... params) { + if (DEBUG) Log.d(TAG, "applySurfaceParams"); SurfaceControl.Transaction t = new SurfaceControl.Transaction(); for (int i = params.length - 1; i >= 0; i--) { SyncRtSurfaceTransactionApplier.SurfaceParams surfaceParams = params[i]; @@ -82,6 +86,7 @@ public class InsetsAnimationThreadControlRunner implements InsetsAnimationContro @Override public void releaseSurfaceControlFromRt(SurfaceControl sc) { + if (DEBUG) Log.d(TAG, "releaseSurfaceControlFromRt"); // Since we don't push the SurfaceParams to the RT we can release directly sc.release(); } diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java index 758062f41428..3d95f65df842 100644 --- a/core/java/android/view/InsetsController.java +++ b/core/java/android/view/InsetsController.java @@ -37,6 +37,7 @@ import android.os.CancellationSignal; import android.os.Handler; import android.os.Trace; import android.util.ArraySet; +import android.util.Log; import android.util.Pair; import android.util.SparseArray; import android.view.InsetsSourceConsumer.ShowResult; @@ -152,8 +153,16 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation * Obtains {@link InputMethodManager} instance from host. */ InputMethodManager getInputMethodManager(); + + /** + * @return title of the rootView, if it has one. + * Note: this method is for debugging purposes only. + */ + @Nullable + String getRootViewTitle(); } + private static final String TAG = "InsetsController"; private static final int ANIMATION_DURATION_SHOW_MS = 275; private static final int ANIMATION_DURATION_HIDE_MS = 340; @@ -171,6 +180,9 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation private static final Interpolator FAST_OUT_LINEAR_IN_INTERPOLATOR = new PathInterpolator(0.4f, 0f, 1f, 1f); + static final boolean DEBUG = false; + static final boolean WARN = false; + /** * Layout mode during insets animation: The views should be laid out as if the changing inset * types are fully shown. Before starting the animation, {@link View#onApplyWindowInsets} will @@ -268,6 +280,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation @Override public void onReady(WindowInsetsAnimationController controller, int types) { mController = controller; + if (DEBUG) Log.d(TAG, "default animation onReady types: " + types); mAnimator = ValueAnimator.ofFloat(0f, 1f); mAnimator.setDuration(mDurationMs); @@ -290,6 +303,8 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation sEvaluator.evaluate(insetsFraction, start, end), alphaInterpolator.getInterpolation(alphaFraction), rawFraction); + if (DEBUG) Log.d(TAG, "Default animation setInsetsAndAlpha fraction: " + + insetsFraction); }); mAnimator.addListener(new AnimatorListenerAdapter() { @@ -306,6 +321,8 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation @Override public void onFinished(WindowInsetsAnimationController controller) { + if (DEBUG) Log.d(TAG, "InternalAnimationControlListener onFinished types:" + + Type.toString(mRequestedTypes)); } @Override @@ -314,6 +331,8 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation if (mAnimator != null) { mAnimator.cancel(); } + if (DEBUG) Log.d(TAG, "InternalAnimationControlListener onCancelled types:" + + mRequestedTypes); } Interpolator getInterpolator() { @@ -348,6 +367,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation protected void onAnimationFinish() { mController.finish(mShow); + if (DEBUG) Log.d(TAG, "onAnimationFinish showOnFinish: " + mShow); } /** @@ -420,8 +440,6 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation final boolean useInsetsAnimationThread; } - private final String TAG = "InsetsControllerImpl"; - /** The local state */ private final InsetsState mState = new InsetsState(); @@ -494,6 +512,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation InsetsState state = new InsetsState(mState, true /* copySources */); for (int i = mRunningAnimations.size() - 1; i >= 0; i--) { RunningAnimation runningAnimation = mRunningAnimations.get(i); + if (DEBUG) Log.d(TAG, "Running animation type: " + runningAnimation.type); InsetsAnimationControlRunner runner = runningAnimation.runner; if (runner instanceof InsetsAnimationControlImpl) { InsetsAnimationControlImpl control = (InsetsAnimationControlImpl) runner; @@ -516,6 +535,12 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation mLastDisplayCutout, mLastLegacySoftInputMode, mLastLegacySystemUiFlags, null /* typeSideMap */); mHost.dispatchWindowInsetsAnimationProgress(insets, mUnmodifiableTmpRunningAnims); + if (DEBUG) { + for (WindowInsetsAnimation anim : mUnmodifiableTmpRunningAnims) { + Log.d(TAG, String.format("Running animation type: %d, progress: %f", + anim.getTypeMask(), anim.getInterpolatedFraction())); + } + } for (int i = mTmpFinishedControls.size() - 1; i >= 0; i--) { dispatchAnimationEnd(mTmpFinishedControls.get(i).getAnimation()); @@ -553,13 +578,16 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation if (!localStateChanged && mLastDispatchedState.equals(state)) { return false; } + if (DEBUG) Log.d(TAG, "onStateChanged: " + state); updateState(state); mLastDispatchedState.set(state, true /* copySources */); applyLocalVisibilityOverride(); if (localStateChanged) { + if (DEBUG) Log.d(TAG, "onStateChanged, notifyInsetsChanged"); mHost.notifyInsetsChanged(); } if (!mState.equals(mLastDispatchedState, true /* excludingCaptionInsets */)) { + if (DEBUG) Log.d(TAG, "onStateChanged, send state to WM: " + mState); updateRequestedState(); } return true; @@ -683,7 +711,6 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation @VisibleForTesting public void show(@InsetsType int types, boolean fromIme) { - // Handle pending request ready in case there was one set. if (fromIme && mPendingImeControlRequest != null) { PendingControlRequest pendingRequest = mPendingImeControlRequest; @@ -711,10 +738,14 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation || animationType == ANIMATION_TYPE_SHOW) { // no-op: already shown or animating in (because window visibility is // applied before starting animation). + if (DEBUG) Log.d(TAG, String.format( + "show ignored for type: %d animType: %d requestedVisible: %s", + consumer.getType(), animationType, consumer.isRequestedVisible())); continue; } typesReady |= InsetsState.toPublicType(consumer.getType()); } + if (DEBUG) Log.d(TAG, "show typesReady: " + typesReady); applyAnimation(typesReady, true /* show */, fromIme); } @@ -781,9 +812,11 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation if (types == 0) { // nothing to animate. listener.onCancelled(null); + if (DEBUG) Log.d(TAG, "no types to animate in controlAnimationUnchecked"); return; } cancelExistingControllers(types); + if (DEBUG) Log.d(TAG, "controlAnimation types: " + types); mLastStartedAnimTypes |= types; final ArraySet<Integer> internalTypes = InsetsState.toInternalType(types); @@ -793,6 +826,8 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation fromIme, internalTypes, controls, animationType); int typesReady = typesReadyPair.first; boolean imeReady = typesReadyPair.second; + if (DEBUG) Log.d(TAG, String.format( + "controlAnimationUnchecked, typesReady: %s imeReady: %s", typesReady, imeReady)); if (!imeReady) { // IME isn't ready, all requested types will be animated once IME is ready abortPendingImeControlRequest(); @@ -802,9 +837,12 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation useInsetsAnimationThread); mPendingImeControlRequest = request; mHandler.postDelayed(mPendingControlTimeout, PENDING_CONTROL_TIMEOUT_MS); + if (DEBUG) Log.d(TAG, "Ime not ready. Create pending request"); if (cancellationSignal != null) { cancellationSignal.setOnCancelListener(() -> { if (mPendingImeControlRequest == request) { + if (DEBUG) Log.d(TAG, + "Cancellation signal abortPendingImeControlRequest"); abortPendingImeControlRequest(); } }); @@ -813,6 +851,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation } if (typesReady == 0) { + if (DEBUG) Log.d(TAG, "No types ready. onCancelled()"); listener.onCancelled(null); return; } @@ -826,6 +865,8 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation frame, mState, listener, typesReady, this, durationMs, interpolator, animationType); mRunningAnimations.add(new RunningAnimation(runner, animationType)); + if (DEBUG) Log.d(TAG, "Animation added to runner. useInsetsAnimationThread: " + + useInsetsAnimationThread); if (cancellationSignal != null) { cancellationSignal.setOnCancelListener(runner::cancel); } @@ -857,8 +898,11 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation break; case ShowResult.IME_SHOW_DELAYED: imeReady = false; + if (DEBUG) Log.d(TAG, "requestShow IME_SHOW_DELAYED"); break; case ShowResult.IME_SHOW_FAILED: + if (WARN) Log.w(TAG, "requestShow IME_SHOW_FAILED. fromIme: " + + fromIme); // IME cannot be shown (since it didn't have focus), proceed // with animation of other types. break; @@ -873,6 +917,9 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation canRun = true; } if (!canRun) { + if (WARN) Log.w(TAG, String.format( + "collectSourceControls can't continue show for type: %s fromIme: %b", + InsetsState.typeToString(consumer.getType()), fromIme)); continue; } final InsetsSourceControl control = consumer.getControl(); @@ -880,7 +927,8 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation controls.put(consumer.getType(), new InsetsSourceControl(control)); typesReady |= toPublicType(consumer.getType()); } else if (animationType == ANIMATION_TYPE_SHOW) { - + if (DEBUG) Log.d(TAG, "collectSourceControls no control for show(). fromIme: " + + fromIme); // We don't have a control at the moment. However, we still want to update requested // visibility state such that in case we get control, we can apply show animation. consumer.show(fromIme); @@ -931,6 +979,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation mPendingImeControlRequest.listener.onCancelled(null); mPendingImeControlRequest = null; mHandler.removeCallbacks(mPendingControlTimeout); + if (DEBUG) Log.d(TAG, "abortPendingImeControlRequest"); } } @@ -938,6 +987,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation @Override public void notifyFinished(InsetsAnimationControlRunner runner, boolean shown) { cancelAnimation(runner, false /* invokeCallback */); + if (DEBUG) Log.d(TAG, "notifyFinished. shown: " + shown); if (shown) { showDirectly(runner.getTypes()); } else { @@ -964,6 +1014,8 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation } private void cancelAnimation(InsetsAnimationControlRunner control, boolean invokeCallback) { + if (DEBUG) Log.d(TAG, String.format("cancelAnimation of types: %d, animType: %d", + control.getTypes(), control.getAnimationType())); if (invokeCallback) { control.cancel(); } @@ -1088,6 +1140,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation public void applyAnimation(@InsetsType final int types, boolean show, boolean fromIme) { if (types == 0) { // nothing to animate. + if (DEBUG) Log.d(TAG, "applyAnimation, nothing to animate"); return; } @@ -1142,6 +1195,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation mHost.dispatchWindowInsetsAnimationPrepare(animation); mHost.addOnPreDrawRunnable(() -> { if (controller.isCancelled()) { + if (WARN) Log.w(TAG, "startAnimation canceled before preDraw"); return; } Trace.asyncTraceBegin(Trace.TRACE_TAG_VIEW, diff --git a/core/java/android/view/InsetsSourceConsumer.java b/core/java/android/view/InsetsSourceConsumer.java index df3ac8787b57..3869484468ae 100644 --- a/core/java/android/view/InsetsSourceConsumer.java +++ b/core/java/android/view/InsetsSourceConsumer.java @@ -19,11 +19,13 @@ package android.view; import static android.view.InsetsController.ANIMATION_TYPE_NONE; import static android.view.InsetsController.AnimationType; import static android.view.InsetsState.getDefaultVisibility; +import static android.view.InsetsController.DEBUG; import static android.view.InsetsState.toPublicType; import android.annotation.IntDef; import android.annotation.Nullable; import android.graphics.Rect; +import android.util.Log; import android.view.InsetsState.InternalInsetsType; import android.view.SurfaceControl.Transaction; import android.view.WindowInsets.Type.InsetsType; @@ -64,6 +66,7 @@ public class InsetsSourceConsumer { protected final InsetsState mState; protected final @InternalInsetsType int mType; + private static final String TAG = "InsetsSourceConsumer"; private final Supplier<Transaction> mTransactionSupplier; private @Nullable InsetsSourceControl mSourceControl; private boolean mHasWindowFocus; @@ -103,7 +106,11 @@ public class InsetsSourceConsumer { final InsetsSourceControl lastControl = mSourceControl; mSourceControl = control; - + if (control != null) { + if (DEBUG) Log.d(TAG, String.format("setControl -> %s on %s", + InsetsState.typeToString(control.getType()), + mController.getHost().getRootViewTitle())); + } // We are loosing control if (mSourceControl == null) { mController.notifyControlRevoked(this); @@ -118,6 +125,8 @@ public class InsetsSourceConsumer { final boolean requestedVisible = isRequestedVisibleAwaitingControl(); final boolean needAnimation = requestedVisible != mState.getSource(mType).isVisible(); if (control.getLeash() != null && (needAnimation || mIsAnimationPending)) { + if (DEBUG) Log.d(TAG, String.format("Gaining control in %s, requestedVisible: %b", + mController.getHost().getRootViewTitle(), requestedVisible)); if (requestedVisible) { showTypes[0] |= toPublicType(getType()); } else { @@ -170,11 +179,15 @@ public class InsetsSourceConsumer { @VisibleForTesting public void show(boolean fromIme) { + if (DEBUG) Log.d(TAG, String.format("Call show() for type: %s fromIme: %b ", + InsetsState.typeToString(mType), fromIme)); setRequestedVisible(true); } @VisibleForTesting public void hide() { + if (DEBUG) Log.d(TAG, String.format("Call hide for %s on %s", + InsetsState.typeToString(mType), mController.getHost().getRootViewTitle())); setRequestedVisible(false); } @@ -212,11 +225,16 @@ public class InsetsSourceConsumer { // If we don't have control, we are not able to change the visibility. if (!hasControl) { + if (DEBUG) Log.d(TAG, "applyLocalVisibilityOverride: No control in " + + mController.getHost().getRootViewTitle() + + " requestedVisible " + mRequestedVisible); return false; } if (isVisible == mRequestedVisible) { return false; } + if (DEBUG) Log.d(TAG, String.format("applyLocalVisibilityOverride: %s requestedVisible: %b", + mController.getHost().getRootViewTitle(), mRequestedVisible)); mState.getSource(mType).setVisible(mRequestedVisible); return true; } @@ -271,6 +289,7 @@ public class InsetsSourceConsumer { newSource.setFrame(source.getFrame()); newSource.setVisibleFrame(source.getVisibleFrame()); mState.addSource(newSource); + if (DEBUG) Log.d(TAG, "updateSource: " + newSource); } boolean notifyAnimationFinished() { @@ -293,6 +312,7 @@ public class InsetsSourceConsumer { if (mRequestedVisible != requestedVisible) { mRequestedVisible = requestedVisible; mIsAnimationPending = false; + if (DEBUG) Log.d(TAG, "setRequestedVisible: " + requestedVisible); } if (applyLocalVisibilityOverride()) { mController.notifyVisibilityChanged(); @@ -305,6 +325,7 @@ public class InsetsSourceConsumer { } final Transaction t = mTransactionSupplier.get(); + if (DEBUG) Log.d(TAG, "applyHiddenToControl: " + mRequestedVisible); if (mRequestedVisible) { t.show(mSourceControl.getLeash()); } else { diff --git a/core/java/android/view/InsetsSourceControl.java b/core/java/android/view/InsetsSourceControl.java index e001b668f71a..2c2ecd504519 100644 --- a/core/java/android/view/InsetsSourceControl.java +++ b/core/java/android/view/InsetsSourceControl.java @@ -22,6 +22,7 @@ import android.os.Parcel; import android.os.Parcelable; import android.view.InsetsState.InternalInsetsType; +import java.io.PrintWriter; import java.util.function.Consumer; /** @@ -101,6 +102,14 @@ public class InsetsSourceControl implements Parcelable { } } + public void dump(String prefix, PrintWriter pw) { + pw.print(prefix); + pw.print("InsetsSourceControl type="); pw.print(InsetsState.typeToString(mType)); + pw.print(" mLeash="); pw.print(mLeash); + pw.print(" mSurfacePosition="); pw.print(mSurfacePosition); + pw.println(); + } + public static final @android.annotation.NonNull Creator<InsetsSourceControl> CREATOR = new Creator<InsetsSourceControl>() { public InsetsSourceControl createFromParcel(Parcel in) { diff --git a/core/java/android/view/InsetsState.java b/core/java/android/view/InsetsState.java index 9896aa4fe214..18368af11a69 100644 --- a/core/java/android/view/InsetsState.java +++ b/core/java/android/view/InsetsState.java @@ -51,6 +51,7 @@ import java.io.PrintWriter; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.Objects; +import java.util.StringJoiner; /** * Holder for state of system windows that cause window insets for all other windows in the system. @@ -600,10 +601,16 @@ public class InsetsState implements Parcelable { @Override public String toString() { + StringJoiner joiner = new StringJoiner(", "); + for (InsetsSource source : mSources.values()) { + if (source != null) { + joiner.add(source.toString()); + } + } return "InsetsState: {" + "mDisplayFrame=" + mDisplayFrame - + ", mSources=" + mSources - + "}"; + + ", mSources= { " + joiner + + " }"; } } diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 511e75541ba7..8b5d033072fb 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -4990,6 +4990,11 @@ public final class ViewRootImpl implements ViewParent, break; } case MSG_SHOW_INSETS: { + if (mView == null) { + Log.e(TAG, + String.format("Calling showInsets(%d,%b) on window that no longer" + + " has views.", msg.arg1, msg.arg2 == 1)); + } mInsetsController.show(msg.arg1, msg.arg2 == 1); break; } diff --git a/core/java/android/view/ViewRootInsetsControllerHost.java b/core/java/android/view/ViewRootInsetsControllerHost.java index 9674a80c8159..686d561a1a5a 100644 --- a/core/java/android/view/ViewRootInsetsControllerHost.java +++ b/core/java/android/view/ViewRootInsetsControllerHost.java @@ -16,6 +16,7 @@ package android.view; +import static android.view.InsetsController.DEBUG; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_APPEARANCE_CONTROLLED; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_BEHAVIOR_CONTROLLED; @@ -84,6 +85,7 @@ public class ViewRootInsetsControllerHost implements InsetsController.Host { if (mViewRoot.mView == null) { return null; } + if (DEBUG) Log.d(TAG, "windowInsetsAnimation started"); return mViewRoot.mView.dispatchWindowInsetsAnimationStart(animation, bounds); } @@ -94,11 +96,18 @@ public class ViewRootInsetsControllerHost implements InsetsController.Host { // The view has already detached from window. return null; } + if (DEBUG) { + for (WindowInsetsAnimation anim : runningAnimations) { + Log.d(TAG, "windowInsetsAnimation progress: " + + anim.getInterpolatedFraction()); + } + } return mViewRoot.mView.dispatchWindowInsetsAnimationProgress(insets, runningAnimations); } @Override public void dispatchWindowInsetsAnimationEnd(@NonNull WindowInsetsAnimation animation) { + if (DEBUG) Log.d(TAG, "windowInsetsAnimation ended"); mViewRoot.mView.dispatchWindowInsetsAnimationEnd(animation); } @@ -212,4 +221,12 @@ public class ViewRootInsetsControllerHost implements InsetsController.Host { public InputMethodManager getInputMethodManager() { return mViewRoot.mContext.getSystemService(InputMethodManager.class); } + + @Override + public String getRootViewTitle() { + if (mViewRoot == null) { + return null; + } + return mViewRoot.getTitle().toString(); + } } diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json index b5c19a895413..bfc623faeaef 100644 --- a/data/etc/services.core.protolog.json +++ b/data/etc/services.core.protolog.json @@ -253,6 +253,12 @@ "group": "WM_DEBUG_ORIENTATION", "at": "com\/android\/server\/wm\/DisplayRotation.java" }, + "-1554521902": { + "message": "showInsets(ime) was requested by different window: %s ", + "level": "WARN", + "group": "WM_DEBUG_IME", + "at": "com\/android\/server\/wm\/ImeInsetsSourceProvider.java" + }, "-1545962566": { "message": "View server did not start", "level": "WARN", @@ -367,6 +373,12 @@ "group": "WM_DEBUG_STARTING_WINDOW", "at": "com\/android\/server\/wm\/ActivityRecord.java" }, + "-1312861660": { + "message": "notifyInsetsControlChanged for %s ", + "level": "DEBUG", + "group": "WM_DEBUG_IME", + "at": "com\/android\/server\/wm\/WindowState.java" + }, "-1292329638": { "message": "Added starting %s: startingWindow=%s startingView=%s", "level": "VERBOSE", @@ -817,6 +829,12 @@ "group": "WM_DEBUG_STARTING_WINDOW", "at": "com\/android\/server\/wm\/TaskSnapshotSurface.java" }, + "-395922585": { + "message": "InsetsSource setWin %s", + "level": "DEBUG", + "group": "WM_DEBUG_IME", + "at": "com\/android\/server\/wm\/InsetsSourceProvider.java" + }, "-393505149": { "message": "unable to update pointer icon", "level": "WARN", @@ -859,6 +877,12 @@ "group": "WM_SHOW_TRANSACTIONS", "at": "com\/android\/server\/wm\/WindowSurfaceController.java" }, + "-322743468": { + "message": "setInputMethodInputTarget %s", + "level": "INFO", + "group": "WM_DEBUG_IME", + "at": "com\/android\/server\/wm\/DisplayContent.java" + }, "-322035974": { "message": "App freeze timeout expired.", "level": "WARN", @@ -925,6 +949,12 @@ "group": "WM_DEBUG_SCREEN_ON", "at": "com\/android\/server\/wm\/WindowManagerService.java" }, + "-112805366": { + "message": "InsetsSource updateVisibility serverVisible: %s clientVisible: %s", + "level": "DEBUG", + "group": "WM_DEBUG_IME", + "at": "com\/android\/server\/wm\/InsetsSourceProvider.java" + }, "-106400104": { "message": "Preload recents with %s", "level": "DEBUG", @@ -1003,6 +1033,12 @@ "group": "WM_DEBUG_RECENTS_ANIMATIONS", "at": "com\/android\/server\/wm\/RecentsAnimationController.java" }, + "29780972": { + "message": "InsetsSource Control %s for target %s", + "level": "DEBUG", + "group": "WM_DEBUG_IME", + "at": "com\/android\/server\/wm\/InsetsSourceProvider.java" + }, "38267433": { "message": "Attempted to reset replacing window on non-existing app token %s", "level": "WARN", @@ -1027,6 +1063,18 @@ "group": "WM_ERROR", "at": "com\/android\/server\/wm\/WindowManagerService.java" }, + "73987756": { + "message": "ControlAdapter onAnimationCancelled mSource: %s mControlTarget: %s", + "level": "INFO", + "group": "WM_DEBUG_IME", + "at": "com\/android\/server\/wm\/InsetsSourceProvider.java" + }, + "75707221": { + "message": "ControlAdapter startAnimation mSource: %s controlTarget: %s", + "level": "INFO", + "group": "WM_DEBUG_IME", + "at": "com\/android\/server\/wm\/InsetsSourceProvider.java" + }, "83950285": { "message": "removeAnimation(%d)", "level": "DEBUG", @@ -1285,12 +1333,6 @@ "group": "WM_ERROR", "at": "com\/android\/server\/wm\/WindowManagerService.java" }, - "438102669": { - "message": "call showInsets(ime) on %s", - "level": "DEBUG", - "group": "WM_DEBUG_IME", - "at": "com\/android\/server\/wm\/ImeInsetsSourceProvider.java" - }, "457951957": { "message": "\tNot visible=%s", "level": "DEBUG", @@ -1369,6 +1411,12 @@ "group": "WM_SHOW_TRANSACTIONS", "at": "com\/android\/server\/wm\/WindowSurfaceController.java" }, + "585839596": { + "message": "call showInsets(ime) on %s", + "level": "INFO", + "group": "WM_DEBUG_IME", + "at": "com\/android\/server\/wm\/ImeInsetsSourceProvider.java" + }, "594260577": { "message": "createWallpaperAnimations()", "level": "DEBUG", @@ -1873,6 +1921,12 @@ "group": "WM_DEBUG_APP_TRANSITIONS", "at": "com\/android\/server\/wm\/ActivityRecord.java" }, + "1533154777": { + "message": "notifyInsetsChanged for %s ", + "level": "DEBUG", + "group": "WM_DEBUG_IME", + "at": "com\/android\/server\/wm\/WindowState.java" + }, "1563755163": { "message": "Permission Denial: %s from pid=%d, uid=%d requires %s", "level": "WARN", @@ -1897,6 +1951,12 @@ "group": "WM_DEBUG_APP_TRANSITIONS_ANIM", "at": "com\/android\/server\/wm\/AppTransition.java" }, + "1591969812": { + "message": "updateImeControlTarget %s", + "level": "INFO", + "group": "WM_DEBUG_IME", + "at": "com\/android\/server\/wm\/DisplayContent.java" + }, "1628345525": { "message": "Now opening app %s", "level": "VERBOSE", @@ -1927,6 +1987,12 @@ "group": "WM_DEBUG_APP_TRANSITIONS", "at": "com\/android\/server\/wm\/ActivityRecord.java" }, + "1658605381": { + "message": "onImeControlTargetChanged %s", + "level": "DEBUG", + "group": "WM_DEBUG_IME", + "at": "com\/android\/server\/wm\/InsetsStateController.java" + }, "1671994402": { "message": "Nulling last startingData", "level": "VERBOSE", @@ -2173,6 +2239,12 @@ "group": "WM_DEBUG_ADD_REMOVE", "at": "com\/android\/server\/wm\/WindowState.java" }, + "2119122320": { + "message": "setInputMethodTarget %s", + "level": "INFO", + "group": "WM_DEBUG_IME", + "at": "com\/android\/server\/wm\/DisplayContent.java" + }, "2128604122": { "message": "findFocusedWindow: No focusable windows.", "level": "VERBOSE", diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index eb85db61754f..578bcb692a00 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -99,6 +99,7 @@ import static com.android.server.wm.DisplayContentProto.WINDOW_CONTAINER; import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_APP_TRANSITIONS; import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_FOCUS; import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_FOCUS_LIGHT; +import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_IME; import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_ORIENTATION; import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_SCREEN_ON; import static com.android.server.wm.ProtoLogGroup.WM_SHOW_TRANSACTIONS; @@ -3494,7 +3495,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo if (target == mInputMethodTarget && mInputMethodTargetWaitingAnim == targetWaitingAnim) { return; } - + ProtoLog.i(WM_DEBUG_IME, "setInputMethodTarget %s", target); mInputMethodTarget = target; mInputMethodTargetWaitingAnim = targetWaitingAnim; assignWindowLayers(true /* setLayoutNeeded */); @@ -3508,6 +3509,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo */ void setInputMethodInputTarget(WindowState target) { if (mInputMethodInputTarget != target) { + ProtoLog.i(WM_DEBUG_IME, "setInputMethodInputTarget %s", target); mInputMethodInputTarget = target; updateImeControlTarget(); } @@ -3515,6 +3517,8 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo private void updateImeControlTarget() { mInputMethodControlTarget = computeImeControlTarget(); + ProtoLog.i(WM_DEBUG_IME, "updateImeControlTarget %s", + mInputMethodControlTarget.getWindow()); mInsetsStateController.onImeControlTargetChanged(mInputMethodControlTarget); } diff --git a/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java b/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java index 7491376cd152..a0985fc48422 100644 --- a/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java +++ b/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java @@ -65,9 +65,16 @@ class ImeInsetsSourceProvider extends InsetsSourceProvider { // Target should still be the same. if (isImeTargetFromDisplayContentAndImeSame()) { final InsetsControlTarget target = mDisplayContent.mInputMethodControlTarget; - ProtoLog.d(WM_DEBUG_IME, "call showInsets(ime) on %s", + + ProtoLog.i(WM_DEBUG_IME, "call showInsets(ime) on %s", target.getWindow() != null ? target.getWindow().getName() : ""); target.showInsets(WindowInsets.Type.ime(), true /* fromIme */); + if (target != mImeTargetFromIme && mImeTargetFromIme != null) { + ProtoLog.w(WM_DEBUG_IME, + "showInsets(ime) was requested by different window: %s ", + (mImeTargetFromIme.getWindow() != null + ? mImeTargetFromIme.getWindow().getName() : "")); + } } abortShowImePostLayout(); }; diff --git a/services/core/java/com/android/server/wm/InsetsSourceProvider.java b/services/core/java/com/android/server/wm/InsetsSourceProvider.java index a6a21fc55770..6a4975950f1a 100644 --- a/services/core/java/com/android/server/wm/InsetsSourceProvider.java +++ b/services/core/java/com/android/server/wm/InsetsSourceProvider.java @@ -24,6 +24,7 @@ import static android.view.ViewRootImpl.NEW_INSETS_MODE_IME; import static android.view.ViewRootImpl.NEW_INSETS_MODE_NONE; import static android.view.ViewRootImpl.sNewInsetsMode; +import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_IME; 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; @@ -40,6 +41,7 @@ import android.view.SurfaceControl.Transaction; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.function.TriConsumer; +import com.android.server.protolog.common.ProtoLog; import com.android.server.wm.SurfaceAnimator.AnimationType; import com.android.server.wm.SurfaceAnimator.OnAnimationFinishedCallback; @@ -134,6 +136,7 @@ class InsetsSourceProvider { // animate-out as new one animates-in. mWin.cancelAnimation(); } + ProtoLog.d(WM_DEBUG_IME, "InsetsSource setWin %s", win); mWin = win; mFrameProvider = frameProvider; mImeFrameProvider = imeFrameProvider; @@ -299,6 +302,8 @@ class InsetsSourceProvider { updateVisibility(); mControl = new InsetsSourceControl(mSource.getType(), leash, new Point(mWin.getWindowFrames().mFrame.left, mWin.getWindowFrames().mFrame.top)); + ProtoLog.d(WM_DEBUG_IME, + "InsetsSource Control %s for target %s", mControl, mControlTarget); } void startSeamlessRotation() { @@ -349,6 +354,9 @@ class InsetsSourceProvider { final boolean isClientControlled = mControlTarget != null && mControlTarget.isClientControlled(); mSource.setVisible(mServerVisible && (!isClientControlled || mClientVisible)); + ProtoLog.d(WM_DEBUG_IME, + "InsetsSource updateVisibility serverVisible: %s clientVisible: %s", + mServerVisible, mClientVisible); } InsetsSourceControl getControl(InsetsControlTarget target) { @@ -391,6 +399,44 @@ class InsetsSourceProvider { return mImeOverrideFrame; } + public void dump(PrintWriter pw, String prefix) { + pw.println(prefix + "InsetsSourceProvider"); + pw.print(prefix + " mSource="); mSource.dump(prefix + " ", pw); + if (mControl != null) { + pw.print(prefix + " mControl="); + mControl.dump(prefix + " ", pw); + } + pw.print(prefix + " mFakeControl="); mFakeControl.dump(prefix + " ", pw); + pw.print(" mIsLeashReadyForDispatching="); pw.print(mIsLeashReadyForDispatching); + pw.print(" mImeOverrideFrame="); pw.print(mImeOverrideFrame.toString()); + if (mWin != null) { + pw.print(prefix + " mWin="); + mWin.dump(pw, prefix + " ", false /* dumpAll */); + } + if (mAdapter != null) { + pw.print(prefix + " mAdapter="); + mAdapter.dump(pw, prefix + " "); + } + if (mControlTarget != null) { + pw.print(prefix + " mControlTarget="); + if (mControlTarget.getWindow() != null) { + mControlTarget.getWindow().dump(pw, prefix + " ", false /* dumpAll */); + } + } + if (mPendingControlTarget != null) { + pw.print(prefix + " mPendingControlTarget="); + if (mPendingControlTarget.getWindow() != null) { + mPendingControlTarget.getWindow().dump(pw, prefix + " ", false /* dumpAll */); + } + } + if (mFakeControlTarget != null) { + pw.print(prefix + " mFakeControlTarget="); + if (mFakeControlTarget.getWindow() != null) { + mFakeControlTarget.getWindow().dump(pw, prefix + " ", false /* dumpAll */); + } + } + } + private class ControlAdapter implements AnimationAdapter { private SurfaceControl mCapturedLeash; @@ -410,6 +456,9 @@ class InsetsSourceProvider { t.setAlpha(animationLeash, 1 /* alpha */); t.hide(animationLeash); } + ProtoLog.i(WM_DEBUG_IME, + "ControlAdapter startAnimation mSource: %s controlTarget: %s", mSource, + mControlTarget); mCapturedLeash = animationLeash; final Rect frame = mWin.getWindowFrames().mFrame; @@ -424,6 +473,9 @@ class InsetsSourceProvider { mControlTarget = null; mAdapter = null; setClientVisible(InsetsState.getDefaultVisibility(mSource.getType())); + ProtoLog.i(WM_DEBUG_IME, + "ControlAdapter onAnimationCancelled mSource: %s mControlTarget: %s", + mSource, mControlTarget); } } @@ -439,6 +491,8 @@ class InsetsSourceProvider { @Override public void dump(PrintWriter pw, String prefix) { + pw.println(prefix + "ControlAdapter"); + pw.print(prefix + " mCapturedLeash="); pw.print(mCapturedLeash); } @Override diff --git a/services/core/java/com/android/server/wm/InsetsStateController.java b/services/core/java/com/android/server/wm/InsetsStateController.java index 9798d77c5975..77bc37f0c2d7 100644 --- a/services/core/java/com/android/server/wm/InsetsStateController.java +++ b/services/core/java/com/android/server/wm/InsetsStateController.java @@ -29,6 +29,8 @@ import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD; import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR; import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR; +import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_IME; + import android.annotation.NonNull; import android.annotation.Nullable; import android.app.WindowConfiguration; @@ -42,6 +44,8 @@ import android.view.InsetsState; import android.view.InsetsState.InternalInsetsType; import android.view.WindowManager; +import com.android.server.protolog.common.ProtoLog; + import java.io.PrintWriter; import java.util.ArrayList; import java.util.function.Consumer; @@ -289,7 +293,10 @@ class InsetsStateController { // Make sure that we always have a control target for the IME, even if the IME target is // null. Otherwise there is no leash that will hide it and IME becomes "randomly" visible. - onControlChanged(ITYPE_IME, imeTarget != null ? imeTarget : mEmptyImeControlTarget); + InsetsControlTarget target = imeTarget != null ? imeTarget : mEmptyImeControlTarget; + onControlChanged(ITYPE_IME, target); + ProtoLog.d(WM_DEBUG_IME, "onImeControlTargetChanged %s", + target != null ? target.getWindow() : "null"); notifyPendingInsetsControlChanged(); } @@ -440,5 +447,11 @@ class InsetsStateController { pw.println(InsetsState.typeToString(mTypeControlTargetMap.keyAt(i)) + " -> " + mTypeControlTargetMap.valueAt(i)); } + pw.println(prefix + " " + "InsetsSourceProviders map:"); + for (int i = mProviders.size() - 1; i >= 0; i--) { + pw.print(prefix + " "); + pw.println(InsetsState.typeToString(mProviders.keyAt(i)) + " -> "); + mProviders.valueAt(i).dump(pw, prefix); + } } } diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 159c59b86b43..eee4e7795252 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -6191,6 +6191,7 @@ public class WindowManagerService extends IWindowManager.Stub final int displayId = dc.getDisplayId(); final WindowState inputMethodTarget = dc.mInputMethodTarget; final WindowState inputMethodInputTarget = dc.mInputMethodInputTarget; + final InsetsControlTarget inputMethodControlTarget = dc.mInputMethodControlTarget; if (inputMethodTarget != null) { pw.print(" mInputMethodTarget in display# "); pw.print(displayId); pw.print(' '); pw.println(inputMethodTarget); @@ -6199,6 +6200,10 @@ public class WindowManagerService extends IWindowManager.Stub pw.print(" mInputMethodInputTarget in display# "); pw.print(displayId); pw.print(' '); pw.println(inputMethodInputTarget); } + if (inputMethodControlTarget != null) { + pw.print(" inputMethodControlTarget in display# "); pw.print(displayId); + pw.print(' '); pw.println(inputMethodControlTarget.getWindow()); + } }); pw.print(" mInTouchMode="); pw.println(mInTouchMode); pw.print(" mLastDisplayFreezeDuration="); diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index e9aff88d0f80..58f85799cddb 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -113,6 +113,7 @@ import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_ADD_REMOVE; import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_APP_TRANSITIONS; import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_FOCUS; import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_FOCUS_LIGHT; +import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_IME; import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_ORIENTATION; import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_RESIZE; import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_STARTING_WINDOW; @@ -3553,6 +3554,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP * Called when the insets state changed. */ void notifyInsetsChanged() { + ProtoLog.d(WM_DEBUG_IME, "notifyInsetsChanged for %s ", this); try { mClient.insetsChanged(getInsetsState()); } catch (RemoteException e) { @@ -3562,6 +3564,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP @Override public void notifyInsetsControlChanged() { + ProtoLog.d(WM_DEBUG_IME, "notifyInsetsControlChanged for %s ", this); final InsetsStateController stateController = getDisplayContent().getInsetsStateController(); try { |