Loading core/java/android/view/ImeInsetsSourceConsumer.java +26 −5 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package android.view; import static android.view.InsetsState.ITYPE_IME; import static android.view.InsetsState.toPublicType; import android.annotation.Nullable; import android.inputmethodservice.InputMethodService; Loading Loading @@ -44,6 +45,12 @@ public final class ImeInsetsSourceConsumer extends InsetsSourceConsumer { */ private boolean mShowOnNextImeRender; /** * 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 mImeRequestedShow; public ImeInsetsSourceConsumer( InsetsState state, Supplier<Transaction> transactionSupplier, InsetsController controller) { Loading Loading @@ -81,13 +88,14 @@ public final class ImeInsetsSourceConsumer extends InsetsSourceConsumer { public void onWindowFocusLost() { super.onWindowFocusLost(); getImm().unregisterImeConsumer(this); mImeRequestedShow = false; } @Override public void setControl(@Nullable InsetsSourceControl control) { super.setControl(control); if (control == null) { hide(); public void show(boolean fromIme) { super.show(fromIme); if (fromIme) { mImeRequestedShow = true; } } Loading @@ -99,7 +107,11 @@ public final class ImeInsetsSourceConsumer extends InsetsSourceConsumer { public @ShowResult int requestShow(boolean fromIme) { // TODO: ResultReceiver for IME. // TODO: Set mShowOnNextImeRender to automatically show IME and guard it with a flag. if (fromIme) { // If we had a request before to show from IME (tracked with mImeRequestedShow), reaching // this code here means that we now got control, so we can start the animation immediately. if (fromIme || mImeRequestedShow) { mImeRequestedShow = false; return ShowResult.SHOW_IMMEDIATELY; } Loading @@ -115,6 +127,15 @@ public final class ImeInsetsSourceConsumer extends InsetsSourceConsumer { getImm().notifyImeHidden(); } @Override public void setControl(@Nullable InsetsSourceControl control, int[] showTypes, int[] hideTypes) { super.setControl(control, showTypes, hideTypes); if (control == null) { hide(); } } private boolean isDummyOrEmptyEditor(EditorInfo info) { // TODO(b/123044812): Handle dummy input gracefully in IME Insets API return info == null || (info.fieldId <= 0 && info.inputType <= 0); Loading core/java/android/view/InsetsAnimationControlImpl.java +4 −0 Original line number Diff line number Diff line Loading @@ -210,6 +210,10 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll mListener.onCancelled(); } public boolean isCancelled() { return mCancelled; } InsetsAnimation getAnimation() { return mAnimation; } Loading core/java/android/view/InsetsController.java +50 −16 Original line number Diff line number Diff line Loading @@ -39,6 +39,7 @@ import android.util.Log; import android.util.Pair; import android.util.Property; import android.util.SparseArray; import android.view.InputDevice.MotionRange; import android.view.InsetsSourceConsumer.ShowResult; import android.view.InsetsState.InternalInsetsType; import android.view.SurfaceControl.Transaction; Loading Loading @@ -273,7 +274,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation private final String TAG = "InsetsControllerImpl"; private final InsetsState mState = new InsetsState(); private final InsetsState mTmpState = new InsetsState(); private final InsetsState mLastDispachedState = new InsetsState(); private final Rect mFrame = new Rect(); private final BiFunction<InsetsController, Integer, InsetsSourceConsumer> mConsumerCreator; Loading Loading @@ -367,15 +368,20 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation return mState; } boolean onStateChanged(InsetsState state) { if (mState.equals(state)) { public InsetsState getLastDispatchedState() { return mLastDispachedState; } @VisibleForTesting public boolean onStateChanged(InsetsState state) { if (mState.equals(state) && mLastDispachedState.equals(state)) { return false; } mState.set(state); mTmpState.set(state, true /* copySources */); mLastDispachedState.set(state, true /* copySources */); applyLocalVisibilityOverride(); mViewRoot.notifyInsetsChanged(); if (!mState.equals(mTmpState)) { if (!mState.equals(mLastDispachedState)) { sendStateToWindowManager(); } return true; Loading Loading @@ -419,6 +425,9 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation } } int[] showTypes = new int[1]; int[] hideTypes = new int[1]; // Ensure to update all existing source consumers for (int i = mSourceConsumers.size() - 1; i >= 0; i--) { final InsetsSourceConsumer consumer = mSourceConsumers.valueAt(i); Loading @@ -426,15 +435,23 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation // control may be null, but we still need to update the control to null if it got // revoked. consumer.setControl(control); consumer.setControl(control, showTypes, hideTypes); } // Ensure to create source consumers if not available yet. for (int i = mTmpControlArray.size() - 1; i >= 0; i--) { final InsetsSourceControl control = mTmpControlArray.valueAt(i); getSourceConsumer(control.getType()).setControl(control); InsetsSourceConsumer consumer = getSourceConsumer(control.getType()); consumer.setControl(control, showTypes, hideTypes); } mTmpControlArray.clear(); if (showTypes[0] != 0) { applyAnimation(showTypes[0], true /* show */, false /* fromIme */); } if (hideTypes[0] != 0) { applyAnimation(hideTypes[0], false /* show */, false /* fromIme */); } } @Override Loading Loading @@ -465,7 +482,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation @InternalInsetsType int internalType = internalTypes.valueAt(i); @AnimationType int animationType = getAnimationType(internalType); InsetsSourceConsumer consumer = getSourceConsumer(internalType); if (mState.getSource(internalType).isVisible() && animationType == ANIMATION_TYPE_NONE if (consumer.isRequestedVisible() && animationType == ANIMATION_TYPE_NONE || animationType == ANIMATION_TYPE_SHOW) { // no-op: already shown or animating in (because window visibility is // applied before starting animation). Loading @@ -488,7 +505,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation @InternalInsetsType int internalType = internalTypes.valueAt(i); @AnimationType int animationType = getAnimationType(internalType); InsetsSourceConsumer consumer = getSourceConsumer(internalType); if (!mState.getSource(internalType).isVisible() && animationType == ANIMATION_TYPE_NONE if (!consumer.isRequestedVisible() && animationType == ANIMATION_TYPE_NONE || animationType == ANIMATION_TYPE_HIDE) { // no-op: already hidden or animating out. continue; Loading Loading @@ -535,7 +552,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation final SparseArray<InsetsSourceControl> controls = new SparseArray<>(); Pair<Integer, Boolean> typesReadyPair = collectSourceControls( fromIme, internalTypes, controls); fromIme, internalTypes, controls, animationType); int typesReady = typesReadyPair.first; boolean imeReady = typesReadyPair.second; if (!imeReady) { Loading @@ -562,17 +579,20 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation * @return Pair of (types ready to animate, IME ready to animate). */ private Pair<Integer, Boolean> collectSourceControls(boolean fromIme, ArraySet<Integer> internalTypes, SparseArray<InsetsSourceControl> controls) { ArraySet<Integer> internalTypes, SparseArray<InsetsSourceControl> controls, @AnimationType int animationType) { int typesReady = 0; boolean imeReady = true; for (int i = internalTypes.size() - 1; i >= 0; i--) { InsetsSourceConsumer consumer = getSourceConsumer(internalTypes.valueAt(i)); boolean setVisible = !consumer.isRequestedVisible(); if (setVisible) { boolean show = animationType == ANIMATION_TYPE_SHOW || animationType == ANIMATION_TYPE_USER; boolean canRun = false; if (show) { // Show request switch(consumer.requestShow(fromIme)) { case ShowResult.SHOW_IMMEDIATELY: typesReady |= InsetsState.toPublicType(consumer.getType()); canRun = true; break; case ShowResult.IME_SHOW_DELAYED: imeReady = false; Loading @@ -589,11 +609,22 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation if (!fromIme) { consumer.notifyHidden(); } typesReady |= InsetsState.toPublicType(consumer.getType()); canRun = true; } if (!canRun) { continue; } final InsetsSourceControl control = consumer.getControl(); if (control != null) { controls.put(consumer.getType(), control); typesReady |= toPublicType(consumer.getType()); } else if (animationType == ANIMATION_TYPE_SHOW) { // 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); } else if (animationType == ANIMATION_TYPE_HIDE) { consumer.hide(); } } return new Pair<>(typesReady, imeReady); Loading Loading @@ -808,7 +839,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation private void showDirectly(@InsetsType int types) { final ArraySet<Integer> internalTypes = InsetsState.toInternalType(types); for (int i = internalTypes.size() - 1; i >= 0; i--) { getSourceConsumer(internalTypes.valueAt(i)).show(); getSourceConsumer(internalTypes.valueAt(i)).show(false /* fromIme */); } } Loading Loading @@ -840,6 +871,9 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation @Override public boolean onPreDraw() { mViewRoot.mView.getViewTreeObserver().removeOnPreDrawListener(this); if (controller.isCancelled()) { return true; } mViewRoot.mView.dispatchWindowInsetsAnimationStart(animation, bounds); listener.onReady(controller, types); return true; Loading core/java/android/view/InsetsSourceConsumer.java +42 −13 Original line number Diff line number Diff line Loading @@ -17,11 +17,14 @@ package android.view; import static android.view.InsetsController.ANIMATION_TYPE_NONE; import static android.view.InsetsState.toPublicType; import android.annotation.IntDef; import android.annotation.Nullable; import android.util.MutableShort; import android.view.InsetsState.InternalInsetsType; import android.view.SurfaceControl.Transaction; import android.view.WindowInsets.Type.InsetsType; import com.android.internal.annotations.VisibleForTesting; Loading Loading @@ -71,18 +74,48 @@ public class InsetsSourceConsumer { mRequestedVisible = InsetsState.getDefaultVisibility(type); } public void setControl(@Nullable InsetsSourceControl control) { /** * Updates the control delivered from the server. * @param showTypes An integer array with a single entry that determines which types a show * animation should be run after setting the control. * @param hideTypes An integer array with a single entry that determines which types a hide * animation should be run after setting the control. */ public void setControl(@Nullable InsetsSourceControl control, @InsetsType int[] showTypes, @InsetsType int[] hideTypes) { if (mSourceControl == control) { return; } mSourceControl = control; applyHiddenToControl(); if (applyLocalVisibilityOverride()) { mController.notifyVisibilityChanged(); } // We are loosing control if (mSourceControl == null) { mController.notifyControlRevoked(this); // Restore server visibility. mState.getSource(getType()).setVisible( mController.getLastDispatchedState().getSource(getType()).isVisible()); applyLocalVisibilityOverride(); return; } // We are gaining control, and need to run an animation since previous state didn't match if (mRequestedVisible != mState.getSource(mType).isVisible()) { if (mRequestedVisible) { showTypes[0] |= toPublicType(getType()); } else { hideTypes[0] |= toPublicType(getType()); } return; } // We are gaining control, but don't need to run an animation. However make sure that the // leash visibility is still up to date. if (applyLocalVisibilityOverride()) { mController.notifyVisibilityChanged(); } applyHiddenToControl(); } @VisibleForTesting Loading @@ -95,7 +128,7 @@ public class InsetsSourceConsumer { } @VisibleForTesting public void show() { public void show(boolean fromIme) { setRequestedVisible(true); } Loading Loading @@ -172,17 +205,13 @@ public class InsetsSourceConsumer { * the moment. */ private void setRequestedVisible(boolean requestedVisible) { if (mRequestedVisible == requestedVisible) { return; } mRequestedVisible = requestedVisible; applyLocalVisibilityOverride(); if (applyLocalVisibilityOverride()) { mController.notifyVisibilityChanged(); } } private void applyHiddenToControl() { // TODO: Handle case properly when animation is running already (it shouldn't!) if (mSourceControl == null || mSourceControl.getLeash() == null) { return; } Loading core/java/android/view/ViewRootImpl.java +7 −1 Original line number Diff line number Diff line Loading @@ -4887,8 +4887,14 @@ public final class ViewRootImpl implements ViewParent, break; case MSG_INSETS_CONTROL_CHANGED: { SomeArgs args = (SomeArgs) msg.obj; mInsetsController.onControlsChanged((InsetsSourceControl[]) args.arg2); // Deliver state change before control change, such that: // a) When gaining control, controller can compare with server state to evaluate // whether it needs to run animation. // b) When loosing control, controller can restore server state by taking last // dispatched state as truth. mInsetsController.onStateChanged((InsetsState) args.arg1); mInsetsController.onControlsChanged((InsetsSourceControl[]) args.arg2); break; } case MSG_SHOW_INSETS: { Loading Loading
core/java/android/view/ImeInsetsSourceConsumer.java +26 −5 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package android.view; import static android.view.InsetsState.ITYPE_IME; import static android.view.InsetsState.toPublicType; import android.annotation.Nullable; import android.inputmethodservice.InputMethodService; Loading Loading @@ -44,6 +45,12 @@ public final class ImeInsetsSourceConsumer extends InsetsSourceConsumer { */ private boolean mShowOnNextImeRender; /** * 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 mImeRequestedShow; public ImeInsetsSourceConsumer( InsetsState state, Supplier<Transaction> transactionSupplier, InsetsController controller) { Loading Loading @@ -81,13 +88,14 @@ public final class ImeInsetsSourceConsumer extends InsetsSourceConsumer { public void onWindowFocusLost() { super.onWindowFocusLost(); getImm().unregisterImeConsumer(this); mImeRequestedShow = false; } @Override public void setControl(@Nullable InsetsSourceControl control) { super.setControl(control); if (control == null) { hide(); public void show(boolean fromIme) { super.show(fromIme); if (fromIme) { mImeRequestedShow = true; } } Loading @@ -99,7 +107,11 @@ public final class ImeInsetsSourceConsumer extends InsetsSourceConsumer { public @ShowResult int requestShow(boolean fromIme) { // TODO: ResultReceiver for IME. // TODO: Set mShowOnNextImeRender to automatically show IME and guard it with a flag. if (fromIme) { // If we had a request before to show from IME (tracked with mImeRequestedShow), reaching // this code here means that we now got control, so we can start the animation immediately. if (fromIme || mImeRequestedShow) { mImeRequestedShow = false; return ShowResult.SHOW_IMMEDIATELY; } Loading @@ -115,6 +127,15 @@ public final class ImeInsetsSourceConsumer extends InsetsSourceConsumer { getImm().notifyImeHidden(); } @Override public void setControl(@Nullable InsetsSourceControl control, int[] showTypes, int[] hideTypes) { super.setControl(control, showTypes, hideTypes); if (control == null) { hide(); } } private boolean isDummyOrEmptyEditor(EditorInfo info) { // TODO(b/123044812): Handle dummy input gracefully in IME Insets API return info == null || (info.fieldId <= 0 && info.inputType <= 0); Loading
core/java/android/view/InsetsAnimationControlImpl.java +4 −0 Original line number Diff line number Diff line Loading @@ -210,6 +210,10 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll mListener.onCancelled(); } public boolean isCancelled() { return mCancelled; } InsetsAnimation getAnimation() { return mAnimation; } Loading
core/java/android/view/InsetsController.java +50 −16 Original line number Diff line number Diff line Loading @@ -39,6 +39,7 @@ import android.util.Log; import android.util.Pair; import android.util.Property; import android.util.SparseArray; import android.view.InputDevice.MotionRange; import android.view.InsetsSourceConsumer.ShowResult; import android.view.InsetsState.InternalInsetsType; import android.view.SurfaceControl.Transaction; Loading Loading @@ -273,7 +274,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation private final String TAG = "InsetsControllerImpl"; private final InsetsState mState = new InsetsState(); private final InsetsState mTmpState = new InsetsState(); private final InsetsState mLastDispachedState = new InsetsState(); private final Rect mFrame = new Rect(); private final BiFunction<InsetsController, Integer, InsetsSourceConsumer> mConsumerCreator; Loading Loading @@ -367,15 +368,20 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation return mState; } boolean onStateChanged(InsetsState state) { if (mState.equals(state)) { public InsetsState getLastDispatchedState() { return mLastDispachedState; } @VisibleForTesting public boolean onStateChanged(InsetsState state) { if (mState.equals(state) && mLastDispachedState.equals(state)) { return false; } mState.set(state); mTmpState.set(state, true /* copySources */); mLastDispachedState.set(state, true /* copySources */); applyLocalVisibilityOverride(); mViewRoot.notifyInsetsChanged(); if (!mState.equals(mTmpState)) { if (!mState.equals(mLastDispachedState)) { sendStateToWindowManager(); } return true; Loading Loading @@ -419,6 +425,9 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation } } int[] showTypes = new int[1]; int[] hideTypes = new int[1]; // Ensure to update all existing source consumers for (int i = mSourceConsumers.size() - 1; i >= 0; i--) { final InsetsSourceConsumer consumer = mSourceConsumers.valueAt(i); Loading @@ -426,15 +435,23 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation // control may be null, but we still need to update the control to null if it got // revoked. consumer.setControl(control); consumer.setControl(control, showTypes, hideTypes); } // Ensure to create source consumers if not available yet. for (int i = mTmpControlArray.size() - 1; i >= 0; i--) { final InsetsSourceControl control = mTmpControlArray.valueAt(i); getSourceConsumer(control.getType()).setControl(control); InsetsSourceConsumer consumer = getSourceConsumer(control.getType()); consumer.setControl(control, showTypes, hideTypes); } mTmpControlArray.clear(); if (showTypes[0] != 0) { applyAnimation(showTypes[0], true /* show */, false /* fromIme */); } if (hideTypes[0] != 0) { applyAnimation(hideTypes[0], false /* show */, false /* fromIme */); } } @Override Loading Loading @@ -465,7 +482,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation @InternalInsetsType int internalType = internalTypes.valueAt(i); @AnimationType int animationType = getAnimationType(internalType); InsetsSourceConsumer consumer = getSourceConsumer(internalType); if (mState.getSource(internalType).isVisible() && animationType == ANIMATION_TYPE_NONE if (consumer.isRequestedVisible() && animationType == ANIMATION_TYPE_NONE || animationType == ANIMATION_TYPE_SHOW) { // no-op: already shown or animating in (because window visibility is // applied before starting animation). Loading @@ -488,7 +505,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation @InternalInsetsType int internalType = internalTypes.valueAt(i); @AnimationType int animationType = getAnimationType(internalType); InsetsSourceConsumer consumer = getSourceConsumer(internalType); if (!mState.getSource(internalType).isVisible() && animationType == ANIMATION_TYPE_NONE if (!consumer.isRequestedVisible() && animationType == ANIMATION_TYPE_NONE || animationType == ANIMATION_TYPE_HIDE) { // no-op: already hidden or animating out. continue; Loading Loading @@ -535,7 +552,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation final SparseArray<InsetsSourceControl> controls = new SparseArray<>(); Pair<Integer, Boolean> typesReadyPair = collectSourceControls( fromIme, internalTypes, controls); fromIme, internalTypes, controls, animationType); int typesReady = typesReadyPair.first; boolean imeReady = typesReadyPair.second; if (!imeReady) { Loading @@ -562,17 +579,20 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation * @return Pair of (types ready to animate, IME ready to animate). */ private Pair<Integer, Boolean> collectSourceControls(boolean fromIme, ArraySet<Integer> internalTypes, SparseArray<InsetsSourceControl> controls) { ArraySet<Integer> internalTypes, SparseArray<InsetsSourceControl> controls, @AnimationType int animationType) { int typesReady = 0; boolean imeReady = true; for (int i = internalTypes.size() - 1; i >= 0; i--) { InsetsSourceConsumer consumer = getSourceConsumer(internalTypes.valueAt(i)); boolean setVisible = !consumer.isRequestedVisible(); if (setVisible) { boolean show = animationType == ANIMATION_TYPE_SHOW || animationType == ANIMATION_TYPE_USER; boolean canRun = false; if (show) { // Show request switch(consumer.requestShow(fromIme)) { case ShowResult.SHOW_IMMEDIATELY: typesReady |= InsetsState.toPublicType(consumer.getType()); canRun = true; break; case ShowResult.IME_SHOW_DELAYED: imeReady = false; Loading @@ -589,11 +609,22 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation if (!fromIme) { consumer.notifyHidden(); } typesReady |= InsetsState.toPublicType(consumer.getType()); canRun = true; } if (!canRun) { continue; } final InsetsSourceControl control = consumer.getControl(); if (control != null) { controls.put(consumer.getType(), control); typesReady |= toPublicType(consumer.getType()); } else if (animationType == ANIMATION_TYPE_SHOW) { // 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); } else if (animationType == ANIMATION_TYPE_HIDE) { consumer.hide(); } } return new Pair<>(typesReady, imeReady); Loading Loading @@ -808,7 +839,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation private void showDirectly(@InsetsType int types) { final ArraySet<Integer> internalTypes = InsetsState.toInternalType(types); for (int i = internalTypes.size() - 1; i >= 0; i--) { getSourceConsumer(internalTypes.valueAt(i)).show(); getSourceConsumer(internalTypes.valueAt(i)).show(false /* fromIme */); } } Loading Loading @@ -840,6 +871,9 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation @Override public boolean onPreDraw() { mViewRoot.mView.getViewTreeObserver().removeOnPreDrawListener(this); if (controller.isCancelled()) { return true; } mViewRoot.mView.dispatchWindowInsetsAnimationStart(animation, bounds); listener.onReady(controller, types); return true; Loading
core/java/android/view/InsetsSourceConsumer.java +42 −13 Original line number Diff line number Diff line Loading @@ -17,11 +17,14 @@ package android.view; import static android.view.InsetsController.ANIMATION_TYPE_NONE; import static android.view.InsetsState.toPublicType; import android.annotation.IntDef; import android.annotation.Nullable; import android.util.MutableShort; import android.view.InsetsState.InternalInsetsType; import android.view.SurfaceControl.Transaction; import android.view.WindowInsets.Type.InsetsType; import com.android.internal.annotations.VisibleForTesting; Loading Loading @@ -71,18 +74,48 @@ public class InsetsSourceConsumer { mRequestedVisible = InsetsState.getDefaultVisibility(type); } public void setControl(@Nullable InsetsSourceControl control) { /** * Updates the control delivered from the server. * @param showTypes An integer array with a single entry that determines which types a show * animation should be run after setting the control. * @param hideTypes An integer array with a single entry that determines which types a hide * animation should be run after setting the control. */ public void setControl(@Nullable InsetsSourceControl control, @InsetsType int[] showTypes, @InsetsType int[] hideTypes) { if (mSourceControl == control) { return; } mSourceControl = control; applyHiddenToControl(); if (applyLocalVisibilityOverride()) { mController.notifyVisibilityChanged(); } // We are loosing control if (mSourceControl == null) { mController.notifyControlRevoked(this); // Restore server visibility. mState.getSource(getType()).setVisible( mController.getLastDispatchedState().getSource(getType()).isVisible()); applyLocalVisibilityOverride(); return; } // We are gaining control, and need to run an animation since previous state didn't match if (mRequestedVisible != mState.getSource(mType).isVisible()) { if (mRequestedVisible) { showTypes[0] |= toPublicType(getType()); } else { hideTypes[0] |= toPublicType(getType()); } return; } // We are gaining control, but don't need to run an animation. However make sure that the // leash visibility is still up to date. if (applyLocalVisibilityOverride()) { mController.notifyVisibilityChanged(); } applyHiddenToControl(); } @VisibleForTesting Loading @@ -95,7 +128,7 @@ public class InsetsSourceConsumer { } @VisibleForTesting public void show() { public void show(boolean fromIme) { setRequestedVisible(true); } Loading Loading @@ -172,17 +205,13 @@ public class InsetsSourceConsumer { * the moment. */ private void setRequestedVisible(boolean requestedVisible) { if (mRequestedVisible == requestedVisible) { return; } mRequestedVisible = requestedVisible; applyLocalVisibilityOverride(); if (applyLocalVisibilityOverride()) { mController.notifyVisibilityChanged(); } } private void applyHiddenToControl() { // TODO: Handle case properly when animation is running already (it shouldn't!) if (mSourceControl == null || mSourceControl.getLeash() == null) { return; } Loading
core/java/android/view/ViewRootImpl.java +7 −1 Original line number Diff line number Diff line Loading @@ -4887,8 +4887,14 @@ public final class ViewRootImpl implements ViewParent, break; case MSG_INSETS_CONTROL_CHANGED: { SomeArgs args = (SomeArgs) msg.obj; mInsetsController.onControlsChanged((InsetsSourceControl[]) args.arg2); // Deliver state change before control change, such that: // a) When gaining control, controller can compare with server state to evaluate // whether it needs to run animation. // b) When loosing control, controller can restore server state by taking last // dispatched state as truth. mInsetsController.onStateChanged((InsetsState) args.arg1); mInsetsController.onControlsChanged((InsetsSourceControl[]) args.arg2); break; } case MSG_SHOW_INSETS: { Loading