Location provider check for subattribution

Bug: 200280741
Test: atest com.android.systemui.privacy.PrivacyDialogTest
Change-Id: I7240db08025d801eb537234ca95aeb17c3f302f2
Merged-In: I7240db08025d801eb537234ca95aeb17c3f302f2
This commit is contained in:
Ganesh Olekar
2022-02-17 19:44:39 +00:00
parent 8fb55d4172
commit 7f13dcaadf
3 changed files with 126 additions and 12 deletions

View File

@@ -47,6 +47,7 @@ import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.icu.text.ListFormatter;
import android.location.LocationManager;
import android.media.AudioManager;
import android.os.Process;
import android.os.UserHandle;
@@ -411,10 +412,13 @@ public class PermissionUsageHelper implements AppOpsManager.OnOpActiveChangedLis
}
/**
* Returns true if the app supports subattribution.
* Returns true if the app satisfies subattribution policies and supports it
*/
private boolean isSubattributionSupported(String packageName, int uid) {
try {
if (!isLocationProvider(packageName)) {
return false;
}
PackageManager userPkgManager =
getUserContext(UserHandle.getUserHandleForUid(uid)).getPackageManager();
ApplicationInfo appInfo = userPkgManager.getApplicationInfoAsUser(packageName,
@@ -429,6 +433,15 @@ public class PermissionUsageHelper implements AppOpsManager.OnOpActiveChangedLis
}
}
/**
* @param packageName
* @return If the package is location provider
*/
private boolean isLocationProvider(String packageName) {
return Objects.requireNonNull(
mContext.getSystemService(LocationManager.class)).isProviderPackage(packageName);
}
/**
* Get the raw usages from the system, and then parse out the ones that are not recent enough,
* determine which permission group each belongs in, and removes duplicates (if the same app

View File

@@ -150,24 +150,27 @@ class PrivacyDialogController(
packageName: String,
userId: Int,
permGroupName: CharSequence,
attributionTag: CharSequence?
attributionTag: CharSequence?,
isAttributionSupported: Boolean
): Intent
{
lateinit var intent: Intent
if (attributionTag != null) {
if (attributionTag != null && isAttributionSupported) {
intent = Intent(Intent.ACTION_MANAGE_PERMISSION_USAGE)
intent.setPackage(packageName)
intent.putExtra(Intent.EXTRA_PERMISSION_GROUP_NAME, permGroupName.toString())
intent.putExtra(Intent.EXTRA_ATTRIBUTION_TAGS, arrayOf(attributionTag.toString()))
intent.putExtra(Intent.EXTRA_SHOWING_ATTRIBUTION, true)
val resolveInfo = packageManager.resolveActivity(
intent, PackageManager.ResolveInfoFlags.of(0))
?: return getDefaultManageAppPermissionsIntent(packageName, userId)
intent.component = ComponentName(packageName, resolveInfo.activityInfo.name)
return intent
} else {
return getDefaultManageAppPermissionsIntent(packageName, userId)
intent, PackageManager.ResolveInfoFlags.of(0))
if (resolveInfo != null && resolveInfo.activityInfo != null &&
resolveInfo.activityInfo.permission ==
android.Manifest.permission.START_VIEW_PERMISSION_USAGE) {
intent.component = ComponentName(packageName, resolveInfo.activityInfo.name)
return intent
}
}
return getDefaultManageAppPermissionsIntent(packageName, userId)
}
fun getDefaultManageAppPermissionsIntent(packageName: String, userId: Int): Intent {
@@ -226,9 +229,15 @@ class PrivacyDialogController(
userInfo?.isManagedProfile ?: false,
it.isPhoneCall,
it.permissionGroupName,
getManagePermissionIntent(it.packageName, userId,
it.permissionGroupName,
it.attributionTag)
getManagePermissionIntent(
it.packageName,
userId,
it.permissionGroupName,
it.attributionTag,
// attributionLabel is set only when subattribution policies
// are supported and satisfied
it.attributionLabel != null
)
)
}
} else {

View File

@@ -19,8 +19,11 @@ package com.android.systemui.privacy
import android.app.ActivityManager
import android.content.Context
import android.content.Intent
import android.content.pm.ActivityInfo
import android.content.pm.ApplicationInfo
import android.content.pm.PackageManager
import android.content.pm.PackageManager.ResolveInfoFlags
import android.content.pm.ResolveInfo
import android.content.pm.UserInfo
import android.os.Process.SYSTEM_UID
import android.os.UserHandle
@@ -648,6 +651,77 @@ class PrivacyDialogControllerTest : SysuiTestCase() {
}
}
@Test
fun testCorrectIntentSubAttribution() {
val usage = createMockPermGroupUsage(
attributionTag = TEST_ATTRIBUTION_TAG,
attributionLabel = "TEST_LABEL"
)
val activityInfo = createMockActivityInfo()
val resolveInfo = createMockResolveInfo(activityInfo)
`when`(permissionManager.getIndicatorAppOpUsageData(anyBoolean())).thenReturn(listOf(usage))
`when`(packageManager.resolveActivity(any(), any<ResolveInfoFlags>()))
.thenAnswer { resolveInfo }
controller.showDialog(context)
exhaustExecutors()
dialogProvider.list?.let { list ->
val navigationIntent = list.get(0).navigationIntent!!
assertThat(navigationIntent.action).isEqualTo(Intent.ACTION_MANAGE_PERMISSION_USAGE)
assertThat(navigationIntent.getStringExtra(Intent.EXTRA_PERMISSION_GROUP_NAME))
.isEqualTo(PERM_CAMERA)
assertThat(navigationIntent.getStringArrayExtra(Intent.EXTRA_ATTRIBUTION_TAGS))
.isEqualTo(arrayOf(TEST_ATTRIBUTION_TAG.toString()))
assertThat(navigationIntent.getBooleanExtra(Intent.EXTRA_SHOWING_ATTRIBUTION, false))
.isTrue()
}
}
@Test
fun testDefaultIntentOnMissingAttributionLabel() {
val usage = createMockPermGroupUsage(
attributionTag = TEST_ATTRIBUTION_TAG
)
val activityInfo = createMockActivityInfo()
val resolveInfo = createMockResolveInfo(activityInfo)
`when`(permissionManager.getIndicatorAppOpUsageData(anyBoolean())).thenReturn(listOf(usage))
`when`(packageManager.resolveActivity(any(), any<ResolveInfoFlags>()))
.thenAnswer { resolveInfo }
controller.showDialog(context)
exhaustExecutors()
dialogProvider.list?.let { list ->
assertThat(isIntentEqual(list.get(0).navigationIntent!!,
controller.getDefaultManageAppPermissionsIntent(TEST_PACKAGE_NAME, USER_ID)))
.isTrue()
}
}
@Test
fun testDefaultIntentOnIncorrectPermission() {
val usage = createMockPermGroupUsage(
attributionTag = TEST_ATTRIBUTION_TAG
)
val activityInfo = createMockActivityInfo(
permission = "INCORRECT_PERMISSION"
)
val resolveInfo = createMockResolveInfo(activityInfo)
`when`(permissionManager.getIndicatorAppOpUsageData(anyBoolean())).thenReturn(listOf(usage))
`when`(packageManager.resolveActivity(any(), any<ResolveInfoFlags>()))
.thenAnswer { resolveInfo }
controller.showDialog(context)
exhaustExecutors()
dialogProvider.list?.let { list ->
assertThat(isIntentEqual(list.get(0).navigationIntent!!,
controller.getDefaultManageAppPermissionsIntent(TEST_PACKAGE_NAME, USER_ID)))
.isTrue()
}
}
private fun exhaustExecutors() {
FakeExecutor.exhaustExecutors(backgroundExecutor, uiExecutor)
}
@@ -680,6 +754,24 @@ class PrivacyDialogControllerTest : SysuiTestCase() {
return user * UserHandle.PER_USER_RANGE + nextUid++
}
private fun createMockResolveInfo(
activityInfo: ActivityInfo? = null
): ResolveInfo {
val resolveInfo = mock(ResolveInfo::class.java)
resolveInfo.activityInfo = activityInfo
return resolveInfo
}
private fun createMockActivityInfo(
permission: String = android.Manifest.permission.START_VIEW_PERMISSION_USAGE,
className: String = "TEST_CLASS_NAME"
): ActivityInfo {
val activityInfo = mock(ActivityInfo::class.java)
activityInfo.permission = permission
activityInfo.name = className
return activityInfo
}
private fun createMockPermGroupUsage(
packageName: String = TEST_PACKAGE_NAME,
uid: Int = generateUidForUser(USER_ID),