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.
5 #include "runtime/web_application.h"
7 #include <cert-service.h>
9 #include <ewk_chromium.h>
13 #include "common/message_types.h"
14 #include "runtime/native_window.h"
15 #include "runtime/command_line.h"
16 #include "runtime/web_view.h"
17 #include "runtime/vibration_manager.h"
20 // TODO(sngn.lee) : It should be declare in common header
21 const char* kKeyNameBack = "back";
23 const char* kAppControlEventScript = \
24 "var __event = document.createEvent(\"CustomEvent\");\n"
25 "__event.initCustomEvent(\"appcontrol\", true, true);\n"
26 "document.dispatchEvent(__event);\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"
36 "for (var i=0; i < window.frames.length; i++)\n"
37 "{ window.frames[i].document.dispatchEvent(__event); }";
42 WebApplication::WebApplication(const std::string& appid)
43 : initialized_(false),
45 ewk_context_(ewk_context_new()) {
47 std::unique_ptr<char, decltype(std::free)*>
48 path {app_get_data_path(), std::free};
49 app_data_path_ = path.get();
52 extension_server_ = new ExtensionServer(ewk_context_);
55 WebApplication::~WebApplication() {
56 ewk_context_delete(ewk_context_);
57 if (extension_server_)
58 delete extension_server_;
61 bool WebApplication::Initialize(NativeWindow* window) {
64 // start extension server
65 if (extension_server_)
66 extension_server_->Start();
69 ewk_context_cache_model_set(ewk_context_, EWK_CACHE_MODEL_DOCUMENT_BROWSER);
72 auto cookie_manager = ewk_context_cookie_manager_get(ewk_context_);
73 ewk_cookie_manager_accept_policy_set(cookie_manager,
74 EWK_COOKIE_ACCEPT_POLICY_ALWAYS);
76 // set persistent storage path
77 std::string cookie_path = data_path() + ".cookie";
78 ewk_cookie_manager_persistent_storage_set(
79 cookie_manager, cookie_path.c_str(),
80 EWK_COOKIE_PERSISTENT_STORAGE_SQLITE);
83 auto vibration_start_callback = [](uint64_t ms, void*) {
84 platform::VibrationManager::GetInstance()->Start(static_cast<int>(ms));
86 auto vibration_stop_callback = [](void* /*user_data*/) {
87 platform::VibrationManager::GetInstance()->Stop();
89 ewk_context_vibration_client_callbacks_set(ewk_context_,
90 vibration_start_callback,
91 vibration_stop_callback,
94 // Set certificate path
95 char* cert_path = cert_svc_get_certificate_crt_file_path();
96 if (cert_path != NULL) {
97 ewk_context_certificate_file_set(ewk_context_, cert_path);
100 // TODO(sngn.lee): find the proxy url
101 // ewk_context_proxy_uri_set(ewk_context_, ... );
105 void WebApplication::Launch() {
107 WebView* view = new WebView(window_, ewk_context_);
109 // TODO(sngn.lee): Get the start file
110 view->LoadUrl("index.html");
111 view_stack_.push_front(view);
112 window_->SetContent(view->evas_object());
114 // TODO(sngn.lee): below code only debug code
115 auto callback = [](void* data, Evas* e, Evas_Object* obj, void* eventInfo) -> void {
117 evas_object_geometry_get(obj, &x,&y,&w,&h);
118 fprintf(stderr,"resize ! (%d, %d, %d, %d)\n", x,y,w,h);
120 evas_object_event_callback_add(view->evas_object(), EVAS_CALLBACK_RESIZE, callback, NULL );
122 // TODO(sngn.lee): check the below code location.
123 // in Wearable, webkit can render contents before show window
124 // but Mobile, webkit can't render contents before show window
128 void WebApplication::AppControl() {
129 // TODO(sngn.lee): find the app control url and the reset options
131 // TODO(sngn.lee): Set the injected bundle into extension process
137 WebView* view = new WebView(window_, ewk_context_);
138 view->LoadUrl("file:///index.html");
139 view_stack_.push_front(view);
140 window_->SetContent(view->evas_object());
143 SendAppControlEvent();
147 void WebApplication::SendAppControlEvent() {
148 auto it = view_stack_.begin();
149 while (it != view_stack_.end()) {
150 (*it)->EvalJavascript(kAppControlEventScript);
154 void WebApplication::ClearViewStack() {
155 window_->SetContent(NULL);
156 auto it = view_stack_.begin();
157 while (it != view_stack_.end()) {
164 void WebApplication::Resume() {
165 if (view_stack_.size() > 0 && view_stack_.front() != NULL)
166 view_stack_.front()->SetVisibility(true);
168 // TODO(sngn.lee) : should be check the background support option
169 // if background suuport options was on, skip below code
171 auto it = view_stack_.begin();
172 for ( ; it != view_stack_.end(); ++it) {
177 void WebApplication::Suspend() {
178 if (view_stack_.size() > 0 && view_stack_.front() != NULL)
179 view_stack_.front()->SetVisibility(false);
181 // TODO(sngn.lee) : should be check the background support option
182 // if background suuport options was on, skip below code
183 auto it = view_stack_.begin();
184 for ( ; it != view_stack_.end(); ++it) {
189 void WebApplication::OnCreatedNewWebView(WebView* view, WebView* new_view) {
190 if (view_stack_.size() > 0 && view_stack_.front() != NULL)
191 view_stack_.front()->SetVisibility(false);
193 view_stack_.push_front(new_view);
194 window_->SetContent(new_view->evas_object());
197 void WebApplication::OnClosedWebView(WebView * view) {
198 if (view_stack_.size() == 0)
201 WebView* current = view_stack_.front();
202 if (current == view) {
203 view_stack_.pop_front();
205 auto found = std::find(view_stack_.begin(), view_stack_.end(), view);
206 if (found != view_stack_.end()) {
207 view_stack_.erase(found);
211 if (view_stack_.size() == 0) {
212 // TODO(sngn.lee): terminate the webapp
213 } else if (current != view_stack_.front()) {
214 view_stack_.front()->SetVisibility(true);
215 window_->SetContent(view_stack_.front()->evas_object());
221 void WebApplication::OnRendered(WebView* view) {
225 void WebApplication::OnReceivedWrtMessage(
227 Ewk_IPC_Wrt_Message_Data* message) {
229 Eina_Stringshare* msg_type = ewk_ipc_wrt_message_data_type_get(message);
231 #define START_WITHS(x, s) (strncmp(x, s, strlen(s)) == 0)
233 if (START_WITHS(msg_type, message_types::kExtensionTypePrefix)) {
234 extension_server_->HandleWrtMessage(message);
237 // TODO(wy80.choi): handle other message type?
238 // changeUserAgent, clearAllCookie, GetWindowID, hide, exit, blockedUrl
244 void WebApplication::OnOrientationLock(WebView* view,
246 int preferred_rotation) {
247 if (view_stack_.size() == 0)
250 // Only top-most view can set the orientation relate operation
251 if (view_stack_.front() != view)
254 // TODO(sngn.lee): check the orientaion setting
255 // if allow the auto orientation
256 // if (is not allow orientation) {
260 window_->SetRotationLock(preferred_rotation);
262 window_->SetAutoRotation();
266 void WebApplication::OnHardwareKey(WebView* view, const std::string& keyname) {
267 // TODO(sngn.lee): Check the hw key event was enabled
268 if (true && kKeyNameBack == keyname) {
269 view->EvalJavascript(kBackKeyEventScript);