From 5dd2686919d9e95c971791d9ecb02d329e5ad478 Mon Sep 17 00:00:00 2001 From: WonYoung Choi Date: Thu, 14 Jan 2016 19:25:11 +0900 Subject: [PATCH] Add tizen-device module Change-Id: Id008e1e0331811dad605dd58f567014810553837 --- modules/CMakeLists.txt | 1 + modules/tizen-device/CMakeLists.txt | 20 + modules/tizen-device/device_extension.cc | 535 ++++++++++++++++++++++++++ modules/tizen-device/device_extension.h | 79 ++++ modules/tizen-device/package.json | 10 + modules/tizen-device/tizen-device_api.js | 641 +++++++++++++++++++++++++++++++ packaging/jsnative.spec | 9 +- 7 files changed, 1292 insertions(+), 3 deletions(-) create mode 100644 modules/tizen-device/CMakeLists.txt create mode 100644 modules/tizen-device/device_extension.cc create mode 100644 modules/tizen-device/device_extension.h create mode 100644 modules/tizen-device/package.json create mode 100644 modules/tizen-device/tizen-device_api.js diff --git a/modules/CMakeLists.txt b/modules/CMakeLists.txt index 354dae9..dad5c41 100644 --- a/modules/CMakeLists.txt +++ b/modules/CMakeLists.txt @@ -11,3 +11,4 @@ ADD_SUBDIRECTORY(tizen-app-preference) ADD_SUBDIRECTORY(tizen-sound-manager) ADD_SUBDIRECTORY(tizen-notification) ADD_SUBDIRECTORY(tizen-message-port) +ADD_SUBDIRECTORY(tizen-device) diff --git a/modules/tizen-device/CMakeLists.txt b/modules/tizen-device/CMakeLists.txt new file mode 100644 index 0000000..934b69e --- /dev/null +++ b/modules/tizen-device/CMakeLists.txt @@ -0,0 +1,20 @@ +SET(MODULE "tizen-device") + +# Native Module +ADD_MODULE(${MODULE} XWALK + JSAPI + tizen-device_api.js + SRCS + device_extension.cc + DEPENDS + dlog jsoncpp capi-system-device +) + +# Copy Project +INSTALL(FILES package.json + DESTINATION ${GLOBAL_NODE_MODULE_PATH}/${MODULE} +) + +INSTALL(TARGETS ${MODULE} + DESTINATION ${GLOBAL_NODE_MODULE_PATH}/${MODULE} +) \ No newline at end of file diff --git a/modules/tizen-device/device_extension.cc b/modules/tizen-device/device_extension.cc new file mode 100644 index 0000000..3afef5f --- /dev/null +++ b/modules/tizen-device/device_extension.cc @@ -0,0 +1,535 @@ +/* + * Copyright (c) 2016 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 "device_extension.h" + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#ifdef LOG_TAG +#undef LOG_TAG +#endif +#define LOG_TAG "JSNative" + +namespace device { + +xwalk::XWalkExtensionInstance* DeviceExtension::CreateInstance() { + return new DeviceInstance(); +} + +namespace { + +const char* GetErrorMessage(int errcode) { + switch (errcode) { + case DEVICE_ERROR_INVALID_PARAMETER: + return "Invalid parameter"; + case DEVICE_ERROR_PERMISSION_DENIED: + return "Permission denied"; + case DEVICE_ERROR_OPERATION_FAILED: + return "Operation not permitted"; + case DEVICE_ERROR_ALREADY_IN_PROGRESS: + return "Operation already in progress"; + case DEVICE_ERROR_NOT_SUPPORTED: + return "Not supported in this device"; + case DEVICE_ERROR_RESOURCE_BUSY: + return "Device or resource busy"; + case DEVICE_ERROR_NOT_INITIALIZED: + return "Not initialized"; + default: + return "Unknown Error"; + } +} + +const char* GetBatteryLevelString(device_battery_level_e level) { + switch (level) { + case DEVICE_BATTERY_LEVEL_EMPTY: + return "empty"; + case DEVICE_BATTERY_LEVEL_CRITICAL: + return "critical"; + case DEVICE_BATTERY_LEVEL_LOW: + return "low"; + case DEVICE_BATTERY_LEVEL_HIGH: + return "high"; + case DEVICE_BATTERY_LEVEL_FULL: + return "full"; + default: + return "unknown"; + } +} + +const char* GetDisplayStateString(display_state_e state) { + switch (state) { + case DISPLAY_STATE_NORMAL: + return "normal"; + case DISPLAY_STATE_SCREEN_DIM: + return "dim"; + case DISPLAY_STATE_SCREEN_OFF: + return "off"; + default: + return "unknown"; + } +} + +int GetDisplayStateFromString(const std::string& state) { + if (state == "normal") + return DISPLAY_STATE_NORMAL; + else if (state == "dim") + return DISPLAY_STATE_SCREEN_DIM; + else if (state == "off") + return DISPLAY_STATE_SCREEN_OFF; + else + return -1; +} + +int GetPowerLockTypeFromString(const std::string& state) { + if (state == "cpu") { + return POWER_LOCK_CPU; + } else if (state == "normal") { + return POWER_LOCK_DISPLAY; + } else if (state == "dim") { + return POWER_LOCK_DISPLAY_DIM; + } else { + return -1; + } +} + +void DeviceChangedCallback(device_callback_e type, void* value, void* data) { + DeviceInstance* self = reinterpret_cast(data); + if (self == nullptr) { + LOGE("Pointer of DeviceInstance has nullptr"); + return; + } + + Json::Value event; + switch (type) { + case DEVICE_CALLBACK_BATTERY_CAPACITY: + event["event"] = "battery.capacity"; + event["value"] = reinterpret_cast(value); + break; + case DEVICE_CALLBACK_BATTERY_LEVEL: + event["event"] = "battery.level"; + event["value"] = GetBatteryLevelString( + static_cast(reinterpret_cast(value))); + break; + case DEVICE_CALLBACK_BATTERY_CHARGING: + event["event"] = "battery.charging"; + event["value"] = (reinterpret_cast(value) != 0); + break; + case DEVICE_CALLBACK_DISPLAY_STATE: + event["event"] = "display.state"; + event["value"] = GetDisplayStateString( + static_cast(reinterpret_cast(value))); + break; + case DEVICE_CALLBACK_FLASH_BRIGHTNESS: + event["event"] = "flash.brightness"; + event["value"] = reinterpret_cast(value); + break; + default: + event["event"] = "unknown"; + break; + } + + if (event["event"].asString() != "unknown") { + Json::FastWriter writer; + self->PostMessage(writer.write(event).c_str()); + } +} + +} // namespace + +DeviceInstance::DeviceInstance() + : haptic_device_handle_(NULL) { +} + +DeviceInstance::~DeviceInstance() { + if (haptic_device_handle_) { + device_haptic_close(haptic_device_handle_); + } +} + +void DeviceInstance::Initialize() { + // Battery + REGISTER_XWALK_METHOD("battery.isCharging", + this, &DeviceInstance::HandleBatteryIsCharging); + REGISTER_XWALK_METHOD("battery.getCapacity", + this, &DeviceInstance::HandleBatteryGetCapacity); + REGISTER_XWALK_METHOD("battery.getLevel", + this, &DeviceInstance::HandleBatteryGetLevel); + + // Display + REGISTER_XWALK_METHOD("display.getCount", + this, &DeviceInstance::HandleDisplayGetCount); + REGISTER_XWALK_METHOD("display.getState", + this, &DeviceInstance::HandleDisplayGetState); + REGISTER_XWALK_METHOD("display.setState", + this, &DeviceInstance::HandleDisplaySetState); + REGISTER_XWALK_METHOD("display.getMaxBrightness", + this, &DeviceInstance::HandleDisplayGetMaxBrightness); + REGISTER_XWALK_METHOD("display.getBrightness", + this, &DeviceInstance::HandleDisplayGetBrightness); + REGISTER_XWALK_METHOD("display.setBrightness", + this, &DeviceInstance::HandleDisplaySetBrightness); + + // Haptic + REGISTER_XWALK_METHOD("haptic.vibrate", + this, &DeviceInstance::HandleHapticVibrate); + REGISTER_XWALK_METHOD("haptic.cancel", + this, &DeviceInstance::HandleHapticCancel); + + // Flash + REGISTER_XWALK_METHOD("flash.getMaxBrightness", + this, &DeviceInstance::HandleFlashGetMaxBrightness); + REGISTER_XWALK_METHOD("flash.getBrightness", + this, &DeviceInstance::HandleFlashGetBrightness); + REGISTER_XWALK_METHOD("flash.setBrightness", + this, &DeviceInstance::HandleFlashSetBrightness); + + // LED + REGISTER_XWALK_METHOD("led.play", + this, &DeviceInstance::HandleLEDPlay); + REGISTER_XWALK_METHOD("led.stop", + this, &DeviceInstance::HandleLEDStop); + + // Power + REGISTER_XWALK_METHOD("power.request", + this, &DeviceInstance::HandlePowerRequest); + REGISTER_XWALK_METHOD("power.release", + this, &DeviceInstance::HandlePowerRelease); + REGISTER_XWALK_METHOD("power.reboot", + this, &DeviceInstance::HandlePowerReboot); + + InitializeCallbacks(); +} + +void DeviceInstance::InitializeCallbacks() { + if (device_add_callback(DEVICE_CALLBACK_BATTERY_CAPACITY, + DeviceChangedCallback, this) < 0) { + LOGE("Failed to add callback for battery.capacity"); + } + if (device_add_callback(DEVICE_CALLBACK_BATTERY_LEVEL, + DeviceChangedCallback, this) < 0) { + LOGE("Failed to add callback for battery.level"); + } + if (device_add_callback(DEVICE_CALLBACK_BATTERY_CHARGING, + DeviceChangedCallback, this) < 0) { + LOGE("Failed to add callback for battery.charging"); + } + if (device_add_callback(DEVICE_CALLBACK_DISPLAY_STATE, + DeviceChangedCallback, this) < 0) { + LOGE("Failed to add callback for display.state"); + } + if (device_add_callback(DEVICE_CALLBACK_FLASH_BRIGHTNESS, + DeviceChangedCallback, this) < 0) { + LOGE("Failed to add callback for led.brightness"); + } +} + +void DeviceInstance::HandleBatteryIsCharging( + const Json::Value& /*args*/, Json::Value& reply) { + int ret; + bool value; + if ((ret = device_battery_is_charging(&value)) < 0) { + const char* errmsg = GetErrorMessage(ret); + LOGE("Failed to get status of battery charging. %s", errmsg); + reply["error"] = errmsg; + } else { + reply["value"] = value; + } +} + +void DeviceInstance::HandleBatteryGetCapacity( + const Json::Value& /*args*/, Json::Value& reply) { + int ret; + int value; + if ((ret = device_battery_get_percent(&value)) < 0) { + const char* errmsg = GetErrorMessage(ret); + LOGE("Failed to get percentage of battery. %s", errmsg); + reply["error"] = errmsg; + } else { + reply["value"] = value; + } +} + +void DeviceInstance::HandleBatteryGetLevel( + const Json::Value& /*args*/, Json::Value& reply) { + int ret; + device_battery_level_e value; + if ((ret = device_battery_get_level_status(&value)) < 0) { + const char* errmsg = GetErrorMessage(ret); + LOGE("Failed to get level status of battery. %s", errmsg); + reply["error"] = errmsg; + } else { + reply["value"] = GetBatteryLevelString(value); + } +} + +void DeviceInstance::HandleDisplayGetCount( + const Json::Value& /*args*/, Json::Value& reply) { + int ret; + int value; + if ((ret = device_display_get_numbers(&value)) < 0) { + const char* errmsg = GetErrorMessage(ret); + LOGE("Failed to get display count. %s", errmsg); + reply["error"] = errmsg; + } else { + reply["value"] = value; + } +} + +void DeviceInstance::HandleDisplayGetState( + const Json::Value& /*args*/, Json::Value& reply) { + int ret; + display_state_e value; + if ((ret = device_display_get_state(&value)) < 0) { + const char* errmsg = GetErrorMessage(ret); + LOGE("Failed to get display state. %s", errmsg); + reply["error"] = errmsg; + } else { + reply["value"] = GetDisplayStateString(value); + } +} + +void DeviceInstance::HandleDisplayGetMaxBrightness( + const Json::Value& args, Json::Value& reply) { + int ret; + int index = args.get("index", 0).asInt(); + int value; + if ((ret = device_display_get_max_brightness(index, &value)) < 0) { + const char* errmsg = GetErrorMessage(ret); + LOGE("Failed to get max brightness. %s", errmsg); + reply["error"] = errmsg; + } else { + reply["value"] = value; + } +} + +void DeviceInstance::HandleDisplayGetBrightness( + const Json::Value& args, Json::Value& reply) { + int ret; + int index = args.get("index", 0).asInt(); + int value; + if ((ret = device_display_get_brightness(index, &value))< 0) { + const char* errmsg = GetErrorMessage(ret); + LOGE("Failed to get brightness. %s", errmsg); + reply["error"] = errmsg; + } else { + reply["value"] = value; + } +} + +void DeviceInstance::HandleDisplaySetBrightness( + const Json::Value& args, Json::Value& reply) { + int ret; + int index = args.get("index", 0).asInt(); + int value = args.get("value", 0).asInt(); + if ((ret = device_display_set_brightness(index, value)) < 0) { + const char* errmsg = GetErrorMessage(ret); + LOGE("Failed to set brightness. %s", errmsg); + reply["error"] = errmsg; + } +} + +void DeviceInstance::HandleDisplaySetState( + const Json::Value& args, Json::Value& reply) { + + std::string state = args.get("state", "").asString(); + int state_n = GetDisplayStateFromString(state); + if (state_n >= 0) { + int ret; + if ((ret = device_display_change_state( + static_cast(state_n))) < 0) { + const char* errmsg = GetErrorMessage(ret); + LOGE("Failed to change display state. %s", errmsg); + reply["error"] = errmsg; + } + } + + if (reply["error"].isNull()) { + HandleDisplayGetState(args, reply); + } +} + +// async +void DeviceInstance::HandleHapticVibrate( + const Json::Value& args, Json::Value& /*reply*/) { + int duration = args.get("duration", 0).asInt(); + int intensity = args.get("intensity", 0).asInt(); + int count = 0; + int ret; + if ((ret = device_haptic_get_count(&count)) < 0) { + const char* errmsg = GetErrorMessage(ret); + LOGE("Failed to get haptic device count. %s", errmsg); + return; + } + + // If at least one device is available + if (count > 0) { + if (!haptic_device_handle_) { + if ((ret = device_haptic_open(0, &haptic_device_handle_)) < 0) { + const char* errmsg = GetErrorMessage(ret); + LOGE("Failed to open haptic device. %s", errmsg); + return; + } + } + + ret = device_haptic_vibrate(haptic_device_handle_, + duration, intensity, NULL); + if (ret < 0) { + const char* errmsg = GetErrorMessage(ret); + LOGE("Failed to vibrate haptic device. %s", errmsg); + } + } +} + +// async +void DeviceInstance::HandleHapticCancel( + const Json::Value& /*args*/, Json::Value& /*reply*/) { + if (haptic_device_handle_) { + int ret = device_haptic_stop(haptic_device_handle_, NULL); + if (ret < 0) { + const char* errmsg = GetErrorMessage(ret); + LOGE("Failed to stop haptic device. %s", errmsg); + } + + ret = device_haptic_close(haptic_device_handle_); + if (ret < 0) { + const char* errmsg = GetErrorMessage(ret); + LOGE("Failed to close haptic device. %s", errmsg); + } + } +} + +void DeviceInstance::HandleFlashGetMaxBrightness( + const Json::Value& /*args*/, Json::Value& reply) { + int ret; + int value; + if ((ret = device_flash_get_max_brightness(&value)) < 0) { + const char* errmsg = GetErrorMessage(ret); + LOGE("Failed to get max brightness of flash device. %s", errmsg); + reply["error"] = errmsg; + } else { + reply["value"] = value; + } +} + +void DeviceInstance::HandleFlashGetBrightness( + const Json::Value& /*args*/, Json::Value& reply) { + int ret; + int value; + if ((ret = device_flash_get_brightness(&value)) < 0) { + const char* errmsg = GetErrorMessage(ret); + LOGE("Failed to get brightness of flash device. %s", errmsg); + reply["error"] = errmsg; + } else { + reply["value"] = value; + } +} + +void DeviceInstance::HandleFlashSetBrightness( + const Json::Value& args, Json::Value& reply) { + int ret; + int value = args.get("value", 0).asInt(); + if ((ret = device_flash_set_brightness(value)) < 0) { + const char* errmsg = GetErrorMessage(ret); + LOGE("Failed to set brightness of flash device. %s", errmsg); + reply["error"] = errmsg; + } + + if (reply["error"].isNull()) { + HandleFlashGetBrightness(args, reply); + } +} + +// async +void DeviceInstance::HandleLEDPlay( + const Json::Value& args, Json::Value& /*reply*/) { + int timeOn = args.get("timeOn", 0).asInt(); + int timeOff = args.get("timeOff", 0).asInt(); + int color = args.get("color", 0).asInt(); + + int ret; + if ((ret = device_led_play_custom(timeOn, timeOff, color, 0)) < 0) { + const char* errmsg = GetErrorMessage(ret); + LOGE("Failed to play led device. %s", errmsg); + } +} + +// async +void DeviceInstance::HandleLEDStop( + const Json::Value& /*args*/, Json::Value& /*reply*/) { + int ret; + if ((ret = device_led_stop_custom()) < 0) { + const char* errmsg = GetErrorMessage(ret); + LOGE("Failed to stop led device. %s", errmsg); + } +} + +// async +void DeviceInstance::HandlePowerRequest( + const Json::Value& args, Json::Value& /*reply*/) { + std::string state = args.get("state", "").asString(); + int timeout = args.get("timeout", 0).asInt(); + + int state_n = GetPowerLockTypeFromString(state); + if (state_n >= 0) { + int ret; + if ((ret = device_power_request_lock( + static_cast(state_n), timeout)) < 0) { + const char* errmsg = GetErrorMessage(ret); + LOGE("Failed to request lock with %s. %s", state.c_str(), errmsg); + } + } +} + +// async +void DeviceInstance::HandlePowerRelease( + const Json::Value& args, Json::Value& /*reply*/) { + std::string state = args.get("state", "").asString(); + int state_n = GetPowerLockTypeFromString(state); + if (state_n >= 0) { + int ret; + if ((ret = device_power_release_lock( + static_cast(state_n))) < 0) { + const char* errmsg = GetErrorMessage(ret); + LOGE("Failed to release lock with %s. %s", state.c_str(), errmsg); + } + } +} + +// async +void DeviceInstance::HandlePowerReboot( + const Json::Value& args, Json::Value& /*reply*/) { + std::string reason = args.get("reason", "").asString(); + int ret; + if ((ret = device_power_reboot(reason.empty() ? NULL : reason.c_str())) < 0) { + const char* errmsg = GetErrorMessage(ret); + LOGE("Failed to reboot the device. %s", errmsg); + } +} + +} // namespace device + +EXPORT_XWALK_EXTENSION(tizen_device, device::DeviceExtension); + diff --git a/modules/tizen-device/device_extension.h b/modules/tizen-device/device_extension.h new file mode 100644 index 0000000..8205c45 --- /dev/null +++ b/modules/tizen-device/device_extension.h @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2016 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 JS_DEVICE_EXTENSION_H_ +#define JS_DEVICE_EXTENSION_H_ + +#include + +namespace device { + +class DeviceExtension : public xwalk::XWalkExtension { + public: + // @override + xwalk::XWalkExtensionInstance* CreateInstance(); +}; + +class DeviceInstance : public xwalk::XWalkExtensionInstance { + public: + DeviceInstance(); + ~DeviceInstance(); + + // @override + void Initialize(); + private: + void InitializeCallbacks(); + + // Handlers for Battery + void HandleBatteryIsCharging(const Json::Value& args, Json::Value& reply); + void HandleBatteryGetCapacity(const Json::Value& args, Json::Value& reply); + void HandleBatteryGetLevel(const Json::Value& args, Json::Value& reply); + + // Handlers for Display + void HandleDisplayGetCount(const Json::Value& args, Json::Value& reply); + void HandleDisplayGetMaxBrightness( + const Json::Value& args, Json::Value& reply); + void HandleDisplayGetState(const Json::Value& args, Json::Value& reply); + void HandleDisplaySetState(const Json::Value& args, Json::Value& reply); + void HandleDisplayGetBrightness(const Json::Value& args, Json::Value& reply); + void HandleDisplaySetBrightness(const Json::Value& args, Json::Value& reply); + + // Handlers for Haptic + void HandleHapticVibrate(const Json::Value& args, Json::Value& reply); + void HandleHapticCancel(const Json::Value& args, Json::Value& reply); + + // Handlers for Flash + void HandleFlashGetMaxBrightness(const Json::Value& args, Json::Value& reply); + void HandleFlashGetBrightness(const Json::Value& args, Json::Value& reply); + void HandleFlashSetBrightness(const Json::Value& args, Json::Value& reply); + + // Handlers for LED + void HandleLEDPlay(const Json::Value& args, Json::Value& reply); + void HandleLEDStop(const Json::Value& args, Json::Value& reply); + + // Handlers for Power + void HandlePowerRequest(const Json::Value& args, Json::Value& reply); + void HandlePowerRelease(const Json::Value& args, Json::Value& reply); + void HandlePowerReboot(const Json::Value& args, Json::Value& reply); + + // handle pointer for haptic device + void* haptic_device_handle_; +}; + +} // namespace device + +#endif // JS_DEVICE_EXTENSION_H_ + diff --git a/modules/tizen-device/package.json b/modules/tizen-device/package.json new file mode 100644 index 0000000..70e6be9 --- /dev/null +++ b/modules/tizen-device/package.json @@ -0,0 +1,10 @@ +{ + "name": "tizen-device", + "version": "0.0.1", + "description": "tizen device api", + "main": "tizen-device.xwalk", + "author": { + "name": "Wonyoung Choi", + "email": "wy80.choi@samsung.com" + } +} diff --git a/modules/tizen-device/tizen-device_api.js b/modules/tizen-device/tizen-device_api.js new file mode 100644 index 0000000..e4bb312 --- /dev/null +++ b/modules/tizen-device/tizen-device_api.js @@ -0,0 +1,641 @@ +/* + * Copyright (c) 2016 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. + */ + +/** + * The Device module provides functions to control devices or to get status + * of devices. An instance of the {{#crossLink "Device"}}{{/crossLink}} class + * is returned when require 'tizen-device'. + * ``` + * var device = require('tizen-device'); + * ``` + * @module tizen-device + */ + +'use strict'; + +var EE = require('events'); + +function callSync(cmd, args) { + var obj = {}; + obj['cmd'] = cmd; + obj = Object.assign(obj, args); + try { + return JSON.parse(extension.internal.sendSyncMessage(JSON.stringify(obj))); + } catch (e) { + console.err(e.message); + return {}; + } +} + +function callAsync(cmd, args) { + var obj = {}; + obj['cmd'] = cmd; + obj = Object.assign(obj, args); + try { + extension.postMessage(JSON.stringify(obj)); + } catch (e) { + console.err(e.message); + } +} + +extension.setMessageListener(function(msg) { + var ev = JSON.parse(msg); + if (exports.battery && ev['event'].startsWith('battery.')) { + exports.battery.__event_handle__(ev); + } else if (exports.display && ev['event'].startsWith('display')) { + exports.display.__event_handle__(ev); + } +}); + +/** + * The Device class has sub modules to control each device or to get status of + * each device. + * + * An instance of the this class is returned when require + * 'tizen-device'. + * ``` + * var device = require('tizen-device'); + * ``` + * @class Device + * @since 3.0 + * @public + */ +var DEVICE_BATTERY = Symbol(); +var DEVICE_DISPLAY = Symbol(); +var DEVICE_HAPTIC = Symbol(); +var DEVICE_FLASH = Symbol(); +var DEVICE_LED = Symbol(); +var DEVICE_POWER = Symbol(); + +class Device { + /** + * @attribute battery + * @type Device.Battery + * @readOnly + */ + get battery() { + if (!this[DEVICE_BATTERY]) { + this[DEVICE_BATTERY] = new Battery(); + } + return this[DEVICE_BATTERY]; + } + + /** + * @attribute display + * @type Device.Display + * @readOnly + */ + get display() { + if (!this[DEVICE_DISPLAY]) { + this[DEVICE_DISPLAY] = new Display(); + } + return this[DEVICE_DISPLAY]; + } + + /** + * @attribute haptic + * @type Device.Haptic + * @readOnly + */ + get haptic() { + if (!this[DEVICE_HAPTIC]) { + this[DEVICE_HAPTIC] = new Haptic(); + } + return this[DEVICE_HAPTIC]; + } + + /** + * @attribute flash + * @type Device.Flash + * @readOnly + */ + get flash() { + if (!this[DEVICE_FLASH]) { + this[DEVICE_FLASH] = new Flash(); + } + return this[DEVICE_FLASH]; + } + + /** + * @attribute led + * @type Device.Led + * @readOnly + */ + get led() { + if (!this[DEVICE_LED]) { + this[DEVICE_LED] = new Led(); + } + return this[DEVICE_LED]; + } + + /** + * @attribute power + * @type Device.Power + * @readOnly + */ + get power() { + if (!this[DEVICE_POWER]) { + this[DEVICE_POWER] = new Power(); + } + return this[DEVICE_POWER]; + } +}; + + +/** + * The Battery class provides functions to get information about the battery. + * + * An instance of this class can be accessed with the + * {{#crossLink "Device/battery:attribute"}}{{/crossLink}} attribute of the + * {{#crossLink "Device"}}{{/crossLink}} class. + * ``` + * var battery = require('tizen-device').battery; + * ``` + * @class Battery + * @since 3.0 + * @namespace Device + * @extends Node.EventEmitter + */ +var BATTERY_STATE = Symbol(); +var BATTERY_CAPACITY = Symbol(); +var BATTERY_LEVEL = Symbol(); + +class Battery extends EE { + + constructor() { + super(); + } + + /** + * Gets the charging state. + * The value will be true if the battery is charging, else false + * + * @attribute isCharging + * @type {Boolean} + * @readOnly + */ + get isCharging() { + if (!this[BATTERY_STATE]) { + this[BATTERY_STATE] = callSync('battery.isCharging')['value']; + } + return this[BATTERY_STATE]; + } + + /** + * Gets the battery level status. + * + * @attribute level + * @value 'empty' The battery goes empty + * @value 'critical' The battery charge is at a critical state + * @value 'low' The battery has little charge left + * @value 'high' The battery is charged + * @value 'full' The battery status is full + * @type {String} + * @readOnly + */ + get level() { + if (!this[BATTERY_LEVEL]) { + this[BATTERY_LEVEL] = callSync('battery.getLevel')['value']; + } + return this[BATTERY_LEVEL]; + } + + /** + * Gets the remaining battery charge percentage (0-100). + * + * @attribute capacity + * @type {Number} + * @readOnly + */ + get capacity() { + if (!this[BATTERY_CAPACITY]) { + this[BATTERY_CAPACITY] = callSync('battery.getCapacity')['value']; + } + return this[BATTERY_CAPACITY]; + } + + /** + * Emitted when a battery status is changed. + * ``` + * var device = require('tizen-device'); + * device.battery.on('change', function(isCharging, level, capacity) { + * console.log('battery status has changed'); + * console.log(' state : ' + (isCharging ? 'charging' : 'not charging')); + * console.log(' level : ' + level); + * console.log(' capacity : ' + capacity); + * }); + * ``` + * @event change + * @param {Boolean} isCharging true if the battery is charging, else false + * @param {String} level The changed battery level + * @value 'empty' The battery goes empty + * @value 'critical' The battery charge is at a critical state + * @value 'low' The battery has little charge left + * @value 'high' The battery is charged + * @value 'full' The battery status is full + * @param {Number} capacity The changed battery percentage + */ + __event_handle__(ev) { + var changed = false; + if (ev['event'] === 'battery.charging') { + this[BATTERY_STATE] = ev['value']; + changed = true; + } else if (ev['event'] === 'battery.capacity') { + this[BATTERY_CAPACITY] = ev['value']; + changed = true; + } else if (ev['event'] === 'battery.level') { + this[BATTERY_LEVEL] = ev['value']; + changed = true; + } + if (changed) { + this.emit('change', + this[BATTERY_STATE], this[BATTERY_LEVEL], this[BATTERY_CAPACITY]); + } + } +}; + + +/** + * The Display class provides functions to control the display status. + * + * An instance of this class can be accessed with the + * {{#crossLink "Device/display:attribute"}}{{/crossLink}} attribute of the + * {{#crossLink "Device"}}{{/crossLink}} class. + * ``` + * var display = require('tizen-device').display; + * ``` + * @class Display + * @since 3.0 + * @namespace Device + * @extends Node.EventEmitter + */ +var DISPLAY_STATE = Symbol(); + +class Display extends EE { + + constructor() { + super(); + } + + /** + * Gets the number of display devices. + * + * @attribute count + * @type {Number} + * @readOnly + * @privilege http://tizen.org/privilege/display + */ + get count() { + return callSync('display.getCount')['value']; + } + + /** + * Gets or sets the current display state. + * + * @attribute state + * @type {String} + * @value 'normal' Normal state + * @value 'dim' Screen dim state + * @value 'off' Screen off state + * @privilege http://tizen.org/privilege/display + */ + get state() { + if (!this[DISPLAY_STATE]) { + this[DISPLAY_STATE] = callSync('display.getState')['value']; + } + return this[DISPLAY_STATE]; + } + + set state(value) { + var value_v = String(value).toLowerCase(); + if (['normal', 'dim', 'off'].indexOf(value_v) >= 0) { + var ret = callSync('display.setState', {'state': value_v})['value']; + if (ret) { + this[DISPLAY_STATE] = ret; + } + } + } + + /** + * Gets the maximum brightness value that can be set. + * + * @method getMaxBrightness + * @param {Number} index The index of the display. + * It can be greater than or equal to 0 and less than the + * {{#crossLink "Device.Display/count:attribute"}}{{/crossLink}}. + * The index zero is always assigned to the main display. + * @return {Number} The maximum brightness value of the display + * @privilege http://tizen.org/privilege/display + */ + getMaxBrightness(index) { + var ret = callSync('display.getMaxBrightness', + {'index': Number(index)}); + return ret['value']; + } + + /** + * Gets the display brightness value. + * + * @method getBrightness + * @param {Number} index The index of the display. + * It can be greater than or equal to 0 and less than the + * {{#crossLink "Device.Display/count:attribute"}}{{/crossLink}}. + * The index zero is always assigned to the main display. + * @return {Number} The current brightness value of the display + * @privilege http://tizen.org/privilege/display + */ + getBrightness(index) { + var ret = callSync('display.getBrightness', + {'index': Number(index)}); + return ret['value']; + } + + /** + * Sets the display brightness value. + * + * @method setBrightness + * @param {Number} index The index of the display. + * It can be greater than or equal to 0 and less than the + * {{#crossLink "Device.Display/count:attribute"}}{{/crossLink}}. + * The index zero is always assigned to the main display. + * @param {Number} value The new brightness value to set + * @privilege http://tizen.org/privilege/display + */ + setBrightness(index, value) { + callSync('display.setBrightness', + {'index': Number(index), + 'value': Number(value)}); + } + + /** + * Emitted when a display state is changed. + * ``` + * var device = require('tizen-device'); + * device.display.on('change', function(state) { + * console.log('display state is '+ state); + * }); + * ``` + * @event change + * @param {String} state The changed display state + * @value 'normal' Normal state + * @value 'dim' Screen dim state + * @value 'off' Screen off state + */ + __event_handle__(ev) { + if (ev['event'] === 'dispaly.state') { + this[DISPLAY_STATE] = ev['value']; + this.emit('change', this[DISPLAY_STATE]); + } + } +}; + +/** + * The Haptic class provides functions to control a vibrator. + * + * An instance of this class can be accessed with the + * {{#crossLink "Device/haptic:attribute"}}{{/crossLink}} attribute of the + * {{#crossLink "Device"}}{{/crossLink}} class. + * ``` + * var haptic = require('tizen-device').haptic; + * ``` + * @class Haptic + * @since 3.0 + * @namespace Device + */ +class Haptic { + /** + * Vibrates during the specified time with a constant intensity. + * + * @method vibrate + * @param {Number} duration The play duration in milliseconds + * @param {Number} intensity The amount of the intensity variation (0-100) + * @privilege http://tizen.org/privilege/haptic + */ + vibrate(duration, intensity) { + callAsync('haptic.vibrate', + {'duration': Number(duration), + 'intensity': Number(intensity)}); + } + + /** + * Cancels all vibration effects which are being played. + * + * @method cancel + * @privilege http://tizen.org/privilege/haptic + */ + cancel() { + callAsync('haptic.cancel'); + } +}; + +/** + * The Flash class provides functions to control a flash device that is located + * next to the camera. + * + * An instance of this class can be accessed with the + * {{#crossLink "Device/flash:attribute"}}{{/crossLink}} attribute of the + * {{#crossLink "Device"}}{{/crossLink}} class. + * ``` + * var flash = require('tizen-device').flash; + * ``` + * @class Flash + * @since 3.0 + * @namespace Device + * @extends Node.EventEmitter + */ +var FLASH_BRIGHTNESS = Symbol(); + +class Flash extends EE { + constructor() { + super(); + } + + /** + * Gets the maximum brightness value of a flash device. + * + * @attribute maxBrightness + * @type {Number} + * @readOnly + * @privilege http://tizen.org/privilege/led + */ + get maxBrightness() { + return callSync('flash.getMaxBrightness')['value']; + } + + /** + * Gets or sets the brightness value of a flash device. + * + * @attribute brightness + * @type {Number} + * @privilege http://tizen.org/privilege/led + */ + get brightness() { + if (!this[FLASH_BRIGHTNESS]) { + this[FLASH_BRIGHTNESS] = callSync('flash.getBrightness')['value']; + } + return this[FLASH_BRIGHTNESS]; + } + + set brightness(value) { + var ret = callSync('flash.setBrightness', + {'value': Number(value)})['value']; + if (ret) { + this[FLASH_BRIGHTNESS] = ret; + } + } + + /** + * Emitted when a flash brightness is changed. + * ``` + * var device = require('tizen-device'); + * device.flash.on('changed', function(brightness) { + * console.log('changed flash brightness is '+ brightness); + * }); + * ``` + * @event changed + * @param {Number} brightness The changed brightness value + */ + __event_handle__(ev) { + if (ev['event'] === 'flash.brightness') { + this[FLASH_BRIGHTNESS] = ev['value']; + this.emit('changed', this[FLASH_BRIGHTNESS]); + } + } +}; + +/** + * The Led class provides functions to control a LED that is located + * to the front of a device. + * + * An instance of this class can be accessed with the + * {{#crossLink "Device/led:attribute"}}{{/crossLink}} attribute of the + * {{#crossLink "Device"}}{{/crossLink}} class. + * ``` + * var led = require('tizen-device').led; + * ``` + * @class Led + * @since 3.0 + * @namespace Device + */ +class Led { + /** + * Plays the custom effect of the LED device. + * + * @method play + * @param {Number} timeOn Turn on time in milliseconds + * @param {Number} timeOff Turn off time in milliseconds + * @param {String} color The Color value, RGB in hex, eg '#00FF00' + * @privilege http://tizen.org/privilege/led + */ + play(timeOn, timeOff, color) { + if (typeof color === 'string' && color[0] === '#') { + color = parseInt(color.substring(1, color.length), 16); + } + + callAsync('led.play', { + 'timeOn': Number(timeOn), + 'timeOff': Number(timeOff), + 'color': color + }); + } + + /** + * Stops the custom effect of the LED device. + * + * @method stop + * @privilege http://tizen.org/privilege/led + */ + stop() { + callAsync('led.stop'); + } +}; + + +/** + * The Power class provides functions to control the power service. + * It can be made to hold the specific state to avoid changing display + * and CPI state internally. + * + * An instance of this class can be accessed with the + * {{#crossLink "Device/power:attribute"}}{{/crossLink}} attribute of the + * {{#crossLink "Device"}}{{/crossLink}} class. + * ``` + * var power = require('tizen-device').power; + * ``` + * @class Power + * @since 3.0 + * @namespace Device + */ +var POWER_STATES = ['cpu', 'normal', 'dim']; +class Power { + /** + * Locks the given lock state for a specified time. + * + * @method request + * @param {String} state The power state to request lock + * @value 'cpu' The 'cpu' state is set to awake and it does not go to sleep + * state automatically. + * @value 'normal' The minimal screen state is set to 'normal' and device does + * not change to 'dim' state automatically. + * @value 'dim' The minimal screen state is set to 'dim' and device does not + * change to 'off' state automatically. + * @param {Number} timeout The positive number in milliseconds + * or 0 for permanent lock + * @privilege http://tizen.org/privilege/display + */ + request(state, timeout) { + var state_v = String(state).toLowerCase(); + if (POWER_STATES.indexOf(state_v) >= 0) { + callAsync('power.request', + {'state': state_v, + 'timeout': Number(timeout)}); + } + } + + /** + * Releases the given lock state locked before. + * + * @method release + * @param {String} state The power state to release lock + * @value 'cpu' The CPU state is set to awake and it does not go to SLEEP + * state automatically. + * @value 'normal' The minimal screen state is set to NORMAL and device does + * not change to DIM state automatically. + * @value 'dim' The minimal screen state is set to DIM and device does not + * change to OFF state automatically. + * @privilege http://tizen.org/privilege/display + */ + release(state) { + var state_v = String(state).toLowerCase(); + if (POWER_STATES.indexOf(state_v) >= 0) { + callAsync('power.release', {'state': state_v}); + } + } + + /** + * Reboots the device. + * + * @method reboot + * @param {String} reason Pass to the platform and kernel to request special + * reboot reason + * @privilege http://tizen.org/privilege/reboot + */ + reboot(reason) { + callAsync('power.reboot', {'reason': reason}); + } +}; + +exports = new Device(); diff --git a/packaging/jsnative.spec b/packaging/jsnative.spec index 366dcc3..fbc504d 100644 --- a/packaging/jsnative.spec +++ b/packaging/jsnative.spec @@ -12,19 +12,22 @@ Source1: %{name}.manifest BuildRequires: cmake BuildRequires: pkgconfig(nodejs) +BuildRequires: pkgconfig(jsoncpp) BuildRequires: pkgconfig(xwalk-extensions-common) BuildRequires: pkgconfig(dlog) BuildRequires: pkgconfig(libsmack) BuildRequires: pkgconfig(cynara-client) BuildRequires: pkgconfig(appcore-efl) BuildRequires: pkgconfig(aul) -BuildRequires: pkgconfig(capi-appfw-application) -BuildRequires: pkgconfig(capi-appfw-app-manager) BuildRequires: pkgconfig(pkgmgr-info) BuildRequires: pkgconfig(bundle) +BuildRequires: pkgconfig(notification) +BuildRequires: pkgconfig(capi-system-device) +BuildRequires: pkgconfig(capi-appfw-application) +BuildRequires: pkgconfig(capi-appfw-app-manager) BuildRequires: pkgconfig(capi-message-port) BuildRequires: pkgconfig(capi-media-sound-manager) -BuildRequires: pkgconfig(notification) +BuildRequires: pkgconfig(capi-system-device) Requires: nodejs -- 2.7.4