1 /* 2 * Copyright (C) 2024 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #pragma once 18 19 #include <string> 20 #include <vector> 21 22 #include <android-base/unique_fd.h> 23 24 #include <binder/Parcelable.h> 25 #include <gui/ITransactionCompletedListener.h> 26 #include <ui/Fence.h> 27 #include <utils/Errors.h> 28 29 namespace android::gui { 30 31 /** 32 * IPC wrapper to pass release fences from SurfaceFlinger to apps via a local unix domain socket. 33 */ 34 class BufferReleaseChannel { 35 private: 36 class Endpoint { 37 public: Endpoint(std::string name,android::base::unique_fd fd)38 Endpoint(std::string name, android::base::unique_fd fd) 39 : mName(std::move(name)), mFd(std::move(fd)) {} Endpoint()40 Endpoint() {} 41 42 Endpoint(Endpoint&&) noexcept = default; 43 Endpoint& operator=(Endpoint&&) noexcept = default; 44 45 Endpoint(const Endpoint&) = delete; 46 void operator=(const Endpoint&) = delete; 47 getFd()48 const android::base::unique_fd& getFd() const { return mFd; } 49 50 protected: 51 std::string mName; 52 android::base::unique_fd mFd; 53 }; 54 55 public: 56 class ConsumerEndpoint : public Endpoint { 57 public: ConsumerEndpoint(std::string name,android::base::unique_fd fd)58 ConsumerEndpoint(std::string name, android::base::unique_fd fd) 59 : Endpoint(std::move(name), std::move(fd)) {} 60 61 /** 62 * Reads a release fence from the BufferReleaseChannel. 63 * 64 * Returns OK on success. 65 * Returns WOULD_BLOCK if there is no fence present. 66 * Other errors probably indicate that the channel is broken. 67 */ 68 status_t readReleaseFence(ReleaseCallbackId& outReleaseCallbackId, 69 sp<Fence>& outReleaseFence, uint32_t& maxAcquiredBufferCount); 70 71 private: 72 std::mutex mMutex; 73 std::vector<uint8_t> mFlattenedBuffer GUARDED_BY(mMutex); 74 }; 75 76 class ProducerEndpoint : public Endpoint, public Parcelable { 77 public: ProducerEndpoint(std::string name,android::base::unique_fd fd)78 ProducerEndpoint(std::string name, android::base::unique_fd fd) 79 : Endpoint(std::move(name), std::move(fd)) {} ProducerEndpoint()80 ProducerEndpoint() {} 81 82 status_t readFromParcel(const android::Parcel* parcel) override; 83 status_t writeToParcel(android::Parcel* parcel) const override; 84 85 status_t writeReleaseFence(const ReleaseCallbackId&, const sp<Fence>& releaseFence, 86 uint32_t maxAcquiredBufferCount); 87 88 private: 89 std::vector<uint8_t> mFlattenedBuffer; 90 }; 91 92 /** 93 * Create two endpoints that make up the BufferReleaseChannel. 94 * 95 * Return OK on success. 96 */ 97 static status_t open(const std::string name, std::unique_ptr<ConsumerEndpoint>& outConsumer, 98 std::shared_ptr<ProducerEndpoint>& outProducer); 99 100 struct Message : public Flattenable<Message> { 101 ReleaseCallbackId releaseCallbackId; 102 sp<Fence> releaseFence = Fence::NO_FENCE; 103 uint32_t maxAcquiredBufferCount; 104 105 Message() = default; MessageMessage106 Message(ReleaseCallbackId releaseCallbackId, sp<Fence> releaseFence, 107 uint32_t maxAcquiredBufferCount) 108 : releaseCallbackId{releaseCallbackId}, 109 releaseFence{std::move(releaseFence)}, 110 maxAcquiredBufferCount{maxAcquiredBufferCount} {} 111 112 // Flattenable protocol 113 size_t getFlattenedSize() const; 114 getFdCountMessage115 size_t getFdCount() const { return releaseFence->getFdCount(); } 116 117 status_t flatten(void*& buffer, size_t& size, int*& fds, size_t& count) const; 118 119 status_t unflatten(void const*& buffer, size_t& size, int const*& fds, size_t& count); 120 121 private: 122 size_t getPodSize() const; 123 }; 124 }; 125 126 } // namespace android::gui 127