1 /*
2  * Copyright (C) 2011 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <common_time/local_clock.h>
18 #include <utils/String8.h>
19 
20 #include "common_clock_service.h"
21 #include "common_clock.h"
22 #include "common_time_server.h"
23 
24 namespace android {
25 
instantiate(CommonTimeServer & timeServer)26 sp<CommonClockService> CommonClockService::instantiate(
27         CommonTimeServer& timeServer) {
28     sp<CommonClockService> tcc = new CommonClockService(timeServer);
29     if (tcc == NULL)
30         return NULL;
31 
32     defaultServiceManager()->addService(ICommonClock::kServiceName, tcc);
33     return tcc;
34 }
35 
dump(int fd,const Vector<String16> & args)36 status_t CommonClockService::dump(int fd, const Vector<String16>& args) {
37     Mutex::Autolock lock(mRegistrationLock);
38     return mTimeServer.dumpClockInterface(fd, args, mListeners.size());
39 }
40 
isCommonTimeValid(bool * valid,uint32_t * timelineID)41 status_t CommonClockService::isCommonTimeValid(bool* valid,
42                                                uint32_t* timelineID) {
43     return mTimeServer.isCommonTimeValid(valid, timelineID);
44 }
45 
commonTimeToLocalTime(int64_t commonTime,int64_t * localTime)46 status_t CommonClockService::commonTimeToLocalTime(int64_t  commonTime,
47                                                    int64_t* localTime) {
48     return mTimeServer.getCommonClock().commonToLocal(commonTime, localTime);
49 }
50 
localTimeToCommonTime(int64_t localTime,int64_t * commonTime)51 status_t CommonClockService::localTimeToCommonTime(int64_t  localTime,
52                                                    int64_t* commonTime) {
53     return mTimeServer.getCommonClock().localToCommon(localTime, commonTime);
54 }
55 
getCommonTime(int64_t * commonTime)56 status_t CommonClockService::getCommonTime(int64_t* commonTime) {
57     return localTimeToCommonTime(mTimeServer.getLocalClock().getLocalTime(), commonTime);
58 }
59 
getCommonFreq(uint64_t * freq)60 status_t CommonClockService::getCommonFreq(uint64_t* freq) {
61     *freq = mTimeServer.getCommonClock().getCommonFreq();
62     return OK;
63 }
64 
getLocalTime(int64_t * localTime)65 status_t CommonClockService::getLocalTime(int64_t* localTime) {
66     *localTime = mTimeServer.getLocalClock().getLocalTime();
67     return OK;
68 }
69 
getLocalFreq(uint64_t * freq)70 status_t CommonClockService::getLocalFreq(uint64_t* freq) {
71     *freq = mTimeServer.getLocalClock().getLocalFreq();
72     return OK;
73 }
74 
getEstimatedError(int32_t * estimate)75 status_t CommonClockService::getEstimatedError(int32_t* estimate) {
76     *estimate = mTimeServer.getEstimatedError();
77     return OK;
78 }
79 
getTimelineID(uint64_t * id)80 status_t CommonClockService::getTimelineID(uint64_t* id) {
81     *id = mTimeServer.getTimelineID();
82     return OK;
83 }
84 
getState(State * state)85 status_t CommonClockService::getState(State* state) {
86     *state = mTimeServer.getState();
87     return OK;
88 }
89 
getMasterAddr(struct sockaddr_storage * addr)90 status_t CommonClockService::getMasterAddr(struct sockaddr_storage* addr) {
91     return mTimeServer.getMasterAddr(addr);
92 }
93 
registerListener(const sp<ICommonClockListener> & listener)94 status_t CommonClockService::registerListener(
95         const sp<ICommonClockListener>& listener) {
96     Mutex::Autolock lock(mRegistrationLock);
97 
98     {   // scoping for autolock pattern
99         Mutex::Autolock lock(mCallbackLock);
100         // check whether this is a duplicate
101         for (size_t i = 0; i < mListeners.size(); i++) {
102             if (IInterface::asBinder(mListeners[i]) == IInterface::asBinder(listener))
103                 return ALREADY_EXISTS;
104         }
105     }
106 
107     mListeners.add(listener);
108     mTimeServer.reevaluateAutoDisableState(0 != mListeners.size());
109     return IInterface::asBinder(listener)->linkToDeath(this);
110 }
111 
unregisterListener(const sp<ICommonClockListener> & listener)112 status_t CommonClockService::unregisterListener(
113         const sp<ICommonClockListener>& listener) {
114     Mutex::Autolock lock(mRegistrationLock);
115     status_t ret_val = NAME_NOT_FOUND;
116 
117     {   // scoping for autolock pattern
118         Mutex::Autolock lock(mCallbackLock);
119         for (size_t i = 0; i < mListeners.size(); i++) {
120             if (IInterface::asBinder(mListeners[i]) == IInterface::asBinder(listener)) {
121                 IInterface::asBinder(mListeners[i])->unlinkToDeath(this);
122                 mListeners.removeAt(i);
123                 ret_val = OK;
124                 break;
125             }
126         }
127     }
128 
129     mTimeServer.reevaluateAutoDisableState(0 != mListeners.size());
130     return ret_val;
131 }
132 
binderDied(const wp<IBinder> & who)133 void CommonClockService::binderDied(const wp<IBinder>& who) {
134     Mutex::Autolock lock(mRegistrationLock);
135 
136     {   // scoping for autolock pattern
137         Mutex::Autolock lock(mCallbackLock);
138         for (size_t i = 0; i < mListeners.size(); i++) {
139             if (IInterface::asBinder(mListeners[i]) == who) {
140                 mListeners.removeAt(i);
141                 break;
142             }
143         }
144     }
145 
146     mTimeServer.reevaluateAutoDisableState(0 != mListeners.size());
147 }
148 
notifyOnTimelineChanged(uint64_t timelineID)149 void CommonClockService::notifyOnTimelineChanged(uint64_t timelineID) {
150     Mutex::Autolock lock(mCallbackLock);
151 
152     for (size_t i = 0; i < mListeners.size(); i++) {
153         mListeners[i]->onTimelineChanged(timelineID);
154     }
155 }
156 
157 }; // namespace android
158