#include <service_app.h>
#include <app_manager.h>
#include <app.h>
+#include <aul.h>
#include <malloc.h>
#include <Ecore.h>
#include <message_port.h>
static const char *g_current_lang = "en_US";
static int g_local_port_id = -1;
+static char g_current_maclient_appid[MAX_APPID_LEN] = {"com.samsung.bixby-voice"};
+static ma_client_s *g_current_maclient = NULL;
+/* The following variable would not be needed when ma_request_speech_data() gets implemented */
+static char g_launching_maclient_appid[MAX_APPID_LEN] = {""};
+
+/* client list */
+static GSList* g_client_list = NULL;
+
+int mas_check_client_available()
+{
+ if (g_current_maclient) {
+ if (g_current_maclient->appid && 0 == strncmp(g_current_maclient_appid, g_current_maclient->appid, MAX_APPID_LEN)) {
+ MAS_LOGD("MA client with appid %s currently seems to be available : %d",
+ g_current_maclient_appid, g_current_maclient->pid);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+int mas_launch_client()
+{
+ app_control_h app_control;
+ int ret = 0;
+
+ MAS_LOGD("Current MA Client appid : %s", g_current_maclient_appid);
+
+ ret = app_control_create(&app_control);
+ if (APP_CONTROL_ERROR_NONE != ret) {
+ MAS_LOGW("app_control_create returned %08x", ret);
+ return -1;
+ }
+
+ ret = app_control_set_operation(app_control, APP_CONTROL_OPERATION_DEFAULT);
+ if (APP_CONTROL_ERROR_NONE != ret) {
+ MAS_LOGW("app_control_set_operation returned %08x", ret);
+ app_control_destroy(app_control);
+ return -1;
+ }
+
+ /* These extra data key/value should be defined somewhere in multi-assistant framework */
+ ret = app_control_add_extra_data(app_control, "request_speech_data", "true");
+ if (APP_CONTROL_ERROR_NONE != ret) {
+ MAS_LOGW("app_control_add_extra_data returned %08x", ret);
+ app_control_destroy(app_control);
+ return -1;
+ }
+
+ ret = app_control_set_app_id(app_control, g_current_maclient_appid);
+ if (APP_CONTROL_ERROR_NONE != ret) {
+ MAS_LOGW("app_control_set_app_id returned %08x", ret);
+ app_control_destroy(app_control);
+ return -1;
+ }
+
+ ret = app_control_send_launch_request(app_control, NULL, NULL);
+ if (APP_CONTROL_ERROR_NONE != ret) {
+ MAS_LOGW ("app_control_send_launch_request returned %08x, app_id=%s", ret, g_current_maclient_appid);
+ }
+ app_control_destroy (app_control);
+
+ if (APP_CONTROL_ERROR_NONE == ret) {
+ strncpy(g_launching_maclient_appid, g_current_maclient_appid, MAX_APPID_LEN);
+ g_launching_maclient_appid[MAX_APPID_LEN - 1] = '\0';
+ }
+
+ return ret;
+}
+
+int ma_client_create(ma_client_s info)
+{
+ ma_client_s* data = NULL;
+
+ data = (ma_client_s*)calloc(1, sizeof(ma_client_s));
+ if (NULL == data) {
+ MAS_LOGE("[ERROR] Fail to allocate memory"); //LCOV_EXCL_LINE
+ return -1;// MA_ERROR_OUT_OF_MEMORY;
+ }
+
+ *data = info;
+
+ g_client_list = g_slist_append(g_client_list, data);
+
+ return 0;
+}
+
+int ma_client_destroy(ma_client_s *client)
+{
+ if (NULL == client) {
+ MAS_LOGE("Input parameter is NULL"); //LCOV_EXCL_LINE
+ return -1;// MA_ERROR_OPERATION_FAILED;
+ }
+
+ g_client_list = g_slist_remove(g_client_list, client);
+
+ free(client);
+ client = NULL;
+
+ return 0;
+}
+
+ma_client_s* ma_client_find_by_appid(const char *appid)
+{
+ if (NULL == appid) {
+ MAS_LOGE("Input parameter is NULL"); //LCOV_EXCL_LINE
+ return -1;// MA_ERROR_OPERATION_FAILED;
+ }
+
+ ma_client_s *data = NULL;
+
+ int count = g_slist_length(g_client_list);
+ int i;
+
+ for (i = 0; i < count; i++) {
+ data = g_slist_nth_data(g_client_list, i);
+
+ if (NULL != data) {
+ if (0 == strncmp(data->appid, appid, MAX_APPID_LEN)) {
+ return data;
+ }
+ }
+ }
+
+ MAS_LOGE("[ERROR] client Not found");
+
+ return NULL;
+}
+
+ma_client_s* ma_client_find_by_pid(int pid)
+{
+ ma_client_s *data = NULL;
+
+ int count = g_slist_length(g_client_list);
+ int i;
+
+ for (i = 0; i < count; i++) {
+ data = g_slist_nth_data(g_client_list, i);
+
+ if (NULL != data) {
+ if (data->pid == pid) {
+ return data;
+ }
+ }
+ }
+
+ MAS_LOGE("[ERROR] client Not found");
+
+ return NULL;
+}
+
int mas_client_initialize(int pid)
{
MAS_LOGD("[Enter] pid(%d)", pid);
+ char appid[MAX_APPID_LEN] = {'\0',};
+ if (AUL_R_OK == aul_app_get_appid_bypid(pid, appid, sizeof(appid))) {
+ appid[MAX_APPID_LEN - 1] = '\0';
+
+ MAS_LOGD("appid for pid %d is : %s", pid, (appid ? appid : "Unknown"));
+
+ /* Remove existing client that has same appid, if there's any */
+ ma_client_s *old_client = NULL;
+ old_client = ma_client_find_by_appid(appid);
+ if (old_client) {
+ ma_client_destroy(old_client);
+ old_client = NULL;
+ }
+
+ /* And remove a client that has same pid also */
+ old_client = ma_client_find_by_pid(pid);
+ if (old_client) {
+ ma_client_destroy(old_client);
+ old_client = NULL;
+ }
+
+ ma_client_s new_client;
+ new_client.pid = pid;
+ strncpy(new_client.appid, appid, MAX_APPID_LEN);
+ new_client.appid[MAX_APPID_LEN - 1] = '\0';
+ ma_client_create(new_client);
+
+ if (0 == strncmp(g_current_maclient_appid, appid, MAX_APPID_LEN)) {
+ g_current_maclient = &new_client;
+ MAS_LOGD("MA client with current maclient appid connected!");
+
+ /* Since the ma_request_speech_data() is not available, we will request speech data here.
+ Need to remove below code when ma_request_speech_data() get implemented.
+ */
+ if (0 == strncmp(g_launching_maclient_appid, appid, MAX_APPID_LEN)) {
+ g_launching_maclient_appid[0] = '\0';
+ mas_client_request_speech_data(pid);
+ }
+ }
+ }
+
return 0;
}
int mas_client_deinitialize(int pid)
{
MAS_LOGD("[Enter] pid(%d)", pid);
-
+ ma_client_s *client = ma_client_find_by_pid(pid);
+ if (client) {
+ ma_client_destroy(client);
+ client = NULL;
+ }
return 0;
}
return ret;
}
+int mas_client_request_speech_data(int pid)
+{
+ int ret = -1;
+ MAS_LOGD("[Enter] pid(%d)", pid);
+
+ char appid[MAX_APPID_LEN] = {'\0',};
+ if (AUL_R_OK == aul_app_get_appid_bypid(pid, appid, sizeof(appid))) {
+ appid[MAX_APPID_LEN - 1] = '\0';
+
+ if (0 == strncmp(g_current_maclient_appid, appid, MAX_APPID_LEN)) {
+ MAS_LOGD("appid %s matches with current MA Client, requesting speech data", appid);
+ ret = wakeup_service_request_speech_data();
+ if (0 != ret) {
+ MAS_LOGE("[ERROR] Fail to request speech data(%d)", ret);
+ }
+ } else {
+ MAS_LOGE("appid %s does not match with current MA Client", appid);
+ }
+ }
+
+ return ret;
+}
+
int mas_client_send_asr_result(int pid, int event, char* asr_result)
{
MAS_LOGD("[Enter] pid(%d), event(%d), asr_result(%s)", pid, event, asr_result);
MAS_LOGE("[ERROR] Fail to send asr result, ret(%d)", ret);
}
- // if final event is , launch assistant app which is invoked with wakeup word.
+ // if final event is , launch assistant app which is invoked with wakeup word.
/* TO_DO */
return ret;
}
{
MAS_LOGD("[Enter] init_wakeup ");
- int ret = mas_dbus_open_connection();
+ int ret = mas_dbus_open_connection();
if (0 != ret) {
MAS_LOGE("[ERROR] Fail to open connection");
}
*/
deinit_message_port();
- int ret = mas_dbus_close_connection();
+ int ret = mas_dbus_close_connection();
if (0 != ret) {
MAS_LOGE("[ERROR] Fail to close connection");
}
bool service_app_create(void *data)
{
- // Todo: add your code here.
+ // Todo: add your code here.
MAS_LOGD("[Enter] Service app create");
void service_app_terminate(void *data)
{
- // Todo: add your code here.
+ // Todo: add your code here.
deinit_wakeup();
- return;
+ return;
}
void service_app_control(app_control_h app_control, void *data)
{
- // Todo: add your code here.
- return;
+ // Todo: add your code here.
+ return;
}
static void
int main(int argc, char* argv[])
{
- char ad[50] = {0,};
+ char ad[50] = {0,};
service_app_lifecycle_callback_s event_callback;
app_event_handler_h handlers[5] = {NULL, };
if (!strcmp((char*)data, "Today's")) {
masc_ui_dbus_send_asr_result(-1, 1, "Today's");
}
- if (!strcmp((char*)data, "weather.")) {
+ if (!strcmp((char*)data, "weather.")) {
masc_ui_dbus_send_asr_result(-1, 0, "Today's weather.");
}
{
MAS_LOGD("[ENTER]");
- int ret = wakeup_service_request_speech_data();
- if (0 != ret) {
- MAS_LOGE("[ERROR] Fail to request speech data(%d)", ret);
+ if (mas_check_client_available()) {
+ int ret = wakeup_service_request_speech_data();
+ if (0 != ret) {
+ MAS_LOGE("[ERROR] Fail to request speech data(%d)", ret);
+ }
+ } else {
+ // Appropriate MA Client not available, trying to launch new one
+ mas_launch_client();
}
MAS_LOGD("END");
return EINA_FALSE;
}
+
static void __wakeup_event_cb(wakeup_service_wakeup_event_e event, const char* wakeup_word, void* user_data)
{
- MAS_LOGD( "[SUCCESS] __wakeup_event_cb is called, event(%d), wakeup_word(%s)", event, wakeup_word);
+ MAS_LOGD("[SUCCESS] __wakeup_event_cb is called, event(%d), wakeup_word(%s)", event, wakeup_word);
int ret = -1;
int retry_cnt = 0;
while (0 != ret) {
}
#endif
- // app control background launch
- /* TO_DO */
- ret = -1;
- retry_cnt = 0;
- while (0 != ret) {
- ret = masc_dbus_send_hello(getpid());
- retry_cnt++;
- if (30 == retry_cnt) {
- MAS_LOGE("[ERROR] Fail to receive reply for hello, ret(%d)", ret);
- break;
- }
- }
-
#if 0 /* + TEST_CODE */
if (WAKEUP_EVENT_SUCCESS == event) {
ecore_thread_main_loop_begin();
ecore_thread_main_loop_end();
}
#endif /* - TEST_CODE */
-
- // if App is already launched, request speech data
- /* TO_DO */
if (WAKEUP_EVENT_SUCCESS == event) {
ecore_thread_main_loop_begin();
- ecore_timer_add(0, __request_speech_data, NULL);
+ ecore_timer_add(0.0f, __request_speech_data, NULL);
ecore_thread_main_loop_end();
}
+
}
static void __speech_streaming_cb(wakeup_service_speech_streaming_event_e event, unsigned char* buffer, int len, void *user_data)