Merge "[Pkcs] Fixed the TC's failure" into tizen_2.1
[platform/framework/native/appfw.git] / src / system / FSys_VibratorImpl.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 //
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
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0
10 //
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.
16 //
17
18 /**
19  * @file                FSys_VibratorImpl.cpp
20  * @brief               This is the implementation file for _VibratorImpl class.
21  */
22
23 #include <new>
24 #include <unique_ptr.h>
25
26 #include <FBaseSysLog.h>
27 #include <FBaseResult.h>
28 #include <FSysVibrator.h>
29
30 #include <FSys_VibratorImpl.h>
31
32 namespace Tizen { namespace System
33 {
34 static const int MAX_SIZE_OF_VIBRATION_BUFFER = 64 * 1024; // Immersion lib guide value. 64kbytes
35
36 _VibratorImpl::_VibratorImpl(void)
37         : __handle(null)
38         , __effectHandle(null)
39 {
40
41 }
42
43 _VibratorImpl::~_VibratorImpl(void)
44 {
45         if (__handle != null)
46         {
47                 Stop();
48                 int deviceResult = haptic_close(__handle);
49
50                 if (deviceResult != HAPTIC_ERROR_NONE)
51                 {
52                         SysLogException(NID_SYS, E_SYSTEM,
53                                 "[E_SYSTEM] Vibrator finalize operation has failed. [handle:%d, result:%d]", __handle, deviceResult);
54                 }
55         }
56 }
57
58 result
59 _VibratorImpl::Construct(void)
60 {
61         SysTryReturnResult(NID_SYS, __handle == null, E_DEVICE_FAILED, "_VibratorImpl was already constructed.");
62
63         int ret = haptic_open(HAPTIC_DEVICE_ALL, &__handle);
64
65         SysTryReturnResult(NID_SYS, ret == HAPTIC_ERROR_NONE,E_SYSTEM,
66                         "[E_SYSTEM] Vibrator initialize operation has failed. [result:%d]", ret);
67         SysLog(NID_SYS, "vibrator created handle = %d", __handle);
68         return E_SUCCESS;
69 }
70
71
72 result
73 _VibratorImpl::Start(IntensityDurationVibrationPattern* patterns, int length, int repeatCount)
74 {
75         SysTryReturnResult(NID_SYS, __handle != null, E_DEVICE_FAILED, "_VibratorImpl was not constructed.");
76
77         result r = E_SUCCESS;
78         int errorCode = 0;
79         haptic_state_e state;
80         errorCode = haptic_get_effect_state(__handle, __effectHandle, &state);
81         
82         if ((haptic_error_e)errorCode == HAPTIC_ERROR_NONE)
83         {
84                 if (state == HAPTIC_STATE_PLAYING)
85                 {
86                         r = Stop();
87                         SysTryReturnResult(NID_SYS, r == E_SUCCESS, r, "It failed to stop previous vibration.");
88                 }
89         }
90
91         int numberOfElement = length / sizeof(IntensityDurationVibrationPattern);
92         std::unique_ptr<haptic_effect_element_s[]> pPatterns(new (std::nothrow) haptic_effect_element_s[numberOfElement * sizeof(haptic_effect_element_s)]);
93         SysTryReturnResult(NID_SYS, pPatterns != null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] It failed to allocate memory");
94
95         for (int i = 0; i < numberOfElement; i++)
96         {
97                 SysTryReturnResult(NID_SYS, patterns[i].duration >= 0, E_INVALID_ARG, 
98                                                 "[E_INVALID_ARG] The %dth pattern is the invalid duration[%d].", i, patterns[i].duration);              
99                 pPatterns[i].haptic_duration = patterns[i].duration;
100
101                 SysTryReturnResult(NID_SYS, patterns[i].intensity >= -1 && patterns[i].intensity <= 100, E_INVALID_ARG,
102                                                 "[E_INVALID_ARG] The %dth pattern is the invalid intensity[%d].", i, patterns[i].intensity);
103                 pPatterns[i].haptic_level = (patterns[i].intensity == -1) ? HAPTIC_FEEDBACK_AUTO : (haptic_feedback_e)patterns[i].intensity;
104         }
105
106         int sizeOfBuf = MAX_SIZE_OF_VIBRATION_BUFFER;
107         std::unique_ptr<unsigned char[]> pEffectBuffer(new (std::nothrow) unsigned char[sizeOfBuf]);
108         SysTryReturnResult(NID_SYS, pEffectBuffer != null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] It failed to allocate memory");
109
110         errorCode = haptic_create_effect(pEffectBuffer.get(), sizeOfBuf, pPatterns.get(), numberOfElement);     
111         r = ConvertErrorCode(errorCode);
112         SysTryReturnResult(NID_SYS, r == E_SUCCESS, r,"[%s] It failed to start vibrator.",GetErrorMessage(r));
113
114         SysLog(NID_SYS, "The number of patterns %d, repeate count %d", numberOfElement, repeatCount);
115         errorCode = haptic_vibrate_buffer_with_detail(__handle, pEffectBuffer.get(), (haptic_iteration_e)repeatCount, HAPTIC_FEEDBACK_5, HAPTIC_PRIORITY_MIN, &__effectHandle);
116         r = ConvertErrorCode(errorCode);
117         SysTryReturnResult(NID_SYS, r == E_SUCCESS, r,"[%s] It failed to start vibrator.",GetErrorMessage(r));
118         return r;
119 }
120
121
122 result
123 _VibratorImpl::Start(long onPeriod, long offPeriod, int count, int level)
124 {
125         SysTryReturnResult(NID_SYS, __handle != null, E_DEVICE_FAILED, "_VibratorImpl was not constructed.");
126
127         result r = E_SUCCESS;
128         int errorCode = 0;
129         haptic_state_e state;
130         errorCode = haptic_get_effect_state(__handle, __effectHandle, &state);
131         
132         if ((haptic_error_e)errorCode == HAPTIC_ERROR_NONE)
133         {
134                 if (state == HAPTIC_STATE_PLAYING)
135                 {
136                         r = Stop();
137                         SysTryReturnResult(NID_SYS, r == E_SUCCESS, r, "It failed to stop previous vibration.");
138                 }
139         }
140
141         haptic_effect_element_s pattern[2];
142         
143         pattern[0].haptic_duration = onPeriod;
144         pattern[0].haptic_level = (level == 0) ? HAPTIC_FEEDBACK_AUTO : (haptic_feedback_e)level;
145
146         pattern[1].haptic_duration = offPeriod;
147         pattern[1].haptic_level = HAPTIC_FEEDBACK_0;    
148
149         int sizeOfBuf = MAX_SIZE_OF_VIBRATION_BUFFER;
150         std::unique_ptr<unsigned char[]> pEffectBuffer(new (std::nothrow) unsigned char[sizeOfBuf]);
151         SysTryReturnResult(NID_SYS, pEffectBuffer != null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] It failed to allocate memory");
152
153         errorCode = haptic_create_effect(pEffectBuffer.get(), sizeOfBuf, pattern, sizeof(pattern) / sizeof(haptic_effect_element_s));
154         r = ConvertErrorCode(errorCode);
155         SysTryReturnResult(NID_SYS, r == E_SUCCESS, r,"[%s] It failed to start vibrator.",GetErrorMessage(r));
156
157         SysLog(NID_SYS, "onPeriod %d, offPeriod %d, count %d, level = %d", onPeriod, offPeriod, count, level);
158         errorCode = haptic_vibrate_buffer_with_detail(__handle, pEffectBuffer.get(), (haptic_iteration_e)count, HAPTIC_FEEDBACK_5, HAPTIC_PRIORITY_MIN, &__effectHandle);
159         r = ConvertErrorCode(errorCode);
160         SysTryReturnResult(NID_SYS, r == E_SUCCESS, r,"[%s] It failed to start vibrator.",GetErrorMessage(r));
161         return r;
162 }
163
164
165 result
166 _VibratorImpl::Stop(void)
167 {
168         SysTryReturnResult(NID_SYS, __handle != null, E_FAILURE, "_VibratorImpl was not constructed.");
169
170         int deviceResult = haptic_stop_all_effects(__handle);
171         SysTryReturnResult(NID_SYS, deviceResult == HAPTIC_ERROR_NONE,E_DEVICE_FAILED,
172                 "[E_SYSTEM] Vibration stop operation has failed. [result:%d]", deviceResult);
173         SysLog(NID_SYS, "vibrator stopped handle = %d", __handle);
174         __effectHandle = null;
175
176         return E_SUCCESS;
177 }
178
179 result
180 _VibratorImpl::ConvertErrorCode(int errorCode)
181 {
182         switch ((haptic_error_e)errorCode)
183         {
184         case HAPTIC_ERROR_NONE: return E_SUCCESS;
185         case HAPTIC_ERROR_INVALID_PARAMETER: return E_INVALID_ARG;
186         default: return E_DEVICE_FAILED;
187         }
188 }
189
190
191 _VibratorImpl*
192 _VibratorImpl::GetInstance(Vibrator& vibrator)
193 {
194         return vibrator.__pVibratorImpl;
195 }
196
197 const _VibratorImpl*
198 _VibratorImpl::GetInstance(const Vibrator& vibrator)
199 {
200         return vibrator.__pVibratorImpl;
201 }
202
203 } } // Tizen::System