4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Seungbae Shin <seungbae.shin@samsung.com>
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
26 #include <sys/types.h>
34 #include <avsys-audio.h>
38 #include "../include/mm_sound_common.h"
39 #include "../include/mm_sound_utils.h"
40 #include "include/mm_sound_thread_pool.h"
41 #include "include/mm_sound_mgr_run.h"
42 #include "include/mm_sound_mgr_codec.h"
43 #include "include/mm_sound_mgr_ipc.h"
44 #include "include/mm_sound_mgr_pulse.h"
45 #include "include/mm_sound_mgr_asm.h"
46 #include "include/mm_sound_mgr_session.h"
47 #include "include/mm_sound_mgr_device.h"
48 #include "include/mm_sound_mgr_headset.h"
49 #include "include/mm_sound_mgr_dock.h"
50 #include "include/mm_sound_mgr_hdmi.h"
51 #include "include/mm_sound_mgr_wfd.h"
57 #define PLUGIN_ENV "MM_SOUND_PLUGIN_PATH"
58 #define PLUGIN_DIR "/usr/lib/soundplugins/"
61 #define HIBERNATION_SOUND_CHECK_PATH "/tmp/hibernation/sound_ready"
62 #define USE_SYSTEM_SERVER_PROCESS_MONITORING
64 #define ASM_CHECK_INTERVAL 10000
66 #define MAX_PLUGIN_DIR_PATH_LEN 256
69 char plugdir[MAX_PLUGIN_DIR_PATH_LEN];
75 static int getOption(int argc, char **argv, server_arg *arg);
76 static int usgae(int argc, char **argv);
78 static struct sigaction sigint_action; /* Backup pointer of SIGINT handler */
79 static struct sigaction sigabrt_action; /* Backup pointer of SIGABRT signal handler */
80 static struct sigaction sigsegv_action; /* Backup pointer of SIGSEGV fault signal handler */
81 static struct sigaction sigterm_action; /* Backup pointer of SIGTERM signal handler */
82 static struct sigaction sigsys_action; /* Backup pointer of SIGSYS signal handler */
83 static void _exit_handler(int sig);
85 GMainLoop *g_mainloop;
89 gpointer event_loop_thread(gpointer data)
91 g_mainloop = g_main_loop_new(NULL, TRUE);
92 if(g_mainloop == NULL) {
93 debug_error("g_main_loop_new() failed\n");
95 g_main_loop_run(g_mainloop);
99 #ifdef USE_HIBERNATION
100 static void __hibernation_leave_cb()
102 int volumes[VOLUME_TYPE_MAX] = {0, };
104 MMSoundMgrPulseHandleRegisterMonoAudio(pulse_handle);
105 MMSoundMgrPulseHandleRegisterBluetoothStatus (pulse_handle);
107 _mm_sound_volume_get_values_on_bootup(volumes);
108 if (avsys_audio_hibernation_reset(volumes)) {
109 debug_error("Audio reset failed\n");
111 debug_msg("Audio reset success\n");
116 static void __wait_for_asm_ready ()
121 debug_log("Checking ASM ready....[%d]\n", retry_count++);
122 if (vconf_get_int(ASM_READY_KEY, &asm_ready)) {
123 debug_warning("vconf_get_int for ASM_READY_KEY (%s) failed\n", ASM_READY_KEY);
125 usleep (ASM_CHECK_INTERVAL);
127 debug_log("ASM is now ready...clear key!!!\n");
128 vconf_unset (ASM_READY_KEY);
131 int main(int argc, char **argv)
133 server_arg serveropt;
134 struct sigaction action;
135 #ifdef USE_HIBERNATION
138 int volumes[VOLUME_TYPE_MAX] = {0, };
139 #if !defined(USE_SYSTEM_SERVER_PROCESS_MONITORING)
144 action.sa_handler = _exit_handler;
146 sigemptyset(&action.sa_mask);
148 if (getOption(argc, argv, &serveropt))
151 /* Daemon process create */
152 if (!serveropt.testmode && serveropt.startserver) {
153 #if !defined(USE_SYSTEM_SERVER_PROCESS_MONITORING)
154 daemon(0,0); //chdir to ("/"), and close stdio
158 signal(SIGPIPE, SIG_IGN); //ignore SIGPIPE
160 _mm_sound_volume_get_values_on_bootup(volumes);
161 if (avsys_audio_hibernation_reset(volumes)) {
162 debug_error("Audio reset failed\n");
164 debug_msg("Audio reset success\n");
167 #ifdef USE_HIBERNATION
168 heynotifd = heynoti_init();
169 if(heynoti_subscribe(heynotifd, "HIBERNATION_LEAVE", __hibernation_leave_cb, NULL)) {
170 debug_error("heynoti_subscribe failed...\n");
172 debug_msg("heynoti_subscribe() success\n");
175 if(heynoti_attach_handler(heynotifd)) {
176 debug_error("heynoti_attach_handler() failed\n");
178 debug_msg("heynoti_attach_handler() success\n");
182 #if !defined(USE_SYSTEM_SERVER_PROCESS_MONITORING)
185 if ((pid = fork()) < 0)
187 fprintf(stderr, "Sub Fork Error\n");
197 fprintf(stderr, "Killed by signal [%05X]\n", ret);
198 fprintf(stderr, "Daemon is run againg\n");
202 sigaction(SIGABRT, &action, &sigabrt_action);
203 sigaction(SIGSEGV, &action, &sigsegv_action);
204 sigaction(SIGTERM, &action, &sigterm_action);
205 sigaction(SIGSYS, &action, &sigsys_action);
207 if (!g_thread_supported ())
208 g_thread_init (NULL);
210 if(NULL == g_thread_create(event_loop_thread, NULL, FALSE, NULL)) {
211 fprintf(stderr,"event loop thread create failed\n");
216 if (serveropt.startserver || serveropt.printlist) {
217 MMSoundThreadPoolInit();
218 MMSoundMgrRunInit(serveropt.plugdir);
219 MMSoundMgrCodecInit(serveropt.plugdir);
220 if (!serveropt.testmode)
223 pulse_handle = MMSoundMgrPulseInit();
226 /* Wait for ASM Ready */
227 __wait_for_asm_ready();
229 _mm_sound_mgr_device_init();
230 MMSoundMgrHeadsetInit();
231 MMSoundMgrDockInit();
232 MMSoundMgrHdmiInit();
234 MMSoundMgrSessionInit();
237 if (serveropt.startserver) {
238 /* Start Run types */
239 MMSoundMgrRunRunAll();
241 #ifdef USE_HIBERNATION
242 /* set hibernation check */
243 _mm_sound_check_hibernation (HIBERNATION_SOUND_CHECK_PATH);
247 MMSoundMgrIpcReady();
250 if (serveropt.startserver || serveropt.printlist) {
251 MMSoundMgrRunStopAll();
252 if (!serveropt.testmode)
255 MMSoundMgrCodecFini();
257 MMSoundThreadPoolFini();
260 MMSoundMgrHdmiFini();
261 MMSoundMgrDockFini();
262 MMSoundMgrHeadsetFini();
263 MMSoundMgrSessionFini();
264 _mm_sound_mgr_device_fini();
266 MMSoundMgrPulseFini(pulse_handle);
268 #ifdef USE_HIBERNATION
269 if(heynoti_unsubscribe(heynotifd, "HIBERNATION_LEAVE", NULL)) {
270 debug_error("heynoti_unsubscribe failed..\n");
272 heynoti_close(heynotifd);
278 static int getOption(int argc, char **argv, server_arg *arg)
281 char *plugin_env_dir = NULL;
282 static struct option long_options[] = {
283 {"start", 0, 0, 'S'},
286 {"plugdir", 1, 0, 'P'},
287 {"testmode", 0, 0, 'T'},
290 memset(arg, 0, sizeof(server_arg));
292 plugin_env_dir = getenv(PLUGIN_ENV);
293 if (plugin_env_dir) {
294 strncpy (arg->plugdir, plugin_env_dir, sizeof(arg->plugdir)-1);
296 strncpy (arg->plugdir, PLUGIN_DIR, sizeof(arg->plugdir)-1);
305 c = getopt_long (argc, argv, "SLHRP:T", long_options, &opt_idx);
310 case 'S': /* Start daemon */
311 arg->startserver = 1;
313 case 'L': /* list of plugins */
317 MMSoundMgrCodecInit(arg->plugdir);
319 case 'P': /* Custom plugindir */
320 strncpy (arg->plugdir, optarg, sizeof(arg->plugdir)-1);
322 case 'T': /* Test mode */
325 case 'H': /* help msg */
327 return usgae(argc, argv);
331 return usgae(argc, argv);
335 //__attribute__ ((destructor))
336 static void _exit_handler(int sig)
338 int ret = MM_ERROR_NONE;
340 ret = MMSoundMgrRunStopAll();
341 if (ret != MM_ERROR_NONE) {
342 debug_error("Fail to stop run-plugin\n");
344 debug_log("All run-type plugin stopped\n");
350 sigaction(SIGINT, &sigint_action, NULL);
351 debug_error("signal(SIGINT) error");
354 sigaction(SIGABRT, &sigabrt_action, NULL);
355 debug_error("signal(SIGABRT) error");
358 sigaction(SIGSEGV, &sigsegv_action, NULL);
359 debug_error("signal(SIGSEGV) error");
362 sigaction(SIGTERM, &sigterm_action, NULL);
363 debug_error("signal(SIGTERM) error");
366 sigaction(SIGSYS, &sigsys_action, NULL);
367 debug_error("signal(SIGSYS) error");
375 static int usgae(int argc, char **argv)
377 fprintf(stderr, "Usage: %s [Options]\n", argv[0]);
378 fprintf(stderr, "\t%-20s: start sound server.\n", "--start,-S");
379 fprintf(stderr, "\t%-20s: print plugin list.\n", "--list,-L");
380 fprintf(stderr, "\t%-20s: print this message.\n", "--help,-H");
381 fprintf(stderr, "\t%-20s: print this message.\n", "--plugdir,-P");