2219fb2a93099873881f2f783efa447a4dd7df46
[platform/framework/web/crosswalk-tizen.git] / src / runtime / web_application.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_application.h"
6
7 #include <cert-service.h>
8 #include <app.h>
9 #include <ewk_chromium.h>
10 #include <algorithm>
11 #include <memory>
12
13 #include "runtime/native_window.h"
14 #include "runtime/command_line.h"
15 #include "runtime/web_view.h"
16 #include "runtime/vibration_manager.h"
17
18 namespace {
19
20   // TODO(sngn.lee) : It should be declare in common header
21   const char* kKeyNameBack = "back";
22
23   const char* kAppControlEventScript = \
24         "var __event = document.createEvent(\"CustomEvent\");\n"
25         "__event.initCustomEvent(\"appcontrol\", true, true);\n"
26         "document.dispatchEvent(__event);\n"
27         "\n"
28         "for (var i=0; i < window.frames.length; i++)\n"
29         "{ window.frames[i].document.dispatchEvent(__event); }";
30   const char* kBackKeyEventScript = \
31         "var __event = document.createEvent(\"CustomEvent\");\n"
32         "__event.initCustomEvent(\"tizenhwkey\", true, true);\n"
33         "__event.keyName = \"back\";\n"
34         "document.dispatchEvent(__event);\n"
35         "\n"
36         "for (var i=0; i < window.frames.length; i++)\n"
37         "{ window.frames[i].document.dispatchEvent(__event); }";
38
39 }  // namespace
40
41 namespace wrt {
42
43 WebApplication::WebApplication(const std::string& appid)
44     : initialized_(false),
45       appid_(appid), ewk_context_(ewk_context_new()) {
46   std::unique_ptr<char, decltype(std::free)*>
47     path {app_get_data_path(), std::free};
48   app_data_path_ = path.get();
49 }
50
51 WebApplication::~WebApplication() {
52   ewk_context_delete(ewk_context_);
53 }
54
55 bool WebApplication::Initialize(NativeWindow* window) {
56   window_ = window;
57
58   // ewk setting
59   ewk_context_cache_model_set(ewk_context_, EWK_CACHE_MODEL_DOCUMENT_BROWSER);
60
61   // cookie
62   auto cookie_manager = ewk_context_cookie_manager_get(ewk_context_);
63   ewk_cookie_manager_accept_policy_set(cookie_manager,
64                                        EWK_COOKIE_ACCEPT_POLICY_ALWAYS);
65
66   // set persistent storage path
67   std::string cookie_path = data_path() + ".cookie";
68   ewk_cookie_manager_persistent_storage_set(
69                                       cookie_manager, cookie_path.c_str(),
70                                       EWK_COOKIE_PERSISTENT_STORAGE_SQLITE);
71
72   // vibration callback
73   auto vibration_start_callback = [](uint64_t ms, void*) {
74     platform::VibrationManager::GetInstance()->Start(static_cast<int>(ms));
75   };
76   auto vibration_stop_callback = [](void* /*user_data*/) {
77     platform::VibrationManager::GetInstance()->Stop();
78   };
79   ewk_context_vibration_client_callbacks_set(ewk_context_,
80                                              vibration_start_callback,
81                                              vibration_stop_callback,
82                                              NULL);
83
84   // Set certificate path
85   char* cert_path = cert_svc_get_certificate_crt_file_path();
86   if (cert_path != NULL) {
87     ewk_context_certificate_file_set(ewk_context_, cert_path);
88   }
89
90   // TODO(sngn.lee): find the proxy url
91   // ewk_context_proxy_uri_set(ewk_context_, ... );
92   return true;
93 }
94
95 void WebApplication::Launch() {
96   initialized_ = true;
97   WebView* view = new WebView(window_, ewk_context_);
98
99   // TODO(sngn.lee): Get the start file
100   view->LoadUrl("index.html");
101   view_stack_.push_front(view);
102   window_->SetContent(view->evas_object());
103
104   // TODO(sngn.lee): below code only debug code
105   auto callback = [](void* data, Evas* e, Evas_Object* obj, void* eventInfo) -> void {
106     int x,y,w,h;
107     evas_object_geometry_get(obj, &x,&y,&w,&h);
108     fprintf(stderr,"resize ! (%d, %d, %d, %d)\n", x,y,w,h);
109   };
110   evas_object_event_callback_add(view->evas_object(), EVAS_CALLBACK_RESIZE, callback, NULL );
111
112   // TODO(sngn.lee): check the below code location.
113   // in Wearable, webkit can render contents before show window
114   // but Mobile, webkit can't render contents before show window
115   window_->Show();
116 }
117
118 void WebApplication::AppControl() {
119   // TODO(sngn.lee): find the app control url and the reset options
120
121   // TODO(sngn.lee): Set the injected bundle into extension process
122
123
124   if (true) {
125     // Reset to context
126     ClearViewStack();
127     WebView* view = new WebView(window_, ewk_context_);
128     view->LoadUrl("file:///index.html");
129     view_stack_.push_front(view);
130     window_->SetContent(view->evas_object());
131   } else {
132     // Send Event
133     SendAppControlEvent();
134   }
135 }
136
137 void WebApplication::SendAppControlEvent() {
138   auto it = view_stack_.begin();
139   while (it != view_stack_.end()) {
140     (*it)->EvalJavascript(kAppControlEventScript);
141   }
142 }
143
144 void WebApplication::ClearViewStack() {
145   window_->SetContent(NULL);
146   auto it = view_stack_.begin();
147   while (it != view_stack_.end()) {
148     (*it)->Suspend();
149     delete *it;
150   }
151   view_stack_.clear();
152 }
153
154 void WebApplication::Resume() {
155   if (view_stack_.size() > 0 && view_stack_.front() != NULL)
156     view_stack_.front()->SetVisibility(true);
157
158   // TODO(sngn.lee) : should be check the background support option
159   // if background suuport options was on, skip below code
160
161   auto it = view_stack_.begin();
162   for ( ; it != view_stack_.end(); ++it) {
163     (*it)->Resume();
164   }
165 }
166
167 void WebApplication::Suspend() {
168   if (view_stack_.size() > 0 && view_stack_.front() != NULL)
169     view_stack_.front()->SetVisibility(false);
170
171   // TODO(sngn.lee) : should be check the background support option
172   // if background suuport options was on, skip below code
173   auto it = view_stack_.begin();
174   for ( ; it != view_stack_.end(); ++it) {
175     (*it)->Suspend();
176   }
177 }
178
179 void WebApplication::OnCreatedNewWebView(WebView* view, WebView* new_view) {
180   if (view_stack_.size() > 0 && view_stack_.front() != NULL)
181     view_stack_.front()->SetVisibility(false);
182
183   view_stack_.push_front(new_view);
184   window_->SetContent(new_view->evas_object());
185 }
186
187 void WebApplication::OnClosedWebView(WebView * view) {
188   if (view_stack_.size() == 0)
189     return;
190
191   WebView* current = view_stack_.front();
192   if (current == view) {
193     view_stack_.pop_front();
194   } else {
195     auto found = std::find(view_stack_.begin(), view_stack_.end(), view);
196     if (found != view_stack_.end()) {
197       view_stack_.erase(found);
198     }
199   }
200
201   if (view_stack_.size() == 0) {
202     // TODO(sngn.lee): terminate the webapp
203   } else if (current != view_stack_.front()) {
204     view_stack_.front()->SetVisibility(true);
205     window_->SetContent(view_stack_.front()->evas_object());
206   }
207
208   delete view;
209 }
210
211 void WebApplication::OnRendered(WebView* view) {
212 }
213
214
215 void WebApplication::OnReceivedWrtMessage(
216     WebView* view,
217     const Ewk_IPC_Wrt_Message_Data& message) {
218   // TODO(wy80.choi): To be implemented
219 }
220
221 void WebApplication::OnOrientationLock(WebView* view,
222                                        bool lock,
223                                        int preferred_rotation) {
224   if (view_stack_.size() == 0)
225     return;
226
227   // Only top-most view can set the orientation relate operation
228   if (view_stack_.front() != view)
229     return;
230
231   // TODO(sngn.lee): check the orientaion setting
232   // if allow the auto orientation
233   // if (is not allow orientation) {
234   //   return;
235   // }
236   if ( lock ) {
237     window_->SetRotationLock(preferred_rotation);
238   } else {
239     window_->SetAutoRotation();
240   }
241 }
242
243 void WebApplication::OnHardwareKey(WebView* view, const std::string& keyname) {
244   // TODO(sngn.lee): Check the hw key event was enabled
245   if (true && kKeyNameBack == keyname) {
246     view->EvalJavascript(kBackKeyEventScript);
247   }
248 }
249
250 }  // namespace wrt