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

Commit 85bf55ae authored by chaviw's avatar chaviw
Browse files

Added ScreenCaptureListener to allow for screenshot request callbacks

Added boiler plate code to send a listener to the screenshot requests to
allow screenshots to be async.

Test: LayerStateTest
Bug: 162367424
Change-Id: I747e7316364a145bed6a920d72a592e493ca0029
parent 9c53ee71
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -234,6 +234,7 @@ constexpr const char* const kManualInterfaces[] = {
  "android.gui.IGraphicBufferConsumer",
  "android.gui.IRegionSamplingListener",
  "android.gui.ITransactionComposerListener",
  "android.gui.IScreenCaptureListener",
  "android.gui.SensorEventConnection",
  "android.gui.SensorServer",
  "android.hardware.ICamera",
+1 −0
Original line number Diff line number Diff line
@@ -62,6 +62,7 @@ cc_library_shared {
        "IGraphicBufferProducer.cpp",
        "IProducerListener.cpp",
        "IRegionSamplingListener.cpp",
        "IScreenCaptureListener.cpp",
        "ISurfaceComposer.cpp",
        "ISurfaceComposerClient.cpp",
        "ITransactionCompletedListener.cpp",
+70 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 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.
 */

#include <gui/IScreenCaptureListener.h>
#include <gui/LayerState.h>

namespace android {

namespace { // Anonymous

enum class Tag : uint32_t {
    ON_SCREEN_CAPTURE_COMPLETE = IBinder::FIRST_CALL_TRANSACTION,
    LAST = ON_SCREEN_CAPTURE_COMPLETE,
};

} // Anonymous namespace

class BpScreenCaptureListener : public SafeBpInterface<IScreenCaptureListener> {
public:
    explicit BpScreenCaptureListener(const sp<IBinder>& impl)
          : SafeBpInterface<IScreenCaptureListener>(impl, "BpScreenCaptureListener") {}

    ~BpScreenCaptureListener() override;

    status_t onScreenCaptureComplete(const ScreenCaptureResults& captureResults) override {
        Parcel data, reply;
        data.writeInterfaceToken(IScreenCaptureListener::getInterfaceDescriptor());

        SAFE_PARCEL(captureResults.write, data);
        return remote()->transact(static_cast<uint32_t>(Tag::ON_SCREEN_CAPTURE_COMPLETE), data,
                                  &reply, IBinder::FLAG_ONEWAY);
    }
};

// Out-of-line virtual method definitions to trigger vtable emission in this translation unit (see
// clang warning -Wweak-vtables)
BpScreenCaptureListener::~BpScreenCaptureListener() = default;

IMPLEMENT_META_INTERFACE(ScreenCaptureListener, "android.gui.IScreenCaptureListener");

status_t BnScreenCaptureListener::onTransact(uint32_t code, const Parcel& data, Parcel* reply,
                                             uint32_t flags) {
    auto tag = static_cast<Tag>(code);
    switch (tag) {
        case Tag::ON_SCREEN_CAPTURE_COMPLETE: {
            CHECK_INTERFACE(IScreenCaptureListener, data, reply);
            ScreenCaptureResults captureResults;
            SAFE_PARCEL(captureResults.read, data);
            return onScreenCaptureComplete(captureResults);
        }
        default: {
            return BBinder::onTransact(code, data, reply, flags);
        }
    }
}

} // namespace android
 No newline at end of file
+15 −3
Original line number Diff line number Diff line
@@ -607,19 +607,31 @@ status_t LayerCaptureArgs::read(const Parcel& input) {
}

status_t ScreenCaptureResults::write(Parcel& output) const {
    if (buffer != nullptr) {
        SAFE_PARCEL(output.writeBool, true);
        SAFE_PARCEL(output.write, *buffer);
    } else {
        SAFE_PARCEL(output.writeBool, false);
    }
    SAFE_PARCEL(output.writeBool, capturedSecureLayers);
    SAFE_PARCEL(output.writeUint32, static_cast<uint32_t>(capturedDataspace));
    SAFE_PARCEL(output.writeInt32, result);
    return NO_ERROR;
}

status_t ScreenCaptureResults::read(const Parcel& input) {
    bool hasGraphicBuffer;
    SAFE_PARCEL(input.readBool, &hasGraphicBuffer);
    if (hasGraphicBuffer) {
        buffer = new GraphicBuffer();
        SAFE_PARCEL(input.read, *buffer);
    }

    SAFE_PARCEL(input.readBool, &capturedSecureLayers);
    uint32_t dataspace = 0;
    SAFE_PARCEL(input.readUint32, &dataspace);
    capturedDataspace = static_cast<ui::Dataspace>(dataspace);
    SAFE_PARCEL(input.readInt32, &result);
    return NO_ERROR;
}

+45 −0
Original line number Diff line number Diff line
/*
 * Copyright 2020 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.
 */

#pragma once

#include <binder/Binder.h>
#include <binder/IInterface.h>
#include <binder/Parcel.h>
#include <binder/SafeInterface.h>

namespace android {

struct ScreenCaptureResults;

// TODO(b/166271443): Convert to AIDL
class IScreenCaptureListener : public IInterface {
public:
    DECLARE_META_INTERFACE(ScreenCaptureListener)

    virtual status_t onScreenCaptureComplete(const ScreenCaptureResults& captureResults) = 0;
};

class BnScreenCaptureListener : public SafeBnInterface<IScreenCaptureListener> {
public:
    BnScreenCaptureListener()
          : SafeBnInterface<IScreenCaptureListener>("BnScreenCaptureListener") {}

    status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply,
                        uint32_t flags = 0) override;
};

} // namespace android
Loading