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/ITransactionCompletedListener.h>
21 
22 namespace android {
23 
24 namespace { // Anonymous
25 
26 enum class Tag : uint32_t {
27     ON_TRANSACTION_COMPLETED = IBinder::FIRST_CALL_TRANSACTION,
28     LAST = ON_TRANSACTION_COMPLETED,
29 };
30 
31 } // Anonymous namespace
32 
writeToParcel(Parcel * output) const33 status_t SurfaceStats::writeToParcel(Parcel* output) const {
34     status_t err = output->writeStrongBinder(surfaceControl);
35     if (err != NO_ERROR) {
36         return err;
37     }
38     err = output->writeInt64(acquireTime);
39     if (err != NO_ERROR) {
40         return err;
41     }
42     if (previousReleaseFence) {
43         err = output->writeBool(true);
44         if (err != NO_ERROR) {
45             return err;
46         }
47         err = output->write(*previousReleaseFence);
48     } else {
49         err = output->writeBool(false);
50     }
51     return err;
52 }
53 
readFromParcel(const Parcel * input)54 status_t SurfaceStats::readFromParcel(const Parcel* input) {
55     status_t err = input->readStrongBinder(&surfaceControl);
56     if (err != NO_ERROR) {
57         return err;
58     }
59     err = input->readInt64(&acquireTime);
60     if (err != NO_ERROR) {
61         return err;
62     }
63     bool hasFence = false;
64     err = input->readBool(&hasFence);
65     if (err != NO_ERROR) {
66         return err;
67     }
68     if (hasFence) {
69         previousReleaseFence = new Fence();
70         err = input->read(*previousReleaseFence);
71         if (err != NO_ERROR) {
72             return err;
73         }
74     }
75     return NO_ERROR;
76 }
77 
writeToParcel(Parcel * output) const78 status_t TransactionStats::writeToParcel(Parcel* output) const {
79     status_t err = output->writeInt64Vector(callbackIds);
80     if (err != NO_ERROR) {
81         return err;
82     }
83     err = output->writeInt64(latchTime);
84     if (err != NO_ERROR) {
85         return err;
86     }
87     if (presentFence) {
88         err = output->writeBool(true);
89         if (err != NO_ERROR) {
90             return err;
91         }
92         err = output->write(*presentFence);
93     } else {
94         err = output->writeBool(false);
95     }
96     if (err != NO_ERROR) {
97         return err;
98     }
99     return output->writeParcelableVector(surfaceStats);
100 }
101 
readFromParcel(const Parcel * input)102 status_t TransactionStats::readFromParcel(const Parcel* input) {
103     status_t err = input->readInt64Vector(&callbackIds);
104     if (err != NO_ERROR) {
105         return err;
106     }
107     err = input->readInt64(&latchTime);
108     if (err != NO_ERROR) {
109         return err;
110     }
111     bool hasFence = false;
112     err = input->readBool(&hasFence);
113     if (err != NO_ERROR) {
114         return err;
115     }
116     if (hasFence) {
117         presentFence = new Fence();
118         err = input->read(*presentFence);
119         if (err != NO_ERROR) {
120             return err;
121         }
122     }
123     return input->readParcelableVector(&surfaceStats);
124 }
125 
writeToParcel(Parcel * output) const126 status_t ListenerStats::writeToParcel(Parcel* output) const {
127     status_t err = output->writeInt32(static_cast<int32_t>(transactionStats.size()));
128     if (err != NO_ERROR) {
129         return err;
130     }
131     for (const auto& stats : transactionStats) {
132         err = output->writeParcelable(stats);
133         if (err != NO_ERROR) {
134             return err;
135         }
136     }
137     return NO_ERROR;
138 }
139 
readFromParcel(const Parcel * input)140 status_t ListenerStats::readFromParcel(const Parcel* input) {
141     int32_t transactionStats_size = input->readInt32();
142 
143     for (int i = 0; i < transactionStats_size; i++) {
144         TransactionStats stats;
145         status_t err = input->readParcelable(&stats);
146         if (err != NO_ERROR) {
147             return err;
148         }
149         transactionStats.push_back(stats);
150     }
151     return NO_ERROR;
152 }
153 
createEmpty(const sp<ITransactionCompletedListener> & listener,const std::unordered_set<CallbackId> & callbackIds)154 ListenerStats ListenerStats::createEmpty(const sp<ITransactionCompletedListener>& listener,
155                                          const std::unordered_set<CallbackId>& callbackIds) {
156     ListenerStats listenerStats;
157     listenerStats.listener = listener;
158     listenerStats.transactionStats.emplace_back(callbackIds);
159 
160     return listenerStats;
161 }
162 
163 class BpTransactionCompletedListener : public SafeBpInterface<ITransactionCompletedListener> {
164 public:
BpTransactionCompletedListener(const sp<IBinder> & impl)165     explicit BpTransactionCompletedListener(const sp<IBinder>& impl)
166           : SafeBpInterface<ITransactionCompletedListener>(impl, "BpTransactionCompletedListener") {
167     }
168 
169     ~BpTransactionCompletedListener() override;
170 
onTransactionCompleted(ListenerStats stats)171     void onTransactionCompleted(ListenerStats stats) override {
172         callRemoteAsync<decltype(&ITransactionCompletedListener::
173                                          onTransactionCompleted)>(Tag::ON_TRANSACTION_COMPLETED,
174                                                                   stats);
175     }
176 };
177 
178 // Out-of-line virtual method definitions to trigger vtable emission in this translation unit (see
179 // clang warning -Wweak-vtables)
180 BpTransactionCompletedListener::~BpTransactionCompletedListener() = default;
181 
182 IMPLEMENT_META_INTERFACE(TransactionCompletedListener, "android.gui.ITransactionComposerListener");
183 
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)184 status_t BnTransactionCompletedListener::onTransact(uint32_t code, const Parcel& data,
185                                                     Parcel* reply, uint32_t flags) {
186     if (code < IBinder::FIRST_CALL_TRANSACTION || code > static_cast<uint32_t>(Tag::LAST)) {
187         return BBinder::onTransact(code, data, reply, flags);
188     }
189     auto tag = static_cast<Tag>(code);
190     switch (tag) {
191         case Tag::ON_TRANSACTION_COMPLETED:
192             return callLocalAsync(data, reply,
193                                   &ITransactionCompletedListener::onTransactionCompleted);
194     }
195 }
196 
197 }; // namespace android
198