* limitations under the License.
*/
#include "modes.h"
+
#include <glib.h>
#include "mdsc.h"
#include "mdsc_dbus.h"
RETV_IF(NULL == name, MODES_ERROR_INVALID_PARAMETER);
- dbus_handle = _mdsc_dbus_start();
+ dbus_handle = mdsc_dbus_start();
if (NULL == dbus_handle) {
ERR("_mdsc_dbus_start() Fail");
return MODES_ERROR_SYSTEM;
return ret;
}
- _mdsc_dbus_stop(dbus_handle);
+ mdsc_dbus_stop(dbus_handle);
return MODES_ERROR_NONE;
}
* limitations under the License.
*/
#include "mdsc_dbus.h"
+
#include <glib.h>
#include "mdsc.h"
#include "common/dbus.h"
#include "common/dbus_def.h"
-mdsDbus* _mdsc_dbus_start()
+static mdsDbus *mdsc_proxy = NULL;
+static int mdsc_dbus_cnt = 0;
+
+mdsDbus* mdsc_dbus_start()
{
+ if (mdsc_proxy) {
+ DBG("bus is already connected");
+ mdsc_dbus_cnt++;
+ return mdsc_proxy;
+ }
+
GError *gdbusErr = NULL;
- mdsDbus *ret = mds_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM,
+ mdsc_proxy = mds_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM,
G_DBUS_PROXY_FLAGS_NONE, MODES_DBUS_INTERFACE, MODES_DBUS_OBJPATH, NULL, &gdbusErr);
- if (NULL == ret) {
+ if (NULL == mdsc_proxy) {
ERR("mds_dbus_proxy_new_for_bus_sync() Fail(%s)", gdbusErr ? gdbusErr->message : "unknown");
g_error_free(gdbusErr);
return NULL;
}
- return ret;
+ return mdsc_proxy;
}
-void _mdsc_dbus_stop(mdsDbus *handle)
+void mdsc_dbus_stop(mdsDbus *handle)
{
+ //TODO: I'm not sure when the handle should be released.
+ if (mdsc_dbus_cnt) {
+ mdsc_dbus_cnt--;
+ return;
+ }
+
if (handle)
g_object_unref(handle);
+
+ mdsc_proxy = NULL;
}
#include "common/dbus.h"
-mdsDbus* _mdsc_dbus_start();
-void _mdsc_dbus_stop(mdsDbus *handle);
+mdsDbus* mdsc_dbus_start();
+void mdsc_dbus_stop(mdsDbus *handle);
--- /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"
+
+struct mdsc_noti_data_s {
+ modes_noti_fn cb;
+ void *user_data;
+};
+
+static gulong mdsc_noti_signal_ID = 0;
+static struct mdsc_noti_data_s mdsc_noti_data;
+
+static void _on_changed_mode(mdsDbus *mdsc_dbus, const char *mode, int state, gpointer user_data)
+{
+ RET_IF(NULL == user_data);
+
+ mdsc_noti_data.cb(mode, state, mdsc_noti_data.user_data);
+}
+
+API int modes_subscribe_mode_changes(modes_noti_fn cb, void *user_data)
+{
+ RETV_IF(0 != mdsc_noti_signal_ID, MODES_ERROR_ALREADY);
+
+ mdsDbus *dbus_handle = mdsc_dbus_start();
+ if (NULL == dbus_handle) {
+ ERR("_mdsc_dbus_start() Fail");
+ return MODES_ERROR_SYSTEM;
+ }
+
+ mdsc_noti_data.cb = cb;
+ mdsc_noti_data.user_data = user_data;
+
+ mdsc_noti_signal_ID = g_signal_connect(dbus_handle,
+ "changed-mode",
+ G_CALLBACK(_on_changed_mode),
+ NULL);
+
+ return MODES_ERROR_NONE;
+}
+
+//TODO: modes_noti_disconnect(ModesNotiFunc cb, void *user_data)
+API void modes_unsubscribe_mode_changes()
+{
+ RET_IF(0 == mdsc_noti_signal_ID);
+
+ mdsDbus *dbus_handle = mdsc_dbus_start();
+ if (NULL == dbus_handle)
+ ERR("mdsc_dbus_start() Fail");
+
+ g_signal_handler_disconnect(dbus_handle, mdsc_noti_signal_ID);
+ mdsc_noti_data.cb = NULL;
+ mdsc_noti_data.user_data = NULL;
+
+ mdsc_dbus_stop(dbus_handle);
+}
* limitations under the License.
*/
#include "modes.h"
+
#include <stdlib.h>
#include <glib.h>
#include "mdsc.h"
GList *action_list;
};
-int _mdsc_dbus_register_mode_sync(mdsDbus *mdsc_dbus, GVariant *mode_data)
+static int _mdsc_dbus_register_mode_sync(mdsDbus *mdsc_dbus, GVariant *mode_data)
{
int result = MODES_ERROR_NONE;
gboolean ret;
return result;
}
-void _mdsc_free_action(gpointer data)
+static void _mdsc_free_action(gpointer data)
{
RET_IF(NULL == data);
free(action_data);
}
-GVariant* _mdsc_create_mode_data(modes_h mode)
+static GVariant* _mdsc_create_mode_data(modes_h mode)
{
RETV_IF(NULL == mode, NULL);
RETV_IF(NULL == mode, MODES_ERROR_INVALID_PARAMETER);
- dbus_handle = _mdsc_dbus_start();
+ dbus_handle = mdsc_dbus_start();
if (NULL == dbus_handle) {
- ERR("_mdsc_dbus_start() Fail");
+ ERR("mdsc_dbus_start() Fail");
return MODES_ERROR_SYSTEM;
}
return ret;
}
- _mdsc_dbus_stop(dbus_handle);
+ mdsc_dbus_stop(dbus_handle);
return MODES_ERROR_NONE;
}
* limitations under the License.
*/
#include "modes.h"
+
#include <glib.h>
#include "mdsc.h"
#include "mdsc_dbus.h"
#include "common/dbus.h"
-int _mdsc_dbus_undo_mode_sync(mdsDbus *mdsc_dbus, const char *mode)
+static int _mdsc_dbus_undo_mode_sync(mdsDbus *mdsc_dbus, const char *mode)
{
gboolean ret;
GError *error = NULL;
API int modes_undo_mode(const char *name)
{
int ret;
- mdsDbus* dbus_handle;
+ mdsDbus *dbus_handle;
RETV_IF(NULL == name, MODES_ERROR_INVALID_PARAMETER);
- dbus_handle = _mdsc_dbus_start();
+ dbus_handle = mdsc_dbus_start();
if (NULL == dbus_handle) {
- ERR("_mdsc_dbus_start() Fail");
+ ERR("mdsc_dbus_start() Fail");
return MODES_ERROR_SYSTEM;
}
return ret;
}
- _mdsc_dbus_stop(dbus_handle);
+ mdsc_dbus_stop(dbus_handle);
return MODES_ERROR_NONE;
}
<arg type="(siv)" name="modeData" direction="in"/>
<arg type="i" name="ret" direction="out"/>
</method>
+
+ <signal name="changedMode">
+ <arg type="s" name="modeName"/>
+ <arg type="i" name="modeState"/>
+ </signal>
</interface>
</node>
*/
void modes_destroy_mode(modes_h mode);
+
+/**
+ * @brief Specifies the type of function passed to modes_noti_connect().
+ * @details When the Modes apply/undo a mode, it is called, immediately.
+ * @since_tizen 6.0
+ * @param[in] mode_name The name of mode which was changed state
+ * @param[in] user_data The user data to pass to the function
+ *
+ * @pre The callback must be registered using modes_noti_connect()
+ *
+ * @see modes_subscribe_mode_changes()
+ * @see modes_unsubscribe_mode_changes()
+ */
+typedef int(*modes_noti_fn) (const char *mode_name, int state, void *user_data);
+
+/**
+ * @brief Adds callback for recognizing the changed of mode.
+ * @details Sets a function to be called when the mode is changed.
+ * @since_tizen 6.0
+ *
+ * @param[in] cb The callback function to invoke
+ * @param[in] user_data The user data to pass to the function
+ *
+ * @return 0 on success, otherwise a negative error value.
+ * @retval #MODES_ERROR_NONE Successful
+ * @retval #MODES_ERROR_INVALID_PARAMETER Invalid parameter
+ *
+ * @see modes_unsubscribe_mode_changes()
+ */
+int modes_subscribe_mode_changes(modes_noti_fn cb, void *user_data);
+
+/**
+ * @brief stop recognizing the changed of mode.
+ * @details Removes a function to be called when the mode is changed.
+ * @since_tizen 6.0
+ *
+ * @see modes_subscribe_mode_changes()
+ */
+void modes_unsubscribe_mode_changes();
+
/**
* @}
*/
*/
typedef enum {
MODES_ERROR_NONE = TIZEN_ERROR_NONE, /**< Successful */
+ MODES_ERROR_ALREADY = TIZEN_ERROR_ALREADY_IN_PROGRESS, /** Operation already in progress */
+ MODES_ERROR_NO_DATA = TIZEN_ERROR_NO_DATA, /**< No data available */
+ MODES_ERROR_TIMEOUT = TIZEN_ERROR_TIMED_OUT, /**< Time out */
MODES_ERROR_IO_ERROR = TIZEN_ERROR_IO_ERROR, /**< I/O error */
+ MODES_ERROR_NOT_SUPPORTED = TIZEN_ERROR_NOT_SUPPORTED, /**< Not supported */
MODES_ERROR_OUT_OF_MEMORY = TIZEN_ERROR_OUT_OF_MEMORY, /**< Out of memory */
MODES_ERROR_PERMISSION_DENIED = TIZEN_ERROR_PERMISSION_DENIED, /**< Permission denied */
- MODES_ERROR_NOT_SUPPORTED = TIZEN_ERROR_NOT_SUPPORTED, /**< Not supported */
MODES_ERROR_INVALID_PARAMETER = TIZEN_ERROR_INVALID_PARAMETER, /**< Invalid parameter */
- MODES_ERROR_NO_DATA = TIZEN_ERROR_NO_DATA, /**< No data available */
- MODES_ERROR_TIMEOUT = TIZEN_ERROR_TIMED_OUT, /**< Time out */
- MODES_ERROR_INVALID_TYPE = TIZEN_ERROR_MODES | 0x03, /**< Invalid type */
+ MODES_ERROR_SYSTEM = TIZEN_ERROR_MODES | 0x03, /**< System errors */
MODES_ERROR_CONFLICT = TIZEN_ERROR_MODES | 0x04, /**< Conflict */
- MODES_ERROR_SYSTEM = TIZEN_ERROR_MODES | 0x06, /**< System errors */
} modes_error_e;
/*
* MODES_ERROR_NONE 0
- * MODES_ERROR_IO_ERROR -5
- * MODES_ERROR_OUT_OF_MEMORY -12
- * MODES_ERROR_PERMISSION_DENIED -13
- * MODES_ERROR_NOT_SUPPORTED -1073741822
- * MODES_ERROR_INVALID_PARAMETER -22
- * MODES_ERROR_NO_DATA -61
- * MODES_ERROR_TIMEOUT -1073741823
+ * MODES_ERROR_ALREADY - 114
+ * MODES_ERROR_NO_DATA - 61
+ * MODES_ERROR_TIMEOUT - 1073741823
+ * MODES_ERROR_IO_ERROR - 5
+ * MODES_ERROR_NOT_SUPPORTED - 1073741822
+ * MODES_ERROR_OUT_OF_MEMORY - 12
+ * MODES_ERROR_PERMISSION_DENIED - 13
+ * MODES_ERROR_INVALID_PARAMETER - 22
+ * MODES_ERROR_SYSTEM - 50462717
+ * MODES_ERROR_CONFLICT - 50462716
*/
+
/**
* @}
*/
}
}
-const Mode::ModeType Mode::getModeType() const
+Mode::ModeType Mode::getModeType() const
{
return type;
}
customized = data;
}
-const bool Mode::getCustomized() const
+bool Mode::getCustomized() const
{
return customized;
}
void setModeType(const std::string &data);
void setModeType(int val);
- const ModeType getModeType() const;
+ ModeType getModeType() const;
void setCustomized(bool data);
- const bool getCustomized() const;
+ bool getCustomized() const;
void addAction(Action *action);
std::list<std::shared_ptr<Action>> getActionList() const;
int ret = modeMgr->applyMode(modeName);
mds_dbus_complete_apply_mode(object, invocation, ret);
+ if (MODES_ERROR_NONE == ret)
+ mds_dbus_emit_changed_mode(object, modeName, 1);
return TRUE;
}
int ret = modeMgr->undoMode(modeName);
mds_dbus_complete_undo_mode(object, invocation, ret);
+ if (MODES_ERROR_NONE == ret)
+ mds_dbus_emit_changed_mode(object, modeName, 0);
return TRUE;
}
std::istringstream iss(val);
iss >> value;
} else {
- return MODES_ERROR_INVALID_TYPE;
+ ERR("Action(%s) has Invalid val(%s)", ruleName.c_str(), val.c_str());
+ return MODES_ERROR_NOT_SUPPORTED;
}
}
{
ValueChecker checker;
if (false == checker.checkValue(T(), value)) {
- ERR("checkValue() Fail");
- return MODES_ERROR_INVALID_TYPE;
+ ERR("checkValue(Rule:%s, Alias:%s, Val:%s) Fail",
+ ruleName.c_str(), alias.c_str(), value.c_str());
+ return MODES_ERROR_NOT_SUPPORTED;
}
T realVal;
FILE(GLOB SRC "modes_test_main.cpp")
#=======================================================================================#
+SET(GTEST_NOTI "modes-gtest-noti")
+SET(GTEST_NOTI_SRCS modes_test_noti.cpp)
+ADD_EXECUTABLE(${GTEST_NOTI} ${SRC} ${GTEST_NOTI_SRCS})
+TARGET_LINK_LIBRARIES(${GTEST_NOTI} ${CLIENT} ${gtest_pkgs_LIBRARIES})
+INSTALL(TARGETS ${GTEST_NOTI} DESTINATION ${TEST_INSTALL_DIR})
+#=======================================================================================#
+SET(GTEST_CLIENT "modes-gtest-client")
+SET(GTEST_CLIENT_SRCS modes_test_client.cpp)
+ADD_EXECUTABLE(${GTEST_CLIENT} ${SRC} ${GTEST_CLIENT_SRCS})
+TARGET_LINK_LIBRARIES(${GTEST_CLIENT} ${CLIENT} ${gtest_pkgs_LIBRARIES})
+INSTALL(TARGETS ${GTEST_CLIENT} DESTINATION ${TEST_INSTALL_DIR})
+#=======================================================================================#
+SET(TEST_APPLY_MODE "modes-apply-mode-test")
+SET(TEST_APPLY_MODE_SRC modes_apply_mode.c)
+ADD_EXECUTABLE(${TEST_APPLY_MODE} ${TEST_APPLY_MODE_SRC})
+TARGET_LINK_LIBRARIES(${TEST_APPLY_MODE} ${CLIENT})
+INSTALL(TARGETS ${TEST_APPLY_MODE} DESTINATION ${TEST_INSTALL_DIR})
+#=======================================================================================#
SET(GTEST_MODEMGR "modes-gtest-modemgr")
FILE(GLOB GTEST_MODEMGR_SRCS
${SUPERVISOR_DIR}/ModeTag.cpp
ADD_EXECUTABLE(${GTEST_PARSER} ${SRC} ${GTEST_PARSER_SRCS})
TARGET_LINK_LIBRARIES(${GTEST_PARSER} ${gtest_pkgs_LIBRARIES} dl)
INSTALL(TARGETS ${GTEST_PARSER} DESTINATION ${TEST_INSTALL_DIR})
-
-#=======================================================================================#
-SET(GTEST_CLIENT "modes-gtest-client")
-SET(GTEST_CLIENT_SRCS modes_test_client.cpp)
-ADD_EXECUTABLE(${GTEST_CLIENT} ${SRC} ${GTEST_CLIENT_SRCS})
-TARGET_LINK_LIBRARIES(${GTEST_CLIENT} ${CLIENT} ${gtest_pkgs_LIBRARIES})
-INSTALL(TARGETS ${GTEST_CLIENT} DESTINATION ${TEST_INSTALL_DIR})
-
-#=======================================================================================#
-SET(TEST_APPLY_MODE "modes-apply-mode-test")
-SET(TEST_APPLY_MODE_SRC modes_apply_mode.c)
-ADD_EXECUTABLE(${TEST_APPLY_MODE} ${TEST_APPLY_MODE_SRC})
-TARGET_LINK_LIBRARIES(${TEST_APPLY_MODE} ${CLIENT})
-INSTALL(TARGETS ${TEST_APPLY_MODE} DESTINATION ${TEST_INSTALL_DIR})
-
#=======================================================================================#
SET(GTEST_GENERATOR "modes-gtest-generator")
FILE(GLOB GTEST_GENERATOR_SRCS
else # on Target
cp $DATA_DIR/schema/*.xsd ./
./modes-gtest-client
+ ./modes-gtest-noti
fi
./modes-gtest-rulemgr
loop = NULL;
}
- static gboolean apply_mode_idler(gpointer data)
+ static gboolean applyModeIdler(gpointer data)
{
result = modes_apply_mode((const char*)data);
return G_SOURCE_REMOVE;
}
- static gboolean undo_mode_idler(gpointer data)
+ static gboolean undoModeIdler(gpointer data)
{
result = modes_apply_mode((const char*)data);
EXPECT_EQ(MODES_ERROR_NONE, result);
- sleep(5);
+ sleep(1);
result = modes_undo_mode((const char*)data);
g_main_loop_quit(loop);
return G_SOURCE_REMOVE;
}
- static gboolean request_register_mode_idler(gpointer data)
+ static gboolean registerModeIdler(gpointer data)
{
modes_h mode_handle = modes_create_mode("created", MODES_TYPE_MODE_NORMAL);
action_h action_handle[2];
TEST_F(ClientTest, applyModeP)
{
- g_idle_add(apply_mode_idler, (gpointer)"ex1");
+ g_idle_add(applyModeIdler, (gpointer)"ex1");
g_main_loop_run(loop);
EXPECT_EQ(MODES_ERROR_NONE, result);
}
TEST_F(ClientTest, applyModeN)
{
- g_idle_add(apply_mode_idler, (gpointer)"non_ex2");
+ g_idle_add(applyModeIdler, (gpointer)"non_ex2");
g_main_loop_run(loop);
EXPECT_EQ(MODES_ERROR_NO_DATA, result);
}
TEST_F(ClientTest, registerMode)
{
- g_idle_add(request_register_mode_idler, NULL);
+ g_idle_add(registerModeIdler, NULL);
g_main_loop_run(loop);
EXPECT_EQ(MODES_ERROR_NONE, result);
}
TEST_F(ClientTest, undoModeEx1)
{
modes_undo_mode("ex1");
- g_idle_add(undo_mode_idler, (gpointer)"ex1");
+ g_idle_add(undoModeIdler, (gpointer)"ex1");
g_main_loop_run(loop);
EXPECT_EQ(MODES_ERROR_NONE, result);
}
TEST_F(ClientTest, undoModeEx2)
{
modes_undo_mode("ex2");
- g_idle_add(undo_mode_idler, (gpointer)"ex2");
+ g_idle_add(undoModeIdler, (gpointer)"ex2");
g_main_loop_run(loop);
EXPECT_EQ(MODES_ERROR_NONE, result);
}
--- /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 <glib.h>
+#include <gtest/gtest.h>
+#include <modes.h>
+
+class ClientNotiTest : 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 undoTimeout(gpointer data)
+ {
+ expectedState = 0;
+ int ret = modes_undo_mode((const char*)data);
+ EXPECT_EQ(MODES_ERROR_NONE, ret);
+
+ g_main_loop_quit(loop);
+ return G_SOURCE_REMOVE;
+ }
+
+ static int notiFunc(const char *modeName, int state, void *user_data)
+ {
+ char *requestMode = (char*)user_data;
+
+ std::cout << "Changed Mode : " << modeName << std::endl;
+ EXPECT_EQ(requestMode, std::string(modeName));
+ std::cout << "state : " << state << std::endl;
+ EXPECT_EQ(expectedState, state);
+
+ g_main_loop_quit(loop);
+ return MODES_ERROR_NONE;
+ }
+
+ static int expectedState;
+ static GMainLoop *loop;
+};
+
+int ClientNotiTest::expectedState = 1;
+GMainLoop *ClientNotiTest::loop = NULL;
+
+TEST_F(ClientNotiTest, notiConnect)
+{
+ const char *testMode = "ex2";
+ int ret = modes_subscribe_mode_changes(notiFunc, (void*)testMode);
+ EXPECT_EQ(MODES_ERROR_NONE, ret);
+
+ ClientNotiTest::expectedState = 1;
+ ret = modes_apply_mode(testMode);
+ EXPECT_EQ(MODES_ERROR_NONE, ret);
+
+ g_timeout_add_seconds(1, undoTimeout, (void*)testMode);
+
+ g_main_loop_run(loop);
+
+ modes_unsubscribe_mode_changes();
+}
ModeXMLParser modeparser2("tizen_invalid2_mode.xml", ruleMgr, piMgr);
EXPECT_THROW(modeparser2.getMode(), ModesEx);
}
+
+TEST_F(ParserTest, printError)
+{
+ EXPECT_NO_THROW(
+ std::cout << "MODES_ERROR_NONE " << MODES_ERROR_NONE << std::endl;
+ std::cout << "MODES_ERROR_ALREADY " << MODES_ERROR_ALREADY << std::endl;
+ std::cout << "MODES_ERROR_NO_DATA " << MODES_ERROR_NO_DATA << std::endl;
+ std::cout << "MODES_ERROR_TIMEOUT " << MODES_ERROR_TIMEOUT << std::endl;
+ std::cout << "MODES_ERROR_IO_ERROR " << MODES_ERROR_IO_ERROR << std::endl;
+ std::cout << "MODES_ERROR_NOT_SUPPORTED " << MODES_ERROR_NOT_SUPPORTED << std::endl;
+ std::cout << "MODES_ERROR_OUT_OF_MEMORY " << MODES_ERROR_OUT_OF_MEMORY << std::endl;
+ std::cout << "MODES_ERROR_PERMISSION_DENIED " << MODES_ERROR_PERMISSION_DENIED << std::endl;
+ std::cout << "MODES_ERROR_INVALID_PARAMETER " << MODES_ERROR_INVALID_PARAMETER << std::endl;
+ std::cout << "MODES_ERROR_SYSTEM " << MODES_ERROR_SYSTEM << std::endl;
+ std::cout << "MODES_ERROR_CONFLICT " << MODES_ERROR_CONFLICT << std::endl;
+ );
+}