1951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen/*
2951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen * Copyright (C) 2011 The Android Open Source Project
3951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen *
4951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen * Licensed under the Apache License, Version 2.0 (the "License");
5951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen * you may not use this file except in compliance with the License.
6951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen * You may obtain a copy of the License at
7951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen *
8951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen *      http://www.apache.org/licenses/LICENSE-2.0
9951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen *
10951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen * Unless required by applicable law or agreed to in writing, software
11951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen * distributed under the License is distributed on an "AS IS" BASIS,
12951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen * See the License for the specific language governing permissions and
14951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen * limitations under the License.
15951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen */
16951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen
17951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen#include <stdint.h>
18951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen
19951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen#include <common_time/cc_helper.h>
20951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen#include <common_time/ICommonClock.h>
21951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen#include <utils/threads.h>
22951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen
23951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chennamespace android {
24951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen
25951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. ChenMutex CCHelper::lock_;
26951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chensp<ICommonClock> CCHelper::common_clock_;
27951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chensp<ICommonClockListener> CCHelper::common_clock_listener_;
28951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chenuint32_t CCHelper::ref_count_ = 0;
29951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen
30951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chenbool CCHelper::verifyClock_l() {
31951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen    bool ret = false;
32951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen
33951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen    if (common_clock_ == NULL) {
34951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen        common_clock_ = ICommonClock::getInstance();
35951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen        if (common_clock_ == NULL)
36951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen            goto bailout;
37951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen    }
38951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen
39951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen    if (ref_count_ > 0) {
40951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen        if (common_clock_listener_ == NULL) {
41951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen            common_clock_listener_ = new CommonClockListener();
42951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen            if (common_clock_listener_ == NULL)
43951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen                goto bailout;
44951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen
45951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen            if (OK != common_clock_->registerListener(common_clock_listener_))
46951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen                goto bailout;
47951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen        }
48951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen    }
49951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen
50951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen    ret = true;
51951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen
52951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chenbailout:
53951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen    if (!ret) {
54951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen        common_clock_listener_ = NULL;
55951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen        common_clock_ = NULL;
56951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen    }
57951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen    return ret;
58951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen}
59951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen
60951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. ChenCCHelper::CCHelper() {
61951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen    Mutex::Autolock lock(&lock_);
62951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen    ref_count_++;
63951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen    verifyClock_l();
64951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen}
65951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen
66951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. ChenCCHelper::~CCHelper() {
67951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen    Mutex::Autolock lock(&lock_);
68951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen
69951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen    assert(ref_count_ > 0);
70951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen    ref_count_--;
71951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen
72951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen    // If we were the last CCHelper instance in the system, and we had
73951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen    // previously register a listener, unregister it now so that the common time
74951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen    // service has the chance to go into auto-disabled mode.
75951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen    if (!ref_count_ &&
76951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen       (common_clock_ != NULL) &&
77951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen       (common_clock_listener_ != NULL)) {
78951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen        common_clock_->unregisterListener(common_clock_listener_);
79951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen        common_clock_listener_ = NULL;
80951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen    }
81951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen}
82951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen
83951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chenvoid CCHelper::CommonClockListener::onTimelineChanged(uint64_t timelineID) {
84951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen    // do nothing; listener is only really used as a token so the server can
85951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen    // find out when clients die.
86951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen}
87951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen
88951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen// Helper methods which attempts to make calls to the common time binder
89951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen// service.  If the first attempt fails with DEAD_OBJECT, the helpers will
90951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen// attempt to make a connection to the service again (assuming that the process
91951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen// hosting the service had crashed and the client proxy we are holding is dead)
92951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen// If the second attempt fails, or no connection can be made, the we let the
93951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen// error propagate up the stack and let the caller deal with the situation as
94951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen// best they can.
95951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen#define CCHELPER_METHOD(decl, call)                 \
96951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen    status_t CCHelper::decl {                       \
97951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen        Mutex::Autolock lock(&lock_);               \
98951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen                                                    \
99951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen        if (!verifyClock_l())                       \
100951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen            return DEAD_OBJECT;                     \
101951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen                                                    \
102951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen        status_t status = common_clock_->call;      \
103951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen        if (DEAD_OBJECT == status) {                \
104951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen            if (!verifyClock_l())                   \
105951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen                return DEAD_OBJECT;                 \
106951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen            status = common_clock_->call;           \
107951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen        }                                           \
108951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen                                                    \
109951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen        return status;                              \
110951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen    }
111951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen
112951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen#define VERIFY_CLOCK()
113951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen
114951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. ChenCCHELPER_METHOD(isCommonTimeValid(bool* valid, uint32_t* timelineID),
115951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen                isCommonTimeValid(valid, timelineID))
116951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. ChenCCHELPER_METHOD(commonTimeToLocalTime(int64_t commonTime, int64_t* localTime),
117951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen                commonTimeToLocalTime(commonTime, localTime))
118951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. ChenCCHELPER_METHOD(localTimeToCommonTime(int64_t localTime, int64_t* commonTime),
119951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen                localTimeToCommonTime(localTime, commonTime))
120951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. ChenCCHELPER_METHOD(getCommonTime(int64_t* commonTime),
121951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen                getCommonTime(commonTime))
122951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. ChenCCHELPER_METHOD(getCommonFreq(uint64_t* freq),
123951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen                getCommonFreq(freq))
124951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. ChenCCHELPER_METHOD(getLocalTime(int64_t* localTime),
125951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen                getLocalTime(localTime))
126951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. ChenCCHELPER_METHOD(getLocalFreq(uint64_t* freq),
127951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen                getLocalFreq(freq))
128951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen
129951bd8d1ad9581a414e171ad8605a9515d0ad667Mike J. Chen}  // namespace android
130