Loading proguard.flags +7 −0 Original line number Diff line number Diff line Loading @@ -13,3 +13,10 @@ } -keep class com.android.car.ui.** {*;} # for proto names for Proto.toString -keepclassmembers class * extends com.google.protobuf.GeneratedMessageLite { *** get*(); *** set*(***); *** has*(); } No newline at end of file src/com/android/permissioncontroller/DumpableLog.kt +3 −6 Original line number Diff line number Diff line Loading @@ -19,7 +19,6 @@ package com.android.permissioncontroller import android.util.Log import com.android.permissioncontroller.Constants.LOGS_TO_DUMP_FILE import java.io.File import java.io.PrintWriter /** * Like {@link Log} but stores the logs in a file which can later be dumped via {@link #dump} Loading Loading @@ -90,13 +89,11 @@ object DumpableLog { } /** * Write the previously logged entries to the print writer. * * @param pw the writer to dump to * @return the previously logged entries */ fun dump(pw: PrintWriter) { suspend fun get(): List<String> { synchronized(lock) { file.forEachLine { pw.println(it) } return file.readLines() } } } No newline at end of file src/com/android/permissioncontroller/PermissionController.proto 0 → 100644 +26 −0 Original line number Diff line number Diff line /* * Copyright (C) 2020 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. */ syntax = "proto2"; package com.android.permissioncontroller; option java_outer_classname = "PermissionControllerProto"; import "packages/apps/PermissionController/src/com/android/permissioncontroller/permission/service/AutoRevokePermissions.proto"; message PermissionControllerDumpProto { optional permission.service.AutoRevokePermissionsDumpProto autoRevoke = 1; repeated string logs = 3; } src/com/android/permissioncontroller/permission/service/AutoRevokePermissions.kt +257 −0 Original line number Diff line number Diff line Loading @@ -86,11 +86,17 @@ import com.android.permissioncontroller.permission.data.AllPackageInfosLiveData import com.android.permissioncontroller.permission.data.AppOpLiveData import com.android.permissioncontroller.permission.data.LightAppPermGroupLiveData import com.android.permissioncontroller.permission.data.PackagePermissionsLiveData import com.android.permissioncontroller.permission.data.SmartUpdateMediatorLiveData import com.android.permissioncontroller.permission.data.UnusedAutoRevokedPackagesLiveData import com.android.permissioncontroller.permission.data.UsageStatsLiveData import com.android.permissioncontroller.permission.data.get import com.android.permissioncontroller.permission.model.livedatatypes.LightAppPermGroup import com.android.permissioncontroller.permission.model.livedatatypes.LightPackageInfo import com.android.permissioncontroller.permission.service.AutoRevokePermissionsProto.AutoRevokePermissionsDumpProto import com.android.permissioncontroller.permission.service.AutoRevokePermissionsProto.PackageProto import com.android.permissioncontroller.permission.service.AutoRevokePermissionsProto.PerUserProto import com.android.permissioncontroller.permission.service.AutoRevokePermissionsProto.PermissionGroupProto import com.android.permissioncontroller.permission.service.AutoRevokePermissionsProto.TeamFoodSettingsProto import com.android.permissioncontroller.permission.ui.ManagePermissionsActivity import com.android.permissioncontroller.permission.utils.IPC import com.android.permissioncontroller.permission.utils.KotlinUtils Loading @@ -103,6 +109,7 @@ import com.android.permissioncontroller.permission.utils.updatePermissionFlags import kotlinx.coroutines.Dispatchers.Main import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.Job import kotlinx.coroutines.async import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import java.util.concurrent.TimeUnit.DAYS Loading Loading @@ -152,6 +159,25 @@ fun isAutoRevokeEnabled(context: Context): Boolean { getUnusedThresholdMs(context) != Long.MAX_VALUE } /** * @return dump of auto revoke service as a proto */ suspend fun dumpAutoRevokePermissions(context: Context): AutoRevokePermissionsDumpProto { val teamFoodSettings = GlobalScope.async(IPC) { TeamfoodSettings.get(context)?.dump() ?: TeamFoodSettingsProto.newBuilder().build() } val dumpData = GlobalScope.async(IPC) { AutoRevokeDumpLiveData(context).getInitializedValue(staleOk = true) } return AutoRevokePermissionsDumpProto.newBuilder() .setTeamfoodSettings(teamFoodSettings.await()) .addAllUsers(dumpData.await().dumpUsers()) .build() } /** * Receiver of the onBoot event. */ Loading Loading @@ -652,4 +678,235 @@ private data class TeamfoodSettings( } } } /** * @return team food settings for dumping as as a proto */ suspend fun dump(): TeamFoodSettingsProto { return TeamFoodSettingsProto.newBuilder() .setEnabledForPreRApps(enabledForPreRApps) .setUnusedThresholdMillis(unusedThresholdMs) .setCheckFrequencyMillis(checkFrequencyMs) .build() } } /** Data interesting to auto-revoke */ private class AutoRevokeDumpLiveData(context: Context) : SmartUpdateMediatorLiveData<AutoRevokeDumpLiveData.AutoRevokeDumpData>() { /** All data */ data class AutoRevokeDumpData( val users: List<AutoRevokeDumpUserData> ) { fun dumpUsers(): List<PerUserProto> { return users.map { it.dump() } } } /** Per user data */ data class AutoRevokeDumpUserData( val user: UserHandle, val pkgs: List<AutoRevokeDumpPackageData> ) { fun dump(): PerUserProto { val dump = PerUserProto.newBuilder() .setUserId(user.identifier) pkgs.forEach { dump.addPackages(it.dump()) } return dump.build() } } /** Per package data */ data class AutoRevokeDumpPackageData( val uid: Int, val packageName: String, val firstInstallTime: Long, val lastTimeVisible: Long?, val groups: List<AutoRevokeDumpGroupData> ) { fun dump(): PackageProto { val dump = PackageProto.newBuilder() .setUid(uid) .setPackageName(packageName) .setFirstInstallTime(firstInstallTime) lastTimeVisible?.let { dump.lastTimeVisible = lastTimeVisible } groups.forEach { dump.addGroups(it.dump()) } return dump.build() } } /** Per permission group data */ data class AutoRevokeDumpGroupData( val groupName: String, val isFixed: Boolean, val isAnyGrantedIncludingAppOp: Boolean, val isGrantedByDefault: Boolean, val isGrantedByRole: Boolean, val isUserSensitive: Boolean, val isAutoRevoked: Boolean ) { fun dump(): PermissionGroupProto { return PermissionGroupProto.newBuilder() .setGroupName(groupName) .setIsFixed(isFixed) .setIsAnyGrantedIncludingAppop(isAnyGrantedIncludingAppOp) .setIsGrantedByDefault(isGrantedByDefault) .setIsGrantedByRole(isGrantedByRole) .setIsUserSensitive(isUserSensitive) .setIsAutoRevoked(isAutoRevoked) .build() } } /** Usage stats: user -> list<usages> */ private val usages = UsageStatsLiveData[ getUnusedThresholdMs(context), if (DEBUG_OVERRIDE_THRESHOLDS) INTERVAL_DAILY else INTERVAL_MONTHLY ] /** All package infos: user -> pkg **/ private val packages = AllPackageInfosLiveData /** Group names of revoked permission groups: (user, pkg-name) -> set<group-name> **/ private val revokedPermGroupNames = UnusedAutoRevokedPackagesLiveData /** * Group names for packages * map<user, pkg-name> -> list<perm-group-name>. {@code null} before step 1 */ private var pkgPermGroupNames: MutableMap<Pair<UserHandle, String>, PackagePermissionsLiveData>? = null /** * Group state for packages * map<(user, pkg-name) -> map<perm-group-name -> group>>, value {@code null} before step 2 */ private val pkgPermGroups = mutableMapOf<Pair<UserHandle, String>, MutableMap<String, LightAppPermGroupLiveData>?>() /** If this live-data currently inside onUpdate */ private var isUpdating = false init { addSource(revokedPermGroupNames) { updateIfActive() } addSource(usages) { updateIfActive() } addSource(packages) { pkgPermGroupNames?.values?.forEach { removeSource(it) } pkgPermGroupNames = null pkgPermGroups.values.forEach { it?.values?.forEach { removeSource(it) } } updateIfActive() } } override fun onUpdate() { // If a source is already ready, the call onUpdate when added. Suppress this if (isUpdating) { return } isUpdating = true // Step 1, packages is loaded, nothing else if (packages.isInitialized && pkgPermGroupNames == null) { pkgPermGroupNames = mutableMapOf() for ((user, userPkgs) in packages.value!!) { for (pkg in userPkgs) { val newPermGroupNames = PackagePermissionsLiveData[pkg.packageName, user] pkgPermGroupNames!![user to pkg.packageName] = newPermGroupNames addSource(newPermGroupNames) { pkgPermGroups[user to pkg.packageName]?.forEach { removeSource(it.value) } pkgPermGroups.remove(user to pkg.packageName) updateIfActive() } } } } // Step 2, packages and pkgPermGroupNames are loaded, but pkgPermGroups are not loaded yet if (packages.isInitialized && pkgPermGroupNames != null) { for ((user, userPkgs) in packages.value!!) { for (pkg in userPkgs) { if (pkgPermGroupNames!![user to pkg.packageName]?.isInitialized == true && pkgPermGroups[user to pkg.packageName] == null) { pkgPermGroups[user to pkg.packageName] = mutableMapOf() for (groupName in pkgPermGroupNames!![user to pkg.packageName]!!.value!!.keys) { if (groupName == PackagePermissionsLiveData.NON_RUNTIME_NORMAL_PERMS) { continue } val newPkgPermGroup = LightAppPermGroupLiveData[pkg.packageName, groupName, user] pkgPermGroups[user to pkg.packageName]!![groupName] = newPkgPermGroup addSource(newPkgPermGroup) { updateIfActive() } } } } } } // Step 3, everything is loaded, generate data if (packages.isInitialized && usages.isInitialized && revokedPermGroupNames.isInitialized && pkgPermGroupNames?.values?.all { it.isInitialized } == true && pkgPermGroupNames?.size == pkgPermGroups.size && pkgPermGroups.values.all { it?.values?.all { it.isInitialized } == true }) { val users = mutableListOf<AutoRevokeDumpUserData>() for ((user, userPkgs) in packages.value!!) { val pkgs = mutableListOf<AutoRevokeDumpPackageData>() for (pkg in userPkgs) { val groups = mutableListOf<AutoRevokeDumpGroupData>() for (groupName in pkgPermGroupNames!![user to pkg.packageName]!!.value!!.keys) { if (groupName == PackagePermissionsLiveData.NON_RUNTIME_NORMAL_PERMS) { continue } pkgPermGroups[user to pkg.packageName]!![groupName]!!.value!!.apply { groups.add(AutoRevokeDumpGroupData(groupName, isBackgroundFixed || isForegroundFixed, permissions.any { (_, p) -> p.isGrantedIncludingAppOp }, isGrantedByDefault, isGrantedByRole, isUserSensitive, revokedPermGroupNames.value!![pkg.packageName to user] ?.contains(groupName) ?: false )) } } pkgs.add(AutoRevokeDumpPackageData(pkg.uid, pkg.packageName, pkg.firstInstallTime, usages.value!![user] ?.find { it.packageName == pkg.packageName }?.lastTimeVisible, groups)) } users.add(AutoRevokeDumpUserData(user, pkgs)) } value = AutoRevokeDumpData(users) } isUpdating = false } } src/com/android/permissioncontroller/permission/service/AutoRevokePermissions.proto 0 → 100644 +58 −0 Original line number Diff line number Diff line /* * Copyright (C) 2020 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. */ syntax = "proto2"; package com.android.permissioncontroller.permission.service; option java_outer_classname = "AutoRevokePermissionsProto"; message PackageProto { optional int32 uid = 1; optional string package_name = 2; optional int64 last_time_visible = 4; optional int64 first_install_time = 5; repeated PermissionGroupProto groups = 6; } message PermissionGroupProto { optional string group_name = 1; optional bool is_fixed = 2; optional bool is_any_granted_including_appop = 3; optional bool is_granted_by_default = 4; optional bool is_granted_by_role = 5; optional bool is_user_sensitive = 6; optional bool is_auto_revoked = 7; } message AutoRevokedPackageProto { optional string package_name = 1; repeated string revoked_groups = 2; } message PerUserProto { optional int32 user_id = 1; repeated PackageProto packages = 2; } message TeamFoodSettingsProto { optional bool enabled_for_pre_R_apps = 1; optional int64 unused_threshold_millis = 2; optional int64 check_frequency_millis = 3; } message AutoRevokePermissionsDumpProto { repeated PerUserProto users = 1; optional TeamFoodSettingsProto teamfood_settings = 2; } Loading
proguard.flags +7 −0 Original line number Diff line number Diff line Loading @@ -13,3 +13,10 @@ } -keep class com.android.car.ui.** {*;} # for proto names for Proto.toString -keepclassmembers class * extends com.google.protobuf.GeneratedMessageLite { *** get*(); *** set*(***); *** has*(); } No newline at end of file
src/com/android/permissioncontroller/DumpableLog.kt +3 −6 Original line number Diff line number Diff line Loading @@ -19,7 +19,6 @@ package com.android.permissioncontroller import android.util.Log import com.android.permissioncontroller.Constants.LOGS_TO_DUMP_FILE import java.io.File import java.io.PrintWriter /** * Like {@link Log} but stores the logs in a file which can later be dumped via {@link #dump} Loading Loading @@ -90,13 +89,11 @@ object DumpableLog { } /** * Write the previously logged entries to the print writer. * * @param pw the writer to dump to * @return the previously logged entries */ fun dump(pw: PrintWriter) { suspend fun get(): List<String> { synchronized(lock) { file.forEachLine { pw.println(it) } return file.readLines() } } } No newline at end of file
src/com/android/permissioncontroller/PermissionController.proto 0 → 100644 +26 −0 Original line number Diff line number Diff line /* * Copyright (C) 2020 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. */ syntax = "proto2"; package com.android.permissioncontroller; option java_outer_classname = "PermissionControllerProto"; import "packages/apps/PermissionController/src/com/android/permissioncontroller/permission/service/AutoRevokePermissions.proto"; message PermissionControllerDumpProto { optional permission.service.AutoRevokePermissionsDumpProto autoRevoke = 1; repeated string logs = 3; }
src/com/android/permissioncontroller/permission/service/AutoRevokePermissions.kt +257 −0 Original line number Diff line number Diff line Loading @@ -86,11 +86,17 @@ import com.android.permissioncontroller.permission.data.AllPackageInfosLiveData import com.android.permissioncontroller.permission.data.AppOpLiveData import com.android.permissioncontroller.permission.data.LightAppPermGroupLiveData import com.android.permissioncontroller.permission.data.PackagePermissionsLiveData import com.android.permissioncontroller.permission.data.SmartUpdateMediatorLiveData import com.android.permissioncontroller.permission.data.UnusedAutoRevokedPackagesLiveData import com.android.permissioncontroller.permission.data.UsageStatsLiveData import com.android.permissioncontroller.permission.data.get import com.android.permissioncontroller.permission.model.livedatatypes.LightAppPermGroup import com.android.permissioncontroller.permission.model.livedatatypes.LightPackageInfo import com.android.permissioncontroller.permission.service.AutoRevokePermissionsProto.AutoRevokePermissionsDumpProto import com.android.permissioncontroller.permission.service.AutoRevokePermissionsProto.PackageProto import com.android.permissioncontroller.permission.service.AutoRevokePermissionsProto.PerUserProto import com.android.permissioncontroller.permission.service.AutoRevokePermissionsProto.PermissionGroupProto import com.android.permissioncontroller.permission.service.AutoRevokePermissionsProto.TeamFoodSettingsProto import com.android.permissioncontroller.permission.ui.ManagePermissionsActivity import com.android.permissioncontroller.permission.utils.IPC import com.android.permissioncontroller.permission.utils.KotlinUtils Loading @@ -103,6 +109,7 @@ import com.android.permissioncontroller.permission.utils.updatePermissionFlags import kotlinx.coroutines.Dispatchers.Main import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.Job import kotlinx.coroutines.async import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import java.util.concurrent.TimeUnit.DAYS Loading Loading @@ -152,6 +159,25 @@ fun isAutoRevokeEnabled(context: Context): Boolean { getUnusedThresholdMs(context) != Long.MAX_VALUE } /** * @return dump of auto revoke service as a proto */ suspend fun dumpAutoRevokePermissions(context: Context): AutoRevokePermissionsDumpProto { val teamFoodSettings = GlobalScope.async(IPC) { TeamfoodSettings.get(context)?.dump() ?: TeamFoodSettingsProto.newBuilder().build() } val dumpData = GlobalScope.async(IPC) { AutoRevokeDumpLiveData(context).getInitializedValue(staleOk = true) } return AutoRevokePermissionsDumpProto.newBuilder() .setTeamfoodSettings(teamFoodSettings.await()) .addAllUsers(dumpData.await().dumpUsers()) .build() } /** * Receiver of the onBoot event. */ Loading Loading @@ -652,4 +678,235 @@ private data class TeamfoodSettings( } } } /** * @return team food settings for dumping as as a proto */ suspend fun dump(): TeamFoodSettingsProto { return TeamFoodSettingsProto.newBuilder() .setEnabledForPreRApps(enabledForPreRApps) .setUnusedThresholdMillis(unusedThresholdMs) .setCheckFrequencyMillis(checkFrequencyMs) .build() } } /** Data interesting to auto-revoke */ private class AutoRevokeDumpLiveData(context: Context) : SmartUpdateMediatorLiveData<AutoRevokeDumpLiveData.AutoRevokeDumpData>() { /** All data */ data class AutoRevokeDumpData( val users: List<AutoRevokeDumpUserData> ) { fun dumpUsers(): List<PerUserProto> { return users.map { it.dump() } } } /** Per user data */ data class AutoRevokeDumpUserData( val user: UserHandle, val pkgs: List<AutoRevokeDumpPackageData> ) { fun dump(): PerUserProto { val dump = PerUserProto.newBuilder() .setUserId(user.identifier) pkgs.forEach { dump.addPackages(it.dump()) } return dump.build() } } /** Per package data */ data class AutoRevokeDumpPackageData( val uid: Int, val packageName: String, val firstInstallTime: Long, val lastTimeVisible: Long?, val groups: List<AutoRevokeDumpGroupData> ) { fun dump(): PackageProto { val dump = PackageProto.newBuilder() .setUid(uid) .setPackageName(packageName) .setFirstInstallTime(firstInstallTime) lastTimeVisible?.let { dump.lastTimeVisible = lastTimeVisible } groups.forEach { dump.addGroups(it.dump()) } return dump.build() } } /** Per permission group data */ data class AutoRevokeDumpGroupData( val groupName: String, val isFixed: Boolean, val isAnyGrantedIncludingAppOp: Boolean, val isGrantedByDefault: Boolean, val isGrantedByRole: Boolean, val isUserSensitive: Boolean, val isAutoRevoked: Boolean ) { fun dump(): PermissionGroupProto { return PermissionGroupProto.newBuilder() .setGroupName(groupName) .setIsFixed(isFixed) .setIsAnyGrantedIncludingAppop(isAnyGrantedIncludingAppOp) .setIsGrantedByDefault(isGrantedByDefault) .setIsGrantedByRole(isGrantedByRole) .setIsUserSensitive(isUserSensitive) .setIsAutoRevoked(isAutoRevoked) .build() } } /** Usage stats: user -> list<usages> */ private val usages = UsageStatsLiveData[ getUnusedThresholdMs(context), if (DEBUG_OVERRIDE_THRESHOLDS) INTERVAL_DAILY else INTERVAL_MONTHLY ] /** All package infos: user -> pkg **/ private val packages = AllPackageInfosLiveData /** Group names of revoked permission groups: (user, pkg-name) -> set<group-name> **/ private val revokedPermGroupNames = UnusedAutoRevokedPackagesLiveData /** * Group names for packages * map<user, pkg-name> -> list<perm-group-name>. {@code null} before step 1 */ private var pkgPermGroupNames: MutableMap<Pair<UserHandle, String>, PackagePermissionsLiveData>? = null /** * Group state for packages * map<(user, pkg-name) -> map<perm-group-name -> group>>, value {@code null} before step 2 */ private val pkgPermGroups = mutableMapOf<Pair<UserHandle, String>, MutableMap<String, LightAppPermGroupLiveData>?>() /** If this live-data currently inside onUpdate */ private var isUpdating = false init { addSource(revokedPermGroupNames) { updateIfActive() } addSource(usages) { updateIfActive() } addSource(packages) { pkgPermGroupNames?.values?.forEach { removeSource(it) } pkgPermGroupNames = null pkgPermGroups.values.forEach { it?.values?.forEach { removeSource(it) } } updateIfActive() } } override fun onUpdate() { // If a source is already ready, the call onUpdate when added. Suppress this if (isUpdating) { return } isUpdating = true // Step 1, packages is loaded, nothing else if (packages.isInitialized && pkgPermGroupNames == null) { pkgPermGroupNames = mutableMapOf() for ((user, userPkgs) in packages.value!!) { for (pkg in userPkgs) { val newPermGroupNames = PackagePermissionsLiveData[pkg.packageName, user] pkgPermGroupNames!![user to pkg.packageName] = newPermGroupNames addSource(newPermGroupNames) { pkgPermGroups[user to pkg.packageName]?.forEach { removeSource(it.value) } pkgPermGroups.remove(user to pkg.packageName) updateIfActive() } } } } // Step 2, packages and pkgPermGroupNames are loaded, but pkgPermGroups are not loaded yet if (packages.isInitialized && pkgPermGroupNames != null) { for ((user, userPkgs) in packages.value!!) { for (pkg in userPkgs) { if (pkgPermGroupNames!![user to pkg.packageName]?.isInitialized == true && pkgPermGroups[user to pkg.packageName] == null) { pkgPermGroups[user to pkg.packageName] = mutableMapOf() for (groupName in pkgPermGroupNames!![user to pkg.packageName]!!.value!!.keys) { if (groupName == PackagePermissionsLiveData.NON_RUNTIME_NORMAL_PERMS) { continue } val newPkgPermGroup = LightAppPermGroupLiveData[pkg.packageName, groupName, user] pkgPermGroups[user to pkg.packageName]!![groupName] = newPkgPermGroup addSource(newPkgPermGroup) { updateIfActive() } } } } } } // Step 3, everything is loaded, generate data if (packages.isInitialized && usages.isInitialized && revokedPermGroupNames.isInitialized && pkgPermGroupNames?.values?.all { it.isInitialized } == true && pkgPermGroupNames?.size == pkgPermGroups.size && pkgPermGroups.values.all { it?.values?.all { it.isInitialized } == true }) { val users = mutableListOf<AutoRevokeDumpUserData>() for ((user, userPkgs) in packages.value!!) { val pkgs = mutableListOf<AutoRevokeDumpPackageData>() for (pkg in userPkgs) { val groups = mutableListOf<AutoRevokeDumpGroupData>() for (groupName in pkgPermGroupNames!![user to pkg.packageName]!!.value!!.keys) { if (groupName == PackagePermissionsLiveData.NON_RUNTIME_NORMAL_PERMS) { continue } pkgPermGroups[user to pkg.packageName]!![groupName]!!.value!!.apply { groups.add(AutoRevokeDumpGroupData(groupName, isBackgroundFixed || isForegroundFixed, permissions.any { (_, p) -> p.isGrantedIncludingAppOp }, isGrantedByDefault, isGrantedByRole, isUserSensitive, revokedPermGroupNames.value!![pkg.packageName to user] ?.contains(groupName) ?: false )) } } pkgs.add(AutoRevokeDumpPackageData(pkg.uid, pkg.packageName, pkg.firstInstallTime, usages.value!![user] ?.find { it.packageName == pkg.packageName }?.lastTimeVisible, groups)) } users.add(AutoRevokeDumpUserData(user, pkgs)) } value = AutoRevokeDumpData(users) } isUpdating = false } }
src/com/android/permissioncontroller/permission/service/AutoRevokePermissions.proto 0 → 100644 +58 −0 Original line number Diff line number Diff line /* * Copyright (C) 2020 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. */ syntax = "proto2"; package com.android.permissioncontroller.permission.service; option java_outer_classname = "AutoRevokePermissionsProto"; message PackageProto { optional int32 uid = 1; optional string package_name = 2; optional int64 last_time_visible = 4; optional int64 first_install_time = 5; repeated PermissionGroupProto groups = 6; } message PermissionGroupProto { optional string group_name = 1; optional bool is_fixed = 2; optional bool is_any_granted_including_appop = 3; optional bool is_granted_by_default = 4; optional bool is_granted_by_role = 5; optional bool is_user_sensitive = 6; optional bool is_auto_revoked = 7; } message AutoRevokedPackageProto { optional string package_name = 1; repeated string revoked_groups = 2; } message PerUserProto { optional int32 user_id = 1; repeated PackageProto packages = 2; } message TeamFoodSettingsProto { optional bool enabled_for_pre_R_apps = 1; optional int64 unused_threshold_millis = 2; optional int64 check_frequency_millis = 3; } message AutoRevokePermissionsDumpProto { repeated PerUserProto users = 1; optional TeamFoodSettingsProto teamfood_settings = 2; }