2 * Copyright (c) 2019 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include <dali/internal/system/common/timer-impl.h>
22 #include <dali/integration-api/adaptor-framework/android/android-framework.h>
25 #include <dali/internal/adaptor/common/adaptor-impl.h>
26 #include <dali/internal/adaptor/common/framework.h>
27 #include <dali/internal/adaptor/android/android-framework-impl.h>
28 #include <dali/public-api/dali-adaptor-common.h>
43 // Copied from x server
44 static unsigned int GetCurrentMilliSeconds()
49 static clockid_t clockid;
53 #ifdef CLOCK_MONOTONIC_COARSE
54 if (clock_getres(CLOCK_MONOTONIC_COARSE, &tp) == 0 &&
55 (tp.tv_nsec / 1000) <= 1000 && clock_gettime(CLOCK_MONOTONIC_COARSE, &tp) == 0)
57 clockid = CLOCK_MONOTONIC_COARSE;
61 if (clock_gettime(CLOCK_MONOTONIC, &tp) == 0)
63 clockid = CLOCK_MONOTONIC;
70 if (clockid != ~0L && clock_gettime(clockid, &tp) == 0)
72 return (tp.tv_sec * 1000) + (tp.tv_nsec / 1000000L);
75 gettimeofday(&tv, NULL);
76 return (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
83 Impl( unsigned int milliSec )
84 : mInterval( milliSec ),
92 unsigned int mInterval;
93 unsigned int mStartTimestamp;
94 unsigned int mPauseTimestamp;
99 TimerPtr Timer::New( unsigned int milliSec )
101 TimerPtr timer( new Timer( milliSec ) );
105 Timer::Timer( unsigned int milliSec )
106 : mImpl( new Impl( milliSec ) )
116 bool TimerCallback( void *data )
118 Timer* timer = static_cast<Timer*>( data );
119 if( timer->IsRunning() )
121 return timer->Tick();
129 // Timer should be used in the event thread
130 DALI_ASSERT_DEBUG( Adaptor::IsAvailable() );
132 if( mImpl->mRunning )
137 mImpl->mId = AndroidFramework::GetFramework( Dali::Integration::AndroidFramework::Get() ).AddIdle( mImpl->mInterval, this, TimerCallback );
138 mImpl->mRunning = true;
139 mImpl->mStartTimestamp = GetCurrentMilliSeconds();
144 // Timer should be used in the event thread
145 DALI_ASSERT_DEBUG( Adaptor::IsAvailable() );
147 if( mImpl->mId != 0 )
149 AndroidFramework::GetFramework( Dali::Integration::AndroidFramework::Get() ).RemoveIdle( mImpl->mId );
150 mImpl->mStartTimestamp = 0;
151 mImpl->mPauseTimestamp = 0;
159 // Timer should be used in the event thread
160 DALI_ASSERT_DEBUG( Adaptor::IsAvailable() );
162 if( mImpl->mRunning )
164 mImpl->mPauseTimestamp = GetCurrentMilliSeconds();
165 AndroidFramework::GetFramework( Dali::Integration::AndroidFramework::Get() ).RemoveIdle( mImpl->mId );
172 // Timer should be used in the event thread
173 DALI_ASSERT_DEBUG( Adaptor::IsAvailable() );
175 if( mImpl->mRunning && mImpl->mId == 0 )
177 unsigned int newInterval = 0;
178 unsigned int runningTime = mImpl->mPauseTimestamp - mImpl->mStartTimestamp;
179 if( mImpl->mInterval > runningTime )
181 newInterval = mImpl->mInterval - runningTime;
184 mImpl->mStartTimestamp = GetCurrentMilliSeconds() - runningTime;
185 mImpl->mPauseTimestamp = 0;
186 mImpl->mId = AndroidFramework::GetFramework( Dali::Integration::AndroidFramework::Get() ).AddIdle( newInterval, this, TimerCallback );
190 void Timer::SetInterval( unsigned int interval, bool restart )
192 // stop existing timer
194 mImpl->mInterval = interval;
203 unsigned int Timer::GetInterval() const
205 return mImpl->mInterval;
210 // Guard against destruction during signal emission
211 Dali::Timer handle( this );
213 bool retVal( false );
215 // Override with new signal if used
216 if( !mTickSignal.Empty() )
218 retVal = mTickSignal.Emit();
220 // Timer stops if return value is false
227 retVal = true; // continue emission
230 else // no callbacks registered
232 // periodic timer is started but nobody listens, continue
239 Dali::Timer::TimerSignalType& Timer::TickSignal()
244 void Timer::ResetTimerData()
246 mImpl->mRunning = false;
250 bool Timer::IsRunning() const
252 return mImpl->mRunning;
255 } // namespace Adaptor
257 } // namespace Internal