[Verification] Code compiles.
Change-Id: I320493804fafd9efa26f1f6cbe3a4425a845d1a7
Signed-off-by: Tomasz Marciniak <t.marciniak@samsung.com>
applicationEventListener.removeListener(args.watchId);
};
+function StatusListenerManager(native, listenerName) {
+ this.listeners = {};
+ this.listenersCount = 0;
+ this.nextId = 1;
+ this.nativeSet = false;
+ this.native = native;
+ this.listenerName = listenerName;
+};
+
+StatusListenerManager.prototype.onListenerCalled = function(msg) {
+ var statusType = msg.statusType;
+ var app_id = msg.appId;
+
+ for (var watchId in this.listeners) {
+ if (this.listeners.hasOwnProperty(watchId)) {
+ var listener = this.listeners[watchId];
+ if (!listener.appId || listener.appId === app_id) {
+ listener.callback(app_id, statusType);
+ }
+ }
+ }
+};
+
+StatusListenerManager.prototype.addListener = function(callback, appId) {
+ if (!this.nativeSet) {
+ var result = this.native.callSync('ApplicationManager_addAppStatusChangeListener');
+ if (this.native.isFailure(result)) {
+ throw this.native.getErrorObject(result);
+ }
+
+ this.native.addListener(this.listenerName, this.onListenerCalled.bind(this));
+ this.nativeSet = true;
+ }
+
+ var listener = {
+ 'callback' : callback,
+ 'appId' : appId
+ };
+
+ var id = this.nextId++;
+ this.listeners[id] = listener;
+ this.listenersCount++;
+
+ return id;
+};
+
+StatusListenerManager.prototype.removeListener = function(watchId) {
+ if (this.listeners.hasOwnProperty(watchId)) {
+ if (this.listenersCount > 1) {
+ delete this.listeners[watchId];
+ this.listenersCount--;
+ return;
+ }
+
+ if (this.nativeSet) {
+ var result = this.native.callSync('ApplicationManager_removeStatusChangeListener');
+ if (this.native.isFailure(result)) {
+ throw this.native.getErrorObject(result);
+ }
+
+ delete this.listeners[watchId];
+ this.listenersCount--;
+
+ this.native.removeListener(this.listenerName);
+ this.nativeSet = false;
+ }
+ }
+};
+
+var APP_STATUS_CHANGE_LISTENER = 'AppStatusChangeListener';
+var appStatusChangeListener = new StatusListenerManager(native, APP_STATUS_CHANGE_LISTENER);
+
+ApplicationManager.prototype.addAppStatusChangeListener = function() {
+ var args = AV.validateMethod(arguments, [
+ {
+ name : 'statusChangeListener',
+ type : AV.Types.FUNCTION,
+ },
+ {
+ name : 'appId',
+ type : AV.Types.STRING,
+ optional : true,
+ nullable : true
+ }
+ ]);
+
+ if (args.appId !== undefined && args.appId !== null && !args.appId.length) {
+ throw new WebAPIException(WebAPIException.INVALID_VALUES_ERR, 'Application id is empty');
+ }
+
+ return appStatusChangeListener.addListener(args.statusChangeListener, args.appId);
+};
+
+ApplicationManager.prototype.removeAppStatusChangeListener = function() {
+ var args = AV.validateMethod(arguments, [
+ {
+ name : 'watchId',
+ type : AV.Types.LONG
+ }
+ ]);
+
+ appStatusChangeListener.removeListener(args.watchId);
+};
+
// class Application ////////////////////////////////////////////////////
function Application(data) {
REGISTER_SYNC("ApplicationManager_getAppMetaData", GetAppMetaData);
REGISTER_SYNC("ApplicationManager_addAppInfoEventListener", AddAppInfoEventListener);
REGISTER_SYNC("ApplicationManager_removeAppInfoEventListener", RemoveAppInfoEventListener);
+ REGISTER_SYNC("ApplicationManager_addAppStatusChangeListener", AddStatusListener);
+ REGISTER_SYNC("ApplicationManager_removeStatusChangeListener", RemoveStatusListener);
//Application
REGISTER_SYNC("Application_getRequestedAppControl", GetRequestedAppControl);
manager_.StopEventListener(event_name);
}
+void ApplicationInstance::AddStatusListener(const picojson::value& args, picojson::object& out) {
+ LoggerD("Entered");
+
+ JsonCallback cb = [this](picojson::value* event) -> void {
+ Instance::PostMessage(this, event->serialize().c_str());
+ };
+
+ PlatformResult result = manager_.StartStatusListener(cb);
+ if (result) {
+ ReportSuccess(out);
+ } else {
+ LogAndReportError(result, &out);
+ }
+}
+
+void ApplicationInstance::RemoveStatusListener(const picojson::value& args, picojson::object& out) {
+ LoggerD("Entered");
+
+ PlatformResult result = manager_.StopStatusChangeListener();
+ if (result) {
+ ReportSuccess(out);
+ } else {
+ LogAndReportError(result, &out);
+ }
+}
+
} // namespace application
} // namespace extension
void BroadcastTrustedEvent(const picojson::value& args, picojson::object& out);
void AddEventListener(const picojson::value& args, picojson::object& out);
void RemoveEventListener(const picojson::value& args, picojson::object& out);
+ void AddStatusListener(const picojson::value& args, picojson::object& out);
+ void RemoveStatusListener(const picojson::value& args, picojson::object& out);
ApplicationManager manager_;
Application current_application_;
#include <unistd.h>
#include <app_info.h>
-#include <app_manager.h>
#include <app_manager_extension.h>
#include <aul.h>
#include <pkgmgr_installer.h>
const std::string kOnUpdated = "onupdated";
const std::string kOnUninstalled = "onuninstalled";
const std::string kData = "data";
+const std::string kStatusType = "statusType";
+const std::string kAppId = "appId";
+const std::string kListenerId = "listenerId";
+const std::string kAppStatusChangeListener = "AppStatusChangeListener";
const std::map<std::string, std::string> event_map_ = {
{SYSTEM_EVENT_BATTERY_CHARGER_STATUS, EVENT_KEY_BATTERY_CHARGER_STATUS},
ApplicationManager::ApplicationManager(ApplicationInstance& instance) :
pkgmgr_client_handle_(nullptr),
pkgmgr_client_uninstall_handle_(nullptr),
- instance_(instance) {
+ instance_(instance),
+ app_status_handle_(nullptr) {
LoggerD("Enter");
}
ApplicationManager::~ApplicationManager() {
LoggerD("Enter");
StopAppInfoEventListener();
+ StopStatusChangeListener();
+
+ if (app_status_handle_) {
+ int ret = app_manager_event_destroy(app_status_handle_);
+ if (APP_MANAGER_ERROR_NONE != ret) {
+ LoggerE ("app_manager_event_destroy failed, error: %d", ret);
+ }
+ }
}
void ApplicationManager::GetCurrentApplication(const std::string& app_id,
}
}
+void ApplicationManager::OnStatusEvent(const char *type, const char *app_id,
+ app_manager_event_type_e event_type,
+ app_manager_event_state_e event_state,
+ app_manager_event_h handle, void *user_data) {
+ LoggerD("Entered");
+
+ if (APP_MANAGER_EVENT_STATE_COMPLETED != event_state) {
+ LoggerD("State different from completed");
+ return;
+ }
+
+ ApplicationManager* manager = static_cast<ApplicationManager*>(user_data);
+
+ if (!manager || !manager->status_callback_) {
+ LoggerD("No event listener registered, skipping.");
+ return;
+ }
+
+ bool status_type;
+ switch (event_type) {
+ case APP_MANAGER_EVENT_ENABLE_APP:
+ status_type = true;
+ break;
+ case APP_MANAGER_EVENT_DISABLE_APP:
+ status_type = false;
+ break;
+ default:
+ LoggerD("Uknown status type skipping.");
+ return;
+ }
+
+ picojson::value event = picojson::value(picojson::object());
+ picojson::object& event_o = event.get<picojson::object>();
+
+ event_o[kStatusType] = picojson::value(status_type);
+ event_o[kAppId] = picojson::value(app_id);
+ event_o[kListenerId] = picojson::value(kAppStatusChangeListener);
+
+ manager->status_callback_(&event);
+}
+
+PlatformResult ApplicationManager::StartStatusListener(const JsonCallback& callback) {
+ LoggerD("Entered");
+
+ int ret = APP_MANAGER_ERROR_NONE;
+
+ if (!app_status_handle_) {
+ ret = app_manager_event_create(&app_status_handle_);
+ if (APP_MANAGER_ERROR_NONE != ret) {
+ return LogAndCreateResult(ErrorCode::ABORT_ERR, "Error while creating event handle",
+ ("app_manager_event_create failed, error: %d", ret));
+ }
+
+ ret = app_manager_event_set_status(app_status_handle_, APP_MANAGER_EVENT_STATUS_TYPE_ALL);
+ if (APP_MANAGER_ERROR_NONE != ret) {
+ return LogAndCreateResult(ErrorCode::ABORT_ERR, "Error while setting status type",
+ ("app_manager_event_set_status failed, error: %d", ret));
+ }
+ }
+
+ status_callback_ = callback;
+ ret = app_manager_set_event_cb(app_status_handle_, OnStatusEvent, this);
+ if (APP_MANAGER_ERROR_NONE != ret) {
+ return LogAndCreateResult(ErrorCode::ABORT_ERR, "Error while setting status listener",
+ ("app_manager_set_event_cb failed, error: %d", ret));
+ }
+
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
+PlatformResult ApplicationManager::StopStatusChangeListener() {
+ LoggerD("Entered");
+
+ if (app_status_handle_) {
+ int ret = app_manager_unset_event_cb(app_status_handle_);
+ if (APP_MANAGER_ERROR_NONE != ret) {
+ return LogAndCreateResult(ErrorCode::ABORT_ERR, "Error while removing status listener",
+ ("app_manager_unset_event_cb failed, error: %d", ret));
+ }
+ }
+
+ return PlatformResult(ErrorCode::NO_ERROR);
+}
+
} // namespace application
} // namespace extension
#define SRC_APPLICATION_APPLICATION_MANAGER_H__
#include <app_event.h>
+#include <app_manager.h>
#include <bundle.h>
#include <functional>
#include <memory>
common::PlatformResult StartEventListener(const std::string& event_name,
const JsonCallback& callback);
void StopEventListener(const std::string& event_name);
+ common::PlatformResult StartStatusListener(const JsonCallback& callback);
+ common::PlatformResult StopStatusChangeListener();
private:
char* GetPackageId(const std::string& app_id);
pkgmgr_client* pkgmgr_client_handle_;
pkgmgr_client* pkgmgr_client_uninstall_handle_;
ApplicationInstance& instance_;
+ app_manager_event_h app_status_handle_;
JsonCallback event_callback_;
+ JsonCallback status_callback_;
std::map<std::string, event_handler_h> event_handler_map_;
static void OnEvent(const char* event_name,
bundle* event_data,
void* user_data);
+ static void OnStatusEvent(const char *type, const char *app_id,
+ app_manager_event_type_e event_type,
+ app_manager_event_state_e event_state,
+ app_manager_event_h handle,
+ void *user_data);
};
} // namespace application