diff --git a/packages/CarSystemUI/res/layout/sysui_primary_window.xml b/packages/CarSystemUI/res/layout/sysui_primary_window.xml index 309d9ef3ccfd8..cc36e87eb480a 100644 --- a/packages/CarSystemUI/res/layout/sysui_primary_window.xml +++ b/packages/CarSystemUI/res/layout/sysui_primary_window.xml @@ -15,9 +15,16 @@ ~ limitations under the License. --> + + + + \ No newline at end of file diff --git a/packages/CarSystemUI/src/com/android/systemui/car/SystemUIPrimaryWindowController.java b/packages/CarSystemUI/src/com/android/systemui/car/SystemUIPrimaryWindowController.java index e3e9ab75e3a2d..c7e14d677b045 100644 --- a/packages/CarSystemUI/src/com/android/systemui/car/SystemUIPrimaryWindowController.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/SystemUIPrimaryWindowController.java @@ -54,6 +54,7 @@ public class SystemUIPrimaryWindowController implements private ViewGroup mBaseLayout; private WindowManager.LayoutParams mLp; private WindowManager.LayoutParams mLpChanged; + private boolean mIsAttached = false; @Inject public SystemUIPrimaryWindowController( @@ -86,8 +87,17 @@ public class SystemUIPrimaryWindowController implements return mBaseLayout; } + /** Returns {@code true} if the window is already attached. */ + public boolean isAttached() { + return mIsAttached; + } + /** Attaches the window to the window manager. */ public void attach() { + if (mIsAttached) { + return; + } + mIsAttached = true; // Now that the status bar window encompasses the sliding panel and its // translucent backdrop, the entire thing is made TRANSLUCENT and is // hardware-accelerated. @@ -98,13 +108,14 @@ public class SystemUIPrimaryWindowController implements WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH - | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN, + | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN + | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE, PixelFormat.TRANSLUCENT); mLp.token = new Binder(); mLp.gravity = Gravity.TOP; mLp.setFitWindowInsetsTypes(/* types= */ 0); mLp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE; - mLp.setTitle("NotificationShade"); + mLp.setTitle("SystemUIPrimaryWindow"); mLp.packageName = mContext.getPackageName(); mLp.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS; @@ -118,8 +129,11 @@ public class SystemUIPrimaryWindowController implements // TODO: Update this so that the windowing type gets the full height of the display // when we use MATCH_PARENT. mLpChanged.height = mDisplayHeight + mNavBarHeight; + mLpChanged.flags &= ~WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; } else { mLpChanged.height = mStatusBarHeight; + // TODO: Allow touches to go through to the status bar to handle notification panel. + mLpChanged.flags |= WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; } updateWindow(); } @@ -131,7 +145,9 @@ public class SystemUIPrimaryWindowController implements private void updateWindow() { if (mLp != null && mLp.copyFrom(mLpChanged) != 0) { - mWindowManager.updateViewLayout(mBaseLayout, mLp); + if (isAttached()) { + mWindowManager.updateViewLayout(mBaseLayout, mLp); + } } } } diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java index 77db54c067c66..a79c9fb8ebbea 100644 --- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java +++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java @@ -68,6 +68,7 @@ import com.android.systemui.bubbles.BubbleController; import com.android.systemui.car.CarDeviceProvisionedController; import com.android.systemui.car.CarDeviceProvisionedListener; import com.android.systemui.car.CarServiceProvider; +import com.android.systemui.car.SystemUIPrimaryWindowController; import com.android.systemui.classifier.FalsingLog; import com.android.systemui.colorextraction.SysuiColorExtractor; import com.android.systemui.dagger.qualifiers.UiBackground; @@ -168,6 +169,7 @@ public class CarStatusBar extends StatusBar implements CarBatteryController.Batt // acceleration rate for the fling animation private static final float FLING_SPEED_UP_FACTOR = 0.6f; + private final UserSwitcherController mUserSwitcherController; private final ScrimController mScrimController; private final LockscreenLockIconController mLockscreenLockIconController; @@ -177,17 +179,16 @@ public class CarStatusBar extends StatusBar implements CarBatteryController.Batt private float mBackgroundAlphaDiff; private float mInitialBackgroundAlpha; - private final Lazy mFullscreenUserSwitcherLazy; - private FullscreenUserSwitcher mFullscreenUserSwitcher; - private CarBatteryController mCarBatteryController; private BatteryMeterView mBatteryMeterView; private Drawable mNotificationPanelBackground; private final Object mQueueLock = new Object(); + private final SystemUIPrimaryWindowController mSystemUIPrimaryWindowController; private final CarNavigationBarController mCarNavigationBarController; private final FlingAnimationUtils.Builder mFlingAnimationUtilsBuilder; private final Lazy mPowerManagerHelperLazy; + private final FullscreenUserSwitcher mFullscreenUserSwitcher; private final ShadeController mShadeController; private final CarServiceProvider mCarServiceProvider; private final CarDeviceProvisionedController mCarDeviceProvisionedController; @@ -338,7 +339,8 @@ public class CarStatusBar extends StatusBar implements CarBatteryController.Batt /* Car Settings injected components. */ CarServiceProvider carServiceProvider, Lazy powerManagerHelperLazy, - Lazy fullscreenUserSwitcherLazy, + FullscreenUserSwitcher fullscreenUserSwitcher, + SystemUIPrimaryWindowController systemUIPrimaryWindowController, CarNavigationBarController carNavigationBarController, FlingAnimationUtils.Builder flingAnimationUtilsBuilder) { super( @@ -422,6 +424,7 @@ public class CarStatusBar extends StatusBar implements CarBatteryController.Batt extensionController, userInfoControllerImpl, dismissCallbackRegistry); + mUserSwitcherController = userSwitcherController; mScrimController = scrimController; mLockscreenLockIconController = lockscreenLockIconController; mCarDeviceProvisionedController = @@ -429,7 +432,8 @@ public class CarStatusBar extends StatusBar implements CarBatteryController.Batt mShadeController = shadeController; mCarServiceProvider = carServiceProvider; mPowerManagerHelperLazy = powerManagerHelperLazy; - mFullscreenUserSwitcherLazy = fullscreenUserSwitcherLazy; + mFullscreenUserSwitcher = fullscreenUserSwitcher; + mSystemUIPrimaryWindowController = systemUIPrimaryWindowController; mCarNavigationBarController = carNavigationBarController; mFlingAnimationUtilsBuilder = flingAnimationUtilsBuilder; } @@ -444,6 +448,13 @@ public class CarStatusBar extends StatusBar implements CarBatteryController.Batt mScreenLifecycle = Dependency.get(ScreenLifecycle.class); mScreenLifecycle.addObserver(mScreenObserver); + // TODO: Remove the setup of user switcher from Car Status Bar. + mSystemUIPrimaryWindowController.attach(); + mFullscreenUserSwitcher.setStatusBar(this); + mFullscreenUserSwitcher.setContainer( + mSystemUIPrimaryWindowController.getBaseLayout().findViewById( + R.id.fullscreen_user_switcher_stub)); + // Notification bar related setup. mInitialBackgroundAlpha = (float) mContext.getResources().getInteger( R.integer.config_initialNotificationBackgroundAlpha) / 100; @@ -510,16 +521,6 @@ public class CarStatusBar extends StatusBar implements CarBatteryController.Batt }); } - /** - * Allows for showing or hiding just the navigation bars. This is indented to be used when - * the full screen user selector is shown. - */ - void setNavBarVisibility(@View.Visibility int visibility) { - mCarNavigationBarController.setBottomWindowVisibility(visibility); - mCarNavigationBarController.setLeftWindowVisibility(visibility); - mCarNavigationBarController.setRightWindowVisibility(visibility); - } - @Override public boolean hideKeyguard() { boolean result = super.hideKeyguard(); @@ -924,9 +925,6 @@ public class CarStatusBar extends StatusBar implements CarBatteryController.Batt + " scroll " + mStackScroller.getScrollX() + "," + mStackScroller.getScrollY()); } - - pw.print(" mFullscreenUserSwitcher="); - pw.println(mFullscreenUserSwitcher); pw.print(" mCarBatteryController="); pw.println(mCarBatteryController); pw.print(" mBatteryMeterView="); @@ -972,14 +970,7 @@ public class CarStatusBar extends StatusBar implements CarBatteryController.Batt @Override protected void createUserSwitcher() { - UserSwitcherController userSwitcherController = - Dependency.get(UserSwitcherController.class); - if (userSwitcherController.useFullscreenUserSwitcher()) { - mFullscreenUserSwitcher = mFullscreenUserSwitcherLazy.get(); - mFullscreenUserSwitcher.setStatusBar(this); - mFullscreenUserSwitcher.setContainer( - mStatusBarWindow.findViewById(R.id.fullscreen_user_switcher_stub)); - } else { + if (!mUserSwitcherController.useFullscreenUserSwitcher()) { super.createUserSwitcher(); } } @@ -996,25 +987,12 @@ public class CarStatusBar extends StatusBar implements CarBatteryController.Batt super.onStateChanged(newState); if (newState != StatusBarState.FULLSCREEN_USER_SWITCHER) { - hideUserSwitcher(); + mFullscreenUserSwitcher.hide(); } else { dismissKeyguardWhenUserSwitcherNotDisplayed(); } } - /** Makes the full screen user switcher visible, if applicable. */ - public void showUserSwitcher() { - if (mFullscreenUserSwitcher != null && mState == StatusBarState.FULLSCREEN_USER_SWITCHER) { - mFullscreenUserSwitcher.show(); // Makes the switcher visible. - } - } - - private void hideUserSwitcher() { - if (mFullscreenUserSwitcher != null) { - mFullscreenUserSwitcher.hide(); - } - } - final ScreenLifecycle.Observer mScreenObserver = new ScreenLifecycle.Observer() { @Override public void onScreenTurnedOn() { @@ -1024,7 +1002,7 @@ public class CarStatusBar extends StatusBar implements CarBatteryController.Batt // We automatically dismiss keyguard unless user switcher is being shown on the keyguard. private void dismissKeyguardWhenUserSwitcherNotDisplayed() { - if (mFullscreenUserSwitcher == null) { + if (!mUserSwitcherController.useFullscreenUserSwitcher()) { return; // Not using the full screen user switcher. } diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBarKeyguardViewManager.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBarKeyguardViewManager.java index 0ad0992b68a4a..2a2eb69766531 100644 --- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBarKeyguardViewManager.java +++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBarKeyguardViewManager.java @@ -24,6 +24,7 @@ import com.android.keyguard.KeyguardUpdateMonitor; import com.android.keyguard.ViewMediatorCallback; import com.android.systemui.R; import com.android.systemui.dock.DockManager; +import com.android.systemui.navigationbar.car.CarNavigationBarController; import com.android.systemui.statusbar.NotificationMediaManager; import com.android.systemui.statusbar.SysuiStatusBarStateController; import com.android.systemui.statusbar.phone.NavigationModeController; @@ -40,6 +41,8 @@ import javax.inject.Singleton; public class CarStatusBarKeyguardViewManager extends StatusBarKeyguardViewManager { protected boolean mShouldHideNavBar; + private final CarNavigationBarController mCarNavigationBarController; + private final FullscreenUserSwitcher mFullscreenUserSwitcher; @Inject public CarStatusBarKeyguardViewManager(Context context, @@ -52,13 +55,17 @@ public class CarStatusBarKeyguardViewManager extends StatusBarKeyguardViewManage DockManager dockManager, StatusBarWindowController statusBarWindowController, KeyguardStateController keyguardStateController, - NotificationMediaManager notificationMediaManager) { + NotificationMediaManager notificationMediaManager, + CarNavigationBarController carNavigationBarController, + FullscreenUserSwitcher fullscreenUserSwitcher) { super(context, callback, lockPatternUtils, sysuiStatusBarStateController, configurationController, keyguardUpdateMonitor, navigationModeController, dockManager, statusBarWindowController, keyguardStateController, notificationMediaManager); mShouldHideNavBar = context.getResources() .getBoolean(R.bool.config_hideNavWhenKeyguardBouncerShown); + mCarNavigationBarController = carNavigationBarController; + mFullscreenUserSwitcher = fullscreenUserSwitcher; } @Override @@ -66,8 +73,10 @@ public class CarStatusBarKeyguardViewManager extends StatusBarKeyguardViewManage if (!mShouldHideNavBar) { return; } - CarStatusBar statusBar = (CarStatusBar) mStatusBar; - statusBar.setNavBarVisibility(navBarVisible ? View.VISIBLE : View.GONE); + int visibility = navBarVisible ? View.VISIBLE : View.GONE; + mCarNavigationBarController.setBottomWindowVisibility(visibility); + mCarNavigationBarController.setLeftWindowVisibility(visibility); + mCarNavigationBarController.setRightWindowVisibility(visibility); } /** @@ -86,8 +95,7 @@ public class CarStatusBarKeyguardViewManager extends StatusBarKeyguardViewManage */ @Override public void onCancelClicked() { - CarStatusBar statusBar = (CarStatusBar) mStatusBar; - statusBar.showUserSwitcher(); + mFullscreenUserSwitcher.show(); } /** diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBarModule.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBarModule.java index 1ebaef7022865..a6f720d5c7d27 100644 --- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBarModule.java +++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBarModule.java @@ -32,6 +32,7 @@ import com.android.systemui.assist.AssistManager; import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.bubbles.BubbleController; import com.android.systemui.car.CarServiceProvider; +import com.android.systemui.car.SystemUIPrimaryWindowController; import com.android.systemui.colorextraction.SysuiColorExtractor; import com.android.systemui.dagger.qualifiers.UiBackground; import com.android.systemui.keyguard.DismissCallbackRegistry; @@ -207,7 +208,8 @@ public class CarStatusBarModule { DismissCallbackRegistry dismissCallbackRegistry, CarServiceProvider carServiceProvider, Lazy powerManagerHelperLazy, - Lazy fullscreenUserSwitcherLazy, + FullscreenUserSwitcher fullscreenUserSwitcher, + SystemUIPrimaryWindowController systemUIPrimaryWindowController, CarNavigationBarController carNavigationBarController, FlingAnimationUtils.Builder flingAnimationUtilsBuilder) { return new CarStatusBar( @@ -292,7 +294,8 @@ public class CarStatusBarModule { dismissCallbackRegistry, carServiceProvider, powerManagerHelperLazy, - fullscreenUserSwitcherLazy, + fullscreenUserSwitcher, + systemUIPrimaryWindowController, carNavigationBarController, flingAnimationUtilsBuilder); } diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/FullscreenUserSwitcher.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/FullscreenUserSwitcher.java index f8fc3bbefb012..3cd66c232717c 100644 --- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/FullscreenUserSwitcher.java +++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/FullscreenUserSwitcher.java @@ -38,6 +38,7 @@ import androidx.recyclerview.widget.GridLayoutManager; import com.android.internal.widget.LockPatternUtils; import com.android.systemui.R; import com.android.systemui.car.CarServiceProvider; +import com.android.systemui.car.SystemUIPrimaryWindowController; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.statusbar.car.CarTrustAgentUnlockDialogHelper.OnHideListener; import com.android.systemui.statusbar.car.UserGridRecyclerView.UserRecord; @@ -56,9 +57,10 @@ public class FullscreenUserSwitcher { private final UserManager mUserManager; private final CarServiceProvider mCarServiceProvider; private final CarTrustAgentUnlockDialogHelper mUnlockDialogHelper; + private final SystemUIPrimaryWindowController mSystemUIPrimaryWindowController; + private CarStatusBar mCarStatusBar; private final int mShortAnimDuration; - private CarStatusBar mStatusBar; private View mParent; private UserGridRecyclerView mUserGridView; private CarTrustAgentEnrollmentManager mEnrollmentManager; @@ -81,23 +83,35 @@ public class FullscreenUserSwitcher { @Main Resources resources, UserManager userManager, CarServiceProvider carServiceProvider, - CarTrustAgentUnlockDialogHelper carTrustAgentUnlockDialogHelper) { + CarTrustAgentUnlockDialogHelper carTrustAgentUnlockDialogHelper, + SystemUIPrimaryWindowController systemUIPrimaryWindowController) { mContext = context; mResources = resources; mUserManager = userManager; mCarServiceProvider = carServiceProvider; mUnlockDialogHelper = carTrustAgentUnlockDialogHelper; + mSystemUIPrimaryWindowController = systemUIPrimaryWindowController; mShortAnimDuration = mResources.getInteger(android.R.integer.config_shortAnimTime); } - /** Sets the status bar which controls the keyguard. */ + /** Sets the status bar which gives an entry point to dismiss the keyguard. */ + // TODO: Remove this in favor of a keyguard controller. public void setStatusBar(CarStatusBar statusBar) { - mStatusBar = statusBar; + mCarStatusBar = statusBar; + } + + /** Returns {@code true} if the user switcher already has a parent view. */ + public boolean isAttached() { + return mParent != null; } /** Sets the {@link ViewStub} to show the user switcher. */ public void setContainer(ViewStub containerStub) { + if (isAttached()) { + return; + } + mParent = containerStub.inflate(); View container = mParent.findViewById(R.id.container); @@ -148,20 +162,31 @@ public class FullscreenUserSwitcher { * Makes user grid visible. */ public void show() { + if (!isAttached()) { + return; + } mParent.setVisibility(View.VISIBLE); + mSystemUIPrimaryWindowController.setWindowExpanded(true); } /** * Hides the user grid. */ public void hide() { + if (!isAttached()) { + return; + } mParent.setVisibility(View.INVISIBLE); + mSystemUIPrimaryWindowController.setWindowExpanded(false); } /** * @return {@code true} if user grid is visible, {@code false} otherwise. */ public boolean isVisible() { + if (!isAttached()) { + return false; + } return mParent.getVisibility() == View.VISIBLE; } @@ -196,7 +221,7 @@ public class FullscreenUserSwitcher { } if (mSelectedUser.mType == UserRecord.FOREGROUND_USER) { hide(); - mStatusBar.dismissKeyguard(); + mCarStatusBar.dismissKeyguard(); return; } // Switching is about to happen, since it takes time, fade out the switcher gradually. diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/UserGridRecyclerView.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/UserGridRecyclerView.java index cdabeebe28196..8c756ecbaefc1 100644 --- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/UserGridRecyclerView.java +++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/UserGridRecyclerView.java @@ -43,6 +43,9 @@ import android.util.AttributeSet; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.view.Window; +import android.view.WindowInsets; +import android.view.WindowManager; import android.widget.ImageView; import android.widget.TextView; @@ -53,7 +56,6 @@ import androidx.recyclerview.widget.RecyclerView; import com.android.internal.util.UserIcons; import com.android.systemui.R; -import com.android.systemui.statusbar.phone.SystemUIDialog; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -337,7 +339,7 @@ public class UserGridRecyclerView extends RecyclerView { .setPositiveButton(android.R.string.ok, null) .create(); // Sets window flags for the SysUI dialog - SystemUIDialog.applyFlags(maxUsersDialog); + applyCarSysUIDialogFlags(maxUsersDialog); maxUsersDialog.show(); } @@ -356,10 +358,19 @@ public class UserGridRecyclerView extends RecyclerView { .setOnCancelListener(this) .create(); // Sets window flags for the SysUI dialog - SystemUIDialog.applyFlags(addUserDialog); + applyCarSysUIDialogFlags(addUserDialog); addUserDialog.show(); } + private void applyCarSysUIDialogFlags(AlertDialog dialog) { + final Window window = dialog.getWindow(); + window.setType(WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL); + window.addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM + | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED); + window.setFitWindowInsetsTypes( + window.getFitWindowInsetsTypes() & ~WindowInsets.Type.statusBars()); + } + private void notifyUserSelected(UserRecord userRecord) { // Notify the listener which user was selected if (mUserSelectionListener != null) {