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

Commit d84ed808 authored by Evan Laird's avatar Evan Laird
Browse files

[sb] StatusBarInitializer to CoreStartable

Decouple the creation of the StatusBarInitializer and subsequent
starting of the CollapsedStatusBarFragment from CentralSurfacesImpl.

Test: atest SystemUITests with the flag on
Flag: com.android.systemui.status_bar_simple_fragment
Bug: 364360986
Change-Id: I9e8043a6105657bc6ac33b25d24a95b900594d6d
parent 0fb50e83
Loading
Loading
Loading
Loading
+30 −1
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@
package com.android.systemui.statusbar.core

import android.app.Fragment
import androidx.annotation.VisibleForTesting
import com.android.systemui.CoreStartable
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.fragments.FragmentHostManager
import com.android.systemui.res.R
@@ -72,11 +74,38 @@ constructor(
    private val windowController: StatusBarWindowController,
    private val collapsedStatusBarFragmentProvider: Provider<CollapsedStatusBarFragment>,
    private val creationListeners: Set<@JvmSuppressWildcards OnStatusBarViewInitializedListener>,
) : StatusBarInitializer {
) : CoreStartable, StatusBarInitializer {
    private var component: StatusBarFragmentComponent? = null

    @get:VisibleForTesting
    var initialized = false
        private set

    override var statusBarViewUpdatedListener: OnStatusBarViewUpdatedListener? = null
        set(value) {
            field = value
            // If a listener is added after initialization, immediately call the callback
            component?.let { component ->
                field?.onStatusBarViewUpdated(
                    component.phoneStatusBarViewController,
                    component.phoneStatusBarTransitions,
                )
            }
        }

    override fun start() {
        if (StatusBarSimpleFragment.isEnabled) {
            doStart()
        }
    }

    override fun initializeStatusBar() {
        StatusBarSimpleFragment.assertInLegacyMode()
        doStart()
    }

    private fun doStart() {
        initialized = true
        windowController.fragmentHostManager
            .addTagListener(
                CollapsedStatusBarFragment.TAG,
+0 −4
Original line number Diff line number Diff line
@@ -22,8 +22,6 @@ import com.android.systemui.CoreStartable
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.log.LogBuffer
import com.android.systemui.log.LogBufferFactory
import com.android.systemui.statusbar.core.StatusBarInitializer
import com.android.systemui.statusbar.core.StatusBarInitializerImpl
import com.android.systemui.statusbar.data.StatusBarDataLayerModule
import com.android.systemui.statusbar.phone.LightBarController
import com.android.systemui.statusbar.phone.StatusBarSignalPolicy
@@ -63,8 +61,6 @@ abstract class StatusBarModule {
    @ClassKey(StatusBarSignalPolicy::class)
    abstract fun bindStatusBarSignalPolicy(impl: StatusBarSignalPolicy): CoreStartable

    @Binds abstract fun statusBarInitializer(impl: StatusBarInitializerImpl): StatusBarInitializer

    companion object {

        @Provides
+5 −1
Original line number Diff line number Diff line
@@ -206,6 +206,7 @@ import com.android.systemui.statusbar.PulseExpansionHandler;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.core.StatusBarInitializer;
import com.android.systemui.statusbar.core.StatusBarSimpleFragment;
import com.android.systemui.statusbar.data.model.StatusBarMode;
import com.android.systemui.statusbar.data.repository.StatusBarModeRepositoryStore;
import com.android.systemui.statusbar.notification.NotificationActivityStarter;
@@ -1204,7 +1205,10 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
                    setBouncerShowingForStatusBarComponents(mBouncerShowing);
                    checkBarModes();
                });
        // When the flag is on, we register the fragment as a core startable and this is not needed
        if (!StatusBarSimpleFragment.isEnabled()) {
            mStatusBarInitializer.initializeStatusBar();
        }

        mStatusBarTouchableRegionManager.setup(getNotificationShadeWindowView());

+37 −0
Original line number Diff line number Diff line
@@ -13,14 +13,25 @@
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.android.systemui.statusbar.phone.dagger

package com.android.systemui.statusbar.phone.dagger;
import com.android.systemui.CoreStartable
import com.android.systemui.statusbar.core.StatusBarInitializer
import com.android.systemui.statusbar.core.StatusBarInitializerImpl
import dagger.Binds
import dagger.Module
import dagger.multibindings.ClassKey
import dagger.multibindings.IntoMap

import dagger.Module;

/**
 * Similar in purpose to [StatusBarModule], but scoped only to phones
 */
/** Similar in purpose to [StatusBarModule], but scoped only to phones */
@Module
public interface StatusBarPhoneModule {
interface StatusBarPhoneModule {

    /** Binds {@link StatusBarInitializer} as a {@link CoreStartable}. */
    @Binds
    @IntoMap
    @ClassKey(StatusBarInitializerImpl::class)
    fun bindStatusBarInitializer(impl: StatusBarInitializerImpl): CoreStartable

    @Binds fun statusBarInitializer(impl: StatusBarInitializerImpl): StatusBarInitializer
}
+92 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 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.statusbar.core

import android.app.FragmentManager
import android.app.FragmentTransaction
import android.platform.test.annotations.DisableFlags
import android.platform.test.annotations.EnableFlags
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.Flags
import com.android.systemui.SysuiTestCase
import com.android.systemui.fragments.FragmentHostManager
import com.android.systemui.statusbar.phone.fragment.CollapsedStatusBarFragment
import com.android.systemui.statusbar.window.StatusBarWindowController
import com.google.common.truth.Truth.assertThat
import kotlin.test.Test
import org.junit.Assert.assertThrows
import org.junit.Before
import org.junit.runner.RunWith
import org.mockito.Mockito.mock
import org.mockito.kotlin.any
import org.mockito.kotlin.whenever

@SmallTest
@RunWith(AndroidJUnit4::class)
class StatusBarInitializerTest : SysuiTestCase() {
    val windowController = mock(StatusBarWindowController::class.java)

    @Before
    fun setup() {
        // TODO(b/364360986) this will go away once the fragment is deprecated. Hence, there is no
        // need right now for moving this to kosmos
        val transaction = mock(FragmentTransaction::class.java)
        val fragmentManager = mock(FragmentManager::class.java)
        val fragmentHostManager = mock(FragmentHostManager::class.java)
        whenever(fragmentHostManager.addTagListener(any(), any())).thenReturn(fragmentHostManager)
        whenever(fragmentHostManager.fragmentManager).thenReturn(fragmentManager)
        whenever(fragmentManager.beginTransaction()).thenReturn(transaction)
        whenever(transaction.replace(any(), any(), any())).thenReturn(transaction)

        whenever(windowController.fragmentHostManager).thenReturn(fragmentHostManager)
    }

    val underTest =
        StatusBarInitializerImpl(
            windowController,
            { mock(CollapsedStatusBarFragment::class.java) },
            setOf(),
        )

    @Test
    @EnableFlags(Flags.FLAG_STATUS_BAR_SIMPLE_FRAGMENT)
    fun simpleFragment_startsFromCoreStartable() {
        underTest.start()
        assertThat(underTest.initialized).isTrue()
    }

    @Test
    @EnableFlags(Flags.FLAG_STATUS_BAR_SIMPLE_FRAGMENT)
    fun simpleFragment_throwsIfInitializeIsCalled() {
        assertThrows(IllegalStateException::class.java) { underTest.initializeStatusBar() }
    }

    @Test
    @DisableFlags(Flags.FLAG_STATUS_BAR_SIMPLE_FRAGMENT)
    fun flagOff_doesNotInitializeViaCoreStartable() {
        underTest.start()
        assertThat(underTest.initialized).isFalse()
    }

    @Test
    @DisableFlags(Flags.FLAG_STATUS_BAR_SIMPLE_FRAGMENT)
    fun flagOff_doesNotThrowIfInitializeIsCalled() {
        underTest.initializeStatusBar()
        assertThat(underTest.initialized).isTrue()
    }
}
Loading