2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
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.
18 * @modify Lileiming (leiming.li@samsung.com)
20 * @brief add function run_beep &stop_beep
23 #include <Commons/Exception.h>
24 #include <VConf/Key.h>
25 #include <sys/utsname.h>
28 #include <mmf/mm_sound_private.h>
30 namespace WrtDeviceApis {
33 const int INVALID_BEEP_HANDLER = -1;
36 Motor::Motor(haptic_dev_idx index) :
37 EventHapticActionReqReceiver(Commons::ThreadEnum::HAPTICS_THREAD),
38 EventStartMotorReqReceiver(Commons::ThreadEnum::HAPTICS_THREAD),
39 EventPlayBeepReqReceiver(Commons::ThreadEnum::HAPTICS_THREAD),
40 m_beepHandle(INVALID_BEEP_HANDLER)
42 m_device = device_haptic_open(index, 0);
44 ThrowMsg(Commons::PlatformException, "Could not open haptic device.");
50 if (device_haptic_close(m_device) < 0) {
51 LogDebug("Could not close haptic device.");
55 int Motor::playBeep(unsigned long duration,
60 retMmSound = mm_sound_play_tone(MM_SOUND_TONE_PROP_BEEP, VOLUME_TYPE_SYSTEM, 1, duration, &m_beepHandle);
61 // retMmSound = mm_sound_play_beep(VOLUME_TYPE_SYSTEM, duration, &m_beepHandle);
63 m_beepHandle = INVALID_BEEP_HANDLER;
64 ThrowMsg(Commons::PlatformException, "Play Beep is Failed!");
70 void Motor::playBeep(const Api::EventPlayBeepPtr& event)
72 EventPlayBeepReqReceiver::PostRequest(event);
75 void Motor::stopBeep()
77 if (m_beepHandle == INVALID_BEEP_HANDLER) {
78 LogError("m_beepHandle is wrong!!");
79 ThrowMsg(Commons::PlatformException, "m_beepHandle is wrong!!");
81 if (mm_sound_stop_sound(m_beepHandle) != 0) {
82 LogError("mm_sound_stop_sound FAIL!!");
83 ThrowMsg(Commons::PlatformException, "mm_sound_stop_sound FAIL!!");
85 m_beepHandle = INVALID_BEEP_HANDLER;
88 void Motor::run(unsigned long duration)
90 if (device_haptic_play_monotone(m_device, duration) != 0) {
91 ThrowMsg(Commons::PlatformException, "Could not run haptic motor.");
95 void Motor::run(const Api::HapticPatternPtr& pattern)
100 if (!pattern || 0 == pattern->length()) {
101 return; // nothing to do
106 LogDebug("Wait current event! And then run Next pattern!");
112 void Motor::run(const Api::EventStartMotorPtr& event)
114 EventStartMotorReqReceiver::PostRequest(event);
117 void Motor::stopMotor()
119 if (device_haptic_stop_play(m_device) != 0) {
120 LogError("Haptic motor stop fail!");
121 ThrowMsg(Commons::PlatformException, "Could not stop haptic motor.");
125 void Motor::stopVibration()
127 LogDebug("Entered!");
131 m_current = m_pattern->length();
138 void Motor::OnRequestReceived(const EventHapticActionPtr& event)
140 LogInfo("Haptic action event received");
142 DPL::Mutex::ScopedLock lock(&m_patternMutex);
143 if (event->checkCancelled()) {
144 LogWarning("Haptic pattern canceled by another one");
145 return; // event has been canceled by another Motor::run -> nothing to do
151 void Motor::OnRequestReceived(const Api::EventStartMotorPtr& event)
153 LogInfo("Start motor event received");
157 LogError("Event is NULL!");
158 ThrowMsg(Commons::PlatformException, "Event is NULL!!");
161 unsigned long duration = 0;
162 Api::HapticPatternPtr patternPtr = event->getPatternRef();
163 size_t patternLength = patternPtr->length();
165 if (event->getDuration() > 0) {
166 // Ignore duration if duration is lower than 0
167 duration = event->getDuration();
170 if ((duration > 0) && (patternLength == 0)) {
171 // run motor during duration
173 } else if ((duration == 0) && (patternLength > 0)) {
174 // run motor by pattern
176 } else if ((duration > 0) && (patternLength > 0)) {
177 // run motor by pattern during duration
178 arragePattern(patternPtr, duration);
181 LogDebug("duration is 0 and pattern is null!!! Do Nothing!");
184 catch (Commons::PlatformException) {
185 LogError("platform exception");
186 event->setExceptionCode(Commons::ExceptionCodes::PlatformException);
190 void Motor::OnRequestReceived(const Api::EventPlayBeepPtr& event)
192 LogInfo("Play beep event received");
196 LogError("event is NULL!");
197 ThrowMsg(Commons::PlatformException, "Event is NULL!!");
201 "duration: " << event->getDuration() << ", volume: " <<
203 if (event->getDuration() <= 0) {
204 LogDebug("duration is less than 0!! Do Nothing!");
207 if (playBeep(static_cast<unsigned long>(event->getDuration()),
208 event->getVolume()) < 0) {
209 LogError("playBeep returned error!!");
210 ThrowMsg(Commons::PlatformException, "Play Beep is Failed!");
213 catch (Commons::PlatformException) {
214 LogError("platform exception");
215 event->setExceptionCode(Commons::ExceptionCodes::PlatformException);
219 void Motor::runNextPattern()
221 // always stop the motor
222 LogInfo("stopping motor");
225 if (m_current >= m_pattern->length()) {
228 LogInfo("end of pattern");
229 return; // end of pattern
232 unsigned long duration = m_pattern->duration(m_current);
236 active = m_pattern->isActive(m_current);
238 Catch(Commons::OutOfRangeException) {
239 LogError("Platform sequence size exceeded. Finishing.");
247 LogInfo("haptic action for " << duration << "ms");
252 LogInfo("pausing for " << duration << "ms");
255 LogInfo("post request delayed for " << duration << "ms");
257 m_event = EventHapticActionPtr(new EventHapticAction());
258 m_event->setForAsynchronousCall(NULL); // not interested in answer
260 // post delayed event
261 EventHapticActionReqReceiver::PostRequest(m_event, duration / 1000.0);
264 void Motor::arragePattern(Api::HapticPatternPtr& patternPtr,
265 const unsigned long duration)
267 LogInfo("Entered!!");
269 if (patternPtr == NULL) {
270 LogError("patternPtr is NULL");
274 size_t patternLength = patternPtr->length();
275 unsigned long totalPatternDuration = 0;
276 unsigned long repeatCnt = 0;
277 unsigned long addingCnt = 0;
278 size_t currentInterval = 0;
280 for (size_t i = 0; i < patternLength; i++) {
281 totalPatternDuration += patternPtr->duration(i);
283 if ((duration % totalPatternDuration) == 0) {
284 repeatCnt = (duration / totalPatternDuration);
286 repeatCnt = (duration / totalPatternDuration) + 1;
288 addingCnt = repeatCnt - 1;
290 /* Repeat pattern during duration */
291 for (unsigned long i = 0; i < addingCnt; i++) {
292 for (currentInterval = 0;
293 currentInterval < patternLength;
295 patternPtr->addInterval(patternPtr->duration(
297 patternPtr->isActive(currentInterval));