rebase code with tizen 2.3 26/38226/4 tizen_3.0.2015.q2_common accepted/tizen/common/20150506.091346 accepted/tizen/mobile/20150511.004058 accepted/tizen/tv/20150506.233449 accepted/tizen/wearable/20150506.234518 submit/tizen/20150429.013912 submit/tizen_common/20150505.090000
authorSeungbae Shin <seungbae.shin@samsung.com>
Wed, 15 Apr 2015 05:11:48 +0000 (14:11 +0900)
committerSeungbae Shin <seungbae.shin@samsung.com>
Mon, 27 Apr 2015 08:58:32 +0000 (17:58 +0900)
remove smack label for vconf
replace/remove deprecated glib functions
set static declaration on global variables / local functions

Change-Id: Idc5eb38eda9e45943010815d984f4d2548fd4311

12 files changed:
AUTHORS
LICENSE.APLv2 [new file with mode: 0644]
NOTICE [new file with mode: 0644]
audio-session-mgr.pc.in
configure.ac
include/asm-error.h [deleted file]
include/asm-log.h [deleted file]
include/audio-session-manager-types.h
include/audio-session-manager.h
packaging/audio-session-manager.spec
src/audio-session-mgr.c
test/asm_testsuite.c

diff --git a/AUTHORS b/AUTHORS
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..79a79b1332ed522524c6a5718da605dc661efb10 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -0,0 +1,2 @@
+Seungbae Shin <seungbae.shin at samsung.com>
+Sangchul Lee <sc11.lee at samsung.com>
diff --git a/LICENSE.APLv2 b/LICENSE.APLv2
new file mode 100644 (file)
index 0000000..76f9119
--- /dev/null
@@ -0,0 +1,204 @@
+Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   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.
+
diff --git a/NOTICE b/NOTICE
new file mode 100644 (file)
index 0000000..ccdad52
--- /dev/null
+++ b/NOTICE
@@ -0,0 +1,3 @@
+Copyright (c) Samsung Electronics Co., Ltd. All rights reserved.
+Except as noted, this software is licensed under Apache License, Version 2.
+Please, see the LICENSE file for Apache License terms and conditions.
index 0fb8fc23738cb6b3656df3ada7b2a6a857f4a6e4..d62f7059cf929264d7134afc1b8616f3ffb68b3e 100644 (file)
@@ -5,7 +5,7 @@ includedir=@includedir@
 
 Name: audio-session-mgr
 Description: audio-session-mgr
-Version: @VERSION@ 
-Requires: vconf sysman mm-common
+Version: @VERSION@
+Requires: vconf mm-common
 Libs: -L${libdir} -laudio-session-mgr
 Cflags: -I${includedir}/mmf
index 47cb576d272bc98d010d7377b571f4960b724231..24c96af0863fa00ee430cdbd71441e03c076a41d 100644 (file)
@@ -30,16 +30,6 @@ PKG_CHECK_MODULES(VCONF, vconf)
 AC_SUBST(VCONF_CFLAGS)
 AC_SUBST(VCONF_LIBS)
 
-PKG_CHECK_MODULES(SYSMAN, sysman)
-AC_SUBST(SYSMAN_CFLAGS)
-AC_SUBST(SYSMAN_LIBS)
-
-PKG_CHECK_MODULES(AVSYSAUDIO, avsysaudio)
-AC_SUBST(AVSYSAUDIO_CFLAGS)
-AC_SUBST(AVSYSAUDIO_LIBS)
-
-
-
 # Checks for header files.
 AC_HEADER_STDC
 AC_CHECK_HEADERS([fcntl.h stdlib.h sys/time.h unistd.h])
diff --git a/include/asm-error.h b/include/asm-error.h
deleted file mode 100644 (file)
index 9084444..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * 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.
- *
- */
-
-#ifndef __ASM_ERROR_H__
-#define __ASM_ERROR_H__
-
-#ifdef __cplusplus
-       extern "C" {
-#endif
-
-/**
-  * ASM CLASS
-  */
-#define ASM_STATE_SUCCESS                 (0x00000000)                    /**< No Error */
-#define ASM_STATE_ERROR                   (0x80000000)                    /**< Error Class */
-#define ASM_STATE_WARING                  (0x70000000)                    /**< Waring Class */
-
-/*
- * Detail enumeration
- */
-enum {
-    ASM_IN_UNKNOWN = 0,
-    ASM_IN_PARAMETER,
-    ASM_IN_HANDLE,
-    ASM_IN_MEMORY,
-};
-
-/*
- * ASM_WARING
- */
-#define ASM_STATE_WAR_INVALID_PARAMETER   (ASM_STATE_WARING | ASM_IN_PARAMETER)
-#define ASM_STATE_WAR_INVALID_HANDLE      (ASM_STATE_WARING | ASM_IN_HANDLE)
-#define ASM_STATE_WAR_INVALID_MEMORY       (ASM_STATE_WARING | ASM_IN_MEMORY)
-
-
-/**
- *  ASM_ERROR
- */
-#define ASM_STATE_ERR_INVALID_PARAMETER   (ASM_STATE_ERROR | ASM_IN_PARAMETER)
-#define ASM_STATE_ERR_INVALID_HANDLE      (ASM_STATE_ERROR | ASM_IN_HANDLE)
-#define ASM_STATE_ERR_INVALID_MEMORY       (ASM_STATE_ERROR | ASM_IN_MEMORY)
-
-
-#define ASM_FAIL(_A_)                     (ASM_STATE_ERROR & (_A_))
-#define ASM_SUCCESS(_A_)                  (!ASM_FAIL(_A_))
-#define ASM_WARING(_A_)                   (ASM_STATE_WARING & (_A_))
-#define ASM_ERROR(_A_)                    (ASM_STATE_ERROR & (_A_))
-
-#ifdef __cplusplus
-       }
-#endif
-
-#endif /* __ASM_ERROR_H__ */
diff --git a/include/asm-log.h b/include/asm-log.h
deleted file mode 100644 (file)
index 16a721b..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * 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.
- *
- */
-
-#ifndef __ASM_LOG_H__
-#define __ASM_LOG_H__
-
-#ifdef __DEBUG_MODE__
-#include <stdio.h>
-
-#ifdef __USE_LOGMANAGER__
-#include <dlog.h>
-
-#define LOG_TAG        "MMFW_SESSIONMGR"
-#define asm_info(fmt, arg...) SLOG(LOG_VERBOSE, LOG_TAG, "<DEBUG> [%s:%d] "fmt"", __FUNCTION__,__LINE__,##arg)
-#define asm_warning(fmt, arg...) SLOG(LOG_WARN, LOG_TAG, "<WARNI> [%s:%d] "fmt"", __FUNCTION__,__LINE__,##arg)
-#define asm_error(fmt, arg...) SLOG(LOG_ERROR, LOG_TAG, "<ERROR> [%s:%d] "fmt"", __FUNCTION__,__LINE__,##arg)
-#define asm_critical(fmt, arg...) SLOG(LOG_ERROR, LOG_TAG, "<FATAL> [%s:%d] "fmt"", __FUNCTION__,__LINE__,##arg)
-#define asm_fenter()   SLOG(LOG_VERBOSE, LOG_TAG, "<ENTER> [%s:%d]", __FUNCTION__,__LINE__)
-#define asm_fleave()   SLOG(LOG_VERBOSE, LOG_TAG, "<LEAVE> [%s:%d]", __FUNCTION__,__LINE__)
-
-#else  //__USE_LOGMANAGER__
-
-#define asm_info_r(msg, args...) fprintf(stderr, msg, ##args)
-#define asm_warning_r(msg, args...) fprintf(stderr, msg, ##args)
-#define asm_error_r(msg, args...) fprintf(stderr, msg, ##args)
-#define asm_critical_r(msg, args...) fprintf(stderr, msg, ##args)
-#define asm_assert_r(condition)                (condition)
-
-#define asm_info(msg, args...) fprintf(stderr, msg, ##args)
-#define asm_warning(msg, args...) fprintf(stderr, msg, ##args)
-#define asm_error(msg, args...) fprintf(stderr, msg, ##args)
-#define asm_critical(msg, args...) fprintf(stderr, msg, ##args)
-#define asm_assert(condition)                  (condition)
-#define asm_fenter()
-#define asm_fleave()
-
-#endif //__USE_LOGMANAGER__
-
-#else  //__DEBUG_MODE__
-
-#define asm_info_r(msg, args...)
-#define asm_warning_r(msg, args...)
-#define asm_error_r(msg, args...)
-#define asm_critical_r(msg, args...)
-#define asm_assert_r(condition)        (condition)
-
-#define asm_info(msg, args...)
-#define asm_warning(msg, args...)
-#define asm_error(msg, args...)
-#define asm_critical(msg, args...)
-#define asm_assert(condition)          (condition)
-#define asm_fenter()
-#define asm_fleave()
-
-#endif  // __DEBUG_MODE__
-
-#endif /* __ASM_LOG_H__ */
index 7160a156eb9c4aa09e18627fa80800814e02a31c..beb0c1b4f82b11c48ef5de51f28a45823d66c0e2 100644 (file)
@@ -1,9 +1,9 @@
 /*
  * audio-session-manager
  *
- * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
  *
- * Contact: Seungbae Shin <seungbae.shin@samsung.com>
+ * Contact: Seungbae Shin <seungbae.shin at samsung.com>, Sangchul Lee <sc11.lee at samsung.com>
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 #include <stdbool.h>
 
 /* Error codes */
-#define ERR_ASM_THREAD_CREATE_ERROR            0x01
-#define ERR_ASM_THREAD_CANCEL_ERROR            0x02
-#define ERR_ASM_MSG_QUEUE_MSGID_GET_FAILED     0x03
-#define ERR_ASM_MSG_QUEUE_SND_ERROR            0x04
-#define ERR_ASM_MSG_QUEUE_RCV_ERROR            0x05
-#define ERR_ASM_ALREADY_REGISTERED             0x06
-#define ERR_ASM_ALREADY_UNREGISTERED           0x07
-#define ERR_ASM_EVENT_IS_INVALID               0x08
-#define ERR_ASM_EVENT_IS_FULL                  0x09
-#define ERR_ASM_POLICY_CANNOT_PLAY             0x10
-#define ERR_ASM_POLICY_CANNOT_PLAY_BY_CALL     0x11    /* CALL / VIDEOCALL / RICH_CALL */
-#define ERR_ASM_POLICY_CANNOT_PLAY_BY_ALARM    0x12
-#define ERR_ASM_POLICY_INVALID_HANDLE          0x1f
-#define ERR_ASM_INVALID_PARAMETER              0x20
-#define ERR_ASM_VCONF_ERROR                    0x21
-#define ERR_ASM_UNKNOWN_ERROR                  0x2F
-#define ERR_ASM_HANDLE_IS_FULL                 0x30
+#define ERR_ASM_ERROR_NONE                     0x00
+#define ERR_ASM_THREAD_CREATE_ERROR            0x01
+#define ERR_ASM_THREAD_CANCEL_ERROR            0x02
+#define ERR_ASM_MSG_QUEUE_MSGID_GET_FAILED     0x03
+#define ERR_ASM_MSG_QUEUE_SND_ERROR            0x04
+#define ERR_ASM_MSG_QUEUE_RCV_ERROR            0x05
+#define ERR_ASM_ALREADY_REGISTERED             0x06
+#define ERR_ASM_ALREADY_UNREGISTERED           0x07
+#define ERR_ASM_EVENT_IS_INVALID               0x08
+#define ERR_ASM_LOCAL_HANDLE_IS_FULL           0x09
+#define ERR_ASM_LOCAL_HANDLE_IS_INVALID        0x0A
+#define ERR_ASM_POLICY_CANNOT_PLAY             0x10
+#define ERR_ASM_POLICY_CANNOT_PLAY_BY_CALL     0x11 /* CALL / VIDEOCALL / VOIP */
+#define ERR_ASM_POLICY_CANNOT_PLAY_BY_ALARM    0x12 /* ALARM */
+#define ERR_ASM_POLICY_CANNOT_PLAY_BY_PROFILE  0x13 /* blocked by sound profile */
+#define ERR_ASM_POLICY_CANNOT_PLAY_BY_CUSTOM   0x14 /* blocked by custom reason */
+#define ERR_ASM_INVALID_PARAMETER              0x20
+#define ERR_ASM_VCONF_ERROR                    0x21
+#define ERR_ASM_NOT_SUPPORTED                  0x22
+#define ERR_ASM_NO_OPERATION                   0x23
+#define ERR_ASM_UNKNOWN_ERROR                  0x2F
+#define ERR_ASM_SERVER_HANDLE_IS_FULL          0x30
+#define ERR_ASM_SERVER_HANDLE_IS_INVALID       0x31
+#define ERR_ASM_WATCH_ALREADY_REQUESTED        0x40
+#define ERR_ASM_WATCH_ALREADY_UNREQUESTED      0x41
+#define ERR_ASM_WATCH_NOT_SUPPORTED            0x42
+#define ERR_ASM_ADD_WATCH_LIST_FAILURE         0x43
+#define ERR_ASM_DEL_WATCH_LIST_FAILURE         0x44
+
+/* Session Option */
+#define ASM_SESSION_OPTION_PAUSE_OTHERS                  0x0001
+#define ASM_SESSION_OPTION_UNINTERRUPTIBLE               0x0002
+#define ASM_SESSION_OPTION_RESUME_BY_MEDIA_PAUSED        0x0010
+#define ASM_SESSION_OPTION_RESUME_BY_MEDIA_STOPPED       0x0020
 
 
 #define ASM_PRIORITY_MATRIX_MIN (ASM_EVENT_MAX-1)
-#define ASM_SERVER_HANDLE_MAX 256 
-
+#define ASM_PRIORITY_SUB_MATRIX_MIN (ASM_SUB_EVENT_MAX-1)
+#define ASM_SERVER_HANDLE_MAX 256
+#define ASM_HANDLE_INIT_VAL -1
 
 #define SOUND_STATUS_KEY               "memory/Sound/SoundStatus"
 /**
@@ -59,7 +77,7 @@
   */
 typedef enum
 {
-       ASM_REQUEST_REGISTER            = 0,
+       ASM_REQUEST_REGISTER = 0,
        ASM_REQUEST_UNREGISTER,
        ASM_REQUEST_GETSTATE,
        ASM_REQUEST_GETMYSTATE,
@@ -68,39 +86,62 @@ typedef enum
        ASM_REQUEST_DUMP,
        ASM_REQUEST_SET_SUBSESSION,
        ASM_REQUEST_GET_SUBSESSION,
+       ASM_REQUEST_REGISTER_WATCHER,
+       ASM_REQUEST_UNREGISTER_WATCHER,
+       ASM_REQUEST_SET_SUBEVENT,
+       ASM_REQUEST_GET_SUBEVENT,
+       ASM_REQUEST_RESET_RESUME_TAG,
+       ASM_REQUEST_SET_SESSION_OPTIONS,
+       ASM_REQUEST_GET_SESSION_OPTIONS
 } ASM_requests_t;
 
 /**
   * This enumeration defines sound event for Sound Scenario in Multimedia Resources Conflict Manager.
   */
-
 typedef enum
 {
-       ASM_EVENT_NONE          = -1, // [Notice] Don't use it in application (Never use it), it is internal sound event
-       ASM_EVENT_SHARE_MMPLAYER        =  0,
-       ASM_EVENT_SHARE_MMCAMCORDER,
-       ASM_EVENT_SHARE_MMSOUND,
-       ASM_EVENT_SHARE_OPENAL,
-       ASM_EVENT_SHARE_AVSYSTEM,
-       ASM_EVENT_EXCLUSIVE_MMPLAYER,
-       ASM_EVENT_EXCLUSIVE_MMCAMCORDER,
-       ASM_EVENT_EXCLUSIVE_MMSOUND,
-       ASM_EVENT_EXCLUSIVE_OPENAL,
-       ASM_EVENT_EXCLUSIVE_AVSYSTEM,
+       ASM_EVENT_NONE = -1,             // [Notice] Don't use it in application (Never use it), it is internal sound event
+       ASM_EVENT_MEDIA_MMPLAYER = 0,
+       ASM_EVENT_MEDIA_MMCAMCORDER,
+       ASM_EVENT_MEDIA_MMSOUND,
+       ASM_EVENT_MEDIA_OPENAL,
+       ASM_EVENT_MEDIA_FMRADIO,
+       ASM_EVENT_MEDIA_WEBKIT,
        ASM_EVENT_NOTIFY,
-       ASM_EVENT_CALL,
-       ASM_EVENT_SHARE_FMRADIO,
-       ASM_EVENT_EXCLUSIVE_FMRADIO,
-       ASM_EVENT_EARJACK_UNPLUG,
        ASM_EVENT_ALARM,
+       ASM_EVENT_EARJACK_UNPLUG,
+       ASM_EVENT_CALL,
        ASM_EVENT_VIDEOCALL,
+       ASM_EVENT_VOIP,
        ASM_EVENT_MONITOR,
-       ASM_EVENT_RICH_CALL,
        ASM_EVENT_EMERGENCY,
        ASM_EVENT_EXCLUSIVE_RESOURCE,
+       ASM_EVENT_VOICE_RECOGNITION,
+       ASM_EVENT_MMCAMCORDER_AUDIO,
+       ASM_EVENT_MMCAMCORDER_VIDEO,
        ASM_EVENT_MAX
 } ASM_sound_events_t;
 
+typedef enum
+{
+       ASM_SUB_EVENT_NONE = 0,
+       ASM_SUB_EVENT_SHARE,
+       ASM_SUB_EVENT_EXCLUSIVE,
+       ASM_SUB_EVENT_MAX
+} ASM_sound_sub_events_t;
+
+typedef enum {
+       ASM_SUB_SESSION_TYPE_VOICE = 0,
+       ASM_SUB_SESSION_TYPE_RINGTONE,
+       ASM_SUB_SESSION_TYPE_MEDIA,
+       ASM_SUB_SESSION_TYPE_INIT,
+       ASM_SUB_SESSION_TYPE_VR_NORMAL,
+       ASM_SUB_SESSION_TYPE_VR_DRIVE,
+       ASM_SUB_SESSION_TYPE_RECORD_STEREO,
+       ASM_SUB_SESSION_TYPE_RECORD_MONO,
+       ASM_SUB_SESSION_TYPE_MAX
+} ASM_sound_sub_sessions_t;
+
 /*
  * This enumeration defines event source for sound conflict scenario
  */
@@ -108,6 +149,7 @@ typedef enum
 {
        ASM_EVENT_SOURCE_MEDIA = 0,
        ASM_EVENT_SOURCE_CALL_START,
+       ASM_EVENT_SOURCE_CALL_END,
        ASM_EVENT_SOURCE_EARJACK_UNPLUG,
        ASM_EVENT_SOURCE_RESOURCE_CONFLICT,
        ASM_EVENT_SOURCE_ALARM_START,
@@ -115,53 +157,50 @@ typedef enum
        ASM_EVENT_SOURCE_EMERGENCY_START,
        ASM_EVENT_SOURCE_EMERGENCY_END,
        ASM_EVENT_SOURCE_OTHER_PLAYER_APP,
-       ASM_EVENT_SOURCE_RESUMABLE_MEDIA,
+       ASM_EVENT_SOURCE_NOTIFY_START,
+       ASM_EVENT_SOURCE_NOTIFY_END
 } ASM_event_sources_t;
 
 /**
   * This enumeration defines sound case between playing sound and request sound
-  * ALTER_PLAY : DTMF tone
   */
 typedef enum
 {
-       ASM_CASE_NONE                                   = 0,
-       ASM_CASE_1PLAY_2STOP                    = 1,
-       ASM_CASE_1STOP_2PLAY                    = 5,
-       ASM_CASE_1PAUSE_2PLAY                   = 6,
-       ASM_CASE_1PLAY_2PLAY_MIX                = 8,
-       ASM_CASE_RESOURCE_CHECK                 = 9
+       ASM_CASE_NONE = 0,
+       ASM_CASE_1PLAY_2STOP,
+       ASM_CASE_1STOP_2PLAY,
+       ASM_CASE_1PAUSE_2PLAY,
+       ASM_CASE_1PLAY_2PLAY_MIX,
+       ASM_CASE_RESOURCE_CHECK,
+       ASM_CASE_SUB_EVENT,
 } ASM_sound_cases_t;
 
 
-
 /*
  * This enumeration defines Sound Playing Status Information
  * Each bit is Sound Status Type( 0 : None , 1 : Playing)
  */
 typedef enum
 {
-       ASM_STATUS_NONE                                         = 0x00000000,
-       ASM_STATUS_SHARE_MMPLAYER                       = 0x00000001,
-       ASM_STATUS_SHARE_MMCAMCORDER                    = 0x00000002,
-       ASM_STATUS_SHARE_MMSOUND                                = 0x00000004,
-       ASM_STATUS_SHARE_OPENAL                         = 0x00000008,
-       ASM_STATUS_SHARE_AVSYSTEM                       = 0x00000010,
-       ASM_STATUS_EXCLUSIVE_MMPLAYER           = 0x00000020,
-       ASM_STATUS_EXCLUSIVE_MMCAMCORDER                = 0x00000040,
-       ASM_STATUS_EXCLUSIVE_MMSOUND                    = 0x00000080,
-       ASM_STATUS_EXCLUSIVE_OPENAL                     = 0x00000100,
-       ASM_STATUS_EXCLUSIVE_AVSYSTEM           = 0x00000200,
-       ASM_STATUS_NOTIFY                                       = 0x00000400,
-       ASM_STATUS_CALL                                         = 0x10000000, //Watch out
-       ASM_STATUS_SHARE_FMRADIO                                = 0x00000800,
-       ASM_STATUS_EXCLUSIVE_FMRADIO                    = 0x00001000,
-       ASM_STATUS_EARJACK_UNPLUG                       = 0x00002000,
-       ASM_STATUS_ALARM                                                = 0x00100000,
-       ASM_STATUS_VIDEOCALL                                            = 0x20000000, //Watch out
-       ASM_STATUS_MONITOR                                      = 0x80000000, //watch out
-       ASM_STATUS_RICH_CALL                            = 0x40000000, //Watch out
-       ASM_STATUS_EMERGENCY                            = 0x00004000,
-       ASM_STATUS_EXCLUSIVE_RESOURCE           = 0x00008000,
+       ASM_STATUS_NONE                = 0x00000000,
+       ASM_STATUS_MEDIA_MMPLAYER      = 0x00000001,
+       ASM_STATUS_MEDIA_MMCAMCORDER   = 0x00000002,
+       ASM_STATUS_MEDIA_MMSOUND       = 0x00000004,
+       ASM_STATUS_MEDIA_OPENAL        = 0x00000008,
+       ASM_STATUS_MEDIA_FMRADIO       = 0x00000010,
+       ASM_STATUS_MEDIA_WEBKIT        = 0x00000020,
+       ASM_STATUS_NOTIFY              = 0x00000040,
+       ASM_STATUS_ALARM               = 0x00000080,
+       ASM_STATUS_EARJACK_UNPLUG      = 0x00001000,
+       ASM_STATUS_CALL                = 0x10000000,
+       ASM_STATUS_VIDEOCALL           = 0x20000000,
+       ASM_STATUS_VOIP                = 0x40000000,
+       ASM_STATUS_MONITOR             = 0x80000000,
+       ASM_STATUS_EMERGENCY           = 0x00002000,
+       ASM_STATUS_EXCLUSIVE_RESOURCE  = 0x00004000,
+       ASM_STATUS_VOICE_RECOGNITION   = 0x00010000,
+       ASM_STATUS_MMCAMCORDER_AUDIO   = 0x00020000,
+       ASM_STATUS_MMCAMCORDER_VIDEO   = 0x00040000
 } ASM_sound_status_t;
 
 
@@ -170,13 +209,11 @@ typedef enum
   */
 typedef enum
 {
-       ASM_STATE_NONE                  = 0,
-       ASM_STATE_PLAYING                       = 1,
-       ASM_STATE_WAITING                       = 2,
-       ASM_STATE_STOP                  = 3,
-       ASM_STATE_PAUSE                 = 4,
-       ASM_STATE_PAUSE_BY_APP  = 5,
-       ASM_STATE_IGNORE                        = 6,
+       ASM_STATE_NONE         = 0,
+       ASM_STATE_PLAYING      = 1,
+       ASM_STATE_WAITING      = 2,
+       ASM_STATE_STOP         = 3,
+       ASM_STATE_PAUSE        = 4
 } ASM_sound_states_t;
 
 
@@ -185,19 +222,19 @@ typedef enum
  */
 typedef enum
 {
-       ASM_NEED_NOT_RESUME = 0,
-       ASM_NEED_RESUME = 1,
+       ASM_NEED_NOT_RESUME      = 0,
+       ASM_NEED_RESUME          = 1
 }ASM_resume_states_t;
 /*
  * This enumeration defines state return of client.
  */
 typedef enum
 {
-       ASM_CB_RES_IGNORE       = -1,
-       ASM_CB_RES_NONE         = 0,
-       ASM_CB_RES_PLAYING      = 1,
-       ASM_CB_RES_STOP         = 2,
-       ASM_CB_RES_PAUSE        = 3,
+       ASM_CB_RES_IGNORE   = -1,
+       ASM_CB_RES_NONE     = 0,
+       ASM_CB_RES_PLAYING  = 1,
+       ASM_CB_RES_STOP     = 2,
+       ASM_CB_RES_PAUSE    = 3,
 }ASM_cb_result_t;
 
 /*
@@ -206,29 +243,28 @@ typedef enum
 
 typedef enum
 {
-       ASM_RESOURCE_NONE                               = 0x0000,
-       ASM_RESOURCE_CAMERA                             = 0x0001,
-       ASM_RESOURCE_VIDEO_OVERLAY              = 0x0002,
-       ASM_RESOURCE_HW_DECORDER                = 0x0100, //this should be removed. miss type
-       ASM_RESOURCE_HW_ENCORDER                = 0x0200, //this should be removed. miss type
-       ASM_RESOURCE_HW_DECODER                 = 0x0100,
-       ASM_RESOURCE_HW_ENCODER                 = 0x0200,
-       ASM_RESOURCE_RADIO_TUNNER               = 0x1000,
-       ASM_RESOURCE_TV_TUNNER                  = 0x2000,
+       ASM_RESOURCE_NONE           = 0x0000,
+       ASM_RESOURCE_CAMERA         = 0x0001,
+       ASM_RESOURCE_VIDEO_OVERLAY  = 0x0002,
+       ASM_RESOURCE_STREAMING      = 0x0004,
+       ASM_RESOURCE_HW_DECODER     = 0x0100,
+       ASM_RESOURCE_HW_ENCODER     = 0x0200,
+       ASM_RESOURCE_RADIO_TUNNER   = 0x1000,
+       ASM_RESOURCE_TV_TUNNER      = 0x2000,
+       ASM_RESOURCE_VOICECONTROL   = 0x10000,
 }ASM_resource_t;
 
 
 /* Sound command for applications */
 typedef enum
 {
-       ASM_COMMAND_NONE                = 0x0,
-       ASM_COMMAND_PLAY                = 0x2,
-       ASM_COMMAND_STOP                = 0x3,
-       ASM_COMMAND_PAUSE               = 0x4,
-       ASM_COMMAND_RESUME              = 0x5,
+       ASM_COMMAND_NONE   0,
+       ASM_COMMAND_PLAY   2,
+       ASM_COMMAND_STOP   3,
+       ASM_COMMAND_PAUSE  4,
+       ASM_COMMAND_RESUME 5,
 } ASM_sound_commands_t;
 
-
 /**
   * This structure defines the message data from library to conflict manager.
   */
@@ -250,7 +286,9 @@ typedef struct
        int                                     cmd_handle;
        ASM_sound_commands_t                    result_sound_command;
        ASM_sound_states_t                      result_sound_state;
-       ASM_sound_events_t                      former_sound_event;
+       ASM_requests_t                          source_request_id;
+       int                                             option_flags;
+       int                                             error_code;
 } __ASM_msg_data_asm_to_lib_t;
 
 /**
@@ -296,37 +334,29 @@ typedef struct
        ASM_sound_status_t              sound_status;
 }ASM_sound_event_type_t;
 
-
 static const ASM_sound_event_type_t ASM_sound_type[] = {
     { ASM_EVENT_NONE,                                  ASM_STATUS_NONE },
-    { ASM_EVENT_SHARE_MMPLAYER,                        ASM_STATUS_SHARE_MMPLAYER },
-    { ASM_EVENT_SHARE_MMCAMCORDER,             ASM_STATUS_SHARE_MMCAMCORDER },
-    { ASM_EVENT_SHARE_MMSOUND,                         ASM_STATUS_SHARE_MMSOUND },
-    { ASM_EVENT_SHARE_OPENAL,                  ASM_STATUS_SHARE_OPENAL },
-    { ASM_EVENT_SHARE_AVSYSTEM,                        ASM_STATUS_SHARE_AVSYSTEM },
-    { ASM_EVENT_EXCLUSIVE_MMPLAYER,            ASM_STATUS_EXCLUSIVE_MMPLAYER },
-    { ASM_EVENT_EXCLUSIVE_MMCAMCORDER, ASM_STATUS_EXCLUSIVE_MMCAMCORDER },
-    { ASM_EVENT_EXCLUSIVE_MMSOUND,             ASM_STATUS_EXCLUSIVE_MMSOUND },
-    { ASM_EVENT_EXCLUSIVE_OPENAL,              ASM_STATUS_EXCLUSIVE_OPENAL },
-    { ASM_EVENT_EXCLUSIVE_AVSYSTEM,            ASM_STATUS_EXCLUSIVE_AVSYSTEM },
+    { ASM_EVENT_MEDIA_MMPLAYER,                        ASM_STATUS_MEDIA_MMPLAYER },
+    { ASM_EVENT_MEDIA_MMCAMCORDER,             ASM_STATUS_MEDIA_MMCAMCORDER },
+    { ASM_EVENT_MEDIA_MMSOUND,                         ASM_STATUS_MEDIA_MMSOUND },
+    { ASM_EVENT_MEDIA_OPENAL,                  ASM_STATUS_MEDIA_OPENAL },
+    { ASM_EVENT_MEDIA_FMRADIO,                         ASM_STATUS_MEDIA_FMRADIO },
+    { ASM_EVENT_MEDIA_WEBKIT,                  ASM_STATUS_MEDIA_WEBKIT },
     { ASM_EVENT_NOTIFY,                                ASM_STATUS_NOTIFY },
-    { ASM_EVENT_CALL,                                  ASM_STATUS_CALL },
-    { ASM_EVENT_SHARE_FMRADIO,                         ASM_STATUS_SHARE_FMRADIO },
-    { ASM_EVENT_EXCLUSIVE_FMRADIO,             ASM_STATUS_EXCLUSIVE_FMRADIO },
-    { ASM_EVENT_EARJACK_UNPLUG,                        ASM_STATUS_EARJACK_UNPLUG },
     { ASM_EVENT_ALARM,                                         ASM_STATUS_ALARM },
-    { ASM_EVENT_VIDEOCALL,                                     ASM_STATUS_VIDEOCALL },
+    { ASM_EVENT_EARJACK_UNPLUG,                        ASM_STATUS_EARJACK_UNPLUG },
+    { ASM_EVENT_CALL,                                  ASM_STATUS_CALL },
+    { ASM_EVENT_VIDEOCALL,                             ASM_STATUS_VIDEOCALL },
+    { ASM_EVENT_VOIP,                                  ASM_STATUS_VOIP },
     { ASM_EVENT_MONITOR,                               ASM_STATUS_MONITOR },
-    { ASM_EVENT_RICH_CALL,                             ASM_STATUS_RICH_CALL },
     { ASM_EVENT_EMERGENCY,                             ASM_STATUS_EMERGENCY },
     { ASM_EVENT_EXCLUSIVE_RESOURCE,            ASM_STATUS_EXCLUSIVE_RESOURCE },
+    { ASM_EVENT_VOICE_RECOGNITION,             ASM_STATUS_VOICE_RECOGNITION },
+    { ASM_EVENT_MMCAMCORDER_AUDIO,             ASM_STATUS_MMCAMCORDER_AUDIO },
+    { ASM_EVENT_MMCAMCORDER_VIDEO,             ASM_STATUS_MMCAMCORDER_VIDEO }
 };
 
 
-
-
-
-
 /**
  * This callback function is called when sound status of other sound event is changed
  *
@@ -335,4 +365,13 @@ static const ASM_sound_event_type_t ASM_sound_type[] = {
  */
 typedef ASM_cb_result_t        (*ASM_sound_cb_t) (int handle, ASM_event_sources_t event_source, ASM_sound_commands_t command, unsigned int sound_status, void* cb_data);
 
+
+/**
+ * This callback function is called when sound status of other sound event and state that you want to watch is changed
+ *
+ * @return                                                     No return value
+ * @param[in]  sound_status            Argument passed when callback was set
+ */
+typedef ASM_cb_result_t        (*ASM_watch_cb_t) (int handle, ASM_sound_events_t sound_event, ASM_sound_states_t sound_state, void* cb_data);
+
 #endif
index b7434b20b3b6dd9d4a36d265e668c7d9057b5115..5c5a55a0e0ddc8433cb00f3b3679349b5c8913a2 100644 (file)
@@ -1,9 +1,9 @@
 /*
  * audio-session-manager
  *
- * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
  *
- * Contact: Seungbae Shin <seungbae.shin@samsung.com>
+ * Contact: Seungbae Shin <seungbae.shin at samsung.com>, Sangchul Lee <sc11.lee at samsung.com>
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -47,9 +47,9 @@ extern "C" {
  * @param[in] cb_data                                  This is data of callback function
  * @param[in] mm_resource                              System resources will be used.
  * @param[out] error_code                              specifies the error code
- * @exception                                          
+ * @exception
  */
-bool 
+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);
 
@@ -63,12 +63,13 @@ ASM_register_sound_ex (const int application_pid, int *asm_handle, ASM_sound_eve
  * @return                                                     This function returns @c true on success; @c false otherwise.
  * @param[in] sound_event                              sound event of instance to requested unregister
  * @param[out] error_code                              specifies the error code
- * @exception                                          
+ * @exception
  */
-bool 
+bool
 ASM_unregister_sound(const int asm_handle, ASM_sound_events_t sound_event, int *error_code);
 
-bool ASM_unregister_sound_ex(const int asm_handle, ASM_sound_events_t sound_event, int *error_code, int (*func)(void*,void*));
+bool
+ASM_unregister_sound_ex(const int asm_handle, ASM_sound_events_t sound_event, int *error_code, int (*func)(void*,void*));
 
 
 /**
@@ -79,9 +80,9 @@ bool ASM_unregister_sound_ex(const int asm_handle, ASM_sound_events_t sound_even
  *                                                                     return value defined in ASM_sound_status_t
  *                                                                     Each bit is Sound Status Type( 0 : None , 1 : Playing )
  * @param[out] error_code                              specifies the error code
- * @exception                                          
+ * @exception
  */
-bool 
+bool
 ASM_get_sound_status(unsigned int *all_sound_status, int *error_code);
 
 
@@ -109,6 +110,9 @@ ASM_get_sound_state(const int asm_handle, ASM_sound_events_t sound_event, ASM_so
 bool
 ASM_get_process_session_state(const int asm_handle, ASM_sound_states_t *sound_state, int *error_code);
 
+bool
+ASM_attach_callback(ASM_sound_events_t sound_event, ASM_sound_cb_t callback, void *user_data, int *error_code);
+
 /**
  * This function set sound state to ASM server.
  *
@@ -119,25 +123,41 @@ ASM_get_process_session_state(const int asm_handle, ASM_sound_states_t *sound_st
  * @param[out] error_code                              specifies the error code
  * @exception #ERR_asm_MSG_QUEUE_SND_ERROR   - Is is failed to send to message queue.
  */
-bool 
+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);
 
-bool ASM_set_sound_state_ex (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 (*func)(void*,void*));
-
-/**
- * This function ask sound policy to ASM server.
- *
- * @return                                                     No return value
- * @param[in] playing_sound                    playing sound event 
- * @param[in] request_sound                    request sound event
- * @param[out] sound_policy                    Return sound case between playing sound and request sound
- */
-void
-ASM_ask_sound_policy(ASM_sound_events_t playing_sound, ASM_sound_events_t request_sound, ASM_sound_cases_t *sound_policy) __attribute__((deprecated)) ; 
+bool
+ASM_set_sound_state_ex (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 (*func)(void*,void*));
 
 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);
 
+bool
+ASM_set_watch_session (const int application_pid, ASM_sound_events_t interest_sound_event, ASM_sound_states_t interest_sound_state, ASM_watch_cb_t callback, void *user_data, int *error_code);
+
+bool
+ASM_unset_watch_session (ASM_sound_events_t interest_sound_event, ASM_sound_states_t interest_sound_state, int *error_code);
+
+bool
+ASM_reset_resumption_info(const int asm_handle, int *error_code);
+
+bool
+ASM_set_subevent (const int asm_handle, ASM_sound_sub_events_t subevent, int *error_code);
+
+bool
+ASM_get_subevent (const int asm_handle, ASM_sound_sub_events_t *subevent, int *error_code);
+
+bool
+ASM_set_subsession (const int asm_handle, ASM_sound_sub_sessions_t subsession, int resource, int *error_code);
+
+bool
+ASM_get_subsession (const int asm_handle, ASM_sound_sub_sessions_t *subsession, int *error_code);
+
+bool
+ASM_set_session_option (const int asm_handle, int option_flags, int *error_code);
+
+bool
+ASM_get_session_option (const int asm_handle, int *option_flags, int *error_code);
 
 
 #ifdef __cplusplus
index 5644f0c0961149638c8b5019c10149db847da378..b97606009806ed66fcf18d598f98cb2eea8906c5 100644 (file)
@@ -11,9 +11,7 @@ Requires(post): /usr/bin/vconftool
 Requires(postun): /sbin/ldconfig
 BuildRequires:  pkgconfig(glib-2.0)
 BuildRequires:  pkgconfig(mm-common)
-BuildRequires:  pkgconfig(sysman)
 BuildRequires:  pkgconfig(vconf)
-BuildRequires:  pkgconfig(avsysaudio)
 
 %description
 Audio Session Manager package.
index 19e678e39f52012fbbd0cdcc3c67263ff02f0792..bbbac0d32f8114b368e150aa8573ebda0cda61f6 100644 (file)
@@ -1,9 +1,9 @@
 /*
  * audio-session-manager
  *
- * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
  *
- * Contact: Seungbae Shin <seungbae.shin@samsung.com>
+ * Contact: Seungbae Shin <seungbae.shin at samsung.com>, Sangchul Lee <sc11.lee at samsung.com>
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 
 #define NO_EINTR(stmt) while ((stmt) == -1 && errno == EINTR);  /* sample code by THE LINUX PROGRAMMING INTERFACE */
 
-int asm_register_instance_id;
+static int asm_snd_msgid;
+static int asm_rcv_msgid;
+static int asm_cb_msgid;
 
-int asm_snd_msgid;
-int asm_rcv_msgid;
-int asm_cb_msgid;
+static ASM_msg_lib_to_asm_t asm_snd_msg;
+static ASM_msg_asm_to_lib_t asm_rcv_msg;
 
-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>";
+static unsigned char           str_pass[] = "< OK >";
+static unsigned char           str_fail[] = "<FAIL>";
 
 typedef gboolean (*gLoopPollHandler_t)(gpointer d);
 
+static GThread *g_asm_thread;
+static GMainLoop *g_asm_loop;
+
 typedef struct
 {
-       ASM_sound_events_t      sound_event;
-       GSourceFuncs*           g_src_funcs;
-       GPollFD*                g_poll_fd;
-       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];
+       int                asm_tid;
+       int                handle;
+       ASM_sound_events_t sound_event;
+       ASM_sound_states_t sound_state;
+       ASM_sound_cb_t     asm_callback;
+       ASM_watch_cb_t     watch_callback;
+       void               *user_data;
+       int                option_flags;
+       int                asm_fd;
+       GSourceFuncs*      g_src_funcs;
+       GPollFD*           g_poll_fd;
+       GSource*           asm_src;
+       bool               is_used;
+       bool               is_for_watching;
+       GMutex*            asm_lock;
+} ASM_sound_info_t;
+
+static ASM_sound_info_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",
+       "MEDIA_MMPLAYER",
+       "MEDIA_MMCAMCORDER",
+       "MEDIA_MMSOUND",
+       "MEDIA_OPENAL",
+       "MEDIA_FMRADIO",
+       "MEDIA_WEBKIT",
        "NOTIFY",
-       "CALL",
-       "SHARE_FMRADIO",
-       "EXCLUSIVE_FMRADIO",
-       "EARJACK_UNPLUG",
        "ALARM",
+       "EARJACK_UNPLUG",
+       "CALL",
        "VIDEOCALL",
+       "VOIP",
        "MONITOR",
-       "RICH_CALL",
        "EMERGENCY",
-       "EXCLUSIVE_RESOURCE"
-};
-
-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",
-       "CASE_RESOURCE_CHECK"
+       "EXCLUSIVE_RESOURCE",
+       "VOICE_RECOGNITION",
+       "MMCAMCORDER_AUDIO",
+       "MMCAMCORDER_VIDEO"
 };
 
 static const char* ASM_sound_state_str[] =
@@ -137,23 +122,22 @@ static const char* ASM_sound_state_str[] =
        "STATE_PLAYING",
        "STATE_WAITING",
        "STATE_STOP",
-       "STATE_PAUSE",
-       "STATE_PAUSE_BY_APP",
-       "STATE_ALTER_PLAYING"
+       "STATE_PAUSE"
 };
 
-/*
- * function prototypes
- */
-
+static unsigned int ASM_all_sound_status;
 
-unsigned int ASM_all_sound_status;
+static int __ASM_find_index_by_handle(int handle);
 
-void __asm_init_module(void);
-void __asm_fini_module(void);
-int __ASM_find_index(int handle);
+static gpointer thread_func(gpointer data)
+{
+       debug_log(">>> thread func..ID of this thread(%u)\n", (unsigned int)pthread_self());
+       g_main_loop_run(g_asm_loop);
+       debug_log("<<< quit thread func..\n");
+       return NULL;
+}
 
-bool __ASM_get_sound_state(unsigned int *all_sound_status, int *error_code)
+static bool __ASM_get_sound_state(unsigned int *all_sound_status, int *error_code)
 {
        int value = 0;
 
@@ -162,61 +146,62 @@ bool __ASM_get_sound_state(unsigned int *all_sound_status, int *error_code)
                *error_code = ERR_ASM_VCONF_ERROR;
                return false;
        }
-       debug_msg("All status(%#X)", value);
+       debug_log("All status(%#X)", 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 */
-       debug_msg("Event(%s), State(%s)", ASM_sound_events_str[sound_event], ASM_sound_state_str[sound_state]);
-
-       return true;
-}
-
-gboolean __asm_fd_check(GSource * source)
+static gboolean __asm_fd_check(GSource * source)
 {
        GSList *fd_list;
+       GPollFD *temp;
+
        if (!source) {
                debug_error("GSource is null");
                return FALSE;
        }
        fd_list = source->poll_fds;
-       GPollFD *temp;
-
+       if (!fd_list) {
+               debug_error("fd_list is null");
+               return FALSE;
+       }
        do {
                temp = (GPollFD*)fd_list->data;
-               if (temp->revents & (POLLIN | POLLPRI))
+               if (!temp) {
+                       debug_error("fd_list->data is null");
+                       return FALSE;
+               }
+               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)
+static gboolean __asm_fd_prepare(GSource *source, gint *timeout)
 {
        return FALSE;
 }
 
-gboolean __asm_fd_dispatch(GSource *source,    GSourceFunc callback, gpointer user_data)
+static gboolean __asm_fd_dispatch(GSource *source,     GSourceFunc callback, gpointer user_data)
 {
        callback(user_data);
        return TRUE;
 }
 
-gboolean asm_callback_handler( gpointer d)
+static gboolean asm_callback_handler( gpointer d)
 {
        GPollFD *data = (GPollFD*)d;
        unsigned int buf;
        int count;
        int tid = 0;
        int asm_index = 0;
-       debug_fenter();
+       //debug_fenter();
+       debug_log(">>> asm_callback_handler()..ID of this thread(%u)\n", (unsigned int)pthread_self());
 
        if (!data) {
                debug_error("GPollFd is null");
@@ -232,21 +217,28 @@ gboolean asm_callback_handler( gpointer d)
 
 
                count = read(data->fd, &buf, sizeof(int));
+               if (count != sizeof(int)) {
+                       debug_log("read %d/%d", count, sizeof(int));
+               }
 
                handle = (int)( buf & 0x0000ffff);
-               rcv_command = (ASM_sound_commands_t)((buf >> 16) & 0x0f);
-               event_src = (ASM_event_sources_t)((buf >> 24) & 0x0f);
+               rcv_command = (ASM_sound_commands_t)((buf >> 16) & 0xff);
+               event_src = (ASM_event_sources_t)((buf >> 24) & 0xff);
 
-               asm_index = __ASM_find_index(handle);
+               asm_index = __ASM_find_index_by_handle(handle);
                if (asm_index == -1) {
                        debug_error("Can not find index");
                        return FALSE;
                }
 
+               if (ASM_sound_handle[asm_index].asm_lock) {
+                       g_mutex_lock(ASM_sound_handle[asm_index].asm_lock);
+               }
+
                tid = ASM_sound_handle[asm_index].asm_tid;
-               
+
                if (rcv_command) {
-                       debug_msg("got and start CB : TID(%d), handle(%d) cmd(%d) event_src(%d)", tid, handle, rcv_command, event_src );
+                       debug_msg("Got and start CB : TID(%d), handle(%d), command(%d,(PLAY(2)/STOP(3)/PAUSE(4)/RESUME(5)), event_src(%d)", tid, handle, rcv_command, event_src );
                        if (!__ASM_get_sound_state(&sound_status_value, &error_code)) {
                                debug_error("failed to __ASM_get_sound_state(), error(%d)", error_code);
                        }
@@ -257,10 +249,10 @@ gboolean asm_callback_handler( gpointer d)
                        case ASM_COMMAND_STOP:
                                if (ASM_sound_handle[asm_index].asm_callback == NULL) {
                                        debug_msg("callback is null..");
-                                       return FALSE;
+                                       break;
                                }
                                debug_msg("[CALLBACK(%p) START]",ASM_sound_handle[asm_index].asm_callback);
-                               cb_res = (ASM_sound_handle[asm_index].asm_callback)(handle, event_src, rcv_command, sound_status_value, ASM_sound_handle[asm_index].cb_data);
+                               cb_res = (ASM_sound_handle[asm_index].asm_callback)(handle, event_src, rcv_command, sound_status_value, ASM_sound_handle[asm_index].user_data);
                                debug_msg("[CALLBACK END]");
                                break;
                        default:
@@ -268,7 +260,7 @@ gboolean asm_callback_handler( gpointer d)
                        }
 #ifdef CONFIG_ENABLE_RETCB
 
-                       /* If command is other than RESUME, send return */
+                       /* If the command is not RESUME, send return */
                        if (rcv_command != ASM_COMMAND_RESUME) {
                                int rett = 0;
                                int buf = cb_res;
@@ -280,6 +272,9 @@ gboolean asm_callback_handler( gpointer d)
                                        strerror_r(errno, str_error, sizeof(str_error));
                                        debug_error("[RETCB][Failed(May Server Close First)]tid(%d) fd(%d) %s errno=%d(%s)\n", tid, tmpfd, filename2, errno, str_error);
                                        g_free(filename2);
+                                       if (ASM_sound_handle[asm_index].asm_lock) {
+                                               g_mutex_unlock(ASM_sound_handle[asm_index].asm_lock);
+                                       }
                                        return FALSE;
                                }
                                rett = write(tmpfd, &buf, sizeof(buf));
@@ -292,17 +287,127 @@ gboolean asm_callback_handler( gpointer d)
 #endif
                }
        }
+       //debug_fleave();
+
+       if (ASM_sound_handle[asm_index].asm_lock) {
+               g_mutex_unlock(ASM_sound_handle[asm_index].asm_lock);
+       }
+
+       return TRUE;
+}
+
+static gboolean watch_callback_handler( gpointer d)
+{
+       GPollFD *data = (GPollFD*)d;
+       unsigned int buf;
+       int count;
+       int tid = 0;
+       int asm_index = 0;
+
+       debug_fenter();
+
+       if (!data) {
+               debug_error("GPollFd is null");
+               return FALSE;
+       }
+       if (data->revents & (POLLIN | POLLPRI)) {
+               int handle;
+               ASM_sound_events_t rcv_sound_event = ASM_EVENT_NONE;
+               ASM_sound_states_t rcv_sound_state = ASM_STATE_NONE;
+               int error_code = 0;
+
+               unsigned int sound_status_value;
+
+               ASM_cb_result_t cb_res = ASM_CB_RES_NONE;
+
+
+               count = read(data->fd, &buf, sizeof(int));
+               if (count != sizeof(int)) {
+                       debug_log("read %d/%d", count, sizeof(int));
+               }
+
+               handle = (int)( buf & 0x0000ffff);
+               rcv_sound_event = (ASM_sound_events_t)((buf >> 16) & 0xff);
+               rcv_sound_state = (ASM_sound_states_t)((buf >> 24) & 0xff);
+
+               asm_index = __ASM_find_index_by_handle(handle);
+               if (asm_index == -1) {
+                       debug_error("Can not find index");
+                       return FALSE;
+               }
+
+               if (ASM_sound_handle[asm_index].asm_lock) {
+                       g_mutex_lock(ASM_sound_handle[asm_index].asm_lock);
+               }
+
+               tid = ASM_sound_handle[asm_index].asm_tid;
+
+               debug_msg("Got and start CB : handle(%d) sound_event(%d) sound_state(%d)", handle, rcv_sound_event, rcv_sound_state );
+
+               if (!__ASM_get_sound_state(&sound_status_value, &error_code)) {
+                       debug_error("failed to __ASM_get_sound_state(), error(%d)", error_code);
+               }
+
+               if (ASM_sound_handle[asm_index].watch_callback == NULL) {
+                       debug_msg("callback is null..");
+                       if (ASM_sound_handle[asm_index].asm_lock) {
+                               g_mutex_unlock(ASM_sound_handle[asm_index].asm_lock);
+                       }
+                       return FALSE;
+               }
+               debug_msg("[CALLBACK(%p) START]",ASM_sound_handle[asm_index].watch_callback);
+               cb_res = (ASM_sound_handle[asm_index].watch_callback)(handle, rcv_sound_event, rcv_sound_state, ASM_sound_handle[asm_index].user_data);
+               debug_msg("[CALLBACK END]");
+
+#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));
+                               debug_error("[RETCB][Failed(May Server Close First)]tid(%d) fd(%d) %s errno=%d(%s)\n", tid, tmpfd, filename2, errno, str_error);
+                               g_free(filename2);
+                               if (ASM_sound_handle[asm_index].asm_lock) {
+                                       g_mutex_unlock(ASM_sound_handle[asm_index].asm_lock);
+                               }
+                               return FALSE;
+                       }
+                       rett = write(tmpfd, &buf, sizeof(buf));
+                       close(tmpfd);
+                       g_free(filename2);
+                       debug_msg("[RETCB] tid(%d) finishing CB (write=%d)\n", tid, rett);
+               }
+#endif
+
+       }
        debug_fleave();
+
+       if (ASM_sound_handle[asm_index].asm_lock) {
+               g_mutex_unlock(ASM_sound_handle[asm_index].asm_lock);
+       }
+
        return TRUE;
 }
 
-bool __ASM_add_sound_callback(int index, int fd, gushort events, gLoopPollHandler_t p_gloop_poll_handler )
+
+static bool __ASM_add_sound_callback(int index, int fd, gushort events, gLoopPollHandler_t p_gloop_poll_handler )
 {
        GSource* g_src = NULL;
        GSourceFuncs *g_src_funcs = NULL;               /* handler function */
        guint gsource_handle;
        GPollFD *g_poll_fd = NULL;                      /* file descriptor */
 
+       ASM_sound_handle[index].asm_lock = g_new(GMutex, 1);
+       if (!ASM_sound_handle[index].asm_lock) {
+               debug_error("failed to alloc GMutex for index(%d)", index);
+               return false;
+       }
+       g_mutex_init(ASM_sound_handle[index].asm_lock);
+
        /* 1. make GSource Object */
        g_src_funcs = (GSourceFuncs *)g_malloc(sizeof(GSourceFuncs));
        if (!g_src_funcs) {
@@ -317,10 +422,9 @@ bool __ASM_add_sound_callback(int index, int fd, gushort events, gLoopPollHandle
        if (!g_src) {
                debug_error("g_malloc failed on m_readfd");
                return false;
-       }
+       }
        ASM_sound_handle[index].asm_src = g_src;
        ASM_sound_handle[index].g_src_funcs = g_src_funcs;
-       debug_msg(" g_malloc : g_src_funcs(%#X)", g_src_funcs);
 
        /* 2. add file description which used in g_loop() */
        g_poll_fd = (GPollFD *)g_malloc(sizeof(GPollFD));
@@ -331,33 +435,36 @@ bool __ASM_add_sound_callback(int index, int fd, gushort events, gLoopPollHandle
        g_poll_fd->fd = fd;
        g_poll_fd->events = events;
        ASM_sound_handle[index].g_poll_fd = g_poll_fd;
-       debug_msg(" g_malloc : g_poll_fd(%#X)", g_poll_fd);
 
        /* 3. combine g_source object and file descriptor */
        g_source_add_poll(g_src, g_poll_fd);
-       gsource_handle = g_source_attach(g_src, NULL);
-       if (!gsource_handle) {
+       gsource_handle = g_source_attach(g_src, g_main_loop_get_context(g_asm_loop));
+       if (!gsource_handle) {
                debug_error(" Failed to attach the source to context");
                return false;
-       }
-
-       debug_msg(" g_source_add_poll : g_src_id(%d)", gsource_handle);
-       ASM_sound_handle[index].ASM_g_id = gsource_handle;
+       }
+       g_source_unref(g_src);
 
        /* 4. set callback */
        g_source_set_callback(g_src, p_gloop_poll_handler,(gpointer)g_poll_fd, NULL);
 
-       debug_msg(" g_source_set_callback : %d", errno);
+       debug_log(" g_malloc:g_src_funcs(%#X),g_poll_fd(%#X)  g_source_add_poll:g_src_id(%d)  g_source_set_callback:errno(%d)",
+                               g_src_funcs, g_poll_fd, gsource_handle, errno);
        return true;
 }
 
 
-bool __ASM_remove_sound_callback(int index, gushort events)
+static bool __ASM_remove_sound_callback(int index, gushort events)
 {
        bool ret = true;
-       gboolean gret = TRUE;
 
-       GSourceFunc *g_src_funcs = ASM_sound_handle[index].g_src_funcs;
+       if (ASM_sound_handle[index].asm_lock) {
+               g_mutex_clear(ASM_sound_handle[index].asm_lock);
+               g_free(ASM_sound_handle[index].asm_lock);
+               ASM_sound_handle[index].asm_lock = NULL;
+       }
+
+       GSourceFuncs *g_src_funcs = ASM_sound_handle[index].g_src_funcs;
        GPollFD *g_poll_fd = ASM_sound_handle[index].g_poll_fd; /* store file descriptor */
        if (!g_poll_fd) {
                debug_error("g_poll_fd is null..");
@@ -367,61 +474,154 @@ bool __ASM_remove_sound_callback(int index, gushort events)
        g_poll_fd->fd = ASM_sound_handle[index].asm_fd;
        g_poll_fd->events = events;
 
-       debug_msg(" g_source_remove_poll : fd(%d), event(%x)", g_poll_fd->fd, g_poll_fd->events);
-       g_source_remove_poll(ASM_sound_handle[index].asm_src, g_poll_fd);
-       debug_msg(" g_source_remove_poll : %d", errno);
-
-       gret = g_source_remove(ASM_sound_handle[index].ASM_g_id);
-       debug_msg(" g_source_remove : gret(%d)", gret);
-       if (!gret) {
-               debug_error("failed to g_source_remove(). ASM_g_id(%d)", ASM_sound_handle[index].ASM_g_id);
-               ret = false;
+       if (!ASM_sound_handle[index].asm_src) {
+               debug_error("ASM_sound_handle[%d].asm_src is null..", index);
                goto init_handle;
        }
+       debug_log(" g_source_remove_poll : fd(%d), event(%x), errno(%d)", g_poll_fd->fd, g_poll_fd->events, errno);
+       g_source_remove_poll(ASM_sound_handle[index].asm_src, g_poll_fd);
 
 init_handle:
 
+       if (ASM_sound_handle[index].asm_src) {
+               g_source_destroy(ASM_sound_handle[index].asm_src);
+               if (!g_source_is_destroyed (ASM_sound_handle[index].asm_src)) {
+                       debug_warning(" failed to g_source_destroy(), asm_src(0x%p)", ASM_sound_handle[index].asm_src);
+               }
+       }
+       debug_log(" g_free : g_src_funcs(%#X), g_poll_fd(%#X)", g_src_funcs, g_poll_fd);
+
        if (g_src_funcs) {
-               debug_msg(" g_free : g_src_funcs(%#X)", g_src_funcs);
                g_free(g_src_funcs);
-
+               g_src_funcs = NULL;
        }
        if (g_poll_fd) {
-               debug_msg(" g_free : g_poll_fd(%#X)", g_poll_fd);
                g_free(g_poll_fd);
+               g_poll_fd = NULL;
        }
 
        ASM_sound_handle[index].g_src_funcs = NULL;
        ASM_sound_handle[index].g_poll_fd = NULL;
-       ASM_sound_handle[index].ASM_g_id = 0;
        ASM_sound_handle[index].asm_src = NULL;
        ASM_sound_handle[index].asm_callback = NULL;
+       ASM_sound_handle[index].watch_callback = NULL;
+
+       return ret;
+}
+
+
+static bool __ASM_is_existed_request_for_watching(ASM_sound_events_t interest_event, ASM_sound_states_t interest_state, int *index)
+{
+       int i = 0;
+       for(i = 0; i< ASM_HANDLE_MAX; i++) {
+               if (ASM_sound_handle[i].is_for_watching && ASM_sound_handle[i].sound_event == interest_event) {
+                       if (ASM_sound_handle[i].sound_state == interest_state) {
+                               debug_warning("already requested interest-session(%s, %s)",
+                                               ASM_sound_events_str[interest_event], ASM_sound_state_str[interest_state]);
+                               *index = i;
+                               return true;
+                       }
+               }
+       }
+       *index = 0;
+       return false;
+}
+
+
+static bool __ASM_is_supported_session_for_watching(ASM_sound_events_t interest_event, ASM_sound_states_t interest_state)
+{
+       bool ret = false;
+
+       /* check sound_event */
+       switch (interest_event) {
+       case ASM_EVENT_MEDIA_MMPLAYER:
+       case ASM_EVENT_MEDIA_MMCAMCORDER:
+       case ASM_EVENT_MEDIA_MMSOUND:
+       case ASM_EVENT_MEDIA_OPENAL:
+       case ASM_EVENT_MEDIA_FMRADIO:
+       case ASM_EVENT_MEDIA_WEBKIT:
+       case ASM_EVENT_NOTIFY:
+       case ASM_EVENT_ALARM:
+       case ASM_EVENT_EARJACK_UNPLUG:
+       case ASM_EVENT_CALL:
+       case ASM_EVENT_VIDEOCALL:
+       case ASM_EVENT_VOIP:
+       case ASM_EVENT_MONITOR:
+       case ASM_EVENT_EMERGENCY:
+       case ASM_EVENT_EXCLUSIVE_RESOURCE:
+       case ASM_EVENT_VOICE_RECOGNITION:
+       case ASM_EVENT_MMCAMCORDER_AUDIO:
+       case ASM_EVENT_MMCAMCORDER_VIDEO:
+               ret = true;
+               break;
+       default:
+               debug_error("not supported sound_event(%d)", interest_event);
+               ret = false;
+               return ret;
+       }
+
+       /* check sound_state */
+       switch (interest_state) {
+       case ASM_STATE_PLAYING:
+       case ASM_STATE_STOP:
+               ret = true;
+               break;
+       default:
+               debug_error("not supported sound_state(%d)", interest_state);
+               ret = false;
+               return ret;
+       }
 
        return ret;
 }
 
-int __ASM_find_index(int handle)
+
+static int __ASM_find_index_by_handle(int handle)
 {
        int i = 0;
        for(i = 0; i< ASM_HANDLE_MAX; i++) {
                if (handle == ASM_sound_handle[i].handle) {
-                       debug_msg("found index(%d) for handle(%d)", i, handle);
+                       //debug_msg("found index(%d) for handle(%d)", i, handle);
+                       if (handle == ASM_HANDLE_INIT_VAL) {
+                               return -1;
+                       }
                        return i;
                }
        }
        return -1;
 }
 
-void __ASM_add_callback(int index)
+static int __ASM_find_index_by_event(ASM_sound_events_t sound_event, int pid)
 {
-       if (!__ASM_add_sound_callback(index, ASM_sound_handle[index].asm_fd, (gushort)POLLIN | POLLPRI, asm_callback_handler)) {
-               debug_error("failed to __ASM_add_sound_callback()");
-               //return false;
+       int i = 0;
+
+       for(i = 0; i< ASM_HANDLE_MAX; i++) {
+               if (sound_event == ASM_sound_handle[i].sound_event && pid == ASM_sound_handle[i].asm_tid) {
+                       debug_msg("found index(%d) for sound_event(%d)", i, sound_event);
+                       return i;
+               }
+       }
+       return -1;
+}
+
+
+static void __ASM_add_callback(int index, bool is_for_watching)
+{
+       if (!is_for_watching) {
+               if (!__ASM_add_sound_callback(index, ASM_sound_handle[index].asm_fd, (gushort)POLLIN | POLLPRI, asm_callback_handler)) {
+                       debug_error("failed to __ASM_add_sound_callback(asm_callback_handler)");
+                       //return false;
+               }
+       } else {
+               if (!__ASM_add_sound_callback(index, ASM_sound_handle[index].asm_fd, (gushort)POLLIN | POLLPRI, watch_callback_handler)) {
+                       debug_error("failed to __ASM_add_sound_callback(watch_callback_handler)");
+                       //return false;
+               }
        }
 }
 
 
-void __ASM_remove_callback(int index)
+static void __ASM_remove_callback(int index)
 {
        if (!__ASM_remove_sound_callback(index, (gushort)POLLIN | POLLPRI)) {
                debug_error("failed to __ASM_remove_sound_callback()");
@@ -430,11 +630,10 @@ void __ASM_remove_callback(int index)
 }
 
 
-void __ASM_open_callback(int index)
+static void __ASM_open_callback(int index)
 {
        mode_t pre_mask;
 
-       debug_msg("index (%d)", 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);
        if (mknod(filename, S_IFIFO|0666, 0)) {
@@ -443,11 +642,12 @@ void __ASM_open_callback(int index)
        umask(pre_mask);
        ASM_sound_handle[index].asm_fd = open( filename, O_RDWR|O_NONBLOCK);
        if (ASM_sound_handle[index].asm_fd == -1) {
-               debug_error("%s : file open error(%d)", str_fail, errno);
+               debug_error("%s : index(%d), file open error(%d)", str_fail, index, errno);
        } else {
-               debug_msg("%s : filename(%s), fd(%d)", str_pass, filename, ASM_sound_handle[index].asm_fd);
+               debug_log("%s : index(%d), filename(%s), fd(%d)", str_pass, index, filename, ASM_sound_handle[index].asm_fd);
        }
        g_free(filename);
+       filename = NULL;
 
 #ifdef CONFIG_ENABLE_RETCB
        char *filename2 = g_strdup_printf("/tmp/ASM.%d.%dr", ASM_sound_handle[index].asm_tid,  ASM_sound_handle[index].handle);
@@ -457,6 +657,7 @@ void __ASM_open_callback(int index)
        }
        umask(pre_mask);
        g_free(filename2);
+       filename2 = NULL;
 #endif
 
 }
@@ -464,7 +665,6 @@ void __ASM_open_callback(int index)
 
 void __ASM_close_callback(int index)
 {
-       debug_msg("index (%d)", index);
        if (ASM_sound_handle[index].asm_fd < 0) {
                debug_error("%s : fd error.", str_fail);
        } else {
@@ -473,8 +673,9 @@ void __ASM_close_callback(int index)
                if (remove(filename)) {
                        debug_error("remove() failure, filename(%s), errno(%d)", filename, errno);
                }
-               debug_msg("%s : filename(%s), fd(%d)", str_pass, filename, ASM_sound_handle[index].asm_fd);
+               debug_log("%s : index(%d), filename(%s), fd(%d)", str_pass, index, filename, ASM_sound_handle[index].asm_fd);
                g_free(filename);
+               filename = NULL;
        }
 
 #ifdef CONFIG_ENABLE_RETCB
@@ -483,28 +684,29 @@ void __ASM_close_callback(int index)
        /* Defensive code - wait until callback timeout although callback is removed */
        int buf = ASM_CB_RES_STOP;
        int tmpfd = -1;
-
+       int ret;
        tmpfd = open(filename2, O_WRONLY | O_NONBLOCK);
        if (tmpfd < 0) {
                char str_error[256];
                strerror_r(errno, str_error, sizeof(str_error));
-               debug_error("failed to open file(%s) (may server close first), tid(%d) fd(%d) %s errno=%d(%s)",
+               debug_warning("could not open file(%s) (may server close it first), tid(%d) fd(%d) %s errno=%d(%s)",
                        filename2, ASM_sound_handle[index].asm_tid, tmpfd, filename2, errno, str_error);
        } else {
-               debug_msg("write ASM_CB_RES_STOP(tid:%d) for waiting server", ASM_sound_handle[index].asm_tid);
-               write(tmpfd, &buf, sizeof(buf));
+               ret = write(tmpfd, &buf, sizeof(buf));
                close(tmpfd);
+               debug_msg("write ASM_CB_RES_STOP(tid:%d) for waiting server , error code(%d)", ASM_sound_handle[index].asm_tid, ret);
        }
 
        if (remove(filename2)) {
                debug_error("remove() failure, filename(%s), errno(%d)", filename2, errno);
        }
        g_free(filename2);
+       filename2 = NULL;
 #endif
 
 }
 
-bool __asm_construct_snd_msg(int asm_pid, int handle, ASM_sound_events_t sound_event,
+static 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;
@@ -515,17 +717,16 @@ bool __asm_construct_snd_msg(int asm_pid, int handle, ASM_sound_events_t sound_e
        asm_snd_msg.data.sound_state = sound_state;
        asm_snd_msg.data.system_resource = resource;
 
-       debug_msg("tid=%ld,handle=%d,req=%d,evt=%d,state=%d,resource=%d", 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);
-       debug_msg("     instance_id : %ld\n", asm_snd_msg.instance_id);
-       debug_msg("     handle : %d\n", asm_snd_msg.data.handle);
+       debug_msg("tid=%ld,handle=%d,req=%d,evt=%d,state=%d,resource=%d,instance_id=%ld", 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_snd_msg.instance_id);
 
        return true;
 }
 
 
-bool __ASM_init_msg(int *error_code)
+static bool __ASM_init_msg(int *error_code)
 {
+       int i = 0;
        asm_snd_msgid = msgget((key_t)2014, 0666);
        asm_rcv_msgid = msgget((key_t)4102, 0666);
        asm_cb_msgid = msgget((key_t)4103, 0666);
@@ -533,24 +734,46 @@ bool __ASM_init_msg(int *error_code)
        debug_msg("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;
-               debug_error("failed to msgget with error(%d)",error_code);
-               return false;
+               if (errno == EACCES) {
+                       debug_warning("Require ROOT permission.\n");
+               } else if (errno == ENOMEM) {
+                       debug_warning("System memory is empty.\n");
+               } else if(errno == ENOSPC) {
+                       debug_warning("Resource is empty.\n");
+               }
+               /* try again in 50ms later by 10 times */
+               for (i=0;i<10;i++) {
+                       usleep(50000);
+                       asm_snd_msgid = msgget((key_t)2014, 0666);
+                       asm_rcv_msgid = msgget((key_t)4102, 0666);
+                       asm_cb_msgid = msgget((key_t)4103, 0666);
+                       if (asm_snd_msgid == -1 || asm_rcv_msgid == -1 || asm_cb_msgid == -1) {
+                               debug_error("Fail to GET msgid by retrying %d times\n", i+1);
+                       } else {
+                               break;
+                       }
+               }
+
+               if (asm_snd_msgid == -1 || asm_rcv_msgid == -1 || asm_cb_msgid == -1) {
+                       *error_code = ERR_ASM_MSG_QUEUE_MSGID_GET_FAILED;
+                       debug_error("failed to msgget with error(%d)",*error_code);
+                       return false;
+               }
        }
 
        return true;
 }
 
-void __ASM_init_callback(int index)
+static void __ASM_init_callback(int index, bool is_for_watching)
 {
        debug_fenter();
        __ASM_open_callback(index);
-       __ASM_add_callback(index);
+       __ASM_add_callback(index, is_for_watching);
        debug_fleave();
 }
 
 
-void __ASM_destroy_callback(int index)
+static void __ASM_destroy_callback(int index)
 {
        debug_fenter();
        __ASM_remove_callback(index);
@@ -560,15 +783,13 @@ void __ASM_destroy_callback(int index)
 
 EXPORT_API
 bool ASM_register_sound_ex (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 (*func)(void*,void*))
+                                               ASM_sound_cb_t callback, void *user_data, ASM_resource_t mm_resource, int *error_code, int (*func)(void*,void*))
 {
-       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;
 
        debug_fenter();
 
@@ -576,8 +797,9 @@ bool ASM_register_sound_ex (const int application_pid, int *asm_handle, ASM_soun
                debug_error ("invalid parameter. error code is null");
                return false;
        }
+       *error_code = ERR_ASM_ERROR_NONE;
 
-       if (sound_event< ASM_EVENT_SHARE_MMPLAYER || sound_event >= ASM_EVENT_MAX) {
+       if (sound_event < ASM_EVENT_MEDIA_MMPLAYER || sound_event >= ASM_EVENT_MAX) {
                *error_code = ERR_ASM_EVENT_IS_INVALID;
                debug_error ("invalid sound event(%d)",sound_event);
                return false;
@@ -590,11 +812,23 @@ bool ASM_register_sound_ex (const int application_pid, int *asm_handle, ASM_soun
        }
 
        if (index == ASM_HANDLE_MAX) {
-               *error_code = ERR_ASM_EVENT_IS_FULL;
+               *error_code = ERR_ASM_LOCAL_HANDLE_IS_FULL;
                debug_error ("local sound event is full(MAX)");
                return false;
        }
 
+       if (!g_asm_thread) {
+               GMainContext* asm_context = g_main_context_new ();
+               g_asm_loop = g_main_loop_new (asm_context, FALSE);
+               g_main_context_unref(asm_context);
+               g_asm_thread = g_thread_new("ASM Thread", thread_func, NULL);
+               if (g_asm_thread == NULL) {
+                       debug_error ("could not create thread..");
+                       g_main_loop_unref(g_asm_loop);
+                       return false;
+               }
+       }
+
        if (application_pid == -1) {
                asm_pid = asmgettid();
        } else if (application_pid > 2) {
@@ -608,27 +842,17 @@ bool ASM_register_sound_ex (const int application_pid, int *asm_handle, ASM_soun
        ASM_sound_handle[index].sound_event = sound_event;
        ASM_sound_handle[index].asm_tid = asm_pid;
 
-       debug_msg(" <<<< Event(%s), Tid(%d), Index(%d)", ASM_sound_events_str[sound_event], ASM_sound_handle[index].asm_tid, index);
-
-       if (!__ASM_init_msg(&error)) {
-               debug_error("failed to __ASM_init_msg(), error(%d)", error);
+       if (!__ASM_init_msg(error_code)) {
+               debug_error("failed to __ASM_init_msg(), error(%d)", *error_code);
+               return false;
        }
 
        if (!__ASM_get_sound_state(&sound_status_value, error_code)) {
                debug_error("failed to __ASM_get_sound_state(), error(%d)", *error_code);
+               return false;
        }
 
-       /* If state is PLAYING, do set state immediately */
-       if (sound_state == ASM_STATE_PLAYING) {
-               debug_msg(" <<<< Event(%s), Tid(%d), State(PLAYING)", ASM_sound_events_str[sound_event], ASM_sound_handle[index].asm_tid);
-               if (!__ASM_set_sound_state(sound_event, ASM_STATE_PLAYING, error_code)) {
-                       debug_error("failed to __ASM_set_sound_state(PLAYING), error(%d)", *error_code);
-                       return false;
-               }
-       } else {
-               debug_msg(" <<<< Event(%s), Tid(%ld), State(WAITING)", ASM_sound_events_str[sound_event], asmgettid());
-       }
-
+       debug_msg(" <<<< Event(%s), Tid(%d), Index(%d), State(%s)", ASM_sound_events_str[sound_event], ASM_sound_handle[index].asm_tid, index, ASM_sound_state_str[sound_state]);
 
        handle = -1; /* for register & get handle from server */
 
@@ -647,30 +871,38 @@ bool ASM_register_sound_ex (const int application_pid, int *asm_handle, ASM_soun
                        debug_error("failed to msgsnd(%d,%s)", errno, strerror(errno));
                        return false;
                }
-               NO_EINTR(ret = msgrcv(asm_rcv_msgid, (void *)&asm_rcv_msg, sizeof(asm_rcv_msg.data), asm_pid, 0));
+
+               NO_EINTR(ret = msgrcv(asm_rcv_msgid, (void *)&asm_rcv_msg, sizeof(asm_rcv_msg.data), ASM_sound_handle[index].asm_tid, 0));
                if (ret == -1) {
                        *error_code = ERR_ASM_MSG_QUEUE_RCV_ERROR;
                        debug_error("failed to msgrcv(%d,%s)", errno, strerror(errno));
                        return false;
                }
+
+               if (asm_rcv_msg.data.source_request_id != ASM_REQUEST_REGISTER) {
+                       *error_code = ERR_ASM_MSG_QUEUE_RCV_ERROR;
+                       debug_error("received msg is not valid, source_request_id(%d)", asm_rcv_msg.data.source_request_id);
+                       return false;
+               }
        }
        /* Construct msg to send -> send msg -> recv msg : end */
 
        handle = asm_rcv_msg.data.alloc_handle; /* get handle from server */
        if (handle == -1) {
                debug_error("failed to create handle from server");
-               *error_code = ERR_ASM_HANDLE_IS_FULL;
+               *error_code = ERR_ASM_SERVER_HANDLE_IS_FULL;
                return false;
        }
 
        ASM_sound_handle[index].handle = handle;
 
-       __ASM_init_callback(index);
+       __ASM_init_callback(index, ASM_sound_handle[index].is_for_watching);
 
 /********************************************************************************************************/
        switch (asm_rcv_msg.data.result_sound_command) {
        case ASM_COMMAND_PAUSE:
        case ASM_COMMAND_STOP:
+               debug_msg( " <<<<<<<<<<<<<<<< Received command : %d (STOP(3)/PAUSE(4)) >>>>>>>>>>>>>>>>>>>>\n", asm_rcv_msg.data.result_sound_command);
                if (handle == asm_rcv_msg.data.cmd_handle) {
 
                        __ASM_destroy_callback(index);
@@ -679,23 +911,33 @@ bool ASM_register_sound_ex (const int application_pid, int *asm_handle, ASM_soun
                        ASM_sound_handle[index].asm_tid = 0;
                        ASM_sound_handle[index].sound_event = ASM_EVENT_NONE;
                        ASM_sound_handle[index].is_used = false;
+                       if (asm_rcv_msg.data.result_sound_command == ASM_COMMAND_PAUSE) {
+                               ASM_sound_handle[index].sound_state = ASM_STATE_PAUSE;
+                       } else if (asm_rcv_msg.data.result_sound_command == ASM_COMMAND_STOP) {
+                               ASM_sound_handle[index].sound_state = ASM_STATE_STOP;
+                       }
 
-                       *error_code = ERR_ASM_POLICY_CANNOT_PLAY;
+                       if (asm_rcv_msg.data.error_code){
+                               *error_code = asm_rcv_msg.data.error_code;
+                               debug_warning("error code: %x",*error_code);
+                       }
                        return false;
+
                } else {
                        int action_index = 0;
+                       unsigned int rcv_sound_status_value = 0;
 
                        if (!__ASM_get_sound_state(&rcv_sound_status_value, error_code)) {
                                debug_error("failed to __ASM_get_sound_state(), error(%d)", *error_code);
                        }
 
                        debug_msg("Callback : TID(%ld), handle(%d), command(%d)", asm_rcv_msg.instance_id, asm_rcv_msg.data.cmd_handle, asm_rcv_msg.data.result_sound_command);
-                       action_index = __ASM_find_index(asm_rcv_msg.data.cmd_handle);
+                       action_index = __ASM_find_index_by_handle(asm_rcv_msg.data.cmd_handle);
                        if (action_index == -1) {
                                debug_error("Can not find index of instance %ld, handle %d", 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);
+                                       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].user_data);
                                } else {
                                        debug_msg("null callback");
                                }
@@ -706,6 +948,8 @@ bool ASM_register_sound_ex (const int application_pid, int *asm_handle, ASM_soun
        case ASM_COMMAND_PLAY:
        case ASM_COMMAND_NONE:
        case ASM_COMMAND_RESUME:
+               ASM_sound_handle[index].sound_state = sound_state;
+               break;
        default:
                break;
        }
@@ -713,7 +957,7 @@ bool ASM_register_sound_ex (const int application_pid, int *asm_handle, ASM_soun
 
 
        ASM_sound_handle[index].asm_callback = callback;
-       ASM_sound_handle[index].cb_data = cb_data;
+       ASM_sound_handle[index].user_data = user_data;
        ASM_sound_handle[index].is_used = true;
 
        debug_msg(" >>>> Event(%s), Handle(%d), CBFuncPtr(%p)", ASM_sound_events_str[sound_event], handle, callback);
@@ -728,14 +972,14 @@ bool ASM_register_sound_ex (const int application_pid, int *asm_handle, ASM_soun
 
 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)
+                                               ASM_sound_cb_t callback, void *user_data, ASM_resource_t mm_resource, int *error_code)
 {
-       return ASM_register_sound_ex (application_pid, asm_handle, sound_event, sound_state, callback, cb_data, mm_resource, error_code, NULL);
+       return ASM_register_sound_ex (application_pid, asm_handle, sound_event, sound_state, callback, user_data, mm_resource, error_code, NULL);
 }
 
 
 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)
+bool ASM_change_callback(const int asm_handle, ASM_sound_events_t sound_event, ASM_sound_cb_t callback, void *user_data, int *error_code)
 {
        int handle=0;
 
@@ -743,8 +987,9 @@ bool ASM_change_callback(const int asm_handle, ASM_sound_events_t sound_event, A
                debug_error ("invalid parameter. error code is null");
                return false;
        }
+       *error_code = ERR_ASM_ERROR_NONE;
 
-       if (sound_event < ASM_EVENT_SHARE_MMPLAYER || sound_event >= ASM_EVENT_MAX) {
+       if (sound_event < ASM_EVENT_MEDIA_MMPLAYER || sound_event >= ASM_EVENT_MAX) {
                *error_code = ERR_ASM_EVENT_IS_INVALID;
                debug_error ("invalid sound event(%d)",sound_event);
                return false;
@@ -753,23 +998,23 @@ bool ASM_change_callback(const int asm_handle, ASM_sound_events_t sound_event, A
        int asm_index = -1;
 
        if (asm_handle < 0 || asm_handle >= ASM_SERVER_HANDLE_MAX) {
-               *error_code = ERR_ASM_POLICY_INVALID_HANDLE;
+               *error_code = ERR_ASM_LOCAL_HANDLE_IS_INVALID;
                debug_error("invalid handle(%d). callback is not registered", asm_handle);
                return false;
        }
 
        handle = asm_handle;
 
-       asm_index = __ASM_find_index(handle);
+       asm_index = __ASM_find_index_by_handle(handle);
        if (asm_index == -1) {
-               *error_code = ERR_ASM_POLICY_INVALID_HANDLE;
+               *error_code = ERR_ASM_LOCAL_HANDLE_IS_INVALID;
                debug_error("Can not find index for handle %d", handle);
                return false;
        }
 
        debug_msg("callback function has changed to %p", callback);
        ASM_sound_handle[asm_index].asm_callback = callback;
-       ASM_sound_handle[asm_index].cb_data = cb_data;
+       ASM_sound_handle[asm_index].user_data = user_data;
 
        return true;
 }
@@ -783,27 +1028,28 @@ bool ASM_unregister_sound_ex(const int asm_handle, ASM_sound_events_t sound_even
 
        debug_fenter();
 
-       if (error_code==NULL) {
+       if (error_code == NULL) {
                debug_error ("invalid parameter. error code is null");
                return false;
        }
+       *error_code = ERR_ASM_ERROR_NONE;
 
-       if (sound_event<ASM_EVENT_SHARE_MMPLAYER || sound_event >= ASM_EVENT_MAX) {
+       if (sound_event < ASM_EVENT_MEDIA_MMPLAYER || sound_event >= ASM_EVENT_MAX) {
                *error_code = ERR_ASM_EVENT_IS_INVALID;
                debug_error ("invalid sound event(%d)",sound_event);
                return false;
        }
 
        if (asm_handle < 0 || asm_handle >= ASM_SERVER_HANDLE_MAX) {
-               *error_code = ERR_ASM_POLICY_INVALID_HANDLE;
+               *error_code = ERR_ASM_LOCAL_HANDLE_IS_INVALID;
                debug_error("invalid handle(%d). callback is not registered", asm_handle);
                return false;
        }
 
        handle = asm_handle;
-       asm_index = __ASM_find_index(handle);
+       asm_index = __ASM_find_index_by_handle(handle);
        if (asm_index == -1) {
-               *error_code = ERR_ASM_POLICY_INVALID_HANDLE;
+               *error_code = ERR_ASM_LOCAL_HANDLE_IS_INVALID;
                debug_error("Can not find index for handle(%d)", handle);
                return false;
        }
@@ -815,6 +1061,16 @@ bool ASM_unregister_sound_ex(const int asm_handle, ASM_sound_events_t sound_even
                return false;
        }
 
+       if (ASM_sound_handle[asm_index].asm_lock) {
+               if (!g_mutex_trylock(ASM_sound_handle[asm_index].asm_lock)) {
+                       debug_warning("maybe asm_callback is being called, try one more time..");
+                       usleep(2500000); // 2.5 sec
+                       if (g_mutex_trylock(ASM_sound_handle[asm_index].asm_lock)) {
+                               debug_msg("finally got asm_lock");
+                       }
+               }
+       }
+
        if (func) {
                func(&asm_snd_msg, &asm_rcv_msg);
        } else  {
@@ -822,19 +1078,26 @@ bool ASM_unregister_sound_ex(const int asm_handle, ASM_sound_events_t sound_even
                if (ret == -1) {
                        *error_code = ERR_ASM_MSG_QUEUE_SND_ERROR;
                        debug_error("failed to msgsnd(%d,%s)", errno, strerror(errno));
+                       if (ASM_sound_handle[asm_index].asm_lock) {
+                               g_mutex_unlock(ASM_sound_handle[asm_index].asm_lock);
+                       }
                        return false;
                }
        }
 
+       if (ASM_sound_handle[asm_index].asm_lock) {
+               g_mutex_unlock(ASM_sound_handle[asm_index].asm_lock);
+       }
+
        __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].handle = 0;
        ASM_sound_handle[asm_index].sound_event = ASM_EVENT_NONE;
+       ASM_sound_handle[asm_index].sound_state = ASM_STATE_NONE;
        ASM_sound_handle[asm_index].is_used = false;
 
-       debug_msg(">>>> Event(%s)", ASM_sound_events_str[sound_event]);
-
        debug_fleave();
 
        return true;
@@ -847,51 +1110,281 @@ bool ASM_unregister_sound(const int asm_handle, ASM_sound_events_t sound_event,
 }
 
 EXPORT_API
-bool ASM_get_sound_status(unsigned int *all_sound_status, int *error_code)
+bool ASM_set_watch_session (const int application_pid, ASM_sound_events_t interest_sound_event,
+                            ASM_sound_states_t interest_sound_state, ASM_watch_cb_t callback, void *user_data, int *error_code)
 {
-       if (all_sound_status == NULL || error_code == NULL) {
-               if (error_code)
-                       *error_code = ERR_ASM_UNKNOWN_ERROR;
-               debug_error("invalid parameter");
+       unsigned int sound_status_value;
+       int handle = 0;
+       int asm_pid = 0;
+       int index = 0;
+       int ret = 0;
+
+       debug_fenter();
+
+       if (error_code==NULL) {
+               debug_error ("invalid parameter. error code is null");
                return false;
        }
+       *error_code = ERR_ASM_ERROR_NONE;
 
-       debug_msg("Tid(%ld)", asmgettid());
+       if (interest_sound_event < ASM_EVENT_MEDIA_MMPLAYER || interest_sound_event >= ASM_EVENT_MAX) {
+               *error_code = ERR_ASM_EVENT_IS_INVALID;
+               debug_error ("invalid sound event(%d)", interest_sound_event);
+               return false;
+       }
 
-       if (!__ASM_get_sound_state(all_sound_status, error_code)) {
-               debug_error("failed to __ASM_get_sound_state(), error(%d)", *error_code);
+       if (!__ASM_is_supported_session_for_watching(interest_sound_event, interest_sound_state)) {
+               debug_error("not supported sound_event(%d) or sound_state(%d)", interest_sound_event, interest_sound_state);
+               *error_code = ERR_ASM_WATCH_NOT_SUPPORTED;
                return false;
        }
 
-       return true;
-}
+       if (__ASM_is_existed_request_for_watching(interest_sound_event, interest_sound_state, &index))
+       {
+               debug_warning("already requested interest-session, do not send request message");
+               *error_code = ERR_ASM_WATCH_ALREADY_REQUESTED;
+               return false;
+       }
 
-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;
+       for (index = 0; index < ASM_HANDLE_MAX; index++) {
+               if (ASM_sound_handle[index].is_used == false) {
+                       break;
+               }
+       }
 
-       if (sound_state == NULL || error_code == NULL) {
-               if (error_code)
-                       *error_code = ERR_ASM_UNKNOWN_ERROR;
-               debug_error("invalid parameter");
+       if (index == ASM_HANDLE_MAX) {
+               *error_code = ERR_ASM_LOCAL_HANDLE_IS_FULL;
+               debug_error ("local sound event is full(MAX)");
                return false;
        }
 
-       handle = asm_handle;
-       asm_index = __ASM_find_index(handle);
-       if (asm_index == -1) {
-               debug_error("Can not find index of %d", handle);
+       if (application_pid == -1) {
+               asm_pid = asmgettid();
+       } else if (application_pid > 2) {
+               asm_pid = application_pid;
+       } else {
+               *error_code = ERR_ASM_INVALID_PARAMETER;
+               debug_error ("invalid pid %d", application_pid);
                return false;
        }
 
+       ASM_sound_handle[index].asm_tid = asm_pid;
+       ASM_sound_handle[index].sound_event = interest_sound_event;
+       ASM_sound_handle[index].sound_state = interest_sound_state;
 
-       debug_msg("Pid(%d)", ASM_sound_handle[asm_index].asm_tid);
+       debug_msg(" <<<< Interest event(%s), state(%s), Tid(%d), Index(%d)",
+                               ASM_sound_events_str[interest_sound_event], ASM_sound_state_str[interest_sound_state], ASM_sound_handle[index].asm_tid, index);
 
-       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)) {
-               debug_error("failed to __asm_construct_snd_msg(), error(%d)", *error_code);
+       if (!__ASM_init_msg(error_code)) {
+               debug_error("failed to __ASM_init_msg(), error(%d)", *error_code);
+               return false;
+       }
+
+       if (!__ASM_get_sound_state(&sound_status_value, error_code)) {
+               debug_error("failed to __ASM_get_sound_state(), error(%d)", *error_code);
+               return false;
+       }
+
+       handle = -1; /* for register & get handle from server */
+
+       /* Construct msg to send -> send msg -> recv msg */
+       if (!__asm_construct_snd_msg(asm_pid, handle, interest_sound_event, ASM_REQUEST_REGISTER_WATCHER, interest_sound_state, ASM_RESOURCE_NONE, error_code)) {
+               debug_error("failed to __asm_construct_snd_msg(), error(%d)", *error_code);
+               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;
+               debug_error("failed to msgsnd(%d,%s)", errno, strerror(errno));
+               return false;
+       }
+
+       NO_EINTR(ret = msgrcv(asm_rcv_msgid, (void *)&asm_rcv_msg, sizeof(asm_rcv_msg.data), ASM_sound_handle[index].asm_tid, 0));
+       if (ret == -1) {
+               *error_code = ERR_ASM_MSG_QUEUE_RCV_ERROR;
+               debug_error("failed to msgrcv(%d,%s)", errno, strerror(errno));
+               return false;
+       }
+       if (asm_rcv_msg.data.source_request_id != ASM_REQUEST_REGISTER_WATCHER) {
+               *error_code = ERR_ASM_MSG_QUEUE_RCV_ERROR;
+               debug_error("received msg is not valid, source_request_id(%d)", asm_rcv_msg.data.source_request_id);
+               return false;
+       }
+       /* Construct msg to send -> send msg -> recv msg : end */
+
+       handle = asm_rcv_msg.data.alloc_handle; /* get handle from server */
+       if (handle == -1) {
+               debug_error("failed to create handle from server");
+               *error_code = ERR_ASM_SERVER_HANDLE_IS_FULL;
+               return false;
+       }
+
+       ASM_sound_handle[index].handle = handle;
+       ASM_sound_handle[index].watch_callback = callback;
+       ASM_sound_handle[index].user_data = user_data;
+       ASM_sound_handle[index].is_used = true;
+       ASM_sound_handle[index].is_for_watching = true;
+
+       __ASM_init_callback(index, ASM_sound_handle[index].is_for_watching);
+
+       /********************************************************************************************************/
+       switch (asm_rcv_msg.data.result_sound_command) {
+       case ASM_COMMAND_PLAY:
+               debug_msg(" >>>> added to watch list successfully");
+               break;
+
+       default:
+               debug_error("received message is abnormal..result_sound_command(%d) from ASM server", asm_rcv_msg.data.result_sound_command);
+               *error_code = ERR_ASM_MSG_QUEUE_RCV_ERROR;
+               return false;
+       }
+       /********************************************************************************************************/
+
+       debug_fleave();
+
+       return true;
+}
+
+EXPORT_API
+bool ASM_unset_watch_session (ASM_sound_events_t interest_sound_event, ASM_sound_states_t interest_sound_state, int *error_code)
+{
+       unsigned int sound_status_value;
+       int handle = 0;
+       int asm_pid = 0;
+       int index = 0;
+       int ret = 0;
+
+       debug_fenter();
+
+       if (error_code==NULL) {
+               debug_error ("invalid parameter. error code is null");
+               return false;
+       }
+       *error_code = ERR_ASM_ERROR_NONE;
+
+       if (interest_sound_event < ASM_EVENT_MEDIA_MMPLAYER || interest_sound_event >= ASM_EVENT_MAX) {
+               *error_code = ERR_ASM_EVENT_IS_INVALID;
+               debug_error ("invalid sound event(%d)",interest_sound_event);
+               return false;
+       }
+
+       if (!__ASM_is_supported_session_for_watching(interest_sound_event, interest_sound_state)) {
+               debug_error("not supported sound_event(%d) or sound_state(%d)", interest_sound_event, interest_sound_state);
+               *error_code = ERR_ASM_WATCH_NOT_SUPPORTED;
+               return false;
+       }
+
+       if (!__ASM_is_existed_request_for_watching(interest_sound_event, interest_sound_state, &index))
+       {
+               debug_warning("already unrequested interest-session or have not been requested it before, do not send request message");
+               *error_code = ERR_ASM_WATCH_ALREADY_UNREQUESTED;
+               return false;
+       }
+
+       debug_msg(" <<<< Unregister interest event(%s), state(%s), Tid(%d), Index(%d)",
+                               ASM_sound_events_str[ASM_sound_handle[index].sound_event], ASM_sound_state_str[ASM_sound_handle[index].sound_state], ASM_sound_handle[index].asm_tid, index);
+
+       if (!__ASM_init_msg(error_code)) {
+               debug_error("failed to __ASM_init_msg(), error(%d)", *error_code);
+               return false;
+       }
+
+       if (!__ASM_get_sound_state(&sound_status_value, error_code)) {
+               debug_error("failed to __ASM_get_sound_state(), error(%d)", *error_code);
+               return false;
+       }
+
+       handle = ASM_sound_handle[index].handle;
+       asm_pid = ASM_sound_handle[index].asm_tid;
+
+       /* Construct msg to send -> send msg */
+       if (!__asm_construct_snd_msg(asm_pid, handle, interest_sound_event, ASM_REQUEST_UNREGISTER_WATCHER, interest_sound_state, ASM_RESOURCE_NONE, error_code)) {
+               debug_error("failed to __asm_construct_snd_msg(), error(%d)", *error_code);
+               return false;
+       }
+
+       if (ASM_sound_handle[index].asm_lock) {
+               g_mutex_lock(ASM_sound_handle[index].asm_lock);
+       }
+
+       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;
+               debug_error("failed to msgsnd(%d,%s)", errno, strerror(errno));
+               if (ASM_sound_handle[index].asm_lock) {
+                       g_mutex_unlock(ASM_sound_handle[index].asm_lock);
+               }
+               return false;
+       }
+       /* Construct msg to send -> send msg : end */
+
+       if (ASM_sound_handle[index].asm_lock) {
+               g_mutex_unlock(ASM_sound_handle[index].asm_lock);
+       }
+
+       __ASM_destroy_callback(index);
+
+       ASM_sound_handle[index].asm_tid = 0;
+       ASM_sound_handle[index].handle = 0;
+       ASM_sound_handle[index].sound_event = ASM_EVENT_NONE;
+       ASM_sound_handle[index].sound_state = ASM_STATE_NONE;
+       ASM_sound_handle[index].is_used = false;
+       ASM_sound_handle[index].is_for_watching = false;
+
+       debug_msg(" >>>> send requesting message successfully");
+
+       debug_fleave();
+
+       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_INVALID_PARAMETER;
+               debug_error("invalid parameter");
+               return false;
+       }
+
+       debug_msg("Tid(%ld)", asmgettid());
+
+       if (!__ASM_get_sound_state(all_sound_status, error_code)) {
+               debug_error("failed to __ASM_get_sound_state(), error(%d)", *error_code);
+               return false;
+       }
+
+       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_INVALID_PARAMETER;
+               debug_error("invalid parameter");
+               return false;
+       }
+
+       handle = asm_handle;
+       asm_index = __ASM_find_index_by_handle(handle);
+       if (asm_index == -1) {
+               debug_error("Can not find index of %d", handle);
+               return false;
+       }
+
+
+       debug_msg("Pid(%d)", 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)) {
+               debug_error("failed to __asm_construct_snd_msg(), error(%d)", *error_code);
                return false;
        }
 
@@ -903,13 +1396,19 @@ bool ASM_get_process_session_state(const int asm_handle, ASM_sound_states_t *sou
                return false;
        }
 
-       NO_EINTR(ret = msgrcv(asm_rcv_msgid, (void *)&asm_rcv_msg, sizeof(asm_rcv_msg.data), asm_snd_msg.instance_id, 0));
+       NO_EINTR(ret = msgrcv(asm_rcv_msgid, (void *)&asm_rcv_msg, sizeof(asm_rcv_msg.data), ASM_sound_handle[asm_index].asm_tid, 0));
        if (ret == -1) {
                *error_code = ERR_ASM_MSG_QUEUE_RCV_ERROR;
                debug_error("failed to msgrcv(%d,%s)", errno, strerror(errno));
                return false;
        }
 
+       if (asm_rcv_msg.data.source_request_id != ASM_REQUEST_GETMYSTATE) {
+               *error_code = ERR_ASM_MSG_QUEUE_RCV_ERROR;
+               debug_error("received msg is not valid, source_request_id(%d)", asm_rcv_msg.data.source_request_id);
+               return false;
+       }
+
        *sound_state = asm_rcv_msg.data.result_sound_state;
 
        debug_msg(">>>> Pid(%d), State(%s)", ASM_sound_handle[asm_index].asm_tid, ASM_sound_state_str[*sound_state]);
@@ -918,6 +1417,40 @@ bool ASM_get_process_session_state(const int asm_handle, ASM_sound_states_t *sou
        return true;
 }
 
+EXPORT_API
+bool ASM_attach_callback(ASM_sound_events_t sound_event, ASM_sound_cb_t callback, void *user_data, int *error_code)
+{
+       int asm_index = 0;
+
+       if (callback == NULL || error_code == NULL) {
+               if (error_code)
+                       *error_code = ERR_ASM_INVALID_PARAMETER;
+               debug_error("invalid parameter");
+               return false;
+       }
+
+       asm_index = __ASM_find_index_by_event(sound_event, asmgettid());
+       if (asm_index == -1) {
+               debug_error("Could not find index of the event(%d)", sound_event);
+               return false;
+       }
+
+       if (!ASM_sound_handle[asm_index].asm_callback) {
+               ASM_sound_handle[asm_index].asm_callback = callback;
+               ASM_sound_handle[asm_index].user_data = user_data;
+       } else {
+               if (error_code)
+                       *error_code = ERR_ASM_ALREADY_REGISTERED;
+               debug_error("asm_callback was already registered(0x%x)", ASM_sound_handle[asm_index].asm_callback);
+               return false;
+       }
+
+       debug_msg(">>>> Pid(%d), Handle(%d), Event(%s), Callback(0x%x)", ASM_sound_handle[asm_index].asm_tid, ASM_sound_handle[asm_index].handle,
+               ASM_sound_events_str[ASM_sound_handle[asm_index].sound_event], ASM_sound_handle[asm_index].asm_callback);
+
+       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)
 {
@@ -931,14 +1464,14 @@ bool ASM_get_sound_state(const int asm_handle, ASM_sound_events_t sound_event, A
                debug_error("invalid parameter");
                return false;
        }
-       if (sound_event < ASM_EVENT_SHARE_MMPLAYER || sound_event >= ASM_EVENT_MAX) {
+       if (sound_event < ASM_EVENT_MEDIA_MMPLAYER || sound_event >= ASM_EVENT_MAX) {
                *error_code = ERR_ASM_EVENT_IS_INVALID;
                debug_error("invalid sound event(%d)",sound_event);
                return false;
        }
        handle = asm_handle;
 
-       asm_index = __ASM_find_index(handle);
+       asm_index = __ASM_find_index_by_handle(handle);
        if (asm_index == -1) {
                debug_error("Can not find index of %d", handle);
                return false;
@@ -951,7 +1484,6 @@ bool ASM_get_sound_state(const int asm_handle, ASM_sound_events_t sound_event, A
                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;
@@ -959,13 +1491,19 @@ bool ASM_get_sound_state(const int asm_handle, ASM_sound_events_t sound_event, A
                return false;
        }
 
-       NO_EINTR(ret = msgrcv(asm_rcv_msgid, (void *)&asm_rcv_msg, sizeof(asm_rcv_msg.data), asm_snd_msg.instance_id, 0));
+       NO_EINTR(ret = msgrcv(asm_rcv_msgid, (void *)&asm_rcv_msg, sizeof(asm_rcv_msg.data), ASM_sound_handle[asm_index].asm_tid, 0));
        if (ret == -1) {
                *error_code = ERR_ASM_MSG_QUEUE_RCV_ERROR;
                debug_error("failed to msgrcv(%d,%s)", errno, strerror(errno));
                return false;
        }
 
+       if (asm_rcv_msg.data.source_request_id != ASM_REQUEST_GETSTATE) {
+               *error_code = ERR_ASM_MSG_QUEUE_RCV_ERROR;
+               debug_error("received msg is not valid, source_request_id(%d)", asm_rcv_msg.data.source_request_id);
+               return false;
+       }
+
        *sound_state = asm_rcv_msg.data.result_sound_state;
 
        debug_msg(">>>> Event(%s), State(%s)", ASM_sound_events_str[sound_event], ASM_sound_state_str[*sound_state]);
@@ -980,7 +1518,6 @@ bool ASM_set_sound_state_ex (const int asm_handle, ASM_sound_events_t sound_even
        int handle = 0;
        int asm_index = 0;
        int ret = 0;
-       unsigned int rcv_sound_status_value;
 
        debug_fenter();
 
@@ -996,14 +1533,14 @@ bool ASM_set_sound_state_ex (const int asm_handle, ASM_sound_events_t sound_even
        }
 
        if (asm_handle < 0 || asm_handle >= ASM_SERVER_HANDLE_MAX) {
-               *error_code = ERR_ASM_POLICY_INVALID_HANDLE;
+               *error_code = ERR_ASM_LOCAL_HANDLE_IS_INVALID;
                debug_error("Invalid handle %d", asm_handle);
                return false;
        }
 
        handle = asm_handle;
 
-       asm_index = __ASM_find_index(handle);
+       asm_index = __ASM_find_index_by_handle(handle);
        if (asm_index == -1) {
                debug_error("Can not find index of %d", handle);
                return false;
@@ -1031,91 +1568,85 @@ bool ASM_set_sound_state_ex (const int asm_handle, ASM_sound_events_t sound_even
        }
 
        if (sound_state == ASM_STATE_PLAYING ) {
-               debug_msg( "sound_state is PLAYING");
+               debug_log( "sound_state is PLAYING, func(0x%x)", func);
                if (func == NULL) {
-                       NO_EINTR(ret = msgrcv(asm_rcv_msgid, (void *)&asm_rcv_msg, sizeof(asm_rcv_msg.data), ASM_sound_handle[handle].asm_tid, 0));
+                       NO_EINTR(ret = msgrcv(asm_rcv_msgid, (void *)&asm_rcv_msg, sizeof(asm_rcv_msg.data), ASM_sound_handle[asm_index].asm_tid, 0));
                        if (ret == -1) {
                                *error_code = ERR_ASM_MSG_QUEUE_RCV_ERROR;
                                debug_error("failed to msgrcv(%d,%s)", errno, strerror(errno));
                                return false;
-                       } else {
+                       }
 
+                       if (asm_rcv_msg.data.source_request_id != ASM_REQUEST_SETSTATE) {
+                               *error_code = ERR_ASM_MSG_QUEUE_RCV_ERROR;
+                               debug_error("received msg is not valid, source_request_id(%d)", asm_rcv_msg.data.source_request_id);
+                               return false;
                        }
                }
 
-               debug_msg( " <<<<<<<<<<<<<<<< [BEFORE] Callback : Main Context >>>>>>>>>>>>>>>>>>>> \n");
-       /********************************************************************************************************/
+
                switch (asm_rcv_msg.data.result_sound_command) {
                case ASM_COMMAND_PAUSE:
                case ASM_COMMAND_STOP:
+                       debug_msg( " <<<<<<<<<<<<<<<< Received command : %d (STOP(3)/PAUSE(4)) >>>>>>>>>>>>>>>>>>>>\n", asm_rcv_msg.data.result_sound_command);
                        if (handle == asm_rcv_msg.data.cmd_handle) {
 
                                debug_msg("handle(%d) is same as asm_rcv_msg.data.cmd_handle", handle);
 
-                               asm_index = __ASM_find_index(asm_rcv_msg.data.cmd_handle);
+                               asm_index = __ASM_find_index_by_handle(asm_rcv_msg.data.cmd_handle);
                                if (asm_index == -1) {
-                                       *error_code = ERR_ASM_POLICY_INVALID_HANDLE;
-                                       debug_error( "Can not find index from instance_id %ld, handle %d",      asm_rcv_msg.instance_id, asm_rcv_msg.data.cmd_handle);
+                                       *error_code = ERR_ASM_LOCAL_HANDLE_IS_INVALID;
+                                       debug_error( "Can not find index from instance_id %ld, handle %d", asm_rcv_msg.instance_id, asm_rcv_msg.data.cmd_handle);
                                        return false;
                                }
 
-                               /* check former sound event */
-                               switch (asm_rcv_msg.data.former_sound_event) {
-                               case ASM_EVENT_ALARM:
-                                       debug_msg("blocked by ALARM");
-                                       *error_code = ERR_ASM_POLICY_CANNOT_PLAY_BY_ALARM;
-                                       break;
-                               case ASM_EVENT_CALL:
-                               case ASM_EVENT_VIDEOCALL:
-                               case ASM_EVENT_RICH_CALL:
-                                       debug_msg("blocked by CALL/VIDEOCALL/RICH_CALL");
-                                       *error_code = ERR_ASM_POLICY_CANNOT_PLAY_BY_CALL;
-                                       break;
-                               default:
-                                       debug_msg("blocked by Other(sound_event num:%d)", asm_rcv_msg.data.former_sound_event);
-                                       *error_code = ERR_ASM_POLICY_CANNOT_PLAY;
-                                       break;
+                               if (asm_rcv_msg.data.result_sound_command == ASM_COMMAND_PAUSE) {
+                                       ASM_sound_handle[asm_index].sound_state = ASM_STATE_PAUSE;
+                               } else if (asm_rcv_msg.data.result_sound_command == ASM_COMMAND_STOP) {
+                                       ASM_sound_handle[asm_index].sound_state = ASM_STATE_STOP;
+                               }
+
+                               if (asm_rcv_msg.data.error_code){
+                                       *error_code = asm_rcv_msg.data.error_code;
+                                       debug_warning("error code: %x",*error_code);
                                }
                                return false;
-                       } else {
 
+                       } else {
+                               unsigned int rcv_sound_status_value = 0;
                                if (!__ASM_get_sound_state(&rcv_sound_status_value, error_code)) {
                                        debug_error("failed to __ASM_get_sound_state(), error(%d)", *error_code);
                                }
 
                                debug_msg("[ASM_CB] Callback : TID(%ld), handle(%d)", asm_rcv_msg.instance_id, asm_rcv_msg.data.cmd_handle);
 
-                               asm_index = __ASM_find_index(asm_rcv_msg.data.cmd_handle);
+                               asm_index = __ASM_find_index_by_handle(asm_rcv_msg.data.cmd_handle);
                                if (asm_index == -1) {
-                                       *error_code = ERR_ASM_POLICY_INVALID_HANDLE;
+                                       *error_code = ERR_ASM_LOCAL_HANDLE_IS_INVALID;
                                        debug_error("Can not find index from instance_id %ld, handle %d", asm_rcv_msg.instance_id, asm_rcv_msg.data.cmd_handle);
                                        return false;
                                }
 
                                if (ASM_sound_handle[asm_index].asm_callback!=NULL) {
                                        debug_msg( "[ASM_CB(%p) START]", ASM_sound_handle[asm_index].asm_callback);
-                                       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);
+                                       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].user_data);
                                        debug_msg( "[ASM_CB END]");
                                } else {
                                        debug_msg("asm callback is null");
                                }
                        }
                        break;
-
                case ASM_COMMAND_PLAY:
                case ASM_COMMAND_NONE:
                case ASM_COMMAND_RESUME:
+                       ASM_sound_handle[asm_index].sound_state = sound_state;
+                       break;
                default:
                        break;
                }
-       /********************************************************************************************************/
-               debug_msg(" <<<<<<<<<<<<<<<< [AFTER]  Callback : Main Context >>>>>>>>>>>>>>>>>>>> \n");
 
        }
 
-
-       debug_msg(">>>> Event(%s), State(%s)", ASM_sound_events_str[sound_event],ASM_sound_state_str[sound_state]);
-
        debug_fleave();
 
        return true;
@@ -1128,12 +1659,11 @@ bool ASM_set_sound_state (const int asm_handle, ASM_sound_events_t sound_event,
 }
 
 EXPORT_API
-bool ASM_set_subsession (const int asm_handle, int subsession, int *error_code, int (*func)(void*,void*))
+bool ASM_set_subsession (const int asm_handle, ASM_sound_sub_sessions_t subsession, int resource, int *error_code)
 {
        int handle = 0;
        int asm_index = 0;
        int ret = 0;
-       unsigned int rcv_sound_status_value;
 
        debug_fenter();
 
@@ -1143,41 +1673,49 @@ bool ASM_set_subsession (const int asm_handle, int subsession, int *error_code,
        }
 
        if (asm_handle < 0 || asm_handle >= ASM_SERVER_HANDLE_MAX) {
-               *error_code = ERR_ASM_POLICY_INVALID_HANDLE;
+               *error_code = ERR_ASM_LOCAL_HANDLE_IS_INVALID;
                debug_error("Invalid handle(%d)", asm_handle);
                return false;
        }
 
+       if (subsession < ASM_SUB_SESSION_TYPE_VOICE || subsession >= ASM_SUB_SESSION_TYPE_MAX) {
+               *error_code = ERR_ASM_INVALID_PARAMETER;
+               debug_error("Invalid sub session type(%d)", subsession);
+               return false;
+       }
+
        handle = asm_handle;
 
-       asm_index = __ASM_find_index(handle);
+       asm_index = __ASM_find_index_by_handle(handle);
        if (asm_index == -1) {
                debug_error("Can not find index of %d", handle);
                return false;
        }
 
-       if (!__asm_construct_snd_msg(ASM_sound_handle[asm_index].asm_tid, ASM_sound_handle[asm_index].handle, subsession, ASM_REQUEST_SET_SUBSESSION, 0, 0, error_code)) {
+       if (!__asm_construct_snd_msg(ASM_sound_handle[asm_index].asm_tid, ASM_sound_handle[asm_index].handle, subsession, ASM_REQUEST_SET_SUBSESSION, ASM_sound_handle[asm_index].sound_state, resource, error_code)) {
                debug_error("failed to __asm_construct_snd_msg(), error(%d)", *error_code);
                return false;
        }
 
 
-       if (func) {
-               func (&asm_snd_msg, &asm_rcv_msg);
-       } else {
-               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;
-                       debug_error("failed to msgsnd(%d,%s)", errno, strerror(errno));
-                       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;
+               debug_error("failed to msgsnd(%d,%s)", errno, strerror(errno));
+               return false;
+       }
 
-               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;
-                       debug_error("failed to msgrcv(%d,%s)", errno, strerror(errno));
-                       return false;
-               }
+       NO_EINTR(ret = msgrcv(asm_rcv_msgid, (void *)&asm_rcv_msg, sizeof(asm_rcv_msg.data), ASM_sound_handle[asm_index].asm_tid, 0));
+       if (ret == -1) {
+               *error_code = ERR_ASM_MSG_QUEUE_RCV_ERROR;
+               debug_error("failed to msgrcv(%d,%s)", errno, strerror(errno));
+               return false;
+       }
+
+       if (asm_rcv_msg.data.source_request_id != ASM_REQUEST_SET_SUBSESSION) {
+               *error_code = ERR_ASM_MSG_QUEUE_RCV_ERROR;
+               debug_error("received msg is not valid, source_request_id(%d)", asm_rcv_msg.data.source_request_id);
+               return false;
        }
 
        /* TODO: Should check msg returned.....*/
@@ -1206,12 +1744,11 @@ bool ASM_set_subsession (const int asm_handle, int subsession, int *error_code,
 }
 
 EXPORT_API
-bool ASM_get_subsession (const int asm_handle, int *subsession_value, int *error_code, int (*func)(void*,void*))
+bool ASM_get_subsession (const int asm_handle, ASM_sound_sub_sessions_t *subsession, int *error_code)
 {
        int handle = 0;
        int asm_index = 0;
        int ret = 0;
-       unsigned int rcv_sound_status_value;
 
        debug_fenter();
 
@@ -1220,24 +1757,21 @@ bool ASM_get_subsession (const int asm_handle, int *subsession_value, int *error
                return false;
        }
 
-       /* TODO : Error Handling */
-#if 0
-       if (sound_event < 0 || sound_event > ASM_PRIORITY_MATRIX_MIN) {
-               debug_error("invalid sound event(%d)",sound_event);
-               *error_code = ERR_ASM_EVENT_IS_INVALID;
+       if (subsession == NULL) {
+               debug_error("subsession is null");
+               *error_code = ERR_ASM_INVALID_PARAMETER;
                return false;
        }
-#endif
 
        if (asm_handle < 0 || asm_handle >= ASM_SERVER_HANDLE_MAX) {
-               *error_code = ERR_ASM_POLICY_INVALID_HANDLE;
+               *error_code = ERR_ASM_LOCAL_HANDLE_IS_INVALID;
                debug_error("Invalid handle %d \n", asm_handle);
                return false;
        }
 
        handle = asm_handle;
 
-       asm_index = __ASM_find_index(handle);
+       asm_index = __ASM_find_index_by_handle(handle);
        if (asm_index == -1) {
                debug_error("Can not find index of %d", handle);
                return false;
@@ -1249,147 +1783,557 @@ bool ASM_get_subsession (const int asm_handle, int *subsession_value, int *error
        }
 
 
-       if (func) {
-               func (&asm_snd_msg, &asm_rcv_msg);
-       } else {
-               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;
-                       debug_error("failed to msgsnd(%d,%s)", errno, strerror(errno));
+       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;
+               debug_error("failed to msgsnd(%d,%s)", errno, strerror(errno));
+               return false;
+       }
+
+       NO_EINTR(ret = msgrcv(asm_rcv_msgid, (void *)&asm_rcv_msg, sizeof(asm_rcv_msg.data), ASM_sound_handle[asm_index].asm_tid, 0));
+       if (ret == -1) {
+               *error_code = ERR_ASM_MSG_QUEUE_RCV_ERROR;
+               debug_error("failed to msgrcv(%d,%s)", errno, strerror(errno));
+               return false;
+       }
+
+       if (asm_rcv_msg.data.source_request_id != ASM_REQUEST_GET_SUBSESSION) {
+               *error_code = ERR_ASM_MSG_QUEUE_RCV_ERROR;
+               debug_error("received msg is not valid, source_request_id(%d)", asm_rcv_msg.data.source_request_id);
+               return false;
+       }
+
+       *subsession = asm_rcv_msg.data.result_sound_command;
+
+       debug_msg(">>>> ASM_get_subsession with subsession value [%d]\n", *subsession);
+       debug_fleave();
+
+       return true;
+}
+
+EXPORT_API
+bool ASM_set_subevent (const int asm_handle, ASM_sound_sub_events_t subevent, int *error_code)
+{
+       int handle = 0;
+       int asm_index = 0;
+       int ret = 0;
+       ASM_sound_states_t sound_state = ASM_STATE_NONE;
+
+       debug_fenter();
+
+       if (error_code == NULL) {
+               debug_error("error_code is null");
+               return false;
+       }
+
+       if (asm_handle < 0 || asm_handle >= ASM_SERVER_HANDLE_MAX) {
+               *error_code = ERR_ASM_LOCAL_HANDLE_IS_INVALID;
+               debug_error("Invalid handle(%d)", asm_handle);
+               return false;
+       }
+
+       if (subevent < ASM_SUB_EVENT_NONE || subevent >= ASM_SUB_EVENT_MAX) {
+               *error_code = ERR_ASM_INVALID_PARAMETER;
+               debug_error("Invalid sub event(%d)", subevent);
+               return false;
+       }
+
+       handle = asm_handle;
+
+       asm_index = __ASM_find_index_by_handle(handle);
+       if (asm_index == -1) {
+               debug_error("Can not find index of %d", handle);
+               return false;
+       }
+
+       if (subevent == ASM_SUB_EVENT_NONE) {
+               sound_state = ASM_STATE_STOP;
+               if (!__asm_construct_snd_msg(ASM_sound_handle[asm_index].asm_tid, ASM_sound_handle[asm_index].handle, subevent, ASM_REQUEST_SET_SUBEVENT, sound_state, 0, error_code)) {
+                       debug_error("failed to __asm_construct_snd_msg() for ASM_SUB_EVENT_NONE, error(%d)", *error_code);
                        return false;
                }
-
-               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;
-                       debug_error("failed to msgrcv(%d,%s)", errno, strerror(errno));
+       } else if (subevent < ASM_SUB_EVENT_MAX) {
+               sound_state = ASM_STATE_PLAYING;
+               if (!__asm_construct_snd_msg(ASM_sound_handle[asm_index].asm_tid, ASM_sound_handle[asm_index].handle, subevent, ASM_REQUEST_SET_SUBEVENT, sound_state, 0, error_code)) {
+                       debug_error("failed to __asm_construct_snd_msg() for ASM_SUB_EVENT(%d), error(%d)", subevent, *error_code);
                        return false;
                }
        }
 
-       *subsession_value = asm_rcv_msg.data.result_sound_command;
 
-       debug_msg(">>>> ASM_get_subsession with subsession value [%d]\n", *subsession_value);
+       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;
+               debug_error("failed to msgsnd(%d,%s)", errno, strerror(errno));
+               return false;
+       }
+
+       if (subevent == ASM_SUB_EVENT_NONE) {
+               ASM_sound_handle[asm_index].sound_state = sound_state;
+               debug_msg("Sent SUB_EVENT_NONE, do not wait a returned message");
+               debug_fleave();
+               return true;
+       }
+
+       NO_EINTR(ret = msgrcv(asm_rcv_msgid, (void *)&asm_rcv_msg, sizeof(asm_rcv_msg.data), ASM_sound_handle[asm_index].asm_tid, 0));
+       if (ret == -1) {
+               *error_code = ERR_ASM_MSG_QUEUE_RCV_ERROR;
+               debug_error("failed to msgrcv(%d,%s)", errno, strerror(errno));
+               return false;
+       }
+
+       if (asm_rcv_msg.data.source_request_id != ASM_REQUEST_SET_SUBEVENT) {
+               *error_code = ERR_ASM_MSG_QUEUE_RCV_ERROR;
+               debug_error("received msg is not valid, source_request_id(%d)", asm_rcv_msg.data.source_request_id);
+               return false;
+       }
+
+       switch (asm_rcv_msg.data.result_sound_command) {
+       case ASM_COMMAND_PAUSE:
+       case ASM_COMMAND_STOP:
+               debug_msg( " <<<<<<<<<<<<<<<< Received command : %d (STOP(3)/PAUSE(4)) >>>>>>>>>>>>>>>>>>>>\n", asm_rcv_msg.data.result_sound_command);
+               if (handle == asm_rcv_msg.data.cmd_handle) {
+
+                       debug_msg("handle(%d) is same as asm_rcv_msg.data.cmd_handle", handle);
+
+                       asm_index = __ASM_find_index_by_handle(asm_rcv_msg.data.cmd_handle);
+                       if (asm_index == -1) {
+                               *error_code = ERR_ASM_LOCAL_HANDLE_IS_INVALID;
+                               debug_error( "Can not find index from instance_id %ld, handle %d", asm_rcv_msg.instance_id, asm_rcv_msg.data.cmd_handle);
+                               return false;
+                       }
+
+                       if (asm_rcv_msg.data.result_sound_command == ASM_COMMAND_PAUSE) {
+                               ASM_sound_handle[asm_index].sound_state = ASM_STATE_PAUSE;
+                       } else if (asm_rcv_msg.data.result_sound_command == ASM_COMMAND_STOP) {
+                               ASM_sound_handle[asm_index].sound_state = ASM_STATE_STOP;
+                       }
+
+                       if (asm_rcv_msg.data.error_code){
+                               *error_code = asm_rcv_msg.data.error_code;
+                               debug_warning("error code: %x",*error_code);
+                       }
+                       return false;
+
+               } else {
+                       unsigned int rcv_sound_status_value = 0;
+                       if (!__ASM_get_sound_state(&rcv_sound_status_value, error_code)) {
+                               debug_error("failed to __ASM_get_sound_state(), error(%d)", *error_code);
+                       }
+                       asm_index = __ASM_find_index_by_handle(asm_rcv_msg.data.cmd_handle);
+                       if (asm_index == -1) {
+                               *error_code = ERR_ASM_LOCAL_HANDLE_IS_INVALID;
+                               debug_error("Can not find index from instance_id %ld, handle %d", asm_rcv_msg.instance_id, asm_rcv_msg.data.cmd_handle);
+                               return false;
+                       }
+
+                       if (ASM_sound_handle[asm_index].asm_callback!=NULL) {
+                               debug_msg( "[ASM_CB(%p) START]", ASM_sound_handle[asm_index].asm_callback);
+                               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].user_data);
+                               debug_msg( "[ASM_CB END]");
+                       } else {
+                               debug_msg("asm callback is null");
+                       }
+               }
+               break;
+       case ASM_COMMAND_PLAY:
+       case ASM_COMMAND_NONE:
+       case ASM_COMMAND_RESUME:
+               ASM_sound_handle[asm_index].sound_state = sound_state;
+               break;
+       default:
+               break;
+       }
+
        debug_fleave();
 
        return true;
 }
 
 EXPORT_API
-void ASM_dump_sound_state()
+bool ASM_get_subevent (const int asm_handle, ASM_sound_sub_events_t *subevent, int *error_code)
 {
-       int error = 0;
+       int handle = 0;
+       int asm_index = 0;
        int ret = 0;
 
-       if (!__ASM_init_msg(&error) ) {
-               debug_error("failed to __ASM_init_msg(), error(%d)", error);
+       debug_fenter();
+
+       if (error_code == NULL) {
+               debug_error("error_code is null");
+               return false;
        }
-       if (!__asm_construct_snd_msg(getpid(), 0, 0, ASM_REQUEST_DUMP, ASM_STATE_NONE, ASM_RESOURCE_NONE, &error)) {
-               debug_error("failed to __asm_construct_snd_msg(), error(%d)", error);
-               return;
+
+       if (subevent == NULL) {
+               debug_error("subevent is null");
+               *error_code = ERR_ASM_INVALID_PARAMETER;
+               return false;
        }
+
+       if (asm_handle < 0 || asm_handle >= ASM_SERVER_HANDLE_MAX) {
+               *error_code = ERR_ASM_LOCAL_HANDLE_IS_INVALID;
+               debug_error("Invalid handle %d \n", asm_handle);
+               return false;
+       }
+
+       handle = asm_handle;
+
+       asm_index = __ASM_find_index_by_handle(handle);
+       if (asm_index == -1) {
+               debug_error("Can not find index of %d", handle);
+               return false;
+       }
+
+       if (!__asm_construct_snd_msg(ASM_sound_handle[asm_index].asm_tid, ASM_sound_handle[asm_index].handle, 0, ASM_REQUEST_GET_SUBEVENT, 0, 0, error_code)) {
+               debug_error("failed to __asm_construct_snd_msg(), error(%d)", *error_code);
+               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;
                debug_error("failed to msgsnd(%d,%s)", errno, strerror(errno));
-               return;
+               return false;
+       }
+
+       NO_EINTR(ret = msgrcv(asm_rcv_msgid, (void *)&asm_rcv_msg, sizeof(asm_rcv_msg.data), ASM_sound_handle[asm_index].asm_tid, 0));
+       if (ret == -1) {
+               *error_code = ERR_ASM_MSG_QUEUE_RCV_ERROR;
+               debug_error("failed to msgrcv(%d,%s)", errno, strerror(errno));
+               return false;
        }
+
+       if (asm_rcv_msg.data.source_request_id != ASM_REQUEST_GET_SUBEVENT) {
+               *error_code = ERR_ASM_MSG_QUEUE_RCV_ERROR;
+               debug_error("received msg is not valid, source_request_id(%d)", asm_rcv_msg.data.source_request_id);
+               return false;
+       }
+
+       *subevent = asm_rcv_msg.data.result_sound_command;
+
+       debug_msg(">>>> ASM_get_subevent with subevent value [%d]\n", *subevent);
+       debug_fleave();
+
+       return true;
 }
 
 
-void ASM_ask_sound_policy(ASM_sound_events_t playing_sound, ASM_sound_events_t request_sound,
-                               ASM_sound_cases_t *sound_policy)
+EXPORT_API
+bool ASM_set_session_option (const int asm_handle, int option_flags, int *error_code)
 {
-}
+       int handle = 0;
+       int asm_index = 0;
+       int ret = 0;
+       ASM_sound_states_t sound_state = ASM_STATE_NONE;
 
+       debug_fenter();
 
-#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;
+       if (error_code == NULL) {
+               debug_error("error_code is null");
+               return false;
+       }
+
+       if (asm_handle < 0 || asm_handle >= ASM_SERVER_HANDLE_MAX) {
+               *error_code = ERR_ASM_LOCAL_HANDLE_IS_INVALID;
+               debug_error("Invalid handle(%d)", asm_handle);
+               return false;
+       }
+
+       if (option_flags < 0) {
+               *error_code = ERR_ASM_INVALID_PARAMETER;
+               debug_error("Invalid option_flags(%x)", option_flags);
+               return false;
+       }
+
+       handle = asm_handle;
+
+       asm_index = __ASM_find_index_by_handle(handle);
+       if (asm_index == -1) {
+               debug_error("Can not find index of %d", handle);
+               return false;
+       }
 
-void __ASM_unregister_sound(int index)
+       if (!__asm_construct_snd_msg(ASM_sound_handle[asm_index].asm_tid, ASM_sound_handle[asm_index].handle, option_flags, ASM_REQUEST_SET_SESSION_OPTIONS, sound_state, 0, error_code)) {
+               debug_error("failed to __asm_construct_snd_msg() for option_flags, error(%d)", *error_code);
+               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;
+               debug_error("failed to msgsnd(%d,%s)", errno, strerror(errno));
+               return false;
+       }
+
+       NO_EINTR(ret = msgrcv(asm_rcv_msgid, (void *)&asm_rcv_msg, sizeof(asm_rcv_msg.data), ASM_sound_handle[asm_index].asm_tid, 0));
+       if (ret == -1) {
+               *error_code = ERR_ASM_MSG_QUEUE_RCV_ERROR;
+               debug_error("failed to msgrcv(%d,%s)", errno, strerror(errno));
+               return false;
+       }
+
+       if (asm_rcv_msg.data.source_request_id != ASM_REQUEST_SET_SESSION_OPTIONS) {
+               *error_code = ERR_ASM_MSG_QUEUE_RCV_ERROR;
+               debug_error("received msg is not valid, source_request_id(%d)", asm_rcv_msg.data.source_request_id);
+               return false;
+       }
+
+       switch (asm_rcv_msg.data.result_sound_command) {
+       case ASM_COMMAND_PAUSE:
+       case ASM_COMMAND_STOP:
+               debug_msg( " <<<<<<<<<<<<<<<< Received command : %d (STOP(3)/PAUSE(4)) >>>>>>>>>>>>>>>>>>>>\n", asm_rcv_msg.data.result_sound_command);
+               if (handle == asm_rcv_msg.data.cmd_handle) {
+
+                       debug_msg("handle(%d) is same as asm_rcv_msg.data.cmd_handle", handle);
+
+                       asm_index = __ASM_find_index_by_handle(asm_rcv_msg.data.cmd_handle);
+                       if (asm_index == -1) {
+                               *error_code = ERR_ASM_LOCAL_HANDLE_IS_INVALID;
+                               debug_error( "Can not find index from instance_id %ld, handle %d", asm_rcv_msg.instance_id, asm_rcv_msg.data.cmd_handle);
+                               return false;
+                       }
+
+                       if (asm_rcv_msg.data.result_sound_command == ASM_COMMAND_PAUSE) {
+                               ASM_sound_handle[asm_index].sound_state = ASM_STATE_PAUSE;
+                       } else if (asm_rcv_msg.data.result_sound_command == ASM_COMMAND_STOP) {
+                               ASM_sound_handle[asm_index].sound_state = ASM_STATE_STOP;
+                       }
+
+                       if (asm_rcv_msg.data.error_code){
+                               *error_code = asm_rcv_msg.data.error_code;
+                               debug_warning("error code: %x",*error_code);
+                       }
+                       return false;
+
+               }
+               break;
+       case ASM_COMMAND_PLAY:
+               ASM_sound_handle[asm_index].option_flags = option_flags;
+               break;
+       default:
+               break;
+       }
+
+       debug_fleave();
+
+       return true;
+}
+
+EXPORT_API
+bool ASM_get_session_option (const int asm_handle, int *option_flags, int *error_code)
 {
-       int error_code = 0;
+       int handle = 0;
+       int asm_index = 0;
        int ret = 0;
-       unsigned int sound_status_value;
 
        debug_fenter();
 
-       debug_msg(" <<<< Event(%s), Index(%d)", ASM_sound_events_str[ASM_sound_handle[index].sound_event], index);
+       if (error_code == NULL) {
+               debug_error("error_code is null");
+               return false;
+       }
 
-       if (!__ASM_get_sound_state(&sound_status_value, &error_code)) {
-               debug_error("failed to __ASM_get_sound_state()", error_code);
+       if (option_flags == NULL) {
+               debug_error("option_flags is null");
+               *error_code = ERR_ASM_INVALID_PARAMETER;
+               return false;
        }
-       if (!__ASM_set_sound_state(ASM_sound_handle[index].sound_event, ASM_STATE_NONE, &error_code)) {
-               debug_error("failed to __ASM_set_sound_state(NONE)", error_code);
+
+       if (asm_handle < 0 || asm_handle >= ASM_SERVER_HANDLE_MAX) {
+               *error_code = ERR_ASM_LOCAL_HANDLE_IS_INVALID;
+               debug_error("Invalid handle %d \n", asm_handle);
+               return false;
        }
 
-       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)) {
-               debug_error("failed to __asm_construct_snd_msg(), error(%d)", error_code);
+       handle = asm_handle;
+
+       asm_index = __ASM_find_index_by_handle(handle);
+       if (asm_index == -1) {
+               debug_error("Can not find index of %d", handle);
+               return false;
+       }
+
+       if (!__asm_construct_snd_msg(ASM_sound_handle[asm_index].asm_tid, ASM_sound_handle[asm_index].handle, 0, ASM_REQUEST_GET_SESSION_OPTIONS, 0, 0, error_code)) {
+               debug_error("failed to __asm_construct_snd_msg(), error(%d)", *error_code);
+               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;
                debug_error("failed to msgsnd(%d,%s)", errno, strerror(errno));
+               return false;
        }
 
-       __ASM_destroy_callback(index);
+       NO_EINTR(ret = msgrcv(asm_rcv_msgid, (void *)&asm_rcv_msg, sizeof(asm_rcv_msg.data), ASM_sound_handle[asm_index].asm_tid, 0));
+       if (ret == -1) {
+               *error_code = ERR_ASM_MSG_QUEUE_RCV_ERROR;
+               debug_error("failed to msgrcv(%d,%s)", errno, strerror(errno));
+               return false;
+       }
 
-       debug_msg(" >>>> Event(%s)", ASM_sound_events_str[ASM_sound_handle[index].sound_event]);
+       if (asm_rcv_msg.data.source_request_id != ASM_REQUEST_GET_SESSION_OPTIONS) {
+               *error_code = ERR_ASM_MSG_QUEUE_RCV_ERROR;
+               debug_error("received msg is not valid, source_request_id(%d)", asm_rcv_msg.data.source_request_id);
+               return false;
+       }
 
-       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;
+       if (asm_rcv_msg.data.result_sound_command == ASM_COMMAND_STOP) {
+               *error_code = asm_rcv_msg.data.error_code;
+               debug_error("received handle is not valid");
+               return false;
+       }
+
+       *option_flags = asm_rcv_msg.data.option_flags;
+       if (ASM_sound_handle[asm_index].option_flags != *option_flags) {
+               debug_error("received flag(%x) from server is not same as local's(%x)", *option_flags, ASM_sound_handle[asm_index].option_flags);
+               return false;
+       }
+
+       debug_msg(">>>> option flags [%x]\n", *option_flags);
 
        debug_fleave();
+
+       return true;
 }
 
+EXPORT_API
+bool ASM_reset_resumption_info(const int asm_handle, int *error_code)
+{
+       int handle = 0;
+       int asm_index = 0;
+       int ret = 0;
+
+       debug_fenter();
 
-void __ASM_signal_handler(int signo)
+       if (error_code == NULL) {
+               debug_error("error_code is null");
+               return false;
+       }
+
+       if (asm_handle < 0 || asm_handle >= ASM_SERVER_HANDLE_MAX) {
+               *error_code = ERR_ASM_LOCAL_HANDLE_IS_INVALID;
+               debug_error("Invalid handle %d \n", asm_handle);
+               return false;
+       }
+
+       handle = asm_handle;
+
+       asm_index = __ASM_find_index_by_handle(handle);
+       if (asm_index == -1) {
+               debug_error("Can not find index of %d", handle);
+               return false;
+       }
+
+       if (!__asm_construct_snd_msg(ASM_sound_handle[asm_index].asm_tid, ASM_sound_handle[asm_index].handle, 0, ASM_REQUEST_RESET_RESUME_TAG, 0, 0, error_code)) {
+               debug_error("failed to __asm_construct_snd_msg(), error(%d)", *error_code);
+               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;
+               debug_error("failed to msgsnd(%d,%s)", errno, strerror(errno));
+               return false;
+       }
+
+       NO_EINTR(ret = msgrcv(asm_rcv_msgid, (void *)&asm_rcv_msg, sizeof(asm_rcv_msg.data), ASM_sound_handle[asm_index].asm_tid, 0));
+       if (ret == -1) {
+               *error_code = ERR_ASM_MSG_QUEUE_RCV_ERROR;
+               debug_error("failed to msgrcv(%d,%s)", errno, strerror(errno));
+               return false;
+       }
+
+       if (asm_rcv_msg.data.source_request_id != ASM_REQUEST_RESET_RESUME_TAG) {
+               *error_code = ERR_ASM_MSG_QUEUE_RCV_ERROR;
+               debug_error("received msg is not valid, source_request_id(%d)", asm_rcv_msg.data.source_request_id);
+               return false;
+       }
+
+       switch (asm_rcv_msg.data.result_sound_command) {
+       case ASM_COMMAND_PLAY:
+               debug_msg(" >>>> reset information of resumption successfully");
+               break;
+       default:
+               debug_error("received message is abnormal..result_sound_command(%d) from ASM server", asm_rcv_msg.data.result_sound_command);
+               *error_code = ERR_ASM_MSG_QUEUE_RCV_ERROR;
+               return false;
+       }
+
+       debug_leave();
+
+       return true;
+}
+
+EXPORT_API
+void ASM_dump_sound_state()
+{
+       int error = 0;
+       int ret = 0;
+
+       if (!__ASM_init_msg(&error) ) {
+               debug_error("failed to __ASM_init_msg(), error(%d)", error);
+       }
+       if (!__asm_construct_snd_msg(getpid(), 0, 0, ASM_REQUEST_DUMP, ASM_STATE_NONE, ASM_RESOURCE_NONE, &error)) {
+               debug_error("failed to __asm_construct_snd_msg(), error(%d)", error);
+               return;
+       }
+       NO_EINTR(ret = msgsnd(asm_snd_msgid, (void *)&asm_snd_msg, sizeof(asm_snd_msg.data), 0));
+       if (ret == -1) {
+               debug_error("failed to msgsnd(%d,%s)", errno, strerror(errno));
+               return;
+       }
+}
+
+
+#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;
+
+static void __ASM_signal_handler(int signo)
 {
        int exit_pid = 0;
        int asm_index = 0;
-       int run_emergency_exit = 0;
+
+       debug_warning("ENTER, sig.num(%d)",signo);
+
+       /* signal block -------------- */
+       sigset_t old_mask, all_mask;
+       sigfillset(&all_mask);
+       sigprocmask(SIG_BLOCK, &all_mask, &old_mask);
 
        for (asm_index=0 ;asm_index < ASM_HANDLE_MAX; asm_index++) {
-               if (ASM_sound_handle[asm_index].is_used == true) {
+               if (ASM_sound_handle[asm_index].is_used == true &&
+                               ASM_sound_handle[asm_index].is_for_watching == false) {
                        exit_pid = ASM_sound_handle[asm_index].asm_tid;
                        if (exit_pid == asmgettid()) {
-                               run_emergency_exit = 1;
-                               break;
+                               asm_snd_msg.instance_id = exit_pid;
+                               asm_snd_msg.data.handle = ASM_sound_handle[asm_index].handle;
+                               asm_snd_msg.data.request_id = ASM_REQUEST_EMERGENT_EXIT;
+                               asm_snd_msg.data.sound_event = ASM_sound_handle[asm_index].sound_event;
+                               asm_snd_msg.data.sound_state = ASM_sound_handle[asm_index].sound_state;
+
+                               if (msgsnd(asm_snd_msgid, (void *)&asm_snd_msg, sizeof(asm_snd_msg.data), 0) < 0 ) {
+                                       debug_msg( "msgsnd() failed, tid=%ld, reqid=%d, handle=0x%x, state=0x%x event=%d size=%d",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) {
+                                               debug_warning("msgsnd() succeed");
+                                       } else {
+                                               debug_error("msgsnd() retry also failed");
+                                       }
+                               }
                        }
                }
        }
 
-       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) {
-                       debug_error("msgsnd() failed, tid=%ld, reqid=%d, handle=0x%x, state=0x%x event=%d size=%d",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) {
-                               debug_msg("msgsnd() succeed");
-                       } else {
-                               debug_error("msgsnd() retry also failed");
-                       }
-               }
-
-               sigprocmask(SIG_SETMASK, &old_mask, NULL);
-               /* signal unblock ------------ */
-       }
+       sigprocmask(SIG_SETMASK, &old_mask, NULL);
+       /* signal unblock ------------ */
 
        switch (signo) {
        case SIGINT:
@@ -1419,18 +2363,25 @@ void __ASM_signal_handler(int signo)
        default:
                break;
        }
+
+       debug_warning("LEAVE");
 }
 
 #endif
-void __attribute__((constructor)) __ASM_init_module(void)
+static 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;
+       int asm_index = 0;
 
        debug_fenter();
 
+       for (asm_index = 0; asm_index < ASM_HANDLE_MAX; asm_index++) {
+               ASM_sound_handle[asm_index].handle = ASM_HANDLE_INIT_VAL;
+       }
+
        sigemptyset(&ASM_action.sa_mask);
 
        sigaction(SIGINT, &ASM_action, &ASM_int_old_action);
@@ -1445,7 +2396,7 @@ void __attribute__((constructor)) __ASM_init_module(void)
 }
 
 
-void __attribute__((destructor)) __ASM_fini_module(void)
+static void __attribute__((destructor)) __ASM_fini_module(void)
 {
        debug_fenter();
 
@@ -1453,37 +2404,41 @@ void __attribute__((destructor)) __ASM_fini_module(void)
 
        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) {
+               if (ASM_sound_handle[asm_index].is_used == true &&
+                               ASM_sound_handle[asm_index].is_for_watching == false) {
                        exit_pid = ASM_sound_handle[asm_index].asm_tid;
                        if (exit_pid == asmgettid()) {
-                               run_emergency_exit = 1;
-                               break;
+                               asm_snd_msg.instance_id = exit_pid;
+                               asm_snd_msg.data.handle = ASM_sound_handle[asm_index].handle;
+                               asm_snd_msg.data.request_id = ASM_REQUEST_EMERGENT_EXIT;
+                               asm_snd_msg.data.sound_event = ASM_sound_handle[asm_index].sound_event;
+                               asm_snd_msg.data.sound_state = ASM_sound_handle[asm_index].sound_state;
+
+                               if (msgsnd(asm_snd_msgid, (void *)&asm_snd_msg, sizeof(asm_snd_msg.data), 0) < 0 ) {
+                                       debug_msg( "msgsnd() failed, tid=%ld, reqid=%d, handle=0x%x, state=0x%x event=%d size=%d",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) {
+                                               debug_warning("msgsnd() succeed");
+                                       } else {
+                                               debug_error("msgsnd() retry also failed");
+                                       }
+                               }
                        }
                }
        }
 
-       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;
+#endif
 
-               if (msgsnd(asm_snd_msgid, (void *)&asm_snd_msg, sizeof(asm_snd_msg.data), 0) < 0 ) {
-                       debug_msg( "msgsnd() failed, tid=%ld, reqid=%d, handle=0x%x, state=0x%x event=%d size=%d",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) {
-                               debug_msg("msgsnd() succeed");
-                       } else {
-                               debug_error("msgsnd() retry also failed");
-                       }
-               }
+       if (g_asm_thread) {
+               g_main_loop_quit(g_asm_loop);
+               g_thread_join(g_asm_thread);
+               debug_log("after thread join");
+               g_main_loop_unref(g_asm_loop);
+               g_asm_thread = NULL;
        }
-#endif
        sigaction(SIGINT, &ASM_int_old_action, NULL);
        sigaction(SIGABRT, &ASM_abrt_old_action, NULL);
        sigaction(SIGSEGV, &ASM_segv_old_action, NULL);
index 238a2b0e0701aad60d2cf493abfd650351d9ca96..88b8f323326e1e74f798268b4ba2e9ddc1f0b97c 100644 (file)
@@ -7,42 +7,63 @@
 
 GMainLoop *g_loop;
 GThreadPool* g_pool;
-gint asm_handle = -1;
-gint event_type = ASM_EVENT_NONE;
-gint asm_state = ASM_STATE_NONE;
+gint g_asm_handle = -1;
+gint g_event_type = ASM_EVENT_NONE;
+gint g_sub_event_type = ASM_SUB_EVENT_NONE;
+gint g_sub_session_type = ASM_SUB_SESSION_TYPE_VOICE;
+gint g_asm_state = ASM_STATE_NONE;
 ASM_resource_t g_resource = ASM_RESOURCE_NONE;
 gboolean thread_run;
 
 ASM_cb_result_t
 asm_callback (int handle, ASM_event_sources_t event_src, ASM_sound_commands_t command, unsigned int sound_status, void* cb_data)
 {
-       g_print ("\n[%s][%d] handle = %d, event src = %d, command = %d, sound_state = %d\n\n", __func__, __LINE__, handle ,event_src, command, sound_status);
-       return ASM_CB_RES_IGNORE;
+       g_print ("\n[%s] handle = %d, event src = %d, command = %d, sound_state = %d, cb_data = %p\n\n",
+                                               __func__, handle, event_src, command, sound_status, cb_data);
+       return ASM_CB_RES_NONE;
+}
+
+ASM_cb_result_t
+watch_callback (int handle, ASM_sound_events_t sound_event, ASM_sound_states_t sound_state, void* cb_data)
+{
+       g_print ("\n[%s] handle = %d, sound_event = %d, sound_state = %d, cb_data = %p\n\n",
+                                               __func__, handle, sound_event, sound_state, cb_data);
+       return ASM_CB_RES_NONE;
 }
 
 void print_menu_main(void)
 {
-       printf("========ASM Testsuite======\n");
-       printf(" r. Register ASM\n");
-       printf(" s. Set state\n");
-       printf(" u. Unregister ASM\n");
+       printf("===============ASM Testsuite==============\n");
+       printf(" a. Register ASM handle\n");
+       printf(" o. Set options\n");
+       printf(" r. Set resource\n");
+       printf(" s. Set state\t\t");
+       printf(" x. Get state\n");
+       printf(" d. Set sub-event\t");
+       printf(" c. Get sub-event\n");
+       printf(" f. Set sub-session\t");
+       printf(" v. Get sub-session\n");
+       printf(" z. Unregister ASM handle\n");
+       printf(" j. Set watcher\n");
+       printf(" m. Unset watcher\n");
+       printf(" w. Reset resume tag\n");
        printf(" q. Quit\n");
-       printf("============================\n");
+       printf("==========================================\n");
        printf(">> ");
 }
 
 void menu_unregister(void)
 {
        gint errorcode = 0;
-       if(asm_handle == -1) {
-               g_print("Register sound first..\n\n");
+       if(g_asm_handle == -1) {
+               g_print("Register handle first..\n\n");
                return;
        }
-       if( !ASM_unregister_sound(asm_handle, event_type, &errorcode) ) {
-               g_print("Unregister sound failed 0x%X\n\n", errorcode);
+       if( !ASM_unregister_sound(g_asm_handle, g_event_type, &errorcode) ) {
+               g_print("ASM_unregister_sound() failed 0x%X\n\n", errorcode);
        } else {
                g_print("Unregister success..\n\n");
-               asm_handle = -1;
+               g_asm_handle = -1;
        }
 }
 
@@ -52,31 +73,27 @@ void menu_register(void)
        int input = 0;
        gint errorcode = 0;
        gint pid = -1;
-       g_resource = ASM_RESOURCE_NONE;
 
        while(1) {
                printf("==========select ASM event=============\n");
-               printf(" 0. ASM_EVENT_SHARE_MMPLAYER \n");
-               printf(" 1. ASM_EVENT_SHARE_MMCAMCORDER\n");
-               printf(" 2. ASM_EVENT_SHARE_MMSOUND\n");
-               printf(" 3. ASM_EVENT_SHARE_OPENAL\n");
-               printf(" 4. ASM_EVENT_SHARE_AVSYSTEM\n");
-               printf(" 5. ASM_EVENT_SHARE_FMRADIO\n");
-               printf(" 6. ASM_EVENT_EXCLUSIVE_MMPLAYER\n");
-               printf(" 7. ASM_EVENT_EXCLUSIVE_MMCAMCORDER\n");
-               printf(" 8. ASM_EVENT_EXCLUSIVE_MMSOUND\n");
-               printf(" 9. ASM_EVENT_EXCLUSIVE_OPENAL\n");
-               printf(" a. ASM_EVENT_EXCLUSIVE_AVSYSTEM\n");
-               printf(" b. ASM_EVENT_EXCLUSIVE_FMRADIO\n");
-               printf(" c. ASM_EVENT_NOTIFY\n");
-               printf(" d. ASM_EVENT_CALL\n");
-               printf(" e. ASM_EVENT_EARJACK_UNPLUG\n");
-               printf(" f. ASM_EVENT_ALARM\n");
-               printf(" g. ASM_EVENT_VIDEOCALL\n");
-               printf(" h. ASM_EVENT_MONITOR\n");
-               printf(" i. ASM_EVENT_RICHCALL\n");
-               printf(" j. ASM_EVENT_EMERGENCY\n");
-               printf(" k. ASM_EVENT_EXCLUSIVE_RESOURCE\n");
+               printf(" 0. ASM_EVENT_MEDIA_MMPLAYER \n");
+               printf(" 1. ASM_EVENT_MEDIA_MMCAMCORDER \n");
+               printf(" 2. ASM_EVENT_MEDIA_MMSOUND\n");
+               printf(" 3. ASM_EVENT_MEDIA_OPENAL\n");
+               printf(" 4. ASM_EVENT_MEDIA_FMRADIO\n");
+               printf(" 5. ASM_EVENT_MEDIA_WEBKIT\n");
+               printf(" 6. ASM_EVENT_NOTIFY\n");
+               printf(" 7. ASM_EVENT_ALARM\n");
+               printf(" 8. ASM_EVENT_EARJACK_UNPLUG\n");
+               printf(" 9. ASM_EVENT_CALL\n");
+               printf(" a. ASM_EVENT_VIDEOCALL\n");
+               printf(" b. ASM_EVENT_VOIP\n");
+               printf(" c. ASM_EVENT_MONITOR\n");
+               printf(" d. ASM_EVENT_EMERGENCY\n");
+               printf(" e. ASM_EVENT_EXCLUSIVE_RESOURCE\n");
+               printf(" f. ASM_EVENT_VOICE_RECOGNITION\n");
+               printf(" g. ASM_EVENT_MMCAMCORDER_AUDIO\n");
+               printf(" h. ASM_EVENT_MMCAMCORDER_VIDEO\n");
                printf(" q. Back to main menu\n");
                printf("=======================================\n");
                printf(">> ");
@@ -87,94 +104,200 @@ void menu_register(void)
                }
                switch (key) {
                        case '0':
-                               event_type = ASM_EVENT_SHARE_MMPLAYER;
+                               g_event_type = ASM_EVENT_MEDIA_MMPLAYER;
                                break;
                        case '1':
-                               event_type = ASM_EVENT_SHARE_MMCAMCORDER;
-                               g_resource = ASM_RESOURCE_CAMERA;
+                               g_event_type = ASM_EVENT_MEDIA_MMCAMCORDER;
                                break;
                        case '2':
-                               event_type = ASM_EVENT_SHARE_MMSOUND;
+                               g_event_type = ASM_EVENT_MEDIA_MMSOUND;
                                break;
                        case '3':
-                               event_type = ASM_EVENT_SHARE_OPENAL;
+                               g_event_type = ASM_EVENT_MEDIA_OPENAL;
                                break;
                        case '4':
-                               event_type = ASM_EVENT_SHARE_AVSYSTEM;
+                               g_event_type = ASM_EVENT_MEDIA_FMRADIO;
                                break;
                        case '5':
-                               event_type = ASM_EVENT_SHARE_FMRADIO;
+                               g_event_type = ASM_EVENT_MEDIA_WEBKIT;
                                break;
                        case '6':
-                               event_type = ASM_EVENT_EXCLUSIVE_MMPLAYER;
+                               g_event_type = ASM_EVENT_NOTIFY;
                                break;
                        case '7':
-                               event_type = ASM_EVENT_EXCLUSIVE_MMCAMCORDER;
-                               g_resource = ASM_RESOURCE_CAMERA;
+                               g_event_type = ASM_EVENT_ALARM;
                                break;
                        case '8':
-                               event_type = ASM_EVENT_EXCLUSIVE_MMSOUND;
+                               g_event_type = ASM_EVENT_EARJACK_UNPLUG;
                                break;
                        case '9':
-                               event_type = ASM_EVENT_EXCLUSIVE_OPENAL;
+                               g_event_type = ASM_EVENT_CALL;
                                break;
                        case 'a':
-                               event_type = ASM_EVENT_EXCLUSIVE_AVSYSTEM;
+                               g_event_type = ASM_EVENT_VIDEOCALL;
                                break;
                        case 'b':
-                               event_type = ASM_EVENT_EXCLUSIVE_FMRADIO;
+                               g_event_type = ASM_EVENT_VOIP;
                                break;
                        case 'c':
-                               event_type = ASM_EVENT_NOTIFY;
+                               g_event_type = ASM_EVENT_MONITOR;
                                break;
                        case 'd':
-                               event_type = ASM_EVENT_CALL;
+                               g_event_type = ASM_EVENT_EMERGENCY;
                                break;
                        case 'e':
-                               event_type = ASM_EVENT_EARJACK_UNPLUG;
+                               g_event_type = ASM_EVENT_EXCLUSIVE_RESOURCE;
                                break;
                        case 'f':
-                               event_type = ASM_EVENT_ALARM;
+                               g_event_type = ASM_EVENT_VOICE_RECOGNITION;
                                break;
                        case 'g':
-                               event_type = ASM_EVENT_VIDEOCALL;
-                               g_resource = ASM_RESOURCE_CAMERA;
+                               g_event_type = ASM_EVENT_MMCAMCORDER_AUDIO;
                                break;
                        case 'h':
-                               event_type = ASM_EVENT_MONITOR;
-                               break;
-                       case 'i':
-                               event_type = ASM_EVENT_RICH_CALL;
-                               g_resource = ASM_RESOURCE_CAMERA;
-                               break;
-                       case 'j':
-                               event_type = ASM_EVENT_EMERGENCY;
-                               break;
-                       case 'k':
-                               event_type = ASM_EVENT_EXCLUSIVE_RESOURCE;
-                               /* temporarily set it ASM_RESOURCE_CAMERA */
-                               g_resource = ASM_RESOURCE_CAMERA;
+                               g_event_type = ASM_EVENT_MMCAMCORDER_VIDEO;
                                break;
                        case 'q':
                                return;
                        default :
                                g_print("select event again...\n");
-                               event_type = -1;
+                               g_event_type = -1;
                                break;
                }
-               if (event_type == -1) {
+               if (g_event_type == -1) {
                        continue;
                }
-               if( ! ASM_register_sound(pid, &asm_handle, event_type, ASM_STATE_NONE, asm_callback, NULL, g_resource, &errorcode)) {
+               if (g_asm_handle != -1) {
+                       g_print("Unregister handle first..\n\n");
+                       break;
+               }
+               if( ! ASM_register_sound(pid, &g_asm_handle, g_event_type, ASM_STATE_NONE, asm_callback, NULL, g_resource, &errorcode)) {
                        g_print("ASM_register_sound() failed, error = %x\n\n", errorcode);
                        break;
                } else {
-                       g_print("ASM_register_sound() success, ASM handle=%d, ASM_EVENT=%d, ASM_RESOURCE=%d, ASM_STATE_NONE.\n\n", asm_handle, event_type, g_resource);
+                       g_print("ASM_register_sound() success, ASM handle=%d, ASM_EVENT=%d, ASM_RESOURCE=%d, ASM_STATE_NONE.\n\n", g_asm_handle, g_event_type, g_resource);
                        break;
                }
        }
 }
 
+void menu_set_options(void)
+{
+       char key = 0;
+       int input = 0;
+       int options = 0;
+       gint errorcode = 0;
+
+       if( ! ASM_get_session_option(g_asm_handle, &options, &errorcode)) {
+               g_print("ASM_get_session_option() failed, error = %x\n\n", errorcode);
+       }
+       while(1) {
+               printf("===========ASM SESSION OPTION===========\n");
+               printf(">> current(0x%x)\n", options);
+               printf(" 0. ASM_SESSION_OPTION_PAUSE_OTHERS\n");
+               printf(" 1. ASM_SESSION_OPTION_UNINTERRUTIBLE\n");
+               printf(" 2. ASM_SESSION_OPTION_RESUME_BY_MEDIA_PAUSED\n");
+               printf(" r. Reset ASM SESSION OPTION\n");
+               printf(" q. Back to main menu\n");
+               printf("========================================\n");
+               printf(">> ");
+               while( (input = getchar())!= '\n' && input != EOF) {
+                       key = (char)input;
+               }
+
+               switch (key) {
+                       case '0':
+                               options |= ASM_SESSION_OPTION_PAUSE_OTHERS;
+                               break;
+                       case '1':
+                               options |= ASM_SESSION_OPTION_UNINTERRUPTIBLE;
+                               break;
+                       case '2':
+                               options |= ASM_SESSION_OPTION_RESUME_BY_MEDIA_PAUSED;
+                               break;
+                       case 'r':
+                               options = 0;
+                               break;
+                       case 'q':
+                               return;
+                       default :
+                               g_print("select ASM session option again...\n");
+                               options = -1;
+                               break;
+               }
+               if (options == -1) {
+                       continue;
+               }
+               if( ! ASM_set_session_option(g_asm_handle, options, &errorcode)) {
+                       g_print("ASM_get_session_option() failed, error = %x\n\n", errorcode);
+               }
+       }
+}
+
+void menu_set_resource(void)
+{
+       char key = 0;
+       int input = 0;
+       while(1) {
+               printf("==========ASM RESOURCE==========\n");
+               printf(">> current(0x%x)\n", g_resource);
+               printf(" 0. ASM_RESOURCE_CAMERA\n");
+               printf(" 1. ASM_RESOURCE_VIDEO_OVERLAY\n");
+               printf(" 2. ASM_RESOURCE_STREAMING\n");
+               printf(" 3. ASM_RESOURCE_HW_DECODER\n");
+               printf(" 4. ASM_RESOURCE_HW_ENCODER\n");
+               printf(" 5. ASM_RESOURCE_RADIO_TUNNER\n");
+               printf(" 6. ASM_RESOURCE_TV_TUNNER\n");
+               printf(" 9. ASM_RESOURCE_VOICECONTROL\n");
+               printf(" r. Reset ASM RESOURCE\n");
+               printf(" q. Back to main menu\n");
+               printf("================================\n");
+               printf(">> ");
+               while( (input = getchar())!= '\n' && input != EOF) {
+                       key = (char)input;
+               }
+
+               switch (key) {
+                       case '0':
+                               g_resource |= ASM_RESOURCE_CAMERA;
+                               break;
+                       case '1':
+                               g_resource |= ASM_RESOURCE_VIDEO_OVERLAY;
+                               break;
+                       case '2':
+                               g_resource |= ASM_RESOURCE_STREAMING;
+                               break;
+                       case '3':
+                               g_resource |= ASM_RESOURCE_HW_DECODER;
+                               break;
+                       case '4':
+                               g_resource |= ASM_RESOURCE_HW_ENCODER;
+                               break;
+                       case '5':
+                               g_resource |= ASM_RESOURCE_RADIO_TUNNER;
+                               break;
+                       case '6':
+                               g_resource |= ASM_RESOURCE_TV_TUNNER;
+                               break;
+                       case '9':
+                               g_resource |= ASM_RESOURCE_VOICECONTROL;
+                               break;
+                       case 'r':
+                               g_resource = ASM_RESOURCE_NONE;
+                               return;
+                       case 'q':
+                               return;
+                       default :
+                               g_print("select ASM resource again...\n");
+                               g_resource = -1;
+                               break;
+               }
+               if (g_resource == -1) {
+                       continue;
+               }
+       }
+}
+
 void menu_set_state(void)
 {
        int ret = 0;
@@ -182,13 +305,67 @@ void menu_set_state(void)
        int input = 0;
        while(1) {
                printf("==========ASM state==========\n");
-               printf(" 0. ASM_STATE_IGNORE\n");
-               printf(" 1. ASM_STATE_NONE\n");
-               printf(" 2. ASM_STATE_PLAYING\n");
-               printf(" 3. ASM_STATE_WAITING\n");
-               printf(" 4. ASM_STATE_STOP\n");
-               printf(" 5. ASM_STATE_PAUSE\n");
-               printf(" 6. ASM_STATE_PAUSE_BY_APP\n");
+               printf(" 0. ASM_STATE_NONE\n");
+               printf(" 1. ASM_STATE_PLAYING\n");
+               printf(" 2. ASM_STATE_WAITING\n");
+               printf(" 3. ASM_STATE_STOP\n");
+               printf(" 4. ASM_STATE_PAUSE\n");
+               printf(" q. Back to main menu\n");
+               printf("=============================\n");
+               printf(">> ");
+               while( (input = getchar())!= '\n' && input != EOF) {
+                       key = (char)input;
+               }
+
+               switch (key) {
+                       case '0':
+                               g_asm_state = ASM_STATE_NONE;
+                               break;
+                       case '1':
+                               g_asm_state = ASM_STATE_PLAYING;
+                               break;
+                       case '2':
+                               g_asm_state = ASM_STATE_WAITING;
+                               break;
+                       case '3':
+                               g_asm_state = ASM_STATE_STOP;
+                               break;
+                       case '4':
+                               g_asm_state = ASM_STATE_PAUSE;
+                               break;
+                       case 'q':
+                               return;
+                       default :
+                               g_print("select ASM state again...\n");
+                               g_asm_state = 9;
+                               break;
+               }
+               if (g_asm_state == 9) {
+                       continue;
+               }
+               /* set ASM sound state */
+               if( ! ASM_set_sound_state( g_asm_handle, g_event_type, g_asm_state, g_resource, &ret) ) {
+                       g_print("ASM_set_sound_state() failed, Set state to [%d] failed 0x%X\n\n", g_asm_state, ret);
+                       break;
+               } else {
+                       g_print("ASM_set_sound_state() success, ASM handle=%d, ASM_EVENT=%d, ASM_RESOURCE=%d, ASM_STATE=%d\n\n", g_asm_handle, g_event_type, g_resource, g_asm_state);
+                       break;
+               }
+       }
+}
+
+void menu_set_sub_event(void)
+{
+       int ret = 0;
+       char key = 0;
+       int input = 0;
+       gint error = 0;
+
+       while(1) {
+               printf("==========ASM sub-event==========\n");
+               printf(" 0. ASM_SUB_EVENT_NONE\n");
+               printf(" 1. ASM_SUB_EVENT_SHARE\n");
+               printf(" 2. ASM_SUB_EVENT_EXCLUSIVE\n");
                printf(" q. Back to main menu\n");
                printf("=============================\n");
                printf(">> ");
@@ -198,8 +375,120 @@ void menu_set_state(void)
 
                switch (key) {
                        case '0':
-                               asm_state = ASM_STATE_IGNORE;
+                               g_sub_event_type = ASM_SUB_EVENT_NONE;
+                               break;
+                       case '1':
+                               g_sub_event_type = ASM_SUB_EVENT_SHARE;
+                               break;
+                       case '2':
+                               g_sub_event_type = ASM_SUB_EVENT_EXCLUSIVE;
+                               break;
+                       case 'q':
+                               return;
+                       default :
+                               g_print("select ASM sub event again...\n");
+                               g_sub_event_type = 9;
+                               break;
+               }
+               if (g_sub_event_type == 9) {
+                       continue;
+               }
+               /* set ASM set subevent */
+               ret = ASM_set_subevent (g_asm_handle, g_sub_event_type, &error);
+               if (!ret) {
+                       g_print("ASM_set_subevent() failed, Set state to [%d] failed 0x%X\n\n", g_sub_event_type, error);
+               }
+       }
+}
+
+void menu_set_sub_session(void)
+{
+       int ret = 0;
+       char key = 0;
+       int input = 0;
+       gint error = 0;
+       ASM_resource_t resource = ASM_RESOURCE_NONE;
+
+       while(1) {
+               printf("===============ASM sub-session==========================\n");
+               printf(" 0. ASM_SUB_SESSION_TYPE_VOICE\n");
+               printf(" 1. ASM_SUB_SESSION_TYPE_RINGTONE\n");
+               printf(" 2. ASM_SUB_SESSION_TYPE_MEDIA\n");
+               printf(" 3. ASM_SUB_SESSION_TYPE_INIT\n");
+               printf(" 4. ASM_SUB_SESSION_TYPE_VR_NORMAL\n");
+               printf(" 5. ASM_SUB_SESSION_TYPE_VR_DRIVE\n");
+               printf(" 6. ASM_SUB_SESSION_TYPE_RECORD_STEREO\n");
+               printf(" 7. ASM_SUB_SESSION_TYPE_RECORD_MONO\n");
+               printf(" q. Back to main menu\n");
+               printf("========================================================\n");
+               printf(">> ");
+               while( (input = getchar())!= '\n' && input != EOF) {
+                       key = (char)input;
+               }
+
+               switch (key) {
+                       case '0':
+                               g_sub_session_type = ASM_SUB_SESSION_TYPE_VOICE;
                                break;
+                       case '1':
+                               g_sub_session_type = ASM_SUB_SESSION_TYPE_RINGTONE;
+                               break;
+                       case '2':
+                               g_sub_session_type = ASM_SUB_SESSION_TYPE_MEDIA;
+                               break;
+                       case '3':
+                               g_sub_session_type = ASM_SUB_SESSION_TYPE_INIT;
+                               break;
+                       case '4':
+                               g_sub_session_type = ASM_SUB_SESSION_TYPE_VR_NORMAL;
+                               break;
+                       case '5':
+                               g_sub_session_type = ASM_SUB_SESSION_TYPE_VR_DRIVE;
+                               break;
+                       case '6':
+                               g_sub_session_type = ASM_SUB_SESSION_TYPE_RECORD_STEREO;
+                               break;
+                       case '7':
+                               g_sub_session_type = ASM_SUB_SESSION_TYPE_RECORD_MONO;
+                               break;
+                       case 'q':
+                               return;
+                       default :
+                               g_print("select ASM sub session again...\n");
+                               g_sub_session_type = -1;
+                               break;
+               }
+               if (g_sub_session_type == -1) {
+                       continue;
+               }
+               /* set ASM set subsession */
+               ret = ASM_set_subsession (g_asm_handle, g_sub_session_type, resource, &error);
+               if (!ret) {
+                       g_print("ASM_set_subsession() failed, sub_session_type[%d], resource[%d], 0x%X\n\n", g_sub_session_type, resource, error);
+               }
+       }
+}
+
+void menu_set_watch_state(gint pid, gint event_type)
+{
+       int ret = 0;
+       char key = 0;
+       int input = 0;
+       gint asm_state = 0;
+       while(1) {
+               printf("======ASM state to be watched======\n");
+               printf(" 1. ASM_STATE_NONE\n");
+               printf(" 2. ASM_STATE_PLAYING\n");
+               printf(" 3. ASM_STATE_STOP\n");
+               printf(" 4. ASM_STATE_PAUSE\n");
+               printf(" q. Back to main menu\n");
+               printf("===================================\n");
+               printf(">> ");
+               while( (input = getchar())!= '\n' && input != EOF) {
+                       key = (char)input;
+               }
+
+               switch (key) {
                        case '1':
                                asm_state = ASM_STATE_NONE;
                                break;
@@ -207,34 +496,264 @@ void menu_set_state(void)
                                asm_state = ASM_STATE_PLAYING;
                                break;
                        case '3':
-                               asm_state = ASM_STATE_WAITING;
+                               asm_state = ASM_STATE_STOP;
                                break;
                        case '4':
+                               asm_state = ASM_STATE_PAUSE;
+                               break;
+                       case 'q':
+                               return;
+                       default :
+                               g_print("select ASM state again...\n");
+                               asm_state = 9;
+                               break;
+               }
+               if (asm_state == 9) {
+                       continue;
+               }
+               /* set ASM sound state */
+               if( ! ASM_set_watch_session( pid, event_type, asm_state, watch_callback, NULL, &ret) ) {
+                       g_print("ASM_set_watch_session() failed, 0x%X\n\n", ret);
+                       break;
+               } else {
+                       g_print("ASM_set_watch_session() success");
+                       break;
+               }
+       }
+}
+
+void menu_set_watch(void)
+{
+       char key = 0;
+       int input = 0;
+       gint pid = -1;
+       gint event_type = 0;
+       g_resource = ASM_RESOURCE_NONE;
+
+       while(1) {
+               printf("======select ASM event to be watched======\n");
+               printf(" 0. ASM_EVENT_MEDIA_MMPLAYER \n");
+               printf(" 1. ASM_EVENT_MEDIA_MMPLAYER \n");
+               printf(" 2. ASM_EVENT_MEDIA_MMSOUND\n");
+               printf(" 3. ASM_EVENT_MEDIA_OPENAL\n");
+               printf(" 4. ASM_EVENT_MEDIA_FMRADIO\n");
+               printf(" 5. ASM_EVENT_MEDIA_WEBKIT\n");
+               printf(" 6. ASM_EVENT_NOTIFY\n");
+               printf(" 7. ASM_EVENT_ALARM\n");
+               printf(" 8. ASM_EVENT_EARJACK_UNPLUG\n");
+               printf(" 9. ASM_EVENT_CALL\n");
+               printf(" a. ASM_EVENT_VIDEOCALL\n");
+               printf(" b. ASM_EVENT_VOIP\n");
+               printf(" c. ASM_EVENT_MONITOR\n");
+               printf(" d. ASM_EVENT_EMERGENCY\n");
+               printf(" q. Back to main menu\n");
+               printf("==========================================\n");
+               printf(">> ");
+
+
+               while( (input = getchar())!= '\n' && input != EOF) {
+                       key = (char)input;
+               }
+               switch (key) {
+               case '0':
+                       event_type = ASM_EVENT_MEDIA_MMPLAYER;
+                       break;
+               case '1':
+                       event_type = ASM_EVENT_MEDIA_MMCAMCORDER;
+                       break;
+               case '2':
+                       event_type = ASM_EVENT_MEDIA_MMSOUND;
+                       break;
+               case '3':
+                       event_type = ASM_EVENT_MEDIA_OPENAL;
+                       break;
+               case '4':
+                       event_type = ASM_EVENT_MEDIA_FMRADIO;
+                       break;
+               case '5':
+                       event_type = ASM_EVENT_MEDIA_WEBKIT;
+                       break;
+               case '6':
+                       event_type = ASM_EVENT_NOTIFY;
+                       break;
+               case '7':
+                       event_type = ASM_EVENT_ALARM;
+                       break;
+               case '8':
+                       event_type = ASM_EVENT_EARJACK_UNPLUG;
+                       break;
+               case '9':
+                       event_type = ASM_EVENT_CALL;
+                       break;
+               case 'a':
+                       event_type = ASM_EVENT_VIDEOCALL;
+                       break;
+               case 'b':
+                       event_type = ASM_EVENT_VOIP;
+                       break;
+               case 'c':
+                       event_type = ASM_EVENT_MONITOR;
+                       break;
+               case 'd':
+                       event_type = ASM_EVENT_EMERGENCY;
+                       break;
+               case 'q':
+                       return;
+               default :
+                       g_print("select event again...\n");
+                       event_type = -1;
+                       break;
+               }
+               if (event_type == -1) {
+                       continue;
+               }
+
+               menu_set_watch_state(pid, event_type);
+               break;
+       }
+}
+
+void menu_unset_watch_state(gint pid, gint event_type)
+{
+       int ret = 0;
+       char key = 0;
+       int input = 0;
+       gint asm_state = 0;
+       while(1) {
+               printf("======ASM state to be watched======\n");
+               printf(" 1. ASM_STATE_NONE\n");
+               printf(" 2. ASM_STATE_PLAYING\n");
+               printf(" 3. ASM_STATE_STOP\n");
+               printf(" 4. ASM_STATE_PAUSE\n");
+               printf(" q. Back to main menu\n");
+               printf("===================================\n");
+               printf(">> ");
+               while( (input = getchar())!= '\n' && input != EOF) {
+                       key = (char)input;
+               }
+
+               switch (key) {
+                       case '1':
+                               asm_state = ASM_STATE_NONE;
+                               break;
+                       case '2':
+                               asm_state = ASM_STATE_PLAYING;
+                               break;
+                       case '3':
                                asm_state = ASM_STATE_STOP;
                                break;
-                       case '5':
+                       case '4':
                                asm_state = ASM_STATE_PAUSE;
                                break;
-                       case '6':
-                               asm_state = ASM_STATE_PAUSE_BY_APP;
-                               break;
                        case 'q':
                                return;
                        default :
                                g_print("select ASM state again...\n");
                                asm_state = 9;
+                               break;
                }
                if (asm_state == 9) {
                        continue;
                }
                /* set ASM sound state */
-               if( ! ASM_set_sound_state( asm_handle, event_type, asm_state, g_resource, &ret) ) {
-                       g_print("ASM_set_sound_state() failed, Set state to [%d] failed 0x%X\n\n", asm_state, ret);
+               if( ! ASM_unset_watch_session( event_type, asm_state, &ret) ) {
+                       g_print("ASM_unset_watch_session() failed, 0x%X\n\n", ret);
                        break;
                } else {
-                       g_print("ASM_set_sound_state() success, ASM handle=%d, ASM_EVENT=%d, ASM_RESOURCE=%d, ASM_STATE=%d\n\n", asm_handle, event_type, g_resource, asm_state);
+                       g_print("ASM_unset_watch_session() success");
+                       break;
+               }
+       }
+}
+
+void menu_unset_watch(void)
+{
+       char key = 0;
+       int input = 0;
+       gint pid = -1;
+       gint event_type = 0;
+       g_resource = ASM_RESOURCE_NONE;
+
+       while(1) {
+               printf("======select ASM event to be un-watched======\n");
+               printf(" 0. ASM_EVENT_MEDIA_MMPLAYER \n");
+               printf(" 1. ASM_EVENT_MEDIA_MMPLAYER \n");
+               printf(" 2. ASM_EVENT_MEDIA_MMSOUND\n");
+               printf(" 3. ASM_EVENT_MEDIA_OPENAL\n");
+               printf(" 4. ASM_EVENT_MEDIA_FMRADIO\n");
+               printf(" 5. ASM_EVENT_MEDIA_WEBKIT\n");
+               printf(" 6. ASM_EVENT_NOTIFY\n");
+               printf(" 7. ASM_EVENT_ALARM\n");
+               printf(" 8. ASM_EVENT_EARJACK_UNPLUG\n");
+               printf(" 9. ASM_EVENT_CALL\n");
+               printf(" a. ASM_EVENT_VIDEOCALL\n");
+               printf(" b. ASM_EVENT_VOIP\n");
+               printf(" c. ASM_EVENT_MONITOR\n");
+               printf(" d. ASM_EVENT_EMERGENCY\n");
+               printf(" q. Back to main menu\n");
+               printf("==========================================\n");
+               printf(">> ");
+
+
+               while( (input = getchar())!= '\n' && input != EOF) {
+                       key = (char)input;
+               }
+               switch (key) {
+               case '0':
+                       event_type = ASM_EVENT_MEDIA_MMPLAYER;
+                       break;
+               case '1':
+                       event_type = ASM_EVENT_MEDIA_MMCAMCORDER;
+                       break;
+               case '2':
+                       event_type = ASM_EVENT_MEDIA_MMSOUND;
+                       break;
+               case '3':
+                       event_type = ASM_EVENT_MEDIA_OPENAL;
+                       break;
+               case '4':
+                       event_type = ASM_EVENT_MEDIA_FMRADIO;
+                       break;
+               case '5':
+                       event_type = ASM_EVENT_MEDIA_WEBKIT;
+                       break;
+               case '6':
+                       event_type = ASM_EVENT_NOTIFY;
                        break;
+               case '7':
+                       event_type = ASM_EVENT_ALARM;
+                       break;
+               case '8':
+                       event_type = ASM_EVENT_EARJACK_UNPLUG;
+                       break;
+               case '9':
+                       event_type = ASM_EVENT_CALL;
+                       break;
+               case 'a':
+                       event_type = ASM_EVENT_VIDEOCALL;
+                       break;
+               case 'b':
+                       event_type = ASM_EVENT_VOIP;
+                       break;
+               case 'c':
+                       event_type = ASM_EVENT_MONITOR;
+                       break;
+               case 'd':
+                       event_type = ASM_EVENT_EMERGENCY;
+                       break;
+               case 'q':
+                       return;
+               default :
+                       g_print("select event again...\n");
+                       event_type = -1;
+                       break;
+               }
+               if (event_type == -1) {
+                       continue;
                }
+
+               menu_unset_watch_state(pid, event_type);
+               break;
        }
 }
 
@@ -250,23 +769,85 @@ gpointer keythread(gpointer data)
                }
 
                switch (key) {
-                       case 'r':
+                       case 'a':
                                menu_register();
                                break;
+                       case 'o':
+                               menu_set_options();
+                               break;
+                       case 'r':
+                               menu_set_resource();
+                               break;
                        case 's':
                                menu_set_state();
                                break;
-                       case 'u':
+                       case 'x':
+                       {
+                               int ret = 0;
+                               ASM_sound_states_t asm_state = ASM_STATE_NONE;
+                               if( ! ASM_get_sound_state( g_asm_handle, g_event_type, &asm_state, &ret) ) {
+                                       g_print("ASM_get_sound_state() failed, asm_handle[%d], asm_event[%d], 0x%X\n\n", g_asm_handle, g_event_type, ret);
+                               } else {
+                                       g_print("ASM_get_sound_state() success, ASM handle=%d, ASM_EVENT=%d, ASM_STATE=%d\n\n", g_asm_handle, g_event_type, asm_state);
+                               }
+                               break;
+                       }
+                       case 'd':
+                               menu_set_sub_event();
+                               break;
+                       case 'c':
+                       {
+                               int ret = 0;
+                               ASM_sound_sub_events_t asm_sub_event = ASM_SUB_EVENT_NONE;
+                               if ( ! ASM_get_subevent (g_asm_handle, &asm_sub_event, &ret) ) {
+                                       g_print("ASM_get_subevent() failed, asm_handle[%d], 0x%X\n\n", g_asm_handle, ret);
+                               } else {
+                                       g_print("ASM_get_sound_state() success, ASM handle=%d, ASM_SUB_EVENT=%d\n\n", g_asm_handle, asm_sub_event);
+                               }
+                               break;
+                       }
+                       case 'f':
+                               menu_set_sub_session();
+                               break;
+                       case 'v':
+                       {
+                               int ret = 0;
+                               ASM_sound_sub_sessions_t asm_sub_session = ASM_SUB_SESSION_TYPE_VOICE;
+                               if ( ! ASM_get_subsession (g_asm_handle, &asm_sub_session, &ret)) {
+                                       g_print("ASM_get_subsession() failed, asm_handle[%d], 0x%X\n\n", g_asm_handle, ret);
+                               } else {
+                                       g_print("ASM_get_subsession() success, ASM handle=%d, ASM_SUB_SESSION=%d\n\n", g_asm_handle, asm_sub_session);
+                               }
+                               break;
+                       }
+                       case 'z':
                                menu_unregister();
                                break;
+                       case 'j':
+                               menu_set_watch();
+                               break;
+                       case 'm':
+                               menu_unset_watch();
+                               break;
+                       case 'w':
+                               if (g_asm_handle == -1) {
+                                       g_print("Register ASM handle first...\n");
+                               } else {
+                                       int error = 0;
+                                       if (!ASM_reset_resumption_info(g_asm_handle, &error)) {
+                                               g_print("ASM_reset_resumption_info() failed 0x%X\n", error);
+                                       }
+                               }
+                               break;
                        case 'q':
-                               if(asm_handle != -1) {
+                               if(g_asm_handle != -1) {
                                        menu_unregister();
                                }
                                g_main_loop_quit(g_loop);
                                break;
                        default :
                                g_print("wrong input, select again...\n\n");
+                               break;
                } /* switch (key) */
        } /* while () */
        return NULL;
@@ -274,11 +855,10 @@ gpointer keythread(gpointer data)
 
 int main ()
 {
-       g_thread_init (NULL);
        thread_run = TRUE;
 
        g_loop = g_main_loop_new (NULL, 0);
-       GThread * command_thread = g_thread_create (keythread, NULL, FALSE, NULL);
+       GThread *command_thread = g_thread_new("keythread", keythread, NULL);
        if (!command_thread) {
                g_print ("key thread creation failure\n");
                return 0;