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

Commit 4873f6ef authored by Miranda Kephart's avatar Miranda Kephart Committed by Android (Google) Code Review
Browse files

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

parents 9e4022e4 91519b7b
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -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;
        }
+6 −0
Original line number Diff line number Diff line
@@ -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);
+2 −0
Original line number Diff line number Diff line
@@ -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")
+37 −28
Original line number Diff line number Diff line
@@ -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);
            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 {
            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);
                }
                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) {
+35 −6
Original line number Diff line number Diff line
@@ -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)
@@ -190,6 +193,32 @@ class RequestProcessorTest {
        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
    fun testProvidedImageScreenshot_workProfilePolicyDisabled() = runBlocking {
        flags.set(Flags.SCREENSHOT_WORK_PROFILE_POLICY, false)
Loading