blob: 28b43acff16a48f289c484628d57518a03509f4a [file] [log] [blame]
Mike J. Chen951bd8d2011-08-15 11:59:47 -07001/*
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