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.app.settings.SettingsEnums
20 import android.content.pm.ApplicationInfo
21 import android.widget.Toast
22 import androidx.compose.material.icons.Icons
23 import androidx.compose.material.icons.outlined.Add
24 import androidx.compose.runtime.Composable
25 import androidx.compose.runtime.mutableStateOf
26 import androidx.compose.runtime.rememberCoroutineScope
27 import com.android.settings.R
28 import com.android.settings.applications.manageapplications.CloneBackend
29 import com.android.settings.overlay.FeatureFactory.Companion.featureFactory
30 import com.android.settings.spa.app.appinfo.AppInfoSettingsProvider.getRoute
31 import com.android.settingslib.spa.framework.compose.LocalNavController
32 import com.android.settingslib.spa.widget.button.ActionButton
33 import kotlinx.coroutines.Dispatchers
34 import kotlinx.coroutines.launch
35 import kotlinx.coroutines.withContext
36 
37 class AppCreateButton(packageInfoPresenter: PackageInfoPresenter) {
38     private val context = packageInfoPresenter.context
39     val enabledState = mutableStateOf(true)
40 
41     @Composable
getActionButtonnull42     fun getActionButton(app: ApplicationInfo): ActionButton? {
43         return createButton(app)
44     }
45 
46     @Composable
createButtonnull47     private fun createButton(app: ApplicationInfo): ActionButton {
48         val coroutineScope = rememberCoroutineScope()
49         val navController = LocalNavController.current
50         return ActionButton(
51                 text = context.getString(R.string.create),
52                 imageVector = Icons.Outlined.Add,
53                 enabled = enabledState.value,
54         )
55         {
56             val cloneBackend = CloneBackend.getInstance(context)
57             featureFactory.metricsFeatureProvider.action(context,
58                     SettingsEnums.ACTION_CREATE_CLONE_APP)
59             val appLabel = app.loadLabel(context.packageManager)
60             Toast.makeText(context, context.getString(R.string.cloned_app_creation_toast_summary,
61                 appLabel),Toast.LENGTH_SHORT).show()
62             coroutineScope.launch {
63                 enabledState.value = false
64                 val result = installCloneApp(app, cloneBackend)
65                 if (result == CloneBackend.SUCCESS) {
66                     Toast.makeText(context,
67                         context.getString(R.string.cloned_app_created_toast_summary, appLabel),
68                             Toast.LENGTH_SHORT).show()
69                     navController.navigate(getRoute(app.packageName, cloneBackend.cloneUserId),
70                             /* popUpCurrent*/ true)
71                 } else {
72                     enabledState.value = true
73                 }
74             }
75         }
76     }
77 
installCloneAppnull78     private suspend fun installCloneApp(app: ApplicationInfo, cloneBackend: CloneBackend): Int = withContext(Dispatchers.IO) {
79         cloneBackend.installCloneApp(app.packageName)
80     }
81 }