b74831df0ef78ad87f63385e05b4372059fd6189
[framework/osp/web.git] / src / controls / FWebCtrl_UserConfirmPopup.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_UserConfirmPopup.cpp
20  * @brief               The file contains the definition of _UserConfirmPopup 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 <FUiLayout.h>
35 #include <FUiVerticalBoxLayout.h>
36 #include <FIo_DatabaseImpl.h>
37 #include <FUi_ControlManager.h>
38 #include <FUi_ResourceManager.h>
39 #include "FWebCtrl_EflWebkit.h"
40 #include "FWebCtrl_UserConfirmPopup.h"
41 #include "FWebCtrl_Utility.h"
42
43
44 using namespace Tizen::Base;
45 using namespace Tizen::Base::Collection;
46 using namespace Tizen::Base::Utility;
47 using namespace Tizen::Graphics;
48 using namespace Tizen::Io;
49 using namespace Tizen::Security::Cert;
50 using namespace Tizen::Ui;
51 using namespace Tizen::Ui::Controls;
52
53
54 namespace Tizen { namespace Web { namespace Controls
55 {
56
57
58 _UserConfirmPopup::_UserConfirmPopup(void)
59         : __pUserPolicyData(null)
60         , __userConfirmMode(USER_CONFIRM_USERMEDIA)
61         , __pCheckButton(null)
62         , __sync(false)
63 {
64 }
65
66
67 _UserConfirmPopup::~_UserConfirmPopup(void)
68 {
69 }
70
71
72 result
73 _UserConfirmPopup::Construct(_UserConfirmMode userConfirmMode, void* pEventInfo, Tizen::Base::String msg, bool sync)
74 {
75         result r = E_SUCCESS;
76         SysTryReturnResult(NID_WEB_CTRL, pEventInfo, E_INVALID_ARG, "Invalid argument(s) is used. pPolicy is null.");
77         SysTryReturnResult(NID_WEB_CTRL, userConfirmMode >= USER_CONFIRM_USERMEDIA && userConfirmMode <= USER_CONFIRM_INDEXED_DB_QUOTA_EXCEDED, E_INVALID_ARG,
78                                         "Invalid userConfirmMode is used. [%d]", userConfirmMode);
79
80         _WebPopupData* pPopupData = _WebPopup::GetPopupData();
81         SysTryReturn(NID_WEB_CTRL, pPopupData, r = GetLastResult(), r, "[%s] Propagating.", GetErrorMessage(r));
82
83         __pUserPolicyData = pEventInfo;
84         __userConfirmMode = userConfirmMode;
85         __sync = sync;
86         __defMsg = msg;
87
88         int popupMaxHeight = 2*pPopupData->labelDim.height + 2*pPopupData->btnDim.height + 6*pPopupData->sideMargin;
89         if (__userConfirmMode == USER_CONFIRM_GEOLOCATION)
90         {
91                 popupMaxHeight +=  pPopupData->checkDim.height;
92         }
93
94         r = _WebPopup::Construct(true, Dimension(pPopupData->popupDim.width, popupMaxHeight));
95         SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
96
97         SetTitleText("Security Warning");
98
99         Rectangle rect(0, 0, 0, 0);
100
101         //label
102         rect.height = 2*pPopupData->labelDim.height;
103         rect.width = pPopupData->labelDim.width;
104
105         std::unique_ptr<Label> pLabel(new (std::nothrow) Label());
106         SysTryReturnResult(NID_WEB_CTRL, pLabel.get(), E_OUT_OF_MEMORY, "Memory Allocation failed.");
107
108         String message = GetMessageFromPolicy();
109         r = pLabel->Construct(rect, message);
110         SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
111
112         pLabel->SetTextConfig(pPopupData->labelFontSize, LABEL_TEXT_STYLE_NORMAL);
113
114         r = AddControl(*pLabel);
115         SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
116
117         Label* pInfoLabel = pLabel.release();
118         //checkbutton
119         if (__userConfirmMode == USER_CONFIRM_GEOLOCATION)
120         {
121                 rect.y = 0;
122                 rect.height = pPopupData->checkDim.height;
123
124                 std::unique_ptr<CheckButton> pCheckButton (new (std::nothrow) CheckButton());
125                 SysTryReturnResult(NID_WEB_CTRL, pCheckButton.get(), E_OUT_OF_MEMORY, "Memory Allocation failed.");
126
127                 r = pCheckButton->Construct(Rectangle(0, 0, rect.width, rect.height), CHECK_BUTTON_STYLE_MARK, BACKGROUND_STYLE_NONE, false, L"Remember Preference");
128                 SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
129
130                 r = AddControl(*pCheckButton);
131                 SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
132
133                 __pCheckButton = pCheckButton.release();
134         }
135
136         Panel* pButtonPanel = CreateAndAddPanel();
137         SysTryReturn(NID_WEB_CTRL, pButtonPanel, GetLastResult(), GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
138
139         ArrayList idList;
140         r = idList.Construct();
141         SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
142         idList.Add(*(new Integer(ID_BUTTON_USER_ALLOW)));
143         idList.Add(*(new Integer(ID_BUTTON_USER_CANCEL)));
144
145         ArrayList titleList;
146         r = titleList.Construct();
147         SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
148         titleList.Add(*(new String(L"Allow")));
149         titleList.Add(*(new String(L"Cancel")));
150
151         r = CreateAndAddButtons(idList, titleList, pButtonPanel);
152         SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
153
154         std::unique_ptr<VerticalBoxLayout> pLayout(dynamic_cast< VerticalBoxLayout* >(GetLayoutN()));
155         SysTryReturn(NID_WEB_CTRL, pLayout.get(), r = GetLastResult(), GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
156
157         pLayout->SetHorizontalAlignment(*pInfoLabel, LAYOUT_HORIZONTAL_ALIGN_CENTER);
158         if (__userConfirmMode == USER_CONFIRM_GEOLOCATION)
159         {
160                 pLayout->SetHorizontalAlignment(*__pCheckButton, LAYOUT_HORIZONTAL_ALIGN_CENTER);
161         }
162         pLayout->SetHorizontalAlignment(*pButtonPanel, LAYOUT_HORIZONTAL_ALIGN_CENTER);
163
164         pLayout->SetSpacing(*pButtonPanel, 2*pPopupData->sideMargin);
165
166         return E_SUCCESS;
167 }
168
169
170 void
171 _UserConfirmPopup::OnActionPerformed(const Control& source, int actionId)
172 {
173         result r = E_SUCCESS;
174
175         switch (actionId)
176         {
177         case ID_BUTTON_USER_ALLOW:
178                 HandleUserAction(EINA_TRUE);
179                 break;
180
181         case ID_BUTTON_USER_CANCEL:
182                 HandleUserAction(EINA_FALSE);
183                 break;
184
185         default:
186                 break;
187         }
188
189         r = HidePopup();
190         if (IsFailed(r))
191         {
192                 SysLogException(NID_WEB_CTRL, r, "[%s] Propagating.", GetErrorMessage(r));
193         }
194
195         if (!__sync)
196         {
197                 delete this;
198         }
199 }
200
201
202 String
203 _UserConfirmPopup::GetMessageFromPolicy(void)
204 {
205         String message;
206
207         switch(__userConfirmMode)
208         {
209         case USER_CONFIRM_USERMEDIA:
210         {
211                 message = L"Do you want to allow acccess to media?\n";
212                 break;
213         }
214         case USER_PROTOCOL_HANDLER:
215         {
216                 Ewk_Custom_Handlers_Data* pHandlerData = reinterpret_cast< Ewk_Custom_Handlers_Data* >(__pUserPolicyData);
217                 SysAssertf(pHandlerData, "Failed to request");
218
219                 String target(ewk_custom_handlers_data_target_get(pHandlerData));
220                 String baseUri(ewk_custom_handlers_data_base_url_get(pHandlerData));
221
222                 message = baseUri + String(L" is asking to register ") + target + String(L" protocol handler.");
223                 break;
224         }
225         case USER_CONTENT_HANDLER:
226         {
227                 Ewk_Custom_Handlers_Data* pHandlerData = reinterpret_cast< Ewk_Custom_Handlers_Data* >(__pUserPolicyData);
228                 SysAssertf(pHandlerData, "Failed to request");
229
230                 String target(ewk_custom_handlers_data_target_get(pHandlerData));
231                 String baseUri(ewk_custom_handlers_data_base_url_get(pHandlerData));
232
233                 message = String(baseUri) + String(L" is asking to register ") + String(target) + String(L" content handler.");
234                 break;
235         }
236         case USER_CONFIRM_GEOLOCATION:
237         {
238                 Ewk_Geolocation_Permission_Request* pGeoLocPermReq = reinterpret_cast< Ewk_Geolocation_Permission_Request* >(__pUserPolicyData);
239                 const Ewk_Security_Origin* pSecurityOrigin = ewk_geolocation_permission_request_origin_get(pGeoLocPermReq);
240
241                 message = _Utility::CreateOrigin(pSecurityOrigin);
242                 message.Append(" Requests your Location");
243                 break;
244         }
245         case USER_CONFIRM_APP_CACHE:
246                 //fall through
247         case USER_CONFIRM_DB_QUOTA_EXCEDED:
248                 //fall through
249         case USER_CONFIRM_LOCAL_FS_QUOTA_EXCEDED:
250                 //fall through
251         case USER_CONFIRM_INDEXED_DB_QUOTA_EXCEDED:
252                 message = __defMsg;
253                 break;
254
255         default:
256                 SysAssert(false);
257         }
258
259         return message;
260 }
261
262
263 void
264 _UserConfirmPopup::HandleUserAction(Eina_Bool allow)
265 {
266         switch (__userConfirmMode)
267         {
268         case USER_CONFIRM_USERMEDIA:
269         {
270                 Ewk_User_Media_Permission_Request* pPolicy = reinterpret_cast< Ewk_User_Media_Permission_Request* >(__pUserPolicyData);
271                 ewk_user_media_permission_request_set(pPolicy, allow);
272                 break;
273         }
274         case USER_PROTOCOL_HANDLER:
275         {
276                 RegisterHandler(false, allow);
277                 break;
278         }
279         case USER_CONTENT_HANDLER:
280         {
281                 RegisterHandler(true, allow);
282                 break;
283         }
284         case USER_CONFIRM_GEOLOCATION:
285         {
286                 Ewk_Geolocation_Permission_Request* pPolicy =  reinterpret_cast< Ewk_Geolocation_Permission_Request* >(__pUserPolicyData);
287                 if (__pCheckButton->IsSelected())
288                 {
289                         result r = AddGeolocationDb(pPolicy, static_cast < bool >(allow));
290                         SysTryCatch(NID_WEB_CTRL, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
291                 }
292 CATCH:
293                 ewk_geolocation_permission_request_set(pPolicy, allow);
294                 break;
295         }
296         case USER_CONFIRM_APP_CACHE:
297         {
298                 Evas_Object *pObj = reinterpret_cast< Evas_Object* >(__pUserPolicyData);
299                 ewk_view_application_cache_permission_reply(pObj, allow);
300                 break;
301         }
302
303         case USER_CONFIRM_DB_QUOTA_EXCEDED:
304         {
305                 Evas_Object *pObj = reinterpret_cast< Evas_Object* >(__pUserPolicyData);
306                 ewk_view_exceeded_database_quota_reply(pObj, allow);
307                 break;
308         }
309
310         case USER_CONFIRM_LOCAL_FS_QUOTA_EXCEDED:
311         {
312                 Evas_Object *pObj = reinterpret_cast< Evas_Object* >(__pUserPolicyData);
313                 ewk_view_exceeded_local_file_system_quota_reply(pObj, allow);
314                 break;
315         }
316
317         case USER_CONFIRM_INDEXED_DB_QUOTA_EXCEDED:
318         {
319                 Evas_Object *pObj = reinterpret_cast< Evas_Object* >(__pUserPolicyData);
320                 ewk_view_exceeded_indexed_database_quota_reply(pObj, allow);
321                 break;
322         }
323
324         default:
325                 SysAssert(false);
326         }
327 }
328
329
330 result
331 _UserConfirmPopup::AddGeolocationDb(Ewk_Geolocation_Permission_Request* pPolicy, bool enable)
332 {
333         _DatabaseImpl db;
334         String geolocationPath(Tizen::App::App::GetInstance()->GetAppRootPath() + CUSTOM_DB_DIRECTORY_PATH + USER_CONFIRM_DB_NAME);
335         String table(GEOLOCATION_TABLE_NAME);
336
337         const Ewk_Security_Origin* pSecurityOrigin = ewk_geolocation_permission_request_origin_get(pPolicy);
338         String origin = _Utility::CreateOrigin(pSecurityOrigin);
339
340         result r = db.Construct(geolocationPath, "r+", null);
341         SysTryReturn(NID_WEB_CTRL, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
342
343         std::unique_ptr<DbStatement> pStmt(db.CreateStatementN(L"Insert Into " + table + L" (origin, permission) Values (?, ?)"));
344         SysTryReturn(NID_WEB_CTRL, pStmt.get(), GetLastResult(), GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
345
346         SysLog(NID_WEB_CTRL, "The current value of stmt is %u, host is %ls", pStmt.get(), origin.GetPointer());
347
348         pStmt->BindString(0, origin);
349         pStmt->BindInt(1, static_cast < int >(enable));
350
351         db.BeginTransaction();
352
353         std::unique_ptr<DbEnumerator> pEnum(db.ExecuteStatementN(*pStmt));
354
355         db.CommitTransaction();
356
357         return E_SUCCESS;
358 }
359
360 void
361 _UserConfirmPopup::RegisterHandler(bool checkHandler, Eina_Bool allow)
362 {
363         _DatabaseImpl db;
364         String handlerPath(Tizen::App::App::GetInstance()->GetAppRootPath() + CUSTOM_DB_DIRECTORY_PATH + USER_CONFIRM_DB_NAME);
365         String table;
366         int checkId = 0;
367
368         if(checkHandler == true)
369         {
370                 table = CUSTOM_CONTENT_TABLE_NAME;
371         }
372         else
373         {
374                 table = CUSTOM_PROTOCOL_TABLE_NAME;
375         }
376         Ewk_Custom_Handlers_Data* pHandlerData = reinterpret_cast< Ewk_Custom_Handlers_Data* >(__pUserPolicyData);
377         SysAssertf(pHandlerData, "Failed to request");
378
379         String baseUri(ewk_custom_handlers_data_base_url_get(pHandlerData));
380         String uri = ewk_custom_handlers_data_url_get(pHandlerData);
381         String target = ewk_custom_handlers_data_target_get(pHandlerData);
382
383         result r = db.Construct(handlerPath, "r+", null);
384         SysTryReturnVoidResult(NID_WEB_CTRL, r == E_SUCCESS, r, "[%s] Propagating.", GetErrorMessage(r));
385
386         std::unique_ptr<DbEnumerator> pEnum(db.QueryN(L"Select id From " + table + L" Where baseUrl = '" + baseUri + L"' AND url = '" + uri + L"' AND mime = '" + target + L"'"));
387
388         if(pEnum.get())
389         {
390                 pEnum->MoveNext();
391                 pEnum->GetIntAt(0, checkId);
392
393                 std::unique_ptr<DbStatement> pUpdateStmt(db.CreateStatementN(L"Update " + table + L" Set allow = (?) Where id = (?)"));
394                 SysTryReturnVoidResult(NID_WEB_CTRL, pUpdateStmt.get(), GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
395
396                 pUpdateStmt->BindInt(0, static_cast < int >(allow));
397                 pUpdateStmt->BindInt(1, checkId);
398
399                 db.BeginTransaction();
400
401                 std::unique_ptr<DbEnumerator> pEnum(db.ExecuteStatementN(*pUpdateStmt));
402
403                 db.CommitTransaction();
404
405         }
406         else
407         {
408                 std::unique_ptr<DbStatement> pStmt(db.CreateStatementN(L"Insert Into " + table + L" (baseUrl, url, mime, allow) Values (?, ?, ?, ?)"));
409                 SysTryReturnVoidResult(NID_WEB_CTRL, pStmt.get(),  GetLastResult(), "[%s] Propagating.", GetErrorMessage(GetLastResult()));
410
411                 pStmt->BindString(0, baseUri);
412                 pStmt->BindString(1, uri);
413                 pStmt->BindString(2, target);
414                 pStmt->BindInt(3, static_cast < int >(allow));
415
416                 db.BeginTransaction();
417
418                 std::unique_ptr<DbEnumerator> pRegisterEnum(db.ExecuteStatementN(*pStmt));
419
420                 db.CommitTransaction();
421         }
422 }
423
424 }}} // Tizen::Web::Controls