OSDN Git Service

Add marshallers for the new common clock methods.
authorJohn Grossman <johngro@google.com>
Wed, 18 Jan 2012 01:10:55 +0000 (17:10 -0800)
committerJohn Grossman <johngro@google.com>
Sat, 4 Feb 2012 01:45:53 +0000 (17:45 -0800)
Add marshallers and stub implementations for new methods in the common
clock interface to support new functionality being added in the
process of integrating the common time service more closely with the
Java level of Android.

Change-Id: Iac2d3fb405d1b64cea1d8e13f988160afb76a06d

include/common_time/ICommonClock.h
media/common_time/Android.mk
media/common_time/ICommonClock.cpp
media/common_time/utils.cpp [new file with mode: 0644]
media/common_time/utils.h [new file with mode: 0644]

index 65f0c01..d7073f1 100644 (file)
@@ -18,6 +18,7 @@
 #define ANDROID_ICOMMONCLOCK_H
 
 #include <stdint.h>
+#include <linux/socket.h>
 
 #include <binder/IInterface.h>
 #include <binder/IServiceManager.h>
@@ -28,8 +29,7 @@ class ICommonClockListener : public IInterface {
   public:
     DECLARE_META_INTERFACE(CommonClockListener);
 
-    virtual void onClockSync(uint32_t timelineID) = 0;
-    virtual void onClockSyncLoss() = 0;
+    virtual void onTimelineChanged(uint64_t timelineID) = 0;
 };
 
 class BnCommonClockListener : public BnInterface<ICommonClockListener> {
@@ -46,7 +46,28 @@ class ICommonClock : public IInterface {
     static const String16 kServiceName;
 
     // a reserved invalid timeline ID
-    static const uint32_t kInvalidTimelineID;
+    static const uint64_t kInvalidTimelineID;
+
+    // a reserved invalid error estimate
+    static const int32_t kErrorEstimateUnknown;
+
+    enum State {
+        // the device just came up and is trying to discover the master
+        STATE_INITIAL,
+
+        // the device is a client of a master
+        STATE_CLIENT,
+
+        // the device is acting as master
+        STATE_MASTER,
+
+        // the device has lost contact with its master and needs to participate
+        // in the election of a new master
+        STATE_RONIN,
+
+        // the device is waiting for announcement of the newly elected master
+        STATE_WAIT_FOR_ELECTION,
+    };
 
     virtual status_t isCommonTimeValid(bool* valid, uint32_t* timelineID) = 0;
     virtual status_t commonTimeToLocalTime(int64_t commonTime,
@@ -57,6 +78,10 @@ class ICommonClock : public IInterface {
     virtual status_t getCommonFreq(uint64_t* freq) = 0;
     virtual status_t getLocalTime(int64_t* localTime) = 0;
     virtual status_t getLocalFreq(uint64_t* freq) = 0;
+    virtual status_t getEstimatedError(int32_t* estimate) = 0;
+    virtual status_t getTimelineID(uint64_t* id) = 0;
+    virtual status_t getState(State* state) = 0;
+    virtual status_t getMasterAddr(struct sockaddr_storage* addr) = 0;
 
     virtual status_t registerListener(
             const sp<ICommonClockListener>& listener) = 0;
@@ -70,25 +95,6 @@ class ICommonClock : public IInterface {
         sp<ICommonClock> clk = interface_cast<ICommonClock>(binder);
         return clk;
     }
-
-    enum State {
-        // the device just came up and is trying to discover the master
-        STATE_INITIAL,
-
-        // the device is a client of a master
-        STATE_CLIENT,
-
-        // the device is acting as master
-        STATE_MASTER,
-
-        // the device has lost contact with its master and needs to participate
-        // in the election of a new master
-        STATE_RONIN,
-
-        // the device is waiting for announcement of the newly elected master
-        STATE_WAIT_FOR_ELECTION,
-    };
-
 };
 
 class BnCommonClock : public BnInterface<ICommonClock> {
index 1d484c2..6aa3597 100644 (file)
@@ -11,7 +11,8 @@ LOCAL_MODULE := libcommon_time_client
 LOCAL_MODULE_TAGS := optional
 LOCAL_SRC_FILES := cc_helper.cpp \
                    local_clock.cpp \
-                   ICommonClock.cpp
+                   ICommonClock.cpp \
+                   utils.cpp
 LOCAL_SHARED_LIBRARIES := libbinder \
                           libhardware \
                           libutils
index c7f4847..28b43ac 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011 The Android Open Source Project
+ * Copyright (C) 2012 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+#include <linux/socket.h>
 
 #include <common_time/ICommonClock.h>
 #include <binder/Parcel.h>
 
+#include "utils.h"
+
 namespace android {
 
 /***** ICommonClock *****/
@@ -29,12 +32,17 @@ enum {
     GET_COMMON_FREQ,
     GET_LOCAL_TIME,
     GET_LOCAL_FREQ,
+    GET_ESTIMATED_ERROR,
+    GET_TIMELINE_ID,
+    GET_STATE,
+    GET_MASTER_ADDRESS,
     REGISTER_LISTENER,
     UNREGISTER_LISTENER,
 };
 
 const String16 ICommonClock::kServiceName("common_time.clock");
 const uint64_t ICommonClock::kInvalidTimelineID = 0;
+const int32_t ICommonClock::kErrorEstimateUnknown = 0x7FFFFFFF;
 
 class BpCommonClock : public BpInterface<ICommonClock>
 {
@@ -142,6 +150,57 @@ class BpCommonClock : public BpInterface<ICommonClock>
         return status;
     }
 
+    virtual status_t getEstimatedError(int32_t* estimate) {
+        Parcel data, reply;
+        data.writeInterfaceToken(ICommonClock::getInterfaceDescriptor());
+        status_t status = remote()->transact(GET_ESTIMATED_ERROR, data, &reply);
+        if (status == OK) {
+            status = reply.readInt32();
+            if (status == OK) {
+                *estimate = reply.readInt32();
+            }
+        }
+        return status;
+    }
+
+    virtual status_t getTimelineID(uint64_t* id) {
+        Parcel data, reply;
+        data.writeInterfaceToken(ICommonClock::getInterfaceDescriptor());
+        status_t status = remote()->transact(GET_TIMELINE_ID, data, &reply);
+        if (status == OK) {
+            status = reply.readInt32();
+            if (status == OK) {
+                *id = static_cast<uint64_t>(reply.readInt64());
+            }
+        }
+        return status;
+    }
+
+    virtual status_t getState(State* state) {
+        Parcel data, reply;
+        data.writeInterfaceToken(ICommonClock::getInterfaceDescriptor());
+        status_t status = remote()->transact(GET_STATE, data, &reply);
+        if (status == OK) {
+            status = reply.readInt32();
+            if (status == OK) {
+                *state = static_cast<State>(reply.readInt32());
+            }
+        }
+        return status;
+    }
+
+    virtual status_t getMasterAddr(struct sockaddr_storage* addr) {
+        Parcel data, reply;
+        data.writeInterfaceToken(ICommonClock::getInterfaceDescriptor());
+        status_t status = remote()->transact(GET_MASTER_ADDRESS, data, &reply);
+        if (status == OK) {
+            status = reply.readInt32();
+            if (status == OK)
+                deserializeSockaddr(&reply, addr);
+        }
+        return status;
+    }
+
     virtual status_t registerListener(
             const sp<ICommonClockListener>& listener) {
         Parcel data, reply;
@@ -260,6 +319,57 @@ status_t BnCommonClock::onTransact(uint32_t code,
             return OK;
         } break;
 
+        case GET_ESTIMATED_ERROR: {
+            CHECK_INTERFACE(ICommonClock, data, reply);
+            int32_t error;
+            status_t status = getEstimatedError(&error);
+            reply->writeInt32(status);
+            if (status == OK) {
+                reply->writeInt32(error);
+            }
+            return OK;
+        } break;
+
+        case GET_TIMELINE_ID: {
+            CHECK_INTERFACE(ICommonClock, data, reply);
+            uint64_t id;
+            status_t status = getTimelineID(&id);
+            reply->writeInt32(status);
+            if (status == OK) {
+                reply->writeInt64(static_cast<int64_t>(id));
+            }
+            return OK;
+        } break;
+
+        case GET_STATE: {
+            CHECK_INTERFACE(ICommonClock, data, reply);
+            State state;
+            status_t status = getState(&state);
+            reply->writeInt32(status);
+            if (status == OK) {
+                reply->writeInt32(static_cast<int32_t>(state));
+            }
+            return OK;
+        } break;
+
+        case GET_MASTER_ADDRESS: {
+            CHECK_INTERFACE(ICommonClock, data, reply);
+            struct sockaddr_storage addr;
+            status_t status = getMasterAddr(&addr);
+
+            if ((status == OK) && !canSerializeSockaddr(&addr)) {
+                status = UNKNOWN_ERROR;
+            }
+
+            reply->writeInt32(status);
+
+            if (status == OK) {
+                serializeSockaddr(reply, &addr);
+            }
+
+            return OK;
+        } break;
+
         case REGISTER_LISTENER: {
             CHECK_INTERFACE(ICommonClock, data, reply);
             sp<ICommonClockListener> listener =
@@ -284,8 +394,7 @@ status_t BnCommonClock::onTransact(uint32_t code,
 /***** ICommonClockListener *****/
 
 enum {
-    ON_CLOCK_SYNC = IBinder::FIRST_CALL_TRANSACTION,
-    ON_CLOCK_SYNC_LOSS,
+    ON_TIMELINE_CHANGED = IBinder::FIRST_CALL_TRANSACTION,
 };
 
 class BpCommonClockListener : public BpInterface<ICommonClockListener>
@@ -294,19 +403,12 @@ class BpCommonClockListener : public BpInterface<ICommonClockListener>
     BpCommonClockListener(const sp<IBinder>& impl)
         : BpInterface<ICommonClockListener>(impl) {}
 
-    virtual void onClockSync(uint32_t timelineID) {
-        Parcel data, reply;
-        data.writeInterfaceToken(
-                ICommonClockListener::getInterfaceDescriptor());
-        data.writeInt32(timelineID);
-        remote()->transact(ON_CLOCK_SYNC, data, &reply);
-    }
-
-    virtual void onClockSyncLoss() {
+    virtual void onTimelineChanged(uint64_t timelineID) {
         Parcel data, reply;
         data.writeInterfaceToken(
                 ICommonClockListener::getInterfaceDescriptor());
-        remote()->transact(ON_CLOCK_SYNC_LOSS, data, &reply);
+        data.writeInt64(timelineID);
+        remote()->transact(ON_TIMELINE_CHANGED, data, &reply);
     }
 };
 
@@ -316,16 +418,10 @@ IMPLEMENT_META_INTERFACE(CommonClockListener,
 status_t BnCommonClockListener::onTransact(
         uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
     switch(code) {
-        case ON_CLOCK_SYNC: {
-            CHECK_INTERFACE(ICommonClockListener, data, reply);
-            uint32_t timelineID = data.readInt32();
-            onClockSync(timelineID);
-            return NO_ERROR;
-        } break;
-
-        case ON_CLOCK_SYNC_LOSS: {
+        case ON_TIMELINE_CHANGED: {
             CHECK_INTERFACE(ICommonClockListener, data, reply);
-            onClockSyncLoss();
+            uint32_t timelineID = data.readInt64();
+            onTimelineChanged(timelineID);
             return NO_ERROR;
         } break;
     }
diff --git a/media/common_time/utils.cpp b/media/common_time/utils.cpp
new file mode 100644 (file)
index 0000000..6539171
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <arpa/inet.h>
+#include <linux/socket.h>
+
+#include <binder/Parcel.h>
+
+namespace android {
+
+bool canSerializeSockaddr(const struct sockaddr_storage* addr) {
+    switch (addr->ss_family) {
+        case AF_INET:
+        case AF_INET6:
+            return true;
+        default:
+            return false;
+    }
+}
+
+void serializeSockaddr(Parcel* p, const struct sockaddr_storage* addr) {
+    switch (addr->ss_family) {
+        case AF_INET: {
+            const struct sockaddr_in* s =
+                reinterpret_cast<const struct sockaddr_in*>(addr);
+            p->writeInt32(AF_INET);
+            p->writeInt32(ntohl(s->sin_addr.s_addr));
+            p->writeInt32(static_cast<int32_t>(ntohs(s->sin_port)));
+        } break;
+
+        case AF_INET6: {
+            const struct sockaddr_in6* s =
+                reinterpret_cast<const struct sockaddr_in6*>(addr);
+            const int32_t* a =
+                reinterpret_cast<const int32_t*>(s->sin6_addr.s6_addr);
+            p->writeInt32(AF_INET6);
+            p->writeInt32(ntohl(a[0]));
+            p->writeInt32(ntohl(a[1]));
+            p->writeInt32(ntohl(a[2]));
+            p->writeInt32(ntohl(a[3]));
+            p->writeInt32(static_cast<int32_t>(ntohs(s->sin6_port)));
+            p->writeInt32(ntohl(s->sin6_flowinfo));
+            p->writeInt32(ntohl(s->sin6_scope_id));
+        } break;
+    }
+}
+
+void deserializeSockaddr(const Parcel* p, struct sockaddr_storage* addr) {
+    memset(addr, 0, sizeof(addr));
+
+    addr->ss_family = p->readInt32();
+    switch(addr->ss_family) {
+        case AF_INET: {
+            struct sockaddr_in* s =
+                reinterpret_cast<struct sockaddr_in*>(addr);
+            s->sin_addr.s_addr = htonl(p->readInt32());
+            s->sin_port = htons(static_cast<uint16_t>(p->readInt32()));
+        } break;
+
+        case AF_INET6: {
+            struct sockaddr_in6* s =
+                reinterpret_cast<struct sockaddr_in6*>(addr);
+            int32_t* a = reinterpret_cast<int32_t*>(s->sin6_addr.s6_addr);
+
+            a[0] = htonl(p->readInt32());
+            a[1] = htonl(p->readInt32());
+            a[2] = htonl(p->readInt32());
+            a[3] = htonl(p->readInt32());
+            s->sin6_port = htons(static_cast<uint16_t>(p->readInt32()));
+            s->sin6_flowinfo = htonl(p->readInt32());
+            s->sin6_scope_id = htonl(p->readInt32());
+        } break;
+    }
+}
+
+}  // namespace android
diff --git a/media/common_time/utils.h b/media/common_time/utils.h
new file mode 100644 (file)
index 0000000..ce79d0d
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_LIBCOMMONCLOCK_UTILS_H
+#define ANDROID_LIBCOMMONCLOCK_UTILS_H
+
+#include <linux/socket.h>
+
+#include <binder/Parcel.h>
+#include <utils/Errors.h>
+
+namespace android {
+
+extern bool canSerializeSockaddr(const struct sockaddr_storage* addr);
+extern void serializeSockaddr(Parcel* p, const struct sockaddr_storage* addr);
+extern status_t deserializeSockaddr(const Parcel* p,
+                                    struct sockaddr_storage* addr);
+
+};  // namespace android
+
+#endif  // ANDROID_LIBCOMMONCLOCK_UTILS_H