summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKibum Kim <kb0929.kim@samsung.com>2012-02-27 21:15:48 +0900
committerKibum Kim <kb0929.kim@samsung.com>2012-02-27 21:15:48 +0900
commit10c786e725207327fb35035100b391d073da6aeb (patch)
tree27e35f47dfbe9651647e8df83be258ceff8796df /src
downloadaudio-session-manager-10c786e725207327fb35035100b391d073da6aeb.tar.gz
audio-session-manager-10c786e725207327fb35035100b391d073da6aeb.tar.bz2
audio-session-manager-10c786e725207327fb35035100b391d073da6aeb.zip
tizen beta release
Diffstat (limited to 'src')
-rw-r--r--src/audio-session-mgr-server.c1582
-rw-r--r--src/audio-session-mgr.c1252
2 files changed, 2834 insertions, 0 deletions
diff --git a/src/audio-session-mgr-server.c b/src/audio-session-mgr-server.c
new file mode 100644
index 0000000..f7bbd1b
--- /dev/null
+++ b/src/audio-session-mgr-server.c
@@ -0,0 +1,1582 @@
+/*
+ * audio-session-manager
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Seungbae Shin <seungbae.shin@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/ipc.h>
+#include <sys/select.h>
+#include <sys/time.h>
+#include <sys/msg.h>
+#include <glib.h>
+#include <glib/gprintf.h>
+#include <poll.h>
+
+#include <vconf.h>
+#include <audio-session-manager.h>
+#include <asm-log.h>
+#include <string.h>
+#include <errno.h>
+
+#include <sysman.h>
+
+#ifdef USE_SECURITY
+#include <security-server.h>
+#endif
+
+#include <avsys-audio.h>
+
+#define HIBERNATION_CHECK_KEY "memory/hibernation/audio_ready"
+#define HIBERNATION_READY 1
+#define USE_SYSTEM_SERVER_PROCESS_MONITORING
+
+#define SUPPORT_GCF /* currently in use */
+
+static const ASM_sound_cases_t ASM_sound_case[ASM_PRIORITY_MATRIX_MIN+1][ASM_PRIORITY_MATRIX_MIN+1] =
+{
+ /* SP SC SS SO SA, EP EC ES EO EA, N C SF EF EU, A VC M */
+ { 8, 8, 8, 8, 8, 6, 6, 6, 6, 6, 8, 8, 8, 6, 6, 6, 6, 8 }, /* 00 Shared MMPlayer */
+ { 8, 8, 8, 8, 8, 5, 5, 5, 5, 5, 8, 5, 8, 5, 8, 5, 5, 8 }, /* 01 Shared MMCamcorder */
+ { 8, 8, 8, 8, 8, 5, 5, 5, 5, 5, 8, 5, 8, 5, 6, 5, 5, 8 }, /* 02 Shared MMSound */
+ { 8, 8, 8, 8, 8, 5, 5, 5, 5, 5, 8, 5, 8, 5, 6, 5, 5, 8 }, /* 03 Shared OpenAL */
+ { 8, 8, 8, 8, 8, 5, 5, 5, 5, 5, 8, 5, 8, 5, 8, 5, 5, 8 }, /* 04 Shared AVsystem */
+ { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 8, 8, 6, 6, 6, 6, 6, 8 }, /* 05 Exclusive MMPlayer */
+ { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 8, 5, 5, 5, 8, 5, 5 ,8 }, /* 06 Exclusive MMCamcorder */
+ { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 8, 5, 5, 5, 6, 5, 5, 8 }, /* 07 Exclusive MMSound */
+ { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 8, 5, 5, 5, 6, 5, 5, 8 }, /* 08 Exclusive OpenAL */
+ { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 8, 5, 5, 5, 8, 5, 5, 8 }, /* 09 Exclusive AVsystem */
+ { 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 5, 8, 8, 8, 5, 5, 8 }, /* 10 Notify */
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 0, 1, 1, 8, 8, 1, 8 }, /* 11 Call */
+ { 8, 8, 8, 8, 8, 5, 5, 5, 5, 5, 8, 5, 5, 5, 8, 5, 5, 8 }, /* 12 Shared FMradio */
+ { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 8, 5, 5, 5, 8, 5, 5, 8 }, /* 13 Exclusive FMradio */
+ { 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 }, /* 14 Earjack Unplug */
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 5, 1, 1, 8, 8, 5, 8 }, /* 15 Alarm */
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 1, 1, 1, 8, 8, 0, 8 }, /* 16 Video Call */
+ { 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 }, /* 17 Monitor */
+};
+
+typedef struct _list
+{
+ long int instance_id;
+ int sound_handle;
+ ASM_sound_events_t sound_event;
+ ASM_sound_states_t sound_state;
+ ASM_resume_states_t need_resume;
+ ASM_resource_t mm_resource;
+ avsys_audio_playing_devcie_t device_when_interrupted;
+ unsigned short monitor_active;
+ unsigned short monitor_dirty;
+ struct _list *next;
+} asm_instance_list_t;
+
+asm_instance_list_t *head_list, *tail_list;
+
+int asm_snd_msgid;
+int asm_rcv_msgid;
+int asm_cb_msgid;
+ASM_msg_lib_to_asm_t asm_rcv_msg;
+ASM_msg_asm_to_lib_t asm_snd_msg;
+ASM_msg_asm_to_cb_t asm_cb_msg;
+
+bool asm_is_send_msg_to_cb = false;
+
+#ifdef SUPPORT_GCF
+#define GCF_DEFAULT 0
+int is_gcf = GCF_DEFAULT;
+#endif
+
+unsigned int g_sound_status_pause = 0;
+unsigned int g_sound_status_playing = 0;
+
+#define SERVER_HANDLE_MAX_COUNT 256
+
+static const char* ASM_sound_events_str[] =
+{
+ "SHARE_MMPLAYER",
+ "SHARE_MMCAMCORDER",
+ "SHARE_MMSOUND",
+ "SHARE_OPENAL",
+ "SHARE_AVSYSTEM",
+ "EXCLUSIVE_MMPLAYER",
+ "EXCLUSIVE_MMCAMCORDER",
+ "EXCLUSIVE_MMSOUND",
+ "EXCLUSIVE_OPENAL",
+ "EXCLUSIVE_AVSYSTEM",
+ "NOTIFY",
+ "CALL",
+ "SHARE_FMRADIO",
+ "EXCLUSIVE_FMRADIO",
+ "EARJACK_UNPLUG",
+ "ALARM",
+ "VIDEOCALL",
+ "MONITOR"
+};
+
+static const char* ASM_sound_state_str[] =
+{
+ "STATE_NONE",
+ "STATE_PLAYING",
+ "STATE_WAITING",
+ "STATE_STOP",
+ "STATE_PAUSE",
+ "STATE_PAUSE_BY_APP",
+ "STATE_ALTER_PLAYING"
+};
+
+
+static const char* ASM_sound_request_str[] =
+{
+ "REQUEST_REGISTER",
+ "REQUEST_UNREGISTER",
+ "REQUEST_GETSTATE",
+ "REQUEST_GETMYSTATE",
+ "REQUEST_SETSTATE",
+ "REQUEST_EMEGENT_EXIT",
+ "REQUEST_DUMP"
+};
+
+
+static const char* ASM_sound_cases_str[] =
+{
+ "CASE_NONE",
+ "CASE_1PLAY_2STOP",
+ "CASE_1PLAY_2ALTER_PLAY",
+ "CASE_1PLAY_2WAIT",
+ "CASE_1ALTER_PLAY_2PLAY",
+ "CASE_1STOP_2PLAY",
+ "CASE_1PAUSE_2PLAY",
+ "CASE_1VIRTUAL_2PLAY",
+ "CASE_1PLAY_2PLAY_MIX"
+};
+
+static const char* ASM_sound_resume_str[] =
+{
+ "NO-RESUME",
+ "RESUME"
+};
+
+
+static const char* ASM_sound_command_str[] =
+{
+ "CMD_NONE",
+ "CMD_WAIT",
+ "CMD_PLAY",
+ "CMD_STOP",
+ "CMD_PAUSE",
+ "CMD_RESUME",
+};
+
+#define ASM_SND_MSG_SET(asm_snd_msg, x_alloc_handle, x_cmd_handle, x_result_sound_command, x_result_sound_state) \
+do { \
+ asm_snd_msg.data.alloc_handle = x_alloc_handle; \
+ asm_snd_msg.data.cmd_handle = x_cmd_handle; \
+ asm_snd_msg.data.result_sound_command = x_result_sound_command; \
+ asm_snd_msg.data.result_sound_state = x_result_sound_state; \
+} while (0)
+
+void selectSleep(int secs)
+{
+ struct timeval timeout;
+ timeout.tv_sec = (secs < 1 || secs > 10) ? 3 : secs;
+ timeout.tv_usec = 0;
+ select(0, NULL, NULL, NULL, &timeout);
+ return;
+}
+
+
+gboolean __find_clean_monitor_handle(int instance_id, int *handle)
+{
+ asm_instance_list_t *temp_list = head_list;
+ int lhandle = -1;
+
+ while (temp_list->next != tail_list) {
+ if (temp_list->instance_id == instance_id && temp_list->sound_event == ASM_EVENT_MONITOR) {
+ if (temp_list->monitor_dirty == 0) {
+ lhandle = temp_list->sound_handle;
+ }
+ break;
+ }
+ temp_list = temp_list->next;
+ }
+ if (lhandle == -1) {
+ return FALSE;
+ } else {
+ *handle = lhandle;
+ return TRUE;
+ }
+}
+
+void __update_monitor_active(long int instance_id)
+{
+ asm_instance_list_t *temp_list = head_list;
+ asm_instance_list_t *monitor_list = NULL;
+ unsigned short active = 0;
+ asm_info("[ASM_Server] %s\n",__func__);
+
+ while (temp_list->next != tail_list) {
+ if (temp_list->instance_id == instance_id && temp_list->sound_event == ASM_EVENT_MONITOR) {
+ /* backup monitor pointer */
+ monitor_list = temp_list;
+ break;
+ }
+ temp_list = temp_list->next;
+ }
+ if (NULL == monitor_list) {
+ asm_warning("[ASM_Server] %s : No monitor instance for %d\n",__func__, instance_id);
+ return;
+ }
+
+ temp_list = head_list;
+ while (temp_list->next != tail_list) {
+ if (temp_list->instance_id == instance_id && temp_list->sound_event != ASM_EVENT_MONITOR) {
+ if (ASM_STATE_PLAYING == temp_list->sound_state) {
+ active = 1;
+ break;
+ }
+ }
+ temp_list = temp_list->next;
+ }
+
+ monitor_list->monitor_active = active;
+}
+
+void __set_all_monitor_clean()
+{
+ asm_instance_list_t *temp_list = head_list;
+
+ while (temp_list->next != tail_list) {
+ if (temp_list->sound_event == ASM_EVENT_MONITOR) {
+ temp_list->monitor_dirty = 0;
+ }
+ temp_list = temp_list->next;
+ }
+}
+
+void __set_monitor_dirty(long int instance_id)
+{
+ asm_instance_list_t *temp_list = head_list;
+
+ while (temp_list->next != tail_list) {
+ if (temp_list->instance_id == instance_id && temp_list->sound_event == ASM_EVENT_MONITOR) {
+ temp_list->monitor_dirty = 1;
+ break;
+ }
+ temp_list = temp_list->next;
+ }
+}
+
+/* callback without retcb */
+void __do_callback_wo_retcb(int instance_id,int handle,int command)
+{
+ int fd_ASM = 0, cur_handle = 0;
+ char *filename = g_strdup_printf("/tmp/ASM.%d.%d", instance_id, handle);
+
+ if ((fd_ASM = open(filename,O_WRONLY|O_NONBLOCK)) < 0) {
+ asm_info("[ASM_Server][CallCB] %s open error",filename);
+ g_free(filename);
+ return;
+ }
+ cur_handle = (unsigned int)(handle |(command << 4));
+ if (write(fd_ASM, (void *)&cur_handle, sizeof(cur_handle)) < 0) {
+ asm_info("[ASM_Server][CallCB] %s write error",filename);
+ g_free(filename);
+ return;
+ }
+ close(fd_ASM);
+ g_free(filename);
+ selectSleep(2); /* if return immediately bad sound occur */
+}
+
+
+int __do_callback(int instance_id,int handle,int command, ASM_event_sources_t event_src)
+{
+ char *filename = NULL;
+ char *filename2 = NULL;
+ struct timeval time;
+ int starttime = 0;
+ int endtime = 0;
+ int fd=0,nread = 0;
+ int fd_ASM = 0, cur_handle = 0;
+ int buf = 0;
+ struct pollfd pfd;
+ int pret = 0;
+ int pollingTimeout = 7000;
+
+ asm_info("[ASM_Server] __do_callback for pid(%d) handle(%d)\n", instance_id, handle);
+
+ /* Set start time */
+ gettimeofday(&time, NULL);
+ starttime = time.tv_sec * 1000000 + time.tv_usec;
+
+ /**************************************
+ *
+ * Open callback cmd pipe
+ *
+ **************************************/
+ filename = g_strdup_printf("/tmp/ASM.%d.%d", instance_id, handle);
+ if ((fd_ASM = open(filename, O_WRONLY|O_NONBLOCK)) < 0) {
+ asm_error("[ASM_Server][CallCB] %s open error\n", filename);
+ goto fail;
+ }
+
+ /******************************************
+ *
+ * Open callback result pipe
+ * before writing callback cmd to pipe
+ *
+ ******************************************/
+ filename2 = g_strdup_printf("/tmp/ASM.%d.%dr", instance_id, handle);
+ if ((fd=open(filename2,O_RDONLY|O_NONBLOCK))== -1) {
+ char str_error[256];
+ strerror_r (errno, str_error, sizeof(str_error));
+ asm_error("[ASM_Server][RETCB] Fail to open fifo (%s)\n", str_error);
+ goto fail;
+ }
+ asm_info("[ASM_Server] open return cb %s\n", filename2);
+
+
+ /*******************************************
+ * Write Callback msg
+ *******************************************/
+ cur_handle = (unsigned int)((0x0000ffff & handle) |(command << 16) | (event_src << 24));
+ if (write(fd_ASM, (void *)&cur_handle, sizeof(cur_handle)) < 0) {
+ asm_error("[ASM_Server][CallCB] %s write error\n", filename);
+ goto fail;
+ }
+ /**************************************
+ *
+ * Close callback cmd pipe
+ *
+ **************************************/
+ close(fd_ASM);
+ fd_ASM = -1;
+ g_free(filename);
+ filename = NULL;
+
+ pfd.fd = fd;
+ pfd.events = POLLIN;
+
+ asm_instance_list_t *temp_list = head_list;
+
+
+ /*********************************************
+ *
+ * Wait callback result msg
+ *
+ ********************************************/
+ asm_critical("[ASM_Server][RETCB]wait callback(tid=%d, handle=%d, cmd=%d, timeout=%d)\n", instance_id, handle, command, pollingTimeout);
+ pret = poll(&pfd, 1, pollingTimeout); //timeout 7sec
+ if (pret < 0) {
+ asm_error("[ASM_Server][RETCB]poll failed (%d)\n", pret);
+ goto fail;
+ }
+ if (pfd.revents & POLLIN) {
+ nread=read(fd, (void *)&buf, sizeof(buf));
+ }
+ g_free(filename2);
+ filename2 = NULL;
+
+ /* Calculate endtime and display*/
+ gettimeofday(&time, NULL);
+ endtime = time.tv_sec * 1000000 + time.tv_usec;
+ asm_critical("[ASM_Server][RETCB] ASM_CB_END cbtimelab=%3.3f(second), timeout=%d(milli second) (reciever=%d)\n", ((endtime-starttime)/1000000.), pollingTimeout, instance_id);
+
+ /**************************************
+ *
+ * Close callback result pipe
+ *
+ **************************************/
+ close(fd);
+ fd = -1;
+ asm_info("[ASM_Server][RETCB] Return value 0x%x\n", buf);
+ return buf;
+
+fail:
+ if (filename) {
+ g_free (filename);
+ filename = NULL;
+ }
+ if (filename2) {
+ g_free (filename2);
+ filename2 = NULL;
+ }
+ if (fd_ASM != -1) {
+ close(fd_ASM);
+ fd_ASM = -1;
+ }
+ if (fd != -1) {
+ close (fd);
+ fd = -1;
+ }
+
+ return -1;
+}
+
+gboolean __isPlayingNow()
+{
+ asm_instance_list_t *temp_list = head_list;
+ while (temp_list->next != tail_list) {
+ if (temp_list->sound_state == ASM_STATE_PLAYING ) {
+ return TRUE;
+ }
+
+ temp_list = temp_list->next;
+ }
+ return FALSE;
+}
+
+gboolean __isItPlayingNow(int instance_id, int handle)
+{
+ asm_instance_list_t *temp_list = head_list;
+ while (temp_list->next != tail_list) {
+ if (temp_list->instance_id == instance_id && temp_list->sound_handle == handle) {
+ if (temp_list->sound_state == ASM_STATE_PLAYING) {
+ return TRUE;
+ }
+ }
+
+ temp_list = temp_list->next;
+ }
+ return FALSE;
+}
+
+void __temp_print_list(char * msg)
+{
+ asm_instance_list_t *temp_list = head_list;
+ int i = 0;
+
+ if (NULL != msg) {
+ asm_warning("[ASM_Server] %s\n", msg);
+ }
+ while (temp_list->next != tail_list) {
+ asm_info("[ASM_Server] List[%02d] ( %5ld, %2d, %-20s, %-20s, %9s, 0x%04x)\n", i, temp_list->instance_id, temp_list->sound_handle,
+ ASM_sound_events_str[temp_list->sound_event],
+ ASM_sound_state_str[temp_list->sound_state],
+ ASM_sound_resume_str[temp_list->need_resume],
+ temp_list->mm_resource);
+ temp_list = temp_list->next;
+ i++;
+ }
+}
+
+void updatePhoneStatus()
+{
+ asm_instance_list_t *temp_list = head_list;
+ int i = 0, error = 0;
+
+ g_sound_status_pause = 0;
+ g_sound_status_playing = 0;
+
+ while (temp_list->next != tail_list) {
+ if (temp_list->sound_state == ASM_STATE_PLAYING) {
+ if (temp_list->sound_event >= ASM_EVENT_SHARE_MMPLAYER && temp_list->sound_event < ASM_EVENT_MAX) {
+ g_sound_status_playing |= ASM_sound_type[(temp_list->sound_event) + 1].sound_status;
+ }
+ } else if (temp_list->sound_state == ASM_STATE_PAUSE ) {
+ if (temp_list->sound_event >= ASM_EVENT_SHARE_MMPLAYER && temp_list->sound_event < ASM_EVENT_MAX) {
+ g_sound_status_pause |= ASM_sound_type[(temp_list->sound_event) + 1].sound_status;
+ }
+ }
+ temp_list = temp_list->next;
+ }
+
+ if (vconf_set_int(SOUND_STATUS_KEY, g_sound_status_playing)) {
+ asm_info("[ASM_Server[Error = %d][1st try] phonestatus_set \n", error);
+ if (vconf_set_int(SOUND_STATUS_KEY, g_sound_status_playing)) {
+ asm_critical("[ASM_Server][Error = %d][2nd try] phonestatus_set \n", error);
+ }
+ }
+
+ asm_info("[ASM_Server] soundstatus set to (0x%08x)\n", g_sound_status_playing);
+}
+
+
+void __asm_register_list(long int instance_id, int handle, ASM_sound_events_t sound_event, ASM_sound_states_t sound_state, ASM_resource_t mm_resource)
+{
+ asm_instance_list_t *temp_list;
+ temp_list = (asm_instance_list_t *)malloc(sizeof(asm_instance_list_t));
+ temp_list->instance_id = instance_id;
+ temp_list->sound_handle = handle;
+ temp_list->sound_event = sound_event;
+ temp_list->sound_state = sound_state;
+ temp_list->need_resume = 0;
+ temp_list->mm_resource = mm_resource;
+ temp_list->monitor_active = 0;
+ temp_list->monitor_dirty = 0;
+ temp_list->device_when_interrupted = AVSYS_AUDIO_ROUTE_DEVICE_UNKNOWN;
+ temp_list->next = head_list;
+ head_list = temp_list;
+
+ __temp_print_list("Register List");
+ updatePhoneStatus();
+}
+
+int __asm_unregister_list(int handle)
+{
+ asm_instance_list_t *temp_list = head_list;
+ asm_instance_list_t *temp_list2 = head_list;
+ int instance_id = -1;
+
+ asm_info("[ASM_Server] __asm_unregister_list \n");
+
+ while (temp_list->next != tail_list) {
+ if (temp_list->sound_handle == handle) {
+ instance_id = temp_list->instance_id;
+ if (temp_list == head_list)
+ head_list = temp_list->next;
+ else
+ temp_list2->next = temp_list->next;
+ free(temp_list);
+ break;
+ }
+ temp_list2 = temp_list;
+ temp_list = temp_list->next;
+ }
+
+ __temp_print_list("Unregister List for handle");
+ updatePhoneStatus();
+ return instance_id;
+}
+
+
+/* -------------------------
+ * if PID exist return true, else return false
+ */
+gboolean isPIDExist(int pid)
+{
+ if (pid > 999999 || pid < 2)
+ return FALSE;
+ gchar *tmp = g_malloc0(25);
+ g_sprintf(tmp, "/proc/%d", pid);
+ if (access(tmp, R_OK)==0) {
+ g_free(tmp);
+ return TRUE;
+ }
+ g_free(tmp);
+ return FALSE;
+}
+
+
+/* -------------------------
+ *
+ */
+void __check_dead_process()
+{
+ asm_instance_list_t *temp_list = head_list;
+ asm_instance_list_t *temp_list2 = head_list;
+ while (temp_list->next != tail_list) {
+ if (!isPIDExist(temp_list->instance_id)) {
+ asm_critical_r("[ASM_Server] PID(%ld) not exist! -> ASM_Server resource of pid(%ld) will be cleared \n", temp_list->instance_id, temp_list->instance_id);
+
+ if (temp_list == head_list) {
+ head_list = temp_list->next;
+ }
+ temp_list2->next = temp_list->next;
+ free(temp_list);
+ } else {
+ temp_list2 = temp_list;
+ }
+ temp_list = temp_list2->next;
+ }
+ updatePhoneStatus();
+}
+
+
+
+
+void emergent_exit(int exit_pid)
+{
+ asm_instance_list_t *temp_list = head_list;
+ int handle = -1;
+ int instance_id = -1;
+
+ while (temp_list->next != tail_list) {
+ if (temp_list->instance_id == exit_pid) {
+ handle = temp_list->sound_handle;
+
+ instance_id = __asm_unregister_list(handle);
+
+ if (instance_id != -1) {
+ char str_error[256];
+ char* filename = g_strdup_printf("/tmp/ASM.%d.%d", instance_id, handle);
+ char* filename2 = g_strdup_printf("/tmp/ASM.%d.%dr", instance_id, handle);
+ if (!remove(filename)) {
+ asm_info("[ASM_Server] remove %s success\n", filename);
+ } else {
+ strerror_r (errno, str_error, sizeof (str_error));
+ asm_error("[ASM_Server] remove %s failed with %s\n", filename, str_error);
+ }
+
+ if (!remove(filename2)) {
+ asm_info("[ASM_Server] remove %s success\n", filename2);
+ } else {
+ strerror_r (errno, str_error, sizeof (str_error));
+ asm_error("[ASM_Server] remove %s failed with %s\n", filename2, str_error);
+ }
+
+ g_free(filename);
+ g_free(filename2);
+ }
+ temp_list = head_list;
+ } else {
+ temp_list = temp_list->next;
+ }
+ }
+
+ asm_info("[ASM_Server][EMERGENT_EXIT] complete\n");
+ return;
+}
+
+
+int ___reorder_state(ASM_sound_states_t input)
+{
+ int res = 0;
+
+ switch (input) {
+ case ASM_STATE_IGNORE:
+ case ASM_STATE_NONE:
+ res = 0;
+ break;
+ case ASM_STATE_WAITING:
+ case ASM_STATE_STOP:
+ res = 1;
+ break;
+ case ASM_STATE_PAUSE:
+ case ASM_STATE_PAUSE_BY_APP:
+ res = 2;
+ break;
+ case ASM_STATE_PLAYING:
+ res = 3;
+ break;
+ }
+ return res;
+}
+
+ASM_sound_states_t __asm_find_process_status(int pid)
+{
+ asm_instance_list_t *temp_list = head_list;
+ ASM_sound_states_t result_state = ASM_STATE_NONE;
+
+ asm_info("[ASM_Server] __asm_find_process_status for pid %d\n", pid);
+
+ while (temp_list->next != tail_list) {
+ if (temp_list->instance_id == pid) {
+ if ( ___reorder_state(temp_list->sound_state) >= ___reorder_state(result_state)) {
+ result_state = temp_list->sound_state;
+ }
+ }
+ temp_list = temp_list->next;
+ }
+
+ return result_state;
+}
+
+ASM_sound_states_t __asm_find_list(ASM_requests_t request_id, int handle)
+{
+ asm_instance_list_t *temp_list = head_list;
+
+ asm_info("[ASM_Server] __asm_find_list\n");
+
+ while (temp_list->next != tail_list) {
+ if ((request_id == ASM_REQUEST_GETSTATE && temp_list->sound_handle == handle)) {
+ return temp_list->sound_state;
+ } else {
+ temp_list = temp_list->next;
+ }
+ }
+
+ return ASM_STATE_NONE;
+}
+
+void __asm_change_state_list(long int instance_id, int handle, ASM_sound_states_t sound_state, ASM_resource_t mm_resource)
+{
+ asm_instance_list_t *temp_list = head_list;
+ int monitor_handle = -1;
+ asm_info("[ASM_Server] __asm_change_state_list\n");
+ if (sound_state == ASM_STATE_IGNORE) {
+ asm_info("[ASM_Server] skip update state list %ld-%d\n", instance_id, handle);
+ return;
+ }
+
+ while (temp_list->next != tail_list) {
+ if (temp_list->instance_id == instance_id && temp_list->sound_handle == handle) {
+ temp_list->sound_state = sound_state;
+ temp_list->mm_resource = mm_resource;
+ break;
+ }
+ temp_list = temp_list->next;
+ }
+ __update_monitor_active(instance_id);
+ updatePhoneStatus();
+}
+
+void __asm_change_need_resume_list(long int instance_id, int handle, ASM_resume_states_t need_resume)
+{
+ asm_instance_list_t *temp_list = head_list;
+ asm_info("[ASM_Server] __asm_change_need_resume_list\n");
+ while (temp_list->next != tail_list) {
+ if (temp_list->instance_id == instance_id && temp_list->sound_handle == handle) {
+ temp_list->need_resume = need_resume;
+
+ if (need_resume == ASM_NEED_RESUME) {
+ avsys_audio_playing_devcie_t dev = AVSYS_AUDIO_ROUTE_DEVICE_UNKNOWN;
+ if (AVSYS_SUCCESS(avsys_audio_get_playing_device_info(&dev))) {
+ temp_list->device_when_interrupted = dev;
+ }
+ }
+ break;
+ }
+ temp_list = temp_list->next;
+ }
+}
+
+
+void __asm_create_message_queue()
+{
+ asm_rcv_msgid = msgget((key_t)2014, 0666 | IPC_CREAT);
+ asm_snd_msgid = msgget((key_t)4102, 0666 | IPC_CREAT);
+ asm_cb_msgid = msgget((key_t)4103, 0666 | IPC_CREAT);
+
+ if (asm_snd_msgid == -1 || asm_rcv_msgid == -1 || asm_cb_msgid == -1) {
+ asm_critical("[ASM_Server] msgget failed with error: \n");
+ exit(EXIT_FAILURE);
+ }
+}
+
+void __asm_snd_message()
+{
+ if (msgsnd(asm_snd_msgid, (void *)&asm_snd_msg, sizeof(asm_snd_msg.data), 0) == -1) {
+ asm_critical("[ASM_Server] msgsnd failed with error %d\n", errno);
+ exit(EXIT_FAILURE);
+ }
+}
+
+void __asm_cb_message()
+{
+ if (msgsnd(asm_cb_msgid, (void *)&asm_cb_msg, sizeof(asm_cb_msg.data), 0) == -1) {
+ asm_critical_r("[ASM_Server] msgsnd(Callback msg) failed with error %d\n", errno);
+ exit(EXIT_FAILURE);
+ }
+}
+
+void __asm_rcv_message()
+{
+ if (msgrcv(asm_rcv_msgid, (void *)&asm_rcv_msg, sizeof(asm_rcv_msg.data), 0, 0) == -1) {
+ asm_critical_r("[ASM_Server] msgrcv failed with error %d\n", errno);
+ exit(EXIT_FAILURE);
+ }
+}
+
+void __asm_get_empty_handle(long int instance_id, int *handle)
+{
+ asm_instance_list_t *temp_list = head_list;
+ unsigned int i = 0, find_empty = 0, j = 0;
+ char handle_info[SERVER_HANDLE_MAX_COUNT];
+
+ asm_info("[ASM_Server] __asm_make_handle for %ld\n", instance_id);
+ __temp_print_list("current list before get new handle");
+
+ memset(handle_info, 0, sizeof(char) * SERVER_HANDLE_MAX_COUNT);
+
+ while (temp_list->next != tail_list) {
+ handle_info[temp_list->sound_handle] = 1;
+ temp_list = temp_list->next;
+ }
+
+ for (i = 0; i < ASM_SERVER_HANDLE_MAX; i++) {
+ if (handle_info[i] == 0) {
+ find_empty = 1;
+ break;
+ }
+ }
+ if (find_empty && (i != ASM_SERVER_HANDLE_MAX)) {
+ asm_error_r("[ASM_Server] New handle for %ld is %d\n", instance_id, i);
+ *handle = i;
+ } else {
+ asm_error_r("[ASM_Server] Handle is full for pid %ld\n", instance_id);
+ *handle = -1;
+ }
+
+}
+
+void __print_resource(unsigned short resource_status)
+{
+ if (resource_status == ASM_RESOURCE_NONE)
+ asm_info("[ASM_Server] resource NONE\n");
+ if (resource_status | ASM_RESOURCE_CAMERA)
+ asm_info("[ASM_Server] resource CAMERA\n");
+ if (resource_status | ASM_RESOURCE_VIDEO_OVERLAY)
+ asm_info("[ASM_Server] resource VIDEO OVERLAY\n");
+ if (resource_status | ASM_RESOURCE_HW_ENCORDER)
+ asm_info("[ASM_Server] resource HW ENCORDER\n");
+ if (resource_status | ASM_RESOURCE_HW_DECORDER)
+ asm_info("[ASM_Server] resource HW DECORDER\n");
+ if (resource_status | ASM_RESOURCE_RADIO_TUNNER)
+ asm_info("[ASM_Server] resource RADIO TUNNER\n");
+ if (resource_status | ASM_RESOURCE_TV_TUNNER)
+ asm_info("[ASM_Server] resource TV TUNNER\n");
+}
+
+void __asm_compare_priority_matrix(long int instance_id, int handle, ASM_requests_t request_id,
+ ASM_sound_events_t sound_event,ASM_sound_states_t sound_state, ASM_resource_t mm_resource)
+{
+ int no_conflict_flag = 0;
+
+ /* If nobody is playing now, this means no conflict */
+ if (ASM_STATUS_NONE == g_sound_status_playing) {
+ asm_info("[ASM_Server] __asm_compare_priority_matrix : No conflict ( No existing Sound )\n");
+
+ ASM_SND_MSG_SET(asm_snd_msg, handle, -1, ASM_COMMAND_NONE, sound_state);
+
+ no_conflict_flag = 1;
+ } else { /* Somebody is playing */
+ asm_instance_list_t *temp_list = head_list;
+ int updatedflag = 0;
+ int cb_res = 0;
+ int update_state = ASM_STATE_NONE;
+
+ while (temp_list->next != tail_list) {
+ /* Find who's playing now */
+ if (temp_list->sound_state == ASM_STATE_PLAYING) {
+ /* Found it */
+ ASM_sound_states_t current_play_state = temp_list->sound_state;
+ ASM_sound_events_t current_play_sound_event = temp_list->sound_event;
+ long int current_play_instance_id = temp_list->instance_id;
+ int current_play_handle = temp_list->sound_handle;
+ ASM_resource_t current_using_resource = temp_list->mm_resource;
+
+ if ((current_play_instance_id == instance_id) && (current_play_handle == handle)) {
+ asm_warning("[ASM_Server] This is my handle. skip %d %d\n", instance_id, handle);
+ temp_list = temp_list->next;
+ continue;
+ }
+
+ /* Request is PLAYING */
+ if (sound_state == ASM_STATE_PLAYING) {
+ /* Determine sound policy */
+ ASM_sound_cases_t sound_case = ASM_sound_case[current_play_sound_event][sound_event];
+
+#ifdef SUPPORT_GCF
+ /* GCF case is exception case */
+ /* NOTE : GCF exception case only */
+ if ((is_gcf) && (sound_case != ASM_CASE_1PLAY_2PLAY_MIX)) {
+ sound_case = ASM_CASE_1PLAY_2PLAY_MIX;;
+ }
+#endif
+
+ asm_critical("[ASM_Server] Conflict policy[%x][%x]: %s\n", current_play_sound_event,sound_event,ASM_sound_cases_str[sound_case]);
+ switch (sound_case) {
+ case ASM_CASE_1PLAY_2STOP:
+ {
+ if (current_play_instance_id == instance_id) {
+ /* PID is policy group.*/
+ asm_info("[ASM_Server] Do not send Stop callback in same pid %ld\n", instance_id);
+ } else {
+ ASM_SND_MSG_SET(asm_snd_msg, handle, handle, ASM_COMMAND_STOP, sound_state);
+ temp_list = tail_list; /* skip all remain list */
+ break;
+ }
+
+ /* Prepare msg to send */
+ ASM_SND_MSG_SET(asm_snd_msg, handle, handle, ASM_COMMAND_PLAY, sound_state);
+
+ if (!updatedflag) {
+ if (request_id == ASM_REQUEST_REGISTER){
+ __asm_register_list(instance_id, handle, sound_event, sound_state, mm_resource);
+ } else {
+ __asm_change_state_list(instance_id, handle, sound_state, mm_resource);
+ }
+ updatedflag = 1;
+ }
+ break;
+ }
+
+ case ASM_CASE_1STOP_2PLAY:
+ {
+ if (current_play_instance_id == instance_id) {
+ /* PID is policy group. */
+ asm_info("[ASM_Server] Do not send Stop callback in same pid %ld\n", instance_id);
+ } else {
+ ASM_event_sources_t event_src;
+ unsigned short resource_status = current_using_resource & mm_resource;
+
+ /* Determine root cause of conflict */
+ if (resource_status != ASM_RESOURCE_NONE) {
+ event_src = ASM_EVENT_SOURCE_RESOURCE_CONFLICT;
+ } else {
+ switch (sound_event) {
+ case ASM_EVENT_CALL:
+ case ASM_EVENT_VIDEOCALL:
+ event_src = ASM_EVENT_SOURCE_CALL_START;
+ break;
+
+ case ASM_EVENT_EARJACK_UNPLUG:
+ event_src = ASM_EVENT_SOURCE_EARJACK_UNPLUG;
+ break;
+
+ case ASM_EVENT_ALARM:
+ event_src = ASM_EVENT_SOURCE_ALARM_START;
+ break;
+
+ default:
+ event_src = ASM_EVENT_SOURCE_OTHER_APP;
+ break;
+ }
+ }
+
+ /* Execute callback function for monitor handle */
+ int monitor_handle = -1;
+ if (__find_clean_monitor_handle(current_play_instance_id, &monitor_handle)) {
+ cb_res = __do_callback(current_play_instance_id, monitor_handle, ASM_COMMAND_STOP, event_src);
+ asm_warning("[ASM_Server] send stop callback for monitor handle of pid %d\n", current_play_instance_id);
+ if (cb_res != ASM_CB_RES_NONE && cb_res != ASM_CB_RES_STOP) {
+ asm_error_r("[ASM_Server] oops! not suspected callback result %d\n", cb_res);
+ }
+ __set_monitor_dirty(current_play_instance_id);
+
+ /* If current is playing and input event is CALL/VIDEOCALL/ALARM, set to need resume */
+ if ((sound_event == ASM_EVENT_CALL || sound_event == ASM_EVENT_VIDEOCALL || sound_event == ASM_EVENT_ALARM)
+ && (current_play_state == ASM_STATE_PLAYING)) {
+ __asm_change_need_resume_list(current_play_instance_id, monitor_handle, ASM_NEED_RESUME);
+ }
+ }
+
+ /* Execute callback function for worker handle */
+ cb_res = __do_callback(current_play_instance_id,current_play_handle,ASM_COMMAND_STOP, event_src);
+ if (cb_res != ASM_CB_RES_NONE && cb_res != ASM_CB_RES_STOP)
+ asm_error_r("[ASM_Server] oops! not suspected result %d\n", cb_res);
+ asm_warning("[ASM_Server] __asm_compare_priority_matrix(1STOP_2PLAY) : __do_callback Complete : TID=%ld, handle=%d",
+ current_play_instance_id,current_play_handle );
+
+ /* If current is playing and input event is CALL/VIDEOCALL/ALARM, set to need resume */
+ if ((sound_event == ASM_EVENT_CALL || sound_event == ASM_EVENT_VIDEOCALL || sound_event == ASM_EVENT_ALARM)
+ && (current_play_state == ASM_STATE_PLAYING)) {
+ __asm_change_need_resume_list(current_play_instance_id, current_play_handle, ASM_NEED_RESUME);
+ }
+
+ /* Set state to NONE */
+ __asm_change_state_list(current_play_instance_id, current_play_handle, ASM_STATE_NONE, ASM_RESOURCE_NONE);
+ }
+
+ /* Prepare msg to send */
+ ASM_SND_MSG_SET(asm_snd_msg, handle, handle, ASM_COMMAND_PLAY, sound_state);
+
+ if (!updatedflag) {
+ if (request_id == ASM_REQUEST_REGISTER) {
+ __asm_register_list(instance_id, handle, sound_event, sound_state, mm_resource);
+ } else {
+ __asm_change_state_list(instance_id, handle, sound_state, mm_resource);
+ }
+ updatedflag = 1;
+ }
+ break;
+ }
+
+ case ASM_CASE_1PAUSE_2PLAY:
+ {
+ ASM_resource_t update_resource = current_using_resource;
+ if (current_play_instance_id == instance_id) {
+ asm_info("[ASM_Server] Do not send Pause callback in same pid %ld\n", instance_id);
+ } else {
+ ASM_event_sources_t event_src;
+ ASM_sound_commands_t command;
+
+ unsigned short resource_status = current_using_resource & mm_resource;
+ if (resource_status != ASM_RESOURCE_NONE) {
+ asm_info("[ASM_Server] resource conflict found 0x%x\n", resource_status);
+ event_src = ASM_EVENT_SOURCE_RESOURCE_CONFLICT;
+ command = ASM_COMMAND_STOP;
+ } else {
+ switch (sound_event) {
+ case ASM_EVENT_CALL:
+ case ASM_EVENT_VIDEOCALL:
+ event_src = ASM_EVENT_SOURCE_CALL_START;
+ break;
+
+ case ASM_EVENT_EARJACK_UNPLUG:
+ event_src = ASM_EVENT_SOURCE_EARJACK_UNPLUG;
+ break;
+
+ case ASM_EVENT_ALARM:
+ event_src = ASM_EVENT_SOURCE_ALARM_START;
+ break;
+
+ case ASM_EVENT_SHARE_MMPLAYER:
+ case ASM_EVENT_EXCLUSIVE_MMPLAYER:
+ if ( current_play_sound_event == ASM_EVENT_SHARE_MMPLAYER ||
+ current_play_sound_event == ASM_EVENT_EXCLUSIVE_MMPLAYER ) {
+ event_src = ASM_EVENT_SOURCE_OTHER_PLAYER_APP;
+ break;
+ }
+
+ default:
+ event_src = ASM_EVENT_SOURCE_OTHER_APP;
+ break;
+ }
+ command = ASM_COMMAND_PAUSE;
+ }
+
+ /* Execute callback function for monitor handle */
+ int monitor_handle = -1;
+ if (__find_clean_monitor_handle(current_play_instance_id, &monitor_handle)) {
+ cb_res = __do_callback(current_play_instance_id, monitor_handle, ASM_COMMAND_STOP, event_src);
+ asm_warning("[ASM_Server] send stop callback for monitor handle of pid %d\n", current_play_instance_id);
+ if (cb_res != ASM_CB_RES_NONE && cb_res != ASM_CB_RES_STOP) {
+ asm_error_r("[ASM_Server] oops! not suspected callback result %d\n", cb_res);
+ }
+ __set_monitor_dirty(current_play_instance_id);
+
+ /* If current is playing and input event is CALL/VIDEOCALL/ALARM, set to need resume */
+ if ((sound_event == ASM_EVENT_CALL || sound_event == ASM_EVENT_VIDEOCALL || sound_event == ASM_EVENT_ALARM)
+ && (current_play_state == ASM_STATE_PLAYING)) {
+ __asm_change_need_resume_list(current_play_instance_id, monitor_handle, ASM_NEED_RESUME);
+ }
+ }
+
+ /* Execute callback function for worker handle */
+ cb_res = __do_callback(current_play_instance_id,current_play_handle,command, event_src);
+ asm_warning("[ASM_Server] %s(1PAUSE_2PLAY) : Callback of %s: TID(%ld)\n",
+ __func__,ASM_sound_command_str[command], current_play_instance_id);
+ /*Change current sound' state when it is in 1Pause_2Play case */
+ switch (cb_res) {
+ case ASM_CB_RES_PAUSE:
+ update_state = ASM_STATE_PAUSE;
+ break;
+
+ case ASM_CB_RES_NONE:
+ case ASM_CB_RES_STOP:
+ update_state = ASM_STATE_NONE;
+ update_resource = ASM_RESOURCE_NONE;
+ break;
+
+ case ASM_CB_RES_IGNORE:
+ update_state = ASM_STATE_IGNORE;
+ break;
+
+ default:
+ asm_error_r("[ASM_Server] oops! not suspected result %d\n", cb_res);
+ update_state = ASM_STATE_NONE;
+ break;
+ }
+
+ /* If current is playing and input event is CALL/VIDEOCALL/ALARM, set to need resume */
+ if ((sound_event == ASM_EVENT_CALL || sound_event == ASM_EVENT_VIDEOCALL || sound_event == ASM_EVENT_ALARM)
+ &&(current_play_state == ASM_STATE_PLAYING)) {
+ __asm_change_need_resume_list(current_play_instance_id, current_play_handle, ASM_NEED_RESUME);
+ }
+
+ __asm_change_state_list(current_play_instance_id, current_play_handle, update_state, update_resource);
+ }
+
+ /* Prepare msg to send */
+ ASM_SND_MSG_SET(asm_snd_msg, handle, handle, ASM_COMMAND_PLAY, sound_state);
+
+ if (!updatedflag) {
+ if (request_id == ASM_REQUEST_REGISTER) {
+ __asm_register_list(instance_id, handle, sound_event, sound_state, mm_resource);
+ } else {
+ __asm_change_state_list(instance_id, handle, sound_state, mm_resource);
+ }
+ updatedflag = 1;
+ }
+ break;
+ }
+
+ case ASM_CASE_1PLAY_2PLAY_MIX:
+ {
+ if (current_play_instance_id == instance_id) {
+ asm_info("[ASM_Server] Do not send check resource conflict in same pid %ld\n", instance_id);
+ } else {
+ /* MIX but need to check resource conflict */
+ asm_warning("[ASM_Server] >>>> __asm_compare_priority_matrix(1PLAY_2PLAY_MIX) : !!!\n");
+ ASM_resource_t update_resource = current_using_resource;
+ unsigned short resource_status = current_using_resource & mm_resource;
+ if (resource_status) { /* Resouce conflict */
+ asm_warning("[ASM_Server] there is system resource conflict 0x%x\n", resource_status);
+ __print_resource(resource_status);
+
+ /* Execute callback function for monitor handle */
+ int monitor_handle = -1;
+ if (__find_clean_monitor_handle(current_play_instance_id, &monitor_handle)) {
+ cb_res = __do_callback(current_play_instance_id, monitor_handle, ASM_COMMAND_STOP, ASM_EVENT_SOURCE_RESOURCE_CONFLICT);
+ if (cb_res != ASM_CB_RES_NONE && cb_res != ASM_CB_RES_STOP) {
+ asm_error_r("[ASM_Server] oops! not suspected callback result %d\n", cb_res);
+ }
+ asm_warning("[ASM_Server] send stop callback for monitor handle of pid %d\n", current_play_instance_id);
+ __set_monitor_dirty(current_play_instance_id);
+
+ /* If current is playing and input event is CALL/VIDEOCALL/ALARM, set to need resume */
+ if ((sound_event == ASM_EVENT_CALL || sound_event == ASM_EVENT_VIDEOCALL || sound_event == ASM_EVENT_ALARM)
+ && (current_play_state == ASM_STATE_PLAYING) ) {
+ __asm_change_need_resume_list(current_play_instance_id, monitor_handle, ASM_NEED_RESUME);
+ }
+ }
+
+ /* Execute callback function for worker handle */
+ /* Stop current resource holding instance */
+ cb_res = __do_callback(current_play_instance_id, current_play_handle, ASM_COMMAND_STOP, ASM_EVENT_SOURCE_RESOURCE_CONFLICT);
+ asm_warning("[ASM_Server] __asm_compare_priority_matrix(1PLAY_2PLAY_MIX) : Resource Conflict : TID(%ld)\n",
+ current_play_instance_id);
+
+ /* Change current sound */
+ switch (cb_res) {
+ case ASM_CB_RES_NONE:
+ case ASM_CB_RES_STOP:
+ update_state = ASM_STATE_NONE;
+ update_resource = ASM_RESOURCE_NONE;
+ break;
+
+ case ASM_CB_RES_IGNORE:
+ update_state = ASM_STATE_IGNORE;
+ break;
+
+ default:
+ asm_error_r("[ASM_Server] oops! not suspected result %d\n", cb_res);
+ update_state = ASM_STATE_NONE;
+ break;
+ }
+
+ __asm_change_state_list(current_play_instance_id, current_play_handle, update_state, update_resource);
+ }
+ }
+
+ /* Prepare msg to send */
+ ASM_SND_MSG_SET(asm_snd_msg, handle, handle, ASM_COMMAND_PLAY, sound_state);
+
+ if (!updatedflag) {
+ if (request_id == ASM_REQUEST_REGISTER) {
+ __asm_register_list(instance_id, handle, sound_event, sound_state, mm_resource);
+ } else {
+ __asm_change_state_list(instance_id, handle, sound_state, mm_resource);
+ }
+ updatedflag = 1;
+ }
+ break;
+ }
+
+ default:
+ {
+ ASM_SND_MSG_SET(asm_snd_msg, handle, handle, ASM_COMMAND_NONE, sound_state);
+ asm_warning("[ASM_Server] >>>> __asm_compare_priority_matrix : ASM_CASE_NONE [It should not be seen] !!!\n");
+ break;
+ }
+ } /* switch (sound_case) */
+ } else {
+ /* Request was not PLAYING, this means no conflict, just do set */
+ asm_info("[ASM_Server] __asm_compare_priority_matrix : No Conflict (Just Register or Set State) !!!\n");
+ ASM_SND_MSG_SET(asm_snd_msg, handle, handle, ASM_COMMAND_NONE, sound_state);
+
+ if (sound_state == ASM_STATE_NONE) {
+ asm_info("[ASM_Server] __asm_compare_priority_matrix(1PLAY_2NONE) : No Conflict !!!\n");
+ } else if (sound_state == ASM_STATE_WAITING) {
+ asm_info("[ASM_Server] __asm_compare_priority_matrix(1PLAY_2WAIT) : No Conflict !!!\n");
+ }
+
+ if (!updatedflag) {
+ if (request_id == ASM_REQUEST_REGISTER) {
+ __asm_register_list(instance_id, handle, sound_event, sound_state, mm_resource);
+ } else {
+ __asm_change_state_list(instance_id, handle, sound_state, mm_resource);
+ }
+ updatedflag = 1;
+ }
+ }
+ } /* if (temp_list->sound_state == ASM_STATE_PLAYING) */
+
+ temp_list = temp_list->next;
+
+ } /* while (temp_list->next != tail_list) */
+
+ /* Make all monitor handle dirty flag clean. */
+ __set_all_monitor_clean();
+ }
+
+ /* Find if resource confilct exists in case of 1Pause 2Play or 1Stop 2Play */
+ if (ASM_STATUS_NONE != g_sound_status_pause && mm_resource != ASM_RESOURCE_NONE &&
+ (asm_snd_msg.data.result_sound_command == ASM_COMMAND_PLAY || no_conflict_flag)) {
+ asm_instance_list_t *temp_list = head_list;
+ int cb_res = 0;
+
+ while (temp_list->next != tail_list) {
+ /* Who is in PAUSE state? */
+ if (temp_list->sound_state == ASM_STATE_PAUSE) {
+ /* Found PAUSE state */
+ asm_warning("[ASM_Server] Now list's state is pause. %d %d\n", instance_id, handle);
+ ASM_sound_states_t current_play_state = temp_list->sound_state;
+ ASM_sound_events_t current_play_sound_event = temp_list->sound_event;
+ long int current_play_instance_id = temp_list->instance_id;
+ int current_play_handle = temp_list->sound_handle;
+ ASM_resource_t current_using_resource = temp_list->mm_resource;
+
+ if ((current_play_instance_id == instance_id) && (current_play_handle == handle)) {
+ if (request_id == ASM_REQUEST_SETSTATE) {
+ asm_warning("[ASM_Server] Own handle. Pause state change to play. %d %d\n", instance_id, handle);
+ __asm_change_state_list(instance_id, handle, sound_state, mm_resource);
+ } else {
+ asm_warning("[ASM_Server] This is my handle. skip %d %d\n", instance_id, handle);
+ }
+ temp_list = temp_list->next;
+ continue;
+ }
+
+ if (sound_state == ASM_STATE_PLAYING) {
+ ASM_sound_cases_t sound_case = ASM_sound_case[current_play_sound_event][sound_event];
+
+ asm_critical("[ASM_Server] Conflict policy[%x][%x]: %s\n", current_play_sound_event, sound_event, ASM_sound_cases_str[sound_case]);
+ switch (sound_case) {
+ case ASM_CASE_1PAUSE_2PLAY:
+ case ASM_CASE_1STOP_2PLAY:
+ {
+ if (current_play_instance_id == instance_id) {
+ //PID is policy group.
+ asm_info("[ASM_Server] Do not send Stop callback in same pid %ld\n", instance_id);
+ } else {
+ unsigned short resource_status = current_using_resource & mm_resource;
+
+ /* Check conflict with paused instance */
+ if (resource_status != ASM_RESOURCE_NONE) {
+ asm_warning("[ASM_Server] there is system resource conflict with paused instance 0x%x\n",resource_status);
+ __print_resource(resource_status);
+ } else {
+ asm_info("[ASM_Server] no resource conflict with paused instance\n");
+ break;
+ }
+
+ /* Execute callback function for monitor handle */
+ int monitor_handle = -1;
+ if (__find_clean_monitor_handle(current_play_instance_id, &monitor_handle)) {
+ cb_res = __do_callback(current_play_instance_id, monitor_handle, ASM_COMMAND_STOP, ASM_EVENT_SOURCE_RESOURCE_CONFLICT);
+ if (cb_res != ASM_CB_RES_NONE && cb_res != ASM_CB_RES_STOP) {
+ asm_error_r("[ASM_Server] oops! not suspected callback result %d\n", cb_res);
+ }
+ asm_warning("[ASM_Server] send stop callback for monitor handle of pid %d\n", current_play_instance_id);
+
+ __set_monitor_dirty(current_play_instance_id);
+ }
+
+ /* Execute callback function for worker handle */
+ cb_res = __do_callback(current_play_instance_id,current_play_handle, ASM_COMMAND_STOP, ASM_EVENT_SOURCE_RESOURCE_CONFLICT);
+ if (cb_res != ASM_CB_RES_NONE && cb_res != ASM_CB_RES_STOP) {
+ asm_error_r("[ASM_Server] oops! not suspected result %d\n", cb_res);
+ }
+ asm_warning("[ASM_Server] __asm_compare_priority_matrix(1STOP_2PLAY) cause RESOURCE : __do_callback Complete : TID=%ld, handle=%d",current_play_instance_id,current_play_handle );
+
+ __asm_change_state_list(current_play_instance_id, current_play_handle, ASM_STATE_NONE, ASM_RESOURCE_NONE);
+ }
+
+ asm_info("[ASM_Server] >>>> __asm_compare_priority_matrix(1STOP_2PLAY) cause RESOURCE : msg sent and then received msg !!!\n");
+ break;
+ }
+
+ default:
+ {
+ /* asm_warning("[ASM_Server] >>>> __asm_compare_priority_matrix : ASM_CASE_NONE [do not anything] !!!\n"); */
+ break;
+ }
+ } /* switch (sound_case) */
+ } else {
+ /* asm_warning("[ASM_Server] >>>> __asm_compare_priority_matrix : ASM_CASE_NONE [do not anything] !!!\n"); */
+ }
+ } /* if (temp_list->sound_state == ASM_STATE_PAUSE) */
+
+ temp_list = temp_list->next;
+ } /* while (temp_list->next != tail_list) */
+ }
+
+ /* Finally, no conflict */
+ if (no_conflict_flag) {
+ if (request_id == ASM_REQUEST_REGISTER) {
+ __asm_register_list(instance_id, handle, sound_event, sound_state, mm_resource);
+ } else {
+ __asm_change_state_list(instance_id, handle, sound_state, mm_resource);
+ }
+ }
+
+ /* Send response to client */
+ asm_snd_msg.instance_id = instance_id;
+ __asm_snd_message();
+}
+
+void __asm_do_all_resume_callback(ASM_event_sources_t eventsrc)
+{
+ asm_instance_list_t *temp_list = head_list;
+ int cb_res = 0;
+ int avsys_err = 0;
+ avsys_audio_playing_devcie_t dev = AVSYS_AUDIO_ROUTE_DEVICE_UNKNOWN;
+
+ asm_info("[ASM_Server] __asm_do_all_resume_callback\n");
+
+ if (AVSYS_FAIL(avsys_err = avsys_audio_get_playing_device_info(&dev))) {
+ asm_error("[ASM_Server] Can not get playing device info\n");
+ }
+
+ while (temp_list->next != tail_list) {
+ if (temp_list->need_resume == ASM_NEED_RESUME) {
+ if ((avsys_err != AVSYS_STATE_SUCCESS) ||
+ (dev == AVSYS_AUDIO_ROUTE_DEVICE_HANDSET && temp_list->device_when_interrupted != AVSYS_AUDIO_ROUTE_DEVICE_HANDSET)) {
+ asm_warning("[ASM_Server] Skip send resume callback. Because sound path has changed to loud during interruption.\n");
+ } else {
+ cb_res = __do_callback(temp_list->instance_id, temp_list->sound_handle, ASM_COMMAND_RESUME, eventsrc);
+ switch (cb_res) {
+ case ASM_CB_RES_PLAYING:
+ temp_list->sound_state = ASM_STATE_PLAYING;
+ break;
+ case ASM_CB_RES_IGNORE:
+ case ASM_CB_RES_NONE:
+ case ASM_CB_RES_STOP:
+ case ASM_CB_RES_PAUSE:
+ default:
+ /* do nothing */
+ break;
+ }
+ }
+ temp_list->need_resume = ASM_NEED_NOT_RESUME;
+ }
+ temp_list = temp_list->next;
+ }
+}
+
+#ifdef USE_SECURITY
+gboolean __asm_check_check_privilege (unsigned char* cookie)
+{
+ int asm_gid = -1;
+ int retval = 0;
+
+ /* Get ASM server group id */
+ asm_gid = security_server_get_gid("asm");
+ asm_info ("[Security] asm server gid = [%d]\n", asm_gid);
+ if (asm_gid < 0) {
+ asm_error ("[Security] security_server_get_gid() failed. error=[%d]\n", asm_gid);
+ return false;
+ }
+
+ /* Check privilege with valid group id */
+ retval = security_server_check_privilege((char *)cookie, asm_gid);
+ if (retval == SECURITY_SERVER_API_SUCCESS) {
+ asm_info("[Security] security_server_check_privilege() returns [%d]\n", retval);
+ return true;
+ } else {
+ asm_error("[Security] security_server_check_privilege() returns [%d]\n", retval);
+ return false;
+ }
+}
+#endif /* USE_SECURITY */
+
+int main()
+{
+ int pid = 0, ret = 0;
+
+ if (sysconf_set_mempolicy(OOM_IGNORE)) {
+ fprintf(stderr, "set mem policy failed\n");
+ }
+ signal(SIGPIPE, SIG_IGN);
+#if !defined(USE_SYSTEM_SERVER_PROCESS_MONITORING)
+ while (1) {
+ if (( pid = fork()) < 0) {
+ asm_critical_r("[ASM_Server]Fork Failed!!!\n");
+ return 0;
+ } else if (pid == 0) {
+ break;
+ } else if (pid > 0) {
+ wait(&ret);
+ asm_critical_r("[ASM_Server]worker(child) dead!!!, try to refork()");
+ }
+ }
+#endif
+ __asm_create_message_queue();
+
+ int temp_msgctl_id1 = msgctl(asm_snd_msgid, IPC_RMID, 0);
+ int temp_msgctl_id2 = msgctl(asm_rcv_msgid, IPC_RMID, 0);
+ int temp_msgctl_id3 = msgctl(asm_cb_msgid, IPC_RMID, 0);
+
+
+ if (temp_msgctl_id1 == -1 || temp_msgctl_id2 == -1 || temp_msgctl_id3 == -1) {
+ asm_info("[ASM_Server] msgctl failed with error: \n");
+ exit(EXIT_FAILURE);
+ }
+ //-------------------------------------------------------------------
+ /*
+ This is unnessasry finaly, but nessasary during implement.
+ */
+
+ __asm_create_message_queue();
+
+ head_list = (asm_instance_list_t *)malloc(sizeof(asm_instance_list_t));
+ tail_list = (asm_instance_list_t *)malloc(sizeof(asm_instance_list_t));
+ head_list->next = tail_list;
+ tail_list->next = tail_list;
+
+
+ long int rcv_instance_id;
+ ASM_requests_t rcv_request_id;
+ ASM_sound_events_t rcv_sound_event;
+ ASM_sound_states_t rcv_sound_state;
+ ASM_resource_t rcv_resource;
+ int rcv_sound_handle;
+
+ /*
+ * Init Vconf
+ */
+ if (vconf_set_int(SOUND_STATUS_KEY, 0)) {
+ asm_critical("[ASM_Server] vconf_set_int fail\n");
+ if (vconf_set_int(SOUND_STATUS_KEY, 0)) {
+ asm_critical_r("[ASM_Server] vconf_set_int fail\n");
+ }
+ }
+ if (vconf_set_int(HIBERNATION_CHECK_KEY, HIBERNATION_READY)) {
+ asm_critical("[ASM_Server] Hibernation check vconf_set_int fail\n");
+ }
+
+#ifdef SUPPORT_GCF
+ if (vconf_get_int(VCONFKEY_ADMIN_GCF_TEST, &is_gcf)) {
+ asm_warning_r("[ASM_Server] vconf_get_int for VCONFKEY_ADMIN_GCF_TEST failed, set as default\n");
+ is_gcf = GCF_DEFAULT;
+ }
+#endif
+
+ while (true) {
+ asm_info("[ASM_Server] asm_Server is waiting message(%d)!!!\n", asm_is_send_msg_to_cb);
+
+ if (!asm_is_send_msg_to_cb) {
+ __asm_rcv_message();
+
+ rcv_instance_id = asm_rcv_msg.instance_id;
+ rcv_sound_handle = asm_rcv_msg.data.handle;
+ rcv_request_id = asm_rcv_msg.data.request_id;
+ rcv_sound_event = asm_rcv_msg.data.sound_event;
+ rcv_sound_state = asm_rcv_msg.data.sound_state;
+ rcv_resource = asm_rcv_msg.data.system_resource;
+
+ /*******************************************************************/
+ asm_info("[ASM_Server] received msg (tid=%ld,handle=%d,req=%d,event=0x%x,state=0x%x,resource=0x%x)\n",
+ rcv_instance_id, rcv_sound_handle, rcv_request_id, rcv_sound_event, rcv_sound_state, rcv_resource);
+ if (rcv_request_id != ASM_REQUEST_EMERGENT_EXIT) {
+ asm_warning("[ASM_Server] request_id : %s\n", ASM_sound_request_str[rcv_request_id]);
+ asm_warning("[ASM_Server] sound_event : %s\n", ASM_sound_events_str[rcv_sound_event]);
+ asm_warning("[ASM_Server] sound_state : %s\n", ASM_sound_state_str[rcv_sound_state]);
+ asm_warning("[ASM_Server] resource : 0x%x\n", rcv_resource);
+ }
+ /*******************************************************************/
+
+ switch (rcv_request_id) {
+ case ASM_REQUEST_REGISTER:
+#ifdef USE_SECURITY
+ /* do security check */
+ if (__asm_check_check_privilege(asm_rcv_msg.data.cookie) == 0) {
+ asm_error ("[Security] __asm_check_check_privilege() failed....\n");
+ asm_snd_msg.instance_id = rcv_instance_id;
+ asm_snd_msg.data.alloc_handle = -1;
+ asm_snd_msg.data.cmd_handle = -1;
+ asm_snd_msg.data.check_privilege = 0;
+ __asm_snd_message();
+ break;
+ }
+ asm_info ("[Security] __asm_check_check_privilege() success\n");
+ asm_snd_msg.data.check_privilege = 1;
+#endif /* USE_SECURITY */
+ __check_dead_process();
+
+ __asm_get_empty_handle(rcv_instance_id, &rcv_sound_handle);
+ if (rcv_sound_handle == -1) {
+ asm_snd_msg.instance_id = rcv_instance_id;
+ asm_snd_msg.data.alloc_handle = -1;
+ asm_snd_msg.data.cmd_handle = -1;
+ __asm_snd_message();
+ } else {
+ __asm_compare_priority_matrix(rcv_instance_id, rcv_sound_handle, rcv_request_id, rcv_sound_event, rcv_sound_state, rcv_resource);
+ }
+
+ break;
+
+ case ASM_REQUEST_UNREGISTER:
+ __asm_unregister_list(rcv_sound_handle);
+ /* only support resuming at end of call & alarm interrupt */
+ switch (rcv_sound_event) {
+ case ASM_EVENT_CALL:
+ case ASM_EVENT_VIDEOCALL:
+ __asm_do_all_resume_callback(ASM_EVENT_SOURCE_CALL_END);
+ break;
+ case ASM_EVENT_ALARM:
+ __asm_do_all_resume_callback(ASM_EVENT_SOURCE_ALARM_END);
+ break;
+ default:
+ break;
+ }
+
+ break;
+
+ case ASM_REQUEST_SETSTATE:
+ __check_dead_process();
+ if ( rcv_sound_state == ASM_STATE_PLAYING ) {
+ if ( __isItPlayingNow(rcv_instance_id, rcv_sound_handle)) {
+ __asm_change_state_list(rcv_instance_id, rcv_sound_handle, rcv_sound_state, rcv_resource);
+
+ asm_snd_msg.data.cmd_handle = rcv_sound_handle;
+ asm_snd_msg.data.result_sound_command = ASM_COMMAND_NONE;
+ asm_snd_msg.data.result_sound_state = rcv_sound_state;
+ asm_snd_msg.instance_id = rcv_instance_id;
+
+ __asm_snd_message();
+ } else {
+ __asm_compare_priority_matrix(rcv_instance_id, rcv_sound_handle, rcv_request_id, rcv_sound_event, rcv_sound_state, rcv_resource);
+ }
+ __temp_print_list("Set State (Play)");
+ } else {
+ __asm_change_state_list(rcv_instance_id, rcv_sound_handle, rcv_sound_state, rcv_resource);
+ __temp_print_list("Set State (Not Play)");
+ }
+ break;
+
+ case ASM_REQUEST_GETSTATE:
+ asm_snd_msg.instance_id = rcv_instance_id;
+ asm_snd_msg.data.result_sound_state = __asm_find_list(rcv_request_id, rcv_sound_handle);
+ __asm_snd_message();
+ break;
+
+ case ASM_REQUEST_GETMYSTATE:
+ __check_dead_process();
+ asm_snd_msg.instance_id = rcv_instance_id;
+ asm_snd_msg.data.result_sound_state = __asm_find_process_status(rcv_instance_id);
+ __asm_snd_message();
+ break;
+
+ case ASM_REQUEST_DUMP:
+ __temp_print_list("DUMP");
+ break;
+
+ case ASM_REQUEST_EMERGENT_EXIT:
+ emergent_exit(rcv_instance_id);
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+
+ return 0;
+}
+
diff --git a/src/audio-session-mgr.c b/src/audio-session-mgr.c
new file mode 100644
index 0000000..2178161
--- /dev/null
+++ b/src/audio-session-mgr.c
@@ -0,0 +1,1252 @@
+/*
+ * audio-session-manager
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Seungbae Shin <seungbae.shin@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#define CONFIG_ENABLE_MULTI_INSTANCE
+#define CONFIG_ENABLE_ASM_SERVER_USING_GLIB
+#define CONFIG_ENABLE_SIGNAL_HANDLER
+#define CONFIG_ENABLE_RETCB
+#define MAKE_HANDLE_FROM_SERVER
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <glib.h>
+#include <sys/poll.h>
+#include <sys/syscall.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/msg.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <poll.h>
+#include <string.h>
+
+#ifdef USE_SECURITY
+#include <security-server.h>
+#endif
+
+#if defined(USE_VCONF)
+#include <vconf.h>
+#include <errno.h>
+#else
+#include <gconf/gconf.h>
+#include <gconf/gconf-client.h>
+#include <phonestatus.h>
+
+#endif
+#include "../include/audio-session-manager.h"
+#include "../include/asm-log.h"
+
+#define asmgettid() (long int)getpid()
+#define ASM_HANDLE_MAX 256
+
+#define NO_EINTR(stmt) while ((stmt) == -1 && errno == EINTR); /* sample code by THE LINUX PROGRAMMING INTERFACE */
+
+int asm_register_instance_id;
+
+int asm_snd_msgid;
+int asm_rcv_msgid;
+int asm_cb_msgid;
+
+ASM_msg_lib_to_asm_t asm_snd_msg;
+ASM_msg_asm_to_lib_t asm_rcv_msg;
+ASM_msg_asm_to_cb_t asm_cb_msg;
+
+ASM_sound_cb_t asm_callback;
+
+unsigned char str_pass[] = "< OK >";
+unsigned char str_fail[] = "<FAIL>";
+
+typedef gboolean (*gLoopPollHandler_t)(gpointer d);
+
+typedef struct
+{
+ ASM_sound_events_t sound_event;
+ int asm_fd;
+ ASM_sound_cb_t asm_callback;
+ void *cb_data;
+ int asm_tid;
+ int handle;
+ bool is_used;
+ GSource* asm_src;
+ guint ASM_g_id;
+} ASM_sound_ino_t;
+
+ASM_sound_ino_t ASM_sound_handle[ASM_HANDLE_MAX];
+
+static const char* ASM_sound_events_str[] =
+{
+ "SHARE_MMPLAYER",
+ "SHARE_MMCAMCORDER",
+ "SHARE_MMSOUND",
+ "SHARE_OPENAL",
+ "SHARE_AVSYSTEM",
+ "EXCLUSIVE_MMPLAYER",
+ "EXCLUSIVE_MMCAMCORDER",
+ "EXCLUSIVE_MMSOUND",
+ "EXCLUSIVE_OPENAL",
+ "EXCLUSIVE_AVSYSTEM",
+ "NOTIFY",
+ "CALL",
+ "SHARE_FMRADIO",
+ "EXCLUSIVE_FMRADIO",
+ "EARJACK_UNPLUG",
+ "ALARM",
+ "VIDEOCALL",
+ "MONITOR"
+};
+
+static const char* ASM_sound_cases_str[] =
+{
+ "CASE_NONE",
+ "CASE_1PLAY_2STOP",
+ "CASE_1PLAY_2ALTER_PLAY",
+ "CASE_1PLAY_2WAIT",
+ "CASE_1ALTER_PLAY_2PLAY",
+ "CASE_1STOP_2PLAY",
+ "CASE_1PAUSE_2PLAY",
+ "CASE_1VIRTUAL_2PLAY",
+ "CASE_1PLAY_2PLAY_MIX"
+};
+
+static const char* ASM_sound_state_str[] =
+{
+ "STATE_NONE",
+ "STATE_PLAYING",
+ "STATE_WAITING",
+ "STATE_STOP",
+ "STATE_PAUSE",
+ "STATE_PAUSE_BY_APP",
+ "STATE_ALTER_PLAYING"
+};
+
+/*
+ * function prototypes
+ */
+
+
+unsigned int ASM_all_sound_status;
+
+void __asm_init_module(void);
+void __asm_fini_module(void);
+int __ASM_find_index(int handle);
+
+bool __ASM_get_sound_state(unsigned int *all_sound_status, int *error_code)
+{
+ int value = 0;
+
+ if(vconf_get_int(SOUND_STATUS_KEY, &value)) {
+ asm_error_r("[Error = %d] __ASM_get_sound_state => phonestatus_get \n", ERR_ASM_VCONF_ERROR);
+ return false;
+ }
+ asm_info(" __ASM_get_sound_state : All status(%#X) \n", value);
+ *all_sound_status = value;
+ ASM_all_sound_status = value;
+
+ return true;
+}
+
+bool __ASM_set_sound_state(ASM_sound_events_t sound_event, ASM_sound_states_t sound_state, int *error_code)
+{
+ /* this function will deprecated */
+ asm_info(" __ASM_set_sound_state : Event(%s), State(%s)\n",
+ ASM_sound_events_str[sound_event], ASM_sound_state_str[sound_state]);
+
+ return true;
+}
+
+gboolean __asm_fd_check(GSource * source)
+{
+ GSList *fd_list;
+ fd_list = source->poll_fds;
+ GPollFD *temp;
+
+ do {
+ temp = (GPollFD*)fd_list->data;
+ if (temp->revents & (POLLIN | POLLPRI))
+ return TRUE;
+ fd_list = fd_list->next;
+ } while (fd_list);
+
+ return FALSE; /* there is no change in any fd state */
+}
+
+
+gboolean __asm_fd_prepare(GSource *source, gint *timeout)
+{
+ return FALSE;
+}
+
+gboolean __asm_fd_dispatch(GSource *source, GSourceFunc callback, gpointer user_data)
+{
+ callback(user_data);
+ return TRUE;
+}
+
+gboolean asm_callback_handler( gpointer d)
+{
+ GPollFD *data = (GPollFD*)d;
+ unsigned int buf;
+ int count;
+ int tid = 0;
+ int asm_index = 0;
+ asm_info("asm_callback_handler");
+
+ if (data->revents & (POLLIN | POLLPRI)) {
+ int handle;
+ int error_code = 0;
+ int event_src;
+ unsigned int sound_status_value;
+ ASM_sound_commands_t rcv_command;
+ ASM_cb_result_t cb_res = ASM_CB_RES_NONE;
+
+
+ count = read(data->fd, &buf, sizeof(int));
+
+ handle = (int)( buf & 0x0000ffff);
+ rcv_command = (ASM_sound_commands_t)((buf >> 16) & 0x0f);
+ event_src = (ASM_event_sources_t)((buf >> 24) & 0x0f);
+
+ asm_index = __ASM_find_index(handle);
+ if (asm_index == -1) {
+ asm_critical_r("asm_callback_handler : Can not find index\n");
+ return false;
+ }
+
+ tid = ASM_sound_handle[asm_index].asm_tid;
+
+ if (rcv_command) {
+ asm_critical("[RETCB] got and start CB : TID(%d), handle(%d) cmd(%d) event_src(%d)\n", tid, handle, rcv_command, event_src );
+ if (!__ASM_get_sound_state(&sound_status_value, &error_code)) {
+ asm_info("[ASM_CB][Error = %d] asm_callback_handler : ASM_set_sound_state => __ASM_get_sound_state \n", error_code);
+ }
+ switch (rcv_command) {
+ case ASM_COMMAND_PLAY:
+ case ASM_COMMAND_RESUME:
+ case ASM_COMMAND_PAUSE:
+ case ASM_COMMAND_STOP:
+ if (ASM_sound_handle[asm_index].asm_callback == NULL) {
+ asm_info("callback is null!!!!\n");
+ return FALSE;
+ }
+ asm_info("ASM callback function pointer - start(%p)\n",ASM_sound_handle[asm_index].asm_callback);
+ if (ASM_sound_handle[asm_index].asm_callback != NULL) {
+ cb_res = (ASM_sound_handle[asm_index].asm_callback)(handle, event_src, rcv_command, sound_status_value, ASM_sound_handle[asm_index].cb_data);
+ } else {
+ asm_info("[ASM_CB][RETCB]callback in null(possibly unregistered simultaneously)\n");
+ }
+ asm_info("[ASM_CB][RETCB]callback - end\n");
+ break;
+ default:
+ break;
+ }
+#ifdef CONFIG_ENABLE_RETCB
+ int rett = 0;
+ int buf = cb_res;
+ int tmpfd = -1;
+ char *filename2 = g_strdup_printf("/tmp/ASM.%d.%dr", ASM_sound_handle[asm_index].asm_tid, handle);
+ tmpfd = open(filename2, O_WRONLY | O_NONBLOCK);
+ if (tmpfd < 0) {
+ char str_error[256];
+ strerror_r(errno, str_error, sizeof(str_error));
+ asm_error("[ASM_CB][RETCB][Failed(May Server Close First)]tid(%d) fd(%d) %s errno=%d(%s)\n", tid, tmpfd, filename2, errno, str_error);
+ g_free(filename2);
+ return FALSE;
+ }
+ rett = write(tmpfd, &buf, sizeof(buf));
+ close(tmpfd);
+ g_free(filename2);
+ asm_info("[RETCB]tid(%d) finishing CB (write=%d)\n", tid, rett);
+#endif
+ }
+ }
+ return TRUE;
+}
+
+bool __ASM_add_sound_callback(int index, int fd, gushort events, gLoopPollHandler_t p_gloop_poll_handler )
+{
+ GSource* cmd_fd_gsrc = NULL;
+ GSourceFuncs *src_funcs = NULL; /* handler function */
+ guint gsource_handle;
+ GPollFD *g_fd_cmd = NULL; /* file descriptor */
+
+ /* 1. make GSource Object */
+ src_funcs = (GSourceFuncs *)g_malloc(sizeof(GSourceFuncs));
+ if (!src_funcs) {
+ asm_info(" __ASM_add_sound_callback : g_malloc failed on g_src_funcs");
+ return false;
+ }
+ src_funcs->prepare = __asm_fd_prepare;
+ src_funcs->check = __asm_fd_check;
+ src_funcs->dispatch = __asm_fd_dispatch;
+ src_funcs->finalize = NULL;
+ cmd_fd_gsrc = g_source_new(src_funcs, sizeof(GSource));
+ if (!cmd_fd_gsrc) {
+ asm_critical(" __ASM_add_sound_callback : g_malloc failed on m_readfd");
+ return false;
+ }
+ ASM_sound_handle[index].asm_src = cmd_fd_gsrc;
+
+ /* 2. add file description which used in g_loop() */
+ g_fd_cmd = (GPollFD *)g_malloc(sizeof(GPollFD));
+ g_fd_cmd->fd = fd;
+ g_fd_cmd->events = events;
+
+ /* 3. combine g_source object and file descriptor */
+ g_source_add_poll(cmd_fd_gsrc, g_fd_cmd);
+ gsource_handle = g_source_attach(cmd_fd_gsrc, NULL);
+ if (!gsource_handle) {
+ asm_critical(" __ASM_add_sound_callback : Error: Failed to attach the source to context");
+ return false;
+ }
+
+ asm_info(" g_source_add_poll : g_src_id(%d)\n", gsource_handle);
+ ASM_sound_handle[index].ASM_g_id = gsource_handle;
+
+ /* 4. set callback */
+ g_source_set_callback(cmd_fd_gsrc, p_gloop_poll_handler,(gpointer)g_fd_cmd, NULL);
+
+ asm_info(" g_source_set_callback : %d\n", errno);
+ return true;
+}
+
+
+bool __ASM_remove_sound_callback(int index, gushort events)
+{
+ bool ret;
+ GPollFD *g_fd_cmd = NULL; /* store file descriptor */
+
+ g_fd_cmd = (GPollFD *)g_malloc(sizeof(GPollFD));
+ g_fd_cmd->fd = ASM_sound_handle[index].asm_fd;
+ g_fd_cmd->events = events;
+
+ asm_info(" g_source_remove_poll : fd(%d), event(%#x)\n", g_fd_cmd->fd, g_fd_cmd->events);
+ g_source_remove_poll(ASM_sound_handle[index].asm_src, g_fd_cmd);
+ asm_info(" g_source_remove_poll : %d\n", errno);
+ ret = g_source_remove(ASM_sound_handle[index].ASM_g_id);
+ asm_info(" g_source_remove : ret(%#X)\n", ret);
+
+ ASM_sound_handle[index].ASM_g_id = 0;
+ ASM_sound_handle[index].asm_src = NULL;
+ ASM_sound_handle[index].asm_callback = NULL;
+
+ return true;
+}
+
+int __ASM_find_index(int handle)
+{
+ int i = 0;
+ for(i = 0; i< ASM_HANDLE_MAX; i++) {
+ if (handle == ASM_sound_handle[i].handle)
+ return i;
+ }
+ return -1;
+}
+
+void __ASM_add_callback(int index)
+{
+ __ASM_add_sound_callback(index, ASM_sound_handle[index].asm_fd, (gushort)POLLIN | POLLPRI, asm_callback_handler);
+}
+
+
+void __ASM_remove_callback(int index)
+{
+ __ASM_remove_sound_callback(index, (gushort)POLLIN | POLLPRI);
+}
+
+
+void __ASM_open_callback(int index)
+{
+ mode_t pre_mask;
+
+ asm_info(" __ASM_open_callback : index (%d)\n", index);
+ char *filename = g_strdup_printf("/tmp/ASM.%d.%d", ASM_sound_handle[index].asm_tid, ASM_sound_handle[index].handle);
+ pre_mask = umask(0);
+ mknod(filename, S_IFIFO|0666, 0);
+ umask(pre_mask);
+ ASM_sound_handle[index].asm_fd = open( filename, O_RDWR|O_NONBLOCK);
+ if (ASM_sound_handle[index].asm_fd == -1)
+ asm_info(" __ASM_open_callback %s : file open error(%d)\n", str_fail, errno);
+ else
+ asm_info(" __ASM_open_callback : %s : filename(%s), fd(%d)\n", str_pass, filename, ASM_sound_handle[index].asm_fd);
+ g_free(filename);
+
+#ifdef CONFIG_ENABLE_RETCB
+ char *filename2 = g_strdup_printf("/tmp/ASM.%d.%dr", ASM_sound_handle[index].asm_tid, ASM_sound_handle[index].handle);
+ pre_mask = umask(0);
+ mknod(filename2, S_IFIFO | 0666, 0);
+ umask(pre_mask);
+ g_free(filename2);
+#endif
+
+}
+
+
+void __ASM_close_callback(int index)
+{
+ asm_info(" __ASM_close_callback : index (%d)\n", index);
+ if (ASM_sound_handle[index].asm_fd < 0) {
+ asm_info(" __ASM_close_callback : %s : fd error.\n", str_fail);
+ } else {
+ char *filename = g_strdup_printf("/tmp/ASM.%d.%d", ASM_sound_handle[index].asm_tid, ASM_sound_handle[index].handle);
+ close(ASM_sound_handle[index].asm_fd);
+ remove(filename);
+ asm_info(" __ASM_close_callback : %s : filename(%s), fd(%d)\n", str_pass, filename, ASM_sound_handle[index].asm_fd);
+ g_free(filename);
+ }
+
+#ifdef CONFIG_ENABLE_RETCB
+ char *filename2 = g_strdup_printf("/tmp/ASM.%d.%dr", ASM_sound_handle[index].asm_tid, ASM_sound_handle[index].handle);
+
+ /* Defensive code - wait until callback timeout although callback is removed */
+ int buf = ASM_CB_RES_STOP;
+ int tmpfd = -1;
+
+ tmpfd = open(filename2, O_WRONLY | O_NONBLOCK);
+ if (tmpfd < 0) {
+ char str_error[256];
+ strerror_r(errno, str_error, sizeof(str_error));
+ asm_error("[__ASM_close_callback][Failed(May Server Close First)]tid(%d) fd(%d) %s errno=%d(%s)\n",
+ ASM_sound_handle[index].asm_tid, tmpfd, filename2, errno, str_error);
+ } else {
+ asm_info("write ASM_CB_RES_STOP(tid:%d) for waiting server\n", ASM_sound_handle[index].asm_tid);
+ write(tmpfd, &buf, sizeof(buf));
+ close(tmpfd);
+ }
+
+ remove(filename2);
+ g_free(filename2);
+#endif
+
+}
+
+bool __asm_construct_snd_msg(int asm_pid, int handle, ASM_sound_events_t sound_event,
+ ASM_requests_t request_id, ASM_sound_states_t sound_state, ASM_resource_t resource, int *error_code)
+{
+ asm_snd_msg.instance_id = asm_pid;
+
+ asm_snd_msg.data.handle = handle;
+ asm_snd_msg.data.request_id = request_id;
+ asm_snd_msg.data.sound_event = sound_event;
+ asm_snd_msg.data.sound_state = sound_state;
+ asm_snd_msg.data.system_resource = resource;
+
+ asm_info(" ASM_Lib send message (tid=%ld,handle=%d,req=%d,evt=%d,state=%d,resource=%d)\n", asm_snd_msg.instance_id, asm_snd_msg.data.handle,
+ asm_snd_msg.data.request_id, asm_snd_msg.data.sound_event, asm_snd_msg.data.sound_state, asm_snd_msg.data.system_resource);
+ asm_info(" instance_id : %ld\n", asm_snd_msg.instance_id);
+ asm_info(" handle : %d\n", asm_snd_msg.data.handle);
+
+ return true;
+}
+
+
+bool __ASM_init_msg(int *error_code)
+{
+ asm_snd_msgid = msgget((key_t)2014, 0666);
+ asm_rcv_msgid = msgget((key_t)4102, 0666);
+ asm_cb_msgid = msgget((key_t)4103, 0666);
+
+
+ asm_info(" __asm_init !! : snd_msqid(%#X), rcv_msqid(%#X), cb_msqid(%#X)\n", asm_snd_msgid,
+ asm_rcv_msgid, asm_cb_msgid);
+
+
+ if (asm_snd_msgid == -1 || asm_rcv_msgid == -1 || asm_cb_msgid == -1 ) {
+ *error_code = ERR_ASM_MSG_QUEUE_MSGID_GET_FAILED;
+ asm_info(" __ASM_init : Msgget failed with error.\n");
+ return false;
+ }
+
+ return true;
+}
+
+void __ASM_init_callback(int index)
+{
+ __ASM_open_callback(index);
+ __ASM_add_callback(index);
+}
+
+
+void __ASM_destroy_callback(int index)
+{
+ asm_info(" __ASM_destroy_callback !!\n");
+ __ASM_remove_callback(index);
+ __ASM_close_callback(index);
+}
+
+#ifdef USE_SECURITY
+bool __ASM_set_cookie (unsigned char* cookie)
+{
+ int retval = -1;
+ int cookie_size = 0;
+ asm_info ("<<<< [%s]\n", __func__);
+
+ cookie_size = security_server_get_cookie_size();
+ if (cookie_size != COOKIE_SIZE) {
+ asm_error ("[Security] security_server_get_cookie_size(%d) != COOKIE_SIZE(%d)\n", cookie_size, COOKIE_SIZE);
+ return false;
+ }
+
+ retval = security_server_request_cookie (cookie, COOKIE_SIZE);
+ if (retval == SECURITY_SERVER_API_SUCCESS) {
+ asm_info ("[Security] security_server_request_cookie() returns [%d]\n", retval);
+ return true;
+ } else {
+ asm_error ("[Security] security_server_request_cookie() returns [%d]\n", retval);
+ return false;
+ }
+}
+#endif
+
+EXPORT_API
+bool ASM_register_sound(const int application_pid, int *asm_handle, ASM_sound_events_t sound_event, ASM_sound_states_t sound_state, ASM_sound_cb_t callback, void *cb_data, ASM_resource_t mm_resource, int *error_code)
+{
+ int error = 0;
+ unsigned int sound_status_value;
+ int handle = 0;
+ int asm_pid = 0;
+ int index = 0;
+ int ret = 0;
+ unsigned int rcv_sound_status_value;
+
+ if (error_code==NULL) {
+ asm_error_r("[Error] ASM_register_sound : invalid parameter. \n");
+ return false;
+ }
+
+ if (sound_event< ASM_EVENT_SHARE_MMPLAYER || sound_event >= ASM_EVENT_MAX) {
+ *error_code = ERR_ASM_EVENT_IS_INVALID;
+ asm_error_r("[Error] ASM_register_sound : invalid sound event \n");
+ return false;
+ }
+
+ for (index = 0; index < ASM_HANDLE_MAX; index++) {
+ if (ASM_sound_handle[index].is_used == FALSE) {
+ break;
+ }
+ }
+
+ if (index == ASM_HANDLE_MAX) {
+ *error_code = ERR_ASM_EVENT_IS_FULL;
+ asm_error_r("[Error] >>>> ASM_register_sound : local sound event is full(MAX) \n");
+ return false;
+ }
+
+ if (application_pid == -1) {
+ asm_pid = asmgettid();
+ } else if (application_pid > 2) {
+ asm_pid = application_pid;
+ } else {
+ *error_code = ERR_ASM_INVALID_PARAMETER;
+ asm_error_r("[Error] >>>> ASM_register_sound : invalid pid %d\n", application_pid);
+ return false;
+ }
+
+ ASM_sound_handle[index].sound_event = sound_event;
+ ASM_sound_handle[index].asm_tid = asm_pid;
+
+ asm_info(" <<<< ASM_register_sound : Event(%s), Tid(%d), Index(%d) \n", ASM_sound_events_str[sound_event], ASM_sound_handle[index].asm_tid, index);
+
+ if (!__ASM_init_msg(&error)) {
+ asm_error("[Error = %d] >>>> ASM_register_sound =>__asm_init \n", error);
+ }
+
+ if (!__ASM_get_sound_state(&sound_status_value, error_code)) {
+ asm_error("[Error = %d] >>>> ASM_register_sound => __ASM_get_sound_state \n", *error_code);
+ }
+
+ /* If state is PLAYING, do set state immediately */
+ if (sound_state == ASM_STATE_PLAYING) {
+ asm_info(" <<<< ASM_register_sound : Event(%s), Tid(%d), State(PLAYING) \n", ASM_sound_events_str[sound_event], ASM_sound_handle[index].asm_tid);
+ if (!__ASM_set_sound_state(sound_event, ASM_STATE_PLAYING, error_code)) {
+ asm_error_r("[Error = %d] >>>> ASM_register_sound => __ASM_set_sound_state(PLAYING) \n", *error_code);
+ return false;
+ }
+ } else {
+ asm_info(" <<<< ASM_register_sound : Event(%s), Tid(%ld), State(WAITING) \n", ASM_sound_events_str[sound_event], asmgettid());
+ }
+
+
+ handle = -1; /* for register & get handle from server */
+
+#ifdef USE_SECURITY
+ /* get cookie from security server */
+ if (__ASM_set_cookie (asm_snd_msg.data.cookie) == false)
+ return false;
+#endif
+
+ /* Construct msg to send -> send msg -> recv msg */
+ if (!__asm_construct_snd_msg(asm_pid, handle, sound_event, ASM_REQUEST_REGISTER, sound_state, mm_resource, error_code)) {
+ asm_error_r("[Error] >>>> ASM_register_sound : Send msg construct failed.\n");
+ return false;
+ }
+ NO_EINTR(ret = msgsnd(asm_snd_msgid, (void *)&asm_snd_msg, sizeof(asm_snd_msg.data), 0));
+ if (ret == -1) {
+ *error_code = ERR_ASM_MSG_QUEUE_SND_ERROR;
+ asm_error_r("[Error] >>>> ASM_register_sound : Msgsnd failed (%d,%s) \n", errno, strerror(errno));
+ return false;
+ }
+ NO_EINTR(ret = msgrcv(asm_rcv_msgid, (void *)&asm_rcv_msg, sizeof(asm_rcv_msg.data), asm_pid, 0));
+ if (ret == -1) {
+ *error_code = ERR_ASM_MSG_QUEUE_RCV_ERROR;
+ asm_error_r("[Error] >>>> ASM_register_sound : Msgrcv failed (%d,%s) \n", errno, strerror(errno));
+ return false;
+ }
+ /* Construct msg to send -> send msg -> recv msg : end */
+
+#ifdef USE_SECURITY
+ /* Check privilege first */
+ if (asm_rcv_msg.data.check_privilege == 0) {
+ asm_error_r("[Security] Check privilege from server Failed!!!\n");
+ *error_code = ERR_ASM_CHECK_PRIVILEGE_FAILED;
+ return false;
+ } else {
+ asm_info ("[Security] Check privilege from server Success");
+ }
+#endif
+
+ handle = asm_rcv_msg.data.alloc_handle; /* get handle from server */
+ if (handle == -1) {
+ asm_error_r("[Error] >>> ASM_register_sound : Create handle from server failed\n");
+ *error_code = ERR_ASM_HANDLE_IS_FULL;
+ return false;
+ }
+
+ ASM_sound_handle[index].handle = handle;
+
+ __ASM_init_callback(index);
+
+ asm_info( "ASM_register_sound \n");
+/********************************************************************************************************/
+ switch (asm_rcv_msg.data.result_sound_command) {
+ case ASM_COMMAND_PAUSE:
+ case ASM_COMMAND_STOP:
+ if (handle == asm_rcv_msg.data.cmd_handle) {
+
+
+ __ASM_destroy_callback(index);
+
+ ASM_sound_handle[index].asm_fd = 0;
+ ASM_sound_handle[index].asm_tid = 0;
+ ASM_sound_handle[index].sound_event = ASM_EVENT_NONE;
+ ASM_sound_handle[index].is_used = FALSE;
+
+ *error_code = ERR_ASM_POLICY_CANNOT_PLAY;
+ return false;
+ } else {
+ int action_index = 0;
+
+ if (!__ASM_get_sound_state(&rcv_sound_status_value, error_code)) {
+ asm_error("[ASM_CB][Error = %d] asm_callback_handler : ASM_set_sound_state => __ASM_get_sound_state \n", *error_code);
+ }
+
+ asm_info("[ASM_CB] asm_callback_handler : Callback : TID(%ld), handle(%d)\n", asm_rcv_msg.instance_id, asm_rcv_msg.data.cmd_handle);
+ action_index = __ASM_find_index(asm_rcv_msg.data.cmd_handle);
+ if (action_index == -1) {
+ asm_error("[ASM_CB] Can not find index of instance %ld, handle %d\n", asm_rcv_msg.instance_id, asm_rcv_msg.data.cmd_handle);
+ } else {
+ if (ASM_sound_handle[action_index].asm_callback!=NULL) {
+ ASM_sound_handle[action_index].asm_callback(asm_rcv_msg.data.cmd_handle, ASM_sound_handle[action_index].sound_event, asm_rcv_msg.data.result_sound_command, rcv_sound_status_value, ASM_sound_handle[action_index].cb_data);
+ } else {
+ asm_info("[ASM_CB] null callback");
+ }
+ }
+ }
+ break;
+
+ case ASM_COMMAND_PLAY:
+ case ASM_COMMAND_NONE:
+ case ASM_COMMAND_RESUME:
+ default:
+ break;
+ }
+/********************************************************************************************************/
+
+
+ ASM_sound_handle[index].asm_callback = callback;
+ ASM_sound_handle[index].cb_data = cb_data;
+ ASM_sound_handle[index].is_used = TRUE;
+
+ asm_info(" >>>> ASM_register_sound : Event(%s), Handle(%d), CBFuncPtr(%p) \n", ASM_sound_events_str[sound_event], handle, callback);
+ /* Add [out] param, asm_handle */
+ *asm_handle = handle;
+
+ return true;
+
+}
+
+EXPORT_API
+bool ASM_change_callback(const int asm_handle, ASM_sound_events_t sound_event, ASM_sound_cb_t callback, void *cb_data, int *error_code)
+{
+ int handle=0;
+
+ if (error_code==NULL) {
+ asm_error_r("[Error] ASM_unregister_sound : invalid parameter. \n");
+ return false;
+ }
+
+ if (sound_event < ASM_EVENT_SHARE_MMPLAYER || sound_event >= ASM_EVENT_MAX) {
+ *error_code = ERR_ASM_EVENT_IS_INVALID;
+ asm_error_r("[Error] ASM_unregister_sound : invalid sound event \n");
+ return false;
+ }
+
+ int asm_index = -1;
+
+ if (asm_handle < 0 || asm_handle >= ASM_SERVER_HANDLE_MAX) {
+ *error_code = ERR_ASM_POLICY_INVALID_HANDLE;
+ asm_error_r("[Error] >>>> invalid handle %d. callback is not registered\n", asm_handle);
+ return false;
+ }
+
+ handle = asm_handle;
+
+ asm_index = __ASM_find_index(handle);
+ if (asm_index == -1) {
+ *error_code = ERR_ASM_POLICY_INVALID_HANDLE;
+ asm_error_r("[Error] >>>> Can not find index for handle %d [%d]\n", handle, __LINE__);
+ return false;
+ }
+
+ asm_info("callback function has changed to %p\n", callback);
+ ASM_sound_handle[asm_index].asm_callback = callback;
+ ASM_sound_handle[asm_index].cb_data = cb_data;
+
+ return true;
+}
+
+
+EXPORT_API
+bool ASM_unregister_sound(const int asm_handle, ASM_sound_events_t sound_event, int *error_code)
+{
+ int handle=0;
+ int asm_index = -1;
+ int ret = 0;
+
+ if (error_code==NULL) {
+ asm_error_r("[Error] ASM_unregister_sound : invalid parameter. \n");
+ return false;
+ }
+
+ if (sound_event<ASM_EVENT_SHARE_MMPLAYER || sound_event >= ASM_EVENT_MAX) {
+ *error_code = ERR_ASM_EVENT_IS_INVALID;
+ asm_error_r("[Error] ASM_unregister_sound : invalid sound event %d\n", sound_event);
+ return false;
+ }
+
+ if (asm_handle < 0 || asm_handle >= ASM_SERVER_HANDLE_MAX) {
+ *error_code = ERR_ASM_POLICY_INVALID_HANDLE;
+ asm_error_r("[Error] >>>> invalid handle %d. callback is not registered\n", asm_handle);
+ return false;
+ }
+
+ handle = asm_handle;
+ asm_index = __ASM_find_index(handle);
+ if (asm_index == -1) {
+ *error_code = ERR_ASM_POLICY_INVALID_HANDLE;
+ asm_error_r("[Error] >>>> Can not find index for handle %d [%d]\n", handle, __LINE__);
+ return false;
+ }
+ asm_info("<<<< ASM_unregister_sound : Event(%s), Tid(%d), Handle(%d) Index(%d)\n",
+ ASM_sound_events_str[sound_event], ASM_sound_handle[asm_index].asm_tid, ASM_sound_handle[asm_index].handle, asm_index);
+
+ if (!__asm_construct_snd_msg(ASM_sound_handle[asm_index].asm_tid, handle, sound_event, ASM_REQUEST_UNREGISTER, ASM_STATE_NONE, ASM_RESOURCE_NONE, error_code)) {
+ asm_error_r(">>>> Send msg construct failed.\n");
+ return false;
+ }
+
+ NO_EINTR(ret = msgsnd(asm_snd_msgid, (void *)&asm_snd_msg, sizeof(asm_snd_msg.data), 0));
+ if (ret == -1) {
+ *error_code = ERR_ASM_MSG_QUEUE_SND_ERROR;
+ asm_error_r("[Error] >>>> ASM_unregister_sound : Msgsnd failed (%d,%s) \n", errno, strerror(errno));
+ return false;
+ }
+
+ __ASM_destroy_callback(asm_index);
+
+ ASM_sound_handle[asm_index].asm_fd = 0;
+ ASM_sound_handle[asm_index].asm_tid = 0;
+ ASM_sound_handle[asm_index].sound_event = ASM_EVENT_NONE;
+ ASM_sound_handle[asm_index].is_used = FALSE;
+
+ asm_info(">>>> ASM_unregister_sound : Event(%s) \n", ASM_sound_events_str[sound_event]);
+
+ return true;
+}
+
+EXPORT_API
+bool ASM_get_sound_status(unsigned int *all_sound_status, int *error_code)
+{
+ if (all_sound_status == NULL || error_code == NULL) {
+ if (error_code)
+ *error_code = ERR_ASM_UNKNOWN_ERROR;
+ asm_error_r("[Error] ASM_get_sound_status : invalid parameter \n");
+ return false;
+ }
+
+ asm_info("<<<< ASM_get_sound_status : Tid(%ld) \n", asmgettid());
+
+ if (!__ASM_get_sound_state(all_sound_status, error_code)) {
+ asm_error_r("[Error = %d] >>>> ASM_get_sound_status => __ASM_get_sound_state \n", *error_code);
+ return false;
+ }
+
+ asm_info(">>>> ASM_get_sound_status : All status(%#X) \n", *all_sound_status);
+
+ return true;
+}
+
+EXPORT_API
+bool ASM_get_process_session_state(const int asm_handle, ASM_sound_states_t *sound_state, int *error_code)
+{
+ int handle = 0;
+ int asm_index = 0;
+ int ret = 0;
+
+ if (sound_state == NULL || error_code == NULL) {
+ if (error_code)
+ *error_code = ERR_ASM_UNKNOWN_ERROR;
+ asm_error_r("[Error] ASM_get_process_session_state : invalid parameter \n");
+ return false;
+ }
+
+ handle = asm_handle;
+ asm_index = __ASM_find_index(handle);
+ if (asm_index == -1) {
+ asm_error_r("Can not find index of %d [%d]\n", handle, __LINE__);
+ return false;
+ }
+
+
+ asm_info("<<<< ASM_get_process_session_state : Pid(%d)\n", ASM_sound_handle[asm_index].asm_tid);
+
+ if (!__asm_construct_snd_msg(ASM_sound_handle[asm_index].asm_tid, handle, ASM_EVENT_MONITOR, ASM_REQUEST_GETMYSTATE, ASM_STATE_NONE, ASM_RESOURCE_NONE, error_code)) {
+ asm_error_r("[Error] >>>> ASM_get_sound_state : Send msg construct failed.\n");
+ return false;
+ }
+
+
+ NO_EINTR(ret = msgsnd(asm_snd_msgid, (void *)&asm_snd_msg, sizeof(asm_snd_msg.data), 0));
+ if (ret == -1) {
+ *error_code = ERR_ASM_MSG_QUEUE_SND_ERROR;
+ asm_error_r("[Error] >>>> ASM_get_process_session_state : Msgsnd failed (%d,%s) \n", errno, strerror(errno));
+ return false;
+ }
+
+ NO_EINTR(ret = msgrcv(asm_rcv_msgid, (void *)&asm_rcv_msg, sizeof(asm_rcv_msg.data), asm_snd_msg.instance_id, 0));
+ if (ret == -1) {
+ *error_code = ERR_ASM_MSG_QUEUE_RCV_ERROR;
+ asm_error_r("[Error] >>>> ASM_get_process_session_state : Msgrcv failed (%d,%s) \n", errno, strerror(errno));
+ return false;
+ }
+
+ *sound_state = asm_rcv_msg.data.result_sound_state;
+
+ asm_info(">>>> ASM_get_process_session_state : Pid(%d), State(%s) \n", ASM_sound_handle[asm_index].asm_tid, ASM_sound_state_str[*sound_state]);
+
+
+ return true;
+}
+
+EXPORT_API
+bool ASM_get_sound_state(const int asm_handle, ASM_sound_events_t sound_event, ASM_sound_states_t *sound_state, int *error_code)
+{
+ int handle = 0;
+ int asm_index = 0;
+ int ret = 0;
+
+ if (sound_state == NULL || error_code == NULL) {
+ if (error_code)
+ *error_code = ERR_ASM_UNKNOWN_ERROR;
+ asm_error_r("[Error] ASM_get_sound_state : invalid parameter \n");
+ return false;
+ }
+ if (sound_event < ASM_EVENT_SHARE_MMPLAYER || sound_event >= ASM_EVENT_MAX) {
+ *error_code = ERR_ASM_EVENT_IS_INVALID;
+ asm_error_r("[Error] ASM_get_sound_state : invalid sound event (%x)\n",sound_event);
+ return false;
+ }
+ handle = asm_handle;
+
+ asm_index = __ASM_find_index(handle);
+ if (asm_index == -1) {
+ asm_error_r("Can not find index of %d [%d]\n", handle, __LINE__);
+ return false;
+ }
+ asm_info("<<<< ASM_get_sound_state : Event(%s), Tid(%d), handle(%d)\n",
+ ASM_sound_events_str[sound_event], ASM_sound_handle[asm_index].asm_tid, ASM_sound_handle[asm_index].handle);
+
+ if (!__asm_construct_snd_msg(ASM_sound_handle[asm_index].asm_tid, handle, sound_event, ASM_REQUEST_GETSTATE, ASM_STATE_NONE, ASM_RESOURCE_NONE, error_code)) {
+ asm_error_r("[Error] >>>> ASM_get_sound_state : Send msg construct failed.\n");
+ return false;
+ }
+
+
+ NO_EINTR(ret = msgsnd(asm_snd_msgid, (void *)&asm_snd_msg, sizeof(asm_snd_msg.data), 0));
+ if (ret == -1) {
+ *error_code = ERR_ASM_MSG_QUEUE_SND_ERROR;
+ asm_error_r("[Error] >>>> ASM_get_sound_state : Msgsnd failed (%d,%s) \n", errno, strerror(errno));
+ return false;
+ }
+
+ NO_EINTR(ret = msgrcv(asm_rcv_msgid, (void *)&asm_rcv_msg, sizeof(asm_rcv_msg.data), asm_snd_msg.instance_id, 0));
+ if (ret == -1) {
+ *error_code = ERR_ASM_MSG_QUEUE_RCV_ERROR;
+ asm_error_r("[Error] >>>> ASM_get_sound_state : Msgrcv failed (%d,%s) \n", errno, strerror(errno));
+ return false;
+ }
+
+ *sound_state = asm_rcv_msg.data.result_sound_state;
+
+ asm_info(">>>> ASM_get_sound_state : Event(%s), State(%s) \n",
+ ASM_sound_events_str[sound_event], ASM_sound_state_str[*sound_state]);
+
+
+ return true;
+}
+
+
+EXPORT_API
+bool ASM_set_sound_state(const int asm_handle, ASM_sound_events_t sound_event, ASM_sound_states_t sound_state, ASM_resource_t mm_resource, int *error_code)
+{
+ int handle = 0;
+ int asm_index = 0;
+ int ret = 0;
+ unsigned int rcv_sound_status_value;
+
+ asm_info("<<<< ASM_set_sound_state \n");
+ if (error_code == NULL) {
+ asm_error_r("error_code is null \n");
+ return false;
+ }
+
+ if (sound_event < 0 || sound_event > ASM_PRIORITY_MATRIX_MIN) {
+ asm_error_r(" ASM_set_sound_state(%x,%x) arg is out of bound!!\n", sound_event, sound_state);
+ *error_code = ERR_ASM_EVENT_IS_INVALID;
+ return false;
+ }
+
+ if (asm_handle < 0 || asm_handle >= ASM_SERVER_HANDLE_MAX) {
+ *error_code = ERR_ASM_POLICY_INVALID_HANDLE;
+ asm_error_r("[Error] ASM_set_sound_state : Invalid handle %d \n", asm_handle);
+ return false;
+ }
+
+ handle = asm_handle;
+
+ asm_index = __ASM_find_index(handle);
+ if (asm_index == -1) {
+ asm_error_r("Can not find index of %d [%d]\n", handle, __LINE__);
+ return false;
+ }
+
+ asm_info("<<<< ASM_set_sound_state : Event(%s), State(%s), Tid(%d), handle(%d) \n",
+ ASM_sound_events_str[sound_event], ASM_sound_state_str[sound_state], ASM_sound_handle[asm_index].asm_tid, ASM_sound_handle[asm_index].handle);
+
+
+ if (!__asm_construct_snd_msg(ASM_sound_handle[asm_index].asm_tid, ASM_sound_handle[asm_index].handle, sound_event, ASM_REQUEST_SETSTATE, sound_state, mm_resource, error_code)) {
+ asm_error_r("[Error] >>>> ASM_set_sound_state : Send msg construct failed.\n");
+ return false;
+ }
+
+ NO_EINTR(ret = msgsnd(asm_snd_msgid, (void *)&asm_snd_msg, sizeof(asm_snd_msg.data), 0));
+ if (ret == -1) {
+ *error_code = ERR_ASM_MSG_QUEUE_SND_ERROR;
+ asm_error_r("[Error] >>>> ASM_set_sound_state : Msgsnd failed (%d,%s) \n", errno, strerror(errno));
+ return false;
+ }
+
+ if (sound_state == ASM_STATE_PLAYING ) {
+ NO_EINTR(ret = msgrcv(asm_rcv_msgid, (void *)&asm_rcv_msg, sizeof(asm_rcv_msg.data), ASM_sound_handle[handle].asm_tid, 0));
+ if (ret == -1) {
+ *error_code = ERR_ASM_MSG_QUEUE_RCV_ERROR;
+ asm_error_r("[Error] >>>> ASM_set_sound_state : Msgrcv failed (%d,%s) \n", errno, strerror(errno));
+ return false;
+ }
+
+ asm_info( " <<<<<<<<<<<<<<<< [BEFORE] Callback : Main Context >>>>>>>>>>>>>>>>>>>> \n");
+ /********************************************************************************************************/
+ switch (asm_rcv_msg.data.result_sound_command) {
+ case ASM_COMMAND_PAUSE:
+ case ASM_COMMAND_STOP:
+ if (handle == asm_rcv_msg.data.cmd_handle) {
+
+ asm_index = __ASM_find_index(asm_rcv_msg.data.cmd_handle);
+ if (asm_index == -1) {
+ *error_code = ERR_ASM_POLICY_INVALID_HANDLE;
+ asm_error_r( "[Error] >>>> Can not find index from instance_id %ld, handle %d [%d]\n",
+ asm_rcv_msg.instance_id, asm_rcv_msg.data.cmd_handle, __LINE__);
+ return false;
+ }
+
+ *error_code = ERR_ASM_POLICY_CANNOT_PLAY;
+ return false;
+ } else {
+ if (!__ASM_get_sound_state(&rcv_sound_status_value, error_code)) {
+ asm_error("[ASM_CB][Error = %d] asm_callback_handler : ASM_set_sound_state => __ASM_get_sound_state \n", *error_code);
+ }
+
+ asm_info("[ASM_CB] asm_callback_handler : Callback : TID(%ld), handle(%d)\n", asm_rcv_msg.instance_id, asm_rcv_msg.data.cmd_handle);
+
+ asm_index = __ASM_find_index(asm_rcv_msg.data.cmd_handle);
+ if (asm_index == -1) {
+ *error_code = ERR_ASM_POLICY_INVALID_HANDLE;
+ asm_error_r("[Error] >>>> Can not find index from instance_id %ld, handle %d [%d]\n",
+ asm_rcv_msg.instance_id, asm_rcv_msg.data.cmd_handle, __LINE__);
+ return false;
+ }
+
+ if (ASM_sound_handle[asm_index].asm_callback!=NULL) {
+ ASM_sound_handle[asm_index].asm_callback(asm_rcv_msg.data.cmd_handle, ASM_sound_handle[asm_index].sound_event, asm_rcv_msg.data.result_sound_command, rcv_sound_status_value, ASM_sound_handle[asm_index].cb_data);
+ } else {
+ asm_info("[ASM_CB]callback in null\n");
+ }
+ }
+ break;
+
+ case ASM_COMMAND_PLAY:
+ case ASM_COMMAND_NONE:
+ case ASM_COMMAND_RESUME:
+ default:
+ break;
+ }
+ /********************************************************************************************************/
+ asm_info(" <<<<<<<<<<<<<<<< [AFTER] Callback : Main Context >>>>>>>>>>>>>>>>>>>> \n");
+
+ }
+
+
+ asm_info(">>>> ASM_set_sound_state : Event(%s), State(%s) \n", ASM_sound_events_str[sound_event],ASM_sound_state_str[sound_state]);
+
+ return true;
+}
+
+EXPORT_API
+void ASM_dump_sound_state()
+{
+ int error = 0;
+ int ret = 0;
+
+ if (!__ASM_init_msg(&error) ) {
+ asm_error("[Error = %d] >>>> %s =>__asm_init \n", error, __func__);
+ }
+ if (!__asm_construct_snd_msg(getpid(), 0, 0, ASM_REQUEST_DUMP, ASM_STATE_NONE, ASM_RESOURCE_NONE, NULL)) {
+ asm_error_r("[Error] >>>> %s : Send msg construct failed.\n", __func__);
+ return;
+ }
+ NO_EINTR(ret = msgsnd(asm_snd_msgid, (void *)&asm_snd_msg, sizeof(asm_snd_msg.data), 0));
+ if (ret == -1) {
+ asm_error_r("[Error] >>>> ASM_dump_sound_state : Msgsnd failed (%d,%s) \n", errno, strerror(errno));
+ return;
+ }
+}
+
+
+void ASM_ask_sound_policy(ASM_sound_events_t playing_sound, ASM_sound_events_t request_sound,
+ ASM_sound_cases_t *sound_policy)
+{
+}
+
+
+#if defined(CONFIG_ENABLE_SIGNAL_HANDLER)
+struct sigaction ASM_int_old_action;
+struct sigaction ASM_abrt_old_action;
+struct sigaction ASM_segv_old_action;
+struct sigaction ASM_term_old_action;
+struct sigaction ASM_sys_old_action;
+struct sigaction ASM_xcpu_old_action;
+
+void __ASM_unregister_sound(int index)
+{
+ int error_code = 0;
+ int ret = 0;
+ unsigned int sound_status_value;
+
+ asm_info(" <<<< __ASM_unregister_sound : Event(%s), Index(%d) \n", ASM_sound_events_str[ASM_sound_handle[index].sound_event], index);
+ if (!__ASM_get_sound_state(&sound_status_value, &error_code)) {
+ asm_error("[Error = %d] >>>> ASM_unregister_sound => __ASM_get_sound_state \n", error_code);
+ }
+ if (!__ASM_set_sound_state(ASM_sound_handle[index].sound_event, ASM_STATE_NONE, &error_code)) {
+ asm_error("[Error = %d] >>>> __ASM_unregister_sound => __ASM_set_sound_state(NONE) \n", error_code);
+ }
+
+ if (!__asm_construct_snd_msg(ASM_sound_handle[index].asm_tid, ASM_sound_handle[index].handle, ASM_sound_handle[index].sound_event, ASM_REQUEST_UNREGISTER, ASM_STATE_NONE, ASM_RESOURCE_NONE, &error_code)) {
+ asm_error(" >>>> Send msg construct failed.\n");
+ }
+
+ NO_EINTR(ret = msgsnd(asm_snd_msgid, (void *)&asm_snd_msg, sizeof(asm_snd_msg.data), 0));
+ if (ret == -1) {
+ asm_error_r("[Error] >>>> __ASM_unregister_sound : Msgsnd failed (%d,%s) \n", errno, strerror(errno));
+ }
+
+ __ASM_destroy_callback(index);
+
+ asm_info(" >>>> __ASM_unregister_sound : Event(%s) \n", ASM_sound_events_str[ASM_sound_handle[index].sound_event]);
+
+ ASM_sound_handle[index].asm_fd = 0;
+ ASM_sound_handle[index].asm_tid = 0;
+ ASM_sound_handle[index].sound_event = ASM_EVENT_NONE;
+ ASM_sound_handle[index].is_used = FALSE;
+
+}
+
+
+void __ASM_signal_handler(int signo)
+{
+ int exit_pid = 0;
+ int asm_index = 0;
+ int run_emergency_exit = 0;
+
+ for (asm_index=0 ;asm_index < ASM_HANDLE_MAX; asm_index++) {
+ if (ASM_sound_handle[asm_index].is_used == TRUE) {
+ exit_pid = ASM_sound_handle[asm_index].asm_tid;
+ if (exit_pid == asmgettid()) {
+ run_emergency_exit = 1;
+ break;
+ }
+ }
+ }
+
+ if (run_emergency_exit) {
+ asm_snd_msg.instance_id = exit_pid;
+ asm_snd_msg.data.handle = 0;
+ asm_snd_msg.data.request_id = ASM_REQUEST_EMERGENT_EXIT;
+ asm_snd_msg.data.sound_event = 0;
+ asm_snd_msg.data.sound_state = 0;
+ /* signal block -------------- */
+ sigset_t old_mask, all_mask;
+ sigfillset(&all_mask);
+ sigprocmask(SIG_BLOCK, &all_mask, &old_mask);
+
+ if (msgsnd(asm_snd_msgid, (void *)&asm_snd_msg, sizeof(asm_snd_msg.data), 0) < 0) {
+ asm_info("[signal handler][msgsnd failed]tid=%ld, reqid=%d, handle=0x%x, state=0x%x event=%d size=%d\n",asm_snd_msg.instance_id,
+ asm_snd_msg.data.request_id, asm_snd_msg.data.handle, asm_snd_msg.data.sound_state, asm_snd_msg.data.sound_event, sizeof(asm_snd_msg.data) );
+ int tmpid = msgget((key_t)2014, 0666);
+ if (msgsnd(tmpid, (void *)&asm_snd_msg, sizeof(asm_snd_msg.data), 0) > 0) {
+ asm_info("[signal handler]msgsnd succeed\n");
+ } else {
+ asm_critical("[signal handler]msgsnd retry also failed.\n");
+ }
+ }
+
+ sigprocmask(SIG_SETMASK, &old_mask, NULL);
+ /* signal unblock ------------ */
+ }
+
+ switch (signo) {
+ case SIGINT:
+ sigaction(SIGINT, &ASM_int_old_action, NULL);
+ raise( signo);
+ break;
+ case SIGABRT:
+ sigaction(SIGABRT, &ASM_abrt_old_action, NULL);
+ raise( signo);
+ break;
+ case SIGSEGV:
+ sigaction(SIGSEGV, &ASM_segv_old_action, NULL);
+ raise( signo);
+ break;
+ case SIGTERM:
+ sigaction(SIGTERM, &ASM_term_old_action, NULL);
+ raise( signo);
+ break;
+ case SIGSYS:
+ sigaction(SIGSYS, &ASM_sys_old_action, NULL);
+ raise( signo);
+ break;
+ case SIGXCPU:
+ sigaction(SIGXCPU, &ASM_xcpu_old_action, NULL);
+ raise( signo);
+ break;
+ default:
+ break;
+ }
+}
+
+#endif
+void __attribute__((constructor)) __ASM_init_module(void)
+{
+#if defined(CONFIG_ENABLE_SIGNAL_HANDLER)
+ struct sigaction ASM_action;
+ ASM_action.sa_handler = __ASM_signal_handler;
+ ASM_action.sa_flags = SA_NOCLDSTOP;
+ sigemptyset(&ASM_action.sa_mask);
+
+ asm_info(" __ASM_init_module : start \n");
+
+ sigaction(SIGINT, &ASM_action, &ASM_int_old_action);
+ sigaction(SIGABRT, &ASM_action, &ASM_abrt_old_action);
+ sigaction(SIGSEGV, &ASM_action, &ASM_segv_old_action);
+ sigaction(SIGTERM, &ASM_action, &ASM_term_old_action);
+ sigaction(SIGSYS, &ASM_action, &ASM_sys_old_action);
+ sigaction(SIGXCPU, &ASM_action, &ASM_xcpu_old_action);
+#endif
+}
+
+
+void __attribute__((destructor)) __ASM_fini_module(void)
+{
+#if defined(CONFIG_ENABLE_SIGNAL_HANDLER)
+ asm_info(" __ASM_fini_module : start \n");
+
+ int exit_pid = 0;
+ int asm_index = 0;
+ int run_emergency_exit = 0;
+
+ for (asm_index = 0; asm_index < ASM_HANDLE_MAX; asm_index++) {
+ if (ASM_sound_handle[asm_index].is_used == TRUE) {
+ exit_pid = ASM_sound_handle[asm_index].asm_tid;
+ if (exit_pid == asmgettid()) {
+ run_emergency_exit = 1;
+ break;
+ }
+ }
+ }
+
+ if (run_emergency_exit) {
+ asm_snd_msg.instance_id = exit_pid;
+ asm_snd_msg.data.handle = 0; /* dummy */
+ asm_snd_msg.data.request_id = ASM_REQUEST_EMERGENT_EXIT;
+ asm_snd_msg.data.sound_event = 0;
+ asm_snd_msg.data.sound_state = 0;
+
+ if (msgsnd(asm_snd_msgid, (void *)&asm_snd_msg, sizeof(asm_snd_msg.data), 0) < 0 ) {
+ asm_info( "[signal handler][msgsnd failed]tid=%ld, reqid=%d, handle=0x%x, state=0x%x event=%d size=%d\n",asm_snd_msg.instance_id,
+ asm_snd_msg.data.request_id, asm_snd_msg.data.handle, asm_snd_msg.data.sound_state, asm_snd_msg.data.sound_event, sizeof(asm_snd_msg.data) );
+ int tmpid = msgget((key_t)2014, 0666);
+ if (msgsnd(tmpid, (void *)&asm_snd_msg, sizeof(asm_snd_msg.data), 0) > 0) {
+ asm_info("[signal handler]msgsnd succeed\n");
+ } else {
+ asm_critical("[signal handler]msgsnd retry also failed.\n");
+ }
+ }
+ }
+#endif
+ sigaction(SIGINT, &ASM_int_old_action, NULL);
+ sigaction(SIGABRT, &ASM_abrt_old_action, NULL);
+ sigaction(SIGSEGV, &ASM_segv_old_action, NULL);
+ sigaction(SIGTERM, &ASM_term_old_action, NULL);
+ sigaction(SIGSYS, &ASM_sys_old_action, NULL);
+ sigaction(SIGXCPU, &ASM_xcpu_old_action, NULL);
+}
+