tizen-app-manager module 58/57358/9 submit/tizen/20160202.022958
authorSeungkeun Lee <sngn.lee@samsung.com>
Tue, 19 Jan 2016 10:30:41 +0000 (19:30 +0900)
committerSeungkeun Lee <sngn.lee@samsung.com>
Tue, 2 Feb 2016 02:01:49 +0000 (11:01 +0900)
 - Use Jsoncpp

Change-Id: I3c3b09d2878bad295966e7c8dd4d08bcc49b2e9e

modules/CMakeLists.txt
modules/tizen-app-manager/CMakeLists.txt [new file with mode: 0755]
modules/tizen-app-manager/app_manager_extension.cc [new file with mode: 0755]
modules/tizen-app-manager/app_manager_extension.h [new file with mode: 0755]
modules/tizen-app-manager/package.json [new file with mode: 0755]
modules/tizen-app-manager/tizen-app-manager_api.js [new file with mode: 0755]

index 1db4c13..1922577 100755 (executable)
@@ -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 (executable)
index 0000000..d2d6b59
--- /dev/null
@@ -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 (executable)
index 0000000..0ccb790
--- /dev/null
@@ -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 <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);
diff --git a/modules/tizen-app-manager/app_manager_extension.h b/modules/tizen-app-manager/app_manager_extension.h
new file mode 100755 (executable)
index 0000000..4e5250f
--- /dev/null
@@ -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 <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_
+
diff --git a/modules/tizen-app-manager/package.json b/modules/tizen-app-manager/package.json
new file mode 100755 (executable)
index 0000000..f2fe26a
--- /dev/null
@@ -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 (executable)
index 0000000..5560e26
--- /dev/null
@@ -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();