upload tizen1.0 source
[platform/framework/web/wrt.git] / src / view / common / roaming_agent.cpp
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *    Licensed under the Apache License, Version 2.0 (the "License");
5  *    you may not use this file except in compliance with the License.
6  *    You may obtain a copy of the License at
7  *
8  *        http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *    Unless required by applicable law or agreed to in writing, software
11  *    distributed under the License is distributed on an "AS IS" BASIS,
12  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *    See the License for the specific language governing permissions and
14  *    limitations under the License.
15  */
16 /**
17  * @file    roaming_agent.cpp
18  * @author  Pawel Sikorski (p.sikorski@samsung.com)
19  * @author  Lukasz Marek (l.marek@samsung.com)
20  * @version 1.0
21  * @brief   roaming agent
22  */
23
24 #include "roaming_agent.h"
25 #include <PopupInvoker.h>
26 #include <global_logic.h>
27 #include <global_model.h>
28 #include <dpl/singleton_impl.h>
29 #include <dpl/log/log.h>
30 #include <dpl/utils/wrt_global_settings.h>
31 #include <vconf.h>
32
33 IMPLEMENT_SINGLETON(RoamingAgent)
34
35 namespace {
36 const char* CONNECTING_ROAMING_NETWORK = "Connecting to Roaming Network";
37 const char* CONNECTING_HOME_NETWORK = "Connecting to Home Network";
38 const char* CONNECTION_WARNING =
39     "Your terminal is going online.<br>"
40     "Be aware that data charges might apply!<br>"
41     "Do you want to continue?";
42
43 const char* KEEP_CONNECTION_WARNING =
44     "Notwork type changed.<br>"
45     "Do you want to keep active connections?";
46 } // anonymous
47
48 RoamingAgent::RoamingAgent()
49 {
50     if (GlobalSettings::TestModeEnabled()) {
51         return;
52     }
53     //setting say if we are using roaming network or home network
54     int result = 0;
55     if (vconf_get_int(VCONFKEY_TELEPHONY_SVC_ROAM, &result) != 0) {
56         LogError("Cannot get current roaming status");
57     } else {
58         bool type = (result == VCONFKEY_TELEPHONY_SVC_ROAM_ON);
59         m_networkType = type ? ROAMING : HOME;
60         LogInfo("Network type is " << (type ? "ROAMING" : "HOME"));
61     }
62     //setting says if roaming is enabled at all
63     if (vconf_get_bool(VCONFKEY_SETAPPL_STATE_DATA_ROAMING_BOOL,
64                        &result) == -1) {
65         LogError("Cannot get current network setting");
66     } else {
67         m_roamingNetworkEnabled = result;
68         LogInfo("Roaming is " << (result ? "ENABLED" : "DISABLED"));
69     }
70
71     GlobalModel *globalModel =
72         GlobalLogicSingleton::Instance().GetGlobalModel();
73
74     //read current home network access setting
75     SaveNetworkAccessMode(HOME, globalModel->HomeNetworkAccess.Get());
76     //read current roaming network access setting
77     SaveNetworkAccessMode(ROAMING, globalModel->RoamingNetworkAccess.Get());
78
79     LogInfo("Roaming network setting " << m_networkOption.Option(ROAMING));
80     LogInfo("Home network network setting " << m_networkOption.Option(HOME));
81
82     globalModel->HomeNetworkAccess.AddListener(DPL::MakeDelegate(this,
83                                                                  &RoamingAgent
84                                                                      ::
85                                                                      OnHomeNetworkAccessModeChanged));
86     globalModel->RoamingNetworkAccess.AddListener(DPL::MakeDelegate(this,
87                                                                     &
88                                                                     RoamingAgent
89                                                                         ::
90                                                                         OnRoamingNetworkAccessModeChanged));
91
92     // current network is roaming or local
93     if (vconf_notify_key_changed(
94         VCONFKEY_SETAPPL_STATE_DATA_ROAMING_BOOL,
95             vConfChagedCallback, this) < 0)
96     {
97         LogError("Cannot add vconf callback [" <<
98                  VCONFKEY_SETAPPL_STATE_DATA_ROAMING_BOOL << "]");
99     }
100
101     if (vconf_notify_key_changed(
102         VCONFKEY_TELEPHONY_SVC_ROAM,
103         vConfChagedCallback, this) < 0)
104     {
105         LogError("Cannot add vconf callback [" <<
106                  VCONFKEY_TELEPHONY_SVC_ROAM << "]");
107     }
108
109     if (vconf_notify_key_changed(
110             VCONFKEY_NETWORK_WIFI_STATE,
111             vConfChagedCallback, this) < 0)
112     {
113         LogError("Cannot add vconf callback [" <<
114                             VCONFKEY_NETWORK_WIFI_STATE << "]");
115     }
116 }
117
118 RoamingAgent::~RoamingAgent()
119 {
120     if (GlobalSettings::TestModeEnabled()) {
121         return;
122     }
123
124     GlobalModel *globalModel =
125         GlobalLogicSingleton::Instance().GetGlobalModel();
126     globalModel->HomeNetworkAccess.RemoveListener(DPL::MakeDelegate(this,
127                                                                     &
128                                                                     RoamingAgent
129                                                                         ::
130                                                                         OnHomeNetworkAccessModeChanged));
131     globalModel->RoamingNetworkAccess.RemoveListener(DPL::MakeDelegate(this,
132                                                                        &
133                                                                        RoamingAgent
134                                                                            ::
135                                                                            OnRoamingNetworkAccessModeChanged));
136 }
137
138 bool RoamingAgent::CheckAccess()
139 {
140     if (GlobalSettings::TestModeEnabled()) {
141         return true;
142     }
143
144     //Don't allow to use network when global phone setting doesn't allow it
145     if (m_networkType == ROAMING && !m_roamingNetworkEnabled) {
146         LogInfo("global phone setting turned off roaming usage");
147         return false;
148     }
149
150     return AskUser(CONNECTION_WARNING);
151 }
152
153 bool RoamingAgent::AskUser(const std::string &label)
154 {
155     // If current network uses wifi, pass the roaming check
156     int wifiState = VCONFKEY_NETWORK_WIFI_OFF;
157     if (vconf_get_int(VCONFKEY_NETWORK_WIFI_STATE, &wifiState) < 0) {
158         LogError("Fail to get wifi state");
159     } else {
160         if (VCONFKEY_NETWORK_WIFI_CONNECTED == wifiState) {
161             LogInfo("Current network uses WIFI");
162             return true;
163         }
164     }
165
166     NetworkOptionType &option = m_networkOption.Option(m_networkType);
167
168     switch (option) {
169     case NEVER_CONNECT:
170         LogInfo("Network option: never connect");
171         return false;
172     case CONNECT_AUTO:
173         LogInfo("Network option: connect automatically");
174         return true;
175     case ALWAYS_ASK:
176         LogInfo("Network option: always ask");
177         if (!(m_userAnswer.Answer(m_networkType).IsNull())) {
178             return *m_userAnswer.Answer(m_networkType);
179         }
180         //create popup and ask user
181         {
182             std::string title(m_networkType == ROAMING ?
183                               CONNECTING_ROAMING_NETWORK :
184                               CONNECTING_HOME_NETWORK);
185
186             bool response = Wrt::PopupInvoker().askYesNo(title, label);
187
188             LogDebug("Answer: " << response);
189
190             m_userAnswer.Answer(m_networkType) = response;
191             return response;
192         }
193     }
194     return false;
195 }
196
197 void RoamingAgent::Disconnect()
198 {
199     if (m_optionalDisconnectCallback.IsNull()) {
200         LogWarning("No disconnect callback set. Ignoring...");
201     } else {
202         LogInfo("disconnecting connections");
203         (*m_optionalDisconnectCallback)();
204     }
205 }
206
207 void RoamingAgent::HandleDisconnection()
208 {
209     if (!AskUser(KEEP_CONNECTION_WARNING)) {
210         Disconnect();
211     }
212 }
213
214 void RoamingAgent::NetworkAccessModeChanged(NetworkType networkType,
215         GlobalModel::NetworkAccessMode mode)
216 {
217     if (GlobalSettings::TestModeEnabled()) {
218         return;
219     }
220     SaveNetworkAccessMode(networkType, mode);
221     HandleDisconnection();
222 }
223
224 void RoamingAgent::vConfChagedCallback(keynode_t *keyNode, void *data)
225 {
226     LogInfo("vConfChagedCallback ");
227     RoamingAgent *roamAgent = static_cast<RoamingAgent *>(data);
228     if (GlobalSettings::TestModeEnabled()) {
229         return;
230     }
231
232     char *key = vconf_keynode_get_name(keyNode);
233     if (NULL == key) {
234         LogWarning("vconf key is null.");
235         return;
236     }
237     std::string keyString = key;
238
239     // current network is roaming or local
240     if (VCONFKEY_SETAPPL_STATE_DATA_ROAMING_BOOL == keyString) {
241         int value = vconf_keynode_get_bool(keyNode);
242
243         LogInfo("Network is now " << (value ? "ENABLED" : "DISABLED"));
244         if (roamAgent->m_roamingNetworkEnabled != value) {
245             roamAgent->m_roamingNetworkEnabled = value;
246             roamAgent->HandleDisconnection();
247         }
248         return;
249     }
250
251     // allow data connection in the roaming network
252     if (VCONFKEY_TELEPHONY_SVC_ROAM == keyString) {
253         int isRoaming = VCONFKEY_TELEPHONY_SVC_ROAM_OFF;
254         if(vconf_get_int(VCONFKEY_TELEPHONY_SVC_ROAM, &isRoaming) != 0) {
255             LogPedantic("Cannot get current roaming status");
256             return;
257         } else {
258             NetworkType networkType =
259                 (isRoaming == VCONFKEY_TELEPHONY_SVC_ROAM_ON) ? ROAMING : HOME;
260
261             if (networkType != roamAgent->m_networkType) {
262                 roamAgent->m_networkType = networkType;
263                 LogInfo("Network type changed into " <<
264                         (isRoaming ? "Roaming" : "Home network"));
265                 roamAgent->HandleDisconnection();
266             }
267         }
268         return;
269     }
270
271     // wifi setting
272     if (VCONFKEY_NETWORK_WIFI_STATE == keyString) {
273         roamAgent->HandleDisconnection();
274     }
275
276     Assert("Unknown key callback is called");
277     return;
278 }
279
280 void RoamingAgent::SaveNetworkAccessMode(NetworkType networkType,
281         GlobalModel::NetworkAccessMode mode)
282 {
283     LogDebug("SaveNetworkAccessMode");
284     switch (mode) {
285     case GlobalModel::NEVER_CONNECT:
286         m_networkOption.Option(networkType) = NEVER_CONNECT;
287         break;
288     case GlobalModel::CONNECT_AUTOMATICALLY:
289         m_networkOption.Option(networkType) = CONNECT_AUTO;
290         break;
291     case GlobalModel::ALWAYS_ASK:
292         m_networkOption.Option(networkType) = ALWAYS_ASK;
293         break;
294     default:
295         LogWarning("Invalid network access, using default");
296         m_networkOption.Option(networkType) = ALWAYS_ASK;
297         break;
298     }
299 }
300
301 void RoamingAgent::OnHomeNetworkAccessModeChanged(
302         const DPL::Event::PropertyEvent<GlobalModel::NetworkAccessMode> &event)
303 {
304     LogInfo("home network access type: " << event.value);
305     NetworkAccessModeChanged(HOME, event.value);
306 }
307
308 void RoamingAgent::OnRoamingNetworkAccessModeChanged(
309         const DPL::Event::PropertyEvent<GlobalModel::NetworkAccessMode> &event)
310 {
311     LogInfo("roaming network access type: " << event.value);
312     NetworkAccessModeChanged(ROAMING, event.value);
313 }