1 /*
2  * Copyright (C) 2022 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.settings.spa.app.appinfo
18 
19 import android.content.pm.ApplicationInfo
20 import android.content.pm.FeatureFlags as PmFeatureFlags
21 import android.content.pm.FeatureFlagsImpl as PmFeatureFlagsImpl
22 import androidx.compose.runtime.Composable
23 import androidx.compose.runtime.remember
24 import androidx.lifecycle.compose.collectAsStateWithLifecycle
25 import com.android.settingslib.applications.AppUtils
26 import com.android.settingslib.spa.widget.button.ActionButton
27 import com.android.settingslib.spa.widget.button.ActionButtons
28 import kotlinx.coroutines.flow.MutableStateFlow
29 
30 @Composable
31 /**
32  * @param featureFlags can be overridden in tests
33  */
AppButtonsnull34 fun AppButtons(
35     packageInfoPresenter: PackageInfoPresenter,
36     isHibernationSwitchEnabledStateFlow: MutableStateFlow<Boolean>,
37     featureFlags: PmFeatureFlags = PmFeatureFlagsImpl()
38 ) {
39     if (remember(packageInfoPresenter) { packageInfoPresenter.isMainlineModule() }) return
40     val presenter = remember {
41         AppButtonsPresenter(
42             packageInfoPresenter,
43             isHibernationSwitchEnabledStateFlow,
44             featureFlags
45         )
46     }
47     ActionButtons(actionButtons = presenter.getActionButtons())
48 }
49 
PackageInfoPresenternull50 private fun PackageInfoPresenter.isMainlineModule(): Boolean =
51     AppUtils.isMainlineModule(userPackageManager, packageName)
52 
53 private class AppButtonsPresenter(
54     private val packageInfoPresenter: PackageInfoPresenter,
55     isHibernationSwitchEnabledStateFlow: MutableStateFlow<Boolean>,
56     private val featureFlags: PmFeatureFlags
57 ) {
58     private val appLaunchButton = AppLaunchButton(packageInfoPresenter)
59     private val appInstallButton = AppInstallButton(packageInfoPresenter)
60     private val appDisableButton = AppDisableButton(packageInfoPresenter)
61     private val appUninstallButton = AppUninstallButton(packageInfoPresenter)
62     private val appClearButton = AppClearButton(packageInfoPresenter)
63     private val appForceStopButton = AppForceStopButton(packageInfoPresenter)
64     private val appArchiveButton =
65         AppArchiveButton(packageInfoPresenter, isHibernationSwitchEnabledStateFlow)
66     private val appRestoreButton = AppRestoreButton(packageInfoPresenter)
67 
68     @Composable
69     fun getActionButtons() =
70         packageInfoPresenter.flow.collectAsStateWithLifecycle(initialValue = null).value?.let {
71             getActionButtons(checkNotNull(it.applicationInfo))
72         } ?: emptyList()
73 
74     @Composable
75     private fun getActionButtons(app: ApplicationInfo): List<ActionButton> = listOfNotNull(
76         if (isArchivingEnabled(featureFlags)) {
77             if (app.isArchived) {
78                 appRestoreButton.getActionButton(app)
79             } else {
80                 appArchiveButton.getActionButton(app)
81             }
82         } else {
83             appLaunchButton.getActionButton(app)
84         },
85         appInstallButton.getActionButton(app),
86         appDisableButton.getActionButton(app),
87         appUninstallButton.getActionButton(app),
88         appClearButton.getActionButton(app),
89         appForceStopButton.getActionButton(app),
90     )
91 }
92