1 /*
2 * Copyright (C) 2023 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 package com.android.systemui.scene.ui.composable
18
19 import androidx.compose.foundation.layout.Spacer
20 import androidx.compose.foundation.layout.absoluteOffset
21 import androidx.compose.foundation.layout.fillMaxSize
22 import androidx.compose.runtime.Composable
23 import androidx.compose.ui.Modifier
24 import androidx.compose.ui.platform.LocalContext
25 import androidx.compose.ui.platform.LocalDensity
26 import androidx.compose.ui.res.dimensionResource
27 import androidx.compose.ui.unit.IntOffset
28 import com.android.compose.animation.scene.SceneScope
29 import com.android.compose.animation.scene.UserAction
30 import com.android.compose.animation.scene.UserActionResult
31 import com.android.compose.animation.scene.animateSceneDpAsState
32 import com.android.compose.animation.scene.animateSceneFloatAsState
33 import com.android.internal.policy.SystemBarUtils
34 import com.android.systemui.dagger.SysUISingleton
35 import com.android.systemui.notifications.ui.composable.HeadsUpNotificationSpace
36 import com.android.systemui.qs.ui.composable.QuickSettings
37 import com.android.systemui.qs.ui.composable.QuickSettings.SharedValues.MediaLandscapeTopOffset
38 import com.android.systemui.qs.ui.composable.QuickSettings.SharedValues.MediaOffset.Default
39 import com.android.systemui.res.R
40 import com.android.systemui.scene.shared.model.Scenes
41 import com.android.systemui.scene.ui.viewmodel.GoneSceneViewModel
42 import com.android.systemui.statusbar.notification.stack.ui.view.NotificationScrollView
43 import com.android.systemui.statusbar.notification.stack.ui.viewmodel.NotificationsPlaceholderViewModel
44 import dagger.Lazy
45 import javax.inject.Inject
46 import kotlinx.coroutines.flow.StateFlow
47
48 /**
49 * "Gone" is not a real scene but rather the absence of scenes when we want to skip showing any
50 * content from the scene framework.
51 */
52 @SysUISingleton
53 class GoneScene
54 @Inject
55 constructor(
56 private val notificationStackScrolLView: Lazy<NotificationScrollView>,
57 private val notificationsPlaceholderViewModel: NotificationsPlaceholderViewModel,
58 private val viewModel: GoneSceneViewModel,
59 ) : ComposableScene {
60 override val key = Scenes.Gone
61
62 override val destinationScenes: StateFlow<Map<UserAction, UserActionResult>> =
63 viewModel.destinationScenes
64
65 @Composable
Contentnull66 override fun SceneScope.Content(
67 modifier: Modifier,
68 ) {
69 animateSceneFloatAsState(
70 value = QuickSettings.SharedValues.SquishinessValues.GoneSceneStarting,
71 key = QuickSettings.SharedValues.TilesSquishiness,
72 )
73 animateSceneDpAsState(value = Default, key = MediaLandscapeTopOffset, canOverflow = false)
74 Spacer(modifier.fillMaxSize())
75 HeadsUpNotificationStack(
76 stackScrollView = notificationStackScrolLView.get(),
77 viewModel = notificationsPlaceholderViewModel
78 )
79 }
80 }
81
82 @Composable
HeadsUpNotificationStacknull83 private fun SceneScope.HeadsUpNotificationStack(
84 stackScrollView: NotificationScrollView,
85 viewModel: NotificationsPlaceholderViewModel,
86 ) {
87 val context = LocalContext.current
88 val density = LocalDensity.current
89 val statusBarHeight = SystemBarUtils.getStatusBarHeight(context)
90 val headsUpPadding =
91 with(density) { dimensionResource(id = R.dimen.heads_up_status_bar_padding).roundToPx() }
92
93 HeadsUpNotificationSpace(
94 stackScrollView = stackScrollView,
95 viewModel = viewModel,
96 modifier =
97 Modifier.absoluteOffset { IntOffset(x = 0, y = statusBarHeight + headsUpPadding) }
98 )
99 }
100