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

Commit 889b436d authored by Mark Renouf's avatar Mark Renouf
Browse files

Match disabled components for screenshot listeners

Since the notification channel isn't user-specific, the listening
component could be disabled in the primary user profile. In this
case the name of the app is still desired, this adds
MATCH_DISABLED_COMPONENTS to the getActivityInfo call.

Test: atest ScreenshotDetectionControllerTest
Bug: 273834381
Change-Id: Id4a88d4d87d0c88c378e6d66b5afa43c113fd67b
parent 08550633
Loading
Loading
Loading
Loading
+3 −1
Original line number Original line Diff line number Diff line
@@ -17,6 +17,8 @@
package com.android.systemui.screenshot
package com.android.systemui.screenshot


import android.content.pm.PackageManager
import android.content.pm.PackageManager
import android.content.pm.PackageManager.ComponentInfoFlags
import android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS
import android.view.Display
import android.view.Display
import android.view.IWindowManager
import android.view.IWindowManager
import android.view.ViewGroup
import android.view.ViewGroup
@@ -45,7 +47,7 @@ constructor(
        // Convert component names to app names.
        // Convert component names to app names.
        return components.map {
        return components.map {
            packageManager
            packageManager
                .getActivityInfo(it, PackageManager.ComponentInfoFlags.of(0))
                .getActivityInfo(it, ComponentInfoFlags.of(MATCH_DISABLED_COMPONENTS.toLong()))
                .loadLabel(packageManager)
                .loadLabel(packageManager)
        }
        }
    }
    }
+55 −0
Original line number Original line Diff line number Diff line
@@ -19,12 +19,14 @@ package com.android.systemui.screenshot
import android.content.ComponentName
import android.content.ComponentName
import android.content.pm.ActivityInfo
import android.content.pm.ActivityInfo
import android.content.pm.PackageManager
import android.content.pm.PackageManager
import android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS
import android.testing.AndroidTestingRunner
import android.testing.AndroidTestingRunner
import android.view.Display
import android.view.Display
import android.view.IWindowManager
import android.view.IWindowManager
import android.view.WindowManager
import android.view.WindowManager
import androidx.test.filters.SmallTest
import androidx.test.filters.SmallTest
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.argThat
import com.android.systemui.util.mockito.eq
import com.android.systemui.util.mockito.eq
import com.android.systemui.util.mockito.whenever
import com.android.systemui.util.mockito.whenever
import junit.framework.Assert.assertEquals
import junit.framework.Assert.assertEquals
@@ -32,6 +34,7 @@ import junit.framework.Assert.assertTrue
import org.junit.Before
import org.junit.Before
import org.junit.Test
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runner.RunWith
import org.mockito.ArgumentMatcher
import org.mockito.Mock
import org.mockito.Mock
import org.mockito.Mockito.mock
import org.mockito.Mockito.mock
import org.mockito.Mockito.never
import org.mockito.Mockito.never
@@ -158,4 +161,56 @@ class ScreenshotDetectionControllerTest {
        assertEquals(appName2, list[1])
        assertEquals(appName2, list[1])
        assertEquals(appName3, list[2])
        assertEquals(appName3, list[2])
    }
    }

    private fun includesFlagBits(@PackageManager.ComponentInfoFlagsBits mask: Int) =
        ComponentInfoFlagMatcher(mask, mask)
    private fun excludesFlagBits(@PackageManager.ComponentInfoFlagsBits mask: Int) =
        ComponentInfoFlagMatcher(mask, 0)

    private class ComponentInfoFlagMatcher(
        @PackageManager.ComponentInfoFlagsBits val mask: Int, val value: Int
    ): ArgumentMatcher<PackageManager.ComponentInfoFlags> {
        override fun matches(flags: PackageManager.ComponentInfoFlags): Boolean {
            return (mask.toLong() and flags.value) == value.toLong()
        }

        override fun toString(): String{
            return "mask 0x%08x == 0x%08x".format(mask, value)
        }
    }

    @Test
    fun testMaybeNotifyOfScreenshot_disabledApp() {
        val data = ScreenshotData.forTesting()
        data.source = WindowManager.ScreenshotSource.SCREENSHOT_KEY_CHORD

        val component = ComponentName("package1", "class1")
        val appName = "app name"
        val activityInfo = mock(ActivityInfo::class.java)

        whenever(
            packageManager.getActivityInfo(
                eq(component),
                argThat(includesFlagBits(MATCH_DISABLED_COMPONENTS))
            )
        ).thenReturn(activityInfo);

        whenever(
            packageManager.getActivityInfo(
                eq(component),
                argThat(excludesFlagBits(MATCH_DISABLED_COMPONENTS))
            )
        ).thenThrow(PackageManager.NameNotFoundException::class.java);

        whenever(windowManager.notifyScreenshotListeners(eq(Display.DEFAULT_DISPLAY)))
            .thenReturn(listOf(component))

        whenever(activityInfo.loadLabel(eq(packageManager))).thenReturn(appName)

        val list = controller.maybeNotifyOfScreenshot(data)

        assertEquals(1, list.size)
        assertEquals(appName, list[0])
    }

}
}