Loading core/java/android/view/ImeInsetsSourceConsumer.java +33 −35 Original line number Diff line number Diff line Loading @@ -17,10 +17,9 @@ package android.view; import static android.os.Trace.TRACE_TAG_VIEW; import static android.view.ImeInsetsSourceConsumerProto.HAS_PENDING_REQUEST; 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 android.annotation.Nullable; import android.os.IBinder; Loading @@ -43,20 +42,16 @@ import java.util.function.Supplier; public final class ImeInsetsSourceConsumer extends InsetsSourceConsumer { /** * Tracks whether we have an outstanding request from the IME to show, but weren't able to * execute it because we didn't have control yet. * Tracks whether are requested to show during the hide animation or requested to hide during * the show animation. If this is true, we should not remove the surface. */ private boolean mIsRequestedVisibleAwaitingControl; private boolean mIsHideAnimationRunning; private boolean mHasPendingRequest; /** * Tracks whether {@link WindowInsetsController#show(int)} or * {@link InputMethodManager#showSoftInput(View, int)} is called during IME hide animation. * If it was called, we should not call {@link InputMethodManager#notifyImeHidden(IBinder, * ImeTracker.Token)}, because the IME is being shown. * Tracks whether we have an outstanding request from the IME to show, but weren't able to * execute it because we didn't have control yet. */ private boolean mIsShowRequestedDuringHideAnimation; private boolean mIsRequestedVisibleAwaitingControl; public ImeInsetsSourceConsumer( int id, InsetsState state, Supplier<Transaction> transactionSupplier, Loading @@ -72,27 +67,19 @@ public final class ImeInsetsSourceConsumer extends InsetsSourceConsumer { mController.getHost().getInputMethodManager(), null /* icProto */); } final boolean insetsChanged = super.onAnimationStateChanged(running); final boolean showRequested = (mController.getRequestedVisibleTypes() & getType()) != 0; if (showRequested) { onShowRequested(); } else { if (!isShowRequested()) { mIsRequestedVisibleAwaitingControl = false; if (!running) { // Remove IME surface as IME has finished hide animation, if there is no pending // show request. if (!mIsShowRequestedDuringHideAnimation) { if (!running && !mHasPendingRequest) { notifyHidden(null /* statsToken */); 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; } // This method is called // (1) after the animation starts. // (2) after the animation ends (including the case of cancel). // (3) if the IME is not controllable (running == false in this case). // We should reset mHasPendingRequest in all cases. mHasPendingRequest = false; return insetsChanged; } Loading Loading @@ -132,6 +119,7 @@ public final class ImeInsetsSourceConsumer extends InsetsSourceConsumer { "ImeInsetsSourceConsumer#requestShow", mController.getHost().getInputMethodManager(), null /* icProto */); } onShowRequested(); // TODO: ResultReceiver for IME. // TODO: Set mShowOnNextImeRender to automatically show IME and guard it with a flag. Loading @@ -153,6 +141,17 @@ public final class ImeInsetsSourceConsumer extends InsetsSourceConsumer { ? ShowResult.IME_SHOW_DELAYED : ShowResult.IME_SHOW_FAILED; } void requestHide(boolean fromIme, @Nullable ImeTracker.Token statsToken) { if (!fromIme) { // The insets might be controlled by a remote target. Let the server know we are // requested to hide. notifyHidden(statsToken); } if (mAnimationState == ANIMATION_STATE_SHOW) { mHasPendingRequest = true; } } /** * Notify {@link com.android.server.inputmethod.InputMethodManagerService} that * IME insets are hidden. Loading Loading @@ -222,18 +221,17 @@ public final class ImeInsetsSourceConsumer extends InsetsSourceConsumer { final long token = proto.start(fieldId); super.dumpDebug(proto, INSETS_SOURCE_CONSUMER); proto.write(IS_REQUESTED_VISIBLE_AWAITING_CONTROL, mIsRequestedVisibleAwaitingControl); proto.write(IS_HIDE_ANIMATION_RUNNING, mIsHideAnimationRunning); proto.write(IS_SHOW_REQUESTED_DURING_HIDE_ANIMATION, mIsShowRequestedDuringHideAnimation); proto.write(HAS_PENDING_REQUEST, mHasPendingRequest); proto.end(token); } /** * Called when {@link #onAnimationStateChanged(boolean)} or * Called when {@link #requestShow(boolean, ImeTracker.Token)} or * {@link InputMethodManager#showSoftInput(View, int)} is called. */ public void onShowRequested() { if (mIsHideAnimationRunning) { mIsShowRequestedDuringHideAnimation = true; if (mAnimationState == ANIMATION_STATE_HIDE) { mHasPendingRequest = true; } } Loading core/java/android/view/InsetsController.java +6 −6 Original line number Diff line number Diff line Loading @@ -1203,8 +1203,6 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation return; } ImeTracker.get().onProgress(statsToken, ImeTracker.PHASE_CLIENT_DISABLED_USER_ANIMATION); cancelExistingControllers(types); if (DEBUG) Log.d(TAG, "controlAnimation types: " + types); mLastStartedAnimTypes |= types; Loading Loading @@ -1236,9 +1234,9 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation }); } // 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); // The requested visibilities should be delayed as well. Otherwise, we might override // the insets visibility before playing animation. setRequestedVisibleTypes(mReportedRequestedVisibleTypes, typesReady); Trace.asyncTraceEnd(TRACE_TAG_VIEW, "IC.showRequestFromApi", 0); if (!fromIme) { Loading @@ -1250,7 +1248,6 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation if (typesReady == 0) { if (DEBUG) Log.d(TAG, "No types ready. onCancelled()"); listener.onCancelled(null); reportRequestedVisibleTypes(); Trace.asyncTraceEnd(TRACE_TAG_VIEW, "IC.showRequestFromApi", 0); if (!fromIme) { Trace.asyncTraceEnd(TRACE_TAG_VIEW, "IC.showRequestFromApiToImeReady", 0); Loading @@ -1258,6 +1255,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation return; } cancelExistingControllers(typesReady); final InsetsAnimationControlRunner runner = useInsetsAnimationThread ? new InsetsAnimationThreadControlRunner(controls, Loading Loading @@ -1344,6 +1342,8 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation setRequestedVisibleTypes(0 /* visibleTypes */, consumer.getType()); break; } } else { consumer.requestHide(fromIme, statsToken); } if (!canRun) { if (WARN) Log.w(TAG, String.format( Loading core/java/android/view/InsetsSourceConsumer.java +31 −2 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package android.view; import static android.view.InsetsController.ANIMATION_TYPE_NONE; import static android.view.InsetsController.AnimationType; import static android.view.InsetsController.DEBUG; import static android.view.InsetsSourceConsumerProto.ANIMATION_STATE; import static android.view.InsetsSourceConsumerProto.HAS_WINDOW_FOCUS; import static android.view.InsetsSourceConsumerProto.INTERNAL_INSETS_TYPE; import static android.view.InsetsSourceConsumerProto.IS_REQUESTED_VISIBLE; Loading Loading @@ -73,6 +74,12 @@ public class InsetsSourceConsumer { int IME_SHOW_FAILED = 2; } protected static final int ANIMATION_STATE_NONE = 0; protected static final int ANIMATION_STATE_SHOW = 1; protected static final int ANIMATION_STATE_HIDE = 2; protected int mAnimationState = ANIMATION_STATE_NONE; protected final InsetsController mController; protected final InsetsState mState; private int mId; Loading Loading @@ -230,14 +237,31 @@ public class InsetsSourceConsumer { mPendingVisibleFrame = null; } final boolean showRequested = isShowRequested(); final boolean cancelledForNewAnimation = !running && showRequested ? mAnimationState == ANIMATION_STATE_HIDE : mAnimationState == ANIMATION_STATE_SHOW; mAnimationState = running ? (showRequested ? ANIMATION_STATE_SHOW : ANIMATION_STATE_HIDE) : ANIMATION_STATE_NONE; // 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. // If the animation is cancelled because we are going to play a new animation with an // opposite direction, don't apply it now but after the new animation is started. if (!cancelledForNewAnimation) { insetsChanged |= applyLocalVisibilityOverride(); } return insetsChanged; } protected boolean isShowRequested() { return (mController.getRequestedVisibleTypes() & getType()) != 0; } /** * Called when current window gains focus */ Loading Loading @@ -300,6 +324,10 @@ public class InsetsSourceConsumer { return ShowResult.SHOW_IMMEDIATELY; } void requestHide(boolean fromController, @Nullable ImeTracker.Token statsToken) { // no-op for types that always return ShowResult#SHOW_IMMEDIATELY. } /** * Reports that this source's perceptibility has changed * Loading Loading @@ -364,7 +392,7 @@ public class InsetsSourceConsumer { final long token = proto.start(fieldId); proto.write(INTERNAL_INSETS_TYPE, WindowInsets.Type.toString(mType)); proto.write(HAS_WINDOW_FOCUS, mHasWindowFocus); proto.write(IS_REQUESTED_VISIBLE, (mController.getRequestedVisibleTypes() & mType) != 0); proto.write(IS_REQUESTED_VISIBLE, isShowRequested()); if (mSourceControl != null) { mSourceControl.dumpDebug(proto, SOURCE_CONTROL); } Loading @@ -374,6 +402,7 @@ public class InsetsSourceConsumer { if (mPendingVisibleFrame != null) { mPendingVisibleFrame.dumpDebug(proto, PENDING_VISIBLE_FRAME); } proto.write(ANIMATION_STATE, mAnimationState); proto.end(token); } } core/proto/android/view/imeinsetssourceconsumer.proto +3 −2 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ message ImeInsetsSourceConsumerProto { optional InsetsSourceConsumerProto insets_source_consumer = 1; reserved 2; // focused_editor = 2 optional bool is_requested_visible_awaiting_control = 3; optional bool is_hide_animation_running = 4; optional bool is_show_requested_during_hide_animation = 5; optional bool is_hide_animation_running = 4 [deprecated=true]; optional bool is_show_requested_during_hide_animation = 5 [deprecated=true]; optional bool has_pending_request = 6; } No newline at end of file core/proto/android/view/insetssourceconsumer.proto +1 −0 Original line number Diff line number Diff line Loading @@ -33,4 +33,5 @@ message InsetsSourceConsumerProto { optional InsetsSourceControlProto source_control = 4; optional .android.graphics.RectProto pending_frame = 5; optional .android.graphics.RectProto pending_visible_frame = 6; optional int32 animation_state = 7; } No newline at end of file Loading
core/java/android/view/ImeInsetsSourceConsumer.java +33 −35 Original line number Diff line number Diff line Loading @@ -17,10 +17,9 @@ package android.view; import static android.os.Trace.TRACE_TAG_VIEW; import static android.view.ImeInsetsSourceConsumerProto.HAS_PENDING_REQUEST; 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 android.annotation.Nullable; import android.os.IBinder; Loading @@ -43,20 +42,16 @@ import java.util.function.Supplier; public final class ImeInsetsSourceConsumer extends InsetsSourceConsumer { /** * Tracks whether we have an outstanding request from the IME to show, but weren't able to * execute it because we didn't have control yet. * Tracks whether are requested to show during the hide animation or requested to hide during * the show animation. If this is true, we should not remove the surface. */ private boolean mIsRequestedVisibleAwaitingControl; private boolean mIsHideAnimationRunning; private boolean mHasPendingRequest; /** * Tracks whether {@link WindowInsetsController#show(int)} or * {@link InputMethodManager#showSoftInput(View, int)} is called during IME hide animation. * If it was called, we should not call {@link InputMethodManager#notifyImeHidden(IBinder, * ImeTracker.Token)}, because the IME is being shown. * Tracks whether we have an outstanding request from the IME to show, but weren't able to * execute it because we didn't have control yet. */ private boolean mIsShowRequestedDuringHideAnimation; private boolean mIsRequestedVisibleAwaitingControl; public ImeInsetsSourceConsumer( int id, InsetsState state, Supplier<Transaction> transactionSupplier, Loading @@ -72,27 +67,19 @@ public final class ImeInsetsSourceConsumer extends InsetsSourceConsumer { mController.getHost().getInputMethodManager(), null /* icProto */); } final boolean insetsChanged = super.onAnimationStateChanged(running); final boolean showRequested = (mController.getRequestedVisibleTypes() & getType()) != 0; if (showRequested) { onShowRequested(); } else { if (!isShowRequested()) { mIsRequestedVisibleAwaitingControl = false; if (!running) { // Remove IME surface as IME has finished hide animation, if there is no pending // show request. if (!mIsShowRequestedDuringHideAnimation) { if (!running && !mHasPendingRequest) { notifyHidden(null /* statsToken */); 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; } // This method is called // (1) after the animation starts. // (2) after the animation ends (including the case of cancel). // (3) if the IME is not controllable (running == false in this case). // We should reset mHasPendingRequest in all cases. mHasPendingRequest = false; return insetsChanged; } Loading Loading @@ -132,6 +119,7 @@ public final class ImeInsetsSourceConsumer extends InsetsSourceConsumer { "ImeInsetsSourceConsumer#requestShow", mController.getHost().getInputMethodManager(), null /* icProto */); } onShowRequested(); // TODO: ResultReceiver for IME. // TODO: Set mShowOnNextImeRender to automatically show IME and guard it with a flag. Loading @@ -153,6 +141,17 @@ public final class ImeInsetsSourceConsumer extends InsetsSourceConsumer { ? ShowResult.IME_SHOW_DELAYED : ShowResult.IME_SHOW_FAILED; } void requestHide(boolean fromIme, @Nullable ImeTracker.Token statsToken) { if (!fromIme) { // The insets might be controlled by a remote target. Let the server know we are // requested to hide. notifyHidden(statsToken); } if (mAnimationState == ANIMATION_STATE_SHOW) { mHasPendingRequest = true; } } /** * Notify {@link com.android.server.inputmethod.InputMethodManagerService} that * IME insets are hidden. Loading Loading @@ -222,18 +221,17 @@ public final class ImeInsetsSourceConsumer extends InsetsSourceConsumer { final long token = proto.start(fieldId); super.dumpDebug(proto, INSETS_SOURCE_CONSUMER); proto.write(IS_REQUESTED_VISIBLE_AWAITING_CONTROL, mIsRequestedVisibleAwaitingControl); proto.write(IS_HIDE_ANIMATION_RUNNING, mIsHideAnimationRunning); proto.write(IS_SHOW_REQUESTED_DURING_HIDE_ANIMATION, mIsShowRequestedDuringHideAnimation); proto.write(HAS_PENDING_REQUEST, mHasPendingRequest); proto.end(token); } /** * Called when {@link #onAnimationStateChanged(boolean)} or * Called when {@link #requestShow(boolean, ImeTracker.Token)} or * {@link InputMethodManager#showSoftInput(View, int)} is called. */ public void onShowRequested() { if (mIsHideAnimationRunning) { mIsShowRequestedDuringHideAnimation = true; if (mAnimationState == ANIMATION_STATE_HIDE) { mHasPendingRequest = true; } } Loading
core/java/android/view/InsetsController.java +6 −6 Original line number Diff line number Diff line Loading @@ -1203,8 +1203,6 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation return; } ImeTracker.get().onProgress(statsToken, ImeTracker.PHASE_CLIENT_DISABLED_USER_ANIMATION); cancelExistingControllers(types); if (DEBUG) Log.d(TAG, "controlAnimation types: " + types); mLastStartedAnimTypes |= types; Loading Loading @@ -1236,9 +1234,9 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation }); } // 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); // The requested visibilities should be delayed as well. Otherwise, we might override // the insets visibility before playing animation. setRequestedVisibleTypes(mReportedRequestedVisibleTypes, typesReady); Trace.asyncTraceEnd(TRACE_TAG_VIEW, "IC.showRequestFromApi", 0); if (!fromIme) { Loading @@ -1250,7 +1248,6 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation if (typesReady == 0) { if (DEBUG) Log.d(TAG, "No types ready. onCancelled()"); listener.onCancelled(null); reportRequestedVisibleTypes(); Trace.asyncTraceEnd(TRACE_TAG_VIEW, "IC.showRequestFromApi", 0); if (!fromIme) { Trace.asyncTraceEnd(TRACE_TAG_VIEW, "IC.showRequestFromApiToImeReady", 0); Loading @@ -1258,6 +1255,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation return; } cancelExistingControllers(typesReady); final InsetsAnimationControlRunner runner = useInsetsAnimationThread ? new InsetsAnimationThreadControlRunner(controls, Loading Loading @@ -1344,6 +1342,8 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation setRequestedVisibleTypes(0 /* visibleTypes */, consumer.getType()); break; } } else { consumer.requestHide(fromIme, statsToken); } if (!canRun) { if (WARN) Log.w(TAG, String.format( Loading
core/java/android/view/InsetsSourceConsumer.java +31 −2 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package android.view; import static android.view.InsetsController.ANIMATION_TYPE_NONE; import static android.view.InsetsController.AnimationType; import static android.view.InsetsController.DEBUG; import static android.view.InsetsSourceConsumerProto.ANIMATION_STATE; import static android.view.InsetsSourceConsumerProto.HAS_WINDOW_FOCUS; import static android.view.InsetsSourceConsumerProto.INTERNAL_INSETS_TYPE; import static android.view.InsetsSourceConsumerProto.IS_REQUESTED_VISIBLE; Loading Loading @@ -73,6 +74,12 @@ public class InsetsSourceConsumer { int IME_SHOW_FAILED = 2; } protected static final int ANIMATION_STATE_NONE = 0; protected static final int ANIMATION_STATE_SHOW = 1; protected static final int ANIMATION_STATE_HIDE = 2; protected int mAnimationState = ANIMATION_STATE_NONE; protected final InsetsController mController; protected final InsetsState mState; private int mId; Loading Loading @@ -230,14 +237,31 @@ public class InsetsSourceConsumer { mPendingVisibleFrame = null; } final boolean showRequested = isShowRequested(); final boolean cancelledForNewAnimation = !running && showRequested ? mAnimationState == ANIMATION_STATE_HIDE : mAnimationState == ANIMATION_STATE_SHOW; mAnimationState = running ? (showRequested ? ANIMATION_STATE_SHOW : ANIMATION_STATE_HIDE) : ANIMATION_STATE_NONE; // 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. // If the animation is cancelled because we are going to play a new animation with an // opposite direction, don't apply it now but after the new animation is started. if (!cancelledForNewAnimation) { insetsChanged |= applyLocalVisibilityOverride(); } return insetsChanged; } protected boolean isShowRequested() { return (mController.getRequestedVisibleTypes() & getType()) != 0; } /** * Called when current window gains focus */ Loading Loading @@ -300,6 +324,10 @@ public class InsetsSourceConsumer { return ShowResult.SHOW_IMMEDIATELY; } void requestHide(boolean fromController, @Nullable ImeTracker.Token statsToken) { // no-op for types that always return ShowResult#SHOW_IMMEDIATELY. } /** * Reports that this source's perceptibility has changed * Loading Loading @@ -364,7 +392,7 @@ public class InsetsSourceConsumer { final long token = proto.start(fieldId); proto.write(INTERNAL_INSETS_TYPE, WindowInsets.Type.toString(mType)); proto.write(HAS_WINDOW_FOCUS, mHasWindowFocus); proto.write(IS_REQUESTED_VISIBLE, (mController.getRequestedVisibleTypes() & mType) != 0); proto.write(IS_REQUESTED_VISIBLE, isShowRequested()); if (mSourceControl != null) { mSourceControl.dumpDebug(proto, SOURCE_CONTROL); } Loading @@ -374,6 +402,7 @@ public class InsetsSourceConsumer { if (mPendingVisibleFrame != null) { mPendingVisibleFrame.dumpDebug(proto, PENDING_VISIBLE_FRAME); } proto.write(ANIMATION_STATE, mAnimationState); proto.end(token); } }
core/proto/android/view/imeinsetssourceconsumer.proto +3 −2 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ message ImeInsetsSourceConsumerProto { optional InsetsSourceConsumerProto insets_source_consumer = 1; reserved 2; // focused_editor = 2 optional bool is_requested_visible_awaiting_control = 3; optional bool is_hide_animation_running = 4; optional bool is_show_requested_during_hide_animation = 5; optional bool is_hide_animation_running = 4 [deprecated=true]; optional bool is_show_requested_during_hide_animation = 5 [deprecated=true]; optional bool has_pending_request = 6; } No newline at end of file
core/proto/android/view/insetssourceconsumer.proto +1 −0 Original line number Diff line number Diff line Loading @@ -33,4 +33,5 @@ message InsetsSourceConsumerProto { optional InsetsSourceControlProto source_control = 4; optional .android.graphics.RectProto pending_frame = 5; optional .android.graphics.RectProto pending_visible_frame = 6; optional int32 animation_state = 7; } No newline at end of file