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 }