| Mike J. Chen | 951bd8d | 2011-08-15 11:59:47 -0700 | [diff] [blame] | 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 |  */ | 
| Elliott Hughes | e5167f8 | 2012-09-11 18:47:53 -0700 | [diff] [blame] | 16 |  | 
 | 17 | #include <sys/socket.h> | 
| Mike J. Chen | 951bd8d | 2011-08-15 11:59:47 -0700 | [diff] [blame] | 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: | 
 | 51 |     BpCommonClock(const sp<IBinder>& impl) | 
 | 52 |         : BpInterface<ICommonClock>(impl) {} | 
 | 53 |  | 
 | 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 |  | 
 | 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 |  | 
 | 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 |  | 
 | 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 |  | 
 | 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 |  | 
 | 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 |  | 
 | 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 |  | 
 | 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 |  | 
 | 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 |  | 
 | 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 |  | 
 | 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 |  | 
 | 205 |     virtual status_t registerListener( | 
 | 206 |             const sp<ICommonClockListener>& listener) { | 
 | 207 |         Parcel data, reply; | 
 | 208 |         data.writeInterfaceToken(ICommonClock::getInterfaceDescriptor()); | 
| Marco Nelissen | 06b4606 | 2014-11-14 07:58:25 -0800 | [diff] [blame] | 209 |         data.writeStrongBinder(IInterface::asBinder(listener)); | 
| Mike J. Chen | 951bd8d | 2011-08-15 11:59:47 -0700 | [diff] [blame] | 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 |  | 
 | 220 |     virtual status_t unregisterListener( | 
 | 221 |             const sp<ICommonClockListener>& listener) { | 
 | 222 |         Parcel data, reply; | 
 | 223 |         data.writeInterfaceToken(ICommonClock::getInterfaceDescriptor()); | 
| Marco Nelissen | 06b4606 | 2014-11-14 07:58:25 -0800 | [diff] [blame] | 224 |         data.writeStrongBinder(IInterface::asBinder(listener)); | 
| Mike J. Chen | 951bd8d | 2011-08-15 11:59:47 -0700 | [diff] [blame] | 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 |  | 
 | 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: | 
 | 404 |     BpCommonClockListener(const sp<IBinder>& impl) | 
 | 405 |         : BpInterface<ICommonClockListener>(impl) {} | 
 | 406 |  | 
 | 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 |  | 
 | 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 |