Merge "fix: use EINA_* booleans instread of TRUE/FALSE" into tizen
[platform/framework/web/wrt.git] / src / view / webkit / ewk_context_manager.cpp
1 /*
2  * Copyright (c) 2013 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    ewk_context_manager.cpp
18  * @author  Yunchan Cho (yunchan.cho@samsung.com)
19  * @version 0.1
20  * @brief   Implementation of EwkContextManager class.
21  *          This file handles operation regarding Ewk_Context
22  */
23
24 #include <map>
25 #include <string>
26 #include <cert-service.h>
27 #include <vconf.h>
28 #include <ewk_context.h>
29 #include <dpl/log/log.h>
30 #include <dpl/exception.h>
31 #include <profiling_util.h>
32 #include <i_view_module.h>
33 #include <dpl/wrt-dao-ro/widget_dao_read_only.h>
34 #include <dpl/wrt-dao-ro/widget_dao_types.h>
35 #include <dpl/wrt-dao-ro/widget_config.h>
36 #include <dpl/utils/wrt_global_settings.h>
37 #include "ewk_context_manager.h"
38
39 namespace ViewModule {
40 namespace {
41 const std::string bundlePath( LIBDIR_PREFIX "/libwrt-injected-bundle.so");
42 std::map<Ewk_Extensible_API, Eina_Bool> defaultExtensibleAPI = {
43     { EWK_EXTENSIBLE_API_MEDIA_STREAM_RECORD,       EINA_TRUE  },
44     { EWK_EXTENSIBLE_API_ROTATE_CAMERA_VIEW,        EINA_FALSE },
45     { EWK_EXTENSIBLE_API_MEDIA_VOLUME_CONTROL,      EINA_TRUE  },
46 };
47 } // anonymous namespace
48
49 EwkContextManager::EwkContextManager(
50         const std::string& tizenAppId,
51         Ewk_Context* ewkContext,
52         IViewModulePtr viewModule)
53     : IContextManager(tizenAppId, ewkContext, viewModule),
54       m_initialized(false), m_isInternalContext(false)
55 {
56     if (!initialize()) {
57         ThrowMsg(DPL::Exception, "Fail to intialize EwkContextManager");
58     }
59     // set ewk context callbacks
60     setCallbacks();
61 }
62
63 EwkContextManager::~EwkContextManager()
64 {
65     // unset registered ewk context callbacks
66     unsetCallbacks();
67     destroy();
68 }
69
70 Ewk_Context * EwkContextManager::getEwkContext() const
71 {
72     return m_ewkContext;
73 }
74
75 bool EwkContextManager::initialize()
76 {
77     if (!m_ewkContext) {
78         m_ewkContext = ewk_context_new_with_injected_bundle_path(bundlePath.c_str());
79
80         if (!m_ewkContext) {
81             return false;
82         }
83
84         m_isInternalContext = true;
85     }
86
87     // cache model setting
88     ewk_context_cache_model_set(
89         m_ewkContext,
90         EWK_CACHE_MODEL_DOCUMENT_BROWSER);
91     ADD_PROFILING_POINT("WebProcess fork", "start");
92     // To fork a Webprocess as soon as possible,
93     // the following ewk_api is called explicitly.
94     ewk_cookie_manager_accept_policy_set(
95             ewk_context_cookie_manager_get(m_ewkContext),
96             EWK_COOKIE_ACCEPT_POLICY_ALWAYS);
97     ADD_PROFILING_POINT("WebProcess fork", "stop");
98
99     // proxy server setting
100     setNetworkProxy();
101
102     LogDebug("ewk_context_certificate_file_set() was called.");
103     const char* caCertPath = cert_svc_get_certificate_crt_file_path();
104     if (caCertPath) {
105         ewk_context_certificate_file_set(m_ewkContext, caCertPath);
106     } else {
107         LogError("cert path is null");
108     }
109
110     FOREACH(it, defaultExtensibleAPI) {
111         ewk_context_tizen_extensible_api_set(m_ewkContext,
112                                              it->first,
113                                              it->second);
114     }
115
116     // web application dependent settings
117     WrtDB::WidgetDAOReadOnly dao(DPL::FromUTF8String(m_appId));
118     ewk_context_web_storage_path_set(
119             m_ewkContext,
120             dao.getPrivateLocalStoragePath().c_str());
121
122     setAutoFullscreenMode();
123 #ifdef CSP_ENABLED
124     if (dao.getSecurityModelVersion() ==
125         WrtDB::WidgetSecurityModelVersion::WIDGET_SECURITY_MODEL_V2)
126     {
127         ewk_context_tizen_extensible_api_set(m_ewkContext,
128                                              EWK_EXTENSIBLE_API_CSP,
129                                              EINA_TRUE);
130     }
131 #endif
132
133     // WidgetSettingList dependent settings
134     WrtDB::WidgetSettings widgetSettings;
135     dao.getWidgetSettings(widgetSettings);
136     WidgetSettingList settings(widgetSettings);
137
138     ewk_context_tizen_extensible_api_set(
139         m_ewkContext,
140         EWK_EXTENSIBLE_API_BACKGROUND_MUSIC,
141         settings.getBackgroundSupport() == BackgroundSupport_Enable ?
142             EINA_TRUE : EINA_FALSE);
143     // Disable in the RSA
144     //ewk_context_tizen_extensible_api_set(
145     //    m_ewkContext,
146     //    EWK_EXTENSIBLE_API_SOUND_MODE,
147     //    settings.getSoundMode() == SoundMode_Exclusive ?
148     //        EINA_TRUE : EINA_FALSE);
149
150     // ewk storage_path set
151     ewk_context_storage_path_reset(m_ewkContext);
152
153     std::string pluginsPath =
154         WrtDB::WidgetConfig::GetWidgetNPRuntimePluginsPath(
155             dao.getTizenPkgId());
156
157     // npruntime plugins path set
158     LogDebug("ewk_context_additional_plugin_path_set() : " << pluginsPath);
159
160     ewk_context_additional_plugin_path_set(m_ewkContext, pluginsPath.c_str());
161
162     m_initialized = true;
163
164     return true;
165 }
166
167 void EwkContextManager::destroy()
168 {
169     // only in the following case, webkit context should be deleted
170     if (m_initialized && m_isInternalContext) {
171         ewk_context_delete(m_ewkContext);
172     }
173 }
174
175 void EwkContextManager::setCallbacks()
176 {
177     if (!m_initialized) {
178         return;
179     }
180
181     ewk_context_message_from_injected_bundle_callback_set(
182             m_ewkContext,
183             messageFromInjectedBundleCallback,
184             this);
185
186     ewk_context_did_start_download_callback_set(
187             m_ewkContext,
188             didStartDownloadCallback,
189             this);
190
191     ewk_context_vibration_client_callbacks_set(
192             m_ewkContext,
193             vibrationClientStartCallback,
194             vibrationClientStopCallback,
195             this);
196
197     vconf_notify_key_changed(VCONFKEY_NETWORK_PROXY,
198                              vconfChangedCallback,
199                              this);
200 }
201
202 void EwkContextManager::unsetCallbacks()
203 {
204     if (!m_initialized) {
205         return;
206     }
207
208     ewk_context_message_from_injected_bundle_callback_set(
209             m_ewkContext, NULL, NULL);
210     ewk_context_did_start_download_callback_set(
211             m_ewkContext, NULL, NULL);
212     ewk_context_vibration_client_callbacks_set(
213             m_ewkContext, NULL, NULL, NULL);
214
215     vconf_ignore_key_changed(VCONFKEY_NETWORK_PROXY,
216                              vconfChangedCallback);
217 }
218
219 void EwkContextManager::setAutoFullscreenMode()
220 {
221     using namespace WrtDB;
222     WrtDB::WidgetDAOReadOnly dao(DPL::FromUTF8String(m_appId));
223     if(!m_ewkContext) {
224         return;
225     }
226     std::list<DPL::String> widgetPrivilege = dao.getWidgetPrivilege();
227     bool fullscreen = false;
228
229     FOREACH(it, widgetPrivilege) {
230         std::map<std::string, Feature>::const_iterator result =
231         g_W3CPrivilegeTextMap.find(DPL::ToUTF8String(*it));
232             if (result != g_W3CPrivilegeTextMap.end()) {
233                 if (result->second == FEATURE_FULLSCREEN_MODE) {
234                     fullscreen = true;
235                     break;
236             }
237         }
238     }
239     ewk_context_tizen_extensible_api_set(m_ewkContext,
240         EWK_EXTENSIBLE_API_FULL_SCREEN,
241         fullscreen);
242 }
243
244 void EwkContextManager::setNetworkProxy()
245 {
246     Assert(m_ewkContext);
247
248     int networkState;
249     if (vconf_get_int(VCONFKEY_NETWORK_STATUS,
250                       &networkState) != 0)
251     {
252         LogError("Fail to get network state");
253         return;
254     }
255     if (networkState == VCONFKEY_NETWORK_OFF) {
256         return;
257     }
258
259     char* proxy = vconf_get_str(VCONFKEY_NETWORK_PROXY);
260     if (proxy && strlen(proxy) && strcmp(proxy, "0.0.0.0")) {
261         LogDebug("proxy address: " << proxy);
262         ewk_context_proxy_uri_set(m_ewkContext, proxy);
263     } else {
264         LogDebug("proxy address is empty");
265         ewk_context_proxy_uri_set(m_ewkContext, NULL);
266     }
267 }
268
269 void EwkContextManager::messageFromInjectedBundleCallback(
270         const char* name,
271         const char* body,
272         char** returnData,
273         void* clientInfo)
274 {
275     LogDebug("enter");
276
277     EwkContextManager* This = static_cast<EwkContextManager*>(clientInfo);
278     if (returnData) {
279         This->m_view->checkSyncMessageFromBundle(name, body, returnData);
280     } else {
281         This->m_view->checkAsyncMessageFromBundle(name, body);
282     }
283 }
284
285 void EwkContextManager::didStartDownloadCallback(const char* downloadUrl, void* data)
286 {
287     LogDebug("enter");
288
289     EwkContextManager* This = static_cast<EwkContextManager*>(data);
290     This->m_view->downloadData(downloadUrl);
291 }
292
293 void EwkContextManager::vibrationClientStartCallback(uint64_t time, void* data)
294 {
295     LogDebug("enter");
296
297     EwkContextManager* This = static_cast<EwkContextManager*>(data);
298     This->m_view->activateVibration(true, static_cast<long>(time));
299 }
300
301 void EwkContextManager::vibrationClientStopCallback(void* data)
302 {
303     LogDebug("enter");
304
305     EwkContextManager* This = static_cast<EwkContextManager*>(data);
306     This->m_view->activateVibration(false, 0);
307 }
308
309 void EwkContextManager::vconfChangedCallback(keynode_t* keynode, void* data)
310 {
311     LogDebug("enter");
312     char* key = vconf_keynode_get_name(keynode);
313
314     if (NULL == key) {
315         LogError("key is null");
316         return;
317     }
318     std::string keyString = key;
319     Assert(data);
320     EwkContextManager* This = static_cast<EwkContextManager*>(data);
321     if (keyString == VCONFKEY_NETWORK_PROXY) {
322         This->setNetworkProxy();
323     }
324 }
325
326 void EwkContextManager::handleLowMemory()
327 {
328     if (!m_ewkContext) {
329         return;
330     }
331
332     //ewk_context_cache_clear(m_ewkContext);
333     //ewk_context_notify_low_memory(m_ewkContext);
334 }
335
336 ContextManagerPtr createEwkContextManager(
337         std::string& tizenAppId,
338         Ewk_Context* ewkContext,
339         ViewModule::IViewModulePtr viewModule)
340 {
341     return ContextManagerPtr(new EwkContextManager(tizenAppId, ewkContext, viewModule));
342 }
343
344 } // namespace ViewModule