Hide nav bar when keyguard on the 2nd display

Bug: 130963707
Test: atest SystemUITest
Test: atest DisplayPolicyLayoutTests#layoutWindowLw_keyguardDialog_hideNav
Test: manual - use chromecast with debug patch + force Desktop mode
               Press power key to make the lockscreen show and check if
	       nav bar is gone
Change-Id: I7f8f9c2c6d1157218e5dda1068170799fdccb64b
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java b/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java
index ae8bc52..050655c 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java
@@ -19,6 +19,7 @@
 
 import android.app.Presentation;
 import android.content.Context;
+import android.graphics.Color;
 import android.graphics.Point;
 import android.hardware.display.DisplayManager;
 import android.media.MediaRouter;
@@ -32,9 +33,11 @@
 import android.view.View;
 import android.view.WindowManager;
 
+import com.android.systemui.Dependency;
+import com.android.systemui.statusbar.NavigationBarController;
+import com.android.systemui.statusbar.phone.NavigationBarView;
 import com.android.systemui.util.InjectionInflationController;
 
-// TODO(multi-display): Support multiple external displays
 public class KeyguardDisplayManager {
     protected static final String TAG = "KeyguardDisplayManager";
     private static boolean DEBUG = KeyguardConstants.DEBUG;
@@ -49,6 +52,9 @@
 
     private final SparseArray<Presentation> mPresentations = new SparseArray<>();
 
+    private final NavigationBarController mNavBarController =
+            Dependency.get(NavigationBarController.class);
+
     private final DisplayManager.DisplayListener mDisplayListener =
             new DisplayManager.DisplayListener() {
 
@@ -56,6 +62,7 @@
         public void onDisplayAdded(int displayId) {
             final Display display = mDisplayService.getDisplay(displayId);
             if (mShowing) {
+                updateNavigationBarVisibility(displayId, false /* navBarVisible */);
                 showPresentation(display);
             }
         }
@@ -192,11 +199,15 @@
         if (showing) {
             final Display[] displays = mDisplayService.getDisplays();
             for (Display display : displays) {
+                int displayId = display.getDisplayId();
+                updateNavigationBarVisibility(displayId, false /* navBarVisible */);
                 changed |= showPresentation(display);
             }
         } else {
             changed = mPresentations.size() > 0;
             for (int i = mPresentations.size() - 1; i >= 0; i--) {
+                int displayId = mPresentations.keyAt(i);
+                updateNavigationBarVisibility(displayId, true /* navBarVisible */);
                 mPresentations.valueAt(i).dismiss();
             }
             mPresentations.clear();
@@ -204,6 +215,25 @@
         return changed;
     }
 
+    // TODO(b/127878649): this logic is from
+    //  {@link StatusBarKeyguardViewManager#updateNavigationBarVisibility}. Try to revisit a long
+    //  term solution in R.
+    private void updateNavigationBarVisibility(int displayId, boolean navBarVisible) {
+        // Leave this task to {@link StatusBarKeyguardViewManager}
+        if (displayId == DEFAULT_DISPLAY) return;
+
+        NavigationBarView navBarView = mNavBarController.getNavigationBarView(displayId);
+        // We may not have nav bar on a display.
+        if (navBarView == null) return;
+
+        if (navBarVisible) {
+            navBarView.getRootView().setVisibility(View.VISIBLE);
+        } else {
+            navBarView.getRootView().setVisibility(View.GONE);
+        }
+
+    }
+
     private final static class KeyguardPresentation extends Presentation {
         private static final int VIDEO_SAFE_REGION = 80; // Percentage of display width & height
         private static final int MOVE_CLOCK_TIMEOUT = 10000; // 10s
@@ -251,6 +281,15 @@
             LayoutInflater inflater = mInjectableInflater.injectable(
                     LayoutInflater.from(getContext()));
             setContentView(inflater.inflate(R.layout.keyguard_presentation, null));
+
+            // Logic to make the lock screen fullscreen
+            getWindow().getDecorView().setSystemUiVisibility(
+                    View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
+                            | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
+                            | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
+            getWindow().setNavigationBarContrastEnforced(false);
+            getWindow().setNavigationBarColor(Color.TRANSPARENT);
+
             mClock = findViewById(R.id.clock);
 
             // Avoid screen burn in
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NavigationBarController.java b/packages/SystemUI/src/com/android/systemui/statusbar/NavigationBarController.java
index bd25209..7bcbd36 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NavigationBarController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NavigationBarController.java
@@ -32,6 +32,8 @@
 import android.view.View;
 import android.view.WindowManagerGlobal;
 
+import androidx.annotation.Nullable;
+
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.statusbar.RegisterStatusBarResult;
 import com.android.systemui.Dependency;
@@ -213,8 +215,17 @@
     }
 
     /** @return {@link NavigationBarView} on the default display. */
-    public NavigationBarView getDefaultNavigationBarView() {
-        NavigationBarFragment navBar = mNavigationBars.get(DEFAULT_DISPLAY);
+    public @Nullable NavigationBarView getDefaultNavigationBarView() {
+        return getNavigationBarView(DEFAULT_DISPLAY);
+    }
+
+    /**
+     * @param displayId the ID of display which Navigation bar is on
+     * @return {@link NavigationBarView} on the display with {@code displayId}.
+     *         {@code null} if no navigation bar on that display.
+     */
+    public @Nullable NavigationBarView getNavigationBarView(int displayId) {
+        NavigationBarFragment navBar = mNavigationBars.get(displayId);
         return (navBar == null) ? null : (NavigationBarView) navBar.getView();
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index c01367a..776be00 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -3487,7 +3487,7 @@
 
     // TODO: Figure out way to remove these.
     public NavigationBarView getNavigationBarView() {
-        return mNavigationBarController.getDefaultNavigationBarView();
+        return mNavigationBarController.getNavigationBarView(mDisplayId);
     }
 
     /**
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index b6295e1..b8504db 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -70,6 +70,7 @@
 import static android.view.WindowManager.LayoutParams.TYPE_DREAM;
 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_CONSUMER;
 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
+import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG;
 import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
 import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL;
 import static android.view.WindowManager.LayoutParams.TYPE_SCREENSHOT;
@@ -2007,7 +2008,8 @@
                         pf.set(displayFrames.mOverscan);
                     } else if ((sysUiFl & SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) != 0
                             && (type >= FIRST_APPLICATION_WINDOW && type <= LAST_SUB_WINDOW
-                            || type == TYPE_VOLUME_OVERLAY)) {
+                            || type == TYPE_VOLUME_OVERLAY
+                            || type == TYPE_KEYGUARD_DIALOG)) {
                         // Asking for layout as if the nav bar is hidden, lets the application
                         // extend into the unrestricted overscan screen area. We only do this for
                         // application windows and certain system windows to ensure no window that
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 3834d57..dd3c600 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -1078,7 +1078,8 @@
                 + mRequestedWidth + ", mRequestedheight="
                 + mRequestedHeight + ") to" + " (pw=" + pw + ", ph=" + ph
                 + "): frame=" + mWindowFrames.mFrame.toShortString()
-                + " " + mWindowFrames.getInsetsInfo());
+                + " " + mWindowFrames.getInsetsInfo()
+                + " " + mAttrs.getTitle());
     }
 
     // TODO: Look into whether this override is still necessary.
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java
index e90f094..4a87aa4 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java
@@ -21,6 +21,7 @@
 import static android.view.Surface.ROTATION_90;
 import static android.view.View.SYSTEM_UI_FLAG_FULLSCREEN;
 import static android.view.View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
+import static android.view.View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION;
 import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
 import static android.view.WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
 import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR;
@@ -32,6 +33,7 @@
 import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
+import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG;
 
 import static org.hamcrest.Matchers.is;
 import static org.junit.Assert.assertEquals;
@@ -160,6 +162,25 @@
     }
 
     @Test
+    public void layoutWindowLw_keyguardDialog_hideNav() {
+        synchronized (mWm.mGlobalLock) {
+            mWindow.mAttrs.type = TYPE_KEYGUARD_DIALOG;
+            mWindow.mAttrs.flags |= FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
+            mWindow.mAttrs.systemUiVisibility = SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION;
+            addWindow(mWindow);
+
+            mDisplayPolicy.beginLayoutLw(mFrames, 0 /* uiMode */);
+            mDisplayPolicy.layoutWindowLw(mWindow, null /* attached */, mFrames);
+
+            assertInsetByTopBottom(mWindow.getParentFrame(), 0, 0);
+            assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+            assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+            assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);
+            assertInsetByTopBottom(mWindow.getDisplayFrameLw(), 0, 0);
+        }
+    }
+
+    @Test
     public void layoutWindowLw_withDisplayCutout() {
         synchronized (mWm.mGlobalLock) {
             addDisplayCutout();