Show navigation bar on external displays
Add phone navigation bar in 2 situations:
1. When status bar is created and external
displays,which supports system decorations exist.
2. When new displays are added and the displays supports system
decorations
TODO: 1. Support nav bar logic in WM code.
2. Add lightController and more for external nav bars
3. Move the logic to DisplayNavigationController
Bug: 115978725
Test: Manual
Test: atest SystemUITests
Test: atest ActivityManagerMultiDisplayTests
Test: atest ActivityManagerMultiDisplayTests#testNavBarShowingOnDisplayWithDecor
Test: atest ActivityManagerMultiDisplayTests#testNavBarNotShowingOnDisplayWithoutDecor
Test: atest ActivityManagerMultiDisplayTests#testNavBarNotShowingOnPrivateDisplay
Change-Id: Ibf7c548d911ec2aca213b5ac0ecbd67f5f9fbeb5
This commit is contained in:
committed by
Charles Chen
parent
dce7d01911
commit
3ddd7def01
@@ -21,6 +21,7 @@ import android.car.drivingstate.CarDrivingStateEvent;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.util.Log;
|
||||
import android.view.Display;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
@@ -35,7 +36,6 @@ import com.android.systemui.R;
|
||||
import com.android.systemui.classifier.FalsingLog;
|
||||
import com.android.systemui.classifier.FalsingManager;
|
||||
import com.android.systemui.fragments.FragmentHostManager;
|
||||
import com.android.systemui.recents.Recents;
|
||||
import com.android.systemui.shared.system.ActivityManagerWrapper;
|
||||
import com.android.systemui.shared.system.TaskStackChangeListener;
|
||||
import com.android.systemui.statusbar.StatusBarState;
|
||||
@@ -268,6 +268,14 @@ public class CarStatusBar extends StatusBar implements
|
||||
buildNavBarWindows();
|
||||
buildNavBarContent();
|
||||
attachNavBarWindows();
|
||||
|
||||
// Add external navigation bars if more than one displays exist.
|
||||
final Display[] displays = mDisplayManager.getDisplays();
|
||||
|
||||
for (Display display : displays) {
|
||||
// TODO(115978725): Add phone navigationBar for now
|
||||
addExternalNavigationBar(display);
|
||||
}
|
||||
}
|
||||
|
||||
private void buildNavBarContent() {
|
||||
|
||||
@@ -55,7 +55,8 @@ import android.provider.Settings;
|
||||
import android.telecom.TelecomManager;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.view.IRotationWatcher.Stub;
|
||||
import android.view.Display;
|
||||
import android.view.Gravity;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MotionEvent;
|
||||
@@ -74,12 +75,12 @@ import com.android.internal.logging.MetricsLogger;
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
import com.android.internal.util.LatencyTracker;
|
||||
import com.android.systemui.Dependency;
|
||||
import com.android.systemui.recents.OverviewProxyService;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.SysUiServiceProvider;
|
||||
import com.android.systemui.assist.AssistManager;
|
||||
import com.android.systemui.fragments.FragmentHostManager;
|
||||
import com.android.systemui.fragments.FragmentHostManager.FragmentListener;
|
||||
import com.android.systemui.recents.OverviewProxyService;
|
||||
import com.android.systemui.recents.Recents;
|
||||
import com.android.systemui.shared.system.ActivityManagerWrapper;
|
||||
import com.android.systemui.stackdivider.Divider;
|
||||
@@ -419,8 +420,12 @@ public class NavigationBarFragment extends Fragment implements Callbacks {
|
||||
}
|
||||
checkNavBarModes();
|
||||
mStatusBar.touchAutoHide();
|
||||
mLightBarController.onNavigationVisibilityChanged(mSystemUiVisibility, 0 /* mask */,
|
||||
true /* nbModeChanged */, mNavigationBarMode);
|
||||
|
||||
// TODO(115978725): Support light bar controller on external nav bars.
|
||||
if (mLightBarController != null) {
|
||||
mLightBarController.onNavigationVisibilityChanged(mSystemUiVisibility, 0 /* mask */,
|
||||
true /* nbModeChanged */, mNavigationBarMode);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -452,8 +457,11 @@ public class NavigationBarFragment extends Fragment implements Callbacks {
|
||||
}
|
||||
}
|
||||
|
||||
mLightBarController.onNavigationVisibilityChanged(vis, mask, nbModeChanged,
|
||||
mNavigationBarMode);
|
||||
// TODO(115978725): Support light bar controller on external nav bars.
|
||||
if (mLightBarController != null) {
|
||||
mLightBarController.onNavigationVisibilityChanged(vis, mask, nbModeChanged,
|
||||
mNavigationBarMode);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -840,9 +848,17 @@ public class NavigationBarFragment extends Fragment implements Callbacks {
|
||||
};
|
||||
|
||||
public static View create(Context context, FragmentListener listener) {
|
||||
final int displayId = context.getDisplay().getDisplayId();
|
||||
final boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY);
|
||||
final int height = isDefaultDisplay
|
||||
? LayoutParams.MATCH_PARENT
|
||||
: context.getResources().getDimensionPixelSize(R.dimen.navigation_bar_height);
|
||||
WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
|
||||
LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT,
|
||||
WindowManager.LayoutParams.TYPE_NAVIGATION_BAR,
|
||||
LayoutParams.MATCH_PARENT, height,
|
||||
// TODO(b/117478341): Resolve one status bar/ navigation bar assumption
|
||||
isDefaultDisplay
|
||||
? WindowManager.LayoutParams.TYPE_NAVIGATION_BAR
|
||||
: WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL,
|
||||
WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING
|
||||
| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
|
||||
| WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
|
||||
@@ -851,9 +867,13 @@ public class NavigationBarFragment extends Fragment implements Callbacks {
|
||||
| WindowManager.LayoutParams.FLAG_SLIPPERY,
|
||||
PixelFormat.TRANSLUCENT);
|
||||
lp.token = new Binder();
|
||||
lp.setTitle("NavigationBar");
|
||||
lp.setTitle("NavigationBar" + displayId);
|
||||
lp.accessibilityTitle = context.getString(R.string.nav_bar);
|
||||
lp.windowAnimations = 0;
|
||||
if (!isDefaultDisplay) {
|
||||
lp.flags |= LayoutParams.PRIVATE_FLAG_IS_SCREEN_DECOR;
|
||||
lp.gravity = Gravity.BOTTOM;
|
||||
}
|
||||
|
||||
View navigationBarView = LayoutInflater.from(context).inflate(
|
||||
R.layout.navigation_bar_window, null);
|
||||
|
||||
@@ -22,6 +22,7 @@ import static android.app.StatusBarManager.WINDOW_STATE_HIDDEN;
|
||||
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;
|
||||
@@ -70,6 +71,8 @@ import android.content.res.Resources;
|
||||
import android.graphics.Point;
|
||||
import android.graphics.PointF;
|
||||
import android.graphics.Rect;
|
||||
import android.hardware.display.DisplayManager;
|
||||
import android.hardware.display.DisplayManager.DisplayListener;
|
||||
import android.media.AudioAttributes;
|
||||
import android.metrics.LogMaker;
|
||||
import android.net.Uri;
|
||||
@@ -96,6 +99,7 @@ import android.util.DisplayMetrics;
|
||||
import android.util.EventLog;
|
||||
import android.util.Log;
|
||||
import android.util.Slog;
|
||||
import android.util.SparseArray;
|
||||
import android.view.Display;
|
||||
import android.view.IWindowManager;
|
||||
import android.view.KeyEvent;
|
||||
@@ -558,8 +562,37 @@ public class StatusBar extends SystemUI implements DemoMode,
|
||||
}
|
||||
};
|
||||
|
||||
protected DisplayManager mDisplayManager;
|
||||
|
||||
private NavigationBarFragment mNavigationBar;
|
||||
private View mNavigationBarView;
|
||||
|
||||
/** A displayId - nav bar mapping */
|
||||
private SparseArray<NavigationBarFragment> mExternalNavigationBarMap = new SparseArray<>();
|
||||
|
||||
// TODO(b/115978725): Move it to DisplayNavigationBarController
|
||||
private final DisplayListener mDisplayListener = new DisplayListener() {
|
||||
@Override
|
||||
public void onDisplayAdded(int displayId) {
|
||||
final Display display = mDisplayManager.getDisplay(displayId);
|
||||
addExternalNavigationBar(display);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisplayRemoved(int displayId) {
|
||||
final NavigationBarFragment navBar = mExternalNavigationBarMap.get(displayId);
|
||||
if (navBar != null) {
|
||||
final View navigationView = navBar.getView().getRootView();
|
||||
WindowManagerGlobal.getInstance().removeView(navigationView, true);
|
||||
mExternalNavigationBarMap.remove(displayId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisplayChanged(int displayId) {
|
||||
}
|
||||
};
|
||||
|
||||
private HeadsUpAppearanceController mHeadsUpAppearanceController;
|
||||
private boolean mVibrateOnOpening;
|
||||
private VibratorHelper mVibratorHelper;
|
||||
@@ -618,6 +651,9 @@ public class StatusBar extends SystemUI implements DemoMode,
|
||||
mDisplay = mWindowManager.getDefaultDisplay();
|
||||
updateDisplaySize();
|
||||
|
||||
// get display service to detect display status
|
||||
mDisplayManager = (DisplayManager) mContext.getSystemService(Context.DISPLAY_SERVICE);
|
||||
|
||||
Resources res = mContext.getResources();
|
||||
mVibrateOnOpening = mContext.getResources().getBoolean(
|
||||
R.bool.config_vibrateOnIconAnimation);
|
||||
@@ -660,6 +696,7 @@ public class StatusBar extends SystemUI implements DemoMode,
|
||||
// If the system process isn't there we're doomed anyway.
|
||||
}
|
||||
|
||||
mDisplayManager.registerDisplayListener(mDisplayListener, mHandler);
|
||||
createAndAddWindows();
|
||||
|
||||
// Make sure we always have the most current wallpaper info.
|
||||
@@ -864,6 +901,7 @@ public class StatusBar extends SystemUI implements DemoMode,
|
||||
}
|
||||
});
|
||||
|
||||
// TODO(115978725): Support light bar controller on external nav bars.
|
||||
mLightBarController = Dependency.get(LightBarController.class);
|
||||
if (mNavigationBar != null) {
|
||||
mNavigationBar.setLightBarController(mLightBarController);
|
||||
@@ -1047,6 +1085,33 @@ public class StatusBar extends SystemUI implements DemoMode,
|
||||
}
|
||||
mNavigationBar.setCurrentSysuiVisibility(mSystemUiVisibility);
|
||||
});
|
||||
|
||||
// Add external navigation bars if more than one displays exist.
|
||||
final Display[] displays = mDisplayManager.getDisplays();
|
||||
for (Display display : displays) {
|
||||
addExternalNavigationBar(display);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a phone navigation bar on an external display if the display supports system decorations.
|
||||
*
|
||||
* @param display the display to add navigation bar on
|
||||
*/
|
||||
protected void addExternalNavigationBar(Display display) {
|
||||
if (display == null || display.getDisplayId() == DEFAULT_DISPLAY
|
||||
|| !display.supportsSystemDecorations()) {
|
||||
return;
|
||||
}
|
||||
|
||||
final int displayId = display.getDisplayId();
|
||||
final Context externalDisplayContext = mContext.createDisplayContext(display);
|
||||
NavigationBarFragment.create(externalDisplayContext,
|
||||
(tag, fragment) -> {
|
||||
final NavigationBarFragment navBar = (NavigationBarFragment) fragment;
|
||||
navBar.setCurrentSysuiVisibility(mSystemUiVisibility);
|
||||
mExternalNavigationBarMap.append(displayId, navBar);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2065,6 +2130,7 @@ public class StatusBar extends SystemUI implements DemoMode,
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(115978725): Support auto hide on external nav bars.
|
||||
void touchAutoHide() {
|
||||
// update transient bar autohide
|
||||
if (mStatusBarMode == MODE_SEMI_TRANSPARENT || (mNavigationBar != null
|
||||
@@ -2104,6 +2170,7 @@ public class StatusBar extends SystemUI implements DemoMode,
|
||||
: MODE_OPAQUE;
|
||||
}
|
||||
|
||||
// TODO(115978725): Support animations on external nav bars.
|
||||
void checkBarModes() {
|
||||
if (mDemoMode) return;
|
||||
if (mStatusBarView != null) checkBarMode(mStatusBarMode, mStatusBarWindowState,
|
||||
@@ -2123,6 +2190,7 @@ public class StatusBar extends SystemUI implements DemoMode,
|
||||
transitions.transitionTo(mode, anim);
|
||||
}
|
||||
|
||||
// TODO(115978725): Support animations on external nav bars.
|
||||
private void finishBarAnimations() {
|
||||
if (mStatusBarView != null) {
|
||||
mStatusBarView.getBarTransitions().finishAnimations();
|
||||
@@ -2856,6 +2924,16 @@ public class StatusBar extends SystemUI implements DemoMode,
|
||||
mWindowManager.removeViewImmediate(mNavigationBarView);
|
||||
mNavigationBarView = null;
|
||||
}
|
||||
mDisplayManager.unregisterDisplayListener(mDisplayListener);
|
||||
if (mExternalNavigationBarMap.size() > 0) {
|
||||
for (int i = 0; i < mExternalNavigationBarMap.size(); i++) {
|
||||
final View navigationWindow = mExternalNavigationBarMap.valueAt(i)
|
||||
.getView().getRootView();
|
||||
WindowManagerGlobal.getInstance()
|
||||
.removeView(navigationWindow, true /* immediate */);
|
||||
}
|
||||
mExternalNavigationBarMap.clear();
|
||||
}
|
||||
mContext.unregisterReceiver(mBroadcastReceiver);
|
||||
mContext.unregisterReceiver(mDemoReceiver);
|
||||
mAssistManager.destroy();
|
||||
@@ -2924,6 +3002,7 @@ public class StatusBar extends SystemUI implements DemoMode,
|
||||
"transparent".equals(mode) ? MODE_TRANSPARENT :
|
||||
"warning".equals(mode) ? MODE_WARNING :
|
||||
-1;
|
||||
// TODO(115978725): Support external nav bar transitions
|
||||
if (barMode != -1) {
|
||||
boolean animate = true;
|
||||
if (mStatusBarView != null) {
|
||||
@@ -3157,6 +3236,7 @@ public class StatusBar extends SystemUI implements DemoMode,
|
||||
mDraggedDownRow = null;
|
||||
}
|
||||
|
||||
// TODO(115978725): Support animations on external nav bars.
|
||||
// Disable layout transitions in navbar for this transition because the load is just
|
||||
// too heavy for the CPU and GPU on any device.
|
||||
if (mNavigationBar != null) {
|
||||
@@ -4425,6 +4505,7 @@ public class StatusBar extends SystemUI implements DemoMode,
|
||||
}
|
||||
// End Extra BaseStatusBarMethods.
|
||||
|
||||
// TODO(115978725): Handle dimming for external nav bars
|
||||
private final Runnable mAutoDim = () -> {
|
||||
if (mNavigationBar != null) {
|
||||
mNavigationBar.getBarTransitions().setAutoDim(true);
|
||||
|
||||
Reference in New Issue
Block a user