summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/view/ImeInsetsSourceConsumer.java68
-rw-r--r--core/java/android/view/InsetsController.java12
-rw-r--r--core/java/android/view/InsetsSourceConsumer.java33
-rw-r--r--core/proto/android/view/imeinsetssourceconsumer.proto5
-rw-r--r--core/proto/android/view/insetssourceconsumer.proto1
5 files changed, 74 insertions, 45 deletions
diff --git a/core/java/android/view/ImeInsetsSourceConsumer.java b/core/java/android/view/ImeInsetsSourceConsumer.java
index f87b746fa72e..f06ba3b422df 100644
--- a/core/java/android/view/ImeInsetsSourceConsumer.java
+++ b/core/java/android/view/ImeInsetsSourceConsumer.java
@@ -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;
@@ -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,
@@ -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) {
- notifyHidden(null /* statsToken */);
- removeSurface();
- }
+ 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;
}
@@ -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.
@@ -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.
@@ -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;
}
}
diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java
index 8abe66afae4d..829321e3652b 100644
--- a/core/java/android/view/InsetsController.java
+++ b/core/java/android/view/InsetsController.java
@@ -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;
@@ -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) {
@@ -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);
@@ -1258,6 +1255,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
return;
}
+ cancelExistingControllers(typesReady);
final InsetsAnimationControlRunner runner = useInsetsAnimationThread
? new InsetsAnimationThreadControlRunner(controls,
@@ -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(
diff --git a/core/java/android/view/InsetsSourceConsumer.java b/core/java/android/view/InsetsSourceConsumer.java
index 47672a3ec18e..467d720196b1 100644
--- a/core/java/android/view/InsetsSourceConsumer.java
+++ b/core/java/android/view/InsetsSourceConsumer.java
@@ -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;
@@ -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;
@@ -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.
- insetsChanged |= applyLocalVisibilityOverride();
+ // 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
*/
@@ -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
*
@@ -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);
}
@@ -374,6 +402,7 @@ public class InsetsSourceConsumer {
if (mPendingVisibleFrame != null) {
mPendingVisibleFrame.dumpDebug(proto, PENDING_VISIBLE_FRAME);
}
+ proto.write(ANIMATION_STATE, mAnimationState);
proto.end(token);
}
}
diff --git a/core/proto/android/view/imeinsetssourceconsumer.proto b/core/proto/android/view/imeinsetssourceconsumer.proto
index 6e007fad5f8d..a85f6936d252 100644
--- a/core/proto/android/view/imeinsetssourceconsumer.proto
+++ b/core/proto/android/view/imeinsetssourceconsumer.proto
@@ -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
diff --git a/core/proto/android/view/insetssourceconsumer.proto b/core/proto/android/view/insetssourceconsumer.proto
index 487e06c1ccdf..a01ad8eea582 100644
--- a/core/proto/android/view/insetssourceconsumer.proto
+++ b/core/proto/android/view/insetssourceconsumer.proto
@@ -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