Add cooldown feature 73/132673/2
authorWootak Jung <wootak.jung@samsung.com>
Wed, 7 Jun 2017 06:21:51 +0000 (15:21 +0900)
committerWootak Jung <wootak.jung@samsung.com>
Wed, 7 Jun 2017 06:27:08 +0000 (15:27 +0900)
Change-Id: I40bd6b94e96c25da381bd0c42d43fb5fd356cccd

module/CMakeLists.txt
module/include/callmgr-cooldown.h [new file with mode: 0644]
module/src/callmgr-cooldown.c [new file with mode: 0644]
packaging/call-manager.spec
service/include/callmgr-core.h
service/src/callmgr-core.c

index 69268a9e38e2b720a67c1076282518912787c03f..7edc7432ee169f143b1d2517d7134bcf052fb9c6 100644 (file)
@@ -49,6 +49,7 @@ SET(MODULE_SRCS
        src/callmgr-vr.c
        src/callmgr-sensor.c
        src/callmgr-answer-msg.c
+       src/callmgr-cooldown.c
 )
 IF(_ENABLE_EXT_FEATURE)
 SET(MODULE_SRCS ${MODULE_SRCS}
diff --git a/module/include/callmgr-cooldown.h b/module/include/callmgr-cooldown.h
new file mode 100644 (file)
index 0000000..095aa3f
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+
+#ifndef __CALLMGR_COOLDOWN_H__
+#define __CALLMGR_COOLDOWN_H__
+
+#define DBUS_NAME_DEVICED "org.tizen.system.deviced"
+#define DBUS_PATH_DEVICED_SYSNOTI "/Org/Tizen/System/DeviceD/SysNoti"
+#define DBUS_INTERFACE_DEVICED_SYSNOTI "org.tizen.system.deviced.SysNoti"
+#define DBUS_METHOD_GET_COOLDOWN_STATUS "GetCoolDownStatus"
+#define DBUS_SIGNAL_COOLDOWN_CHANGED "CoolDownChanged"
+
+typedef struct __cooldown_data *callmgr_cooldown_h;
+
+typedef enum {
+       CALLMGR_COOLDOWN_STATUS_RELEASE,
+       CALLMGR_COOLDOWN_STATUS_WARNING,
+       CALLMGR_COOLDOWN_STATUS_LIMIT
+} callmgr_cooldown_status_e;
+
+typedef enum {
+       CALLMGR_COOLDOWN_EVENT_LIMIT_ACTION
+} callmgr_cooldown_event_e;
+
+typedef void (*callmgr_cooldown_event_cb)(callmgr_cooldown_event_e event, const void *event_data, void *user_data);
+int _callmgr_cooldown_get_cooldown_status(callmgr_cooldown_h handle, callmgr_cooldown_status_e *status);
+int _callmgr_cooldown_init(callmgr_cooldown_h *cooldown_handle, callmgr_cooldown_event_cb cb, void *user_data);
+void _callmgr_cooldown_deinit(callmgr_cooldown_h cooldown_handle);
+
+#endif /* __CALLMGR_COOLDOWN_H__ */
+
diff --git a/module/src/callmgr-cooldown.c b/module/src/callmgr-cooldown.c
new file mode 100644 (file)
index 0000000..10cd96b
--- /dev/null
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2017 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 "callmgr-cooldown.h"
+#include "callmgr-util.h"
+#include "callmgr-log.h"
+
+struct __cooldown_data {
+       callmgr_cooldown_event_cb event_cb;
+       void *user_data;
+
+       GDBusConnection *dbus_conn;
+       callmgr_cooldown_status_e cooldown_status;
+       guint cooldown_subs_id;
+};
+
+int _callmgr_cooldown_get_cooldown_status(callmgr_cooldown_h handle, callmgr_cooldown_status_e *status)
+{
+       CM_RETURN_VAL_IF_FAIL(handle, -1);
+       dbg("cooldown status: %d", handle->cooldown_status);
+       *status = handle->cooldown_status;
+       return 0;
+}
+
+static void __callmgr_cooldown_subscribe_cooldown_signal_cb(GDBusConnection *connection,
+       const gchar *sender_name, const gchar *object_path,
+       const gchar *interface_name, const gchar *signal_name,
+       GVariant *parameters, gpointer user_data)
+{
+       gchar *cooldown_string = NULL;
+       callmgr_cooldown_h handle = user_data;
+
+       CM_RETURN_IF_FAIL(handle);
+       dbg("__callmgr_cooldown_subscribe_cooldown_signal_cb");
+
+       if (g_strcmp0(signal_name, DBUS_SIGNAL_COOLDOWN_CHANGED) == 0) {
+               g_variant_get(parameters, "(s)", &cooldown_string);
+               if (cooldown_string) {
+                       dbg("cooldown status: %s", cooldown_string);
+                       if (strncasecmp(cooldown_string, "LimitAction", strlen("LimitAction")) == 0) {
+                               handle->cooldown_status = CALLMGR_COOLDOWN_STATUS_LIMIT;
+                               handle->event_cb(CALLMGR_COOLDOWN_EVENT_LIMIT_ACTION, NULL, handle->user_data);
+                       } else if (strncasecmp(cooldown_string, "Release", strlen("Release")) == 0) {
+                               handle->cooldown_status = CALLMGR_COOLDOWN_STATUS_RELEASE;
+                       }
+               } else {
+                       err("Failed to get cooldown status.");
+               }
+               g_free(cooldown_string);
+       }
+}
+
+static void __callmgr_cooldown_subscribe_cooldown_signal(callmgr_cooldown_h handle)
+{
+       CM_RETURN_IF_FAIL(handle);
+       dbg("__callmgr_cooldown_subscribe_cooldown_signal");
+
+       if (!handle->dbus_conn) {
+               GError *error = NULL;
+               handle->dbus_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
+               if (!handle->dbus_conn) {
+                       err("g_bus_get_sync() is failed. (%s)", error->message);
+                       g_error_free(error);
+                       return;
+               }
+       }
+
+       handle->cooldown_subs_id = g_dbus_connection_signal_subscribe(handle->dbus_conn,
+               DBUS_NAME_DEVICED,
+               DBUS_INTERFACE_DEVICED_SYSNOTI,
+               DBUS_SIGNAL_COOLDOWN_CHANGED,
+               DBUS_PATH_DEVICED_SYSNOTI,
+               NULL, G_DBUS_SIGNAL_FLAGS_NONE,
+               __callmgr_cooldown_subscribe_cooldown_signal_cb, handle, NULL);
+       if (handle->cooldown_subs_id == 0) {
+               err("g_dbus_connection_signal_subscribe() is failed.");
+               g_object_unref(handle->dbus_conn);
+       }
+}
+
+static void __callmgr_cooldown_get_cooldown_status(callmgr_cooldown_h handle)
+{
+       GError *error = NULL;
+       GVariant *dbus_result;
+
+       CM_RETURN_IF_FAIL(handle);
+       dbg("__callmgr_cooldown_get_cooldown_status");
+
+       if (!handle->dbus_conn) {
+               handle->dbus_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
+               if (!handle->dbus_conn) {
+                       err("g_bus_get_sync() is failed. (%s)", error->message);
+                       g_error_free(error);
+                       return;
+               }
+       }
+
+       dbus_result = g_dbus_connection_call_sync(handle->dbus_conn,
+               DBUS_NAME_DEVICED,
+               DBUS_PATH_DEVICED_SYSNOTI,
+               DBUS_INTERFACE_DEVICED_SYSNOTI,
+               DBUS_METHOD_GET_COOLDOWN_STATUS,
+               NULL, NULL, G_DBUS_CALL_FLAGS_NONE,
+               60 * 1000, NULL, &error);
+       if (dbus_result) {
+               gchar *status = NULL;
+               g_variant_get(dbus_result, "(s)", &status);
+               dbg("cooldown status: %s", status);
+               if (!g_strcmp0(status, "LimitAction") || !g_strcmp0(status, "ShutDown")) {
+                       dbg("cooldown enabled.");
+                       handle->cooldown_status = CALLMGR_COOLDOWN_STATUS_LIMIT;
+               } else {
+                       dbg("cooldown disabled.");
+               }
+               g_free(status);
+       } else {
+               err("g_dbus_connection_call_sync() is failed. (%s)", error->message);
+               g_error_free(error);
+       }
+}
+
+int _callmgr_cooldown_init(callmgr_cooldown_h *cooldown_handle, callmgr_cooldown_event_cb cb, void *user_data)
+{
+       struct __cooldown_data *handle;
+
+       CM_RETURN_VAL_IF_FAIL(cooldown_handle, -1);
+       dbg("_callmgr_cooldown_init");
+
+       handle = calloc(1, sizeof(struct __cooldown_data));
+       CM_RETURN_VAL_IF_FAIL(handle, -1);
+
+       handle->event_cb = cb;
+       handle->user_data = user_data;
+       handle->cooldown_status = CALLMGR_COOLDOWN_STATUS_RELEASE;
+       __callmgr_cooldown_get_cooldown_status(handle);
+       __callmgr_cooldown_subscribe_cooldown_signal(handle);
+       *cooldown_handle = handle;
+
+       return 0;
+}
+
+void _callmgr_cooldown_deinit(callmgr_cooldown_h cooldown_handle)
+{
+       CM_RETURN_IF_FAIL(cooldown_handle);
+       dbg("_callmgr_cooldown_deinit");
+
+       if (cooldown_handle->cooldown_subs_id) {
+               g_dbus_connection_signal_unsubscribe(cooldown_handle->dbus_conn,
+                       cooldown_handle->cooldown_subs_id);
+               cooldown_handle->cooldown_subs_id = 0;
+       }
+
+       if (cooldown_handle->dbus_conn) {
+               g_object_unref(cooldown_handle->dbus_conn);
+               cooldown_handle->dbus_conn = NULL;
+       }
+}
+
index 970d0dbe5e27bcf14185b94fcc091a6732c25059..d88be79043788c9ee49183b40b4bf9c5f587bbf3 100644 (file)
@@ -1,6 +1,6 @@
 %define major 0
 %define minor 2
-%define patchlevel 17
+%define patchlevel 18
 %define ext_feature 0
 
 Name:           call-manager
index 7000226b6130c3d049ff64e6ee44fdf808b156a6..ba6b002f2a4752a0092db8333be3849ca49956ad 100644 (file)
@@ -30,6 +30,7 @@
 #include "callmgr-sensor.h"
 #include "callmgr-vr.h"
 #include "callmgr-answer-msg.h"
+#include "callmgr-cooldown.h"
 
 #define SOUND_MGR_PATH_NAME "/org/pulseaudio/StreamManager"
 #define SOUND_MGR_INTERFACE_NAME "org.pulseaudio.StreamManager"
@@ -179,6 +180,7 @@ typedef struct _callmgr_core_data {
        callmgr_sensor_handle_h sensor_handle;
        callmgr_vr_handle_h vr_handle;
        callmgr_answer_msg_h answer_msg_handle;
+       callmgr_cooldown_h cooldown_handle;
 
        callmgr_call_data_t *incom;
        callmgr_call_data_t *active_dial;
index af45e2af970671eb16a6ca9e2ec0755f330787cc..b0e85f258faf429b62a167f3836380578fb14911 100644 (file)
@@ -2013,6 +2013,21 @@ static void __callmgr_core_process_sensor_events(cm_sensor_event_type_e event_ty
        }
 }
 
+static void __callmgr_core_process_cooldown_events(callmgr_cooldown_event_e event, const void *event_data, void *user_data)
+{
+       callmgr_core_data_t *core_data = user_data;
+
+       CM_RETURN_IF_FAIL(core_data);
+       info("cooldown event: %d", event);
+
+       switch (event) {
+       case CALLMGR_COOLDOWN_EVENT_LIMIT_ACTION:
+               dbg("cooldown mode is enabled. release cs call.");
+               _callmgr_telephony_end_call(core_data->telephony_handle, 0, CM_TEL_CALL_RELEASE_TYPE_ALL_ACTIVE_CALLS);
+               break;
+       }
+}
+
 int _callmgr_core_init(callmgr_core_data_t **o_core_data)
 {
        CM_RETURN_VAL_IF_FAIL(o_core_data, -1);
@@ -2048,6 +2063,10 @@ int _callmgr_core_init(callmgr_core_data_t **o_core_data)
        if (!core_data->vr_handle)
                err("core_data->vr_handle is NULL");
 
+       _callmgr_cooldown_init(&core_data->cooldown_handle, __callmgr_core_process_cooldown_events, core_data);
+       if (!core_data->cooldown_handle)
+               err("core_data->cooldown_handle is NULL");
+
        *o_core_data = core_data;
 
        _callmgr_ct_set_missed_call_notification();
@@ -2067,6 +2086,7 @@ int _callmgr_core_deinit(callmgr_core_data_t *core_data)
        _callmgr_vr_deinit(core_data->vr_handle);
        if (core_data->audio_routing_enabled)
                _callmgr_core_shutdown_dbus_call_routing_status(core_data);
+       _callmgr_cooldown_deinit(core_data->cooldown_handle);
 
        g_free(core_data);
        return 0;
@@ -2419,6 +2439,7 @@ int _callmgr_core_process_dial(callmgr_core_data_t *core_data, const char *numbe
        gboolean is_security_lock = FALSE;
        gboolean is_ui_visible = FALSE;
        cm_telepony_sim_slot_type_e active_sim = CM_TELEPHONY_SIM_UNKNOWN;
+       callmgr_cooldown_status_e cooldown_status;
 
        int ecc_category = -1;
        callmgr_call_error_cause_e err_cause = CALL_ERR_CAUSE_UNKNOWN_E;
@@ -2447,6 +2468,14 @@ int _callmgr_core_process_dial(callmgr_core_data_t *core_data, const char *numbe
                }
        }
 
+       _callmgr_cooldown_get_cooldown_status(core_data->cooldown_handle, &cooldown_status);
+       if (cooldown_status == CALLMGR_COOLDOWN_STATUS_LIMIT && !is_emergency_call) {
+               dbg("cooldown mode is enabled. only emergency call can be made.");
+               _callmgr_util_launch_popup(CALL_POPUP_CALL_ERR, CALL_ERR_EMERGENCY_ONLY, number, 0, NULL, NULL);
+               _callmgr_dbus_send_dial_status(core_data, CALL_MANAGER_DIAL_FAIL);
+               return -1;
+       }
+
        /* Get call count */
        if (_callmgr_telephony_get_call_count(core_data->telephony_handle, &call_cnt) < 0) {
                err("get call count err");