From: Tomasz Marciniak Date: Fri, 24 Apr 2015 10:11:29 +0000 (+0200) Subject: [Application] Ported implementation. X-Git-Tag: submit/tizen_tv/20150603.064601~1^2~137 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=31ffdb2e3de99cb1d2dfa08d4ccc53bbdfc7b664;p=platform%2Fcore%2Fapi%2Fwebapi-plugins.git [Application] Ported implementation. [Verification] Code compiles without errors. TCT passrate 100% 159(159/0/0/0) Change-Id: Ic455f8db44f343e3887510b088f1024f6c9dae05 Signed-off-by: Tomasz Marciniak --- diff --git a/src/application/application.cc b/src/application/application.cc index d8151071..b5ae237a 100644 --- a/src/application/application.cc +++ b/src/application/application.cc @@ -6,57 +6,40 @@ #include "common/extension.h" #include "common/logger.h" -#include "common/picojson.h" - #include "common/platform_result.h" -using common::ErrorCode; +using namespace common; +using namespace tools; namespace extension { namespace application { -Application::Application() { -} - -Application::~Application() { -} - -void Application::Hide() { -} - -void Application::Exit() { +RequestedApplicationControl& Application::app_control() { + return app_control_; } -std::string Application::get_context_id() { - return context_id_; -} +void Application::GetRequestedAppControl(const picojson::value& args, picojson::object* out) { + LoggerD("Entered"); -void Application::set_context_id(const std::string& context_id) { - context_id_ = context_id; -} + const std::string& encoded_bundle = + GetCurrentExtension()->GetRuntimeVariable("encoded_bundle", 1024); -ApplicationInformationPtr Application::get_app_info() const { - return app_info_; -} + picojson::value result = picojson::value(picojson::object()); -void Application::set_app_info(const ApplicationInformationPtr& app_info) { - app_info_ = app_info; -} + if (!encoded_bundle.empty()) { + PlatformResult ret = app_control_.set_bundle(encoded_bundle); + if (ret.IsError()) { + ReportError(ret, out); + return; + } -const picojson::value& Application::Value() { - if (!app_info_->IsValid()) { - LoggerD("ErrorCode::UNKNOWN_ERR"); - picojson::object obj; - obj["error"] = picojson::value(static_cast(ErrorCode::UNKNOWN_ERR)); - value_ = picojson::value(obj); + app_control_.ToJson(&result.get()); } else { - picojson::object obj; - LoggerD("Value returns appInfo, contextId"); - obj["appInfo"] = app_info_->Value(); - obj["contextId"] = picojson::value(context_id_); - value_ = picojson::value(obj); + LoggerD("bundle string is empty."); + result = picojson::value(); } - return value_; + + ReportSuccess(result, *out); } } // namespace application diff --git a/src/application/application.gyp b/src/application/application.gyp index 62a83855..24d8fbe2 100644 --- a/src/application/application.gyp +++ b/src/application/application.gyp @@ -17,18 +17,10 @@ 'application_instance.h', 'application.cc', 'application.h', - 'application_information.cc', - 'application_information.h', - 'application_context.cc', - 'application_context.h', - 'application_metadata.cc', - 'application_metadata.h', - 'application_certificate.cc', - 'application_certificate.h', - 'application_control.cc', - 'application_control.h', - 'application_controldata.cc', - 'application_controldata.h', + 'application_manager.cc', + 'application_manager.h', + 'application_utils.cc', + 'application_utils.h', 'requested_application_control.cc', 'requested_application_control.h', ], diff --git a/src/application/application.h b/src/application/application.h index 257606cb..48694a46 100644 --- a/src/application/application.h +++ b/src/application/application.h @@ -8,38 +8,19 @@ #include #include -#include "application/application_information.h" +#include "common/picojson.h" +#include "application/requested_application_control.h" namespace extension { namespace application { -class Application; -typedef std::shared_ptr ApplicationPtr; - class Application { public: - Application(); - ~Application(); - - void Hide(); - void Exit(); - - const picojson::value& Value(); - bool IsValid() const; - - std::string get_context_id(); - void set_context_id(const std::string& context_id); - - ApplicationInformationPtr get_app_info() const; - void set_app_info(const ApplicationInformationPtr &appInfo); + RequestedApplicationControl& app_control(); + void GetRequestedAppControl(const picojson::value& args, picojson::object* out); private: - std::string context_id_; - ApplicationInformationPtr app_info_; - - picojson::object data_; - picojson::object error_; - picojson::value value_; + RequestedApplicationControl app_control_; }; } // namespace application diff --git a/src/application/application_api.js b/src/application/application_api.js index 388dbcf3..950dc915 100644 --- a/src/application/application_api.js +++ b/src/application/application_api.js @@ -1,590 +1,927 @@ -/* global tizen, xwalk, extension */ +//Copyright 2015 Samsung Electronics Co, Ltd. All rights reserved. +//Use of this source code is governed by a BSD-style license that can be +//found in the LICENSE file. -// Copyright 2015 Samsung Electronics Co, Ltd. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. +var T = xwalk.utils.type; +var Converter = xwalk.utils.converter; +var AV = xwalk.utils.validator; - -var validator_ = xwalk.utils.validator; -var types_ = validator_.Types; -var native_ = new xwalk.utils.NativeManager(extension); +var native = new xwalk.utils.NativeManager(extension); var ApplicationControlLaunchMode = { SINGLE: 'SINGLE', GROUP: 'GROUP' }; -function callNative(cmd, args) { - var result = native_.callSync(cmd, args); - - if (typeof result !== 'object') { - throw new WebAPIException(WebAPIException.UNKNOWN_ERR); - } - - if (native_.isSuccess(result)) { - if (native_.getResultObject(result)) { - return native_.getResultObject(result); - } - return true; - } else { - if (result.error) { - throw native_.getErrorObject(result); - } - return false; +// helper functions //////////////////////////////////////////////////// +function _createApplicationControlData(object) { + var ret; + if (!T.isNullOrUndefined(object)) { + ret = new tizen.ApplicationControlData(object.key, object.value); } + return ret; } -function callNativeWithCallback(cmd, args, callback) { - return native_.call(cmd, args, callback); -} - -function setReadOnlyProperty(obj, n, v) { - Object.defineProperty(obj, n, {'value': v, 'writable': false}); +function _createApplicationControlDataArray(object) { + var ret = []; + if (!T.isNullOrUndefined(object) && T.isArray(object)) { + object.forEach(function (o) { + var data = _createApplicationControlData(o); + if (!T.isNullOrUndefined(data)) { + ret.push(data); + } + }); + } + return ret; } -function defineReadWriteProperty(object, key, value) { - Object.defineProperty(object, key, { - enumerable: true, - writable: true, - value: value - }); +function _createApplicationControl(object) { + var ret; + if (!T.isNullOrUndefined(object)) { + ret = new tizen.ApplicationControl(object.operation, + object.uri, + object.mime, + object.category, + _createApplicationControlDataArray(object.data)); + } + return ret; } -function defineReadWriteNonNullProperty(object, key, value) { - var hvalue = value; - Object.defineProperty(object, key, { - enumerable: true, - set: function(val) { - if (val !== null && val !== undefined) { - hvalue = val; +function _createApplicationInformationArray(object) { + var ret = []; + if (!T.isNullOrUndefined(object) && T.isArray(object)) { + object.forEach(function (o) { + var data = new ApplicationInformation(o); + if (!T.isNullOrUndefined(data)) { + ret.push(data); } - }, - get: function() { - return hvalue; - } - }); -} - -function ApplicationManager() { - // constructor of ApplicationManager + }); + } + return ret; } -function getAppInfoWithReadOnly(obj) { - var appInfo = new ApplicationInformation(); - setReadOnlyProperty(appInfo, 'id', obj.id); - setReadOnlyProperty(appInfo, 'name', obj.name); - setReadOnlyProperty(appInfo, 'iconPath', obj.iconPath); - setReadOnlyProperty(appInfo, 'version', obj.version); - setReadOnlyProperty(appInfo, 'show', obj.show); - setReadOnlyProperty(appInfo, 'categories', obj.categories); - setReadOnlyProperty(appInfo, 'installDate', new Date(obj.installDate)); - setReadOnlyProperty(appInfo, 'packageId', obj.packageId); - - Object.defineProperty(appInfo, 'size', { - get: function () { - xwalk.utils.checkPrivilegeAccess('http://tizen.org/privilege/application.info'); - return obj.size; - }, - set: function (value) {}, - enumerable: true - }); +// class ApplicationManager //////////////////////////////////////////////////// +var ApplicationManager = function() { +}; - return appInfo; -} ApplicationManager.prototype.getCurrentApplication = function() { - var nativeParam = { - }; + var result = native.callSync('ApplicationManager_getCurrentApplication', {}); - try { - var syncResult = callNative('ApplicationManager_getCurrentApplication', nativeParam); - } catch (e) { - throw e; + if (native.isFailure(result)) { + throw native.getErrorObject(result); + } else { + return new Application(native.getResultObject(result)); } - - var appInfo = getAppInfoWithReadOnly(syncResult.appInfo); - var app = new Application(); - setReadOnlyProperty(app, 'appInfo', appInfo); - setReadOnlyProperty(app, 'contextId', syncResult.contextId); - return app; }; -ApplicationManager.prototype.kill = function(contextId, successCallback, errorCallback) { - var args = validator_.validateArgs(arguments, [ - {'name': 'contextId', 'type': types_.STRING}, - {'name': 'successCallback', 'type': types_.FUNCTION, 'optional': true, 'nullable': true}, - {'name': 'errorCallback', 'type': types_.FUNCTION, 'optional': true, 'nullable': true} +ApplicationManager.prototype.kill = function() { + var args = AV.validateMethod(arguments, [ + { + name : 'contextId', + type : AV.Types.STRING + }, + { + name : 'successCallback', + type : AV.Types.FUNCTION, + optional : true, + nullable : true + }, + { + name : 'errorCallback', + type : AV.Types.FUNCTION, + optional : true, + nullable : true + } ]); - var nativeParam = { - 'contextId': args.contextId + var callback = function(result) { + if (native.isFailure(result)) { + native.callIfPossible(args.errorCallback, native.getErrorObject(result)); + } else { + native.callIfPossible(args.successCallback); + } }; - try { - var syncResult = - callNativeWithCallback('ApplicationManager_kill', nativeParam, function(result) { - if (native_.isSuccess(result)) { - native_.callIfPossible(args.successCallback); - } else { - native_.callIfPossible(args.errorCallback, native_.getErrorObject(result)); - } - }); - if (native_.isFailure(syncResult)){ - var error = native_.getErrorObject(syncResult); - if (error.code === WebAPIException.NOT_FOUND_ERR - || error.code === WebAPIException.INVALID_VALUES_ERR - || error.code === WebAPIException.UNKNOWN_ERR) { - setTimeout(function() { - native_.callIfPossible(args.errorCallback, error); - }, 0); - return; - } - throw error; - } - } catch (e) { - throw e; + var result = native.call('ApplicationManager_kill', {contextId: args.contextId}, callback); + + if (native.isFailure(result)) { + throw native.getErrorObject(result); } }; -ApplicationManager.prototype.launch = function(id, successCallback, errorCallback) { - var args = validator_.validateArgs(arguments, [ - {'name': 'id', 'type': types_.STRING}, - {'name': 'successCallback', 'type': types_.FUNCTION, 'optional': true, 'nullable': true}, - {'name': 'errorCallback', 'type': types_.FUNCTION, 'optional': true, 'nullable': true} +ApplicationManager.prototype.launch = function() { + var args = AV.validateMethod(arguments, [ + { + name : 'id', + type : AV.Types.STRING + }, + { + name : 'successCallback', + type : AV.Types.FUNCTION, + optional : true, + nullable : true + }, + { + name : 'errorCallback', + type : AV.Types.FUNCTION, + optional : true, + nullable : true + } ]); - var nativeParam = { - 'id': args.id + var callback = function(result) { + if (native.isFailure(result)) { + native.callIfPossible(args.errorCallback, native.getErrorObject(result)); + } else { + native.callIfPossible(args.successCallback); + } }; - try { - var syncResult = - callNativeWithCallback('ApplicationManager_launch', nativeParam, function(result) { - if (native_.isSuccess(result)) { - native_.callIfPossible(args.successCallback); - } else { - native_.callIfPossible(args.errorCallback, native_.getErrorObject(result)); - } - }); - } catch (e) { - throw e; + var result = native.call('ApplicationManager_launch', {id: args.id}, callback); + + if (native.isFailure(result)) { + throw native.getErrorObject(result); } }; -ApplicationManager.prototype.launchAppControl = function(appControl, id, successCallback, - errorCallback, replyCallback) { - var args = validator_.validateArgs(arguments, [ - {'name': 'appControl', 'type': types_.PLATFORM_OBJECT, 'values': tizen.ApplicationControl}, - {'name': 'id', 'type': types_.STRING, 'optional': true, 'nullable': true}, - {'name': 'successCallback', 'type': types_.FUNCTION, 'optional': true, 'nullable': true}, - {'name': 'errorCallback', 'type': types_.FUNCTION, 'optional': true, 'nullable': true}, - {'name': 'replyCallback', 'type': types_.LISTENER, 'values': ['onsuccess', 'onfailure'], - 'optional': true, 'nullable': true} +ApplicationManager.prototype.launchAppControl = function() { + var args = AV.validateMethod(arguments, [ + { + name : 'appControl', + type : AV.Types.PLATFORM_OBJECT, + values : tizen.ApplicationControl + }, + { + name : 'id', + type : AV.Types.STRING, + optional : true, + nullable : true + }, + { + name : 'successCallback', + type : AV.Types.FUNCTION, + optional : true, + nullable : true + }, + { + name : 'errorCallback', + type : AV.Types.FUNCTION, + optional : true, + nullable : true + }, + { + name : 'replyCallback', + type : AV.Types.LISTENER, + values : ['onsuccess', 'onfailure'], + optional : true, + nullable : true + } ]); - var nativeParam = { + var replyCallbackId = 'ApplicationControlDataArrayReplyCallback_' + new Date().valueOf(); + var registeredReplyCallback = function(result) { + if (native.isFailure(result)) { + native.callIfPossible(args.replyCallback.onfailure); + } else { + native.callIfPossible(args.replyCallback.onsuccess, + _createApplicationControlDataArray(result.data)); + } + native.removeListener(replyCallbackId, registeredReplyCallback); + }; + + var callback = function(result) { + if (native.isFailure(result)) { + native.callIfPossible(args.errorCallback, native.getErrorObject(result)); + native.removeListener(replyCallbackId, registeredReplyCallback); + } else { + native.callIfPossible(args.successCallback); + } }; - if (args['id']) { - nativeParam['id'] = args.id; - } - if (args['appControl']) { - nativeParam['appControl'] = args.appControl; + + var callArgs = {}; + callArgs.appControl = args.appControl; + if (args.has.id) { + callArgs.id = args.id; } - if (args.appControl['launchMode'] ) { - nativeParam['launchMode'] = args.appControl['launchMode']; + if (args.has.replyCallback) { + callArgs.replyCallback = replyCallbackId; + native.addListener(replyCallbackId, registeredReplyCallback); } - //Try to find application - try { - if (args['id']) { - this.getAppInfo(args.id); - } - } catch(e) { - //If app cannot be found, it should all errorCallback with NotFoundException. - setTimeout(function() { - native_.callIfPossible(args.errorCallback, e); - }, 0); - } - - try { - var syncResult = - callNativeWithCallback('ApplicationManager_launchAppControl', nativeParam, function(ret) { - // In case of reply, can have onsuccess or onfailure with result.status - // It should be checked first of all - if (ret.type === 'onsuccess') { - if (args.replyCallback) { - args.replyCallback.onsuccess(ret.data); - } - } - else if (ret.type === 'onfailure') { - if (args.replyCallback) { - args.replyCallback.onfailure(); - } - } - else if (ret.status === 'success') { - native_.callIfPossible(args.successCallback); - } - else if (ret.status === 'error') { - native_.callIfPossible(args.errorCallback, native_.getErrorObject(ret)); - } - }); - } catch (e) { - throw e; + var result = native.call('ApplicationManager_launchAppControl', callArgs, callback); + + if (native.isFailure(result)) { + throw native.getErrorObject(result); } }; -ApplicationManager.prototype.findAppControl = function(appControl, successCallback, errorCallback) { - var args = validator_.validateArgs(arguments, [ - {'name': 'appControl', 'type': types_.PLATFORM_OBJECT, 'values': tizen.ApplicationControl}, - {'name': 'successCallback', 'type': types_.FUNCTION}, - {'name': 'errorCallback', 'type': types_.FUNCTION, 'optional': true, 'nullable': true} +ApplicationManager.prototype.findAppControl = function() { + var args = AV.validateMethod(arguments, [ + { + name : 'appControl', + type : AV.Types.PLATFORM_OBJECT, + values : tizen.ApplicationControl + }, + { + name : 'successCallback', + type : AV.Types.FUNCTION + }, + { + name : 'errorCallback', + type : AV.Types.FUNCTION, + optional : true, + nullable : true + } ]); - var nativeParam = { + var callback = function(result) { + if (native.isFailure(result)) { + native.callIfPossible(args.errorCallback, native.getErrorObject(result)); + } else { + var r = native.getResultObject(result); + args.successCallback(_createApplicationInformationArray(r.informationArray), + _createApplicationControl(r.appControl)); + } }; - if (args['appControl']) { - nativeParam['appControl'] = args.appControl; - } - try { - var syncResult = - callNativeWithCallback('ApplicationManager_findAppControl', nativeParam, function(result) { - if (native_.isSuccess(result)) { - var returnArray = []; - for (var i = 0; i < result.informationArray.length; i++) { - var appInfo = getAppInfoWithReadOnly(result.informationArray[i]); - returnArray.push(appInfo); - } - args.successCallback(returnArray, result.appControl); - } else if (native_.isFailure(result)) { - native_.callIfPossible(args.errorCallback, native_.getErrorObject(result)); - } - }); - } catch (e) { - throw e; + var callArgs = {appControl: args.appControl}; + var result = native.call('ApplicationManager_findAppControl', callArgs, callback); + + if (native.isFailure(result)) { + throw native.getErrorObject(result); } }; -ApplicationManager.prototype.getAppsContext = function(successCallback, errorCallback) { - var args = validator_.validateArgs(arguments, [ - {'name': 'successCallback', 'type': types_.FUNCTION}, - {'name': 'errorCallback', 'type': types_.FUNCTION, 'optional': true, 'nullable': true} +ApplicationManager.prototype.getAppsContext = function() { + var args = AV.validateMethod(arguments, [ + { + name : 'successCallback', + type : AV.Types.FUNCTION + }, + { + name : 'errorCallback', + type : AV.Types.FUNCTION, + optional : true, + nullable : true + } ]); - var nativeParam = { + var callback = function(result) { + if (native.isFailure(result)) { + native.callIfPossible(args.errorCallback, native.getErrorObject(result)); + } else { + var contexts = native.getResultObject(result).contexts; + var c = []; + contexts.forEach(function (i) { + c.push(new ApplicationContext(i)); + }); + args.successCallback(c); + } }; - try { - var syncResult = - callNativeWithCallback('ApplicationManager_getAppsContext', nativeParam, function(result) { - if (native_.isSuccess(result)) { - var returnArray = []; - for (var index = 0; index < result.contexts.length; index++) { - var appContext = new ApplicationContext(); - setReadOnlyProperty(appContext, 'id', result.contexts[index].id); - setReadOnlyProperty(appContext, 'appId', result.contexts[index].appId); - returnArray.push(appContext); - } - args.successCallback(returnArray); - } - else if (result.status === 'error') { - native_.callIfPossible(args.errorCallback, native_.getErrorObject(result)); - } - }); - } catch (e) { - throw e; + + var result = native.call('ApplicationManager_getAppsContext', {}, callback); + + if (native.isFailure(result)) { + throw native.getErrorObject(result); } }; -ApplicationManager.prototype.getAppContext = function(contextId) { - var args = validator_.validateArgs(arguments, [ - {'name': 'contextId', 'type': types_.STRING, 'optional': true, 'nullable': true} +ApplicationManager.prototype.getAppContext = function() { + var args = AV.validateMethod(arguments, [ + { + name : 'contextId', + type : AV.Types.STRING, + optional : true, + nullable : true + } ]); - var nativeParam = { - }; - if (args['contextId']) { - nativeParam['contextId'] = args.contextId; - } - try { - var syncResult = callNative('ApplicationManager_getAppContext', nativeParam); - } catch (e) { - throw e; + var callArgs = {}; + + if (args.has.contextId) { + callArgs.contextId = args.contextId; } - var returnObject = new ApplicationContext(); - setReadOnlyProperty(returnObject, 'id', syncResult.id); // read only property - setReadOnlyProperty(returnObject, 'appId', syncResult.appId); // read only property + var result = native.callSync('ApplicationManager_getAppContext', callArgs); - return returnObject; + if (native.isFailure(result)) { + throw native.getErrorObject(result); + } else { + return new ApplicationContext(native.getResultObject(result)); + } }; -ApplicationManager.prototype.getAppsInfo = function(successCallback, errorCallback) { - var args = validator_.validateArgs(arguments, [ - {'name': 'successCallback', 'type': types_.FUNCTION}, - {'name': 'errorCallback', 'type': types_.FUNCTION, 'optional': true, 'nullable': true} +ApplicationManager.prototype.getAppsInfo = function() { + var args = AV.validateMethod(arguments, [ + { + name : 'successCallback', + type : AV.Types.FUNCTION + }, + { + name : 'errorCallback', + type : AV.Types.FUNCTION, + optional : true, + nullable : true + } ]); - var nativeParam = { + var callback = function(result) { + if (native.isFailure(result)) { + native.callIfPossible(args.errorCallback, native.getErrorObject(result)); + } else { + args.successCallback(_createApplicationInformationArray( + native.getResultObject(result).informationArray) + ); + } }; - try { - var syncResult = - callNativeWithCallback('ApplicationManager_getAppsInfo', nativeParam, function(result) { - if (native_.isSuccess(result)) { - var returnArray = []; - for (var i = 0; i < result.informationArray.length; i++) { - var appInfo = getAppInfoWithReadOnly(result.informationArray[i]); - returnArray.push(appInfo); - } - args.successCallback(returnArray); - } - else if (native_.isFailure(result)) { - native_.callIfPossible(args.errorCallback, native_.getErrorObject(result)); - } - }); - } catch (e) { - throw e; + + var result = native.call('ApplicationManager_getAppsInfo', {}, callback); + + if (native.isFailure(result)) { + throw native.getErrorObject(result); } }; -ApplicationManager.prototype.getAppInfo = function(id) { - var args = validator_.validateArgs(arguments, [ - {'name': 'id', 'type': types_.STRING, 'optional': true, 'nullable': true} +ApplicationManager.prototype.getAppInfo = function() { + var args = AV.validateMethod(arguments, [ + { + name : 'id', + type : AV.Types.STRING, + optional : true, + nullable : true + } ]); - var nativeParam = { - }; - if (args['id']) { - nativeParam['id'] = args.id; + var callArgs = {}; + + if (args.has.id) { + callArgs.id = args.id; } - try { - var syncResult = callNative('ApplicationManager_getAppInfo', nativeParam); - } catch (e) { - throw e; + + var result = native.callSync('ApplicationManager_getAppInfo', callArgs); + + if (native.isFailure(result)) { + throw native.getErrorObject(result); + } else { + return new ApplicationInformation(native.getResultObject(result)); } - var appInfo = getAppInfoWithReadOnly(syncResult); - return appInfo; }; -ApplicationManager.prototype.getAppCerts = function(id) { - var args = validator_.validateArgs(arguments, [ - {'name': 'id', 'type': types_.STRING, 'optional': true, 'nullable': true} +ApplicationManager.prototype.getAppCerts = function() { + var args = AV.validateMethod(arguments, [ + { + name : 'id', + type : AV.Types.STRING, + optional : true, + nullable : true + } ]); - var nativeParam = { - }; - if (args['id']) { - nativeParam['id'] = args.id; - } - try { - var syncResult = callNative('ApplicationManager_getAppCerts', nativeParam); - } catch (e) { - throw e; + var callArgs = {}; + + if (args.has.id) { + callArgs.id = args.id; } - var returnArrayObject = []; + var result = native.callSync('ApplicationManager_getAppCerts', callArgs); - for (var i = 0; i < syncResult.length; i++) { - var returnObject = new ApplicationCertificate(); - setReadOnlyProperty(returnObject, 'type', syncResult[i].type); // read only property - setReadOnlyProperty(returnObject, 'value', syncResult[i].value); // read only property - returnArrayObject.push(returnObject); + if (native.isFailure(result)) { + throw native.getErrorObject(result); + } else { + var certificates = native.getResultObject(result); + var c = []; + certificates.forEach(function (i) { + c.push(new ApplicationCertificate(i)); + }); + return c; } - return returnArrayObject; }; ApplicationManager.prototype.getAppSharedURI = function() { - var args = validator_.validateArgs(arguments, [ - {'name': 'id', 'type': types_.STRING, optional: true, nullable: true} + var args = AV.validateMethod(arguments, [ + { + name : 'id', + type : AV.Types.STRING, + optional : true, + nullable : true + } ]); - var nativeParam = { - }; - if (args['id']) { - nativeParam['id'] = args.id; - } - try { - var syncResult = callNative('ApplicationManager_getAppSharedURI', nativeParam); - } catch (e) { - throw e; + var callArgs = {}; + + if (args.has.id) { + callArgs.id = args.id; } - return syncResult; + var result = native.callSync('ApplicationManager_getAppSharedURI', callArgs); + + if (native.isFailure(result)) { + throw native.getErrorObject(result); + } else { + return native.getResultObject(result); + } }; -ApplicationManager.prototype.getAppMetaData = function(id) { - var args = validator_.validateArgs(arguments, [ - {'name': 'id', 'type': types_.STRING, 'optional': true, 'nullable': true} +ApplicationManager.prototype.getAppMetaData = function() { + var args = AV.validateMethod(arguments, [ + { + name : 'id', + type : AV.Types.STRING, + optional : true, + nullable : true + } ]); - var nativeParam = { - }; - if (args['id']) { - nativeParam['id'] = args.id; + var callArgs = {}; + + if (args.has.id) { + callArgs.id = args.id; } - try { - var syncResult = callNative('ApplicationManager_getAppMetaData', nativeParam); - } catch (e) { - throw e; + + var result = native.callSync('ApplicationManager_getAppMetaData', callArgs); + + if (native.isFailure(result)) { + throw native.getErrorObject(result); + } else { + var metaData = native.getResultObject(result); + var md = []; + metaData.forEach(function (i) { + md.push(new ApplicationMetaData(i)); + }); + return md; } +}; + +function ListenerManager(native, listenerName) { + this.listeners = {}; + this.nextId = 1; + this.nativeSet = false; + this.native = native; + this.listenerName = listenerName; +}; + +ListenerManager.prototype.onListenerCalled = function(msg) { + var d = null; - var returnArrayObject = []; + switch (msg.action) { + case 'oninstalled': + case 'onupdated': + d = new ApplicationInformation(msg.data); + break; - for (var i = 0; i < syncResult.length; i++) { - var returnObject = new ApplicationMetaData(); - setReadOnlyProperty(returnObject, 'key', syncResult[i].key); // read only property - setReadOnlyProperty(returnObject, 'value', syncResult[i].value); // read only property - returnArrayObject.push(returnObject); + case 'onuninstalled': + d = msg.data; + break; + + default: + console.logd('Unknown mode: ' + msg.action); + return; + } + + for (var watchId in this.listeners) { + if (this.listeners.hasOwnProperty(watchId) && this.listeners[watchId][msg.action]) { + this.listeners[watchId][msg.action](d); + } } - return returnArrayObject; }; -ApplicationManager.prototype.addAppInfoEventListener = function(eventCallback) { - var args = validator_.validateArgs(arguments, [ - {'name': 'eventCallback', 'type': types_.LISTENER, - 'values': ['oninstalled', 'onupdated', 'onuninstalled']} - ]); +ListenerManager.prototype.addListener = function(callback) { + console.log('ListenerManager.prototype.addListener'); + var id = this.nextId; + if (!this.nativeSet) { + this.native.addListener(this.listenerName, this.onListenerCalled.bind(this)); + var result = this.native.callSync('ApplicationManager_addAppInfoEventListener'); + if (this.native.isFailure(result)) { + throw this.native.getErrorObject(result); + } + this.nativeSet = true; + } - var param = { - }; - try { - var syncResult = - callNativeWithCallback('ApplicationManager_addAppInfoEventListener', param, function(ret) { - if (ret.type === 'oninstalled') { - var appInfo = getAppInfoWithReadOnly(ret.info); - args.eventCallback.oninstalled(appInfo); - } else if (ret.type === 'onupdated') { - var appInfo = getAppInfoWithReadOnly(ret.info); - args.eventCallback.oninstalled(appInfo); - } else if (ret.type === 'onuninstalled') { - args.eventCallback.onuninstalled(ret.id); - } - }); - } catch (e) { - throw e; + this.listeners[id] = callback; + ++this.nextId; + + return id; +}; + +ListenerManager.prototype.removeListener = function(watchId) { + if (this.listeners.hasOwnProperty(watchId)) { + delete this.listeners[watchId]; } - return syncResult; + if (this.nativeSet && T.isEmptyObject(this.listeners)) { + this.native.callSync('ApplicationManager_removeAppInfoEventListener'); + this.native.removeListener(this.listenerName); + this.nativeSet = false; + } }; -ApplicationManager.prototype.removeAppInfoEventListener = function(watchId) { - var args = validator_.validateArgs(arguments, [ - {'name': 'watchId', 'type': types_.LONG} +var APPLICATION_EVENT_LISTENER = 'ApplicationEventListener'; +var applicationEventListener = new ListenerManager(native, APPLICATION_EVENT_LISTENER); + +ApplicationManager.prototype.addAppInfoEventListener = function() { + var args = AV.validateMethod(arguments, [ + { + name : 'eventCallback', + type : AV.Types.LISTENER, + values : ['oninstalled', 'onupdated', 'onuninstalled'] + } ]); - var nativeParam = { - 'watchId': args.watchId - }; - try { - var syncResult = callNative('ApplicationManager_removeAppInfoEventListener', nativeParam); - } catch (e) { - throw e; - } + return applicationEventListener.addListener(args.eventCallback); +}; + +ApplicationManager.prototype.removeAppInfoEventListener = function() { + var args = AV.validateMethod(arguments, [ + { + name : 'watchId', + type : AV.Types.LONG + } + ]); + + applicationEventListener.removeListener(args.watchId); }; -function Application() { - // constructor of Application +// class Application //////////////////////////////////////////////////// + +function Application(data) { + Object.defineProperties(this, { + appInfo : { + value : new ApplicationInformation(data.appInfo), + writable : false, + enumerable : true + }, + contextId : { + value : Converter.toString(data.contextId), + writable : false, + enumerable : true + } + }); } Application.prototype.exit = function() { - return native_.sendRuntimeMessage('Application_exit'); + native.sendRuntimeMessage('tizen://exit'); }; Application.prototype.hide = function() { - return native_.sendRuntimeMessage('Application_hide'); + native.sendRuntimeMessage('tizen://hide'); }; Application.prototype.getRequestedAppControl = function() { - var nativeParam = { - }; - try { - var syncResult = callNative('Application_getRequestedAppControl', nativeParam); - } catch (e) { - throw e; + var result = native.callSync('Application_getRequestedAppControl', {}); + + if (native.isFailure(result)) { + throw native.getErrorObject(result); + } else { + result = native.getResultObject(result); + if (result) { + return new RequestedApplicationControl(result); + } else { + return null; + } } +}; - var returnObject = new RequestedApplicationControl(); - setReadOnlyProperty(returnObject, 'appControl', syncResult.appControl); // read only property - setReadOnlyProperty(returnObject, 'callerAppId', syncResult.callerAppId); // read only property +// class ApplicationInformation //////////////////////////////////////////////////// - return returnObject; -}; +function ApplicationInformation(data) { + var size; + var sizeException; -function ApplicationInformation() { - // constructor of ApplicationInformation + function sizeGetter() { + if (undefined === size) { + var callArgs = { packageId : this.packageId }; // jshint ignore:line + var result = native.callSync('ApplicationInformation_getSize', callArgs); + + if (native.isFailure(result)) { + sizeException = native.getErrorObject(result); + size = 0; + } else { + size = native.getResultObject(result).size; + } + } + + if (undefined !== sizeException) { + throw sizeException; + } + + return size; + } + + Object.defineProperties(this, { + id : { + value : data.id, + writable : false, + enumerable : true + }, + name : { + value : data.name, + writable : false, + enumerable : true + }, + iconPath : { + value : data.iconPath, + writable : false, + enumerable : true + }, + version : { + value : data.version, + writable : false, + enumerable : true + }, + show : { + value : data.show, + writable : false, + enumerable : true + }, + categories : { + value : data.categories, + writable : false, + enumerable : true + }, + installDate : { + value : new Date(data.installDate), + writable : false, + enumerable : true + }, + size : { + enumerable : true, + set : function() { + }, + get : sizeGetter + }, + packageId : { + value : data.packageId, + writable : false, + enumerable : true + } + }); } -function ApplicationContext() { - // constructor of ApplicationContext +// class ApplicationContext //////////////////////////////////////////////////// + +function ApplicationContext(data) { + Object.defineProperties(this, { + id : {value: data.id, writable: false, enumerable: true}, + appId : {value: data.appId, writable: false, enumerable: true} + }); } -tizen.ApplicationControlData = function(key, value) { - if (this && this.constructor === tizen.ApplicationControlData && - (typeof(key) === 'string' || key instanceof String) && - (value && value instanceof Array)) { - defineReadWriteNonNullProperty(this, 'key', key); - defineReadWriteNonNullProperty(this, 'value', value); - } else { - throw new WebAPIException(WebAPIException.TYPE_MISMATCH_ERR); +// class ApplicationControlData //////////////////////////////////////////////////// + +tizen.ApplicationControlData = function(k, v) { + AV.validateConstructorCall(this, tizen.ApplicationControlData); + + var valid = (arguments.length >= 2) && T.isArray(v); + + var key; + function keySetter(k) { + key = Converter.toString(k); + } + if (valid) { + keySetter(k); } -}; -tizen.ApplicationControl = function(operation, uri, mime, category, data, launchMode) { - if (this && this.constructor === tizen.ApplicationControl && - (typeof(operation) === 'string' || operation instanceof String)) { + var value; + function valueSetter(v) { + if (T.isArray(v)) { + value = []; + for (var i = 0; i < v.length; ++i) { + value.push(Converter.toString(v[i])); + } + } + } + if (valid) { + valueSetter(v); + } - defineReadWriteNonNullProperty(this, 'operation', operation); - defineReadWriteProperty(this, 'uri', uri); - defineReadWriteProperty(this, 'mime', mime); - defineReadWriteProperty(this, 'category', category); - defineReadWriteProperty(this, 'data', data); - defineReadWriteProperty(this, 'launchMode', launchMode); + Object.defineProperties(this, { + key : { + enumerable : true, + set : keySetter, + get : function() { + return key; + } + }, + value : { + enumerable : true, + set : valueSetter, + get : function() { + return value; + } + } + }); +} - } else { - throw new WebAPIException(WebAPIException.TYPE_MISMATCH_ERR); +// class ApplicationControl //////////////////////////////////////////////////// + +tizen.ApplicationControl = function(o, u, m, c, d, mode) { + AV.validateConstructorCall(this, tizen.ApplicationControl); + + var valid = (arguments.length >= 1); + + var operation; + function operationSetter(o) { + operation = Converter.toString(o); } -}; + if (valid) { + operationSetter(o); + } + + var uri; + function uriSetter(u) { + if (T.isNull(u)) { + uri = u; + } else { + uri = Converter.toString(u); + } + } + if (valid) { + uriSetter(T.isUndefined(u) ? null : u); + } + + var mime; + function mimeSetter(m) { + if (T.isNull(m)) { + mime = m; + } else { + mime = Converter.toString(m); + } + } + if (valid) { + mimeSetter(T.isUndefined(m) ? null : m); + } + + var category; + function categorySetter(c) { + if (T.isNull(c)) { + category = c; + } else { + category = Converter.toString(c); + } + } + if (valid) { + categorySetter(T.isUndefined(c) ? null : c); + } + + var data; + function dataSetter(d) { + if (T.isArray(d)) { + for (var i = 0; i < d.length; ++i) { + if (!(d[i] instanceof tizen.ApplicationControlData)) { + return; + } + } + data = d; + } + } + if (valid) { + dataSetter(T.isNullOrUndefined(d) ? [] : d); + } + + var launchMode; + function launchModeSetter(mode) { + if (ApplicationControlLaunchMode[mode]) { + launchMode = ApplicationControlLaunchMode[mode]; + } + } + if (valid) { + if (T.isNullOrUndefined(mode) || !ApplicationControlLaunchMode[mode]) { + launchMode = ApplicationControlLaunchMode['SINGLE']; + } else { + launchModeSetter(mode); + } + } + + Object.defineProperties(this, { + operation : { + enumerable : true, + set : operationSetter, + get : function() { + return operation; + } + }, + uri : { + enumerable : true, + set : uriSetter, + get : function() { + return uri; + } + }, + mime : { + enumerable : true, + set : mimeSetter, + get : function() { + return mime; + } + }, + category : { + enumerable : true, + set : categorySetter, + get : function() { + return category; + } + }, + data : { + enumerable : true, + set : dataSetter, + get : function() { + return data; + } + }, + launchMode : { + enumerable : true, + set : launchModeSetter, + get : function() { + return launchMode; + } + } + }); +} + +// class RequestedApplicationControl //////////////////////////////////////////////////// -function RequestedApplicationControl() { - // constructor of RequestedApplicationControl +function RequestedApplicationControl(data) { + Object.defineProperties(this, { + appControl : { + value: _createApplicationControl(data.appControl), + writable: false, + enumerable: true + }, + callerAppId : { + value: data.callerAppId, + writable: false, + enumerable: true + } + }); } -RequestedApplicationControl.prototype.replyResult = function(data) { - var args = validator_.validateArgs(arguments, [ - {'name': 'data', 'type': types_.PLATFORM_OBJECT, - 'values': tizen.ApplicationControlData, 'optional': true} +RequestedApplicationControl.prototype.replyResult = function() { + var args = AV.validateMethod(arguments, [ + { + name : 'data', + type : AV.Types.ARRAY, + values : tizen.ApplicationControlData, + optional: true, + nullable: true + } ]); - var nativeParam = { - }; - if (args['data']) { - nativeParam['data'] = args.data; + + var callArgs = {}; + + if (args.has.data) { + callArgs.data = args.data; + } else { + callArgs.data = []; } - if (this.callerAppId) - nativeParam['callerAppId'] = this.callerAppId; - try { - var syncResult = callNative('RequestedApplicationControl_replyResult', nativeParam); - } catch (e) { - throw e; + + var result = native.callSync('RequestedApplicationControl_replyResult', callArgs); + + if (native.isFailure(result)) { + throw native.getErrorObject(result); } }; RequestedApplicationControl.prototype.replyFailure = function() { - var nativeParam = { - }; - if (this.callerAppId) - nativeParam['callerAppId'] = this.callerAppId; - try { - var syncResult = callNative('RequestedApplicationControl_replyFailure', nativeParam); - } catch (e) { - throw e; + var result = native.callSync('RequestedApplicationControl_replyFailure', {}); + + if (native.isFailure(result)) { + throw native.getErrorObject(result); } }; -function ApplicationCertificate() { - // constructor of ApplicationCertificate +// class ApplicationCertificate //////////////////////////////////////////////////// + +function ApplicationCertificate(data) { + Object.defineProperties(this, { + type : { + value : data.type, + writable : false, + enumerable : true + }, + value : { + value : data.value, + writable : false, + enumerable : true + } + }); } -function ApplicationMetaData() { - // constructor of ApplicationMetaData +// class ApplicationMetaData //////////////////////////////////////////////////// +function ApplicationMetaData(data) { + Object.defineProperties(this, { + key : { + value : data.key, + writable : false, + enumerable : true + }, + value : { + value : data.value, + writable : false, + enumerable : true + } + }); } +// exports //////////////////////////////////////////////////// exports = new ApplicationManager(); diff --git a/src/application/application_certificate.cc b/src/application/application_certificate.cc deleted file mode 100644 index c59889f2..00000000 --- a/src/application/application_certificate.cc +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright 2014 Samsung Electronics Co, Ltd. 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_certificate.h" - -#include - -#include "common/logger.h" -#include "tizen/tizen.h" - -namespace extension { -namespace application { - -ApplicationCertificate::ApplicationCertificate() { -} - -ApplicationCertificate::~ApplicationCertificate() { -} - -const picojson::value& ApplicationCertificate::Value() { - if (value_.is() && IsValid()) { - picojson::object obj; - obj["type"] = picojson::value(cert_type_); - obj["value"] = picojson::value(cert_value_); - value_ = picojson::value(obj); - } - return value_; -} - -bool ApplicationCertificate::IsValid() const { - return error_.empty(); -} - -std::string ApplicationCertificate::get_cert_type() const { - return cert_type_; -} - -void ApplicationCertificate::set_cert_type(const std::string& cert_type) { - cert_type_ = cert_type; -} - -std::string ApplicationCertificate::get_cert_value() const { - return cert_value_; -} - -void ApplicationCertificate::set_cert_value(const std::string& cert_value) { - cert_value_ = cert_value; -} - -} // namespace application -} // namespace extension diff --git a/src/application/application_certificate.h b/src/application/application_certificate.h deleted file mode 100644 index 21a9ef0c..00000000 --- a/src/application/application_certificate.h +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright 2014 Samsung Electronics Co, Ltd. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef SRC_APPLICATION_APPLICATION_CERTIFICATE_H_ -#define SRC_APPLICATION_APPLICATION_CERTIFICATE_H_ - -#include -#include -#include - -#include "common/picojson.h" -#include "tizen/tizen.h" - -namespace extension { -namespace application { - -class ApplicationCertificate; -typedef std::shared_ptr ApplicationCertificatePtr; - -typedef std::vector ApplicationCertificateArray; -typedef std::shared_ptr - ApplicationCertificateArrayPtr; - -class ApplicationCertificate { - public: - ApplicationCertificate(); - ~ApplicationCertificate(); - - const picojson::value& Value(); - bool IsValid() const; - - std::string get_cert_type() const; - void set_cert_type(const std::string& cert_type); - - std::string get_cert_value() const; - void set_cert_value(const std::string& cert_value); - - private: - std::string cert_type_; - std::string cert_value_; - - picojson::object data_; - picojson::object error_; - picojson::value value_; -}; - -} // namespace application -} // namespace extension - -#endif // SRC_APPLICATION_APPLICATION_CERTIFICATE_H_ diff --git a/src/application/application_context.cc b/src/application/application_context.cc deleted file mode 100644 index c8254401..00000000 --- a/src/application/application_context.cc +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright 2014 Samsung Electronics Co, Ltd. 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_context.h" - -#include - -#include "common/logger.h" -#include "tizen/tizen.h" - -namespace extension { -namespace application { - -ApplicationContext::ApplicationContext() { -} - -ApplicationContext::ApplicationContext(const std::string& context_id) - : context_id_(context_id) { -} - -ApplicationContext::~ApplicationContext() { -} - -const picojson::value& ApplicationContext::Value() { - if (value_.is() && IsValid()) { - picojson::object obj; - obj["id"] = picojson::value(context_id_); - obj["appId"] = picojson::value(app_id_); - value_ = picojson::value(obj); - } - return value_; -} - -bool ApplicationContext::IsValid() const { - return error_.empty(); -} - -std::string ApplicationContext::get_context_id() { - return context_id_; -} - -void ApplicationContext::set_context_id(const std::string& context_id) { - context_id_ = context_id; -} - -std::string ApplicationContext::get_app_id() { - return app_id_; -} - -void ApplicationContext::set_app_id(const std::string& app_id) { - app_id_ = app_id; -} - -} // namespace application -} // namespace extension diff --git a/src/application/application_context.h b/src/application/application_context.h deleted file mode 100644 index 6aeaf67c..00000000 --- a/src/application/application_context.h +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright 2014 Samsung Electronics Co, Ltd. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef SRC_APPLICATION_APPLICATION_CONTEXT_H_ -#define SRC_APPLICATION_APPLICATION_CONTEXT_H_ - -#include -#include -#include - -#include "common/picojson.h" -#include "tizen/tizen.h" - -namespace extension { -namespace application { - -class ApplicationContext; -typedef std::shared_ptr ApplicationContextPtr; - -typedef std::vector ApplicationContextArray; -typedef std::shared_ptr ApplicationContextArrayPtr; - - -class ApplicationContext { - public: - ApplicationContext(); - explicit ApplicationContext(const std::string& context_id); - ~ApplicationContext(); - - const picojson::value& Value(); - bool IsValid() const; - - std::string get_context_id(); - void set_context_id(const std::string& context_id); - - std::string get_app_id(); - void set_app_id(const std::string& app_id); - - private: - std::string context_id_; - std::string app_id_; - - picojson::object data_; - picojson::object error_; - picojson::value value_; -}; - -} // namespace application -} // namespace extension - -#endif // SRC_APPLICATION_APPLICATION_CONTEXT_H_ diff --git a/src/application/application_control.cc b/src/application/application_control.cc deleted file mode 100644 index d57d3faf..00000000 --- a/src/application/application_control.cc +++ /dev/null @@ -1,91 +0,0 @@ -// Copyright 2014 Samsung Electronics Co, Ltd. 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_control.h" - -#include - -#include "common/logger.h" -#include "tizen/tizen.h" - -namespace extension { -namespace application { - -ApplicationControl::ApplicationControl() { -} - -ApplicationControl::~ApplicationControl() { -} - -const picojson::value& ApplicationControl::Value() { - if (value_.is() && IsValid()) { - data_["operation"] = picojson::value(operation_); - data_["uri"] = picojson::value(uri_); - data_["mime"] = picojson::value(mime_); - data_["category"] = picojson::value(category_); - - picojson::value datas = picojson::value(picojson::array()); - picojson::array& datas_array = datas.get(); - for (auto it = data_array_.begin(); it != data_array_.end(); it++) { - datas_array.push_back((*it)->Value()); - } - data_["data"] = datas; - - value_ = picojson::value(data_); - } - return value_; -} - -bool ApplicationControl::IsValid() const { - return error_.empty(); -} - -std::string ApplicationControl::get_operation() const { - return operation_; -} - -void ApplicationControl::set_operation(const std::string& operation) { - operation_ = operation; -} - -std::string ApplicationControl::get_uri() const { - return uri_; -} - -void ApplicationControl::set_uri(const std::string& uri) { - uri_ = uri; -} - -std::string ApplicationControl::get_mime() const { - return mime_; -} - -void ApplicationControl::set_mime(const std::string& mime) { - mime_ = mime; -} - -std::string ApplicationControl::get_category() const { - return category_; -} - -void ApplicationControl::set_category(const std::string& category) { - category_ = category; -} - -ApplicationControlDataArray ApplicationControl::get_data_array() const { - return data_array_; -} - -void ApplicationControl::set_data_array - (const ApplicationControlDataArray& data_array) { - data_array_ = data_array; -} - -void ApplicationControl::add_data_array - (const ApplicationControlDataPtr& data_ptr) { - data_array_.push_back(data_ptr); -} - -} // namespace application -} // namespace extension diff --git a/src/application/application_control.h b/src/application/application_control.h deleted file mode 100644 index 9d96be28..00000000 --- a/src/application/application_control.h +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright 2014 Samsung Electronics Co, Ltd. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef SRC_APPLICATION_APPLICATION_CONTROL_H_ -#define SRC_APPLICATION_APPLICATION_CONTROL_H_ - -#include -#include - -#include "common/picojson.h" -#include "tizen/tizen.h" - -#include "application/application_controldata.h" - -namespace extension { -namespace application { - -class ApplicationControl; -typedef std::shared_ptr ApplicationControlPtr; - -class ApplicationControl { - public: - ApplicationControl(); - ~ApplicationControl(); - - const picojson::value& Value(); - bool IsValid() const; - - std::string get_operation() const; - void set_operation(const std::string& operation); - std::string get_uri() const; - void set_uri(const std::string& uri); - std::string get_mime() const; - void set_mime(const std::string& mime); - std::string get_category() const; - void set_category(const std::string& category); - ApplicationControlDataArray get_data_array() const; - void set_data_array(const ApplicationControlDataArray& data_array); - void add_data_array(const ApplicationControlDataPtr& data_ptr); - - private: - std::string operation_; - std::string uri_; - std::string mime_; - std::string category_; - ApplicationControlDataArray data_array_; - - picojson::object data_; - picojson::object error_; - picojson::value value_; -}; - -} // namespace application -} // namespace extension - -#endif // SRC_APPLICATION_APPLICATION_CONTROL_H_ diff --git a/src/application/application_controldata.cc b/src/application/application_controldata.cc deleted file mode 100644 index 558a4145..00000000 --- a/src/application/application_controldata.cc +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright 2014 Samsung Electronics Co, Ltd. 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_controldata.h" - -#include - -#include "common/logger.h" -#include "tizen/tizen.h" - -namespace extension { -namespace application { - -ApplicationControlData::ApplicationControlData() { -} - -ApplicationControlData::~ApplicationControlData() { -} - -const picojson::value& ApplicationControlData::Value() { - if (value_.is() && IsValid()) { - data_["key"] = picojson::value(ctr_key_); - picojson::value values = picojson::value(picojson::array()); - picojson::array& values_array = values.get(); - for (auto it = ctr_value_.begin(); it != ctr_value_.end(); it++) { - values_array.push_back(picojson::value(*it)); - } - data_["value"] = values; - - value_ = picojson::value(data_); - } - return value_; -} - -bool ApplicationControlData::IsValid() const { - return error_.empty(); -} - -std::string ApplicationControlData::get_ctr_key() const { - return ctr_key_; -} - -void ApplicationControlData::set_ctr_key(const std::string& ctr_key) { - ctr_key_ = ctr_key; -} - -std::vector ApplicationControlData::get_ctr_value() const { - return ctr_value_; -} - -void ApplicationControlData::set_ctr_value - (const std::vector &ctr_values) { - ctr_value_ = ctr_values; -} - -void ApplicationControlData::add_ctr_value(const std::string& ctr_value) { - ctr_value_.push_back(ctr_value); -} - - - -} // namespace application -} // namespace extension diff --git a/src/application/application_controldata.h b/src/application/application_controldata.h deleted file mode 100644 index a9371dd9..00000000 --- a/src/application/application_controldata.h +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright 2014 Samsung Electronics Co, Ltd. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef SRC_APPLICATION_APPLICATION_CONTROLDATA_H_ -#define SRC_APPLICATION_APPLICATION_CONTROLDATA_H_ - -#include -#include -#include - -#include "common/picojson.h" -#include "tizen/tizen.h" - -namespace extension { -namespace application { - -class ApplicationControlData; -typedef std::shared_ptr ApplicationControlDataPtr; - -typedef std::vector ApplicationControlDataArray; -typedef std::shared_ptr - ApplicationControlDataArrayPtr; - -class ApplicationControlData { - public: - ApplicationControlData(); - ~ApplicationControlData(); - - const picojson::value& Value(); - bool IsValid() const; - - std::string get_ctr_key() const; - void set_ctr_key(const std::string& ctr_key); - - std::vector get_ctr_value() const; - void set_ctr_value(const std::vector& ctr_values); - void add_ctr_value(const std::string& ctr_value); - - private: - std::string ctr_key_; - std::vector ctr_value_; - - picojson::object data_; - picojson::object error_; - picojson::value value_; -}; - -} // namespace application -} // namespace extension - -#endif // SRC_APPLICATION_APPLICATION_CONTROLDATA_H_ diff --git a/src/application/application_extension.cc b/src/application/application_extension.cc index 1156ed33..89cbd020 100644 --- a/src/application/application_extension.cc +++ b/src/application/application_extension.cc @@ -10,6 +10,12 @@ #include "application/application_instance.h" #include "common/logger.h" +namespace { +const char* kApplication = "tizen.application"; +const char* kApplicationControl = "tizen.ApplicationControl"; +const char* kApplicationControlData = "tizen.ApplicationControlData"; +} + // This will be generated from application_api.js extern const char kSource_application_api[]; @@ -30,11 +36,14 @@ ApplicationExtension::ApplicationExtension() { LoggerD("app_id: %s", app_id_.c_str()); - SetExtensionName("tizen.application"); + SetExtensionName(kApplication); SetJavaScriptAPI(kSource_application_api); const char* entry_points[] = { - "tizen.ApplicationControlData", "tizen.ApplicationControl", NULL}; + kApplicationControl, + kApplicationControlData, + NULL + }; SetExtraJSEntryPoints(entry_points); } diff --git a/src/application/application_information.cc b/src/application/application_information.cc deleted file mode 100644 index 57d4d41d..00000000 --- a/src/application/application_information.cc +++ /dev/null @@ -1,131 +0,0 @@ -// Copyright 2014 Samsung Electronics Co, Ltd. 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 -#include - -#include "common/logger.h" -#include "tizen/tizen.h" - -namespace extension { -namespace application { - -ApplicationInformation::ApplicationInformation() { -} - -ApplicationInformation::~ApplicationInformation() { -} - -std::string ApplicationInformation::get_app_id() const { - return app_id_; -} - -void ApplicationInformation::set_app_id(const std::string &app_id) { - app_id_ = app_id; -} - -std::string ApplicationInformation::get_name() const { - return name_; -} - -void ApplicationInformation::set_name(const std::string &name) { - name_ = name; -} - -std::string ApplicationInformation::get_icon_path() const { - return icon_path_; -} - -void ApplicationInformation::set_icon_path(const std::string &icon_path) { - icon_path_ = icon_path; -} - -bool ApplicationInformation::get_show() const { - return show_; -} - -void ApplicationInformation::set_show(const bool show) { - show_ = show; -} - -std::string ApplicationInformation::get_package_id() const { - return package_id_; -} - -void ApplicationInformation::set_package_id(const std::string &package_id) { - package_id_ = package_id; -} - -std::string ApplicationInformation::get_version() const { - return version_; -} - -void ApplicationInformation::set_version(const std::string &version) { - version_ = version; -} - -double ApplicationInformation::get_install_date() const { - return install_date_; -} - -void ApplicationInformation::set_install_date(const time_t &install_date) { - install_date_ = static_cast(install_date); - - // pkgmgrinfo_pkginfo_get_installed_time() returns installed time - // by using int type. but, it can't have millisecond value fully - install_date_ = install_date_ * 1000; -} - -std::vector ApplicationInformation::get_categories() const { - return categories_; -} - -void ApplicationInformation::set_categories - (const std::vector &categories) { - categories_ = categories; -} - -void ApplicationInformation::add_categories(const std::string &category) { - categories_.push_back(category); -} - -void ApplicationInformation::set_size(const int &size) { - size_ = static_cast(size); -} - -double ApplicationInformation::get_size() const { - return size_; -} - -const picojson::value& ApplicationInformation::Value() { - if (value_.is() && IsValid()) { - data_["id"] = picojson::value(app_id_); - data_["name"] = picojson::value(name_); - data_["iconPath"] = picojson::value(icon_path_); - data_["show"] = picojson::value(show_); - data_["packageId"] = picojson::value(package_id_); - data_["version"] = picojson::value(version_); - data_["installDate"] = picojson::value(install_date_); - picojson::value categories = picojson::value(picojson::array()); - picojson::array& categories_array = categories.get(); - for (auto it = categories_.begin(); it != categories_.end(); it++) { - categories_array.push_back(picojson::value(*it)); - } - data_["categories"] = categories; - // LoggerD("size: %f", size_); - data_["size"] = picojson::value(size_); - - value_ = picojson::value(data_); - } - return value_; -} - -bool ApplicationInformation::IsValid() const { - return error_.empty(); -} - -} // namespace application -} // namespace extension diff --git a/src/application/application_information.h b/src/application/application_information.h deleted file mode 100644 index baa44d4d..00000000 --- a/src/application/application_information.h +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright 2014 Samsung Electronics Co, Ltd. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef SRC_APPLICATION_APPLICATION_INFORMATION_H_ -#define SRC_APPLICATION_APPLICATION_INFORMATION_H_ - -#include -#include -#include - -#include "common/picojson.h" - -namespace extension { -namespace application { - -class ApplicationInformation; -typedef std::shared_ptr ApplicationInformationPtr; - -typedef std::vector ApplicationInformationArray; -typedef std::shared_ptr - ApplicationInformationArrayPtr; - -class ApplicationInformation { - public: - ApplicationInformation(); - ~ApplicationInformation(); - - const picojson::value& Value(); - bool IsValid() const; - - std::string get_app_id() const; - void set_app_id(const std::string &app_id); - std::string get_name() const; - void set_name(const std::string &name); - std::string get_icon_path() const; - void set_icon_path(const std::string &icon_path); - bool get_show() const; - void set_show(const bool show); - void set_package_id(const std::string &package_id); - std::string get_package_id() const; - void set_version(const std::string &version); - std::string get_version() const; - void set_install_date(const time_t& install_date); - double get_install_date() const; - std::vector get_categories() const; - void set_categories(const std::vector &categories); - void add_categories(const std::string &category); - void set_size(const int& size); - double get_size() const; - - private: - std::string app_id_; - std::string name_; - std::string icon_path_; - bool show_; - std::string package_id_; - std::string version_; - double install_date_; - std::vector categories_; - double size_; - - picojson::object data_; - picojson::object error_; - picojson::value value_; -}; - -} // namespace application -} // namespace extension - -#endif // SRC_APPLICATION_APPLICATION_INFORMATION_H_ diff --git a/src/application/application_instance.cc b/src/application/application_instance.cc index f4744bb1..ec51c462 100644 --- a/src/application/application_instance.cc +++ b/src/application/application_instance.cc @@ -4,38 +4,11 @@ #include "application/application_instance.h" -// To get pid -#include -#include -#include - -// to launch app by aul -#include - -// to get package name by appid -#include -#include - -// To get app size and installed time -#include - -//#include - -#include -#include -#include -#include -#include - #include "common/logger.h" #include "common/picojson.h" #include "common/platform_exception.h" #include "common/task-queue.h" -#include "application/application.h" -#include "application/application_context.h" -#include "application/application_control.h" - namespace extension { namespace application { @@ -47,2236 +20,199 @@ const std::string kPrivilegeApplicationInfo = "http://tizen.org/privilege/applic const std::string kPrivilegeApplicationLaunch = "http://tizen.org/privilege/application.launch"; } // namespace -using common::PlatformException; -using common::UnknownException; -using common::TypeMismatchException; -using common::IOException; -using common::ServiceNotAvailableException; -using common::SecurityException; -using common::NetworkException; -using common::NotSupportedException; -using common::NotFoundException; -using common::InvalidAccessException; -using common::AbortException; -using common::QuotaExceededException; -using common::InvalidStateException; -using common::InvalidModificationException; -using common::InvalidValuesException; -using common::TaskQueue; - -static ApplicationInformationPtr get_app_info(pkgmgrinfo_appinfo_h handle); +using namespace common; -ApplicationInstance::ApplicationInstance(const std::string& app_id) { - manager_handle_ = NULL; - watch_id_ = 0; - app_id_ = app_id; +ApplicationInstance::ApplicationInstance(const std::string& app_id) : + manager_(*this), + app_id_(app_id) { + LoggerD("Entered"); using std::placeholders::_1; using std::placeholders::_2; - #define REGISTER_SYNC(c, x) \ - RegisterSyncHandler(c, std::bind(&ApplicationInstance::x, this, _1, _2)); - REGISTER_SYNC("ApplicationManager_getAppCerts", - AppMgrGetAppCerts); - REGISTER_SYNC("Application_getRequestedAppControl", - AppGetRequestedAppControl); - REGISTER_SYNC("ApplicationManager_addAppInfoEventListener", - AppMgrAddAppInfoEventListener); - REGISTER_SYNC("ApplicationManager_getAppMetaData", - AppMgrGetAppMetaData); - REGISTER_SYNC("ApplicationManager_launchAppControl", - AppMgrLaunchAppControl); - REGISTER_SYNC("ApplicationManager_removeAppInfoEventListener", - AppMgrRemoveAppInfoEventListener); - REGISTER_SYNC("ApplicationManager_getAppInfo", - AppMgrGetAppInfo); - REGISTER_SYNC("ApplicationManager_getAppSharedURI", - AppMgrGetAppSharedURI); - REGISTER_SYNC("RequestedApplicationControl_replyResult", - RequestedAppControlReplyResult); - REGISTER_SYNC("ApplicationManager_kill", - AppMgrKill); - REGISTER_SYNC("ApplicationManager_getAppsInfo", - AppMgrGetAppsInfo); - REGISTER_SYNC("ApplicationManager_launch", - AppMgrLaunch); - REGISTER_SYNC("ApplicationManager_getAppsContext", - AppMgrGetAppsContext); - REGISTER_SYNC("ApplicationManager_getAppContext", - AppMgrGetAppContext); - REGISTER_SYNC("RequestedApplicationControl_replyFailure", - RequestedAppControlReplyFailure); - REGISTER_SYNC("ApplicationManager_getCurrentApplication", - AppMgrGetCurrentApplication); - REGISTER_SYNC("ApplicationManager_findAppControl", - AppMgrFindAppControl); - #undef REGISTER_SYNC -} - -ApplicationInstance::~ApplicationInstance() { -} - - -enum ApplicationErrors { - APP_ERROR_OK = 0, - APP_ERROR_UNKNOWN = 1, - APP_ERROR_TYPE_MISMATCH = 2, - APP_ERROR_IO = 3, - APP_ERROR_SVC_NOT_AVAILABLE = 4, - APP_ERROR_SECURITY = 5, - APP_ERROR_NETWORK = 6, - APP_ERROR_NOT_SUPPORTED = 7, - APP_ERROR_NOT_FOUND = 8, - APP_ERROR_INVALID_ACCESS = 9, - APP_ERROR_ABORT = 10, - APP_ERROR_QUOTA_EXCEEDED = 11, - APP_ERROR_INVALID_STATE = 12, - APP_ERROR_INVALID_MODIFICATION = 13, - APP_ERROR_INVALID_VALUES = 14, -}; - -struct CallbackInfo { - ApplicationInstance* instance; - bool is_success; - int error_type; - char error_msg[256]; - char id[256]; - int callback_id; - picojson::object data; -}; - -static picojson::value GetAppError(int type, const char* msg) { - switch (type) { - case APP_ERROR_UNKNOWN: - return UnknownException(msg).ToJSON(); - case APP_ERROR_TYPE_MISMATCH: - return TypeMismatchException(msg).ToJSON(); - case APP_ERROR_IO: - return IOException(msg).ToJSON(); - case APP_ERROR_SVC_NOT_AVAILABLE: - return ServiceNotAvailableException(msg).ToJSON(); - case APP_ERROR_SECURITY: - return SecurityException(msg).ToJSON(); - case APP_ERROR_NETWORK: - return NetworkException(msg).ToJSON(); - case APP_ERROR_NOT_SUPPORTED: - return NotSupportedException(msg).ToJSON(); - case APP_ERROR_NOT_FOUND: - return NotFoundException(msg).ToJSON(); - case APP_ERROR_INVALID_ACCESS: - return InvalidAccessException(msg).ToJSON(); - case APP_ERROR_ABORT: - return AbortException(msg).ToJSON(); - case APP_ERROR_QUOTA_EXCEEDED: - return QuotaExceededException(msg).ToJSON(); - case APP_ERROR_INVALID_STATE: - return InvalidStateException(msg).ToJSON(); - case APP_ERROR_INVALID_MODIFICATION: - return InvalidModificationException(msg).ToJSON(); - case APP_ERROR_INVALID_VALUES: - return InvalidValuesException(msg).ToJSON(); - default: - return UnknownException(msg).ToJSON(); - } -} - -static void ReplyAsync(ApplicationInstance* instance, - int callback_id, bool isSuccess, picojson::object* param, - int err_id, const char* err_msg) { - (*param)["callbackId"] = picojson::value(static_cast(callback_id)); - if (isSuccess) { - (*param)["status"] = picojson::value("success"); - } else { - (*param).insert(std::make_pair("status", picojson::value("error"))); - (*param).insert(std::make_pair("error", GetAppError(err_id, err_msg))); - } - - picojson::value result = picojson::value(*param); - char print_buf[300] = {0}; - snprintf(print_buf, sizeof(print_buf), result.serialize().c_str()); - LoggerD("async result: %s", print_buf); - instance->PostMessage(result.serialize().c_str()); -} - -// Callback of 'app_manager_foreach_app_context' -// Used by 'getAppsContext' -static bool app_manager_app_context_callback(app_context_h app_context, - void *user_data) { - int ret = 0; - - char *app_id = NULL; - int pid; - - std::string context_id; - - if (user_data == NULL) { - LoggerD("user_data is NULL"); - return false; - } - - ret = app_context_get_app_id(app_context, &app_id); - if ((ret != APP_MANAGER_ERROR_NONE) || (app_id == NULL)) { - LoggerE("Fail to get app id from context"); - return false; - } - LoggerD("app_context_get_app_id: %s", app_id); - ret = app_context_get_pid(app_context, &pid); - if (ret != APP_MANAGER_ERROR_NONE) { - LoggerE("Fail to get pid from context"); - if (app_id) - free(app_id); - return false; - } - LoggerD("app_context_get_pid: %d", pid); - - std::stringstream sstream; - sstream << pid; - context_id = sstream.str(); - - ApplicationContextPtr app_context_ptr(new ApplicationContext()); - app_context_ptr->set_app_id(app_id); - app_context_ptr->set_context_id(context_id); - - ApplicationContextArray* app_context_array_ptr = - reinterpret_cast(user_data); - app_context_array_ptr->push_back(app_context_ptr); - if (app_id) - free(app_id); - - return true; +#define REGISTER_SYNC(c, x) \ + RegisterSyncHandler(c, std::bind(&ApplicationInstance::x, this, _1, _2)); + //ApplicationManager + REGISTER_SYNC("ApplicationManager_getCurrentApplication", GetCurrentApplication); + REGISTER_SYNC("ApplicationManager_getAppContext", GetAppContext); + REGISTER_SYNC("ApplicationManager_getAppInfo", GetAppInfo); + REGISTER_SYNC("ApplicationManager_getAppCerts", GetAppCerts); + REGISTER_SYNC("ApplicationManager_getAppSharedURI", GetAppSharedURI); + REGISTER_SYNC("ApplicationManager_getAppMetaData", GetAppMetaData); + REGISTER_SYNC("ApplicationManager_addAppInfoEventListener", AddAppInfoEventListener); + REGISTER_SYNC("ApplicationManager_removeAppInfoEventListener", RemoveAppInfoEventListener); + + //Application + REGISTER_SYNC("Application_getRequestedAppControl", GetRequestedAppControl); + + //RequestedApplicationControl + REGISTER_SYNC("RequestedApplicationControl_replyResult", ReplyResult); + REGISTER_SYNC("RequestedApplicationControl_replyFailure", ReplyFailure); + + //ApplicationInformation + REGISTER_SYNC("ApplicationInformation_getSize", GetSize); +#undef REGISTER_SYNC + +#define REGISTER_ASYNC(c, x) \ + RegisterSyncHandler(c, std::bind(&ApplicationInstance::x, this, _1, _2)); + //ApplicationManager + REGISTER_ASYNC("ApplicationManager_kill", Kill); + REGISTER_ASYNC("ApplicationManager_launch", Launch); + REGISTER_ASYNC("ApplicationManager_launchAppControl", LaunchAppControl); + REGISTER_ASYNC("ApplicationManager_findAppControl", FindAppControl); + REGISTER_ASYNC("ApplicationManager_getAppsContext", GetAppsContext); + REGISTER_ASYNC("ApplicationManager_getAppsInfo", GetAppsInfo); +#undef REGISTER_ASYNC } -static int get_app_installed_size(const char* app_id) { - char* package_id = NULL; - int size = 0; - int ret = 0; - - ret = package_manager_get_package_id_by_app_id(app_id, &package_id); - if ((ret != PACKAGE_MANAGER_ERROR_NONE) || (package_id == NULL)) { - LoggerE("Failed to get package id(%s)", package_id); - } else { - // get installed size from package server (to solve smack issue) - pkgmgr_client *pc = pkgmgr_client_new(PC_REQUEST); - if (pc == NULL) { - LoggerE("Failed to create pkgmgr client"); - } else { - size = pkgmgr_client_request_service(PM_REQUEST_GET_SIZE, - PM_GET_TOTAL_SIZE, pc, NULL, package_id, NULL, NULL, NULL); - if (size < 0) { - LoggerE("Failed to get installed size"); - } - pkgmgr_client_free(pc); - pc = NULL; - } - - if (package_id) { - free(package_id); - } - } - - // LoggerD("Get app size: %s[%d]", app_id, size); - return size; -} - -// Callback from 'app_control_foreach_app_matched' -// Used by 'findAppControl' -static bool app_control_app_matched_callback(app_control_h service, - const char *appid, void *user_data) { - if (appid == NULL) { - LoggerD("appid is NULL"); - return false; - } - - pkgmgrinfo_appinfo_h handle; - int ret = pkgmgrinfo_appinfo_get_appinfo(appid, &handle); - if (ret != PMINFO_R_OK) { - LoggerD("Fail to get appInfo from appId : %s", appid); - } else { - LoggerD("Getting app info: %s", appid); - ApplicationInformationPtr app_info_ptr = get_app_info(handle); - pkgmgrinfo_appinfo_destroy_appinfo(handle); - - ApplicationInformationArray* app_info_array = - reinterpret_cast(user_data); - - app_info_array->push_back(app_info_ptr); - } - - return true; +ApplicationInstance::~ApplicationInstance() { + LoggerD("Entered"); } -static bool app_control_extra_data_callback(app_control_h service, - const char* key, void* user_data) { - int ret = 0; - LoggerD("Handing extra data"); - - ApplicationControlDataArray* app_ctr_data_array = - reinterpret_cast(user_data); - - bool is_array = false; - ret = app_control_is_extra_data_array(service, key, &is_array); - if (ret != APP_CONTROL_ERROR_NONE) { - LoggerE("service_is_extra_data_array passes error"); - // fail to checking. go to next extra data. - return true; - } - - std::string key_str(key); - - if (is_array) { - LoggerD("extra data is array"); - int length = 0; - char **value = NULL; - - ret = app_control_get_extra_data_array(service, key, &value, &length); - switch (ret) { - case APP_CONTROL_ERROR_NONE: { - std::vector val_array; - LoggerD("key: %s, value length : %d", key, length); - for (int i = 0; i < length; i++) { - if (value[i]) { - LoggerD("[%d] value: %s", i, value[i]); - val_array.push_back(value[i]); - } - } - - ApplicationControlDataPtr app_control_data( - new ApplicationControlData()); - app_control_data->set_ctr_key(key_str); - app_control_data->set_ctr_value(val_array); - app_ctr_data_array->push_back(app_control_data); - - for (int i = 0; i < length; i++) { - if (value[i]) - free(value[i]); - } - if (value) - free(value); - break; - } - case APP_CONTROL_ERROR_INVALID_PARAMETER: - LoggerE("get_extra_data retuns ERROR_INVALID_PARAMETER"); - break; - case APP_CONTROL_ERROR_KEY_NOT_FOUND: - LoggerE("get_extra_data retuns ERROR_KEY_NOT_FOUND"); - break; - case APP_CONTROL_ERROR_OUT_OF_MEMORY: - LoggerE("get_extra_data retuns ERROR_OUT_OF_MEMORY"); - break; - default: - LoggerE("get_extra_data retuns Unknown Error"); - break; - } - } else { // (!is_array) - LoggerD("extra data is not array"); - char *value = NULL; - - ret = app_control_get_extra_data(service, key, &value); - switch (ret) { - case APP_CONTROL_ERROR_NONE: { - if (value == NULL) { - LoggerE("app_control_get_extra_data returns NULL"); - break; - } - - std::vector val_array; - val_array.push_back(value); - - ApplicationControlDataPtr app_control_data(new ApplicationControlData()); - LoggerD("key: %s, value: %s", key, value); - app_control_data->set_ctr_key(key_str); - app_control_data->set_ctr_value(val_array); - app_ctr_data_array->push_back(app_control_data); - - if (value) - free(value); +void ApplicationInstance::GetCurrentApplication(const picojson::value& args, picojson::object& out) { + LoggerD("Entered"); - break; - } - case APP_CONTROL_ERROR_INVALID_PARAMETER: - LoggerE("get_extra_data retuns ERROR_INVALID_PARAMETER"); - break; - case APP_CONTROL_ERROR_KEY_NOT_FOUND: - LoggerE("get_extra_data retuns ERROR_KEY_NOT_FOUND"); - break; - case APP_CONTROL_ERROR_OUT_OF_MEMORY: - LoggerE("get_extra_data retuns ERROR_OUT_OF_MEMORY"); - break; - default: - LoggerE("get_extra_data retuns Known Error"); - break; - } - } - return true; + manager_.GetCurrentApplication(app_id_, &out); } -// Callback of 'app_control_send_launch_request' -// Used by 'launchAppControl' -static void app_control_reply_callback(app_control_h request, - app_control_h reply, app_control_result_e result, void *user_data) { - CallbackInfo* info = reinterpret_cast(user_data); - - if (result == APP_CONTROL_RESULT_SUCCEEDED) { - LoggerD("APP_CONTROL_RESULT_SUCCEEDED"); - - // create new service object to store result. - ApplicationControlDataArrayPtr app_ctr_data_array_ptr( - new ApplicationControlDataArray()); - - int result = app_control_foreach_extra_data(reply, - app_control_extra_data_callback, app_ctr_data_array_ptr.get()); - if (result == APP_CONTROL_ERROR_NONE) { - LoggerD("Getting extra data is succeeded."); - } else { - LoggerD("Getting extra data is failed."); - } - - picojson::value replied_data = picojson::value(picojson::array()); - picojson::array& replied_data_array = replied_data.get(); - - for (int i = 0; i < app_ctr_data_array_ptr->size(); i++) { - ApplicationControlDataPtr ctr_data_ptr = app_ctr_data_array_ptr->at(i); - - replied_data_array.push_back(ctr_data_ptr->Value()); - } - - // ReplyAsync - picojson::object data; - data.insert(std::make_pair("type", picojson::value("onsuccess"))); - data.insert(std::make_pair("data", replied_data)); - ReplyAsync(info->instance, info->callback_id, true, &data, 0, NULL); - - } else if (result == APP_CONTROL_RESULT_FAILED || - result == APP_CONTROL_RESULT_CANCELED) { - LoggerD("APP_CONTROL_RESULT_FAILED or CANCELED"); - - // ReplyAsync - picojson::object data; - data.insert(std::make_pair("type", picojson::value("onfailure"))); - ReplyAsync(info->instance, info->callback_id, false, &data, - APP_ERROR_ABORT, "Failed or Canceled"); - } +void ApplicationInstance::GetAppContext(const picojson::value& args, picojson::object& out) { + LoggerD("Entered"); - if (info) - free(info); + manager_.GetAppContext(args, &out); } -// get package name by id -static char* getPackageByAppId(const char* app_id) { - app_info_h handle; - char* pkgName; - int ret = 0; - - // TODO(sunggyu.choi): gPkgIdMapInited - - ret = app_manager_get_app_info(app_id, &handle); - if (ret < 0) { - LoggerE("Fail to get appinfo"); - return NULL; - } +void ApplicationInstance::GetAppInfo(const picojson::value& args, picojson::object& out) { + LoggerD("Entered"); - ret = app_info_get_package(handle, &pkgName); - if (ret < 0) { - LoggerE("Fail to get pkgName"); - pkgName = NULL; + std::string app_id = app_id_; + const auto& id = args.get("id"); + if (id.is()) { + app_id = id.get(); } - ret = app_info_destroy(handle); - if (ret < 0) { - LoggerE("Fail to get destory appinfo"); - return NULL; - } - return pkgName; + manager_.GetAppInfo(app_id, &out); } -static int category_cb(const char *category, void *user_data) { - LoggerD("category: %s", category); - if (category == NULL) - return true; - - ApplicationInformation* appInfo = - reinterpret_cast(user_data); - appInfo->add_categories(category); - return true; -} +void ApplicationInstance::GetAppCerts(const picojson::value& args, picojson::object& out) { + LoggerD("Entered"); -static bool package_certificate_cb(package_info_h handle, - package_cert_type_e cert_type, const char *cert_value, void *user_data) { - ApplicationCertificatePtr cert(new ApplicationCertificate()); - std::string cert_type_name; + CHECK_PRIVILEGE_ACCESS(kPrivilegeAppManagerCertificate, &out); - switch (cert_type) { - case PACKAGE_INFO_AUTHOR_ROOT_CERT: - cert_type_name = "AUTHOR_ROOT"; - break; - case PACKAGE_INFO_AUTHOR_INTERMEDIATE_CERT: - cert_type_name = "AUTHOR_INTERMEDIATE"; - break; - case PACKAGE_INFO_AUTHOR_SIGNER_CERT: - cert_type_name = "AUTHOR_SIGNER"; - break; - case PACKAGE_INFO_DISTRIBUTOR_ROOT_CERT: - cert_type_name = "DISTRIBUTOR_ROOT"; - break; - case PACKAGE_INFO_DISTRIBUTOR_INTERMEDIATE_CERT: - cert_type_name = "DISTRIBUTOR_INTERMEDIATE"; - break; - case PACKAGE_INFO_DISTRIBUTOR_SIGNER_CERT: - cert_type_name = "DISTRIBUTOR_SIGNER"; - break; - case PACKAGE_INFO_DISTRIBUTOR2_ROOT_CERT: - cert_type_name = "DISTRIBUTOR2_ROOT"; - break; - case PACKAGE_INFO_DISTRIBUTOR2_INTERMEDIATE_CERT: - cert_type_name = "DISTRIBUTOR2_INTERMEDIATE"; - break; - case PACKAGE_INFO_DISTRIBUTOR2_SIGNER_CERT: - cert_type_name = "DISTRIBUTOR2_SIGNER"; - break; - default: - LoggerE("Unknow Cert type!!!"); - cert_type_name = "UNKNOWN"; - break; + std::string app_id = app_id_; + const auto& id = args.get("id"); + if (id.is()) { + app_id = id.get(); } - cert->set_cert_type(cert_type_name); - std::string cert_type_value = cert_value; - cert->set_cert_value(cert_type_value); - - ApplicationCertificateArray *certs = - reinterpret_cast(user_data); - - certs->push_back(cert); - return true; + manager_.GetAppCerts(app_id, &out); } -static ApplicationInformationPtr get_app_info(pkgmgrinfo_appinfo_h handle) { - char* app_id = NULL; - char* name = NULL; - char* icon_path = NULL; - bool no_display = false; - char* pkg_id = NULL; - int ret = 0; - - ApplicationInformationPtr app_info(new ApplicationInformation()); - ret = pkgmgrinfo_appinfo_get_appid(handle, &app_id); - if (ret != PMINFO_R_OK) { - LoggerD("Fail to get appid"); - } else { - app_info->set_app_id(app_id); - } - - ret = pkgmgrinfo_appinfo_get_label(handle, &name); - if ((ret != PMINFO_R_OK) || (name == NULL)) { - LoggerD("Fail to get label"); - } else { - app_info->set_name(name); - } - - ret = pkgmgrinfo_appinfo_get_icon(handle, &icon_path); - if ((ret != PMINFO_R_OK) || (icon_path == NULL)) { - LoggerD("Fail to get icon"); - } else { - app_info->set_icon_path(icon_path); - } - - ret = pkgmgrinfo_appinfo_foreach_category(handle, category_cb, - reinterpret_cast(app_info.get())); - if (ret != PMINFO_R_OK) { - LoggerD("Fail to get categories"); - } - - ret = pkgmgrinfo_appinfo_is_nodisplay(handle, &no_display); - if (ret != PMINFO_R_OK) { - LoggerD("Fail to get nodisplay"); - } else { - app_info->set_show(!no_display); - } - - ret = pkgmgrinfo_appinfo_get_pkgid(handle, &pkg_id); - if ((ret != PMINFO_R_OK) || (pkg_id == NULL)) { - LoggerD("Fail to get pkgId"); - return app_info; - } else { - app_info->set_package_id(pkg_id); - } - - char* version = NULL; - int installed_time = 0; - pkgmgrinfo_pkginfo_h pkginfo_h; - - ret = pkgmgrinfo_pkginfo_get_pkginfo(pkg_id, &pkginfo_h); - if (ret != PMINFO_R_OK) { - LoggerE("Fail to get pkginfo"); - } else { - ret = pkgmgrinfo_pkginfo_get_version(pkginfo_h, &version); - if (ret != PMINFO_R_OK) { - LoggerE("Fail to get version"); - } else { - app_info->set_version(version); - } - - ret = pkgmgrinfo_pkginfo_get_installed_time(pkginfo_h, &installed_time); - if (ret != PMINFO_R_OK) { - LoggerE("Fail to get installed time"); - } else { - app_info->set_install_date(installed_time); - // LoggerD("installed_time: %d", installed_time); - } +void ApplicationInstance::GetAppSharedURI(const picojson::value& args, picojson::object& out) { + LoggerD("Entered"); - pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo_h); + std::string app_id = app_id_; + const auto& id = args.get("id"); + if (id.is()) { + app_id = id.get(); } - // size - app_info->set_size(get_app_installed_size(app_id)); - return app_info; + manager_.GetAppSharedUri(app_id, &out); } -static int app_meta_data_cb(const char *meta_key, const char *meta_value, - void *user_data) { - if ((meta_key == NULL) || (meta_value == NULL)) { - LoggerE("meta_key or meta_value is null"); - return 0; - } - - LoggerD("key = %s, value = %s", meta_key, meta_value); - ApplicationMetaDataPtr meta_data(new ApplicationMetaData()); - - std::string key = meta_key; - meta_data->set_meta_key(key); - std::string value = meta_value; - meta_data->set_meta_value(value); - - ApplicationMetaDataArray* meta_data_array = - reinterpret_cast(user_data); - meta_data_array->push_back(meta_data); - - return 0; -} - -static int installed_app_info_cb(pkgmgrinfo_appinfo_h handle, - void *user_data) { - // LoggerD("ENTER"); - ApplicationInformationPtr app_info = get_app_info(handle); - ApplicationInformationArray* app_info_array = - reinterpret_cast(user_data); - app_info_array->push_back(app_info); - return 0; -} +void ApplicationInstance::GetAppMetaData(const picojson::value& args, picojson::object& out) { + LoggerD("Entered"); -// Callback from 'app_manager_set_app_context_event_cb' -// Used by 'kill' -static void app_manager_app_context_event_callback(app_context_h app_context, - app_context_event_e event, void *user_data) { - CallbackInfo* info = - reinterpret_cast(user_data); - int ret = 0; + CHECK_PRIVILEGE_ACCESS(kPrivilegeApplicationInfo, &out); - LoggerD("context_id: %s, callback_id: %d", info->id, info->callback_id); - if (event != APP_CONTEXT_EVENT_TERMINATED) { - picojson::object data; - info->error_type = APP_ERROR_UNKNOWN; - snprintf(info->error_msg, sizeof(info->error_msg), "Not terminated."); - ReplyAsync(info->instance, info->callback_id, - false, &data, info->error_type, info->error_msg); - } else { - picojson::object data; - ReplyAsync(info->instance, info->callback_id, - true, &data, 0, NULL); + std::string app_id = app_id_; + const auto& id = args.get("id"); + if (id.is()) { + app_id = id.get(); } - if (info) - free(info); + manager_.GetAppMetaData(app_id, &out); } -static gboolean getappsinfo_callback_thread_completed( - const std::shared_ptr& user_data) { +void ApplicationInstance::AddAppInfoEventListener(const picojson::value& args, picojson::object& out) { LoggerD("Entered"); - if (user_data->is_success) { - ReplyAsync(user_data->instance, user_data->callback_id, - true, &(user_data->data), 0, NULL); - } else { - picojson::object data; - ReplyAsync(user_data->instance, user_data->callback_id, - false, &data, user_data->error_type, user_data->error_msg); - } - return true; -} - -static void* getappsinfo_callback_thread( - const std::shared_ptr& user_data) { - LoggerD("Entered."); - ApplicationInformationArrayPtr app_info_array_ptr( - new ApplicationInformationArray()); - - int ret = pkgmgrinfo_appinfo_get_installed_list(installed_app_info_cb, - app_info_array_ptr.get()); - if (ret == PMINFO_R_OK) { - LoggerE("pkgmgrinfo_appinfo_get_installed_list: ERROR_NONE"); - user_data->is_success = true; - - picojson::value apps_infos = picojson::value(picojson::array()); - picojson::array& apps_infos_array = apps_infos.get(); - - for (int i = 0; i < app_info_array_ptr->size(); i++) { - ApplicationInformationPtr app_info_ptr = app_info_array_ptr->at(i); - - apps_infos_array.push_back(app_info_ptr->Value()); - } - user_data->data.insert(std::make_pair("informationArray", apps_infos)); - } else { - LoggerE("pkgmgrinfo_appinfo_get_installed_list: ERROR"); - - user_data->error_type = APP_ERROR_UNKNOWN; - snprintf(user_data->error_msg, sizeof(user_data->error_msg), "Unknown"); + manager_.StartAppInfoEventListener(&out); + } - user_data->is_success = false; - } -} - -static gboolean getappsctx_callback_thread_completed( - const std::shared_ptr& user_data) { +void ApplicationInstance::RemoveAppInfoEventListener(const picojson::value& args, picojson::object& out) { LoggerD("Entered"); - if (user_data->is_success) { - ReplyAsync(user_data->instance, user_data->callback_id, - true, &(user_data->data), 0, NULL); - } else { - picojson::object data; - ReplyAsync(user_data->instance, user_data->callback_id, - false, &data, user_data->error_type, user_data->error_msg); - } - return true; -} - -static void* getappsctx_callback_thread( - const std::shared_ptr& user_data) { - LoggerD("Entered."); - ApplicationContextArrayPtr app_context_array_ptr( - new ApplicationContextArray()); - - int ret = app_manager_foreach_app_context(app_manager_app_context_callback, - app_context_array_ptr.get()); - if (ret == APP_MANAGER_ERROR_NONE) { - LoggerE("app_manager_foreach_app_context error: ERROR_NONE"); - user_data->is_success = true; - - picojson::value apps_contexts = picojson::value(picojson::array()); - picojson::array& apps_contexts_array = - apps_contexts.get(); - - for (int i = 0; i < app_context_array_ptr->size(); i++) { - ApplicationContextPtr app_ctx_ptr = app_context_array_ptr->at(i); - - apps_contexts_array.push_back(app_ctx_ptr->Value()); - } - user_data->data.insert(std::make_pair("contexts", apps_contexts)); - - } else { - LoggerE("app_manager_foreach_app_context error: ERROR"); - - if (ret == APP_MANAGER_ERROR_INVALID_PARAMETER) { - user_data->error_type = APP_ERROR_TYPE_MISMATCH; - snprintf(user_data->error_msg, sizeof(user_data->error_msg), - "Invalid parameter"); - } else if (ret == APP_MANAGER_ERROR_PERMISSION_DENIED) { - user_data->error_type = APP_ERROR_ABORT; - snprintf(user_data->error_msg, sizeof(user_data->error_msg), - "Permission denied"); - } else { - user_data->error_type = APP_ERROR_UNKNOWN; - snprintf(user_data->error_msg, sizeof(user_data->error_msg), - "Unknown"); - } - - user_data->is_success = false; - } + manager_.StopAppInfoEventListener(); + ReportSuccess(out); } -static gboolean callback_thread_completed - (const std::shared_ptr& user_data) { +void ApplicationInstance::GetRequestedAppControl(const picojson::value& args, picojson::object& out) { LoggerD("Entered"); - picojson::object data; - if (user_data->is_success) { - ReplyAsync(user_data->instance, user_data->callback_id, - true, &data, 0, NULL); - } else { - ReplyAsync(user_data->instance, user_data->callback_id, - false, &data, user_data->error_type, user_data->error_msg); - } - return true; + current_application_.GetRequestedAppControl(args, &out); } -static gboolean find_callback_thread_completed - (const std::shared_ptr& user_data) { +void ApplicationInstance::ReplyResult(const picojson::value& args, picojson::object& out) { LoggerD("Entered"); - picojson::object data; - - if (user_data->is_success) { - ReplyAsync(user_data->instance, user_data->callback_id, - true, &(user_data->data), 0, NULL); - } else { - ReplyAsync(user_data->instance, user_data->callback_id, - false, &data, user_data->error_type, user_data->error_msg); - } - return true; -} -static void* callback_thread - (const std::shared_ptr& user_data) { - LoggerD("Entered. currently, nothing to do"); + current_application_.app_control().ReplyResult(args, &out); } -static gboolean launch_completed - (const std::shared_ptr& user_data) { +void ApplicationInstance::ReplyFailure(const picojson::value& args, picojson::object& out) { LoggerD("Entered"); - picojson::object data; - if (user_data->is_success) { - ReplyAsync(user_data->instance, user_data->callback_id, - true, &data, 0, NULL); - } else { - ReplyAsync(user_data->instance, user_data->callback_id, - false, &data, user_data->error_type, user_data->error_msg); - } - return true; + current_application_.app_control().ReplyFailure(&out); } -static gboolean self_kill_completed - (const std::shared_ptr& user_data) { +void ApplicationInstance::GetSize(const picojson::value& args, picojson::object& out) { LoggerD("Entered"); - picojson::object data; - - // call error callback with InvalidValuesException - ReplyAsync(user_data->instance, user_data->callback_id, - false, &data, user_data->error_type, user_data->error_msg); - return true; -} - -static void* launch_thread(const std::shared_ptr& user_data) { - int ret; - LoggerD("app_id: %s, callback_id: %d", user_data->id, - user_data->callback_id); + CHECK_PRIVILEGE_ACCESS(kPrivilegeApplicationInfo, &out); - ret = aul_open_app(user_data->id); - if (ret < 0) { - std::string msg; - int type = APP_ERROR_OK; - switch (ret) { - case AUL_R_EINVAL: - case AUL_R_ERROR: - LoggerE("Not Found error"); - msg = "Not Found error"; - type = APP_ERROR_NOT_FOUND; - break; - case AUL_R_ECOMM: - LoggerE("Internal IPC error"); - msg = "Internal IPC error"; - type = APP_ERROR_IO; - break; - default: - LoggerE("Unknown error"); - msg = "Unknown error"; - type = APP_ERROR_UNKNOWN; - break; - } - user_data->is_success = false; - user_data->error_type = type; - snprintf(user_data->error_msg, sizeof(user_data->error_msg), msg.c_str()); - } else { - LoggerD("Success to launch."); - user_data->is_success = true; - } + manager_.GetApplicationInformationSize(args, &out); } -#define CHECK_EXIST(args, name, out) \ - if (!args.contains(name)) {\ - ReportError(TypeMismatchException(name" is required argument"), out);\ - return;\ - } - -void ApplicationInstance::AppMgrGetCurrentApplication( - const picojson::value& args, picojson::object& out) { - const std::string& app_id = app_id_; - LoggerD("app_id: %s", app_id.c_str()); - - pkgmgrinfo_appinfo_h handle; - int ret = pkgmgrinfo_appinfo_get_appinfo(app_id.c_str(), &handle); - if (ret != PMINFO_R_OK) { - LoggerE("Fail to get appInfo"); - ReportError(UnknownException("get_appinfo error : unknown error"), out); - return; - } - - ApplicationInformationPtr app_info_ptr = get_app_info(handle); - pkgmgrinfo_appinfo_destroy_appinfo(handle); - - ApplicationPtr app_ptr = ApplicationPtr(new Application()); - app_ptr->set_app_info(app_info_ptr); - - LoggerD("set appinfo to application"); - { - int pid = getpid(); // DO NOT USE getppid(); - LoggerD("context id = %d", pid); - - std::stringstream sstr; - sstr << pid; - app_ptr->set_context_id(sstr.str()); - } - - ReportSuccess(app_ptr->Value(), out); -} +void ApplicationInstance::Kill(const picojson::value& args, picojson::object& out) { + LoggerD("Entered"); -void ApplicationInstance::AppMgrKill(const picojson::value& args, - picojson::object& out) { CHECK_PRIVILEGE_ACCESS(kPrivilegeAppManagerKill, &out); - CHECK_EXIST(args, "callbackId", out) - - int callback_id = static_cast(args.get("callbackId").get()); - const std::string& context_id = args.get("contextId").get(); - - LoggerD("callbackId = %d", callback_id); - LoggerD("contextId = %s", context_id.c_str()); - - if (context_id.empty()) { - LoggerE("contextId is mandatory field."); - ReportError(InvalidValuesException("Context id is mandatory field."), out); - return; - } - - int ret; - int pid; - std::stringstream(context_id) >> pid; - - if (pid <= 0) { - LoggerE("Given context id is wrong."); - ReportError(InvalidValuesException("Given context id is wrong."), out); - return; - } - - // TC checks this case via error callback... moved it to callback - // if kill request is come for current context, - // throw InvalidValueException by spec - if (pid == getpid()) { - LoggerE("Given context id is same with me."); - - auto user_data = std::shared_ptr(new CallbackInfo); - user_data->instance = this; - user_data->callback_id = callback_id; - user_data->error_type = APP_ERROR_INVALID_VALUES; - snprintf(user_data->error_msg, sizeof(user_data->error_msg), - "Given context id is same with me."); - - common::TaskQueue::GetInstance().Queue( - callback_thread, self_kill_completed, user_data); - - ReportSuccess(out); - return; - } - - char *app_id_cstr = NULL; - ret = app_manager_get_app_id(pid, &app_id_cstr); - if (ret != APP_MANAGER_ERROR_NONE) { - LoggerE("Error while getting app id"); - ReportError(NotFoundException("Error while getting app id"), out); - return; - } - - std::string app_id = app_id_cstr; - free(app_id_cstr); - - app_context_h app_context; - ret = app_manager_get_app_context(app_id.c_str(), &app_context); - if (ret != APP_MANAGER_ERROR_NONE) { - LoggerE("Error while getting app context"); - ReportError(NotFoundException("Error while getting app context"), out); - return; - } - - CallbackInfo* info = new CallbackInfo; - info->instance = this; - snprintf(info->id, sizeof(info->id), "%s", context_id.c_str()); - info->callback_id = callback_id; - - ret = app_manager_set_app_context_event_cb( - app_manager_app_context_event_callback, reinterpret_cast(info)); - if (ret != APP_MANAGER_ERROR_NONE) { - if (info) - free(info); - LoggerE("Error while registering app context event"); - ReportError(InvalidValuesException( - "Error while registering app context event"), out); - return; - } - - ret = app_manager_terminate_app(app_context); - if (ret != APP_MANAGER_ERROR_NONE) { - if (info) - free(info); - LoggerE("Error while terminating app"); - ReportError(InvalidValuesException("Error while terminating app"), out); - return; - } - - ReportSuccess(out); + manager_.Kill(args); } -void ApplicationInstance::AppMgrLaunch(const picojson::value& args, - picojson::object& out) { - CHECK_PRIVILEGE_ACCESS(kPrivilegeApplicationLaunch, &out); - - CHECK_EXIST(args, "callbackId", out) - - int callback_id = static_cast(args.get("callbackId").get()); - const std::string& id = args.get("id").get(); - - LoggerD("callbackId = %d", callback_id); - LoggerD("appId = %s", id.c_str()); - - if (id.empty()) { - LoggerE("app_id is mandatory field."); - ReportError(InvalidValuesException("App id is mandatory field."), out); - return; - } - - auto user_data = std::shared_ptr(new CallbackInfo); - user_data->instance = this; - snprintf(user_data->id, sizeof(user_data->id), "%s", id.c_str()); - user_data->callback_id = callback_id; - - common::TaskQueue::GetInstance().Queue( - launch_thread, launch_completed, user_data); - - ReportSuccess(out); -} +void ApplicationInstance::Launch(const picojson::value& args, picojson::object& out) { + LoggerD("Entered"); -void ApplicationInstance::AppMgrLaunchAppControl(const picojson::value& args, - picojson::object& out) { CHECK_PRIVILEGE_ACCESS(kPrivilegeApplicationLaunch, &out); - CHECK_EXIST(args, "callbackId", out) - - int callback_id = static_cast(args.get("callbackId").get()); - LoggerD("callbackId = %d", callback_id); - std::string id; // app id is optional - if (args.contains("id")) { - id = args.get("id").get(); - LoggerD("app_id = %s", id.c_str()); - } - std::string launchMode; // launch mode is optional - if (args.contains("launchMode")) { - launchMode = args.get("launchMode").get(); - LoggerD("launchMode = %s", launchMode.c_str()); - } - ApplicationControlPtr app_ctr_ptr(new ApplicationControl()); - - picojson::value app_control = args.get("appControl"); - std::string operation = app_control.get("operation").get(); - app_ctr_ptr->set_operation(operation); - LoggerD("operation: %s", operation.c_str()); - - if (app_control.contains("uri")) { - if (app_control.get("uri").is() == false) { - std::string uri = app_control.get("uri").get(); - app_ctr_ptr->set_uri(uri); - } else { - LoggerD("uri is null"); - } - } - - if (app_control.contains("mime")) { - if (app_control.get("mime").is() == false) { - std::string mime = app_control.get("mime").get(); - app_ctr_ptr->set_mime(mime); - } else { - LoggerD("mime is null"); - } - } - - if (app_control.contains("category")) { - if (app_control.get("category").is() == false) { - std::string category = app_control.get("category").get(); - app_ctr_ptr->set_category(category); - } else { - LoggerD("category is null"); - } - } - - if (app_control.contains("data")) { - if (app_control.get("data").is() == false) { - std::vector data_array = - app_control.get("data").get(); - for (int i = 0; i < data_array.size(); i++) { - ApplicationControlDataPtr ctr_data_ptr(new ApplicationControlData()); - - picojson::value each_data = data_array.at(i); - std::string key = each_data.get("key").get(); - LoggerD("%d: key = %s", i, key.c_str()); - - ctr_data_ptr->set_ctr_key(key); - - std::vector values = - each_data.get("value").get(); - for (int j = 0; j < values.size(); j++) { - std::string val = values.at(i).to_str(); - - ctr_data_ptr->add_ctr_value(val); - LoggerD("-%d val = %s", j, val.c_str()); - } - app_ctr_ptr->add_data_array(ctr_data_ptr); - } - } else { - LoggerD("data is null."); - } - } - - // check parameters - if (operation.empty()) { - LoggerE("operation is mandatory field."); - ReportError(InvalidValuesException("operation is mandatory field."), out); - return; - } - - app_control_h service; - int ret = app_control_create(&service); - if (ret != APP_CONTROL_ERROR_NONE) { - ReportError(UnknownException("Creating app_control is failed."), out); - return; - } - - if (id.empty() == false) { - LoggerD("set_app_id: %s", id.c_str()); - ret = app_control_set_app_id(service, id.c_str()); - if (ret != APP_CONTROL_ERROR_NONE) { - ReportError(UnknownException("Setting app_id is failed."), out); - app_control_destroy(service); - return; - } - } else { - LoggerD("app_id is empty"); - } - - if (!launchMode.empty()) { - app_control_launch_mode_e launch_mode; - if (launchMode == "SINGLE") { - launch_mode = APP_CONTROL_LAUNCH_MODE_SINGLE; - } else if (launchMode == "GROUP") { - launch_mode = APP_CONTROL_LAUNCH_MODE_GROUP; - } else { - LoggerE("Invalid launch mode!"); - ReportError(UnknownException("Invalid launch mode"), out); - app_control_destroy(service); - return; - } - ret = app_control_set_launch_mode(service, launch_mode); - if (ret != APP_CONTROL_ERROR_NONE) { - ReportError(UnknownException("Setting app_id is failed."), out); - app_control_destroy(service); - return; - } - } - - ret = app_control_set_operation(service, operation.c_str()); - if (ret != APP_CONTROL_ERROR_NONE) { - ReportError(InvalidValuesException("operation is invalid parameter"), out); - app_control_destroy(service); - return; - } - - std::string uri = app_ctr_ptr->get_uri(); - if (!uri.empty()) { - ret = app_control_set_uri(service, uri.c_str()); - if (ret != APP_CONTROL_ERROR_NONE) { - ReportError(InvalidValuesException("uri is invalid parameter"), out); - app_control_destroy(service); - return; - } - } - - std::string mime = app_ctr_ptr->get_mime(); - if (!mime.empty()) { - ret = app_control_set_mime(service, mime.c_str()); - if (ret != APP_CONTROL_ERROR_NONE) { - ReportError(InvalidValuesException("mime is invalid parameter"), out); - app_control_destroy(service); - return; - } - } - - std::string category = app_ctr_ptr->get_category(); - if (!category.empty()) { - ret = app_control_set_category(service, category.c_str()); - if (ret != APP_CONTROL_ERROR_NONE) { - ReportError(InvalidValuesException("category is invalid parameter"), - out); - app_control_destroy(service); - return; - } - } - - CallbackInfo* info = new CallbackInfo; - info->instance = this; - info->callback_id = callback_id; - - LoggerD("Try to launch..."); - ret = app_control_send_launch_request(service, - app_control_reply_callback, reinterpret_cast(info)); - - auto user_data = std::shared_ptr(new CallbackInfo); - user_data->instance = this; - user_data->callback_id = callback_id; - - if (ret != APP_CONTROL_ERROR_NONE) { - switch (ret) { - case APP_CONTROL_ERROR_INVALID_PARAMETER: - LoggerD("launch_request is failed. ERROR_INVALID_PARAMETER"); - user_data->error_type = APP_ERROR_TYPE_MISMATCH; - snprintf(user_data->error_msg, sizeof(user_data->error_msg), - "launch_request is failed. INVALID_PARAMETER"); - break; - case APP_CONTROL_ERROR_OUT_OF_MEMORY: - LoggerD("launch_request is failed. ERROR_OUT_OF_MEMORY"); - user_data->error_type = APP_ERROR_UNKNOWN; - snprintf(user_data->error_msg, sizeof(user_data->error_msg), - "launch_request is failed. OUT_OF_MEMORY"); - break; - case APP_CONTROL_ERROR_LAUNCH_REJECTED: - LoggerD("launch_request is failed. ERROR_LAUNCH_REJECTED"); - user_data->error_type = APP_ERROR_ABORT; - snprintf(user_data->error_msg, sizeof(user_data->error_msg), - "launch_request is failed. LAUNCH_REJECTED"); - break; - case APP_CONTROL_ERROR_APP_NOT_FOUND: - LoggerD("launch_request is failed. ERROR_APP_NOT_FOUND"); - user_data->error_type = APP_ERROR_NOT_FOUND; - snprintf(user_data->error_msg, sizeof(user_data->error_msg), - "launch_request is failed. NOT_FOUND"); - break; - default: - LoggerD("launch_request is failed."); - user_data->error_type = APP_ERROR_UNKNOWN; - snprintf(user_data->error_msg, sizeof(user_data->error_msg), - "launch_request is failed. UNKNOWN"); - break; - } - user_data->is_success = false; - } else { - user_data->is_success = true; - } - // This causes to invalidate callback. This is not expected. - // TODO: Refactor launchAppControl - //common::TaskQueue::GetInstance().Queue( - // callback_thread, callback_thread_completed, user_data); - - ret = app_control_destroy(service); - if (ret != APP_CONTROL_ERROR_NONE) { - LoggerD("app_control_destroy is failed"); - } - - ReportSuccess(out); -} - -void ApplicationInstance::AppMgrFindAppControl(const picojson::value& args, - picojson::object& out) { - CHECK_EXIST(args, "callbackId", out) - - int callback_id = static_cast(args.get("callbackId").get()); - LoggerD("callbackId = %d", callback_id); - - ApplicationControlPtr app_ctr_ptr(new ApplicationControl()); - - picojson::value app_control = args.get("appControl"); - char print_buf[300] = {0}; - snprintf(print_buf, sizeof(print_buf), app_control.serialize().c_str()); - LoggerD("appControl: %s", print_buf); - std::string operation = app_control.get("operation").get(); - app_ctr_ptr->set_operation(operation); - LoggerD("operation: %s", operation.c_str()); - - if (app_control.contains("uri")) { - if (app_control.get("uri").is() == false) { - std::string uri = app_control.get("uri").get(); - app_ctr_ptr->set_uri(uri); - } else { - LoggerD("uri is null"); - } - } - - if (app_control.contains("mime")) { - if (app_control.get("mime").is() == false) { - std::string mime = app_control.get("mime").get(); - app_ctr_ptr->set_mime(mime); - } else { - LoggerD("mime is null"); - } - } - - if (app_control.contains("category")) { - if (app_control.get("category").is() == false) { - std::string category = app_control.get("category").get(); - app_ctr_ptr->set_category(category); - } else { - LoggerD("category is null"); - } - } - - if (app_control.contains("data")) { - if (app_control.get("data").is() == false) { - std::vector data_array = - app_control.get("data").get(); - for (int i = 0; i < data_array.size(); i++) { - ApplicationControlDataPtr ctr_data_ptr(new ApplicationControlData()); - - picojson::value each_data = data_array.at(i); - std::string key = each_data.get("key").get(); - LoggerD("%d: key = %s", i, key.c_str()); - - ctr_data_ptr->set_ctr_key(key); - - std::vector values = - each_data.get("value").get(); - for (int j = 0; j < values.size(); j++) { - std::string val = values.at(i).to_str(); - - ctr_data_ptr->add_ctr_value(val); - LoggerD("-%d val = %s", j, val.c_str()); - } - - app_ctr_ptr->add_data_array(ctr_data_ptr); - } - } else { - LoggerD("data is null."); - } - } - - // check parameters - if (operation.empty()) { - LoggerE("operation is mandatory field."); - ReportError(InvalidValuesException("operation is mandatory field."), out); - return; - } - - app_control_h service; - int ret = app_control_create(&service); - if (ret != APP_CONTROL_ERROR_NONE) { - ReportError(UnknownException("Creating app_control is failed."), out); - app_control_destroy(service); - return; - } - - ret = app_control_set_operation(service, operation.c_str()); - if (ret != APP_CONTROL_ERROR_NONE) { - ReportError(InvalidValuesException("operation is invalid parameter"), out); - app_control_destroy(service); - return; - } - - std::string uri = app_ctr_ptr->get_uri(); - if (!uri.empty()) { - ret = app_control_set_uri(service, uri.c_str()); - if (ret != APP_CONTROL_ERROR_NONE) { - ReportError(InvalidValuesException("uri is invalid parameter"), out); - app_control_destroy(service); - return; - } - } - - std::string mime = app_ctr_ptr->get_mime(); - if (!mime.empty()) { - ret = app_control_set_mime(service, mime.c_str()); - if (ret != APP_CONTROL_ERROR_NONE) { - ReportError(InvalidValuesException("mime is invalid parameter"), out); - app_control_destroy(service); - return; - } - } - - std::string category = app_ctr_ptr->get_category(); - if (!category.empty()) { - ret = app_control_set_category(service, category.c_str()); - if (ret != APP_CONTROL_ERROR_NONE) { - ReportError(InvalidValuesException("category is invalid parameter"), - out); - app_control_destroy(service); - return; - } - } - - auto user_data = std::shared_ptr(new CallbackInfo); - user_data->instance = this; - user_data->callback_id = callback_id; - - ApplicationInformationArrayPtr app_info_array_ptr( - new ApplicationInformationArray()); - - LoggerD("Try to find..."); - ret = app_control_foreach_app_matched(service, - app_control_app_matched_callback, - reinterpret_cast(app_info_array_ptr.get())); - - if (ret == APP_CONTROL_ERROR_NONE) { - LoggerE("app_control_foreach_app_matched: ERROR_NONE"); - user_data->is_success = true; - - picojson::value app_infos = picojson::value(picojson::array()); - picojson::array& app_infos_array = app_infos.get(); - - for (int i = 0; i < app_info_array_ptr->size(); i++) { - ApplicationInformationPtr app_info_ptr = app_info_array_ptr->at(i); - app_infos_array.push_back(app_info_ptr->Value()); - } - - // ReplyAsync - user_data->data.insert(std::make_pair("informationArray", app_infos)); - user_data->data.insert(std::make_pair("appControl", app_ctr_ptr->Value())); - - } else if (ret == APP_CONTROL_ERROR_INVALID_PARAMETER) { - LoggerD("launch_request is failed. ERROR_INVALID_PARAMETER"); - user_data->error_type = APP_ERROR_TYPE_MISMATCH; - snprintf(user_data->error_msg, sizeof(user_data->error_msg), - "launch_request is failed. INVALID_PARAMETER"); - user_data->is_success = false; - } else { - LoggerD("launch_request is failed. UNKNOWN"); - user_data->error_type = APP_ERROR_UNKNOWN; - snprintf(user_data->error_msg, sizeof(user_data->error_msg), - "launch_request is failed. OUT_OF_MEMORY"); - user_data->is_success = false; - } - - common::TaskQueue::GetInstance().Queue(callback_thread, - find_callback_thread_completed, user_data); - - ret = app_control_destroy(service); - if (ret != APP_CONTROL_ERROR_NONE) { - LoggerD("app_control_destroy is failed"); - } - - ReportSuccess(out); -} - -void ApplicationInstance::AppMgrGetAppsContext(const picojson::value& args, - picojson::object& out) { - CHECK_EXIST(args, "callbackId", out) - - int callback_id = static_cast(args.get("callbackId").get()); - - auto user_data = std::shared_ptr(new CallbackInfo); - user_data->instance = this; - user_data->callback_id = callback_id; - - common::TaskQueue::GetInstance().Queue( - getappsctx_callback_thread, getappsctx_callback_thread_completed, - user_data); - - ReportSuccess(out); -} - -void ApplicationInstance::AppMgrGetAppContext(const picojson::value& args, - picojson::object& out) { - LoggerD("ENTER"); - - std::string context_id; - if (args.contains("contextId")) { - LoggerD("ENTER2"); - context_id = args.get("contextId").get(); - LoggerD("contextId = %s", context_id.c_str()); - } else { - LoggerD("contextId is null"); - } - int ret = 0; - - std::string cur_ctx_id = context_id; - int pid; - - if (cur_ctx_id.empty()) { - pid = getpid(); - std::stringstream sstr; - sstr << pid; - cur_ctx_id = sstr.str(); - } else { - std::stringstream(context_id) >> pid; - if (pid <= 0) { - LoggerE("Given context_id is wrong"); - ReportError(NotFoundException("Given context_id is wrong"), out); - return; - } - } - - char *app_id = NULL; - LoggerD("pid: %d", pid); - - ret = app_manager_get_app_id(pid, &app_id); - if (ret != APP_MANAGER_ERROR_NONE) { - // Handles error case - if (app_id) { - free(app_id); - } - switch (ret) { - case APP_MANAGER_ERROR_INVALID_PARAMETER: - LoggerE("get_app_id error : invalid parameter"); - ReportError(NotFoundException("get_app_id error : invalid parameter"), - out); - return; - case APP_MANAGER_ERROR_NO_SUCH_APP: - LoggerE("get_app_id error : no such app"); - ReportError(NotFoundException("get_app_id error : no such app"), out); - return; - case APP_MANAGER_ERROR_DB_FAILED: - LoggerE("get_app_id error : db failed"); - ReportError(NotFoundException("get_app_id error : db failed"), out); - return; - case APP_MANAGER_ERROR_OUT_OF_MEMORY: - LoggerE("get_app_id error : out of memory"); - ReportError(NotFoundException("get_app_id error : out of memory"), - out); - return; - default: - LoggerE("get_app_id known error"); - ReportError(UnknownException("get_app_id error : unknown error"), out); - return; - } - } - - ApplicationContextPtr app_ctx(new ApplicationContext()); - app_ctx->set_app_id(app_id); - app_ctx->set_context_id(cur_ctx_id); - - if (app_id) - free(app_id); - - LoggerD("appCtx: id = %s", app_ctx->get_context_id().c_str()); - LoggerD("appCtx: appId = %s", app_ctx->get_app_id().c_str()); - - ReportSuccess(picojson::value(app_ctx->Value()), out); + manager_.Launch(args); } -void ApplicationInstance::AppMgrGetAppsInfo(const picojson::value& args, - picojson::object& out) { - CHECK_EXIST(args, "callbackId", out) - - int callback_id = static_cast(args.get("callbackId").get()); - - auto user_data = std::shared_ptr(new CallbackInfo); - user_data->instance = this; - user_data->callback_id = callback_id; - - common::TaskQueue::GetInstance().Queue( - getappsinfo_callback_thread, getappsinfo_callback_thread_completed, - user_data); - - ReportSuccess(out); -} - -void ApplicationInstance::AppMgrGetAppInfo(const picojson::value& args, - picojson::object& out) { - std::string id; - if (args.contains("id")) { - id = args.get("id").get(); - if (id.empty()) { - LoggerD("Id is null. use current app id"); - id = app_id_; - } - } else { - id = app_id_; - } - - LoggerD("app_id = %s", id.c_str()); - - pkgmgrinfo_appinfo_h handle; - int ret = pkgmgrinfo_appinfo_get_appinfo(id.c_str(), &handle); - if (ret != PMINFO_R_OK) { - LoggerE("Fail to get appInfo"); - ReportError(NotFoundException("Given app id is not found"), out); - return; - } - - ApplicationInformationPtr app_info_ptr = get_app_info(handle); - pkgmgrinfo_appinfo_destroy_appinfo(handle); - - ReportSuccess(app_info_ptr->Value(), out); -} - -void ApplicationInstance::AppMgrGetAppCerts(const picojson::value& args, - picojson::object& out) { - CHECK_PRIVILEGE_ACCESS(kPrivilegeAppManagerCertificate, &out); - - std::string id; - if (args.contains("id")) { - id = args.get("id").get(); - if (id.empty()) { - LoggerD("Id is null. use current app id"); - id = app_id_; - } - } else { - id = app_id_; - } - - LoggerD("app_id = %s", id.c_str()); - - int ret = 0; - char* package = getPackageByAppId(id.c_str()); - if (package == NULL) { - LoggerE("Can not get package"); - ReportError(NotFoundException("Can not get package"), out); - return; - } - - // TODO(sunggyu.choi): gPkgIdMapInited - package_info_h pkg_info; - int result = 0; - result = package_info_create(package, &pkg_info); - if (result != PACKAGE_MANAGER_ERROR_NONE) { - ReportError(UnknownException("Can not get package info"), out); - return; - } - - ApplicationCertificateArrayPtr cert_array_ptr( - new ApplicationCertificateArray()); - - result = package_info_foreach_cert_info(pkg_info, package_certificate_cb, - reinterpret_cast(cert_array_ptr.get())); - if ((result != PACKAGE_MANAGER_ERROR_NONE) && - (result != PACKAGE_MANAGER_ERROR_IO_ERROR)) { - ReportError(UnknownException("Can not get package cert info"), out); - return; - } - - picojson::value cert_data = picojson::value(picojson::array()); - picojson::array& cert_data_array = cert_data.get(); - - for (int i = 0; i < cert_array_ptr->size(); i++) { - ApplicationCertificatePtr cert_data_ptr = cert_array_ptr->at(i); - cert_data_array.push_back(cert_data_ptr->Value()); - } - - ReportSuccess(cert_data, out); -} - -void ApplicationInstance::AppMgrGetAppSharedURI(const picojson::value& args, - picojson::object& out) { - std::string id; - if (args.contains("id")) { - id = args.get("id").get(); - if (id.empty()) { - LoggerD("Id is null. use current app id"); - id = app_id_; - } - } else { - id = app_id_; - } - - LoggerD("app_id = %s", id.c_str()); - -#define TIZENAPIS_APP_FILE_SCHEME "file://" -#define TIZENAPIS_APP_SLASH "/" -#define TIZENAPIS_APP_SHARED "shared" - - app_info_h handle; - char* pkg_name = NULL; - - int ret = app_manager_get_app_info(id.c_str(), &handle); - if (ret != APP_ERROR_NONE) { - LoggerD("Fail to get appinfo"); - ReportError(NotFoundException("Fail to get appinfo"), out); - return; - } - - ret = app_info_get_package(handle, &pkg_name); - if ((ret != APP_ERROR_NONE) || (pkg_name == NULL)) { - LoggerD("Fail to get pkg_name"); - ReportError(NotFoundException("Fail to get pkg_name"), out); - return; - } - - app_info_destroy(handle); - - pkgmgrinfo_pkginfo_h pkginfo_h; - char* root_path = NULL; - - ret = pkgmgrinfo_pkginfo_get_pkginfo(pkg_name, &pkginfo_h); - if (ret != PMINFO_R_OK) { - free(pkg_name); - ReportError(UnknownException("Fail to get pkginfo"), out); - return; - } - - ret = pkgmgrinfo_pkginfo_get_root_path(pkginfo_h, &root_path); - if ((ret != PMINFO_R_OK) || (root_path == NULL)) { - LoggerE("Fail to get root path"); - free(pkg_name); - ReportError(UnknownException("Fail to get root path"), out); - return; - } - - std::string shared_URI = TIZENAPIS_APP_FILE_SCHEME + std::string(root_path) + - TIZENAPIS_APP_SLASH + TIZENAPIS_APP_SHARED + TIZENAPIS_APP_SLASH; - free(pkg_name); - - pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo_h); - - ReportSuccess(picojson::value(shared_URI), out); -} - -void ApplicationInstance::AppMgrGetAppMetaData(const picojson::value& args, - picojson::object& out) { - CHECK_PRIVILEGE_ACCESS(kPrivilegeApplicationInfo, &out); - - std::string id; - if (args.contains("id")) { - id = args.get("id").get(); - if (id.empty()) { - LoggerD("Id is null. use current app id"); - id = app_id_; - } - } else { - id = app_id_; - } - - LoggerD("app_id = %s", id.c_str()); - - int ret = 0; - pkgmgrinfo_appinfo_h handle; - ret = pkgmgrinfo_appinfo_get_appinfo(id.c_str(), &handle); - if (ret != PMINFO_R_OK) { - ReportError(NotFoundException("Cannot find app with given app_id"), out); - return; - } - - ApplicationMetaDataArrayPtr meta_data_array_ptr( - new ApplicationMetaDataArray()); - ret = pkgmgrinfo_appinfo_foreach_metadata(handle, app_meta_data_cb, - reinterpret_cast(meta_data_array_ptr.get())); - if (ret != PMINFO_R_OK) { - LoggerE("pkgmgrinfo_appinfo_metadata_filter_foreach() failed"); - pkgmgrinfo_appinfo_destroy_appinfo(handle); - ReportError(UnknownException("fail to get custom tag"), out); - return; - } - pkgmgrinfo_appinfo_destroy_appinfo(handle); - - picojson::value meta_data = picojson::value(picojson::array()); - picojson::array& meta_data_array = meta_data.get(); - - for (int i = 0; i < meta_data_array_ptr->size(); i++) { - ApplicationMetaDataPtr meta_data_ptr = meta_data_array_ptr->at(i); - - meta_data_array.push_back(meta_data_ptr->Value()); - } - - char print_buf[300] = {0}; - snprintf(print_buf, sizeof(print_buf), meta_data.serialize().c_str()); - LoggerD("GetAppMetaData:Result: %s", print_buf); - - ReportSuccess(meta_data, out); -} - -void ApplicationInstance::AppMgrAddAppInfoEventListener( - const picojson::value& args, picojson::object& out) { - CHECK_EXIST(args, "callbackId", out) - - int callback_id = static_cast(args.get("callbackId").get()); - - if (manager_handle_ != NULL) { - LoggerD("AppListChanged callback is already registered. watch_id_ = %d", - watch_id_); - ReportError(UnknownException("Listener is already registered."), out); - return; - } - manager_handle_ = pkgmgr_client_new(PC_LISTENING); - if (manager_handle_ == NULL) { - ReportError(UnknownException("Error while registering listener"), out); - return; - } - - pkgmgr_client_listen_status(manager_handle_, app_list_changed_cb, this); - - callback_id_list_.push_back(callback_id); - const double ret = static_cast(get_watch_id_and_increase()); - ReportSuccess(picojson::value(ret), out); -} - -void ApplicationInstance::AppMgrRemoveAppInfoEventListener( - const picojson::value& args, picojson::object& out) { - CHECK_EXIST(args, "watchId", out) - int watch_id = static_cast(args.get("watchId").get()); - - LoggerD("watch_id = %d", watch_id); - - if (manager_handle_ == NULL) { - LoggerE("Listener is not added before."); - ReportError(UnknownException("Listener is not added before."), out); - return; - } - - callback_id_list_.clear(); - - if (watch_id_ != watch_id) { - LoggerE("Invalid watch id: %d", watch_id); - ReportError(InvalidValuesException("Watch id is invalid."), out); - return; - } - - pkgmgr_client_free(manager_handle_); - manager_handle_ = NULL; - - ReportSuccess(out); -} - -void ApplicationInstance::AppGetRequestedAppControl( - const picojson::value& args, picojson::object& out) { - std::string bundle_str = - common::GetCurrentExtension()->GetRuntimeVariable("encoded_bundle", 1024); - if (bundle_str.empty()) { - LoggerE("Getting encoded_bundle is failed"); - ReportError(UnknownException("Gettng encoded_bundle is failed"), out); - return; - } - - app_control_h service = NULL; - char* tmp_str = NULL; - bundle* request_bundle = bundle_decode((bundle_raw*)bundle_str.c_str(), - bundle_str.length()); - if (request_bundle == NULL) { - ReportError(UnknownException("Decoding bundle is failed"), out); - return; - } - - int ret = app_control_create_event(request_bundle, &service); - if (ret != APP_CONTROL_ERROR_NONE) { - LoggerE("Fail to create event"); - bundle_free(request_bundle); - ReportError(UnknownException("Failed to create event"), out); - return; - } - bundle_free(request_bundle); - - ApplicationControlPtr app_ctr_ptr(new ApplicationControl()); - - ret = app_control_get_operation(service, &tmp_str); - if (ret == APP_CONTROL_ERROR_NONE && tmp_str != NULL) { - app_ctr_ptr->set_operation(tmp_str); - free(tmp_str); - tmp_str = NULL; - } - - ret = app_control_get_uri(service, &tmp_str); - if (ret == APP_CONTROL_ERROR_NONE && tmp_str != NULL) { - app_ctr_ptr->set_uri(tmp_str); - free(tmp_str); - tmp_str = NULL; - } - - ret = app_control_get_mime(service, &tmp_str); - if (ret == APP_CONTROL_ERROR_NONE && tmp_str != NULL) { - app_ctr_ptr->set_mime(tmp_str); - free(tmp_str); - tmp_str = NULL; - } - - ret = app_control_get_category(service, &tmp_str); - if (ret == APP_CONTROL_ERROR_NONE && tmp_str != NULL) { - app_ctr_ptr->set_category(tmp_str); - free(tmp_str); - tmp_str = NULL; - } - - ApplicationControlDataArrayPtr app_ctr_data_array_ptr( - new ApplicationControlDataArray()); - ret = app_control_foreach_extra_data(service, - app_control_extra_data_callback, app_ctr_data_array_ptr.get()); - if (ret != APP_CONTROL_ERROR_NONE) { - LoggerE("app_control_foreach_extra_data fail"); - ReportError(UnknownException("Getting extra data is failed"), out); - return; - } else { - app_ctr_ptr->set_data_array(*(app_ctr_data_array_ptr.get())); - } - - RequestedApplicationControlPtr req_app_ctr_ptr( - new RequestedApplicationControl()); - req_app_ctr_ptr->set_app_control(*(app_ctr_ptr.get())); - - // add caller id - ret = app_control_get_caller(service, &tmp_str); - if (ret == APP_CONTROL_ERROR_NONE && tmp_str != NULL) { - req_app_ctr_ptr->set_caller_app_id(tmp_str); - free(tmp_str); - tmp_str = NULL; - } else { - LoggerE("Failed to get caller application ID"); - ReportError(NotFoundException("Failed to get caller application ID"), out); - return; - } - - std::pair::iterator, bool> result = - reply_map_.insert( - std::map::value_type( - req_app_ctr_ptr->get_caller_app_id(), service)); - if (result.second) { - LoggerD("Adding item succeeded"); - } else { - LoggerD("Adding item failed"); - } - - ReportSuccess(req_app_ctr_ptr->Value(), out); -} - -void ApplicationInstance::RequestedAppControlReplyResult( - const picojson::value& args, picojson::object& out) { - ApplicationControlDataArrayPtr app_ctr_data_array_ptr( - new ApplicationControlDataArray()); - std::string caller_app_id; - if (args.contains("callerAppId")) { - caller_app_id = args.get("callerAppId").get(); - } else { - ReportError(InvalidValuesException("unidentified caller"), out); - return; - } - - if (args.contains("data")) { - if (args.get("data").is() == false) { - picojson::array data_array = args.get("data").get(); - - int size = data_array.size(); - LoggerD("size = %d", size); - for (int i = 0; i < size; i++) { - ApplicationControlData* app_ctr_data = new ApplicationControlData(); - ApplicationControlDataPtr app_ctr_data_ptr(app_ctr_data); - - picojson::value& ctr_data = data_array.at(i); - std::string key = ctr_data.get("key").get(); - app_ctr_data_ptr->set_ctr_key(key); - - picojson::array value_array = - ctr_data.get("value").get(); - int value_size = value_array.size(); - - LoggerD("value size = %d", value_size); - for (int j = 0; j < value_size; j++) { - picojson::value& value_data = value_array.at(i); - std::string value = value_data.get(); - LoggerD("value: %s", value.c_str()); - app_ctr_data_ptr->add_ctr_value(value); - } - app_ctr_data_array_ptr->push_back(app_ctr_data_ptr); - } - } else { - LoggerD("data is null."); - } - } - - app_control_h reply; - app_control_create(&reply); - - if (!app_ctr_data_array_ptr->empty()) { - const char** arr = NULL; - - int size = app_ctr_data_array_ptr->size(); - LoggerD("size: %d", size); - for (size_t i = 0; i < size; i++) { - std::vector value_array = - app_ctr_data_array_ptr->at(i)->get_ctr_value(); - arr = (const char**) calloc (sizeof(char*), value_array.size()); - - if (arr != NULL) { - for (size_t j = 0; j < value_array.size(); j++) { - arr[j] = value_array.at(j).c_str(); - LoggerD("[index: %d][value: %s]", j, arr[j]); - } - } - const char* key = app_ctr_data_array_ptr->at(i)->get_ctr_key().c_str(); - LoggerD("key: %s", key); - app_control_add_extra_data_array(reply, key, arr, value_array.size()); - if (arr) { - free(arr); - } - } - } else { - LoggerE("[replyResult] app_ctr_data_array_ptr is empty"); - } - - std::map::iterator it = - reply_map_.find(caller_app_id); - if (it == reply_map_.end()) { - LoggerE("caller handle is not found"); - app_control_destroy(reply); - ReportError(NotFoundException("caller handle is not found"), out); - return; - } - - bool running = false; - int ret = app_manager_is_running(caller_app_id.c_str(), &running); - if ((ret != APP_MANAGER_ERROR_NONE) || !running) { - LoggerE("caller is not running"); - app_control_destroy(reply); - ReportError(NotFoundException("Cannot find caller"), out); - return; - } - - ret = app_control_reply_to_launch_request(reply, it->second, - APP_CONTROL_RESULT_SUCCEEDED); - if (ret != APP_CONTROL_ERROR_NONE) { - LoggerE("Cannot find caller"); - app_control_destroy(reply); - ReportError(NotFoundException("Cannot find caller"), out); - return; - } - - reply_map_.erase(it); - app_control_destroy(reply); - - ReportSuccess(out); -} - -void ApplicationInstance::RequestedAppControlReplyFailure( - const picojson::value& args, picojson::object& out) { - std::string caller_app_id; - if (args.contains("callerAppId")) { - caller_app_id = args.get("callerAppId").get(); - } else { - ReportError(InvalidValuesException("unidentified caller"), out); - return; - } - - app_control_h reply; - app_control_create(&reply); - - std::map::iterator it = - reply_map_.find(caller_app_id); - if (it == reply_map_.end()) { - LoggerE("caller handle is not found"); - ReportError(NotFoundException("caller handle is not found"), out); - return; - } - - bool running = false; - int ret = app_manager_is_running(caller_app_id.c_str(), &running); - if ((ret != APP_MANAGER_ERROR_NONE) || !running) { - LoggerE("caller is not running"); - app_control_destroy(reply); - ReportError(NotFoundException("Cannot find caller"), out); - return; - } - - ret = app_control_reply_to_launch_request(reply, it->second, - APP_CONTROL_RESULT_FAILED); - if (ret != APP_CONTROL_ERROR_NONE) { - LoggerE("Cannot find caller"); - app_control_destroy(reply); - ReportError(NotFoundException("Cannot find caller"), out); - return; - } - - reply_map_.erase(it); - app_control_destroy(reply); - - ReportSuccess(out); -} - -ApplicationInformationPtr ApplicationInstance::GetAppInfo( - const std::string app_id) { - LoggerD("app_id: %s", app_id.c_str()); - - pkgmgrinfo_appinfo_h handle; - int ret = pkgmgrinfo_appinfo_get_appinfo(app_id.c_str(), &handle); - if (ret != PMINFO_R_OK) { - LoggerE("Fail to get appInfo"); - ApplicationInformationPtr app_info_ptr(new ApplicationInformation()); - return app_info_ptr; - } +void ApplicationInstance::LaunchAppControl(const picojson::value& args, picojson::object& out) { + LoggerD("Entered"); - ApplicationInformationPtr app_info_ptr = get_app_info(handle); - pkgmgrinfo_appinfo_destroy_appinfo(handle); + CHECK_PRIVILEGE_ACCESS(kPrivilegeApplicationLaunch, &out); - return app_info_ptr; + manager_.LaunchAppControl(args); } -int ApplicationInstance::app_list_changed_cb(int id, const char *type, - const char *package, const char *key, const char *val, const void *msg, - void *data) { - static app_info_event_e event_type; - - LoggerD("ENTERED"); - - // pre-process - if (!strcasecmp(key, "start")) { - if (!strcasecmp(val, "install")) { - LoggerD("start: install"); - event_type = APP_INFO_EVENT_INSTALLED; - } else if (!strcasecmp(val, "uninstall")) { - // After uninstallation, we cannot get app ids from package name. - // So, we have to store app ids which is included to target package. - LoggerD("start: uninstall"); - package_info_h package_info; - - int ret = package_info_create(package, &package_info); - if (ret != PACKAGE_MANAGER_ERROR_NONE) { - LoggerE("Cannot create package info"); - } - - ret = package_info_foreach_app_from_package(package_info, - PACKAGE_INFO_ALLAPP, app_callback, data); - if (ret != PACKAGE_MANAGER_ERROR_NONE) { - LoggerE("failed while getting appids"); - } - ret = package_info_destroy(package_info); - if (ret != PACKAGE_MANAGER_ERROR_NONE) { - LoggerE("Cannot destroy package info"); - } - event_type = APP_INFO_EVENT_UNINSTALLED; - } else if (!strcasecmp(val, "update")) { - LoggerD("start: update"); - event_type = APP_INFO_EVENT_UPDATED; - } - // post-process - } else if (!strcasecmp(key, "end") && !strcasecmp(val, "ok")) { - if (event_type >= 0) { - if (data != NULL) { - LoggerD("end & ok is called: package = %s", package); - // ApplicationInstance* app_instance = (ApplicationInstance*)data; - ApplicationInstance* app_instance = - reinterpret_cast(data); - app_instance->ReplyAppListChangedCallback(event_type, package, data); - } - } - } +void ApplicationInstance::FindAppControl(const picojson::value& args, picojson::object& out) { + LoggerD("Entered"); - return APP_MANAGER_ERROR_NONE; + manager_.FindAppControl(args); } -bool ApplicationInstance::app_callback( - package_info_app_component_type_e comp_type, const char *app_id, - void *user_data) { - LoggerD("ENTERED"); - - if (app_id == NULL) { - LoggerE("Callback is called. but no package name is passed"); - return true; - } - - if (user_data == NULL) { - LoggerE("user data is not exist. skip this request"); - return true; - } - - LoggerD("app_id = %s", app_id); - ApplicationInstance* app_instance = - reinterpret_cast(user_data); - app_instance->app_list_.push_back(app_id); +void ApplicationInstance::GetAppsContext(const picojson::value& args, picojson::object& out) { + LoggerD("Entered"); - return true; + manager_.GetAppsContext(args); } -void ApplicationInstance::ReplyAppListChangedCallback( - app_info_event_e event_type, const char* pkg_id, void* user_data) { - LoggerD("ENTERED"); - - ApplicationInstance* app_instance = - reinterpret_cast(user_data); - - if (event_type == APP_INFO_EVENT_UNINSTALLED) { - for (size_t i = 0; i < app_list_.size(); i++) { - // onuninstalled - LoggerD("onuninstalled: %d of %d", i, app_list_.size()); - std::string app_id = app_list_.at(i); - - for (size_t j = 0; j < callback_id_list_.size(); j++) { - int callback_id = callback_id_list_.at(j); - LoggerD("%d th callback_id(%d) of %d", j, callback_id, - callback_id_list_.size()); - picojson::object data; - data.insert(std::make_pair("type", picojson::value("onuninstalled"))); - data.insert(std::make_pair("id", picojson::value(app_id))); - ReplyAsync(this, callback_id, true, &data, 0, NULL); - } - } - } else { - package_info_h package_info; - - int ret = package_info_create(pkg_id, &package_info); - if (ret != PACKAGE_MANAGER_ERROR_NONE) { - LoggerE("Cannot create package info"); - return; - } - - // app_callback is called immediately - ret = package_info_foreach_app_from_package(package_info, - PACKAGE_INFO_ALLAPP, app_callback, user_data); - if (ret != PACKAGE_MANAGER_ERROR_NONE) { - LoggerE("failed while getting appids"); - package_info_destroy(package_info); - return; - } - - ret = package_info_destroy(package_info); - if (ret != PACKAGE_MANAGER_ERROR_NONE) { - LoggerE("Cannot destroy package info"); - } - - for (size_t i = 0; i < app_list_.size(); i++) { - switch (event_type) { - case APP_INFO_EVENT_INSTALLED: - { - // oninstalled - LoggerD("oninstalled: %d of %d", i, app_list_.size()); - std::string app_id = app_list_.at(i); - - ApplicationInformationPtr app_info_ptr = GetAppInfo(app_id); - - for (size_t j = 0; j < callback_id_list_.size(); j++) { - int callback_id = callback_id_list_.at(j); - LoggerD("%d th callback_id(%d) of %d", j, callback_id, - callback_id_list_.size()); - picojson::object data; - data.insert(std::make_pair("type", - picojson::value("oninstalled"))); - data.insert(std::make_pair("info", - picojson::value(app_info_ptr->Value()))); - ReplyAsync(this, callback_id, true, &data, 0, NULL); - } - } - break; - case APP_INFO_EVENT_UPDATED: - { - // onupdated - LoggerD("onupdated: %d of %d", i, app_list_.size()); - std::string app_id = app_list_.at(i); - - ApplicationInformationPtr app_info_ptr = GetAppInfo(app_id); - - for (size_t j = 0; j < callback_id_list_.size(); j++) { - int callback_id = callback_id_list_.at(j); - LoggerD("%d th callback_id(%d) of %d", j, callback_id, - callback_id_list_.size()); - picojson::object data; - data.insert(std::make_pair("type", - picojson::value("onupdated"))); - data.insert(std::make_pair("info", - picojson::value(app_info_ptr->Value()))); - ReplyAsync(this, callback_id, true, &data, 0, NULL); - } - } - break; - default: - LoggerE("app_manager listener gave wrong event_type"); - break; - } - } - } - - // clean-up applist - app_list_.clear(); -} +void ApplicationInstance::GetAppsInfo(const picojson::value& args, picojson::object& out) { + LoggerD("Entered"); -int ApplicationInstance::get_watch_id_and_increase() { - return ++watch_id_; + manager_.GetAppsInfo(args); } -#undef CHECK_EXIST } // namespace application } // namespace extension diff --git a/src/application/application_instance.h b/src/application/application_instance.h index c1875e16..61d12c16 100644 --- a/src/application/application_instance.h +++ b/src/application/application_instance.h @@ -5,86 +5,43 @@ #ifndef SRC_APPLICATION_APPLICATION_INSTANCE_H_ #define SRC_APPLICATION_APPLICATION_INSTANCE_H_ -// to handle app-control -#include -#include -#include - -// to get package name bye appid -#include - -// to get cert info from package -#include -#include - #include -#include -#include -#include #include "common/extension.h" +#include "application/application_manager.h" #include "application/application.h" -#include "application/application_context.h" -#include "application/application_metadata.h" -#include "application/application_certificate.h" -#include "application/application_control.h" #include "application/requested_application_control.h" namespace extension { namespace application { -class ApplicationInstance - : public common::ParsedInstance { +class ApplicationInstance: public common::ParsedInstance { public: - explicit ApplicationInstance(const std::string& app_id); + ApplicationInstance(const std::string& app_id); virtual ~ApplicationInstance(); - private: - void AppMgrGetCurrentApplication(const picojson::value& args, - picojson::object& out); - void AppMgrKill(const picojson::value& args, picojson::object& out); - void AppMgrLaunch(const picojson::value& args, picojson::object& out); - void AppMgrLaunchAppControl(const picojson::value& args, - picojson::object& out); - void AppMgrFindAppControl(const picojson::value& args, - picojson::object& out); - void AppMgrGetAppsContext(const picojson::value& args, - picojson::object& out); - void AppMgrGetAppContext(const picojson::value& args, picojson::object& out); - void AppMgrGetAppsInfo(const picojson::value& args, picojson::object& out); - void AppMgrGetAppInfo(const picojson::value& args, picojson::object& out); - void AppMgrGetAppCerts(const picojson::value& args, picojson::object& out); - void AppMgrGetAppSharedURI(const picojson::value& args, - picojson::object& out); - void AppMgrGetAppMetaData(const picojson::value& args, - picojson::object& out); - void AppMgrAddAppInfoEventListener(const picojson::value& args, - picojson::object& out); - void AppMgrRemoveAppInfoEventListener(const picojson::value& args, - picojson::object& out); - void AppGetRequestedAppControl(const picojson::value& args, - picojson::object& out); - void RequestedAppControlReplyResult(const picojson::value& args, - picojson::object& out); - void RequestedAppControlReplyFailure(const picojson::value& args, - picojson::object& out); - - ApplicationInformationPtr GetAppInfo(const std::string app_id); - static bool app_callback(package_info_app_component_type_e comp_type, - const char *app_id, void *user_data); - static int app_list_changed_cb(int id, const char *type, const char *package, - const char *key, const char *val, const void *msg, void *data); - void ReplyAppListChangedCallback(app_info_event_e event_type, - const char *pkg_id, void *user_data); - - int get_watch_id_and_increase(); - + void GetCurrentApplication(const picojson::value& args, picojson::object& out); + void GetAppContext(const picojson::value& args, picojson::object& out); + void GetAppInfo(const picojson::value& args, picojson::object& out); + void GetAppCerts(const picojson::value& args, picojson::object& out); + void GetAppSharedURI(const picojson::value& args, picojson::object& out); + void GetAppMetaData(const picojson::value& args, picojson::object& out); + void AddAppInfoEventListener(const picojson::value& args, picojson::object& out); + void RemoveAppInfoEventListener(const picojson::value& args, picojson::object& out); + void GetRequestedAppControl(const picojson::value& args, picojson::object& out); + void ReplyResult(const picojson::value& args, picojson::object& out); + void ReplyFailure(const picojson::value& args, picojson::object& out); + void GetSize(const picojson::value& args, picojson::object& out); + void Kill(const picojson::value& args, picojson::object& out); + void Launch(const picojson::value& args, picojson::object& out); + void LaunchAppControl(const picojson::value& args, picojson::object& out); + void FindAppControl(const picojson::value& args, picojson::object& out); + void GetAppsContext(const picojson::value& args, picojson::object& out); + void GetAppsInfo(const picojson::value& args, picojson::object& out); + + ApplicationManager manager_; + Application current_application_; std::string app_id_; - pkgmgr_client* manager_handle_; - std::vector callback_id_list_; - int watch_id_; - std::vector app_list_; - std::map reply_map_; }; } // namespace application diff --git a/src/application/application_manager.cc b/src/application/application_manager.cc new file mode 100644 index 00000000..bdc0c33e --- /dev/null +++ b/src/application/application_manager.cc @@ -0,0 +1,1304 @@ +// Copyright 2015 Samsung Electronics Co, Ltd. 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_manager.h" + +#include +#include + +#include +#include +#include +#include +#include + +#include "application/application_instance.h" +#include "application/application_utils.h" +#include "common/current_application.h" +#include "common/logger.h" +#include "common/platform_result.h" +#include "common/task-queue.h" + +using namespace common; +using namespace tools; + +namespace extension { +namespace application { + +namespace { +const std::string kTizenApisFileScheme = "file://"; +const std::string kTizenApisAppSlash = "/"; +const std::string kTizenApisAppShared = "shared"; + +const char* kStartKey = "start"; +const char* kEndKey = "end"; +const char* kOkValue = "ok"; +const char* kInstallEvent = "install"; +const char* kUpdateEvent = "update"; +const char* kUninstallEvent = "uninstall"; + +const std::string kAction = "action"; +const std::string kCallbackId = "callbackId"; +const std::string kOnInstalled = "oninstalled"; +const std::string kOnUpdated = "onupdated"; +const std::string kOnUninstalled = "onuninstalled"; +const std::string kData = "data"; +} + +ApplicationManager::ApplicationManager(ApplicationInstance& instance) : + instance_(instance), + pkgmgr_client_handle_(nullptr) { +} + +ApplicationManager::~ApplicationManager() { + if (pkgmgr_client_handle_) { + StopAppInfoEventListener(); + } +} + +void ApplicationManager::GetCurrentApplication(const std::string& app_id, + picojson::object* out) { + LoggerD("Entered"); + + // obtain handle to application info + pkgmgrinfo_appinfo_h handle; + int ret = pkgmgrinfo_appinfo_get_appinfo(app_id.c_str(), &handle); + if (PMINFO_R_OK != ret) { + LoggerE("Failed to get app info."); + ReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to get app info."), out); + return; + } + + picojson::value app_info = picojson::value(picojson::object()); + picojson::object& app_info_obj = app_info.get(); + + ApplicationUtils::CreateApplicationInformation(handle, &app_info_obj); + pkgmgrinfo_appinfo_destroy_appinfo(handle); + + picojson::value result = picojson::value(picojson::object()); + picojson::object& result_obj = result.get(); + + result_obj.insert(std::make_pair( + "contextId", picojson::value(std::to_string(CurrentApplication::GetInstance().GetProcessId())))); + result_obj.insert(std::make_pair("appInfo", app_info)); + + ReportSuccess(result, *out); +} + +class TerminateHandler { + public: + TerminateHandler(int callback_id, ApplicationInstance* app_instance) : + callback_handle_(callback_id), + app_instance_(app_instance), + pid_(-1), + timeout_id_(0) { + } + + void set_pid(pid_t pid) { + pid_ = pid; + } + + pid_t pid() const { + return pid_; + } + + void Invoke(const std::shared_ptr& response) { + LoggerD("Entered"); + + if (timeout_id_ > 0) { + // cancel terminate callback + g_source_remove(timeout_id_); + timeout_id_ = 0; + } + + ApplicationInstance* app_instance = this->app_instance_; + int callback_id = this->callback_handle_; + TaskQueue::GetInstance().Async([callback_id, app_instance]( + const std::shared_ptr& response) { + picojson::object& obj = response->get(); + obj.insert(std::make_pair(kCallbackId, picojson::value(static_cast(callback_id)))); + app_instance->PostMessage(response->serialize().c_str()); + }, response); + } + + void LaunchCheckTerminate() { + LoggerD("Entered"); + timeout_id_ = g_timeout_add(3000, CheckTerminate, this); + LoggerD("END"); + } + + private: + static gboolean CheckTerminate(gpointer user_data) { + LoggerD("Entered"); + TerminateHandler* that = static_cast(user_data); + LoggerD("PID: %d", that->pid_); + + // we're canceling the callback by returning false, no need for Invoke() to do that again + that->timeout_id_ = 0; + + char* app_id = nullptr; + std::shared_ptr response{new picojson::value(picojson::object())}; + + LoggerD("checking if application is still alive"); + if (app_manager_get_app_id(that->pid_, &app_id) == APP_MANAGER_ERROR_NONE) { + LoggerD("application is alive - failure"); + free(app_id); + // context is still alive, report error + ReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to kill application."), + &response->get()); + } else { + LoggerD("application is dead - success"); + ReportSuccess(response->get()); + } + + that->Invoke(response); + delete that; + + return false; + } + + int callback_handle_; + pid_t pid_; + guint timeout_id_; + ApplicationInstance* app_instance_; +}; + +#define CHECK_RESULT(result, response, handler) \ + if (result.IsError()) { \ + ReportError(result, &response->get()); \ + handler->Invoke(response); \ + delete handler; \ + return; \ + } + +void ApplicationManager::AsyncResponse(PlatformResult& result, + std::shared_ptr* response) { + + ReportError(result, &(*response)->get()); + + TaskQueue::GetInstance().Async([this]( + const std::shared_ptr& response) { + this->instance_.PostMessage(response->serialize().c_str()); + }, *response); +} + +void ApplicationManager::Kill(const picojson::value& args) { + LoggerD("Entered"); + + PlatformResult result = PlatformResult(ErrorCode::NO_ERROR); + + int callback_id = -1; + const auto& callback = args.get(kCallbackId); + if (callback.is()) { + callback_id = static_cast(callback.get()); + } + + const auto& context = args.get("contextId"); + if (!context.is()) { + LoggerE("Invalid parameter passed."); + result = PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter passed."); + } + + const std::string& context_id = context.get(); + + if (context_id.empty() && result.IsSuccess()) { + LoggerE("Context ID is empty."); + result = PlatformResult(ErrorCode::NOT_FOUND_ERR, "Context ID is empty."); + } + + std::shared_ptr response(new picojson::value(picojson::object())); + picojson::object& obj = response->get(); + obj.insert(std::make_pair(kCallbackId, picojson::value(static_cast(callback_id)))); + + if (result.IsError()) { + AsyncResponse(result, &response); + return; + } + + auto kill = [this, callback_id, context_id]() -> void { + LoggerD("Entered Kill async"); + + std::shared_ptr response = + std::shared_ptr(new picojson::value(picojson::object())); + + TerminateHandler* handler = new TerminateHandler(callback_id, &this->instance_); + PlatformResult result = PlatformResult(ErrorCode::NO_ERROR); + + pid_t pid = -1; + try { + pid = std::stoi(context_id); + } catch (...) { + LoggerE("Failed to convert string to int"); + result = PlatformResult(ErrorCode::NOT_FOUND_ERR, "Failed to convert string to int."); + CHECK_RESULT(result, response, handler) + } + + if (pid <= 0) { + LoggerE("Context ID cannot be negative value"); + result = PlatformResult(ErrorCode::NOT_FOUND_ERR, "Context ID cannot be negative value."); + CHECK_RESULT(result, response, handler) + } + + // if kill request comes for current context, throw InvalidValuesException + if (CurrentApplication::GetInstance().GetProcessId() == pid) { + LoggerE("Cannot kill current application."); + result = PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Cannot kill current application."); + CHECK_RESULT(result, response, handler) + } + + LoggerD("Kill async, pid: %d", pid); + + char* app_id = nullptr; + int ret = app_manager_get_app_id(pid, &app_id); + // automatically release the memory + std::unique_ptr app_id_ptr(app_id, &std::free); + + if (APP_MANAGER_ERROR_NONE != ret) { + LoggerE("Failed to get application ID, error: %d", ret); + result = PlatformResult(ErrorCode::NOT_FOUND_ERR, "Failed to get application ID."); + CHECK_RESULT(result, response, handler) + } + + LoggerD("Kill async, app ID: %s", app_id); + + // acquire application context + app_context_h app_context = nullptr; + + ret = app_manager_get_app_context(app_id, &app_context); + std::unique_ptr::type, int(*)(app_context_h)> + app_context_ptr(app_context, &app_context_destroy); // automatically release the memory + + if (APP_MANAGER_ERROR_NONE != ret) { + LoggerE("Failed to get application context handle"); + result = PlatformResult(ErrorCode::NOT_FOUND_ERR, "Failed to get application ID."); + CHECK_RESULT(result, response, handler) + } + + auto terminate_callback = [](app_context_h app_context, + app_context_event_e event, + void* user_data) { + LoggerD("terminate_callback: %d", event); + + if (APP_CONTEXT_EVENT_TERMINATED != event) { + LoggerD("ignoring event"); + return; + } + + int pid = 0; + int ret = app_context_get_pid(app_context, &pid); + + if (APP_MANAGER_ERROR_NONE != ret) { + LoggerE("Failed to get pid of terminated app (%d)", ret); + return; + } + + TerminateHandler* handler = static_cast(user_data); + + LoggerD("Expected PID: %d, got: %d", handler->pid(), pid); + + if (handler->pid() == pid) { + std::shared_ptr response = + std::shared_ptr(new picojson::value(picojson::object())); + ReportSuccess(response->get()); + handler->Invoke(response); + delete handler; + } + }; + + LoggerD("Kill async, setting callback"); + handler->set_pid(pid); + ret = app_manager_set_app_context_event_cb(terminate_callback, handler); + + if (APP_MANAGER_ERROR_NONE != ret) { + LoggerE("Error while registering app context event (%d)", ret); + result = PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to register termination callback."); + CHECK_RESULT(result, response, handler) + } + + // due to platform issue, sometimes termination event is not reported to callback + // registered with app_manager_set_app_context_event_cb() + // this is a workaround, it should be removed when issue is solved + handler->LaunchCheckTerminate(); + + LoggerD("Kill async, KILL!!!!!!!!!"); + + // terminate application + ret = app_manager_terminate_app(app_context); + + if (APP_MANAGER_ERROR_NONE != ret) { + LoggerE("Failed to terminate application."); + result = PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to terminate application."); + CHECK_RESULT(result, response, handler) + } + + LoggerD("Kill async, end, waiting for notification"); + }; + + TaskQueue::GetInstance().Queue(kill); +} + +void ApplicationManager::Launch(const picojson::value& args) { + LoggerD("Entered"); + + int callback_id = -1; + const auto& callback = args.get(kCallbackId); + if (callback.is()) { + callback_id = static_cast(callback.get()); + } + + std::shared_ptr response(new picojson::value(picojson::object())); + picojson::object& obj = response->get(); + obj.insert(std::make_pair(kCallbackId, picojson::value(static_cast(callback_id)))); + + const auto& app_id = args.get("id"); + if (!app_id.is()) { + LoggerE("Invalid parameter passed."); + PlatformResult ret = PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter passed."); + AsyncResponse(ret, &response); + return; + } + const std::string& id = app_id.get(); + + auto launch = [id](const std::shared_ptr& response) -> void { + PlatformResult result = PlatformResult(ErrorCode::NO_ERROR); + const char* app_id = id.c_str(); + const int retry_count = 3; + + int retry = 0; + int ret = 0; + + while (retry < retry_count) { + ret = aul_open_app(app_id); + + if (ret >= 0) { + break; + } + + // delay 300ms for each retry + usleep(300 * 1000); + ++retry; + + LoggerD("Retry launch request: %d", retry); + } + + if (ret < 0) { + result = PlatformResult(ErrorCode::UNKNOWN_ERR, "Unknown error has occurred."); + + switch (ret) { + case AUL_R_EINVAL: + case AUL_R_ERROR: + LoggerE("aul_open_app returns Not Found error"); + result = PlatformResult(ErrorCode::NOT_FOUND_ERR, "Launchpad returns not found error."); + break; + + case AUL_R_ECOMM: + LoggerE("aul_open_app returns internal IPC error"); + result = PlatformResult(ErrorCode::UNKNOWN_ERR, "Internal IPC error has occurred."); + break; + } + + ReportError(result, &response->get()); + } else { + LoggerD("Launch request success"); + ReportSuccess(response->get()); + } + }; + + auto launch_response = [this](const std::shared_ptr& response) -> void { + this->instance_.PostMessage(response->serialize().c_str()); + }; + + TaskQueue::GetInstance().Queue(launch, launch_response, response); +} + +void ApplicationManager::LaunchAppControl(const picojson::value& args) { + LoggerD("Entered"); + + int callback_id = -1; + const auto& callback = args.get(kCallbackId); + if (callback.is()) { + callback_id = static_cast(callback.get()); + } + + std::shared_ptr response(new picojson::value(picojson::object())); + picojson::object& response_obj = response->get(); + response_obj.insert( + std::make_pair(kCallbackId, picojson::value(static_cast(callback_id)))); + + PlatformResult result = PlatformResult(ErrorCode::NO_ERROR); + const auto& control = args.get("appControl"); + if (!control.is()) { + LoggerE("Invalid parameter passed."); + result = PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter passed."); + AsyncResponse(result, &response); + return; + } + const picojson::object& app_control_obj = control.get(); + + std::string launch_mode_str; + const auto& launch_mode = args.get("launchMode"); + if (launch_mode.is()) { + launch_mode_str = launch_mode.get(); + } + + app_control_h app_control; + result = ApplicationUtils::ApplicationControlToService(app_control_obj, &app_control); + std::shared_ptr::type> + app_control_ptr(app_control, &app_control_destroy); // automatically release the memory + + if (result.IsError()) { + LoggerE("Application control to service failed."); + AsyncResponse(result, &response); + return; + } + + std::string app_id; + const auto& id = args.get("id"); + if (id.is()) { + app_id = id.get(); + } + + std::string reply_callback; + const auto& reply = args.get("replyCallback"); + if (reply.is()) { + reply_callback = reply.get(); + } + + auto launch = [this, app_control_ptr, app_id, launch_mode_str, reply_callback]( + const std::shared_ptr& response) -> void { + LoggerD("Entered"); + + if (!app_id.empty()) { + LoggerD("app_id: %s", app_id.c_str()); + + app_control_set_app_id(app_control_ptr.get(), app_id.c_str()); + + char* resolved_app_id = nullptr; + + // application ID can be aliased, read it again to get the real value + app_control_get_app_id(app_control_ptr.get(), &resolved_app_id); + // automatically release the memory + std::unique_ptr resolved_app_id_ptr(resolved_app_id, std::free); + + // Check if application exists + app_info_h info_h = nullptr; + + int ret = app_manager_get_app_info(resolved_app_id, &info_h); + std::unique_ptr::type, int(*)(app_info_h)> + info_h_ptr(info_h, &app_info_destroy); // automatically release the memory + + if (APP_MANAGER_ERROR_NONE != ret) { + LoggerE("Specified application does not exist"); + ReportError(PlatformResult(ErrorCode::NOT_FOUND_ERR, "No matched application found."), + &response->get()); + return; + } + } + + if (!launch_mode_str.empty()) { + app_control_launch_mode_e launch_mode; + + if ("SINGLE" == launch_mode_str) { + launch_mode = APP_CONTROL_LAUNCH_MODE_SINGLE; + } else if ("GROUP" == launch_mode_str) { + launch_mode = APP_CONTROL_LAUNCH_MODE_GROUP; + } else { + LoggerE("Invalid parameter passed."); + ReportError(PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter passed."), + &response->get()); + return; + } + + int ret = app_control_set_launch_mode(app_control_ptr.get(), launch_mode); + if (APP_CONTROL_ERROR_NONE != ret) { + LoggerE("Setting launch mode failed."); + ReportError(PlatformResult(ErrorCode::NOT_FOUND_ERR, "Setting launch mode failed."), + &response->get()); + return; + } + } + + app_control_reply_cb callback = nullptr; + struct ReplayCallbackData { + ApplicationInstance* app_instance; + std::string reply_callback; + }; + + ReplayCallbackData* user_data = nullptr; + + if (!reply_callback.empty()) { + user_data = new ReplayCallbackData(); + user_data->app_instance = &this->instance_; + user_data->reply_callback = reply_callback; + + callback = [](app_control_h request, + app_control_h reply, app_control_result_e result, void* user_data) { + LoggerD("send_launch_request callback"); + + picojson::value return_value = picojson::value(picojson::object()); + picojson::object& return_value_obj = return_value.get(); + ReplayCallbackData* reply_callback = static_cast(user_data); + + if (APP_CONTROL_RESULT_SUCCEEDED == result) { + const std::string data = "data"; + return_value_obj.insert(std::make_pair(data, picojson::value(picojson::array()))); + if (!ApplicationUtils::ServiceToApplicationControlDataArray( + reply, &return_value_obj.find(data)->second.get())) { + return_value_obj.erase(data); + } + ReportSuccess(return_value_obj); + } else { + ReportError(return_value_obj); + } + + return_value_obj.insert( + std::make_pair("listenerId", picojson::value(reply_callback->reply_callback))); + reply_callback->app_instance->PostMessage(return_value.serialize().c_str()); + delete reply_callback; + }; + } + + const int retry_count = 3; + + int retry = 0; + int ret = 0; + + while (retry < retry_count) { + ret = app_control_send_launch_request(app_control_ptr.get(), callback, user_data); + + if (APP_CONTROL_ERROR_NONE == ret) { + break; + } + + // delay 300ms for each retry + usleep(300 * 1000); + ++retry; + + LoggerD("Retry launch request: %d", retry); + } + + if (APP_CONTROL_ERROR_NONE != ret) { + delete user_data; + + switch (ret) { + case APP_CONTROL_ERROR_INVALID_PARAMETER: + LoggerE("app_control_send_launch_request returns APP_CONTROL_ERROR_INVALID_PARAMETER"); + ReportError(PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter returned."), + &response->get()); + return; + case APP_CONTROL_ERROR_OUT_OF_MEMORY: + LoggerE("app_control_send_launch_request returns APP_CONTROL_ERROR_OUT_OF_MEMORY"); + ReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Out of memory."), + &response->get()); + return; + case APP_CONTROL_ERROR_LAUNCH_REJECTED: + case APP_CONTROL_ERROR_APP_NOT_FOUND: + LoggerE("app_control_send_launch_request returns APP_CONTROL_ERROR_APP_NOT_FOUND"); + ReportError(PlatformResult(ErrorCode::NOT_FOUND_ERR, "No matched application found."), + &response->get()); + return; + default: + LoggerE("app_control_send_launch_request returns UNKNOWN ERROR!!!"); + throw UnknownException("Unknown error"); + ReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Unknown error."), + &response->get()); + return; + } + } + + ReportSuccess(response->get()); + }; + + auto launch_response = [this](const std::shared_ptr& response) -> void { + this->instance_.PostMessage(response->serialize().c_str()); + }; + + TaskQueue::GetInstance().Queue(launch, launch_response, response); +} + +void ApplicationManager::FindAppControl(const picojson::value& args) { + LoggerD("Entered"); + + int callback_id = -1; + const auto& callback = args.get(kCallbackId); + if (callback.is()) { + callback_id = static_cast(callback.get()); + } + + std::shared_ptr response(new picojson::value(picojson::object())); + picojson::object& response_obj = response->get(); + response_obj.insert( + std::make_pair(kCallbackId, picojson::value(static_cast(callback_id)))); + + PlatformResult result = PlatformResult(ErrorCode::NO_ERROR); + const auto& control = args.get("appControl"); + if (!control.is()) { + LoggerE("Invalid parameter passed."); + result = PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter passed."); + AsyncResponse(result, &response); + return; + } + + const picojson::object& app_control_obj = control.get(); + + app_control_h app_control; + result = ApplicationUtils::ApplicationControlToService(app_control_obj, &app_control); + std::shared_ptr::type> + app_control_ptr(app_control, &app_control_destroy); // automatically release the memory + + auto find = [app_control_ptr](const std::shared_ptr& response) -> void { + auto app_control_matched = [](app_control_h app_control, const char* appid, void* user_data) -> bool { + if (nullptr == appid) { + LoggerD("appid is NULL"); + return false; + } + + pkgmgrinfo_appinfo_h handle; + int ret = pkgmgrinfo_appinfo_get_appinfo(appid, &handle); + if (PMINFO_R_OK != ret) { + LoggerE("Failed to get appInfo"); + } else { + picojson::array* array = static_cast(user_data); + array->push_back(picojson::value(picojson::object())); + + ApplicationUtils::CreateApplicationInformation(handle, &array->back().get()); + pkgmgrinfo_appinfo_destroy_appinfo(handle); + } + + return true; + }; + + picojson::object& response_obj = response->get(); + auto it_result = response_obj.find("result"); + picojson::object& result_obj = it_result->second.get(); + auto array = result_obj.insert( + std::make_pair("informationArray", picojson::value(picojson::array()))); + + int ret = app_control_foreach_app_matched( + app_control_ptr.get(), app_control_matched, &array.first->second.get()); + + if (APP_CONTROL_ERROR_NONE != ret) { + LoggerE("app_control_foreach_app_matched error: %d", ret); + + ReportError(PlatformResult(ErrorCode::UNKNOWN_ERR,"Unknown error"), &response_obj); + // remove copied ApplicationControl from result + response_obj.erase(it_result); + } else { + ReportSuccess(response_obj); + } + }; + + auto find_response = [this](const std::shared_ptr& response) -> void { + this->instance_.PostMessage(response->serialize().c_str()); + }; + + // prepare result object, we need to do that here, as input parameter is passed to result callback + auto ret = response_obj.insert(std::make_pair("result", picojson::value(picojson::object()))); + // reinsert application control + ret.first->second.get().insert(std::make_pair("appControl", args.get("appControl"))); + + TaskQueue::GetInstance().Queue(find, find_response, response); +} + +void ApplicationManager::GetAppsContext(const picojson::value& args) { + LoggerD("Entered"); + + int callback_id = -1; + const auto& callback = args.get(kCallbackId); + if (callback.is()) { + callback_id = static_cast(callback.get()); + } + + auto get_apps_context = [](const std::shared_ptr& response) -> void { + picojson::object& response_obj = response->get(); + picojson::value result = picojson::value(picojson::object()); + picojson::object& result_obj = result.get(); + picojson::array& array = + result_obj.insert(std::make_pair("contexts", picojson::value( + picojson::array()))).first->second.get(); + + auto app_context_cb = [](app_context_h app_context, void* user_data) -> bool { + if (nullptr == user_data) { + return false; + } + + picojson::array* array = static_cast(user_data); + array->push_back(picojson::value(picojson::object())); + + if (!ApplicationUtils::CreateApplicationContext( + app_context, &array->back().get())) { + array->pop_back(); + return false; + } + + return true; + }; + + int ret = app_manager_foreach_app_context(app_context_cb, &array); + + if (APP_MANAGER_ERROR_NONE != ret) { + LoggerE("app_manager_foreach_app_context error"); + ReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Unknown error."), &response_obj); + } else { + ReportSuccess(result, response_obj); + } + }; + + auto get_apps_context_response = [this, callback_id]( + const std::shared_ptr& response) -> void { + picojson::object& obj = response->get(); + obj.insert(std::make_pair(kCallbackId, picojson::value(static_cast(callback_id)))); + this->instance_.PostMessage(response->serialize().c_str()); + }; + + TaskQueue::GetInstance().Queue( + get_apps_context, + get_apps_context_response, + std::shared_ptr(new picojson::value(picojson::object()))); +} + +void ApplicationManager::GetAppContext(const picojson::value& args, picojson::object* out) { + LoggerD("Entered"); + pid_t pid = 0; + + const auto& context_id = args.get("contextId"); + if (context_id.is()) { + try { + pid = std::stoi(context_id.get()); + } catch(...) { + LoggerE("Failed to convert context id."); + ReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to convert context id."), out); + return; + } + } else { + pid = CurrentApplication::GetInstance().GetProcessId(); + } + + char* app_id = nullptr; + + int ret = app_manager_get_app_id(pid, &app_id); + // automatically release the memory + std::unique_ptr app_id_ptr(app_id, &std::free); + + if (APP_MANAGER_ERROR_NONE != ret || nullptr == app_id) { + switch(ret) { + case APP_MANAGER_ERROR_NO_SUCH_APP: + LoggerE("app_manager_get_app_id returned: APP_MANAGER_ERROR_NO_SUCH_APP"); + ReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "No such application exist."), out); + return; + + case APP_MANAGER_ERROR_INVALID_PARAMETER: + LoggerE("app_manager_get_app_id returned: APP_MANAGER_ERROR_INVALID_PARAMETER"); + ReportError(PlatformResult(ErrorCode::NOT_FOUND_ERR, "Application not found."), out); + return; + + default: + LoggerE("app_manager_get_app_id returned: %d", ret); + ReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Unknown error."), out); + return; + } + } + + picojson::value result = picojson::value(picojson::object()); + ApplicationUtils::CreateApplicationContext(pid, app_id, &result.get()); + + ReportSuccess(result, *out); +} + +void ApplicationManager::GetAppsInfo(const picojson::value& args) { + LoggerD("Entered"); + + int callback_id = -1; + const auto& callback = args.get(kCallbackId); + if (callback.is()) { + callback_id = static_cast(callback.get()); + } + + auto get_apps_info = [](const std::shared_ptr& response) -> void { + picojson::object& response_obj = response->get(); + picojson::value result = picojson::value(picojson::object()); + picojson::object& result_obj = result.get(); + picojson::array& array = + result_obj.insert(std::make_pair("informationArray", picojson::value( + picojson::array()))).first->second.get(); + + auto app_info_cb = [](pkgmgrinfo_appinfo_h handle, void* user_data) -> int { + if (nullptr == user_data) { + return -1; + } + + picojson::array* array = static_cast(user_data); + array->push_back(picojson::value(picojson::object())); + + ApplicationUtils::CreateApplicationInformation(handle, &array->back().get()); + + return 0; + }; + + int ret = pkgmgrinfo_appinfo_get_installed_list(app_info_cb, &array); + + if (APP_MANAGER_ERROR_NONE != ret) { + LoggerE("pkgmgrinfo_appinfo_get_installed_list error"); + ReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Unknown error."), &response_obj); + } else { + ReportSuccess(result, response_obj); + } + }; + + auto get_apps_info_response = [this, callback_id]( + const std::shared_ptr& response) -> void { + picojson::object& obj = response->get(); + obj.insert(std::make_pair(kCallbackId, picojson::value(static_cast(callback_id)))); + this->instance_.PostMessage(response->serialize().c_str()); + }; + + TaskQueue::GetInstance().Queue( + get_apps_info, + get_apps_info_response, + std::shared_ptr(new picojson::value(picojson::object()))); +} + +void ApplicationManager::GetAppInfo(const std::string& app_id, picojson::object* out) { + LoggerD("Entered"); + + pkgmgrinfo_appinfo_h handle = nullptr; + + if (PMINFO_R_OK != pkgmgrinfo_appinfo_get_appinfo(app_id.c_str(), &handle)) { + LoggerE("Failed to get app info"); + ReportError(PlatformResult(ErrorCode::NOT_FOUND_ERR, "Failed to get app info."), out); + return; + } + + picojson::value result = picojson::value(picojson::object()); + ApplicationUtils::CreateApplicationInformation(handle, &result.get()); + pkgmgrinfo_appinfo_destroy_appinfo(handle); + + ReportSuccess(result, *out); +} + +char* ApplicationManager::GetPackageId(const std::string& app_id) { + app_info_h handle; + char* pkg_id = nullptr; + + int ret = app_manager_get_app_info(app_id.c_str(), &handle); + if (APP_MANAGER_ERROR_NONE != ret) { + LoggerE("Failed to get app info."); + return nullptr; + } + + ret = app_info_get_package(handle, &pkg_id); + if (APP_MANAGER_ERROR_NONE != ret) { + LoggerE("Failed to get package id."); + pkg_id = nullptr; + } + + ret = app_info_destroy(handle); + if (APP_MANAGER_ERROR_NONE != ret) { + LoggerE("Failed to destroy app info."); + } + + return pkg_id; +} + +void ApplicationManager::GetAppCerts(const std::string& app_id, picojson::object* out) { + LoggerD("Entered"); + + char* package_id = nullptr; + + package_id = GetPackageId(app_id); + // automatically release the memory + std::unique_ptr package_id_ptr(package_id, &std::free); + + if (!package_id) { + LoggerE("Failed to get package."); + ReportError(PlatformResult(ErrorCode::NOT_FOUND_ERR, "Failed to get package."), out); + return; + } + + package_info_h pkg_info = nullptr; + int ret = package_info_create(package_id, &pkg_info); + + std::unique_ptr::type, int(*)(package_info_h)> + pkg_info_ptr(pkg_info, &package_info_destroy); // automatically release the memory + + if (PACKAGE_MANAGER_ERROR_NONE != ret) { + LoggerE("Failed to get package info."); + ReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to get package info."), out); + return; + } + + auto cert_info_cb = [](package_info_h handle, package_cert_type_e cert_type, + const char* cert_value, void* user_data) -> bool { + const char* cert_name = nullptr; + + switch(cert_type) { + case PACKAGE_INFO_AUTHOR_ROOT_CERT: + cert_name = "AUTHOR_ROOT"; + break; + case PACKAGE_INFO_AUTHOR_INTERMEDIATE_CERT: + cert_name = "AUTHOR_INTERMEDIATE"; + break; + case PACKAGE_INFO_AUTHOR_SIGNER_CERT: + cert_name = "AUTHOR_SIGNER"; + break; + case PACKAGE_INFO_DISTRIBUTOR_ROOT_CERT: + cert_name = "DISTRIBUTOR_ROOT"; + break; + case PACKAGE_INFO_DISTRIBUTOR_INTERMEDIATE_CERT: + cert_name = "DISTRIBUTOR_INTERMEDIATE"; + break; + case PACKAGE_INFO_DISTRIBUTOR_SIGNER_CERT: + cert_name = "DISTRIBUTOR_SIGNER"; + break; + case PACKAGE_INFO_DISTRIBUTOR2_ROOT_CERT: + cert_name = "DISTRIBUTOR2_ROOT"; + break; + case PACKAGE_INFO_DISTRIBUTOR2_INTERMEDIATE_CERT: + cert_name = "DISTRIBUTOR2_INTERMEDIATE"; + break; + case PACKAGE_INFO_DISTRIBUTOR2_SIGNER_CERT: + cert_name = "DISTRIBUTOR2_SIGNER"; + break; + default: + LoggerD("Unknown certificate type: %d", cert_type); + break; + } + + picojson::array* array = static_cast(user_data); + array->push_back(picojson::value(picojson::object())); + + ApplicationUtils::CreateApplicationCertificate( + cert_name, cert_value, &array->back().get()); + + return true; + }; + + picojson::value result = picojson::value(picojson::array()); + + ret = package_info_foreach_cert_info(pkg_info, cert_info_cb, &result.get()); + + if ((PACKAGE_MANAGER_ERROR_NONE != ret) && (PACKAGE_MANAGER_ERROR_IO_ERROR != ret)) { + LoggerE("Failed to get certificates info."); + ReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to get certificates info."), out); + return; + } + + ReportSuccess(result, *out); +} + +void ApplicationManager::GetAppSharedUri(const std::string& app_id, picojson::object* out) { + LoggerD("Entered"); + + char* package_id = nullptr; + + package_id = GetPackageId(app_id); + // automatically release the memory + std::unique_ptr package_id_ptr(package_id, &std::free); + + if (!package_id) { + LoggerE("Failed to get package."); + ReportError(PlatformResult(ErrorCode::NOT_FOUND_ERR, "Failed to get package."), out); + return; + } + + pkgmgrinfo_pkginfo_h pkg_info = nullptr; + + int ret = pkgmgrinfo_pkginfo_get_pkginfo(package_id, &pkg_info); + std::unique_ptr::type, int(*)(pkgmgrinfo_pkginfo_h)> + pkg_info_ptr(pkg_info, &pkgmgrinfo_pkginfo_destroy_pkginfo); // automatically release the memory + + if (PMINFO_R_OK != ret) { + LoggerE("Failed to get package info."); + ReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to get package info."), out); + return; + } + + char* root_path = nullptr; + ret = pkgmgrinfo_pkginfo_get_root_path(pkg_info, &root_path); + + if (PMINFO_R_OK != ret || nullptr == root_path) { + LoggerE("Failed to get root path."); + ReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to get root path."), out); + return; + } + + picojson::value result = picojson::value(kTizenApisFileScheme + + root_path + + kTizenApisAppSlash + + kTizenApisAppShared + + kTizenApisAppSlash); + ReportSuccess(result, *out); +} + +void ApplicationManager::GetAppMetaData(const std::string& app_id, picojson::object* out) { + LoggerD("Entered"); + + pkgmgrinfo_appinfo_h handle = nullptr; + + int ret = pkgmgrinfo_appinfo_get_appinfo(app_id.c_str(), &handle); + std::unique_ptr::type, int(*)(pkgmgrinfo_appinfo_h)> + pkg_info_ptr(handle, &pkgmgrinfo_appinfo_destroy_appinfo); // automatically release the memory + + if (PMINFO_R_OK != ret) { + LoggerE("Failed to get app info."); + ReportError(PlatformResult(ErrorCode::NOT_FOUND_ERR, "Failed to get app info."), out); + return; + } + + auto meta_data_cb = [](const char* meta_key, const char* meta_value, void* user_data) -> int { + if (nullptr == meta_key || nullptr == meta_value) { + LoggerE("meta_key or meta_value is null"); + return 0; + } + + picojson::array* array = static_cast(user_data); + array->push_back(picojson::value(picojson::object())); + + ApplicationUtils::CreateApplicationMetaData(meta_key, meta_value, + &array->back().get()); + return 0; + }; + + picojson::value result = picojson::value(picojson::array()); + ret = pkgmgrinfo_appinfo_foreach_metadata(handle, meta_data_cb, &result.get()); + + if (PMINFO_R_OK != ret) { + LoggerE("Failed to get metadata."); + ReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to get metadata."), out); + return; + } + + ReportSuccess(result, *out); +} + +class ApplicationListChangedBroker { + public: + enum class Event { + kInstalled, + kUpdated, + kUninstalled, + }; + + static int ClientStatusListener(int id, const char* type, const char* package, const char* key, + const char* val, const void* msg, void* data) { + LoggerD("Entered"); + ApplicationListChangedBroker* that = static_cast(data); + + if (0 == strcasecmp(key, kStartKey)) { + that->HandleStart(val, package); + } else if (0 == strcasecmp(key, kEndKey) && 0 == strcasecmp(val, kOkValue)) { + that->HandleEnd(package); + } else { + LoggerD("Ignored key: %s", key); + } + + return 0; + } + + void AddApplicationInstance(ApplicationInstance* app_instance) { + LoggerD("Entered"); + app_instance_list_.push_back(app_instance); + } + + void RemoveApplicationInstance(ApplicationInstance* app_instance) { + LoggerD("Entered"); + for (auto it = app_instance_list_.begin(); it != app_instance_list_.end(); it++) { + if (*it == app_instance) { + app_instance_list_.erase(it); + return; + } + } + } + + private: + void HandleStart(const char* event_type, const char* package) { + LoggerD("Entered"); + app_list_.clear(); + set_event_type(event_type); + + if (Event::kUninstalled == event_type_) { + // we need to get information about application ID before it is uninstalled + GetApplicationIdsFromPackage(package); + } + } + + void HandleEnd(const char* package) { + LoggerD("Entered"); + + if (Event::kUninstalled != event_type_) { + GetApplicationIdsFromPackage(package); + } + + for (auto& app_id : app_list_) { + picojson::value value = picojson::value(picojson::object()); + picojson::object& data_obj = value.get(); + + switch (event_type_) { + case Event::kInstalled: + data_obj.insert(std::make_pair(kAction, picojson::value(kOnInstalled))); + break; + + case Event::kUpdated: + data_obj.insert(std::make_pair(kAction, picojson::value(kOnUpdated))); + break; + + case Event::kUninstalled: + data_obj.insert(std::make_pair(kAction, picojson::value(kOnUninstalled))); + break; + } + + switch (event_type_) { + case Event::kInstalled: + case Event::kUpdated: + { + pkgmgrinfo_appinfo_h handle = nullptr; + if (PMINFO_R_OK != pkgmgrinfo_appinfo_get_appinfo(app_id.c_str(), &handle)) { + LoggerE("Failed to get application information handle."); + continue; + } + auto info = data_obj.insert(std::make_pair(kData, picojson::value(picojson::object()))); + ApplicationUtils::CreateApplicationInformation( + handle, &info.first->second.get()); + pkgmgrinfo_appinfo_destroy_appinfo(handle); + } + break; + + case Event::kUninstalled: + data_obj.insert(std::make_pair(kData, picojson::value(app_id))); + break; + } + + data_obj["listenerId"] = picojson::value("ApplicationEventListener"); + + for (auto instance : app_instance_list_) { + instance->PostMessage(value.serialize().c_str()); + } + } + } + + void GetApplicationIdsFromPackage(const char* package) { + LoggerD("Entered"); + package_info_h package_info = nullptr; + + int ret = package_manager_get_package_info(package, &package_info); + if (PACKAGE_MANAGER_ERROR_NONE != ret) { + LoggerE("Failed to create package info"); + return; + } + + ret = package_info_foreach_app_from_package(package_info, + PACKAGE_INFO_ALLAPP, + ApplicationIdCallback, + this); + if (PACKAGE_MANAGER_ERROR_NONE != ret) { + LoggerE("Failed to get application IDs"); + } + + ret = package_info_destroy(package_info); + if (PACKAGE_MANAGER_ERROR_NONE != ret) { + LoggerE("Failed to destroy package info"); + } + } + + void set_event_type(const char* type) { + LoggerD("Entered"); + if (0 == strcasecmp(type, kInstallEvent)) { + event_type_ = Event::kInstalled; + } else if (0 == strcasecmp(type, kUpdateEvent)) { + event_type_ = Event::kUpdated; + } else if (0 == strcasecmp(type, kUninstallEvent)) { + event_type_ = Event::kUninstalled; + } + } + + static bool ApplicationIdCallback(package_info_app_component_type_e comp_type, + const char* app_id, void* user_data) { + LoggerD("Entered"); + if (nullptr != app_id) { + static_cast(user_data)->app_list_.push_back(app_id); + } + return true; + } + + Event event_type_; + std::vector app_list_; + std::vector app_instance_list_; +}; + +static ApplicationListChangedBroker g_application_list_changed_broker; + +void ApplicationManager::StartAppInfoEventListener(picojson::object* out) { + LoggerD("Entered"); + + if (nullptr == pkgmgr_client_handle_) { + pkgmgr_client_handle_ = pkgmgr_client_new(PC_LISTENING); + + if (nullptr == pkgmgr_client_handle_) { + LoggerE("Failed to register listener."); + ReportError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to register listener."), out); + return; + } + + g_application_list_changed_broker.AddApplicationInstance(&instance_); + pkgmgr_client_listen_status(pkgmgr_client_handle_, + ApplicationListChangedBroker::ClientStatusListener, + &g_application_list_changed_broker); + } else { + LoggerD("Broker callback is already registered."); + } + + ReportSuccess(*out); +} + +void ApplicationManager::StopAppInfoEventListener() { + LoggerD("Entered"); + + if (nullptr != pkgmgr_client_handle_) { + pkgmgr_client_free(pkgmgr_client_handle_); + pkgmgr_client_handle_ = nullptr; + g_application_list_changed_broker.RemoveApplicationInstance(&instance_); + } else { + LoggerD("Broker callback is already unregistered."); + } +} + +void ApplicationManager::GetApplicationInformationSize(const picojson::value& args, + picojson::object* out) { + LoggerD("Entered"); + + const auto& package_id = args.get("packageId"); + if (!package_id.is()) { + LoggerE("Invalid parameter passed."); + ReportError(PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter passed."), out); + return; + } + + const std::string& package_id_str = package_id.get(); + + // get installed size from package server (to solve smack issue) + pkgmgr_client* pc = pkgmgr_client_new(PC_REQUEST); + int size = -1; + + if (nullptr == pc) { + LoggerE("Failed to create pkgmgr client"); + } else { + size = pkgmgr_client_request_service(PM_REQUEST_GET_SIZE, PM_GET_TOTAL_SIZE, pc, NULL, + package_id_str.c_str(), NULL, NULL, NULL); + + if (size < 0) { + LoggerE("Failed to get installed size"); + } + + pkgmgr_client_free(pc); + } + + picojson::value result = picojson::value(picojson::object()); + picojson::object& result_obj = result.get(); + result_obj.insert(std::make_pair("size", picojson::value(static_cast(size)))); + + ReportSuccess(result, *out); +} + +} // namespace application +} // namespace extension diff --git a/src/application/application_manager.h b/src/application/application_manager.h new file mode 100644 index 00000000..0e4e33f1 --- /dev/null +++ b/src/application/application_manager.h @@ -0,0 +1,53 @@ +// Copyright 2015 Samsung Electronics Co, Ltd. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef SRC_APPLICATION_APPLICATION_MANAGER_H__ +#define SRC_APPLICATION_APPLICATION_MANAGER_H__ + +#include +#include + +#include + +#include "common/picojson.h" +#include "common/platform_result.h" + +namespace extension { +namespace application { + +class ApplicationInstance; + +class ApplicationManager { + public: + explicit ApplicationManager(ApplicationInstance& instance); + ~ApplicationManager(); + + void GetCurrentApplication(const std::string& app_id, picojson::object* out); + void Kill(const picojson::value& args); + void Launch(const picojson::value& args); + void LaunchAppControl(const picojson::value& args); + void FindAppControl(const picojson::value& args); + void GetAppsContext(const picojson::value& args); + void GetAppContext(const picojson::value& args, picojson::object* out); + void GetAppsInfo(const picojson::value& args); + void GetAppInfo(const std::string& app_id, picojson::object* out); + void GetAppCerts(const std::string& app_id, picojson::object* out); + void GetAppSharedUri(const std::string& app_id, picojson::object* out); + void GetAppMetaData(const std::string& app_id, picojson::object* out); + void StartAppInfoEventListener(picojson::object* out); + void StopAppInfoEventListener(); + void GetApplicationInformationSize(const picojson::value& args, picojson::object* out); + void AsyncResponse(common::PlatformResult& result, std::shared_ptr* response); + + private: + char* GetPackageId(const std::string& app_id); + + pkgmgr_client* pkgmgr_client_handle_; + ApplicationInstance& instance_; +}; + +} // namespace application +} // namespace extension + +#endif // SRC_APPLICATION_APPLICATION_MANAGER_H__ diff --git a/src/application/application_metadata.cc b/src/application/application_metadata.cc deleted file mode 100644 index 4014bf7c..00000000 --- a/src/application/application_metadata.cc +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright 2014 Samsung Electronics Co, Ltd. 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_metadata.h" - -#include - -#include "common/logger.h" -#include "tizen/tizen.h" - -namespace extension { -namespace application { - -ApplicationMetaData::ApplicationMetaData() { -} - -ApplicationMetaData::~ApplicationMetaData() { -} - -const picojson::value& ApplicationMetaData::Value() { - if (value_.is() && IsValid()) { - picojson::object obj; - obj["key"] = picojson::value(meta_key_); - obj["value"] = picojson::value(meta_value_); - value_ = picojson::value(obj); - } - return value_; -} - -bool ApplicationMetaData::IsValid() const { - return error_.empty(); -} - -std::string ApplicationMetaData::get_meta_key() const { - return meta_key_; -} - -void ApplicationMetaData::set_meta_key(const std::string& meta_key) { - meta_key_ = meta_key; -} - -std::string ApplicationMetaData::get_meta_value() const { - return meta_value_; -} - -void ApplicationMetaData::set_meta_value(const std::string& meta_value) { - meta_value_ = meta_value; -} - -} // namespace application -} // namespace extension diff --git a/src/application/application_metadata.h b/src/application/application_metadata.h deleted file mode 100644 index 53920b5c..00000000 --- a/src/application/application_metadata.h +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright 2014 Samsung Electronics Co, Ltd. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef SRC_APPLICATION_APPLICATION_METADATA_H_ -#define SRC_APPLICATION_APPLICATION_METADATA_H_ - -#include -#include -#include - -#include "common/picojson.h" -#include "tizen/tizen.h" - -namespace extension { -namespace application { - -class ApplicationMetaData; -typedef std::shared_ptr ApplicationMetaDataPtr; - -typedef std::vector ApplicationMetaDataArray; -typedef std::shared_ptr ApplicationMetaDataArrayPtr; - -class ApplicationMetaData { - public: - ApplicationMetaData(); - ~ApplicationMetaData(); - - const picojson::value& Value(); - bool IsValid() const; - - std::string get_meta_key() const; - void set_meta_key(const std::string& meta_key); - - std::string get_meta_value() const; - void set_meta_value(const std::string& meta_value); - - private: - std::string meta_key_; - std::string meta_value_; - - picojson::object data_; - picojson::object error_; - picojson::value value_; -}; - -} // namespace application -} // namespace extension - -#endif // SRC_APPLICATION_APPLICATION_METADATA_H_ diff --git a/src/application/application_utils.cc b/src/application/application_utils.cc new file mode 100644 index 00000000..8d8e14df --- /dev/null +++ b/src/application/application_utils.cc @@ -0,0 +1,376 @@ +// Copyright 2015 Samsung Electronics Co, Ltd. 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_utils.h" + +#include + +#include + +#include "common/logger.h" +#include "common/platform_result.h" + +using namespace common; + +namespace extension { +namespace application { + +void ApplicationUtils::CreateApplicationInformation(const pkgmgrinfo_appinfo_h handle, + picojson::object* app_info) { + + char* tmp_str = nullptr; + int ret = 0; + + // application ID + ret = pkgmgrinfo_appinfo_get_appid(handle, &tmp_str); + if ((PMINFO_R_OK != ret) || (nullptr == tmp_str)) { + LoggerE("Failed to get appid"); + } else { + app_info->insert(std::make_pair("id", picojson::value(tmp_str))); + } + tmp_str = nullptr; + + // name + ret = pkgmgrinfo_appinfo_get_label(handle, &tmp_str); + if ((PMINFO_R_OK != ret) || (nullptr == tmp_str)) { + LoggerE("Failed to get label"); + } else { + app_info->insert(std::make_pair("name", picojson::value(tmp_str))); + } + tmp_str = nullptr; + + // icon path + ret = pkgmgrinfo_appinfo_get_icon(handle, &tmp_str); + if ((PMINFO_R_OK != ret) || (nullptr == tmp_str)) { + LoggerE("Failed to get icon path"); + } else { + app_info->insert(std::make_pair("iconPath", picojson::value(tmp_str))); + } + tmp_str = nullptr; + + // show + bool no_display = false; + ret = pkgmgrinfo_appinfo_is_nodisplay(handle, &no_display); + if (PMINFO_R_OK != ret) { + LoggerE("Failed to get nodisplay"); + } else { + app_info->insert(std::make_pair("show", picojson::value(!no_display))); + } + + // categories + picojson::value categories = picojson::value(picojson::array()); + picojson::array& categories_array = categories.get(); + app_info->insert(std::make_pair("categories", categories)); + + ret = pkgmgrinfo_appinfo_foreach_category( + handle, + [](const char* category, void* user_data) -> int { + picojson::array* categories_array = static_cast(user_data); + + if ((nullptr != category) && (nullptr != categories_array)) { + categories_array->push_back(picojson::value(category)); + } + + return 0; + }, + &categories_array); + + if (PMINFO_R_OK != ret) { + LoggerE("Failed to get categories"); + } + + // package ID + ret = pkgmgrinfo_appinfo_get_pkgid(handle, &tmp_str); + if ((PMINFO_R_OK != ret) || (nullptr == tmp_str)) { + LoggerE("Failed to get pkgid"); + } else { + app_info->insert(std::make_pair("packageId", picojson::value(tmp_str))); + } + + pkgmgrinfo_pkginfo_h pkginfo; + ret = pkgmgrinfo_pkginfo_get_pkginfo(tmp_str, &pkginfo); + if (PMINFO_R_OK != ret) { + LoggerE("Failed to get package info"); + } else { + // version + tmp_str = nullptr; + ret = pkgmgrinfo_pkginfo_get_version(pkginfo, &tmp_str); + if ((PMINFO_R_OK != ret) || (nullptr == tmp_str)) { + LoggerE("Failed to get version"); + } else { + app_info->insert(std::make_pair("version", picojson::value(tmp_str))); + } + tmp_str = nullptr; + + // installation date + int installed_time = 0; + ret = pkgmgrinfo_pkginfo_get_installed_time(pkginfo, &installed_time); + if (ret != PMINFO_R_OK) { + LoggerE("Fail to get installed date"); + } else { + app_info->insert(std::make_pair("installDate", picojson::value(1000.0 * installed_time))); + } + + pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo); + } + + // size is set at first attribute access (performance) +} + +bool ApplicationUtils::CreateApplicationContext(const app_context_h handle, + picojson::object* app_context) { + char* app_id = nullptr; + + int ret = app_context_get_app_id(handle, &app_id); + // automatically release the memory + std::unique_ptr app_id_ptr(app_id, &std::free); + + if ((APP_MANAGER_ERROR_NONE != ret) || (nullptr == app_id)) { + LoggerD("Failed to get application ID from context."); + return false; + } + + pid_t pid; + ret = app_context_get_pid(handle, &pid); + + if(ret != APP_MANAGER_ERROR_NONE) { + LoggerD("Failed to get pid from context."); + return false; + } + + CreateApplicationContext(pid, app_id, app_context); + + return true; +} + +void ApplicationUtils::CreateApplicationContext(pid_t pid, const std::string& app_id, + picojson::object* app_context) { + + app_context->insert(std::make_pair("id", picojson::value(std::to_string(pid)))); + app_context->insert(std::make_pair("appId", picojson::value(app_id))); +} + +void ApplicationUtils::CreateApplicationCertificate(const char* cert_type, + const char* cert_value, + picojson::object* app_certificate) { + + app_certificate->insert(std::make_pair("type", picojson::value(cert_type))); + app_certificate->insert(std::make_pair("value", picojson::value(cert_value))); +} + +void ApplicationUtils::CreateApplicationMetaData(const char* key, + const char* value, + picojson::object* app_meta_data) { + + app_meta_data->insert(std::make_pair("key", picojson::value(key))); + app_meta_data->insert(std::make_pair("value", picojson::value(value))); +} + +PlatformResult ApplicationUtils::ApplicationControlToService( + const picojson::object& app_control_obj, + app_control_h* app_control) { + + const auto it_operation = app_control_obj.find("operation"); + const auto it_uri = app_control_obj.find("uri"); + const auto it_mime = app_control_obj.find("mime"); + const auto it_category = app_control_obj.find("category"); + const auto it_data = app_control_obj.find("data"); + const auto it_app_control_end = app_control_obj.end(); + + if (it_operation == it_app_control_end || + it_uri == it_app_control_end || + it_mime == it_app_control_end || + it_category == it_app_control_end || + it_data == it_app_control_end || + !it_operation->second.is() || + !it_data->second.is()) { + LoggerE("Invalid parameter was passed."); + return PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter was passed."); + } + + app_control_create(app_control); + + // operation + app_control_set_operation(*app_control, it_operation->second.get().c_str()); + + // uri + if (it_uri->second.is()) { + app_control_set_uri(*app_control, it_uri->second.get().c_str()); + } + + // mime + if (it_mime->second.is()) { + app_control_set_mime(*app_control, it_mime->second.get().c_str()); + } + + // category + if (it_category->second.is()) { + app_control_set_category(*app_control, it_category->second.get().c_str()); + } + + // ApplicationControlData + const picojson::array& data = it_data->second.get(); + + for (auto iter = data.begin(); iter != data.end(); ++iter) { + if (iter->is()) { + PlatformResult ret = + ApplicationControlDataToServiceExtraData(iter->get(), *app_control); + if (ret.IsError()) { + return ret; + } + } + } + + return PlatformResult(ErrorCode::NO_ERROR); +} + +PlatformResult ApplicationUtils::ApplicationControlDataToServiceExtraData( + const picojson::object& app_control_data, + app_control_h app_control) { + + const auto it_key = app_control_data.find("key"); + const auto it_value = app_control_data.find("value"); + const auto it_app_control_data_end = app_control_data.end(); + + if (it_key == it_app_control_data_end || + it_value == it_app_control_data_end || + !it_key->second.is() || + !it_value->second.is()) { + LoggerE("Problem with key or value."); + return PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter was passed."); + } + + const std::string& key = it_key->second.get(); + const picojson::array& value = it_value->second.get(); + + const size_t size = value.size(); + const char** arr = new const char*[size]; + size_t i = 0; + + for (auto iter = value.begin(); iter != value.end(); ++iter, ++i) { + if (iter->is()) { + arr[i] = iter->get().c_str(); + } + } + + if (1 == size) { + app_control_add_extra_data(app_control, key.c_str(), arr[0]); + } else { + app_control_add_extra_data_array(app_control, key.c_str(), arr, size); + } + + delete[] arr; + return PlatformResult(ErrorCode::NO_ERROR); +} + +void ApplicationUtils::ServiceToApplicationControl(app_control_h app_control, + picojson::object* app_control_obj) { + int ret = 0; + char* tmp_str = nullptr; + auto clear = [](char*& str) { + free(str); + str = nullptr; + }; + + ret = app_control_get_operation(app_control, &tmp_str); + if ((APP_CONTROL_ERROR_NONE == ret) && (nullptr != tmp_str)) { + LoggerD("operation: %s", tmp_str); + app_control_obj->insert(std::make_pair("operation", picojson::value(std::string(tmp_str)))); + } + clear(tmp_str); + + ret = app_control_get_uri(app_control, &tmp_str); + if ((APP_CONTROL_ERROR_NONE == ret) && (nullptr != tmp_str)) { + LoggerD("URI: %s", tmp_str); + app_control_obj->insert(std::make_pair("uri", picojson::value(std::string(tmp_str)))); + } + clear(tmp_str); + + ret = app_control_get_mime(app_control, &tmp_str); + if ((APP_CONTROL_ERROR_NONE == ret) && (nullptr != tmp_str)) { + LoggerD("MIME: %s", tmp_str); + app_control_obj->insert(std::make_pair("mime", picojson::value(std::string(tmp_str)))); + } + clear(tmp_str); + + ret = app_control_get_category(app_control, &tmp_str); + if ((APP_CONTROL_ERROR_NONE == ret) && (nullptr != tmp_str)) { + LoggerD("category: %s", tmp_str); + app_control_obj->insert(std::make_pair("category", picojson::value(std::string(tmp_str)))); + } + clear(tmp_str); + + app_control_obj->insert(std::make_pair("data", picojson::value(picojson::array()))); + ServiceToApplicationControlDataArray( + app_control, &app_control_obj->find("data")->second.get()); +} + +void ApplicationUtils::ServiceExtraDataToApplicationControlData(app_control_h app_control, + const std::string& key, + picojson::object* app_control_data) { + int ret = 0; + bool is_array = false; + + ret = app_control_is_extra_data_array(app_control, key.c_str(), &is_array); + + if (APP_CONTROL_ERROR_NONE != ret) { + LoggerE("Failed to check whether extra data is array or not"); + return; + } + + app_control_data->insert(std::make_pair("key", picojson::value(key))); + picojson::array value_array; + + if (is_array) { + int length = 0; + char** value = nullptr; + + ret = app_control_get_extra_data_array(app_control, key.c_str(), &value, &length); + + if ((APP_CONTROL_ERROR_NONE == ret) && (nullptr != value)) { + for (int i = 0; i < length; ++i) { + if (value[i]) { + value_array.push_back(picojson::value(value[i])); + free(value[i]); + } + } + free(value); + } else { + LoggerE("Failed to get extra data array, errno: %d", ret); + } + } else { + char* value = nullptr; + + ret = app_control_get_extra_data(app_control, key.c_str(), &value); + + if ((APP_CONTROL_ERROR_NONE == ret) && (nullptr != value)) { + value_array.push_back(picojson::value(value)); + free(value); + } else { + LoggerE("Failed to get extra data, errno: %d", ret); + } + } + + app_control_data->insert(std::make_pair("value", picojson::value(value_array))); +} + +bool ApplicationUtils::ServiceToApplicationControlDataArray(app_control_h app_control, + picojson::array* data) { + int ret = app_control_foreach_extra_data(app_control, ServiceExtraDataCallback, data); + return APP_CONTROL_ERROR_NONE == ret; +} + +bool ApplicationUtils::ServiceExtraDataCallback(app_control_h app_control, + const char* key, + void* user_data) { + picojson::array* data = static_cast(user_data); + + data->push_back(picojson::value(picojson::object())); + ServiceExtraDataToApplicationControlData(app_control, key, &data->back().get()); + + return true; +} + +} // namespace application +} // namespace extension diff --git a/src/application/application_utils.h b/src/application/application_utils.h new file mode 100644 index 00000000..8a9e22a6 --- /dev/null +++ b/src/application/application_utils.h @@ -0,0 +1,63 @@ +// Copyright 2015 Samsung Electronics Co, Ltd. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef SRC_APPLICATION_APPLICATION_UTILS_H__ +#define SRC_APPLICATION_APPLICATION_UTILS_H__ + +#include +#include +#include + +#include "common/picojson.h" +#include "common/platform_result.h" + +namespace extension { +namespace application { + +class ApplicationUtils { + public: + static void CreateApplicationInformation(const pkgmgrinfo_appinfo_h handle, + picojson::object* app_info); + + static bool CreateApplicationContext(const app_context_h handle, + picojson::object* app_context); + + static void CreateApplicationContext(pid_t pid, + const std::string& app_id, + picojson::object* app_context); + + static void CreateApplicationCertificate(const char* cert_type, + const char* cert_value, + picojson::object* app_certificate); + + static void CreateApplicationMetaData(const char* key, + const char* value, + picojson::object* app_meta_data); + + static common::PlatformResult ApplicationControlToService(const picojson::object& app_control_obj, + app_control_h* app_control); + + static common::PlatformResult ApplicationControlDataToServiceExtraData( + const picojson::object& app_control_data, + app_control_h app_control); + + static void ServiceToApplicationControl(app_control_h app_control, + picojson::object* app_control_obj); + + static void ServiceExtraDataToApplicationControlData(app_control_h app_control, + const std::string& key, + picojson::object* app_control_data); + + static bool ServiceToApplicationControlDataArray(app_control_h app_control, + picojson::array* data); + private: + static bool ServiceExtraDataCallback(app_control_h app_control, + const char* key, + void* user_data); +}; + +} // namespace application +} // namespace extension + +#endif // SRC_APPLICATION_APPLICATION_UTILS_H__ diff --git a/src/application/requested_application_control.cc b/src/application/requested_application_control.cc index 7cfb078f..c46ef5e8 100644 --- a/src/application/requested_application_control.cc +++ b/src/application/requested_application_control.cc @@ -2,57 +2,190 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "application/requested_application_control.h" +#include "requested_application_control.h" #include +#include +#include #include "common/logger.h" -#include "tizen/tizen.h" +#include "application/application_utils.h" + +using namespace common; +using namespace tools; namespace extension { namespace application { -RequestedApplicationControl::RequestedApplicationControl() { -} +PlatformResult RequestedApplicationControl::set_bundle(const std::string& encoded_bundle) { + LoggerD("Entered"); -RequestedApplicationControl::~RequestedApplicationControl() { -} + if (encoded_bundle != bundle_) { + bundle_ = encoded_bundle; + + bundle* bundle = bundle_decode((bundle_raw*)(encoded_bundle.c_str()), + encoded_bundle.length()); + app_control_h app_control = nullptr; + int ret = app_control_create_event(bundle, &app_control); + bundle_free(bundle); -const picojson::value& RequestedApplicationControl::Value() { - LoggerD("caller_app_id_: %s", caller_app_id_.c_str()); - data_["callerAppId"] = picojson::value(caller_app_id_); - data_["appControl"] = picojson::value(app_control_.Value()); + if (APP_CONTROL_ERROR_NONE != ret) { + LoggerE("Failed to create app_control"); + return PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to create app_control."); + } - value_ = picojson::value(data_); + set_app_control(app_control); + } - return value_; + return PlatformResult(ErrorCode::NO_ERROR); } -bool RequestedApplicationControl::IsValid() const { - return error_.empty(); +void RequestedApplicationControl::set_app_control(app_control_h app_control) { + LoggerD("Entered"); + + app_control_.reset(app_control, app_control_destroy); + + char* tmp_str = nullptr; + int ret = app_control_get_caller(app_control, &tmp_str); + + if ((APP_CONTROL_ERROR_NONE == ret) && (nullptr != tmp_str)) { + caller_app_id_ = tmp_str; + } else { + LoggerW("Failed to get callerAppId because of platform error"); + LoggerW("Please ignore if the application is launched in debug mode"); + } + + free(tmp_str); } -std::string RequestedApplicationControl::get_caller_app_id() const { - return caller_app_id_; +void RequestedApplicationControl::ToJson(picojson::object* out) { + LoggerD("Entered"); + + if (app_control_) { + out->insert(std::make_pair("callerAppId", picojson::value(caller_app_id_))); + auto appControl = out->insert(std::make_pair( + "appControl", picojson::value(picojson::object()))); + ApplicationUtils::ServiceToApplicationControl( + app_control_.get(), &appControl.first->second.get()); + } } -void RequestedApplicationControl:: - set_caller_app_id(const std::string& caller_app_id) { - caller_app_id_ = caller_app_id; - LoggerD("caller_app_id: %s", caller_app_id.c_str()); +void RequestedApplicationControl::ReplyResult(const picojson::value& args, picojson::object* out) { + LoggerD("Entered"); + + const auto& data_arr = args.get("data"); + if (!data_arr.is()) { + LoggerE("Invalid parameter passed."); + ReportError(PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Invalid parameter passed."), out); + return; + } + + // read input data + PlatformResult result = PlatformResult(ErrorCode::NO_ERROR); + const picojson::array& data = data_arr.get(); + + const std::string& encoded_bundle = + GetCurrentExtension()->GetRuntimeVariable("encoded_bundle", 1024); + + result = set_bundle(encoded_bundle); + if (result.IsError()) { + ReportError(result, out); + return; + } + + // code to check caller liveness + result = VerifyCallerPresence(); + if (result.IsError()) { + ReportError(result, out); + return; + } + + // create reply + app_control_h reply; + app_control_create(&reply); + std::unique_ptr::type, int(*)(app_control_h)> + reply_ptr(reply, &app_control_destroy); // automatically release the memory + + if (!data.empty()) { + for (auto iter = data.begin(); iter != data.end(); ++iter) { + result = ApplicationUtils::ApplicationControlDataToServiceExtraData( + iter->get(), reply); + if (result.IsError()) { + ReportError(result, out); + return; + } + } + } else { + LoggerD("appControlDataArray is empty"); + } + + // send reply + if (APP_CONTROL_ERROR_NONE != + app_control_reply_to_launch_request(reply, app_control_.get(), APP_CONTROL_RESULT_SUCCEEDED)) { + LoggerE("Cannot find caller."); + ReportError(PlatformResult(ErrorCode::NOT_FOUND_ERR, "Cannot find caller."), out); + return; + } + + ReportSuccess(*out); } -ApplicationControl& RequestedApplicationControl::get_app_control() { - return app_control_; +void RequestedApplicationControl::ReplyFailure(picojson::object* out) { + LoggerD("Entered"); + + // read input data + PlatformResult result = PlatformResult(ErrorCode::NO_ERROR); + const std::string& encoded_bundle = + GetCurrentExtension()->GetRuntimeVariable("encoded_bundle", 1024); + + result = set_bundle(encoded_bundle); + if (result.IsError()) { + ReportError(result, out); + return; + } + + // code to check caller liveness + result = VerifyCallerPresence(); + if (result.IsError()) { + ReportError(result, out); + return; + } + + // create reply + app_control_h reply; + app_control_create(&reply); + std::unique_ptr::type, int(*)(app_control_h)> + reply_ptr(reply, &app_control_destroy); // automatically release the memory + + // send reply + int ret = app_control_reply_to_launch_request(reply, app_control_.get(), APP_CONTROL_RESULT_FAILED); + if (APP_CONTROL_ERROR_NONE != ret) { + LoggerE("Cannot find caller."); + ReportError(PlatformResult(ErrorCode::NOT_FOUND_ERR, "Cannot find caller."), out); + return; + } + + ReportSuccess(*out); } -void RequestedApplicationControl:: - set_app_control(const ApplicationControl& app_control) { - app_control_.set_operation(app_control.get_operation()); - app_control_.set_uri(app_control.get_uri()); - app_control_.set_mime(app_control.get_mime()); - app_control_.set_category(app_control.get_category()); - app_control_.set_data_array(app_control.get_data_array()); +PlatformResult RequestedApplicationControl::VerifyCallerPresence() { + LoggerD("Entered"); + + if (caller_app_id_.empty()) { + LoggerE("caller_app_id_ is empty. This means caller is dead."); + return PlatformResult(ErrorCode::NOT_FOUND_ERR, "Cannot find caller."); + } else { + bool running = false; + + int ret = app_manager_is_running(caller_app_id_.c_str(), &running); + + if ((APP_MANAGER_ERROR_NONE != ret) || !running) { + LoggerE("Caller is not running"); + return PlatformResult(ErrorCode::NOT_FOUND_ERR, "Cannot find caller."); + } + + return PlatformResult(ErrorCode::NO_ERROR); + } } } // namespace application diff --git a/src/application/requested_application_control.h b/src/application/requested_application_control.h index 07b7c3ef..0f50186d 100644 --- a/src/application/requested_application_control.h +++ b/src/application/requested_application_control.h @@ -7,40 +7,32 @@ #include #include +#include + +#include #include "common/picojson.h" +#include "common/extension.h" +#include "common/platform_result.h" #include "tizen/tizen.h" -#include "application/application_control.h" - namespace extension { namespace application { -class RequestedApplicationControl; -typedef std::shared_ptr - RequestedApplicationControlPtr; - class RequestedApplicationControl { public: - RequestedApplicationControl(); - ~RequestedApplicationControl(); - - const picojson::value& Value(); - bool IsValid() const; - - std::string get_caller_app_id() const; - void set_caller_app_id(const std::string& caller_app_id); - - ApplicationControl& get_app_control(); - void set_app_control(const ApplicationControl& app_control); + common::PlatformResult set_bundle(const std::string& encoded_bundle); + void ToJson(picojson::object* out); + void ReplyResult(const picojson::value& args, picojson::object* out); + void ReplyFailure(picojson::object* out); private: - std::string caller_app_id_; - ApplicationControl app_control_; + void set_app_control(app_control_h app_control); + common::PlatformResult VerifyCallerPresence(); - picojson::object data_; - picojson::object error_; - picojson::value value_; + std::string bundle_; + std::shared_ptr::type> app_control_; + std::string caller_app_id_; }; } // namespace application