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