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 <gui/ISurfaceComposer.h>
21 #include <gui/ITransactionCompletedListener.h>
22 #include <gui/LayerState.h>
23 #include <private/gui/ParcelUtils.h>
24
25 namespace android {
26
27 namespace { // Anonymous
28
29 enum class Tag : uint32_t {
30 ON_TRANSACTION_COMPLETED = IBinder::FIRST_CALL_TRANSACTION,
31 ON_RELEASE_BUFFER,
32 LAST = ON_RELEASE_BUFFER,
33 };
34
35 } // Anonymous namespace
36
writeToParcel(Parcel * output) const37 status_t FrameEventHistoryStats::writeToParcel(Parcel* output) const {
38 status_t err = output->writeUint64(frameNumber);
39 if (err != NO_ERROR) return err;
40
41 if (gpuCompositionDoneFence) {
42 err = output->writeBool(true);
43 if (err != NO_ERROR) return err;
44
45 err = output->write(*gpuCompositionDoneFence);
46 } else {
47 err = output->writeBool(false);
48 }
49 if (err != NO_ERROR) return err;
50
51 err = output->writeInt64(compositorTiming.deadline);
52 if (err != NO_ERROR) return err;
53
54 err = output->writeInt64(compositorTiming.interval);
55 if (err != NO_ERROR) return err;
56
57 err = output->writeInt64(compositorTiming.presentLatency);
58 if (err != NO_ERROR) return err;
59
60 err = output->writeInt64(refreshStartTime);
61 if (err != NO_ERROR) return err;
62
63 err = output->writeInt64(dequeueReadyTime);
64 return err;
65 }
66
readFromParcel(const Parcel * input)67 status_t FrameEventHistoryStats::readFromParcel(const Parcel* input) {
68 status_t err = input->readUint64(&frameNumber);
69 if (err != NO_ERROR) return err;
70
71 bool hasFence = false;
72 err = input->readBool(&hasFence);
73 if (err != NO_ERROR) return err;
74
75 if (hasFence) {
76 gpuCompositionDoneFence = new Fence();
77 err = input->read(*gpuCompositionDoneFence);
78 if (err != NO_ERROR) return err;
79 }
80
81 err = input->readInt64(&(compositorTiming.deadline));
82 if (err != NO_ERROR) return err;
83
84 err = input->readInt64(&(compositorTiming.interval));
85 if (err != NO_ERROR) return err;
86
87 err = input->readInt64(&(compositorTiming.presentLatency));
88 if (err != NO_ERROR) return err;
89
90 err = input->readInt64(&refreshStartTime);
91 if (err != NO_ERROR) return err;
92
93 err = input->readInt64(&dequeueReadyTime);
94 return err;
95 }
96
JankData()97 JankData::JankData()
98 : frameVsyncId(FrameTimelineInfo::INVALID_VSYNC_ID), jankType(JankType::None) {}
99
writeToParcel(Parcel * output) const100 status_t JankData::writeToParcel(Parcel* output) const {
101 SAFE_PARCEL(output->writeInt64, frameVsyncId);
102 SAFE_PARCEL(output->writeInt32, jankType);
103 return NO_ERROR;
104 }
105
readFromParcel(const Parcel * input)106 status_t JankData::readFromParcel(const Parcel* input) {
107 SAFE_PARCEL(input->readInt64, &frameVsyncId);
108 SAFE_PARCEL(input->readInt32, &jankType);
109 return NO_ERROR;
110 }
111
writeToParcel(Parcel * output) const112 status_t SurfaceStats::writeToParcel(Parcel* output) const {
113 SAFE_PARCEL(output->writeStrongBinder, surfaceControl);
114 SAFE_PARCEL(output->writeInt64, acquireTime);
115 if (previousReleaseFence) {
116 SAFE_PARCEL(output->writeBool, true);
117 SAFE_PARCEL(output->write, *previousReleaseFence);
118 } else {
119 SAFE_PARCEL(output->writeBool, false);
120 }
121 SAFE_PARCEL(output->writeUint32, transformHint);
122 SAFE_PARCEL(output->writeUint32, currentMaxAcquiredBufferCount);
123 SAFE_PARCEL(output->writeParcelable, eventStats);
124 SAFE_PARCEL(output->writeInt32, static_cast<int32_t>(jankData.size()));
125 for (const auto& data : jankData) {
126 SAFE_PARCEL(output->writeParcelable, data);
127 }
128 SAFE_PARCEL(output->writeParcelable, previousReleaseCallbackId);
129 return NO_ERROR;
130 }
131
readFromParcel(const Parcel * input)132 status_t SurfaceStats::readFromParcel(const Parcel* input) {
133 SAFE_PARCEL(input->readStrongBinder, &surfaceControl);
134 SAFE_PARCEL(input->readInt64, &acquireTime);
135 bool hasFence = false;
136 SAFE_PARCEL(input->readBool, &hasFence);
137 if (hasFence) {
138 previousReleaseFence = new Fence();
139 SAFE_PARCEL(input->read, *previousReleaseFence);
140 }
141 SAFE_PARCEL(input->readUint32, &transformHint);
142 SAFE_PARCEL(input->readUint32, ¤tMaxAcquiredBufferCount);
143 SAFE_PARCEL(input->readParcelable, &eventStats);
144
145 int32_t jankData_size = 0;
146 SAFE_PARCEL_READ_SIZE(input->readInt32, &jankData_size, input->dataSize());
147 for (int i = 0; i < jankData_size; i++) {
148 JankData data;
149 SAFE_PARCEL(input->readParcelable, &data);
150 jankData.push_back(data);
151 }
152 SAFE_PARCEL(input->readParcelable, &previousReleaseCallbackId);
153 return NO_ERROR;
154 }
155
writeToParcel(Parcel * output) const156 status_t TransactionStats::writeToParcel(Parcel* output) const {
157 status_t err = output->writeParcelableVector(callbackIds);
158 if (err != NO_ERROR) {
159 return err;
160 }
161 err = output->writeInt64(latchTime);
162 if (err != NO_ERROR) {
163 return err;
164 }
165 if (presentFence) {
166 err = output->writeBool(true);
167 if (err != NO_ERROR) {
168 return err;
169 }
170 err = output->write(*presentFence);
171 } else {
172 err = output->writeBool(false);
173 }
174 if (err != NO_ERROR) {
175 return err;
176 }
177 return output->writeParcelableVector(surfaceStats);
178 }
179
readFromParcel(const Parcel * input)180 status_t TransactionStats::readFromParcel(const Parcel* input) {
181 status_t err = input->readParcelableVector(&callbackIds);
182 if (err != NO_ERROR) {
183 return err;
184 }
185 err = input->readInt64(&latchTime);
186 if (err != NO_ERROR) {
187 return err;
188 }
189 bool hasFence = false;
190 err = input->readBool(&hasFence);
191 if (err != NO_ERROR) {
192 return err;
193 }
194 if (hasFence) {
195 presentFence = new Fence();
196 err = input->read(*presentFence);
197 if (err != NO_ERROR) {
198 return err;
199 }
200 }
201 return input->readParcelableVector(&surfaceStats);
202 }
203
writeToParcel(Parcel * output) const204 status_t ListenerStats::writeToParcel(Parcel* output) const {
205 status_t err = output->writeInt32(static_cast<int32_t>(transactionStats.size()));
206 if (err != NO_ERROR) {
207 return err;
208 }
209 for (const auto& stats : transactionStats) {
210 err = output->writeParcelable(stats);
211 if (err != NO_ERROR) {
212 return err;
213 }
214 }
215 return NO_ERROR;
216 }
217
readFromParcel(const Parcel * input)218 status_t ListenerStats::readFromParcel(const Parcel* input) {
219 int32_t transactionStats_size = input->readInt32();
220
221 for (int i = 0; i < transactionStats_size; i++) {
222 TransactionStats stats;
223 status_t err = input->readParcelable(&stats);
224 if (err != NO_ERROR) {
225 return err;
226 }
227 transactionStats.push_back(stats);
228 }
229 return NO_ERROR;
230 }
231
createEmpty(const sp<IBinder> & listener,const std::unordered_set<CallbackId,CallbackIdHash> & callbackIds)232 ListenerStats ListenerStats::createEmpty(
233 const sp<IBinder>& listener,
234 const std::unordered_set<CallbackId, CallbackIdHash>& callbackIds) {
235 ListenerStats listenerStats;
236 listenerStats.listener = listener;
237 listenerStats.transactionStats.emplace_back(callbackIds);
238
239 return listenerStats;
240 }
241
242 class BpTransactionCompletedListener : public SafeBpInterface<ITransactionCompletedListener> {
243 public:
BpTransactionCompletedListener(const sp<IBinder> & impl)244 explicit BpTransactionCompletedListener(const sp<IBinder>& impl)
245 : SafeBpInterface<ITransactionCompletedListener>(impl, "BpTransactionCompletedListener") {
246 }
247
248 ~BpTransactionCompletedListener() override;
249
onTransactionCompleted(ListenerStats stats)250 void onTransactionCompleted(ListenerStats stats) override {
251 callRemoteAsync<decltype(&ITransactionCompletedListener::
252 onTransactionCompleted)>(Tag::ON_TRANSACTION_COMPLETED,
253 stats);
254 }
255
onReleaseBuffer(ReleaseCallbackId callbackId,sp<Fence> releaseFence,uint32_t transformHint,uint32_t currentMaxAcquiredBufferCount)256 void onReleaseBuffer(ReleaseCallbackId callbackId, sp<Fence> releaseFence,
257 uint32_t transformHint, uint32_t currentMaxAcquiredBufferCount) override {
258 callRemoteAsync<decltype(
259 &ITransactionCompletedListener::onReleaseBuffer)>(Tag::ON_RELEASE_BUFFER,
260 callbackId, releaseFence,
261 transformHint,
262 currentMaxAcquiredBufferCount);
263 }
264 };
265
266 // Out-of-line virtual method definitions to trigger vtable emission in this translation unit (see
267 // clang warning -Wweak-vtables)
268 BpTransactionCompletedListener::~BpTransactionCompletedListener() = default;
269
270 IMPLEMENT_META_INTERFACE(TransactionCompletedListener, "android.gui.ITransactionComposerListener");
271
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)272 status_t BnTransactionCompletedListener::onTransact(uint32_t code, const Parcel& data,
273 Parcel* reply, uint32_t flags) {
274 if (code < IBinder::FIRST_CALL_TRANSACTION || code > static_cast<uint32_t>(Tag::LAST)) {
275 return BBinder::onTransact(code, data, reply, flags);
276 }
277 auto tag = static_cast<Tag>(code);
278 switch (tag) {
279 case Tag::ON_TRANSACTION_COMPLETED:
280 return callLocalAsync(data, reply,
281 &ITransactionCompletedListener::onTransactionCompleted);
282 case Tag::ON_RELEASE_BUFFER:
283 return callLocalAsync(data, reply, &ITransactionCompletedListener::onReleaseBuffer);
284 }
285 }
286
filter(CallbackId::Type type) const287 ListenerCallbacks ListenerCallbacks::filter(CallbackId::Type type) const {
288 std::vector<CallbackId> filteredCallbackIds;
289 for (const auto& callbackId : callbackIds) {
290 if (callbackId.type == type) {
291 filteredCallbackIds.push_back(callbackId);
292 }
293 }
294 return ListenerCallbacks(transactionCompletedListener, filteredCallbackIds);
295 }
296
writeToParcel(Parcel * output) const297 status_t CallbackId::writeToParcel(Parcel* output) const {
298 SAFE_PARCEL(output->writeInt64, id);
299 SAFE_PARCEL(output->writeInt32, static_cast<int32_t>(type));
300 return NO_ERROR;
301 }
302
readFromParcel(const Parcel * input)303 status_t CallbackId::readFromParcel(const Parcel* input) {
304 SAFE_PARCEL(input->readInt64, &id);
305 int32_t typeAsInt;
306 SAFE_PARCEL(input->readInt32, &typeAsInt);
307 type = static_cast<CallbackId::Type>(typeAsInt);
308 return NO_ERROR;
309 }
310
writeToParcel(Parcel * output) const311 status_t ReleaseCallbackId::writeToParcel(Parcel* output) const {
312 SAFE_PARCEL(output->writeUint64, bufferId);
313 SAFE_PARCEL(output->writeUint64, framenumber);
314 return NO_ERROR;
315 }
316
readFromParcel(const Parcel * input)317 status_t ReleaseCallbackId::readFromParcel(const Parcel* input) {
318 SAFE_PARCEL(input->readUint64, &bufferId);
319 SAFE_PARCEL(input->readUint64, &framenumber);
320 return NO_ERROR;
321 }
322
323 const ReleaseCallbackId ReleaseCallbackId::INVALID_ID = ReleaseCallbackId(0, 0);
324
325 }; // namespace android
326