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