• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.os.Bundle
22 import android.os.UserHandle
23 import android.util.FeatureFlagUtils
24 import androidx.compose.runtime.Composable
25 import androidx.compose.runtime.remember
26 import androidx.compose.runtime.rememberCoroutineScope
27 import androidx.compose.ui.platform.LocalContext
28 import androidx.compose.ui.res.stringResource
29 import androidx.fragment.app.Fragment
30 import androidx.lifecycle.compose.ExperimentalLifecycleComposeApi
31 import androidx.lifecycle.compose.collectAsStateWithLifecycle
32 import androidx.navigation.NavType
33 import androidx.navigation.navArgument
34 import com.android.settings.R
35 import com.android.settings.applications.AppInfoBase
36 import com.android.settings.applications.appinfo.AppInfoDashboardFragment
37 import com.android.settings.spa.SpaActivity.Companion.startSpaActivity
38 import com.android.settings.spa.app.appcompat.UserAspectRatioAppPreference
39 import com.android.settings.spa.app.specialaccess.AlarmsAndRemindersAppListProvider
40 import com.android.settings.spa.app.specialaccess.DisplayOverOtherAppsAppListProvider
41 import com.android.settings.spa.app.specialaccess.InstallUnknownAppsListProvider
42 import com.android.settings.spa.app.specialaccess.ModifySystemSettingsAppListProvider
43 import com.android.settings.spa.app.specialaccess.PictureInPictureListProvider
44 import com.android.settingslib.spa.framework.common.SettingsPageProvider
45 import com.android.settingslib.spa.framework.compose.LifecycleEffect
46 import com.android.settingslib.spa.framework.compose.navigator
47 import com.android.settingslib.spa.widget.scaffold.RegularScaffold
48 import com.android.settingslib.spa.widget.ui.Category
49 import com.android.settingslib.spaprivileged.model.app.toRoute
50 import com.android.settingslib.spaprivileged.template.app.AppInfoProvider
51 
52 private const val PACKAGE_NAME = "packageName"
53 private const val USER_ID = "userId"
54 
55 object AppInfoSettingsProvider : SettingsPageProvider {
56     override val name = "AppInfoSettings"
57 
58     override val parameter = listOf(
<lambda>null59         navArgument(PACKAGE_NAME) { type = NavType.StringType },
<lambda>null60         navArgument(USER_ID) { type = NavType.IntType },
61     )
62 
63     const val METRICS_CATEGORY = SettingsEnums.APPLICATIONS_INSTALLED_APP_DETAILS
64 
65     @Composable
Pagenull66     override fun Page(arguments: Bundle?) {
67         val packageName = arguments!!.getString(PACKAGE_NAME)!!
68         val userId = arguments.getInt(USER_ID)
69         val context = LocalContext.current
70         val coroutineScope = rememberCoroutineScope()
71         val packageInfoPresenter = remember {
72             PackageInfoPresenter(context, packageName, userId, coroutineScope)
73         }
74         AppInfoSettings(packageInfoPresenter)
75         packageInfoPresenter.PackageRemoveDetector()
76     }
77 
78     @Composable
navigatornull79     fun navigator(app: ApplicationInfo) = navigator(route = "$name/${app.toRoute()}")
80 
81     /**
82      * Gets the route to the App Info Settings page.
83      *
84      * Expose route to enable enter from non-SPA pages.
85      */
86     fun getRoute(packageName: String, userId: Int): String = "$name/$packageName/$userId"
87 
88     /**
89      * Starts the App Info Settings page from non-SPA.
90      *
91      * Will starts SPA version if flag [FeatureFlagUtils.SETTINGS_ENABLE_SPA] is true.
92      */
93     @JvmStatic
94     fun startAppInfoSettings(
95         packageName: String,
96         uid: Int,
97         source: Fragment,
98         request: Int,
99         sourceMetricsCategory: Int,
100     ) {
101         val context = source.context ?: return
102         if (FeatureFlagUtils.isEnabled(context, FeatureFlagUtils.SETTINGS_ENABLE_SPA)) {
103             context.startSpaActivity(getRoute(packageName, UserHandle.getUserId(uid)))
104         } else {
105             AppInfoBase.startAppInfoFragment(
106                 AppInfoDashboardFragment::class.java,
107                 context.getString(R.string.application_info_label),
108                 packageName,
109                 uid,
110                 source,
111                 request,
112                 sourceMetricsCategory,
113             )
114         }
115     }
116 }
117 
118 @OptIn(ExperimentalLifecycleComposeApi::class)
119 @Composable
AppInfoSettingsnull120 private fun AppInfoSettings(packageInfoPresenter: PackageInfoPresenter) {
121     LifecycleEffect(onStart = { packageInfoPresenter.reloadPackageInfo() })
122     val packageInfo = packageInfoPresenter.flow.collectAsStateWithLifecycle().value ?: return
123     val app = packageInfo.applicationInfo
124     RegularScaffold(
125         title = stringResource(R.string.application_info_label),
126         actions = {
127             AppInfoSettingsMoreOptions(packageInfoPresenter, app)
128         }
129     ) {
130         val appInfoProvider = remember { AppInfoProvider(packageInfo) }
131 
132         appInfoProvider.AppInfo()
133 
134         AppButtons(packageInfoPresenter)
135 
136         AppSettingsPreference(app)
137         AppAllServicesPreference(app)
138         AppNotificationPreference(app)
139         AppPermissionPreference(app)
140         AppStoragePreference(app)
141         InstantAppDomainsPreference(app)
142         AppDataUsagePreference(app)
143         AppTimeSpentPreference(app)
144         AppBatteryPreference(app)
145         AppLocalePreference(app)
146         AppOpenByDefaultPreference(app)
147         DefaultAppShortcuts(app)
148 
149         Category(title = stringResource(R.string.unused_apps_category)) {
150             HibernationSwitchPreference(app)
151         }
152 
153         Category(title = stringResource(R.string.advanced_apps)) {
154             UserAspectRatioAppPreference(app)
155             DisplayOverOtherAppsAppListProvider.InfoPageEntryItem(app)
156             ModifySystemSettingsAppListProvider.InfoPageEntryItem(app)
157             PictureInPictureListProvider.InfoPageEntryItem(app)
158             InstallUnknownAppsListProvider.InfoPageEntryItem(app)
159             InteractAcrossProfilesDetailsPreference(app)
160             AlarmsAndRemindersAppListProvider.InfoPageEntryItem(app)
161         }
162 
163         Category(title = stringResource(R.string.app_install_details_group_title)) {
164             AppInstallerInfoPreference(app)
165         }
166         appInfoProvider.FooterAppVersion()
167     }
168 }
169