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

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

Merge "Move NotificationStack to enableKeyguardCompose" into main

parents 5f1c94d0 08472931
Loading
Loading
Loading
Loading
+66 −35
Original line number Diff line number Diff line
@@ -19,6 +19,11 @@ package com.android.systemui.keyguard.ui.composable.section
import android.content.Context
import android.view.ViewGroup
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import com.android.compose.animation.scene.SceneScope
import com.android.systemui.dagger.SysUISingleton
@@ -40,33 +45,47 @@ import com.android.systemui.statusbar.notification.stack.ui.viewmodel.Notificati
import com.android.systemui.statusbar.notification.stack.ui.viewmodel.SharedNotificationContainerViewModel
import javax.inject.Inject
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.DisposableHandle

@SysUISingleton
class NotificationSection
@Inject
constructor(
    @Application context: Context,
    @Application private val context: Context,
    private val viewModel: NotificationsPlaceholderViewModel,
    controller: NotificationStackScrollLayoutController,
    sceneContainerFlags: SceneContainerFlags,
    sharedNotificationContainer: SharedNotificationContainer,
    sharedNotificationContainerViewModel: SharedNotificationContainerViewModel,
    stackScrollLayout: NotificationStackScrollLayout,
    notificationStackAppearanceViewModel: NotificationStackAppearanceViewModel,
    ambientState: AmbientState,
    notificationStackSizeCalculator: NotificationStackSizeCalculator,
    @Main mainDispatcher: CoroutineDispatcher,
    private val controller: NotificationStackScrollLayoutController,
    private val sceneContainerFlags: SceneContainerFlags,
    private val sharedNotificationContainer: SharedNotificationContainer,
    private val sharedNotificationContainerViewModel: SharedNotificationContainerViewModel,
    private val stackScrollLayout: NotificationStackScrollLayout,
    private val notificationStackAppearanceViewModel: NotificationStackAppearanceViewModel,
    private val ambientState: AmbientState,
    private val notificationStackSizeCalculator: NotificationStackSizeCalculator,
    @Main private val mainDispatcher: CoroutineDispatcher,
) {
    init {
        if (!KeyguardShadeMigrationNssl.isUnexpectedlyInLegacyMode()) {
            // This scene container section moves the NSSL to the SharedNotificationContainer. This
            //  also requires that SharedNotificationContainer gets moved to the SceneWindowRootView
            //  by the SceneWindowRootViewBinder.
            // Prior to Scene Container, but when the KeyguardShadeMigrationNssl flag is enabled,
            //  NSSL is moved into this container by the NotificationStackScrollLayoutSection.
    @Composable
    fun SceneScope.Notifications(modifier: Modifier = Modifier) {
        if (KeyguardShadeMigrationNssl.isUnexpectedlyInLegacyMode()) {
            // This scene container section moves the NSSL to the SharedNotificationContainer.
            // This also requires that SharedNotificationContainer gets moved to the
            // SceneWindowRootView by the SceneWindowRootViewBinder. Prior to Scene Container,
            // but when the KeyguardShadeMigrationNssl flag is enabled, NSSL is moved into this
            // container by the NotificationStackScrollLayoutSection.
            return
        }

        var isBound by remember { mutableStateOf(false) }

        DisposableEffect(Unit) {
            val disposableHandles: MutableList<DisposableHandle> = mutableListOf()

            // Ensure stackScrollLayout is a child of sharedNotificationContainer.
            if (stackScrollLayout.parent != sharedNotificationContainer) {
                (stackScrollLayout.parent as? ViewGroup)?.removeView(stackScrollLayout)
                sharedNotificationContainer.addNotificationStackScrollLayout(stackScrollLayout)
            }

            disposableHandles.add(
                SharedNotificationContainerBinder.bind(
                    sharedNotificationContainer,
                    sharedNotificationContainerViewModel,
@@ -75,8 +94,10 @@ constructor(
                    notificationStackSizeCalculator,
                    mainDispatcher,
                )
            )

            if (sceneContainerFlags.flexiNotifsEnabled()) {
                disposableHandles.add(
                    NotificationStackAppearanceViewBinder.bind(
                        context,
                        sharedNotificationContainer,
@@ -84,12 +105,22 @@ constructor(
                        ambientState,
                        controller,
                    )
                )
            }

            isBound = true

            onDispose {
                disposableHandles.forEach { it.dispose() }
                disposableHandles.clear()
                isBound = false
            }
        }

    @Composable
    fun SceneScope.Notifications(modifier: Modifier = Modifier) {
        if (!isBound) {
            return
        }

        NotificationStack(
            viewModel = viewModel,
            modifier = modifier,
+48 −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.notification.stack.ui.viewmodel

import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.common.shared.model.NotificationContainerBounds
import com.android.systemui.keyguard.domain.interactor.keyguardInteractor
import com.android.systemui.statusbar.notification.stack.domain.interactor.notificationStackAppearanceInteractor
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
import org.junit.Test
import org.junit.runner.RunWith

@SmallTest
@RunWith(AndroidJUnit4::class)
class NotificationsPlaceholderViewModelTest : SysuiTestCase() {
    private val kosmos = testKosmos()
    private val underTest = kosmos.notificationsPlaceholderViewModel
    @Test
    fun onBoundsChanged_setsNotificationContainerBounds() {
        underTest.onBoundsChanged(left = 5f, top = 5f, right = 5f, bottom = 5f)
        assertThat(kosmos.keyguardInteractor.notificationContainerBounds.value)
            .isEqualTo(NotificationContainerBounds(left = 5f, top = 5f, right = 5f, bottom = 5f))
        assertThat(kosmos.notificationStackAppearanceInteractor.stackBounds.value)
            .isEqualTo(NotificationContainerBounds(left = 5f, top = 5f, right = 5f, bottom = 5f))
    }
    @Test
    fun onContentTopChanged_setsContentTop() {
        underTest.onContentTopChanged(padding = 5f)
        assertThat(kosmos.notificationStackAppearanceInteractor.contentTop.value).isEqualTo(5f)
    }
}
+20 −10
Original line number Diff line number Diff line
@@ -57,7 +57,7 @@ constructor(
    private val mainDispatcher: CoroutineDispatcher,
) : KeyguardSection() {
    private val placeHolderId = R.id.nssl_placeholder
    private var disposableHandle: DisposableHandle? = null
    private val disposableHandles: MutableList<DisposableHandle> = mutableListOf()

    /**
     * Align the notification placeholder bottom to the top of either the lock icon or the ambient
@@ -102,8 +102,9 @@ constructor(
        if (!KeyguardShadeMigrationNssl.isEnabled) {
            return
        }
        disposableHandle?.dispose()
        disposableHandle =

        disposeHandles()
        disposableHandles.add(
            SharedNotificationContainerBinder.bind(
                sharedNotificationContainer,
                sharedNotificationContainerViewModel,
@@ -112,7 +113,10 @@ constructor(
                notificationStackSizeCalculator,
                mainDispatcher,
            )
        )

        if (sceneContainerFlags.flexiNotifsEnabled()) {
            disposableHandles.add(
                NotificationStackAppearanceViewBinder.bind(
                    context,
                    sharedNotificationContainer,
@@ -120,11 +124,17 @@ constructor(
                    ambientState,
                    controller,
                )
            )
        }
    }

    override fun removeViews(constraintLayout: ConstraintLayout) {
        disposableHandle?.dispose()
        disposeHandles()
        constraintLayout.removeView(placeHolderId)
    }

    private fun disposeHandles() {
        disposableHandles.forEach { it.dispose() }
        disposableHandles.clear()
    }
}
+3 −5
Original line number Diff line number Diff line
@@ -2472,11 +2472,9 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
            return 0;
        }
        if (!mKeyguardBypassController.getBypassEnabled()) {
            if (migrateClocksToBlueprint()) {
                View nsslPlaceholder = mView.getRootView().findViewById(R.id.nssl_placeholder);
                if (!mSplitShadeEnabled && nsslPlaceholder != null) {
                    return nsslPlaceholder.getTop();
                }
            if (migrateClocksToBlueprint() && !mSplitShadeEnabled) {
                return (int) mKeyguardInteractor.getNotificationContainerBounds()
                        .getValue().getTop();
            }

            return mClockPositionResult.stackScrollerPadding;
+3 −2
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import com.android.systemui.statusbar.notification.stack.NotificationStackScroll
import com.android.systemui.statusbar.notification.stack.ui.view.SharedNotificationContainer
import com.android.systemui.statusbar.notification.stack.ui.viewmodel.NotificationStackAppearanceViewModel
import kotlin.math.roundToInt
import kotlinx.coroutines.DisposableHandle
import kotlinx.coroutines.launch

/** Binds the shared notification container to its view-model. */
@@ -38,8 +39,8 @@ object NotificationStackAppearanceViewBinder {
        viewModel: NotificationStackAppearanceViewModel,
        ambientState: AmbientState,
        controller: NotificationStackScrollLayoutController,
    ) {
        view.repeatWhenAttached {
    ): DisposableHandle {
        return view.repeatWhenAttached {
            repeatOnLifecycle(Lifecycle.State.CREATED) {
                launch {
                    viewModel.stackBounds.collect { bounds ->
Loading