2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
9 // http://www.apache.org/licenses/LICENSE-2.0
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
19 * @file FSys_VibratorImpl.cpp
20 * @brief This is the implementation file for _VibratorImpl class.
24 #include <devman_haptic.h>
26 #include <FBaseSysLog.h>
27 #include <FBaseResult.h>
28 #include <FSysVibrator.h>
30 #include <FSys_VibratorImpl.h>
32 namespace Tizen { namespace System
36 static const haptic_dev_idx INDEX_SYSTEM_VIBRATOR = DEV_IDX_ALL;
37 static const unsigned int MODE_SYSTEM_VIBRATION = 0;
38 static const int LEVEL_SYSTEM_VIBRATION = -1;
39 static const long INVALID_PERIOD = 0L;
40 static const int INVALID_COUNT = -1;
41 static const int INVALID_LEVEL = -1;
44 IsNegative(const int value)
49 template <typename T> inline bool
50 IsCreated(const T* pT)
55 template <typename T> inline void
66 InitializeVibrator(Handle& handle)
70 Handle deviceHandle = device_haptic_open(INDEX_SYSTEM_VIBRATOR, MODE_SYSTEM_VIBRATION);
71 if (IsNegative(deviceHandle))
73 SysAssertf(false, "device_haptic_open() failed. [index:%d, mode:%d, result:%d]", INDEX_SYSTEM_VIBRATOR, MODE_SYSTEM_VIBRATION, deviceHandle);
76 SysLogException(NID_SYS, r, "[%s] Vibrator initialize operation has failed. [result:%d]", GetErrorMessage(r), deviceHandle);
80 handle = deviceHandle;
86 FinalizeVibrator(Handle& handle)
90 if (handle != INVALID_HANDLE)
92 int deviceResult = device_haptic_close(handle);
93 if (IsNegative(deviceResult))
95 SysAssertf(false, "device_haptic_close() failed. [handle:%d, result:%d]", handle, deviceResult);
98 SysLogException(NID_SYS, r, "[%s] Vibrator finalize operation has failed. [result:%d]", GetErrorMessage(r), deviceResult);
102 handle = INVALID_HANDLE;
109 StartVibration(const Handle handle, const long onPeriod, const int level)
111 result r = E_SUCCESS;
112 int aLevel = (level == 0) ? LEVEL_SYSTEM_VIBRATION : level;
113 SysLog(NID_SYS, "Vibrator Action level: %d", aLevel);
115 int deviceResult = device_haptic_play_monotone_with_detail_feedback_level(handle, onPeriod, (level == 0) ? LEVEL_SYSTEM_VIBRATION : level);
116 if (IsNegative(deviceResult))
118 SysAssertf(false, "device_haptic_play_monotone_with_detail_feedback_level() failed. [handle:%d, duration:%ld, level:%d, result:%d]", handle, onPeriod, level, deviceResult);
121 SysLogException(NID_SYS, r, "[%s] Vibration start operation has failed. [handle:%d, duration:%ld, level:%d, result:%d]", GetErrorMessage(r), handle, onPeriod, level, deviceResult);
129 StopVibration(const Handle handle)
131 result r = E_SUCCESS;
133 int deviceResult = device_haptic_stop_play(handle);
134 if (IsNegative(deviceResult))
136 SysAssertf(false, "device_haptic_stop_play() failed. [handle:%d, result:%d]", handle, deviceResult);
139 SysLogException(NID_SYS, r, "[%s] Vibration stop operation has failed. [handle:%d, result:%d]", GetErrorMessage(r), handle, deviceResult);
148 const _VibratorImpl::VibrationInformation _VibratorImpl::__INVALID_VIBRATION_INFORMATION = {
149 INVALID_PERIOD, // on period
150 INVALID_PERIOD, // off period
151 INVALID_COUNT, // count
152 INVALID_LEVEL, // level
153 false, // is vibrating?
154 true, // is finished?
157 _VibratorImpl::_VibratorImpl(void)
158 : __handle(INVALID_HANDLE)
160 , __vibrationInformation(_VibratorImpl::__INVALID_VIBRATION_INFORMATION)
165 _VibratorImpl::~_VibratorImpl(void)
171 _VibratorImpl::Construct(void)
173 SysAssertf(__handle == INVALID_HANDLE, "_VibratorImpl was already constructed. [handle:%d]", __handle);
176 result r = E_SUCCESS;
178 Tizen::Base::Runtime::Timer* pTimer = new (std::nothrow) Tizen::Base::Runtime::Timer();
179 if (!IsCreated(pTimer))
182 SysLogException(NID_SYS, r, "[%s] Timer allocation failed.", GetErrorMessage(r));
186 r = pTimer->Construct(*this);
193 r = InitializeVibrator(__handle);
206 _VibratorImpl::Destruct(void)
208 if (!__vibrationInformation.isFinished)
213 SafeDelete(__pTimer);
215 if (__handle != INVALID_HANDLE)
217 FinalizeVibrator(__handle);
222 _VibratorImpl::Start(long onPeriod, long offPeriod, int count, int level)
224 SysAssertf(__handle != INVALID_HANDLE, "_VibratorImpl was not constructed.");
228 // Stop current vibration immediately
230 // Prepare vibration information
232 // Start vibration(=> This vibration just one repeat)
234 // Start repetition timer(=> Remaining vibration be started by timer)
236 // Modify vibration information
237 result r = E_SUCCESS;
239 if (!__vibrationInformation.isFinished)
247 __vibrationInformation = _VibratorImpl::__INVALID_VIBRATION_INFORMATION;
250 __vibrationInformation.onPeriod = onPeriod;
251 __vibrationInformation.offPeriod = offPeriod;
252 __vibrationInformation.count = count;
253 __vibrationInformation.level = level;
255 r = StartVibration(__handle, __vibrationInformation.onPeriod, __vibrationInformation.level);
258 __vibrationInformation = _VibratorImpl::__INVALID_VIBRATION_INFORMATION;
262 r = __pTimer->Start(__vibrationInformation.onPeriod);
266 SysLogException(NID_SYS, r, "[%s] Repetition timer starting failed.", GetErrorMessage(r));
267 StopVibration(__handle);
268 __vibrationInformation = _VibratorImpl::__INVALID_VIBRATION_INFORMATION;
272 __vibrationInformation.isVibrating = true;
273 __vibrationInformation.isFinished = false;
274 __vibrationInformation.count--;
280 _VibratorImpl::Stop(void)
282 SysAssertf(__handle != INVALID_HANDLE, "_VibratorImpl was not constructed.");
285 // If (is not vibrating)
290 // Cancel timer(=> for block another repetition)
292 // Stop current vibration
294 // Initialize vibration information
295 result r = E_SUCCESS;
297 if (__vibrationInformation.isFinished)
300 SysLogException(NID_SYS, r, "[%s] Vibrator was already stopped.", GetErrorMessage(r));
304 r = __pTimer->Cancel();
305 SysTryLog(NID_SYS, !IsFailed(r), "[%s] This canceling started just after timer has expired.", GetErrorMessage(r));
307 r = StopVibration(__handle);
313 __vibrationInformation = _VibratorImpl::__INVALID_VIBRATION_INFORMATION;
319 _VibratorImpl::GetInstance(Vibrator& vibrator)
321 return vibrator.__pVibratorImpl;
325 _VibratorImpl::GetInstance(const Vibrator& vibrator)
327 return vibrator.__pVibratorImpl;
331 _VibratorImpl::OnTimerExpired(Tizen::Base::Runtime::Timer& timer)
333 // If (is end of repetition)
335 // Initialize vibration information
339 // If (is end of vibration)
345 // If (is end of waiting)
350 if (__vibrationInformation.count == 0)
352 __vibrationInformation = _VibratorImpl::__INVALID_VIBRATION_INFORMATION;
357 result r = E_SUCCESS;
359 if (__vibrationInformation.isVibrating)
362 __vibrationInformation.isVibrating = false;
364 r = timer.Start(__vibrationInformation.offPeriod);
367 SysLog(NID_SYS, "Vibration waiting failed.");
374 r = StartVibration(__handle, __vibrationInformation.onPeriod, __vibrationInformation.level);
380 r = __pTimer->Start(__vibrationInformation.onPeriod);
383 SysLog(NID_SYS, "Vibration re-starting failed.");
384 StopVibration(__handle);
388 __vibrationInformation.isVibrating = true;
389 __vibrationInformation.count--;
395 SysLogException(NID_UIX, r, "[%s] Critical error occurred! Vibration was stopped.", GetErrorMessage(r));
396 __vibrationInformation = _VibratorImpl::__INVALID_VIBRATION_INFORMATION;