1 /* 2 * Copyright (C) 2024 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.qs.panels.ui.viewmodel.toolbar 18 19 import android.content.Context 20 import android.view.ContextThemeWrapper 21 import androidx.compose.runtime.getValue 22 import androidx.compose.runtime.mutableStateOf 23 import androidx.compose.runtime.setValue 24 import com.android.systemui.animation.Expandable 25 import com.android.systemui.classifier.domain.interactor.FalsingInteractor 26 import com.android.systemui.classifier.domain.interactor.runIfNotFalseTap 27 import com.android.systemui.development.ui.viewmodel.BuildNumberViewModel 28 import com.android.systemui.globalactions.GlobalActionsDialogLite 29 import com.android.systemui.lifecycle.ExclusiveActivatable 30 import com.android.systemui.lifecycle.Hydrator 31 import com.android.systemui.qs.footer.domain.interactor.FooterActionsInteractor 32 import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsButtonViewModel 33 import com.android.systemui.qs.footer.ui.viewmodel.powerButtonViewModel 34 import com.android.systemui.qs.footer.ui.viewmodel.settingsButtonViewModel 35 import com.android.systemui.qs.footer.ui.viewmodel.userSwitcherViewModel 36 import com.android.systemui.res.R 37 import com.android.systemui.shade.ShadeDisplayAware 38 import com.android.systemui.shade.domain.interactor.ShadeModeInteractor 39 import dagger.assisted.AssistedFactory 40 import dagger.assisted.AssistedInject 41 import javax.inject.Provider 42 import kotlinx.coroutines.awaitCancellation 43 import kotlinx.coroutines.coroutineScope 44 import kotlinx.coroutines.launch 45 46 class ToolbarViewModel 47 @AssistedInject 48 constructor( 49 editModeButtonViewModelFactory: EditModeButtonViewModel.Factory, 50 val buildNumberViewModelFactory: BuildNumberViewModel.Factory, 51 private val footerActionsInteractor: FooterActionsInteractor, 52 private val globalActionsDialogLiteProvider: Provider<GlobalActionsDialogLite>, 53 private val falsingInteractor: FalsingInteractor, 54 shadeModeInteractor: ShadeModeInteractor, 55 @ShadeDisplayAware appContext: Context, 56 ) : ExclusiveActivatable() { 57 private val qsThemedContext = 58 ContextThemeWrapper(appContext, R.style.Theme_SystemUI_QuickSettings) 59 private val hydrator = Hydrator("ToolbarViewModel.hydrator") 60 61 val powerButtonViewModel: FooterActionsButtonViewModel? by 62 hydrator.hydratedStateOf( 63 traceName = "powerButtonViewModel", 64 initialValue = null, 65 source = 66 powerButtonViewModel( 67 qsThemedContext, 68 ::onPowerButtonClicked, 69 shadeModeInteractor.shadeMode, 70 ), 71 ) 72 73 val settingsButtonViewModel = 74 settingsButtonViewModel(qsThemedContext, ::onSettingsButtonClicked) 75 76 val userSwitcherViewModel: FooterActionsButtonViewModel? by 77 hydrator.hydratedStateOf( 78 traceName = "userSwitcherViewModel", 79 initialValue = null, 80 source = 81 userSwitcherViewModel( 82 qsThemedContext, 83 footerActionsInteractor, 84 ::onUserSwitcherClicked, 85 ), 86 ) 87 88 val editModeButtonViewModel: EditModeButtonViewModel = editModeButtonViewModelFactory.create() 89 onActivatednull90 override suspend fun onActivated(): Nothing { 91 coroutineScope { 92 launch { 93 try { 94 globalActionsDialogLite = globalActionsDialogLiteProvider.get() 95 awaitCancellation() 96 } finally { 97 globalActionsDialogLite?.destroy() 98 } 99 } 100 launch { hydrator.activate() } 101 awaitCancellation() 102 } 103 } 104 105 private var globalActionsDialogLite: GlobalActionsDialogLite? by mutableStateOf(null) 106 onPowerButtonClickednull107 private fun onPowerButtonClicked(expandable: Expandable) { 108 falsingInteractor.runIfNotFalseTap { 109 globalActionsDialogLite?.let { 110 footerActionsInteractor.showPowerMenuDialog(it, expandable) 111 } 112 } 113 } 114 onUserSwitcherClickednull115 private fun onUserSwitcherClicked(expandable: Expandable) { 116 falsingInteractor.runIfNotFalseTap { footerActionsInteractor.showUserSwitcher(expandable) } 117 } 118 onSettingsButtonClickednull119 private fun onSettingsButtonClicked(expandable: Expandable) { 120 falsingInteractor.runIfNotFalseTap { footerActionsInteractor.showSettings(expandable) } 121 } 122 123 @AssistedFactory 124 interface Factory { createnull125 fun create(): ToolbarViewModel 126 } 127 } 128