Merge "Add log on screenshot capture failed" into tm-qpr-dev

This commit is contained in:
Miranda Kephart
2023-01-31 22:00:38 +00:00
committed by Android (Google) Code Review
6 changed files with 360 additions and 64 deletions

View File

@@ -173,6 +173,9 @@ public class ScreenshotRequest implements Parcelable {
public Builder( public Builder(
@WindowManager.ScreenshotType int type, @WindowManager.ScreenshotType int type,
@WindowManager.ScreenshotSource int source) { @WindowManager.ScreenshotSource int source) {
if (type != TAKE_SCREENSHOT_FULLSCREEN && type != TAKE_SCREENSHOT_PROVIDED_IMAGE) {
throw new IllegalArgumentException("Invalid screenshot type requested!");
}
mType = type; mType = type;
mSource = source; mSource = source;
} }

View File

@@ -131,6 +131,12 @@ public final class ScreenshotRequestTest {
assertEquals(Insets.NONE, out.getInsets()); 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) { private Bitmap makeHardwareBitmap(int width, int height) {
HardwareBuffer buffer = HardwareBuffer.create( HardwareBuffer buffer = HardwareBuffer.create(
width, height, HardwareBuffer.RGBA_8888, 1, HardwareBuffer.USAGE_GPU_SAMPLED_IMAGE); width, height, HardwareBuffer.RGBA_8888, 1, HardwareBuffer.USAGE_GPU_SAMPLED_IMAGE);

View File

@@ -46,6 +46,8 @@ public enum ScreenshotEvent implements UiEventLogger.UiEventEnum {
SCREENSHOT_SAVED(306), SCREENSHOT_SAVED(306),
@UiEvent(doc = "screenshot failed to save") @UiEvent(doc = "screenshot failed to save")
SCREENSHOT_NOT_SAVED(336), SCREENSHOT_NOT_SAVED(336),
@UiEvent(doc = "failed to capture screenshot")
SCREENSHOT_CAPTURE_FAILED(1281),
@UiEvent(doc = "screenshot preview tapped") @UiEvent(doc = "screenshot preview tapped")
SCREENSHOT_PREVIEW_TAPPED(307), SCREENSHOT_PREVIEW_TAPPED(307),
@UiEvent(doc = "screenshot edit button tapped") @UiEvent(doc = "screenshot edit button tapped")

View File

@@ -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_DISMISS;
import static com.android.systemui.screenshot.LogConfig.DEBUG_SERVICE; import static com.android.systemui.screenshot.LogConfig.DEBUG_SERVICE;
import static com.android.systemui.screenshot.LogConfig.logTag; 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 static com.android.systemui.screenshot.ScreenshotEvent.SCREENSHOT_DISMISSED_OTHER;
import android.annotation.MainThread; import android.annotation.MainThread;
@@ -202,6 +203,7 @@ public class TakeScreenshotService extends Service {
// animation and error notification. // animation and error notification.
if (!mUserManager.isUserUnlocked()) { if (!mUserManager.isUserUnlocked()) {
Log.w(TAG, "Skipping screenshot because storage is locked!"); Log.w(TAG, "Skipping screenshot because storage is locked!");
logFailedRequest(request);
mNotificationsController.notifyScreenshotError( mNotificationsController.notifyScreenshotError(
R.string.screenshot_failed_to_save_user_locked_text); R.string.screenshot_failed_to_save_user_locked_text);
callback.reportError(); callback.reportError();
@@ -212,6 +214,7 @@ public class TakeScreenshotService extends Service {
mBgExecutor.execute(() -> { mBgExecutor.execute(() -> {
Log.w(TAG, "Skipping screenshot because an IT admin has disabled " Log.w(TAG, "Skipping screenshot because an IT admin has disabled "
+ "screenshots on the device"); + "screenshots on the device");
logFailedRequest(request);
String blockedByAdminText = mDevicePolicyManager.getResources().getString( String blockedByAdminText = mDevicePolicyManager.getResources().getString(
SCREENSHOT_BLOCKED_BY_ADMIN, SCREENSHOT_BLOCKED_BY_ADMIN,
() -> mContext.getString(R.string.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)) { if (mFeatureFlags.isEnabled(Flags.SCREENSHOT_METADATA)) {
Log.d(TAG, "Processing screenshot data"); Log.d(TAG, "Processing screenshot data");
ScreenshotData screenshotData = ScreenshotData.fromRequest(request); ScreenshotData screenshotData = ScreenshotData.fromRequest(request);
try {
mProcessor.processAsync(screenshotData, mProcessor.processAsync(screenshotData,
(data) -> dispatchToController(data, onSaved, callback)); (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 { } else {
try {
mProcessor.processAsync(request, mProcessor.processAsync(request,
(r) -> dispatchToController(r, onSaved, callback)); (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, private void dispatchToController(ScreenshotData screenshot,
Consumer<Uri> uriConsumer, RequestCallback callback) { Consumer<Uri> uriConsumer, RequestCallback callback) {
mUiEventLogger.log(ScreenshotEvent.getScreenshotSource(screenshot.getSource()), 0, mUiEventLogger.log(ScreenshotEvent.getScreenshotSource(screenshot.getSource()), 0,
screenshot.getPackageNameString()); 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); mScreenshot.handleScreenshot(screenshot, uriConsumer, callback);
} }
private void dispatchToController(ScreenshotRequest request, private void dispatchToController(ScreenshotRequest request,
Consumer<Uri> uriConsumer, RequestCallback callback) { Consumer<Uri> uriConsumer, RequestCallback callback) {
ComponentName topComponent = request.getTopComponent(); ComponentName topComponent = request.getTopComponent();
mUiEventLogger.log(ScreenshotEvent.getScreenshotSource(request.getSource()), 0, String packageName = topComponent == null ? "" : topComponent.getPackageName();
topComponent == null ? "" : topComponent.getPackageName()); mUiEventLogger.log(
ScreenshotEvent.getScreenshotSource(request.getSource()), 0, packageName);
switch (request.getType()) { switch (request.getType()) {
case WindowManager.TAKE_SCREENSHOT_FULLSCREEN: case WindowManager.TAKE_SCREENSHOT_FULLSCREEN:
@@ -275,21 +283,22 @@ public class TakeScreenshotService extends Service {
int taskId = request.getTaskId(); int taskId = request.getTaskId();
int userId = request.getUserId(); 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, mScreenshot.handleImageAsScreenshot(screenshot, screenBounds, insets,
taskId, userId, topComponent, uriConsumer, callback); taskId, userId, topComponent, uriConsumer, callback);
}
break; break;
default: 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) { private static void sendComplete(Messenger target) {
try { try {
if (DEBUG_CALLBACK) { if (DEBUG_CALLBACK) {

View File

@@ -23,7 +23,7 @@ import android.graphics.Insets
import android.graphics.Rect import android.graphics.Rect
import android.hardware.HardwareBuffer import android.hardware.HardwareBuffer
import android.os.UserHandle 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.ScreenshotSource.SCREENSHOT_OTHER
import android.view.WindowManager.TAKE_SCREENSHOT_FULLSCREEN import android.view.WindowManager.TAKE_SCREENSHOT_FULLSCREEN
import android.view.WindowManager.TAKE_SCREENSHOT_PROVIDED_IMAGE 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.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
import org.junit.Assert
import org.junit.Test import org.junit.Test
private const val USER_ID = 1 private const val USER_ID = 1
@@ -55,7 +56,7 @@ class RequestProcessorTest {
flags.set(Flags.SCREENSHOT_WORK_PROFILE_POLICY, false) flags.set(Flags.SCREENSHOT_WORK_PROFILE_POLICY, false)
val request = 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 processor = RequestProcessor(imageCapture, policy, flags, scope)
var result: ScreenshotRequest? = null var result: ScreenshotRequest? = null
@@ -78,8 +79,10 @@ class RequestProcessorTest {
fun testProcessAsync_ScreenshotData() { fun testProcessAsync_ScreenshotData() {
flags.set(Flags.SCREENSHOT_WORK_PROFILE_POLICY, false) flags.set(Flags.SCREENSHOT_WORK_PROFILE_POLICY, false)
val request = ScreenshotData.fromRequest( val request =
ScreenshotRequest.Builder(TAKE_SCREENSHOT_FULLSCREEN, SCREENSHOT_KEY_CHORD).build()) ScreenshotData.fromRequest(
ScreenshotRequest.Builder(TAKE_SCREENSHOT_FULLSCREEN, SCREENSHOT_KEY_OTHER).build()
)
val processor = RequestProcessor(imageCapture, policy, flags, scope) val processor = RequestProcessor(imageCapture, policy, flags, scope)
var result: ScreenshotData? = null var result: ScreenshotData? = null
@@ -102,7 +105,7 @@ class RequestProcessorTest {
flags.set(Flags.SCREENSHOT_WORK_PROFILE_POLICY, false) flags.set(Flags.SCREENSHOT_WORK_PROFILE_POLICY, false)
val request = 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 processor = RequestProcessor(imageCapture, policy, flags, scope)
val processedRequest = processor.process(request) val processedRequest = processor.process(request)
@@ -162,7 +165,7 @@ class RequestProcessorTest {
) )
val request = 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 processor = RequestProcessor(imageCapture, policy, flags, scope)
val processedRequest = processor.process(request) val processedRequest = processor.process(request)
@@ -190,6 +193,32 @@ class RequestProcessorTest {
assertThat(processedRequest.topComponent).isEqualTo(component) assertThat(processedRequest.topComponent).isEqualTo(component)
} }
@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 @Test
fun testProvidedImageScreenshot_workProfilePolicyDisabled() = runBlocking { fun testProvidedImageScreenshot_workProfilePolicyDisabled() = runBlocking {
flags.set(Flags.SCREENSHOT_WORK_PROFILE_POLICY, false) flags.set(Flags.SCREENSHOT_WORK_PROFILE_POLICY, false)

View File

@@ -38,8 +38,9 @@ import com.android.internal.logging.testing.UiEventLoggerFake
import com.android.internal.util.ScreenshotRequest import com.android.internal.util.ScreenshotRequest
import com.android.systemui.SysuiTestCase import com.android.systemui.SysuiTestCase
import com.android.systemui.flags.FakeFeatureFlags 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_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_KEY_OTHER
import com.android.systemui.screenshot.ScreenshotEvent.SCREENSHOT_REQUESTED_OVERVIEW import com.android.systemui.screenshot.ScreenshotEvent.SCREENSHOT_REQUESTED_OVERVIEW
import com.android.systemui.screenshot.TakeScreenshotService.RequestCallback 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.argThat
import com.android.systemui.util.mockito.eq import com.android.systemui.util.mockito.eq
import com.android.systemui.util.mockito.mock import com.android.systemui.util.mockito.mock
import com.android.systemui.util.mockito.whenever
import java.util.function.Consumer import java.util.function.Consumer
import org.junit.Assert.assertEquals import org.junit.Assert.assertEquals
import org.junit.Before import org.junit.Before
@@ -55,10 +57,10 @@ import org.junit.runner.RunWith
import org.mockito.ArgumentMatchers.anyInt import org.mockito.ArgumentMatchers.anyInt
import org.mockito.ArgumentMatchers.isNull import org.mockito.ArgumentMatchers.isNull
import org.mockito.Mockito.doAnswer import org.mockito.Mockito.doAnswer
import org.mockito.Mockito.doThrow
import org.mockito.Mockito.times import org.mockito.Mockito.times
import org.mockito.Mockito.verify import org.mockito.Mockito.verify
import org.mockito.Mockito.verifyZeroInteractions import org.mockito.Mockito.verifyZeroInteractions
import org.mockito.Mockito.`when` as whenever
private const val USER_ID = 1 private const val USER_ID = 1
private const val TASK_ID = 11 private const val TASK_ID = 11
@@ -110,15 +112,17 @@ class TakeScreenshotServiceTest : SysuiTestCase() {
val request: ScreenshotRequest = it.getArgument(0) as ScreenshotRequest val request: ScreenshotRequest = it.getArgument(0) as ScreenshotRequest
val consumer: Consumer<ScreenshotRequest> = it.getArgument(1) val consumer: Consumer<ScreenshotRequest> = it.getArgument(1)
consumer.accept(request) consumer.accept(request)
}.`when`(requestProcessor).processAsync( }
/* request= */ any(ScreenshotRequest::class.java), /* callback= */ any()) .whenever(requestProcessor)
.processAsync(/* request= */ any(ScreenshotRequest::class.java), /* callback= */ any())
doAnswer { doAnswer {
val request: ScreenshotData = it.getArgument(0) as ScreenshotData val request: ScreenshotData = it.getArgument(0) as ScreenshotData
val consumer: Consumer<ScreenshotData> = it.getArgument(1) val consumer: Consumer<ScreenshotData> = it.getArgument(1)
consumer.accept(request) consumer.accept(request)
}.`when`(requestProcessor).processAsync( }
/* screenshot= */ any(ScreenshotData::class.java), /* callback= */ any()) .whenever(requestProcessor)
.processAsync(/* screenshot= */ any(ScreenshotData::class.java), /* callback= */ any())
// Flipped in selected test cases // Flipped in selected test cases
flags.set(SCREENSHOT_WORK_PROFILE_POLICY, false) flags.set(SCREENSHOT_WORK_PROFILE_POLICY, false)
@@ -162,37 +166,52 @@ class TakeScreenshotServiceTest : SysuiTestCase() {
/* requestCallback = */ any() /* requestCallback = */ any()
) )
assertEquals("Expected one UiEvent", eventLogger.numLogs(), 1) assertEquals("Expected one UiEvent", 1, eventLogger.numLogs())
val logEvent = eventLogger.get(0) val logEvent = eventLogger.get(0)
assertEquals("Expected SCREENSHOT_REQUESTED UiEvent", assertEquals(
logEvent.eventId, SCREENSHOT_REQUESTED_KEY_OTHER.id) "Expected SCREENSHOT_REQUESTED UiEvent",
assertEquals("Expected supplied package name", logEvent.eventId,
topComponent.packageName, eventLogger.get(0).packageName) SCREENSHOT_REQUESTED_KEY_OTHER.id
)
assertEquals(
"Expected supplied package name",
topComponent.packageName,
eventLogger.get(0).packageName
)
} }
@Test @Test
fun takeScreenshotFullscreen_screenshotDataEnabled() { fun takeScreenshotFullscreen_screenshotDataEnabled() {
flags.set(SCREENSHOT_METADATA, true) flags.set(SCREENSHOT_METADATA, true)
val request = ScreenshotRequest.Builder( val request =
TAKE_SCREENSHOT_FULLSCREEN, ScreenshotRequest.Builder(TAKE_SCREENSHOT_FULLSCREEN, SCREENSHOT_KEY_OTHER)
SCREENSHOT_KEY_OTHER).setTopComponent(topComponent).build() .setTopComponent(topComponent)
.build()
service.handleRequest(request, { /* onSaved */}, callback) service.handleRequest(request, { /* onSaved */}, callback)
verify(controller, times(1)).handleScreenshot( verify(controller, times(1))
.handleScreenshot(
eq(ScreenshotData.fromRequest(request)), eq(ScreenshotData.fromRequest(request)),
/* onSavedListener = */ any(), /* onSavedListener = */ any(),
/* requestCallback = */ any()) /* requestCallback = */ any()
)
assertEquals("Expected one UiEvent", eventLogger.numLogs(), 1) assertEquals("Expected one UiEvent", eventLogger.numLogs(), 1)
val logEvent = eventLogger.get(0) val logEvent = eventLogger.get(0)
assertEquals("Expected SCREENSHOT_REQUESTED UiEvent", assertEquals(
logEvent.eventId, SCREENSHOT_REQUESTED_KEY_OTHER.id) "Expected SCREENSHOT_REQUESTED UiEvent",
assertEquals("Expected supplied package name", logEvent.eventId,
topComponent.packageName, eventLogger.get(0).packageName) SCREENSHOT_REQUESTED_KEY_OTHER.id
)
assertEquals(
"Expected supplied package name",
topComponent.packageName,
eventLogger.get(0).packageName
)
} }
@Test @Test
@@ -224,7 +243,7 @@ class TakeScreenshotServiceTest : SysuiTestCase() {
/* requestCallback = */ any() /* requestCallback = */ any()
) )
assertEquals("Expected one UiEvent", eventLogger.numLogs(), 1) assertEquals("Expected one UiEvent", 1, eventLogger.numLogs())
val logEvent = eventLogger.get(0) val logEvent = eventLogger.get(0)
assertEquals( assertEquals(
@@ -241,6 +260,8 @@ class TakeScreenshotServiceTest : SysuiTestCase() {
@Test @Test
fun takeScreenshotFullscreen_userLocked() { fun takeScreenshotFullscreen_userLocked() {
flags.set(SCREENSHOT_METADATA, true)
whenever(userManager.isUserUnlocked).thenReturn(false) whenever(userManager.isUserUnlocked).thenReturn(false)
val request = val request =
@@ -253,10 +274,36 @@ class TakeScreenshotServiceTest : SysuiTestCase() {
verify(notificationsController, times(1)).notifyScreenshotError(anyInt()) verify(notificationsController, times(1)).notifyScreenshotError(anyInt())
verify(callback, times(1)).reportError() verify(callback, times(1)).reportError()
verifyZeroInteractions(controller) 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 @Test
fun takeScreenshotFullscreen_screenCaptureDisabled_allUsers() { fun takeScreenshotFullscreen_screenCaptureDisabled_allUsers() {
flags.set(SCREENSHOT_METADATA, true)
whenever(devicePolicyManager.getScreenCaptureDisabled(isNull(), eq(UserHandle.USER_ALL))) whenever(devicePolicyManager.getScreenCaptureDisabled(isNull(), eq(UserHandle.USER_ALL)))
.thenReturn(true) .thenReturn(true)
@@ -279,6 +326,206 @@ class TakeScreenshotServiceTest : SysuiTestCase() {
// error shown: Toast.makeText(...).show(), untestable // error shown: Toast.makeText(...).show(), untestable
verify(callback, times(1)).reportError() verify(callback, times(1)).reportError()
verifyZeroInteractions(controller) 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
)
} }
} }