| /* |
| * 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 <common_time/local_clock.h> |
| #include <utils/String8.h> |
| |
| #include "common_clock_service.h" |
| #include "common_clock.h" |
| #include "common_time_server.h" |
| |
| namespace android { |
| |
| sp<CommonClockService> CommonClockService::instantiate( |
| CommonTimeServer& timeServer) { |
| sp<CommonClockService> tcc = new CommonClockService(timeServer); |
| if (tcc == NULL) |
| return NULL; |
| |
| defaultServiceManager()->addService(ICommonClock::kServiceName, tcc); |
| return tcc; |
| } |
| |
| status_t CommonClockService::dump(int fd, const Vector<String16>& 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<ICommonClockListener>& 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<ICommonClockListener>& 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<IBinder>& 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 |