Fix issue detected by static analysis tool
[platform/core/uifw/inputdelegator.git] / src / voice-recorder.cpp
1 /*
2  * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
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 <Elementary.h>
18 #include <app_common.h>
19 #include <app.h>
20 #include <media_content.h>
21 #include "Debug.h"
22 #include <storage.h>
23 #include "voice-recorder.h"
24
25 #define MAX_TIME 1200
26
27 #define VR_AUDIO_SOURCE_SAMPLERATE_LOW          8000
28 #define VR_AUDIO_SOURCE_SAMPLERATE_HIGH         44100
29 #define VR_AUDIO_ENCODER_BITRATE_AMR            12200
30 #define VR_AUDIO_ENCODER_BITRATE_AAC            64000
31
32 static voice_recorder *recorderhandle = NULL;
33
34 static void _recorder_create(voice_recorder *view);
35 static void _recorder_start(voice_recorder *view);
36 static void _recorder_stop(voice_recorder *view);
37 static void _recorder_apply_settings(voice_recorder *view);
38 static void _on_recording_status_cb(unsigned long long elapsed_time, unsigned long long file_size, void *user_data);
39 static void _on_recording_limit_reached_cb(recorder_recording_limit_type_e type, void *user_data);
40 static bool _main_file_register(const char *filename);
41 static void _recorder_destroy(voice_recorder *view);
42
43 void init_voice_recorder(app_control_h service)
44 {
45         voice_recorder *recorder = (voice_recorder *)malloc(sizeof(voice_recorder));
46         if (!recorder) {
47                 LOGD("Error Failed to create recorder");
48                 return;
49         }
50
51         _voice_recorder_set_data(recorder);
52
53         recorder->is_recording = FALSE;
54         recorder->service = service;
55         recorder->limitsize = 1000000;
56
57         _recorder_create(recorder);
58 }
59
60 void destroy_voice_recorder()
61 {
62         LOGD("destroy_voice_recorder()");
63         voice_recorder *recorder = (voice_recorder *)_voice_recorder_get_data();
64         if (recorder) {
65                 _recorder_destroy(recorder);
66         }
67         _voice_recorder_set_data(NULL);
68 }
69
70 void start_voice_recorder()
71 {
72         voice_recorder *recorder = (voice_recorder *)_voice_recorder_get_data();
73         _recorder_start(recorder);
74 }
75
76 void stop_voice_recorder()
77 {
78         voice_recorder *recorder = (voice_recorder *)_voice_recorder_get_data();
79         _recorder_stop(recorder);
80 }
81
82 void _voice_recorder_set_data(void *data)
83 {
84         recorderhandle = (voice_recorder *)data;
85 }
86
87 voice_recorder *_voice_recorder_get_data()
88 {
89         if (recorderhandle) {
90                 return recorderhandle;
91         }
92         return NULL;
93 }
94
95 static void _recorder_create(voice_recorder *recorder)
96 {
97         LOGD("_recorder_create");
98
99         int ret = recorder_create_audiorecorder(&recorder->recorder);
100         if (ret == RECORDER_ERROR_NONE) {
101                 recorder_set_recording_status_cb(recorder->recorder, _on_recording_status_cb, recorder);
102                 if (recorder->limitsize > 0) {
103                         recorder_attr_set_size_limit(recorder->recorder, (recorder->limitsize) / 1024);
104                 }
105                 recorder_set_recording_limit_reached_cb(recorder->recorder, _on_recording_limit_reached_cb, recorder);
106         } else {
107                 LOGD("recorder_create_audiorecorder not successful error code: %d", ret);
108         }
109 }
110
111 static void _recorder_start(voice_recorder *recorder)
112 {
113         LOGD("_recorder_start");
114         if (!recorder->recorder) {
115                 LOGD("Error recorder->recorder is null");
116                 return;
117         }
118
119         recorder_state_e rec_state;
120         recorder_get_state(recorder->recorder, &rec_state);
121
122         if (rec_state == RECORDER_STATE_PAUSED) {
123                 recorder_start(recorder->recorder);
124                 return;
125         }
126
127         struct tm localtime = {0, };
128         time_t rawtime = time(NULL);
129         char filename[256] = {'\0', };
130         char *voice_content_path = NULL;
131         storage_get_directory(STORAGE_TYPE_INTERNAL, STORAGE_DIRECTORY_SOUNDS, &voice_content_path);
132         if (voice_content_path == NULL) {
133                 LOGD("voice_content_path is NULL");
134                 return;
135         }
136
137 #if 1
138         /*For MMS*/
139         recorder->codec = RECORDER_AUDIO_CODEC_AMR;
140         recorder->file_format = RECORDER_FILE_FORMAT_AMR;
141         recorder->sample_rate = VR_AUDIO_SOURCE_SAMPLERATE_LOW;
142         recorder->bitrate = VR_AUDIO_ENCODER_BITRATE_AMR;
143         if (localtime_r(&rawtime, &localtime) != NULL) {
144                 snprintf(filename, sizeof(filename), "Voice-%04i-%02i-%02i_%02i:%02i:%02i.amr",
145                          localtime.tm_year + 1900, localtime.tm_mon + 1, localtime.tm_mday,
146                          localtime.tm_hour, localtime.tm_min, localtime.tm_sec);
147         }
148 #else
149         /*For High Quality*/
150         recorder->codec = RECORDER_AUDIO_CODEC_AAC;
151         recorder->file_format = RECORDER_FILE_FORMAT_MP4;
152         recorder->sample_rate = VR_AUDIO_SOURCE_SAMPLERATE_HIGH;
153         recorder->bitrate = VR_AUDIO_ENCODER_BITRATE_AAC;
154         if (localtime_r(&rawtime, &localtime) != NULL) {
155                 snprintf(filename, sizeof(filename), "Voice-%04i-%02i-%02i_%02i:%02i:%02i.m4a",
156                          localtime.tm_year + 1900, localtime.tm_mon + 1, localtime.tm_mday,
157                          localtime.tm_hour, localtime.tm_min, localtime.tm_sec);
158         }
159 #endif
160         /*set file path*/
161         snprintf(recorder->file_path, PATH_MAX, "%s/%s", voice_content_path, filename);
162         LOGD("recorder->file_path = %s", recorder->file_path);
163         _recorder_apply_settings(recorder);
164         free(voice_content_path);
165         recorder_prepare(recorder->recorder);
166         recorder_start(recorder->recorder);
167 }
168
169 static void _recorder_stop(voice_recorder *recorder)
170 {
171         LOGD("_recorder_stop");
172         int commitResult = RECORDER_ERROR_NONE;
173
174         if (recorder->recorder) {
175                 commitResult = recorder_commit(recorder->recorder);
176                 if (commitResult != RECORDER_ERROR_NONE) {
177                         LOGD("recorder_commit failed Error");
178                 }
179                 _main_file_register(recorder->file_path);
180         }
181 }
182
183 static void _recorder_apply_settings(voice_recorder *recorder)
184 {
185         int error_code;
186         if (recorder->recorder) {
187                 error_code = recorder_attr_set_audio_channel(recorder->recorder, 2);
188                 if (error_code != RECORDER_ERROR_NONE)
189                         LOGW("Failed to set audio channel. error code : %d", error_code);
190
191                 error_code = recorder_attr_set_audio_device(recorder->recorder, RECORDER_AUDIO_DEVICE_MIC);
192                 if (error_code != RECORDER_ERROR_NONE)
193                         LOGW("Failed to set audio device. error code : %d", error_code);
194
195                 error_code = recorder_attr_set_time_limit(recorder->recorder, MAX_TIME);
196                 if (error_code != RECORDER_ERROR_NONE)
197                         LOGW("Failed to set time limit. error code : %d", error_code);
198
199                 error_code = recorder_set_filename(recorder->recorder, recorder->file_path);
200                 if (error_code != RECORDER_ERROR_NONE)
201                         LOGW("Failed to set filename. error code : %d", error_code);
202
203                 error_code = recorder_set_file_format(recorder->recorder, recorder->file_format);
204                 if (error_code != RECORDER_ERROR_NONE)
205                         LOGW("Failed to set file format. error code : %d", error_code);
206
207                 LOGD("file_format: %d", recorder->file_format);
208                 error_code = recorder_set_audio_encoder(recorder->recorder, recorder->codec);
209                 if (error_code != RECORDER_ERROR_NONE)
210                         LOGW("Failed to set audio encoder. error code : %d", error_code);
211
212                 recorder_attr_set_audio_samplerate(recorder->recorder, recorder->sample_rate);
213                 recorder_attr_set_audio_encoder_bitrate(recorder->recorder, recorder->bitrate);
214
215                 recorder_prepare(recorder->recorder);
216         }
217 }
218
219 static void _on_recording_status_cb(unsigned long long elapsed_time, unsigned long long file_size, void *user_data)
220 {
221         voice_recorder *recorder = (voice_recorder *)user_data;
222
223         if (recorder) {
224                 recorder_state_e rec_state = RECORDER_STATE_NONE;
225                 recorder_get_state(recorder->recorder, &rec_state);
226                 if (rec_state == RECORDER_STATE_PAUSED || rec_state == RECORDER_STATE_READY) {
227                         return;
228                 }
229         }
230 }
231
232 static void _on_recording_limit_reached_cb(recorder_recording_limit_type_e type, void *user_data)
233 {
234         voice_recorder *recorder = (voice_recorder *)user_data;
235         if (recorder) {
236                 if (type == RECORDER_RECORDING_LIMIT_TIME) {
237                         _recorder_stop(recorder);
238                 } else if (type == RECORDER_RECORDING_LIMIT_SIZE) {
239                         _recorder_stop(recorder);
240                 }
241         }
242 }
243
244 static bool _main_file_register(const char *filename)
245 {
246         LOGD("_main_file_register");
247         int err_code = 0;
248         media_info_h info = NULL;
249
250         char *register_file = strdup(filename);
251         if (register_file == NULL) {
252                 LOGD("Failed to allocate memory");
253                 return FALSE;
254         }
255
256         err_code = media_info_insert_to_db(register_file, &info);
257         if (err_code != MEDIA_CONTENT_ERROR_NONE) {
258                 LOGD("failed to media_file_register() : [%s], [%d]", register_file, err_code);
259                 media_info_destroy(info);
260                 free(register_file);
261                 return FALSE;
262         }
263
264         media_info_destroy(info);
265         free(register_file);
266
267         return TRUE;
268 }
269
270 static void _recorder_destroy(voice_recorder *recorder)
271 {
272         int error_code;
273         LOGD("_recorder_destroy");
274         if (recorder->recorder) {
275                 error_code = recorder_cancel(recorder->recorder);
276                 if (error_code != RECORDER_ERROR_NONE)
277                         LOGW("failed to cancel recorder. error : %d", error_code);
278
279                 recorder_unprepare(recorder->recorder);
280                 recorder_destroy(recorder->recorder);
281                 recorder->recorder = NULL;
282         }
283 }