1 /*
2 * Copyright (C) 2012 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 #include <sys/socket.h>
18
19 #include <common_time/ICommonClock.h>
20 #include <binder/Parcel.h>
21
22 #include "utils.h"
23
24 namespace android {
25
26 /***** ICommonClock *****/
27
28 enum {
29 IS_COMMON_TIME_VALID = IBinder::FIRST_CALL_TRANSACTION,
30 COMMON_TIME_TO_LOCAL_TIME,
31 LOCAL_TIME_TO_COMMON_TIME,
32 GET_COMMON_TIME,
33 GET_COMMON_FREQ,
34 GET_LOCAL_TIME,
35 GET_LOCAL_FREQ,
36 GET_ESTIMATED_ERROR,
37 GET_TIMELINE_ID,
38 GET_STATE,
39 GET_MASTER_ADDRESS,
40 REGISTER_LISTENER,
41 UNREGISTER_LISTENER,
42 };
43
44 const String16 ICommonClock::kServiceName("common_time.clock");
45 const uint64_t ICommonClock::kInvalidTimelineID = 0;
46 const int32_t ICommonClock::kErrorEstimateUnknown = 0x7FFFFFFF;
47
48 class BpCommonClock : public BpInterface<ICommonClock>
49 {
50 public:
BpCommonClock(const sp<IBinder> & impl)51 BpCommonClock(const sp<IBinder>& impl)
52 : BpInterface<ICommonClock>(impl) {}
53
isCommonTimeValid(bool * valid,uint32_t * timelineID)54 virtual status_t isCommonTimeValid(bool* valid, uint32_t* timelineID) {
55 Parcel data, reply;
56 data.writeInterfaceToken(ICommonClock::getInterfaceDescriptor());
57 status_t status = remote()->transact(IS_COMMON_TIME_VALID,
58 data,
59 &reply);
60 if (status == OK) {
61 status = reply.readInt32();
62 if (status == OK) {
63 *valid = reply.readInt32();
64 *timelineID = reply.readInt32();
65 }
66 }
67 return status;
68 }
69
commonTimeToLocalTime(int64_t commonTime,int64_t * localTime)70 virtual status_t commonTimeToLocalTime(int64_t commonTime,
71 int64_t* localTime) {
72 Parcel data, reply;
73 data.writeInterfaceToken(ICommonClock::getInterfaceDescriptor());
74 data.writeInt64(commonTime);
75 status_t status = remote()->transact(COMMON_TIME_TO_LOCAL_TIME,
76 data, &reply);
77 if (status == OK) {
78 status = reply.readInt32();
79 if (status == OK) {
80 *localTime = reply.readInt64();
81 }
82 }
83 return status;
84 }
85
localTimeToCommonTime(int64_t localTime,int64_t * commonTime)86 virtual status_t localTimeToCommonTime(int64_t localTime,
87 int64_t* commonTime) {
88 Parcel data, reply;
89 data.writeInterfaceToken(ICommonClock::getInterfaceDescriptor());
90 data.writeInt64(localTime);
91 status_t status = remote()->transact(LOCAL_TIME_TO_COMMON_TIME,
92 data, &reply);
93 if (status == OK) {
94 status = reply.readInt32();
95 if (status == OK) {
96 *commonTime = reply.readInt64();
97 }
98 }
99 return status;
100 }
101
getCommonTime(int64_t * commonTime)102 virtual status_t getCommonTime(int64_t* commonTime) {
103 Parcel data, reply;
104 data.writeInterfaceToken(ICommonClock::getInterfaceDescriptor());
105 status_t status = remote()->transact(GET_COMMON_TIME, data, &reply);
106 if (status == OK) {
107 status = reply.readInt32();
108 if (status == OK) {
109 *commonTime = reply.readInt64();
110 }
111 }
112 return status;
113 }
114
getCommonFreq(uint64_t * freq)115 virtual status_t getCommonFreq(uint64_t* freq) {
116 Parcel data, reply;
117 data.writeInterfaceToken(ICommonClock::getInterfaceDescriptor());
118 status_t status = remote()->transact(GET_COMMON_FREQ, data, &reply);
119 if (status == OK) {
120 status = reply.readInt32();
121 if (status == OK) {
122 *freq = reply.readInt64();
123 }
124 }
125 return status;
126 }
127
getLocalTime(int64_t * localTime)128 virtual status_t getLocalTime(int64_t* localTime) {
129 Parcel data, reply;
130 data.writeInterfaceToken(ICommonClock::getInterfaceDescriptor());
131 status_t status = remote()->transact(GET_LOCAL_TIME, data, &reply);
132 if (status == OK) {
133 status = reply.readInt32();
134 if (status == OK) {
135 *localTime = reply.readInt64();
136 }
137 }
138 return status;
139 }
140
getLocalFreq(uint64_t * freq)141 virtual status_t getLocalFreq(uint64_t* freq) {
142 Parcel data, reply;
143 data.writeInterfaceToken(ICommonClock::getInterfaceDescriptor());
144 status_t status = remote()->transact(GET_LOCAL_FREQ, data, &reply);
145 if (status == OK) {
146 status = reply.readInt32();
147 if (status == OK) {
148 *freq = reply.readInt64();
149 }
150 }
151 return status;
152 }
153
getEstimatedError(int32_t * estimate)154 virtual status_t getEstimatedError(int32_t* estimate) {
155 Parcel data, reply;
156 data.writeInterfaceToken(ICommonClock::getInterfaceDescriptor());
157 status_t status = remote()->transact(GET_ESTIMATED_ERROR, data, &reply);
158 if (status == OK) {
159 status = reply.readInt32();
160 if (status == OK) {
161 *estimate = reply.readInt32();
162 }
163 }
164 return status;
165 }
166
getTimelineID(uint64_t * id)167 virtual status_t getTimelineID(uint64_t* id) {
168 Parcel data, reply;
169 data.writeInterfaceToken(ICommonClock::getInterfaceDescriptor());
170 status_t status = remote()->transact(GET_TIMELINE_ID, data, &reply);
171 if (status == OK) {
172 status = reply.readInt32();
173 if (status == OK) {
174 *id = static_cast<uint64_t>(reply.readInt64());
175 }
176 }
177 return status;
178 }
179
getState(State * state)180 virtual status_t getState(State* state) {
181 Parcel data, reply;
182 data.writeInterfaceToken(ICommonClock::getInterfaceDescriptor());
183 status_t status = remote()->transact(GET_STATE, data, &reply);
184 if (status == OK) {
185 status = reply.readInt32();
186 if (status == OK) {
187 *state = static_cast<State>(reply.readInt32());
188 }
189 }
190 return status;
191 }
192
getMasterAddr(struct sockaddr_storage * addr)193 virtual status_t getMasterAddr(struct sockaddr_storage* addr) {
194 Parcel data, reply;
195 data.writeInterfaceToken(ICommonClock::getInterfaceDescriptor());
196 status_t status = remote()->transact(GET_MASTER_ADDRESS, data, &reply);
197 if (status == OK) {
198 status = reply.readInt32();
199 if (status == OK)
200 deserializeSockaddr(&reply, addr);
201 }
202 return status;
203 }
204
registerListener(const sp<ICommonClockListener> & listener)205 virtual status_t registerListener(
206 const sp<ICommonClockListener>& listener) {
207 Parcel data, reply;
208 data.writeInterfaceToken(ICommonClock::getInterfaceDescriptor());
209 data.writeStrongBinder(IInterface::asBinder(listener));
210
211 status_t status = remote()->transact(REGISTER_LISTENER, data, &reply);
212
213 if (status == OK) {
214 status = reply.readInt32();
215 }
216
217 return status;
218 }
219
unregisterListener(const sp<ICommonClockListener> & listener)220 virtual status_t unregisterListener(
221 const sp<ICommonClockListener>& listener) {
222 Parcel data, reply;
223 data.writeInterfaceToken(ICommonClock::getInterfaceDescriptor());
224 data.writeStrongBinder(IInterface::asBinder(listener));
225 status_t status = remote()->transact(UNREGISTER_LISTENER, data, &reply);
226
227 if (status == OK) {
228 status = reply.readInt32();
229 }
230
231 return status;
232 }
233 };
234
235 IMPLEMENT_META_INTERFACE(CommonClock, "android.os.ICommonClock");
236
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)237 status_t BnCommonClock::onTransact(uint32_t code,
238 const Parcel& data,
239 Parcel* reply,
240 uint32_t flags) {
241 switch(code) {
242 case IS_COMMON_TIME_VALID: {
243 CHECK_INTERFACE(ICommonClock, data, reply);
244 bool valid;
245 uint32_t timelineID;
246 status_t status = isCommonTimeValid(&valid, &timelineID);
247 reply->writeInt32(status);
248 if (status == OK) {
249 reply->writeInt32(valid);
250 reply->writeInt32(timelineID);
251 }
252 return OK;
253 } break;
254
255 case COMMON_TIME_TO_LOCAL_TIME: {
256 CHECK_INTERFACE(ICommonClock, data, reply);
257 int64_t commonTime = data.readInt64();
258 int64_t localTime;
259 status_t status = commonTimeToLocalTime(commonTime, &localTime);
260 reply->writeInt32(status);
261 if (status == OK) {
262 reply->writeInt64(localTime);
263 }
264 return OK;
265 } break;
266
267 case LOCAL_TIME_TO_COMMON_TIME: {
268 CHECK_INTERFACE(ICommonClock, data, reply);
269 int64_t localTime = data.readInt64();
270 int64_t commonTime;
271 status_t status = localTimeToCommonTime(localTime, &commonTime);
272 reply->writeInt32(status);
273 if (status == OK) {
274 reply->writeInt64(commonTime);
275 }
276 return OK;
277 } break;
278
279 case GET_COMMON_TIME: {
280 CHECK_INTERFACE(ICommonClock, data, reply);
281 int64_t commonTime;
282 status_t status = getCommonTime(&commonTime);
283 reply->writeInt32(status);
284 if (status == OK) {
285 reply->writeInt64(commonTime);
286 }
287 return OK;
288 } break;
289
290 case GET_COMMON_FREQ: {
291 CHECK_INTERFACE(ICommonClock, data, reply);
292 uint64_t freq;
293 status_t status = getCommonFreq(&freq);
294 reply->writeInt32(status);
295 if (status == OK) {
296 reply->writeInt64(freq);
297 }
298 return OK;
299 } break;
300
301 case GET_LOCAL_TIME: {
302 CHECK_INTERFACE(ICommonClock, data, reply);
303 int64_t localTime;
304 status_t status = getLocalTime(&localTime);
305 reply->writeInt32(status);
306 if (status == OK) {
307 reply->writeInt64(localTime);
308 }
309 return OK;
310 } break;
311
312 case GET_LOCAL_FREQ: {
313 CHECK_INTERFACE(ICommonClock, data, reply);
314 uint64_t freq;
315 status_t status = getLocalFreq(&freq);
316 reply->writeInt32(status);
317 if (status == OK) {
318 reply->writeInt64(freq);
319 }
320 return OK;
321 } break;
322
323 case GET_ESTIMATED_ERROR: {
324 CHECK_INTERFACE(ICommonClock, data, reply);
325 int32_t error;
326 status_t status = getEstimatedError(&error);
327 reply->writeInt32(status);
328 if (status == OK) {
329 reply->writeInt32(error);
330 }
331 return OK;
332 } break;
333
334 case GET_TIMELINE_ID: {
335 CHECK_INTERFACE(ICommonClock, data, reply);
336 uint64_t id;
337 status_t status = getTimelineID(&id);
338 reply->writeInt32(status);
339 if (status == OK) {
340 reply->writeInt64(static_cast<int64_t>(id));
341 }
342 return OK;
343 } break;
344
345 case GET_STATE: {
346 CHECK_INTERFACE(ICommonClock, data, reply);
347 State state;
348 status_t status = getState(&state);
349 reply->writeInt32(status);
350 if (status == OK) {
351 reply->writeInt32(static_cast<int32_t>(state));
352 }
353 return OK;
354 } break;
355
356 case GET_MASTER_ADDRESS: {
357 CHECK_INTERFACE(ICommonClock, data, reply);
358 struct sockaddr_storage addr;
359 status_t status = getMasterAddr(&addr);
360
361 if ((status == OK) && !canSerializeSockaddr(&addr)) {
362 status = UNKNOWN_ERROR;
363 }
364
365 reply->writeInt32(status);
366
367 if (status == OK) {
368 serializeSockaddr(reply, &addr);
369 }
370
371 return OK;
372 } break;
373
374 case REGISTER_LISTENER: {
375 CHECK_INTERFACE(ICommonClock, data, reply);
376 sp<ICommonClockListener> listener =
377 interface_cast<ICommonClockListener>(data.readStrongBinder());
378 status_t status = registerListener(listener);
379 reply->writeInt32(status);
380 return OK;
381 } break;
382
383 case UNREGISTER_LISTENER: {
384 CHECK_INTERFACE(ICommonClock, data, reply);
385 sp<ICommonClockListener> listener =
386 interface_cast<ICommonClockListener>(data.readStrongBinder());
387 status_t status = unregisterListener(listener);
388 reply->writeInt32(status);
389 return OK;
390 } break;
391 }
392 return BBinder::onTransact(code, data, reply, flags);
393 }
394
395 /***** ICommonClockListener *****/
396
397 enum {
398 ON_TIMELINE_CHANGED = IBinder::FIRST_CALL_TRANSACTION,
399 };
400
401 class BpCommonClockListener : public BpInterface<ICommonClockListener>
402 {
403 public:
BpCommonClockListener(const sp<IBinder> & impl)404 BpCommonClockListener(const sp<IBinder>& impl)
405 : BpInterface<ICommonClockListener>(impl) {}
406
onTimelineChanged(uint64_t timelineID)407 virtual void onTimelineChanged(uint64_t timelineID) {
408 Parcel data, reply;
409 data.writeInterfaceToken(
410 ICommonClockListener::getInterfaceDescriptor());
411 data.writeInt64(timelineID);
412 remote()->transact(ON_TIMELINE_CHANGED, data, &reply);
413 }
414 };
415
416 IMPLEMENT_META_INTERFACE(CommonClockListener,
417 "android.os.ICommonClockListener");
418
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)419 status_t BnCommonClockListener::onTransact(
420 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
421 switch(code) {
422 case ON_TIMELINE_CHANGED: {
423 CHECK_INTERFACE(ICommonClockListener, data, reply);
424 uint32_t timelineID = data.readInt64();
425 onTimelineChanged(timelineID);
426 return NO_ERROR;
427 } break;
428 }
429
430 return BBinder::onTransact(code, data, reply, flags);
431 }
432
433 }; // namespace android
434