--- /dev/null
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "modes.h"
+
+#include <glib.h>
+#include "mdsc.h"
+#include "mdsc_dbus.h"
+#include "common/dbus.h"
+
+int _mdsc_dbus_can_apply_sync(mdsDbus *mdsc_dbus, const char *mode)
+{
+ int result = MODES_ERROR_NONE;
+ gboolean ret;
+ GError *error = NULL;
+
+ RETV_IF(NULL == mode, MODES_ERROR_INVALID_PARAMETER);
+
+ ret = mds_dbus_call_can_apply_sync(mdsc_dbus, mode, &result, NULL, &error);
+ if (FALSE == ret) {
+ ERR("mds_dbus_call_can_apply_sync() Fail(%s)", error ? error->message : "unknown");
+ g_error_free(error);
+ return MODES_ERROR_SYSTEM;
+ }
+
+ return result;
+}
+
+API int modes_can_apply(const char *name)
+{
+ int ret;
+ mdsDbus *dbus_handle;
+
+ RETV_IF(NULL == name, MODES_ERROR_INVALID_PARAMETER);
+
+ dbus_handle = mdsc_dbus_start();
+ if (NULL == dbus_handle) {
+ ERR("_mdsc_dbus_start() Fail");
+ return MODES_ERROR_SYSTEM;
+ }
+
+ ret = _mdsc_dbus_can_apply_sync(dbus_handle, name);
+ if (MODES_ERROR_NONE != ret) {
+ ERR("_mdsc_dbus_precheck_mode_sync() Fail(%d)", ret);
+ return ret;
+ }
+
+ mdsc_dbus_stop(dbus_handle);
+
+ return MODES_ERROR_NONE;
+}
<arg type="s" name="modeName" direction="in"/>
<arg type="i" name="ret" direction="out"/>
</method>
+ <method name="canApply">
+ <arg type="s" name="modeName" direction="in"/>
+ <arg type="i" name="ret" direction="out"/>
+ </method>
<method name="undoMode">
<arg type="s" name="modeName" direction="in"/>
<arg type="i" name="ret" direction="out"/>
<arg type="(siv)" name="modeData" direction="in"/>
<arg type="i" name="ret" direction="out"/>
</method>
- <method name="getModes">
+ <method name="getModes">
<arg type="a(si)" name="modeList" direction="out"/>
<arg type="i" name="ret" direction="out"/>
</method>
int modes_apply_mode(const char *name);
/**
+ * @brief Precheck to apply mode with the given name.
+ * @details Calls this function to change Modes.
+ * @since_tizen 6.0
+ * @privlevel public
+ * @param[in] Mode name to change
+ * @return @c 0 on success,
+ * otherwise a negative error value
+ * @retval #MODES_ERROR_NONE Successful
+ * @retval #MODES_ERROR_NO_DATA No data available
+ * @retval #MODES_ERROR_NOT_SUPPORTED Not supported
+ * @retval #MODES_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MODES_ERROR_PERMISSION_DENIED Permission denied
+ * @retval #MODES_ERROR_CONFLICT Conflict
+ * @retval #MODES_ERROR_SYSTEM System errors
+ */
+int modes_can_apply(const char *name);
+
+/**
* @brief undo mode with the given name.
* @details If the mode is not applied bebore, it will be ingnored.
* @since_tizen 6.0
DBG("[%d] modeName : %s, modePath : %s", modeMap.size(), modeName.c_str(), path.c_str());
}
-int ModeManager::applyMode(const string &modeName, ClientPrivilege &priv)
+
+
+int ModeManager::applyMode(const string &modeName, ClientPrivilege &priv, bool isTest)
{
auto found = modeMap.find(modeName);
if (modeMap.end() == found) {
DBG("applyMode(%s) Run", mode.getName().c_str());
+ int ret = priv.check(mode);
+ if (MODES_ERROR_NONE != ret) {
+ ERR("priv.check() Fail(%d)", ret);
+ return ret;
+ }
+
ConflictManager conflictMgr(careTaker);
if (conflictMgr.isConflict(mode)) {
ERR("mode(%s) is conflict", mode.getName().c_str());
return MODES_ERROR_CONFLICT;
}
- int ret = priv.check(mode);
- if (MODES_ERROR_NONE != ret) {
- ERR("priv.check() Fail(%d)", ret);
- return ret;
- }
+ if (isTest)
+ return MODES_ERROR_NONE;
if (Mode::MODE_ONESHOT == mode.getModeType()) {
ret = mode.applyOneShot();
void setOptions(const std::set<std::string> &modeDirs, const std::string &xsdFile, const std::string &undoInfoDir);
void init();
void addModeDirectory(const std::string &dirPath);
- int applyMode(const std::string &modeName, ClientPrivilege &priv);
+ int applyMode(const std::string &modeName, ClientPrivilege &priv, bool isTest);
int registerMode(const Mode &mode);
int undoMode(const std::string &modeName);
std::list<std::tuple<std::string, int>> getModes();
ruleMgr = mgr;
}
+gboolean RequestHandler::canApplyModeHandler(mdsDbus *object, GDBusMethodInvocation *invocation,
+ const gchar *modeName, gpointer userData)
+{
+ RETV_IF(NULL == modeMgr, FALSE);
+
+ DBG("mode name = %s", modeName);
+
+ ClientPrivilege privInfo(invocation);
+ int ret = modeMgr->applyMode(modeName, privInfo, true);
+
+ mds_dbus_complete_can_apply(object, invocation, ret);
+
+ return TRUE;
+}
+
gboolean RequestHandler::applyModeHandler(mdsDbus *object, GDBusMethodInvocation *invocation,
const gchar *modeName, gpointer userData)
{
DBG("mode name = %s", modeName);
ClientPrivilege privInfo(invocation);
- int ret = modeMgr->applyMode(modeName, privInfo);
+ int ret = modeMgr->applyMode(modeName, privInfo, false);
mds_dbus_complete_apply_mode(object, invocation, ret);
if (MODES_ERROR_NONE == ret)
class RequestHandler {
public:
+ static gboolean canApplyModeHandler(mdsDbus *object, GDBusMethodInvocation *invocation,
+ const gchar *modeName, gpointer userData);
static gboolean applyModeHandler(mdsDbus *object, GDBusMethodInvocation *invocation,
const gchar *modeName, gpointer userData);
static gboolean undoModeHandler(mdsDbus * object, GDBusMethodInvocation *invocation,
void Supervisor::registerHandler()
{
+ clientConn.addRequestHandler("handle-can-apply", (GCallback)&RequestHandler::canApplyModeHandler);
clientConn.addRequestHandler("handle-apply-mode", (GCallback)&RequestHandler::applyModeHandler);
clientConn.addRequestHandler("handle-undo-mode", (GCallback)&RequestHandler::undoModeHandler);
clientConn.addRequestHandler("handle-register-mode", (GCallback)&RequestHandler::registerModeHandler);
static GMainLoop *_modes_loop;
-#define PRINT(fmt, arg...) printf("\033[31m %d:" fmt "\n \033[0m", __LINE__, ##arg)
+#define PERR(fmt, arg...) printf("\033[31m %d:" fmt "\n \033[0m", __LINE__, ##arg)
static gboolean apply_idler(gpointer data)
{
int ret = modes_apply_mode(data);
if (MODES_ERROR_NONE != ret)
- PRINT("modes_apply_mode() Fail(%d)", ret);
+ PERR("modes_apply_mode() Fail(%d)", ret);
+
+ g_main_loop_quit(_modes_loop);
+ return G_SOURCE_REMOVE;
+}
+
+static gboolean can_apply_idler(gpointer data)
+{
+ int ret = modes_can_apply(data);
+ if (MODES_ERROR_NONE != ret)
+ PERR("modes_can_apply() Fail(%d)", ret);
g_main_loop_quit(_modes_loop);
return G_SOURCE_REMOVE;
{
int ret = modes_undo_mode(data);
if (MODES_ERROR_NONE != ret)
- PRINT("modes_undo_mode() Fail(%d)", ret);
+ PERR("modes_undo_mode() Fail(%d)", ret);
g_main_loop_quit(_modes_loop);
return G_SOURCE_REMOVE;
static void print_usage(const char *exec_name)
{
printf("Usage)\n");
+ printf("\t%s can_apply ModeName\n", exec_name);
printf("\t%s apply ModeName\n", exec_name);
printf("\t%s undo ModeName\n", exec_name);
}
_modes_loop = g_main_loop_new(NULL, FALSE);
if (0 == strcasecmp(argv[1], "apply")) {
g_idle_add(apply_idler, argv[2]);
+ } else if (0 == strcasecmp(argv[1], "can_apply")) {
+ g_idle_add(can_apply_idler, argv[2]);
} else if (0 == strcasecmp(argv[1], "undo")) {
g_idle_add(undo_idler, argv[2]);
} else {
- PRINT("Invalid option(%s)", argv[1]);
+ PERR("Invalid option(%s)", argv[1]);
print_usage(argv[0]);
}
EXPECT_EQ(MODES_ERROR_NO_DATA, result);
}
+TEST_F(ClientTest, canApplyModeP)
+{
+ modes_undo_mode("ex1");
+ int ret = modes_can_apply("ex1");
+ EXPECT_EQ(MODES_ERROR_NONE, ret);
+}
+
+TEST_F(ClientTest, canApplyModeN)
+{
+ int ret = modes_can_apply("ex4");
+ EXPECT_EQ(MODES_ERROR_NO_DATA, ret);
+}
+
+TEST_F(ClientTest, canApplyModeConflictExclusive)
+{
+ modes_undo_mode("ex2");
+ g_idle_add(applyModeIdler, (gpointer)"ex2");
+ g_main_loop_run(loop);
+ int ret = modes_can_apply("ex1");
+ EXPECT_EQ(MODES_ERROR_CONFLICT, ret);
+ modes_undo_mode("ex2");
+}
+
TEST_F(ClientTest, registerMode)
{
g_idle_add(registerModeIdler, NULL);