Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7cbbc225 authored by Winson Chung's avatar Winson Chung
Browse files

Workaround for back arrow being stuck on screen

- Whenever we defer the cleanup of the back gesture, schedule a failsafe
  to clean up the window if it's not handled properly.  We'll enable
  this failsafe for sc-dev and disable it for further investigations
  post sc-dev
- Dump additional info for the nav bar window so we can narrow down
  the issue post sc-dev

Bug: 190778197
Test: Can't repro the initial issue, so artificially trigger it to verify failsafe
Test: adb shell dumpsys activity service SystemUIService
Change-Id: I0a8f25babe750e6e5ba4c933ab5271a82ef63646
parent 50ffbb96
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -22,6 +22,8 @@ import android.view.WindowManager;

import com.android.systemui.plugins.annotations.ProvidesInterface;

import java.io.PrintWriter;

/** Plugin to handle navigation edge gestures for Back. */
@ProvidesInterface(
        action = NavigationEdgeBackPlugin.ACTION,
@@ -49,6 +51,9 @@ public interface NavigationEdgeBackPlugin extends Plugin {
    /** Updates the UI based on the motion events passed in device coordinates. */
    void onMotionEvent(MotionEvent motionEvent);

    /** Dumps info about the back gesture plugin. */
    void dump(PrintWriter pw);

    /** Callback to let the system react to the detected back gestures. */
    interface BackCallback {
        /** Indicates that a Back gesture was recognized and the system should go back. */
+3 −0
Original line number Diff line number Diff line
@@ -919,6 +919,9 @@ public class EdgeBackGestureHandler extends CurrentUserTracker
        pw.println("  mGestureLogInsideInsets=" + String.join("\n", mGestureLogInsideInsets));
        pw.println("  mGestureLogOutsideInsets=" + String.join("\n", mGestureLogOutsideInsets));
        pw.println("  mEdgeBackPlugin=" + mEdgeBackPlugin);
        if (mEdgeBackPlugin != null) {
            mEdgeBackPlugin.dump(pw);
        }
    }

    private boolean isGestureBlockingActivityRunning() {
+47 −0
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.Handler;
import android.os.SystemClock;
import android.os.VibrationEffect;
import android.util.Log;
@@ -56,13 +57,18 @@ import com.android.systemui.animation.Interpolators;
import com.android.systemui.plugins.NavigationEdgeBackPlugin;
import com.android.systemui.statusbar.VibratorHelper;

import java.io.PrintWriter;

public class NavigationBarEdgePanel extends View implements NavigationEdgeBackPlugin {

    private static final String TAG = "NavigationBarEdgePanel";

    private static final boolean ENABLE_FAILSAFE = true;

    private static final long COLOR_ANIMATION_DURATION_MS = 120;
    private static final long DISAPPEAR_FADE_ANIMATION_DURATION_MS = 80;
    private static final long DISAPPEAR_ARROW_ANIMATION_DURATION_MS = 100;
    private static final long FAILSAFE_DELAY_MS = 200;

    /**
     * The time required since the first vibration effect to automatically trigger a click
@@ -215,6 +221,9 @@ public class NavigationBarEdgePanel extends View implements NavigationEdgeBackPl
    private long mVibrationTime;
    private int mScreenSize;

    private final Handler mHandler = new Handler();
    private final Runnable mFailsafeRunnable = this::onFailsafe;

    private DynamicAnimation.OnAnimationEndListener mSetGoneEndListener
            = new DynamicAnimation.OnAnimationEndListener() {
        @Override
@@ -364,6 +373,7 @@ public class NavigationBarEdgePanel extends View implements NavigationEdgeBackPl

    @Override
    public void onDestroy() {
        cancelFailsafe();
        mWindowManager.removeView(this);
        mRegionSamplingHelper.stop();
        mRegionSamplingHelper = null;
@@ -635,6 +645,8 @@ public class NavigationBarEdgePanel extends View implements NavigationEdgeBackPl
            animate().alpha(0f).setDuration(DISAPPEAR_FADE_ANIMATION_DURATION_MS)
                    .withEndAction(() -> setVisibility(GONE));
            mArrowDisappearAnimation.start();
            // Schedule failsafe in case alpha end callback is not called
            scheduleFailsafe();
        };
        if (mTranslationAnimation.isRunning()) {
            mTranslationAnimation.addEndListener(new DynamicAnimation.OnAnimationEndListener() {
@@ -648,6 +660,8 @@ public class NavigationBarEdgePanel extends View implements NavigationEdgeBackPl
                    }
                }
            });
            // Schedule failsafe in case mTranslationAnimation end callback is not called
            scheduleFailsafe();
        } else {
            translationEnd.run();
        }
@@ -658,6 +672,8 @@ public class NavigationBarEdgePanel extends View implements NavigationEdgeBackPl

        if (mTranslationAnimation.isRunning()) {
            mTranslationAnimation.addEndListener(mSetGoneEndListener);
            // Schedule failsafe in case mTranslationAnimation end callback is not called
            scheduleFailsafe();
        } else {
            setVisibility(GONE);
        }
@@ -683,6 +699,7 @@ public class NavigationBarEdgePanel extends View implements NavigationEdgeBackPl
        mTotalTouchDelta = 0;
        mVibrationTime = 0;
        setDesiredVerticalTransition(0, false /* animated */);
        cancelFailsafe();
    }

    private void handleMoveEvent(MotionEvent event) {
@@ -867,7 +884,37 @@ public class NavigationBarEdgePanel extends View implements NavigationEdgeBackPl
        invalidate();
    }

    private void scheduleFailsafe() {
        if (!ENABLE_FAILSAFE) {
            return;
        }
        cancelFailsafe();
        mHandler.postDelayed(mFailsafeRunnable, FAILSAFE_DELAY_MS);
    }

    private void cancelFailsafe() {
        mHandler.removeCallbacks(mFailsafeRunnable);
    }

    private void onFailsafe() {
        setVisibility(GONE);
    }

    private float dp(float dp) {
        return mDensity * dp;
    }

    @Override
    public void dump(PrintWriter pw) {
        pw.println("NavigationBarEdgePanel:");
        pw.println("  mIsLeftPanel=" + mIsLeftPanel);
        pw.println("  mTriggerBack=" + mTriggerBack);
        pw.println("  mDragSlopPassed=" + mDragSlopPassed);
        pw.println("  mCurrentAngle=" + mCurrentAngle);
        pw.println("  mDesiredAngle=" + mDesiredAngle);
        pw.println("  mCurrentTranslation=" + mCurrentTranslation);
        pw.println("  mDesiredTranslation=" + mDesiredTranslation);
        pw.println("  mTranslationAnimation running=" + mTranslationAnimation.isRunning());
        mRegionSamplingHelper.dump(pw);
    }
}