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

Commit 7f65f246 authored by Caitlin Shkuratov's avatar Caitlin Shkuratov
Browse files

[CS] Add WindowRootViewComponent to get access to the WindowRootView.

This pulls out the WindowRootView from CentralSurfacesComponent so that
we can finish removing CentralSurfacesComponent. The doc on
WindowRootViewComponent explains its existence and why we can't just
inject WindowRootView into NotificationShadeWindowController directly.

Bug: 277762009
Test: smoke test of the shade
Test: atest NotificationShadeWindowControllerImplTest
Change-Id: I8e67af46383a075688ac68c66fa641439e2079c5
parent 268e2ee2
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -77,6 +77,7 @@ import com.android.systemui.qs.footer.dagger.FooterActionsModule;
import com.android.systemui.recents.Recents;
import com.android.systemui.retail.dagger.RetailModeModule;
import com.android.systemui.scene.SceneContainerFrameworkModule;
import com.android.systemui.scene.ui.view.WindowRootViewComponent;
import com.android.systemui.screenrecord.ScreenRecordModule;
import com.android.systemui.screenshot.dagger.ScreenshotModule;
import com.android.systemui.security.data.repository.SecurityRepositoryModule;
@@ -225,7 +226,8 @@ import javax.inject.Named;
            DozeComponent.class,
            ExpandableNotificationRowComponent.class,
            KeyguardBouncerComponent.class,
            NotificationShelfComponent.class
            NotificationShelfComponent.class,
            WindowRootViewComponent.class,
        })
public abstract class SystemUIModule {

+46 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.systemui.scene.ui.view

import dagger.Subcomponent

/**
 * A component providing access to [WindowRootView].
 *
 * Injecting [WindowRootView] directly into controllers can lead to crash loops. This is because
 * [WindowRootView] contains [NotificationStackScrollLayout] and that view accesses [Dependency.get]
 * in its constructor. If [Dependency.get] is not set up when your controller is constructed (which
 * is possible because there are no guarantees from Dagger about the order of construction), then
 * trying to inflate [NotificationStackScrollLayout] will crash. This component provides a way to
 * fetch [WindowRootView] after the full Dagger graph is set up, which ensures that the inflation
 * won't fail.
 *
 * This component is intended to be *temporary* and *only used from [CentralSurfacesImpl]*. Once
 * [Dependency.get] is removed from [NotificationStackScrollLayout], we should re-attempt injecting
 * [WindowRootView] directly into its controller [NotificationShadeWindowController].
 */
@Subcomponent
interface WindowRootViewComponent {

    @Subcomponent.Factory
    interface Factory {
        fun create(): WindowRootViewComponent
    }

    /** Fetches the root view of the main SysUI window. */
    fun getWindowRootView(): WindowRootView
}
+12 −4
Original line number Diff line number Diff line
@@ -57,6 +57,7 @@ import com.android.systemui.dump.DumpsysTableLogger;
import com.android.systemui.keyguard.KeyguardViewMediator;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener;
import com.android.systemui.scene.ui.view.WindowRootViewComponent;
import com.android.systemui.statusbar.NotificationShadeWindowController;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
@@ -91,6 +92,7 @@ public class NotificationShadeWindowControllerImpl implements NotificationShadeW
    private static final int MAX_STATE_CHANGES_BUFFER_SIZE = 100;

    private final Context mContext;
    private final WindowRootViewComponent.Factory mWindowRootViewComponentFactory;
    private final WindowManager mWindowManager;
    private final IActivityManager mActivityManager;
    private final DozeParameters mDozeParameters;
@@ -129,8 +131,12 @@ public class NotificationShadeWindowControllerImpl implements NotificationShadeW
            new NotificationShadeWindowState.Buffer(MAX_STATE_CHANGES_BUFFER_SIZE);

    @Inject
    public NotificationShadeWindowControllerImpl(Context context, WindowManager windowManager,
            IActivityManager activityManager, DozeParameters dozeParameters,
    public NotificationShadeWindowControllerImpl(
            Context context,
            WindowRootViewComponent.Factory windowRootViewComponentFactory,
            WindowManager windowManager,
            IActivityManager activityManager,
            DozeParameters dozeParameters,
            StatusBarStateController statusBarStateController,
            ConfigurationController configurationController,
            KeyguardViewMediator keyguardViewMediator,
@@ -143,6 +149,7 @@ public class NotificationShadeWindowControllerImpl implements NotificationShadeW
            ShadeExpansionStateManager shadeExpansionStateManager,
            ShadeWindowLogger logger) {
        mContext = context;
        mWindowRootViewComponentFactory = windowRootViewComponentFactory;
        mWindowManager = windowManager;
        mActivityManager = activityManager;
        mDozeParameters = dozeParameters;
@@ -274,8 +281,9 @@ public class NotificationShadeWindowControllerImpl implements NotificationShadeW
    }

    @Override
    public void setWindowRootView(ViewGroup view) {
        mWindowRootView = view;
    public void fetchWindowRootView() {
        WindowRootViewComponent component = mWindowRootViewComponentFactory.create();
        mWindowRootView = component.getWindowRootView();
    }

    @Override
+2 −2
Original line number Diff line number Diff line
@@ -59,8 +59,8 @@ public interface NotificationShadeWindowController extends RemoteInputController
     */
    default void attach() {}

    /** Sets the notification shade view. */
    default void setWindowRootView(ViewGroup view) {}
    /** Requests this class to fetch the notification shade view. */
    default void fetchWindowRootView() {}

    /** Gets the notification shade view. */
    @Nullable
+4 −5
Original line number Diff line number Diff line
@@ -92,7 +92,6 @@ import android.view.IWindowManager;
import android.view.MotionEvent;
import android.view.ThreadedRenderer;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewRootImpl;
import android.view.WindowInsets;
import android.view.WindowInsetsController.Appearance;
@@ -1601,10 +1600,10 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
                CollapsedStatusBarFragment.class,
                mCentralSurfacesComponent::createCollapsedStatusBarFragment);

        ViewGroup windowRootView = mCentralSurfacesComponent.getWindowRootView();
        // TODO(b/277762009): Inject [NotificationShadeWindowView] directly into the controller.
        //  (Right now, there's a circular dependency.)
        mNotificationShadeWindowController.setWindowRootView(windowRootView);
        // Ideally, NotificationShadeWindowController could automatically fetch the window root view
        // in #attach or a CoreStartable.start method or something similar. But for now, to avoid
        // regressions, we'll continue standing up the root view in CentralSurfaces.
        mNotificationShadeWindowController.fetchWindowRootView();
        getNotificationShadeWindowViewController().setupExpandedStatusBar();
        mShadeController.setNotificationShadeWindowViewController(
                getNotificationShadeWindowViewController());
Loading