Move launch button from 3-buttons panel to the top right corner

Test: AppButtonsTest, TopBarAppLaunchButtonTest

Bug: 304255179
Change-Id: Ib8ac1670e0910436f4200e2200714c65b2a593f9
This commit is contained in:
Mark Kim
2023-10-24 19:23:39 +00:00
parent af9f60f6c2
commit fda2e169bc
5 changed files with 221 additions and 5 deletions

View File

@@ -17,6 +17,8 @@
package com.android.settings.spa.app.appinfo
import android.content.pm.ApplicationInfo
import android.content.pm.FeatureFlags
import android.content.pm.FeatureFlagsImpl
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.lifecycle.compose.collectAsStateWithLifecycle
@@ -25,16 +27,22 @@ import com.android.settingslib.spa.widget.button.ActionButton
import com.android.settingslib.spa.widget.button.ActionButtons
@Composable
fun AppButtons(packageInfoPresenter: PackageInfoPresenter) {
/**
* @param featureFlags can be overridden in tests
*/
fun AppButtons(packageInfoPresenter: PackageInfoPresenter, featureFlags: FeatureFlags = FeatureFlagsImpl()) {
if (remember(packageInfoPresenter) { packageInfoPresenter.isMainlineModule() }) return
val presenter = remember { AppButtonsPresenter(packageInfoPresenter) }
val presenter = remember { AppButtonsPresenter(packageInfoPresenter, featureFlags) }
ActionButtons(actionButtons = presenter.getActionButtons())
}
private fun PackageInfoPresenter.isMainlineModule(): Boolean =
AppUtils.isMainlineModule(userPackageManager, packageName)
private class AppButtonsPresenter(private val packageInfoPresenter: PackageInfoPresenter) {
private class AppButtonsPresenter(
private val packageInfoPresenter: PackageInfoPresenter,
private val featureFlags: FeatureFlags
) {
private val appLaunchButton = AppLaunchButton(packageInfoPresenter)
private val appInstallButton = AppInstallButton(packageInfoPresenter)
private val appDisableButton = AppDisableButton(packageInfoPresenter)
@@ -50,7 +58,7 @@ private class AppButtonsPresenter(private val packageInfoPresenter: PackageInfoP
@Composable
private fun getActionButtons(app: ApplicationInfo): List<ActionButton> = listOfNotNull(
appLaunchButton.getActionButton(app),
if (featureFlags.archiving()) null else appLaunchButton.getActionButton(app),
appInstallButton.getActionButton(app),
appDisableButton.getActionButton(app),
appUninstallButton.getActionButton(app),

View File

@@ -18,6 +18,8 @@ package com.android.settings.spa.app.appinfo
import android.app.settings.SettingsEnums
import android.content.pm.ApplicationInfo
import android.content.pm.FeatureFlags
import android.content.pm.FeatureFlagsImpl
import android.os.Bundle
import android.os.UserHandle
import android.util.FeatureFlagUtils
@@ -119,9 +121,11 @@ private fun AppInfoSettings(packageInfoPresenter: PackageInfoPresenter) {
LifecycleEffect(onStart = { packageInfoPresenter.reloadPackageInfo() })
val packageInfo = packageInfoPresenter.flow.collectAsStateWithLifecycle().value ?: return
val app = checkNotNull(packageInfo.applicationInfo)
val featureFlags: FeatureFlags = FeatureFlagsImpl()
RegularScaffold(
title = stringResource(R.string.application_info_label),
actions = {
if (featureFlags.archiving()) TopBarAppLaunchButton(packageInfoPresenter, app)
AppInfoSettingsMoreOptions(packageInfoPresenter, app)
}
) {

View File

@@ -0,0 +1,59 @@
/*
* Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.spa.app.appinfo
import android.content.ActivityNotFoundException
import android.content.Intent
import android.content.pm.ApplicationInfo
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.outlined.Launch
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.runtime.Composable
import androidx.compose.ui.res.stringResource
import com.android.settings.R
import com.android.settingslib.spaprivileged.model.app.userHandle
@Composable
fun TopBarAppLaunchButton(packageInfoPresenter: PackageInfoPresenter, app: ApplicationInfo) {
val intent = packageInfoPresenter.launchIntent(app = app) ?: return
IconButton({ launchButtonAction(intent, app, packageInfoPresenter) }) {
Icon(
imageVector = Icons.AutoMirrored.Outlined.Launch,
contentDescription = stringResource(R.string.launch_instant_app),
)
}
}
private fun PackageInfoPresenter.launchIntent(
app: ApplicationInfo
): Intent? {
return userPackageManager.getLaunchIntentForPackage(app.packageName)
}
private fun launchButtonAction(
intent: Intent,
app: ApplicationInfo,
packageInfoPresenter: PackageInfoPresenter
) {
try {
packageInfoPresenter.context.startActivityAsUser(intent, app.userHandle)
} catch (_: ActivityNotFoundException) {
// Only happens after package changes like uninstall, and before page auto refresh or
// close, so ignore this exception is safe.
}
}