diff options
6 files changed, 360 insertions, 64 deletions
diff --git a/core/java/com/android/internal/util/ScreenshotRequest.java b/core/java/com/android/internal/util/ScreenshotRequest.java index 1902f80bd384..c8b7defb5276 100644 --- a/core/java/com/android/internal/util/ScreenshotRequest.java +++ b/core/java/com/android/internal/util/ScreenshotRequest.java @@ -173,6 +173,9 @@ public class ScreenshotRequest implements Parcelable { public Builder( @WindowManager.ScreenshotType int type, @WindowManager.ScreenshotSource int source) { + if (type != TAKE_SCREENSHOT_FULLSCREEN && type != TAKE_SCREENSHOT_PROVIDED_IMAGE) { + throw new IllegalArgumentException("Invalid screenshot type requested!"); + } mType = type; mSource = source; } diff --git a/core/tests/screenshothelpertests/src/com/android/internal/util/ScreenshotRequestTest.java b/core/tests/screenshothelpertests/src/com/android/internal/util/ScreenshotRequestTest.java index 30540a5f013b..89acbc7986fb 100644 --- a/core/tests/screenshothelpertests/src/com/android/internal/util/ScreenshotRequestTest.java +++ b/core/tests/screenshothelpertests/src/com/android/internal/util/ScreenshotRequestTest.java @@ -131,6 +131,12 @@ public final class ScreenshotRequestTest { assertEquals(Insets.NONE, out.getInsets()); } + @Test + public void testInvalidType() { + assertThrows(IllegalArgumentException.class, + () -> new ScreenshotRequest.Builder(5, 2).build()); + } + private Bitmap makeHardwareBitmap(int width, int height) { HardwareBuffer buffer = HardwareBuffer.create( width, height, HardwareBuffer.RGBA_8888, 1, HardwareBuffer.USAGE_GPU_SAMPLED_IMAGE); diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotEvent.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotEvent.java index c891686ada8f..7a62bae5b5ae 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotEvent.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotEvent.java @@ -46,6 +46,8 @@ public enum ScreenshotEvent implements UiEventLogger.UiEventEnum { SCREENSHOT_SAVED(306), @UiEvent(doc = "screenshot failed to save") SCREENSHOT_NOT_SAVED(336), + @UiEvent(doc = "failed to capture screenshot") + SCREENSHOT_CAPTURE_FAILED(1281), @UiEvent(doc = "screenshot preview tapped") SCREENSHOT_PREVIEW_TAPPED(307), @UiEvent(doc = "screenshot edit button tapped") diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java b/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java index 4214c8f6ecf2..8035d19e3b8f 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java @@ -26,6 +26,7 @@ import static com.android.systemui.screenshot.LogConfig.DEBUG_CALLBACK; import static com.android.systemui.screenshot.LogConfig.DEBUG_DISMISS; import static com.android.systemui.screenshot.LogConfig.DEBUG_SERVICE; import static com.android.systemui.screenshot.LogConfig.logTag; +import static com.android.systemui.screenshot.ScreenshotEvent.SCREENSHOT_CAPTURE_FAILED; import static com.android.systemui.screenshot.ScreenshotEvent.SCREENSHOT_DISMISSED_OTHER; import android.annotation.MainThread; @@ -202,6 +203,7 @@ public class TakeScreenshotService extends Service { // animation and error notification. if (!mUserManager.isUserUnlocked()) { Log.w(TAG, "Skipping screenshot because storage is locked!"); + logFailedRequest(request); mNotificationsController.notifyScreenshotError( R.string.screenshot_failed_to_save_user_locked_text); callback.reportError(); @@ -212,6 +214,7 @@ public class TakeScreenshotService extends Service { mBgExecutor.execute(() -> { Log.w(TAG, "Skipping screenshot because an IT admin has disabled " + "screenshots on the device"); + logFailedRequest(request); String blockedByAdminText = mDevicePolicyManager.getResources().getString( SCREENSHOT_BLOCKED_BY_ADMIN, () -> mContext.getString(R.string.screenshot_blocked_by_admin)); @@ -225,38 +228,43 @@ public class TakeScreenshotService extends Service { if (mFeatureFlags.isEnabled(Flags.SCREENSHOT_METADATA)) { Log.d(TAG, "Processing screenshot data"); ScreenshotData screenshotData = ScreenshotData.fromRequest(request); - mProcessor.processAsync(screenshotData, - (data) -> dispatchToController(data, onSaved, callback)); + try { + mProcessor.processAsync(screenshotData, + (data) -> dispatchToController(data, onSaved, callback)); + } catch (IllegalStateException e) { + Log.e(TAG, "Failed to process screenshot request!", e); + logFailedRequest(request); + mNotificationsController.notifyScreenshotError( + R.string.screenshot_failed_to_capture_text); + callback.reportError(); + } } else { - mProcessor.processAsync(request, - (r) -> dispatchToController(r, onSaved, callback)); + try { + mProcessor.processAsync(request, + (r) -> dispatchToController(r, onSaved, callback)); + } catch (IllegalStateException e) { + Log.e(TAG, "Failed to process screenshot request!", e); + logFailedRequest(request); + mNotificationsController.notifyScreenshotError( + R.string.screenshot_failed_to_capture_text); + callback.reportError(); + } } } private void dispatchToController(ScreenshotData screenshot, Consumer<Uri> uriConsumer, RequestCallback callback) { - mUiEventLogger.log(ScreenshotEvent.getScreenshotSource(screenshot.getSource()), 0, screenshot.getPackageNameString()); - - if (screenshot.getType() == WindowManager.TAKE_SCREENSHOT_PROVIDED_IMAGE - && screenshot.getBitmap() == null) { - Log.e(TAG, "Got null bitmap from screenshot message"); - mNotificationsController.notifyScreenshotError( - R.string.screenshot_failed_to_capture_text); - callback.reportError(); - return; - } - mScreenshot.handleScreenshot(screenshot, uriConsumer, callback); } private void dispatchToController(ScreenshotRequest request, Consumer<Uri> uriConsumer, RequestCallback callback) { - ComponentName topComponent = request.getTopComponent(); - mUiEventLogger.log(ScreenshotEvent.getScreenshotSource(request.getSource()), 0, - topComponent == null ? "" : topComponent.getPackageName()); + String packageName = topComponent == null ? "" : topComponent.getPackageName(); + mUiEventLogger.log( + ScreenshotEvent.getScreenshotSource(request.getSource()), 0, packageName); switch (request.getType()) { case WindowManager.TAKE_SCREENSHOT_FULLSCREEN: @@ -275,21 +283,22 @@ public class TakeScreenshotService extends Service { int taskId = request.getTaskId(); int userId = request.getUserId(); - if (screenshot == null) { - Log.e(TAG, "Got null bitmap from screenshot message"); - mNotificationsController.notifyScreenshotError( - R.string.screenshot_failed_to_capture_text); - callback.reportError(); - } else { - mScreenshot.handleImageAsScreenshot(screenshot, screenBounds, insets, - taskId, userId, topComponent, uriConsumer, callback); - } + mScreenshot.handleImageAsScreenshot(screenshot, screenBounds, insets, + taskId, userId, topComponent, uriConsumer, callback); break; default: - Log.w(TAG, "Invalid screenshot option: " + request.getType()); + Log.wtf(TAG, "Invalid screenshot option: " + request.getType()); } } + private void logFailedRequest(ScreenshotRequest request) { + ComponentName topComponent = request.getTopComponent(); + String packageName = topComponent == null ? "" : topComponent.getPackageName(); + mUiEventLogger.log( + ScreenshotEvent.getScreenshotSource(request.getSource()), 0, packageName); + mUiEventLogger.log(SCREENSHOT_CAPTURE_FAILED, 0, packageName); + } + private static void sendComplete(Messenger target) { try { if (DEBUG_CALLBACK) { diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/RequestProcessorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/screenshot/RequestProcessorTest.kt index 541d6c25192f..2e73c0b5d0e3 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/RequestProcessorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/RequestProcessorTest.kt @@ -23,7 +23,7 @@ import android.graphics.Insets import android.graphics.Rect import android.hardware.HardwareBuffer import android.os.UserHandle -import android.view.WindowManager.ScreenshotSource.SCREENSHOT_KEY_CHORD +import android.view.WindowManager.ScreenshotSource.SCREENSHOT_KEY_OTHER import android.view.WindowManager.ScreenshotSource.SCREENSHOT_OTHER import android.view.WindowManager.TAKE_SCREENSHOT_FULLSCREEN import android.view.WindowManager.TAKE_SCREENSHOT_PROVIDED_IMAGE @@ -35,6 +35,7 @@ import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.runBlocking +import org.junit.Assert import org.junit.Test private const val USER_ID = 1 @@ -55,7 +56,7 @@ class RequestProcessorTest { flags.set(Flags.SCREENSHOT_WORK_PROFILE_POLICY, false) val request = - ScreenshotRequest.Builder(TAKE_SCREENSHOT_FULLSCREEN, SCREENSHOT_KEY_CHORD).build() + ScreenshotRequest.Builder(TAKE_SCREENSHOT_FULLSCREEN, SCREENSHOT_KEY_OTHER).build() val processor = RequestProcessor(imageCapture, policy, flags, scope) var result: ScreenshotRequest? = null @@ -78,8 +79,10 @@ class RequestProcessorTest { fun testProcessAsync_ScreenshotData() { flags.set(Flags.SCREENSHOT_WORK_PROFILE_POLICY, false) - val request = ScreenshotData.fromRequest( - ScreenshotRequest.Builder(TAKE_SCREENSHOT_FULLSCREEN, SCREENSHOT_KEY_CHORD).build()) + val request = + ScreenshotData.fromRequest( + ScreenshotRequest.Builder(TAKE_SCREENSHOT_FULLSCREEN, SCREENSHOT_KEY_OTHER).build() + ) val processor = RequestProcessor(imageCapture, policy, flags, scope) var result: ScreenshotData? = null @@ -102,7 +105,7 @@ class RequestProcessorTest { flags.set(Flags.SCREENSHOT_WORK_PROFILE_POLICY, false) val request = - ScreenshotRequest.Builder(TAKE_SCREENSHOT_FULLSCREEN, SCREENSHOT_KEY_CHORD).build() + ScreenshotRequest.Builder(TAKE_SCREENSHOT_FULLSCREEN, SCREENSHOT_KEY_OTHER).build() val processor = RequestProcessor(imageCapture, policy, flags, scope) val processedRequest = processor.process(request) @@ -162,7 +165,7 @@ class RequestProcessorTest { ) val request = - ScreenshotRequest.Builder(TAKE_SCREENSHOT_FULLSCREEN, SCREENSHOT_KEY_CHORD).build() + ScreenshotRequest.Builder(TAKE_SCREENSHOT_FULLSCREEN, SCREENSHOT_KEY_OTHER).build() val processor = RequestProcessor(imageCapture, policy, flags, scope) val processedRequest = processor.process(request) @@ -191,6 +194,32 @@ class RequestProcessorTest { } @Test + fun testFullScreenshot_managedProfile_nullBitmap() { + flags.set(Flags.SCREENSHOT_WORK_PROFILE_POLICY, true) + + // Provide a null task bitmap when asked + imageCapture.image = null + + // Indicate that the primary content belongs to a manged profile + policy.setManagedProfile(USER_ID, true) + policy.setDisplayContentInfo( + policy.getDefaultDisplayId(), + DisplayContentInfo(component, bounds, UserHandle.of(USER_ID), TASK_ID) + ) + + val request = + 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)) } + } + } + + @Test fun testProvidedImageScreenshot_workProfilePolicyDisabled() = runBlocking { flags.set(Flags.SCREENSHOT_WORK_PROFILE_POLICY, false) diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/TakeScreenshotServiceTest.kt b/packages/SystemUI/tests/src/com/android/systemui/screenshot/TakeScreenshotServiceTest.kt index 74969d0e4737..1fa2ace955b0 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/TakeScreenshotServiceTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/TakeScreenshotServiceTest.kt @@ -38,8 +38,9 @@ import com.android.internal.logging.testing.UiEventLoggerFake import com.android.internal.util.ScreenshotRequest import com.android.systemui.SysuiTestCase import com.android.systemui.flags.FakeFeatureFlags -import com.android.systemui.flags.Flags.SCREENSHOT_WORK_PROFILE_POLICY import com.android.systemui.flags.Flags.SCREENSHOT_METADATA +import com.android.systemui.flags.Flags.SCREENSHOT_WORK_PROFILE_POLICY +import com.android.systemui.screenshot.ScreenshotEvent.SCREENSHOT_CAPTURE_FAILED import com.android.systemui.screenshot.ScreenshotEvent.SCREENSHOT_REQUESTED_KEY_OTHER import com.android.systemui.screenshot.ScreenshotEvent.SCREENSHOT_REQUESTED_OVERVIEW import com.android.systemui.screenshot.TakeScreenshotService.RequestCallback @@ -47,6 +48,7 @@ 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.mock +import com.android.systemui.util.mockito.whenever import java.util.function.Consumer import org.junit.Assert.assertEquals import org.junit.Before @@ -55,10 +57,10 @@ import org.junit.runner.RunWith import org.mockito.ArgumentMatchers.anyInt import org.mockito.ArgumentMatchers.isNull import org.mockito.Mockito.doAnswer +import org.mockito.Mockito.doThrow import org.mockito.Mockito.times import org.mockito.Mockito.verify import org.mockito.Mockito.verifyZeroInteractions -import org.mockito.Mockito.`when` as whenever private const val USER_ID = 1 private const val TASK_ID = 11 @@ -107,18 +109,20 @@ class TakeScreenshotServiceTest : SysuiTestCase() { // 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) - }.`when`(requestProcessor).processAsync( - /* request= */ any(ScreenshotRequest::class.java), /* callback= */ any()) + 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) - consumer.accept(request) - }.`when`(requestProcessor).processAsync( - /* screenshot= */ any(ScreenshotData::class.java), /* callback= */ any()) + val request: ScreenshotData = it.getArgument(0) as ScreenshotData + val consumer: Consumer<ScreenshotData> = it.getArgument(1) + consumer.accept(request) + } + .whenever(requestProcessor) + .processAsync(/* screenshot= */ any(ScreenshotData::class.java), /* callback= */ any()) // Flipped in selected test cases flags.set(SCREENSHOT_WORK_PROFILE_POLICY, false) @@ -162,37 +166,52 @@ class TakeScreenshotServiceTest : SysuiTestCase() { /* requestCallback = */ any() ) - assertEquals("Expected one UiEvent", eventLogger.numLogs(), 1) + assertEquals("Expected one UiEvent", 1, eventLogger.numLogs()) val logEvent = eventLogger.get(0) - assertEquals("Expected SCREENSHOT_REQUESTED UiEvent", - logEvent.eventId, SCREENSHOT_REQUESTED_KEY_OTHER.id) - assertEquals("Expected supplied package name", - topComponent.packageName, eventLogger.get(0).packageName) + assertEquals( + "Expected SCREENSHOT_REQUESTED UiEvent", + logEvent.eventId, + SCREENSHOT_REQUESTED_KEY_OTHER.id + ) + assertEquals( + "Expected supplied package name", + topComponent.packageName, + eventLogger.get(0).packageName + ) } @Test fun takeScreenshotFullscreen_screenshotDataEnabled() { flags.set(SCREENSHOT_METADATA, true) - val request = ScreenshotRequest.Builder( - TAKE_SCREENSHOT_FULLSCREEN, - SCREENSHOT_KEY_OTHER).setTopComponent(topComponent).build() + val request = + ScreenshotRequest.Builder(TAKE_SCREENSHOT_FULLSCREEN, SCREENSHOT_KEY_OTHER) + .setTopComponent(topComponent) + .build() - service.handleRequest(request, { /* onSaved */ }, callback) + service.handleRequest(request, { /* onSaved */}, callback) - verify(controller, times(1)).handleScreenshot( - eq(ScreenshotData.fromRequest(request)), - /* onSavedListener = */ any(), - /* requestCallback = */ any()) + verify(controller, times(1)) + .handleScreenshot( + eq(ScreenshotData.fromRequest(request)), + /* onSavedListener = */ any(), + /* requestCallback = */ any() + ) assertEquals("Expected one UiEvent", eventLogger.numLogs(), 1) val logEvent = eventLogger.get(0) - assertEquals("Expected SCREENSHOT_REQUESTED UiEvent", - logEvent.eventId, SCREENSHOT_REQUESTED_KEY_OTHER.id) - assertEquals("Expected supplied package name", - topComponent.packageName, eventLogger.get(0).packageName) + assertEquals( + "Expected SCREENSHOT_REQUESTED UiEvent", + logEvent.eventId, + SCREENSHOT_REQUESTED_KEY_OTHER.id + ) + assertEquals( + "Expected supplied package name", + topComponent.packageName, + eventLogger.get(0).packageName + ) } @Test @@ -224,7 +243,7 @@ class TakeScreenshotServiceTest : SysuiTestCase() { /* requestCallback = */ any() ) - assertEquals("Expected one UiEvent", eventLogger.numLogs(), 1) + assertEquals("Expected one UiEvent", 1, eventLogger.numLogs()) val logEvent = eventLogger.get(0) assertEquals( @@ -241,6 +260,8 @@ class TakeScreenshotServiceTest : SysuiTestCase() { @Test fun takeScreenshotFullscreen_userLocked() { + flags.set(SCREENSHOT_METADATA, true) + whenever(userManager.isUserUnlocked).thenReturn(false) val request = @@ -253,10 +274,36 @@ class TakeScreenshotServiceTest : SysuiTestCase() { verify(notificationsController, times(1)).notifyScreenshotError(anyInt()) verify(callback, times(1)).reportError() verifyZeroInteractions(controller) + + assertEquals("Expected two UiEvents", 2, eventLogger.numLogs()) + val requestEvent = eventLogger.get(0) + assertEquals( + "Expected SCREENSHOT_REQUESTED_* UiEvent", + SCREENSHOT_REQUESTED_KEY_OTHER.id, + requestEvent.eventId + ) + assertEquals( + "Expected supplied package name", + topComponent.packageName, + requestEvent.packageName + ) + val failureEvent = eventLogger.get(1) + assertEquals( + "Expected SCREENSHOT_CAPTURE_FAILED UiEvent", + SCREENSHOT_CAPTURE_FAILED.id, + failureEvent.eventId + ) + assertEquals( + "Expected supplied package name", + topComponent.packageName, + failureEvent.packageName + ) } @Test fun takeScreenshotFullscreen_screenCaptureDisabled_allUsers() { + flags.set(SCREENSHOT_METADATA, true) + whenever(devicePolicyManager.getScreenCaptureDisabled(isNull(), eq(UserHandle.USER_ALL))) .thenReturn(true) @@ -279,6 +326,206 @@ class TakeScreenshotServiceTest : SysuiTestCase() { // error shown: Toast.makeText(...).show(), untestable verify(callback, times(1)).reportError() verifyZeroInteractions(controller) + assertEquals("Expected two UiEvents", 2, eventLogger.numLogs()) + val requestEvent = eventLogger.get(0) + assertEquals( + "Expected SCREENSHOT_REQUESTED_* UiEvent", + SCREENSHOT_REQUESTED_KEY_OTHER.id, + requestEvent.eventId + ) + assertEquals( + "Expected supplied package name", + topComponent.packageName, + requestEvent.packageName + ) + val failureEvent = eventLogger.get(1) + assertEquals( + "Expected SCREENSHOT_CAPTURE_FAILED UiEvent", + SCREENSHOT_CAPTURE_FAILED.id, + failureEvent.eventId + ) + assertEquals( + "Expected supplied package name", + topComponent.packageName, + failureEvent.packageName + ) + } + + @Test + fun takeScreenshotFullscreen_userLocked_metadataDisabled() { + flags.set(SCREENSHOT_METADATA, false) + whenever(userManager.isUserUnlocked).thenReturn(false) + + val request = + ScreenshotRequest.Builder(TAKE_SCREENSHOT_FULLSCREEN, SCREENSHOT_KEY_OTHER) + .setTopComponent(topComponent) + .build() + + service.handleRequest(request, { /* onSaved */}, callback) + + verify(notificationsController, times(1)).notifyScreenshotError(anyInt()) + verify(callback, times(1)).reportError() + verifyZeroInteractions(controller) + + assertEquals("Expected two UiEvents", 2, eventLogger.numLogs()) + val requestEvent = eventLogger.get(0) + assertEquals( + "Expected SCREENSHOT_REQUESTED_* UiEvent", + SCREENSHOT_REQUESTED_KEY_OTHER.id, + requestEvent.eventId + ) + assertEquals( + "Expected supplied package name", + topComponent.packageName, + requestEvent.packageName + ) + val failureEvent = eventLogger.get(1) + assertEquals( + "Expected SCREENSHOT_CAPTURE_FAILED UiEvent", + SCREENSHOT_CAPTURE_FAILED.id, + failureEvent.eventId + ) + assertEquals( + "Expected supplied package name", + topComponent.packageName, + failureEvent.packageName + ) + } + + @Test + fun takeScreenshotFullscreen_screenCaptureDisabled_allUsers_metadataDisabled() { + flags.set(SCREENSHOT_METADATA, false) + + whenever(devicePolicyManager.getScreenCaptureDisabled(isNull(), eq(UserHandle.USER_ALL))) + .thenReturn(true) + + whenever( + devicePolicyResourcesManager.getString( + eq(SCREENSHOT_BLOCKED_BY_ADMIN), + /* Supplier<String> */ + any(), + ) + ) + .thenReturn("SCREENSHOT_BLOCKED_BY_ADMIN") + + val request = + ScreenshotRequest.Builder(TAKE_SCREENSHOT_FULLSCREEN, SCREENSHOT_KEY_OTHER) + .setTopComponent(topComponent) + .build() + + service.handleRequest(request, { /* onSaved */}, callback) + + // error shown: Toast.makeText(...).show(), untestable + verify(callback, times(1)).reportError() + verifyZeroInteractions(controller) + assertEquals("Expected two UiEvents", 2, eventLogger.numLogs()) + val requestEvent = eventLogger.get(0) + assertEquals( + "Expected SCREENSHOT_REQUESTED_* UiEvent", + SCREENSHOT_REQUESTED_KEY_OTHER.id, + requestEvent.eventId + ) + assertEquals( + "Expected supplied package name", + topComponent.packageName, + requestEvent.packageName + ) + val failureEvent = eventLogger.get(1) + assertEquals( + "Expected SCREENSHOT_CAPTURE_FAILED UiEvent", + SCREENSHOT_CAPTURE_FAILED.id, + failureEvent.eventId + ) + assertEquals( + "Expected supplied package name", + topComponent.packageName, + failureEvent.packageName + ) + } + + @Test + fun takeScreenshot_workProfile_nullBitmap_metadataDisabled() { + flags.set(SCREENSHOT_METADATA, false) + + val request = + ScreenshotRequest.Builder(TAKE_SCREENSHOT_FULLSCREEN, SCREENSHOT_KEY_OTHER) + .setTopComponent(topComponent) + .build() + + doThrow(IllegalStateException::class.java) + .whenever(requestProcessor) + .processAsync(any(ScreenshotRequest::class.java), any()) + + service.handleRequest(request, { /* onSaved */}, callback) + + verify(callback, times(1)).reportError() + verify(notificationsController, times(1)).notifyScreenshotError(anyInt()) + verifyZeroInteractions(controller) + assertEquals("Expected two UiEvents", 2, eventLogger.numLogs()) + val requestEvent = eventLogger.get(0) + assertEquals( + "Expected SCREENSHOT_REQUESTED_* UiEvent", + SCREENSHOT_REQUESTED_KEY_OTHER.id, + requestEvent.eventId + ) + assertEquals( + "Expected supplied package name", + topComponent.packageName, + requestEvent.packageName + ) + val failureEvent = eventLogger.get(1) + assertEquals( + "Expected SCREENSHOT_CAPTURE_FAILED UiEvent", + SCREENSHOT_CAPTURE_FAILED.id, + failureEvent.eventId + ) + assertEquals( + "Expected supplied package name", + topComponent.packageName, + failureEvent.packageName + ) + } + @Test + fun takeScreenshot_workProfile_nullBitmap() { + flags.set(SCREENSHOT_METADATA, true) + + val request = + ScreenshotRequest.Builder(TAKE_SCREENSHOT_FULLSCREEN, SCREENSHOT_KEY_OTHER) + .setTopComponent(topComponent) + .build() + + doThrow(IllegalStateException::class.java) + .whenever(requestProcessor) + .processAsync(any(ScreenshotData::class.java), any()) + + service.handleRequest(request, { /* onSaved */}, callback) + + verify(callback, times(1)).reportError() + verify(notificationsController, times(1)).notifyScreenshotError(anyInt()) + verifyZeroInteractions(controller) + assertEquals("Expected two UiEvents", 2, eventLogger.numLogs()) + val requestEvent = eventLogger.get(0) + assertEquals( + "Expected SCREENSHOT_REQUESTED_* UiEvent", + SCREENSHOT_REQUESTED_KEY_OTHER.id, + requestEvent.eventId + ) + assertEquals( + "Expected supplied package name", + topComponent.packageName, + requestEvent.packageName + ) + val failureEvent = eventLogger.get(1) + assertEquals( + "Expected SCREENSHOT_CAPTURE_FAILED UiEvent", + SCREENSHOT_CAPTURE_FAILED.id, + failureEvent.eventId + ) + assertEquals( + "Expected supplied package name", + topComponent.packageName, + failureEvent.packageName + ) } } |