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: 51 explicit 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()); 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 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 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 explicit 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 434