Fix one-handed-tutorial-overlay connection is permanently present
Ensure Tutorial window only exising when OHM enabled & triggered.
Bug: 172670809
Test: manual
Test: atest WMShellUnitTests
Change-Id: I8cb848a4da09a1c6676db4f7e6da2da580c8c986
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedTutorialHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedTutorialHandler.java
index d65ad62..a944e3b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedTutorialHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedTutorialHandler.java
@@ -63,6 +63,16 @@
private String mStartOneHandedDescription;
private String mStopOneHandedDescription;
+ private enum ONE_HANDED_TRIGGER_STATE {
+ UNSET, ENTERING, EXITING
+ }
+ /**
+ * Current One-Handed trigger state.
+ * Note: This is a dynamic state, whenever last state has been confirmed
+ * (i.e. onStartFinished() or onStopFinished()), the state should be set "UNSET" at final.
+ */
+ private ONE_HANDED_TRIGGER_STATE mTriggerState = ONE_HANDED_TRIGGER_STATE.UNSET;
+
/**
* Container of the tutorial panel showing at outside region when one handed starting
*/
@@ -74,6 +84,21 @@
public void onTutorialAnimationUpdate(int offset) {
mUpdateHandler.post(() -> onAnimationUpdate(offset));
}
+
+ @Override
+ public void onOneHandedAnimationStart(
+ OneHandedAnimationController.OneHandedTransitionAnimator animator) {
+ mUpdateHandler.post(() -> {
+ final Rect startValue = (Rect) animator.getStartValue();
+ if (mTriggerState == ONE_HANDED_TRIGGER_STATE.UNSET) {
+ mTriggerState = (startValue.top == 0)
+ ? ONE_HANDED_TRIGGER_STATE.ENTERING : ONE_HANDED_TRIGGER_STATE.EXITING;
+ if (mCanShowTutorial && mTriggerState == ONE_HANDED_TRIGGER_STATE.ENTERING) {
+ createTutorialTarget();
+ }
+ }
+ });
+ }
};
public OneHandedTutorialHandler(Context context) {
@@ -100,9 +125,6 @@
R.string.accessibility_action_start_one_handed);
mStopOneHandedDescription = context.getResources().getString(
R.string.accessibility_action_stop_one_handed);
- if (mCanShowTutorial) {
- createOrUpdateTutorialTarget();
- }
}
@Override
@@ -111,6 +133,7 @@
updateFinished(View.VISIBLE, 0f);
updateTutorialCount();
announcementForScreenReader(true);
+ mTriggerState = ONE_HANDED_TRIGGER_STATE.UNSET;
});
}
@@ -119,6 +142,8 @@
mUpdateHandler.post(() -> {
updateFinished(View.INVISIBLE, -mTargetViewContainer.getHeight());
announcementForScreenReader(false);
+ removeTutorialFromWindowManager();
+ mTriggerState = ONE_HANDED_TRIGGER_STATE.UNSET;
});
}
@@ -126,7 +151,6 @@
if (!canShowTutorial()) {
return;
}
-
mTargetViewContainer.setVisibility(visible);
mTargetViewContainer.setTranslationY(finalPosition);
}
@@ -155,24 +179,23 @@
* Adds the tutorial target view to the WindowManager and update its layout, so it's ready
* to be animated in.
*/
- private void createOrUpdateTutorialTarget() {
- mUpdateHandler.post(() -> {
- if (!mTargetViewContainer.isAttachedToWindow()) {
- mTargetViewContainer.setVisibility(View.INVISIBLE);
-
- try {
- mWindowManager.addView(mTargetViewContainer, getTutorialTargetLayoutParams());
- } catch (IllegalStateException e) {
- // This shouldn't happen, but if the target is already added, just update its
- // layout params.
- mWindowManager.updateViewLayout(
- mTargetViewContainer, getTutorialTargetLayoutParams());
- }
- } else {
- mWindowManager.updateViewLayout(mTargetViewContainer,
- getTutorialTargetLayoutParams());
+ private void createTutorialTarget() {
+ if (!mTargetViewContainer.isAttachedToWindow()) {
+ try {
+ mWindowManager.addView(mTargetViewContainer, getTutorialTargetLayoutParams());
+ } catch (IllegalStateException e) {
+ // This shouldn't happen, but if the target is already added, just update its
+ // layout params.
+ mWindowManager.updateViewLayout(
+ mTargetViewContainer, getTutorialTargetLayoutParams());
}
- });
+ }
+ }
+
+ private void removeTutorialFromWindowManager() {
+ if (mTargetViewContainer.isAttachedToWindow()) {
+ mWindowManager.removeViewImmediate(mTargetViewContainer);
+ }
}
OneHandedAnimationCallback getAnimationCallback() {
@@ -193,7 +216,6 @@
lp.privateFlags |= WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS;
lp.setFitInsetsTypes(0 /* types */);
lp.setTitle("one-handed-tutorial-overlay");
-
return lp;
}
@@ -206,10 +228,12 @@
private boolean canShowTutorial() {
if (!mCanShowTutorial) {
+ // Since canSHowTutorial() will be called in onAnimationUpdate() and we still need to
+ // hide Tutorial text in the period of continuously onAnimationUpdate() API call,
+ // so we have to hide mTargetViewContainer here.
mTargetViewContainer.setVisibility(View.GONE);
return false;
}
-
return true;
}