Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8cc6fabf authored by Nate Myren's avatar Nate Myren Committed by Android (Google) Code Review
Browse files

Merge "Implement Special app access in permissionController" into rvc-dev

parents 80d8a143 fa15c23b
Loading
Loading
Loading
Loading
+12 −4
Original line number Diff line number Diff line
@@ -135,6 +135,14 @@
                    android:clickable="true"
                    style="@style/AppPermissionFooterLink" />

                <TextView
                    android:id="@+id/footer_storage_special_app_access"
                    android:clickable="false"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:drawableLeft="@drawable/ic_info_outline"
                    style="@style/AppPermissionFooterTextWithIcon" />

            </LinearLayout>

        </LinearLayout>
+1 −0
Original line number Diff line number Diff line
@@ -94,6 +94,7 @@
            <item type="style" name="AppPermissionFooterDivider" />
            <item type="style" name="AppPermissionFooterText" />
            <item type="style" name="AppPermissionFooterLink" />
            <item type="style" name="AppPermissionFooterTextWithIcon" />
            <!-- END APP PERMISSION SCREEN -->

            <!-- START PERMISSION FILTER SCREEN -->
+26 −2
Original line number Diff line number Diff line
@@ -106,6 +106,12 @@
    <!-- Title for the dialog button to allow a change from foreground to background permission grant. [CHAR LIMIT=60]  -->
    <string name="grant_dialog_button_allow_background">Allow all the time</string>

    <!-- Title for the dialog button to allow a permission grant for all files. [CHAR LIMIT=60]  -->
    <string name="grant_dialog_button_allow_all_files">Allow management of all files</string>

    <!-- Title for the dialog button to allow a permission grant for media files only. [CHAR LIMIT=60]  -->
    <string name="grant_dialog_button_allow_media_only">Allow access to media files</string>

    <!-- Breadcrumb for page of managing application permissions [CHAR LIMIT=50] -->
    <string name="app_permissions_breadcrumb">Apps</string>

@@ -293,6 +299,12 @@
    <!-- Title for the dialog button to allow a permission grant when you cannot only allow in the foreground. [CHAR LIMIT=60] -->
    <string name="app_permission_button_allow">Allow</string>

    <!-- Title for the dialog button to allow a storage permission grant for all files [CHAR LIMIT=60] -->
    <string name="app_permission_button_allow_all_files">Allow management of all files</string>

    <!-- Title for the dialog button to allow a storage permission grant for media files only [CHAR LIMIT=60] -->
    <string name="app_permission_button_allow_media_only">Allow access to media only</string>

    <!-- Title for the dialog button to allow a permission grant when you can also only allow in the foreground. [CHAR LIMIT=60] -->
    <string name="app_permission_button_allow_always">Allow all the time</string>

@@ -365,6 +377,12 @@
    <!-- Summary for showing when an app was last used, shorter version [CHAR LIMIT=none] -->
    <string name="last_opened_summary_short">Last opened <xliff:g id="date" example="March 12, 2020">%s</xliff:g></string>

    <!-- Text that explains that an app has access to all files[CHAR LIMIT=none] -->
    <string name="app_permission_footer_special_file_access">If you allow management of all files, this app can access, modify, and delete any files in common storage on this device or connected storage devices. The app may access files without asking you.</string>

    <!-- Text that explains that an app requests full file access, and links to the settings page[CHAR LIMIT=none] -->
    <string name="special_file_access_dialog">Allow this app to access, modify and delete files on the device, or any connected storage devices? This app may access files without asking you.</string>

    <!-- Label for showing a permission group's description in the header of the list of apps that have that permission [CHAR LIMIT=none] -->
    <string name="permission_description_summary_generic">Apps with this permission can <xliff:g id="description" example="record audio">%1$s</xliff:g></string>

@@ -423,10 +441,10 @@
    <string name="allowed_foreground_header">Allowed only while in use</string>

    <!-- Subtitle for scoped storage permissions, showing apps that have access to media files only [CHAR LIMIT=45] -->
    <string name="allowed_storage_scoped">Allowed for media only</string>
    <string name="allowed_storage_scoped">Allowed access to media only</string>

    <!-- Subtitle for full storage permissions, showing apps that have access to all files [CHAR LIMIT=45] -->
    <string name="allowed_storage_full">Allowed for all files</string>
    <string name="allowed_storage_full">Allowed to manage all files</string>

    <!-- Header for permissions/apps which need to ask next time they want to use the permission. Note: Permission may or may not be currently granted [CHAR LIMIT=60] -->
    <string name="ask_header">Ask every time</string>
@@ -515,6 +533,12 @@
    <!-- Subtitle for the preference that is currently granted only when the app is in the foreground. [CHAR LIMIT=60] -->
    <string name="permission_subtitle_only_in_foreground">Only while app is in use</string>

    <!-- Subtitle for a storage preference that is currently granted for Media files only. [CHAR LIMIT=60] -->
    <string name="permission_subtitle_media_only">Media</string>

    <!-- Subtitle for a storage preference that is currently granted for all files. [CHAR LIMIT=60] -->
    <string name="permission_subtitle_all_files">All Files</string>

    <!-- Label when app has been granted no permissions [CHAR LIMIT=none] -->
    <string name="no_permissions_allowed">No permissions allowed</string>

+11 −0
Original line number Diff line number Diff line
@@ -366,6 +366,17 @@
        <item name="android:textColor">?android:attr/colorAccent</item>
    </style>

    <style name="AppPermissionFooterTextWithIcon">
        <item name="android:paddingTop">16dp</item>
        <item name="android:paddingBottom">16dp</item>
        <item name="android:clickable">false</item>
        <item name="android:drawablePadding">20dp</item>
        <item name="android:paddingStart">20dp</item>
        <item name="android:paddingEnd">?android:attr/listPreferredItemPaddingEnd</item>
        <item name="android:layout_marginEnd">48dp</item>
        <item name="android:textColor">?android:attr/textColorSecondary</item>
    </style>

    <!-- END APP PERMISSION SCREEN -->

    <!-- START PERMISSION FILTER SCREEN -->
+30 −9
Original line number Diff line number Diff line
@@ -16,10 +16,12 @@

package com.android.permissioncontroller.permission.data

import android.Manifest
import android.Manifest.permission_group.STORAGE
import android.app.AppOpsManager
import android.app.AppOpsManager.MODE_IGNORED
import android.app.AppOpsManager.MODE_ALLOWED
import android.app.AppOpsManager.OPSTR_LEGACY_STORAGE
import android.app.AppOpsManager.OPSTR_MANAGE_EXTERNAL_STORAGE
import android.app.Application
import android.os.Build
import android.os.UserHandle
@@ -32,12 +34,19 @@ import kotlinx.coroutines.Job
 *
 */
object FullStoragePermissionAppsLiveData :
    SmartAsyncMediatorLiveData<List<Pair<String, UserHandle>>>() {
    SmartAsyncMediatorLiveData<List<FullStoragePermissionAppsLiveData.FullStoragePackageState>>() {

    private val app: Application = PermissionControllerApplication.get()
    private val standardPermGroupsPackagesLiveData = PermGroupsPackagesLiveData.get(
        customGroups = false)

    data class FullStoragePackageState(
        val packageName: String,
        val user: UserHandle,
        val isLegacy: Boolean,
        val isGranted: Boolean
    )

    init {
        addSource(standardPermGroupsPackagesLiveData) {
            updateAsync()
@@ -48,25 +57,37 @@ object FullStoragePermissionAppsLiveData :
        val storagePackages = standardPermGroupsPackagesLiveData.value?.get(STORAGE) ?: return
        val appOpsManager = app.getSystemService(AppOpsManager::class.java) ?: return

        val legacyPackages = mutableListOf<Pair<String, UserHandle>>()
        val fullStoragePackages = mutableListOf<FullStoragePackageState>()
        for ((user, packageInfoList) in AllPackageInfosLiveData.value ?: emptyMap()) {
            val userPackages = packageInfoList.filter {
                storagePackages.contains(it.packageName to user)
                storagePackages.contains(it.packageName to user) ||
                    it.requestedPermissions.contains(Manifest.permission.MANAGE_EXTERNAL_STORAGE)
            }

            for (packageInfo in userPackages) {
                val sdk = packageInfo.targetSdkVersion
                if (sdk < Build.VERSION_CODES.P) {
                    legacyPackages.add(packageInfo.packageName to user)
                } else if (sdk < Build.VERSION_CODES.R &&
                    fullStoragePackages.add(FullStoragePackageState(packageInfo.packageName, user,
                        isLegacy = true, isGranted = true))
                    continue
                } else if (sdk <= Build.VERSION_CODES.Q &&
                    appOpsManager.unsafeCheckOpNoThrow(OPSTR_LEGACY_STORAGE, packageInfo.uid,
                        packageInfo.packageName) != MODE_IGNORED) {
                    legacyPackages.add(packageInfo.packageName to user)
                        packageInfo.packageName) == MODE_ALLOWED) {
                    fullStoragePackages.add(FullStoragePackageState(packageInfo.packageName, user,
                        isLegacy = true, isGranted = true))
                    continue
                }
                if (packageInfo.requestedPermissions.contains(
                        Manifest.permission.MANAGE_EXTERNAL_STORAGE)) {
                    val granted = appOpsManager.unsafeCheckOpNoThrow(OPSTR_MANAGE_EXTERNAL_STORAGE,
                            packageInfo.uid, packageInfo.packageName) == MODE_ALLOWED
                    fullStoragePackages.add(FullStoragePackageState(packageInfo.packageName, user,
                        isLegacy = false, isGranted = granted))
                }
            }
        }

        postValue(legacyPackages)
        postValue(fullStoragePackages)
    }

    override fun onActive() {
Loading