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

Commit 2aeba76a authored by Nate Myren's avatar Nate Myren Committed by Android Build Coastguard Worker
Browse files

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:ec99b5a699f1442d680bcaddd42c906765ea1878
Merged-In: I4c7ec006c839f331cd8bd6b7ac366382cf2c2f4d
Change-Id: I4c7ec006c839f331cd8bd6b7ac366382cf2c2f4d
parent 02751bc6
Loading
Loading
Loading
Loading
+63 −0
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.view.View
@@ -21,6 +24,7 @@ import com.android.systemui.privacy.PrivacyDialogController
import com.android.systemui.privacy.PrivacyDialogControllerV2
import com.android.systemui.privacy.PrivacyItemController
import com.android.systemui.privacy.logging.PrivacyLogger
import com.android.systemui.settings.UserTracker
import com.android.systemui.shade.data.repository.shadeDialogContextInteractor
import com.android.systemui.statusbar.phone.StatusIconContainer
import com.android.systemui.statusbar.policy.DeviceProvisionedController
@@ -32,6 +36,8 @@ import com.android.systemui.util.mockito.capture
import com.android.systemui.util.mockito.eq
import com.android.systemui.util.mockito.nullable
import com.android.systemui.util.time.FakeSystemClock
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNotNull
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@@ -81,6 +87,9 @@ class HeaderPrivacyIconsControllerTest : SysuiTestCase() {
    @Mock
    private lateinit var featureFlags: FeatureFlags

    @Mock
    private lateinit var userTracker: UserTracker

    private val uiExecutor = FakeExecutor(FakeSystemClock())
    private val backgroundExecutor = FakeExecutor(FakeSystemClock())
    private lateinit var cameraSlotName: String
@@ -118,6 +127,7 @@ class HeaderPrivacyIconsControllerTest : SysuiTestCase() {
                deviceProvisionedController,
                featureFlags,
                kosmos.shadeDialogContextInteractor,
                userTracker,
        )

        backgroundExecutor.runAllReady()
@@ -269,8 +279,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
    }
}
+18 −3
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
@@ -29,6 +30,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.shade.ShadeViewProviderModule.Companion.SHADE_HEADER
import com.android.systemui.shade.domain.interactor.ShadeDialogContextInteractor
import com.android.systemui.statusbar.policy.DeviceProvisionedController
@@ -66,6 +68,7 @@ class HeaderPrivacyIconsController @Inject constructor(
    private val deviceProvisionedController: DeviceProvisionedController,
    private val featureFlags: FeatureFlags,
    private val shadeDialogContextInteractor: ShadeDialogContextInteractor,
    private val userTracker: UserTracker,
) {

    var chipVisibilityListener: ChipVisibilityListener? = null
@@ -171,7 +174,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,
@@ -185,8 +188,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() {