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

Commit 9e84f339 authored by Huihong Luo's avatar Huihong Luo
Browse files

Migrate screenshot methods to AIDL

Additonal service, named as "SurfaceFlingerAIDL", is added to surfaceflinger during the process of migrating ISurfaceComposer interface to AIDL. New changes are put into namespace, android::gui. Once migration is complete, this service will be deleted.

This CL migrates Screenshot methods to AIDL, more will come.

Bug: 211037638
Test: screencap
Merged-In: Idee91fa2444646639735847b1c76e983af39227f
Change-Id: Idee91fa2444646639735847b1c76e983af39227f
parent 41c0e3f7
Loading
Loading
Loading
Loading
+2 −60
Original line number Diff line number Diff line
@@ -46,9 +46,11 @@ using namespace aidl::android::hardware::graphics;

namespace android {

using gui::DisplayCaptureArgs;
using gui::IDisplayEventConnection;
using gui::IRegionSamplingListener;
using gui::IWindowInfosListener;
using gui::LayerCaptureArgs;
using ui::ColorMode;

class BpSurfaceComposer : public BpInterface<ISurfaceComposer>
@@ -118,36 +120,6 @@ public:
        remote()->transact(BnSurfaceComposer::BOOT_FINISHED, data, &reply);
    }

    status_t captureDisplay(const DisplayCaptureArgs& args,
                            const sp<IScreenCaptureListener>& captureListener) override {
        Parcel data, reply;
        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
        SAFE_PARCEL(args.write, data);
        SAFE_PARCEL(data.writeStrongBinder, IInterface::asBinder(captureListener));

        return remote()->transact(BnSurfaceComposer::CAPTURE_DISPLAY, data, &reply);
    }

    status_t captureDisplay(DisplayId displayId,
                            const sp<IScreenCaptureListener>& captureListener) override {
        Parcel data, reply;
        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
        SAFE_PARCEL(data.writeUint64, displayId.value);
        SAFE_PARCEL(data.writeStrongBinder, IInterface::asBinder(captureListener));

        return remote()->transact(BnSurfaceComposer::CAPTURE_DISPLAY_BY_ID, data, &reply);
    }

    status_t captureLayers(const LayerCaptureArgs& args,
                           const sp<IScreenCaptureListener>& captureListener) override {
        Parcel data, reply;
        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
        SAFE_PARCEL(args.write, data);
        SAFE_PARCEL(data.writeStrongBinder, IInterface::asBinder(captureListener));

        return remote()->transact(BnSurfaceComposer::CAPTURE_LAYERS, data, &reply);
    }

    bool authenticateSurfaceTexture(
            const sp<IGraphicBufferProducer>& bufferProducer) const override {
        Parcel data, reply;
@@ -1451,36 +1423,6 @@ status_t BnSurfaceComposer::onTransact(
            bootFinished();
            return NO_ERROR;
        }
        case CAPTURE_DISPLAY: {
            CHECK_INTERFACE(ISurfaceComposer, data, reply);
            DisplayCaptureArgs args;
            sp<IScreenCaptureListener> captureListener;
            SAFE_PARCEL(args.read, data);
            SAFE_PARCEL(data.readStrongBinder, &captureListener);

            return captureDisplay(args, captureListener);
        }
        case CAPTURE_DISPLAY_BY_ID: {
            CHECK_INTERFACE(ISurfaceComposer, data, reply);
            uint64_t value;
            SAFE_PARCEL(data.readUint64, &value);
            const auto id = DisplayId::fromValue(value);
            if (!id) return BAD_VALUE;

            sp<IScreenCaptureListener> captureListener;
            SAFE_PARCEL(data.readStrongBinder, &captureListener);

            return captureDisplay(*id, captureListener);
        }
        case CAPTURE_LAYERS: {
            CHECK_INTERFACE(ISurfaceComposer, data, reply);
            LayerCaptureArgs args;
            sp<IScreenCaptureListener> captureListener;
            SAFE_PARCEL(args.read, data);
            SAFE_PARCEL(data.readStrongBinder, &captureListener);

            return captureLayers(args, captureListener);
        }
        case AUTHENTICATE_SURFACE: {
            CHECK_INTERFACE(ISurfaceComposer, data, reply);
            sp<IGraphicBufferProducer> bufferProducer =
+48 −44
Original line number Diff line number Diff line
@@ -686,85 +686,89 @@ bool ValidateFrameRate(float frameRate, int8_t compatibility, int8_t changeFrame

// ----------------------------------------------------------------------------

status_t CaptureArgs::write(Parcel& output) const {
    SAFE_PARCEL(output.writeInt32, static_cast<int32_t>(pixelFormat));
    SAFE_PARCEL(output.write, sourceCrop);
    SAFE_PARCEL(output.writeFloat, frameScaleX);
    SAFE_PARCEL(output.writeFloat, frameScaleY);
    SAFE_PARCEL(output.writeBool, captureSecureLayers);
    SAFE_PARCEL(output.writeInt32, uid);
    SAFE_PARCEL(output.writeInt32, static_cast<int32_t>(dataspace));
    SAFE_PARCEL(output.writeBool, allowProtected);
    SAFE_PARCEL(output.writeBool, grayscale);
namespace gui {

status_t CaptureArgs::writeToParcel(Parcel* output) const {
    SAFE_PARCEL(output->writeInt32, static_cast<int32_t>(pixelFormat));
    SAFE_PARCEL(output->write, sourceCrop);
    SAFE_PARCEL(output->writeFloat, frameScaleX);
    SAFE_PARCEL(output->writeFloat, frameScaleY);
    SAFE_PARCEL(output->writeBool, captureSecureLayers);
    SAFE_PARCEL(output->writeInt32, uid);
    SAFE_PARCEL(output->writeInt32, static_cast<int32_t>(dataspace));
    SAFE_PARCEL(output->writeBool, allowProtected);
    SAFE_PARCEL(output->writeBool, grayscale);
    return NO_ERROR;
}

status_t CaptureArgs::read(const Parcel& input) {
status_t CaptureArgs::readFromParcel(const Parcel* input) {
    int32_t value = 0;
    SAFE_PARCEL(input.readInt32, &value);
    SAFE_PARCEL(input->readInt32, &value);
    pixelFormat = static_cast<ui::PixelFormat>(value);
    SAFE_PARCEL(input.read, sourceCrop);
    SAFE_PARCEL(input.readFloat, &frameScaleX);
    SAFE_PARCEL(input.readFloat, &frameScaleY);
    SAFE_PARCEL(input.readBool, &captureSecureLayers);
    SAFE_PARCEL(input.readInt32, &uid);
    SAFE_PARCEL(input.readInt32, &value);
    SAFE_PARCEL(input->read, sourceCrop);
    SAFE_PARCEL(input->readFloat, &frameScaleX);
    SAFE_PARCEL(input->readFloat, &frameScaleY);
    SAFE_PARCEL(input->readBool, &captureSecureLayers);
    SAFE_PARCEL(input->readInt32, &uid);
    SAFE_PARCEL(input->readInt32, &value);
    dataspace = static_cast<ui::Dataspace>(value);
    SAFE_PARCEL(input.readBool, &allowProtected);
    SAFE_PARCEL(input.readBool, &grayscale);
    SAFE_PARCEL(input->readBool, &allowProtected);
    SAFE_PARCEL(input->readBool, &grayscale);
    return NO_ERROR;
}

status_t DisplayCaptureArgs::write(Parcel& output) const {
    SAFE_PARCEL(CaptureArgs::write, output);
status_t DisplayCaptureArgs::writeToParcel(Parcel* output) const {
    SAFE_PARCEL(CaptureArgs::writeToParcel, output);

    SAFE_PARCEL(output.writeStrongBinder, displayToken);
    SAFE_PARCEL(output.writeUint32, width);
    SAFE_PARCEL(output.writeUint32, height);
    SAFE_PARCEL(output.writeBool, useIdentityTransform);
    SAFE_PARCEL(output->writeStrongBinder, displayToken);
    SAFE_PARCEL(output->writeUint32, width);
    SAFE_PARCEL(output->writeUint32, height);
    SAFE_PARCEL(output->writeBool, useIdentityTransform);
    return NO_ERROR;
}

status_t DisplayCaptureArgs::read(const Parcel& input) {
    SAFE_PARCEL(CaptureArgs::read, input);
status_t DisplayCaptureArgs::readFromParcel(const Parcel* input) {
    SAFE_PARCEL(CaptureArgs::readFromParcel, input);

    SAFE_PARCEL(input.readStrongBinder, &displayToken);
    SAFE_PARCEL(input.readUint32, &width);
    SAFE_PARCEL(input.readUint32, &height);
    SAFE_PARCEL(input.readBool, &useIdentityTransform);
    SAFE_PARCEL(input->readStrongBinder, &displayToken);
    SAFE_PARCEL(input->readUint32, &width);
    SAFE_PARCEL(input->readUint32, &height);
    SAFE_PARCEL(input->readBool, &useIdentityTransform);
    return NO_ERROR;
}

status_t LayerCaptureArgs::write(Parcel& output) const {
    SAFE_PARCEL(CaptureArgs::write, output);
status_t LayerCaptureArgs::writeToParcel(Parcel* output) const {
    SAFE_PARCEL(CaptureArgs::writeToParcel, output);

    SAFE_PARCEL(output.writeStrongBinder, layerHandle);
    SAFE_PARCEL(output.writeInt32, excludeHandles.size());
    SAFE_PARCEL(output->writeStrongBinder, layerHandle);
    SAFE_PARCEL(output->writeInt32, excludeHandles.size());
    for (auto el : excludeHandles) {
        SAFE_PARCEL(output.writeStrongBinder, el);
        SAFE_PARCEL(output->writeStrongBinder, el);
    }
    SAFE_PARCEL(output.writeBool, childrenOnly);
    SAFE_PARCEL(output->writeBool, childrenOnly);
    return NO_ERROR;
}

status_t LayerCaptureArgs::read(const Parcel& input) {
    SAFE_PARCEL(CaptureArgs::read, input);
status_t LayerCaptureArgs::readFromParcel(const Parcel* input) {
    SAFE_PARCEL(CaptureArgs::readFromParcel, input);

    SAFE_PARCEL(input.readStrongBinder, &layerHandle);
    SAFE_PARCEL(input->readStrongBinder, &layerHandle);

    int32_t numExcludeHandles = 0;
    SAFE_PARCEL_READ_SIZE(input.readInt32, &numExcludeHandles, input.dataSize());
    SAFE_PARCEL_READ_SIZE(input->readInt32, &numExcludeHandles, input->dataSize());
    excludeHandles.reserve(numExcludeHandles);
    for (int i = 0; i < numExcludeHandles; i++) {
        sp<IBinder> binder;
        SAFE_PARCEL(input.readStrongBinder, &binder);
        SAFE_PARCEL(input->readStrongBinder, &binder);
        excludeHandles.emplace(binder);
    }

    SAFE_PARCEL(input.readBool, &childrenOnly);
    SAFE_PARCEL(input->readBool, &childrenOnly);
    return NO_ERROR;
}

}; // namespace gui

ReleaseCallbackId BufferData::generateReleaseCallbackId() const {
    return {buffer->getId(), frameNumber};
}
+57 −6
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@
#include <ui/DynamicDisplayInfo.h>

#include <private/gui/ComposerService.h>
#include <private/gui/ComposerServiceAIDL.h>

// This server size should always be smaller than the server cache size
#define BUFFER_CACHE_MAX_SIZE 64
@@ -62,6 +63,7 @@ using ui::ColorMode;
// ---------------------------------------------------------------------------

ANDROID_SINGLETON_STATIC_INSTANCE(ComposerService);
ANDROID_SINGLETON_STATIC_INSTANCE(ComposerServiceAIDL);

namespace {
// Initialize transaction id counter used to generate transaction ids
@@ -120,6 +122,52 @@ void ComposerService::composerServiceDied()
    mDeathObserver = nullptr;
}

ComposerServiceAIDL::ComposerServiceAIDL() : Singleton<ComposerServiceAIDL>() {
    std::scoped_lock lock(mMutex);
    connectLocked();
}

bool ComposerServiceAIDL::connectLocked() {
    const String16 name("SurfaceFlingerAIDL");
    mComposerService = waitForService<gui::ISurfaceComposer>(name);
    if (mComposerService == nullptr) {
        return false; // fatal error or permission problem
    }

    // Create the death listener.
    class DeathObserver : public IBinder::DeathRecipient {
        ComposerServiceAIDL& mComposerService;
        virtual void binderDied(const wp<IBinder>& who) {
            ALOGW("ComposerService aidl remote (surfaceflinger) died [%p]", who.unsafe_get());
            mComposerService.composerServiceDied();
        }

    public:
        explicit DeathObserver(ComposerServiceAIDL& mgr) : mComposerService(mgr) {}
    };

    mDeathObserver = new DeathObserver(*const_cast<ComposerServiceAIDL*>(this));
    IInterface::asBinder(mComposerService)->linkToDeath(mDeathObserver);
    return true;
}

/*static*/ sp<gui::ISurfaceComposer> ComposerServiceAIDL::getComposerService() {
    ComposerServiceAIDL& instance = ComposerServiceAIDL::getInstance();
    std::scoped_lock lock(instance.mMutex);
    if (instance.mComposerService == nullptr) {
        if (ComposerServiceAIDL::getInstance().connectLocked()) {
            ALOGD("ComposerServiceAIDL reconnected");
        }
    }
    return instance.mComposerService;
}

void ComposerServiceAIDL::composerServiceDied() {
    std::scoped_lock lock(mMutex);
    mComposerService = nullptr;
    mDeathObserver = nullptr;
}

class DefaultComposerClient: public Singleton<DefaultComposerClient> {
    Mutex mLock;
    sp<SurfaceComposerClient> mClient;
@@ -2267,26 +2315,29 @@ status_t SurfaceComposerClient::removeWindowInfosListener(

status_t ScreenshotClient::captureDisplay(const DisplayCaptureArgs& captureArgs,
                                          const sp<IScreenCaptureListener>& captureListener) {
    sp<ISurfaceComposer> s(ComposerService::getComposerService());
    sp<gui::ISurfaceComposer> s(ComposerServiceAIDL::getComposerService());
    if (s == nullptr) return NO_INIT;

    return s->captureDisplay(captureArgs, captureListener);
    binder::Status status = s->captureDisplay(captureArgs, captureListener);
    return status.transactionError();
}

status_t ScreenshotClient::captureDisplay(DisplayId displayId,
                                          const sp<IScreenCaptureListener>& captureListener) {
    sp<ISurfaceComposer> s(ComposerService::getComposerService());
    sp<gui::ISurfaceComposer> s(ComposerServiceAIDL::getComposerService());
    if (s == nullptr) return NO_INIT;

    return s->captureDisplay(displayId, captureListener);
    binder::Status status = s->captureDisplayById(displayId.value, captureListener);
    return status.transactionError();
}

status_t ScreenshotClient::captureLayers(const LayerCaptureArgs& captureArgs,
                                         const sp<IScreenCaptureListener>& captureListener) {
    sp<ISurfaceComposer> s(ComposerService::getComposerService());
    sp<gui::ISurfaceComposer> s(ComposerServiceAIDL::getComposerService());
    if (s == nullptr) return NO_INIT;

    return s->captureLayers(captureArgs, captureListener);
    binder::Status status = s->captureLayers(captureArgs, captureListener);
    return status.transactionError();
}

// ---------------------------------------------------------------------------------
+19 −0
Original line number Diff line number Diff line
/*
 * Copyright 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.gui;

parcelable DisplayCaptureArgs cpp_header "gui/DisplayCaptureArgs.h";
+42 −0
Original line number Diff line number Diff line
/*
 * Copyright 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.gui;

import android.gui.DisplayCaptureArgs;
import android.gui.LayerCaptureArgs;
import android.gui.IScreenCaptureListener;

/** @hide */
interface ISurfaceComposer {
    /**
     * Capture the specified screen. This requires READ_FRAME_BUFFER
     * permission.  This function will fail if there is a secure window on
     * screen and DisplayCaptureArgs.captureSecureLayers is false.
     *
     * This function can capture a subregion (the source crop) of the screen.
     * The subregion can be optionally rotated.  It will also be scaled to
     * match the size of the output buffer.
     */
    void captureDisplay(in DisplayCaptureArgs args, IScreenCaptureListener listener);
    void captureDisplayById(long displayId, IScreenCaptureListener listener);
    /**
     * Capture a subtree of the layer hierarchy, potentially ignoring the root node.
     * This requires READ_FRAME_BUFFER permission. This function will fail if there
     * is a secure window on screen
     */
    void captureLayers(in LayerCaptureArgs args, IScreenCaptureListener listener);
}
Loading