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, ¤tMaxAcquiredBufferCount);
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