<a href="system_setting.html"><div class="block">system setting</div></a>
<a href="time.html"><div class="block">time</div></a>
<a href="tizen.html"><div class="block">tizen top namespace</div></a>
+<a href="package.html"><div class="block">package</div></a>
</body>
</html>
--- /dev/null
+<html>
+<h1>Tizen Package API</h1>
+<body>
+Input package path to Install: <input type="text" id="pkg_install" value="/home/app/content/Downloads/HangOnMan_0.0.2_2013-10-11_182519.wgt"></input>
+<input type="button" value="Install" onclick="handleInstall()"></input>
+<br>
+<br>Package Installation Status:</br>
+<textarea id="install_output" rows="5" cols="64"></textarea>
+
+<br>
+<br>
+Input package ID to Uninstall: <input type="text" id="pkg_remove" value="nrT4AQuzWO"></input>
+<input type="button" value="Uninstall" onclick="handleUninstall()"></input>
+<br>
+<br>Package Uninstallation Status:</br>
+<textarea id="remove_output" rows="5" cols="64"></textarea>
+
+<br>
+<br>
+Input package id: <input type="text" id="pkg_id" value="nrT4AQuzWO"></input>
+<input type="button" value="GePackageInfo" onclick="handleGetPkgInfo()"></input>
+<br>
+<br>Package Information:</br>
+<textarea id="pkg_info" rows="10" cols="64"></textarea>
+
+<br>
+<br>
+<input type="button" value="GetPackagesInfo" onclick="handleGetPkgsInfo()"></input>
+<br>
+<br>Packages Information:</br>
+<textarea id="pkgs_id" rows="5" cols="64"></textarea>
+
+<br>
+<br>
+<input type="button" value="AddPackageInfoEvent" onclick="handleAddPkgInfoEvent()"></input>
+<input type="button" value="RemovePackageInfoEvent" onclick="handleRemovePkgInfoEvent()"></input>
+<br>
+<br>Notifications:</br>
+<textarea id="pkg_event" rows="6" cols="64"></textarea>
+
+<pre id="console"></pre>
+<script src="js/js-test-pre.js"></script>
+<script>
+
+function handleInstall() {
+ try {
+ var pkg_install = document.getElementById("pkg_install");
+ var output = document.getElementById("install_output");
+ var onInstallation = {
+ onprogress: function(packageId, percentage) {
+ output.value += "On installation(" + packageId + ") : progress(" + percentage + ")" + "\n";
+ },
+ oncomplete: function(packageId) {
+ output.value += "Installation(" + packageId + ") Complete" + "\n";
+ }
+ };
+ var onError = function(error) {
+ output.value += "Error occurred on installation : " + error.name + "\n";
+ };
+ // FIXME(babu): https://crosswalk-project.org/jira/browse/XWALK-2564
+ /*tizen.filesystem.resolve(pkg_install.value,
+ function (file) {
+ console.log("file path : " + file.path);
+ //tizen.package.install(file.toURI(), onInstallation, onError);
+ },
+ function (err) {
+ output.value += "Error occurred on resolve : " + err.name + "\n";
+ },
+ "r");*/
+ tizen.package.install(pkg_install.value, onInstallation, onError);
+ } catch (err) {
+ debug(err.name);
+ }
+}
+
+function handleUninstall() {
+ try {
+ var pkg_remove = document.getElementById("pkg_remove");
+ var output = document.getElementById("remove_output");
+ var onUninstallation = {
+ onprogress: function(packageId, percentage) {
+ output.value += "On Uninstallation(" + packageId + ") : progress(" + percentage + ")" + "\n";
+ },
+ oncomplete: function(packageId) {
+ output.value += "Uninstallation(" + packageId + ") Complete" + "\n";
+ }
+ };
+ var onerror = function(error) {
+ output.value += "Error occurred on Uninstallation : " + error.name + "\n";
+ };
+
+ tizen.package.uninstall(pkg_remove.value, onUninstallation, onerror);
+ } catch (err) {
+ debug(err.name);
+ }
+}
+
+function handleGetPkgInfo() {
+ try {
+ var pkg_id = document.getElementById("pkg_id");
+ var info = (pkg_id.value === "current app") ?
+ tizen.package.getPackageInfo() :
+ tizen.package.getPackageInfo(pkg_id.value);
+
+ var output = document.getElementById("pkg_info");
+ output.value += "Current Package ID: " + info.id + "\n";
+ output.value += "name: " + info.name + "\n";
+ output.value += "iconPath: " + info.iconPath + "\n";
+ output.value += "version: " + info.version + "\n";
+ output.value += "totalSize: " + info.totalSize + "\n";
+ output.value += "dataSize: " + info.dataSize + "\n";
+ output.value += "lastModified: " + info.lastModified+ "\n";
+ output.value += "author: " + info.author + "\n";
+ output.value += "description: " + info.description + "\n";
+ output.value += "appIds: " + info.appIds + "\n";
+ } catch (err) {
+ debug(err.name);
+ }
+}
+
+function handleGetPkgsInfo() {
+ try {
+ var output = document.getElementById("pkgs_id");
+ var onsuccess = function(pkgs) {
+ for (var i = 0; i < pkgs.length; i++) {
+ output.value += "Package id["+i+"]: " + pkgs[i].id + "\n";
+ }
+ };
+
+ var onerror = function(error) {
+ output.value += "Fail to get packages info: " + error.name;
+ };
+
+ tizen.package.getPackagesInfo(onsuccess, onerror);
+ } catch (err) {
+ debug(err.name);
+ }
+}
+
+function handleAddPkgInfoEvent() {
+ try {
+ var output = document.getElementById("pkg_event");
+ tizen.package.setPackageInfoEventListener({
+ oninstalled: function(pkginfo) {
+ output.value += "install package name:" + pkginfo.name + "\n";
+ },
+ onupdated: function(pkginfo) {
+ output.value += "update package name:" + pkginfo.name + "\n";
+ },
+ onuninstalled: function(pkgid) {
+ output.value += "uninstalled package id:" + pkgid + '\n';
+ }
+ });
+ } catch(err) {
+ debug(err.name);
+ }
+}
+
+function handleRemovePkgInfoEvent() {
+ try {
+ tizen.package.unsetPackageInfoEventListener();
+ } catch (err) {
+ debug(err.name);
+ }
+}
+
+</script>
+</body>
+</html>
--- /dev/null
+{
+ 'includes':[
+ '../common/common.gypi',
+ ],
+ 'targets': [
+ {
+ 'target_name': 'tizen_package',
+ 'type': 'loadable_module',
+ 'sources': [
+ 'package_api.js',
+ 'package_extension.cc',
+ 'package_extension.h',
+ 'package_extension_utils.h',
+ 'package_info.cc',
+ 'package_info.h',
+ 'package_instance.cc',
+ 'package_instance.h',
+ 'package_manager.cc',
+ 'package_manager.h',
+ ],
+ 'conditions': [
+ ['tizen == 1', {
+ 'includes': [
+ '../common/pkg-config.gypi',
+ ],
+ 'variables': {
+ 'packages': [
+ 'capi-appfw-package-manager',
+ 'pkgmgr',
+ 'pkgmgr-info',
+ ]
+ },
+ }],
+ ],
+ }
+ ]
+}
--- /dev/null
+// 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 PackageEventState = {
+ 'STARTED': 0,
+ 'PROCESSING': 1,
+ 'COMPLETED': 2,
+ 'FAILED': 3
+};
+
+var PackageEventType = {
+ 'INSTALL': 0,
+ 'UNINSTALL': 1,
+ 'UPDATE': 2
+};
+
+var asyncCallbacks = {
+ _next_id: 0,
+ _callbacks: {},
+ key: '_callback',
+ infoEvent: '_pkgInfoEventCallback',
+
+ setup: function(callback) {
+ var id = ++this._next_id;
+ this._callbacks[id] = callback;
+ return id;
+ },
+
+ dispatch: function(m) {
+ var id = m[this.key];
+ var callback = this._callbacks[id];
+ callback.call(null, m);
+ if (m.error != null || m.cmd == PackageEventState.COMPLETED ||
+ m.cmd == PackageEventState.FAILED)
+ delete this._callbacks[id];
+ }
+};
+
+extension.setMessageListener(function(msg) {
+ var m = JSON.parse(msg);
+ if (typeof m[asyncCallbacks.key] === 'number') {
+ asyncCallbacks.dispatch(m);
+ } else if (m[asyncCallbacks.key] === asyncCallbacks.infoEvent &&
+ exports.changeListener != null) {
+ if (m.eventType == PackageEventType.INSTALL) {
+ var pkgInfo = new PackageInformation(m.data);
+ exports.changeListener.oninstalled(pkgInfo);
+ }
+ if (m.eventType == PackageEventType.UPDATE) {
+ var pkgInfo = new PackageInformation(m.data);
+ exports.changeListener.onupdated(m.data);
+ }
+ if (m.eventType == PackageEventType.UNINSTALL) {
+ exports.changeListener.onuninstalled(m.data);
+ }
+ } else {
+ console.error('unexpected message received' + msg);
+ }
+});
+
+function postMessage(msg, callbackId) {
+ msg[asyncCallbacks.key] = callbackId;
+ extension.postMessage(JSON.stringify(msg));
+}
+
+function sendSyncMessage(msg) {
+ return JSON.parse(extension.internal.sendSyncMessage(JSON.stringify(msg)));
+}
+
+function PackageManager() {
+ this.changeListener = null;
+}
+
+function defineReadOnlyProperty(object, key, value) {
+ Object.defineProperty(object, key, {
+ enumerable: true,
+ writable: false,
+ value: value
+ });
+}
+
+// PackageInformation interface.
+function PackageInformation(json) {
+ for (var field in json) {
+ var val = json[field];
+ if (field === 'installDate')
+ val = new Date(val * 1000);
+ defineReadOnlyProperty(this, field, val);
+ }
+}
+
+PackageManager.prototype.install = function(path, onsuccess, onerror) {
+ if (typeof path !== 'string' ||
+ onsuccess === undefined ||
+ onerror && typeof onerror !== 'function')
+ throw new tizen.WebAPIException(tizen.WebAPIException.TYPE_MISMATCH_ERR);
+
+ var callbackId = asyncCallbacks.setup(function(result) {
+ if (result.error != null && typeof onerror === 'function') {
+ onerror(new tizen.WebAPIError(result.errorCode));
+ } else if (result.cmd == PackageEventState.COMPLETED &&
+ typeof onsuccess.oncomplete !== 'undefined') {
+ onsuccess.oncomplete(result.id);
+ } else if (typeof onsuccess.onprogress !== 'undefined') {
+ onsuccess.onprogress(result.id, result.progress);
+ }
+ });
+
+ var msg = { cmd: 'PackageManager.install', id: path };
+ postMessage(msg, callbackId);
+};
+
+PackageManager.prototype.uninstall = function(id, onsuccess, onerror) {
+ if (typeof id !== 'string' ||
+ onsuccess === undefined ||
+ onerror && typeof onerror !== 'function')
+ throw new tizen.WebAPIException(tizen.WebAPIException.TYPE_MISMATCH_ERR);
+
+ var callbackId = asyncCallbacks.setup(function(result) {
+ if (result.error != null && typeof onerror === 'function') {
+ return onerror(new tizen.WebAPIError(result.error));
+ } else if (result.cmd == PackageEventState.COMPLETED &&
+ typeof onsuccess.oncomplete !== 'undefined') {
+ onsuccess.oncomplete(result.id);
+ } else if (typeof onsuccess.onprogress !== 'undefined') {
+ onsuccess.onprogress(result.id, result.progress);
+ }
+ });
+
+ var msg = { cmd: 'PackageManager.uninstall', id: id };
+ postMessage(msg, callbackId);
+};
+
+PackageManager.prototype.getPackageInfo = function(pkgId) {
+ if (typeof pkgId !== 'string' && pkgId != undefined)
+ throw new tizen.WebAPIException(tizen.WebAPIException.TYPE_MISMATCH_ERR);
+
+ var result = sendSyncMessage({ cmd: 'PackageManager.getPackageInfo', id: pkgId });
+ if (result.error != null)
+ throw new tizen.WebAPIException(result.error);
+
+ return new PackageInformation(result.data);
+};
+
+PackageManager.prototype.getPackagesInfo = function(onsuccess, onerror) {
+ if (typeof onsuccess !== 'function' ||
+ onerror && typeof onerror !== 'function')
+ throw new tizen.WebAPIException(tizen.WebAPIException.TYPE_MISMATCH_ERR);
+
+ var callbackId = asyncCallbacks.setup(function(result) {
+ if (result.error != null && typeof onerror === 'function') {
+ return onerror(new tizen.WebAPIError(result.error));
+ }
+
+ var pkgsInfo = [];
+ for (var i = 0, len = result.data.length; i < len; ++i)
+ pkgsInfo.push(new PackageInformation(result.data[i]));
+ return onsuccess(pkgsInfo);
+ });
+
+ var msg = { cmd: 'PackageManager.getPackagesInfo' };
+ postMessage(msg, callbackId);
+};
+
+PackageManager.prototype.setPackageInfoEventListener = function(listener) {
+ if (typeof listener !== 'object' ||
+ typeof listener.oninstalled !== 'function' ||
+ typeof listener.onupdated !== 'function' ||
+ typeof listener.onuninstalled !== 'function')
+ throw new tizen.WebAPIException(tizen.WebAPIException.TYPE_MISMATCH_ERR);
+
+ this.changeListener = listener;
+ sendSyncMessage({cmd: 'PackageManager.setPackageInfoEventListener'});
+};
+
+PackageManager.prototype.unsetPackageInfoEventListener = function() {
+ this.changeListener = null;
+ sendSyncMessage({cmd: 'PackageManager.unsetPackageInfoEventListener'});
+};
+
+exports = new PackageManager();
--- /dev/null
+// 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 <iostream>
+#include <sstream>
+
+#include "common/picojson.h"
+#include "package/package_extension.h"
+#include "package/package_instance.h"
+
+common::Extension* CreateExtension() {
+ 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 app_id = id_val.get<std::string>();
+ if (app_id.empty()) {
+ std::cerr << "Package extension will not be created without "
+ << "context." << std::endl;
+ return NULL;
+ }
+
+ return new PackageExtension(app_id);
+}
+
+// JS source code for the API
+extern const char kSource_package_api[];
+
+PackageExtension::PackageExtension(const std::string& app_id)
+ : app_id_(app_id) {
+ SetExtensionName("tizen.package");
+ SetJavaScriptAPI(kSource_package_api);
+}
+
+PackageExtension::~PackageExtension() {}
+
+common::Instance* PackageExtension::CreateInstance() {
+ return new PackageInstance(this);
+}
--- /dev/null
+// 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 PACKAGE_PACKAGE_EXTENSION_H_
+#define PACKAGE_PACKAGE_EXTENSION_H_
+
+#include <string>
+
+#include "common/extension.h"
+
+class PackageExtension : public common::Extension {
+ public:
+ explicit PackageExtension(const std::string& app_id);
+ virtual ~PackageExtension();
+
+ const std::string& current_app_id() { return app_id_; }
+
+ private:
+ virtual common::Instance* CreateInstance();
+ std::string app_id_;
+};
+
+#endif // PACKAGE_PACKAGE_EXTENSION_H_
--- /dev/null
+// 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 PACKAGE_PACKAGE_EXTENSION_UTILS_H_
+#define PACKAGE_PACKAGE_EXTENSION_UTILS_H_
+
+#include "common/picojson.h"
+#include "tizen/tizen.h"
+
+inline picojson::value* CreateResultMessage() {
+ return new picojson::value(picojson::object());
+}
+
+inline picojson::value* CreateResultMessage(WebApiAPIErrors error) {
+ picojson::object obj;
+ obj["error"] = picojson::value(static_cast<double>(error));
+ return new picojson::value(obj);
+}
+
+inline picojson::value* CreateResultMessage(const picojson::array& data) {
+ picojson::object obj;
+ obj["data"] = picojson::value(data);
+ return new picojson::value(obj);
+}
+
+inline picojson::value* CreateResultMessage(const picojson::value& data) {
+ picojson::object obj;
+ obj["data"] = data;
+ return new picojson::value(obj);
+}
+
+#endif // PACKAGE_PACKAGE_EXTENSION_UTILS_H_
--- /dev/null
+// 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 "package/package_info.h"
+
+#include <package-manager.h>
+#include <pkgmgr-dbinfo.h>
+#include <pkgmgr-info.h>
+
+#include <unistd.h>
+#include <vector>
+
+#include "common/utils.h"
+#include "package/package_extension_utils.h"
+#include "tizen/tizen.h"
+
+namespace {
+
+void SetErrorMessage(picojson::object& error,
+ const std::string& property_name) {
+ std::string error_message = "Fail to get " + property_name;
+ if (property_name == "pkginfo" || property_name == "pkgid")
+ error["code"] = picojson::value(
+ static_cast<double>(WebApiAPIErrors::NOT_FOUND_ERR));
+ else
+ error["code"] = picojson::value(
+ static_cast<double>(WebApiAPIErrors::UNKNOWN_ERR));
+ error["message"] = picojson::value(error_message);
+ std::cerr << error_message << std::endl;
+}
+
+class PkgMgrHandle {
+ public:
+ static PkgMgrHandle* Create(const std::string& id,
+ bool is_app_id,
+ picojson::object& error) {
+ pkgmgr_pkginfo_h pkginfo_handle;
+ int ret = PMINFO_R_OK;
+ char* pkg_id = NULL;
+ uid_t uid = getuid();
+ // Get the package ID of the current application.
+ if (is_app_id) {
+ pkgmgrinfo_appinfo_h handle;
+ if (uid != GLOBAL_USER)
+ ret = pkgmgrinfo_appinfo_get_usr_appinfo(id.c_str(), uid, &handle);
+ else
+ ret = pkgmgrinfo_appinfo_get_appinfo(id.c_str(), &handle);
+
+ if (ret != PMINFO_R_OK) {
+ SetErrorMessage(error, "pkginfo");
+ return NULL;
+ }
+
+ ret = pkgmgrinfo_appinfo_get_pkgid(handle, &pkg_id);
+ pkgmgrinfo_appinfo_destroy_appinfo(handle);
+ if (ret != PMINFO_R_OK) {
+ SetErrorMessage(error, "pkginfo");
+ return NULL;
+ }
+ } else {
+ pkg_id = const_cast<char*>(id.c_str());
+ }
+
+ if (uid != GLOBAL_USER)
+ ret = pkgmgr_pkginfo_get_usr_pkginfo(pkg_id, uid, &pkginfo_handle);
+ else
+ ret = pkgmgr_pkginfo_get_pkginfo(pkg_id, &pkginfo_handle);
+
+ if (ret != PMINFO_R_OK) {
+ SetErrorMessage(error, "pkginfo");
+ return NULL;
+ }
+
+ return new PkgMgrHandle(pkg_id, pkginfo_handle, true);
+ }
+
+ static PkgMgrHandle* Create(pkgmgrinfo_pkginfo_h& pkginfo_handle,
+ picojson::object& error) {
+ char* pkg_id = NULL;
+ int ret = pkgmgrinfo_pkginfo_get_pkgid(pkginfo_handle, &pkg_id);
+ if (ret != PMINFO_R_OK || !pkg_id) {
+ SetErrorMessage(error, "pkgid");
+ return NULL;
+ }
+
+ return new PkgMgrHandle(pkg_id, pkginfo_handle, false);
+ }
+
+ ~PkgMgrHandle() {
+ if (owns_pkginfo_handle_)
+ pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo_handle_);
+ }
+
+ const std::string& pkg_id() const { return pkg_id_; }
+
+ bool GetName(char** name, picojson::object& error) {
+ int ret = pkgmgrinfo_pkginfo_get_pkgname(pkginfo_handle_, name);
+ if (ret != PMINFO_R_OK || *name == NULL) {
+ SetErrorMessage(error, "name");
+ return false;
+ }
+ return true;
+ }
+
+ bool GetIcon(char** icon_path, picojson::object& error) {
+ int ret = pkgmgrinfo_pkginfo_get_icon(pkginfo_handle_, icon_path);
+ if ((ret != PMINFO_R_OK) || (*icon_path == NULL)) {
+ SetErrorMessage(error, "iconPath");
+ return false;
+ }
+ return true;
+ }
+
+ bool GetVersion(char** version, picojson::object& 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 GetTotalSize(int* total_size, picojson::object& error) {
+ int ret = pkgmgrinfo_pkginfo_get_total_size(pkginfo_handle_, total_size);
+ if (ret != PMINFO_R_OK) {
+ SetErrorMessage(error, "totalSize");
+ return false;
+ }
+ return true;
+ }
+
+ bool GetDataSize(int* data_size, picojson::object& error) {
+ int ret = pkgmgrinfo_pkginfo_get_data_size(pkginfo_handle_, data_size);
+ if (ret != PMINFO_R_OK) {
+ SetErrorMessage(error, "dataSize");
+ return false;
+ }
+ return true;
+ }
+
+ bool GetModifiedDate(int* date, picojson::object& error) {
+ int ret = pkgmgrinfo_pkginfo_get_installed_time(pkginfo_handle_, date);
+ if (ret != PMINFO_R_OK) {
+ SetErrorMessage(error, "lastModified");
+ return false;
+ }
+ return true;
+ }
+
+ bool GetAuthor(char** author, picojson::object& error) {
+ int ret = pkgmgrinfo_pkginfo_get_author_name(pkginfo_handle_, author);
+ if (ret != PMINFO_R_OK) {
+ SetErrorMessage(error, "author");
+ return false;
+ }
+ return true;
+ }
+
+ bool GetDescription(char** description, picojson::object& error) {
+ int ret = pkgmgrinfo_pkginfo_get_description(pkginfo_handle_, description);
+ if (ret != PMINFO_R_OK) {
+ SetErrorMessage(error, "description");
+ return false;
+ }
+ return true;
+ }
+
+ bool GetAppIds(std::vector<picojson::value>* appIds,
+ picojson::object& error) {
+ int ret = pkgmgrinfo_appinfo_get_list(pkginfo_handle_, PMINFO_ALL_APP,
+ &PkgMgrHandle::SaveAppIdsCallback, &appIds);
+ if (ret != PMINFO_R_OK) {
+ SetErrorMessage(error, "appIds");
+ return false;
+ }
+ return true;
+ }
+
+ private:
+ static int SaveAppIdsCallback(const pkgmgrinfo_appinfo_h handle, void* data) {
+ char* app_id = NULL;
+ int ret = pkgmgrinfo_appinfo_get_appid(handle, &app_id);
+ if (ret != PMINFO_R_OK)
+ return -1;
+
+ std::vector<picojson::value>* appIds =
+ static_cast<std::vector<picojson::value>*>(data);
+ appIds->push_back(picojson::value(app_id));
+
+ return 1;
+ }
+
+ PkgMgrHandle(const std::string& pkg_id,
+ pkgmgrinfo_pkginfo_h pkginfo_handle,
+ bool owns_pkginfo_handle)
+ : pkg_id_(pkg_id),
+ pkginfo_handle_(pkginfo_handle),
+ owns_pkginfo_handle_(owns_pkginfo_handle) {
+ }
+
+ std::string pkg_id_;
+ pkgmgrinfo_pkginfo_h pkginfo_handle_;
+ bool owns_pkginfo_handle_;
+
+ DISALLOW_COPY_AND_ASSIGN(PkgMgrHandle);
+};
+
+void RetrieveAppInfo(PkgMgrHandle& handle,
+ picojson::object& info,
+ picojson::object& error) {
+ char* name = NULL;
+ char* icon_path = NULL;
+ char* version = NULL;
+ int total_size = 0;
+ int data_size = 0;
+ int modified_date = 0;
+ char* author = NULL;
+ char* description = NULL;
+ std::vector<picojson::value> appIds;
+
+ if (!handle.GetName(&name, error) ||
+ !handle.GetIcon(&icon_path, error) ||
+ !handle.GetVersion(&version, error) ||
+ !handle.GetTotalSize(&total_size, error) ||
+ !handle.GetDataSize(&data_size, error) ||
+ !handle.GetModifiedDate(&modified_date, error) ||
+ !handle.GetAuthor(&author, error) ||
+ !handle.GetDescription(&description, error) ||
+ !handle.GetAppIds(&appIds, error)) {
+ return;
+ }
+
+ info["id"] = picojson::value(handle.pkg_id());
+ info["name"] = picojson::value(name);
+ info["iconPath"] = picojson::value(icon_path);
+ info["version"] = picojson::value(version);
+ info["totalSize"] = picojson::value(static_cast<double>(total_size));
+ info["dataSize"] = picojson::value(static_cast<double>(data_size));
+ info["lastModified"] = picojson::value(static_cast<double>(modified_date));
+ info["author"] = picojson::value(author);
+ info["description"] = picojson::value(description);
+ info["appIds"] = picojson::value(appIds);
+}
+
+int GetPackagesInfoCallback(pkgmgrinfo_pkginfo_h pkginfo_handle,
+ void* user_data) {
+ picojson::array* data = static_cast<picojson::array*>(user_data);
+ picojson::object info;
+ picojson::object error;
+
+ std::unique_ptr<PkgMgrHandle> handle(
+ PkgMgrHandle::Create(pkginfo_handle, error));
+ if (!handle) {
+ data->clear();
+ return -1;
+ }
+
+ RetrieveAppInfo(*handle, info, error);
+ if (!error.empty()) {
+ data->clear();
+ return -1;
+ }
+
+ data->push_back(picojson::value(info));
+ return 0;
+}
+
+void RetrieveAllInstalledPackagesInfo(picojson::array& data,
+ picojson::object& error) {
+ int ret = PMINFO_R_OK;
+ uid_t uid = getuid();
+
+ if (uid != GLOBAL_USER)
+ ret = pkgmgrinfo_pkginfo_get_usr_list(GetPackagesInfoCallback, &data, uid);
+ else
+ ret = pkgmgrinfo_pkginfo_get_list(GetPackagesInfoCallback, &data);
+
+ if (ret != PMINFO_R_OK) {
+ SetErrorMessage(error, "get_all");
+ return;
+ }
+
+ if (data.empty())
+ SetErrorMessage(error, "get_all");
+}
+
+} // namespace
+
+picojson::value* PackageInformation::GetAllInstalled() {
+ picojson::array data;
+ picojson::object error;
+
+ RetrieveAllInstalledPackagesInfo(data, error);
+ if (!error.empty())
+ return CreateResultMessage(WebApiAPIErrors::UNKNOWN_ERR);
+ else
+ return CreateResultMessage(data);
+}
+
+PackageInformation::PackageInformation(
+ const std::string& id,
+ bool is_app_id) {
+ std::unique_ptr<PkgMgrHandle> handle(PkgMgrHandle::Create(
+ id, is_app_id, error_));
+ if (handle && IsValid())
+ RetrieveAppInfo(*handle, data_, error_);
+}
+
+PackageInformation::~PackageInformation() {}
+
+const picojson::value& PackageInformation::Value() {
+ if (value_.is<picojson::null>() && IsValid())
+ value_ = picojson::value(data_);
+
+ return value_;
+}
+
+const std::string PackageInformation::Serialize() {
+ std::unique_ptr<picojson::value> result;
+ if (!IsValid()) {
+ picojson::object::const_iterator it = error_.find("code");
+ assert(it != error_.end());
+ result.reset(CreateResultMessage(
+ static_cast<WebApiAPIErrors>(it->second.get<double>())));
+ } else {
+ result.reset(CreateResultMessage(Value()));
+ }
+
+ return result->serialize();
+}
+
+bool PackageInformation::IsValid() const {
+ return error_.empty();
+}
--- /dev/null
+// 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 PACKAGE_PACKAGE_INFO_H_
+#define PACKAGE_PACKAGE_INFO_H_
+
+#include <memory>
+#include <string>
+
+#include "common/picojson.h"
+
+class PackageInformation {
+ public:
+ static picojson::value* GetAllInstalled();
+
+ PackageInformation(const std::string& id, bool is_app_id);
+ ~PackageInformation();
+
+ const picojson::value& Value();
+ const std::string Serialize();
+ bool IsValid() const;
+
+ private:
+ picojson::object data_;
+ picojson::object error_;
+ picojson::value value_;
+};
+
+#endif // PACKAGE_PACKAGE_INFO_H_
--- /dev/null
+// 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 "package/package_instance.h"
+
+#include "package/package_extension.h"
+#include "package/package_info.h"
+#include "package/package_manager.h"
+
+namespace {
+
+const char kJSCallbackKey[] = "_callback";
+const char kPkgInfoEventCallback[] = "_pkgInfoEventCallback";
+
+} // namespace
+
+PackageInstance::PackageInstance(PackageExtension* extension)
+ : extension_(extension) {
+ package_manager_.reset(new PackageManager(this));
+}
+
+PackageInstance::~PackageInstance() {
+ package_manager_->PackageManagerDestroy();
+}
+
+void PackageInstance::HandleMessage(const char* message) {
+ picojson::value v;
+ picojson::value::object o;
+
+ std::string err;
+ picojson::parse(v, message, message + strlen(message), &err);
+ if (!err.empty()) {
+ std::cerr << "Ignoring message. \n";
+ return;
+ }
+
+ std::string cmd = v.get("cmd").to_str();
+ if (cmd == "PackageManager.install") {
+ HandleInstallRequest(v);
+ } else if (cmd == "PackageManager.uninstall") {
+ HandleUninstallRequest(v);
+ } else if (cmd == "PackageManager.getPackagesInfo") {
+ HandleGetPackagesInfoRequest(v);
+ } else {
+ std::cerr << "Message " + cmd + " is not supported.\n";
+ }
+}
+
+void PackageInstance::HandleSyncMessage(const char* message) {
+ picojson::value v;
+ picojson::value::object o;
+
+ std::string err;
+ picojson::parse(v, message, message + strlen(message), &err);
+ if (!err.empty()) {
+ std::cerr << "Ignoring message.\n";
+ return;
+ }
+
+ std::string cmd = v.get("cmd").to_str();
+ if (cmd == "PackageManager.setPackageInfoEventListener") {
+ HandleRegisterPackageInfoEvent();
+ } else if (cmd == "PackageManager.unsetPackageInfoEventListener") {
+ HandleUnregisterPackageInfoEvent();
+ } else if (cmd == "PackageManager.getPackageInfo") {
+ HandleGetPackageInfoRequest(v);
+ } else {
+ std::cerr << "Message " + cmd + " is not supported.\n";
+ }
+}
+
+void PackageInstance::HandleInstallRequest(const picojson::value& msg) {
+ const char* pkg_path = msg.get("id").to_str().c_str();
+ double callback_id = msg.get(kJSCallbackKey).get<double>();
+ std::unique_ptr<picojson::value> result(
+ package_manager()->InstallPackage(pkg_path, callback_id));
+ if (result)
+ ReturnMessageAsync(callback_id, *result);
+}
+
+void PackageInstance::HandleUninstallRequest(const picojson::value& msg) {
+ const char* pkg_id = msg.get("id").to_str().c_str();
+ double callback_id = msg.get(kJSCallbackKey).get<double>();
+ std::unique_ptr<picojson::value> result(
+ package_manager()->UnInstallPackage(pkg_id, callback_id));
+ if (result)
+ ReturnMessageAsync(callback_id, *result);
+}
+
+void PackageInstance::HandleGetPackageInfoRequest(const picojson::value& msg) {
+ std::string id = (msg.contains("id") && msg.get("id").is<std::string>()) ?
+ msg.get("id").to_str() :
+ extension_->current_app_id();
+
+ PackageInformation pkg_info(id, false);
+ SendSyncReply(pkg_info.Serialize().c_str());
+}
+
+void PackageInstance::HandleGetPackagesInfoRequest(const picojson::value& msg) {
+ std::unique_ptr<picojson::value> result(
+ PackageInformation::GetAllInstalled());
+ double callback_id = msg.get(kJSCallbackKey).get<double>();
+ ReturnMessageAsync(callback_id, *result);
+}
+
+void PackageInstance::HandleRegisterPackageInfoEvent() {
+ std::unique_ptr<picojson::value> result(
+ package_manager()->RegisterPackageInfoEvent());
+ SendSyncReply(result->serialize().c_str());
+}
+
+void PackageInstance::HandleUnregisterPackageInfoEvent() {
+ std::unique_ptr<picojson::value> result(
+ package_manager()->UnregisterPackageInfoEvent());
+ SendSyncReply(result->serialize().c_str());
+}
+
+void PackageInstance::PostPackageInfoEventMessage(picojson::object& events) {
+ events[kJSCallbackKey] = picojson::value(kPkgInfoEventCallback);
+ PostMessage(picojson::value(events).serialize().c_str());
+}
+
+void PackageInstance::PostPackageRequestMessage(
+ picojson::object& reply,
+ double callback_id) {
+ reply[kJSCallbackKey] = picojson::value(callback_id);
+ PostMessage(picojson::value(reply).serialize().c_str());
+}
+
+void PackageInstance::ReturnMessageAsync(
+ double callback_id,
+ picojson::value& value) {
+ value.get<picojson::object>()[kJSCallbackKey] = picojson::value(callback_id);
+ PostMessage(value.serialize().c_str());
+}
--- /dev/null
+// 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 PACKAGE_PACKAGE_INSTANCE_H_
+#define PACKAGE_PACKAGE_INSTANCE_H_
+
+#include <memory>
+#include <string>
+
+#include "common/extension.h"
+#include "common/picojson.h"
+#include "tizen/tizen.h"
+
+namespace picojson {
+
+class value;
+
+} // namespace picojson
+
+class PackageManager;
+class PackageExtension;
+
+class PackageInstance : public common::Instance {
+ public:
+ explicit PackageInstance(PackageExtension* extension);
+ virtual ~PackageInstance();
+
+ void PostPackageInfoEventMessage(picojson::object& events);
+ void PostPackageRequestMessage(picojson::object& events, double callback_id);
+
+ PackageManager* package_manager() { return package_manager_.get(); }
+
+ private:
+ // common::Instance implementation
+ virtual void HandleMessage(const char* msg);
+ virtual void HandleSyncMessage(const char* msg);
+
+ // Synchronous message handlers.
+ void HandleGetPackageInfoRequest(const picojson::value& json);
+ void HandleRegisterPackageInfoEvent();
+ void HandleUnregisterPackageInfoEvent();
+
+ // Asynchronous message handlers.
+ void HandleInstallRequest(const picojson::value& json);
+ void HandleUninstallRequest(const picojson::value& json);
+ void HandleGetPackagesInfoRequest(const picojson::value& json);
+
+ void ReturnMessageAsync(double callback_id, picojson::value& value);
+
+ std::unique_ptr<PackageManager> package_manager_;
+ PackageExtension* extension_;
+};
+
+#endif // PACKAGE_PACKAGE_INSTANCE_H_
--- /dev/null
+// 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 "package/package_manager.h"
+
+#include <package-manager.h>
+#include <pkgmgr-dbinfo.h>
+#include <unistd.h>
+
+#include "common/picojson.h"
+#include "package/package_extension_utils.h"
+#include "package/package_info.h"
+#include "tizen/tizen.h"
+
+namespace {
+
+void PackageRequestsCallback(int id, const char *type, const char *package,
+ package_manager_event_type_e event_type,
+ package_manager_event_state_e event_state,
+ int progress, package_manager_error_e error,
+ void *user_data) {
+ std::string pkg_id(package);
+ PackageManager* manager = static_cast<PackageManager*> (user_data);
+ manager->OnPackageRequestCallback(id, pkg_id, event_type,
+ event_state, progress);
+}
+
+void PackageEventsCallback(const char *type, const char *package,
+ package_manager_event_type_e event_type,
+ package_manager_event_state_e event_state,
+ int progress, package_manager_error_e error,
+ void *user_data) {
+ if (event_state != PACKAGE_MANAGER_EVENT_STATE_COMPLETED)
+ return;
+
+ std::string pkg_id(package);
+ PackageManager* manager = static_cast<PackageManager*> (user_data);
+ manager->OnPackageInfoEvent(pkg_id, event_type);
+}
+
+} // namespace
+
+PackageManager::PackageManager(PackageInstance* instace)
+ : instance_(instace) {
+ int ret = package_manager_create(&manager_);
+ if (ret != PACKAGE_MANAGER_ERROR_NONE)
+ std::cerr << "package manager creation failed." << std::endl;
+
+ ret = package_manager_request_create(&request_handle_);
+ if (ret != PACKAGE_MANAGER_ERROR_NONE) {
+ std::cerr << "package manager fail to create request handle." << std::endl;
+ } else {
+ // Install/Uninstall works only in quiet mode for now.
+ package_manager_request_set_mode(request_handle_,
+ PACKAGE_MANAGER_REQUEST_MODE_QUIET);
+ package_manager_request_set_event_cb(request_handle_,
+ PackageRequestsCallback,
+ this);
+ }
+}
+
+PackageManager::~PackageManager() {}
+
+void PackageManager::PackageManagerDestroy() {
+ if (request_handle_) {
+ package_manager_request_unset_event_cb(request_handle_);
+ package_manager_request_destroy(request_handle_);
+ }
+
+ if (manager_)
+ package_manager_destroy(manager_);
+}
+
+picojson::value* PackageManager::InstallPackage(
+ const char* pkg_path,
+ double callback_id) {
+ int request_id;
+ int ret = package_manager_request_install(
+ request_handle_,
+ pkg_path,
+ &request_id);
+ if (ret != PACKAGE_MANAGER_ERROR_NONE)
+ return CreateResultMessage(WebApiAPIErrors::UNKNOWN_ERR);
+
+ callbacks_id_map_[request_id] = callback_id;
+ return NULL;
+}
+
+picojson::value* PackageManager::UnInstallPackage(
+ const char* pkg_id,
+ double callback_id) {
+ // FIXME(babu): Carshes on calling package_manager_request_uninstall()
+ // if package is not installed. API must be fixed before we remove this.
+ pkgmgr_pkginfo_h handle;
+ uid_t uid = getuid();
+ int ret = (uid != GLOBAL_USER) ?
+ pkgmgr_pkginfo_get_usr_pkginfo(pkg_id, uid, &handle) :
+ pkgmgr_pkginfo_get_pkginfo(pkg_id, &handle);
+
+ if (ret != PKGMGR_R_OK)
+ return CreateResultMessage(WebApiAPIErrors::UNKNOWN_ERR);
+
+ pkgmgr_pkginfo_destroy_pkginfo(handle);
+
+ int request_id;
+ ret = package_manager_request_uninstall(request_handle_,
+ pkg_id,
+ &request_id);
+ if (ret != PACKAGE_MANAGER_ERROR_NONE)
+ return CreateResultMessage(WebApiAPIErrors::UNKNOWN_ERR);
+
+ callbacks_id_map_[request_id] = callback_id;
+ return NULL;
+}
+
+picojson::value* PackageManager::RegisterPackageInfoEvent() {
+ int ret = package_manager_set_event_cb(manager_,
+ PackageEventsCallback,
+ this);
+ if (ret != PACKAGE_MANAGER_ERROR_NONE)
+ return CreateResultMessage(WebApiAPIErrors::UNKNOWN_ERR);
+
+ return CreateResultMessage();
+}
+
+picojson::value* PackageManager::UnregisterPackageInfoEvent() {
+ if (package_manager_unset_event_cb(manager_) != PACKAGE_MANAGER_ERROR_NONE)
+ return CreateResultMessage(WebApiAPIErrors::UNKNOWN_ERR);
+
+ return CreateResultMessage();
+}
+
+void PackageManager::OnPackageRequestCallback(
+ int id,
+ const std::string& pkg_id,
+ int event_type, int event_state,
+ int progress) {
+ picojson::object result;
+ if (event_state != PACKAGE_MANAGER_EVENT_STATE_FAILED) {
+ result["id"] = picojson::value(pkg_id);
+ result["cmd"] = picojson::value(static_cast<double>(event_state));
+ if (event_state != PACKAGE_MANAGER_EVENT_STATE_PROCESSING)
+ result["progress"] = picojson::value(static_cast<double>(progress));
+ } else {
+ result["error"] =
+ picojson::value(static_cast<double>(WebApiAPIErrors::UNKNOWN_ERR));
+ }
+
+ double callback_id = 0;
+ std::map<int, double>::const_iterator iter = callbacks_id_map_.find(id);
+ if (iter != callbacks_id_map_.end())
+ callback_id = iter->second;
+ instance_->PostPackageRequestMessage(result, callback_id);
+}
+
+void PackageManager::OnPackageInfoEvent(
+ const std::string& pkg_id,
+ int event_type) {
+ picojson::object result;
+ if (event_type == PACAKGE_MANAGER_EVENT_TYPE_INSTALL ||
+ event_type == PACKAGE_MANAGER_EVENT_TYPE_UPDATE) {
+ PackageInformation pkg_info(pkg_id, false);
+ if (pkg_info.IsValid())
+ result["data"] = pkg_info.Value();
+ } else if (event_type == PACKAGE_MANAGER_EVENT_TYPE_UNINSTALL) {
+ result["data"] = picojson::value(pkg_id);
+ }
+
+ result["eventType"] = picojson::value(static_cast<double>(event_type));
+ instance_->PostPackageInfoEventMessage(result);
+}
--- /dev/null
+// 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 PACKAGE_PACKAGE_MANAGER_H_
+#define PACKAGE_PACKAGE_MANAGER_H_
+
+#include <package_manager.h>
+
+#include <map>
+#include <string>
+
+#include "package/package_instance.h"
+
+class PackageManager {
+ public:
+ explicit PackageManager(PackageInstance* instance);
+ ~PackageManager();
+ void PackageManagerDestroy();
+
+ picojson::value* InstallPackage(const char* pkg_path, double request_id);
+ picojson::value* UnInstallPackage(const char* pkg_id, double request_id);
+ picojson::value* RegisterPackageInfoEvent();
+ picojson::value* UnregisterPackageInfoEvent();
+
+ void OnPackageInfoEvent(const std::string& pkg_id, int event_type);
+ void OnPackageRequestCallback(
+ int id, const std::string& pkg_id,
+ int event_type, int event_state,
+ int progress);
+
+ private:
+ PackageInstance* instance_;
+ package_manager_h manager_;
+ package_manager_request_h request_handle_;
+ std::map<int, double> callbacks_id_map_;
+};
+
+#endif // PACKAGE_PACKAGE_MANAGER_H_
'filesystem/filesystem.gyp:*',
'messageport/messageport.gyp:*',
'nfc/nfc.gyp:*',
+ 'package/package.gyp:*',
],
}],
[ 'extension_host_os == "mobile"', {