diff --git a/packages/SystemUI/res/layout/scene_window_root.xml b/packages/SystemUI/res/layout/scene_window_root.xml new file mode 100644 index 0000000000000..0dcd15b429c10 --- /dev/null +++ b/packages/SystemUI/res/layout/scene_window_root.xml @@ -0,0 +1,32 @@ + + + + + + + + diff --git a/packages/SystemUI/res/layout/super_notification_shade.xml b/packages/SystemUI/res/layout/super_notification_shade.xml index d9fe949bb3270..01465d759ab07 100644 --- a/packages/SystemUI/res/layout/super_notification_shade.xml +++ b/packages/SystemUI/res/layout/super_notification_shade.xml @@ -21,6 +21,7 @@ diff --git a/packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneWindowRootView.kt b/packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneWindowRootView.kt new file mode 100644 index 0000000000000..8f001ec6b5e22 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/scene/ui/view/SceneWindowRootView.kt @@ -0,0 +1,7 @@ +package com.android.systemui.scene.ui.view + +import android.content.Context +import android.util.AttributeSet + +/** A root view of the main SysUI window that supports scenes. */ +class SceneWindowRootView(context: Context?, attrs: AttributeSet?) : WindowRootView(context, attrs) \ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/scene/ui/view/WindowRootView.kt b/packages/SystemUI/src/com/android/systemui/scene/ui/view/WindowRootView.kt new file mode 100644 index 0000000000000..a0f9667053811 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/scene/ui/view/WindowRootView.kt @@ -0,0 +1,8 @@ +package com.android.systemui.scene.ui.view + +import android.content.Context +import android.util.AttributeSet +import android.widget.FrameLayout + +/** A view that can serve as the root of the main SysUI window. */ +open class WindowRootView(context: Context?, attrs: AttributeSet?) : FrameLayout(context, attrs) \ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java index 0c800d456f3ca..8105a145d15a7 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java @@ -103,7 +103,7 @@ public class NotificationShadeWindowControllerImpl implements NotificationShadeW private final KeyguardViewMediator mKeyguardViewMediator; private final KeyguardBypassController mKeyguardBypassController; private final AuthController mAuthController; - private ViewGroup mNotificationShadeView; + private ViewGroup mWindowRootView; private LayoutParams mLp; private boolean mHasTopUi; private boolean mHasTopUiChanged; @@ -262,7 +262,7 @@ public class NotificationShadeWindowControllerImpl implements NotificationShadeW mLp.privateFlags |= PRIVATE_FLAG_BEHAVIOR_CONTROLLED; mLp.insetsFlags.behavior = BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE; - mWindowManager.addView(mNotificationShadeView, mLp); + mWindowManager.addView(mWindowRootView, mLp); mLpChanged.copyFrom(mLp); onThemeChanged(); @@ -274,13 +274,13 @@ public class NotificationShadeWindowControllerImpl implements NotificationShadeW } @Override - public void setNotificationShadeView(ViewGroup view) { - mNotificationShadeView = view; + public void setWindowRootView(ViewGroup view) { + mWindowRootView = view; } @Override - public ViewGroup getNotificationShadeView() { - return mNotificationShadeView; + public ViewGroup getWindowRootView() { + return mWindowRootView; } @Override @@ -289,7 +289,7 @@ public class NotificationShadeWindowControllerImpl implements NotificationShadeW } private void setKeyguardDark(boolean dark) { - int vis = mNotificationShadeView.getSystemUiVisibility(); + int vis = mWindowRootView.getSystemUiVisibility(); if (dark) { vis = vis | View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR; vis = vis | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR; @@ -297,7 +297,7 @@ public class NotificationShadeWindowControllerImpl implements NotificationShadeW vis = vis & ~View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR; vis = vis & ~View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR; } - mNotificationShadeView.setSystemUiVisibility(vis); + mWindowRootView.setSystemUiVisibility(vis); } private void applyKeyguardFlags(NotificationShadeWindowState state) { @@ -413,11 +413,11 @@ public class NotificationShadeWindowControllerImpl implements NotificationShadeW visible = true; mLogger.d("Visibility forced to be true"); } - if (mNotificationShadeView != null) { + if (mWindowRootView != null) { if (visible) { - mNotificationShadeView.setVisibility(View.VISIBLE); + mWindowRootView.setVisibility(View.VISIBLE); } else { - mNotificationShadeView.setVisibility(View.INVISIBLE); + mWindowRootView.setVisibility(View.INVISIBLE); } } } @@ -439,10 +439,10 @@ public class NotificationShadeWindowControllerImpl implements NotificationShadeW private void applyFitsSystemWindows(NotificationShadeWindowState state) { boolean fitsSystemWindows = !state.isKeyguardShowingAndNotOccluded(); - if (mNotificationShadeView != null - && mNotificationShadeView.getFitsSystemWindows() != fitsSystemWindows) { - mNotificationShadeView.setFitsSystemWindows(fitsSystemWindows); - mNotificationShadeView.requestApplyInsets(); + if (mWindowRootView != null + && mWindowRootView.getFitsSystemWindows() != fitsSystemWindows) { + mWindowRootView.setFitsSystemWindows(fitsSystemWindows); + mWindowRootView.requestApplyInsets(); } } @@ -482,7 +482,7 @@ public class NotificationShadeWindowControllerImpl implements NotificationShadeW if (mDeferWindowLayoutParams == 0 && mLp != null && mLp.copyFrom(mLpChanged) != 0) { mLogger.logApplyingWindowLayoutParams(mLp); Trace.beginSection("updateViewLayout"); - mWindowManager.updateViewLayout(mNotificationShadeView, mLp); + mWindowManager.updateViewLayout(mWindowRootView, mLp); Trace.endSection(); } } @@ -608,7 +608,7 @@ public class NotificationShadeWindowControllerImpl implements NotificationShadeW try { final IWindowSession session = WindowManagerGlobal.getWindowSession(); session.updateTapExcludeRegion( - IWindow.Stub.asInterface(getNotificationShadeView().getWindowToken()), + IWindow.Stub.asInterface(getWindowRootView().getWindowToken()), region); } catch (RemoteException e) { Log.e(TAG, "could not update the tap exclusion region:" + e); @@ -847,8 +847,8 @@ public class NotificationShadeWindowControllerImpl implements NotificationShadeW pw.println(" mKeyguardPreferredRefreshRate=" + mKeyguardPreferredRefreshRate); pw.println(" mDeferWindowLayoutParams=" + mDeferWindowLayoutParams); pw.println(mCurrentState); - if (mNotificationShadeView != null && mNotificationShadeView.getViewRootImpl() != null) { - mNotificationShadeView.getViewRootImpl().dump(" ", pw); + if (mWindowRootView != null && mWindowRootView.getViewRootImpl() != null) { + mWindowRootView.getViewRootImpl().dump(" ", pw); } new DumpsysTableLogger( TAG, @@ -864,7 +864,7 @@ public class NotificationShadeWindowControllerImpl implements NotificationShadeW @Override public void onThemeChanged() { - if (mNotificationShadeView == null) { + if (mWindowRootView == null) { return; } diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowView.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowView.java index d75190e7289a3..c9122c77c1d41 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowView.java +++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowView.java @@ -59,11 +59,14 @@ import com.android.internal.view.FloatingActionMode; import com.android.internal.widget.floatingtoolbar.FloatingToolbar; import com.android.systemui.R; import com.android.systemui.compose.ComposeFacade; +import com.android.systemui.scene.ui.view.WindowRootView; /** - * Combined keyguard and notification panel view. Also holding backdrop and scrims. + * Combined keyguard and notification panel view. Also holding backdrop and scrims. This view can + * serve as the root view of the main SysUI window, but because other views can also serve that + * purpose, users of this class cannot assume it is the root. */ -public class NotificationShadeWindowView extends FrameLayout { +public class NotificationShadeWindowView extends WindowRootView { public static final String TAG = "NotificationShadeWindowView"; private int mRightInset = 0; diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeModule.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeModule.kt index b7551cf3408e5..44c732d8082fd 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/ShadeModule.kt +++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeModule.kt @@ -31,7 +31,9 @@ import com.android.systemui.biometrics.AuthRippleView import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.flags.FeatureFlags +import com.android.systemui.flags.Flags import com.android.systemui.privacy.OngoingPrivacyChip +import com.android.systemui.scene.ui.view.WindowRootView import com.android.systemui.settings.UserTracker import com.android.systemui.statusbar.LightRevealScrim import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout @@ -59,18 +61,36 @@ abstract class ShadeModule { companion object { const val SHADE_HEADER = "large_screen_shade_header" + @Provides + @SysUISingleton + fun providesWindowRootView( + layoutInflater: LayoutInflater, + featureFlags: FeatureFlags, + ): WindowRootView { + return if (featureFlags.isEnabled(Flags.SCENE_CONTAINER)) { + layoutInflater.inflate(R.layout.scene_window_root, null) + } else { + layoutInflater.inflate(R.layout.super_notification_shade, null) + } as WindowRootView? ?: throw IllegalStateException( + "Window root view could not be properly inflated" + ) + } + @Provides @SysUISingleton // TODO(b/277762009): Do something similar to // {@link StatusBarWindowModule.InternalWindowView} so that only // {@link NotificationShadeWindowViewController} can inject this view. fun providesNotificationShadeWindowView( - layoutInflater: LayoutInflater, + root: WindowRootView, + featureFlags: FeatureFlags, ): NotificationShadeWindowView { - return layoutInflater.inflate(R.layout.super_notification_shade, /* root= */ null) - as NotificationShadeWindowView? + if (featureFlags.isEnabled(Flags.SCENE_CONTAINER)) { + return root.findViewById(R.id.legacy_window_root) + } + return root as NotificationShadeWindowView? ?: throw IllegalStateException( - "R.layout.super_notification_shade could not be properly inflated" + "root view not a NotificationShadeWindowView" ) } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeWindowController.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeWindowController.java index 2ca0b0054bf73..47a4641bcdd91 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeWindowController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeWindowController.java @@ -60,11 +60,11 @@ public interface NotificationShadeWindowController extends RemoteInputController default void attach() {} /** Sets the notification shade view. */ - default void setNotificationShadeView(ViewGroup view) {} + default void setWindowRootView(ViewGroup view) {} /** Gets the notification shade view. */ @Nullable - default ViewGroup getNotificationShadeView() { + default ViewGroup getWindowRootView() { return null; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java index 0402d4f882050..a0cb1181165c8 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java @@ -1658,12 +1658,13 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { CollapsedStatusBarFragment.class, mCentralSurfacesComponent::createCollapsedStatusBarFragment); + ViewGroup windowRootView = mCentralSurfacesComponent.getWindowRootView(); mNotificationShadeWindowView = mCentralSurfacesComponent.getNotificationShadeWindowView(); mNotificationShadeWindowViewController = mCentralSurfacesComponent .getNotificationShadeWindowViewController(); // TODO(b/277762009): Inject [NotificationShadeWindowView] directly into the controller. // (Right now, there's a circular dependency.) - mNotificationShadeWindowController.setNotificationShadeView(mNotificationShadeWindowView); + mNotificationShadeWindowController.setWindowRootView(windowRootView); mNotificationShadeWindowViewController.setupExpandedStatusBar(); NotificationPanelViewController npvc = mCentralSurfacesComponent.getNotificationPanelViewController(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java index 0414a14205d7b..7d0e3b369d165 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java @@ -1311,7 +1311,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb @Override public ViewRootImpl getViewRootImpl() { - ViewGroup viewGroup = mNotificationShadeWindowController.getNotificationShadeView(); + ViewGroup viewGroup = mNotificationShadeWindowController.getWindowRootView(); if (viewGroup != null) { return viewGroup.getViewRootImpl(); } else { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesComponent.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesComponent.java index 273e78350f27b..158f96123d92c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesComponent.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesComponent.java @@ -20,6 +20,7 @@ import static com.android.systemui.statusbar.phone.dagger.StatusBarViewModule.ST import static java.lang.annotation.RetentionPolicy.RUNTIME; +import com.android.systemui.scene.ui.view.WindowRootView; import com.android.systemui.shade.NotificationPanelViewController; import com.android.systemui.shade.NotificationShadeWindowView; import com.android.systemui.shade.NotificationShadeWindowViewController; @@ -80,8 +81,11 @@ public interface CentralSurfacesComponent { @Scope @interface CentralSurfacesScope {} + /** Creates the root view of the main SysUI window}. */ + WindowRootView getWindowRootView(); + /** - * Creates a {@link NotificationShadeWindowView}. + * Creates or returns a {@link NotificationShadeWindowView}. */ NotificationShadeWindowView getNotificationShadeWindowView(); diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowControllerImplTest.java index 526dc8d150fee..cde6ac08d5fd6 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowControllerImplTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowControllerImplTest.java @@ -126,7 +126,7 @@ public class NotificationShadeWindowControllerImplTest extends SysuiTestCase { } }; mNotificationShadeWindowController.setScrimsVisibilityListener((visibility) -> {}); - mNotificationShadeWindowController.setNotificationShadeView(mNotificationShadeWindowView); + mNotificationShadeWindowController.setWindowRootView(mNotificationShadeWindowView); mNotificationShadeWindowController.attach(); verify(mWindowManager).addView(eq(mNotificationShadeWindowView), any()); diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java index 47a86b1fca5cf..2158396b4e150 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java @@ -320,7 +320,7 @@ public class BubblesTest extends SysuiTestCase { mColorExtractor, mDumpManager, mKeyguardStateController, mScreenOffAnimationController, mAuthController, mShadeExpansionStateManager, mShadeWindowLogger); - mNotificationShadeWindowController.setNotificationShadeView(mNotificationShadeWindowView); + mNotificationShadeWindowController.setWindowRootView(mNotificationShadeWindowView); mNotificationShadeWindowController.attach(); mAppBubbleIntent = new Intent(mContext, BubblesTestActivity.class);