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

Commit b710898d authored by Nicolo' Mazzucato's avatar Nicolo' Mazzucato
Browse files

Use default ScreenshotController for PROVIDED_IMAGE type

If the screenshot type is PROVIDED_IMAGE, then there is no need to make multiple display screenshots.
In this case, the screenshot controller for the default display is used to save the image and show the UI.

In the future, we might want to show the UI only in the display that actually provided the image, but for now this is not possible, as only the default display can provide the image.

Bug: 290910794
Bug: 297354762
Test: TakeScreenshotExecutorTest
Change-Id: I1e30be46cf405a0e52047946a1e993266bac94dc
parent 345fd7a6
Loading
Loading
Loading
Loading
+9 −3
Original line number Diff line number Diff line
@@ -4,6 +4,7 @@ import android.net.Uri
import android.os.Trace
import android.util.Log
import android.view.Display
import android.view.WindowManager.TAKE_SCREENSHOT_PROVIDED_IMAGE
import com.android.internal.logging.UiEventLogger
import com.android.internal.util.ScreenshotRequest
import com.android.systemui.dagger.SysUISingleton
@@ -55,7 +56,7 @@ constructor(
        onSaved: (Uri) -> Unit,
        requestCallback: RequestCallback
    ) {
        val displayIds = getDisplaysToScreenshot()
        val displayIds = getDisplaysToScreenshot(screenshotRequest.type)
        val resultCallbackWrapper = MultiResultCallbackWrapper(requestCallback)
        screenshotRequest.oneForEachDisplay(displayIds).forEach { screenshotData: ScreenshotData ->
            dispatchToController(
@@ -93,8 +94,13 @@ constructor(
            .handleScreenshot(screenshotData, onSaved, callback)
    }

    private fun getDisplaysToScreenshot(): List<Int> {
        return displays.value.filter { it.type in ALLOWED_DISPLAY_TYPES }.map { it.displayId }
    private fun getDisplaysToScreenshot(requestType: Int): List<Int> {
        return if (requestType == TAKE_SCREENSHOT_PROVIDED_IMAGE) {
            // If this is a provided image, let's show the UI on the default display only.
            listOf(Display.DEFAULT_DISPLAY)
        } else {
            displays.value.filter { it.type in ALLOWED_DISPLAY_TYPES }.map { it.displayId }
        }
    }

    /**
+38 −5
Original line number Diff line number Diff line
package com.android.systemui.screenshot

import android.content.ComponentName
import android.graphics.Bitmap
import android.net.Uri
import android.testing.AndroidTestingRunner
import android.view.Display
@@ -10,6 +11,7 @@ import android.view.Display.TYPE_OVERLAY
import android.view.Display.TYPE_VIRTUAL
import android.view.Display.TYPE_WIFI
import android.view.WindowManager
import android.view.WindowManager.TAKE_SCREENSHOT_PROVIDED_IMAGE
import androidx.test.filters.SmallTest
import com.android.internal.logging.testing.UiEventLoggerFake
import com.android.internal.util.ScreenshotRequest
@@ -94,6 +96,35 @@ class TakeScreenshotExecutorTest : SysuiTestCase() {
            screenshotExecutor.onDestroy()
        }

    @Test
    fun executeScreenshots_providedImageType_callsOnlyDefaultDisplayController() =
        testScope.runTest {
            setDisplays(display(TYPE_INTERNAL, id = 0), display(TYPE_EXTERNAL, id = 1))
            val onSaved = { _: Uri -> }
            screenshotExecutor.executeScreenshots(
                createScreenshotRequest(TAKE_SCREENSHOT_PROVIDED_IMAGE),
                onSaved,
                callback
            )

            verify(controllerFactory).create(eq(0))
            verify(controllerFactory, never()).create(eq(1))

            val capturer = ArgumentCaptor<ScreenshotData>()

            verify(controller0).handleScreenshot(capturer.capture(), any(), any())
            assertThat(capturer.value.displayId).isEqualTo(0)
            // OnSaved callback should be different.
            verify(controller1, never()).handleScreenshot(any(), any(), any())

            assertThat(eventLogger.numLogs()).isEqualTo(1)
            assertThat(eventLogger.get(0).eventId)
                .isEqualTo(ScreenshotEvent.SCREENSHOT_REQUESTED_KEY_OTHER.id)
            assertThat(eventLogger.get(0).packageName).isEqualTo(topComponent.packageName)

            screenshotExecutor.onDestroy()
        }

    @Test
    fun executeScreenshots_onlyVirtualDisplays_noInteractionsWithControllers() =
        testScope.runTest {
@@ -283,12 +314,14 @@ class TakeScreenshotExecutorTest : SysuiTestCase() {
        runCurrent()
    }

    private fun createScreenshotRequest() =
        ScreenshotRequest.Builder(
                WindowManager.TAKE_SCREENSHOT_FULLSCREEN,
                WindowManager.ScreenshotSource.SCREENSHOT_KEY_OTHER
            )
    private fun createScreenshotRequest(type: Int = WindowManager.TAKE_SCREENSHOT_FULLSCREEN) =
        ScreenshotRequest.Builder(type, WindowManager.ScreenshotSource.SCREENSHOT_KEY_OTHER)
            .setTopComponent(topComponent)
            .also {
                if (type == TAKE_SCREENSHOT_PROVIDED_IMAGE) {
                    it.setBitmap(Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888))
                }
            }
            .build()

    private class FakeRequestProcessor : ScreenshotRequestProcessor {