Loading packages/SystemUI/src/com/android/systemui/screenshot/RequestProcessor.kt +0 −60 Original line number Diff line number Diff line Loading @@ -16,10 +16,8 @@ package com.android.systemui.screenshot import android.graphics.Insets import android.util.Log import android.view.WindowManager.TAKE_SCREENSHOT_PROVIDED_IMAGE import com.android.internal.util.ScreenshotRequest import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.flags.FeatureFlags Loading Loading @@ -49,64 +47,6 @@ class RequestProcessor @Inject constructor( /** For the Java Async version, to invoke the callback. */ @Application private val mainScope: CoroutineScope ) : ScreenshotRequestProcessor { /** * Inspects the incoming request, returning a potentially modified request depending on policy. * * @param request the request to process */ // TODO: Delete once SCREENSHOT_METADATA flag is launched suspend fun process(request: ScreenshotRequest): ScreenshotRequest { var result = request // Apply work profile screenshots policy: // // If the focused app belongs to a work profile, transforms a full screen // (or partial) screenshot request to a task snapshot (provided image) screenshot. // Whenever displayContentInfo is fetched, the topComponent is also populated // regardless of the managed profile status. if (request.type != TAKE_SCREENSHOT_PROVIDED_IMAGE) { val info = policy.findPrimaryContent(policy.getDefaultDisplayId()) Log.d(TAG, "findPrimaryContent: $info") result = if (policy.isManagedProfile(info.user.identifier)) { val image = capture.captureTask(info.taskId) ?: error("Task snapshot returned a null Bitmap!") // Provide the task snapshot as the screenshot ScreenshotRequest.Builder(TAKE_SCREENSHOT_PROVIDED_IMAGE, request.source) .setTopComponent(info.component) .setTaskId(info.taskId) .setUserId(info.user.identifier) .setBitmap(image) .setBoundsOnScreen(info.bounds) .setInsets(Insets.NONE) .build() } else { // Create a new request of the same type which includes the top component ScreenshotRequest.Builder(request.type, request.source) .setTopComponent(info.component).build() } } return result } /** * Note: This is for compatibility with existing Java. Prefer the suspending function when * calling from a Coroutine context. * * @param request the request to process * @param callback the callback to provide the processed request, invoked from the main thread */ // TODO: Delete once SCREENSHOT_METADATA flag is launched fun processAsync(request: ScreenshotRequest, callback: Consumer<ScreenshotRequest>) { mainScope.launch { val result = process(request) callback.accept(result) } } override suspend fun process(screenshot: ScreenshotData): ScreenshotData { var result = screenshot Loading packages/SystemUI/tests/src/com/android/systemui/screenshot/RequestProcessorTest.kt +1 −58 Original line number Diff line number Diff line Loading @@ -49,30 +49,6 @@ class RequestProcessorTest { private val policy = FakeScreenshotPolicy() private val flags = FakeFeatureFlags() /** Tests the Java-compatible function wrapper, ensures callback is invoked. */ @Test fun testProcessAsync() { val request = ScreenshotRequest.Builder(TAKE_SCREENSHOT_PROVIDED_IMAGE, SCREENSHOT_KEY_OTHER) .setBitmap(Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888)) .build() val processor = RequestProcessor(imageCapture, policy, flags, scope) var result: ScreenshotRequest? = null var callbackCount = 0 val callback: (ScreenshotRequest) -> Unit = { processedRequest: ScreenshotRequest -> result = processedRequest callbackCount++ } // runs synchronously, using Unconfined Dispatcher processor.processAsync(request, callback) // Callback invoked once returning the same request (no changes) assertThat(callbackCount).isEqualTo(1) assertThat(result).isEqualTo(request) } /** Tests the Java-compatible function wrapper, ensures callback is invoked. */ @Test fun testProcessAsync_ScreenshotData() { Loading Loading @@ -112,13 +88,6 @@ class RequestProcessorTest { ScreenshotRequest.Builder(TAKE_SCREENSHOT_FULLSCREEN, SCREENSHOT_OTHER).build() val processor = RequestProcessor(imageCapture, policy, flags, scope) val processedRequest = processor.process(request) // Request has topComponent added, but otherwise unchanged. assertThat(processedRequest.type).isEqualTo(TAKE_SCREENSHOT_FULLSCREEN) assertThat(processedRequest.source).isEqualTo(SCREENSHOT_OTHER) assertThat(processedRequest.topComponent).isEqualTo(component) val processedData = processor.process(ScreenshotData.fromRequest(request)) // Request has topComponent added, but otherwise unchanged. Loading @@ -144,18 +113,6 @@ class RequestProcessorTest { ScreenshotRequest.Builder(TAKE_SCREENSHOT_FULLSCREEN, SCREENSHOT_KEY_OTHER).build() val processor = RequestProcessor(imageCapture, policy, flags, scope) val processedRequest = processor.process(request) // Expect a task snapshot is taken, overriding the full screen mode assertThat(processedRequest.type).isEqualTo(TAKE_SCREENSHOT_PROVIDED_IMAGE) assertThat(bitmap.equalsHardwareBitmap(processedRequest.bitmap)).isTrue() assertThat(processedRequest.boundsInScreen).isEqualTo(bounds) assertThat(processedRequest.insets).isEqualTo(Insets.NONE) assertThat(processedRequest.taskId).isEqualTo(TASK_ID) assertThat(imageCapture.requestedTaskId).isEqualTo(TASK_ID) assertThat(processedRequest.userId).isEqualTo(USER_ID) assertThat(processedRequest.topComponent).isEqualTo(component) val processedData = processor.process(ScreenshotData.fromRequest(request)) // Expect a task snapshot is taken, overriding the full screen mode Loading @@ -165,8 +122,6 @@ class RequestProcessorTest { assertThat(processedData.insets).isEqualTo(Insets.NONE) assertThat(processedData.taskId).isEqualTo(TASK_ID) assertThat(imageCapture.requestedTaskId).isEqualTo(TASK_ID) assertThat(processedRequest.userId).isEqualTo(USER_ID) assertThat(processedRequest.topComponent).isEqualTo(component) } @Test Loading @@ -185,9 +140,6 @@ class RequestProcessorTest { ScreenshotRequest.Builder(TAKE_SCREENSHOT_FULLSCREEN, SCREENSHOT_KEY_OTHER).build() val processor = RequestProcessor(imageCapture, policy, flags, scope) Assert.assertThrows(IllegalStateException::class.java) { runBlocking { processor.process(request) } } Assert.assertThrows(IllegalStateException::class.java) { runBlocking { processor.process(ScreenshotData.fromRequest(request)) } } Loading @@ -212,11 +164,6 @@ class RequestProcessorTest { .setInsets(Insets.NONE) .build() val processedRequest = processor.process(request) // No changes assertThat(processedRequest).isEqualTo(request) val screenshotData = ScreenshotData.fromRequest(request) val processedData = processor.process(screenshotData) Loading @@ -243,14 +190,10 @@ class RequestProcessorTest { .setInsets(Insets.NONE) .build() val processedRequest = processor.process(request) // Work profile, but already a task snapshot, so no changes assertThat(processedRequest).isEqualTo(request) val screenshotData = ScreenshotData.fromRequest(request) val processedData = processor.process(screenshotData) // Work profile, but already a task snapshot, so no changes assertThat(processedData).isEqualTo(screenshotData) } Loading packages/SystemUI/tests/src/com/android/systemui/screenshot/TakeScreenshotServiceTest.kt +0 −32 Original line number Diff line number Diff line Loading @@ -20,10 +20,6 @@ import android.app.admin.DevicePolicyManager import android.app.admin.DevicePolicyResources.Strings.SystemUi.SCREENSHOT_BLOCKED_BY_ADMIN import android.app.admin.DevicePolicyResourcesManager import android.content.ComponentName import android.graphics.Bitmap import android.graphics.Bitmap.Config.HARDWARE import android.graphics.ColorSpace import android.hardware.HardwareBuffer import android.os.UserHandle import android.os.UserManager import android.testing.AndroidTestingRunner Loading Loading @@ -93,14 +89,6 @@ class TakeScreenshotServiceTest : SysuiTestCase() { whenever(controllerFactory.create(any())).thenReturn(controller) // Stub request processor as a synchronous no-op for tests with the flag enabled doAnswer { val request: ScreenshotRequest = it.getArgument(0) as ScreenshotRequest val consumer: Consumer<ScreenshotRequest> = it.getArgument(1) consumer.accept(request) } .whenever(requestProcessor) .processAsync(/* request= */ any(ScreenshotRequest::class.java), /* callback= */ any()) doAnswer { val request: ScreenshotData = it.getArgument(0) as ScreenshotData val consumer: Consumer<ScreenshotData> = it.getArgument(1) Loading Loading @@ -353,23 +341,3 @@ class TakeScreenshotServiceTest : SysuiTestCase() { return service } } private fun Bitmap.equalsHardwareBitmap(other: Bitmap): Boolean { return config == HARDWARE && other.config == HARDWARE && hardwareBuffer == other.hardwareBuffer && colorSpace == other.colorSpace } /** A hardware Bitmap is mandated by use of ScreenshotHelper.HardwareBitmapBundler */ private fun makeHardwareBitmap(width: Int, height: Int): Bitmap { val buffer = HardwareBuffer.create( width, height, HardwareBuffer.RGBA_8888, 1, HardwareBuffer.USAGE_GPU_SAMPLED_IMAGE ) return Bitmap.wrapHardwareBuffer(buffer, ColorSpace.get(ColorSpace.Named.SRGB))!! } Loading
packages/SystemUI/src/com/android/systemui/screenshot/RequestProcessor.kt +0 −60 Original line number Diff line number Diff line Loading @@ -16,10 +16,8 @@ package com.android.systemui.screenshot import android.graphics.Insets import android.util.Log import android.view.WindowManager.TAKE_SCREENSHOT_PROVIDED_IMAGE import com.android.internal.util.ScreenshotRequest import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.flags.FeatureFlags Loading Loading @@ -49,64 +47,6 @@ class RequestProcessor @Inject constructor( /** For the Java Async version, to invoke the callback. */ @Application private val mainScope: CoroutineScope ) : ScreenshotRequestProcessor { /** * Inspects the incoming request, returning a potentially modified request depending on policy. * * @param request the request to process */ // TODO: Delete once SCREENSHOT_METADATA flag is launched suspend fun process(request: ScreenshotRequest): ScreenshotRequest { var result = request // Apply work profile screenshots policy: // // If the focused app belongs to a work profile, transforms a full screen // (or partial) screenshot request to a task snapshot (provided image) screenshot. // Whenever displayContentInfo is fetched, the topComponent is also populated // regardless of the managed profile status. if (request.type != TAKE_SCREENSHOT_PROVIDED_IMAGE) { val info = policy.findPrimaryContent(policy.getDefaultDisplayId()) Log.d(TAG, "findPrimaryContent: $info") result = if (policy.isManagedProfile(info.user.identifier)) { val image = capture.captureTask(info.taskId) ?: error("Task snapshot returned a null Bitmap!") // Provide the task snapshot as the screenshot ScreenshotRequest.Builder(TAKE_SCREENSHOT_PROVIDED_IMAGE, request.source) .setTopComponent(info.component) .setTaskId(info.taskId) .setUserId(info.user.identifier) .setBitmap(image) .setBoundsOnScreen(info.bounds) .setInsets(Insets.NONE) .build() } else { // Create a new request of the same type which includes the top component ScreenshotRequest.Builder(request.type, request.source) .setTopComponent(info.component).build() } } return result } /** * Note: This is for compatibility with existing Java. Prefer the suspending function when * calling from a Coroutine context. * * @param request the request to process * @param callback the callback to provide the processed request, invoked from the main thread */ // TODO: Delete once SCREENSHOT_METADATA flag is launched fun processAsync(request: ScreenshotRequest, callback: Consumer<ScreenshotRequest>) { mainScope.launch { val result = process(request) callback.accept(result) } } override suspend fun process(screenshot: ScreenshotData): ScreenshotData { var result = screenshot Loading
packages/SystemUI/tests/src/com/android/systemui/screenshot/RequestProcessorTest.kt +1 −58 Original line number Diff line number Diff line Loading @@ -49,30 +49,6 @@ class RequestProcessorTest { private val policy = FakeScreenshotPolicy() private val flags = FakeFeatureFlags() /** Tests the Java-compatible function wrapper, ensures callback is invoked. */ @Test fun testProcessAsync() { val request = ScreenshotRequest.Builder(TAKE_SCREENSHOT_PROVIDED_IMAGE, SCREENSHOT_KEY_OTHER) .setBitmap(Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888)) .build() val processor = RequestProcessor(imageCapture, policy, flags, scope) var result: ScreenshotRequest? = null var callbackCount = 0 val callback: (ScreenshotRequest) -> Unit = { processedRequest: ScreenshotRequest -> result = processedRequest callbackCount++ } // runs synchronously, using Unconfined Dispatcher processor.processAsync(request, callback) // Callback invoked once returning the same request (no changes) assertThat(callbackCount).isEqualTo(1) assertThat(result).isEqualTo(request) } /** Tests the Java-compatible function wrapper, ensures callback is invoked. */ @Test fun testProcessAsync_ScreenshotData() { Loading Loading @@ -112,13 +88,6 @@ class RequestProcessorTest { ScreenshotRequest.Builder(TAKE_SCREENSHOT_FULLSCREEN, SCREENSHOT_OTHER).build() val processor = RequestProcessor(imageCapture, policy, flags, scope) val processedRequest = processor.process(request) // Request has topComponent added, but otherwise unchanged. assertThat(processedRequest.type).isEqualTo(TAKE_SCREENSHOT_FULLSCREEN) assertThat(processedRequest.source).isEqualTo(SCREENSHOT_OTHER) assertThat(processedRequest.topComponent).isEqualTo(component) val processedData = processor.process(ScreenshotData.fromRequest(request)) // Request has topComponent added, but otherwise unchanged. Loading @@ -144,18 +113,6 @@ class RequestProcessorTest { ScreenshotRequest.Builder(TAKE_SCREENSHOT_FULLSCREEN, SCREENSHOT_KEY_OTHER).build() val processor = RequestProcessor(imageCapture, policy, flags, scope) val processedRequest = processor.process(request) // Expect a task snapshot is taken, overriding the full screen mode assertThat(processedRequest.type).isEqualTo(TAKE_SCREENSHOT_PROVIDED_IMAGE) assertThat(bitmap.equalsHardwareBitmap(processedRequest.bitmap)).isTrue() assertThat(processedRequest.boundsInScreen).isEqualTo(bounds) assertThat(processedRequest.insets).isEqualTo(Insets.NONE) assertThat(processedRequest.taskId).isEqualTo(TASK_ID) assertThat(imageCapture.requestedTaskId).isEqualTo(TASK_ID) assertThat(processedRequest.userId).isEqualTo(USER_ID) assertThat(processedRequest.topComponent).isEqualTo(component) val processedData = processor.process(ScreenshotData.fromRequest(request)) // Expect a task snapshot is taken, overriding the full screen mode Loading @@ -165,8 +122,6 @@ class RequestProcessorTest { assertThat(processedData.insets).isEqualTo(Insets.NONE) assertThat(processedData.taskId).isEqualTo(TASK_ID) assertThat(imageCapture.requestedTaskId).isEqualTo(TASK_ID) assertThat(processedRequest.userId).isEqualTo(USER_ID) assertThat(processedRequest.topComponent).isEqualTo(component) } @Test Loading @@ -185,9 +140,6 @@ class RequestProcessorTest { ScreenshotRequest.Builder(TAKE_SCREENSHOT_FULLSCREEN, SCREENSHOT_KEY_OTHER).build() val processor = RequestProcessor(imageCapture, policy, flags, scope) Assert.assertThrows(IllegalStateException::class.java) { runBlocking { processor.process(request) } } Assert.assertThrows(IllegalStateException::class.java) { runBlocking { processor.process(ScreenshotData.fromRequest(request)) } } Loading @@ -212,11 +164,6 @@ class RequestProcessorTest { .setInsets(Insets.NONE) .build() val processedRequest = processor.process(request) // No changes assertThat(processedRequest).isEqualTo(request) val screenshotData = ScreenshotData.fromRequest(request) val processedData = processor.process(screenshotData) Loading @@ -243,14 +190,10 @@ class RequestProcessorTest { .setInsets(Insets.NONE) .build() val processedRequest = processor.process(request) // Work profile, but already a task snapshot, so no changes assertThat(processedRequest).isEqualTo(request) val screenshotData = ScreenshotData.fromRequest(request) val processedData = processor.process(screenshotData) // Work profile, but already a task snapshot, so no changes assertThat(processedData).isEqualTo(screenshotData) } Loading
packages/SystemUI/tests/src/com/android/systemui/screenshot/TakeScreenshotServiceTest.kt +0 −32 Original line number Diff line number Diff line Loading @@ -20,10 +20,6 @@ import android.app.admin.DevicePolicyManager import android.app.admin.DevicePolicyResources.Strings.SystemUi.SCREENSHOT_BLOCKED_BY_ADMIN import android.app.admin.DevicePolicyResourcesManager import android.content.ComponentName import android.graphics.Bitmap import android.graphics.Bitmap.Config.HARDWARE import android.graphics.ColorSpace import android.hardware.HardwareBuffer import android.os.UserHandle import android.os.UserManager import android.testing.AndroidTestingRunner Loading Loading @@ -93,14 +89,6 @@ class TakeScreenshotServiceTest : SysuiTestCase() { whenever(controllerFactory.create(any())).thenReturn(controller) // Stub request processor as a synchronous no-op for tests with the flag enabled doAnswer { val request: ScreenshotRequest = it.getArgument(0) as ScreenshotRequest val consumer: Consumer<ScreenshotRequest> = it.getArgument(1) consumer.accept(request) } .whenever(requestProcessor) .processAsync(/* request= */ any(ScreenshotRequest::class.java), /* callback= */ any()) doAnswer { val request: ScreenshotData = it.getArgument(0) as ScreenshotData val consumer: Consumer<ScreenshotData> = it.getArgument(1) Loading Loading @@ -353,23 +341,3 @@ class TakeScreenshotServiceTest : SysuiTestCase() { return service } } private fun Bitmap.equalsHardwareBitmap(other: Bitmap): Boolean { return config == HARDWARE && other.config == HARDWARE && hardwareBuffer == other.hardwareBuffer && colorSpace == other.colorSpace } /** A hardware Bitmap is mandated by use of ScreenshotHelper.HardwareBitmapBundler */ private fun makeHardwareBitmap(width: Int, height: Int): Bitmap { val buffer = HardwareBuffer.create( width, height, HardwareBuffer.RGBA_8888, 1, HardwareBuffer.USAGE_GPU_SAMPLED_IMAGE ) return Bitmap.wrapHardwareBuffer(buffer, ColorSpace.get(ColorSpace.Named.SRGB))!! }