1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef INTERFACES_INNERKITS_SURFACE_BUFFER_PRODUCER_LISTENER_H
17 #define INTERFACES_INNERKITS_SURFACE_BUFFER_PRODUCER_LISTENER_H
18 
19 #include <refbase.h>
20 #include "buffer_utils.h"
21 #include "iremote_broker.h"
22 #include "buffer_log.h"
23 #include "surface_buffer.h"
24 #include "ibuffer_producer_listener.h"
25 #include "iremote_proxy.h"
26 #include "iremote_stub.h"
27 #include "message_option.h"
28 #include "sync_fence.h"
29 
30 namespace OHOS {
31 class ProducerListenerProxy : public IRemoteProxy<IProducerListener> {
32 public:
ProducerListenerProxy(const sptr<IRemoteObject> & impl)33     explicit ProducerListenerProxy(const sptr<IRemoteObject>& impl) : IRemoteProxy<IProducerListener>(impl) {};
34     virtual ~ProducerListenerProxy() noexcept = default;
OnBufferReleased()35     GSError OnBufferReleased() override
36     {
37         MessageOption option;
38         MessageParcel arguments;
39         MessageParcel reply;
40         if (!arguments.WriteInterfaceToken(IProducerListener::GetDescriptor())) {
41             BLOGE("write interface token failed");
42             return GSERROR_BINDER;
43         }
44         option.SetFlags(MessageOption::TF_ASYNC);
45         int32_t ret = Remote()->SendRequest(IProducerListener::ON_BUFFER_RELEASED, arguments, reply, option);
46         if (ret != ERR_NONE) {
47             return GSERROR_BINDER;
48         }
49         return GSERROR_OK;
50     }
51 
OnBufferReleasedWithFence(const sptr<SurfaceBuffer> & buffer,const sptr<SyncFence> & fence)52     GSError OnBufferReleasedWithFence(const sptr<SurfaceBuffer>& buffer, const sptr<SyncFence>& fence) override
53     {
54         MessageOption option;
55         MessageParcel arguments;
56         MessageParcel reply;
57         if (!arguments.WriteInterfaceToken(IProducerListener::GetDescriptor())) {
58             BLOGE("write interface token failed");
59             return GSERROR_BINDER;
60         }
61         WriteSurfaceBufferImpl(arguments, buffer->GetSeqNum(), buffer);
62         arguments.WriteBool(fence != nullptr);
63         if (fence != nullptr) {
64             fence->WriteToMessageParcel(arguments);
65         }
66         option.SetFlags(MessageOption::TF_ASYNC);
67         int32_t ret = Remote()->SendRequest(IProducerListener::ON_BUFFER_RELEASED_WITH_FENCE, arguments, reply, option);
68         if (ret != ERR_NONE) {
69             BLOGE("Remote SendRequest fail, ret = %{public}d", ret);
70             return GSERROR_BINDER;
71         }
72         return GSERROR_OK;
73     }
74 
ResetReleaseFunc()75     void ResetReleaseFunc() override {}
76 private:
77     static inline BrokerDelegator<ProducerListenerProxy> delegator_;
78 };
79 
80 class ProducerListenerStub : public IRemoteStub<IProducerListener> {
81 public:
82     ProducerListenerStub() = default;
83     ~ProducerListenerStub() = default;
OnRemoteRequest(uint32_t code,MessageParcel & arguments,MessageParcel & reply,MessageOption & option)84     int32_t OnRemoteRequest(uint32_t code, MessageParcel &arguments,
85                             MessageParcel &reply, MessageOption &option) override
86     {
87         (void)(option);
88         auto remoteDescriptor = arguments.ReadInterfaceToken();
89         if (GetDescriptor() != remoteDescriptor) {
90             return ERR_INVALID_STATE;
91         }
92 
93         auto ret = ERR_NONE;
94         switch (code) {
95             case ON_BUFFER_RELEASED: {
96                 auto sret = OnBufferReleased();
97                 reply.WriteInt32(sret);
98                 break;
99             }
100             case ON_BUFFER_RELEASED_WITH_FENCE: {
101                 auto sret = OnBufferReleasedWithFenceRemote(arguments);
102                 reply.WriteInt32(sret);
103                 break;
104             }
105             default: {
106                 ret = ERR_UNKNOWN_TRANSACTION;
107                 break;
108             }
109         }
110         return ret;
111     }
112 private:
OnBufferReleasedWithFenceRemote(MessageParcel & arguments)113     GSError OnBufferReleasedWithFenceRemote(MessageParcel& arguments)
114     {
115         sptr<SurfaceBuffer> buffer;
116         sptr<SyncFence> fence = SyncFence::InvalidFence();
117         uint32_t sequence = 0;
118         GSError ret = ReadSurfaceBufferImpl(arguments, sequence, buffer);
119         if (ret != GSERROR_OK) {
120             BLOGE("ReadSurfaceBufferImpl failed, return %{public}d", ret);
121             return OnBufferReleasedWithFence(buffer, fence);
122         }
123         if (arguments.ReadBool()) {
124             fence = SyncFence::ReadFromMessageParcel(arguments);
125         }
126         ret = OnBufferReleasedWithFence(buffer, fence);
127         return ret;
128     }
129 };
130 
131 class BufferReleaseProducerListener : public ProducerListenerStub {
132 public:
133     BufferReleaseProducerListener(OnReleaseFunc func = nullptr, OnReleaseFuncWithFence funcWithFence = nullptr)
134         : func_(func), funcWithFence_(funcWithFence) {};
~BufferReleaseProducerListener()135     ~BufferReleaseProducerListener() override {};
OnBufferReleased()136     GSError OnBufferReleased() override
137     {
138         OnReleaseFunc func = nullptr;
139         {
140             std::lock_guard<std::mutex> lock(mutex_);
141             if (func_ != nullptr) {
142                 func = func_;
143             }
144         }
145         if (func != nullptr) {
146             sptr<OHOS::SurfaceBuffer> sBuffer = nullptr;
147             return func(sBuffer);
148         }
149         return GSERROR_INTERNAL;
150     };
OnBufferReleasedWithFence(const sptr<SurfaceBuffer> & buffer,const sptr<SyncFence> & fence)151     GSError OnBufferReleasedWithFence(const sptr<SurfaceBuffer>& buffer, const sptr<SyncFence>& fence) override
152     {
153         OnReleaseFuncWithFence funcWithFence = nullptr;
154         {
155             std::lock_guard<std::mutex> lock(mutex_);
156             if (funcWithFence_ != nullptr) {
157                 funcWithFence = funcWithFence_;
158             }
159         }
160         if (funcWithFence != nullptr) {
161             return funcWithFence(buffer, fence);
162         }
163         return GSERROR_INTERNAL;
164     }
ResetReleaseFunc()165     void ResetReleaseFunc() override
166     {
167         std::lock_guard<std::mutex> lock(mutex_);
168         func_ = nullptr;
169         funcWithFence_ = nullptr;
170     }
171 private:
172     OnReleaseFunc func_;
173     OnReleaseFuncWithFence funcWithFence_;
174     std::mutex mutex_;
175 };
176 } // namespace OHOS
177 
178 #endif // INTERFACES_INNERKITS_SURFACE_BUFFER_PRODUCER_LISTENER_H
179