/* * 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 #include #include "common_clock_service.h" #include "common_clock.h" #include "common_time_server.h" namespace android { sp CommonClockService::instantiate( CommonTimeServer& timeServer) { sp tcc = new CommonClockService(timeServer); if (tcc == NULL) return NULL; defaultServiceManager()->addService(ICommonClock::kServiceName, tcc); return tcc; } status_t CommonClockService::dump(int fd, const Vector& args) { Mutex::Autolock lock(mRegistrationLock); return mTimeServer.dumpClockInterface(fd, args, mListeners.size()); } status_t CommonClockService::isCommonTimeValid(bool* valid, uint32_t* timelineID) { return mTimeServer.isCommonTimeValid(valid, timelineID); } status_t CommonClockService::commonTimeToLocalTime(int64_t commonTime, int64_t* localTime) { return mTimeServer.getCommonClock().commonToLocal(commonTime, localTime); } status_t CommonClockService::localTimeToCommonTime(int64_t localTime, int64_t* commonTime) { return mTimeServer.getCommonClock().localToCommon(localTime, commonTime); } status_t CommonClockService::getCommonTime(int64_t* commonTime) { return localTimeToCommonTime(mTimeServer.getLocalClock().getLocalTime(), commonTime); } status_t CommonClockService::getCommonFreq(uint64_t* freq) { *freq = mTimeServer.getCommonClock().getCommonFreq(); return OK; } status_t CommonClockService::getLocalTime(int64_t* localTime) { *localTime = mTimeServer.getLocalClock().getLocalTime(); return OK; } status_t CommonClockService::getLocalFreq(uint64_t* freq) { *freq = mTimeServer.getLocalClock().getLocalFreq(); return OK; } status_t CommonClockService::getEstimatedError(int32_t* estimate) { *estimate = mTimeServer.getEstimatedError(); return OK; } status_t CommonClockService::getTimelineID(uint64_t* id) { *id = mTimeServer.getTimelineID(); return OK; } status_t CommonClockService::getState(State* state) { *state = mTimeServer.getState(); return OK; } status_t CommonClockService::getMasterAddr(struct sockaddr_storage* addr) { return mTimeServer.getMasterAddr(addr); } status_t CommonClockService::registerListener( const sp& listener) { Mutex::Autolock lock(mRegistrationLock); { // scoping for autolock pattern Mutex::Autolock lock(mCallbackLock); // check whether this is a duplicate for (size_t i = 0; i < mListeners.size(); i++) { if (IInterface::asBinder(mListeners[i]) == IInterface::asBinder(listener)) return ALREADY_EXISTS; } } mListeners.add(listener); mTimeServer.reevaluateAutoDisableState(0 != mListeners.size()); return IInterface::asBinder(listener)->linkToDeath(this); } status_t CommonClockService::unregisterListener( const sp& listener) { Mutex::Autolock lock(mRegistrationLock); status_t ret_val = NAME_NOT_FOUND; { // scoping for autolock pattern Mutex::Autolock lock(mCallbackLock); for (size_t i = 0; i < mListeners.size(); i++) { if (IInterface::asBinder(mListeners[i]) == IInterface::asBinder(listener)) { IInterface::asBinder(mListeners[i])->unlinkToDeath(this); mListeners.removeAt(i); ret_val = OK; break; } } } mTimeServer.reevaluateAutoDisableState(0 != mListeners.size()); return ret_val; } void CommonClockService::binderDied(const wp& who) { Mutex::Autolock lock(mRegistrationLock); { // scoping for autolock pattern Mutex::Autolock lock(mCallbackLock); for (size_t i = 0; i < mListeners.size(); i++) { if (IInterface::asBinder(mListeners[i]) == who) { mListeners.removeAt(i); break; } } } mTimeServer.reevaluateAutoDisableState(0 != mListeners.size()); } void CommonClockService::notifyOnTimelineChanged(uint64_t timelineID) { Mutex::Autolock lock(mCallbackLock); for (size_t i = 0; i < mListeners.size(); i++) { mListeners[i]->onTimelineChanged(timelineID); } } }; // namespace android