summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Riley Jones <jonesriley@google.com> 2023-10-25 20:33:18 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2023-10-25 20:33:18 +0000
commitc88b5c6727ebcd6c94a13b82288845547c818f4d (patch)
tree4365f323fb0aa17ff447de860627e3689d9dc607
parent3871106cdfd948d610717a7f74fccc46ac1ba1c2 (diff)
parent84156fc1b77b9d7a023604382178a4f2d9dc7bec (diff)
Merge "Implement smooth FAB animations for displacement due to IME visibility changes" into main
-rw-r--r--packages/SystemUI/Android.bp2
-rw-r--r--packages/SystemUI/aconfig/accessibility.aconfig7
-rw-r--r--packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuAnimationController.java100
-rw-r--r--packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuView.java28
-rw-r--r--packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayer.java7
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuAnimationControllerTest.java6
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayerTest.java73
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/accessibility/utils/FlagUtils.java1
8 files changed, 189 insertions, 35 deletions
diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp
index e6a82e83433b..17cc9f8135f4 100644
--- a/packages/SystemUI/Android.bp
+++ b/packages/SystemUI/Android.bp
@@ -485,6 +485,8 @@ android_library {
"motion_tool_lib",
"androidx.core_core-animation-testing-nodeps",
"androidx.compose.ui_ui",
+ "flag-junit",
+ "platform-test-annotations",
],
}
diff --git a/packages/SystemUI/aconfig/accessibility.aconfig b/packages/SystemUI/aconfig/accessibility.aconfig
index bcf1535b94fa..08ecf09b2365 100644
--- a/packages/SystemUI/aconfig/accessibility.aconfig
+++ b/packages/SystemUI/aconfig/accessibility.aconfig
@@ -8,3 +8,10 @@ flag {
description: "Adjusts bounds to allow the floating menu to render on top of navigation bars."
bug: "283768342"
}
+
+flag {
+ name: "floating_menu_ime_displacement_animation"
+ namespace: "accessibility"
+ description: "Adds an animation for when the FAB is displaced by an IME becoming visible."
+ bug: "281150010"
+} \ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuAnimationController.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuAnimationController.java
index 105de16ce66b..cd8bef1ab6ed 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuAnimationController.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuAnimationController.java
@@ -38,6 +38,7 @@ import androidx.recyclerview.widget.RecyclerView;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.Preconditions;
+import com.android.systemui.Flags;
import java.util.HashMap;
@@ -91,16 +92,48 @@ class MenuAnimationController {
}
void moveToPosition(PointF position) {
- moveToPositionX(position.x);
- moveToPositionY(position.y);
+ moveToPosition(position, /* animateMovement = */ false);
+ }
+
+ /* Moves position without updating underlying percentage position. Can be animated. */
+ void moveToPosition(PointF position, boolean animateMovement) {
+ if (Flags.floatingMenuImeDisplacementAnimation()) {
+ moveToPositionX(position.x, animateMovement);
+ moveToPositionY(position.y, animateMovement);
+ } else {
+ moveToPositionX(position.x, /* animateMovement = */ false);
+ moveToPositionY(position.y, /* animateMovement = */ false);
+ }
}
void moveToPositionX(float positionX) {
- DynamicAnimation.TRANSLATION_X.setValue(mMenuView, positionX);
+ moveToPositionX(positionX, /* animateMovement = */ false);
}
- private void moveToPositionY(float positionY) {
- DynamicAnimation.TRANSLATION_Y.setValue(mMenuView, positionY);
+ void moveToPositionX(float positionX, boolean animateMovement) {
+ if (animateMovement && Flags.floatingMenuImeDisplacementAnimation()) {
+ springMenuWith(DynamicAnimation.TRANSLATION_X,
+ createSpringForce(),
+ /* velocity = */ 0,
+ positionX, /* writeToPosition = */ false);
+ } else {
+ DynamicAnimation.TRANSLATION_X.setValue(mMenuView, positionX);
+ }
+ }
+
+ void moveToPositionY(float positionY) {
+ moveToPositionY(positionY, /* animateMovement = */ false);
+ }
+
+ void moveToPositionY(float positionY, boolean animateMovement) {
+ if (animateMovement && Flags.floatingMenuImeDisplacementAnimation()) {
+ springMenuWith(DynamicAnimation.TRANSLATION_Y,
+ createSpringForce(),
+ /* velocity = */ 0,
+ positionY, /* writeToPosition = */ false);
+ } else {
+ DynamicAnimation.TRANSLATION_Y.setValue(mMenuView, positionY);
+ }
}
void moveToPositionYIfNeeded(float positionY) {
@@ -151,7 +184,7 @@ class MenuAnimationController {
void moveAndPersistPosition(PointF position) {
moveToPosition(position);
mMenuView.onBoundsInParentChanged((int) position.x, (int) position.y);
- constrainPositionAndUpdate(position);
+ constrainPositionAndUpdate(position, /* writeToPosition = */ true);
}
void removeMenu() {
@@ -180,17 +213,13 @@ class MenuAnimationController {
flingThenSpringMenuWith(DynamicAnimation.TRANSLATION_X,
startXVelocity,
FLING_FRICTION_SCALAR,
- new SpringForce()
- .setStiffness(SPRING_STIFFNESS)
- .setDampingRatio(SPRING_AFTER_FLING_DAMPING_RATIO),
+ createSpringForce(),
finalPositionX);
flingThenSpringMenuWith(DynamicAnimation.TRANSLATION_Y,
velocityY,
FLING_FRICTION_SCALAR,
- new SpringForce()
- .setStiffness(SPRING_STIFFNESS)
- .setDampingRatio(SPRING_AFTER_FLING_DAMPING_RATIO),
+ createSpringForce(),
/* finalPosition= */ null);
}
@@ -226,7 +255,8 @@ class MenuAnimationController {
final float endPosition = finalPosition != null
? finalPosition
: Math.max(min, Math.min(max, endValue));
- springMenuWith(property, spring, endVelocity, endPosition);
+ springMenuWith(property, spring, endVelocity, endPosition,
+ /* writeToPosition = */ true);
});
cancelAnimation(property);
@@ -242,7 +272,7 @@ class MenuAnimationController {
@VisibleForTesting
void springMenuWith(DynamicAnimation.ViewProperty property, SpringForce spring,
- float velocity, float finalPosition) {
+ float velocity, float finalPosition, boolean writeToPosition) {
final MenuPositionProperty menuPositionProperty = new MenuPositionProperty(property);
final SpringAnimation springAnimation =
new SpringAnimation(mMenuView, menuPositionProperty)
@@ -257,7 +287,7 @@ class MenuAnimationController {
DynamicAnimation::isRunning);
if (!areAnimationsRunning) {
onSpringAnimationsEnd(new PointF(mMenuView.getTranslationX(),
- mMenuView.getTranslationY()));
+ mMenuView.getTranslationY()), writeToPosition);
}
})
.setStartVelocity(velocity);
@@ -281,7 +311,8 @@ class MenuAnimationController {
if (currentXTranslation < draggableBounds.left
|| currentXTranslation > draggableBounds.right) {
constrainPositionAndUpdate(
- new PointF(mMenuView.getTranslationX(), mMenuView.getTranslationY()));
+ new PointF(mMenuView.getTranslationX(), mMenuView.getTranslationY()),
+ /* writeToPosition = */ true);
moveToEdgeAndHide();
return true;
}
@@ -298,15 +329,19 @@ class MenuAnimationController {
return mMenuView.isMoveToTucked();
}
- void moveToEdgeAndHide() {
- mMenuView.updateMenuMoveToTucked(/* isMoveToTucked= */ true);
-
+ PointF getTuckedMenuPosition() {
final PointF position = mMenuView.getMenuPosition();
final float menuHalfWidth = mMenuView.getMenuWidth() / 2.0f;
final float endX = isOnLeftSide()
? position.x - menuHalfWidth
: position.x + menuHalfWidth;
- moveToPosition(new PointF(endX, position.y));
+ return new PointF(endX, position.y);
+ }
+
+ void moveToEdgeAndHide() {
+ mMenuView.updateMenuMoveToTucked(/* isMoveToTucked= */ true);
+ final PointF position = mMenuView.getMenuPosition();
+ moveToPosition(getTuckedMenuPosition());
// Keep the touch region let users could click extra space to pop up the menu view
// from the screen edge
@@ -335,6 +370,11 @@ class MenuAnimationController {
mPositionAnimations.get(property).cancel();
}
+ @VisibleForTesting
+ DynamicAnimation getAnimation(DynamicAnimation.ViewProperty property) {
+ return mPositionAnimations.getOrDefault(property, null);
+ }
+
void onDraggingStart() {
mMenuView.onDraggingStart();
}
@@ -361,9 +401,9 @@ class MenuAnimationController {
.start();
}
- private void onSpringAnimationsEnd(PointF position) {
+ private void onSpringAnimationsEnd(PointF position, boolean writeToPosition) {
mMenuView.onBoundsInParentChanged((int) position.x, (int) position.y);
- constrainPositionAndUpdate(position);
+ constrainPositionAndUpdate(position, writeToPosition);
fadeOutIfEnabled();
@@ -372,7 +412,7 @@ class MenuAnimationController {
}
}
- private void constrainPositionAndUpdate(PointF position) {
+ private void constrainPositionAndUpdate(PointF position, boolean writeToPosition) {
final Rect draggableBounds = mMenuView.getMenuDraggableBoundsExcludeIme();
// Have the space gap margin between the top bound and the menu view, so actually the
// position y range needs to cut the margin.
@@ -384,7 +424,12 @@ class MenuAnimationController {
final float percentageY = position.y < 0 || draggableBounds.height() == 0
? MIN_PERCENT
: Math.min(MAX_PERCENT, position.y / draggableBounds.height());
- mMenuView.persistPositionAndUpdateEdge(new Position(percentageX, percentageY));
+
+ if (Flags.floatingMenuImeDisplacementAnimation() && !writeToPosition) {
+ mMenuView.onEdgeChangedIfNeeded();
+ } else {
+ mMenuView.persistPositionAndUpdateEdge(new Position(percentageX, percentageY));
+ }
}
void updateOpacityWith(boolean isFadeEffectEnabled, float newOpacityValue) {
@@ -463,4 +508,11 @@ class MenuAnimationController {
mProperty.setValue(menuView, value);
}
}
+
+ @VisibleForTesting
+ static SpringForce createSpringForce() {
+ return new SpringForce()
+ .setStiffness(SPRING_STIFFNESS)
+ .setDampingRatio(SPRING_AFTER_FLING_DAMPING_RATIO);
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuView.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuView.java
index e1612b071458..ea5a56c6a0f5 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuView.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuView.java
@@ -54,7 +54,6 @@ class MenuView extends FrameLayout implements
private final List<AccessibilityTarget> mTargetFeatures = new ArrayList<>();
private final AccessibilityTargetAdapter mAdapter;
private final MenuViewModel mMenuViewModel;
- private final MenuAnimationController mMenuAnimationController;
private final Rect mBoundsInParent = new Rect();
private final RecyclerView mTargetFeaturesView;
private final ViewTreeObserver.OnDrawListener mSystemGestureExcludeUpdater =
@@ -70,6 +69,7 @@ class MenuView extends FrameLayout implements
private boolean mIsMoveToTucked;
+ private final MenuAnimationController mMenuAnimationController;
private OnTargetFeaturesChangeListener mFeaturesChangeListener;
MenuView(Context context, MenuViewModel menuViewModel, MenuViewAppearance menuViewAppearance) {
@@ -197,8 +197,30 @@ class MenuView extends FrameLayout implements
}
void onPositionChanged() {
- final PointF position = mMenuViewAppearance.getMenuPosition();
- mMenuAnimationController.moveToPosition(position);
+ onPositionChanged(/* animateMovement = */ false);
+ }
+
+ void onPositionChanged(boolean animateMovement) {
+ final PointF position;
+ if (isMoveToTucked()) {
+ position = mMenuAnimationController.getTuckedMenuPosition();
+ } else {
+ position = getMenuPosition();
+ }
+
+ // We can skip animating if FAB is not visible
+ if (Flags.floatingMenuImeDisplacementAnimation()
+ && animateMovement && getVisibility() == VISIBLE) {
+ mMenuAnimationController.moveToPosition(position, /* animateMovement = */ true);
+ // onArrivalAtPosition() is called at the end of the animation.
+ } else {
+ mMenuAnimationController.moveToPosition(position);
+ onArrivalAtPosition(); // no animation, so we call this immediately.
+ }
+ }
+
+ void onArrivalAtPosition() {
+ final PointF position = getMenuPosition();
onBoundsInParentChanged((int) position.x, (int) position.y);
if (isMoveToTucked()) {
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayer.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayer.java
index b6e8997c31e7..fbca02290236 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayer.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayer.java
@@ -59,6 +59,7 @@ import androidx.lifecycle.Observer;
import com.android.internal.accessibility.dialog.AccessibilityTarget;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.Preconditions;
+import com.android.systemui.Flags;
import com.android.systemui.res.R;
import com.android.systemui.util.settings.SecureSettings;
import com.android.wm.shell.bubbles.DismissViewUtils;
@@ -331,7 +332,7 @@ class MenuViewLayer extends FrameLayout implements
mMenuViewAppearance.onImeVisibilityChanged(windowInsets.isVisible(ime()), imeTop);
mMenuView.onEdgeChanged();
- mMenuView.onPositionChanged();
+ mMenuView.onPositionChanged(/* animateMovement = */ true);
mImeInsetsRect.set(imeInsetsRect);
}
@@ -362,6 +363,10 @@ class MenuViewLayer extends FrameLayout implements
mMenuAnimationController.startTuckedAnimationPreview();
}
+
+ if (Flags.floatingMenuImeDisplacementAnimation()) {
+ mMenuView.onArrivalAtPosition();
+ }
}
private CharSequence getMigrationMessage() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuAnimationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuAnimationControllerTest.java
index ec6ec63d213d..e8329409ff10 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuAnimationControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuAnimationControllerTest.java
@@ -234,10 +234,12 @@ public class MenuAnimationControllerTest extends SysuiTestCase {
mMenuAnimationController.springMenuWith(DynamicAnimation.TRANSLATION_X, new SpringForce()
.setStiffness(stiffness)
- .setDampingRatio(dampingRatio), velocity, finalPosition);
+ .setDampingRatio(dampingRatio), velocity, finalPosition,
+ /* writeToPosition = */ true);
mMenuAnimationController.springMenuWith(DynamicAnimation.TRANSLATION_Y, new SpringForce()
.setStiffness(stiffness)
- .setDampingRatio(dampingRatio), velocity, finalPosition);
+ .setDampingRatio(dampingRatio), velocity, finalPosition,
+ /* writeToPosition = */ true);
}
private void skipAnimationToEnd(DynamicAnimation animation) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayerTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayerTest.java
index aed795a440b4..76094c1cf185 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayerTest.java
@@ -42,6 +42,10 @@ import android.graphics.PointF;
import android.graphics.Rect;
import android.os.Build;
import android.os.UserHandle;
+import android.platform.test.annotations.RequiresFlagsDisabled;
+import android.platform.test.annotations.RequiresFlagsEnabled;
+import android.platform.test.flag.junit.CheckFlagsRule;
+import android.platform.test.flag.junit.DeviceFlagsValueProvider;
import android.provider.Settings;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
@@ -52,8 +56,10 @@ import android.view.WindowMetrics;
import android.view.accessibility.AccessibilityManager;
import androidx.dynamicanimation.animation.DynamicAnimation;
+import androidx.dynamicanimation.animation.SpringAnimation;
import androidx.test.filters.SmallTest;
+import com.android.systemui.Flags;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.util.settings.SecureSettings;
@@ -98,6 +104,10 @@ public class MenuViewLayerTest extends SysuiTestCase {
@Rule
public MockitoRule mockito = MockitoJUnit.rule();
+ @Rule
+ public final CheckFlagsRule mCheckFlagsRule =
+ DeviceFlagsValueProvider.createCheckFlagsRule();
+
@Mock
private IAccessibilityFloatingMenu mFloatingMenu;
@@ -116,7 +126,8 @@ public class MenuViewLayerTest extends SysuiTestCase {
final Rect mDisplayBounds = new Rect();
mDisplayBounds.set(/* left= */ 0, /* top= */ 0, DISPLAY_WINDOW_WIDTH,
DISPLAY_WINDOW_HEIGHT);
- mWindowMetrics = spy(new WindowMetrics(mDisplayBounds, fakeDisplayInsets()));
+ mWindowMetrics = spy(
+ new WindowMetrics(mDisplayBounds, fakeDisplayInsets(), /* density = */ 0.0f));
doReturn(mWindowMetrics).when(mStubWindowManager).getCurrentWindowMetrics();
mMenuViewLayer = new MenuViewLayer(mContext, mStubWindowManager, mStubAccessibilityManager,
@@ -221,27 +232,62 @@ public class MenuViewLayerTest extends SysuiTestCase {
}
@Test
+ @RequiresFlagsDisabled(Flags.FLAG_FLOATING_MENU_IME_DISPLACEMENT_ANIMATION)
+ public void showingImeInsetsChange_overlapOnIme_menuShownAboveIme_old() {
+ mMenuAnimationController.moveAndPersistPosition(new PointF(0, IME_TOP + 100));
+ final PointF beforePosition = mMenuView.getMenuPosition();
+
+ dispatchShowingImeInsets();
+
+ final float menuBottom = mMenuView.getTranslationY() + mMenuView.getMenuHeight();
+ assertThat(mMenuView.getTranslationX()).isEqualTo(beforePosition.x);
+ assertThat(menuBottom).isLessThan(beforePosition.y);
+ }
+
+ @Test
+ @RequiresFlagsEnabled(Flags.FLAG_FLOATING_MENU_IME_DISPLACEMENT_ANIMATION)
public void showingImeInsetsChange_overlapOnIme_menuShownAboveIme() {
mMenuAnimationController.moveAndPersistPosition(new PointF(0, IME_TOP + 100));
final PointF beforePosition = mMenuView.getMenuPosition();
dispatchShowingImeInsets();
+ assertThat(isPositionAnimationRunning()).isTrue();
+ skipPositionAnimations();
final float menuBottom = mMenuView.getTranslationY() + mMenuView.getMenuHeight();
+
assertThat(mMenuView.getTranslationX()).isEqualTo(beforePosition.x);
assertThat(menuBottom).isLessThan(beforePosition.y);
}
@Test
+ @RequiresFlagsDisabled(Flags.FLAG_FLOATING_MENU_IME_DISPLACEMENT_ANIMATION)
+ public void hidingImeInsetsChange_overlapOnIme_menuBackToOriginalPosition_old() {
+ mMenuAnimationController.moveAndPersistPosition(new PointF(0, IME_TOP + 200));
+ final PointF beforePosition = mMenuView.getMenuPosition();
+
+ dispatchHidingImeInsets();
+
+ assertThat(mMenuView.getTranslationX()).isEqualTo(beforePosition.x);
+ assertThat(mMenuView.getTranslationY()).isEqualTo(beforePosition.y);
+ }
+
+ @Test
+ @RequiresFlagsEnabled(Flags.FLAG_FLOATING_MENU_IME_DISPLACEMENT_ANIMATION)
public void hidingImeInsetsChange_overlapOnIme_menuBackToOriginalPosition() {
- final float menuTop = IME_TOP + 200;
- mMenuAnimationController.moveAndPersistPosition(new PointF(0, menuTop));
+ mMenuAnimationController.moveAndPersistPosition(new PointF(0, IME_TOP + 200));
+ final PointF beforePosition = mMenuView.getMenuPosition();
+
dispatchShowingImeInsets();
+ assertThat(isPositionAnimationRunning()).isTrue();
+ skipPositionAnimations();
dispatchHidingImeInsets();
+ assertThat(isPositionAnimationRunning()).isTrue();
+ skipPositionAnimations();
- assertThat(mMenuView.getTranslationX()).isEqualTo(0);
- assertThat(mMenuView.getTranslationY()).isEqualTo(menuTop);
+ assertThat(mMenuView.getTranslationX()).isEqualTo(beforePosition.x);
+ assertThat(mMenuView.getTranslationY()).isEqualTo(beforePosition.y);
}
private void setupEnabledAccessibilityServiceList() {
@@ -294,4 +340,21 @@ public class MenuViewLayerTest extends SysuiTestCase {
Insets.of(/* left= */ 0, /* top= */ 0, /* right= */ 0, bottom))
.build();
}
+
+ private boolean isPositionAnimationRunning() {
+ return !mMenuAnimationController.mPositionAnimations.values().stream().filter(
+ (animation) -> animation.isRunning()).findAny().isEmpty();
+ }
+
+ private void skipPositionAnimations() {
+ mMenuAnimationController.mPositionAnimations.values().stream().forEach(
+ (animation) -> {
+ final SpringAnimation springAnimation = ((SpringAnimation) animation);
+ // The doAnimationFrame function is used for skipping animation to the end.
+ springAnimation.doAnimationFrame(500);
+ springAnimation.skipToEnd();
+ springAnimation.doAnimationFrame(500);
+ });
+
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/utils/FlagUtils.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/utils/FlagUtils.java
index 297554956ed8..c7bb0f5d3906 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/utils/FlagUtils.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/utils/FlagUtils.java
@@ -31,5 +31,6 @@ public class FlagUtils {
*/
public static void setFlagDefaults(SetFlagsRule setFlagsRule) {
setFlagDefault(setFlagsRule, Flags.FLAG_FLOATING_MENU_OVERLAPS_NAV_BARS_FLAG);
+ setFlagDefault(setFlagsRule, Flags.FLAG_FLOATING_MENU_IME_DISPLACEMENT_ANIMATION);
}
}