summaryrefslogtreecommitdiffstats
path: root/libs/common_time/cc_helper.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libs/common_time/cc_helper.cpp')
-rw-r--r--libs/common_time/cc_helper.cpp129
1 files changed, 129 insertions, 0 deletions
diff --git a/libs/common_time/cc_helper.cpp b/libs/common_time/cc_helper.cpp
new file mode 100644
index 0000000..8d8556c
--- /dev/null
+++ b/libs/common_time/cc_helper.cpp
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2011 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 <stdint.h>
+
+#include <common_time/cc_helper.h>
+#include <common_time/ICommonClock.h>
+#include <utils/threads.h>
+
+namespace android {
+
+Mutex CCHelper::lock_;
+sp<ICommonClock> CCHelper::common_clock_;
+sp<ICommonClockListener> CCHelper::common_clock_listener_;
+uint32_t CCHelper::ref_count_ = 0;
+
+bool CCHelper::verifyClock_l() {
+ bool ret = false;
+
+ if (common_clock_ == NULL) {
+ common_clock_ = ICommonClock::getInstance();
+ if (common_clock_ == NULL)
+ goto bailout;
+ }
+
+ if (ref_count_ > 0) {
+ if (common_clock_listener_ == NULL) {
+ common_clock_listener_ = new CommonClockListener();
+ if (common_clock_listener_ == NULL)
+ goto bailout;
+
+ if (OK != common_clock_->registerListener(common_clock_listener_))
+ goto bailout;
+ }
+ }
+
+ ret = true;
+
+bailout:
+ if (!ret) {
+ common_clock_listener_ = NULL;
+ common_clock_ = NULL;
+ }
+ return ret;
+}
+
+CCHelper::CCHelper() {
+ Mutex::Autolock lock(&lock_);
+ ref_count_++;
+ verifyClock_l();
+}
+
+CCHelper::~CCHelper() {
+ Mutex::Autolock lock(&lock_);
+
+ assert(ref_count_ > 0);
+ ref_count_--;
+
+ // If we were the last CCHelper instance in the system, and we had
+ // previously register a listener, unregister it now so that the common time
+ // service has the chance to go into auto-disabled mode.
+ if (!ref_count_ &&
+ (common_clock_ != NULL) &&
+ (common_clock_listener_ != NULL)) {
+ common_clock_->unregisterListener(common_clock_listener_);
+ common_clock_listener_ = NULL;
+ }
+}
+
+void CCHelper::CommonClockListener::onTimelineChanged(uint64_t timelineID) {
+ // do nothing; listener is only really used as a token so the server can
+ // find out when clients die.
+}
+
+// Helper methods which attempts to make calls to the common time binder
+// service. If the first attempt fails with DEAD_OBJECT, the helpers will
+// attempt to make a connection to the service again (assuming that the process
+// hosting the service had crashed and the client proxy we are holding is dead)
+// If the second attempt fails, or no connection can be made, the we let the
+// error propagate up the stack and let the caller deal with the situation as
+// best they can.
+#define CCHELPER_METHOD(decl, call) \
+ status_t CCHelper::decl { \
+ Mutex::Autolock lock(&lock_); \
+ \
+ if (!verifyClock_l()) \
+ return DEAD_OBJECT; \
+ \
+ status_t status = common_clock_->call; \
+ if (DEAD_OBJECT == status) { \
+ if (!verifyClock_l()) \
+ return DEAD_OBJECT; \
+ status = common_clock_->call; \
+ } \
+ \
+ return status; \
+ }
+
+#define VERIFY_CLOCK()
+
+CCHELPER_METHOD(isCommonTimeValid(bool* valid, uint32_t* timelineID),
+ isCommonTimeValid(valid, timelineID))
+CCHELPER_METHOD(commonTimeToLocalTime(int64_t commonTime, int64_t* localTime),
+ commonTimeToLocalTime(commonTime, localTime))
+CCHELPER_METHOD(localTimeToCommonTime(int64_t localTime, int64_t* commonTime),
+ localTimeToCommonTime(localTime, commonTime))
+CCHELPER_METHOD(getCommonTime(int64_t* commonTime),
+ getCommonTime(commonTime))
+CCHELPER_METHOD(getCommonFreq(uint64_t* freq),
+ getCommonFreq(freq))
+CCHELPER_METHOD(getLocalTime(int64_t* localTime),
+ getLocalTime(localTime))
+CCHELPER_METHOD(getLocalFreq(uint64_t* freq),
+ getLocalFreq(freq))
+
+} // namespace android