Request transient bars after panic

Bug: 19282730
Change-Id: Ib621a837ba06847a02333e1786ea50e5d854c7d7
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index a4e9c68..7196165 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -51,7 +51,6 @@
 import android.media.Ringtone;
 import android.media.RingtoneManager;
 import android.media.session.MediaSessionLegacyHelper;
-import android.os.Build;
 import android.os.Bundle;
 import android.os.Debug;
 import android.os.FactoryTest;
@@ -97,7 +96,6 @@
 import android.view.Surface;
 import android.view.View;
 import android.view.ViewConfiguration;
-import android.view.ViewRootImpl;
 import android.view.Window;
 import android.view.WindowManager;
 import android.view.WindowManagerGlobal;
@@ -209,6 +207,10 @@
             .setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION)
             .build();
 
+    // The panic gesture may become active only after the keyguard is dismissed and the immersive
+    // app shows again. If that doesn't happen for 30s we drop the gesture.
+    private static final long PANIC_GESTURE_EXPIRATION = 30000;
+
     /**
      * Keyguard stuff
      */
@@ -457,6 +459,8 @@
     // What we last reported to system UI about whether the compatibility
     // menu needs to be displayed.
     boolean mLastFocusNeedsMenu = false;
+    // If nonzero, a panic gesture was performed at that time in uptime millis and is still pending.
+    private long mPendingPanicGestureUptime;
 
     FakeWindow mHideNavFakeWindow = null;
 
@@ -864,7 +868,7 @@
         boolean panic = mImmersiveModeConfirmation.onPowerKeyDown(interactive,
                 SystemClock.elapsedRealtime(), isImmersiveMode(mLastSystemUiFlags));
         if (panic) {
-            mHandler.post(mRequestTransientNav);
+            mHandler.post(mHiddenNavPanic);
         }
 
         // Latch power key state to detect screenshot chord.
@@ -5184,10 +5188,17 @@
         }
     };
 
-    private final Runnable mRequestTransientNav = new Runnable() {
+    private final Runnable mHiddenNavPanic = new Runnable() {
         @Override
         public void run() {
-            requestTransientBars(mNavigationBar);
+            synchronized (mWindowManagerFuncs.getWindowManagerLock()) {
+                if (!isUserSetupComplete()) {
+                    // Swipe-up for navigation bar is disabled during setup
+                    return;
+                }
+                mPendingPanicGestureUptime = SystemClock.uptimeMillis();
+                mNavigationBarController.showTransient();
+            }
         }
     };
 
@@ -6351,6 +6362,17 @@
                 mNavigationBar != null &&
                 hideNavBarSysui && immersiveSticky;
 
+        final long now = SystemClock.uptimeMillis();
+        final boolean pendingPanic = mPendingPanicGestureUptime != 0
+                && now - mPendingPanicGestureUptime <= PANIC_GESTURE_EXPIRATION;
+        if (pendingPanic && hideNavBarSysui && !isStatusBarKeyguard() && mKeyguardDrawComplete) {
+            // The user performed the panic gesture recently, we're about to hide the bars,
+            // we're no longer on the Keyguard and the screen is ready. We can now request the bars.
+            mPendingPanicGestureUptime = 0;
+            mStatusBarController.showTransient();
+            mNavigationBarController.showTransient();
+        }
+
         boolean denyTransientStatus = mStatusBarController.isTransientShowRequested()
                 && !transientStatusBarAllowed && hideStatusBarSysui;
         boolean denyTransientNav = mNavigationBarController.isTransientShowRequested()