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

Commit f751c394 authored by Aaron Liu's avatar Aaron Liu Committed by Android (Google) Code Review
Browse files

Merge "Clean up LAZY_INFLATE_KEYGUARD flag" into main

parents a8cae266 a563c3fd
Loading
Loading
Loading
Loading
+2 −206
Original line number Diff line number Diff line
@@ -18,10 +18,8 @@
package com.android.systemui.keyguard

import android.content.Context
import android.content.res.Configuration
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.android.keyguard.KeyguardStatusView
import com.android.keyguard.KeyguardStatusViewController
import com.android.keyguard.LockIconView
@@ -29,38 +27,21 @@ import com.android.keyguard.LockIconViewController
import com.android.keyguard.dagger.KeyguardStatusViewComponent
import com.android.systemui.CoreStartable
import com.android.systemui.R
import com.android.systemui.communal.ui.adapter.CommunalWidgetViewAdapter
import com.android.systemui.communal.ui.binder.CommunalWidgetViewBinder
import com.android.systemui.communal.ui.viewmodel.CommunalWidgetViewModel
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.flags.FeatureFlags
import com.android.systemui.flags.Flags
import com.android.systemui.keyguard.domain.interactor.KeyguardBlueprintInteractor
import com.android.systemui.keyguard.ui.binder.KeyguardAmbientIndicationAreaViewBinder
import com.android.systemui.keyguard.ui.binder.KeyguardBlueprintViewBinder
import com.android.systemui.keyguard.ui.binder.KeyguardIndicationAreaBinder
import com.android.systemui.keyguard.ui.binder.KeyguardQuickAffordanceViewBinder
import com.android.systemui.keyguard.ui.binder.KeyguardRootViewBinder
import com.android.systemui.keyguard.ui.binder.KeyguardSettingsViewBinder
import com.android.systemui.keyguard.ui.view.KeyguardIndicationArea
import com.android.systemui.keyguard.ui.view.KeyguardRootView
import com.android.systemui.keyguard.ui.view.layout.KeyguardBlueprintCommandListener
import com.android.systemui.keyguard.ui.viewmodel.KeyguardAmbientIndicationViewModel
import com.android.systemui.keyguard.ui.viewmodel.KeyguardBlueprintViewModel
import com.android.systemui.keyguard.ui.viewmodel.KeyguardIndicationAreaViewModel
import com.android.systemui.keyguard.ui.viewmodel.KeyguardQuickAffordancesCombinedViewModel
import com.android.systemui.keyguard.ui.viewmodel.KeyguardRootViewModel
import com.android.systemui.keyguard.ui.viewmodel.KeyguardSettingsMenuViewModel
import com.android.systemui.keyguard.ui.viewmodel.OccludingAppDeviceEntryMessageViewModel
import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.plugins.FalsingManager
import com.android.systemui.shade.NotificationShadeWindowView
import com.android.systemui.statusbar.KeyguardIndicationController
import com.android.systemui.statusbar.VibratorHelper
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController
import com.android.systemui.statusbar.notification.stack.ui.view.SharedNotificationContainer
import com.android.systemui.statusbar.notification.stack.ui.viewbinder.SharedNotificationContainerBinder
import com.android.systemui.statusbar.notification.stack.ui.viewmodel.SharedNotificationContainerViewModel
import com.android.systemui.statusbar.policy.KeyguardStateController
import com.android.systemui.temporarydisplay.chipbar.ChipbarCoordinator
import javax.inject.Inject
@@ -74,30 +55,17 @@ class KeyguardViewConfigurator
@Inject
constructor(
    private val keyguardRootView: KeyguardRootView,
    private val sharedNotificationContainer: SharedNotificationContainer,
    private val keyguardRootViewModel: KeyguardRootViewModel,
    private val keyguardIndicationAreaViewModel: KeyguardIndicationAreaViewModel,
    private val sharedNotificationContainerViewModel: SharedNotificationContainerViewModel,
    private val keyguardAmbientIndicationViewModel: KeyguardAmbientIndicationViewModel,
    private val notificationShadeWindowView: NotificationShadeWindowView,
    private val featureFlags: FeatureFlags,
    private val indicationController: KeyguardIndicationController,
    private val keyguardQuickAffordancesCombinedViewModel:
        KeyguardQuickAffordancesCombinedViewModel,
    private val falsingManager: FalsingManager,
    private val vibratorHelper: VibratorHelper,
    private val keyguardStateController: KeyguardStateController,
    private val keyguardSettingsMenuViewModel: KeyguardSettingsMenuViewModel,
    private val activityStarter: ActivityStarter,
    private val occludingAppDeviceEntryMessageViewModel: OccludingAppDeviceEntryMessageViewModel,
    private val chipbarCoordinator: ChipbarCoordinator,
    private val keyguardBlueprintCommandListener: KeyguardBlueprintCommandListener,
    private val keyguardBlueprintViewModel: KeyguardBlueprintViewModel,
    private val keyguardStatusViewComponentFactory: KeyguardStatusViewComponent.Factory,
    private val keyguardBlueprintInteractor: KeyguardBlueprintInteractor,
    private val communalWidgetViewModel: CommunalWidgetViewModel,
    private val communalWidgetViewAdapter: CommunalWidgetViewAdapter,
    private val notificationStackScrollerLayoutController: NotificationStackScrollLayoutController,
    private val context: Context,
    private val keyguardIndicationController: KeyguardIndicationController,
    private val lockIconViewController: LockIconViewController,
@@ -105,10 +73,7 @@ constructor(

    private var rootViewHandle: DisposableHandle? = null
    private var indicationAreaHandle: DisposableHandle? = null
    private var leftShortcutHandle: KeyguardQuickAffordanceViewBinder.Binding? = null
    private var rightShortcutHandle: KeyguardQuickAffordanceViewBinder.Binding? = null
    private var ambientIndicationAreaHandle: KeyguardAmbientIndicationAreaViewBinder.Binding? = null
    private var settingsPopupMenuHandle: DisposableHandle? = null

    var keyguardStatusViewController: KeyguardStatusViewController? = null
        get() {
            if (field == null) {
@@ -127,52 +92,12 @@ constructor(

    override fun start() {
        bindKeyguardRootView()
        if (featureFlags.isEnabled(Flags.LAZY_INFLATE_KEYGUARD)) {
            keyguardRootView.removeAllViews()
        initializeViews()
        } else {
            val notificationPanel =
                notificationShadeWindowView.requireViewById(R.id.notification_panel) as ViewGroup
            unbindKeyguardBottomArea(notificationPanel)
            bindIndicationArea()
            bindLockIconView(notificationPanel)
            bindKeyguardStatusView(notificationPanel)
            setupNotificationStackScrollLayout(notificationPanel)
            bindLeftShortcut()
            bindRightShortcut()
            bindAmbientIndicationArea()
            bindSettingsPopupMenu()
            bindCommunalWidgetArea()
        }

        KeyguardBlueprintViewBinder.bind(keyguardRootView, keyguardBlueprintViewModel)
        keyguardBlueprintCommandListener.start()
    }

    fun setupNotificationStackScrollLayout(legacyParent: ViewGroup) {
        if (featureFlags.isEnabled(Flags.MIGRATE_NSSL)) {
            // This moves the existing NSSL view to a different parent, as the controller is a
            // singleton and recreating it has other bad side effects
            val nssl =
                legacyParent.requireViewById<View>(R.id.notification_stack_scroller).also {
                    (it.getParent() as ViewGroup).removeView(it)
                }
            sharedNotificationContainer.addNotificationStackScrollLayout(nssl)
            SharedNotificationContainerBinder.bind(
                sharedNotificationContainer,
                sharedNotificationContainerViewModel,
                notificationStackScrollerLayoutController,
            )
        }
    }

    override fun onConfigurationChanged(newConfig: Configuration?) {
        super.onConfigurationChanged(newConfig)
        leftShortcutHandle?.onConfigurationChanged()
        rightShortcutHandle?.onConfigurationChanged()
        ambientIndicationAreaHandle?.onConfigurationChanged()
    }

    fun bindIndicationArea() {
        indicationAreaHandle?.dispose()

@@ -213,135 +138,6 @@ constructor(
            )
    }

    private fun bindLockIconView(legacyParent: ViewGroup) {
        if (featureFlags.isEnabled(Flags.MIGRATE_LOCK_ICON)) {
            legacyParent.requireViewById<View>(R.id.lock_icon_view).let {
                legacyParent.removeView(it)
            }
        } else {
            keyguardRootView.findViewById<View?>(R.id.lock_icon_view)?.let {
                keyguardRootView.removeView(it)
            }
            legacyParent.requireViewById<LockIconView>(R.id.lock_icon_view).let {
                lockIconViewController.setLockIconView(it)
            }
        }
    }

    private fun bindAmbientIndicationArea() {
        if (featureFlags.isEnabled(Flags.MIGRATE_SPLIT_KEYGUARD_BOTTOM_AREA)) {
            ambientIndicationAreaHandle?.destroy()
            ambientIndicationAreaHandle =
                KeyguardAmbientIndicationAreaViewBinder.bind(
                    notificationShadeWindowView,
                    keyguardAmbientIndicationViewModel,
                    keyguardRootViewModel,
                )
        } else {
            keyguardRootView.findViewById<View?>(R.id.ambient_indication_container)?.let {
                keyguardRootView.removeView(it)
            }
        }
    }

    private fun bindSettingsPopupMenu() {
        if (featureFlags.isEnabled(Flags.MIGRATE_SPLIT_KEYGUARD_BOTTOM_AREA)) {
            settingsPopupMenuHandle?.dispose()
            settingsPopupMenuHandle =
                KeyguardSettingsViewBinder.bind(
                    keyguardRootView,
                    keyguardSettingsMenuViewModel,
                    vibratorHelper,
                    activityStarter,
                )
        } else {
            keyguardRootView.findViewById<View?>(R.id.keyguard_settings_button)?.let {
                keyguardRootView.removeView(it)
            }
        }
    }

    private fun unbindKeyguardBottomArea(legacyParent: ViewGroup) {
        if (featureFlags.isEnabled(Flags.MIGRATE_SPLIT_KEYGUARD_BOTTOM_AREA)) {
            legacyParent.requireViewById<View>(R.id.keyguard_bottom_area).let {
                legacyParent.removeView(it)
            }
        }
    }

    private fun bindLeftShortcut() {
        leftShortcutHandle?.destroy()
        if (featureFlags.isEnabled(Flags.MIGRATE_SPLIT_KEYGUARD_BOTTOM_AREA)) {
            leftShortcutHandle =
                KeyguardQuickAffordanceViewBinder.bind(
                    keyguardRootView.requireViewById(R.id.start_button),
                    keyguardQuickAffordancesCombinedViewModel.startButton,
                    keyguardRootViewModel.alpha,
                    falsingManager,
                    vibratorHelper,
                ) {
                    indicationController.showTransientIndication(it)
                }
        } else {
            keyguardRootView.findViewById<View?>(R.id.start_button)?.let {
                keyguardRootView.removeView(it)
            }
        }
    }

    private fun bindRightShortcut() {
        rightShortcutHandle?.destroy()
        if (featureFlags.isEnabled(Flags.MIGRATE_SPLIT_KEYGUARD_BOTTOM_AREA)) {
            rightShortcutHandle =
                KeyguardQuickAffordanceViewBinder.bind(
                    keyguardRootView.requireViewById(R.id.end_button),
                    keyguardQuickAffordancesCombinedViewModel.endButton,
                    keyguardRootViewModel.alpha,
                    falsingManager,
                    vibratorHelper,
                ) {
                    indicationController.showTransientIndication(it)
                }
        } else {
            keyguardRootView.findViewById<View?>(R.id.end_button)?.let {
                keyguardRootView.removeView(it)
            }
        }
    }

    fun bindKeyguardStatusView(legacyParent: ViewGroup) {
        // At startup, 2 views with the ID `R.id.keyguard_status_view` will be available.
        // Disable one of them
        if (featureFlags.isEnabled(Flags.MIGRATE_KEYGUARD_STATUS_VIEW)) {
            legacyParent.findViewById<View>(R.id.keyguard_status_view)?.let {
                legacyParent.removeView(it)
            }

            val keyguardStatusView = keyguardRootView.addStatusView()
            val statusViewComponent = keyguardStatusViewComponentFactory.build(keyguardStatusView)
            val controller = statusViewComponent.getKeyguardStatusViewController()
            controller.init()
            keyguardStatusViewController = controller
        } else {
            keyguardRootView.findViewById<View?>(R.id.keyguard_status_view)?.let {
                keyguardRootView.removeView(it)
            }
        }
    }

    private fun bindCommunalWidgetArea() {
        if (!featureFlags.isEnabled(Flags.WIDGET_ON_KEYGUARD)) {
            return
        }

        CommunalWidgetViewBinder.bind(
            keyguardRootView,
            communalWidgetViewModel,
            communalWidgetViewAdapter,
            keyguardBlueprintInteractor,
        )
    }

    /**
     * Temporary, to allow NotificationPanelViewController to use the same instance while code is
     * migrated: b/288242803
+2 −111
Original line number Diff line number Diff line
@@ -19,123 +19,14 @@ package com.android.systemui.keyguard.ui.view

import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View
import android.widget.ImageView
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.content.res.ResourcesCompat
import com.android.keyguard.KeyguardStatusView
import com.android.keyguard.LockIconView
import com.android.systemui.R
import com.android.systemui.animation.view.LaunchableImageView

/** Provides a container for all keyguard ui content. */
class KeyguardRootView(
    context: Context,
    private val attrs: AttributeSet?,
    attrs: AttributeSet?,
) :
    ConstraintLayout(
        context,
        attrs,
    ) {

    private var statusView: KeyguardStatusView? = null

    init {
        addIndicationTextArea()
        addLockIconView()
        addAmbientIndicationArea()
        addLeftShortcut()
        addRightShortcut()
        addSettingsPopupMenu()
        addStatusView()
    }

    private fun addIndicationTextArea() {
        val view = KeyguardIndicationArea(context, attrs)
        addView(view)
    }

    private fun addLockIconView() {
        val view = LockIconView(context, attrs).apply { id = R.id.lock_icon_view }
        addView(view)
    }

    private fun addAmbientIndicationArea() {
        LayoutInflater.from(context).inflate(R.layout.ambient_indication, this)
    }

    private fun addLeftShortcut() {
        val padding = resources.getDimensionPixelSize(R.dimen.keyguard_affordance_fixed_padding)
        val view =
            LaunchableImageView(context, attrs).apply {
                id = R.id.start_button
                scaleType = ImageView.ScaleType.FIT_CENTER
                background =
                    ResourcesCompat.getDrawable(
                        context.resources,
                        R.drawable.keyguard_bottom_affordance_bg,
                        context.theme
                    )
                foreground =
                    ResourcesCompat.getDrawable(
                        context.resources,
                        R.drawable.keyguard_bottom_affordance_selected_border,
                        context.theme
    )
                visibility = View.INVISIBLE
                setPadding(padding, padding, padding, padding)
            }
        addView(view)
    }

    private fun addRightShortcut() {
        val padding = resources.getDimensionPixelSize(R.dimen.keyguard_affordance_fixed_padding)
        val view =
            LaunchableImageView(context, attrs).apply {
                id = R.id.end_button
                scaleType = ImageView.ScaleType.FIT_CENTER
                background =
                    ResourcesCompat.getDrawable(
                        context.resources,
                        R.drawable.keyguard_bottom_affordance_bg,
                        context.theme
                    )
                foreground =
                    ResourcesCompat.getDrawable(
                        context.resources,
                        R.drawable.keyguard_bottom_affordance_selected_border,
                        context.theme
                    )
                visibility = View.INVISIBLE
                setPadding(padding, padding, padding, padding)
            }
        addView(view)
    }

    private fun addSettingsPopupMenu() {
        val view =
            LayoutInflater.from(context)
                .inflate(R.layout.keyguard_settings_popup_menu, this, false)
                .apply {
                    id = R.id.keyguard_settings_button
                    visibility = GONE
                }
        addView(view)
    }

    fun addStatusView(): KeyguardStatusView {
        // StatusView may need to be rebuilt on config changes. Remove and reinflate
        statusView?.let { removeView(it) }
        val view =
            (LayoutInflater.from(context).inflate(R.layout.keyguard_status_view, this, false)
                    as KeyguardStatusView)
                .apply {
                    setClipChildren(false)
                    statusView = this
                }

        addView(view)
        return view
    }
}
+0 −14
Original line number Diff line number Diff line
@@ -17,10 +17,7 @@

package com.android.systemui.keyguard.ui.view.layout.blueprints

import androidx.constraintlayout.widget.ConstraintLayout
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.flags.FeatureFlags
import com.android.systemui.flags.Flags
import com.android.systemui.keyguard.shared.model.KeyguardBlueprint
import com.android.systemui.keyguard.ui.view.layout.sections.AodNotificationIconsSection
import com.android.systemui.keyguard.ui.view.layout.sections.DefaultAmbientIndicationAreaSection
@@ -54,7 +51,6 @@ constructor(
    defaultNotificationStackScrollLayoutSection: DefaultNotificationStackScrollLayoutSection,
    splitShadeGuidelines: SplitShadeGuidelines,
    aodNotificationIconsSection: AodNotificationIconsSection,
    private val featureFlags: FeatureFlags,
) : KeyguardBlueprint {
    override val id: String = DEFAULT

@@ -72,16 +68,6 @@ constructor(
            aodNotificationIconsSection,
        )

    override fun replaceViews(
        previousBlueprint: KeyguardBlueprint?,
        constraintLayout: ConstraintLayout,
        bindData: Boolean
    ) {
        if (featureFlags.isEnabled(Flags.LAZY_INFLATE_KEYGUARD)) {
            super.replaceViews(previousBlueprint, constraintLayout, bindData)
        }
    }

    companion object {
        const val DEFAULT = "default"
    }
+0 −7
Original line number Diff line number Diff line
@@ -1404,13 +1404,6 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump

        updateViewControllers(userAvatarView, keyguardUserSwitcherView);

        if (mFeatureFlags.isEnabled(Flags.MIGRATE_KEYGUARD_STATUS_VIEW) && !mFeatureFlags.isEnabled(
                Flags.LAZY_INFLATE_KEYGUARD)) {
            attachSplitShadeMediaPlayerContainer(
                    mKeyguardViewConfigurator.getKeyguardRootView()
                        .findViewById(R.id.status_view_media_container));
        }

        if (!mFeatureFlags.isEnabled(Flags.MIGRATE_SPLIT_KEYGUARD_BOTTOM_AREA)) {
            // Update keyguard bottom area
            int index = mView.indexOfChild(mKeyguardBottomArea);
+0 −15
Original line number Diff line number Diff line
@@ -23,8 +23,6 @@ import androidx.constraintlayout.widget.ConstraintLayout
import androidx.constraintlayout.widget.ConstraintSet
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.flags.FakeFeatureFlags
import com.android.systemui.flags.Flags
import com.android.systemui.keyguard.shared.model.KeyguardBlueprint
import com.android.systemui.keyguard.shared.model.KeyguardSection
import com.android.systemui.keyguard.ui.view.KeyguardRootView
@@ -66,8 +64,6 @@ class DefaultKeyguardBlueprintTest : SysuiTestCase() {
    @Mock private lateinit var splitShadeGuidelines: SplitShadeGuidelines
    @Mock private lateinit var aodNotificationIconsSection: AodNotificationIconsSection

    private val featureFlags = FakeFeatureFlags()

    @Before
    fun setup() {
        MockitoAnnotations.initMocks(this)
@@ -84,21 +80,11 @@ class DefaultKeyguardBlueprintTest : SysuiTestCase() {
                defaultNSSLSection,
                splitShadeGuidelines,
                aodNotificationIconsSection,
                featureFlags,
            )
        featureFlags.set(Flags.LAZY_INFLATE_KEYGUARD, false)
    }

    @Test
    fun replaceViews() {
        val constraintLayout = ConstraintLayout(context, null)
        underTest.replaceViews(null, constraintLayout)
        underTest.sections.forEach { verify(it, never()).addViews(constraintLayout) }
    }

    @Test
    fun replaceViews_lazyInflateFlagOn() {
        featureFlags.set(Flags.LAZY_INFLATE_KEYGUARD, true)
        val constraintLayout = ConstraintLayout(context, null)
        underTest.replaceViews(null, constraintLayout)
        underTest.sections.forEach { verify(it).addViews(constraintLayout) }
@@ -110,7 +96,6 @@ class DefaultKeyguardBlueprintTest : SysuiTestCase() {
        val someSection = mock(KeyguardSection::class.java)
        whenever(prevBlueprint.sections)
            .thenReturn(underTest.sections.minus(defaultLockIconSection).plus(someSection))
        featureFlags.set(Flags.LAZY_INFLATE_KEYGUARD, true)
        val constraintLayout = ConstraintLayout(context, null)
        underTest.replaceViews(prevBlueprint, constraintLayout)
        underTest.sections.minus(defaultLockIconSection).forEach {