return MODES_ERROR_NOT_SUPPORTED;
}
+int AppfwAction::undo(const std::string &val)
+{
+ return MODES_ERROR_NOT_SUPPORTED;
+}
+
+int AppfwAction::get(std::string *val)
+{
+ return MODES_ERROR_NOT_SUPPORTED;
+}
+
void AppfwAction::setName(std::string name)
{
this->name = name;
std::string getName();
virtual int set(const std::string &val);
+ virtual int get(std::string *val);
+ virtual int undo(const std::string &val);
protected:
void setName(std::string name);
*/
#include "AppfwActionLaunch.h"
+#include <algorithm>
#include <app_control.h>
+#include <app_manager.h>
+#include <app_manager_extension.h>
#include <modes_errors.h>
#include "plugin-log.h"
MODES_NAMESPACE_USE;
const std::string AppfwActionLaunch::NAME = "launch";
+std::list<std::string> AppfwActionLaunch::appidList;
+void AppfwActionLaunch::appContextStatusCallback(app_context_h app_context, app_context_status_e status, void *user_data)
+{
+ char *appid = NULL;
+ DBG("appContextStatusCallback(status:%d)", status);
+ if (app_context_get_app_id(app_context, &appid) != APP_MANAGER_ERROR_NONE) {
+ ERR("Failed to get appid\n");
+ return;
+ }
+
+ DBG("app_context_cb(appid:%s)", appid);
+ if (APP_CONTEXT_STATUS_TERMINATED == status) {
+ DBG("APP_CONTEXT_STATUS_TERMINATED appid : %s\n", appid);
+ appidList.remove(appid);
+ }
+
+ free(appid);
+ return;
+}
AppfwActionLaunch::AppfwActionLaunch()
{
{
DBG("id(%s)", val.c_str());
- app_control_h service;
- app_control_create(&service);
- app_control_set_app_id(service, val.c_str());
- app_control_set_operation(service, APP_CONTROL_OPERATION_DEFAULT);
- app_control_set_launch_mode(service, APP_CONTROL_LAUNCH_MODE_SINGLE);
+ auto found = std::find(appidList.begin(), appidList.end(), val);
+
+ if (found == appidList.end())
+ {
+ bool running;
+ app_manager_is_running(val.c_str(), &running);
+
+ if (running) {
+ ERR("It's already running before started mode-supervisor daemon");
+ return MODES_ERROR_CONFLICT;
+ }
- int ret = app_control_send_launch_request(service, NULL, NULL);
- if (APP_CONTROL_ERROR_NONE != ret) {
- ERR("app_control_send_launch_request() Fail(%s)", get_error_message(ret));
- return MODES_ERROR_IO_ERROR;
+ app_control_h service;
+ app_control_create(&service);
+ app_control_set_app_id(service, val.c_str());
+ app_control_set_operation(service, APP_CONTROL_OPERATION_DEFAULT);
+ app_control_set_launch_mode(service, APP_CONTROL_LAUNCH_MODE_SINGLE);
+
+ int ret = app_control_send_launch_request(service, NULL, NULL);
+ if (APP_CONTROL_ERROR_NONE != ret) {
+ ERR("app_control_send_launch_request() Fail(%s)", get_error_message(ret));
+ return MODES_ERROR_IO_ERROR;
+ }
+ app_control_destroy(service);
+
+ appidList.push_back(val);
+
+ DBG("APP_CONTEXT_EVENT_LAUNCHED(appid : %s) added list\n", val.c_str());
+
+ ret = app_manager_set_app_context_status_cb(AppfwActionLaunch::appContextStatusCallback, val.c_str(), NULL);
+ if (APP_MANAGER_ERROR_NONE != ret) {
+ ERR("app_manager_set_app_context_status_cb() Fail(%s)", get_error_message(ret));
+ return MODES_ERROR_IO_ERROR;
+ }
+
+ appID = val;
}
- app_control_destroy(service);
+ return MODES_ERROR_NONE;
+}
+
+int AppfwActionLaunch::get(std::string *val)
+{
+ if(val)
+ *val = appID;
+ return MODES_ERROR_NONE;
+}
+
+int AppfwActionLaunch::undo(const std::string &val)
+{
+ bool running;
+ app_context_h runAppContext;
+
+ app_manager_is_running(val.c_str(), &running);
+ if (!running) {
+ DBG("It's NOT running");
+ return MODES_ERROR_NONE;
+ }
+
+ int ret = app_manager_unset_app_context_status_cb(AppfwActionLaunch::appContextStatusCallback, val.c_str());
+ if (APP_MANAGER_ERROR_NONE != ret) {
+ ERR("app_manager_unset_app_context_status_cb() Fail(%s)", get_error_message(ret));
+ return MODES_ERROR_IO_ERROR;
+ }
+
+ appidList.remove(val);
+
+ ret = app_manager_get_app_context(val.c_str(), &runAppContext);
+ if (APP_MANAGER_ERROR_NONE != ret) {
+ ERR("app_manager_get_app_context(%s) Fail(%s)", val.c_str(), get_error_message(ret));
+ return MODES_ERROR_IO_ERROR;
+ }
+ ret = app_manager_terminate_app(runAppContext);
+ if (APP_MANAGER_ERROR_NONE != ret) {
+ ERR("app_manager_terminate_app() Fail(%s)", get_error_message(ret));
+ return MODES_ERROR_IO_ERROR;
+ }
return MODES_ERROR_NONE;
}
*/
#pragma once
+#include <list>
#include <string>
+#include <app_manager.h>
+#include <app_manager_extension.h>
#include "AppfwAction.h"
MODES_NAMESPACE_BEGIN
AppfwActionLaunch();
virtual int set(const std::string &val) override;
+ virtual int get(std::string *val) override;
+ virtual int undo(const std::string &val) override;
static const std::string NAME;
+ static void appContextStatusCallback(app_context_h app_context, app_context_status_e status, void *user_data);
+
+private:
+ std::string appID;
+ static std::list<std::string> appidList;
};
MODES_NAMESPACE_END
* limitations under the License.
*/
#include "AppfwFactory.h"
-#include <modes_errors.h>
#include "plugin-log.h"
#include "AppfwActionLaunch.h"
*/
#pragma once
-#include <string>
#include <map>
+#include <string>
#include "AppfwAction.h"
MODES_NAMESPACE_BEGIN
* limitations under the License.
*/
#include <string>
-#include <map>
#include <modes_errors.h>
#include <Plugin.h>
#include "plugin-log.h"
~AppfwPlugin();
int set(const std::string &key, const std::string &val, std::string *oldVal) override;
+ int undo(const std::string &key, const std::string &val) override;
+
private:
AppfwFactory appfwFactory;
};
DBG("set [%s, %s]", key.c_str(), val.c_str());
int appfwRet = action->set(val);
+
+ if (oldVal)
+ action->get(oldVal);
+
appfwFactory.destroyAction(action);
return appfwRet;
}
+int AppfwPlugin::undo(const std::string &key, const std::string &val)
+{
+ AppfwAction *action = appfwFactory.createAction(key);
+ RETVM_IF(nullptr == action, MODES_ERROR_INVALID_PARAMETER, "action(%s) is null", key.c_str());
+
+ DBG("set [%s, %s]", key.c_str(), val.c_str());
+
+ int appfwRet = action->undo(val);
+ appfwFactory.destroyAction(action);
+ return appfwRet;
+}
FILE(GLOB APPFW_SRCS *.cpp)
-pkg_check_modules(appfw_pkgs REQUIRED modes dlog capi-base-common capi-appfw-application)
+pkg_check_modules(appfw_pkgs REQUIRED modes dlog capi-base-common capi-appfw-application capi-appfw-app-manager aul)
INCLUDE_DIRECTORIES(${appfw_pkgs_INCLUDE_DIRS})
LINK_DIRECTORIES(${appfw_pkgs_LIBRARY_DIRS})
btFactory.destroyAction(action);
return btRet;
}
-
BuildRequires: modes-plugin-devel
BuildRequires: pkgconfig(dlog)
BuildRequires: pkgconfig(capi-appfw-application)
+BuildRequires: pkgconfig(capi-appfw-app-manager)
BuildRequires: pkgconfig(capi-base-common)
BuildRequires: pkgconfig(libxml-2.0)
BuildRequires: pkgconfig(capi-network-wifi-manager)
BuildRequires: pkgconfig(capi-network-bluetooth)
BuildRequires: pkgconfig(vconf)
BuildRequires: pkgconfig(gmock)
+BuildRequires: pkgconfig(aul)
%description
Plugin Libraries for Mode Supervisor
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIE")
ADD_DEFINITIONS("-DMDS_TEST")
-pkg_check_modules(test_pkgs REQUIRED modes dlog capi-network-wifi-manager capi-network-bluetooth gmock capi-appfw-application vconf)
+pkg_check_modules(test_pkgs REQUIRED modes dlog capi-network-wifi-manager capi-network-bluetooth gmock capi-appfw-application vconf capi-appfw-app-manager aul)
INCLUDE_DIRECTORIES(${test_pkgs_INCLUDE_DIRS})
LINK_DIRECTORIES(${test_pkgs_LIBRARY_DIRS})
#include <string>
#include <gtest/gtest.h>
#include <Plugin.h>
-#include <modes.h>
#include <modes_errors.h>
-#include "plugin-log.h"
+#include <app_manager.h>
+#include <app_manager_extension.h>
#include "plugin-def.h"
MODES_NAMESPACE_USE;
extern "C" API Plugin *objectCreate(void);
extern "C" API void objectDelete(Plugin *plugin);
-TEST(PluginTest, setPluginAppfw)
-{
- int ret;
- Plugin *plugin = objectCreate();
+class PluginTest : public ::testing::Test {
+protected:
+ void SetUp() override
+ {
+ loop = g_main_loop_new(NULL, FALSE);
+ }
+
+ void TearDown() override
+ {
+ g_main_loop_unref(loop);
+ loop = NULL;
+ }
+
+ static gboolean appfwPluginUndoConflictIdler(gpointer data)
+ {
+ app_context_h runAppContext;
+ Plugin *plugin = objectCreate();
+ result = plugin->set("launch", std::string("org.tizen.w-stopwatch"), nullptr);
+ EXPECT_EQ(MODES_ERROR_NONE, result);
+ app_manager_get_app_context("org.tizen.w-stopwatch", &runAppContext);
+ app_manager_terminate_app(runAppContext);
+ result = plugin->undo("launch", std::string("org.tizen.w-stopwatch"));
+ EXPECT_EQ(MODES_ERROR_NONE, result);
+ objectDelete(plugin);
+ g_main_loop_quit(loop);
+
+ return G_SOURCE_REMOVE;
+ }
+
+ static gboolean appfwPluginSetUndoTimeout(gpointer data)
+ {
+ Plugin *plugin = (Plugin *)data;
+ result = plugin->undo("launch", std::string("org.tizen.w-stopwatch"));
+ EXPECT_EQ(MODES_ERROR_NONE, result);
+ g_main_loop_quit(loop);
+ return false;
+ }
+
+ static gboolean appfwPluginSetUndoIdler(gpointer data)
+ {
+ Plugin *plugin = (Plugin *)data;
+ result = plugin->set("launch", std::string("org.tizen.w-stopwatch"), nullptr);
+ EXPECT_EQ(MODES_ERROR_NONE, result);
+
+ g_timeout_add(1000, appfwPluginSetUndoTimeout, plugin);
+ return G_SOURCE_REMOVE;
+ }
- ret = plugin->set("launch", std::string("org.tizen.w-stopwatch"), nullptr);
- EXPECT_EQ(ret, MODES_ERROR_NONE);
+ static int result;
+ static GMainLoop *loop;
+ static GThread *my_thread;
+};
- objectDelete(plugin);
+int PluginTest::result = 0;
+GMainLoop *PluginTest::loop = NULL;
+
+TEST_F(PluginTest, setUndoPluginAppfw)
+{
+ Plugin *plugin = objectCreate();
+ g_idle_add(appfwPluginSetUndoIdler, plugin);
+ g_main_loop_run(loop);
+ objectDelete(plugin);
+}
+
+TEST_F(PluginTest, undoConflictPluginAppfw)
+{
+ g_idle_add(appfwPluginUndoConflictIdler, nullptr);
+ g_main_loop_run(loop);
}
+
int main(int argc, char **argv) {
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();