From a097e26e0ff71c073180672ce18dfbbff859eea0 Mon Sep 17 00:00:00 2001 From: Seungkeun Lee Date: Tue, 19 Jan 2016 19:30:41 +0900 Subject: [PATCH] tizen-app-manager module - Use Jsoncpp Change-Id: I3c3b09d2878bad295966e7c8dd4d08bcc49b2e9e --- modules/CMakeLists.txt | 1 + modules/tizen-app-manager/CMakeLists.txt | 20 + modules/tizen-app-manager/app_manager_extension.cc | 411 +++++++++++++++++++ modules/tizen-app-manager/app_manager_extension.h | 92 +++++ modules/tizen-app-manager/package.json | 12 + modules/tizen-app-manager/tizen-app-manager_api.js | 454 +++++++++++++++++++++ 6 files changed, 990 insertions(+) create mode 100755 modules/tizen-app-manager/CMakeLists.txt create mode 100755 modules/tizen-app-manager/app_manager_extension.cc create mode 100755 modules/tizen-app-manager/app_manager_extension.h create mode 100755 modules/tizen-app-manager/package.json create mode 100755 modules/tizen-app-manager/tizen-app-manager_api.js diff --git a/modules/CMakeLists.txt b/modules/CMakeLists.txt index 1db4c13..1922577 100755 --- a/modules/CMakeLists.txt +++ b/modules/CMakeLists.txt @@ -14,3 +14,4 @@ ADD_SUBDIRECTORY(tizen-message-port) ADD_SUBDIRECTORY(tizen-device) ADD_SUBDIRECTORY(tizen-system-setting) ADD_SUBDIRECTORY(tizen-alarm) +ADD_SUBDIRECTORY(tizen-app-manager) diff --git a/modules/tizen-app-manager/CMakeLists.txt b/modules/tizen-app-manager/CMakeLists.txt new file mode 100755 index 0000000..d2d6b59 --- /dev/null +++ b/modules/tizen-app-manager/CMakeLists.txt @@ -0,0 +1,20 @@ +SET(MODULE "tizen-app-manager") + +# Native Module +ADD_MODULE(${MODULE} XWALK + JSAPI + tizen-app-manager_api.js + SRCS + app_manager_extension.cc + DEPENDS + dlog jsoncpp capi-appfw-app-manager glib-2.0 +) + +# Copy Project +INSTALL(FILES package.json + DESTINATION ${GLOBAL_NODE_MODULE_PATH}/${MODULE} +) + +INSTALL(TARGETS ${MODULE} + DESTINATION ${GLOBAL_NODE_MODULE_PATH}/${MODULE} +) diff --git a/modules/tizen-app-manager/app_manager_extension.cc b/modules/tizen-app-manager/app_manager_extension.cc new file mode 100755 index 0000000..0ccb790 --- /dev/null +++ b/modules/tizen-app-manager/app_manager_extension.cc @@ -0,0 +1,411 @@ +/* + * Copyright (c) 2015 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 "app_manager_extension.h" + +#include +#include +#include +#include + +#include // NOLINT + +#ifdef LOG_TAG +#undef LOG_TAG +#endif +#define LOG_TAG "JSNative" + +namespace appfw { + +namespace { + +static bool StartsWith(const std::string& str, const std::string& sub) { + if (sub.size() > str.size()) return false; + return std::equal(sub.begin(), sub.end(), str.begin()); +} + +} // namespace + +xwalk::XWalkExtensionInstance* AppManagerExtension::CreateInstance() { + return new AppManagerInstance(); +} + +AppManagerInstance::AppManagerInstance():handle_key_(1) { +} + +AppManagerInstance::~AppManagerInstance() { + app_manager_unset_app_context_event_cb(); + { + std::lock_guard guard(handle_lock_); + handle_map_.clear(); + } +} + +void AppManagerInstance::Initialize() { + LOGD("Created tizen-app-manager instance"); + app_manager_set_app_context_event_cb( + [](app_context_h app_context, app_context_event_e event, void *user_data) { + AppManagerInstance* self = static_cast(user_data); + Json::Value result; + if (event == APP_CONTEXT_EVENT_LAUNCHED) { + result["event"] = "launch"; + } else { + result["event"] = "terminate"; + } + int pid; + app_context_get_pid(app_context, &pid); + result["data"]["pid"] = pid; + char* id = nullptr; + app_context_get_app_id(app_context, &id); + if (id) { + result["data"]["id"] = id; + free(id); + } + Json::FastWriter writer; + self->PostMessage(writer.write(result).c_str()); + }, this); +} + +void AppManagerInstance::HandleMessage(const char* msg) { + Json::Value args; + Json::Reader reader; + if (!reader.parse(msg, msg + strlen(msg), args)) { + LOGE("Ignoring message. Can't parse msessage : %s", + reader.getFormattedErrorMessages().c_str()); + return; + } + + Json::Value result; + result["result"] = "FAIL"; + std::string cmd = args.get("cmd", "").asString(); + std::string asyncid = args.get("asyncid", "").asString(); + if (asyncid.empty()) { + LOGE("Ignoring message. asyncid is empty"); + return; + } + + if (cmd == "manager.instapps") { + HandleManagerInstalledApps(args["filter"], asyncid); + } else if (cmd == "manager.runningapps") { + HandleManagerRunningApps(asyncid); + } +} + +void AppManagerInstance::HandleSyncMessage(const char* msg) { + Json::Value args; + Json::Reader reader; + if (!reader.parse(msg, msg + strlen(msg), args)) { + LOGE("Ignoring message. Can't parse msessage : %s", + reader.getFormattedErrorMessages().c_str()); + return; + } + + Json::Value result; + result["result"] = "FAIL"; + std::string cmd = args.get("cmd", "").asString(); + + if (StartsWith(cmd, "instapp.")) { + auto handle = args.get("handle", 0); + int key = 0; + if (handle.isInt()) { + key = handle.asInt(); + } + { + std::lock_guard guard(handle_lock_); + auto found = handle_map_.find(key); + if (found != handle_map_.end()) { + if (cmd == "instapp.delete") { + handle_map_.erase(found); + result["result"] = "OK"; + } else { + found->second->HandleMessage(args, &result); + } + } else { + LOGE("Invalid handle was used"); + } + } + } else if (cmd == "manager.instapp") { + std::string appid = args.get("appid", "").asString(); + HandleManagerInstalledApp(appid, &result); + } else if (cmd == "manager.runningapp") { + int pid = args.get("pid", -1).asInt(); + std::string appid = args.get("appid", "").asString(); + HandleManagerRunningApp(pid, appid, &result); + } + + Json::FastWriter writer; + SendSyncReply(writer.write(result).c_str()); +} + + +void AppManagerInstance::HandleManagerInstalledApp(const std::string& appid, + Json::Value* data) { + app_info_h handle = nullptr; + Json::Value& result = *data; + if (app_manager_get_app_info(appid.c_str(), &handle) == 0) { + std::shared_ptr appinfo(new AppInfo(handle)); + { + std::lock_guard guard(handle_lock_); + auto key = handle_key_++; + handle_map_[key] = appinfo; + result["result"] = "OK"; + result["data"] = key; + } + } +} + +void AppManagerInstance::HandleManagerRunningApp(int pid, + const std::string& appid, + Json::Value* data) { + Json::Value& result = *data; + std::string id = appid; + if (pid != -1) { + char* ptr = nullptr; + app_manager_get_app_id(pid, &ptr); + if (ptr != nullptr) { + id = ptr; + free(ptr); + } + } + + app_context_h context = nullptr; + app_manager_get_app_context(id.c_str(), &context); + if (context != nullptr) { + int pid = 0; + app_context_get_pid(context, &pid); + result["result"] = "OK"; + result["data"]["id"] = id; + result["data"]["pid"] = pid; + app_context_destroy(context); + } +} + +struct CallbackData { + AppManagerInstance* self; + Json::Value result; + std::string json; +}; + +void AppManagerInstance::HandleManagerInstalledApps( + const Json::Value& filter, const std::string& asyncid) { + std::thread task([filter, asyncid, this]() { + CallbackData* data = new CallbackData(); + data->self = this; + data->result["asyncid"] = asyncid; + app_info_filter_h filter_h = nullptr; + if (filter != Json::Value::nullRef) { + app_info_filter_create(&filter_h); + auto keys = filter.getMemberNames(); + for (auto& key : keys) { + if (filter[key].isBool()) { + app_info_filter_add_bool(filter_h, key.c_str(), filter[key].asBool()); + } else { + app_info_filter_add_string(filter_h, + key.c_str(), + filter[key].asString().c_str()); + } + } + } + + auto callback = [](app_info_h app, void* user_data) { + CallbackData* data = static_cast(user_data); + app_info_h tostore; + app_info_clone(&tostore, app); + std::shared_ptr appinfo(new AppInfo(tostore)); + { + std::lock_guard guard(data->self->handle_lock_); + auto key = data->self->handle_key_++; + data->self->handle_map_[key] = appinfo; + data->result["data"].append(key); + } + return true; + }; + + if (filter_h != nullptr) { + app_info_filter_foreach_appinfo(filter_h, callback, data); + } else { + app_manager_foreach_app_info(callback, data); + } + + Json::FastWriter writer; + data->json = writer.write(data->result); + g_idle_add([](void* user_data) { + CallbackData* data = static_cast(user_data); + data->self->PostMessage(data->json.c_str()); + delete data; + return 0; + }, data); + }); + task.detach(); +} + +void AppManagerInstance::HandleManagerRunningApps(const std::string& asyncid) { + std::thread task([asyncid, this]() { + CallbackData* data = new CallbackData(); + data->self = this; + data->result["asyncid"] = asyncid; + app_manager_foreach_app_context([](app_context_h app_context, + void *user_data) { + CallbackData* data = static_cast(user_data); + Json::Value app; + { + int pid; + char* id = nullptr; + app_context_get_pid(app_context, &pid); + app_context_get_app_id(app_context, &id); + app["pid"] = pid; + app["id"] = id ? id : ""; + free(id); + } + data->result["data"].append(app); + return true; + }, data); + + Json::FastWriter writer; + data->json = writer.write(data->result); + g_idle_add([](void* user_data) { + CallbackData* data = static_cast(user_data); + data->self->PostMessage(data->json.c_str()); + delete data; + return 0; + }, data); + }); + task.detach(); +} + +AppInfo::AppInfo(app_info_h handle):handle_(handle) { +} + +AppInfo::~AppInfo() { + app_info_destroy(handle_); + handle_ = nullptr; +} + +std::string AppInfo::GetStringAttribute(int(*capi)(app_info_h, char**)) { + char* ptr = nullptr; + if (capi) + capi(handle_, &ptr); + if (ptr) { + std::string id = ptr; + free(ptr); + return id; + } + return std::string(); +} + +bool AppInfo::GetBooleanAttribute(int(*capi)(app_info_h, bool*)) { + bool result = false; + capi(handle_, &result); + return result; +} + +std::string AppInfo::id() { + return GetStringAttribute(app_info_get_app_id); +} + +std::string AppInfo::exe() { + return GetStringAttribute(app_info_get_exec); +} + +std::string AppInfo::label() { + return GetStringAttribute(app_info_get_label); +} + +std::string AppInfo::icon() { + return GetStringAttribute(app_info_get_icon); +} + +std::string AppInfo::package() { + return GetStringAttribute(app_info_get_package); +} + +std::string AppInfo::type() { + return GetStringAttribute(app_info_get_type); +} + +bool AppInfo::nodisplay() { + return GetBooleanAttribute(app_info_is_nodisplay); +} + +bool AppInfo::disabled() { + return !GetBooleanAttribute(app_info_is_enabled); +} + +bool AppInfo::onboot() { + return GetBooleanAttribute(app_info_is_onboot); +} + +bool AppInfo::preloaded() { + return GetBooleanAttribute(app_info_is_preload); +} + +std::string AppInfo::GetLocalizedLabel(const std::string& locale) { + char* label = nullptr; + app_info_get_localed_label(id().c_str(), locale.c_str(), &label); + if (label) { + std::string result = label; + free(label); + return result; + } + return std::string(); +} + +void AppInfo::HandleMetadata(Json::Value* data) { + app_info_foreach_metadata(handle_, + [](const char* key, const char* value, void* user_data) { + Json::Value& result = *(static_cast(user_data)); + result[key] = value; + return true; + }, data); +} + +void AppInfo::HandleMessage(const Json::Value& args, Json::Value* data) { + Json::Value& result = *data; + std::string cmd = args.get("cmd", "").asString(); + result["result"] = "OK"; + if (cmd == "instapp.id") { + result["data"] = id(); + } else if (cmd == "instapp.exe") { + result["data"] = exe(); + } else if (cmd == "instapp.label") { + result["data"] = label(); + } else if (cmd == "instapp.iconpath") { + result["data"] = icon(); + } else if (cmd == "instapp.package") { + result["data"] = package(); + } else if (cmd == "instapp.type") { + result["data"] = type(); + } else if (cmd == "instapp.nodisplay") { + result["data"] = nodisplay(); + } else if (cmd == "instapp.disabled") { + result["data"] = disabled(); + } else if (cmd == "instapp.onboot") { + result["data"] = onboot(); + } else if (cmd == "instapp.preloaded") { + result["data"] = preloaded(); + } else if (cmd == "instapp.localizelabel") { + std::string locale = args.get("locale", "").asString(); + result["data"] = GetLocalizedLabel(locale); + } else if (cmd == "instapp.metadata") { + AppInfo::HandleMetadata(&(result["data"])); + } else { + result["result"] = "FAIL"; + } +} + +} // namespace appfw + +EXPORT_XWALK_EXTENSION(tizen_app_manager, appfw::AppManagerExtension); diff --git a/modules/tizen-app-manager/app_manager_extension.h b/modules/tizen-app-manager/app_manager_extension.h new file mode 100755 index 0000000..4e5250f --- /dev/null +++ b/modules/tizen-app-manager/app_manager_extension.h @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2015 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 APP_MANAGER_EXTENSION_H_ +#define APP_MANAGER_EXTENSION_H_ + +#include +#include +#include + +#include +#include +#include // NOLINT +#include + + +namespace appfw { + +class AppInfo { + public: + explicit AppInfo(app_info_h handle); + ~AppInfo(); + + std::string id(); + std::string exe(); + std::string label(); + std::string icon(); + std::string package(); + std::string type(); + bool nodisplay(); + bool disabled(); + bool onboot(); + bool preloaded(); + std::string GetLocalizedLabel(const std::string& locale); + + void HandleMessage(const Json::Value& args, Json::Value* data); + private: + std::string GetStringAttribute(int(*capi)(app_info_h, char**)); + bool GetBooleanAttribute(int(*capi)(app_info_h, bool*)); + void HandleMetadata(Json::Value* data); + app_info_h handle_; +}; + +class AppManagerExtension : public xwalk::XWalkExtension { + public: + // @override + xwalk::XWalkExtensionInstance* CreateInstance(); +}; + +class AppManagerInstance : public xwalk::XWalkExtensionInstance { + public: + AppManagerInstance(); + ~AppManagerInstance(); + // @override + void Initialize(); + + // @override + void HandleMessage(const char* msg); + + // @override + void HandleSyncMessage(const char* msg); + private: + std::shared_ptr GetHandle(int key); + void HandleManagerInstalledApp(const std::string& appid, Json::Value* data); + void HandleManagerRunningApp(int pid, + const std::string& appid, + Json::Value* data); + void HandleManagerInstalledApps( + const Json::Value& filter, const std::string& asyncid); + void HandleManagerRunningApps(const std::string& asyncid); + int handle_key_; + std::map > handle_map_; + std::mutex handle_lock_; +}; + +} // namespace appfw + +#endif // APP_MANAGER_EXTENSION_H_ + diff --git a/modules/tizen-app-manager/package.json b/modules/tizen-app-manager/package.json new file mode 100755 index 0000000..f2fe26a --- /dev/null +++ b/modules/tizen-app-manager/package.json @@ -0,0 +1,12 @@ +{ + "name": "tizen-app-manager", + "version": "0.0.1", + "description": "Module for ApplicationManager", + "main": "tizen-app-manager.xwalk", + "dependencies": { + }, + "author": { + "name": "Seungkeun Lee", + "email": "sngn.lee@samsung.com" + } +} diff --git a/modules/tizen-app-manager/tizen-app-manager_api.js b/modules/tizen-app-manager/tizen-app-manager_api.js new file mode 100755 index 0000000..5560e26 --- /dev/null +++ b/modules/tizen-app-manager/tizen-app-manager_api.js @@ -0,0 +1,454 @@ +/* + * 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. + */ + +/** + * Tizen Application Manager module + * + * The 'tizen-app-manager' module exports an instance of the AppManager class. + * + * ``` + * var app_manager = require('tizen-app-manager'); + * app_manager.getInstalledApps().then(function(){ ... }); + * + * @module tizen-app-manager + */ + +'use strict'; + +function native_sync_call(method, parameter) { + var args = {}; + args['cmd'] = method; + args = Object.assign(args, parameter); + try { + return JSON.parse(extension.internal.sendSyncMessage(JSON.stringify(args))); + } catch (e) { + console.log('recevied message parse error:' + e.message); + return {}; + } +} + +var async_message_id = 0; +var async_map = new Map(); + +function native_async_call(method, parameter, cb) { + var args = {}; + args['cmd'] = method; + args = Object.assign(args, parameter); + var asyncid = async_message_id++; + args['asyncid'] = 'asyncid_' + asyncid; + async_map.set(args['asyncid'], cb); + extension.postMessage(JSON.stringify(args)); +} + +function registEventHandler(manager) { + extension.setMessageListener(function(json) { + var msg = JSON.parse(json); + if (msg['asyncid'] && async_map.has(msg['asyncid'])) { + var cb = async_map.get(msg['asyncid']); + async_map.delete(msg['asyncid']); + if (cb instanceof Function) { + cb(msg); + } else { + console.log('cb is not function'); + } + } else { + if (manager && typeof manager.__event_handle__ === 'function') + manager.__event_handle__(msg); + } + }); +} + +var handle_ = Symbol(); +var cache_ = Symbol(); +/** + * @class InstalledApplication + * This class defines the general information available + * to an installed application + */ +class InstalledApplication { + constructor(handle) { + this[handle_] = handle; + this[cache_] = {}; + require('reaper').setReaper(this, function(deleted) { + native_sync_call('instapp.delete', {'handle': deleted[handle_]}); + }); + } + + /** + * Application ID + * @attribute id + * @type {string} + * @readonly + */ + get id() { + if (!this[cache_]['id']) { + this[cache_]['id'] = + native_sync_call('instapp.id', {'handle': this[handle_]})['data']; + } + return this[cache_]['id']; + } + + /** + * The executable path of the application + * @attribute executablePath + * @type {string} + * @readonly + */ + get executablePath() { + if (!this[cache_]['executablePath']) { + this[cache_]['executablePath'] = + native_sync_call('instapp.exe', {'handle': this[handle_]})['data']; + } + return this[cache_]['executablePath']; + } + + /** + * The label of the application. + * @attribute label + * @type {string} + * @readonly + */ + get label() { + if (!this[cache_]['label']) { + this[cache_]['label'] = + native_sync_call('instapp.label', {'handle': this[handle_]})['data']; + } + return this[cache_]['label']; + } + + /** + * The absolute path to the icon image. + * @attribute iconPath + * @type {string} + * @readonly + */ + get iconPath() { + if (!this[cache_]['iconPath']) { + this[cache_]['iconPath'] = + native_sync_call('instapp.iconpath', + {'handle': this[handle_]})['data']; + } + return this[cache_]['iconPath']; + } + + /** + * The package ID + * @attribute packageID + * @type {string} + * @readonly + */ + get packageID() { + if (!this[cache_]['packageID']) { + this[cache_]['packageID'] = + native_sync_call('instapp.package', + {'handle': this[handle_]})['data']; + } + return this[cache_]['packageID']; + } + + /** + * The application type + * @attribute type + * @type {string} + * @readonly + */ + get type() { + if (!this[cache_]['type']) { + this[cache_]['type'] = + native_sync_call('instapp.type', + {'handle': this[handle_]})['data']; + } + return this[cache_]['type']; + } + + /** + * The metadata + * @attribute metadata + * @type {Object} {'key':value, ....} + * @readonly + */ + get metadata() { + if (!this[cache_]['metadata']) { + this[cache_]['metadata'] = + native_sync_call('instapp.metadata', + {'handle': this[handle_]})['data']; + } + return this[cache_]['metadata']; + } + + /** + * Do not displayed in menuscreen + * @attribute nodisplay + * @type {boolean} + * @readonly + */ + get nodisplay() { + if (!this[cache_]['nodisplay']) { + this[cache_]['nodisplay'] = + native_sync_call('instapp.nodisplay', + {'handle': this[handle_]})['data']; + } + return this[cache_]['nodisplay']; + } + + /** + * Application was disabled + * @attribute nodisplay + * @type {boolean} + * @readonly + */ + get disabled() { + if (!this[cache_]['disabled']) { + this[cache_]['disabled'] = + native_sync_call('instapp.disabled', + {'handle': this[handle_]})['data']; + } + return this[cache_]['disabled']; + } + + /** + * Application was running on boot + * @attribute onboot + * @type {boolean} + * @readonly + */ + get onboot() { + if (!this[cache_]['onboot']) { + this[cache_]['onboot'] = + native_sync_call('instapp.onboot', + {'handle': this[handle_]})['data']; + } + return this[cache_]['onboot']; + } + + /** + * Application was installed in preload time + * @attribute preloaded + * @type {boolean} + * @readonly + */ + get preloaded() { + if (this[cache_]['preloaded']) { + this[cache_]['preloaded'] = + native_sync_call('instapp.preloaded', + {'handle': this[handle_]})['data']; + } + return this[cache_]['preloaded']; + } + + /** + * The localized name of the application. + * @param {string} locale Locale + * @method getLocalizedLabel + * @return {string} + */ + getLocalizedLabel(locale) { + var args = {}; + args['handle'] = this[handle_]; + args['locale'] = locale; + return native_sync_call('instapp.localizelabel', args)['data']; + } + +}; + + +/** + * @class RunningApplication + */ +class RunningApplication { + constructor(appid, pid) { + /** + * Application ID + * @attribute id + * @type {string} + * @readonly + */ + this.id = appid; + + /** + * Process ID of Running Application + * @attribute pid + * @type {Number} + * @readonly + */ + this.pid = pid; + Object.freeze(this); + } +}; + + +var available_keys = ['id', 'type', 'category', 'nodisplay']; +var convert_key = {'id': 'PACKAGE_INFO_PROP_APP_ID', + 'type': 'PACKAGE_INFO_PROP_APP_TYPE', + 'category': 'PACKAGE_INFO_PROP_APP_CATEGORY', + 'nodisplay': 'PACKAGE_INFO_PROP_APP_NODISPLAY'}; + +var EE = require('events'); +/** + * @class AppManager + * @extends Node.EventEmitter + * + * The AppManager class provides methods to retrieve application information + */ +class AppManager extends EE { + + constructor() { + super(); + registEventHandler(this); + } + + /** + * @method getInstalledApps + * + * @param {Object} [filter] + * You can use key in ['id', 'type', 'category', 'nodisplay'(boolean)] + * to filter out + * + * @return {Promise | InstalledApplication[]} + * + * + * ``` + * var app_manager = require('tizen-app-manager'); + * app_manager.getInstalledApps({'type':'jsapp'}) + * .then(function(apps) { + * apps.forEach(function(app) { + * console.log('All jsapp type application : '+ app.id); + * }) + * }); + * + * app_manager.getInstalledApps({'type':'jsapp', 'disabled':true}) + * .then(function(apps) { + * apps.forEach(function(app) { + * console.log('All disabled jsapp type application : '+ app.id); + * }) + * }); + * ``` + */ + getInstalledApps(filter) { + return new Promise(function(resolve, reject) { + var args = {}; + if (filter) { + var converted_filter = {}; + for (var key in filter) { + if (available_keys.indexOf(key) !== -1) { + converted_filter[convert_key[key]] = filter[key]; + } + } + args['filter'] = converted_filter; + } + native_async_call('manager.instapps', args, function(msg) { + if (msg['reason']) { + reject(new Error(msg['reason'])); + return; + } + var apps = msg['data'].map(function(handle) { + return new InstalledApplication(handle); + }); + resolve(apps); + }); + }); + } + + /** + * @method getInstalledApp + * + * @param {string} appid + * + * @return {InstalledApplication} + * If does not existed, undefined will returned + */ + getInstalledApp(appid) { + var ret = native_sync_call('manager.instapp', {'appid': appid}); + if (ret['data']) { + return new InstalledApplication(ret['data']); + } + return undefined; + } + + /** + * @method getRunningApps + * + * @return {Promise | RunningApplication[]} + */ + getRunningApps() { + return new Promise(function(resolve, reject) { + native_async_call('manager.runningapps', undefined, function(msg) { + if (msg['reason']) { + reject(new Error(msg['reason'])); + return; + } + var apps = msg['data'].map(function(app) { + return new RunningApplication(app.id, app.pid); + }); + resolve(apps); + }); + }); + } + + /** + * @method getRunningApp + * + * @param {string | Number} appid or pid + * + * @return {RunningApplication} + * If does not existed, undefined will returned + */ + getRunningApp(appidOrPid) { + var args = {}; + if (typeof appidOrPid === 'number') { + args['pid'] = appidOrPid; + } else { + args['appid'] = appidOrPid; + } + var ret = native_sync_call('manager.runningapp', args); + if (ret['data']) { + return new RunningApplication(ret['data'].id, ret['data'].pid); + } + return undefined; + } + + /** + * @method isRunningApp + * + * @param {string | Number} appid or pid + * @return {boolean} + */ + isRunningApp(appidOrPid) { + return this.getRunningApp(appidOrPid) !== undefined; + } + + __event_handle__(data) { + if (data['event'] != 'launch' && data['event'] !== 'terminate') { + var app = new RunningApplication(data['data'].id, data['data'].pid); + this.emit(data['event'], app); + } + } + + /** + * The event fired when a application is launched + * @event launch + * @param {RunningApplication} launched application + */ + + /** + * The event fired when a application is terminated + * @event terminate + * @param {RunningApplication} terminated application + */ + +}; + +exports = new AppManager(); -- 2.7.4