Add modes_can_apply()
authorJinWang An <jinwang.an@samsung.com>
Fri, 13 Dec 2019 01:21:03 +0000 (10:21 +0900)
committerYoungjae Shin <yj99.shin@samsung.com>
Wed, 18 Mar 2020 08:53:50 +0000 (17:53 +0900)
client/mdsc_can_apply.c [new file with mode: 0644]
common/dbus.xml
include/modes.h
supervisor/ModeManager.cpp
supervisor/ModeManager.h
supervisor/RequestHandler.cpp
supervisor/RequestHandler.h
supervisor/Supervisor.cpp
unittest/modes_mode_test.c
unittest/modes_test_client.cpp

diff --git a/client/mdsc_can_apply.c b/client/mdsc_can_apply.c
new file mode 100644 (file)
index 0000000..99e4650
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * 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;
+}
index 46901a6..604b976 100644 (file)
@@ -4,6 +4,10 @@
                        <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"/>
@@ -12,7 +16,7 @@
                        <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>
index 9c36255..12304b4 100644 (file)
@@ -54,6 +54,24 @@ extern "C" {
 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
index 5bf5f58..2b3cd60 100644 (file)
@@ -76,7 +76,9 @@ void ModeManager::addModeName(ModeParser *parser, const string &path)
        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) {
@@ -93,17 +95,20 @@ int ModeManager::applyMode(const string &modeName, ClientPrivilege &priv)
 
                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();
index feccb17..d2f8306 100644 (file)
@@ -38,7 +38,7 @@ public:
        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();
index 6ae2e4c..f5edffa 100644 (file)
@@ -35,6 +35,21 @@ void RequestHandler::setRuleManager(RuleManager *mgr)
        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)
 {
@@ -44,7 +59,7 @@ gboolean RequestHandler::applyModeHandler(mdsDbus *object, GDBusMethodInvocation
        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)
index e0f91b6..363e562 100644 (file)
@@ -24,6 +24,8 @@ MODES_NAMESPACE_BEGIN
 
 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,
index e633e8f..92c4de2 100644 (file)
@@ -62,6 +62,7 @@ void Supervisor::setOptions(const ModesConfig &config)
 
 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);
index 4468f2f..64628b5 100644 (file)
 
 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;
@@ -39,7 +49,7 @@ static gboolean undo_idler(gpointer data)
 {
        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;
@@ -48,6 +58,7 @@ static gboolean undo_idler(gpointer data)
 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);
 }
@@ -62,10 +73,12 @@ int main(int argc, char **argv)
        _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]);
        }
 
index 8231785..e31cd0c 100644 (file)
@@ -91,6 +91,29 @@ TEST_F(ClientTest, applyModeN)
        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);