--- /dev/null
+Ja-young Gu <jygu@samsung.com>
+JunHwan An <jh48.an@samsung.com>
--- /dev/null
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(ui_notifier-plugin C)
+
+### Global setting ###
+SET(PREFIX ${CMAKE_INSTALL_PREFIX})
+SET(EXEC_PREFIX "\${prefix}")
+SET(LIBDIR ${LIB_INSTALL_DIR})
+SET(INCLUDEDIR "\${prefix}/include")
+SET(PKGCONFIGDIR "${PREFIX}/${LIBDIR}/pkgconfig" CACHE PATH PKGCONFIGDIR)
+SET(CMAKE_INSTALL_PREFIX "${PREFIX}")
+
+# Set required packages
+INCLUDE(FindPkgConfig)
+pkg_check_modules(pkgs REQUIRED
+ glib-2.0
+ tcore
+ aul
+ capi-system-device
+ pkgmgr
+ vconf
+ libtzplatform-config
+)
+
+FOREACH(flag ${pkgs_CFLAGS})
+ SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror -Wextra -fvisibility=hidden -fPIC -fdata-sections -ffunction-sections -Wl,--gc-sections")
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-parameter -Wno-missing-field-initializers -Wdeclaration-after-statement -Wmissing-declarations -Wredundant-decls -Wcast-align")
+
+ADD_DEFINITIONS("-DFEATURE_TLOG_DEBUG")
+ADD_DEFINITIONS("-DTCORE_LOG_TAG=\"UI_NOTI\"")
+ADD_DEFINITIONS("-DPLUGIN_VERSION=${VERSION}")
+ADD_DEFINITIONS("-DEXPORT_API=__attribute__((visibility(\"default\")))")
+
+IF (FEATURE_MULTISIM)
+ ADD_DEFINITIONS("-DTIZEN_FEATURE_MULTISIM")
+ENDIF (FEATURE_MULTISIM)
+
+INCLUDE_DIRECTORIES(
+ ${CMAKE_SOURCE_DIR}/inc/
+)
+
+MESSAGE(${CMAKE_C_FLAGS})
+MESSAGE(${pkgs_LDFLAGS})
+
+SET(SRCS
+ src/desc.c
+ src/notifier.c
+ src/notifier_launcher.c
+ src/notifier_internal.c
+ src/notifier_preferred_network.c
+ src/notifier_preferred_voice.c
+ src/notifier_util.c
+)
+
+# library build
+ADD_LIBRARY(${PROJECT_NAME} SHARED ${SRCS} ${CDMA_SRCS} ${ACTIVATION_SRCS} ${TEST_SRCS})
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_LDFLAGS})
+SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES PREFIX "" OUTPUT_NAME ${PROJECT_NAME})
+
+# install
+INSTALL(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION ${LIBDIR}/telephony/plugins)
--- /dev/null
+/*
+ * tel-plugin-ui_notifier
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Ja-young Gu <jygu@samsung.com>
+ *
+ * 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.
+ */
+
+#pragma once
+
+#include <glib.h>
+#include <tcore.h>
+
+#include "notifier_internal.h"
+
+gboolean ui_notifier_init(TcorePlugin *plugin);
+void ui_notifier_deinit(TcorePlugin *plugin);
+
+sim_slot_id __get_sim_slotid(CoreObject *source);
--- /dev/null
+/*
+ * tel-plugin-ui_notifier
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Ja-young Gu <jygu@samsung.com>
+ *
+ * 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.
+ */
+
+#pragma once
+
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <glib.h>
+#include <gio/gio.h>
+
+////////////////////// SIM //////////////////////////
+#define IPC_MSG_SIM_NOT_PRESENTED "SimNotPresented"
+#define IPC_MSG_SIM_CARD_REMOVED "SimRemoved"
+#define IPC_MSG_SIM_CARD_ERROR "SimError"
+#define IPC_MSG_SIM_CARD_CRASHED "SimCrashed"
+
+////////////////////// NETWORK //////////////////////////
+/* Emergency cb mode */
+#define IPC_MSG_NETWORK_EMERGENCY_CB_MODE_ENTER "NetworkEmergencyCbModeEnter"
+#define IPC_MSG_NETWORK_EMERGENCY_CB_MODE_EXIT "NetworkEmergencyCbModeExit"
+#define IPC_MSG_NETWORK_EMERGENCY_CB_MODE_READY "NetworkEmergencyCbModeReady"
+
+/* No Svc after manual network selection */
+#define IPC_MSG_SIM1_ADD_NETWORK_MANUAL_FAIL_NOTI "add_sim1_manual_network_fail_noti"
+#define IPC_MSG_SIM1_DEL_NETWORK_MANUAL_FAIL_NOTI "del_sim1_manual_network_fail_noti"
+
+#define IPC_MSG_SIM2_ADD_NETWORK_MANUAL_FAIL_NOTI "add_sim2_manual_network_fail_noti"
+#define IPC_MSG_SIM2_DEL_NETWORK_MANUAL_FAIL_NOTI "del_sim2_manual_network_fail_noti"
+
+/* No Svc after manual plmn selection */
+#define IPC_MSG_NETWORK_MANUAL_FAIL_POPUP "network_manual_fail_popup"
+/* Roaming and roaming data allowed disalbed */
+#define IPC_MSG_NETWORK_DATA_ROAMING_POPUP "network_data_roaming_popup"
+/* Roaming > Home network, Erase data roaming notification */
+#define IPC_MSG_NETWORK_DEL_DATA_ROAMING "del_network_data_roaming"
+
+/* DSAC rectricted */
+#define IPC_MSG_ADD_NETWORK_CS_RESTRICTED_NOTI "add_cs_restricted_state_noti"
+#define IPC_MSG_ADD_NETWORK_PS_RESTRICTED_NOTI "add_ps_restricted_state_noti"
+#define IPC_MSG_ADD_NETWORK_CS_PS_RESTRICTED_NOTI "add_cs_ps_restricted_state_noti"
+#define IPC_MSG_DEL_NETWORK_RESTRICTED_NOTI "del_restricted_state_noti"
+
+/* Location update reject cause display */
+#define IPC_MSG_DISPLAY_NETWORK_LU_REJECT_CAUSE "DisplayNetworkLuRejectCause"
+
+/* NETWORK - Display MIP ERROR Cause */
+#define IPC_MSG_DISPLAY_MIP_ERROR_CAUSE "DisplayMIPErrorCause"
+
+/* NETWORK - Display NITZ Time Update */
+#define IPC_MSG_DISPLAY_NITZ_TIME_UPDATE "DisplayNitzTimeUpdate"
+#define IPC_MSG_NITZ_MANUL_DATE_AND_TIME "nitz_manual_date_and_time"
+
+////////////////////// CALL //////////////////////////
+/* display information */
+#define IPC_CALL_DISPLAY_INFORMATION "DisplayInformation"
+
+////////////////////// activation ///////////////////
+#define IPC_MSG_NETWORK_ACTIVATION_MODE "Network_Activation_Mode"
+#define IPC_MSG_NETWORK_ACTIVATION_PASS "Network_Activation_Pass"
+#define IPC_MSG_NETWORK_ACTIVATION_FAIL "Network_Activation_Fail"
+#define IPC_MSG_NETWORK_ACTIVATION_FAIL_3TIMES "Network_Activation_Fail_3Times"
+#define IPC_MSG_NETWORK_ACTIVATION_OTAPA_COMMITTED "Network_Activation_Otapa_Committed"
+
+#define NO_SVC_WAITING_TIMEOUT (25)
+#define NITZ_TIMEZONE_SELECT_WAITING_TIMEOUT (30)
+
+#define PROP_NET_NITZ_TIMEZONE "nitz_timezone"
+
+struct activation_data {
+ int activation_fail_count;
+ CoreObject *co_modem;
+ char *esn;
+} ;
+
+/**
+ * This structure defines the data needed to create desktop file.
+ */
+struct sat_desktop_file_data {
+ gboolean is_event; /* TRUE if any even available to process */
+ gchar *title; /**<title of the sim*/
+};
+
+typedef struct activation_data activation_data_t;
+
+/* Modem Plugin related data for data handling wrt SIM1 or SIM2 */
+typedef enum {
+ SLOT_ID_DEFAULT,
+ SLOT_ID_PRIMARY = SLOT_ID_DEFAULT,
+ SLOT_ID_SECONDARY,
+ SLOT_ID_TERTIARY,
+ SLOT_ID_MAX
+} sim_slot_id;
+
+typedef struct manual_plmn_cb_data {
+ void *ud;
+ sim_slot_id id;
+} manual_plmn_data;
+
+struct __telephony_popup_payload_t {
+ char *message;
+ char *param;
+};
+
+struct ui_notifier_user_data {
+ enum tel_sim_status sim_status[SLOT_ID_MAX];
+ enum telephony_network_service_type svc_type[SLOT_ID_MAX];
+
+ gboolean flight_mode;
+ gboolean prop_event_registered[SLOT_ID_MAX];
+ gboolean nitz_popup_launched;
+ gboolean first_bootup_sim[SLOT_ID_MAX];
+ gboolean mobile_data_allowed;
+ gboolean roaming_data_allowed;
+ gboolean roaming_popup_launched;
+ gboolean manual_plmn_noti_launched[SLOT_ID_MAX];
+ gboolean manual_plmn_popup_required[SLOT_ID_MAX];
+ gboolean roaming_status[SLOT_ID_MAX];
+
+ unsigned char retry_count;
+
+ char *manual_plmn[SLOT_ID_MAX];
+ char *sim_plmn;
+ char *current_plmn;
+
+ int default_data_slot;
+ int default_voice_slot;
+ int data_roaming_option;
+ int idle_screen_launched;
+ int psmode;
+ guint modems_count;
+ guint no_svc_timer_id[SLOT_ID_MAX];
+ manual_plmn_data *manual_plmn_cb_data[SLOT_ID_MAX];
+
+ CoreObject *co_network[SLOT_ID_MAX];
+ CoreObject *co_sim;
+
+ Storage *strg_vconf;
+ struct sat_desktop_file_data desktop_data[SLOT_ID_MAX];
+ GSList *pending_payload;
+};
+
+typedef struct ui_notifier_user_data ui_noti_data;
+
+void launch_no_svc_with_manual_plmn_popup(ui_noti_data *p, sim_slot_id id);
+void cancel_no_svc_with_manual_plmn_popup(ui_noti_data *p, sim_slot_id id);
+void launch_timezone_select_popup(ui_noti_data *ud);
+void launch_roaming_data_allowed_popup(ui_noti_data *ud);
+
--- /dev/null
+/*
+ * tel-plugin-ui_notifier
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Ja-young Gu <jygu@samsung.com>
+ *
+ * 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.
+ */
+
+#pragma once
+
+#include <stdio.h>
+#include <gio/gio.h>
+
+#define POPUP_IPC "msg"
+#define POPUP_IPC_PARAM "param"
+#define AUL_NAME "org.tizen.telephony-syspopup"
+#define SYSPOPUP_NAME "telephony-syspopup"
+#define UI_NOTI_ONE_SEC 1
+
+void launch_pwlock(void);
+void launch_pwlock_pin_block(void);
+void launch_setup_ota(void);
+void launch_telephony_popup(const char *message, const char *param, void *ud);
+
+
--- /dev/null
+/*
+ * tel-plugin-ui_notifier
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Ja-young Gu <jygu@samsung.com>
+ *
+ * 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 <tcore.h>
+
+gboolean notifier_preferred_network_init(TcorePlugin *plugin);
+
--- /dev/null
+/*
+ * tel-plugin-ui_notifier
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Ja-young Gu <jygu@samsung.com>
+ *
+ * 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 <tcore.h>
+
+gboolean notifier_preferred_voice_init(TcorePlugin *plugin);
+
+
--- /dev/null
+/*
+ * tel-plugin-ui_notifier
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Ja-young Gu <jygu@samsung.com>
+ *
+ * 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.
+ */
+
+#pragma once
+
+#include <systemd/sd-login.h>
+#include <tzplatform_config.h>
+
+#define GLOBAL_USER tzplatform_getuid(TZ_SYS_GLOBALAPP_USER)
+
+void ui_notifier_lock_sleep(void);
+void ui_notifier_unlock_sleep(void);
+float ui_notifier_check_uptime();
\ No newline at end of file
--- /dev/null
+%define major 0
+%define minor 1
+%define patchlevel 0
+
+Name: tel-plugin-ui_notifier
+Version: %{major}.%{minor}.%{patchlevel}
+Release: 1
+License: Apache
+Summary: Telephony UI Notifier plugin
+Group: System/Libraries
+Source0: tel-plugin-ui_notifier-%{version}.tar.gz
+BuildRequires: cmake
+BuildRequires: pkgconfig(aul)
+BuildRequires: pkgconfig(capi-system-device)
+BuildRequires: pkgconfig(glib-2.0)
+BuildRequires: pkgconfig(pkgmgr)
+BuildRequires: pkgconfig(tcore)
+BuildRequires: pkgconfig(vconf)
+BuildRequires: pkgconfig(capi-appfw-application)
+Requires(post): /sbin/ldconfig
+Requires(postun): /sbin/ldconfig
+
+%description
+Telephony UI Notifier plugin
+
+%prep
+%setup -q
+
+%build
+versionint=$[%{major} * 1000000 + %{minor} * 1000 + %{patchlevel}]
+cmake . -DCMAKE_INSTALL_PREFIX=%{_prefix} -DVERSION=$versionint \
+ -DLIB_INSTALL_DIR=%{_libdir} \
+%if 1%{?sec_product_feature_network_dsds}
+ -DFEATURE_MULTISIM=1 \
+%endif
+
+make %{?_smp_mflags}
+
+%post
+/sbin/ldconfig
+
+%postun -p /sbin/ldconfig
+
+%install
+%make_install
+
+%files
+%manifest tel-plugin-ui_notifier.manifest
+%defattr(-,root,root,-)
+%{_libdir}/telephony/plugins/ui_notifier-plugin*
--- /dev/null
+/*
+ * tel-plugin-ui_notifier
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Ja-young Gu <jygu@samsung.com>
+ *
+ * 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 "notifier.h"
+
+#include <plugin.h>
+
+#ifndef PLUGIN_VERSION
+#define PLUGIN_VERSION 1
+#endif
+
+static gboolean on_load()
+{
+ dbg("i'm load!");
+ return TRUE;
+}
+
+static gboolean on_init(TcorePlugin *plugin)
+{
+ dbg("i'm init!");
+ g_assert(plugin != NULL);
+
+ return ui_notifier_init(plugin);
+}
+
+static void on_unload(TcorePlugin *plugin)
+{
+ dbg("i'm unload!");
+ g_assert(plugin != NULL);
+
+ ui_notifier_deinit(plugin);
+}
+
+EXPORT_API struct tcore_plugin_define_desc plugin_define_desc =
+{
+ .name = "UI_NOTIFIER",
+ .priority = TCORE_PLUGIN_PRIORITY_LOW,
+ .version = PLUGIN_VERSION,
+ .load = on_load,
+ .init = on_init,
+ .unload = on_unload
+};
--- /dev/null
+/*
+ * tel-plugin-ui_notifier
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Ja-young Gu <jygu@samsung.com>
+ *
+ * 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 <tcore.h>
+#include <server.h>
+#include <plugin.h>
+#include <storage.h>
+#include <user_request.h>
+#include <co_network.h>
+#include <co_modem.h>
+#include <co_sim.h>
+#include <vconf.h>
+
+#include "notifier.h"
+#include "notifier_util.h"
+#include "notifier_internal.h"
+#include "notifier_launcher.h"
+#include "notifier_preferred_network.h"
+#include "notifier_preferred_voice.h"
+
+//Temporaily add for build
+#define VCONFKEY_TELEPHONY_PRIVATE_MANUAL_PLMN_SIM1 VCONFKEY_TELEPHONY_PRIVATE_MANUAL_PLMN
+#define VCONFKEY_TELEPHONY_PRIVATE_MANUAL_PLMN_SIM2 VCONFKEY_TELEPHONY_PRIVATE_MANUAL_PLMN
+
+static gboolean on_prop_changed (CoreObject *co, const void *event_info, void *user_data);
+
+static gboolean _is_in_service(enum telephony_network_service_type service_type)
+{
+ switch (service_type) {
+ case NETWORK_SERVICE_TYPE_UNKNOWN:
+ case NETWORK_SERVICE_TYPE_NO_SERVICE:
+ case NETWORK_SERVICE_TYPE_EMERGENCY:
+ case NETWORK_SERVICE_TYPE_SEARCH:
+ return FALSE;
+ default:
+ return TRUE;
+ }
+}
+
+static gboolean __is_file_exist(char *path)
+{
+ FILE* fp = NULL;
+ gboolean ret = FALSE;
+
+ if (!path)
+ return FALSE;
+
+ fp = fopen(path, "r");
+ if(fp) {
+ info("[%s] exist", path);
+ fclose(fp);
+ ret = TRUE;
+ }
+
+ return ret;
+}
+
+sim_slot_id __get_sim_slotid(CoreObject *source)
+{
+ TcorePlugin *plugin = NULL;
+ char *cp_name = NULL;
+
+ if (!source) {
+ return SLOT_ID_MAX;
+ }
+ plugin = tcore_object_ref_plugin(source);
+ if (!plugin) {
+ return SLOT_ID_MAX;
+ }
+ cp_name = (char *)tcore_server_get_cp_name_by_plugin(plugin);
+ if (!cp_name) {
+ return SLOT_ID_MAX;
+ }
+ if(g_str_has_suffix(cp_name , "0")){
+ return SLOT_ID_PRIMARY;
+ } else if (g_str_has_suffix(cp_name , "1")){
+ return SLOT_ID_SECONDARY;
+ } else if(g_str_has_suffix(cp_name , "2")){
+ return SLOT_ID_TERTIARY;
+ } else {
+ return SLOT_ID_MAX;
+ }
+}
+
+static gboolean __all_sims_absent(ui_noti_data *ud)
+{
+ guint id, sim_not_present_count = 0;
+
+ for (id = 0; id < ud->modems_count; id++) {
+ if (ud->sim_status[id] == SIM_STATUS_CARD_NOT_PRESENT) {
+ sim_not_present_count++;
+ }
+ dbg("slot:[%d] sim_status : [0x%x]", id, ud->sim_status[id]);
+ }
+
+ dbg("modems_count %d sim_not_present_count %d", ud->modems_count, sim_not_present_count);
+
+ if (sim_not_present_count == ud->modems_count) {
+ dbg("Both SIMS are not present");
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static void __update_first_bootup_info(TcorePlugin *p, sim_slot_id id, enum tel_sim_status sim_status)
+{
+ ui_noti_data *ud = NULL;
+
+ if ((ud = tcore_plugin_ref_user_data(p)) == NULL) {
+ err("tcore_plugin_ref_user_data() returns NULL.");
+ return;
+ }
+
+ if (sim_status == SIM_STATUS_CARD_ERROR ||
+ sim_status == SIM_STATUS_CARD_NOT_PRESENT ||
+ sim_status == SIM_STATUS_INIT_COMPLETED ||
+ sim_status == SIM_STATUS_CARD_BLOCKED ||
+ sim_status == SIM_STATUS_CARD_POWEROFF) {
+
+ dbg("updating bootup info..slot[%d]", id);
+ ud->first_bootup_sim[id] = TRUE;
+ }
+}
+
+static void _check_net_prop_event_registered(ui_noti_data *ud, CoreObject *co_network, TcorePlugin *p, sim_slot_id id)
+{
+ if (ud->prop_event_registered[id] == FALSE) {
+ dbg ("event register for id %d", id);
+ ud->prop_event_registered[id] = TRUE;
+ ud->co_network[id] = co_network;
+ tcore_object_add_callback (co_network, CORE_OBJECT_EVENT_PROPERTY_CHANGED,
+ on_prop_changed, p);
+ }
+}
+
+
+static void _update_roaming_popup(ui_noti_data *ud)
+{
+ gboolean roaming_status = ud->roaming_status[ud->default_data_slot];
+
+ info("DefaultDataSlot(%d), RoamingStatus(%d), MobileDataAllowed(%d), RoamingDataAllowed(%d), RoamingPopupLaunched(%d)",
+ ud->default_data_slot, roaming_status, ud->mobile_data_allowed, ud->roaming_data_allowed, ud->roaming_popup_launched);
+
+ if (ud->mobile_data_allowed && roaming_status) {
+ if (!ud->roaming_data_allowed && !ud->roaming_popup_launched) {
+ info("Roaming data allowed enable popup required");
+ ud->roaming_popup_launched = TRUE;
+ launch_roaming_data_allowed_popup(ud);
+ return;
+ }
+ }
+
+ if (ud->roaming_popup_launched) {
+ info("Remove roaming notification");
+ launch_telephony_popup(IPC_MSG_NETWORK_DEL_DATA_ROAMING, "", ud);
+ ud->roaming_popup_launched = FALSE;
+ }
+}
+
+
+#ifdef TIZEN_FEATURE_MULTISIM
+static void _check_net_roaming_data_allowed_with_slot_id(ui_noti_data *ud, int roaming_status, sim_slot_id id)
+{
+ if (ud->roaming_status[id] != roaming_status) {
+ info("SIM%d Roaming Status Change:(%d)->(%d)", id+1, ud->roaming_status[id], roaming_status);
+ ud->roaming_status[id] = roaming_status;
+ _update_roaming_popup(ud);
+ }
+}
+
+static void on_default_data_slot_changed(keynode_t* node, void* user_data) {
+ TcorePlugin *p = user_data;
+ ui_noti_data *ud = tcore_plugin_ref_user_data(p);
+
+ if (!ud)
+ return;
+
+ vconf_get_int(VCONFKEY_TELEPHONY_DB_DEFAULT_DATA_SUBS, &ud->default_data_slot);
+ dbg("default data slot:[%d]", ud->default_data_slot);
+ _update_roaming_popup(ud);
+}
+#else
+static void _check_net_roaming_data_allowed(ui_noti_data *ud, int roaming_status,
+ enum telephony_network_service_domain_status ps_domain_status)
+{
+
+ if (ud->roaming_status[SLOT_ID_DEFAULT] != roaming_status) {
+ info("Status Change:(%d)->(%d). PS(%d) Roam Data Allowed (%d)",
+ ud->roaming_status[SLOT_ID_DEFAULT], roaming_status, ps_domain_status, ud->roaming_data_allowed);
+
+ ud->roaming_status[SLOT_ID_DEFAULT] = roaming_status;
+
+ if (ud->roaming_status[SLOT_ID_DEFAULT]) {
+ int do_not_ask = 0;
+ vconf_get_int(VCONFKEY_TELEPHONY_PRIVATE_DATA_ROAMING_POPUP_CHECKBOX, &do_not_ask);
+ if (do_not_ask) {
+ info("Roaming area. But, User don't want to see popup");
+ return;
+ } else {
+ info("Roaming area. We check roaming popup required");
+ }
+ }
+
+ _update_roaming_popup(ud);
+ }
+}
+#endif
+
+static void _check_net_manual_selection_no_svc(ui_noti_data *ud, enum telephony_network_service_type svc_type, sim_slot_id id)
+{
+ //if (!tfeature_is_supported(TFEATURE_UI_NO_SVC_MANUAL_PLMN_CHECK))
+ // return;
+
+ if (!ud->manual_plmn[id])
+ return;
+
+
+ if (ud->sim_status[id] != SIM_STATUS_INIT_COMPLETED) {
+ info ("We don't need to check manual_selection with sim_status(%d)", ud->sim_status[id]);
+ return;
+ }
+
+ if (ud->flight_mode) {
+ info ("We don't need to check manual_selection with flight mode(%d)", ud->flight_mode);
+ return;
+ }
+ if (ud->psmode) {
+ info ("We don't need to check manual_selection with power saving mode(%d)", ud->psmode);
+ return;
+ }
+
+ ud->svc_type[id] = svc_type;
+ dbg ("For slot(%d) service_type (%d) manual_plmn (%s)", id, ud->svc_type[id], ud->manual_plmn[id]?ud->manual_plmn[id]:"");
+
+ switch (ud->svc_type[id]) {
+ case NETWORK_SERVICE_TYPE_UNKNOWN:
+ break;
+ case NETWORK_SERVICE_TYPE_NO_SERVICE:
+ case NETWORK_SERVICE_TYPE_EMERGENCY:
+ case NETWORK_SERVICE_TYPE_SEARCH:
+ {
+ if (ud->manual_plmn[id]) {
+ if (ud->manual_plmn_popup_required[id]) {
+ info ("manual selection (%s) exist and home screen launched. launch popup", ud->manual_plmn[id]);
+ launch_no_svc_with_manual_plmn_popup(ud, id);
+ ud->manual_plmn_popup_required[id] = FALSE;
+ } else {
+ dbg ("popup is not required");
+ }
+ } else {
+ dbg ("No manual plmn (Automatic). do nothing");
+ }
+ }
+ break;
+ default : {
+ if (ud->manual_plmn[id]) {
+ cancel_no_svc_with_manual_plmn_popup(ud, id);
+ }
+ }
+ break;
+ }
+}
+
+static void _check_net_manual_selection_no_svc_current(ui_noti_data *ud, sim_slot_id id)
+{
+ if (ud->co_network[id]) {
+ enum telephony_network_service_type svc_type;
+ tcore_network_get_service_type(ud->co_network[id], &svc_type);
+ _check_net_manual_selection_no_svc(ud, svc_type, id);
+ }
+}
+
+static void _handle_prop_net_nitz_timezone(TcorePlugin *p, CoreObject *co)
+{
+ ui_noti_data *ud = NULL;
+ const char *value = NULL;
+
+ if ((ud = tcore_plugin_ref_user_data(p)) == NULL) {
+ err("tcore_plugin_ref_user_data() returns NULL.");
+ return;
+ }
+
+ value = tcore_object_ref_property (co, PROP_NET_NITZ_TIMEZONE);
+ info ("Nitz Timezone Status = %s", value);
+
+ if (g_strcmp0 (value, "user_selection_required") == 0) {
+ launch_timezone_select_popup(ud);
+ }
+}
+
+static void _handle_prop_net_manual_selection_status(TcorePlugin *p, CoreObject *co)
+{
+ ui_noti_data *ud = NULL;
+ const char *value = NULL;
+ sim_slot_id id;
+
+ if ((ud = tcore_plugin_ref_user_data(p)) == NULL) {
+ err("tcore_plugin_ref_user_data() returns NULL.");
+ return;
+ }
+
+ id = __get_sim_slotid(co);
+ value = tcore_object_ref_property (co, PROP_NET_MANUAL_SELECTION_STATUS);
+ info ("slot(%d), manual selection status = %s", id, value);
+
+ if (g_strcmp0 (value, "waiting") == 0) {
+ dbg ("Waiting for manual selection result");
+ cancel_no_svc_with_manual_plmn_popup(ud, id);
+ ud->manual_plmn_popup_required[id] = FALSE;
+ }
+ else if ((g_strcmp0 (value, "failure") == 0)
+ || (g_strcmp0 (value, "success") == 0)) {
+ dbg ("manual selection done. Check service type");
+ ud->manual_plmn_popup_required[id] = TRUE;
+ _check_net_manual_selection_no_svc_current(ud, id);
+ } else {
+ dbg ("Changed to Automatic.");
+ cancel_no_svc_with_manual_plmn_popup(ud, id);
+ ud->manual_plmn_popup_required[id] = FALSE;
+ }
+}
+
+static void _handle_prop_net_manual_plmn(TcorePlugin *p, CoreObject *co)
+{
+ ui_noti_data *ud = NULL;
+ const char *manual_plmn = NULL;
+ sim_slot_id id;
+
+ if ((ud = tcore_plugin_ref_user_data(p)) == NULL) {
+ err("tcore_plugin_ref_user_data() returns NULL.");
+ return;
+ }
+
+ id = __get_sim_slotid(co);
+ manual_plmn = tcore_object_ref_property (co, PROP_NET_MANUAL_PLMN);
+ dbg ("property changed (value = %s) for slot(%d)", (manual_plmn?manual_plmn:"Null"), id);
+
+ if (manual_plmn == NULL) {
+ manual_plmn = "";
+ free(ud->manual_plmn[id]);
+ ud->manual_plmn[id] = NULL;
+ } else {
+ free(ud->manual_plmn[id]);
+ ud->manual_plmn[id] = strdup(manual_plmn);
+ ud->manual_plmn_popup_required[id] = TRUE;
+ }
+
+ if (id == SLOT_ID_PRIMARY) {
+ vconf_set_str(VCONFKEY_TELEPHONY_PRIVATE_MANUAL_PLMN_SIM1, manual_plmn);
+ } else if (id == SLOT_ID_SECONDARY) {
+ vconf_set_str(VCONFKEY_TELEPHONY_PRIVATE_MANUAL_PLMN_SIM2, manual_plmn);
+ } else {
+ warn("Unsupported id(%d)", id);
+ return;
+ }
+ info ("For slot(%d) key Set to : [%s], manual_plmn:[%s], popup_required:[%d]",
+ id, manual_plmn, ud->manual_plmn[id]?ud->manual_plmn[id]:"Null", ud->manual_plmn_popup_required[id]);
+
+ _check_net_manual_selection_no_svc_current(ud, id);
+
+}
+
+static void _process_flight_mode_state(TcorePlugin *p, gboolean new_mode)
+{
+ ui_noti_data *ud = NULL;
+ guint id;
+ enum tel_sim_status sim_status;
+
+ if ((ud = tcore_plugin_ref_user_data(p)) == NULL) {
+ err("tcore_plugin_ref_user_data() returns NULL.");
+ return;
+ }
+
+ if (ud->flight_mode == new_mode)
+ return;
+
+ do {
+ if (new_mode == FALSE && ud->flight_mode == TRUE) { // Flight enable -> Disable
+ dbg("Flight mode changed On to Off");
+ for (id = 0; id < ud->modems_count; id++) {
+ sim_status = ud->sim_status[id];
+ dbg("slot:[%d] sim_status : [0x%x]", id, ud->sim_status[id]);
+ if (sim_status == SIM_STATUS_PIN_REQUIRED ||
+ sim_status == SIM_STATUS_PUK_REQUIRED ||
+ sim_status == SIM_STATUS_NCK_REQUIRED ||
+ sim_status == SIM_STATUS_NSCK_REQUIRED ||
+ sim_status == SIM_STATUS_SPCK_REQUIRED ||
+ sim_status == SIM_STATUS_CCK_REQUIRED) {
+ dbg("Launching pwlock(flight mode)");
+ launch_pwlock();
+ break;
+ }
+ }
+ }
+ } while (0);
+ ud->flight_mode = new_mode;
+
+ //if (tfeature_is_supported(TFEATURE_UI_NO_SVC_MANUAL_PLMN_CHECK)) {
+ if(1) {
+ if (ud->flight_mode) {
+ dbg("Flight mode on. stop checking manual plmn");
+ for (id = 0; id < ud->modems_count; id++) {
+ cancel_no_svc_with_manual_plmn_popup(ud, id);
+ ud->manual_plmn_popup_required[id] = FALSE;
+ }
+ } else {
+ dbg("Flight mode off. Check no svc manual plmn");
+ for (id = 0; id < ud->modems_count; id++) {
+ ud->manual_plmn_popup_required[id] = TRUE;
+ _check_net_manual_selection_no_svc_current(ud, id);
+ }
+ }
+ }
+
+}
+
+static gboolean on_prop_changed (CoreObject *co, const void *event_info,
+ void *user_data)
+{
+ GSList *key = (GSList *)event_info;
+
+ if (CORE_OBJECT_KEY_FIND(key, PROP_NET_MANUAL_PLMN)) {
+ //if (tfeature_is_supported(TFEATURE_UI_NO_SVC_MANUAL_PLMN_CHECK)) {
+ _handle_prop_net_manual_plmn((TcorePlugin *)user_data, co);
+ //}
+ }
+ else if (CORE_OBJECT_KEY_FIND(key, PROP_NET_MANUAL_SELECTION_STATUS)) {
+ //if (tfeature_is_supported(TFEATURE_UI_NO_SVC_MANUAL_PLMN_CHECK)) {
+ _handle_prop_net_manual_selection_status((TcorePlugin *)user_data, co);
+ //}
+ }
+ else if (CORE_OBJECT_KEY_FIND(key, PROP_NET_NITZ_TIMEZONE)) {
+ _handle_prop_net_nitz_timezone((TcorePlugin *)user_data, co);
+ }
+
+ return TRUE;
+}
+
+static enum tcore_hook_return on_hook_network_plmn_change(Server *s, CoreObject *source,
+ enum tcore_notification_command command, unsigned int data_len, void *data, void *user_data)
+{
+ ui_noti_data *ud;
+ struct tnoti_network_change *info = data;
+
+ ud = tcore_plugin_ref_user_data (user_data);
+ if (!ud || !info || strlen(info->plmn) == 0) {
+ dbg ("Invalid Data");
+ return TCORE_HOOK_RETURN_CONTINUE;
+ }
+
+ if ((ud->current_plmn && strncmp(info->plmn, ud->current_plmn, 3))
+ || (!ud->current_plmn)) {
+ info("MCC change (%s) -> (%s)", ud->current_plmn?ud->current_plmn:"", info->plmn);
+ g_free(ud->current_plmn);
+ ud->current_plmn = g_strdup(info->plmn);
+ }
+
+ return TCORE_HOOK_RETURN_CONTINUE;
+}
+
+static enum tcore_hook_return on_hook_network_service_type_change(Server *s, CoreObject *source,
+ enum tcore_notification_command command, unsigned int data_len, void *data, void *user_data)
+{
+ TcorePlugin *p = user_data;
+ ui_noti_data *ud;
+ struct tnoti_network_registration_status *info = data;
+ sim_slot_id id;
+
+ ud = tcore_plugin_ref_user_data (user_data);
+ if (!ud) {
+ err ("tcore_plugin_ref_user_data() is NULL");
+ return TCORE_HOOK_RETURN_CONTINUE;
+ }
+
+ if (!info) {
+ err ("tnoti_network_registration_status() is NULL");
+ return TCORE_HOOK_RETURN_CONTINUE;
+ }
+
+ id = __get_sim_slotid(source);
+ if (ud->sim_status[id] == SIM_STATUS_CARD_NOT_PRESENT ||
+ ud->sim_status[id]== SIM_STATUS_UNKNOWN) {
+ dbg ("No SIM or Unknown");
+ return TCORE_HOOK_RETURN_CONTINUE;
+ }
+
+ dbg("slot:[%d] sim_status : [0x%x]", id, ud->sim_status[id]);
+
+ _check_net_prop_event_registered(ud, source, p, id);
+ if (_is_in_service(info->service_type)) {
+#ifdef TIZEN_FEATURE_MULTISIM
+ _check_net_roaming_data_allowed_with_slot_id(ud, info->roaming_status, id);
+#else
+ _check_net_roaming_data_allowed(ud, info->roaming_status, info->ps_domain_status);
+#endif
+ } else {
+ warn("UE is not in service. Do not refer roaming status yet");
+ }
+ _check_net_manual_selection_no_svc(ud, info->service_type, id);
+
+ return TCORE_HOOK_RETURN_CONTINUE;
+}
+
+static void on_hook_nitz_gmt_change(keynode_t* node, void* user_data) {
+ TcorePlugin *p = user_data;
+ ui_noti_data *ud = tcore_plugin_ref_user_data(p);
+
+ if (!ud)
+ return;
+
+ if (!ud->nitz_popup_launched) {
+ gboolean audo_update;
+ vconf_get_bool(VCONFKEY_SETAPPL_STATE_AUTOMATIC_TIME_UPDATE_BOOL, &audo_update);
+ if (audo_update == FALSE)
+ return;
+
+ //if (tfeature_is_supported(TFEATURE_UI_NITZ_TIME_UPDATE_POPUP)) {
+ if(1) {
+ info("Launch NITZ Time Update popup (Only for First NITZ)");
+ launch_telephony_popup(IPC_MSG_DISPLAY_NITZ_TIME_UPDATE, "", ud);
+ }
+ ud->nitz_popup_launched = TRUE;
+ }
+}
+
+static void on_power_saving_mode_changed(keynode_t* node, void* user_data) {
+ TcorePlugin *p = user_data;
+ ui_noti_data *ud = tcore_plugin_ref_user_data(p);
+ guint id;
+
+ if (!ud)
+ return;
+
+ vconf_get_int(VCONFKEY_SETAPPL_PSMODE, &ud->psmode);
+
+ //if (tfeature_is_supported(TFEATURE_UI_NO_SVC_MANUAL_PLMN_CHECK)) {
+ for (id = 0; id < ud->modems_count; id++) {
+ _check_net_manual_selection_no_svc_current(ud, id);
+ }
+ //}
+}
+
+static enum tcore_hook_return on_hook_sim_status(Server *s, CoreObject *source,
+ enum tcore_notification_command command, unsigned int data_len, void *data, void *user_data)
+{
+ TcorePlugin *p = user_data;
+ ui_noti_data *ud = NULL;
+ const struct tnoti_sim_status *sim = data;
+ const char *cp_name;
+ sim_slot_id id;
+ guint i, first_bootup_count = 0;
+
+ if ((ud = tcore_plugin_ref_user_data(p)) == NULL) {
+ err("tcore_plugin_ref_user_data() returns NULL.");
+ return TCORE_HOOK_RETURN_CONTINUE;
+ }
+
+ if (!ud->co_sim) {
+ ud->co_sim = source;
+ }
+
+ id = __get_sim_slotid(source);
+ ud->sim_status[id] = sim->sim_status;
+ dbg("slot:[%d] sim_status : [0x%x]", id, ud->sim_status[id]);
+
+ /*
+ * 14/10/17
+ * PLM# : P141007-00246
+ * Problem : when AT+CFUN=0 "SIM ERROR" popup is coming
+ * Requirement : should not raise a popup while in automation test.
+ */
+ if (sim->sim_status == SIM_STATUS_CARD_ERROR ||
+ sim->sim_status == SIM_STATUS_CARD_CRASHED ||
+ sim->sim_status == SIM_STATUS_CARD_REMOVED) {
+ #define TMP_FILE_AT_CFUN_0 "/tmp/data-router/at_cfun0"
+ if (__is_file_exist(TMP_FILE_AT_CFUN_0)) {
+ dbg("not handling SIM ERROR/REMOVAL event.");
+ return TCORE_HOOK_RETURN_CONTINUE;
+ }
+ }
+
+ switch(ud->sim_status[id]) {
+ case SIM_STATUS_CARD_NOT_PRESENT:
+ case SIM_STATUS_CARD_ERROR:
+ /*
+ * To let User knows current SIM Card has ERROR
+ * raise pop-up when initial SIM Card error case (SIM_STATUS_CARD_ERROR)
+ * since there is no displaying area to show "SIM Card Error" msg in Gear 3.
+ */
+ info("NO SIM or SIM CARD ERROR!");
+ /* launch NO SIM notification only when both sims are not present*/
+ if (__all_sims_absent(ud)) {
+#ifdef TIZEN_FEATURE_SHOW_NO_SIM_ONGOING_NOTI
+ launch_telephony_popup(IPC_MSG_SIM_NOT_PRESENTED, "", ud);
+#endif
+ //if (tfeature_is_supported(TFEATURE_UI_SIM_RAISE_INVALID_SIM_POPUP)) {
+ launch_telephony_popup(IPC_MSG_SIM_CARD_ERROR, "", ud);
+ //}
+ }
+ break;
+ case SIM_STATUS_CARD_CRASHED:
+ info("SIM CARD CRASHED!");
+#ifdef TIZEN_FEATURE_SHOW_NO_SIM_ONGOING_NOTI
+ launch_telephony_popup(IPC_MSG_SIM_NOT_PRESENTED, "", ud);
+#endif
+ //if (tfeature_is_supported(TFEATURE_UI_SIM_RAISE_INVALID_SIM_POPUP)) {
+ if(1) {
+ launch_telephony_popup(IPC_MSG_SIM_CARD_CRASHED, "", ud);
+ } else {
+ launch_telephony_popup(IPC_MSG_SIM_CARD_REMOVED, "", ud);
+ }
+ break;
+ case SIM_STATUS_CARD_REMOVED:
+ info("SIM IS REMOVED!");
+ cp_name = tcore_server_get_cp_name_by_plugin(tcore_object_ref_plugin(source));
+ dbg("cp_name: [%s]", cp_name);
+#ifdef TIZEN_FEATURE_SHOW_NO_SIM_ONGOING_NOTI
+ if (__all_sims_absent(ud)) {
+ launch_telephony_popup(IPC_MSG_SIM_NOT_PRESENTED, "", ud);
+ }
+#endif
+ launch_telephony_popup(IPC_MSG_SIM_CARD_REMOVED, "", ud);
+ break;
+ case SIM_STATUS_INIT_COMPLETED:
+ //if (tfeature_is_supported(TFEATURE_UI_NO_SVC_MANUAL_PLMN_CHECK)) {
+ _check_net_manual_selection_no_svc_current(ud, id);
+ //}
+ //if (tfeature_is_supported(TFEATURE_FUNCTION_CHECK_ACTIVATED_SIM)) {
+ // _check_sim_ota_status();
+ //}
+ break;
+ case SIM_STATUS_PIN_REQUIRED:
+ case SIM_STATUS_PUK_REQUIRED:
+ case SIM_STATUS_CARD_BLOCKED:
+ case SIM_STATUS_NCK_REQUIRED:
+ case SIM_STATUS_NSCK_REQUIRED:
+ case SIM_STATUS_SPCK_REQUIRED:
+ case SIM_STATUS_CCK_REQUIRED:
+ case SIM_STATUS_LOCK_REQUIRED:
+ for (i = 0; i < ud->modems_count; i++) {
+ if (ud->first_bootup_sim[i] == TRUE)
+ first_bootup_count++;
+ }
+
+ if (first_bootup_count == ud->modems_count) {
+ dbg("Launching pwlock(pin_block)");
+ launch_pwlock_pin_block();
+ } else {
+ dbg("On Bootup - No need to launch pwlock");
+ }
+ break;
+ default:
+ break;
+ }
+
+ /* Updating bootup info to detect first boot */
+ __update_first_bootup_info(p, id, ud->sim_status[id]);
+
+ return TCORE_HOOK_RETURN_CONTINUE;
+}
+
+static void on_storage_key_callback(enum tcore_storage_key key, void *value, void *user_data)
+{
+ TcorePlugin *p = user_data;
+ GVariant *tmp = (GVariant *)value;
+ gboolean type_check = FALSE;
+
+ if (!tmp || !p) {
+ err("Invalid cb data");
+ return;
+ }
+
+ switch(key) {
+ case STORAGE_KEY_FLIGHT_MODE_BOOL:
+ case STORAGE_KEY_SETAPPL_STATE_DATA_ROAMING_BOOL:
+ case STORAGE_KEY_3G_ENABLE:
+ {
+ type_check = g_variant_is_of_type(tmp, G_VARIANT_TYPE_BOOLEAN);
+ if (!type_check){
+ err("wrong variant data type");
+ g_variant_unref(tmp);
+ return;
+ }
+ }
+ break;
+ default: {
+ warn("unknown key");
+ return;
+ }
+ break;
+ }
+
+ if (key == STORAGE_KEY_FLIGHT_MODE_BOOL){
+ gboolean new_mode;
+ new_mode = g_variant_get_boolean(tmp);
+ _process_flight_mode_state(p, new_mode);
+ } else if (key == STORAGE_KEY_SETAPPL_STATE_DATA_ROAMING_BOOL) {
+ ui_noti_data *ud = tcore_plugin_ref_user_data(p);
+ if (ud) {
+ ud->roaming_data_allowed = g_variant_get_boolean(tmp);
+ dbg("roaming_data_allowed changed (%d)", ud->roaming_data_allowed);
+ _update_roaming_popup(ud);
+ }
+ } else if (key == STORAGE_KEY_3G_ENABLE) {
+ ui_noti_data *ud = tcore_plugin_ref_user_data(p);
+ if (ud) {
+ ud->mobile_data_allowed = g_variant_get_boolean(tmp);
+ dbg("mobile_data_allowed changed (%d)", ud->mobile_data_allowed);
+ _update_roaming_popup(ud);
+ }
+ }
+ return;
+}
+
+gboolean ui_notifier_init(TcorePlugin *plugin)
+{
+ Server *s;
+ ui_noti_data *ud;
+ guint id;
+
+ ud = calloc(sizeof(ui_noti_data), 1);
+ if (tcore_plugin_link_user_data(plugin, ud) != TCORE_RETURN_SUCCESS) {
+ free(ud);
+ return FALSE;
+ }
+
+ ud->flight_mode = FALSE;
+ ud->roaming_popup_launched = FALSE;
+
+ s = tcore_plugin_ref_server(plugin);
+ ud->modems_count = tcore_server_get_modems_count(s);
+
+ for (id = 0; id < ud->modems_count; id++) {
+ ud->sim_status[id] = SIM_STATUS_UNKNOWN;
+ ud->first_bootup_sim[id] = FALSE;
+ ud->roaming_status[id] = 0;
+ if (id == SLOT_ID_PRIMARY) {
+ ud->manual_plmn[id] = vconf_get_str (VCONFKEY_TELEPHONY_PRIVATE_MANUAL_PLMN_SIM1);
+ } else if (id == SLOT_ID_SECONDARY) {
+ ud->manual_plmn[id] = vconf_get_str (VCONFKEY_TELEPHONY_PRIVATE_MANUAL_PLMN_SIM2);
+ } else {
+ warn("Unsupported id(%d)", id);
+ break;
+ }
+
+ ud->manual_plmn_noti_launched[id] = FALSE;
+ if (ud->manual_plmn[id] && strlen(ud->manual_plmn[id]) == 0) {
+ dbg("No saved manual plmn. set to NULL");
+ free(ud->manual_plmn[id]);
+ ud->manual_plmn[id] = NULL;
+ ud->manual_plmn_popup_required[id] = FALSE;
+ } else {
+ dbg("For slot(%d), Saved manual plmn:(%s)", id, ud->manual_plmn[id]);
+ ud->manual_plmn_popup_required[id] = TRUE;
+ }
+ }
+
+ ud->strg_vconf = tcore_server_find_storage(s, "vconf");
+ ud->flight_mode = tcore_storage_get_bool(ud->strg_vconf, STORAGE_KEY_FLIGHT_MODE_BOOL);
+ ud->roaming_data_allowed = tcore_storage_get_bool(ud->strg_vconf, STORAGE_KEY_SETAPPL_STATE_DATA_ROAMING_BOOL);
+ ud->mobile_data_allowed = tcore_storage_get_bool(ud->strg_vconf, STORAGE_KEY_3G_ENABLE);
+
+ vconf_get_int(VCONFKEY_SETAPPL_PSMODE, &ud->psmode);
+ vconf_get_int(VCONFKEY_TELEPHONY_DB_DEFAULT_DATA_SUBS, &ud->default_data_slot);
+ info("default data slot:[%d]", ud->default_data_slot);
+
+ tcore_storage_set_key_callback(ud->strg_vconf, STORAGE_KEY_3G_ENABLE, on_storage_key_callback, plugin);
+ tcore_storage_set_key_callback(ud->strg_vconf, STORAGE_KEY_FLIGHT_MODE_BOOL, on_storage_key_callback, plugin);
+ tcore_storage_set_key_callback(ud->strg_vconf, STORAGE_KEY_SETAPPL_STATE_DATA_ROAMING_BOOL, on_storage_key_callback, plugin);
+ tcore_server_add_notification_hook(s, TNOTI_NETWORK_REGISTRATION_STATUS, on_hook_network_service_type_change, plugin);
+ tcore_server_add_notification_hook(s, TNOTI_NETWORK_CHANGE, on_hook_network_plmn_change, plugin);
+ tcore_server_add_notification_hook(s, TNOTI_SIM_STATUS, on_hook_sim_status, plugin);
+
+ vconf_notify_key_changed(VCONFKEY_TELEPHONY_NITZ_GMT, on_hook_nitz_gmt_change, plugin);
+ vconf_notify_key_changed(VCONFKEY_SETAPPL_PSMODE, on_power_saving_mode_changed, plugin);
+#ifdef TIZEN_FEATURE_MULTISIM
+ vconf_notify_key_changed(VCONFKEY_TELEPHONY_DB_DEFAULT_DATA_SUBS, on_default_data_slot_changed, plugin);
+#endif
+ notifier_preferred_network_init(plugin);
+ notifier_preferred_voice_init(plugin);
+
+
+ return TRUE;
+}
+
+void ui_notifier_deinit(TcorePlugin *plugin)
+{
+ ui_noti_data *ud;
+ Server *s;
+ guint id;
+
+ s = tcore_plugin_ref_server(plugin);
+ ud = tcore_plugin_ref_user_data(plugin);
+ if (ud) {
+ ud->modems_count = tcore_server_get_modems_count(s);
+
+ for (id = 0; id < ud->modems_count; id++) {
+ if (ud->no_svc_timer_id[id] != 0) {
+ g_source_remove(ud->no_svc_timer_id[id]);
+ }
+ if (ud->manual_plmn[id])
+ free(ud->manual_plmn[id]);
+ if (ud->manual_plmn_cb_data[id])
+ free(ud->manual_plmn_cb_data[id]);
+ }
+
+ tcore_storage_remove_key_callback(ud->strg_vconf, STORAGE_KEY_3G_ENABLE, on_storage_key_callback);
+ tcore_storage_remove_key_callback(ud->strg_vconf, STORAGE_KEY_FLIGHT_MODE_BOOL, on_storage_key_callback);
+ tcore_storage_remove_key_callback(ud->strg_vconf, STORAGE_KEY_SETAPPL_STATE_DATA_ROAMING_BOOL, on_storage_key_callback);
+ if (ud->sim_plmn)
+ free(ud->sim_plmn);
+ if (ud->current_plmn)
+ free(ud->current_plmn);
+ }
+
+ tcore_server_remove_notification_hook(s, on_hook_network_service_type_change);
+ tcore_server_remove_notification_hook(s, on_hook_network_plmn_change);
+ tcore_server_remove_notification_hook(s, on_hook_sim_status);
+
+ vconf_ignore_key_changed(VCONFKEY_TELEPHONY_NITZ_GMT, on_hook_nitz_gmt_change);
+ vconf_ignore_key_changed(VCONFKEY_SETAPPL_PSMODE, on_power_saving_mode_changed);
+#ifdef TIZEN_FEATURE_MULTISIM
+ vconf_ignore_key_changed(VCONFKEY_TELEPHONY_DB_DEFAULT_DATA_SUBS, on_default_data_slot_changed);
+#endif
+
+ free(ud);
+}
--- /dev/null
+/*
+ * tel-plugin-ui_notifier
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Ja-young Gu <jygu@samsung.com>
+ *
+ * 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 <tcore.h>
+#include <server.h>
+#include <plugin.h>
+#include <vconf.h>
+#include <user_request.h>
+#include <co_network.h>
+
+#include "notifier_internal.h"
+#include "notifier_launcher.h"
+
+struct manual_plmn_noti_data {
+ ui_noti_data *ud;
+ sim_slot_id id;
+};
+
+static void _network_get_name_from_plmn(CoreObject *co, char *name, const char *plmn)
+{
+ struct tcore_network_operator_info *noi = NULL;
+ char mcc[4] = { 0, };
+ const char *mnc;
+
+ if (G_UNLIKELY(!plmn) || G_UNLIKELY(strlen(plmn) < 4)) {
+ warn("Invalid plmn");
+ return;
+ }
+
+ memcpy(mcc, plmn, 3);
+ mnc = plmn + 3;
+
+ if (G_UNLIKELY(atoi(mcc) == 0)) {
+ err("atoi(mcc) is Zero. mcc[%s]", mcc);
+ return;
+ }
+
+ noi = tcore_network_operator_info_find(co, mcc, mnc);
+ if (!noi) {
+ memcpy(name, plmn, NETWORK_MAX_PLMN_LEN+1);
+ } else {
+ memcpy(name, noi->name, NETWORK_MAX_NETWORK_NAME_LEN+1);
+ }
+ dbg("name:[%s] plmn:[%s]", name, plmn);
+}
+
+static void _on_response_selection_mode(UserRequest *ur,
+ enum tcore_response_command command,
+ unsigned int data_len, const void *data, void *user_data)
+{
+ const struct tresp_network_get_plmn_selection_mode *info = data;
+ const char *manual_plmn = NULL;
+ char name[NETWORK_MAX_NETWORK_NAME_LEN+1];
+ struct manual_plmn_noti_data *net_selection_info = user_data;
+ CoreObject *co;
+ sim_slot_id id;
+
+ if (!info || !net_selection_info)
+ return;
+
+ id = net_selection_info->id;
+ co = net_selection_info->ud->co_network[id];
+ if (info->mode == NETWORK_SELECT_MODE_AUTOMATIC) {
+ info("Automatic Selection mode.");
+ tcore_object_set_property(co, PROP_NET_MANUAL_PLMN, NULL);
+ } else {
+ info("Manual Selection mode.");
+ manual_plmn = tcore_object_ref_property (co, PROP_NET_MANUAL_PLMN);
+ launch_telephony_popup(IPC_MSG_NETWORK_MANUAL_FAIL_POPUP, "", net_selection_info->ud);
+ _network_get_name_from_plmn(co, name, manual_plmn);
+ if (id == SLOT_ID_PRIMARY)
+ launch_telephony_popup(IPC_MSG_SIM1_ADD_NETWORK_MANUAL_FAIL_NOTI, name, net_selection_info->ud);
+ else
+ launch_telephony_popup(IPC_MSG_SIM2_ADD_NETWORK_MANUAL_FAIL_NOTI, name, net_selection_info->ud);
+ net_selection_info->ud->manual_plmn_noti_launched[id] = TRUE;
+ }
+ g_free(net_selection_info);
+}
+
+static void _check_net_selection_mode_from_modem(ui_noti_data *ud, sim_slot_id id)
+{
+ struct manual_plmn_noti_data *net_selection_info;
+
+ if (ud->co_network[id]) {
+ UserRequest *ur = NULL;
+ dbg("Get Plmn Selection Mode");
+ net_selection_info = (struct manual_plmn_noti_data *)g_malloc0(sizeof(struct manual_plmn_noti_data));
+ net_selection_info->ud = ud;
+ net_selection_info->id = id;
+
+ ur = tcore_user_request_new (NULL, NULL);
+ tcore_user_request_set_command(ur, TREQ_NETWORK_GET_PLMN_SELECTION_MODE);
+ tcore_user_request_set_response_hook(ur, _on_response_selection_mode, net_selection_info);
+ if (TCORE_RETURN_SUCCESS != tcore_object_dispatch_request(ud->co_network[id], ur)) {
+ err("Request [0x%x] dispatch failed", TREQ_NETWORK_GET_PLMN_SELECTION_MODE);
+ tcore_user_request_unref(ur);
+ g_free(net_selection_info);
+ }
+ }
+}
+
+static gboolean _on_timeout_no_svc_waiting(gpointer user_cb_data)
+{
+ enum telephony_network_service_type svc_type;
+ manual_plmn_data *cb_data = user_cb_data;
+ ui_noti_data *ud = (ui_noti_data *)cb_data->ud;
+ sim_slot_id id = cb_data->id;
+
+ tcore_network_get_service_type(ud->co_network[id], &svc_type);
+ if (svc_type > NETWORK_SERVICE_TYPE_SEARCH) {
+ info ("In Service. Do not launch popup");
+ } else {
+ dbg("For slot(%d), no svc timeout. check network mode again", id);
+ _check_net_selection_mode_from_modem(ud, id);
+ }
+ ud->no_svc_timer_id[id] = 0;
+ free(cb_data);
+ return G_SOURCE_REMOVE;
+}
+
+void launch_no_svc_with_manual_plmn_popup(ui_noti_data *ud, sim_slot_id id)
+{
+ manual_plmn_data *cb_data = NULL;
+ const char *value = NULL;
+
+ //tempporaily modify for build
+ //if (tfeature_is_supported(TFEATURE_UI_NO_SVC_MANUAL_PLMN_CHECK)) {
+ if(1) {
+ unsigned int timeout = NO_SVC_WAITING_TIMEOUT;
+ cancel_no_svc_with_manual_plmn_popup(ud, id);
+ cb_data = calloc(sizeof(manual_plmn_data), 1);
+ if (cb_data == NULL) {
+ err("memory allocation failed");
+ return;
+ }
+ cb_data->ud = ud;
+ cb_data->id = id;
+ ud->manual_plmn_cb_data[id] = cb_data;
+
+ value = tcore_object_ref_property (ud->co_network[id], PROP_NET_MANUAL_SELECTION_STATUS);
+ info ("slot(%d), manual selection status = %s", id, value);
+
+ if (g_strcmp0 (value, "failure") == 0) {
+ dbg ("manual selection failed. Launch popup");
+ _on_timeout_no_svc_waiting(cb_data);
+ } else {
+ ud->no_svc_timer_id[id] = g_timeout_add_seconds(timeout,
+ _on_timeout_no_svc_waiting, cb_data);
+ dbg("Add timer(%d) timeout(%d)", ud->no_svc_timer_id[id], timeout);
+ }
+ } else {
+ dbg("Feature is not defined. Do nothing");
+ }
+}
+
+void cancel_no_svc_with_manual_plmn_popup(ui_noti_data *ud, sim_slot_id id)
+{
+ const char *manual_plmn = NULL;
+ char name[NETWORK_MAX_NETWORK_NAME_LEN+1];
+
+ if (ud->no_svc_timer_id[id] != 0) {
+ gboolean ret;
+ ret = g_source_remove(ud->no_svc_timer_id[id]);
+ if (FALSE == ret) {
+ warn("g_source_remove fail");
+ }
+ else {
+ dbg("timer(%d) was cancelled", ud->no_svc_timer_id[id]);
+ }
+ ud->no_svc_timer_id[id] = 0;
+ if (ud->manual_plmn_cb_data[id])
+ free(ud->manual_plmn_cb_data[id]);
+ }
+ if (ud->manual_plmn_noti_launched[id] == TRUE) {
+ manual_plmn = tcore_object_ref_property (ud->co_network[id], PROP_NET_MANUAL_PLMN);
+ _network_get_name_from_plmn(ud->co_network[id], name, manual_plmn);
+ if (id == SLOT_ID_PRIMARY)
+ launch_telephony_popup(IPC_MSG_SIM1_DEL_NETWORK_MANUAL_FAIL_NOTI, name, ud);
+ else
+ launch_telephony_popup(IPC_MSG_SIM2_DEL_NETWORK_MANUAL_FAIL_NOTI, name, ud);
+ ud->manual_plmn_noti_launched[id] = FALSE;
+ }
+}
+
+void launch_timezone_select_popup(ui_noti_data *ud)
+{
+ launch_telephony_popup(IPC_MSG_NITZ_MANUL_DATE_AND_TIME, "", ud);
+
+ tcore_object_set_property (ud->co_network[SLOT_ID_DEFAULT], PROP_NET_NITZ_TIMEZONE, "requested");
+}
+
+void launch_roaming_data_allowed_popup(ui_noti_data *ud)
+{
+ launch_telephony_popup(IPC_MSG_NETWORK_DATA_ROAMING_POPUP, "", ud);
+}
--- /dev/null
+/*
+ * tel-plugin-ui_notifier
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Ja-young Gu <jygu@samsung.com>
+ *
+ * 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 <tcore.h>
+#include <server.h>
+#include <plugin.h>
+#include <vconf.h>
+#include "notifier_internal.h"
+#include "notifier_launcher.h"
+#include "notifier_util.h"
+
+#include <bundle_internal.h>
+#include <aul.h>
+
+static gpointer __launch_pwlock_internal(gpointer data)
+{
+ bundle *kb;
+ int ret;
+
+ kb = bundle_create();
+ if (kb == NULL)
+ return NULL;
+
+ info("launch pwlock");
+
+ bundle_add(kb, "after_bootup", "1");
+ ret = aul_launch_app_for_uid ("com.samsung.pwlock", kb, GLOBAL_USER);
+ if (ret < 0)
+ err("Unable to launch pwlock. Error [%d]", ret);
+
+ bundle_free(kb);
+ return NULL;
+}
+
+static gpointer __launch_pwlock_pin_block(gpointer data)
+{
+ bundle *kb;
+ int ret;
+
+ kb = bundle_create();
+ if (kb == NULL)
+ return NULL;
+
+ info("launch pwlock for PIN Block");
+
+ bundle_add(kb, "after_bootup", "2");
+
+ ret = aul_launch_app_for_uid("com.samsung.pwlock", kb, GLOBAL_USER);
+ if (ret < 0)
+ err("Unable to launch pwlock. Error [%d]", ret);
+
+ bundle_free(kb);
+ return NULL;
+}
+
+static gpointer __launch_setup_ota_internal(gpointer data)
+{
+ int ret;
+
+ info("launch setup ota app");
+ ret = aul_launch_app_for_uid ("com.samsung.setup-kt-net", NULL, GLOBAL_USER);
+ if (ret < 0)
+ err("Unable to setup ota. Error [%d]", ret);
+
+ info("launch setup done");
+ return NULL;
+}
+
+static gpointer __launch_telephony_popup_internal(gpointer data)
+{
+ struct __telephony_popup_payload_t *payload = data;
+ unsigned short retry_count = 0;
+ bundle *kb;
+ int ret;
+
+ info("request telephony_syspopup ('%s', '%s')",
+ payload->message, payload->param);
+RETRY:
+
+ kb = bundle_create();
+ if (kb == NULL) {
+ err("Fail to create bundle");
+ goto EXIT;
+ }
+
+ if(payload->message) {
+ bundle_add (kb, POPUP_IPC, payload->message);
+ }
+
+ if(payload->param) {
+ bundle_add (kb, POPUP_IPC_PARAM, payload->param);
+ }
+
+ info("Request sent to launch %s", AUL_NAME);
+ ret = aul_launch_app_for_uid(AUL_NAME, kb, GLOBAL_USER);
+ bundle_free(kb);
+
+ if (ret < 0 && retry_count < 5) {
+ err("fail to launch (%d). Retry count [%d]",ret, retry_count);
+ retry_count++;
+ g_usleep(G_USEC_PER_SEC * 1);
+ goto RETRY;
+ } else {
+ info("success.('%s', '%s')", payload->message, payload->param);
+ }
+
+EXIT:
+ /* Free resources */
+ g_free(payload->message);
+ g_free(payload->param);
+ g_free(payload);
+
+ return NULL;
+}
+
+void launch_pwlock_pin_block(void)
+{
+ GThread *thread;
+
+ thread = g_thread_new("PWLOCK-APP", __launch_pwlock_pin_block, NULL);
+ g_thread_unref(thread);
+}
+
+void launch_pwlock(void)
+{
+ GThread *thread;
+
+ thread = g_thread_new("PWLOCK-APP", __launch_pwlock_internal, NULL);
+ g_thread_unref(thread);
+}
+
+void launch_setup_ota(void)
+{
+ GThread *thread;
+
+ thread = g_thread_new("SETUP-OTA-APP", __launch_setup_ota_internal, NULL);
+ g_thread_unref(thread);
+}
+
+void launch_telephony_popup(const char *message, const char *param, void *data)
+{
+ GThread *thread;
+ ui_noti_data *ud = (ui_noti_data *)data;
+ struct __telephony_popup_payload_t *payload;
+
+ if (!ud)
+ return;
+
+ payload = g_malloc0(sizeof(struct __telephony_popup_payload_t));
+ payload->message = g_strdup(message);
+ payload->param = g_strdup(param);
+
+ ui_notifier_lock_sleep();
+ thread = g_thread_new("TEL-POPUP", __launch_telephony_popup_internal, payload);
+ g_thread_unref(thread);
+ ui_notifier_unlock_sleep();
+}
--- /dev/null
+/*
+ * tel-plugin-ui_notifier
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Ja-young Gu <jygu@samsung.com>
+ *
+ * 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 <tcore.h>
+#include <plugin.h>
+#include <server.h>
+#include <co_call.h>
+#include <storage.h>
+#include <user_request.h>
+#include "notifier_preferred_network.h"
+#include "notifier_internal.h"
+#include "notifier_util.h"
+
+#define MODEM_INDEX_UNDECIDED 0
+#define MODEM_INDEX_PRIMARY 1
+#define MODEM_INDEX_SECONDARY 2
+#define MODEM_INDEX_TERTIARY 3
+#define MODEM_INDEX_INVALID -1
+
+static int __get_modem_index(TcorePlugin *plugin)
+{
+ char *cp_name = NULL;
+
+ if (!plugin)
+ return MODEM_INDEX_INVALID;
+
+ cp_name = (char *)tcore_server_get_cp_name_by_plugin(plugin);
+ if (!cp_name)
+ return MODEM_INDEX_INVALID;
+
+ if (g_str_has_suffix(cp_name , "0"))
+ return MODEM_INDEX_PRIMARY;
+ else if (g_str_has_suffix(cp_name , "1"))
+ return MODEM_INDEX_SECONDARY;
+ else if(g_str_has_suffix(cp_name , "2"))
+ return MODEM_INDEX_TERTIARY;
+ else
+ return MODEM_INDEX_INVALID;
+
+}
+
+static gboolean __is_ongoing_call_exist(CoreObject *co_call)
+{
+ GSList* call_obj_list = NULL;
+ unsigned int total_call_cnt = 0;
+ unsigned int call_status_count = 0;
+
+ total_call_cnt = tcore_call_object_total_length(co_call);
+ if (total_call_cnt == 0) {
+ dbg("Active call not found");
+ return FALSE;
+ }
+
+ for(call_status_count = TCORE_CALL_STATUS_ACTIVE; call_status_count <= TCORE_CALL_STATUS_WAITING; call_status_count++) {
+ call_obj_list = tcore_call_object_find_by_status(co_call,call_status_count);
+ if (call_obj_list) {
+ dbg("ongoing call(s) exist");
+ g_slist_free(call_obj_list);
+ return TRUE;
+ }
+ }
+ dbg("ongoing call not found");
+ return FALSE;
+}
+
+static void __set_preferred_network(TcorePlugin *plugin, int modem_index,
+ enum telephony_call_preferred_voice_subs pv)
+{
+ CoreObject *co_network = NULL;
+ UserRequest *ur = NULL;
+ struct treq_network_set_default_subscription req;
+
+ dbg("set preferred network based on modem index : %d, pv : %d", modem_index, pv);
+ if (MODEM_INDEX_INVALID == modem_index)
+ return;
+
+ co_network = tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_NETWORK);
+ if (!co_network) {
+ err("network co_object not found");
+ return;
+ }
+
+ switch(pv) {
+ case CALL_PREFERRED_VOICE_SUBS_UNKNOWN:
+ case CALL_PREFERRED_VOICE_SUBS_CURRENT_NETWORK:
+ case CALL_PREFERRED_VOICE_SUBS_ASK_ALWAYS:
+ /* preferred network have pirority to preferred voice - ignore preferred voice */
+ /* SET preferred network to vconf */
+ switch(modem_index ) {
+ case MODEM_INDEX_PRIMARY:
+ req.default_subs = NETWORK_DEFAULT_SUBS_SIM1;
+ break;
+
+ case MODEM_INDEX_SECONDARY:
+ req.default_subs = NETWORK_DEFAULT_SUBS_SIM2;
+ break;
+
+ case MODEM_INDEX_UNDECIDED:
+ default:
+ req.default_subs = NETWORK_DEFAULT_SUBS_UNKNOWN;
+ break;
+ }
+ break;
+ case CALL_PREFERRED_VOICE_SUBS_SIM1:
+ /* preferred voice have priority to preferred network */
+ /* SET preferred network vconf */
+ req.default_subs = NETWORK_DEFAULT_SUBS_SIM1;
+ break;
+ case CALL_PREFERRED_VOICE_SUBS_SIM2:
+ /* preferred voice have priority to preferred network */
+ /* set preferred network vconf */
+ req.default_subs = NETWORK_DEFAULT_SUBS_SIM2;
+ break;
+ default :
+ req.default_subs = NETWORK_DEFAULT_SUBS_UNKNOWN;
+ break;
+ }
+
+ ur = tcore_user_request_new(NULL, NULL);
+ tcore_user_request_set_data(ur, sizeof(struct treq_network_set_default_subscription), &req);
+ tcore_user_request_set_command(ur, TREQ_NETWORK_SET_DEFAULT_SUBSCRIPTION);
+
+ dbg("Setting preferred network [0x%x]", req.default_subs);
+
+ if (TCORE_RETURN_SUCCESS != tcore_object_dispatch_request(co_network, ur)) {
+ err("Request [0x%x] dispatch failed", TREQ_NETWORK_SET_DEFAULT_SUBSCRIPTION);
+ tcore_user_request_unref(ur);
+ }
+}
+
+static void __apply_preferred_voice_change(TcorePlugin *plugin)
+{
+ GSList *modem_list, *iter;
+ gboolean b_set_preferred_network = TRUE;
+ TcorePlugin *modem_plgn = NULL;
+ CoreObject *co_call = NULL;
+ Server *s;
+
+ s = tcore_plugin_ref_server(plugin);
+ modem_list = tcore_server_get_modem_plugin_list(s);
+ if (!modem_list)
+ return;
+
+ /* Check whether active/originating/incoming/waiting call exist in each modem */
+ for (iter = modem_list; iter != NULL; iter = iter->next) {
+ modem_plgn = iter->data;
+ if (!modem_plgn) {
+ err("modem plgn not found");
+ b_set_preferred_network = FALSE;
+ break;
+ }
+
+ co_call = tcore_plugin_ref_core_object(modem_plgn, CORE_OBJECT_TYPE_CALL);
+ if(!co_call) {
+ dbg("call_obj not found - skip this plugin ");
+ continue;
+ }
+
+ /* if exist, sustain modem index with PN value */
+ if(__is_ongoing_call_exist(co_call)) {
+ dbg("call exist - sustain current PN value");
+ b_set_preferred_network = FALSE;
+ break;
+ }
+ }
+
+ g_slist_free(modem_list);
+
+ if (b_set_preferred_network) {
+ ui_noti_data *ud = tcore_plugin_ref_user_data(plugin);
+ /* Active call not exist, update Preferred Network value to comply Preferred Voice value */
+ dbg("call not exist - update PN to comply pv : %d", ud->default_voice_slot);
+ __set_preferred_network(modem_plgn, MODEM_INDEX_UNDECIDED, ud->default_voice_slot);
+ }
+}
+
+static void __on_response_get_preferred_voice(UserRequest *ur,
+ enum tcore_response_command command, unsigned int data_len, const void *data, void *user_data)
+{
+ const struct tresp_call_get_preferred_voice_subscription *resp = data;
+ ui_noti_data *ud = tcore_plugin_ref_user_data(user_data);
+
+ if (!resp || !ud)
+ return;
+
+ if (ud->default_voice_slot != resp->preferred_subs) {
+ dbg("Preferred Voice Change (%d) -> (%d)", ud->default_voice_slot, resp->preferred_subs);
+ ud->default_voice_slot = resp->preferred_subs;
+ __apply_preferred_voice_change(user_data);
+ } else
+ dbg("Value(%d) was not changed.", ud->default_voice_slot);
+}
+
+static void __get_preferred_voice(TcorePlugin *plugin)
+{
+ GSList *modem_list, *iter;
+ TcorePlugin *modem_plgn = NULL;
+ CoreObject *co_call = NULL;
+ UserRequest *ur = NULL;
+
+ modem_list = tcore_server_get_modem_plugin_list(tcore_plugin_ref_server(plugin));
+ for (iter = modem_list; iter != NULL; iter = iter->next) {
+ modem_plgn = iter->data;
+ co_call = tcore_plugin_ref_core_object(modem_plgn, CORE_OBJECT_TYPE_CALL);
+ if(co_call)
+ break;
+ }
+ g_slist_free(modem_list);
+
+ if (!co_call)
+ return;
+
+ ur = tcore_user_request_new(NULL, NULL);
+ tcore_user_request_set_command(ur, TREQ_CALL_GET_PREFERRED_VOICE_SUBSCRIPTION);
+ tcore_user_request_set_response_hook(ur, __on_response_get_preferred_voice, plugin);
+
+ dbg("Getting preferred Voice");
+
+ if (TCORE_RETURN_SUCCESS != tcore_object_dispatch_request(co_call, ur)) {
+ err("Request [0x%x] dispatch failed", TREQ_CALL_GET_PREFERRED_VOICE_SUBSCRIPTION);
+ tcore_user_request_unref(ur);
+ }
+}
+
+static enum tcore_hook_return on_hook_call_status_change(Server *s, CoreObject *source,
+ enum tcore_notification_command command, unsigned int data_len, void *data, void *user_data)
+{
+ TcorePlugin *modem_plgn = NULL;
+ int modem_index = MODEM_INDEX_INVALID;
+ gboolean b_call_ongoing = FALSE;
+
+ modem_plgn = tcore_object_ref_plugin(source);
+ modem_index = __get_modem_index(modem_plgn);
+
+ switch(command) {
+ case TNOTI_CALL_STATUS_DIALING:
+ case TNOTI_CALL_STATUS_INCOMING:
+ /* call being setup - update pn to comply ongoing line */
+ dbg("call under establishment - change perferred Network state");
+ __set_preferred_network(modem_plgn, modem_index, CALL_PREFERRED_VOICE_SUBS_UNKNOWN);
+ break;
+
+ case TNOTI_CALL_STATUS_IDLE:
+ /* call released - check ongoing call */
+ b_call_ongoing = __is_ongoing_call_exist(source);
+
+ /* if exist - sustain current PN */
+ if (TRUE == b_call_ongoing) {
+ dbg("ongoing call exist - sustain current perferred network state");
+ } else {/* if not exist - update PN to comply PV */
+ ui_noti_data *ud = tcore_plugin_ref_user_data((TcorePlugin*)user_data);
+ __set_preferred_network(modem_plgn, MODEM_INDEX_UNDECIDED, ud->default_voice_slot);
+ }
+ break;
+
+ default:
+ break;
+ }
+ return TCORE_HOOK_RETURN_CONTINUE;
+}
+
+
+static enum tcore_hook_return on_hook_call_preferred_voice_change(Server *s, CoreObject *source,
+ enum tcore_notification_command command, unsigned int data_len, void *data, void *user_data)
+{
+ struct tnoti_call_preferred_voice_subscription *noti_data = data;
+ ui_noti_data *ud = tcore_plugin_ref_user_data(user_data);
+
+ if (!noti_data || !ud)
+ return TCORE_HOOK_RETURN_CONTINUE;
+
+ /* Ignore Duplicated TNOTI_CALL_PREFERRED_VOICE_SUBSCRIPTION */
+ if (MODEM_INDEX_PRIMARY != __get_modem_index(tcore_object_ref_plugin(source)))
+ return TCORE_HOOK_RETURN_CONTINUE;
+
+ if (ud->default_voice_slot != noti_data->preferred_subs) {
+ dbg("Preferred Voice Change (%d) -> (%d)", ud->default_voice_slot, noti_data->preferred_subs);
+ ud->default_voice_slot = noti_data->preferred_subs;
+ __apply_preferred_voice_change(user_data);
+ } else
+ dbg("Value(%d) was not changed.", ud->default_voice_slot);
+
+ return TCORE_HOOK_RETURN_CONTINUE;
+}
+
+gboolean notifier_preferred_network_init(TcorePlugin *plugin)
+{
+ Server *s = NULL;
+ unsigned int sim_count = 0;
+ GSList *list = NULL;
+
+ s = tcore_plugin_ref_server(plugin);
+ if (!s)
+ return FALSE;
+
+ list = tcore_server_get_modem_plugin_list(s);
+ sim_count = g_slist_length(list);
+
+ if (sim_count < 2) {
+ err("device does not support DSDS. disable preferred network");
+ g_slist_free(list);
+ return TRUE;
+ }
+
+ /* add hook to call related events & PV change event */
+ tcore_server_add_notification_hook(s, TNOTI_CALL_STATUS_IDLE, on_hook_call_status_change, plugin);
+ tcore_server_add_notification_hook(s, TNOTI_CALL_STATUS_INCOMING, on_hook_call_status_change, plugin);
+ tcore_server_add_notification_hook(s, TNOTI_CALL_STATUS_DIALING, on_hook_call_status_change, plugin);
+ tcore_server_add_notification_hook(s, TNOTI_CALL_PREFERRED_VOICE_SUBSCRIPTION, on_hook_call_preferred_voice_change, plugin);
+
+ __get_preferred_voice(plugin);
+
+ g_slist_free(list);
+
+ return TRUE;
+}
--- /dev/null
+/*
+ * tel-plugin-ui_notifier
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Ja-young Gu <jygu@samsung.com>
+ *
+ * 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 <tcore.h>
+#include <server.h>
+#include <plugin.h>
+#include <user_request.h>
+#include <vconf.h>
+#include <co_call.h>
+
+#include "notifier.h"
+#include "notifier_preferred_voice.h"
+#include "notifier_internal.h"
+#include "notifier_util.h"
+
+static enum tcore_hook_return on_hook_sim_status(Server *s,
+ CoreObject *source, enum tcore_notification_command command,
+ unsigned int data_len, void *data, void *user_data)
+{
+ TcorePlugin *plugin = user_data;
+ TcorePlugin *modem_plugin;
+ ui_noti_data *ud = NULL;
+
+ const struct tnoti_sim_status *sim = data;
+ enum tel_sim_status sim_status, other_sim_status;
+
+ sim_slot_id slot_id, other_slot_id;
+ int pref_voice_subscription = -1;
+ TReturn ret;
+
+ if (sim == NULL) {
+ err("sim data is NULL");
+ return TCORE_HOOK_RETURN_CONTINUE;
+ }
+
+ if ((ud = tcore_plugin_ref_user_data(plugin)) == NULL) {
+ err("tcore_plugin_ref_user_data() returns NULL.");
+ return TCORE_HOOK_RETURN_CONTINUE;
+ }
+
+ modem_plugin = tcore_object_ref_plugin(source);
+
+ slot_id = __get_sim_slotid(source);
+ other_slot_id = (slot_id == SLOT_ID_PRIMARY) ? SLOT_ID_SECONDARY : SLOT_ID_PRIMARY;
+
+ sim_status = ud->sim_status[slot_id] = sim->sim_status;
+ other_sim_status = ud->sim_status[other_slot_id];
+ dbg("SIM Status - SIM 1: [%d] SIM 2: [%d]",
+ slot_id == SLOT_ID_PRIMARY ? sim_status : other_sim_status,
+ slot_id == SLOT_ID_PRIMARY ? other_sim_status : sim_status);
+
+ ret= vconf_get_int(VCONFKEY_TELEPHONY_PREFERRED_VOICE_SUBSCRIPTION, &pref_voice_subscription);
+ if (ret < 0) {
+ err("vconf_get_int() failed - Preferred Voice Subscription");
+ return TCORE_HOOK_RETURN_CONTINUE;
+ }
+ dbg("Preferred Voice Subscription: [%d]", pref_voice_subscription);
+
+ if ((sim_status == SIM_STATUS_CARD_NOT_PRESENT)
+ || (sim_status == SIM_STATUS_CARD_ERROR)) {
+ if (other_sim_status == SIM_STATUS_INIT_COMPLETED) {
+ /*
+ * Check for Preferred Voice Subscription value and if it is
+ * ASK ALWAYS
+ * OR
+ * CURRENT Network
+ * OR
+ * Matches our Subscription, then
+ * update it to other Subscription
+ */
+ if ((pref_voice_subscription == CALL_PREFERRED_VOICE_SUBS_ASK_ALWAYS)
+ || (pref_voice_subscription == CALL_PREFERRED_VOICE_SUBS_CURRENT_NETWORK)
+ || ((slot_id == SLOT_ID_PRIMARY)
+ && (pref_voice_subscription == CALL_PREFERRED_VOICE_SUBS_SIM1))
+ || ((slot_id == SLOT_ID_SECONDARY)
+ && (pref_voice_subscription == CALL_PREFERRED_VOICE_SUBS_SIM2))) {
+
+ struct treq_call_set_preferred_voice_subscription req;
+ UserRequest *ur;
+ CoreObject *co_call;
+
+ /* Create UR */
+ ur = tcore_user_request_new(NULL, tcore_server_get_cp_name_by_plugin(modem_plugin));
+ if (ur == NULL) {
+ err("Failed to create UR");
+ return TCORE_HOOK_RETURN_CONTINUE;
+ }
+
+ /*
+ * Send Set Preferred Voice request
+ */
+ req.preferred_subs = (slot_id == SLOT_ID_PRIMARY) ?
+ CALL_PREFERRED_VOICE_SUBS_SIM2 : CALL_PREFERRED_VOICE_SUBS_SIM1;
+
+ tcore_user_request_set_command(ur, TREQ_CALL_SET_PREFERRED_VOICE_SUBSCRIPTION);
+ tcore_user_request_set_data(ur, sizeof(struct treq_call_set_preferred_voice_subscription), &req);
+
+ co_call = tcore_plugin_ref_core_object(modem_plugin, CORE_OBJECT_TYPE_CALL);
+
+ dbg("Send request to set Preferred Voice subscription for SIM %d",
+ (slot_id == SLOT_ID_PRIMARY ? SLOT_ID_SECONDARY + 1 : SLOT_ID_PRIMARY + 1));
+
+ /* Dispatch request */
+ ret = tcore_object_dispatch_request(co_call, ur);
+ if (ret != TCORE_RETURN_SUCCESS) {
+ err("Failed to disaptch request");
+
+ tcore_user_request_unref(ur);
+ }
+ } else {
+ dbg("Do nothing Preferred Voice Subscription is for other slot [%d]",
+ pref_voice_subscription);
+ }
+ }
+ } else if (sim_status == SIM_STATUS_INIT_COMPLETED) {
+ if ((other_sim_status == SIM_STATUS_CARD_NOT_PRESENT)
+ || (other_sim_status == SIM_STATUS_CARD_ERROR)) {
+ /*
+ * Check for Preferred Voice Subscription value and if it is
+ * ASK ALWAYS
+ * OR
+ * CURRENT Network
+ * OR
+ * Doesn't match our Subscription, then
+ * update it to our Subscription
+ */
+ if ((pref_voice_subscription == CALL_PREFERRED_VOICE_SUBS_ASK_ALWAYS)
+ || (pref_voice_subscription == CALL_PREFERRED_VOICE_SUBS_CURRENT_NETWORK)
+ || ((slot_id == SLOT_ID_PRIMARY)
+ && (pref_voice_subscription == CALL_PREFERRED_VOICE_SUBS_SIM2))
+ || ((slot_id == SLOT_ID_SECONDARY)
+ && (pref_voice_subscription == CALL_PREFERRED_VOICE_SUBS_SIM1))) {
+ struct treq_call_set_preferred_voice_subscription req;
+ UserRequest *ur;
+ CoreObject *co_call;
+
+ /* Create UR */
+ ur = tcore_user_request_new(NULL, tcore_server_get_cp_name_by_plugin(modem_plugin));
+ if (ur == NULL) {
+ err("Failed to create UR");
+ return TCORE_HOOK_RETURN_CONTINUE;
+ }
+
+ /*
+ * Send Set Preferred Voice request
+ */
+ req.preferred_subs = (slot_id == SLOT_ID_PRIMARY) ?
+ CALL_PREFERRED_VOICE_SUBS_SIM1 : CALL_PREFERRED_VOICE_SUBS_SIM2;
+
+ tcore_user_request_set_command(ur, TREQ_CALL_SET_PREFERRED_VOICE_SUBSCRIPTION);
+ tcore_user_request_set_data(ur, sizeof(struct treq_call_set_preferred_voice_subscription), &req);
+
+ co_call = tcore_plugin_ref_core_object(modem_plugin, CORE_OBJECT_TYPE_CALL);
+
+ dbg("Send request to set Preferred Voice subscription for SIM %d",
+ (slot_id == SLOT_ID_PRIMARY ? SLOT_ID_PRIMARY + 1 : SLOT_ID_SECONDARY + 1));
+
+ /* Dispatch request */
+ ret = tcore_object_dispatch_request(co_call, ur);
+ if (ret != TCORE_RETURN_SUCCESS) {
+ err("Failed to disaptch request");
+
+ tcore_user_request_unref(ur);
+ }
+ } else {
+ dbg("Do nothing Preferred Voice Subscription is for same slot [%d]",
+ pref_voice_subscription);
+ }
+ }
+ }
+
+ return TCORE_HOOK_RETURN_CONTINUE;
+}
+
+gboolean notifier_preferred_voice_init(TcorePlugin *plugin)
+{
+ Server *s = NULL;
+ unsigned int sim_count = 0;
+
+ s = tcore_plugin_ref_server(plugin);
+ if (!s)
+ return FALSE;
+
+ sim_count = tcore_server_get_modems_count(s);
+
+ /*
+ * Proceed ahead only in case of Dual-/Multi- SIM
+ */
+ if (sim_count < 2) {
+ err("device does not support DSDS. disable preferred voice");
+
+ return TRUE;
+ }
+
+ /*
+ * Add notification hook for SIM status change
+ */
+ tcore_server_add_notification_hook(s,
+ TNOTI_SIM_STATUS, on_hook_sim_status, plugin);
+
+ return TRUE;
+}
--- /dev/null
+/*
+ * tel-plugin-ui_notifier
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Ja-young Gu <jygu@samsung.com>
+ *
+ * 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 "notifier_util.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <tcore.h>
+#include <device/power.h>
+
+void ui_notifier_lock_sleep(void)
+{
+ int ret = 0;
+ ret = device_power_request_lock(POWER_LOCK_CPU, 0);
+ if (ret < 0)
+ err("ret : (0x%x)", ret);
+}
+
+void ui_notifier_unlock_sleep(void)
+{
+ int ret = 0;
+ device_power_release_lock(POWER_LOCK_CPU);
+ if (ret < 0)
+ err("ret : (0x%x)", ret);
+}
+
+float ui_notifier_check_uptime()
+{
+ FILE *fp;
+ float uptime = 0.0, b = 0.0;
+
+ fp = fopen("/proc/uptime", "r");
+
+ if (fp) {
+ if(fscanf(fp, "%f %f", &uptime, &b)){};
+ fclose(fp);
+ }
+ dbg("uptime=[%f]", uptime);
+
+ return uptime;
+}
--- /dev/null
+<manifest>
+ <request>
+ <domain name="_"/>
+ </request>
+</manifest>