ADD_SUBDIRECTORY(tizen-device)
ADD_SUBDIRECTORY(tizen-system-setting)
ADD_SUBDIRECTORY(tizen-alarm)
+ADD_SUBDIRECTORY(tizen-app-manager)
--- /dev/null
+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}
+)
--- /dev/null
+/*
+ * 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 <dlog.h>
+#include <app_manager.h>
+#include <json/json.h>
+#include <glib.h>
+
+#include <thread> // 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<std::mutex> 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<AppManagerInstance*>(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<std::mutex> 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> appinfo(new AppInfo(handle));
+ {
+ std::lock_guard<std::mutex> 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<CallbackData*>(user_data);
+ app_info_h tostore;
+ app_info_clone(&tostore, app);
+ std::shared_ptr<AppInfo> appinfo(new AppInfo(tostore));
+ {
+ std::lock_guard<std::mutex> 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<CallbackData*>(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<CallbackData*>(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<CallbackData*>(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<Json::Value*>(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);
--- /dev/null
+/*
+ * 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 <app_info.h>
+#include <json/json.h>
+#include <xwalk/xwalk_extension.h>
+
+#include <string>
+#include <map>
+#include <memory> // NOLINT
+#include <mutex>
+
+
+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<AppInfo> 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<int, std::shared_ptr<AppInfo> > handle_map_;
+ std::mutex handle_lock_;
+};
+
+} // namespace appfw
+
+#endif // APP_MANAGER_EXTENSION_H_
+
--- /dev/null
+{
+ "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"
+ }
+}
--- /dev/null
+/*
+ * 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();