Merge "add H/W backkey action" into tizen_2.2
[framework/osp/web.git] / src / controls / FWebCtrl_EflWebkit.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17
18 /**
19  * @file                FWebCtrl_EflWebkit.cpp
20  * @brief               The file contains the definition of _EflWebkit class.
21  *
22  * The file contains the definition of _EflWebkit class.
23  */
24 #include <unique_ptr.h>
25 #include <vconf.h>
26 #include <EWebKit2.h>
27 #include <net_connection.h>
28 #include <FAppApp.h>
29 #include <FGrpPoint.h>
30 #include <FGrpRectangle.h>
31 #include <FIoDbEnumerator.h>
32 #include <FSysVibrator.h>
33 #include <FUiAnimVisualElement.h>
34 #include <FApp_AppInfo.h>
35 #include <FBaseSysLog.h>
36 #include <FBase_StringConverter.h>
37 #include <FGrp_CoordinateSystem.h>
38 #include <FIo_DirectoryImpl.h>
39 #include <FIo_DatabaseImpl.h>
40 #include <FIo_FileImpl.h>
41 #include <FSecCert_CertService.h>
42 #include <FSys_VibratorImpl.h>
43 #include <FUi_Control.h>
44 #include <FUi_Window.h>
45 #include "FUiAnim_EflNode.h"
46 #include "FUiAnim_VisualElementImpl.h"
47 #include "FUiAnim_VisualElementSurfaceImpl.h"
48 #include "FWebCtrl_EflWebkit.h"
49 #include "FWebCtrl_Utility.h"
50 #include "FWebCtrl_WebImpl.h"
51
52
53 using namespace Tizen::Base;
54 using namespace Tizen::Graphics;
55 using namespace Tizen::Io;
56 using namespace Tizen::Security::Cert;
57 using namespace Tizen::Ui;
58 using namespace Tizen::Ui::Animations;
59
60
61 namespace Tizen { namespace Web { namespace Controls
62 {
63
64
65 static const char PLUGIN_DIRECTORY_PATH[] =  "/usr/lib/osp/browser-plugin/";
66
67
68 extern const wchar_t CUSTOM_DB_DIRECTORY_PATH[] = L"data/.webkit/customDatabase/";
69 extern const wchar_t USER_CONFIRM_DB_NAME[] = L"userConfirm.db";
70 extern const wchar_t GEOLOCATION_TABLE_NAME[] = L"geolocationPermission";
71 extern const wchar_t CUSTOM_PROTOCOL_TABLE_NAME[] = L"customProtocol";
72 extern const wchar_t CUSTOM_CONTENT_TABLE_NAME[] = L"customContent";
73 extern const wchar_t CERTIFICATE_TABLE_NAME[] = L"certificate";
74
75
76 static const int CUSTOM_DB_TABLE_COUNT= 4;
77
78
79 _EflWebkit::_EflWebkit(void)
80         : __pWebFrame(null)
81         , __pContainerVisualElement(null)
82         , __pSurface(null)
83 {
84 }
85
86
87 _EflWebkit::~_EflWebkit(void)
88 {
89         if (__pContainerVisualElement)
90         {
91                 __pContainerVisualElement->SetSurface(null);
92         }
93         delete __pSurface;
94 //      evas_object_smart_member_del(__pWebFrame);
95         evas_object_del(__pWebFrame);
96         __pWebFrame = null;
97 }
98
99
100 result
101 _EflWebkit::Construct(const Rectangle& rect, VisualElement& containerVisualElement, _Control* pControl)
102 {
103         result r = E_SUCCESS;
104
105         const _VisualElementImpl* pWebVisualElementImpl = _VisualElementImpl::GetInstance(containerVisualElement);
106         SysAssertf(pWebVisualElementImpl, "Failed to get VisualElement of Web control.");
107
108         _EflNode* pEflNode = dynamic_cast< _EflNode* >(pWebVisualElementImpl->GetNativeNode());
109         SysAssertf(pEflNode, "Failed to get native node.");
110
111         Evas* pEvas = pEflNode->GetEvas();
112         SysAssertf(pEvas, "Failed to get Evas.");
113
114         __pWebFrame = ewk_view_add(pEvas);
115         SysTryReturnResult(NID_WEB_CTRL, __pWebFrame, E_SYSTEM, "A system error has been occurred. Failed to create webkit instance.");
116
117         evas_object_pass_events_set(__pWebFrame, EINA_TRUE);
118
119         r = SetWebConfiguration();
120         SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
121
122         _ICoordinateSystemTransformer* pXformer = _CoordinateSystem::GetInstance()->GetTransformer();
123         SysAssertf(pXformer, "Failed to get coordinate transformer.");
124
125         evas_object_resize(__pWebFrame, pXformer->TransformHorizontal(rect.width), pXformer->TransformVertical(rect.height));
126         evas_object_move(__pWebFrame, pXformer->TransformHorizontal(rect.x), pXformer->TransformVertical(rect.y));
127
128 #if 0
129         pEflNode->AddNativeSmartObject(containerVisualElement, __pWebFrame);
130 #else
131         __pContainerVisualElement = &containerVisualElement;
132
133         DisplayContext* pDisplayContext = pControl->GetRootWindow()->GetDisplayContext();
134         SysTryReturn(NID_WEB_CTRL, pDisplayContext, GetLastResult(), GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
135
136         __pSurface = _VisualElementSurfaceImpl::CreateSurfaceUsingExistingObjectN(*pDisplayContext, (Handle)__pWebFrame, Dimension(rect.width, rect.height));
137         SysTryReturn(NID_WEB_CTRL, __pSurface, GetLastResult(), GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
138
139         containerVisualElement.SetSurface(__pSurface);
140 #endif
141
142         return E_SUCCESS;
143 }
144
145
146 result
147 _EflWebkit::SetWebConfiguration(void) const
148 {
149         result r = E_SUCCESS;
150
151         Ewk_Context* pContext = ewk_view_context_get(__pWebFrame);
152         SysAssertf(pContext, "Failed to request.");
153
154         Ewk_Settings* pSettings = ewk_view_settings_get(__pWebFrame);
155         SysAssertf(pSettings, "Failed to get webkit instance.");
156
157         ewk_context_cache_model_set(pContext, EWK_CACHE_MODEL_PRIMARY_WEBBROWSER);
158
159         ewk_settings_text_selection_enabled_set(pSettings, EINA_FALSE);
160         ewk_settings_uses_keypad_without_user_action_set(pSettings, EINA_FALSE);
161
162         ewk_context_additional_plugin_path_set(pContext, PLUGIN_DIRECTORY_PATH);
163
164         String certPath(_CertService::GetCertificateCrtFilePath());
165         std::unique_ptr<char[]> pcertPath(_StringConverter::CopyToCharArrayN(certPath));
166         SysTryReturn(NID_WEB_CTRL, pcertPath.get(), GetLastResult(), GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
167
168         ewk_context_certificate_file_set(pContext, pcertPath.get());
169
170         r = CreateResourceDirectory();
171         SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
172
173         r = InitializeCustomDb();
174         SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
175
176         r = SetProxyAddress();
177         SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
178
179         InitializeCustomHeader();
180
181         return E_SUCCESS;
182 }
183
184
185 result
186 _EflWebkit::CreateResourceDirectory(void) const
187 {
188         String html5FeaturesPath(Tizen::App::App::GetInstance()->GetAppRootPath() + CUSTOM_DB_DIRECTORY_PATH);
189
190         if (!_FileImpl::IsFileExist(html5FeaturesPath))
191         {
192                 result r = E_SUCCESS;
193
194                 r = _DirectoryImpl::Create(html5FeaturesPath, true);
195                 SysTryReturnResult(NID_WEB_CTRL, r == E_SUCCESS, E_SYSTEM, "A system error has been occurred. create html5 features directory.");
196         }
197
198         return E_SUCCESS;
199 }
200
201
202 result
203 _EflWebkit::InitializeCustomDb(void) const
204 {
205         result r = E_SUCCESS;
206
207         _DatabaseImpl db;
208         String path(Tizen::App::App::GetInstance()->GetAppRootPath() + CUSTOM_DB_DIRECTORY_PATH + USER_CONFIRM_DB_NAME);
209         String geolocationTable(GEOLOCATION_TABLE_NAME);
210         String protocolTable(CUSTOM_PROTOCOL_TABLE_NAME);
211         String contentTable(CUSTOM_CONTENT_TABLE_NAME);
212         String certificateTable(CERTIFICATE_TABLE_NAME);
213
214         r = db.Construct(path, "a+", null);
215         SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
216
217         std::unique_ptr<DbEnumerator>   pEnum(db.QueryN(L"Select count(name) from sqlite_master Where type='table' And name in ('" + geolocationTable + L"', '" + protocolTable + L"', '" + contentTable + L"', '" + certificateTable + L"')"));
218         if (pEnum.get())
219         {
220                 int count = 0;
221
222                 r = pEnum->MoveNext();
223                 SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, false, r, "[%s] Propagating.", GetErrorMessage(r));
224
225                 r = pEnum->GetIntAt(0, count);
226                 SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, false, r, "[%s] Propagating.", GetErrorMessage(r));
227
228                 if (count == CUSTOM_DB_TABLE_COUNT)
229                 {
230                         return E_SUCCESS;
231                 }
232         }
233
234         pEnum.reset();
235         pEnum = std::unique_ptr<DbEnumerator>(db.QueryN(L"Select name from sqlite_master Where type='table' And name = '" + geolocationTable + L"'"));
236         if (!pEnum.get())
237         {
238                 r = db.ExecuteSql(
239                         L"CREATE TABLE IF NOT EXISTS " + geolocationTable + L"(id INTEGER PRIMARY KEY AUTOINCREMENT, origin TEXT, permission INTEGER)",
240                         true);
241                 SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
242         }
243
244         pEnum.reset();
245         pEnum = std::unique_ptr<DbEnumerator>(db.QueryN(L"Select name from sqlite_master Where type='table' And name = '" + protocolTable + L"'"));
246         if (!pEnum.get())
247         {
248                 r = db.ExecuteSql(
249                         L"CREATE TABLE IF NOT EXISTS " + protocolTable + L"(id INTEGER PRIMARY KEY AUTOINCREMENT, baseUrl TEXT, url TEXT, mime TEXT, allow INTEGER)",
250                         true);
251                 SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
252         }
253
254         pEnum.reset();
255         pEnum = std::unique_ptr<DbEnumerator>(db.QueryN(L"Select name from sqlite_master Where type='table' And name = '" + contentTable + L"'"));
256         if (!pEnum.get())
257         {
258                 r = db.ExecuteSql(
259                         L"CREATE TABLE IF NOT EXISTS " + contentTable + L"(id INTEGER PRIMARY KEY AUTOINCREMENT, baseUrl TEXT, url TEXT, mime TEXT, allow INTEGER)",
260                         true);
261                 SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
262         }
263
264         pEnum.reset();
265         pEnum = std::unique_ptr<DbEnumerator>(db.QueryN(L"Select name from sqlite_master Where type='table' And name = '" + certificateTable + L"'"));
266         if (!pEnum.get())
267         {
268                 r = db.ExecuteSql(
269                         L"CREATE TABLE IF NOT EXISTS " + certificateTable + L"(id INTEGER PRIMARY KEY AUTOINCREMENT, pem TEXT, allow INTEGER)",
270                         true);
271                 SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
272         }
273
274         return E_SUCCESS;
275 }
276
277
278 result
279 _EflWebkit::SetProxyAddress(void) const
280 {
281         int ret = -1;
282         connection_h handle = null;
283
284         ret = connection_create(&handle);
285         SysTryReturnResult(NID_WEB_CTRL, ret == CONNECTION_ERROR_NONE, E_SYSTEM, "A system error has been occurred. Failed to create connection.");
286
287         char* pProxy = null;
288         connection_address_family_e family = CONNECTION_ADDRESS_FAMILY_IPV4;
289
290         ret = connection_get_proxy(handle, family, &pProxy);
291         SysTryReturnResult(NID_WEB_CTRL, ret == CONNECTION_ERROR_NONE, E_SYSTEM, "A system error has been occurred. Failed to get proxy address.");
292
293         ret = connection_destroy(handle);
294         SysTryReturnResult(NID_WEB_CTRL, ret == CONNECTION_ERROR_NONE, E_SYSTEM, "A system error has been occurred. Failed to destroy connection.");
295
296         Ewk_Context* pContext = ewk_view_context_get(__pWebFrame);
297         SysAssertf(pContext, "Failed to get context.");
298
299         if (!pProxy || !strlen(pProxy))
300         {
301                 ewk_context_proxy_uri_set(pContext, null);
302         }
303         else
304         {
305                 ewk_context_proxy_uri_set(pContext, pProxy);
306         }
307
308         SysLog(NID_WEB_CTRL, "The current value of proxy is %s", pProxy);
309
310         if (pProxy)
311         {
312                 free(pProxy);
313         }
314
315         return E_SUCCESS;
316 }
317
318
319 void
320 _EflWebkit::InitializeCustomHeader(void) const
321 {
322         std::unique_ptr<char[]> pLang(vconf_get_str(VCONFKEY_LANGSET));
323         std::unique_ptr<char[]> pRegion(vconf_get_str(VCONFKEY_LANGSET));
324         const char name[] = "Accept-Language";
325         String value(L"");
326
327         if (pLang.get())
328         {
329                 if (pRegion.get())
330                 {
331                         value.Append(pLang.get());
332                         value.Append(L"_");
333                         value.Append(pRegion.get());
334                 }
335                 else
336                 {
337                         value.Append(pLang.get());
338                 }
339         }
340         else
341         {
342                 value = L"en";
343         }
344
345         std::unique_ptr<char[]> pValue(_StringConverter::CopyToCharArrayN(value));
346         SysTryReturnVoidResult(NID_WEB_CTRL, pValue.get(), E_OUT_OF_MEMORY, "[%s] Memory allocation failed.", GetErrorMessage(E_OUT_OF_MEMORY));
347
348         ewk_view_custom_header_add(__pWebFrame, name, pValue.get());
349 }
350
351
352 Evas_Object*
353 _EflWebkit::GetWebEvasObject(void) const
354 {
355         return __pWebFrame;
356 }
357
358
359 }}} // Tizen::Web::Controls