() {
init {
postValue(SdkLevel.isAtLeastS() &&
DeviceConfig.getBoolean(NAMESPACE_APP_HIBERNATION,
diff --git a/PermissionController/src/com/android/permissioncontroller/permission/TEST_MAPPING b/PermissionController/src/com/android/permissioncontroller/permission/TEST_MAPPING
index e9b30d20abd38ef49cde7f1c08678a3286159932..b65eb6710d1c4eb9f5ec55e73ce7a6317d4e56fe 100644
--- a/PermissionController/src/com/android/permissioncontroller/permission/TEST_MAPPING
+++ b/PermissionController/src/com/android/permissioncontroller/permission/TEST_MAPPING
@@ -5,6 +5,24 @@
"options": [
{
"include-filter": "android.permission.cts.BackgroundPermissionsTest"
+ },
+ {
+ "include-filter": "android.permission.cts.LocationAccessCheckTest"
+ },
+ {
+ "include-filter": "android.permission.cts.NotificationListenerCheckTest"
+ },
+ {
+ "include-filter": "android.permission.cts.OneTimePermissionTest"
+ },
+ {
+ "include-filter": "android.permission.cts.PermissionControllerTest"
+ },
+ {
+ "include-filter": "android.permission.cts.PlatformPermissionGroupMappingTest"
+ },
+ {
+ "exclude-annotation": "android.platform.test.annotations.FlakyTest"
}
]
},
@@ -12,15 +30,45 @@
"name": "CtsHibernationTestCases",
"options": [
{
- "include-filter": "android.hibernation.cts.AutoRevokeTest"
+ "exclude-annotation": "android.platform.test.annotations.FlakyTest"
}
]
}
],
- "presubmit-large": [
+ "mainline-presubmit": [
{
- "name": "CtsPermission3TestCases",
+ "name": "CtsPermissionTestCases[com.google.android.permission.apex]",
"options": [
+ {
+ "include-filter": "android.permission.cts.BackgroundPermissionsTest"
+ },
+ {
+ "include-filter": "android.permission.cts.LocationAccessCheckTest"
+ },
+ {
+ "include-filter": "android.permission.cts.NotificationListenerCheckTest"
+ },
+ {
+ "include-filter": "android.permission.cts.OneTimePermissionTest"
+ },
+ {
+ "include-filter": "android.permission.cts.PermissionControllerTest"
+ },
+ {
+ "include-filter": "android.permission.cts.PlatformPermissionGroupMappingTest"
+ },
+ {
+ "exclude-annotation": "android.platform.test.annotations.FlakyTest"
+ }
+ ]
+ },
+ {
+ "name": "CtsHibernationTestCases[com.google.android.permission.apex]",
+ "options": [
+ // TODO(b/238677038): This test currently fails on R base image
+ {
+ "exclude-filter": "android.hibernation.cts.AutoRevokeTest#testUnusedApp_uninstallApp"
+ },
{
"exclude-annotation": "android.platform.test.annotations.FlakyTest"
}
diff --git a/PermissionController/src/com/android/permissioncontroller/permission/compat/LinkMovementMethodCompat.java b/PermissionController/src/com/android/permissioncontroller/permission/compat/LinkMovementMethodCompat.java
new file mode 100644
index 0000000000000000000000000000000000000000..637eb5fc40b4c1dad5ad470d5a6b1177b383f056
--- /dev/null
+++ b/PermissionController/src/com/android/permissioncontroller/permission/compat/LinkMovementMethodCompat.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2023 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.permissioncontroller.permission.compat;
+
+import android.text.Layout;
+import android.text.Selection;
+import android.text.Spannable;
+import android.text.method.LinkMovementMethod;
+import android.text.method.Touch;
+import android.view.MotionEvent;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+
+/**
+ * Fixes the issue that links can be triggered for touches outside of line bounds for
+ * {@link LinkMovementMethod}.
+ *
+ * This is based on the fix in ag/22301465.
+ */
+public class LinkMovementMethodCompat extends LinkMovementMethod {
+ @Override
+ public boolean onTouchEvent(@NonNull TextView widget, @NonNull Spannable buffer,
+ @NonNull MotionEvent event) {
+ int action = event.getAction();
+
+ if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_DOWN) {
+ int x = (int) event.getX();
+ int y = (int) event.getY();
+
+ x -= widget.getTotalPaddingLeft();
+ y -= widget.getTotalPaddingTop();
+
+ x += widget.getScrollX();
+ y += widget.getScrollY();
+
+ Layout layout = widget.getLayout();
+ boolean isOutOfLineBounds;
+ if (y < 0 || y > layout.getHeight()) {
+ isOutOfLineBounds = true;
+ } else {
+ int line = layout.getLineForVertical(y);
+ isOutOfLineBounds = x < layout.getLineLeft(line) || x > layout.getLineRight(line);
+ }
+
+ if (isOutOfLineBounds) {
+ Selection.removeSelection(buffer);
+
+ // return LinkMovementMethod.super.onTouchEvent(widget, buffer, event);
+ return Touch.onTouchEvent(widget, buffer, event);
+ }
+ }
+
+ return super.onTouchEvent(widget, buffer, event);
+ }
+
+ /**
+ * @return a {@link LinkMovementMethodCompat} instance
+ */
+ @NonNull
+ public static LinkMovementMethodCompat getInstance() {
+ if (sInstance == null) {
+ sInstance = new LinkMovementMethodCompat();
+ }
+
+ return sInstance;
+ }
+
+ private static LinkMovementMethodCompat sInstance;
+}
diff --git a/PermissionController/src/com/android/permissioncontroller/permission/data/AppPermGroupUiInfoLiveData.kt b/PermissionController/src/com/android/permissioncontroller/permission/data/AppPermGroupUiInfoLiveData.kt
index f3addd112169513121c97faf50b2c55f20c74d39..b9d2d237ad320f76ac262e09cdf56c38da3fd44d 100644
--- a/PermissionController/src/com/android/permissioncontroller/permission/data/AppPermGroupUiInfoLiveData.kt
+++ b/PermissionController/src/com/android/permissioncontroller/permission/data/AppPermGroupUiInfoLiveData.kt
@@ -17,6 +17,7 @@
package com.android.permissioncontroller.permission.data
import android.Manifest
+import android.Manifest.permission.READ_MEDIA_VISUAL_USER_SELECTED
import android.Manifest.permission_group.STORAGE
import android.app.AppOpsManager
import android.app.Application
@@ -31,9 +32,9 @@ import com.android.permissioncontroller.permission.model.livedatatypes.LightPack
import com.android.permissioncontroller.permission.model.livedatatypes.LightPermGroupInfo
import com.android.permissioncontroller.permission.model.livedatatypes.LightPermInfo
import com.android.permissioncontroller.permission.model.livedatatypes.PermState
+import com.android.permissioncontroller.permission.utils.PermissionMapping.isPlatformPermissionGroup
import com.android.permissioncontroller.permission.utils.LocationUtils
import com.android.permissioncontroller.permission.utils.Utils
-import com.android.permissioncontroller.permission.utils.Utils.isModernPermissionGroup
import kotlinx.coroutines.Job
/**
@@ -132,9 +133,10 @@ class AppPermGroupUiInfoLiveData private constructor(
val isUserSet = isUserSet(permissionState)
- val isGranted = getGrantedIncludingBackground(permissionState, allPermInfos, packageInfo)
+ val permGrantState =
+ getGrantedIncludingBackground(permissionState, allPermInfos, packageInfo)
- return AppPermGroupUiInfo(shouldShow, isGranted, isSystemApp, isUserSet)
+ return AppPermGroupUiInfo(shouldShow, permGrantState, isSystemApp, isUserSet)
}
/**
@@ -155,7 +157,7 @@ class AppPermGroupUiInfoLiveData private constructor(
permissionInfos: Collection
): Boolean {
if (groupInfo.packageName == Utils.OS_PKG &&
- !isModernPermissionGroup(groupInfo.name)) {
+ !isPlatformPermissionGroup(groupInfo.name)) {
return false
}
@@ -193,7 +195,7 @@ class AppPermGroupUiInfoLiveData private constructor(
* permission group
*/
private fun isUserSensitive(permissionState: Map): Boolean {
- if (!isModernPermissionGroup(permGroupName)) {
+ if (!isPlatformPermissionGroup(permGroupName)) {
return true
}
@@ -282,6 +284,12 @@ class AppPermGroupUiInfoLiveData private constructor(
state.granted || (supportsRuntime &&
(state.permFlags and PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED) != 0)
}
+ val onlySelectedPhotosGranted =
+ permissionState.containsKey(READ_MEDIA_VISUAL_USER_SELECTED) &&
+ permissionState.all { (permName, state) ->
+ (permName == READ_MEDIA_VISUAL_USER_SELECTED && state.granted) ||
+ (permName != READ_MEDIA_VISUAL_USER_SELECTED && !state.granted)
+ }
if (anyAllowed && (hasPermWithBackground || shouldShowAsForegroundGroup())) {
return if (isOneTime) {
PermGrantState.PERMS_ASK
@@ -289,7 +297,7 @@ class AppPermGroupUiInfoLiveData private constructor(
PermGrantState.PERMS_ALLOWED_FOREGROUND_ONLY
}
} else if (anyAllowed) {
- return if (isOneTime) {
+ return if (isOneTime || onlySelectedPhotosGranted) {
PermGrantState.PERMS_ASK
} else {
PermGrantState.PERMS_ALLOWED
diff --git a/PermissionController/src/com/android/permissioncontroller/permission/data/AutoRevokedPackagesLiveData.kt b/PermissionController/src/com/android/permissioncontroller/permission/data/AutoRevokedPackagesLiveData.kt
index eb5dee214afba77d0550ae402d0b54fe9ab47c5c..70f857afbe3bc527c4be46c8aafad71d996de765 100644
--- a/PermissionController/src/com/android/permissioncontroller/permission/data/AutoRevokedPackagesLiveData.kt
+++ b/PermissionController/src/com/android/permissioncontroller/permission/data/AutoRevokedPackagesLiveData.kt
@@ -21,8 +21,8 @@ import android.content.pm.PackageManager.FLAG_PERMISSION_AUTO_REVOKED
import android.os.Build
import android.os.UserHandle
import android.util.Log
+import com.android.permissioncontroller.permission.utils.PermissionMapping
import com.android.permissioncontroller.permission.utils.KotlinUtils
-import com.android.permissioncontroller.permission.utils.Utils
import kotlinx.coroutines.Dispatchers.Main
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.Job
@@ -64,7 +64,8 @@ object AutoRevokedPackagesLiveData
val pkgGroups = mutableSetOf>()
for ((idx, requestedPerm) in pkg.requestedPermissions.withIndex()) {
- val group = Utils.getGroupOfPlatformPermission(requestedPerm) ?: continue
+ val group =
+ PermissionMapping.getGroupOfPlatformPermission(requestedPerm) ?: continue
val granted = (pkg.requestedPermissionsFlags[idx] and
PackageInfo.REQUESTED_PERMISSION_GRANTED) != 0
if (pkg.targetSdkVersion < Build.VERSION_CODES.M || !granted) {
diff --git a/PermissionController/src/com/android/permissioncontroller/permission/data/CustomPermGroupNamesLiveData.kt b/PermissionController/src/com/android/permissioncontroller/permission/data/CustomPermGroupNamesLiveData.kt
index b2b645b41475f0f5ee168d9a9badf1dc500190f3..cb44c0a27b99e1f1d36106f75eb26f253f5a2f11 100644
--- a/PermissionController/src/com/android/permissioncontroller/permission/data/CustomPermGroupNamesLiveData.kt
+++ b/PermissionController/src/com/android/permissioncontroller/permission/data/CustomPermGroupNamesLiveData.kt
@@ -19,7 +19,7 @@ package com.android.permissioncontroller.permission.data
import android.app.Application
import android.content.pm.PermissionInfo
import com.android.permissioncontroller.PermissionControllerApplication
-import com.android.permissioncontroller.permission.utils.Utils
+import com.android.permissioncontroller.permission.utils.PermissionMapping
/**
* A class which tracks the names of all custom permission groups in the system, including
@@ -38,7 +38,7 @@ object CustomPermGroupNamesLiveData : SmartUpdateMediatorLiveData>(
}
override fun onUpdate() {
- val platformGroupNames = Utils.getPlatformPermissionGroups()
+ val platformGroupNames = PermissionMapping.getPlatformPermissionGroups()
val groupNames = mutableListOf()
val allPackages = packagesLiveData.value ?: return
diff --git a/PermissionController/src/com/android/permissioncontroller/permission/data/ForegroundPermNamesLiveData.kt b/PermissionController/src/com/android/permissioncontroller/permission/data/ForegroundPermNamesLiveData.kt
index 8ed2429ad6a7febe00447b6c4ecd8713af3ad4b0..1471ed15f2a89cf5d2d744191dab1821c09e6eae 100644
--- a/PermissionController/src/com/android/permissioncontroller/permission/data/ForegroundPermNamesLiveData.kt
+++ b/PermissionController/src/com/android/permissioncontroller/permission/data/ForegroundPermNamesLiveData.kt
@@ -18,6 +18,7 @@ package com.android.permissioncontroller.permission.data
import android.content.pm.PackageManager
import com.android.permissioncontroller.PermissionControllerApplication
+import com.android.permissioncontroller.permission.utils.PermissionMapping
import com.android.permissioncontroller.permission.utils.Utils
import kotlinx.coroutines.Job
@@ -35,7 +36,7 @@ object ForegroundPermNamesLiveData : SmartAsyncMediatorLiveData