Add new Alarms & reminders App List

The entry item will also be available through App Settings.

Bug: 235727273
Test: Manual with Settings App
Change-Id: I2e40803203e5430988b6e7394856448c82e20fd2
This commit is contained in:
Chaohui Wang
2022-09-19 16:00:22 +08:00
parent 3659711fe0
commit d4f1898e95
4 changed files with 157 additions and 2 deletions

View File

@@ -18,6 +18,7 @@ package com.android.settings.spa
import com.android.settings.spa.app.AppsMainPageProvider
import com.android.settings.spa.app.appsettings.AppSettingsProvider
import com.android.settings.spa.app.specialaccess.AlarmsAndRemindersAppListProvider
import com.android.settings.spa.app.specialaccess.AllFilesAccessAppListProvider
import com.android.settings.spa.app.specialaccess.DisplayOverOtherAppsAppListProvider
import com.android.settings.spa.app.specialaccess.InstallUnknownAppsListProvider
@@ -43,8 +44,9 @@ object SpaEnvironment {
DisplayOverOtherAppsAppListProvider,
MediaManagementAppsAppListProvider,
ModifySystemSettingsAppListProvider,
InstallUnknownAppsListProvider,
PictureInPictureListProvider,
InstallUnknownAppsListProvider,
AlarmsAndRemindersAppListProvider,
),
)
SettingsPageProviderRepository(

View File

@@ -25,6 +25,7 @@ import androidx.compose.ui.res.stringResource
import androidx.navigation.NavType
import androidx.navigation.navArgument
import com.android.settings.R
import com.android.settings.spa.app.specialaccess.AlarmsAndRemindersAppListProvider
import com.android.settings.spa.app.specialaccess.DisplayOverOtherAppsAppListProvider
import com.android.settings.spa.app.specialaccess.InstallUnknownAppsListProvider
import com.android.settings.spa.app.specialaccess.ModifySystemSettingsAppListProvider
@@ -75,7 +76,7 @@ private fun AppSettings(packageInfo: PackageInfo) {
PictureInPictureListProvider.InfoPageEntryItem(app)
InstallUnknownAppsListProvider.InfoPageEntryItem(app)
// TODO: interact_across_profiles
// TODO: alarms_and_reminders
AlarmsAndRemindersAppListProvider.InfoPageEntryItem(app)
}
// TODO: app_installer

View File

@@ -0,0 +1,99 @@
/*
* Copyright (C) 2022 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.specialaccess
import android.Manifest
import android.app.AlarmManager
import android.app.compat.CompatChanges
import android.content.Context
import android.content.pm.ApplicationInfo
import androidx.compose.runtime.Composable
import androidx.compose.runtime.livedata.observeAsState
import com.android.settings.R
import com.android.settingslib.spaprivileged.model.app.AppRecord
import com.android.settingslib.spaprivileged.model.app.PackageManagers
import com.android.settingslib.spaprivileged.model.app.PackageManagers.hasRequestPermission
import com.android.settingslib.spaprivileged.model.app.userHandle
import com.android.settingslib.spaprivileged.template.app.TogglePermissionAppListModel
import com.android.settingslib.spaprivileged.template.app.TogglePermissionAppListProvider
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.map
object AlarmsAndRemindersAppListProvider : TogglePermissionAppListProvider {
override val permissionType = "AlarmsAndReminders"
override fun createModel(context: Context) = AlarmsAndRemindersAppListModel(context)
}
data class AlarmsAndRemindersAppRecord(
override val app: ApplicationInfo,
val isChangeable: Boolean,
var controller: AlarmsAndRemindersController,
) : AppRecord
class AlarmsAndRemindersAppListModel(
private val context: Context,
) : TogglePermissionAppListModel<AlarmsAndRemindersAppRecord> {
override val pageTitleResId = R.string.alarms_and_reminders_title
override val switchTitleResId = R.string.alarms_and_reminders_switch_title
override val footerResId = R.string.alarms_and_reminders_footer_title
override fun transform(userIdFlow: Flow<Int>, appListFlow: Flow<List<ApplicationInfo>>) =
userIdFlow.map { userId ->
PackageManagers.getAppOpPermissionPackages(userId, PERMISSION)
}.combine(appListFlow) { packageNames, appList ->
appList.map { app ->
createRecord(app = app, hasRequestPermission = app.packageName in packageNames)
}
}
override fun transformItem(app: ApplicationInfo) =
createRecord(app = app, hasRequestPermission = app.hasRequestPermission(PERMISSION))
override fun filter(
userIdFlow: Flow<Int>,
recordListFlow: Flow<List<AlarmsAndRemindersAppRecord>>,
) = recordListFlow.map { recordList ->
recordList.filter { it.isChangeable }
}
@Composable
override fun isAllowed(record: AlarmsAndRemindersAppRecord) =
record.controller.isAllowed.observeAsState()
override fun isChangeable(record: AlarmsAndRemindersAppRecord) = record.isChangeable
override fun setAllowed(record: AlarmsAndRemindersAppRecord, newAllowed: Boolean) {
record.controller.setAllowed(newAllowed)
}
private fun createRecord(app: ApplicationInfo, hasRequestPermission: Boolean) =
AlarmsAndRemindersAppRecord(
app = app,
isChangeable = hasRequestPermission && app.isChangeEnabled(),
controller = AlarmsAndRemindersController(context, app),
)
companion object {
private const val PERMISSION: String = Manifest.permission.SCHEDULE_EXACT_ALARM
private fun ApplicationInfo.isChangeEnabled(): Boolean =
CompatChanges.isChangeEnabled(
AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, packageName, userHandle,
)
}
}

View File

@@ -0,0 +1,53 @@
/*
* Copyright (C) 2022 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.specialaccess
import android.app.AlarmManager
import android.app.AppOpsManager
import android.app.AppOpsManager.MODE_ALLOWED
import android.app.AppOpsManager.MODE_ERRORED
import android.content.Context
import android.content.pm.ApplicationInfo
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import com.android.settingslib.spaprivileged.model.app.userId
class AlarmsAndRemindersController(
context: Context,
private val app: ApplicationInfo,
) {
private val alarmManager = context.getSystemService(AlarmManager::class.java)!!
private val appOpsManager = context.getSystemService(AppOpsManager::class.java)!!
val isAllowed: LiveData<Boolean>
get() = _allowed
fun setAllowed(allowed: Boolean) {
val mode = if (allowed) MODE_ALLOWED else MODE_ERRORED
appOpsManager.setUidMode(AppOpsManager.OPSTR_SCHEDULE_EXACT_ALARM, app.uid, mode)
_allowed.postValue(allowed)
}
private val _allowed = object : MutableLiveData<Boolean>() {
override fun onActive() {
postValue(alarmManager.hasScheduleExactAlarm(app.packageName, app.userId))
}
override fun onInactive() {
}
}
}