add patch
[framework/osp/web.git] / src / controls / FWebCtrl_CertificateConfirmPopup.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_CertificateConfirmPopup.cpp
20  * @brief               The file contains the definition of _CertificateConfirmPopup class.
21  */
22 #include <FAppApp.h>
23 #include <FBaseColArrayList.h>
24 #include <FBaseSysLog.h>
25 #include <FBaseUtilUri.h>
26 #include <FGrpDimension.h>
27 #include <FGrpRectangle.h>
28 #include <FIoDbEnumerator.h>
29 #include <FIoDbStatement.h>
30 #include <FSecCertX509Certificate.h>
31 #include <FUiCtrlButton.h>
32 #include <FUiCtrlLabel.h>
33 #include <FUiCtrlPanel.h>
34 #include <FUiKeyEventInfo.h>
35 #include <FUiLayout.h>
36 #include <FUiVerticalBoxLayout.h>
37 #include <FIo_DatabaseImpl.h>
38 #include <FSys_SystemResource.h>
39 #include <FUi_ControlManager.h>
40 #include <FUi_ResourceManager.h>
41 #include "FWebCtrl_CertificateConfirmPopup.h"
42 #include "FWebCtrl_EflWebkit.h"
43 #include "FWebCtrl_Utility.h"
44 #include "FWebCtrl_WebImpl.h"
45
46
47 using namespace Tizen::Base;
48 using namespace Tizen::Base::Collection;
49 using namespace Tizen::Base::Utility;
50 using namespace Tizen::Graphics;
51 using namespace Tizen::Io;
52 using namespace Tizen::Security::Cert;
53 using namespace Tizen::System;
54 using namespace Tizen::Ui;
55 using namespace Tizen::Ui::Controls;
56
57
58 namespace Tizen { namespace Web { namespace Controls
59 {
60
61
62 static const int EDIT_TEXT_SIZE = 30;
63
64
65 _CertificateConfirmPopup::_CertificateConfirmPopup(void)
66                                                 : __certPopupMode(CERTIFICATE_POPUP_MODE_USER_CONFIRM)
67                                                 , __confirm(false)
68                                                 , __pCertificatePolicyData(null)
69                                                 , __pParent(null)
70                                                 , __pCertificatePopup(null)
71 {
72 }
73
74
75 _CertificateConfirmPopup::~_CertificateConfirmPopup(void)
76 {
77         if (IsModalPopup() == true)
78         {
79                 HandleUserAction(false);
80         }
81 }
82
83
84 result
85 _CertificateConfirmPopup::Construct(_CertificatePopupMode certPopupMode, Ewk_Certificate_Policy_Decision* pPolicy, Tizen::Web::Controls::_CertificateConfirmPopup* pParent)
86 {
87         SysTryReturnResult(NID_WEB_CTRL, pPolicy, E_INVALID_ARG, "Certificate Policy pointer is null.");
88         result r = E_SUCCESS;
89
90         _SystemResource* pSysResource = _SystemResource::GetInstance();
91         SysAssertf(pSysResource != null, "Failed to get _SystemResource instance");
92
93         _WebPopupData* pPopupData = _WebPopup::GetPopupData();
94         SysTryReturn(NID_WEB_CTRL, pPopupData, r = GetLastResult(), r, "[%s] Propagating.", GetErrorMessage(r));
95
96         __pCertificatePolicyData = pPolicy;
97         __certPopupMode = certPopupMode;
98         String titleText = L"";
99         int popupMaxHeight = 0;
100         Rectangle rect(0, 0, 0, 0);
101
102         __pParent = pParent;
103
104         ArrayList idList;
105         r = idList.Construct();
106         SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
107
108         ArrayList titleList;
109         r = titleList.Construct();
110         SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
111
112         if( __certPopupMode == CERTIFICATE_POPUP_MODE_VIEW )
113         {
114                 titleText = pSysResource->GetString(_RESOURCE_DOMAIN_ID_OSP, "IDS_TPLATFORM_HEADER_SECURITY_CERTIFICATE_ABB");
115                 popupMaxHeight = 4*pPopupData->labelDim.height + pPopupData->btnDim.height + 2*pPopupData->sideMargin;
116
117                 rect.height = 4*pPopupData->labelDim.height;
118                 rect.width = pPopupData->labelDim.width;
119
120                 idList.Add(*(new Integer(ID_BUTTON_CERTIFICATE_CLOSE)));
121                 titleList.Add(*(new String(pSysResource->GetString("sys_string", "IDS_TPLATFORM_BUTTON_OK"))));
122         }
123         else    // CERTIFICATE_POPUP_MODE_CONFIRM
124         {
125                 titleText = pSysResource->GetString(_RESOURCE_DOMAIN_ID_OSP, "IDS_TPLATFORM_HEADER_SECURITY_WARNING_ABB");
126                 popupMaxHeight = 2*pPopupData->labelDim.height + pPopupData->btnDim.height + 2*pPopupData->sideMargin;
127
128                 rect.height = 2*pPopupData->labelDim.height;
129                 rect.width = pPopupData->labelDim.width;
130
131                 idList.Add(*(new Integer(ID_BUTTON_CERTIFICATE_CANCEL)));
132                 idList.Add(*(new Integer(ID_BUTTON_CERTIFICATE_VIEW)));
133                 idList.Add(*(new Integer(ID_BUTTON_CERTIFICATE_ALLOW)));
134
135                 titleList.Add(*(new String(pSysResource->GetString(_RESOURCE_DOMAIN_ID_OSP, "IDS_TPLATFORM_BUTTON_CANCEL_ABB"))));
136                 titleList.Add(*(new String(pSysResource->GetString(_RESOURCE_DOMAIN_ID_OSP, "IDS_TPLATFORM_BUTTON2_VIEW_CERTIFICATE"))));
137                 titleList.Add(*(new String(pSysResource->GetString(_RESOURCE_DOMAIN_ID_OSP, "IDS_TPLATFORM_BUTTON_CONTINUE_ABB"))));
138         }
139
140         r = _WebPopup::Construct(true, Dimension(pPopupData->popupDim.width, popupMaxHeight));
141         SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
142
143         SetTitleText(titleText);
144
145         std::unique_ptr<VerticalBoxLayout> pLayout(dynamic_cast< VerticalBoxLayout* >(GetLayoutN()));
146         SysTryReturn(NID_WEB_CTRL, pLayout.get(), r = GetLastResult(), r, "[%s] Propagating.", GetErrorMessage(r));
147
148         if( certPopupMode == CERTIFICATE_POPUP_MODE_VIEW )
149         {
150                 String certString;
151                 result r = GenerateCertifiate(certString);
152                 SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
153
154                 std::unique_ptr<TextBox> pTextBox(new (std::nothrow) TextBox());
155                 SysTryReturnResult(NID_WEB_CTRL, pTextBox.get(), E_OUT_OF_MEMORY, "Memory Allocation failed.");
156
157                 r = pTextBox->Construct(rect, TEXT_BOX_BORDER_ROUNDED);
158                 SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
159
160                 r = pTextBox->SetTextSize(EDIT_TEXT_SIZE);
161                 SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
162
163                 r = pTextBox->SetAutoLinkMask(LINK_TYPE_NONE);
164                 SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
165
166                 r = pTextBox->SetText(certString);
167                 SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
168
169                 r = AddControl(*pTextBox);
170                 SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
171
172                 TextBox* pCertBox = pTextBox.release();
173                 pLayout->SetHorizontalAlignment(*pCertBox, LAYOUT_HORIZONTAL_ALIGN_CENTER);
174         }
175         else    // CERTIFICATE_POPUP_MODE_CONFIRM
176         {
177                 std::unique_ptr<Label> pLabel(new (std::nothrow) Label());
178                 SysTryReturnResult(NID_WEB_CTRL, pLabel.get(), E_OUT_OF_MEMORY, "Memory Allocation failed.");
179
180                 String message = L"";
181                 message = pSysResource->GetString(_RESOURCE_DOMAIN_ID_OSP, "IDS_TPLATFORM_BODY_THERE_ARE_PROBLEMS_WITH_THE_SECURITY_CERTIFICATE_FOR_THIS_SITE_C");
182                 message.Append(L"\n");
183                 message.Append(ewk_certificate_policy_decision_url_get(__pCertificatePolicyData));
184
185                 r = pLabel->Construct(rect, message);
186                 SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
187
188                 pLabel->SetTextConfig(pPopupData->labelFontSize, LABEL_TEXT_STYLE_NORMAL);
189
190                 r = AddControl(*pLabel);
191                 SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
192
193                 Label* pInfoLabel = pLabel.release();
194                 pLayout->SetHorizontalFitPolicy(*pInfoLabel, FIT_POLICY_PARENT);
195         }
196         Panel* pButtonPanel = CreateAndAddPanel();
197         SysTryReturn(NID_WEB_CTRL, pButtonPanel, GetLastResult(), GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
198
199         r = CreateAndAddButtons(idList, titleList, pButtonPanel);
200         SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
201
202         pLayout->SetHorizontalFitPolicy(*pButtonPanel, FIT_POLICY_PARENT);
203         pLayout->SetHorizontalAlignment(*pButtonPanel, LAYOUT_HORIZONTAL_ALIGN_CENTER);
204
205         pLayout->SetSpacing(*pButtonPanel, 2*pPopupData->sideMargin);
206
207         SetPropagatedKeyEventListener(this);
208
209         return E_SUCCESS;
210 }
211
212
213 void
214 _CertificateConfirmPopup::OnActionPerformed(const Control& source, int actionId)
215 {
216         result r = E_SUCCESS;
217
218         switch (actionId)
219         {
220         case ID_BUTTON_CERTIFICATE_ALLOW:
221                 HandleUserAction(true);
222                 break;
223
224         case ID_BUTTON_CERTIFICATE_VIEW:
225         {
226                 std::unique_ptr<_CertificateConfirmPopup> pCertificatePopup(new (std::nothrow) _CertificateConfirmPopup());
227                 SysTryReturnVoidResult(NID_WEB_CTRL, pCertificatePopup.get(), E_OUT_OF_MEMORY, "Memory Allocation failed.");
228
229                 r = pCertificatePopup->Construct(CERTIFICATE_POPUP_MODE_VIEW, __pCertificatePolicyData, this);
230                 SysTryReturnVoidResult(NID_WEB_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
231
232                 __pCertificatePopup = std::move(pCertificatePopup);
233
234                 r = __pCertificatePopup->ShowPopup();
235                 SysTryReturnVoidResult(NID_WEB_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
236                 __pCertificatePopup.release();
237                 return;
238         }
239
240         case ID_BUTTON_CERTIFICATE_CANCEL:
241                 HandleUserAction(false);
242                 break;
243
244         case ID_BUTTON_CERTIFICATE_CLOSE:
245                 break;
246
247         default:
248                 SysAssert(false);
249                 break;
250         }
251
252         r = HidePopup();
253         if (IsFailed(r))
254         {
255                 SysLogException(NID_WEB_CTRL, r, "[%s] Propagating.", GetErrorMessage(r));
256         }
257         if (__certPopupMode == CERTIFICATE_POPUP_MODE_VIEW)
258         {
259                 __pParent->SendUserEvent(ID_CERTIFICATE_CONFIRM_POPUP_CLOSE, null);
260         }
261 }
262
263
264 void
265 _CertificateConfirmPopup::OnUserEventReceivedN(RequestId requestId, IList* pArgs)
266 {
267         switch (requestId)
268         {
269         case ID_CERTIFICATE_CONFIRM_POPUP_CLOSE:
270                 __pCertificatePopup.reset();
271                 break;
272         default:
273                 break;
274         }
275
276 }
277
278
279 bool
280 _CertificateConfirmPopup::OnKeyPressed(Control& source, const KeyEventInfo& keyEventInfo)
281 {
282         return false;
283 }
284
285 bool
286 _CertificateConfirmPopup::OnKeyReleased(Control& source, const KeyEventInfo& keyEventInfo)
287 {
288         result r = E_SUCCESS;
289         if ((keyEventInfo.GetKeyCode() == KEY_ESC || keyEventInfo.GetKeyCode() == KEY_BACK) && source.GetShowState() == true)
290         {
291                 if (__certPopupMode == CERTIFICATE_POPUP_MODE_USER_CONFIRM)
292                 {
293                         HandleUserAction(false);
294                 }
295                 r = HidePopup();
296                 if (IsFailed(r))
297                 {
298                         SysLogException(NID_WEB_CTRL, r, "[%s] Propagating.", GetErrorMessage(r));
299                 }
300                 if (__certPopupMode == CERTIFICATE_POPUP_MODE_VIEW)
301                 {
302                         __pParent->SendUserEvent(ID_CERTIFICATE_CONFIRM_POPUP_CLOSE, null);
303                 }
304         }
305
306         return false;
307 }
308
309 bool
310 _CertificateConfirmPopup::OnPreviewKeyPressed(Control& source, const KeyEventInfo& keyEventInfo)
311 {
312         return false;
313 }
314
315 bool
316 _CertificateConfirmPopup::OnPreviewKeyReleased(Control& source, const KeyEventInfo& keyEventInfo)
317 {
318         return false;
319 }
320
321 bool
322 _CertificateConfirmPopup::TranslateKeyEventInfo(Control& source, KeyEventInfo& keyEventInfo)
323 {
324         return false;
325 }
326
327 bool
328 _CertificateConfirmPopup::GetConfirmResult() const
329 {
330         return __confirm;
331 }
332
333
334 void
335 _CertificateConfirmPopup::HandleUserAction(bool allow)
336 {
337         __confirm = allow;
338
339         String pem(ewk_certificate_policy_decision_certificate_pem_get(__pCertificatePolicyData));
340         ewk_certificate_policy_decision_allowed_set(__pCertificatePolicyData, static_cast< Eina_Bool >(allow));
341         AddCertificateDb(pem, allow);
342 }
343
344
345 void
346 _CertificateConfirmPopup::AddCertificateDb(const String& pem, bool allow)
347 {
348         _DatabaseImpl db;
349         String certificatePath(Tizen::App::App::GetInstance()->GetAppRootPath() + CUSTOM_DB_DIRECTORY_PATH + USER_CONFIRM_DB_NAME);
350         String table(CERTIFICATE_TABLE_NAME);
351
352         result r = db.Construct(certificatePath, "r+", null);
353         SysTryReturnVoidResult(NID_WEB_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
354
355         std::unique_ptr<DbStatement> pStmt(db.CreateStatementN(L"Insert Into " + table + L" (pem, allow) Values (?, ?)"));
356         SysTryReturnVoidResult(NID_WEB_CTRL, pStmt.get(), GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
357
358         SysLog(NID_WEB_CTRL, "The current value of pem is %ls, allow is %d", pem.GetPointer(), allow);
359
360         pStmt->BindString(0, pem);
361         pStmt->BindInt(1, static_cast < int >(allow));
362
363         db.BeginTransaction();
364
365         std::unique_ptr<DbEnumerator> pEnum(db.ExecuteStatementN(*pStmt));
366
367         db.CommitTransaction();
368 }
369
370
371 result
372 _CertificateConfirmPopup::GenerateCertifiate(String& certString)
373 {
374         SysTryReturnResult(NID_WEB_CTRL, __pCertificatePolicyData, E_INVALID_ARG, "Certificate Policy pointer is null.");
375
376         _SystemResource* pSysResource = _SystemResource::GetInstance();
377         SysAssertf(pSysResource != null, "Failed to get _SystemResource instance");
378
379         String pemString(ewk_certificate_policy_decision_certificate_pem_get(__pCertificatePolicyData));
380         std::unique_ptr<ByteBuffer> pByteBuf(StringUtil::StringToUtf8N(pemString));
381         SysTryReturnResult(NID_WEB_CTRL, pByteBuf.get(), E_INVALID_DATA, "Certificate pem information is Empty.");
382
383         X509Certificate certificate;
384         result r = certificate.Construct(*pByteBuf);
385         SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
386
387         //Issued to
388         certString.Append(pSysResource->GetString(_RESOURCE_DOMAIN_ID_OSP, "IDS_TPLATFORM_BODY_ISSUED_TO_C"));
389         certString.Append(L"\n\n");
390         String subject = certificate.GetSubject();
391
392         certString.Append(pSysResource->GetString(_RESOURCE_DOMAIN_ID_OSP, "IDS_TPLATFORM_BODY_COMMON_NAME_C"));
393         certString.Append(L"\n");
394         certString.Append(GetStringOfToken(subject, L"/CN=") + L"\n");
395
396         certString.Append(pSysResource->GetString(_RESOURCE_DOMAIN_ID_OSP, "IDS_TPLATFORM_BODY_ORGANISATION_C"));
397         certString.Append(L"\n");
398         certString.Append(GetStringOfToken(subject, L"/O=") + L"\n");
399
400         certString.Append(pSysResource->GetString(_RESOURCE_DOMAIN_ID_OSP ,"IDS_TPLATFORM_BODY_ORGANISATIONAL_UNIT_C"));
401         certString.Append(L"\n");
402         certString.Append(GetStringOfToken(subject, L"/OU=") + L"\n");
403
404         certString.Append(pSysResource->GetString(_RESOURCE_DOMAIN_ID_OSP, "IDS_TPLATFORM_BODY_SERIAL_NUMBER_C"));
405         certString.Append(L":\n");
406         certString.Append(certificate.GetSerialNumber() + L"\n\n\n");
407
408         //Issued by
409         certString.Append(pSysResource->GetString(_RESOURCE_DOMAIN_ID_OSP, "IDS_TPLATFORM_BODY_ISSUED_BY_C"));
410         certString.Append(L"\n\n");
411         String issuer = certificate.GetIssuer();
412
413         certString.Append(pSysResource->GetString(_RESOURCE_DOMAIN_ID_OSP, "IDS_TPLATFORM_BODY_COMMON_NAME_C"));
414         certString.Append(L"\n");
415         certString.Append(GetStringOfToken(issuer, L"/CN=") + L"\n");
416
417         certString.Append(pSysResource->GetString(_RESOURCE_DOMAIN_ID_OSP, "IDS_TPLATFORM_BODY_ORGANISATION_C"));
418         certString.Append(L"\n");
419         certString.Append(GetStringOfToken(issuer, L"/O=") + L"\n");
420
421         certString.Append(pSysResource->GetString(_RESOURCE_DOMAIN_ID_OSP, "IDS_TPLATFORM_BODY_ORGANISATIONAL_UNIT_C"));
422         certString.Append(L"\n");
423         certString.Append(GetStringOfToken(issuer, L"/OU=") + L"\n\n");
424
425         //Validity
426         certString.Append(pSysResource->GetString(_RESOURCE_DOMAIN_ID_OSP, "IDS_TPLATFORM_BODY_VALIDITY_C"));
427         certString.Append(L"\n\n");
428         certString.Append(pSysResource->GetString(_RESOURCE_DOMAIN_ID_OSP, "IDS_BR_POP_CERTI_VALID_FROM_C"));
429         certString.Append(L"\n");
430         certString.Append(certificate.GetNotBefore() + L"\n\n");
431
432         certString.Append(pSysResource->GetString(_RESOURCE_DOMAIN_ID_OSP, "IDS_BR_BODY_CERTIFICATE_VALID_TILL"));
433         certString.Append(L":\n");
434         certString.Append(certificate.GetNotAfter() + L"\n\n\n");
435
436         //FingerPrints
437         certString.Append(pSysResource->GetString(_RESOURCE_DOMAIN_ID_OSP, "IDS_TPLATFORM_BODY_FINGERPRINTS_C"));
438         certString.Append(L":\n\n");
439         certString.Append(pSysResource->GetString(_RESOURCE_DOMAIN_ID_OSP, "IDS_BR_BODY_SIGNATURE_ALGORITHM_VODA"));
440         certString.Append(L":\n");
441         certString.Append(certificate.GetSignatureAlgorithm() + L"\n\n");
442
443         std::unique_ptr<ByteBuffer> pFingerPrint(certificate.GetFingerprintN());
444         if (pFingerPrint.get() && pFingerPrint->GetPointer())
445         {
446                 String fingerPrint;
447                 StringUtil::Utf8ToString((const char*)pFingerPrint->GetPointer(), fingerPrint);
448                 certString.Append(fingerPrint + L"\n\n");
449         }
450
451         return E_SUCCESS;
452 }
453
454
455 String
456 _CertificateConfirmPopup::GetStringOfToken(const String& parseString, const String& parseToken)
457 {
458         String inString(parseString);
459         int index = 0;
460
461         String outString;
462         outString.Append(L"\n");
463
464         result r = inString.IndexOf(parseToken, 0, index);
465         SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, outString, r, "[%s] Propagating.", GetErrorMessage(r));
466
467         int prsTokLen = parseToken.GetLength();
468         r = inString.Remove(0, index + prsTokLen);
469         SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, outString, r, "[%s] Propagating.", GetErrorMessage(r));
470
471         while (true)
472         {
473                 r = inString.IndexOf(parseToken, 0, index);
474
475                 switch (r)
476                 {
477                 case E_SUCCESS:
478                         r = inString.Remove(index, prsTokLen);
479                         SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, outString, r, "[%s] Propagating.", GetErrorMessage(r));
480
481                         inString.Insert(L"\n", index);
482                         continue;
483
484                 case E_OBJ_NOT_FOUND:
485                         r = inString.IndexOf('=', 0, index);
486                         if (r == E_SUCCESS)
487                         {
488                                 int slashIndex = 0;
489                                 r = inString.LastIndexOf('/', index - 3, slashIndex);
490
491                                 if (!IsFailed(r) && (slashIndex == index - 2 || slashIndex == index - 3))
492                                 {
493                                         inString.Remove(slashIndex, inString.GetLength() - slashIndex);
494                                 }
495                         }
496                         inString.Append(L"\n");
497                         outString = inString;
498                         return outString;
499
500                 default:
501                         return outString;
502                 }
503         }
504 }
505
506
507 }}} // Tizen::Web::Controls