Add interanl API for supporting resource path 30/232530/1
authorYunmi Ha <yunmi.ha@samsung.com>
Wed, 6 May 2020 06:52:56 +0000 (15:52 +0900)
committerYunmi Ha <yunmi.ha@samsung.com>
Wed, 6 May 2020 06:54:01 +0000 (15:54 +0900)
Noti app want to play feedback without any vconf changes.
But original API decides resource path for sound play with vconf value.
So add new API which has additional parameter of sound resource path.

Change-Id: I85bb37daacf14684c29e13cabfea6c7ee80e0008
Signed-off-by: Yunmi Ha <yunmi.ha@samsung.com>
include/feedback-internal.h
src/devices.c
src/devices.h
src/feedback.c
src/sound.c

index 188e104..6c93801 100644 (file)
@@ -82,6 +82,31 @@ int feedback_play_type_by_name(char *type, char *pattern);
 int feedback_play_internal(feedback_pattern_internal_e pattern);
 
 /**
+ * @brief Plays various types of reactions that are pre-defined.
+ * @details This function can be used to react to pre-defined actions. \n
+ *          It play various types of system pre-defined media or vibration patterns.
+ * @since_tizen 5.5
+ * @remarks Currently, there are two types of reactions: sound and vibration. \n
+ *          Depending on the settings, some types cannot operate.
+ *          For example, when set to silent mode, the device doesn't produce any sound.
+ *          If to play one of the devices is successful, this function regards as success.
+ *          And for controlling haptic device, the privilege should be set to, %http://tizen.org/privilege/haptic.
+ *          If you don't have the haptic privilege, it only works sound operation.
+ *          It does not return any error in this case.
+ * @param[in] pattern The pre-defined internal pattern
+ * @param[in] soundpath The resource file path for sound (can't be NULL)
+ * @return @c 0 on success,
+ *         otherwise a negative error value
+ * @retval #FEEDBACK_ERROR_NONE Successful
+ * @retval #FEEDBACK_ERROR_OPERATION_FAILED Operation not permitted
+ * @retval #FEEDBACK_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #FEEDBACK_ERROR_NOT_SUPPORTED Not supported device
+ * @retval #FEEDBACK_ERROR_NOT_INITIALIZED Not initialized
+ * @pre feedback_initialize()
+ */
+int feedback_play_soundpath_internal(feedback_pattern_internal_e internal_pattern, const char *soundpath);
+
+/**
  * @brief Plays specific type of reactions that are pre-defined.
  * @details This function can be used to react to pre-defined actions. \n
  *          It play specific type of system pre-defined pattern.
@@ -105,6 +130,32 @@ int feedback_play_internal(feedback_pattern_internal_e pattern);
  */
 int feedback_play_type_internal(feedback_type_e type, feedback_pattern_internal_e pattern);
 
+
+/**
+ * @brief Plays specific type of reactions that are pre-defined.
+ * @details This function can be used to react to pre-defined actions. \n
+ *          It play specific type of system pre-defined pattern.
+ * @since_tizen 4.0
+ * @remarks Currently, there are two types of reactions: sound and vibration. \n
+ *          Depending on the settings, some types cannot operate.
+ *          For example, when set to silent mode, the device doesn't produce any sound.
+ *          And for controlling haptic device, the privilege should be set to, %http://tizen.org/privilege/haptic.
+ *          If you don't have the haptic privilege, it returns FEEDBACK_ERROR_PERMISSION_DENIED error.
+ * @param[in] type The pattern type
+ * @param[in] pattern The pre-defined internal pattern
+ * @param[in] soundpath The resource file path for sound
+ * @return @c 0 on success,
+ *         otherwise a negative error value
+ * @retval #FEEDBACK_ERROR_NONE Successful
+ * @retval #FEEDBACK_ERROR_OPERATION_FAILED Operation not permitted
+ * @retval #FEEDBACK_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #FEEDBACK_ERROR_NOT_SUPPORTED Not supported device
+ * @retval #FEEDBACK_ERROR_PERMISSION_DENIED Permission denied
+ * @retval #FEEDBACK_ERROR_NOT_INITIALIZED Not initialized
+ * @pre feedback_initialize()
+ */
+int feedback_play_type_soundpath_internal(feedback_type_e type, feedback_pattern_internal_e internal_pattern, const char *soundpath);
+
 /**
  * @}
  */
index 5cc3663..fa3f54d 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <stdio.h>
 
+#include "feedback-ids.h"
 #include "devices.h"
 #include "log.h"
 
@@ -95,6 +96,38 @@ int devices_play(int pattern)
        return prev;
 }
 
+int devices_play_soundpath(int pattern, const char *soundpath)
+{
+       dd_list *elem;
+       const struct device_ops *dev;
+       int ret, prev = -EPERM;
+
+       DD_LIST_FOREACH(dev_head, elem, dev) {
+               if (dev->type == FEEDBACK_TYPE_SOUND) {
+                       if (dev->play_path)
+                               ret = dev->play_path(pattern, soundpath);
+                       else
+                               continue;       //LCOV_EXCL_LINE
+               } else {
+                       if (dev->play)
+                               ret = dev->play(pattern);
+                       else
+                               continue;       //LCOV_EXCL_LINE
+               }
+
+               if ((prev < 0 && ret == 0) ||
+                       (prev == 0 && ret < 0))
+                       prev = 0;
+               else if ((prev < 0 && ret == -ENOTSUP) ||
+                       (prev == -ENOTSUP && ret < 0))
+                       prev = -ENOTSUP;
+               else
+                       prev = ret;
+       }
+
+       return prev;
+}
+
 int devices_stop(void)
 {
        dd_list *elem;
index 2774967..898b975 100644 (file)
@@ -29,6 +29,7 @@ struct device_ops {
        void (*init) (void);
        void (*exit) (void);
        int (*play) (int);
+       int (*play_path) (int, const char *);
        int (*stop) (void);
        int (*is_supported) (int, bool *);
        int (*get_path) (int, char *, unsigned int);
@@ -38,6 +39,7 @@ struct device_ops {
 void devices_init(void);
 void devices_exit(void);
 int devices_play(int pattern);
+int devices_play_soundpath(int pattern, const char *soundpath);
 int devices_stop(void);
 
 #define DEVICE_OPS_REGISTER(dev)       \
index f847cb9..ab72a02 100644 (file)
@@ -444,3 +444,129 @@ API int feedback_play_type_internal(feedback_type_e type, feedback_pattern_inter
 
        return FEEDBACK_ERROR_NONE;
 }
+
+API int feedback_play_soundpath_internal(feedback_pattern_internal_e internal_pattern, const char *soundpath)
+{
+       int err;
+       bool result;
+       int switched;
+       feedback_pattern_e pattern = (feedback_pattern_e)internal_pattern;
+
+       /* check initialize */
+       pthread_mutex_lock(&fmutex);
+       if (!init_cnt) {
+               _E("Not initialized"); //LCOV_EXCL_LINE
+               pthread_mutex_unlock(&fmutex);
+               return FEEDBACK_ERROR_NOT_INITIALIZED;
+       }
+       pthread_mutex_unlock(&fmutex);
+
+       if (pattern <= FEEDBACK_PATTERN_NONE ||
+               pattern >= profile->max_pattern) {
+               _E("Invalid parameter : pattern(%d)", pattern);
+               return FEEDBACK_ERROR_INVALID_PARAMETER;
+       }
+
+       if (!soundpath) {
+               _E("Invalid parameter : pattern path(NULL)");
+               return FEEDBACK_ERROR_INVALID_PARAMETER;
+       }
+
+       /* if you need to switch pattern */
+       if (profile->get_switched_pattern) {
+               result = profile->get_switched_pattern(pattern, &switched);
+               if (result) {
+                       _W("pattern is changed : (%s) -> (%s)", //LCOV_EXCL_LINE
+                                       profile->str_pattern(pattern), profile->str_pattern(switched));
+                       pattern = switched;
+               }
+       }
+
+       _D("request all type with pattern %s(%d), soundpath %s", profile->str_pattern(pattern), pattern, soundpath);
+       /* play all device */
+       err = devices_play_soundpath(pattern, soundpath);
+       /**
+        * devices_play() returns error even if all devices are failed.
+        * It means if to play anything is successful,
+        * this function regards as success.
+        */
+       if (err == -ENOTSUP)
+               return FEEDBACK_ERROR_NOT_SUPPORTED;
+       else if (err < 0)
+               return FEEDBACK_ERROR_OPERATION_FAILED;
+
+       return FEEDBACK_ERROR_NONE;
+}
+
+API int feedback_play_type_soundpath_internal(feedback_type_e type, feedback_pattern_internal_e internal_pattern, const char *soundpath)
+{
+       const struct device_ops *dev;
+       int err;
+       bool result;
+       int switched;
+       feedback_pattern_e pattern = (feedback_pattern_e)internal_pattern;
+
+       /* check initialize */
+       pthread_mutex_lock(&fmutex);
+       if (!init_cnt) {
+               _E("Not initialized"); //LCOV_EXCL_LINE
+               pthread_mutex_unlock(&fmutex);
+               return FEEDBACK_ERROR_NOT_INITIALIZED;
+       }
+       pthread_mutex_unlock(&fmutex);
+
+       if (type <= FEEDBACK_TYPE_NONE ||
+           type >= profile->max_type) {
+               _E("Invalid parameter : type(%d)", type);
+               return FEEDBACK_ERROR_INVALID_PARAMETER;
+       }
+
+       if (pattern <= FEEDBACK_PATTERN_NONE ||
+           pattern >= profile->max_pattern) {
+               _E("Invalid parameter : pattern(%d)", pattern);
+               return FEEDBACK_ERROR_INVALID_PARAMETER;
+       }
+
+       if ((type == FEEDBACK_TYPE_SOUND) && (soundpath == NULL)) {
+               _E("Invalid parameter : sound path(NULL)");
+               return FEEDBACK_ERROR_INVALID_PARAMETER;
+       }
+
+       /* if you need to switch pattern */
+       if (profile->get_switched_pattern) {
+               result = profile->get_switched_pattern(pattern, &switched);
+               if (result) {
+                       _W("pattern is changed : (%s) -> (%s)", //LCOV_EXCL_LINE
+                                       profile->str_pattern(pattern), profile->str_pattern(switched));
+                       pattern = switched;
+               }
+       }
+
+       /* play proper device */
+       dev = find_device(type);
+       if (!dev) {
+               _E("Not supported device : type(%s)", profile->str_type[type]); //LCOV_EXCL_LINE
+               return FEEDBACK_ERROR_NOT_SUPPORTED;
+       }
+       _D("request type %s with pattern(%s), soundpath(%s)", profile->str_type[type], profile->str_pattern(pattern), soundpath?soundpath:"NULL");
+       if (type == FEEDBACK_TYPE_SOUND) {
+               if (dev->play_path)
+                       err = dev->play_path(pattern, soundpath);
+               else
+                       err = -ENOTSUP; //LCOV_EXCL_LINE
+       } else {
+               if (dev->play)
+                       err = dev->play(pattern);
+               else
+                       err = -ENOTSUP; //LCOV_EXCL_LINE
+       }
+
+       if (err == -ENOTSUP)
+               return FEEDBACK_ERROR_NOT_SUPPORTED;
+       else if (err == -ECOMM || err == -EACCES)
+               return FEEDBACK_ERROR_PERMISSION_DENIED;
+       else if (err < 0)
+               return FEEDBACK_ERROR_OPERATION_FAILED;
+
+       return FEEDBACK_ERROR_NONE;
+}
index 886b707..55235cb 100644 (file)
@@ -197,6 +197,56 @@ static int sound_play(feedback_pattern_e pattern)
        return -EPERM;
 }
 
+static int sound_play_path(feedback_pattern_e pattern, const char *soundpath)
+{
+       struct stat buf;
+       int retry = FEEDBACK_RETRY_CNT, ret;
+       char *path;
+       int level;
+
+       if (!soundpath || stat(soundpath, &buf)) {
+               if (!soundpath)
+                       _E("Not supported sound pattern(pattern %d)", pattern); //LCOV_EXCL_LINE
+               else
+                       _E("Not supported sound pattern(soundpath %s of pattern %s)", soundpath, profile->str_pattern(pattern)); //LCOV_EXCL_LINE
+               return -ENOTSUP;
+       }
+
+       if (vconf_get_bool(VCONFKEY_SETAPPL_SOUND_STATUS_BOOL, &sndstatus) < 0) {
+               _D("fail to get sound status, will work as turning off"); //LCOV_EXCL_LINE
+               sndstatus = 0;
+       }
+
+       if (sndstatus == 0 && profile->get_always_alert_case &&
+           !profile->get_always_alert_case(FEEDBACK_TYPE_SOUND, pattern)) {
+               _D("Sound condition is OFF (sndstatus : %d)", sndstatus); //LCOV_EXCL_LINE
+               return 0;
+       }
+
+       if (sndstatus && profile->get_always_off_case &&
+           profile->get_always_off_case(FEEDBACK_TYPE_SOUND, pattern)) {
+               _D("Sound always off condition(pattern %s)", profile->str_pattern(pattern)); //LCOV_EXCL_LINE
+               return 0;
+       }
+
+       /* play sound file */
+       do {
+               if (profile->get_strength_type)
+                       level = profile->get_strength_type(FEEDBACK_TYPE_SOUND, pattern);
+               else
+                       level = VOLUME_TYPE_SYSTEM;
+
+               ret = mm_sound_play_keysound(soundpath, level);
+               if (ret == MM_ERROR_NONE) {
+                       _D("Play success! SND filename is %s", soundpath); //LCOV_EXCL_LINE
+                       return 0;
+               }
+               _E("mm_sound_play_keysound(\'%s\') returned error(%d)", soundpath, ret); //LCOV_EXCL_LINE
+       } while (retry--);
+
+       return -EPERM;
+}
+
 static int sound_is_supported(feedback_pattern_e pattern, bool *supported)
 {
        struct stat buf;
@@ -328,6 +378,7 @@ static const struct device_ops sound_device_ops = {
        .init = sound_init,
        .exit = sound_exit,
        .play = sound_play,
+       .play_path = sound_play_path,
        .stop = sound_stop,
        .is_supported = sound_is_supported,
        .get_path = sound_get_path,