Home | History | Annotate | Download | only in common_time
      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     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(listener->asBinder());
    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(listener->asBinder());
    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
    434