Loading packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettings.kt +0 −7 Original line number Original line Diff line number Diff line Loading @@ -25,9 +25,6 @@ import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.defaultMinSize import androidx.compose.foundation.layout.defaultMinSize import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.LaunchedEffect Loading @@ -36,7 +33,6 @@ import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp import androidx.compose.ui.viewinterop.AndroidView import androidx.compose.ui.viewinterop.AndroidView Loading Loading @@ -76,9 +72,6 @@ fun SceneScope.QuickSettings( .element(QuickSettings.Elements.Content) .element(QuickSettings.Elements.Content) .fillMaxWidth() .fillMaxWidth() .defaultMinSize(minHeight = 300.dp) .defaultMinSize(minHeight = 300.dp) .clip(RoundedCornerShape(32.dp)) .background(MaterialTheme.colorScheme.primary) .padding(1.dp), ) { ) { QuickSettingsContent(qsSceneAdapter = qsSceneAdapter, state) QuickSettingsContent(qsSceneAdapter = qsSceneAdapter, state) } } Loading packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsScene.kt +50 −42 Original line number Original line Diff line number Diff line Loading @@ -23,7 +23,7 @@ import androidx.compose.animation.expandVertically import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeOut import androidx.compose.animation.fadeOut import androidx.compose.animation.shrinkVertically import androidx.compose.animation.shrinkVertically import androidx.compose.foundation.clickable import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer Loading @@ -31,6 +31,7 @@ import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding import androidx.compose.material3.MaterialTheme import androidx.compose.material3.windowsizeclass.WindowWidthSizeClass import androidx.compose.material3.windowsizeclass.WindowWidthSizeClass import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState import androidx.compose.runtime.collectAsState Loading @@ -51,6 +52,7 @@ import com.android.systemui.scene.shared.model.SceneKey import com.android.systemui.scene.ui.composable.ComposableScene import com.android.systemui.scene.ui.composable.ComposableScene import com.android.systemui.shade.ui.composable.CollapsedShadeHeader import com.android.systemui.shade.ui.composable.CollapsedShadeHeader import com.android.systemui.shade.ui.composable.ExpandedShadeHeader import com.android.systemui.shade.ui.composable.ExpandedShadeHeader import com.android.systemui.shade.ui.composable.Shade import com.android.systemui.shade.ui.composable.ShadeHeader import com.android.systemui.shade.ui.composable.ShadeHeader import com.android.systemui.statusbar.phone.StatusBarIconController import com.android.systemui.statusbar.phone.StatusBarIconController import com.android.systemui.statusbar.phone.StatusBarIconController.TintedIconManager import com.android.systemui.statusbar.phone.StatusBarIconController.TintedIconManager Loading Loading @@ -104,15 +106,20 @@ private fun SceneScope.QuickSettingsScene( ) { ) { // TODO(b/280887232): implement the real UI. // TODO(b/280887232): implement the real UI. Box(modifier = modifier.fillMaxSize()) { Box(modifier = modifier.fillMaxSize()) { Box(modifier = Modifier.fillMaxSize()) { val isCustomizing by viewModel.qsSceneAdapter.isCustomizing.collectAsState() val isCustomizing by viewModel.qsSceneAdapter.isCustomizing.collectAsState() val collapsedHeaderHeight = val collapsedHeaderHeight = with(LocalDensity.current) { ShadeHeader.Dimensions.CollapsedHeight.roundToPx() } with(LocalDensity.current) { ShadeHeader.Dimensions.CollapsedHeight.roundToPx() } Spacer( modifier = Modifier.element(Shade.Elements.ScrimBackground) .fillMaxSize() .background(MaterialTheme.colorScheme.scrim, shape = Shade.Shapes.Scrim) ) Column( Column( horizontalAlignment = Alignment.CenterHorizontally, horizontalAlignment = Alignment.CenterHorizontally, modifier = modifier = Modifier.fillMaxSize() Modifier.fillMaxSize().padding(start = 16.dp, end = 16.dp, bottom = 48.dp) .clickable(onClick = { viewModel.onContentClicked() }) .padding(start = 16.dp, end = 16.dp, bottom = 48.dp) ) { ) { when (LocalWindowSizeClass.current.widthSizeClass) { when (LocalWindowSizeClass.current.widthSizeClass) { WindowWidthSizeClass.Compact -> WindowWidthSizeClass.Compact -> Loading Loading @@ -152,6 +159,7 @@ private fun SceneScope.QuickSettingsScene( QSSceneAdapter.State.QS QSSceneAdapter.State.QS ) ) } } } HeadsUpNotificationSpace( HeadsUpNotificationSpace( viewModel = viewModel.notifications, viewModel = viewModel.notifications, isPeekFromBottom = true, isPeekFromBottom = true, Loading packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModel.kt +0 −5 Original line number Original line Diff line number Diff line Loading @@ -17,7 +17,6 @@ package com.android.systemui.qs.ui.viewmodel package com.android.systemui.qs.ui.viewmodel import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.SysUISingleton import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor import com.android.systemui.qs.ui.adapter.QSSceneAdapter import com.android.systemui.qs.ui.adapter.QSSceneAdapter import com.android.systemui.scene.shared.model.Direction import com.android.systemui.scene.shared.model.Direction import com.android.systemui.scene.shared.model.SceneKey import com.android.systemui.scene.shared.model.SceneKey Loading @@ -33,14 +32,10 @@ import kotlinx.coroutines.flow.map class QuickSettingsSceneViewModel class QuickSettingsSceneViewModel @Inject @Inject constructor( constructor( private val deviceEntryInteractor: DeviceEntryInteractor, val shadeHeaderViewModel: ShadeHeaderViewModel, val shadeHeaderViewModel: ShadeHeaderViewModel, val qsSceneAdapter: QSSceneAdapter, val qsSceneAdapter: QSSceneAdapter, val notifications: NotificationsPlaceholderViewModel, val notifications: NotificationsPlaceholderViewModel, ) { ) { /** Notifies that some content in quick settings was clicked. */ fun onContentClicked() = deviceEntryInteractor.attemptDeviceEntry() val destinationScenes = val destinationScenes = qsSceneAdapter.isCustomizing.map { customizing -> qsSceneAdapter.isCustomizing.map { customizing -> if (customizing) { if (customizing) { Loading packages/SystemUI/tests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModelTest.kt +0 −37 Original line number Original line Diff line number Diff line Loading @@ -19,7 +19,6 @@ package com.android.systemui.qs.ui.viewmodel import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.SysuiTestCase import com.android.systemui.authentication.shared.model.AuthenticationMethodModel import com.android.systemui.coroutines.collectLastValue import com.android.systemui.coroutines.collectLastValue import com.android.systemui.flags.FakeFeatureFlagsClassic import com.android.systemui.flags.FakeFeatureFlagsClassic import com.android.systemui.flags.Flags import com.android.systemui.flags.Flags Loading @@ -39,14 +38,11 @@ import com.android.systemui.statusbar.pipeline.mobile.util.FakeMobileMappingsPro import com.android.systemui.statusbar.pipeline.shared.data.repository.FakeConnectivityRepository import com.android.systemui.statusbar.pipeline.shared.data.repository.FakeConnectivityRepository import com.android.systemui.util.mockito.mock import com.android.systemui.util.mockito.mock import com.google.common.truth.Truth.assertThat import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest import kotlinx.coroutines.test.runTest import org.junit.Before import org.junit.Before import org.junit.Test import org.junit.Test import org.junit.runner.RunWith import org.junit.runner.RunWith @OptIn(ExperimentalCoroutinesApi::class) @SmallTest @SmallTest @RunWith(AndroidJUnit4::class) @RunWith(AndroidJUnit4::class) class QuickSettingsSceneViewModelTest : SysuiTestCase() { class QuickSettingsSceneViewModelTest : SysuiTestCase() { Loading Loading @@ -90,47 +86,14 @@ class QuickSettingsSceneViewModelTest : SysuiTestCase() { broadcastDispatcher = fakeBroadcastDispatcher, broadcastDispatcher = fakeBroadcastDispatcher, ) ) val authenticationInteractor = utils.authenticationInteractor() underTest = underTest = QuickSettingsSceneViewModel( QuickSettingsSceneViewModel( deviceEntryInteractor = utils.deviceEntryInteractor( authenticationInteractor = authenticationInteractor, sceneInteractor = sceneInteractor, ), shadeHeaderViewModel = shadeHeaderViewModel, shadeHeaderViewModel = shadeHeaderViewModel, qsSceneAdapter = qsFlexiglassAdapter, qsSceneAdapter = qsFlexiglassAdapter, notifications = utils.notificationsPlaceholderViewModel(), notifications = utils.notificationsPlaceholderViewModel(), ) ) } } @Test fun onContentClicked_deviceUnlocked_switchesToGone() = testScope.runTest { val currentScene by collectLastValue(sceneInteractor.desiredScene) utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin) utils.deviceEntryRepository.setUnlocked(true) runCurrent() underTest.onContentClicked() assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Gone)) } @Test fun onContentClicked_deviceLockedSecurely_switchesToBouncer() = testScope.runTest { val currentScene by collectLastValue(sceneInteractor.desiredScene) utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin) utils.deviceEntryRepository.setUnlocked(false) runCurrent() underTest.onContentClicked() assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer)) } @Test @Test fun destinationsNotCustomizing() = fun destinationsNotCustomizing() = testScope.runTest { testScope.runTest { Loading Loading
packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettings.kt +0 −7 Original line number Original line Diff line number Diff line Loading @@ -25,9 +25,6 @@ import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.defaultMinSize import androidx.compose.foundation.layout.defaultMinSize import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.LaunchedEffect Loading @@ -36,7 +33,6 @@ import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp import androidx.compose.ui.viewinterop.AndroidView import androidx.compose.ui.viewinterop.AndroidView Loading Loading @@ -76,9 +72,6 @@ fun SceneScope.QuickSettings( .element(QuickSettings.Elements.Content) .element(QuickSettings.Elements.Content) .fillMaxWidth() .fillMaxWidth() .defaultMinSize(minHeight = 300.dp) .defaultMinSize(minHeight = 300.dp) .clip(RoundedCornerShape(32.dp)) .background(MaterialTheme.colorScheme.primary) .padding(1.dp), ) { ) { QuickSettingsContent(qsSceneAdapter = qsSceneAdapter, state) QuickSettingsContent(qsSceneAdapter = qsSceneAdapter, state) } } Loading
packages/SystemUI/compose/features/src/com/android/systemui/qs/ui/composable/QuickSettingsScene.kt +50 −42 Original line number Original line Diff line number Diff line Loading @@ -23,7 +23,7 @@ import androidx.compose.animation.expandVertically import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeOut import androidx.compose.animation.fadeOut import androidx.compose.animation.shrinkVertically import androidx.compose.animation.shrinkVertically import androidx.compose.foundation.clickable import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer Loading @@ -31,6 +31,7 @@ import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding import androidx.compose.material3.MaterialTheme import androidx.compose.material3.windowsizeclass.WindowWidthSizeClass import androidx.compose.material3.windowsizeclass.WindowWidthSizeClass import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState import androidx.compose.runtime.collectAsState Loading @@ -51,6 +52,7 @@ import com.android.systemui.scene.shared.model.SceneKey import com.android.systemui.scene.ui.composable.ComposableScene import com.android.systemui.scene.ui.composable.ComposableScene import com.android.systemui.shade.ui.composable.CollapsedShadeHeader import com.android.systemui.shade.ui.composable.CollapsedShadeHeader import com.android.systemui.shade.ui.composable.ExpandedShadeHeader import com.android.systemui.shade.ui.composable.ExpandedShadeHeader import com.android.systemui.shade.ui.composable.Shade import com.android.systemui.shade.ui.composable.ShadeHeader import com.android.systemui.shade.ui.composable.ShadeHeader import com.android.systemui.statusbar.phone.StatusBarIconController import com.android.systemui.statusbar.phone.StatusBarIconController import com.android.systemui.statusbar.phone.StatusBarIconController.TintedIconManager import com.android.systemui.statusbar.phone.StatusBarIconController.TintedIconManager Loading Loading @@ -104,15 +106,20 @@ private fun SceneScope.QuickSettingsScene( ) { ) { // TODO(b/280887232): implement the real UI. // TODO(b/280887232): implement the real UI. Box(modifier = modifier.fillMaxSize()) { Box(modifier = modifier.fillMaxSize()) { Box(modifier = Modifier.fillMaxSize()) { val isCustomizing by viewModel.qsSceneAdapter.isCustomizing.collectAsState() val isCustomizing by viewModel.qsSceneAdapter.isCustomizing.collectAsState() val collapsedHeaderHeight = val collapsedHeaderHeight = with(LocalDensity.current) { ShadeHeader.Dimensions.CollapsedHeight.roundToPx() } with(LocalDensity.current) { ShadeHeader.Dimensions.CollapsedHeight.roundToPx() } Spacer( modifier = Modifier.element(Shade.Elements.ScrimBackground) .fillMaxSize() .background(MaterialTheme.colorScheme.scrim, shape = Shade.Shapes.Scrim) ) Column( Column( horizontalAlignment = Alignment.CenterHorizontally, horizontalAlignment = Alignment.CenterHorizontally, modifier = modifier = Modifier.fillMaxSize() Modifier.fillMaxSize().padding(start = 16.dp, end = 16.dp, bottom = 48.dp) .clickable(onClick = { viewModel.onContentClicked() }) .padding(start = 16.dp, end = 16.dp, bottom = 48.dp) ) { ) { when (LocalWindowSizeClass.current.widthSizeClass) { when (LocalWindowSizeClass.current.widthSizeClass) { WindowWidthSizeClass.Compact -> WindowWidthSizeClass.Compact -> Loading Loading @@ -152,6 +159,7 @@ private fun SceneScope.QuickSettingsScene( QSSceneAdapter.State.QS QSSceneAdapter.State.QS ) ) } } } HeadsUpNotificationSpace( HeadsUpNotificationSpace( viewModel = viewModel.notifications, viewModel = viewModel.notifications, isPeekFromBottom = true, isPeekFromBottom = true, Loading
packages/SystemUI/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModel.kt +0 −5 Original line number Original line Diff line number Diff line Loading @@ -17,7 +17,6 @@ package com.android.systemui.qs.ui.viewmodel package com.android.systemui.qs.ui.viewmodel import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.SysUISingleton import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor import com.android.systemui.qs.ui.adapter.QSSceneAdapter import com.android.systemui.qs.ui.adapter.QSSceneAdapter import com.android.systemui.scene.shared.model.Direction import com.android.systemui.scene.shared.model.Direction import com.android.systemui.scene.shared.model.SceneKey import com.android.systemui.scene.shared.model.SceneKey Loading @@ -33,14 +32,10 @@ import kotlinx.coroutines.flow.map class QuickSettingsSceneViewModel class QuickSettingsSceneViewModel @Inject @Inject constructor( constructor( private val deviceEntryInteractor: DeviceEntryInteractor, val shadeHeaderViewModel: ShadeHeaderViewModel, val shadeHeaderViewModel: ShadeHeaderViewModel, val qsSceneAdapter: QSSceneAdapter, val qsSceneAdapter: QSSceneAdapter, val notifications: NotificationsPlaceholderViewModel, val notifications: NotificationsPlaceholderViewModel, ) { ) { /** Notifies that some content in quick settings was clicked. */ fun onContentClicked() = deviceEntryInteractor.attemptDeviceEntry() val destinationScenes = val destinationScenes = qsSceneAdapter.isCustomizing.map { customizing -> qsSceneAdapter.isCustomizing.map { customizing -> if (customizing) { if (customizing) { Loading
packages/SystemUI/tests/src/com/android/systemui/qs/ui/viewmodel/QuickSettingsSceneViewModelTest.kt +0 −37 Original line number Original line Diff line number Diff line Loading @@ -19,7 +19,6 @@ package com.android.systemui.qs.ui.viewmodel import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.SysuiTestCase import com.android.systemui.authentication.shared.model.AuthenticationMethodModel import com.android.systemui.coroutines.collectLastValue import com.android.systemui.coroutines.collectLastValue import com.android.systemui.flags.FakeFeatureFlagsClassic import com.android.systemui.flags.FakeFeatureFlagsClassic import com.android.systemui.flags.Flags import com.android.systemui.flags.Flags Loading @@ -39,14 +38,11 @@ import com.android.systemui.statusbar.pipeline.mobile.util.FakeMobileMappingsPro import com.android.systemui.statusbar.pipeline.shared.data.repository.FakeConnectivityRepository import com.android.systemui.statusbar.pipeline.shared.data.repository.FakeConnectivityRepository import com.android.systemui.util.mockito.mock import com.android.systemui.util.mockito.mock import com.google.common.truth.Truth.assertThat import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest import kotlinx.coroutines.test.runTest import org.junit.Before import org.junit.Before import org.junit.Test import org.junit.Test import org.junit.runner.RunWith import org.junit.runner.RunWith @OptIn(ExperimentalCoroutinesApi::class) @SmallTest @SmallTest @RunWith(AndroidJUnit4::class) @RunWith(AndroidJUnit4::class) class QuickSettingsSceneViewModelTest : SysuiTestCase() { class QuickSettingsSceneViewModelTest : SysuiTestCase() { Loading Loading @@ -90,47 +86,14 @@ class QuickSettingsSceneViewModelTest : SysuiTestCase() { broadcastDispatcher = fakeBroadcastDispatcher, broadcastDispatcher = fakeBroadcastDispatcher, ) ) val authenticationInteractor = utils.authenticationInteractor() underTest = underTest = QuickSettingsSceneViewModel( QuickSettingsSceneViewModel( deviceEntryInteractor = utils.deviceEntryInteractor( authenticationInteractor = authenticationInteractor, sceneInteractor = sceneInteractor, ), shadeHeaderViewModel = shadeHeaderViewModel, shadeHeaderViewModel = shadeHeaderViewModel, qsSceneAdapter = qsFlexiglassAdapter, qsSceneAdapter = qsFlexiglassAdapter, notifications = utils.notificationsPlaceholderViewModel(), notifications = utils.notificationsPlaceholderViewModel(), ) ) } } @Test fun onContentClicked_deviceUnlocked_switchesToGone() = testScope.runTest { val currentScene by collectLastValue(sceneInteractor.desiredScene) utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin) utils.deviceEntryRepository.setUnlocked(true) runCurrent() underTest.onContentClicked() assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Gone)) } @Test fun onContentClicked_deviceLockedSecurely_switchesToBouncer() = testScope.runTest { val currentScene by collectLastValue(sceneInteractor.desiredScene) utils.authenticationRepository.setAuthenticationMethod(AuthenticationMethodModel.Pin) utils.deviceEntryRepository.setUnlocked(false) runCurrent() underTest.onContentClicked() assertThat(currentScene).isEqualTo(SceneModel(SceneKey.Bouncer)) } @Test @Test fun destinationsNotCustomizing() = fun destinationsNotCustomizing() = testScope.runTest { testScope.runTest { Loading