Merge "Fix the logic about notifyImeHidden and removeImeSurface"
This commit is contained in:
@@ -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;
|
||||
@@ -42,22 +41,18 @@ import java.util.function.Supplier;
|
||||
*/
|
||||
public final class ImeInsetsSourceConsumer extends InsetsSourceConsumer {
|
||||
|
||||
/**
|
||||
* 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 mHasPendingRequest;
|
||||
|
||||
/**
|
||||
* 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 mIsRequestedVisibleAwaitingControl;
|
||||
|
||||
private boolean mIsHideAnimationRunning;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
private boolean mIsShowRequestedDuringHideAnimation;
|
||||
|
||||
public ImeInsetsSourceConsumer(
|
||||
int id, InsetsState state, Supplier<Transaction> transactionSupplier,
|
||||
InsetsController controller) {
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
Reference in New Issue
Block a user