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

Commit 58de12bc authored by Android Build Coastguard Worker's avatar Android Build Coastguard Worker
Browse files

Snap for 10322046 from f312e919 to udc-qpr1-release

Change-Id: I32c006a0c979cfc4889b2bd0df253222e4254892
parents 21663395 f312e919
Loading
Loading
Loading
Loading
+6 −6
Original line number Diff line number Diff line
@@ -39,7 +39,6 @@ import android.os.ServiceManager;
import android.os.UserHandle;
import android.permission.IPermissionManager;
import android.util.Log;
import android.util.Pair;
import android.view.IWindowManager;
import android.view.InputDevice;
import android.view.InputEvent;
@@ -52,7 +51,8 @@ import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.IAccessibilityManager;
import android.window.ScreenCapture;
import android.window.ScreenCapture.CaptureArgs;
import android.window.ScreenCapture.ScreenCaptureListener;
import android.window.ScreenCapture.ScreenshotHardwareBuffer;
import android.window.ScreenCapture.SynchronousScreenCaptureListener;

import libcore.io.IoUtils;

@@ -235,12 +235,12 @@ public final class UiAutomationConnection extends IUiAutomationConnection.Stub {
            final CaptureArgs captureArgs = new CaptureArgs.Builder<>()
                    .setSourceCrop(crop)
                    .build();
            Pair<ScreenCaptureListener, ScreenCapture.ScreenshotSync> syncScreenCapture =
            SynchronousScreenCaptureListener syncScreenCapture =
                    ScreenCapture.createSyncCaptureListener();
            mWindowManager.captureDisplay(DEFAULT_DISPLAY, captureArgs,
                    syncScreenCapture.first);
            final ScreenCapture.ScreenshotHardwareBuffer screenshotBuffer =
                    syncScreenCapture.second.get();
                    syncScreenCapture);
            final ScreenshotHardwareBuffer screenshotBuffer =
                    syncScreenCapture.getBuffer();
            return screenshotBuffer == null ? null : screenshotBuffer.asBitmap();
        } catch (RemoteException re) {
            re.rethrowAsRuntimeException();
+38 −31
Original line number Diff line number Diff line
@@ -27,7 +27,6 @@ import android.os.IBinder;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.Log;
import android.util.Pair;
import android.view.SurfaceControl;

import libcore.util.NativeAllocationRegistry;
@@ -73,14 +72,14 @@ public class ScreenCapture {
     */
    public static ScreenshotHardwareBuffer captureDisplay(
            DisplayCaptureArgs captureArgs) {
        Pair<ScreenCaptureListener, ScreenshotSync> syncScreenCapture = createSyncCaptureListener();
        int status = captureDisplay(captureArgs, syncScreenCapture.first);
        SynchronousScreenCaptureListener syncScreenCapture = createSyncCaptureListener();
        int status = captureDisplay(captureArgs, syncScreenCapture);
        if (status != 0) {
            return null;
        }

        try {
            return syncScreenCapture.second.get();
            return syncScreenCapture.getBuffer();
        } catch (Exception e) {
            return null;
        }
@@ -133,14 +132,14 @@ public class ScreenCapture {
     * @hide
     */
    public static ScreenshotHardwareBuffer captureLayers(LayerCaptureArgs captureArgs) {
        Pair<ScreenCaptureListener, ScreenshotSync> syncScreenCapture = createSyncCaptureListener();
        int status = captureLayers(captureArgs, syncScreenCapture.first);
        SynchronousScreenCaptureListener syncScreenCapture = createSyncCaptureListener();
        int status = captureLayers(captureArgs, syncScreenCapture);
        if (status != 0) {
            return null;
        }

        try {
            return syncScreenCapture.second.get();
            return syncScreenCapture.getBuffer();
        } catch (Exception e) {
            return null;
        }
@@ -743,14 +742,35 @@ public class ScreenCapture {
     * A helper method to handle the async screencapture callbacks synchronously. This should only
     * be used if the screencapture caller doesn't care that it blocks waiting for a screenshot.
     *
     * @return a Pair that holds the {@link ScreenCaptureListener} that should be used for capture
     * calls into SurfaceFlinger and a {@link ScreenshotSync} object to retrieve the results.
     */
    public static Pair<ScreenCaptureListener, ScreenshotSync> createSyncCaptureListener() {
        final ScreenshotSync screenshotSync = new ScreenshotSync();
        final ScreenCaptureListener screenCaptureListener = new ScreenCaptureListener(
                screenshotSync::setScreenshotHardwareBuffer);
        return new Pair<>(screenCaptureListener, screenshotSync);
     * @return a {@link SynchronousScreenCaptureListener} that should be used for capture
     * calls into SurfaceFlinger.
     */
    public static SynchronousScreenCaptureListener createSyncCaptureListener() {
        ScreenshotHardwareBuffer[] bufferRef = new ScreenshotHardwareBuffer[1];
        CountDownLatch latch = new CountDownLatch(1);
        Consumer<ScreenshotHardwareBuffer> consumer = buffer -> {
            bufferRef[0] = buffer;
            latch.countDown();
        };

        return new SynchronousScreenCaptureListener(consumer) {
            // In order to avoid requiring two GC cycles to clean up the consumer and the buffer
            // it references, the underlying JNI listener holds a weak reference to the consumer.
            // This property exists to ensure the consumer stays alive during the listener's
            // lifetime.
            private Consumer<ScreenshotHardwareBuffer> mConsumer = consumer;

            @Override
            public ScreenshotHardwareBuffer getBuffer() {
                try {
                    latch.await(SCREENSHOT_WAIT_TIME_S, TimeUnit.SECONDS);
                    return bufferRef[0];
                } catch (Exception e) {
                    Log.e(TAG, "Failed to wait for screen capture result", e);
                    return null;
                }
            }
        };
    }

    /**
@@ -758,28 +778,15 @@ public class ScreenCapture {
     * {@link #captureLayers(LayerCaptureArgs, ScreenCaptureListener)} or
     * {@link #captureDisplay(DisplayCaptureArgs, ScreenCaptureListener)}
     */
    public static class ScreenshotSync {
        private final CountDownLatch mCountDownLatch = new CountDownLatch(1);
        private ScreenshotHardwareBuffer mScreenshotHardwareBuffer;

        private void setScreenshotHardwareBuffer(
                ScreenshotHardwareBuffer screenshotHardwareBuffer) {
            mScreenshotHardwareBuffer = screenshotHardwareBuffer;
            mCountDownLatch.countDown();
    public abstract static class SynchronousScreenCaptureListener extends ScreenCaptureListener {
        SynchronousScreenCaptureListener(Consumer<ScreenshotHardwareBuffer> consumer) {
            super(consumer);
        }

        /**
         * Get the {@link ScreenshotHardwareBuffer} synchronously. This can be null if the
         * screenshot failed or if there was no callback in {@link #SCREENSHOT_WAIT_TIME_S} seconds.
         */
        public ScreenshotHardwareBuffer get() {
            try {
                mCountDownLatch.await(SCREENSHOT_WAIT_TIME_S, TimeUnit.SECONDS);
                return mScreenshotHardwareBuffer;
            } catch (Exception e) {
                Log.e(TAG, "Failed to wait for screen capture result", e);
                return null;
            }
        }
        public abstract ScreenshotHardwareBuffer getBuffer();
    }
}
+5 −5
Original line number Diff line number Diff line
@@ -145,13 +145,13 @@ public final class WindowMetricsController {
        for (int i = 0; i < possibleDisplayInfos.size(); i++) {
            currentDisplayInfo = possibleDisplayInfos.get(i);

            // Calculate max bounds for this rotation and state.
            Rect maxBounds = new Rect(0, 0, currentDisplayInfo.logicalWidth,
                    currentDisplayInfo.logicalHeight);
            // Calculate max bounds for natural rotation and state.
            Rect maxBounds = new Rect(0, 0, currentDisplayInfo.getNaturalWidth(),
                    currentDisplayInfo.getNaturalHeight());

            // Calculate insets for the rotated max bounds.
            // Calculate insets for the natural max bounds.
            final boolean isScreenRound = (currentDisplayInfo.flags & Display.FLAG_ROUND) != 0;
            // Initialize insets based upon display rotation. Note any window-provided insets
            // Initialize insets based on Surface.ROTATION_0. Note any window-provided insets
            // will not be set.
            windowInsets = getWindowInsetsFromServerForDisplay(
                    currentDisplayInfo.displayId, null /* token */,
+14 −8
Original line number Diff line number Diff line
@@ -81,22 +81,28 @@ class ScreenCaptureListenerWrapper : public gui::BnScreenCaptureListener {
public:
    explicit ScreenCaptureListenerWrapper(JNIEnv* env, jobject jobject) {
        env->GetJavaVM(&mVm);
        mConsumerObject = env->NewGlobalRef(jobject);
        LOG_ALWAYS_FATAL_IF(!mConsumerObject, "Failed to make global ref");
        mConsumerWeak = env->NewWeakGlobalRef(jobject);
    }

    ~ScreenCaptureListenerWrapper() {
        if (mConsumerObject) {
            getenv()->DeleteGlobalRef(mConsumerObject);
            mConsumerObject = nullptr;
        if (mConsumerWeak) {
            getenv()->DeleteWeakGlobalRef(mConsumerWeak);
            mConsumerWeak = nullptr;
        }
    }

    binder::Status onScreenCaptureCompleted(
            const gui::ScreenCaptureResults& captureResults) override {
        JNIEnv* env = getenv();

        ScopedLocalRef<jobject> consumer{env, env->NewLocalRef(mConsumerWeak)};
        if (consumer == nullptr) {
            ALOGE("ScreenCaptureListenerWrapper consumer not alive.");
            return binder::Status::ok();
        }

        if (!captureResults.fenceResult.ok() || captureResults.buffer == nullptr) {
            env->CallVoidMethod(mConsumerObject, gConsumerClassInfo.accept, nullptr);
            env->CallVoidMethod(consumer.get(), gConsumerClassInfo.accept, nullptr);
            checkAndClearException(env, "accept");
            return binder::Status::ok();
        }
@@ -111,7 +117,7 @@ public:
                                            captureResults.capturedSecureLayers,
                                            captureResults.capturedHdrLayers);
        checkAndClearException(env, "builder");
        env->CallVoidMethod(mConsumerObject, gConsumerClassInfo.accept, screenshotHardwareBuffer);
        env->CallVoidMethod(consumer.get(), gConsumerClassInfo.accept, screenshotHardwareBuffer);
        checkAndClearException(env, "accept");
        env->DeleteLocalRef(jhardwareBuffer);
        env->DeleteLocalRef(screenshotHardwareBuffer);
@@ -119,7 +125,7 @@ public:
    }

private:
    jobject mConsumerObject;
    jweak mConsumerWeak;
    JavaVM* mVm;

    JNIEnv* getenv() {
+2 −1
Original line number Diff line number Diff line
@@ -620,6 +620,7 @@
    <string name="biometric_error_hw_unavailable" msgid="2494077380540615216">"Biometriese hardeware is nie beskikbaar nie"</string>
    <string name="biometric_error_user_canceled" msgid="6732303949695293730">"Stawing is gekanselleer"</string>
    <string name="biometric_not_recognized" msgid="5106687642694635888">"Nie herken nie"</string>
    <string name="biometric_face_not_recognized" msgid="5535599455744525200">"Gesig word nie herken nie"</string>
    <string name="biometric_error_canceled" msgid="8266582404844179778">"Stawing is gekanselleer"</string>
    <string name="biometric_error_device_not_secured" msgid="3129845065043995924">"Geen PIN, patroon of wagwoord is gestel nie"</string>
    <string name="biometric_error_generic" msgid="6784371929985434439">"Kon nie staaf nie"</string>
@@ -1850,7 +1851,7 @@
    <string name="immersive_cling_description" msgid="7092737175345204832">"Swiep van bo na onder as jy wil uitgaan."</string>
    <string name="immersive_cling_positive" msgid="7047498036346489883">"Het dit"</string>
    <string name="display_rotation_camera_compat_toast_after_rotation" msgid="7600891546249829854">"Draai vir ’n beter aansig"</string>
    <string name="display_rotation_camera_compat_toast_in_split_screen" msgid="8393302456336805466">"Verlaat gedeelde skerm vir ’n beter aansig"</string>
    <string name="display_rotation_camera_compat_toast_in_multi_window" msgid="2473122980393502775">"Maak <xliff:g id="NAME">%s</xliff:g> in volskerm oop vir ’n beter aansig"</string>
    <string name="done_label" msgid="7283767013231718521">"Klaar"</string>
    <string name="hour_picker_description" msgid="5153757582093524635">"Ure se sirkelglyer"</string>
    <string name="minute_picker_description" msgid="9029797023621927294">"Minute se sirkelglyer"</string>
Loading