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:
@@ -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(
|
||||
|
@@ -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
|
||||
|
@@ -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,
|
||||
)
|
||||
}
|
||||
}
|
@@ -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() {
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user