Add audio hal testcases 47/185547/16 accepted/tizen/unified/20180817.140839 submit/tizen/20180817.064104
authorSeungbae Shin <seungbae.shin@samsung.com>
Wed, 25 Jul 2018 11:58:38 +0000 (20:58 +0900)
committerSeungbae Shin <seungbae.shin@samsung.com>
Thu, 16 Aug 2018 11:21:19 +0000 (20:21 +0900)
[Version] 0.0.13
[Profile] Common
[Issue Type] Add
[Dependency module] N/A

Change-Id: I1c3bc6f1b84242ee04a4cfa1b5d8fd0432f0295e

configure.ac
include/audio/audio_hal_interface.h [new file with mode: 0644]
mm-hal-interface-audio.manifest [new file with mode: 0644]
packaging/mm-hal-interface.spec
src/Makefile.am
src/audio/Makefile.am [new file with mode: 0644]
src/audio/audio_hal_interface.c [new file with mode: 0644]
testcase/Makefile.am
testcase/audio/Makefile.am [new file with mode: 0644]
testcase/audio/audio_haltests.cpp [new file with mode: 0644]
testcase/audio/dtmf_16le_44100_2ch.raw [new file with mode: 0644]

index 0c305a9..9616f12 100644 (file)
@@ -36,9 +36,11 @@ Makefile
 src/Makefile
 src/camera/Makefile
 src/radio/Makefile
+src/audio/Makefile
 testcase/Makefile
 testcase/camera/Makefile
 testcase/radio/Makefile
+testcase/audio/Makefile
 camera-hal-interface.pc
 radio-hal-interface.pc
 ])
diff --git a/include/audio/audio_hal_interface.h b/include/audio/audio_hal_interface.h
new file mode 100644 (file)
index 0000000..e7bb157
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ * audio_hal_interface.h
+ *
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Seungbae Shin <seungbae.shin@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <tizen-audio.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum _io_direction {
+       DIRECTION_IN,
+       DIRECTION_OUT,
+} io_direction_t;
+
+typedef enum _audio_hal_return {
+       AUDIO_HAL_ERROR = -1,
+       AUDIO_HAL_SUCCESS
+} audio_hal_return_t;
+
+typedef struct _hal_device_info {
+       const char *type;
+       uint32_t direction;
+       uint32_t id;
+} hal_device_info;
+
+typedef struct _hal_route_info {
+       const char *role;
+       hal_device_info *device_infos;
+       uint32_t num_of_devices;
+} hal_route_info;
+
+typedef struct _hal_route_option {
+       const char *role;
+       const char *name;
+       int32_t value;
+} hal_route_option;
+
+typedef struct _hal_stream_connection_info {
+       const char *role;
+       uint32_t direction;
+       uint32_t idx;
+       bool is_connected;
+} hal_stream_connection_info;
+
+typedef void* pcm_handle;
+typedef void (*hal_message_callback)(const char *name, int value, void *user_data);
+typedef struct _audio_hal_interface audio_hal_interface;
+
+int32_t audio_hal_interface_init(audio_hal_interface **h);
+int32_t audio_hal_interface_deinit(audio_hal_interface *h);
+int32_t audio_hal_interface_get_volume_level_max(audio_hal_interface *h, const char *volume_type, io_direction_t direction, uint32_t *level);
+int32_t audio_hal_interface_get_volume_level(audio_hal_interface *h, const char *volume_type, io_direction_t direction, uint32_t *level);
+int32_t audio_hal_interface_set_volume_level(audio_hal_interface *h, const char *volume_type, io_direction_t direction, uint32_t level);
+int32_t audio_hal_interface_get_volume_value(audio_hal_interface *h, const char *volume_type, const char *gain_type,
+                                                                                       io_direction_t direction, uint32_t level, double *value);
+int32_t audio_hal_interface_get_volume_mute(audio_hal_interface *h, const char *volume_type, io_direction_t direction, uint32_t *mute);
+int32_t audio_hal_interface_set_volume_mute(audio_hal_interface *h, const char *volume_type, io_direction_t direction, uint32_t mute);
+int32_t audio_hal_interface_update_route(audio_hal_interface *h, hal_route_info *info);
+int32_t audio_hal_interface_update_route_option(audio_hal_interface *h, hal_route_option *option);
+int32_t audio_hal_interface_notify_stream_connection_changed(audio_hal_interface *h, hal_stream_connection_info *info);
+int32_t audio_hal_interface_pcm_open(audio_hal_interface *h, const char *card, const char *device, io_direction_t direction,
+                                                                       void *sample_spec, uint32_t period_size, uint32_t periods, pcm_handle *pcm_h);
+int32_t audio_hal_interface_pcm_start(audio_hal_interface *h, pcm_handle pcm_h);
+int32_t audio_hal_interface_pcm_stop(audio_hal_interface *h, pcm_handle pcm_h);
+int32_t audio_hal_interface_pcm_close(audio_hal_interface *h, pcm_handle pcm_h);
+int32_t audio_hal_interface_pcm_available(audio_hal_interface *h, pcm_handle pcm_h, uint32_t *available);
+int32_t audio_hal_interface_pcm_write(audio_hal_interface *h, pcm_handle pcm_h, const void *buffer, uint32_t frames);
+int32_t audio_hal_interface_pcm_read(audio_hal_interface *h, pcm_handle pcm_h, void *buffer, uint32_t frames);
+int32_t audio_hal_interface_pcm_get_fd(audio_hal_interface *h, pcm_handle pcm_h, int *fd);
+int32_t audio_hal_interface_pcm_recover(audio_hal_interface *h, pcm_handle pcm_h, int err);
+int32_t audio_hal_interface_pcm_get_params(audio_hal_interface *h, pcm_handle pcm_h, uint32_t direction, void **sample_spec,
+                                                                               uint32_t *period_size, uint32_t *periods);
+int32_t audio_hal_interface_pcm_set_params(audio_hal_interface *h, pcm_handle pcm_h, uint32_t direction, void *sample_spec,
+                                                                               uint32_t period_size, uint32_t periods);
+int32_t audio_hal_interface_add_message_callback(audio_hal_interface *h, hal_message_callback callback, void *user_data);
+int32_t audio_hal_interface_remove_message_callback(audio_hal_interface *h, hal_message_callback callback);
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/mm-hal-interface-audio.manifest b/mm-hal-interface-audio.manifest
new file mode 100644 (file)
index 0000000..a76fdba
--- /dev/null
@@ -0,0 +1,5 @@
+<manifest>
+       <request>
+               <domain name="_" />
+       </request>
+</manifest>
index 3c054f6..9d8fa87 100644 (file)
@@ -1,7 +1,7 @@
 Name:       mm-hal-interface
 Summary:    Multimedia HAL Interface
-Version:    0.0.12
-Release:    1
+Version:    0.0.13
+Release:    0
 Group:      Multimedia/Development
 License:    Apache-2.0
 Source0:    %{name}-%{version}.tar.gz
@@ -32,7 +32,13 @@ Version:    %{version}
 %description radio
 Multimedia framework hardware abstraction layer interface library for radio.
 
+%package audio
+Summary:    Multimedia framework hardware abstraction layer interface library for audio
+Group:      Multimedia/Libraries
+Version:    %{version}
 
+%description audio
+Multimedia framework hardware abstraction layer interface library for audio.
 
 %package devel
 Summary:    Multimedia framework hardware abstraction layer interface development package
@@ -40,6 +46,7 @@ Group:      libdevel
 Version:    %{version}
 Requires:   %{name}-camera = %{version}-%{release}
 Requires:   %{name}-radio = %{version}-%{release}
+Requires:   %{name}-audio = %{version}-%{release}
 
 %description devel
 Multimedia framework hardware abstraction layer interface development package.
@@ -53,6 +60,15 @@ Version:    %{version}
 %description -n camera-haltests
 gtest for camera HAL APIs.
 
+%package -n audio-haltests
+Summary:    gtest for audio HAL APIs
+Group:      Development/Tools
+Version:    %{version}
+
+%description -n audio-haltests
+gtest for audio HAL APIs.
+
+
 
 %package -n radio-haltests
 Summary:    gtest for radio HAL APIs
@@ -78,6 +94,9 @@ install -d -m 755 %{buildroot}%{_includedir}
 install -m 644 include/audio/*.h %{buildroot}%{_includedir}
 install -m 644 include/camera/*.h %{buildroot}%{_includedir}
 install -m 644 include/radio/*.h %{buildroot}%{_includedir}
+
+install -d -m 755 %{buildroot}%{_datadir}/testcase/res/audio/
+install -m 644 testcase/audio/*.raw %{buildroot}%{_datadir}/testcase/res/audio/
 %make_install
 
 %post -p /sbin/ldconfig
@@ -101,6 +120,12 @@ install -m 644 include/radio/*.h %{buildroot}%{_includedir}
 %defattr(-,root,root,-)
 %{_libdir}/libradio*.so.*
 
+%files audio
+%manifest mm-hal-interface-audio.manifest
+%license LICENSE.APLv2
+%defattr(-,root,root,-)
+%{_libdir}/libaudio*.so.*
+
 %files devel
 %defattr(-,root,root,-)
 %{_includedir}/*.h
@@ -118,3 +143,10 @@ install -m 644 include/radio/*.h %{buildroot}%{_includedir}
 %license LICENSE.APLv2
 %defattr(-,root,root,-)
 %{_bindir}/radio_*
+
+%files -n audio-haltests
+%manifest mm-haltests.manifest
+%license LICENSE.APLv2
+%defattr(-,root,root,-)
+%{_bindir}/audio_*
+%{_datadir}/testcase/res/audio/*
index 1d5c729..4c6082d 100644 (file)
@@ -1,3 +1,4 @@
 SUBDIRS = camera \
-         radio
+               radio \
+               audio
 
diff --git a/src/audio/Makefile.am b/src/audio/Makefile.am
new file mode 100644 (file)
index 0000000..cecbb90
--- /dev/null
@@ -0,0 +1,6 @@
+lib_LTLIBRARIES = libaudio_hal_interface.la
+
+libaudio_hal_interface_la_SOURCES = audio_hal_interface.c
+libaudio_hal_interface_la_CFLAGS = $(DLOG_CFLAGS) -I$(srcdir)/../../include/audio
+libaudio_hal_interface_la_LIBADD = $(DLOG_LIBS) -ldl
+
diff --git a/src/audio/audio_hal_interface.c b/src/audio/audio_hal_interface.c
new file mode 100644 (file)
index 0000000..f28ed65
--- /dev/null
@@ -0,0 +1,690 @@
+/*
+ * audio_hal_interface.c
+ *
+ * Copyright (c) 2018 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.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <errno.h>
+#include <dlfcn.h>
+#include <dlog.h>
+#include <stdlib.h>
+#include <assert.h>
+#include "audio_hal_interface.h"
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif /* LOG_TAG */
+#define LOG_TAG "AUDIO_HAL_INTF"
+
+#define LIB_TIZEN_AUDIO "libtizen-audio.so"
+
+struct _audio_hal_interface {
+       void *dl_handle;
+       void *ah_handle;
+       audio_interface_t intf;
+};
+
+int32_t audio_hal_interface_init(audio_hal_interface **h)
+{
+       int ret = AUDIO_RET_OK;
+       audio_hal_interface *tmp_h = NULL;
+
+       if (h == NULL) {
+               LOGE("invalid parameter for audio_hal_interface");
+               return AUDIO_HAL_ERROR;
+       }
+
+       tmp_h = (audio_hal_interface *)malloc(sizeof(struct _audio_hal_interface));
+       if (tmp_h == NULL) {
+               LOGE("failed to allocate hal interface");
+               return AUDIO_HAL_ERROR;
+       }
+
+       tmp_h->dl_handle = dlopen(LIB_TIZEN_AUDIO, RTLD_NOW);
+       if (!tmp_h->dl_handle) {
+               LOGE("dlopen %s failed :%s", LIB_TIZEN_AUDIO, dlerror());
+               free(tmp_h);
+               return AUDIO_HAL_ERROR;
+       }
+
+       tmp_h->intf.init = dlsym(tmp_h->dl_handle, "audio_init");
+       tmp_h->intf.deinit = dlsym(tmp_h->dl_handle, "audio_deinit");
+       tmp_h->intf.get_volume_level_max = dlsym(tmp_h->dl_handle, "audio_get_volume_level_max");
+       tmp_h->intf.get_volume_level = dlsym(tmp_h->dl_handle, "audio_get_volume_level");
+       tmp_h->intf.set_volume_level = dlsym(tmp_h->dl_handle, "audio_set_volume_level");
+       tmp_h->intf.get_volume_value = dlsym(tmp_h->dl_handle, "audio_get_volume_value");
+       tmp_h->intf.get_volume_mute = dlsym(tmp_h->dl_handle, "audio_get_volume_mute");
+       tmp_h->intf.set_volume_mute = dlsym(tmp_h->dl_handle, "audio_set_volume_mute");
+       tmp_h->intf.update_route = dlsym(tmp_h->dl_handle, "audio_update_route");
+       tmp_h->intf.update_route_option = dlsym(tmp_h->dl_handle, "audio_update_route_option");
+       tmp_h->intf.notify_stream_connection_changed = dlsym(tmp_h->dl_handle, "audio_notify_stream_connection_changed");
+       tmp_h->intf.pcm_open = dlsym(tmp_h->dl_handle, "audio_pcm_open");
+       tmp_h->intf.pcm_start = dlsym(tmp_h->dl_handle, "audio_pcm_start");
+       tmp_h->intf.pcm_stop = dlsym(tmp_h->dl_handle, "audio_pcm_stop");
+       tmp_h->intf.pcm_close = dlsym(tmp_h->dl_handle, "audio_pcm_close");
+       tmp_h->intf.pcm_avail = dlsym(tmp_h->dl_handle, "audio_pcm_avail");
+       tmp_h->intf.pcm_write = dlsym(tmp_h->dl_handle, "audio_pcm_write");
+       tmp_h->intf.pcm_read = dlsym(tmp_h->dl_handle, "audio_pcm_read");
+       tmp_h->intf.pcm_get_fd = dlsym(tmp_h->dl_handle, "audio_pcm_get_fd");
+       tmp_h->intf.pcm_recover = dlsym(tmp_h->dl_handle, "audio_pcm_recover");
+       tmp_h->intf.pcm_get_params = dlsym(tmp_h->dl_handle, "audio_pcm_get_params");
+       tmp_h->intf.pcm_set_params = dlsym(tmp_h->dl_handle, "audio_pcm_set_params");
+       tmp_h->intf.add_message_cb = dlsym(tmp_h->dl_handle, "audio_add_message_cb");
+       tmp_h->intf.remove_message_cb = dlsym(tmp_h->dl_handle, "audio_remove_message_cb");
+
+       if (tmp_h->intf.init) {
+               ret = tmp_h->intf.init(&tmp_h->ah_handle);
+               if (ret == AUDIO_RET_OK) {
+                       LOGI("audio_init success!!!");
+                       *h = tmp_h;
+                       return AUDIO_HAL_SUCCESS;
+               }
+               LOGE("audio_init failed 0x%x", ret);
+       } else {
+               LOGE("no audio_init function");
+       }
+
+       dlclose(tmp_h->dl_handle);
+       free(tmp_h);
+
+       return AUDIO_HAL_ERROR;
+}
+
+
+int32_t audio_hal_interface_deinit(audio_hal_interface *h)
+{
+       int ret = AUDIO_RET_OK;
+
+       assert(h);
+       assert(h->dl_handle);
+       assert(h->ah_handle);
+
+       if (h->intf.deinit) {
+               ret = h->intf.deinit(h->ah_handle);
+               if (ret != AUDIO_RET_OK) {
+                       LOGE("audio_deinit failed 0x%x", ret);
+                       return AUDIO_HAL_ERROR;
+               }
+               LOGI("audio_deinit success!!!");
+       } else {
+               LOGE("Not implemented....");
+       }
+
+       dlclose(h->dl_handle);
+       free(h);
+
+       return AUDIO_HAL_SUCCESS;
+}
+
+int32_t audio_hal_interface_get_volume_level_max(audio_hal_interface *h,
+                                                                                               const char *volume_type,
+                                                                                               io_direction_t direction,
+                                                                                               uint32_t *level)
+{
+       audio_return_t ret = AUDIO_RET_OK;
+       audio_volume_info_t info = { NULL, NULL, 0 };
+
+       assert(h);
+       assert(h->ah_handle);
+
+       info.type = volume_type;
+       info.direction = direction;
+
+       if (!h->intf.get_volume_level_max) {
+               LOGE("Not implemented....");
+               return AUDIO_HAL_ERROR;
+       }
+
+       ret = h->intf.get_volume_level_max(h->ah_handle, &info, level);
+       if (ret != AUDIO_RET_OK) {
+               LOGE("get_volume_level_max returns error:0x%x", ret);
+               return AUDIO_HAL_ERROR;
+       }
+
+       return AUDIO_HAL_SUCCESS;
+}
+
+int32_t audio_hal_interface_get_volume_level(audio_hal_interface *h,
+                                                                                       const char *volume_type,
+                                                                                       io_direction_t direction,
+                                                                                       uint32_t *level)
+{
+       audio_return_t ret = AUDIO_RET_OK;
+       audio_volume_info_t info = { NULL, NULL, 0 };
+
+       assert(h);
+       assert(h->ah_handle);
+
+       info.type = volume_type;
+       info.direction = direction;
+
+       if (!h->intf.get_volume_level) {
+               LOGE("Not implemented....");
+               return AUDIO_HAL_ERROR;
+       }
+
+       ret = h->intf.get_volume_level(h->ah_handle, &info, level);
+       if (ret != AUDIO_RET_OK) {
+               LOGE("get_volume_level returns error:0x%x", ret);
+               return AUDIO_HAL_ERROR;
+       }
+
+       return AUDIO_HAL_SUCCESS;
+}
+
+int32_t audio_hal_interface_set_volume_level(audio_hal_interface *h,
+                                                                                       const char *volume_type,
+                                                                                       io_direction_t direction,
+                                                                                       uint32_t level)
+{
+       audio_return_t ret = AUDIO_RET_OK;
+       audio_volume_info_t info = { NULL, NULL, 0 };
+
+       assert(h);
+       assert(h->ah_handle);
+
+       info.type = volume_type;
+       info.direction = direction;
+
+       if (!h->intf.set_volume_level) {
+               LOGE("Not implemented....");
+               return AUDIO_HAL_ERROR;
+       }
+
+       ret = h->intf.set_volume_level(h->ah_handle, &info, level);
+       if (ret != AUDIO_RET_OK) {
+               LOGE("set_volume_level returns error:0x%x", ret);
+               return AUDIO_HAL_ERROR;
+       }
+
+       return AUDIO_HAL_SUCCESS;
+}
+
+int32_t audio_hal_interface_get_volume_value(audio_hal_interface *h,
+                                                                                       const char *volume_type,
+                                                                                       const char *gain_type,
+                                                                                       io_direction_t direction,
+                                                                                       uint32_t level,
+                                                                                       double *value)
+{
+       audio_return_t ret = AUDIO_RET_OK;
+       audio_volume_info_t info = { NULL, NULL, 0 };
+
+       assert(h);
+       assert(h->ah_handle);
+
+       info.type = volume_type;
+       info.gain = gain_type;
+       info.direction = direction;
+
+       if (!h->intf.get_volume_value) {
+               LOGE("Not implemented....");
+               return AUDIO_HAL_ERROR;
+       }
+
+       ret = h->intf.get_volume_value(h->ah_handle, &info, level, value);
+       if (ret != AUDIO_RET_OK) {
+               LOGE("get_volume_value returns error:0x%x", ret);
+               return AUDIO_HAL_ERROR;
+       }
+
+       return AUDIO_HAL_SUCCESS;
+}
+
+int32_t audio_hal_interface_get_volume_mute(audio_hal_interface *h,
+                                                                                       const char *volume_type,
+                                                                                       io_direction_t direction,
+                                                                                       uint32_t *mute)
+{
+       audio_return_t ret = AUDIO_RET_OK;
+       audio_volume_info_t info = { NULL, NULL, 0 };
+
+       assert(h);
+       assert(h->ah_handle);
+
+       info.type = volume_type;
+       info.direction = direction;
+
+       if (!h->intf.get_volume_mute) {
+               LOGE("Not implemented....");
+               return AUDIO_HAL_ERROR;
+       }
+
+       ret = h->intf.get_volume_mute(h->ah_handle, &info, mute);
+       if (ret != AUDIO_RET_OK) {
+               LOGE("get_volume_mute returns error:0x%x", ret);
+               return AUDIO_HAL_ERROR;
+       }
+
+       return AUDIO_HAL_SUCCESS;
+}
+
+int32_t audio_hal_interface_set_volume_mute(audio_hal_interface *h,
+                                                                                       const char *volume_type,
+                                                                                       io_direction_t direction,
+                                                                                       uint32_t mute)
+{
+       audio_return_t ret = AUDIO_RET_OK;
+       audio_volume_info_t info = { NULL, NULL, 0 };
+
+       assert(h);
+       assert(h->ah_handle);
+
+       info.type = volume_type;
+       info.direction = direction;
+
+       if (!h->intf.set_volume_mute) {
+               LOGE("Not implemented....");
+               return AUDIO_HAL_ERROR;
+       }
+
+       ret = h->intf.set_volume_mute(h->ah_handle, &info, mute);
+       if (ret != AUDIO_RET_OK) {
+               LOGE("set_volume_mute returns error:0x%x", ret);
+               return AUDIO_HAL_ERROR;
+       }
+
+       return AUDIO_HAL_SUCCESS;
+}
+
+int32_t audio_hal_interface_update_route(audio_hal_interface *h,
+                                                                               hal_route_info *info)
+{
+       audio_return_t ret = AUDIO_RET_OK;
+
+       assert(h);
+       assert(h->ah_handle);
+
+       if (!h->intf.update_route) {
+               LOGE("Not implemented....");
+               return AUDIO_HAL_ERROR;
+       }
+
+       ret = h->intf.update_route(h->ah_handle, (audio_route_info_t *)info);
+       if (ret != AUDIO_RET_OK) {
+               LOGE("update_route returns error:0x%x", ret);
+               return AUDIO_HAL_ERROR;
+       }
+
+       return AUDIO_HAL_SUCCESS;
+}
+
+int32_t audio_hal_interface_update_route_option(audio_hal_interface *h,
+                                                                                               hal_route_option *option)
+{
+       audio_return_t ret = AUDIO_RET_OK;
+
+       assert(h);
+       assert(h->ah_handle);
+
+       if (!h->intf.update_route_option) {
+               LOGE("Not implemented....");
+               return AUDIO_HAL_ERROR;
+       }
+
+       ret = h->intf.update_route_option(h->ah_handle, (audio_route_option_t*)option);
+       if (ret != AUDIO_RET_OK) {
+               LOGE("update_route_option returns error:0x%x", ret);
+               return AUDIO_HAL_ERROR;
+       }
+
+       return AUDIO_HAL_SUCCESS;
+}
+
+int32_t audio_hal_interface_notify_stream_connection_changed(audio_hal_interface *h,
+                                                                                                                       hal_stream_connection_info *info)
+{
+       audio_return_t ret = AUDIO_RET_OK;
+       audio_stream_info_t hal_info;
+       uint32_t is_connected = 0;
+
+       assert(h);
+       assert(h->ah_handle);
+
+       if (info) {
+               hal_info.role = info->role;
+               hal_info.direction = info->direction;
+               hal_info.idx = info->idx;
+               is_connected = info->is_connected;
+       }
+
+       if (!h->intf.notify_stream_connection_changed) {
+               LOGE("Not implemented....");
+               return AUDIO_HAL_ERROR;
+       }
+
+       ret = h->intf.notify_stream_connection_changed(h->ah_handle, &hal_info, is_connected);
+       if (ret != AUDIO_RET_OK) {
+               LOGE("notify_stream_connection_changed returns error:0x%x", ret);
+               return AUDIO_HAL_ERROR;
+       }
+
+       return AUDIO_HAL_SUCCESS;
+}
+
+int32_t audio_hal_interface_pcm_open(audio_hal_interface *h,
+                                                                       const char *card,
+                                                                       const char *device,
+                                                                       io_direction_t direction,
+                                                                       void *sample_spec,
+                                                                       uint32_t period_size,
+                                                                       uint32_t periods,
+                                                                       pcm_handle *pcm_h)
+{
+       audio_return_t ret = AUDIO_RET_OK;
+
+       assert(h);
+       assert(h->ah_handle);
+
+       if (!h->intf.pcm_open) {
+               LOGE("Not implemented....");
+               return AUDIO_HAL_ERROR;
+       }
+
+       ret = h->intf.pcm_open(h->ah_handle, card, device, direction, sample_spec, period_size, periods, pcm_h);
+       if (ret != AUDIO_RET_OK) {
+               LOGE("pcm_open returns error:0x%x", ret);
+               return AUDIO_HAL_ERROR;
+       }
+
+       return AUDIO_HAL_SUCCESS;
+}
+
+int32_t audio_hal_interface_pcm_start(audio_hal_interface *h,
+                                                                       pcm_handle pcm_h)
+{
+       audio_return_t ret = AUDIO_RET_OK;
+
+       assert(h);
+       assert(h->ah_handle);
+
+       if (!h->intf.pcm_start) {
+               LOGE("Not implemented....");
+               return AUDIO_HAL_ERROR;
+       }
+
+       ret = h->intf.pcm_start(h->ah_handle, pcm_h);
+       if (ret != AUDIO_RET_OK) {
+               LOGE("pcm_start returns error:0x%x", ret);
+               return AUDIO_HAL_ERROR;
+       }
+
+       return AUDIO_HAL_SUCCESS;
+}
+
+int32_t audio_hal_interface_pcm_stop(audio_hal_interface *h,
+                                                                       pcm_handle pcm_h)
+{
+       audio_return_t ret = AUDIO_RET_OK;
+
+       assert(h);
+       assert(h->ah_handle);
+
+       if (!h->intf.pcm_stop) {
+               LOGE("Not implemented....");
+               return AUDIO_HAL_ERROR;
+       }
+
+       ret = h->intf.pcm_stop(h->ah_handle, pcm_h);
+       if (ret != AUDIO_RET_OK) {
+               LOGE("pcm_stop returns error:0x%x", ret);
+               return AUDIO_HAL_ERROR;
+       }
+
+       return AUDIO_HAL_SUCCESS;
+}
+
+int32_t audio_hal_interface_pcm_close(audio_hal_interface *h,
+                                                                       pcm_handle pcm_h)
+{
+       audio_return_t ret = AUDIO_RET_OK;
+
+       assert(h);
+       assert(h->ah_handle);
+
+       if (!h->intf.pcm_close) {
+               LOGE("Not implemented....");
+               return AUDIO_HAL_ERROR;
+       }
+
+       ret = h->intf.pcm_close(h->ah_handle, pcm_h);
+       if (ret != AUDIO_RET_OK) {
+               LOGE("pcm_close returns error:0x%x", ret);
+               return AUDIO_HAL_ERROR;
+       }
+
+       return AUDIO_HAL_SUCCESS;
+}
+
+int32_t audio_hal_interface_pcm_available(audio_hal_interface *h,
+                                                                               pcm_handle pcm_h,
+                                                                               uint32_t *available)
+{
+       audio_return_t ret = AUDIO_RET_OK;
+
+       assert(h);
+       assert(h->ah_handle);
+
+       if (!h->intf.pcm_avail) {
+               LOGE("Not implemented....");
+               return AUDIO_HAL_ERROR;
+       }
+
+       ret = h->intf.pcm_avail(h->ah_handle, pcm_h, available);
+       if (ret != AUDIO_RET_OK) {
+               LOGE("pcm_avail returns error:0x%x", ret);
+               return AUDIO_HAL_ERROR;
+       }
+
+       return AUDIO_HAL_SUCCESS;
+}
+
+int32_t audio_hal_interface_pcm_write(audio_hal_interface *h,
+                                                                       pcm_handle pcm_h,
+                                                                       const void *buffer,
+                                                                       uint32_t frames)
+{
+       audio_return_t ret = AUDIO_RET_OK;
+
+       assert(h);
+       assert(h->ah_handle);
+
+       if (!h->intf.pcm_write) {
+               LOGE("Not implemented....");
+               return AUDIO_HAL_ERROR;
+       }
+
+       ret = h->intf.pcm_write(h->ah_handle, pcm_h, buffer, frames);
+       if (ret != AUDIO_RET_OK) {
+               LOGE("pcm_write returns error:0x%x", ret);
+               return AUDIO_HAL_ERROR;
+       }
+
+       return AUDIO_HAL_SUCCESS;
+}
+
+int32_t audio_hal_interface_pcm_read(audio_hal_interface *h,
+                                                                       pcm_handle pcm_h,
+                                                                       void *buffer,
+                                                                       uint32_t frames)
+{
+       audio_return_t ret = AUDIO_RET_OK;
+
+       assert(h);
+       assert(h->ah_handle);
+
+       if (!h->intf.pcm_read) {
+               LOGE("Not implemented....");
+               return AUDIO_HAL_ERROR;
+       }
+
+       ret = h->intf.pcm_read(h->ah_handle, pcm_h, buffer, frames);
+       if (ret != AUDIO_RET_OK) {
+               LOGE("pcm_read returns error:0x%x", ret);
+               return AUDIO_HAL_ERROR;
+       }
+
+       return AUDIO_HAL_SUCCESS;
+}
+
+int32_t audio_hal_interface_pcm_get_fd(audio_hal_interface *h,
+                                                                       pcm_handle pcm_h,
+                                                                       int *fd)
+{
+       audio_return_t ret = AUDIO_RET_OK;
+
+       assert(h);
+       assert(h->ah_handle);
+
+       if (!h->intf.pcm_get_fd) {
+               LOGE("Not implemented....");
+               return AUDIO_HAL_ERROR;
+       }
+
+       ret = h->intf.pcm_get_fd(h->ah_handle, pcm_h, fd);
+       if (ret != AUDIO_RET_OK) {
+               LOGE("pcm_get_fd returns error:0x%x", ret);
+               return AUDIO_HAL_ERROR;
+       }
+
+       return AUDIO_HAL_SUCCESS;
+}
+
+int32_t audio_hal_interface_pcm_recover(audio_hal_interface *h,
+                                                                               pcm_handle pcm_h,
+                                                                               int err)
+{
+       audio_return_t ret = AUDIO_RET_OK;
+
+       assert(h);
+       assert(h->ah_handle);
+
+       if (!h->intf.pcm_recover) {
+               LOGE("Not implemented....");
+               return AUDIO_HAL_ERROR;
+       }
+
+       ret = h->intf.pcm_recover(h->ah_handle, pcm_h, err);
+       if (ret != AUDIO_RET_OK) {
+               LOGE("pcm_recover returns error:0x%x", ret);
+               return AUDIO_HAL_ERROR;
+       }
+
+       return AUDIO_HAL_SUCCESS;
+}
+
+int32_t audio_hal_interface_pcm_get_params(audio_hal_interface *h,
+                                                                               pcm_handle pcm_h,
+                                                                               uint32_t direction,
+                                                                               void **sample_spec,
+                                                                               uint32_t *period_size,
+                                                                               uint32_t *periods)
+{
+       audio_return_t ret = AUDIO_RET_OK;
+
+       assert(h);
+       assert(h->ah_handle);
+
+       if (!h->intf.pcm_get_params) {
+               LOGE("Not implemented....");
+               return AUDIO_HAL_ERROR;
+       }
+
+       ret = h->intf.pcm_get_params(h->ah_handle, pcm_h, direction, sample_spec, period_size, periods);
+       if (ret != AUDIO_RET_OK) {
+               LOGE("pcm_get_params returns error:0x%x", ret);
+               return AUDIO_HAL_ERROR;
+       }
+
+       return AUDIO_HAL_SUCCESS;
+}
+
+int32_t audio_hal_interface_pcm_set_params(audio_hal_interface *h,
+                                                                               pcm_handle pcm_h,
+                                                                               uint32_t direction,
+                                                                               void *sample_spec,
+                                                                               uint32_t period_size,
+                                                                               uint32_t periods)
+{
+       audio_return_t ret = AUDIO_RET_OK;
+
+       assert(h);
+       assert(h->ah_handle);
+
+       if (!h->intf.pcm_set_params) {
+               LOGE("Not implemented....");
+               return AUDIO_HAL_ERROR;
+       }
+
+       ret = h->intf.pcm_set_params(h->ah_handle, pcm_h, direction, sample_spec, period_size, periods);
+       if (ret != AUDIO_RET_OK) {
+               LOGE("pcm_set_params returns error:0x%x", ret);
+               return AUDIO_HAL_ERROR;
+       }
+
+       return AUDIO_HAL_SUCCESS;
+}
+
+int32_t audio_hal_interface_add_message_callback(audio_hal_interface *h,
+                                                                                               hal_message_callback callback,
+                                                                                               void *user_data)
+{
+       audio_return_t ret = AUDIO_RET_OK;
+
+       assert(h);
+       assert(h->ah_handle);
+
+       if (!h->intf.add_message_cb) {
+               LOGE("Not implemented....");
+               return AUDIO_HAL_ERROR;
+       }
+
+       ret = h->intf.add_message_cb(h->ah_handle, (message_cb)callback, user_data);
+       if (ret != AUDIO_RET_OK) {
+               LOGE("add_message_cb returns error:0x%x", ret);
+               return AUDIO_HAL_ERROR;
+       }
+
+       return AUDIO_HAL_SUCCESS;
+}
+
+int32_t audio_hal_interface_remove_message_callback(audio_hal_interface *h,
+                                                                                                       hal_message_callback callback)
+{
+       audio_return_t ret = AUDIO_RET_OK;
+
+       assert(h);
+       assert(h->ah_handle);
+
+       if (!h->intf.remove_message_cb) {
+               LOGE("Not implemented....");
+               return AUDIO_HAL_ERROR;
+       }
+
+       ret = h->intf.remove_message_cb(h->ah_handle, (message_cb)callback);
+       if (ret != AUDIO_RET_OK) {
+               LOGE("remove_message_cb returns error:0x%x", ret);
+               return AUDIO_HAL_ERROR;
+       }
+
+       return AUDIO_HAL_SUCCESS;
+}
index 1d5c729..4c6082d 100644 (file)
@@ -1,3 +1,4 @@
 SUBDIRS = camera \
-         radio
+               radio \
+               audio
 
diff --git a/testcase/audio/Makefile.am b/testcase/audio/Makefile.am
new file mode 100644 (file)
index 0000000..779de11
--- /dev/null
@@ -0,0 +1,18 @@
+# with gtest
+bin_PROGRAMS = audio_haltests
+
+audio_haltests_SOURCES = \
+       audio_haltests.cpp
+
+audio_haltests_CPPFLAGS = \
+       $(DLOG_CFLAGS)\
+       $(SYSTEM_INFO_CFLAGS)\
+       -I$(srcdir)/../../include/audio
+
+audio_haltests_LDADD = \
+       -ldl\
+       -lgtest\
+       $(top_builddir)/src/audio/libaudio_hal_interface.la\
+       $(DLOG_LIBS)\
+       $(SYSTEM_INFO_LIBS)
+
diff --git a/testcase/audio/audio_haltests.cpp b/testcase/audio/audio_haltests.cpp
new file mode 100644 (file)
index 0000000..49fb907
--- /dev/null
@@ -0,0 +1,870 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Seungbae Shin <seungbae.shin@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <string.h>
+#include <unistd.h>
+#include <iostream>
+#include <array>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include <gtest/gtest.h>
+
+#include <audio_hal_interface.h>
+#include <system_info.h>
+
+using namespace std;
+
+typedef enum audio_sample_format {
+       AUDIO_SAMPLE_U8,
+       AUDIO_SAMPLE_ALAW,
+       AUDIO_SAMPLE_ULAW,
+       AUDIO_SAMPLE_S16LE,
+       AUDIO_SAMPLE_S16BE,
+       AUDIO_SAMPLE_FLOAT32LE,
+       AUDIO_SAMPLE_FLOAT32BE,
+       AUDIO_SAMPLE_S32LE,
+       AUDIO_SAMPLE_S32BE,
+       AUDIO_SAMPLE_S24LE,
+       AUDIO_SAMPLE_S24BE,
+       AUDIO_SAMPLE_S24_32LE,
+       AUDIO_SAMPLE_S24_32BE,
+       AUDIO_SAMPLE_MAX,
+       AUDIO_SAMPLE_INVALID = -1
+} audio_sample_format_t;
+
+typedef struct {
+       audio_sample_format_t format;
+       uint32_t rate;
+       uint8_t channels;
+} audio_pcm_sample_spec_t;
+
+
+/*
+ * TestSuite Class
+ */
+class AudioHalTest : public testing::Test
+{
+       public:
+               virtual void SetUp();
+               virtual void TearDown();
+
+       protected:
+               void SetRouteToSpeaker();
+               int32_t WritePcmFromFile(pcm_handle pcm_h, audio_pcm_sample_spec_t *spec);
+               uint32_t BytesToFrames(uint32_t bytes, audio_pcm_sample_spec_t *spec);
+               uint32_t FramesToBytes(uint32_t frames, audio_pcm_sample_spec_t *spec);
+               static void HalMessageCallback(const char *name, int value, void *user_data);
+
+               audio_hal_interface *m_h;
+               const string default_card = "sprdphone";
+               const string default_device = "0";
+
+       private:
+};
+
+void AudioHalTest::SetUp()
+{
+       m_h = nullptr;
+
+       int32_t ret = audio_hal_interface_init(&m_h);
+       if (ret != AUDIO_HAL_SUCCESS)
+               cout << "audio hal init failed : " << ret << endl;
+}
+
+void AudioHalTest::TearDown()
+{
+       if (m_h == nullptr)
+               return;
+
+       int32_t ret = audio_hal_interface_deinit(m_h);
+       if (ret != AUDIO_HAL_SUCCESS)
+               cout << "audio hal deinit failed : " << ret << endl;
+
+       m_h = nullptr;
+}
+
+void AudioHalTest::SetRouteToSpeaker()
+{
+       hal_route_info info;
+       int32_t num_of_devices = 1;
+
+       memset(&info, 0, sizeof(hal_route_info));
+
+       info.role = "media";
+       info.device_infos = (hal_device_info*)malloc(sizeof(hal_device_info) * num_of_devices);
+       if (info.device_infos == nullptr) {
+               cout << "malloc error!!! : " << errno << endl;
+               return;
+       }
+       info.device_infos[0].direction = DIRECTION_OUT;
+       info.device_infos[0].type = "builtin-speaker";
+       info.device_infos[0].id = 100;
+       info.num_of_devices = num_of_devices;
+
+       int32_t ret = audio_hal_interface_update_route(m_h, &info);
+
+       cout << "update route : " << ret << endl;
+
+       free(info.device_infos);
+}
+
+int32_t AudioHalTest::WritePcmFromFile(pcm_handle pcm_h, audio_pcm_sample_spec_t *spec)
+{
+       int32_t ret = AUDIO_HAL_SUCCESS;
+       char buffer[65536];
+
+       const char res_path[] = "/usr/share/testcase/res/audio/dtmf_16le_44100_2ch.raw";
+
+       int fd = open(res_path, O_RDONLY);
+       cout << res_path << ", fd opened : " << fd << endl;
+
+       cout << "start to play dtmf sounds for 5 sec. " << endl;
+
+       while (fd != -1) {
+
+               uint32_t avail_frames = 0;
+               ret = audio_hal_interface_pcm_available(m_h, pcm_h, &avail_frames);
+
+               if (avail_frames == 0) {
+                       usleep(20000); // 20ms
+                       continue;
+               }
+
+               int bytes_read = read(fd, buffer, FramesToBytes(avail_frames, spec));
+               //cout << "avail frames : " << avail_frames << ", read_n : " << bytes_read << endl;
+
+               ret = audio_hal_interface_pcm_write(m_h, pcm_h, buffer, BytesToFrames(bytes_read, spec));
+               if (ret == AUDIO_HAL_ERROR)
+                       break;
+
+               if (bytes_read < static_cast<int>(FramesToBytes(avail_frames, spec))) {
+                       cout << "EOS!!!" << endl;
+                       break;
+               }
+       }
+
+       cout << "Done!!!" << endl;
+
+       if (fd != -1)
+               close(fd);
+
+       return ret;
+}
+
+uint32_t AudioHalTest::BytesToFrames(uint32_t bytes, audio_pcm_sample_spec_t *spec)
+{
+       if (spec->format == AUDIO_SAMPLE_S16LE)
+               return bytes / spec->channels / 2;
+       else
+               return 0; // not supported yet.
+
+}
+
+uint32_t AudioHalTest::FramesToBytes(uint32_t frames, audio_pcm_sample_spec_t *spec)
+{
+       if (spec->format == AUDIO_SAMPLE_S16LE)
+               return frames * spec->channels * 2;
+       else
+               return 0; // not supported yet.
+}
+
+void AudioHalTest::HalMessageCallback(const char *name, int value, void *user_data)
+{
+       cout << name << "," << value << "," << user_data << endl;
+}
+
+/**
+ * @testcase           InitP
+ * @sizen_tizen                4.0
+ * @author                     SR(seungbae.shin)
+ * @reviewer           SR(sc11.lee)
+ * @type                       auto
+ * @description                Positive, Initialize audio HAL handle
+ * @apicovered         audio_init, audio_deinit
+ * @passcase           XXX
+ * @failcase           YYY
+ * @precondition       None
+ * @postcondition      None
+ */
+TEST(AudioHalPreTest, InitP)
+{
+       audio_hal_interface *h = nullptr;
+
+       int32_t ret = audio_hal_interface_init(&h);
+       ASSERT_EQ(ret, AUDIO_HAL_SUCCESS);
+       ASSERT_NE(h, nullptr);
+
+       ret = audio_hal_interface_deinit(h);
+       EXPECT_EQ(ret, AUDIO_HAL_SUCCESS);
+}
+
+/**
+ * @testcase           InitN
+ * @sizen_tizen                4.0
+ * @author                     SR(seungbae.shin)
+ * @reviewer           SR(sc11.lee)
+ * @type                       auto
+ * @description                Negative, Initialize audio HAL handle
+ * @apicovered         audio_init
+ * @passcase           XXX
+ * @failcase           YYY
+ * @precondition       None
+ * @postcondition      None
+ */
+TEST(AudioHalPreTest, InitN)
+{
+       int32_t ret = audio_hal_interface_init(nullptr);
+       ASSERT_EQ(ret, AUDIO_HAL_ERROR);
+}
+
+/**
+ * @testcase           DeinitP
+ * @sizen_tizen                4.0
+ * @author                     SR(seungbae.shin)
+ * @reviewer           SR(sc11.lee)
+ * @type                       auto
+ * @description                Positive, Deinitialize audio HAL handle
+ * @apicovered         audio_init, audio_deinit
+ * @passcase           XXX
+ * @failcase           YYY
+ * @precondition       None
+ * @postcondition      None
+ */
+TEST(AudioHalPreTest, DeinitP)
+{
+       audio_hal_interface *h = nullptr;
+
+       int32_t ret = audio_hal_interface_init(&h);
+       ASSERT_EQ(ret, AUDIO_HAL_SUCCESS);
+       ASSERT_NE(h, nullptr);
+
+       ret = audio_hal_interface_deinit(h);
+       ASSERT_EQ(ret, AUDIO_HAL_SUCCESS);
+}
+
+/**
+ * @testcase           GetVolumeLevelMaxP
+ * @sizen_tizen                4.0
+ * @author                     SR(seungbae.shin)
+ * @reviewer           SR(sc11.lee)
+ * @type                       auto
+ * @description                Positive, Get maximum volume level of each volume types
+ * @apicovered         audio_get_volume_level_max
+ * @passcase           XXX
+ * @failcase           YYY
+ * @precondition       None
+ * @postcondition      None
+ */
+TEST_F(AudioHalTest, GetVolumeLevelMaxP)
+{
+       uint32_t level_max;
+       const array<string, 8> vol_types = { "system", "notification", "alarm", "ringtone",
+                                                                               "media", "call", "voip", "voice" };
+
+       for (const auto& i : vol_types) {
+               int32_t ret = audio_hal_interface_get_volume_level_max(m_h, i.c_str(), DIRECTION_OUT, &level_max);
+               cout << i << " : " << level_max << endl;
+               EXPECT_EQ(ret, AUDIO_HAL_SUCCESS);
+       }
+}
+
+/**
+ * @testcase           GetVolumeLevelMaxN
+ * @sizen_tizen                4.0
+ * @author                     SR(seungbae.shin)
+ * @reviewer           SR(sc11.lee)
+ * @type                       auto
+ * @description                Negative, Get maximum volume level of each volume types
+ * @apicovered         audio_get_volume_level_max
+ * @passcase           XXX
+ * @failcase           YYY
+ * @precondition       None
+ * @postcondition      None
+ */
+TEST_F(AudioHalTest, GetVolumeLevelMaxN)
+{
+       int32_t ret = audio_hal_interface_get_volume_level_max(m_h, "media", DIRECTION_OUT, nullptr);
+       EXPECT_EQ(ret, AUDIO_HAL_ERROR);
+}
+
+/**
+ * @testcase           GetVolumeLevelP
+ * @sizen_tizen                4.0
+ * @author                     SR(seungbae.shin)
+ * @reviewer           SR(sc11.lee)
+ * @type                       auto
+ * @description                Positive, Get volume level of each volume types
+ * @apicovered         audio_get_volume_level
+ * @passcase           XXX
+ * @failcase           YYY
+ * @precondition       None
+ * @postcondition      None
+ */
+TEST_F(AudioHalTest, GetVolumeLevelP)
+{
+       uint32_t level;
+       const array<string, 8> vol_types = { "system", "notification", "alarm", "ringtone",
+                                                                               "media", "call", "voip", "voice" };
+
+       for (const auto& i : vol_types) {
+               int32_t ret = audio_hal_interface_get_volume_level(m_h, i.c_str(), DIRECTION_OUT, &level);
+               cout << i << " : " << level << endl;
+               EXPECT_EQ(ret, AUDIO_HAL_SUCCESS);
+       }
+}
+
+/**
+ * @testcase           GetVolumeLevelN
+ * @sizen_tizen                4.0
+ * @author                     SR(seungbae.shin)
+ * @reviewer           SR(sc11.lee)
+ * @type                       auto
+ * @description                Negative, Get volume level of each volume types
+ * @apicovered         audio_get_volume_level
+ * @passcase           XXX
+ * @failcase           YYY
+ * @precondition       None
+ * @postcondition      None
+ */
+TEST_F(AudioHalTest, GetVolumeLevelN)
+{
+       int32_t ret = audio_hal_interface_get_volume_level(m_h, "media", DIRECTION_OUT, nullptr);
+       EXPECT_EQ(ret, AUDIO_HAL_ERROR);
+}
+
+/**
+ * @testcase           SetVolumeLevelP
+ * @sizen_tizen                4.0
+ * @author                     SR(seungbae.shin)
+ * @reviewer           SR(sc11.lee)
+ * @type                       auto
+ * @description                Positive, Set volume level of each volume types
+ * @apicovered         audio_set_volume_level
+ * @passcase           XXX
+ * @failcase           YYY
+ * @precondition       None
+ * @postcondition      None
+ */
+TEST_F(AudioHalTest, SetVolumeLevelP)
+{
+       /* FIXME : need to revise */
+       int32_t ret = audio_hal_interface_set_volume_level(m_h, "media", DIRECTION_OUT, 15);
+       EXPECT_EQ(ret, AUDIO_HAL_SUCCESS);
+
+       ret = audio_hal_interface_set_volume_level(m_h, "media", DIRECTION_OUT, 7);
+       EXPECT_EQ(ret, AUDIO_HAL_SUCCESS);
+}
+
+
+/**
+ * @testcase           SetVolumeLevelN
+ * @sizen_tizen                4.0
+ * @author                     SR(seungbae.shin)
+ * @reviewer           SR(sc11.lee)
+ * @type                       auto
+ * @description                Negative, Set volume level of each volume types
+ * @apicovered         audio_set_volume_level
+ * @passcase           XXX
+ * @failcase           YYY
+ * @precondition       None
+ * @postcondition      None
+ */
+TEST_F(AudioHalTest, SetVolumeLevelN)
+{
+       int32_t ret = audio_hal_interface_set_volume_level(m_h, "media", DIRECTION_OUT, 10000);
+       EXPECT_EQ(ret, AUDIO_HAL_ERROR);
+}
+
+
+/**
+ * @testcase           GetVolumeValueP
+ * @sizen_tizen                4.0
+ * @author                     SR(seungbae.shin)
+ * @reviewer           SR(sc11.lee)
+ * @type                       auto
+ * @description                Positive, Get volume value of each volume types with given volume level
+ * @apicovered         audio_get_volume_value
+ * @passcase           XXX
+ * @failcase           YYY
+ * @precondition       None
+ * @postcondition      None
+ */
+TEST_F(AudioHalTest, GetVolumeValueP)
+{
+       double value;
+
+       int32_t ret = audio_hal_interface_get_volume_value(m_h, "media", nullptr, DIRECTION_OUT, 15, &value);
+       EXPECT_EQ(ret, AUDIO_HAL_SUCCESS);
+
+       cout << "media vol value : " << value << endl;
+}
+
+/**
+ * @testcase           GetVolumeValueN
+ * @sizen_tizen                4.0
+ * @author                     SR(seungbae.shin)
+ * @reviewer           SR(sc11.lee)
+ * @type                       auto
+ * @description                Negative, Get volume value of each volume types with given volume level
+ * @apicovered         audio_get_volume_value
+ * @passcase           XXX
+ * @failcase           YYY
+ * @precondition       None
+ * @postcondition      None
+ */
+TEST_F(AudioHalTest, GetVolumeValueN)
+{
+       int32_t ret = audio_hal_interface_get_volume_value(m_h, "media", nullptr, DIRECTION_OUT, 15, nullptr);
+       EXPECT_EQ(ret, AUDIO_HAL_ERROR);
+}
+
+/**
+ * @testcase           GetVolumeMuteP
+ * @sizen_tizen                4.0
+ * @author                     SR(seungbae.shin)
+ * @reviewer           SR(sc11.lee)
+ * @type                       auto
+ * @description                Positive, Get volume mute of each volume types.
+ * @apicovered         audio_get_volume_mute
+ * @passcase           XXX
+ * @failcase           YYY
+ * @precondition       None
+ * @postcondition      None
+ */
+TEST_F(AudioHalTest, GetVolumeMuteP)
+{
+       uint32_t mute;
+
+       int32_t ret = audio_hal_interface_get_volume_mute(m_h, "media", DIRECTION_OUT, &mute);
+       EXPECT_EQ(ret, AUDIO_HAL_SUCCESS);
+
+       cout << "mute : " << mute << endl;
+}
+
+/**
+ * @testcase           GetVolumeMuteN
+ * @sizen_tizen                4.0
+ * @author                     SR(seungbae.shin)
+ * @reviewer           SR(sc11.lee)
+ * @type                       auto
+ * @description                Negative, Get volume mute of each volume types.
+ * @apicovered         audio_get_volume_mute
+ * @passcase           XXX
+ * @failcase           YYY
+ * @precondition       None
+ * @postcondition      None
+ */
+TEST_F(AudioHalTest, GetVolumeMuteN)
+{
+       int32_t ret = audio_hal_interface_get_volume_mute(m_h, "media", DIRECTION_OUT, nullptr);
+       EXPECT_EQ(ret, AUDIO_HAL_ERROR);
+}
+
+/**
+ * @testcase           SetVolumeMuteP
+ * @sizen_tizen                4.0
+ * @author                     SR(seungbae.shin)
+ * @reviewer           SR(sc11.lee)
+ * @type                       auto
+ * @description                Positive, Set volume mute of each volume types.
+ * @apicovered         audio_set_volume_mute
+ * @passcase           XXX
+ * @failcase           YYY
+ * @precondition       None
+ * @postcondition      None
+ */
+TEST_F(AudioHalTest, SetVolumeMuteP)
+{
+       int32_t ret = audio_hal_interface_set_volume_mute(m_h, "media", DIRECTION_OUT, 1);
+       EXPECT_EQ(ret, AUDIO_HAL_SUCCESS);
+
+       ret = audio_hal_interface_set_volume_mute(m_h, "media", DIRECTION_OUT, 0);
+       EXPECT_EQ(ret, AUDIO_HAL_SUCCESS);
+}
+
+#if 0 // can't test because mute is not implemented yet...
+TEST_F(AudioHalTest, SetVolumeMuteN)
+{
+       int32_t ret = audio_hal_interface_set_volume_mute(m_h, "media", DIRECTION_OUT, 10000);
+       EXPECT_EQ(ret, AUDIO_HAL_ERROR);
+}
+#endif
+
+/**
+ * @testcase           UpdateRouteP
+ * @sizen_tizen                4.0
+ * @author                     SR(seungbae.shin)
+ * @reviewer           SR(sc11.lee)
+ * @type                       auto
+ * @description                Positive, Update route
+ * @apicovered         audio_update_route
+ * @passcase           XXX
+ * @failcase           YYY
+ * @precondition       None
+ * @postcondition      None
+ */
+TEST_F(AudioHalTest, UpdateRouteP)
+{
+       hal_route_info info;
+       int32_t num_of_devices = 1;
+
+       memset(&info, 0, sizeof(hal_route_info));
+
+       info.role = "media";
+       info.device_infos = (hal_device_info*)malloc(sizeof(hal_device_info) * num_of_devices);
+       ASSERT_NE(info.device_infos, nullptr);
+       info.device_infos[0].direction = DIRECTION_OUT;
+       info.device_infos[0].type = "builtin-speaker";
+       info.device_infos[0].id = 100;
+       info.num_of_devices = num_of_devices;
+
+       int32_t ret = audio_hal_interface_update_route(m_h, &info);
+       EXPECT_EQ(ret, AUDIO_HAL_SUCCESS);
+
+       free(info.device_infos);
+}
+
+
+/**
+ * @testcase           UpdateRouteN
+ * @sizen_tizen                4.0
+ * @author                     SR(seungbae.shin)
+ * @reviewer           SR(sc11.lee)
+ * @type                       auto
+ * @description                Negative, Update route
+ * @apicovered         audio_update_route
+ * @passcase           XXX
+ * @failcase           YYY
+ * @precondition       None
+ * @postcondition      None
+ */
+TEST_F(AudioHalTest, UpdateRouteN)
+{
+       int32_t ret = audio_hal_interface_update_route(m_h, nullptr);
+       EXPECT_EQ(ret, AUDIO_HAL_ERROR);
+
+       hal_route_info info;
+       memset(&info, 0, sizeof(hal_route_info));
+       info.role = nullptr;
+       ret = audio_hal_interface_update_route(m_h, &info);
+       EXPECT_EQ(ret, AUDIO_HAL_ERROR);
+}
+
+/**
+ * @testcase           UpdateRouteOptionP
+ * @sizen_tizen                4.0
+ * @author                     SR(seungbae.shin)
+ * @reviewer           SR(sc11.lee)
+ * @type                       auto
+ * @description                Positive, Update route option
+ * @apicovered         audio_update_route_option
+ * @passcase           XXX
+ * @failcase           YYY
+ * @precondition       None
+ * @postcondition      None
+ */
+TEST_F(AudioHalTest, UpdateRouteOptionP)
+{
+       hal_route_option option;
+
+       int32_t ret = audio_hal_interface_update_route_option(m_h, &option);
+       EXPECT_EQ(ret, AUDIO_HAL_SUCCESS);
+}
+
+
+/**
+ * @testcase           UpdateRouteOptionN
+ * @sizen_tizen                4.0
+ * @author                     SR(seungbae.shin)
+ * @reviewer           SR(sc11.lee)
+ * @type                       auto
+ * @description                Negative, Update route option
+ * @apicovered         audio_update_route_option
+ * @passcase           XXX
+ * @failcase           YYY
+ * @precondition       None
+ * @postcondition      None
+ */
+TEST_F(AudioHalTest, UpdateRouteOptionN)
+{
+       int32_t ret = audio_hal_interface_update_route_option(m_h, nullptr);
+       EXPECT_EQ(ret, AUDIO_HAL_ERROR);
+}
+
+/**
+ * @testcase           NotifyStreamConnectionChangedP
+ * @sizen_tizen                4.0
+ * @author                     SR(seungbae.shin)
+ * @reviewer           SR(sc11.lee)
+ * @type                       auto
+ * @description                Positive, Notify stream connection changed
+ * @apicovered         audio_notify_stream_connection_changed
+ * @passcase           XXX
+ * @failcase           YYY
+ * @precondition       None
+ * @postcondition      None
+ */
+TEST_F(AudioHalTest, NotifyStreamConnectionChangedP)
+{
+       hal_stream_connection_info info;
+
+       memset(&info, 0, sizeof(hal_stream_connection_info));
+       info.role = "media";
+       info.direction = DIRECTION_OUT;
+       info.idx = 100;
+       info.is_connected = true;
+
+       int32_t ret = audio_hal_interface_notify_stream_connection_changed(m_h, &info);
+       EXPECT_EQ(ret, AUDIO_HAL_SUCCESS);
+}
+
+/**
+ * @testcase           NotifyStreamConnectionChangedN
+ * @sizen_tizen                4.0
+ * @author                     SR(seungbae.shin)
+ * @reviewer           SR(sc11.lee)
+ * @type                       auto
+ * @description                Negative, Notify stream connection changed
+ * @apicovered         audio_notify_stream_connection_changed
+ * @passcase           XXX
+ * @failcase           YYY
+ * @precondition       None
+ * @postcondition      None
+ */
+TEST_F(AudioHalTest, NotifyStreamConnectionChangedN)
+{
+       // check for nullptr ptr
+       int32_t ret = audio_hal_interface_notify_stream_connection_changed(m_h, nullptr);
+       EXPECT_EQ(ret, AUDIO_HAL_ERROR);
+
+       // check for invalid role
+       hal_stream_connection_info info;
+       memset(&info, 0, sizeof(hal_stream_connection_info));
+       info.role = nullptr;
+       info.direction = DIRECTION_OUT;
+       info.idx = 100;
+       info.is_connected = true;
+
+       ret = audio_hal_interface_notify_stream_connection_changed(m_h, &info);
+       EXPECT_EQ(ret, AUDIO_HAL_ERROR);
+}
+
+/**
+ * @testcase           MessageCallbackP
+ * @sizen_tizen                4.0
+ * @author                     SR(seungbae.shin)
+ * @reviewer           SR(sc11.lee)
+ * @type                       auto
+ * @description                Positive, add/remove message callback
+ * @apicovered         audio_add_message_cb, audio_remove_message_cb
+ * @passcase           XXX
+ * @failcase           YYY
+ * @precondition       None
+ * @postcondition      None
+ */
+TEST_F(AudioHalTest, MessageCallbackP)
+{
+       int32_t ret = audio_hal_interface_add_message_callback(m_h, HalMessageCallback, nullptr);
+       ASSERT_EQ(ret, AUDIO_HAL_SUCCESS);
+
+       ret = audio_hal_interface_remove_message_callback(m_h, HalMessageCallback);
+       EXPECT_EQ(ret, AUDIO_HAL_SUCCESS);
+}
+
+/**
+ * @testcase           MessageCallbackN
+ * @sizen_tizen                4.0
+ * @author                     SR(seungbae.shin)
+ * @reviewer           SR(sc11.lee)
+ * @type                       auto
+ * @description                Negative, add/remove message callback
+ * @apicovered         audio_add_message_cb, audio_remove_message_cb
+ * @passcase           XXX
+ * @failcase           YYY
+ * @precondition       None
+ * @postcondition      None
+ */
+TEST_F(AudioHalTest, MessageCallbackN)
+{
+       int32_t ret = audio_hal_interface_add_message_callback(m_h, nullptr, nullptr);
+       EXPECT_EQ(ret, AUDIO_HAL_ERROR);
+
+       ret = audio_hal_interface_remove_message_callback(m_h, nullptr);
+       EXPECT_EQ(ret, AUDIO_HAL_ERROR);
+}
+
+
+/**
+ * @testcase           PcmGetFdP
+ * @sizen_tizen                4.0
+ * @author                     SR(seungbae.shin)
+ * @reviewer           SR(sc11.lee)
+ * @type                       auto
+ * @description                Positive, get fd from the pcm handle
+ * @apicovered         audio_pcm_get_fd, audio_pcm_open, audio_pcm_close
+ * @passcase           XXX
+ * @failcase           YYY
+ * @precondition       None
+ * @postcondition      None
+ */
+TEST_F(AudioHalTest, PcmGetFdP)
+{
+       pcm_handle pcm_h = nullptr;
+
+       audio_pcm_sample_spec_t sample_spec;
+       sample_spec.format = AUDIO_SAMPLE_S16LE;
+       sample_spec.rate = 44100;
+       sample_spec.channels = 2;
+
+       SetRouteToSpeaker();
+
+       int32_t ret = audio_hal_interface_pcm_open(m_h, default_card.c_str(), default_device.c_str(), DIRECTION_OUT, &sample_spec,
+                                                                                       BytesToFrames(6400, &sample_spec), 5, &pcm_h);
+       ASSERT_EQ(ret, AUDIO_HAL_SUCCESS);
+
+       int pcm_fd = 0;
+       ret = audio_hal_interface_pcm_get_fd(m_h, pcm_h, &pcm_fd);
+       EXPECT_EQ(ret, AUDIO_HAL_SUCCESS);
+       cout << "pcm fd : " << pcm_fd << endl;
+
+       ret = audio_hal_interface_pcm_close(m_h, pcm_h);
+       EXPECT_EQ(ret, AUDIO_HAL_SUCCESS);
+}
+
+/**
+ * @testcase           PcmGetFdN
+ * @sizen_tizen                4.0
+ * @author                     SR(seungbae.shin)
+ * @reviewer           SR(sc11.lee)
+ * @type                       auto
+ * @description                Negative, get fd from the pcm handle
+ * @apicovered         audio_pcm_get_fd, audio_pcm_open, audio_pcm_close
+ * @passcase           XXX
+ * @failcase           YYY
+ * @precondition       None
+ * @postcondition      None
+ */
+TEST_F(AudioHalTest, PcmGetFdN)
+{
+       // check for pcm handle
+       int pcm_fd = 0;
+       int32_t ret = audio_hal_interface_pcm_get_fd(m_h, nullptr, &pcm_fd);
+       EXPECT_EQ(ret, AUDIO_HAL_ERROR);
+
+       // check for fd
+       pcm_handle pcm_h = nullptr;
+
+       audio_pcm_sample_spec_t sample_spec;
+       sample_spec.format = AUDIO_SAMPLE_S16LE;
+       sample_spec.rate = 44100;
+       sample_spec.channels = 2;
+
+       SetRouteToSpeaker();
+
+       ret = audio_hal_interface_pcm_open(m_h, default_card.c_str(), default_device.c_str(), DIRECTION_OUT, &sample_spec,
+                                                                       BytesToFrames(6400, &sample_spec), 5, &pcm_h);
+       ASSERT_EQ(ret, AUDIO_HAL_SUCCESS);
+
+       ret = audio_hal_interface_pcm_get_fd(m_h, pcm_h, nullptr);
+       EXPECT_EQ(ret, AUDIO_HAL_ERROR);
+
+       ret = audio_hal_interface_pcm_close(m_h, pcm_h);
+       EXPECT_EQ(ret, AUDIO_HAL_SUCCESS);
+}
+
+/**
+ * @testcase           PcmOpenWriteCloseP
+ * @sizen_tizen                4.0
+ * @author                     SR(seungbae.shin)
+ * @reviewer           SR(sc11.lee)
+ * @type                       auto
+ * @description                Positive, open pcm handle, start pcm handle, write pcm buffers, stop pcm handle and close pcm_handle
+ * @apicovered         audio_pcm_open, audio_pcm_start, audio_pcm_avail, audio_pcm_write, audio_pcm_stop, audio_pcm_close
+ * @passcase           XXX
+ * @failcase           YYY
+ * @precondition       None
+ * @postcondition      None
+ */
+TEST_F(AudioHalTest, PcmOpenWriteCloseP)
+{
+       pcm_handle pcm_h = nullptr;
+
+       audio_pcm_sample_spec_t sample_spec;
+       sample_spec.format = AUDIO_SAMPLE_S16LE;
+       sample_spec.rate = 44100;
+       sample_spec.channels = 2;
+
+       SetRouteToSpeaker();
+
+       int32_t ret = audio_hal_interface_pcm_open(m_h, default_card.c_str(), default_device.c_str(), DIRECTION_OUT, &sample_spec,
+                                                                                       BytesToFrames(6400, &sample_spec), 5, &pcm_h);
+       ASSERT_EQ(ret, AUDIO_HAL_SUCCESS);
+
+       ret = audio_hal_interface_pcm_start(m_h, pcm_h);
+       EXPECT_EQ(ret, AUDIO_HAL_SUCCESS);
+
+       ret = WritePcmFromFile(pcm_h, &sample_spec);
+       EXPECT_EQ(ret, AUDIO_HAL_SUCCESS);
+
+       ret = audio_hal_interface_pcm_stop(m_h, pcm_h);
+       EXPECT_EQ(ret, AUDIO_HAL_SUCCESS);
+
+       ret = audio_hal_interface_pcm_close(m_h, pcm_h);
+       EXPECT_EQ(ret, AUDIO_HAL_SUCCESS);
+}
+
+/**
+ * @testcase           PcmRecoverN
+ * @sizen_tizen                4.0
+ * @author                     SR(seungbae.shin)
+ * @reviewer           SR(sc11.lee)
+ * @type                       auto
+ * @description                Negative, pcm recovery
+ * @apicovered         audio_pcm_recover
+ * @passcase           XXX
+ * @failcase           YYY
+ * @precondition       None
+ * @postcondition      None
+ */
+TEST_F(AudioHalTest, PcmRecoverN)
+{
+       int32_t ret = audio_hal_interface_pcm_recover(m_h, nullptr, 0);
+       EXPECT_EQ(ret, AUDIO_HAL_ERROR);
+}
+
+/* // ToDo :
+int32_t audio_hal_interface_pcm_read(audio_hal_interface *h, pcm_handle pcm_h, void *buffer, uint32_t frames);
+*/
+
+/* This is not used */
+#if 0
+int32_t audio_hal_interface_pcm_get_params(audio_hal_interface *h, pcm_handle pcm_h, uint32_t direction, void **sample_spec,
+                                                                               uint32_t *period_size, uint32_t *periods);
+int32_t audio_hal_interface_pcm_set_params(audio_hal_interface *h, pcm_handle pcm_h, uint32_t direction, void *sample_spec,
+                                                                               uint32_t period_size, uint32_t periods);
+#endif
+
+int main(int argc, char **argv)
+{
+       testing::InitGoogleTest(&argc, argv);
+
+       return RUN_ALL_TESTS();
+}
diff --git a/testcase/audio/dtmf_16le_44100_2ch.raw b/testcase/audio/dtmf_16le_44100_2ch.raw
new file mode 100644 (file)
index 0000000..99a20f7
Binary files /dev/null and b/testcase/audio/dtmf_16le_44100_2ch.raw differ