Support hasNavigationBar per display(1/2)
This change is to support Auto case.
Auto may need to support displays without navigation bar by default,
because the display may be far away from driver.
Note: currently, hasNavigationBar is global since it's from config.
In future patches, it will also check hasSystemDecorations() on
secondary display.
TODO: We may find a way to make OEMs set hasNavigationBar() for each
display.
Fixes: 119584629
Test: atest WmTests
Test: atest InputMethodManagerServiceTests
Test: atest SystemUiTests
Change-Id: I427f8ad1f3da644a2bf79ee5b777830378515348
diff --git a/config/hiddenapi-light-greylist.txt b/config/hiddenapi-light-greylist.txt
index ab1bf36..7e1b329 100644
--- a/config/hiddenapi-light-greylist.txt
+++ b/config/hiddenapi-light-greylist.txt
@@ -1435,7 +1435,7 @@
Landroid/view/IWindowManager$Stub$Proxy;->getBaseDisplayDensity(I)I
Landroid/view/IWindowManager$Stub$Proxy;->getDockedStackSide()I
Landroid/view/IWindowManager$Stub$Proxy;->getInitialDisplayDensity(I)I
-Landroid/view/IWindowManager$Stub$Proxy;->hasNavigationBar()Z
+Landroid/view/IWindowManager$Stub$Proxy;->hasNavigationBar(I)Z
Landroid/view/IWindowManager$Stub$Proxy;->watchRotation(Landroid/view/IRotationWatcher;I)I
Landroid/view/IWindowManager$Stub;-><init>()V
Landroid/view/IWindowManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/view/IWindowManager;
@@ -1447,7 +1447,7 @@
Landroid/view/IWindowManager;->getDockedStackSide()I
Landroid/view/IWindowManager;->getInitialDisplayDensity(I)I
Landroid/view/IWindowManager;->getInitialDisplaySize(ILandroid/graphics/Point;)V
-Landroid/view/IWindowManager;->hasNavigationBar()Z
+Landroid/view/IWindowManager;->hasNavigationBar(I)Z
Landroid/view/IWindowManager;->isKeyguardLocked()Z
Landroid/view/IWindowManager;->isKeyguardSecure()Z
Landroid/view/IWindowManager;->isSafeModeEnabled()Z
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index 308a000..6c4c3f1 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -294,9 +294,11 @@
void setNavBarVirtualKeyHapticFeedbackEnabled(boolean enabled);
/**
- * Device has a software navigation bar (separate from the status bar).
+ * Device has a software navigation bar (separate from the status bar) on specific display.
+ *
+ * @param displayId the id of display to check if there is a software navigation bar.
*/
- boolean hasNavigationBar();
+ boolean hasNavigationBar(int displayId);
/**
* Get the position of the nav bar
diff --git a/core/java/android/view/ViewConfiguration.java b/core/java/android/view/ViewConfiguration.java
index 767cd33..d03d97e 100644
--- a/core/java/android/view/ViewConfiguration.java
+++ b/core/java/android/view/ViewConfiguration.java
@@ -393,7 +393,7 @@
case HAS_PERMANENT_MENU_KEY_AUTODETECT: {
IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
try {
- sHasPermanentMenuKey = !wm.hasNavigationBar();
+ sHasPermanentMenuKey = !wm.hasNavigationBar(context.getDisplayId());
sHasPermanentMenuKeySet = true;
} catch (RemoteException ex) {
sHasPermanentMenuKey = false;
diff --git a/packages/SystemUI/legacy/recents/src/com/android/systemui/recents/misc/SystemServicesProxy.java b/packages/SystemUI/legacy/recents/src/com/android/systemui/recents/misc/SystemServicesProxy.java
index f8b61cd..44354bc1 100644
--- a/packages/SystemUI/legacy/recents/src/com/android/systemui/recents/misc/SystemServicesProxy.java
+++ b/packages/SystemUI/legacy/recents/src/com/android/systemui/recents/misc/SystemServicesProxy.java
@@ -302,11 +302,13 @@
}
/**
- * Returns whether there is a soft nav bar.
+ * Returns whether there is a soft nav bar on specified display.
+ *
+ * @param displayId the id of display to check if there is a software navigation bar.
*/
- public boolean hasSoftNavigationBar() {
+ public boolean hasSoftNavigationBar(int displayId) {
try {
- return mIwm.hasNavigationBar();
+ return mIwm.hasNavigationBar(displayId);
} catch (RemoteException e) {
e.printStackTrace();
}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowManagerWrapper.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowManagerWrapper.java
index 42e60aa..5cd7039 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowManagerWrapper.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowManagerWrapper.java
@@ -159,11 +159,13 @@
}
/**
- * @return whether there is a soft nav bar.
+ * @param displayId the id of display to check if there is a software navigation bar.
+ *
+ * @return whether there is a soft nav bar on specific display.
*/
- public boolean hasSoftNavigationBar() {
+ public boolean hasSoftNavigationBar(int displayId) {
try {
- return WindowManagerGlobal.getWindowManagerService().hasNavigationBar();
+ return WindowManagerGlobal.getWindowManagerService().hasNavigationBar(displayId);
} catch (RemoteException e) {
return false;
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java b/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java
index 216b940..f796793 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java
@@ -219,7 +219,7 @@
mLayout.findViewById(R.id.screen_pinning_text_area)
.setLayoutDirection(View.LAYOUT_DIRECTION_LOCALE);
View buttons = mLayout.findViewById(R.id.screen_pinning_buttons);
- if (WindowManagerWrapper.getInstance().hasSoftNavigationBar()) {
+ if (WindowManagerWrapper.getInstance().hasSoftNavigationBar(mContext.getDisplayId())) {
buttons.setLayoutDirection(View.LAYOUT_DIRECTION_LOCALE);
swapChildrenIfRtlAndVertical(buttons);
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/DisplayNavigationBarController.java b/packages/SystemUI/src/com/android/systemui/statusbar/DisplayNavigationBarController.java
index 3b611a31..2f26109 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/DisplayNavigationBarController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/DisplayNavigationBarController.java
@@ -22,8 +22,11 @@
import android.hardware.display.DisplayManager;
import android.hardware.display.DisplayManager.DisplayListener;
import android.os.Handler;
+import android.os.RemoteException;
+import android.util.Log;
import android.util.SparseArray;
import android.view.Display;
+import android.view.IWindowManager;
import android.view.View;
import android.view.WindowManagerGlobal;
@@ -34,6 +37,8 @@
*/
public class DisplayNavigationBarController implements DisplayListener {
+ private static final String TAG = DisplayNavigationBarController.class.getName();
+
private final Context mContext;
private final Handler mHandler;
private final DisplayManager mDisplayManager;
@@ -112,14 +117,23 @@
}
final int displayId = display.getDisplayId();
+ final IWindowManager wms = WindowManagerGlobal.getWindowManagerService();
+
+ try {
+ if (!wms.hasNavigationBar(displayId)) {
+ return;
+ }
+ } catch (RemoteException e) {
+ // Cannot get wms, just return with warning message.
+ Log.w(TAG, "Cannot get WindowManager.");
+ return;
+ }
final Context externalDisplayContext = mContext.createDisplayContext(display);
- NavigationBarFragment.create(externalDisplayContext,
- (tag, fragment) -> {
- final NavigationBarFragment navBar = (NavigationBarFragment) fragment;
- // TODO(b/115978725): handle external nav bars sysuiVisibility
- navBar.setCurrentSysuiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);
- mExternalNavigationBarMap.append(displayId, navBar);
- }
- );
+ NavigationBarFragment.create(externalDisplayContext, (tag, fragment) -> {
+ final NavigationBarFragment navBar = (NavigationBarFragment) fragment;
+ // TODO(b/115978725): handle external nav bars sysuiVisibility
+ navBar.setCurrentSysuiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);
+ mExternalNavigationBarMap.append(displayId, navBar);
+ });
}
}
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 bdddf5b..c5ddc0e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -22,6 +22,7 @@
import static android.app.StatusBarManager.WINDOW_STATE_SHOWING;
import static android.app.StatusBarManager.windowStateToString;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY;
+import static android.view.Display.DEFAULT_DISPLAY;
import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_ASLEEP;
import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_AWAKE;
@@ -843,16 +844,7 @@
mGroupAlertTransferHelper.setHeadsUpManager(mHeadsUpManager);
putComponent(HeadsUpManager.class, mHeadsUpManager);
-
- try {
- boolean showNav = mWindowManagerService.hasNavigationBar();
- if (DEBUG) Log.v(TAG, "hasNavigationBar=" + showNav);
- if (showNav) {
- createNavigationBar();
- }
- } catch (RemoteException ex) {
- // no window manager? good luck with that
- }
+ createNavigationBar();
if (ENABLE_LOCKSCREEN_WALLPAPER) {
mLockscreenWallpaper = new LockscreenWallpaper(mContext, this, mHandler);
@@ -1061,13 +1053,24 @@
}
protected void createNavigationBar() {
- mNavigationBarView = NavigationBarFragment.create(mContext, (tag, fragment) -> {
- mNavigationBar = (NavigationBarFragment) fragment;
- if (mLightBarController != null) {
- mNavigationBar.setLightBarController(mLightBarController);
- }
- mNavigationBar.setCurrentSysuiVisibility(mSystemUiVisibility);
- });
+ try {
+ // TODO(117478341): Move this into DisplayNavigationBarController#createNavigationBars
+ // for-loop. We will also move the whole navigation bar logic together.
+ final boolean showNav = mWindowManagerService.hasNavigationBar(DEFAULT_DISPLAY);
+ if (DEBUG) Log.v(TAG, "hasNavigationBar=" + showNav);
+ if (!showNav) return;
+
+ mNavigationBarView = NavigationBarFragment.create(mContext, (tag, fragment) -> {
+ mNavigationBar = (NavigationBarFragment) fragment;
+ if (mLightBarController != null) {
+ mNavigationBar.setLightBarController(mLightBarController);
+ }
+ mNavigationBar.setCurrentSysuiVisibility(mSystemUiVisibility);
+ });
+ } catch (RemoteException ex) {
+ // no window manager? good luck with that
+ }
+ mNavigationBarController.createNavigationBars();
}
/**
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index 1dfb86a..a8da968 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -2420,8 +2420,9 @@
.setContentText(summary)
.setContentIntent(mImeSwitchPendingIntent);
try {
+ // TODO(b/120076400): Figure out what is the best behavior
if ((mNotificationManager != null)
- && !mIWindowManager.hasNavigationBar()) {
+ && !mIWindowManager.hasNavigationBar(DEFAULT_DISPLAY)) {
if (DEBUG) {
Slog.d(TAG, "--- show notification: label = " + summary);
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 39a8465..6f5dfa4 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -5707,8 +5707,14 @@
}
@Override
- public boolean hasNavigationBar() {
- return mPolicy.hasNavigationBar();
+ public boolean hasNavigationBar(int displayId) {
+ synchronized (mGlobalLock) {
+ final DisplayContent dc = mRoot.getDisplayContent(displayId);
+ if (dc == null) {
+ return false;
+ }
+ return dc.getDisplayPolicy().hasNavigationBar();
+ }
}
@Override