%define tizen_common_feature_callhistory_support 0
%define tizen_common_feature_nbs_support 0
%define tizen_common_feature_tvinputdevice_support 0
+%define tizen_common_feature_voicecontrol_support 0
####################################################################
%define tizen_mobile_feature_tvinputdevice_support 0
+%define tizen_mobile_feature_voicecontrol_support 1
####################################################################
# Wearable Profile : B2 / TW2 #
%define tizen_wearable_feature_inputdevice_support 1
%define tizen_wearable_feature_tvinputdevice_support 0
+%define tizen_wearable_feature_voicecontrol_support 1
+
####################################################################
# TV Profile #
%define tizen_tv_feature_wi_fi_support 1
%define tizen_tv_feature_inputdevice_support 0
%define tizen_tv_feature_tvinputdevice_support 1
+%define tizen_tv_feature_voicecontrol_support 1
# common, or "unified (undefined)"
%define unified_build 1
%define tizen_feature_callhistory_support %{expand:%tizen_%{?profile}_feature_callhistory_support}
%define tizen_feature_nbs_support %{expand:%tizen_%{?profile}_feature_nbs_support}
%define tizen_feature_tvinputdevice_support %{expand:%tizen_%{?profile}_feature_tvinputdevice_support}
+%define tizen_feature_voicecontrol_support %{expand:%tizen_%{?profile}_feature_voicecontrol_support}
%endif
BuildRequires: pkgconfig(security-privilege-manager)
BuildRequires: pkgconfig(widget_service)
%endif
+%if "%{?tizen_feature_voicecontrol_support}" == "1" || "%{?unified_build}" == "1"
+BuildRequires: pkgconfig(voice-control)
+%endif
+
Requires: %{name}-compat = %{version}-%{release}
%if "%{?unified_build}" == "1"
Recommends: %{name}-profile_common = %{version}-%{release}
GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_widget_service_support=%{?tizen_mobile_feature_widget_service_support}"
GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_wi_fi_support=%{?tizen_mobile_feature_wi_fi_support}"
GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_tvinputdevice_support=%{?tizen_mobile_feature_tvinputdevice_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_voicecontrol_support=%{?tizen_mobile_feature_voicecontrol_support}"
./tools/gyp/gyp $GYP_OPTIONS src/tizen-wrt.gyp
GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_widget_service_support=%{?tizen_mobile_feature_widget_service_support}"
GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_wi_fi_support=%{?tizen_mobile_feature_wi_fi_support}"
GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_tvinputdevice_support=%{?tizen_mobile_feature_tvinputdevice_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_voicecontrol_support=%{?tizen_mobile_feature_voicecontrol_support}"
./tools/gyp/gyp $GYP_OPTIONS src/tizen-wrt.gyp
GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_widget_service_support=%{?tizen_wearable_feature_widget_service_support}"
GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_wi_fi_support=%{?tizen_wearable_feature_wi_fi_support}"
GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_tvinputdevice_support=%{?tizen_wearable_feature_tvinputdevice_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_voicecontrol_support=%{?tizen_wearable_feature_voicecontrol_support}"
./tools/gyp/gyp $GYP_OPTIONS src/tizen-wrt.gyp
GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_widget_service_support=%{?tizen_wearable_feature_widget_service_support}"
GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_wi_fi_support=%{?tizen_wearable_feature_wi_fi_support}"
GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_tvinputdevice_support=%{?tizen_wearable_feature_tvinputdevice_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_voicecontrol_support=%{?tizen_wearable_feature_voicecontrol_support}"
./tools/gyp/gyp $GYP_OPTIONS src/tizen-wrt.gyp
GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_widget_service_support=%{?tizen_tv_feature_widget_service_support}"
GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_wi_fi_support=%{?tizen_tv_feature_wi_fi_support}"
GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_tvinputdevice_support=%{?tizen_tv_feature_tvinputdevice_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_voicecontrol_support=%{?tizen_tv_feature_voicecontrol_support}"
./tools/gyp/gyp $GYP_OPTIONS src/tizen-wrt.gyp
GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_widget_service_support=%{?tizen_common_feature_widget_service_support}"
GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_wi_fi_support=%{?tizen_common_feature_wi_fi_support}"
GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_tvinputdevice_support=%{?tizen_common_feature_tvinputdevice_support}"
+GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_voicecontrol_support=%{?tizen_common_feature_voicecontrol_support}"
./tools/gyp/gyp $GYP_OPTIONS src/tizen-wrt.gyp
],
},
],
+ [
+ 'tizen_feature_voicecontrol_support==1', {
+ 'dependencies': [
+ 'voicecontrol/voicecontrol.gyp:*',
+ ],
+ },
+ ],
], # end conditions
},
], # end targets
--- /dev/null
+{
+ 'includes':[
+ '../common/common.gypi',
+ ],
+ 'targets': [
+ {
+ 'target_name': 'tizen_voicecontrol',
+ 'type': 'loadable_module',
+ 'dependencies': [
+ '../common/common.gyp:tizen_common',
+ ],
+ 'sources': [
+ 'voicecontrol_api.js',
+ 'voicecontrol_client.cc',
+ 'voicecontrol_client.h',
+ 'voicecontrol_extension.cc',
+ 'voicecontrol_extension.h',
+ 'voicecontrol_instance.cc',
+ 'voicecontrol_instance.h',
+ 'voicecontrol_util.cc',
+ 'voicecontrol_util.cc'
+ ],
+ 'conditions': [
+ ['tizen == 1', {
+ 'variables': {
+ 'packages': [
+ 'voice-control'
+ ]
+ },
+ }],
+ ],
+ },
+ ],
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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.
+ */
+
+
+var utils_ = xwalk.utils;
+var type_ = utils_.type;
+var converter_ = utils_.converter;
+var validator_ = utils_.validator;
+var types_ = validator_.Types;
+var native_ = new xwalk.utils.NativeManager(extension);
+
+function ListenerManager(native, listenerName, handle) {
+ this.listeners = {};
+ this.nextId = 1;
+ this.nativeSet = false;
+ this.native = native;
+ this.listenerName = listenerName;
+ this.handle = handle || function (msg, listener, watchId) {};
+}
+
+ListenerManager.prototype.addListener = function (callback, nativeCall, data) {
+ var id = this.nextId;
+ if (!this.nativeSet) {
+ this.native.addListener(this.listenerName, function (msg) {
+ for (var watchId in this.listeners) {
+ if (this.listeners.hasOwnProperty(watchId)) {
+ this.handle(msg, this.listeners[watchId], watchId);
+ }
+ }
+ }.bind(this));
+ var result = this.native.callSync(nativeCall, data || {});
+ if (this.native.isFailure(result)) {
+ throw this.native.getErrorObject(result);
+ }
+ this.nativeSet = true;
+ }
+
+ this.listeners[id] = callback;
+ ++this.nextId;
+
+ return id;
+};
+
+ListenerManager.prototype.removeListener = function (watchId, nativeCall) {
+ if (this.listeners.hasOwnProperty(watchId)) {
+ delete this.listeners[watchId];
+ }
+
+ if (this.nativeSet && type_.isEmptyObject(this.listeners)) {
+ this.native.callSync(nativeCall);
+ this.native.removeListener(this.listenerName);
+ this.nativeSet = false;
+ }
+};
+
+var VcResultListener = new ListenerManager(native_, 'onresult', function(result, listener) {
+ listener(result.event, result.list, result.results);
+});
+
+var VcLangListener = new ListenerManager(native_, 'onlanguagechanged', function(result, listener) {
+ listener(result.previous, result.current);
+});
+
+var VoiceControlResultEvent = {
+ SUCCESS: 'SUCCESS',
+ FAILURE: 'FAILURE'
+};
+
+var VoiceControlCommandType = {
+ FOREGROUND: 'FOREGROUND'
+};
+
+function VoiceControlClientManager() {
+}
+
+VoiceControlClientManager.prototype.getVoiceControlClient = function () {
+ var result = native_.callSync('VoiceControlClientManager_getVoiceControlClient', {});
+
+ if (native_.isFailure(result)) {
+ throw native_.getErrorObject(result);
+ }
+
+ return new VoiceControlClient();
+};
+
+function VoiceControlClient() {
+}
+
+VoiceControlClient.prototype.getCurrentLanguage = function () {
+ var result = native_.callSync('VoiceControlClient_getCurrentLanguage', {});
+
+ if (native_.isFailure(result)) {
+ throw native_.getErrorObject(result);
+ }
+
+ return native_.getResultObject(result);
+};
+
+VoiceControlClient.prototype.setCommandList = function (list, type) {
+ var args = validator_.validateArgs(arguments, [
+ {name: 'list', type: types_.ARRAY, values: VoiceControlCommand},
+ {name: 'type', type: types_.ENUM, values: type_.getValues(VoiceControlCommandType), optional: true, nullable: true}
+ ]);
+
+ if (type_.isNullOrUndefined(args.type)) {
+ args.type = VoiceControlCommandType.FOREGROUND;
+ }
+
+ var data = {
+ list: args.list,
+ type: args.type
+ };
+
+ var result = native_.callSync('VoiceControlClient_setCommandList', data);
+
+ if (native_.isFailure(result)) {
+ throw native_.getErrorObject(result);
+ }
+};
+
+VoiceControlClient.prototype.unsetCommandList = function (type) {
+ var args = validator_.validateArgs(arguments, [
+ {name: 'type', type: types_.ENUM, values: type_.getValues(VoiceControlCommandType), optional: true, nullable: true}
+ ]);
+
+ if (type_.isNullOrUndefined(args.type)) {
+ args.type = VoiceControlCommandType.FOREGROUND;
+ }
+
+ var result = native_.callSync('VoiceControlClient_unsetCommandList', {type: args.type});
+
+ if (native_.isFailure(result)) {
+ throw native_.getErrorObject(result);
+ }
+};
+
+VoiceControlClient.prototype.addResultListener = function (listener) {
+ var args = validator_.validateArgs(arguments, [
+ {name: 'listener', type: types_.FUNCTION}
+ ]);
+
+ return VcResultListener.addListener(args.listener, 'VoiceControlClient_addResultListener');
+};
+
+VoiceControlClient.prototype.removeResultListener = function (id) {
+ if (!type_.isNumber(id)) {
+ throw new WebAPIException(WebAPIException.TYPE_MISMATCH_ERR, 'Cannot convert id to int.');
+ }
+
+ var args = validator_.validateArgs(arguments, [
+ {name: 'id', type: types_.LONG}
+ ]);
+
+ VcResultListener.removeListener(args.id, 'VoiceControlClient_removeResultListener');
+};
+
+VoiceControlClient.prototype.addLanguageChangeListener = function (listener) {
+ var args = validator_.validateArgs(arguments, [
+ {name: 'listener', type: types_.FUNCTION}
+ ]);
+
+ return VcLangListener.addListener(args.listener, 'VoiceControlClient_addLanguageChangeListener');
+};
+
+VoiceControlClient.prototype.removeLanguageChangeListener = function (id) {
+ if (!type_.isNumber(id)) {
+ throw new WebAPIException(WebAPIException.TYPE_MISMATCH_ERR, 'Cannot convert id to int.');
+ }
+
+ var args = validator_.validateArgs(arguments, [
+ {name: 'id', type: types_.LONG}
+ ]);
+
+ VcLangListener.removeListener(args.id, 'VoiceControlClient_removeLanguageChangeListener');
+};
+
+VoiceControlClient.prototype.release = function () {
+ var result = native_.callSync('VoiceControlClient_release', {});
+
+ if (native_.isFailure(result)) {
+ throw native_.getErrorObject(result);
+ }
+};
+
+// Constructor of VoiceControlCommand
+function VoiceControlCommand(command, type) {
+ validator_.isConstructorCall(this, VoiceControlCommand);
+
+ var _command = command;
+ var _type = type;
+
+ if (type_.isNullOrUndefined(_type)) {
+ _type = VoiceControlCommandType.FOREGROUND;
+ }
+
+ Object.defineProperties(this,
+ {
+ command: {
+ enumerable: true,
+ get: function () {
+ return _command;
+ },
+ set: function (value) {
+ _command = value;
+ }
+ },
+ type: {
+ enumerable: true,
+ get: function () {
+ return _type;
+ },
+ set: function (value) {
+ if (type_.arrayContains(type_.getValues(VoiceControlCommandType), value)) {
+ _type = value;
+ }
+ }
+ }
+ });
+}
+
+exports = new VoiceControlClientManager();
+tizen.VoiceControlCommand = VoiceControlCommand;
--- /dev/null
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 "voicecontrol/voicecontrol_util.h"
+#include "voicecontrol/voicecontrol_client.h"
+#include <voice_control.h>
+#include <voice_control_internal.h>
+
+#include <functional>
+
+#include "common/picojson.h"
+#include "common/logger.h"
+#include "common/platform_exception.h"
+#include "common/scope_exit.h"
+#include "common/tools.h"
+
+namespace extension {
+namespace voicecontrol {
+
+VoiceControlClient* VoiceControlClient::GetInstance() {
+ ScopeLogger();
+ static VoiceControlClient instance;
+
+ return &instance;
+}
+
+VoiceControlClient::VoiceControlClient() : is_result_cb_set(false), is_lang_cb_set(false) {
+}
+
+VoiceControlClient::~VoiceControlClient() {
+}
+
+int VcConvertCmdType(const std::string &type) {
+ // TODO add switch here when also other types of command will be also supported.
+ // For now, only foreground is supported, we are returning it as default value.
+ return VC_COMMAND_TYPE_FOREGROUND;
+}
+
+common::PlatformResult VoiceControlClient::GetCurrentLanguage(std::string *language) {
+ ScopeLogger();
+
+ char *lang = nullptr;
+ int ret = VC_ERROR_NONE;
+
+ ret = vc_get_current_language(&lang);
+ if (VC_ERROR_NONE != ret) {
+ LoggerE("Fail to get current language");
+ return MakeErrorObject(ret);
+ }
+
+ *language = std::string(lang);
+ free(lang);
+
+ return MakeErrorObject(ret);
+}
+
+common::PlatformResult VoiceControlClient::SetCommandList(const std::vector<picojson::value>& list, const std::string& type) {
+ ScopeLogger();
+
+ int ret = VC_ERROR_NONE;
+ int type_enum = VcConvertCmdType(type);
+
+ vc_cmd_list_h vc_cmd_list = nullptr;
+ SCOPE_EXIT {
+ vc_cmd_list_destroy(vc_cmd_list, true);
+ };
+
+ ret = vc_cmd_list_create(&vc_cmd_list);
+ if (VC_ERROR_NONE != ret) {
+ return MakeErrorObject(ret);
+ }
+
+ for (auto it = list.begin(); it != list.end(); it++) {
+ vc_cmd_h vc_command = nullptr;
+ ret = vc_cmd_create(&vc_command);
+ if (VC_ERROR_NONE != ret) {
+ return MakeErrorObject(ret);
+ }
+
+ std::unique_ptr<std::remove_pointer<vc_cmd_h>::type, int (*)(vc_cmd_h)> ptr(vc_command, &vc_cmd_destroy);
+
+ ret = vc_cmd_set_command(ptr.get(), (*it).get(COMMAND).get<std::string>().c_str());
+ if (VC_ERROR_NONE != ret) {
+ return MakeErrorObject(ret);
+ }
+
+ ret = vc_cmd_set_type(ptr.get(), VcConvertCmdType((*it).get(TYPE).get<std::string>()));
+ if (VC_ERROR_NONE != ret) {
+ return MakeErrorObject(ret);
+ }
+
+ ret = vc_cmd_list_add(vc_cmd_list, ptr.get());
+ if (VC_ERROR_NONE != ret) {
+ return MakeErrorObject(ret);
+ }
+ ptr.release();
+ }
+
+ ret = vc_set_command_list(vc_cmd_list, type_enum);
+ return MakeErrorObject(ret);
+}
+
+common::PlatformResult VoiceControlClient::UnsetCommandList(const std::string& type) {
+ ScopeLogger();
+
+ int ret = VC_ERROR_NONE;
+ int type_enum = VcConvertCmdType(type);
+
+ ret = vc_unset_command_list(type_enum);
+ return MakeErrorObject(ret);
+}
+
+common::PlatformResult VoiceControlClient::AddResultListener() {
+ ScopeLogger();
+
+ is_result_cb_set = true;
+ return MakeErrorObject(VC_ERROR_NONE);
+}
+
+common::PlatformResult VoiceControlClient::RemoveResultListener() {
+ ScopeLogger();
+
+ is_result_cb_set = false;
+ return MakeErrorObject(VC_ERROR_NONE);
+}
+
+common::PlatformResult VoiceControlClient::AddLanguageChangeListener() {
+ ScopeLogger();
+
+ is_lang_cb_set = true;
+ return MakeErrorObject(VC_ERROR_NONE);
+}
+
+common::PlatformResult VoiceControlClient::RemoveLanguageChangeListener() {
+ ScopeLogger();
+
+ is_lang_cb_set = false;
+ return MakeErrorObject(VC_ERROR_NONE);
+}
+
+
+const bool VoiceControlClient::IsResultListenerSet() {
+ ScopeLogger();
+
+ return is_result_cb_set;
+}
+
+const bool VoiceControlClient::IsLanguageChangedListenerSet() {
+ ScopeLogger();
+
+ return is_lang_cb_set;
+}
+
+#undef CHECK_EXIST
+
+} // namespace voicecontrol
+} // namespace extension
--- /dev/null
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef VOICECONTROL_VOICECONTROL_CLIENT_H_
+#define VOICECONTROL_VOICECONTROL_CLIENT_H_
+
+#include "common/extension.h"
+#include <voice_control.h>
+
+namespace extension {
+namespace voicecontrol {
+
+class VoiceControlClient {
+ public:
+ static VoiceControlClient* GetInstance();
+
+ public:
+ VoiceControlClient();
+ ~VoiceControlClient();
+
+ common::PlatformResult GetCurrentLanguage(std::string *language);
+ common::PlatformResult SetCommandList(const std::vector<picojson::value>& list, const std::string& type);
+ common::PlatformResult UnsetCommandList(const std::string& type);
+ common::PlatformResult AddResultListener();
+ common::PlatformResult RemoveResultListener();
+ common::PlatformResult AddLanguageChangeListener();
+ common::PlatformResult RemoveLanguageChangeListener();
+
+ const bool IsResultListenerSet();
+ const bool IsLanguageChangedListenerSet();
+
+ private:
+ bool is_result_cb_set;
+ bool is_lang_cb_set;
+};
+
+} // namespace voicecontrol
+} // namespace extension
+
+#endif // VOICECONTROL_VOICECONTROL_CLIENT_H_
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 "voicecontrol/voicecontrol_extension.h"
+
+#include "voicecontrol/voicecontrol_instance.h"
+
+// This will be generated from voicecontrol_api.js
+extern const char kSource_voicecontrol_api[];
+
+common::Extension* CreateExtension() {
+ return new VoicecontrolExtension;
+}
+
+VoicecontrolExtension::VoicecontrolExtension() {
+ SetExtensionName("tizen.voicecontrol");
+ SetJavaScriptAPI(kSource_voicecontrol_api);
+
+ const char* entry_points[] = {
+ "tizen.VoiceControlCommand",
+ NULL
+ };
+ SetExtraJSEntryPoints(entry_points);
+}
+
+VoicecontrolExtension::~VoicecontrolExtension() {}
+
+common::Instance* VoicecontrolExtension::CreateInstance() {
+ return new extension::voicecontrol::VoiceControlInstance;
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef VOICECONTROL_VOICECONTROL_EXTENSION_H_
+#define VOICECONTROL_VOICECONTROL_EXTENSION_H_
+
+#include "common/extension.h"
+
+class VoicecontrolExtension : public common::Extension {
+ public:
+ VoicecontrolExtension();
+ virtual ~VoicecontrolExtension();
+
+ private:
+ virtual common::Instance* CreateInstance();
+};
+
+#endif // VOICECONTROL_VOICECONTROL_EXTENSION_H_
--- /dev/null
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 "voicecontrol/voicecontrol_instance.h"
+#include "voicecontrol/voicecontrol_client.h"
+#include "voicecontrol/voicecontrol_util.h"
+#include <voice_control.h>
+#include <voice_control_internal.h>
+
+#include <functional>
+
+#include "common/picojson.h"
+#include "common/logger.h"
+#include "common/platform_exception.h"
+#include "common/scope_exit.h"
+#include "common/tools.h"
+
+namespace extension {
+namespace voicecontrol {
+
+namespace {
+// The privileges that are required in Voicecontrol API
+const std::string kPrivilegeVoiceControl = "http://tizen.org/privilege/recorder";
+
+void ReplyAsync(VoiceControlInstance* instance, const std::string& listenerId, bool isSuccess, picojson::object& param) {
+ ScopeLogger();
+ param["listenerId"] = picojson::value(listenerId);
+ param["status"] = picojson::value(isSuccess ? "success" : "error");
+
+ /* All callback functions are called by voice control framework */
+ /* Send result from callback to javascript */
+ picojson::value result = picojson::value(param);
+
+ instance->PostMessage(instance, result.serialize().c_str());
+}
+
+
+
+/* Define callback functions for voice control */
+void VcResultCb(vc_result_event_e event, vc_cmd_list_h cmd_list, const char* result, void *user_data) {
+ ScopeLogger();
+ VoiceControlInstance *instance = static_cast<VoiceControlInstance *>(user_data);
+
+ if (nullptr != instance && VoiceControlClient::GetInstance()->IsResultListenerSet()) {
+ LoggerD("VcResultCb");
+ picojson::object param = picojson::object();
+ param["event"] = picojson::value(std::string(((event == VC_RESULT_EVENT_RESULT_SUCCESS) ? "SUCCESS" : "FAILURE")));
+
+ int len = 0;
+ int ret = VC_ERROR_NONE;
+
+ ret = vc_cmd_list_get_count(cmd_list, &len);
+ if (VC_ERROR_NONE != ret) {
+ LoggerE("Fail to get the count of the result list");
+ return;
+ }
+
+ picojson::array& value_vector = param.insert(std::make_pair("list",
+ picojson::value(picojson::array(len)))).first->second.get<picojson::array>();
+
+ ret = vc_cmd_list_first(cmd_list);
+ for (auto i = 0; VC_ERROR_NONE == ret && i < len; i++) {
+ LoggerD("Current (%d), Count (%d)", i, len);
+ vc_cmd_h vc_command = nullptr;
+ char* command = nullptr;
+ SCOPE_EXIT {
+ free(command);
+ };
+
+ ret = vc_cmd_list_get_current(cmd_list, &vc_command);
+ if (VC_ERROR_NONE != ret) {
+ break;
+ }
+ ret = vc_cmd_get_command(vc_command, &command);
+ if (VC_ERROR_NONE != ret) {
+ break;
+ }
+
+ if (nullptr != command) {
+ LoggerD("Command (%s)", command);
+ value_vector[i] = picojson::value(command);
+ }
+
+ ret = vc_cmd_list_next(cmd_list);
+ }
+
+ param["results"] = picojson::value(std::string(result));
+
+ ReplyAsync(instance, ON_RESULT, true, param);
+ }
+}
+
+void VcLanguageChangedCb(const char* previous, const char* current, void* user_data) {
+ ScopeLogger();
+ VoiceControlInstance *instance = static_cast<VoiceControlInstance *>(user_data);
+ if (nullptr != instance && VoiceControlClient::GetInstance()->IsLanguageChangedListenerSet()) {
+ LoggerD("VcLanguageChangedCb");
+ picojson::object param = picojson::object();
+ param["previous"] = picojson::value(std::string(previous));
+ param["current"] = picojson::value(std::string(current));
+
+ ReplyAsync(instance, ON_LANG, true, param);
+ }
+}
+} // namespace
+
+using namespace common;
+using namespace extension::voicecontrol;
+
+VoiceControlInstance::VoiceControlInstance() {
+ using namespace std::placeholders;
+ #define REGISTER_SYNC(c,x) \
+ RegisterSyncHandler(c, std::bind(&VoiceControlInstance::x, this, _1, _2));
+ REGISTER_SYNC("VoiceControlClient_getCurrentLanguage", GetCurrentLanguage);
+ REGISTER_SYNC("VoiceControlClient_setCommandList", SetCommandList);
+ REGISTER_SYNC("VoiceControlClient_unsetCommandList", UnsetCommandList);
+ REGISTER_SYNC("VoiceControlClient_addResultListener", AddResultListener);
+ REGISTER_SYNC("VoiceControlClient_removeResultListener", RemoveResultListener);
+ REGISTER_SYNC("VoiceControlClient_addLanguageChangeListener", AddLanguageChangeListener);
+ REGISTER_SYNC("VoiceControlClient_removeLanguageChangeListener", RemoveLanguageChangeListener);
+ REGISTER_SYNC("VoiceControlClient_release", Release);
+ REGISTER_SYNC("VoiceControlClientManager_getVoiceControlClient", GetVoiceControlClient);
+ #undef REGISTER_SYNC
+}
+
+VoiceControlInstance::~VoiceControlInstance() {
+ int ret = VC_ERROR_NONE;
+ ret = vc_deinitialize();
+ if (VC_ERROR_NONE != ret && VC_ERROR_INVALID_STATE != ret) {
+ LoggerE("Fail to deinitialize voice control, ret(%d)", ret);
+ }
+}
+
+#define CHECK_EXIST(args, name, out) \
+ if (!args.contains(name)) {\
+ ReportError(TypeMismatchException(name + " is required argument"), out);\
+ return;\
+ }
+
+void VoiceControlInstance::GetVoiceControlClient(const picojson::value& args, picojson::object& out) {
+ ScopeLogger();
+
+ CHECK_PRIVILEGE_ACCESS(kPrivilegeVoiceControl, &out);
+
+ int ret = VC_ERROR_NONE;
+ vc_state_e state = VC_STATE_NONE;
+ ret = vc_initialize();
+ if (VC_ERROR_NONE != ret) {
+ LogAndReportError(MakeErrorObject(ret), &out);
+ return;
+ }
+
+ ret = vc_get_state(&state);
+ if (VC_ERROR_NONE != ret) {
+ LogAndReportError(MakeErrorObject(ret), &out);
+ return;
+ }
+
+ if (VC_STATE_READY == state) {
+ LoggerD("VoiceControlClient already initialized");
+ ReportSuccess(out);
+ return;
+ }
+
+ ret = vc_set_result_cb(VcResultCb, this);
+ if (VC_ERROR_NONE != ret) {
+ LogAndReportError(MakeErrorObject(ret), &out);
+ return;
+ }
+
+ ret = vc_set_current_language_changed_cb(VcLanguageChangedCb, this);
+ if (VC_ERROR_NONE != ret) {
+ LogAndReportError(MakeErrorObject(ret), &out);
+ return;
+ }
+
+ ret = vc_prepare_sync();
+ if (VC_ERROR_NONE != ret) {
+ LogAndReportError(MakeErrorObject(ret), &out);
+ return;
+ }
+
+ ReportSuccess(out);
+}
+
+
+void VoiceControlInstance::Release(const picojson::value& args, picojson::object& out) {
+ ScopeLogger();
+ int ret = VC_ERROR_NONE;
+
+ ret = vc_unprepare();
+ if (VC_ERROR_NONE != ret) {
+ LogAndReportError(MakeErrorObject(ret), &out);
+ return;
+ }
+
+ ret = vc_unset_result_cb();
+ if (VC_ERROR_NONE != ret) {
+ LogAndReportError(MakeErrorObject(ret), &out);
+ return;
+ }
+
+ ret = vc_unset_current_language_changed_cb();
+ if (VC_ERROR_NONE != ret) {
+ LogAndReportError(MakeErrorObject(ret), &out);
+ return;
+ }
+
+ ret = vc_deinitialize();
+ if (VC_ERROR_NONE != ret) {
+ LogAndReportError(MakeErrorObject(ret), &out);
+ return;
+ }
+
+ ReportSuccess(out);
+}
+
+void VoiceControlInstance::GetCurrentLanguage(const picojson::value& args, picojson::object& out) {
+ ScopeLogger();
+
+ std::string language;
+ common::PlatformResult result = VoiceControlClient::GetInstance()->GetCurrentLanguage(&language);
+
+ if (result.IsSuccess()) {
+ ReportSuccess(picojson::value(language), out);
+ } else {
+ LogAndReportError(result, &out);
+ }
+}
+
+void VoiceControlInstance::SetCommandList(const picojson::value& args, picojson::object& out) {
+ ScopeLogger();
+ CHECK_PRIVILEGE_ACCESS(kPrivilegeVoiceControl, &out);
+
+ CHECK_EXIST(args, TYPE, out)
+ CHECK_EXIST(args, LIST, out)
+
+ std::string type = args.get(TYPE).get<std::string>();
+ std::vector<picojson::value> list = args.get(LIST).get<picojson::array>();
+
+ common::PlatformResult result = VoiceControlClient::GetInstance()->SetCommandList(list, type);
+
+ if (result.IsSuccess()) {
+ ReportSuccess(out);
+ } else {
+ LogAndReportError(result, &out);
+ }
+}
+
+void VoiceControlInstance::UnsetCommandList(const picojson::value& args, picojson::object& out) {
+ ScopeLogger();
+ CHECK_PRIVILEGE_ACCESS(kPrivilegeVoiceControl, &out);
+
+ CHECK_EXIST(args, TYPE, out)
+
+ std::string type = args.get(TYPE).get<std::string>();
+
+ common::PlatformResult result = VoiceControlClient::GetInstance()->UnsetCommandList(type);
+
+ if (result.IsSuccess()) {
+ ReportSuccess(out);
+ } else {
+ LogAndReportError(result, &out);
+ }
+}
+
+void VoiceControlInstance::AddResultListener(const picojson::value& args, picojson::object& out) {
+ ScopeLogger();
+
+ common::PlatformResult result = VoiceControlClient::GetInstance()->AddResultListener();
+
+ if (result.IsSuccess()) {
+ ReportSuccess(out);
+ } else {
+ LogAndReportError(result, &out);
+ }
+}
+
+void VoiceControlInstance::RemoveResultListener(const picojson::value& args, picojson::object& out) {
+ ScopeLogger();
+
+ common::PlatformResult result = VoiceControlClient::GetInstance()->RemoveResultListener();
+
+ if (result.IsSuccess()) {
+ ReportSuccess(out);
+ } else {
+ LogAndReportError(result, &out);
+ }
+}
+
+void VoiceControlInstance::AddLanguageChangeListener(const picojson::value& args, picojson::object& out) {
+ ScopeLogger();
+
+ common::PlatformResult result = VoiceControlClient::GetInstance()->AddLanguageChangeListener();
+
+ if (result.IsSuccess()) {
+ ReportSuccess(out);
+ } else {
+ LogAndReportError(result, &out);
+ }
+}
+
+void VoiceControlInstance::RemoveLanguageChangeListener(const picojson::value& args, picojson::object& out) {
+ ScopeLogger();
+
+ common::PlatformResult result = VoiceControlClient::GetInstance()->RemoveLanguageChangeListener();
+
+ if (result.IsSuccess()) {
+ ReportSuccess(out);
+ } else {
+ LogAndReportError(result, &out);
+ }
+}
+
+#undef CHECK_EXIST
+
+} // namespace voicecontrol
+} // namespace extension
--- /dev/null
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef VOICECONTROL_VOICECONTROL_INSTANCE_H_
+#define VOICECONTROL_VOICECONTROL_INSTANCE_H_
+
+#include "common/extension.h"
+
+namespace extension {
+namespace voicecontrol {
+
+class VoiceControlInstance : public common::ParsedInstance {
+ public:
+ VoiceControlInstance();
+ virtual ~VoiceControlInstance();
+
+ private:
+ void GetVoiceControlClient(const picojson::value& args, picojson::object& out);
+ void Release(const picojson::value& args, picojson::object& out);
+
+ void GetCurrentLanguage(const picojson::value& args, picojson::object& out);
+ void SetCommandList(const picojson::value& args, picojson::object& out);
+ void UnsetCommandList(const picojson::value& args, picojson::object& out);
+ void AddResultListener(const picojson::value& args, picojson::object& out);
+ void RemoveResultListener(const picojson::value& args, picojson::object& out);
+ void AddLanguageChangeListener(const picojson::value& args, picojson::object& out);
+ void RemoveLanguageChangeListener(const picojson::value& args, picojson::object& out);
+};
+
+} // namespace voicecontrol
+} // namespace extension
+
+#endif // VOICECONTROL_VOICECONTROL_INSTANCE_H_
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 "voicecontrol/voicecontrol_util.h"
+#include <voice_control.h>
+
+namespace extension {
+namespace voicecontrol {
+
+const std::string& MakeErrorMessage(const int ret) {
+ switch (ret) {
+ case VC_ERROR_NONE:
+ return NO_ERROR;
+ case VC_ERROR_INVALID_PARAMETER:
+ return INVALID_PARAMETER;
+ case VC_ERROR_OUT_OF_MEMORY:
+ return OUT_OF_MEMORY;
+ case VC_ERROR_OPERATION_FAILED:
+ case VC_ERROR_INVALID_STATE:
+ return OPERATION_FAILED;
+ case VC_ERROR_PERMISSION_DENIED:
+ return PERMISSION_DENIED;
+ case VC_ERROR_NOT_SUPPORTED:
+ return NOT_SUPPORTED;
+ default:
+ return OPERATION_FAILED;
+ }
+}
+
+common::PlatformResult MakeErrorObject(const int ret) {
+ std::string message = MakeErrorMessage(ret);
+ switch (ret) {
+ case VC_ERROR_NONE:
+ return common::PlatformResult(common::ErrorCode::NO_ERROR);
+ case VC_ERROR_INVALID_PARAMETER:
+ return common::PlatformResult(common::ErrorCode::INVALID_VALUES_ERR, message);
+ case VC_ERROR_PERMISSION_DENIED:
+ return common::PlatformResult(common::ErrorCode::SECURITY_ERR, message);
+ case VC_ERROR_NOT_SUPPORTED:
+ return common::PlatformResult(common::ErrorCode::NOT_SUPPORTED_ERR, message);
+ default:
+ return common::PlatformResult(common::ErrorCode::ABORT_ERR, message);
+ }
+}
+
+} // namespace voicecontrol
+} // namespace extension
--- /dev/null
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef VOICECONTROL_VOICECONTROL_UTIL_H_
+#define VOICECONTROL_VOICECONTROL_UTIL_H_
+
+#include "common/extension.h"
+
+namespace extension {
+namespace voicecontrol {
+
+namespace {
+ /* Error message text */
+ const std::string NO_ERROR = "No error";
+ const std::string INVALID_PARAMETER = "Invalid parameter!";
+ const std::string OUT_OF_MEMORY = "Out of memory!";
+ const std::string OPERATION_FAILED = "Operation failed!";
+ const std::string PERMISSION_DENIED = "Permission denied!";
+ const std::string NOT_SUPPORTED = "Not supported!";
+
+ /* Parameter name */
+ const std::string CALLBACK_ID = "callbackId";
+ const std::string TYPE = "type";
+ const std::string LIST = "list";
+ const std::string COMMAND = "command";
+
+ /* Voice control command type */
+ const std::string FOREGROUND = "FOREGROUND";
+
+ /* Listener types on javascript */
+ const std::string ON_RESULT = "onresult";
+ const std::string ON_LANG = "onlanguagechanged";
+}
+
+ const std::string& MakeErrorMessage(const int ret);
+ common::PlatformResult MakeErrorObject(const int ret);
+
+} // namespace voicecontrol
+} // namespace extension
+
+#endif // VOICECONTROL_VOICECONTROL_UTIL_H_
\ No newline at end of file