Implement of file quota callback
[platform/framework/web/crosswalk-tizen.git] / src / runtime / web_view.cc
1 // Copyright 2015 Samsung Electronics Co, Ltd. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "runtime/web_view.h"
6
7 #include <ewk_chromium.h>
8 #include <functional>
9
10 #include "runtime/native_window.h"
11
12 namespace wrt {
13
14 namespace {
15
16 // TODO(sngn.lee) : It should be declare in common header
17 const char* kKeyNameBack = "back";
18 const char* kKeyNameMenu = "menu";
19
20 static int ToWebRotation(int r) {
21   switch (r) {
22     case 0:
23     case 180:
24       return r;
25     case 90:
26       return -90;
27     case 270:
28       return 90;
29   }
30   return r;
31 }
32
33 }  // namespace
34
35
36 WebView::WebView(NativeWindow* window, Ewk_Context* context)
37     : window_(window),
38       context_(context),
39       ewk_view_(NULL),
40       listener_(NULL),
41       always_run_(false) {
42   Initialize();
43 }
44
45 WebView::~WebView() {
46   window_->RemoveRotationHandler(rotation_handler_id_);
47 }
48
49 void WebView::LoadUrl(const std::string& url) {
50   ewk_view_url_set(ewk_view_, url.c_str());
51 }
52
53 void WebView::Suspend() {
54   // change the visibility
55   ewk_view_visibility_set(ewk_view_, EINA_FALSE);
56
57   if (!always_run_) {
58     // suspend webview
59     ewk_view_suspend(ewk_view_);
60   }
61 }
62
63 void WebView::Resume() {
64   if (!always_run_) {
65     // resume webview
66     ewk_view_resume(ewk_view_);
67   }
68   // change the visiblity
69   ewk_view_visibility_set(ewk_view_, EINA_TRUE);
70 }
71
72 void WebView::Reload() {
73   ewk_view_reload(ewk_view_);
74 }
75
76 void WebView::AlwaysRun(bool run) {
77   always_run_ = run;
78 }
79
80 bool WebView::EvalJavascript(const std::string& script) {
81   return ewk_view_script_execute(ewk_view_, script.c_str(), NULL, NULL);
82 }
83
84 void WebView::Initialize() {
85   ewk_view_ = ewk_view_add_with_context(window_->evas_object(), context_);
86
87   // TODO(sngn.lee): To be implemented - orientation lock
88
89
90   auto key_callback = [](void* user_data,
91                          Evas_Object* /*obj*/,
92                          void* event_info) -> void {
93     WebView* self = static_cast<WebView*>(user_data);
94     Ea_Callback_Type key = static_cast<Ea_Callback_Type>(
95                               reinterpret_cast<int>(event_info));
96     self->OnKeyEvent(key);
97   };
98   ea_object_event_callback_add(ewk_view_,
99                                EA_CALLBACK_BACK,
100                                key_callback,
101                                this);
102   ea_object_event_callback_add(ewk_view_,
103                                EA_CALLBACK_MORE,
104                                key_callback,
105                                this);
106
107
108   // load statred callback
109   auto loadstart_callback = [](void* user_data,
110                                Evas_Object* /*obj*/,
111                                void*) {
112     WebView* self = static_cast<WebView*>(user_data);
113     if (self->listener_)
114       self->listener_->OnLoadStart(self);
115   };
116   evas_object_smart_callback_add(ewk_view_,
117                                  "load,started",
118                                  loadstart_callback,
119                                  this);
120   // load finished callback
121   auto loadfinished_callback = [](void* user_data,
122                                   Evas_Object*,
123                                   void*) {
124     WebView* self = static_cast<WebView*>(user_data);
125     if (self->listener_)
126       self->listener_->OnLoadFinished(self);
127   };
128   evas_object_smart_callback_add(ewk_view_,
129                                  "load,finished",
130                                  loadfinished_callback,
131                                  this);
132
133   // load progress callback
134   auto loadprogress_callback = [](void* user_data,
135                                   Evas_Object*,
136                                   void* event_info) {
137     WebView* self = static_cast<WebView*>(user_data);
138     double* progress = static_cast<double*>(event_info);
139     if (self->listener_)
140       self->listener_->OnLoadProgress(self, *progress);
141   };
142   evas_object_smart_callback_add(ewk_view_,
143                                  "load,progress",
144                                  loadprogress_callback,
145                                  this);
146   // rendered callback
147   auto rendered_callback = [](void* user_data,
148                               Evas_Object*,
149                               void*) {
150     WebView* self = static_cast<WebView*>(user_data);
151     if (self->listener_)
152       self->listener_->OnRendered(self);
153   };
154   evas_object_smart_callback_add(ewk_view_,
155                                  "frame,rendered",
156                                  rendered_callback,
157                                  this);
158
159   // "policy,navigation,decide"
160   auto navigation_decide_callback = [](void* user_data,
161                                        Evas_Object*,
162                                        void* event_info) {
163     WebView* self = static_cast<WebView*>(user_data);
164     Ewk_Policy_Decision* policy =
165             static_cast<Ewk_Policy_Decision*>(event_info);
166     const char* url = ewk_policy_decision_url_get(policy);
167
168     if (self->listener_) {
169       if (self->listener_->OnDidNavigation(self, url))
170         ewk_policy_decision_use(policy);
171       else
172         ewk_policy_decision_ignore(policy);
173     } else {
174       ewk_policy_decision_use(policy);
175     }
176   };
177   evas_object_smart_callback_add(ewk_view_,
178                                  "policy,navigation,decide",
179                                  navigation_decide_callback,
180                                  this);
181
182   // policy,newwindow,decide
183   auto newwindow_decide_callback = [](void* user_data,
184                                       Evas_Object*,
185                                       void* event_info) {
186     WebView* self = static_cast<WebView*>(user_data);
187     Ewk_Policy_Decision* policy =
188             static_cast<Ewk_Policy_Decision*>(event_info);
189
190     const char* url = ewk_policy_decision_url_get(policy);
191
192     if (self->listener_) {
193       if (self->listener_->OnDidNavigation(self, url) &&
194          self->listener_->OnDidOpenWindow(self, url)) {
195          ewk_policy_decision_use(policy);
196       } else {
197         ewk_policy_decision_ignore(policy);
198       }
199     } else {
200       ewk_policy_decision_use(policy);
201     }
202   };
203   evas_object_smart_callback_add(ewk_view_,
204                                  "policy,newwindow,decide",
205                                  newwindow_decide_callback,
206                                  this);
207
208   // callback for database quota exceeded
209   auto database_exceeded_callback = [](Evas_Object* view,
210                                        Ewk_Security_Origin* origin,
211                                        const char*,
212                                        uint64_t,
213                                        void*) -> Eina_Bool {
214     std::string protocol(ewk_security_origin_protocol_get(origin));
215     if (protocol == "file://" || protocol == "app://") {
216       // Allow for local origin
217       ewk_view_exceeded_database_quota_reply(view, EINA_TRUE);
218     } else {
219       // Deny for remote origin
220       ewk_view_exceeded_database_quota_reply(view, EINA_FALSE);
221     }
222     return EINA_TRUE;
223   };
224   ewk_view_exceeded_database_quota_callback_set(
225     ewk_view_,
226     database_exceeded_callback,
227     NULL);
228
229   // callback for indexed database quota exceeded
230   auto indexed_db_exceeded_callback = [](Evas_Object* view,
231                                        Ewk_Security_Origin* origin,
232                                        int64_t,
233                                        void*) -> Eina_Bool {
234     std::string protocol(ewk_security_origin_protocol_get(origin));
235     if (protocol == "file://" || protocol == "app://") {
236       // Allow for local origin
237       ewk_view_exceeded_indexed_database_quota_reply(view, EINA_TRUE);
238     } else {
239       // Deny for remote origin
240       ewk_view_exceeded_indexed_database_quota_reply(view, EINA_FALSE);
241     }
242     return EINA_TRUE;
243   };
244   ewk_view_exceeded_indexed_database_quota_callback_set(
245     ewk_view_,
246     indexed_db_exceeded_callback,
247     NULL);
248
249   // callback for localfile quota exceeded
250   auto localfile_exceeded_callback = [](Evas_Object* view,
251                                        Ewk_Security_Origin* origin,
252                                        int64_t,
253                                        void*) -> Eina_Bool {
254     std::string protocol(ewk_security_origin_protocol_get(origin));
255     if (protocol == "file://" || protocol == "app://") {
256       // Allow for local origin
257       ewk_view_exceeded_local_file_system_quota_reply(view, EINA_TRUE);
258     } else {
259       // Deny for remote origin
260       ewk_view_exceeded_local_file_system_quota_reply(view, EINA_FALSE);
261     }
262     return EINA_TRUE;
263   };
264   ewk_view_exceeded_local_file_system_quota_callback_set(
265     ewk_view_,
266     localfile_exceeded_callback,
267     NULL);
268
269   ewk_view_orientation_send(ewk_view_, ToWebRotation(window_->rotation()));
270   rotation_handler_id_ = window_->AddRotationHandler(
271                                   std::bind(&WebView::OnRotation,
272                                   this,
273                                   std::placeholders::_1));
274   // Show webview
275   evas_object_show(ewk_view_);
276 }
277
278 std::string WebView::GetUrl() {
279   return std::string(ewk_view_url_get(ewk_view_));
280 }
281
282 Evas_Object* WebView::evas_object() const {
283   return ewk_view_;
284 }
285
286 void WebView::OnRotation(int degree) {
287   ewk_view_orientation_send(ewk_view_, ToWebRotation(degree));
288 }
289
290 void WebView::OnKeyEvent(Ea_Callback_Type key_type) {
291   std::string keyname;
292   if (key_type == EA_CALLBACK_BACK) {
293     if (EINA_TRUE == ewk_view_text_selection_clear(ewk_view_)) {
294       return;
295     }
296     keyname = kKeyNameBack;
297   } else if (key_type == EA_CALLBACK_MORE) {
298     keyname = kKeyNameMenu;
299   } else {
300     return;
301   }
302
303   if (listener_)
304     listener_->OnHardwareKey(this, keyname);
305 }
306
307
308 }  // namespace wrt
309