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

Commit a8085d20 authored by Nate Myren's avatar Nate Myren Committed by mse1969
Browse files

RESTRICT AUTOMERGE Limit usages sent to safety center by user

Only the current users (and profiles) should be sent to the safety
center when the mic/camera indicator is clicked

Bug: 362492829
Test: manual
Flag: EXEMPT see bug
Cherrypick-From: https://googleplex-android-review.googlesource.com/q/commit:eab3dee4a2bb1463822547e12006ff6b2f8379d9
Merged-In: I4c7ec006c839f331cd8bd6b7ac366382cf2c2f4d
Change-Id: I4c7ec006c839f331cd8bd6b7ac366382cf2c2f4d
parent 0addda03
Loading
Loading
Loading
Loading
+19 −4
Original line number Diff line number Diff line
@@ -6,6 +6,7 @@ import android.content.Intent
import android.content.IntentFilter
import android.permission.PermissionGroupUsage
import android.permission.PermissionManager
import android.os.UserHandle
import android.safetycenter.SafetyCenterManager
import android.view.View
import androidx.annotation.WorkerThread
@@ -26,6 +27,7 @@ import java.util.concurrent.Executor
import javax.inject.Inject
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.settings.UserTracker
import com.android.systemui.statusbar.policy.DeviceProvisionedController

interface ChipVisibilityListener {
@@ -56,7 +58,8 @@ class HeaderPrivacyIconsController @Inject constructor(
    private val appOpsController: AppOpsController,
    private val broadcastDispatcher: BroadcastDispatcher,
    private val safetyCenterManager: SafetyCenterManager,
    private val deviceProvisionedController: DeviceProvisionedController
    private val deviceProvisionedController: DeviceProvisionedController,
    private val userTracker: UserTracker,
) {

    var chipVisibilityListener: ChipVisibilityListener? = null
@@ -156,7 +159,7 @@ class HeaderPrivacyIconsController @Inject constructor(

    private fun showSafetyCenter() {
        backgroundExecutor.execute {
            val usage = ArrayList(permGroupUsage())
            val usage = permGroupUsage()
            privacyLogger.logUnfilteredPermGroupUsage(usage)
            val startSafetyCenter = Intent(Intent.ACTION_VIEW_SAFETY_CENTER_QS)
            startSafetyCenter.putParcelableArrayListExtra(PermissionManager.EXTRA_PERMISSION_USAGES,
@@ -170,8 +173,20 @@ class HeaderPrivacyIconsController @Inject constructor(
    }

    @WorkerThread
    private fun permGroupUsage(): List<PermissionGroupUsage> {
        return permissionManager.getIndicatorAppOpUsageData(appOpsController.isMicMuted)
    fun permGroupUsage(): ArrayList<PermissionGroupUsage> {
        val usages =
            ArrayList(permissionManager.getIndicatorAppOpUsageData(appOpsController.isMicMuted))
        val invalidUserUsages = mutableListOf<PermissionGroupUsage>()
        val userProfiles = userTracker.userProfiles
        for (usage in usages) {
            val userId = UserHandle.getUserId(usage.uid)
            if (usage.isPhoneCall || userProfiles.any { it.id == userId }) {
                continue
            }
            invalidUserUsages.add(usage)
        }
        usages.removeAll(invalidUserUsages)
        return usages
    }

    fun onParentInvisible() {
+63 −1
Original line number Diff line number Diff line
@@ -4,6 +4,9 @@ import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.content.pm.UserInfo
import android.os.UserHandle
import android.permission.PermissionGroupUsage
import android.permission.PermissionManager
import android.safetycenter.SafetyCenterManager
import android.testing.AndroidTestingRunner
@@ -18,6 +21,7 @@ import com.android.systemui.privacy.OngoingPrivacyChip
import com.android.systemui.privacy.PrivacyDialogController
import com.android.systemui.privacy.PrivacyItemController
import com.android.systemui.privacy.logging.PrivacyLogger
import com.android.systemui.settings.UserTracker
import com.android.systemui.statusbar.phone.StatusIconContainer
import com.android.systemui.statusbar.policy.DeviceProvisionedController
import com.android.systemui.util.concurrency.FakeExecutor
@@ -29,6 +33,8 @@ import com.android.systemui.util.time.FakeSystemClock
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNotNull
import org.mockito.ArgumentMatchers.anyInt
import org.mockito.Mock
import org.mockito.Mockito
@@ -69,6 +75,8 @@ class HeaderPrivacyIconsControllerTest : SysuiTestCase() {
    private lateinit var safetyCenterManager: SafetyCenterManager
    @Mock
    private lateinit var deviceProvisionedController: DeviceProvisionedController
    @Mock
    private lateinit var userTracker: UserTracker

    private val uiExecutor = FakeExecutor(FakeSystemClock())
    private val backgroundExecutor = FakeExecutor(FakeSystemClock())
@@ -103,7 +111,8 @@ class HeaderPrivacyIconsControllerTest : SysuiTestCase() {
                appOpsController,
                broadcastDispatcher,
                safetyCenterManager,
                deviceProvisionedController
                deviceProvisionedController,
                userTracker,
        )

        backgroundExecutor.runAllReady()
@@ -216,8 +225,61 @@ class HeaderPrivacyIconsControllerTest : SysuiTestCase() {
        verify(privacyDialogController, never()).showDialog(any(Context::class.java))
    }

    @Test
    fun testPermGroupUsage_filtersOutInactiveUsers() {
        whenever(userTracker.userProfiles).thenReturn(listOf(createUserInfo(USER_ID)))
        whenever(permissionManager.getIndicatorAppOpUsageData(false))
            .thenReturn(listOf(createPermUsage(USER_ID), createPermUsage(OTHER_USER_ID)))
        val usages = controller.permGroupUsage()
        assertEquals(1, usages.size)
        assertEquals(USER_ID, UserHandle.getUserId(usages[0].uid))
    }

    @Test
    fun testPermGroupUsage_alwaysReturnPhoneCallUsage() {
        whenever(userTracker.userProfiles).thenReturn(listOf(createUserInfo(USER_ID)))
        whenever(permissionManager.getIndicatorAppOpUsageData(false))
            .thenReturn(listOf(createPermUsage(OTHER_USER_ID, isPhone = true)))
        val usages = controller.permGroupUsage()
        assertEquals(OTHER_USER_ID, UserHandle.getUserId(usages[0].uid))
    }

    @Test
    fun testPermGroupUsage_returnsProfileUsages() {
        whenever(userTracker.userProfiles)
            .thenReturn(listOf(createUserInfo(USER_ID), createUserInfo(PROFILE_USER_ID)))
        whenever(permissionManager.getIndicatorAppOpUsageData(false))
            .thenReturn(listOf(createPermUsage(USER_ID), createPermUsage(PROFILE_USER_ID)))
        val usages = controller.permGroupUsage()
        assertEquals(2, usages.size)
        assertNotNull(usages.firstOrNull { UserHandle.getUserId(it.uid) == USER_ID })
        assertNotNull(usages.firstOrNull { UserHandle.getUserId(it.uid) == PROFILE_USER_ID })
    }

    private fun createPermUsage(user: Int, isPhone: Boolean = false): PermissionGroupUsage =
        PermissionGroupUsage(
            "",
            UserHandle.getUid(user, 0),
            0,
            "",
            true,
            isPhone,
            null,
            null,
            null,
        )

    private fun createUserInfo(userId: Int) = UserInfo(userId, "", 0)


    private fun setPrivacyController(micCamera: Boolean, location: Boolean) {
        whenever(privacyItemController.micCameraAvailable).thenReturn(micCamera)
        whenever(privacyItemController.locationAvailable).thenReturn(location)
    }

    companion object {
        const val USER_ID = 0
        const val PROFILE_USER_ID = 1
        const val OTHER_USER_ID = 2
    }
}
 No newline at end of file