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);