[Application] Add Applicatin extension skeleton and getAppInfo/getAppsInfo support
authorLong Xiang <xiang.long@intel.com>
Thu, 27 Feb 2014 07:19:52 +0000 (15:19 +0800)
committerLong Xiang <xiang.long@intel.com>
Thu, 27 Feb 2014 07:19:52 +0000 (15:19 +0800)
The implementation is based on below spec:
https://developer.tizen.org/dev-guide/2.2.0/org.tizen.web.device.apireference/tizen/application.html

The ApplicationInformation class will encapsulate Tizen application info, and
provides serialization method to transfer its data. An internal PkgMgrHandle
class is implemented to abstract appinfo and pkginfo handles, it also provides
methods to fetch different application information from them by using
pkgmgr-info/pkgmgr APIs.

In order to bind current ApplicationId to application extension, we will
translate the Crosswalk application ID to Tizen ApplicationId when it is
created.

13 files changed:
application/application.gyp [new file with mode: 0644]
application/application_api.js [new file with mode: 0644]
application/application_extension.cc [new file with mode: 0644]
application/application_extension.h [new file with mode: 0644]
application/application_information.cc [new file with mode: 0644]
application/application_information.h [new file with mode: 0644]
application/application_instance.cc [new file with mode: 0644]
application/application_instance.h [new file with mode: 0644]
common/common.gypi
common/extension.cc
common/extension.h
packaging/tizen-extensions-crosswalk.spec
tizen-wrt.gyp

diff --git a/application/application.gyp b/application/application.gyp
new file mode 100644 (file)
index 0000000..8fc3812
--- /dev/null
@@ -0,0 +1,36 @@
+{
+  'includes':[
+    '../common/common.gypi',
+  ],
+  'targets': [
+    {
+      'target_name': 'tizen_application',
+      'type': 'loadable_module',
+      'sources': [
+        '../common/extension.cc',
+        '../common/extension.h',
+        'application_api.js',
+        'application_extension.cc',
+        'application_extension.h',
+        'application_information.cc',
+        'application_information.h',
+        'application_instance.cc',
+        'application_instance.h',
+      ],
+      'conditions': [
+        ['extension_host_os == "mobile"', {
+          'includes': [
+            '../common/pkg-config.gypi',
+          ],
+          'variables': {
+            'packages': [
+              'capi-appfw-package-manager',
+              'pkgmgr',
+              'pkgmgr-info',
+            ]
+          },
+        }],
+      ],
+    },
+  ],
+}
diff --git a/application/application_api.js b/application/application_api.js
new file mode 100644 (file)
index 0000000..1548e77
--- /dev/null
@@ -0,0 +1,74 @@
+// Copyright (c) 2014 Intel Corporation. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+var callbacks = {};
+var callbackId = 0;
+var cbKey = '_callback';
+
+function setupCallback(callback) {
+  var id = ++callbackId;
+  callbacks[id] = callback;
+  return id;
+}
+
+// This callback will dispatch message to different handlers by callbackId.
+extension.setMessageListener(function(msg) {
+  var m = JSON.parse(msg);
+  var callback = callbacks[m[cbKey]];
+  delete callbacks[m[cbKey]];
+  callback(m);
+});
+
+// Post async message to extension with callbackId saved. The extension will return
+// a message with the same callbackId to the callback set in setMessageListener.
+var postMessage = function(msg, callbackId) {
+  msg[cbKey] = callbackId;
+  extension.postMessage(JSON.stringify(msg));
+};
+
+var sendSyncMessage = function(msg) {
+  return JSON.parse(extension.internal.sendSyncMessage(JSON.stringify(msg)));
+};
+
+function ApplicationInformation(json) {
+  for (var field in json) {
+    var val = json[field];
+    if (field === 'installDate')
+      val = new Date(val * 1000);
+    Object.defineProperty(this, field, { writable: false, enumerable: true, value: val });
+  }
+}
+
+exports.getAppInfo = function(appId) {
+  if (typeof appId !== 'string' && appId != undefined)
+    throw new tizen.WebAPIException(tizen.WebAPIException.TYPE_MISMATCH_ERR);
+
+  var result = sendSyncMessage({ cmd: 'GetAppInfo', id: appId });
+  if (!result.error)
+    return new ApplicationInformation(result);
+
+  if (result.error === 'appinfo')
+    throw new tizen.WebAPIException(tizen.WebAPIException.NOT_FOUND_ERR);
+  else
+    throw new tizen.WebAPIException(tizen.WebAPIException.UNKNOWN_ERR);
+};
+
+exports.getAppsInfo = function(onsuccess, onerror) {
+  if ((typeof onsuccess !== 'function') ||
+      (onerror && typeof onerror !== 'function'))
+    throw new tizen.WebAPIException(tizen.WebAPIException.TYPE_MISMATCH_ERR);
+
+  var callbackId = setupCallback(function(result) {
+    if (result.error)
+      return onerror(new tizen.WebAPIError(tizen.WebAPIException.UNKNOWN_ERR));
+
+    var appsInfo = [];
+    for (var i = 0, len = result.data.length; i < len; ++i)
+      appsInfo.push(new ApplicationInformation(result.data[i]));
+    return onsuccess(appsInfo);
+  });
+
+  var msg = { cmd: 'GetAppsInfo' };
+  postMessage(msg, callbackId);
+};
diff --git a/application/application_extension.cc b/application/application_extension.cc
new file mode 100644 (file)
index 0000000..4e92314
--- /dev/null
@@ -0,0 +1,59 @@
+// Copyright (c) 2014 Intel Corporation. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "application/application_extension.h"
+
+#include <iostream>
+#include <sstream>
+
+#include "application/application_information.h"
+#include "application/application_instance.h"
+#include "common/picojson.h"
+
+common::Extension* CreateExtension() {
+  // NOTE: The app_id here is package ID instead of application ID for Tizen.
+  // As Crosswalk app has 1 to 1 mapping between package and application, we
+  // can transfer pkg_id to app_id.
+  std::string id_str = common::Extension::GetRuntimeVariable("app_id", 64);
+  picojson::value id_val;
+  std::istringstream buf(id_str);
+  std::string error = picojson::parse(id_val, buf);
+  if (!error.empty()) {
+    std::cerr << "Got invalid application ID." << std::endl;
+    return NULL;
+  }
+
+  std::string pkg_id = id_val.get<std::string>();
+  if (pkg_id.empty()) {
+    std::cerr << "Application extension will not be created without "
+              << "application context." << std::endl;
+    return NULL;
+  }
+
+  std::string app_id = ApplicationInformation::PkgIdToAppId(pkg_id);
+  if (app_id.empty()) {
+    std::cerr << "Can't translate app package ID to application ID."
+              << std::endl;
+    return NULL;
+  }
+
+  return new ApplicationExtension(app_id, pkg_id);
+}
+
+// This will be generated from application_api.js
+extern const char kSource_application_api[];
+
+ApplicationExtension::ApplicationExtension(const std::string& app_id,
+                                           const std::string& pkg_id)
+    : app_id_(app_id),
+      pkg_id_(pkg_id) {
+  SetExtensionName("tizen.application");
+  SetJavaScriptAPI(kSource_application_api);
+}
+
+ApplicationExtension::~ApplicationExtension() {}
+
+common::Instance* ApplicationExtension::CreateInstance() {
+  return new ApplicationInstance(this);
+}
diff --git a/application/application_extension.h b/application/application_extension.h
new file mode 100644 (file)
index 0000000..2a44949
--- /dev/null
@@ -0,0 +1,29 @@
+// Copyright (c) 2014 Intel Corporation. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef APPLICATION_APPLICATION_EXTENSION_H_
+#define APPLICATION_APPLICATION_EXTENSION_H_
+
+#include <string>
+
+#include "common/extension.h"
+
+class ApplicationExtension : public common::Extension {
+ public:
+  ApplicationExtension(const std::string& app_id, const std::string& pkg_id);
+  virtual ~ApplicationExtension();
+
+  const std::string& app_id() const { return app_id_; }
+
+  const std::string& pkg_id() const { return pkg_id_; }
+
+ private:
+  // common::Extension implementation.
+  virtual common::Instance* CreateInstance();
+
+  std::string app_id_;
+  std::string pkg_id_;
+};
+
+#endif  // APPLICATION_APPLICATION_EXTENSION_H_
diff --git a/application/application_information.cc b/application/application_information.cc
new file mode 100644 (file)
index 0000000..186e56f
--- /dev/null
@@ -0,0 +1,313 @@
+// Copyright (c) 2014 Intel Corporation. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "application/application_information.h"
+
+#include <package_info.h>
+#include <package_manager.h>
+#include <package-manager.h>
+#include <pkgmgr-info.h>
+
+#include <memory>
+#include <vector>
+
+namespace {
+
+void SetErrorMessage(picojson::value& error, const std::string& property_name) {
+  std::string error_message = "Fail to get " + property_name;
+  error.get<picojson::object>()["error"] = picojson::value(property_name);
+  error.get<picojson::object>()["message"] = picojson::value(error_message);
+  std::cerr << error_message << std::endl;
+}
+
+// This class contains both appinfo and pkginfo handles for an application, it
+// will manage both handles' lifetime. A special case is when it is instantiated
+// by an existing appinfo handle(e.g. in pkgmgrinfo_app_list_cb callback), the
+// appinfo handle will not owned by it.
+class PkgMgrHandle {
+ public:
+  static PkgMgrHandle* Create(const std::string& app_id,
+                              picojson::value& error) {
+    pkgmgrinfo_appinfo_h appinfo_handle;
+    int ret = pkgmgrinfo_appinfo_get_appinfo(app_id.c_str(), &appinfo_handle);
+    if (ret != PMINFO_R_OK) {
+      SetErrorMessage(error, "appinfo");
+      return NULL;
+    }
+    return CreateInternal(app_id, appinfo_handle, true, error);
+  }
+
+  static PkgMgrHandle* Create(pkgmgrinfo_appinfo_h& appinfo_handle,
+                              picojson::value& error) {
+    char* app_id = NULL;
+    int ret = pkgmgrinfo_appinfo_get_appid(appinfo_handle, &app_id);
+    if (ret != PMINFO_R_OK || !app_id) {
+      SetErrorMessage(error, "appid");
+      return NULL;
+    }
+    return CreateInternal(app_id, appinfo_handle, false, error);
+  }
+
+  ~PkgMgrHandle() {
+    if (owns_appinfo_handle_)
+      pkgmgrinfo_appinfo_destroy_appinfo(appinfo_handle_);
+    pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo_handle_);
+  }
+
+  const std::string& app_id() const { return app_id_; }
+
+  const std::string& pkg_id() const { return pkg_id_; }
+
+  bool GetName(char** name, picojson::value& error) {
+    int ret = pkgmgrinfo_appinfo_get_label(appinfo_handle_, name);
+    if ((ret != PMINFO_R_OK) || (*name == NULL)) {
+      SetErrorMessage(error, "name");
+      return false;
+    }
+    return true;
+  }
+
+  bool GetIcon(char** icon_path, picojson::value& error) {
+    int ret = pkgmgrinfo_appinfo_get_icon(appinfo_handle_, icon_path);
+    if ((ret != PMINFO_R_OK) || (*icon_path == NULL)) {
+      SetErrorMessage(error, "icon_path");
+      return false;
+    }
+    return true;
+  }
+
+  bool GetNoDisplay(bool* show, picojson::value& error) {
+    int ret = pkgmgrinfo_appinfo_is_nodisplay(appinfo_handle_, show);
+    if (ret != PMINFO_R_OK) {
+      SetErrorMessage(error, "show");
+      return false;
+    }
+
+    *show = !(*show);
+    return true;
+  }
+
+  bool GetCategories(std::vector<picojson::value>* categories,
+                     picojson::value& error) {
+    int ret = pkgmgrinfo_appinfo_foreach_category(
+        appinfo_handle_, &PkgMgrHandle::SaveCategoriesCallback, &categories);
+    if (ret != PMINFO_R_OK) {
+      SetErrorMessage(error, "categories");
+      return false;
+    }
+    return true;
+  }
+
+  bool GetVersion(char** version, picojson::value& error) {
+    int ret = pkgmgrinfo_pkginfo_get_version(pkginfo_handle_, version);
+    if ((ret != PMINFO_R_OK) || (*version == NULL)) {
+      SetErrorMessage(error, "version");
+      return false;
+    }
+    return true;
+  }
+
+  bool GetInstallTime(int* install_date, picojson::value& error) {
+    int ret = pkgmgrinfo_pkginfo_get_installed_time(
+        pkginfo_handle_, install_date);
+    if (ret != PMINFO_R_OK) {
+      SetErrorMessage(error, "install_time");
+      return false;
+    }
+    return true;
+  }
+
+  bool GetSize(int* install_size, picojson::value& error) {
+    int ret = pkgmgrinfo_pkginfo_get_total_size(pkginfo_handle_, install_size);
+    if (ret != PMINFO_R_OK) {
+      SetErrorMessage(error, "install_size");
+      return false;
+    }
+    return true;
+  }
+
+ private:
+  static PkgMgrHandle* CreateInternal(const std::string& app_id,
+                                      pkgmgrinfo_appinfo_h& appinfo_handle,
+                                      bool owns_appinfo_handle,
+                                      picojson::value& error) {
+    char* pkg_id = NULL;
+    int ret = package_manager_get_package_id_by_app_id(app_id.c_str(), &pkg_id);
+    if (ret != PACKAGE_MANAGER_ERROR_NONE) {
+      SetErrorMessage(error, "pkgid");
+      pkgmgrinfo_appinfo_destroy_appinfo(appinfo_handle);
+      return NULL;
+    }
+
+    pkgmgrinfo_pkginfo_h pkginfo_handle;
+    ret = pkgmgrinfo_pkginfo_get_pkginfo(pkg_id, &pkginfo_handle);
+    if (ret != PMINFO_R_OK) {
+      SetErrorMessage(error, "pkginfo");
+      pkgmgrinfo_appinfo_destroy_appinfo(appinfo_handle);
+      return NULL;
+    }
+
+    return new PkgMgrHandle(app_id, pkg_id, appinfo_handle,
+                            pkginfo_handle, owns_appinfo_handle);
+  }
+
+  static int SaveCategoriesCallback(const char* category, void* user_data) {
+    if (category) {
+      std::vector<picojson::value>* categories =
+          static_cast<std::vector<picojson::value>*>(user_data);
+      categories->push_back(picojson::value(category));
+    }
+    return 1;
+  }
+
+  PkgMgrHandle(const std::string& app_id,
+               const std::string& pkg_id,
+               pkgmgrinfo_appinfo_h appinfo_handle,
+               pkgmgrinfo_pkginfo_h pkginfo_handle,
+               bool owns_appinfo_handle)
+    : app_id_(app_id),
+      pkg_id_(pkg_id),
+      appinfo_handle_(appinfo_handle),
+      pkginfo_handle_(pkginfo_handle),
+      owns_appinfo_handle_(owns_appinfo_handle) {
+  }
+
+  std::string app_id_;
+  std::string pkg_id_;
+  pkgmgrinfo_appinfo_h appinfo_handle_;
+  pkgmgrinfo_pkginfo_h pkginfo_handle_;
+  bool owns_appinfo_handle_;
+};
+
+void RetrieveAppInfo(PkgMgrHandle& handle,
+                     picojson::value& info,
+                     picojson::value& error) {
+  char* name = NULL;
+  char* icon_path = NULL;
+  char* version = NULL;
+  int install_date = 0;
+  int install_size = 0;
+  bool show = true;
+  std::vector<picojson::value> categories;
+
+  if (!handle.GetName(&name, error) ||
+      !handle.GetIcon(&icon_path, error) ||
+      !handle.GetNoDisplay(&show, error) ||
+      !handle.GetCategories(&categories, error) ||
+      !handle.GetVersion(&version, error) ||
+      !handle.GetInstallTime(&install_date, error) ||
+      !handle.GetSize(&install_size, error)) {
+    return;
+  }
+
+  picojson::value::object& data = info.get<picojson::object>();
+  data["id"] = picojson::value(handle.app_id());
+  data["name"] = picojson::value(name);
+  data["iconPath"] = picojson::value(icon_path);
+  data["version"] = picojson::value(version);
+  data["show"] = picojson::value(show);
+  data["categories"] = picojson::value(categories);
+  data["installDate"] = picojson::value(static_cast<double>(install_date));
+  data["size"] = picojson::value(static_cast<double>(install_size));
+  data["packageId"] = picojson::value(handle.pkg_id());
+}
+
+int GetAllAppInfoCallback(pkgmgrinfo_appinfo_h appinfo_handle,
+                          void* user_data) {
+  picojson::array* data = static_cast<picojson::array*>(user_data);
+  picojson::value info(picojson::object_type, true);
+  picojson::value error(picojson::object_type, true);
+
+  std::unique_ptr<PkgMgrHandle> handle(
+      PkgMgrHandle::Create(appinfo_handle, error));
+  if (!handle) {
+    data->clear();
+    return -1;
+  }
+
+  RetrieveAppInfo(*handle, info, error);
+  if (!error.get<picojson::object>().empty()) {
+    data->clear();
+    return -1;
+  }
+
+  data->push_back(info);
+  return 0;
+}
+
+void RetrieveAllInstalledAppInfo(picojson::value& data,
+                                 picojson::value& error) {
+  int ret = pkgmgrinfo_appinfo_get_installed_list(
+      GetAllAppInfoCallback, &data.get<picojson::array>());
+  if (ret != PMINFO_R_OK) {
+    SetErrorMessage(error, "installed");
+    return;
+  }
+
+  if (data.get<picojson::array>().empty())
+    SetErrorMessage(error, "get_all");
+}
+
+int PkgIdToAppIdCallback(const pkgmgr_appinfo_h handle, void* user_data) {
+  char* app_id = NULL;
+  if (pkgmgr_appinfo_get_appid(handle, &app_id) != PMINFO_R_OK)
+    return 0;
+
+  std::string* data = static_cast<std::string*>(user_data);
+  (*data) = app_id;
+  return 0;
+}
+
+}  // namespace
+
+std::string ApplicationInformation::PkgIdToAppId(const std::string& pkg_id) {
+  pkgmgrinfo_pkginfo_h pkginfo_handle;
+  int ret = pkgmgrinfo_pkginfo_get_pkginfo(pkg_id.c_str(), &pkginfo_handle);
+  if (ret != PMINFO_R_OK)
+    return "";
+
+  std::string app_id;
+  // By now, we only have UI Crosswalk application.
+  pkgmgr_appinfo_get_list(
+      pkginfo_handle, PM_UI_APP, &PkgIdToAppIdCallback, &app_id);
+  return app_id;
+}
+
+picojson::value* ApplicationInformation::GetAllInstalled() {
+  picojson::value* result = new picojson::value(picojson::object_type, true);
+  picojson::value data(picojson::array_type, true);
+  picojson::value error(picojson::object_type, true);
+
+  RetrieveAllInstalledAppInfo(data, error);
+  if (!error.get<picojson::object>().empty())
+    result->get<picojson::object>()["error"] = error;
+  else
+    result->get<picojson::object>()["data"] = data;
+  return result;
+}
+
+ApplicationInformation::ApplicationInformation(const std::string& app_id)
+    : data_(picojson::object_type, true),
+      error_(picojson::object_type, true) {
+  std::unique_ptr<PkgMgrHandle> handle(PkgMgrHandle::Create(app_id, error_));
+  if (handle && IsValid())
+    RetrieveAppInfo(*handle, data_, error_);
+}
+
+ApplicationInformation::~ApplicationInformation() {
+}
+
+std::string ApplicationInformation::Serialize() const {
+  if (IsValid()) {
+    return data_.serialize();
+  } else if (!error_.get<picojson::object>().empty()) {
+    return error_.serialize();
+  } else {
+    return "";
+  }
+}
+
+bool ApplicationInformation::IsValid() const {
+  return error_.get<picojson::object>().empty();
+}
diff --git a/application/application_information.h b/application/application_information.h
new file mode 100644 (file)
index 0000000..c3b60ce
--- /dev/null
@@ -0,0 +1,37 @@
+// Copyright (c) 2014 Intel Corporation. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef APPLICATION_APPLICATION_INFORMATION_H_
+#define APPLICATION_APPLICATION_INFORMATION_H_
+
+#include <string>
+
+#include "common/picojson.h"
+
+// If application information is successfully retrieved, then the data_ value
+// will contains the related info. Otherwise the error_ value will contains
+// failure reason.
+class ApplicationInformation {
+ public:
+  // Translate app's package ID to application ID, only valid for XWalk apps.
+  static std::string PkgIdToAppId(const std::string& pkg_id);
+
+  // Returns a object type value to caller. When success its "data" field will
+  // contains an app info array. When fail its "error" field will contains error
+  // info.
+  static picojson::value* GetAllInstalled();
+
+  explicit ApplicationInformation(const std::string& app_id);
+  ~ApplicationInformation();
+
+  std::string Serialize() const;
+
+ private:
+  bool IsValid() const;
+
+  picojson::value data_;
+  picojson::value error_;
+};
+
+#endif  // APPLICATION_APPLICATION_INFORMATION_H_
diff --git a/application/application_instance.cc b/application/application_instance.cc
new file mode 100644 (file)
index 0000000..5f5bc43
--- /dev/null
@@ -0,0 +1,78 @@
+// Copyright (c) 2014 Intel Corporation. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "application/application_instance.h"
+
+#include "application/application_extension.h"
+#include "application/application_information.h"
+
+#include <memory>
+#include <string>
+
+ApplicationInstance::ApplicationInstance(ApplicationExtension* extension)
+    : extension_(extension) {
+}
+
+ApplicationInstance::~ApplicationInstance() {
+}
+
+void ApplicationInstance::HandleMessage(const char* msg) {
+  picojson::value v;
+
+  std::string err;
+  picojson::parse(v, msg, msg + strlen(msg), &err);
+  if (!err.empty()) {
+    std::cout << "Ignoring message.\n";
+    return;
+  }
+
+  std::string cmd = v.get("cmd").to_str();
+  if (cmd == "GetAppsInfo") {
+    HandleGetAppsInfo(v);
+  } else {
+    std::cout << "ASSERT NOT REACHED.\n";
+  }
+}
+
+void ApplicationInstance::HandleSyncMessage(const char* msg) {
+  picojson::value v;
+  std::string err;
+
+  picojson::parse(v, msg, msg + strlen(msg), &err);
+  if (!err.empty()) {
+    std::cout << "Ignoring message.\n";
+    return;
+  }
+
+  std::string cmd = v.get("cmd").to_str();
+  if (cmd == "GetAppInfo") {
+    HandleGetAppInfo(v);
+  } else {
+    std::cout << "ASSERT NOT REACHED.\n";
+  }
+}
+
+void ApplicationInstance::HandleGetAppInfo(picojson::value& msg) {
+  std::string app_id;
+  if (msg.contains("id") && msg.get("id").is<std::string>())
+    app_id = msg.get("id").to_str();
+  else
+    app_id = extension_->app_id();
+
+  ApplicationInformation app_info(app_id);
+  SendSyncReply(app_info.Serialize().c_str());
+}
+
+void ApplicationInstance::HandleGetAppsInfo(picojson::value& msg) {
+  std::unique_ptr<picojson::value> result(
+      ApplicationInformation::GetAllInstalled());
+  ReturnMessageAsync(msg, result->get<picojson::object>());
+}
+
+void ApplicationInstance::ReturnMessageAsync(picojson::value& msg,
+                                             const picojson::object& obj) {
+  picojson::object& msg_obj = msg.get<picojson::object>();
+  msg_obj.insert(obj.begin(), obj.end());
+  PostMessage(msg.serialize().c_str());
+}
diff --git a/application/application_instance.h b/application/application_instance.h
new file mode 100644 (file)
index 0000000..3fc65c3
--- /dev/null
@@ -0,0 +1,31 @@
+// Copyright (c) 2014 Intel Corporation. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef APPLICATION_APPLICATION_INSTANCE_H_
+#define APPLICATION_APPLICATION_INSTANCE_H_
+
+#include "common/extension.h"
+#include "common/picojson.h"
+
+class ApplicationExtension;
+
+class ApplicationInstance : public common::Instance {
+ public:
+  explicit ApplicationInstance(ApplicationExtension* extension);
+  ~ApplicationInstance();
+
+ private:
+  // common::Instance implementation.
+  virtual void HandleMessage(const char* msg);
+  virtual void HandleSyncMessage(const char* msg);
+
+  void HandleGetAppInfo(picojson::value& msg);
+  void HandleGetAppsInfo(picojson::value& msg);
+
+  void ReturnMessageAsync(picojson::value& msg, const picojson::object& obj);
+
+  ApplicationExtension* extension_;
+};
+
+#endif  // APPLICATION_APPLICATION_INSTANCE_H_
index 1b5be37..fff1cda 100644 (file)
     'sources': [
       'extension_adapter.cc',
       'extension_adapter.h',
+      'picojson.h',
+      'utils.h',
       'XW_Extension.h',
-      'XW_Extension_SyncMessage.h',
       'XW_Extension_EntryPoints.h',
-      'XW_Extension_Runtime.h',
       'XW_Extension_Permissions.h',
-      'picojson.h',
-      'utils.h',
+      'XW_Extension_Runtime.h',
+      'XW_Extension_SyncMessage.h',
     ],
     'cflags': [
       '-std=c++0x',
index 2252d4b..168483a 100644 (file)
@@ -6,6 +6,7 @@
 
 #include <assert.h>
 #include <iostream>
+#include <vector>
 
 namespace {
 
@@ -129,6 +130,15 @@ Instance* Extension::CreateInstance() {
   return NULL;
 }
 
+std::string Extension::GetRuntimeVariable(const char* var_name, unsigned len) {
+  if (!g_runtime)
+    return "";
+
+  std::vector<char> res(len + 1, 0);
+  g_runtime->GetRuntimeVariableString(g_xw_extension, var_name, &res[0], len);
+  return std::string(res.begin(), res.end());
+}
+
 // static
 void Extension::OnShutdown(XW_Extension) {
   delete g_extension;
index d473078..66d8bef 100644 (file)
 // storage points for extension specific objects, use them for that.
 
 #include <sys/types.h>
+
+#include <string>
+
 #include "common/XW_Extension.h"
-#include "common/XW_Extension_SyncMessage.h"
 #include "common/XW_Extension_EntryPoints.h"
-#include "common/XW_Extension_Runtime.h"
 #include "common/XW_Extension_Permissions.h"
+#include "common/XW_Extension_Runtime.h"
+#include "common/XW_Extension_SyncMessage.h"
 
 namespace common {
 
@@ -54,6 +57,8 @@ class Extension {
 
   virtual Instance* CreateInstance();
 
+  static std::string GetRuntimeVariable(const char* var_name, unsigned len);
+
  private:
   friend int32_t ::XW_Initialize(XW_Extension extension,
                                  XW_GetInterface get_interface);
index dc7b10c..f251160 100644 (file)
@@ -22,6 +22,8 @@ Source1001: %{name}.manifest
 BuildRequires: pkgconfig(appcore-common)
 BuildRequires: pkgconfig(bluez)
 BuildRequires: pkgconfig(capi-appfw-application)
+BuildRequires: pkgconfig(capi-appfw-app-manager)
+BuildRequires: pkgconfig(capi-appfw-package-manager)
 BuildRequires: pkgconfig(capi-network-bluetooth)
 BuildRequires: pkgconfig(capi-network-connection)
 BuildRequires: pkgconfig(capi-system-device)
@@ -45,6 +47,7 @@ BuildRequires: pkgconfig(tapi)
 BuildRequires: pkgconfig(libudev)
 BuildRequires: pkgconfig(message-port)
 BuildRequires: pkgconfig(notification)
+BuildRequires: pkgconfig(pkgmgr)
 BuildRequires: pkgconfig(pkgmgr-info)
 BuildRequires: pkgconfig(pmapi)
 BuildRequires: pkgconfig(vconf)
index 12f9fb0..b5dc7d9 100644 (file)
@@ -21,6 +21,7 @@
       'conditions': [
         [ 'extension_host_os == "mobile"', {
           'dependencies': [
+            'application/application.gyp:*',
             'download/download.gyp:*',
             'bookmark/bookmark.gyp:*',
             'messageport/messageport.gyp:*',