Add dependency module for tv
authorJi-hoon Lee <dalton.lee@samsung.com>
Fri, 9 Aug 2019 08:56:37 +0000 (17:56 +0900)
committerJi-hoon Lee <dalton.lee@samsung.com>
Tue, 13 Aug 2019 01:34:43 +0000 (10:34 +0900)
Change-Id: Id6f629870bfc08015cbf63faa7a37bf794942531

packaging/org.tizen.multi-assistant-service.spec
plugins/wakeup-manager/CMakeLists.txt
plugins/wakeup-manager/dependency-tv/CMakeLists.txt [new file with mode: 0644]
plugins/wakeup-manager/dependency-tv/inc/dependency_tv.h [new file with mode: 0644]
plugins/wakeup-manager/dependency-tv/inc/dependency_tv_audio.h [new file with mode: 0644]
plugins/wakeup-manager/dependency-tv/inc/dependency_tv_button.h [new file with mode: 0644]
plugins/wakeup-manager/dependency-tv/src/dependency_tv.cpp [new file with mode: 0644]
plugins/wakeup-manager/dependency-tv/src/dependency_tv_audio.cpp [new file with mode: 0644]
plugins/wakeup-manager/dependency-tv/src/dependency_tv_button.cpp [new file with mode: 0644]
plugins/wakeup-manager/inc/dependency_resolver.h

index ca96f19..958c169 100644 (file)
@@ -61,6 +61,9 @@ LDFLAGS="$LDFLAGS -Wl,-z -Wl,nodelete"
 
 export LDFLAGS
 cmake \
+%if "%{tizen_profile_name}" == "tv"
+      -D_TV_PRODUCT=TRUE \
+%endif
       -DCMAKE_INSTALL_PREFIX=%{_appdir} \
       -DTZ_SYS_RO_SHARE=%TZ_SYS_RO_SHARE \
 
@@ -98,7 +101,11 @@ exit 0
 /usr/share/license/*
 /usr/share/packages/org.tizen.multi-assistant-service.xml
 %{TZ_SYS_RO_SHARE}/multiassistant/libma-wakeup-manager.so
+%if "%{tizen_profile_name}" == "tv"
+%{TZ_SYS_RO_SHARE}/multiassistant/libma-dependency-tv.so
+%else
 %{TZ_SYS_RO_SHARE}/multiassistant/libma-dependency-default.so
+%endif
 %{_appdir}/author-signature.xml
 %{_appdir}/signature1.xml
 #%{_appdir}/lib/*
index 9bb3141..0596fde 100644 (file)
@@ -56,6 +56,9 @@ ENDFOREACH(flag)
 
 
 SET(EXTRA_CXXFLAGS  "${EXTRA_CXXFLAGS} -fPIC -Wall" )
+IF("${_TV_PRODUCT}" STREQUAL "TRUE")
+       SET(EXTRA_CXXFLAGS "${EXTRA_CXXFLAGS} -DTV_PRODUCT")
+ENDIF()
 SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CXXFLAGS} -fPIC -std=c++11 -fvisibility=hidden")
 SET(CMAKE_CXX_FLAGS_DEBUG "-O0 -g")
 
@@ -66,4 +69,8 @@ TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${wmpkgs_LDFLAGS} -ldl ${EXTRA_LDFLAGS})
 MESSAGE("LDFLAG : ${wmpkgs_LDFLAGS}")
 INSTALL(FILES ${CMAKE_SOURCE_DIR}/plugins/wakeup-manager/libma-wakeup-manager.so DESTINATION ${TZ_SYS_RO_SHARE}/multiassistant/)
 
+IF("${_TV_PRODUCT}" STREQUAL "TRUE")
+ADD_SUBDIRECTORY(dependency-tv)
+ELSE()
 ADD_SUBDIRECTORY(dependency-default)
+ENDIF()
diff --git a/plugins/wakeup-manager/dependency-tv/CMakeLists.txt b/plugins/wakeup-manager/dependency-tv/CMakeLists.txt
new file mode 100644 (file)
index 0000000..b89f19a
--- /dev/null
@@ -0,0 +1,62 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(ma-dependency-tv)
+
+SET(PREFIX ${CMAKE_INSTALL_PREFIX})
+SET(PACKAGE ${PROJECT_NAME})
+
+SET(CMAKE_SKIP_BUILD_RPATH TRUE)
+
+INCLUDE_DIRECTORIES(
+       ${CMAKE_SOURCE_DIR}/inc
+       ./inc
+       )
+
+SET(DDPKG_CHECK_MODULES
+       ecore
+       ecore-wl2
+       dlog
+       eina
+       capi-media-sound-manager
+       capi-network-bluetooth
+       capi-network-bluetooth-tv
+       vd-win-util
+       farfield-voice-api
+)
+
+INCLUDE(FindPkgConfig)
+pkg_check_modules(ddpkgs REQUIRED ${DDPKG_CHECK_MODULES})
+MESSAGE("Modules : ${DDPKG_CHECK_MODULES}")
+
+IF("${CMAKE_BUILD_TYPE}" STREQUAL "")
+        SET(CMAKE_BUILD_TYPE "Release")
+ENDIF("${CMAKE_BUILD_TYPE}" STREQUAL "")
+MESSAGE("Build type: ${CMAKE_BUILD_TYPE}")
+
+ADD_DEFINITIONS("-DPREFIX=\"${CMAKE_INSTALL_PREFIX}\"")
+ADD_DEFINITIONS("-DPACKAGE=\"${PACKAGE}\"")
+
+SET(SRCS
+       src/dependency_tv.cpp
+       src/dependency_tv_audio.cpp
+       src/dependency_tv_button.cpp
+)
+
+FOREACH(flag ${ddpkgs_CFLAGS})
+       SET(EXTRA_CXXFLAGS "${EXTRA_CXXFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+
+
+SET(EXTRA_CXXFLAGS  "${EXTRA_CXXFLAGS} -fPIC -Wall" )
+IF("${_TV_PRODUCT}" STREQUAL "TRUE")
+    SET(EXTRA_CXXFLAGS "${EXTRA_CXXFLAGS} -DTV_PRODUCT")
+ENDIF()
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CXXFLAGS} -fPIC -std=c++11 -fvisibility=hidden")
+SET(CMAKE_CXX_FLAGS_DEBUG "-O0 -g")
+
+ADD_LIBRARY(${PROJECT_NAME} SHARED ${SRCS} )
+
+# Install libraries
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${ddpkgs_LDFLAGS} -ldl ${EXTRA_LDFLAGS})
+MESSAGE("LDFLAG : ${ddpkgs_LDFLAGS}")
+INSTALL(FILES ${CMAKE_SOURCE_DIR}/plugins/wakeup-manager/dependency-tv/lib${PACKAGE}.so DESTINATION ${TZ_SYS_RO_SHARE}/multiassistant/)
diff --git a/plugins/wakeup-manager/dependency-tv/inc/dependency_tv.h b/plugins/wakeup-manager/dependency-tv/inc/dependency_tv.h
new file mode 100644 (file)
index 0000000..ef725eb
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2018  Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * 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 _DEPENDENCY_TV_H_
+#define _DEPENDENCY_TV_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef LOG_TAG
+#define LOG_TAG "dependency_tv"
+#endif
+
+typedef enum {
+       WAKEUP_SPEECH_STREAMING_EVENT_FAIL = -1,    /**< Failed */
+       WAKEUP_SPEECH_STREAMING_EVENT_START = 1,    /**< Start event */
+       WAKEUP_SPEECH_STREAMING_EVENT_CONTINUE = 2, /**< Continue event */
+       WAKEUP_SPEECH_STREAMING_EVENT_FINISH = 3    /**< Finish event */
+} wakeup_speech_streaming_event_e;
+
+typedef enum {
+       MA_PLUGIN_EVENT_VOICE_KEY_PRESSED = 0,
+       MA_PLUGIN_EVENT_VOICE_KEY_RELEASED,
+       MA_PLUGIN_EVENT_VOICE_KEY_RELEASED_AFTER_PUSH = MA_PLUGIN_EVENT_VOICE_KEY_RELEASED,
+       MA_PLUGIN_EVENT_VOICE_KEY_RELEASED_AFTER_TAP,
+} ma_plugin_event_e;
+
+typedef void (*mas_dependency_error_cb)(int error, const char* err_msg, void* user_data);
+
+typedef int (*mas_proxy_process_event)(int event, void* data, int len);
+typedef int (*mas_proxy_feed_audio_data)(wakeup_speech_streaming_event_e event, void* buffer, int len);
+
+typedef struct {
+    mas_proxy_process_event                                            process_event;
+       mas_proxy_feed_audio_data                                       feed_audio_data;
+} mas_proxy_interface;
+
+#ifndef EXPORT_API
+       #if defined _WIN32 || defined __CYGWIN__
+       #ifdef BUILDING_DLL
+               #ifdef __GNUC__
+               #define EXPORT_API __attribute__ ((dllexport))
+               #else
+               #define EXPORT_API __declspec(dllexport) // Note: actually gcc seems to also supports this syntax.
+               #endif
+       #else
+               #ifdef __GNUC__
+               #define EXPORT_API __attribute__ ((dllimport))
+               #else
+               #define EXPORT_API __declspec(dllimport) // Note: actually gcc seems to also supports this syntax.
+               #endif
+       #endif
+       #define DLL_LOCAL
+       #else
+       #if __GNUC__ >= 4
+               #define EXPORT_API __attribute__ ((visibility ("default")))
+               #define DLL_LOCAL  __attribute__ ((visibility ("hidden")))
+       #else
+               #define EXPORT_API
+               #define DLL_LOCAL
+       #endif
+       #endif
+#endif
+
+EXPORT_API int mas_dependency_initialize(mas_proxy_interface interfaces, int *dependency_version);
+EXPORT_API int mas_dependency_deinitialize(void);
+EXPORT_API int mas_dependency_set_error_callback(mas_dependency_error_cb callback, void* user_data);
+EXPORT_API int mas_dependency_start_recording(void);
+EXPORT_API int mas_dependency_stop_recording(void);
+EXPORT_API int mas_dependency_change_system_volume(void);
+EXPORT_API int mas_dependency_recover_system_volume(void);
+EXPORT_API int mas_dependency_get_audio_format(int* rate, int* channel, int* audio_type);
+EXPORT_API int mas_dependency_get_audio_source_type(char** type);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _DEPENDENCY_TV_H_ */
diff --git a/plugins/wakeup-manager/dependency-tv/inc/dependency_tv_audio.h b/plugins/wakeup-manager/dependency-tv/inc/dependency_tv_audio.h
new file mode 100644 (file)
index 0000000..fb5437e
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2018  Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * 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 _DEPENDENCY_TV_AUDIO_H_
+#define _DEPENDENCY_TV_AUDIO_H_
+
+void dependency_tv_audio_initialize(mas_proxy_interface interface);
+void dependency_tv_audio_deinitialize();
+
+void dependency_tv_audio_start_recording();
+void dependency_tv_audio_stop_recording();
+
+void dependency_tv_audio_change_system_volume();
+void dependency_tv_audio_recover_system_volume();
+
+void dependency_tv_audio_voice_key_pressed_set(bool pressed);
+
+void dependency_tv_audio_get_audio_format(int* rate, int* channel, int* audio_type);
+
+void dependency_tv_audio_get_audio_source_type(char** type);
+
+#endif //_DEPENDENCY_TV_AUDIO_H_
diff --git a/plugins/wakeup-manager/dependency-tv/inc/dependency_tv_button.h b/plugins/wakeup-manager/dependency-tv/inc/dependency_tv_button.h
new file mode 100644 (file)
index 0000000..a1b1db7
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2018  Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * 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 _DEPENDENCY_TV_BUTTON_H_
+#define _DEPENDENCY_TV_BUTTON_H_
+
+void dependency_tv_button_initialize(mas_proxy_interface interface);
+void dependency_tv_button_deinitialize();
+
+#endif //_DEPENDENCY_TV_BUTTON_H_
diff --git a/plugins/wakeup-manager/dependency-tv/src/dependency_tv.cpp b/plugins/wakeup-manager/dependency-tv/src/dependency_tv.cpp
new file mode 100644 (file)
index 0000000..fc75aae
--- /dev/null
@@ -0,0 +1,70 @@
+#include "dependency_tv.h"
+#include "dependency_tv_audio.h"
+#include "dependency_tv_button.h"
+
+static mas_proxy_interface g_proxy_interface;
+const int g_dependency_version = 1;
+
+int mas_dependency_initialize(mas_proxy_interface interface, int *dependency_version)
+{
+       g_proxy_interface = interface;
+
+       dependency_tv_audio_initialize(interface);
+       dependency_tv_button_initialize(interface);
+
+       if (dependency_version) {
+               *dependency_version = g_dependency_version;
+       }
+
+       return 0;
+}
+
+int mas_dependency_deinitialize(void)
+{
+       dependency_tv_audio_deinitialize();
+       dependency_tv_button_deinitialize();
+
+       return 0;
+}
+
+int mas_dependency_set_error_callback(mas_dependency_error_cb callback, void* user_data)
+{
+       return 0;
+}
+
+int mas_dependency_start_recording(void)
+{
+       dependency_tv_audio_start_recording();
+       return 0;
+}
+
+int mas_dependency_stop_recording(void)
+{
+       dependency_tv_audio_stop_recording();
+       return 0;
+}
+
+int mas_dependency_change_system_volume(void)
+{
+       dependency_tv_audio_change_system_volume();
+       return 0;
+}
+
+int mas_dependency_recover_system_volume()
+{
+       dependency_tv_audio_recover_system_volume();
+       return 0;
+}
+
+int mas_dependency_get_audio_format(int* rate, int* channel, int* audio_type)
+{
+       dependency_tv_audio_get_audio_format(rate, channel, audio_type);
+       return 0;
+}
+
+int mas_dependency_get_audio_source_type(char** type)
+{
+       dependency_tv_audio_get_audio_source_type(type);
+       return 0;
+}
+
diff --git a/plugins/wakeup-manager/dependency-tv/src/dependency_tv_audio.cpp b/plugins/wakeup-manager/dependency-tv/src/dependency_tv_audio.cpp
new file mode 100644 (file)
index 0000000..c648d33
--- /dev/null
@@ -0,0 +1,315 @@
+#include "dependency_tv.h"
+#include "dependency_tv_audio.h"
+
+static bool g_voice_key_pressed = false;
+static mas_proxy_interface g_proxy_interface;
+
+#include <stdlib.h>
+#include <thread>
+#include <atomic>
+#include <chrono>
+
+#include <dlog.h>
+#include <sound_manager.h>
+#include <sound_manager_internal.h>
+
+using namespace std;
+
+#include <bluetooth_product.h>
+#include <farfield-voice-api.h>
+
+#define SMART_CONTROL_EXTEND_CMD       0x03
+#define SMART_CONTROL_START_CMD                0x04
+
+static int g_bt_extend_count;
+static farfield_voice_h g_farfieldvoice_h = NULL;
+
+static sound_stream_info_h g_volume_stream = NULL;
+static virtual_sound_stream_h g_virtual_sound_stream = NULL;
+
+static long get_current_milliseconds_after_epoch()
+{
+       auto now = chrono::system_clock::now();
+       auto now_ms = chrono::time_point_cast<chrono::milliseconds>(now);
+       /* number of milliseconds since the epoch of system_clock */
+       auto value = now_ms.time_since_epoch();
+
+       return value.count();
+}
+
+static void _bt_cb_hid_state_changed(int result, bool connected, const char *remote_address, void *user_data)
+{
+       LOGD("[Recorder] Bluetooth Event [%d] Received address [%s]", result, remote_address);
+       return;
+}
+
+static void _bt_hid_audio_data_receive_cb(bt_hid_voice_data_s *voice_data, void *user_data)
+{
+       static int g_buffer_count = 0;
+       if (nullptr == voice_data) return;
+
+       if (g_voice_key_pressed) {
+               g_proxy_interface.feed_audio_data(WAKEUP_SPEECH_STREAMING_EVENT_CONTINUE,
+                       voice_data->audio_buf, voice_data->length);
+       } else {
+               LOGE("[Recorder ERROR] voice key seems to be already released");
+               return;
+       }
+
+       if (0 == g_buffer_count || 0 == g_buffer_count % 50) {
+               LOGD("[Recorder][%d] Recording... : read_size(%d)", g_buffer_count, voice_data->length);
+
+               if (0 == g_bt_extend_count % 5 && 0 != g_buffer_count) {
+                       const unsigned char input_data[2] = {SMART_CONTROL_EXTEND_CMD, 0x10 };
+                       if (BT_ERROR_NONE != bt_hid_send_rc_command(NULL, input_data, sizeof(input_data))) {
+                               LOGE("[Recorder ERROR] Fail bt_hid_send_rc_command");
+                       } else {
+                               LOGD("[Recorder] Extend bt audio recorder");
+                       }
+               }
+               g_bt_extend_count++;
+
+               if (100000 == g_buffer_count) {
+                       g_buffer_count = 0;
+               }
+       }
+
+       g_buffer_count++;
+
+       return;
+}
+
+static void _ffv_audio_function_cb(void* data, unsigned int length, void* user_data)
+{
+       /* When voice key is pressed, _bt_hid_audio should receive audio data */
+       if (g_voice_key_pressed) return;
+
+       static int g_buffer_count = 0;
+       if (0 == g_buffer_count || 0 == g_buffer_count % 50) {
+               LOGD("[Recorder INFO] farfield audio function callback is invoked");
+
+               if (100000 == g_buffer_count) {
+                       g_buffer_count = 0;
+               }
+       }
+       g_buffer_count++;
+
+       g_proxy_interface.feed_audio_data(WAKEUP_SPEECH_STREAMING_EVENT_CONTINUE,
+               data, length);
+}
+
+void dependency_tv_audio_initialize(mas_proxy_interface interfaces)
+{
+       g_proxy_interface = interfaces;
+
+       bool is_bt_failed = false;
+
+       if (false == is_bt_failed && BT_ERROR_NONE != bt_product_init()) {
+               LOGE("[Recorder ERROR] Fail to init bt");
+               is_bt_failed = true;
+       }
+
+       if (false == is_bt_failed && BT_ERROR_NONE != bt_hid_host_initialize(_bt_cb_hid_state_changed, NULL)) {
+               LOGE("[Recorder ERROR] Fail bt_hid_host_initialize()");
+               is_bt_failed = true;
+       }
+
+       if (false == is_bt_failed && BT_ERROR_NONE != bt_hid_set_audio_data_receive_cb(_bt_hid_audio_data_receive_cb, NULL)) {
+               LOGE("[Recorder ERROR] Fail bt_hid_set_audio_data_receive_cb()");
+               is_bt_failed = true;
+       }
+
+       if (false == is_bt_failed) {
+               LOGD("[Recorder] Bluetooth is available");
+       }
+
+    /*
+       g_farfieldvoice_h = farfield_voice_init();
+       if (NULL == g_farfieldvoice_h) {
+               LOGE("[Recorder ERROR] Fail to init farfield_voice_init");
+       }
+
+       if (g_farfieldvoice_h) {
+               LOGI("[Recorder INFO] Register farfield voice audio callback");
+               farfield_voice_register_audio_cb(g_farfieldvoice_h, _ffv_audio_function_cb, NULL);
+       }
+    */
+}
+
+void dependency_tv_audio_deinitialize()
+{
+       int ret;
+       if (g_virtual_sound_stream) {
+               sound_manager_stop_virtual_stream(g_virtual_sound_stream);
+               ret = sound_manager_destroy_virtual_stream(g_virtual_sound_stream);
+               if (0 != ret) {
+                       LOGE("[Audio ERROR] Fail to destroy virtual stream, ret(%d)", ret);
+               }
+               g_virtual_sound_stream = NULL;
+       }
+
+       if (g_volume_stream) {
+               ret = sound_manager_destroy_stream_information(g_volume_stream);
+               if (0 != ret) {
+                       LOGE("[Audio ERROR] Fail to destroy stream information, ret(%d)", ret);
+               }
+               g_volume_stream = NULL;
+       }
+
+    /*
+       if (NULL != g_farfieldvoice_h) {
+               LOGD("[Recorder INFO] Unregister farfield voice");
+               farfield_voice_unregister_audio_cb(g_farfieldvoice_h);
+               farfield_voice_final(g_farfieldvoice_h);
+               g_farfieldvoice_h = NULL;
+       }
+    */
+
+       bt_hid_unset_audio_data_receive_cb();
+       bt_hid_host_deinitialize();
+       bt_product_deinit();
+}
+
+static void recorder_thread_func()
+{
+       const int FRAME_LENGTH = 160;
+       const int BUFFER_LENGTH = FRAME_LENGTH * 2;
+}
+
+void dependency_tv_audio_start_recording()
+{
+       /* Do not start normal recorder thread if TV_PRODUCT and g_voice_key_pressed,
+               just send bt_hid start message */
+       if (g_voice_key_pressed) {
+               const unsigned char input_data[2] = {SMART_CONTROL_START_CMD, 0x00};
+               int bt_retry = 0;
+               const int max_retry = 5;
+               while (max_retry > bt_retry) {
+                       int ret = bt_hid_send_rc_command(NULL, input_data, sizeof(input_data));
+                       if (BT_ERROR_NONE == ret) {
+                               LOGD("[Recorder] Start bt audio recorder");
+                               break;
+                       } else if (BT_ERROR_NOW_IN_PROGRESS == ret) {
+                               LOGE("[Recorder ERROR] Fail bt_hid_send_rc_command : %d", ret);
+                               this_thread::sleep_for(chrono::milliseconds(50));
+                               bt_retry++;
+                       } else {
+                               break;
+                       }
+               }
+               if (max_retry == bt_retry) {
+                       LOGE("[Recorder ERROR] Fail to start bt audio");
+                       return;
+               }
+
+               g_bt_extend_count = 0;
+       }
+}
+
+void dependency_tv_audio_stop_recording()
+{
+}
+
+
+void dependency_tv_audio_change_system_volume()
+{
+       int ret;
+
+       if (!g_volume_stream) {
+               ret = sound_manager_create_stream_information_internal(SOUND_STREAM_TYPE_VOICE_RECOGNITION_SERVICE, NULL, NULL, &g_volume_stream);
+               if (0 != ret) {
+                       LOGE("[Audio] Fail to create stream information, ret(%d)", ret);
+                       return;
+               }
+       }
+
+       if (!g_virtual_sound_stream) {
+               ret = sound_manager_create_virtual_stream(g_volume_stream, &g_virtual_sound_stream);
+               if (0 != ret) {
+                       if (g_volume_stream) {
+                               sound_manager_destroy_stream_information(g_volume_stream);
+                               g_volume_stream = NULL;
+                       }
+                       LOGE("[Audio ERROR] Fail to create virtual stream, ret(%d)", ret);
+                       return;
+               }
+       }
+       if (g_virtual_sound_stream) {
+               ret = sound_manager_start_virtual_stream(g_virtual_sound_stream);
+               if (0 != ret) {
+                       if (g_virtual_sound_stream) {
+                               sound_manager_destroy_virtual_stream(g_virtual_sound_stream);
+                               g_virtual_sound_stream = NULL;
+                       }
+                       if (g_volume_stream) {
+                               sound_manager_destroy_stream_information(g_volume_stream);
+                               g_volume_stream = NULL;
+                       }
+                       LOGE("[Audio ERROR] Fail to start virtual stream, ret(%d)", ret);
+                       return;
+               }
+       }
+}
+
+void dependency_tv_audio_recover_system_volume()
+{
+       int ret;
+       if (g_virtual_sound_stream) {
+               ret = sound_manager_stop_virtual_stream(g_virtual_sound_stream);
+               if (0 != ret) {
+                       LOGE("[Audio ERROR] Fail to stop virtual stream, ret(%d)", ret);
+               }
+               ret = sound_manager_destroy_virtual_stream(g_virtual_sound_stream);
+               if (0 != ret) {
+                       LOGE("[Audio ERROR] Fail to destroy virtual stream, ret(%d)", ret);
+               }
+               g_virtual_sound_stream = NULL;
+       }
+
+       if (g_volume_stream) {
+               ret = sound_manager_destroy_stream_information(g_volume_stream);
+               if (0 != ret) {
+                       LOGE("[Audio ERROR] Fail to destroy stream information, ret(%d)", ret);
+               }
+               g_volume_stream = NULL;
+       }
+}
+
+void dependency_tv_audio_voice_key_pressed_set(bool pressed)
+{
+       LOGE("ENTER : %d", pressed);
+       if (true == g_voice_key_pressed && false == pressed) {
+               bt_hid_rc_stop_sending_voice(NULL);
+       }
+
+       if (pressed != g_voice_key_pressed) {
+               if (pressed) {
+                       dependency_tv_audio_change_system_volume();
+               } else {
+                       dependency_tv_audio_recover_system_volume();
+               }
+       }
+
+       g_voice_key_pressed = pressed;
+       LOGE("EXIT : %d", g_voice_key_pressed);
+}
+
+void dependency_tv_audio_get_audio_format(int* rate, int* channel, int* audio_type)
+{
+       if (!audio_type || !rate || !channel) {
+               return;
+       }
+       *rate = 16000;
+       *channel = 0;
+       *audio_type = 0;
+}
+
+void dependency_tv_audio_get_audio_source_type(char** type)
+{
+       static char source_type[] = "VC_AUDIO_ID_BLUETOOTH";
+       if (!type) {
+               return;
+       }
+       *type = source_type;
+}
+
diff --git a/plugins/wakeup-manager/dependency-tv/src/dependency_tv_button.cpp b/plugins/wakeup-manager/dependency-tv/src/dependency_tv_button.cpp
new file mode 100644 (file)
index 0000000..350d2fd
--- /dev/null
@@ -0,0 +1,142 @@
+#include "dependency_tv.h"
+#include "dependency_tv_button.h"
+#include "dependency_tv_audio.h"
+
+#include <chrono>
+
+#include <dlog.h>
+
+static mas_proxy_interface g_proxy_interface;
+
+#define EFL_BETA_API_SUPPORT
+
+#include <Ecore_Input.h>
+#include <Ecore_Wl2.h>
+#include <Key_Mode.h>
+
+static Ecore_Event_Handler* _key_down_handler = NULL;
+static Ecore_Event_Handler* _key_up_handler = NULL;
+
+static long get_current_milliseconds_after_epoch()
+{
+       auto now = std::chrono::system_clock::now();
+       auto now_ms = std::chrono::time_point_cast<std::chrono::milliseconds>(now);
+       /* number of milliseconds since the epoch of system_clock */
+       auto value = now_ms.time_since_epoch();
+
+       return value.count();
+}
+
+static Eina_Bool _key_down_cb(void* data, int type, void* event)
+{
+       Ecore_Event_Key *ev = (Ecore_Event_Key *) event;
+       if (ev) {
+               LOGE("KEY[%s], typep[%d]", ev->keyname, type);
+
+               if (ev->keyname && strncmp(ev->keyname, KEY_BT_VOICE, strlen(KEY_BT_VOICE)) == 0 ) {
+                       dependency_tv_audio_voice_key_pressed_set(true);
+                       if (g_proxy_interface.process_event) {
+                               g_proxy_interface.process_event(MA_PLUGIN_EVENT_VOICE_KEY_PRESSED, NULL, 0);
+                       }
+               }
+       }
+
+       return ECORE_CALLBACK_DONE;
+}
+
+static Eina_Bool _key_up_cb(void* data, int type, void* event)
+{
+       Ecore_Event_Key *ev = (Ecore_Event_Key *) event;
+       if (ev) {
+               LOGE("KEY[%s], typep[%d]", ev->keyname, type);
+
+               if (ev->keyname && strncmp(ev->keyname, KEY_BT_VOICE, strlen(KEY_BT_VOICE)) == 0) {
+                       dependency_tv_audio_voice_key_pressed_set(false);
+                       long key_up_time = get_current_milliseconds_after_epoch();
+                       ma_plugin_event_e event = MA_PLUGIN_EVENT_VOICE_KEY_RELEASED_AFTER_PUSH;
+                       if (g_proxy_interface.process_event) {
+                               g_proxy_interface.process_event(event, NULL, 0);
+                       }
+               }
+       }
+       return ECORE_CALLBACK_DONE;
+}
+
+static bool _grab_voice_key(void)
+{
+       Eina_Bool bRet = true;
+       bRet = ecore_wl2_window_keygrab_set(NULL,  KEY_BT_VOICE,  0, 0,  0, ECORE_WL2_WINDOW_KEYGRAB_SHARED);
+       LOGD("ecore_wl2_window_keygrab_set ret[%d] [%s]", bRet, KEY_BT_VOICE);
+       return bRet;
+}
+
+static bool _ungrab_voice_key(void)
+{
+       Eina_Bool bRet = true;
+       bRet = ecore_wl2_window_keygrab_unset(NULL,  KEY_BT_VOICE,      0, 0);
+       LOGD("ecore_wl2_window_keygrab_unset ret[%d] [%s]", bRet, KEY_BT_VOICE);
+       return bRet;
+}
+
+static bool _add_key_cb()
+{
+       if (_key_down_handler == NULL)
+       {
+               LOGE("_key_down_handler");
+               _key_down_handler = ecore_event_handler_add(ECORE_EVENT_KEY_DOWN, _key_down_cb, NULL);
+               if(_key_down_handler == NULL)
+               {
+                       LOGE("_key_down_handler == NULL ");
+               }
+       }
+
+       if (_key_up_handler == NULL)
+       {
+               LOGE("_key_down_handler");
+               _key_up_handler = ecore_event_handler_add(ECORE_EVENT_KEY_UP, _key_up_cb, NULL);
+               if(_key_up_handler == NULL)
+               {
+                       LOGE("_key_up_handler == NULL ");
+               }
+       }
+       return true;
+}
+
+static bool _delete_key_cb(void)
+{
+       LOGE("start");
+       if (_key_down_handler != NULL)
+       {
+               ecore_event_handler_del(_key_down_handler);
+               _key_down_handler = NULL;
+       }
+
+       if (_key_up_handler != NULL)
+       {
+               ecore_event_handler_del(_key_up_handler);
+               _key_up_handler = NULL;
+       }
+       LOGE("end");
+       return true;
+}
+
+void dependency_tv_button_initialize(mas_proxy_interface interface)
+{
+       g_proxy_interface = interface;
+       Ecore_Wl2_Display *_ecore_wl2_display = NULL;
+
+       Eina_Bool bRet = ecore_wl2_init();
+       LOGD("ecore_wl2_init: %d", bRet);
+
+       _ecore_wl2_display = ecore_wl2_display_connect(NULL);
+       LOGD("_ecore_wl2_display: %p", _ecore_wl2_display);
+
+       _grab_voice_key();
+       _add_key_cb();
+}
+
+void dependency_tv_button_deinitialize()
+{
+       _delete_key_cb();
+       _ungrab_voice_key();
+}
index 6d224f8..38e1202 100644 (file)
@@ -48,7 +48,11 @@ int dependency_resolver_get_audio_source_type(char** type);
  *** Definitions for dependencies
  *************************************************************************************/
 #define MAS_DEPENDENCY_DEFAULT_PATH tzplatform_mkpath(tzplatform_getid("TZ_SYS_RO_SHARE"), "multiassistant/")
+#ifdef TV_PRODUCT
+#define MAS_DEPENDENCY_DEFAULT_FILENAME "libma-dependency-tv.so"
+#else
 #define MAS_DEPENDENCY_DEFAULT_FILENAME "libma-dependency-default.so"
+#endif
 #define MAS_DEPENDENCY_MODULE_PATH "db/multi-assistant/dependency_module_path"
 
 #define MAS_DEPENDENCY_FUNC_INITIALIZE "mas_dependency_initialize"