xref: /aosp_15_r20/frameworks/native/libs/gui/ITransactionCompletedListener.cpp (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
1 /*
2  * Copyright 2018 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 #define LOG_TAG "ITransactionCompletedListener"
18 //#define LOG_NDEBUG 0
19 
20 #include <cstdint>
21 #include <optional>
22 
23 #include <gui/ISurfaceComposer.h>
24 #include <gui/ITransactionCompletedListener.h>
25 #include <gui/LayerState.h>
26 #include <private/gui/ParcelUtils.h>
27 
28 #include <com_android_graphics_libgui_flags.h>
29 
30 using namespace com::android::graphics::libgui;
31 
32 namespace android {
33 
34 namespace { // Anonymous
35 
36 enum class Tag : uint32_t {
37     ON_TRANSACTION_COMPLETED = IBinder::FIRST_CALL_TRANSACTION,
38     ON_RELEASE_BUFFER,
39     ON_TRANSACTION_QUEUE_STALLED,
40     ON_TRUSTED_PRESENTATION_CHANGED,
41     LAST = ON_TRUSTED_PRESENTATION_CHANGED,
42 };
43 
44 } // Anonymous namespace
45 
writeToParcel(Parcel * output) const46 status_t FrameEventHistoryStats::writeToParcel(Parcel* output) const {
47     status_t err = output->writeUint64(frameNumber);
48     if (err != NO_ERROR) return err;
49 
50     if (flags::frametimestamps_previousrelease()) {
51         err = output->writeUint64(previousFrameNumber);
52         if (err != NO_ERROR) return err;
53     }
54 
55     if (gpuCompositionDoneFence) {
56         err = output->writeBool(true);
57         if (err != NO_ERROR) return err;
58 
59         err = output->write(*gpuCompositionDoneFence);
60     } else {
61         err = output->writeBool(false);
62     }
63     if (err != NO_ERROR) return err;
64 
65     err = output->writeInt64(compositorTiming.deadline);
66     if (err != NO_ERROR) return err;
67 
68     err = output->writeInt64(compositorTiming.interval);
69     if (err != NO_ERROR) return err;
70 
71     err = output->writeInt64(compositorTiming.presentLatency);
72     if (err != NO_ERROR) return err;
73 
74     err = output->writeInt64(refreshStartTime);
75     if (err != NO_ERROR) return err;
76 
77     err = output->writeInt64(dequeueReadyTime);
78     return err;
79 }
80 
readFromParcel(const Parcel * input)81 status_t FrameEventHistoryStats::readFromParcel(const Parcel* input) {
82     status_t err = input->readUint64(&frameNumber);
83     if (err != NO_ERROR) return err;
84 
85     if (flags::frametimestamps_previousrelease()) {
86         err = input->readUint64(&previousFrameNumber);
87         if (err != NO_ERROR) return err;
88     }
89 
90     bool hasFence = false;
91     err = input->readBool(&hasFence);
92     if (err != NO_ERROR) return err;
93 
94     if (hasFence) {
95         gpuCompositionDoneFence = new Fence();
96         err = input->read(*gpuCompositionDoneFence);
97         if (err != NO_ERROR) return err;
98     }
99 
100     err = input->readInt64(&(compositorTiming.deadline));
101     if (err != NO_ERROR) return err;
102 
103     err = input->readInt64(&(compositorTiming.interval));
104     if (err != NO_ERROR) return err;
105 
106     err = input->readInt64(&(compositorTiming.presentLatency));
107     if (err != NO_ERROR) return err;
108 
109     err = input->readInt64(&refreshStartTime);
110     if (err != NO_ERROR) return err;
111 
112     err = input->readInt64(&dequeueReadyTime);
113     return err;
114 }
115 
writeToParcel(Parcel * output) const116 status_t SurfaceStats::writeToParcel(Parcel* output) const {
117     SAFE_PARCEL(output->writeStrongBinder, surfaceControl);
118     if (const auto* acquireFence = std::get_if<sp<Fence>>(&acquireTimeOrFence)) {
119         SAFE_PARCEL(output->writeBool, true);
120         SAFE_PARCEL(output->write, **acquireFence);
121     } else {
122         SAFE_PARCEL(output->writeBool, false);
123         SAFE_PARCEL(output->writeInt64, std::get<nsecs_t>(acquireTimeOrFence));
124     }
125 
126     if (previousReleaseFence) {
127         SAFE_PARCEL(output->writeBool, true);
128         SAFE_PARCEL(output->write, *previousReleaseFence);
129     } else {
130         SAFE_PARCEL(output->writeBool, false);
131     }
132 
133     SAFE_PARCEL(output->writeBool, transformHint.has_value());
134     if (transformHint.has_value()) {
135         output->writeUint32(transformHint.value());
136     }
137 
138     SAFE_PARCEL(output->writeUint32, currentMaxAcquiredBufferCount);
139     SAFE_PARCEL(output->writeParcelable, eventStats);
140     SAFE_PARCEL(output->writeParcelable, previousReleaseCallbackId);
141     return NO_ERROR;
142 }
143 
readFromParcel(const Parcel * input)144 status_t SurfaceStats::readFromParcel(const Parcel* input) {
145     SAFE_PARCEL(input->readStrongBinder, &surfaceControl);
146 
147     bool hasFence = false;
148     SAFE_PARCEL(input->readBool, &hasFence);
149     if (hasFence) {
150         acquireTimeOrFence = sp<Fence>::make();
151         SAFE_PARCEL(input->read, *std::get<sp<Fence>>(acquireTimeOrFence));
152     } else {
153         nsecs_t acquireTime;
154         SAFE_PARCEL(input->readInt64, &acquireTime);
155         acquireTimeOrFence = acquireTime;
156     }
157 
158     SAFE_PARCEL(input->readBool, &hasFence);
159     if (hasFence) {
160         previousReleaseFence = new Fence();
161         SAFE_PARCEL(input->read, *previousReleaseFence);
162     }
163     bool hasTransformHint = false;
164     SAFE_PARCEL(input->readBool, &hasTransformHint);
165     if (hasTransformHint) {
166         uint32_t tempTransformHint;
167         SAFE_PARCEL(input->readUint32, &tempTransformHint);
168         transformHint = std::make_optional(tempTransformHint);
169     } else {
170         transformHint = std::nullopt;
171     }
172 
173     SAFE_PARCEL(input->readUint32, &currentMaxAcquiredBufferCount);
174     SAFE_PARCEL(input->readParcelable, &eventStats);
175 
176     SAFE_PARCEL(input->readParcelable, &previousReleaseCallbackId);
177     return NO_ERROR;
178 }
179 
writeToParcel(Parcel * output) const180 status_t TransactionStats::writeToParcel(Parcel* output) const {
181     status_t err = output->writeParcelableVector(callbackIds);
182     if (err != NO_ERROR) {
183         return err;
184     }
185     err = output->writeInt64(latchTime);
186     if (err != NO_ERROR) {
187         return err;
188     }
189     if (presentFence) {
190         err = output->writeBool(true);
191         if (err != NO_ERROR) {
192             return err;
193         }
194         err = output->write(*presentFence);
195     } else {
196         err = output->writeBool(false);
197     }
198     if (err != NO_ERROR) {
199         return err;
200     }
201     return output->writeParcelableVector(surfaceStats);
202 }
203 
readFromParcel(const Parcel * input)204 status_t TransactionStats::readFromParcel(const Parcel* input) {
205     status_t err = input->readParcelableVector(&callbackIds);
206     if (err != NO_ERROR) {
207         return err;
208     }
209     err = input->readInt64(&latchTime);
210     if (err != NO_ERROR) {
211         return err;
212     }
213     bool hasFence = false;
214     err = input->readBool(&hasFence);
215     if (err != NO_ERROR) {
216         return err;
217     }
218     if (hasFence) {
219         presentFence = new Fence();
220         err = input->read(*presentFence);
221         if (err != NO_ERROR) {
222             return err;
223         }
224     }
225     return input->readParcelableVector(&surfaceStats);
226 }
227 
writeToParcel(Parcel * output) const228 status_t ListenerStats::writeToParcel(Parcel* output) const {
229     status_t err = output->writeInt32(static_cast<int32_t>(transactionStats.size()));
230     if (err != NO_ERROR) {
231         return err;
232     }
233     for (const auto& stats : transactionStats) {
234         err = output->writeParcelable(stats);
235         if (err != NO_ERROR) {
236             return err;
237         }
238     }
239     return NO_ERROR;
240 }
241 
readFromParcel(const Parcel * input)242 status_t ListenerStats::readFromParcel(const Parcel* input) {
243     int32_t transactionStats_size = input->readInt32();
244 
245     for (int i = 0; i < transactionStats_size; i++) {
246         TransactionStats stats;
247         status_t err = input->readParcelable(&stats);
248         if (err != NO_ERROR) {
249             return err;
250         }
251         transactionStats.push_back(stats);
252     }
253     return NO_ERROR;
254 }
255 
createEmpty(const sp<IBinder> & listener,const std::unordered_set<CallbackId,CallbackIdHash> & callbackIds)256 ListenerStats ListenerStats::createEmpty(
257         const sp<IBinder>& listener,
258         const std::unordered_set<CallbackId, CallbackIdHash>& callbackIds) {
259     ListenerStats listenerStats;
260     listenerStats.listener = listener;
261     listenerStats.transactionStats.emplace_back(callbackIds);
262 
263     return listenerStats;
264 }
265 
266 class BpTransactionCompletedListener : public SafeBpInterface<ITransactionCompletedListener> {
267 public:
BpTransactionCompletedListener(const sp<IBinder> & impl)268     explicit BpTransactionCompletedListener(const sp<IBinder>& impl)
269           : SafeBpInterface<ITransactionCompletedListener>(impl, "BpTransactionCompletedListener") {
270     }
271 
272     ~BpTransactionCompletedListener() override;
273 
onTransactionCompleted(ListenerStats stats)274     void onTransactionCompleted(ListenerStats stats) override {
275         callRemoteAsync<decltype(&ITransactionCompletedListener::
276                                          onTransactionCompleted)>(Tag::ON_TRANSACTION_COMPLETED,
277                                                                   stats);
278     }
279 
onReleaseBuffer(ReleaseCallbackId callbackId,sp<Fence> releaseFence,uint32_t currentMaxAcquiredBufferCount)280     void onReleaseBuffer(ReleaseCallbackId callbackId, sp<Fence> releaseFence,
281                          uint32_t currentMaxAcquiredBufferCount) override {
282         callRemoteAsync<decltype(&ITransactionCompletedListener::
283                                          onReleaseBuffer)>(Tag::ON_RELEASE_BUFFER, callbackId,
284                                                            releaseFence,
285                                                            currentMaxAcquiredBufferCount);
286     }
287 
onTransactionQueueStalled(const String8 & reason)288     void onTransactionQueueStalled(const String8& reason) override {
289         callRemoteAsync<
290                 decltype(&ITransactionCompletedListener::
291                                  onTransactionQueueStalled)>(Tag::ON_TRANSACTION_QUEUE_STALLED,
292                                                              reason);
293     }
294 
onTrustedPresentationChanged(int id,bool inTrustedPresentationState)295     void onTrustedPresentationChanged(int id, bool inTrustedPresentationState) override {
296         callRemoteAsync<decltype(&ITransactionCompletedListener::onTrustedPresentationChanged)>(
297                 Tag::ON_TRUSTED_PRESENTATION_CHANGED, id, inTrustedPresentationState);
298     }
299 };
300 
301 // Out-of-line virtual method definitions to trigger vtable emission in this translation unit (see
302 // clang warning -Wweak-vtables)
303 BpTransactionCompletedListener::~BpTransactionCompletedListener() = default;
304 
305 IMPLEMENT_META_INTERFACE(TransactionCompletedListener, "android.gui.ITransactionComposerListener");
306 
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)307 status_t BnTransactionCompletedListener::onTransact(uint32_t code, const Parcel& data,
308                                                     Parcel* reply, uint32_t flags) {
309     if (code < IBinder::FIRST_CALL_TRANSACTION || code > static_cast<uint32_t>(Tag::LAST)) {
310         return BBinder::onTransact(code, data, reply, flags);
311     }
312     auto tag = static_cast<Tag>(code);
313     switch (tag) {
314         case Tag::ON_TRANSACTION_COMPLETED:
315             return callLocalAsync(data, reply,
316                                   &ITransactionCompletedListener::onTransactionCompleted);
317         case Tag::ON_RELEASE_BUFFER:
318             return callLocalAsync(data, reply, &ITransactionCompletedListener::onReleaseBuffer);
319         case Tag::ON_TRANSACTION_QUEUE_STALLED:
320             return callLocalAsync(data, reply,
321                                   &ITransactionCompletedListener::onTransactionQueueStalled);
322         case Tag::ON_TRUSTED_PRESENTATION_CHANGED:
323             return callLocalAsync(data, reply,
324                                   &ITransactionCompletedListener::onTrustedPresentationChanged);
325     }
326 }
327 
filter(CallbackId::Type type) const328 ListenerCallbacks ListenerCallbacks::filter(CallbackId::Type type) const {
329     std::vector<CallbackId> filteredCallbackIds;
330     for (const auto& callbackId : callbackIds) {
331         if (callbackId.type == type) {
332             filteredCallbackIds.push_back(callbackId);
333         }
334     }
335     return ListenerCallbacks(transactionCompletedListener, filteredCallbackIds);
336 }
337 
writeToParcel(Parcel * output) const338 status_t CallbackId::writeToParcel(Parcel* output) const {
339     SAFE_PARCEL(output->writeInt64, id);
340     SAFE_PARCEL(output->writeInt32, static_cast<int32_t>(type));
341     return NO_ERROR;
342 }
343 
readFromParcel(const Parcel * input)344 status_t CallbackId::readFromParcel(const Parcel* input) {
345     SAFE_PARCEL(input->readInt64, &id);
346     int32_t typeAsInt;
347     SAFE_PARCEL(input->readInt32, &typeAsInt);
348     type = static_cast<CallbackId::Type>(typeAsInt);
349     return NO_ERROR;
350 }
351 
writeToParcel(Parcel * output) const352 status_t ReleaseCallbackId::writeToParcel(Parcel* output) const {
353     SAFE_PARCEL(output->writeUint64, bufferId);
354     SAFE_PARCEL(output->writeUint64, framenumber);
355     return NO_ERROR;
356 }
357 
readFromParcel(const Parcel * input)358 status_t ReleaseCallbackId::readFromParcel(const Parcel* input) {
359     SAFE_PARCEL(input->readUint64, &bufferId);
360     SAFE_PARCEL(input->readUint64, &framenumber);
361     return NO_ERROR;
362 }
363 
364 const ReleaseCallbackId ReleaseCallbackId::INVALID_ID = ReleaseCallbackId(0, 0);
365 
366 }; // namespace android
367