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

Commit 42319cb7 authored by Miranda Kephart's avatar Miranda Kephart Committed by Automerger Merge Worker
Browse files

Merge "Add log on screenshot capture failed" into tm-qpr-dev am: 4873f6ef am: 216ac319

parents 902081f6 216ac319
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