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"
52 #include <audio-session-manager.h>
58 #define PLUGIN_ENV "MM_SOUND_PLUGIN_PATH"
59 #define PLUGIN_DIR "/usr/lib/soundplugins/"
62 #define HIBERNATION_SOUND_CHECK_PATH "/tmp/hibernation/sound_ready"
63 #define USE_SYSTEM_SERVER_PROCESS_MONITORING
65 #define ASM_CHECK_INTERVAL 10000
67 #define MAX_PLUGIN_DIR_PATH_LEN 256
70 char plugdir[MAX_PLUGIN_DIR_PATH_LEN];
77 static int getOption(int argc, char **argv, server_arg *arg);
78 static int usgae(int argc, char **argv);
80 static struct sigaction sigint_action; /* Backup pointer of SIGINT handler */
81 static struct sigaction sigabrt_action; /* Backup pointer of SIGABRT signal handler */
82 static struct sigaction sigsegv_action; /* Backup pointer of SIGSEGV fault signal handler */
83 static struct sigaction sigterm_action; /* Backup pointer of SIGTERM signal handler */
84 static struct sigaction sigsys_action; /* Backup pointer of SIGSYS signal handler */
85 static void _exit_handler(int sig);
87 GMainLoop *g_mainloop;
91 gpointer event_loop_thread(gpointer data)
93 g_mainloop = g_main_loop_new(NULL, TRUE);
94 if(g_mainloop == NULL) {
95 debug_error("g_main_loop_new() failed\n");
97 g_main_loop_run(g_mainloop);
101 #ifdef USE_HIBERNATION
102 static void __hibernation_leave_cb()
104 int volumes[VOLUME_TYPE_MAX] = {0, };
106 MMSoundMgrPulseHandleRegisterMonoAudio(pulse_handle);
107 MMSoundMgrPulseHandleRegisterBluetoothStatus (pulse_handle);
109 _mm_sound_volume_get_values_on_bootup(volumes);
110 if (avsys_audio_hibernation_reset(volumes)) {
111 debug_error("Audio reset failed\n");
113 debug_msg("Audio reset success\n");
118 static void __wait_for_asm_ready ()
123 debug_log("Checking ASM ready....[%d]\n", retry_count++);
124 if (vconf_get_int(ASM_READY_KEY, &asm_ready)) {
125 debug_warning("vconf_get_int for ASM_READY_KEY (%s) failed\n", ASM_READY_KEY);
127 usleep (ASM_CHECK_INTERVAL);
129 debug_log("ASM is now ready...clear key!!!\n");
130 vconf_unset (ASM_READY_KEY);
133 static int _handle_power_off ()
138 if (ASM_register_sound (-1, &handle, ASM_EVENT_EXCLUSIVE_MMPLAYER, ASM_STATE_PLAYING, NULL, NULL, ASM_RESOURCE_NONE, &asm_error)) {
139 if (ASM_unregister_sound (handle, ASM_EVENT_EXCLUSIVE_MMPLAYER, &asm_error)) {
140 debug_log ("asm register/unregister success!!!\n");
143 debug_error ("asm unregister failed...0x%x\n", asm_error);
146 debug_error ("asm register failed...0x%x\n", asm_error);
152 int main(int argc, char **argv)
154 server_arg serveropt;
155 struct sigaction action;
156 #ifdef USE_HIBERNATION
159 int volumes[VOLUME_TYPE_MAX] = {0, };
160 #if !defined(USE_SYSTEM_SERVER_PROCESS_MONITORING)
165 action.sa_handler = _exit_handler;
167 sigemptyset(&action.sa_mask);
169 if (getOption(argc, argv, &serveropt))
172 /* Daemon process create */
173 if (!serveropt.testmode && serveropt.startserver) {
174 #if !defined(USE_SYSTEM_SERVER_PROCESS_MONITORING)
175 daemon(0,0); //chdir to ("/"), and close stdio
179 if (serveropt.poweroff) {
180 if (_handle_power_off() == 0) {
181 debug_log("_handle_power_off success!!\n");
183 debug_error("_handle_power_off failed..\n");
188 signal(SIGPIPE, SIG_IGN); //ignore SIGPIPE
190 _mm_sound_volume_get_values_on_bootup(volumes);
191 if (avsys_audio_hibernation_reset(volumes)) {
192 debug_error("Audio reset failed\n");
194 debug_msg("Audio reset success\n");
197 #ifdef USE_HIBERNATION
198 heynotifd = heynoti_init();
199 if(heynoti_subscribe(heynotifd, "HIBERNATION_LEAVE", __hibernation_leave_cb, NULL)) {
200 debug_error("heynoti_subscribe failed...\n");
202 debug_msg("heynoti_subscribe() success\n");
205 if(heynoti_attach_handler(heynotifd)) {
206 debug_error("heynoti_attach_handler() failed\n");
208 debug_msg("heynoti_attach_handler() success\n");
212 #if !defined(USE_SYSTEM_SERVER_PROCESS_MONITORING)
215 if ((pid = fork()) < 0)
217 fprintf(stderr, "Sub Fork Error\n");
227 fprintf(stderr, "Killed by signal [%05X]\n", ret);
228 fprintf(stderr, "Daemon is run againg\n");
232 sigaction(SIGABRT, &action, &sigabrt_action);
233 sigaction(SIGSEGV, &action, &sigsegv_action);
234 sigaction(SIGTERM, &action, &sigterm_action);
235 sigaction(SIGSYS, &action, &sigsys_action);
237 if (!g_thread_supported ())
238 g_thread_init (NULL);
240 if(NULL == g_thread_create(event_loop_thread, NULL, FALSE, NULL)) {
241 fprintf(stderr,"event loop thread create failed\n");
247 if (serveropt.startserver || serveropt.printlist) {
248 MMSoundThreadPoolInit();
249 MMSoundMgrRunInit(serveropt.plugdir);
250 MMSoundMgrCodecInit(serveropt.plugdir);
251 MMSoundMgrHALInit(serveropt.plugdir);
252 if (!serveropt.testmode)
255 pulse_handle = MMSoundMgrPulseInit();
258 /* Wait for ASM Ready */
259 __wait_for_asm_ready();
261 _mm_sound_mgr_device_init();
262 MMSoundMgrHeadsetInit();
263 MMSoundMgrDockInit();
264 MMSoundMgrHdmiInit();
266 MMSoundMgrSessionInit();
269 if (serveropt.startserver) {
270 /* Start Run types */
271 MMSoundMgrRunRunAll();
273 #ifdef USE_HIBERNATION
274 /* set hibernation check */
275 _mm_sound_check_hibernation (HIBERNATION_SOUND_CHECK_PATH);
279 MMSoundMgrIpcReady();
282 if (serveropt.startserver || serveropt.printlist) {
283 MMSoundMgrRunStopAll();
284 if (!serveropt.testmode)
287 MMSoundMgrCodecFini();
290 MMSoundThreadPoolFini();
293 MMSoundMgrHdmiFini();
294 MMSoundMgrDockFini();
295 MMSoundMgrHeadsetFini();
296 MMSoundMgrSessionFini();
297 _mm_sound_mgr_device_fini();
299 MMSoundMgrPulseFini(pulse_handle);
301 #ifdef USE_HIBERNATION
302 if(heynoti_unsubscribe(heynotifd, "HIBERNATION_LEAVE", NULL)) {
303 debug_error("heynoti_unsubscribe failed..\n");
305 heynoti_close(heynotifd);
311 static int getOption(int argc, char **argv, server_arg *arg)
314 char *plugin_env_dir = NULL;
315 static struct option long_options[] = {
316 {"start", 0, 0, 'S'},
317 {"poweroff", 0, 0, 'F'},
320 {"plugdir", 1, 0, 'P'},
321 {"testmode", 0, 0, 'T'},
324 memset(arg, 0, sizeof(server_arg));
326 plugin_env_dir = getenv(PLUGIN_ENV);
327 if (plugin_env_dir) {
328 strncpy (arg->plugdir, plugin_env_dir, sizeof(arg->plugdir)-1);
330 strncpy (arg->plugdir, PLUGIN_DIR, sizeof(arg->plugdir)-1);
339 c = getopt_long (argc, argv, "SFLHRP:T", long_options, &opt_idx);
344 case 'S': /* Start daemon */
345 arg->startserver = 1;
347 case 'F': /* Poweroff */
350 case 'L': /* list of plugins */
354 MMSoundMgrCodecInit(arg->plugdir);
356 case 'P': /* Custom plugindir */
357 strncpy (arg->plugdir, optarg, sizeof(arg->plugdir)-1);
359 case 'T': /* Test mode */
362 case 'H': /* help msg */
364 return usgae(argc, argv);
368 return usgae(argc, argv);
372 //__attribute__ ((destructor))
373 static void _exit_handler(int sig)
375 int ret = MM_ERROR_NONE;
377 ret = MMSoundMgrRunStopAll();
378 if (ret != MM_ERROR_NONE) {
379 debug_error("Fail to stop run-plugin\n");
381 debug_log("All run-type plugin stopped\n");
387 sigaction(SIGINT, &sigint_action, NULL);
388 debug_error("signal(SIGINT) error");
391 sigaction(SIGABRT, &sigabrt_action, NULL);
392 debug_error("signal(SIGABRT) error");
395 sigaction(SIGSEGV, &sigsegv_action, NULL);
396 debug_error("signal(SIGSEGV) error");
399 sigaction(SIGTERM, &sigterm_action, NULL);
400 debug_error("signal(SIGTERM) error");
403 sigaction(SIGSYS, &sigsys_action, NULL);
404 debug_error("signal(SIGSYS) error");
412 static int usgae(int argc, char **argv)
414 fprintf(stderr, "Usage: %s [Options]\n", argv[0]);
415 fprintf(stderr, "\t%-20s: start sound server.\n", "--start,-S");
416 fprintf(stderr, "\t%-20s: handle poweroff\n", "--poweroff,-F");
417 fprintf(stderr, "\t%-20s: help message.\n", "--help,-H");
418 #if 0 /* currently not in use */
419 fprintf(stderr, "\t%-20s: print plugin list.\n", "--list,-L");
420 fprintf(stderr, "\t%-20s: print this message.\n", "--plugdir,-P");