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

Commit afa4e52c authored by Huihong Luo's avatar Huihong Luo Committed by Android (Google) Code Review
Browse files

Merge "Migrate screenshot methods to AIDL" into tm-dev

parents a31e4a13 9e84f339
Loading
Loading
Loading
Loading
+2 −60
Original line number Original line Diff line number Diff line
@@ -46,9 +46,11 @@ using namespace aidl::android::hardware::graphics;


namespace android {
namespace android {


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


class BpSurfaceComposer : public BpInterface<ISurfaceComposer>
class BpSurfaceComposer : public BpInterface<ISurfaceComposer>
@@ -118,36 +120,6 @@ public:
        remote()->transact(BnSurfaceComposer::BOOT_FINISHED, data, &reply);
        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(
    bool authenticateSurfaceTexture(
            const sp<IGraphicBufferProducer>& bufferProducer) const override {
            const sp<IGraphicBufferProducer>& bufferProducer) const override {
        Parcel data, reply;
        Parcel data, reply;
@@ -1451,36 +1423,6 @@ status_t BnSurfaceComposer::onTransact(
            bootFinished();
            bootFinished();
            return NO_ERROR;
            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: {
        case AUTHENTICATE_SURFACE: {
            CHECK_INTERFACE(ISurfaceComposer, data, reply);
            CHECK_INTERFACE(ISurfaceComposer, data, reply);
            sp<IGraphicBufferProducer> bufferProducer =
            sp<IGraphicBufferProducer> bufferProducer =
+48 −44
Original line number Original line 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 {
namespace gui {
    SAFE_PARCEL(output.writeInt32, static_cast<int32_t>(pixelFormat));

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


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


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


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


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


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


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


    SAFE_PARCEL(output.writeStrongBinder, layerHandle);
    SAFE_PARCEL(output->writeStrongBinder, layerHandle);
    SAFE_PARCEL(output.writeInt32, excludeHandles.size());
    SAFE_PARCEL(output->writeInt32, excludeHandles.size());
    for (auto el : excludeHandles) {
    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;
    return NO_ERROR;
}
}


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


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


    int32_t numExcludeHandles = 0;
    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);
    excludeHandles.reserve(numExcludeHandles);
    for (int i = 0; i < numExcludeHandles; i++) {
    for (int i = 0; i < numExcludeHandles; i++) {
        sp<IBinder> binder;
        sp<IBinder> binder;
        SAFE_PARCEL(input.readStrongBinder, &binder);
        SAFE_PARCEL(input->readStrongBinder, &binder);
        excludeHandles.emplace(binder);
        excludeHandles.emplace(binder);
    }
    }


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


}; // namespace gui

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


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


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


ANDROID_SINGLETON_STATIC_INSTANCE(ComposerService);
ANDROID_SINGLETON_STATIC_INSTANCE(ComposerService);
ANDROID_SINGLETON_STATIC_INSTANCE(ComposerServiceAIDL);


namespace {
namespace {
// Initialize transaction id counter used to generate transaction ids
// Initialize transaction id counter used to generate transaction ids
@@ -120,6 +122,52 @@ void ComposerService::composerServiceDied()
    mDeathObserver = nullptr;
    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> {
class DefaultComposerClient: public Singleton<DefaultComposerClient> {
    Mutex mLock;
    Mutex mLock;
    sp<SurfaceComposerClient> mClient;
    sp<SurfaceComposerClient> mClient;
@@ -2267,26 +2315,29 @@ status_t SurfaceComposerClient::removeWindowInfosListener(


status_t ScreenshotClient::captureDisplay(const DisplayCaptureArgs& captureArgs,
status_t ScreenshotClient::captureDisplay(const DisplayCaptureArgs& captureArgs,
                                          const sp<IScreenCaptureListener>& captureListener) {
                                          const sp<IScreenCaptureListener>& captureListener) {
    sp<ISurfaceComposer> s(ComposerService::getComposerService());
    sp<gui::ISurfaceComposer> s(ComposerServiceAIDL::getComposerService());
    if (s == nullptr) return NO_INIT;
    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,
status_t ScreenshotClient::captureDisplay(DisplayId displayId,
                                          const sp<IScreenCaptureListener>& captureListener) {
                                          const sp<IScreenCaptureListener>& captureListener) {
    sp<ISurfaceComposer> s(ComposerService::getComposerService());
    sp<gui::ISurfaceComposer> s(ComposerServiceAIDL::getComposerService());
    if (s == nullptr) return NO_INIT;
    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,
status_t ScreenshotClient::captureLayers(const LayerCaptureArgs& captureArgs,
                                         const sp<IScreenCaptureListener>& captureListener) {
                                         const sp<IScreenCaptureListener>& captureListener) {
    sp<ISurfaceComposer> s(ComposerService::getComposerService());
    sp<gui::ISurfaceComposer> s(ComposerServiceAIDL::getComposerService());
    if (s == nullptr) return NO_INIT;
    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 Original line 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 Original line 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