diff options
| author | 2022-12-20 12:06:49 +0000 | |
|---|---|---|
| committer | 2022-12-20 12:06:49 +0000 | |
| commit | 80cb333f059a37c3458eb544ae85257ce72e0783 (patch) | |
| tree | 4bb9c5dc17c918597dbdad732d02099315de8260 | |
| parent | cb7dd5c61b051cfae9dcae31645e603f20f7f0ee (diff) | |
| parent | 5e6f95454c0a028920f759220a3db2c17be99a5d (diff) | |
Merge "Let InsetsController control requested visible types"
6 files changed, 175 insertions, 220 deletions
diff --git a/core/java/android/view/ImeInsetsSourceConsumer.java b/core/java/android/view/ImeInsetsSourceConsumer.java index 02e0fccd7d6c..e34aef97a8ab 100644 --- a/core/java/android/view/ImeInsetsSourceConsumer.java +++ b/core/java/android/view/ImeInsetsSourceConsumer.java @@ -16,21 +16,20 @@ package android.view; -import static android.os.Trace.TRACE_TAG_VIEW; import static android.view.ImeInsetsSourceConsumerProto.INSETS_SOURCE_CONSUMER; import static android.view.ImeInsetsSourceConsumerProto.IS_HIDE_ANIMATION_RUNNING; import static android.view.ImeInsetsSourceConsumerProto.IS_REQUESTED_VISIBLE_AWAITING_CONTROL; import static android.view.ImeInsetsSourceConsumerProto.IS_SHOW_REQUESTED_DURING_HIDE_ANIMATION; -import static android.view.InsetsController.AnimationType; import static android.view.InsetsState.ITYPE_IME; import android.annotation.Nullable; import android.os.IBinder; -import android.os.Trace; import android.util.proto.ProtoOutputStream; import android.view.SurfaceControl.Transaction; import android.view.inputmethod.InputMethodManager; +import com.android.internal.inputmethod.ImeTracing; + import java.util.function.Supplier; /** @@ -62,6 +61,38 @@ public final class ImeInsetsSourceConsumer extends InsetsSourceConsumer { } @Override + public boolean onAnimationStateChanged(boolean running) { + if (!running) { + ImeTracing.getInstance().triggerClientDump( + "ImeInsetsSourceConsumer#onAnimationFinished", + mController.getHost().getInputMethodManager(), null /* icProto */); + } + final boolean insetsChanged = super.onAnimationStateChanged(running); + final boolean showRequested = (mController.getRequestedVisibleTypes() & getType()) != 0; + if (showRequested) { + onShowRequested(); + } else { + mIsRequestedVisibleAwaitingControl = false; + if (!running) { + // Remove IME surface as IME has finished hide animation, if there is no pending + // show request. + if (!mIsShowRequestedDuringHideAnimation) { + notifyHidden(); + removeSurface(); + } + } + // Here is reached + // (1) before the hide animation starts. + // (2) after the hide animation ends. + // (3) if the IME is not controllable (animationFinished == true in this case). + // We should reset mIsShowRequestedDuringHideAnimation in all cases. + mIsHideAnimationRunning = running; + mIsShowRequestedDuringHideAnimation = false; + } + return insetsChanged; + } + + @Override public void onWindowFocusGained(boolean hasViewFocus) { super.onWindowFocusGained(hasViewFocus); getImm().registerImeConsumer(this); @@ -78,36 +109,11 @@ public final class ImeInsetsSourceConsumer extends InsetsSourceConsumer { } @Override - public void show(boolean fromIme) { - super.show(fromIme); - onShowRequested(); - } - - @Override - public void hide() { - super.hide(); - mIsRequestedVisibleAwaitingControl = false; - } - - @Override - void hide(boolean animationFinished, @AnimationType int animationType) { - hide(); - - if (animationFinished) { - // Remove IME surface as IME has finished hide animation, if there is no pending - // show request. - if (!mIsShowRequestedDuringHideAnimation) { - notifyHidden(); - removeSurface(); - } - } - // This method is called - // (1) before the hide animation starts. - // (2) after the hide animation ends. - // (3) if the IME is not controllable (animationFinished == true in this case). - // We should reset mIsShowRequestedDuringHideAnimation in all cases. - mIsHideAnimationRunning = !animationFinished; - mIsShowRequestedDuringHideAnimation = false; + public boolean applyLocalVisibilityOverride() { + ImeTracing.getInstance().triggerClientDump( + "ImeInsetsSourceConsumer#applyLocalVisibilityOverride", + mController.getHost().getInputMethodManager(), null /* icProto */); + return super.applyLocalVisibilityOverride(); } /** @@ -116,6 +122,12 @@ public final class ImeInsetsSourceConsumer extends InsetsSourceConsumer { */ @Override public @ShowResult int requestShow(boolean fromIme) { + if (fromIme) { + ImeTracing.getInstance().triggerClientDump( + "ImeInsetsSourceConsumer#requestShow", + mController.getHost().getInputMethodManager(), null /* icProto */); + } + // TODO: ResultReceiver for IME. // TODO: Set mShowOnNextImeRender to automatically show IME and guard it with a flag. if (getControl() == null) { @@ -137,10 +149,8 @@ public final class ImeInsetsSourceConsumer extends InsetsSourceConsumer { * Notify {@link com.android.server.inputmethod.InputMethodManagerService} that * IME insets are hidden. */ - @Override - void notifyHidden() { + private void notifyHidden() { getImm().notifyImeHidden(mController.getHost().getWindowToken()); - Trace.asyncTraceEnd(TRACE_TAG_VIEW, "IC.hideRequestFromApi", 0); } @Override @@ -154,11 +164,13 @@ public final class ImeInsetsSourceConsumer extends InsetsSourceConsumer { @Override public boolean setControl(@Nullable InsetsSourceControl control, int[] showTypes, int[] hideTypes) { + ImeTracing.getInstance().triggerClientDump("ImeInsetsSourceConsumer#setControl", + mController.getHost().getInputMethodManager(), null /* icProto */); if (!super.setControl(control, showTypes, hideTypes)) { return false; } if (control == null && !mIsRequestedVisibleAwaitingControl) { - hide(); + mController.setRequestedVisibleTypes(0 /* visibleTypes */, getType()); removeSurface(); } if (control != null) { @@ -192,7 +204,8 @@ public final class ImeInsetsSourceConsumer extends InsetsSourceConsumer { } /** - * Called when {@link #show} or {@link InputMethodManager#showSoftInput(View, int)} is called. + * Called when {@link #onAnimationStateChanged(boolean)} or + * {@link InputMethodManager#showSoftInput(View, int)} is called. */ public void onShowRequested() { if (mIsHideAnimationRunning) { diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java index 421efed83852..e1b27ffe035d 100644 --- a/core/java/android/view/InsetsController.java +++ b/core/java/android/view/InsetsController.java @@ -21,7 +21,6 @@ import static android.view.InsetsControllerProto.CONTROL; import static android.view.InsetsControllerProto.STATE; import static android.view.InsetsState.ITYPE_CAPTION_BAR; import static android.view.InsetsState.ITYPE_IME; -import static android.view.InsetsState.toInternalType; import static android.view.InsetsState.toPublicType; import static android.view.ViewRootImpl.CAPTION_ON_SHELL; import static android.view.WindowInsets.Type.FIRST; @@ -742,6 +741,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation private void updateState(InsetsState newState) { mState.set(newState, 0 /* types */); + @InsetsType int existingTypes = 0; @InsetsType int visibleTypes = 0; @InsetsType int disabledUserAnimationTypes = 0; @InsetsType int[] cancelledUserAnimationTypes = {0}; @@ -760,10 +760,15 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation } } getSourceConsumer(type).updateSource(source, animationType); + existingTypes |= insetsType; if (source.isVisible()) { visibleTypes |= insetsType; } } + + // If a type doesn't have a source, treat it as visible if it is visible by default. + visibleTypes |= WindowInsets.Type.defaultVisible() & ~existingTypes; + if (mVisibleTypes != visibleTypes) { if (WindowInsets.Type.hasCompatSystemBars(mVisibleTypes ^ visibleTypes)) { mCompatSysUiVisibilityStaled = true; @@ -1103,6 +1108,29 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation @AnimationType int animationType, @LayoutInsetsDuringAnimation int layoutInsetsDuringAnimation, boolean useInsetsAnimationThread, @Nullable ImeTracker.Token statsToken) { + final boolean visible = layoutInsetsDuringAnimation == LAYOUT_INSETS_DURING_ANIMATION_SHOWN; + + // Basically, we accept the requested visibilities from the upstream callers... + setRequestedVisibleTypes(visible ? types : 0, types); + + // However, we might reject the request in some cases, such as delaying showing IME or + // rejecting showing IME. + controlAnimationUncheckedInner(types, cancellationSignal, listener, frame, fromIme, + durationMs, interpolator, animationType, layoutInsetsDuringAnimation, + useInsetsAnimationThread, statsToken); + + // We are finishing setting the requested visible types. Report them to the server and/or + // the app. + reportRequestedVisibleTypes(); + } + + private void controlAnimationUncheckedInner(@InsetsType int types, + @Nullable CancellationSignal cancellationSignal, + WindowInsetsAnimationControlListener listener, @Nullable Rect frame, boolean fromIme, + long durationMs, Interpolator interpolator, + @AnimationType int animationType, + @LayoutInsetsDuringAnimation int layoutInsetsDuringAnimation, + boolean useInsetsAnimationThread, @Nullable ImeTracker.Token statsToken) { ImeTracker.get().onProgress(statsToken, ImeTracker.PHASE_CLIENT_CONTROL_ANIMATION); if ((types & mTypesBeingCancelled) != 0) { throw new IllegalStateException("Cannot start a new insets animation of " @@ -1119,13 +1147,15 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation && !mState.getSource(ITYPE_IME).isVisible()) { // We've requested IMM to show IME, but the IME is not controllable. We need to // cancel the request. - getSourceConsumer(ITYPE_IME).hide(true, animationType); + setRequestedVisibleTypes(0 /* visibleTypes */, ime()); + if (getSourceConsumer(ITYPE_IME).onAnimationStateChanged(false /* running */)) { + notifyVisibilityChanged(); + } } } if (types == 0) { // nothing to animate. listener.onCancelled(null); - reportRequestedVisibleTypes(); if (DEBUG) Log.d(TAG, "no types to animate in controlAnimationUnchecked"); return; } @@ -1161,7 +1191,11 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation } }); } - reportRequestedVisibleTypes(); + + // The requested visibilities should be delayed as well. Otherwise, the server will + // create already visible leashes for us before we play the show animation. + setRequestedVisibleTypes(mReportedRequestedVisibleTypes, types); + Trace.asyncTraceEnd(TRACE_TAG_VIEW, "IC.showRequestFromApi", 0); return; } @@ -1169,7 +1203,6 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation if (typesReady == 0) { if (DEBUG) Log.d(TAG, "No types ready. onCancelled()"); listener.onCancelled(null); - reportRequestedVisibleTypes(); return; } @@ -1198,12 +1231,20 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation } else { Trace.asyncTraceBegin(TRACE_TAG_VIEW, "IC.pendingAnim", 0); } - if (layoutInsetsDuringAnimation == LAYOUT_INSETS_DURING_ANIMATION_SHOWN) { - showDirectly(types, fromIme); - } else { - hideDirectly(types, false /* animationFinished */, animationType, fromIme); + onAnimationStateChanged(types, true /* running */); + + if (fromIme) { + switch (animationType) { + case ANIMATION_TYPE_SHOW: + Trace.asyncTraceEnd(TRACE_TAG_VIEW, "IC.showRequestFromIme", 0); + break; + case ANIMATION_TYPE_HIDE: + Trace.asyncTraceEnd(TRACE_TAG_VIEW, "IC.hideRequestFromIme", 0); + break; + } + } else if (animationType == ANIMATION_TYPE_HIDE) { + Trace.asyncTraceEnd(TRACE_TAG_VIEW, "IC.hideRequestFromApi", 0); } - reportRequestedVisibleTypes(); } // TODO(b/242962223): Make this setter restrictive. @@ -1228,11 +1269,6 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation boolean canRun = true; if (show) { // Show request - if (fromIme) { - ImeTracing.getInstance().triggerClientDump( - "ImeInsetsSourceConsumer#requestShow", mHost.getInputMethodManager(), - null /* icProto */); - } switch(consumer.requestShow(fromIme)) { case ShowResult.SHOW_IMMEDIATELY: break; @@ -1246,15 +1282,11 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation // IME cannot be shown (since it didn't have focus), proceed // with animation of other types. canRun = false; + + // Reject the show request. + setRequestedVisibleTypes(0 /* visibleTypes */, consumer.getType()); break; } - } else { - // Hide request - // TODO: Move notifyHidden() to beginning of the hide animation - // (when visibility actually changes using hideDirectly()). - if (!fromIme) { - consumer.notifyHidden(); - } } if (!canRun) { if (WARN) Log.w(TAG, String.format( @@ -1266,24 +1298,6 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation if (control != null && control.getLeash() != null) { controls.put(control.getId(), new InsetsSourceControl(control)); typesReady |= 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. - if (fromIme) { - ImeTracing.getInstance().triggerClientDump( - "InsetsSourceConsumer#show", mHost.getInputMethodManager(), - null /* icProto */); - } - consumer.show(fromIme); - } else if (animationType == ANIMATION_TYPE_HIDE) { - if (fromIme) { - ImeTracing.getInstance().triggerClientDump( - "InsetsSourceConsumer#hide", mHost.getInputMethodManager(), - null /* icProto */); - } - consumer.hide(); } } return new Pair<>(typesReady, imeReady); @@ -1332,6 +1346,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation @VisibleForTesting @Override public void notifyFinished(InsetsAnimationControlRunner runner, boolean shown) { + setRequestedVisibleTypes(shown ? runner.getTypes() : 0, runner.getTypes()); cancelAnimation(runner, false /* invokeCallback */); if (DEBUG) Log.d(TAG, "notifyFinished. shown: " + shown); if (runner.getAnimationType() == ANIMATION_TYPE_RESIZE) { @@ -1343,15 +1358,13 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation if (shown) { ImeTracker.get().onProgress(statsToken, ImeTracker.PHASE_CLIENT_ANIMATION_FINISHED_SHOW); - showDirectly(runner.getTypes(), true /* fromIme */); ImeTracker.get().onShown(statsToken); } else { ImeTracker.get().onProgress(statsToken, ImeTracker.PHASE_CLIENT_ANIMATION_FINISHED_HIDE); - hideDirectly(runner.getTypes(), true /* animationFinished */, - runner.getAnimationType(), true /* fromIme */); ImeTracker.get().onHidden(statsToken); } + reportRequestedVisibleTypes(); } @Override @@ -1388,28 +1401,31 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation "cancelAnimation of types: %d, animType: %d, host: %s", control.getTypes(), control.getAnimationType(), mHost.getRootViewTitle())); } - boolean stateChanged = false; + @InsetsType int removedTypes = 0; for (int i = mRunningAnimations.size() - 1; i >= 0; i--) { RunningAnimation runningAnimation = mRunningAnimations.get(i); if (runningAnimation.runner == control) { mRunningAnimations.remove(i); - ArraySet<Integer> types = toInternalType(control.getTypes()); - for (int j = types.size() - 1; j >= 0; j--) { - if (types.valueAt(j) == ITYPE_IME) { - ImeTracing.getInstance().triggerClientDump( - "InsetsSourceConsumer#notifyAnimationFinished", - mHost.getInputMethodManager(), null /* icProto */); - } - stateChanged |= getSourceConsumer(types.valueAt(j)).notifyAnimationFinished(); - } + removedTypes = control.getTypes(); if (invokeCallback) { dispatchAnimationEnd(runningAnimation.runner.getAnimation()); } break; } } - if (stateChanged) { - mHost.notifyInsetsChanged(); + onAnimationStateChanged(removedTypes, false /* running */); + } + + private void onAnimationStateChanged(@InsetsType int types, boolean running) { + boolean insetsChanged = false; + for (int i = mSourceConsumers.size() - 1; i >= 0; i--) { + final InsetsSourceConsumer consumer = mSourceConsumers.valueAt(i); + if ((consumer.getType() & types) != 0) { + insetsChanged |= consumer.onAnimationStateChanged(running); + } + } + if (insetsChanged) { + notifyVisibilityChanged(); } } @@ -1472,27 +1488,28 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation return ANIMATION_TYPE_NONE; } - void setRequestedVisibleTypes(@InsetsType int visibleTypes, @InsetsType int mask) { + @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) + public void setRequestedVisibleTypes(@InsetsType int visibleTypes, @InsetsType int mask) { final @InsetsType int requestedVisibleTypes = (mRequestedVisibleTypes & ~mask) | (visibleTypes & mask); if (mRequestedVisibleTypes != requestedVisibleTypes) { - if (WindowInsets.Type.hasCompatSystemBars( - mRequestedVisibleTypes ^ requestedVisibleTypes)) { - mCompatSysUiVisibilityStaled = true; - } mRequestedVisibleTypes = requestedVisibleTypes; } } /** - * Sends the requested visible types to window manager if any of them is changed. + * Called when finishing setting requested visible types or finishing setting controls. */ private void reportRequestedVisibleTypes() { - updateCompatSysUiVisibility(); if (mReportedRequestedVisibleTypes != mRequestedVisibleTypes) { + final @InsetsType int diff = mRequestedVisibleTypes ^ mReportedRequestedVisibleTypes; + if (WindowInsets.Type.hasCompatSystemBars(diff)) { + mCompatSysUiVisibilityStaled = true; + } mReportedRequestedVisibleTypes = mRequestedVisibleTypes; mHost.updateRequestedVisibleTypes(mReportedRequestedVisibleTypes); } + updateCompatSysUiVisibility(); } @VisibleForTesting @@ -1538,39 +1555,6 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation !hasAnimationCallbacks /* useInsetsAnimationThread */, statsToken); } - private void hideDirectly(@InsetsType int types, boolean animationFinished, - @AnimationType int animationType, boolean fromIme) { - if ((types & ime()) != 0) { - ImeTracing.getInstance().triggerClientDump("InsetsController#hideDirectly", - mHost.getInputMethodManager(), null /* icProto */); - } - final ArraySet<Integer> internalTypes = InsetsState.toInternalType(types); - for (int i = internalTypes.size() - 1; i >= 0; i--) { - getSourceConsumer(internalTypes.valueAt(i)).hide(animationFinished, animationType); - } - reportRequestedVisibleTypes(); - - if (fromIme) { - Trace.asyncTraceEnd(TRACE_TAG_VIEW, "IC.hideRequestFromIme", 0); - } - } - - private void showDirectly(@InsetsType int types, boolean fromIme) { - if ((types & ime()) != 0) { - ImeTracing.getInstance().triggerClientDump("InsetsController#showDirectly", - mHost.getInputMethodManager(), null /* icProto */); - } - final ArraySet<Integer> internalTypes = InsetsState.toInternalType(types); - for (int i = internalTypes.size() - 1; i >= 0; i--) { - getSourceConsumer(internalTypes.valueAt(i)).show(false /* fromIme */); - } - reportRequestedVisibleTypes(); - - if (fromIme) { - Trace.asyncTraceEnd(TRACE_TAG_VIEW, "IC.showRequestFromIme", 0); - } - } - /** * Cancel on-going animation to show/hide {@link InsetsType}. */ diff --git a/core/java/android/view/InsetsSourceConsumer.java b/core/java/android/view/InsetsSourceConsumer.java index b8c4eaa782e7..7aeada8e9def 100644 --- a/core/java/android/view/InsetsSourceConsumer.java +++ b/core/java/android/view/InsetsSourceConsumer.java @@ -25,7 +25,6 @@ import static android.view.InsetsSourceConsumerProto.IS_REQUESTED_VISIBLE; import static android.view.InsetsSourceConsumerProto.PENDING_FRAME; import static android.view.InsetsSourceConsumerProto.PENDING_VISIBLE_FRAME; import static android.view.InsetsSourceConsumerProto.SOURCE_CONTROL; -import static android.view.InsetsState.ITYPE_IME; import static android.view.InsetsState.getDefaultVisibility; import static com.android.internal.annotations.VisibleForTesting.Visibility.PACKAGE; @@ -40,7 +39,6 @@ import android.view.SurfaceControl.Transaction; import android.view.WindowInsets.Type.InsetsType; import com.android.internal.annotations.VisibleForTesting; -import com.android.internal.inputmethod.ImeTracing; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -116,10 +114,6 @@ public class InsetsSourceConsumer { */ public boolean setControl(@Nullable InsetsSourceControl control, @InsetsType int[] showTypes, @InsetsType int[] hideTypes) { - if (mInternalType == ITYPE_IME) { - ImeTracing.getInstance().triggerClientDump("InsetsSourceConsumer#setControl", - mController.getHost().getInputMethodManager(), null /* icProto */); - } if (Objects.equals(mSourceControl, control)) { if (mSourceControl != null && mSourceControl != control) { mSourceControl.release(SurfaceControl::release); @@ -210,22 +204,27 @@ public class InsetsSourceConsumer { return mInternalType; } - @VisibleForTesting - public void show(boolean fromIme) { - if (DEBUG) Log.d(TAG, String.format("Call show() for type: %s fromIme: %b ", - InsetsState.typeToString(mInternalType), fromIme)); - setRequestedVisible(true); - } - - @VisibleForTesting - public void hide() { - if (DEBUG) Log.d(TAG, String.format("Call hide for %s on %s", - InsetsState.typeToString(mInternalType), mController.getHost().getRootViewTitle())); - setRequestedVisible(false); - } + /** + * Called right after the animation is started or finished. + */ + @VisibleForTesting(visibility = PACKAGE) + public boolean onAnimationStateChanged(boolean running) { + boolean insetsChanged = false; + if (!running && mPendingFrame != null) { + InsetsSource source = mState.getSource(mInternalType); + source.setFrame(mPendingFrame); + source.setVisibleFrame(mPendingVisibleFrame); + mPendingFrame = null; + mPendingVisibleFrame = null; + insetsChanged = true; + } - void hide(boolean animationFinished, @AnimationType int animationType) { - hide(); + // We apply the visibility override after the animation is started. We don't do this before + // that because we need to know the initial insets state while creating the animation. + // We also need to apply the override after the animation is finished because the requested + // visibility can be set when finishing the user animation. + insetsChanged |= applyLocalVisibilityOverride(); + return insetsChanged; } /** @@ -247,19 +246,14 @@ public class InsetsSourceConsumer { return mHasViewFocusWhenWindowFocusGain; } - boolean applyLocalVisibilityOverride() { + @VisibleForTesting(visibility = PACKAGE) + public boolean applyLocalVisibilityOverride() { final InsetsSource source = mState.peekSource(mInternalType); final boolean isVisible = source != null ? source.isVisible() : getDefaultVisibility( mInternalType); final boolean hasControl = mSourceControl != null; final boolean requestedVisible = (mController.getRequestedVisibleTypes() & mType) != 0; - if (mInternalType == ITYPE_IME) { - ImeTracing.getInstance().triggerClientDump( - "InsetsSourceConsumer#applyLocalVisibilityOverride", - mController.getHost().getInputMethodManager(), null /* icProto */); - } - // 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 " @@ -299,13 +293,6 @@ public class InsetsSourceConsumer { } /** - * Notify listeners that window is now hidden. - */ - void notifyHidden() { - // no-op for types that always return ShowResult#SHOW_IMMEDIATELY. - } - - /** * Remove surface on which this consumer type is drawn. */ public void removeSurface() { @@ -336,31 +323,6 @@ public class InsetsSourceConsumer { if (DEBUG) Log.d(TAG, "updateSource: " + newSource); } - @VisibleForTesting(visibility = PACKAGE) - public boolean notifyAnimationFinished() { - if (mPendingFrame != null) { - InsetsSource source = mState.getSource(mInternalType); - source.setFrame(mPendingFrame); - source.setVisibleFrame(mPendingVisibleFrame); - mPendingFrame = null; - mPendingVisibleFrame = null; - return true; - } - return false; - } - - /** - * Sets requested visibility from the client, regardless of whether we are able to control it at - * the moment. - */ - protected void setRequestedVisible(boolean requestedVisible) { - mController.setRequestedVisibleTypes(requestedVisible ? mType : 0, mType); - if (DEBUG) Log.d(TAG, "setRequestedVisible: " + requestedVisible); - if (applyLocalVisibilityOverride()) { - mController.notifyVisibilityChanged(); - } - } - private void applyRequestedVisibilityToControl() { if (mSourceControl == null || mSourceControl.getLeash() == null) { return; diff --git a/core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java b/core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java index 19ff5982f65f..597df0ba4949 100644 --- a/core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java +++ b/core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java @@ -102,7 +102,8 @@ public class InsetsAnimationControlImplTest { new InsetsSourceControl(ITYPE_NAVIGATION_BAR, WindowInsets.Type.navigationBars(), mNavLeash, true, new Point(400, 0), Insets.of(0, 0, 100, 0)), new int[1], new int[1]); - navConsumer.hide(); + mMockController.setRequestedVisibleTypes(0, WindowInsets.Type.navigationBars()); + navConsumer.applyLocalVisibilityOverride(); SparseArray<InsetsSourceControl> controls = new SparseArray<>(); controls.put(ITYPE_STATUS_BAR, topConsumer.getControl()); diff --git a/core/tests/coretests/src/android/view/InsetsControllerTest.java b/core/tests/coretests/src/android/view/InsetsControllerTest.java index fad9a5ca057c..88249ad0db4c 100644 --- a/core/tests/coretests/src/android/view/InsetsControllerTest.java +++ b/core/tests/coretests/src/android/view/InsetsControllerTest.java @@ -133,16 +133,9 @@ public class InsetsControllerTest { private boolean mImeRequestedShow; @Override - public void show(boolean fromIme) { - super.show(fromIme); - if (fromIme) { - mImeRequestedShow = true; - } - } - - @Override public int requestShow(boolean fromController) { if (fromController || mImeRequestedShow) { + mImeRequestedShow = true; return SHOW_IMMEDIATELY; } else { return IME_SHOW_DELAYED; @@ -815,10 +808,10 @@ public class InsetsControllerTest { InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> { prepareControls(); - // Hiding visible system bars should only causes insets change once for each bar. + // Calling to hide system bars once should only cause insets change once. clearInvocations(mTestHost); mController.hide(statusBars() | navigationBars()); - verify(mTestHost, times(2)).notifyInsetsChanged(); + verify(mTestHost, times(1)).notifyInsetsChanged(); // Sending the same insets state should not cause insets change. // This simulates the callback from server after hiding system bars. @@ -826,10 +819,10 @@ public class InsetsControllerTest { mController.onStateChanged(mController.getState()); verify(mTestHost, never()).notifyInsetsChanged(); - // Showing invisible system bars should only causes insets change once for each bar. + // Calling to show system bars once should only cause insets change once. clearInvocations(mTestHost); mController.show(statusBars() | navigationBars()); - verify(mTestHost, times(2)).notifyInsetsChanged(); + verify(mTestHost, times(1)).notifyInsetsChanged(); // Sending the same insets state should not cause insets change. // This simulates the callback from server after showing system bars. @@ -912,7 +905,7 @@ public class InsetsControllerTest { assertNull(imeInsetsConsumer.getControl()); // Verify IME requested visibility should be updated to IME consumer from controller. - mController.show(ime()); + mController.show(ime(), true /* fromIme */, null /* statsToken */); assertTrue(isRequestedVisible(mController, ime())); mController.hide(ime()); diff --git a/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java b/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java index 521b65edf2bd..cec3fc5ba2d8 100644 --- a/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java +++ b/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java @@ -29,7 +29,6 @@ import static junit.framework.TestCase.assertFalse; import static junit.framework.TestCase.assertTrue; import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.reset; import static org.mockito.Mockito.verify; @@ -119,30 +118,33 @@ public class InsetsSourceConsumerTest { } @Test - public void testHide() { + public void testOnAnimationStateChanged_requestedInvisible() { InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> { - mConsumer.hide(); + mController.setRequestedVisibleTypes(0 /* visibleTypes */, mSpyInsetsSource.getType()); + mConsumer.onAnimationStateChanged(false /* running */); verify(mSpyInsetsSource).setVisible(eq(false)); }); - } @Test - public void testShow() { + public void testOnAnimationStateChanged_requestedVisible() { InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> { // Insets source starts out visible - mConsumer.hide(); - mConsumer.show(false /* fromIme */); + final int type = mSpyInsetsSource.getType(); + mController.setRequestedVisibleTypes(0 /* visibleTypes */, type); + mConsumer.onAnimationStateChanged(false /* running */); + mController.setRequestedVisibleTypes(type, type); + mConsumer.onAnimationStateChanged(false /* running */); verify(mSpyInsetsSource).setVisible(eq(false)); verify(mSpyInsetsSource).setVisible(eq(true)); }); - } @Test public void testPendingStates() { InsetsState state = new InsetsState(); - InsetsController controller = mock(InsetsController.class); + InsetsController controller = new InsetsController(new ViewRootInsetsControllerHost( + mViewRoot)); InsetsSourceConsumer consumer = new InsetsSourceConsumer( ITYPE_IME, state, null, controller); @@ -156,7 +158,7 @@ public class InsetsSourceConsumerTest { assertEquals(new Rect(0, 1, 2, 3), state.peekSource(ITYPE_IME).getFrame()); // Finish the animation, now the pending frame should be applied - assertTrue(consumer.notifyAnimationFinished()); + assertTrue(consumer.onAnimationStateChanged(false /* running */)); assertEquals(new Rect(4, 5, 6, 7), state.peekSource(ITYPE_IME).getFrame()); // Animating again, updates are delayed @@ -169,7 +171,7 @@ public class InsetsSourceConsumerTest { source.setFrame(4, 5, 6, 7); consumer.updateSource(new InsetsSource(source), ANIMATION_TYPE_USER); - assertFalse(consumer.notifyAnimationFinished()); + assertFalse(consumer.onAnimationStateChanged(false /* running */)); assertEquals(new Rect(4, 5, 6, 7), state.peekSource(ITYPE_IME).getFrame()); } @@ -178,7 +180,7 @@ public class InsetsSourceConsumerTest { InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> { mConsumer.setControl(null, new int[1], new int[1]); reset(mMockTransaction); - mConsumer.hide(); + mController.setRequestedVisibleTypes(0 /* visibleTypes */, statusBars()); verifyZeroInteractions(mMockTransaction); int[] hideTypes = new int[1]; mConsumer.setControl( @@ -193,7 +195,7 @@ public class InsetsSourceConsumerTest { @Test public void testRestore_noAnimation() { InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> { - mConsumer.hide(); + mController.setRequestedVisibleTypes(0 /* visibleTypes */, statusBars()); mConsumer.setControl(null, new int[1], new int[1]); reset(mMockTransaction); verifyZeroInteractions(mMockTransaction); |