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

Commit 3ddd7def authored by Andrii Kulian's avatar Andrii Kulian Committed by Charles Chen
Browse files

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
parent dce7d019
Loading
Loading
Loading
Loading
+9 −1
Original line number Diff line number Diff line
@@ -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() {
+29 −9
Original line number Diff line number Diff line
@@ -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,9 +420,13 @@ public class NavigationBarFragment extends Fragment implements Callbacks {
        }
        checkNavBarModes();
        mStatusBar.touchAutoHide();

        // TODO(115978725): Support light bar controller on external nav bars.
        if (mLightBarController != null) {
            mLightBarController.onNavigationVisibilityChanged(mSystemUiVisibility, 0 /* mask */,
                    true /* nbModeChanged */, mNavigationBarMode);
        }
    }

    @Override
    public void setSystemUiVisibility(int vis, int fullscreenStackVis, int dockedStackVis,
@@ -452,9 +457,12 @@ public class NavigationBarFragment extends Fragment implements Callbacks {
            }
        }

        // TODO(115978725): Support light bar controller on external nav bars.
        if (mLightBarController != null) {
            mLightBarController.onNavigationVisibilityChanged(vis, mask, nbModeChanged,
                    mNavigationBarMode);
        }
    }

    @Override
    public void disable(int state1, int state2, boolean animate) {
@@ -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);
+81 −0
Original line number Diff line number Diff line
@@ -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);