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