From 38e9ba832327c75448136718b1240b23f8af07b4 Mon Sep 17 00:00:00 2001 From: Youngsoo Choi Date: Tue, 27 Dec 2016 00:23:50 +0900 Subject: [PATCH 01/16] Defer main loop until window is completely closed When uninstalling a webapp is performed while running the webapp, there's no enough time for termination of render thread by |OnTerminate|. In that case, the life-cycle of main loop needs to be guaranteed until closing window callback is called. So, this CL defers main loop until window is completely closed and removes previously implemented timer for the termination. Bug: TSAM-12072 Url: http://suprem.sec.samsung.net/jira/browse/TSAM-12072 Change-Id: I095d522f70d1c1759d07f697a179986fea7ebab5 Signed-off-by: Youngsoo Choi --- runtime/browser/ime_runtime.cc | 1 + runtime/browser/runtime.cc | 15 +++++++++++++++ runtime/browser/runtime.h | 5 +++++ runtime/browser/runtime_process.cc | 26 +++++--------------------- runtime/browser/ui_runtime.cc | 3 +-- runtime/browser/watch_runtime.cc | 9 +-------- runtime/browser/watch_runtime.h | 1 - runtime/browser/web_application.cc | 9 +++++++-- 8 files changed, 35 insertions(+), 34 deletions(-) mode change 100755 => 100644 runtime/browser/runtime.cc mode change 100644 => 100755 runtime/browser/runtime.h diff --git a/runtime/browser/ime_runtime.cc b/runtime/browser/ime_runtime.cc index 9cdc3db..0527c83 100644 --- a/runtime/browser/ime_runtime.cc +++ b/runtime/browser/ime_runtime.cc @@ -164,6 +164,7 @@ void ImeRuntime::OnCreate() { void ImeRuntime::OnTerminate() { LOGGER(DEBUG) << "ime_app_terminate"; + ClosePageFromOnTerminate(application_); } void ImeRuntime::OnShow(int context_id, ime_context_h context) { diff --git a/runtime/browser/runtime.cc b/runtime/browser/runtime.cc old mode 100755 new mode 100644 index 051ffe0..a2e0c03 --- a/runtime/browser/runtime.cc +++ b/runtime/browser/runtime.cc @@ -32,6 +32,8 @@ namespace runtime { +bool Runtime::is_on_terminate_called = false; + Runtime::~Runtime() { } @@ -55,5 +57,18 @@ std::unique_ptr Runtime::MakeRuntime( } } +void Runtime::ClosePageFromOnTerminate(WebApplication* app) { + if (app) { + std::list vstack = app->view_stack(); + auto it = vstack.begin(); + if (it != vstack.end()) { + Runtime::is_on_terminate_called = true; + for (; it != vstack.end(); ++it) { + vstack.front()->SetVisibility(false); + ewk_view_page_close((*it)->evas_object()); + } + } + } +} } // namespace runtime diff --git a/runtime/browser/runtime.h b/runtime/browser/runtime.h old mode 100644 new mode 100755 index db4ef00..b4f1029 --- a/runtime/browser/runtime.h +++ b/runtime/browser/runtime.h @@ -22,6 +22,7 @@ #include #include "common/application_data.h" +#include "runtime/browser/web_application.h" namespace runtime { @@ -31,8 +32,12 @@ class Runtime { virtual int Exec(int argc, char* argv[]) = 0; + static bool is_on_terminate_called; static std::unique_ptr MakeRuntime( common::ApplicationData* app_data); + + protected: + void ClosePageFromOnTerminate(WebApplication* app); }; } // namespace runtime diff --git a/runtime/browser/runtime_process.cc b/runtime/browser/runtime_process.cc index 0f015fe..1d01b99 100755 --- a/runtime/browser/runtime_process.cc +++ b/runtime/browser/runtime_process.cc @@ -33,17 +33,10 @@ #include "runtime/browser/prelauncher.h" #include "runtime/browser/preload_manager.h" -bool g_prelaunch = false; +#include "runtime/browser/ui_runtime.h" -#ifdef IME_FEATURE_SUPPORT -static Ecore_Timer* timeout = NULL; +bool g_prelaunch = false; -static Eina_Bool terminateDelayCallback(void* data) { - timeout = NULL; - ecore_main_loop_quit(); - return ECORE_CALLBACK_CANCEL; -} -#endif #ifdef WATCH_FACE_FEATURE_SUPPORT static int setWatchEnv(int argc, char **argv) { bundle *kb = NULL; @@ -139,20 +132,11 @@ int real_main(int argc, char* argv[]) { std::unique_ptr runtime = runtime::Runtime::MakeRuntime(appdata); ret = runtime->Exec(argc, argv); + if (runtime->is_on_terminate_called) { + ecore_main_loop_begin(); + } runtime.reset(); } -#ifdef IME_FEATURE_SUPPORT - if (appdata->app_type() == common::ApplicationData::IME) { - timeout = ecore_timer_add(0.5, terminateDelayCallback, NULL); - // This timer is added because of deadlock issue. - // If default keyboard is switched from webapp keyboard to tizen keyboard - // before webapp keyboard is completely loaded, main loop waits - // until webview is closed where webview is waiting to finish load. - // This timer delays main loop shutdown until webview load is finished. - // FIXME: http://suprem.sec.samsung.net/jira/browse/TSAM-11361 - ecore_main_loop_begin(); - } -#endif ewk_shutdown(); elm_shutdown(); elm_exit(); diff --git a/runtime/browser/ui_runtime.cc b/runtime/browser/ui_runtime.cc index 20dddc6..4e20943 100755 --- a/runtime/browser/ui_runtime.cc +++ b/runtime/browser/ui_runtime.cc @@ -142,8 +142,7 @@ bool UiRuntime::OnCreate() { } void UiRuntime::OnTerminate() { - application_.reset(); - native_window_.reset(); + ClosePageFromOnTerminate(application_.get()); } void UiRuntime::OnPause() { diff --git a/runtime/browser/watch_runtime.cc b/runtime/browser/watch_runtime.cc index afc3dbd..657a7f1 100644 --- a/runtime/browser/watch_runtime.cc +++ b/runtime/browser/watch_runtime.cc @@ -99,14 +99,7 @@ bool WatchRuntime::OnCreate() { } void WatchRuntime::OnTerminate() { - if (application_) { - delete application_; - application_ = nullptr; - } - if (native_window_) { - delete native_window_; - native_window_ = nullptr; - } + ClosePageFromOnTerminate(application_); } void WatchRuntime::OnPause() { diff --git a/runtime/browser/watch_runtime.h b/runtime/browser/watch_runtime.h index 8838c0d..94c23d2 100644 --- a/runtime/browser/watch_runtime.h +++ b/runtime/browser/watch_runtime.h @@ -24,7 +24,6 @@ #include "common/application_data.h" #include "runtime/browser/runtime.h" #include "runtime/browser/native_window.h" -#include "runtime/browser/web_application.h" namespace runtime { diff --git a/runtime/browser/web_application.cc b/runtime/browser/web_application.cc index d146265..30be530 100755 --- a/runtime/browser/web_application.cc +++ b/runtime/browser/web_application.cc @@ -44,6 +44,7 @@ #include "runtime/browser/vibration_manager.h" #include "runtime/browser/web_view.h" #include "runtime/browser/splash_screen.h" +#include "runtime/browser/ui_runtime.h" #include "extensions/common/xwalk_extension_server.h" #ifndef INJECTED_BUNDLE_PATH @@ -709,8 +710,12 @@ void WebApplication::RemoveWebViewFromStack(WebView* view) { } void WebApplication::OnClosedWebView(WebView* view) { - is_terminated_by_callback_ = true; - RemoveWebViewFromStack(view); + is_terminated_by_callback_ = true; + RemoveWebViewFromStack(view); + + if (runtime::Runtime::is_on_terminate_called) { + ecore_main_loop_quit(); + } } void WebApplication::OnReceivedWrtMessage(WebView* /*view*/, -- 2.7.4 From 8c28224dffb6361852e26af2153433e3fadc9df8 Mon Sep 17 00:00:00 2001 From: Youngcheol Kang Date: Tue, 27 Dec 2016 16:09:11 +0900 Subject: [PATCH 02/16] Reply to javascript dialog before closing webview In order to prevent crash/fress issue, this patch adds the codes which call the ewk_view_javascript_alert_reply() when internal popup was opened. Bug: http://suprem.sec.samsung.net/jira/browse/TWF-2715 Change-Id: I029f0cbc4ffc5b8bb9cdf2dc35d40e0f69c9338f Signed-off-by: Youngcheol Kang --- runtime/browser/web_application.cc | 6 +++++- runtime/browser/web_view.cc | 4 ++++ runtime/browser/web_view.h | 1 + runtime/browser/web_view_impl.cc | 8 ++++++++ runtime/browser/web_view_impl.h | 1 + 5 files changed, 19 insertions(+), 1 deletion(-) diff --git a/runtime/browser/web_application.cc b/runtime/browser/web_application.cc index 30be530..f5f16ba 100755 --- a/runtime/browser/web_application.cc +++ b/runtime/browser/web_application.cc @@ -711,6 +711,8 @@ void WebApplication::RemoveWebViewFromStack(WebView* view) { void WebApplication::OnClosedWebView(WebView* view) { is_terminated_by_callback_ = true; + // Reply to javascript dialog for preventing freeze issue. + view->ReplyToJavascriptDialog(); RemoveWebViewFromStack(view); if (runtime::Runtime::is_on_terminate_called) { @@ -718,7 +720,7 @@ void WebApplication::OnClosedWebView(WebView* view) { } } -void WebApplication::OnReceivedWrtMessage(WebView* /*view*/, +void WebApplication::OnReceivedWrtMessage(WebView* view, Ewk_IPC_Wrt_Message_Data* msg) { Eina_Stringshare* msg_type = ewk_ipc_wrt_message_data_type_get(msg); @@ -739,6 +741,8 @@ void WebApplication::OnReceivedWrtMessage(WebView* /*view*/, window_->InActive(); } else if (TYPE_IS("tizen://exit")) { // One Way Message + // Reply to javascript dialog for preventing freeze issue. + view->ReplyToJavascriptDialog(); ecore_idler_add(ExitAppIdlerCallback, this); } else if (TYPE_IS("tizen://changeUA")) { // Async Message diff --git a/runtime/browser/web_view.cc b/runtime/browser/web_view.cc index c96a28f..7f2b4fe 100644 --- a/runtime/browser/web_view.cc +++ b/runtime/browser/web_view.cc @@ -32,6 +32,10 @@ WebView::~WebView() { delete impl_; } +void WebView::ReplyToJavascriptDialog() { + impl_->ReplyToJavascriptDialog(); +} + void WebView::LoadUrl(const std::string& url, const std::string& mime) { impl_->LoadUrl(url, mime); } diff --git a/runtime/browser/web_view.h b/runtime/browser/web_view.h index 29a6fad..9441db2 100644 --- a/runtime/browser/web_view.h +++ b/runtime/browser/web_view.h @@ -116,6 +116,7 @@ class WebView { WebView(NativeWindow* window, Ewk_Context* context); virtual ~WebView(); + void ReplyToJavascriptDialog(); void LoadUrl(const std::string& url, const std::string& mime = std::string()); std::string GetUrl(); diff --git a/runtime/browser/web_view_impl.cc b/runtime/browser/web_view_impl.cc index 25b2dc3..ca2a92c 100644 --- a/runtime/browser/web_view_impl.cc +++ b/runtime/browser/web_view_impl.cc @@ -87,6 +87,7 @@ WebViewImpl::WebViewImpl(WebView* view, WebViewImpl::~WebViewImpl() { if (internal_popup_opened_) { + internal_popup_opened_ = false; ewk_view_javascript_alert_reply(ewk_view_); } Deinitialize(); @@ -95,6 +96,13 @@ WebViewImpl::~WebViewImpl() { evas_smart_free(evas_smart_class_); } +void WebViewImpl::ReplyToJavascriptDialog() { + if (internal_popup_opened_) { + internal_popup_opened_ = false; + ewk_view_javascript_alert_reply(ewk_view_); + } +} + void WebViewImpl::LoadUrl(const std::string& url, const std::string& mime) { SCOPE_PROFILE(); if (!mime.empty()) { diff --git a/runtime/browser/web_view_impl.h b/runtime/browser/web_view_impl.h index eba7748..b97fb79 100644 --- a/runtime/browser/web_view_impl.h +++ b/runtime/browser/web_view_impl.h @@ -36,6 +36,7 @@ class WebViewImpl { WebViewImpl(WebView* view, NativeWindow* window, Ewk_Context* context); virtual ~WebViewImpl(); + void ReplyToJavascriptDialog(); void LoadUrl(const std::string& url, const std::string& mime = std::string()); std::string GetUrl(); -- 2.7.4 From 6fc53455d5b8b4d0693cced38e70e5ebfd7f2bb1 Mon Sep 17 00:00:00 2001 From: Youngmin Yoo Date: Thu, 29 Dec 2016 11:01:33 +0900 Subject: [PATCH 03/16] Change UserMedia popup message 3.0 UserMedia popup message has wrong mapping. BUG : http://suprem.sec.samsung.net/jira/browse/TWF-2729 Change-Id: Id74ea20f780f00ac35123975f661715653c2fae3 Signed-off-by: Youngmin Yoo --- runtime/browser/popup_string.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/browser/popup_string.cc b/runtime/browser/popup_string.cc index 8bf48be..d6172d6e 100755 --- a/runtime/browser/popup_string.cc +++ b/runtime/browser/popup_string.cc @@ -40,7 +40,7 @@ const char kPopupBodyCert[] = const char kPopupBodyGeoLocation[] = "IDS_WRT_BODY_ALLOWS_THIS_SITE_TO_ACCESS_YOUR_LOCATION_INFORMATION"; const char kPopupBodyUserMedia[] = - "IDS_WRT_BODY_ALLOWS_THIS_SITE_TO_USE_THE_MEDIA_FILES_STORED_ON_YOUR_DEVICE"; + "IDS_BR_POP_P1SS_HP2SS_IS_REQUESTING_PERMISSION_TO_USE_YOUR_CAMERA"; const char kPopupBodyWebNotification[] = "IDS_WRT_BODY_ALLOWS_THIS_SITE_TO_DISPLAY_NOTIFICATIONS"; const char kPopupBodyWebStorage[] = -- 2.7.4 From a554a6ba46892023faf3a4aef4cc6bb9a7ae9fa6 Mon Sep 17 00:00:00 2001 From: Youngsoo Choi Date: Mon, 2 Jan 2017 22:33:48 +0900 Subject: [PATCH 04/16] Refactor ClosePageFromOnTerminate The view stack needs to be handled in class WebApplication. Bug: http://suprem.sec.samsung.net/jira/browse/TWF-2743 Change-Id: Ide43a3d254da9d1746b5235a97ed401aa24ea7b8 Signed-off-by: Youngsoo Choi --- runtime/browser/runtime.cc | 13 ++----------- runtime/browser/web_application.cc | 11 +++++++++++ runtime/browser/web_application.h | 1 + 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/runtime/browser/runtime.cc b/runtime/browser/runtime.cc index a2e0c03..bba1168 100644 --- a/runtime/browser/runtime.cc +++ b/runtime/browser/runtime.cc @@ -58,17 +58,8 @@ std::unique_ptr Runtime::MakeRuntime( } void Runtime::ClosePageFromOnTerminate(WebApplication* app) { - if (app) { - std::list vstack = app->view_stack(); - auto it = vstack.begin(); - if (it != vstack.end()) { - Runtime::is_on_terminate_called = true; - for (; it != vstack.end(); ++it) { - vstack.front()->SetVisibility(false); - ewk_view_page_close((*it)->evas_object()); - } - } - } + if (app) + app->ClosePageFromOnTerminate(); } } // namespace runtime diff --git a/runtime/browser/web_application.cc b/runtime/browser/web_application.cc index f5f16ba..753711a 100755 --- a/runtime/browser/web_application.cc +++ b/runtime/browser/web_application.cc @@ -655,6 +655,17 @@ void WebApplication::Terminate() { extension_server->Shutdown(); } +void WebApplication::ClosePageFromOnTerminate() { + auto it = view_stack_.begin(); + if (it != view_stack_.end()) { + runtime::Runtime::is_on_terminate_called = true; + for (; it != view_stack_.end(); ++it) { + view_stack_.front()->SetVisibility(false); + ewk_view_page_close((*it)->evas_object()); + } + } +} + void WebApplication::OnCreatedNewWebView(WebView* /*view*/, WebView* new_view) { if (view_stack_.size() > 0 && view_stack_.front() != NULL) view_stack_.front()->SetVisibility(false); diff --git a/runtime/browser/web_application.h b/runtime/browser/web_application.h index f219a37..1c31d21 100755 --- a/runtime/browser/web_application.h +++ b/runtime/browser/web_application.h @@ -52,6 +52,7 @@ class WebApplication : public WebView::EventListener { void Suspend(); void Terminate(); + void ClosePageFromOnTerminate(); std::string data_path() const { return app_data_path_; } void set_terminator(std::function terminator) { terminator_ = terminator; -- 2.7.4 From 8b10d34491ddfcc7cf5fd3d75aa873e070c2ea7e Mon Sep 17 00:00:00 2001 From: Youngsoo Choi Date: Tue, 3 Jan 2017 13:10:51 +0900 Subject: [PATCH 05/16] Reply to javascript dialog when exiting by command |pkgcmd| There's an issue not to kill web app when javascript dialog is opened even if the command |pkgcmd -k -n | is executed to kill the web app. To prevent the issue, this CL replies to the dialog to close it right before the termination. Bug: TSAM-11809, TSAM-11813 Url: http://suprem.sec.samsung.net/jira/browse/TSAM-11809 Url: http://suprem.sec.samsung.net/jira/browse/TSAM-11813 Change-Id: I4757f45b3731d25cb57876f12c7b2e52b9f62af7 Signed-off-by: Youngsoo Choi --- runtime/browser/web_application.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/runtime/browser/web_application.cc b/runtime/browser/web_application.cc index 753711a..856c8ab 100755 --- a/runtime/browser/web_application.cc +++ b/runtime/browser/web_application.cc @@ -660,6 +660,7 @@ void WebApplication::ClosePageFromOnTerminate() { if (it != view_stack_.end()) { runtime::Runtime::is_on_terminate_called = true; for (; it != view_stack_.end(); ++it) { + (*it)->ReplyToJavascriptDialog(); view_stack_.front()->SetVisibility(false); ewk_view_page_close((*it)->evas_object()); } -- 2.7.4 From 5b72df93ded5c2f5dcbb8a1135ae9bc1937e0760 Mon Sep 17 00:00:00 2001 From: Sanjana Venkatachalam Date: Fri, 30 Dec 2016 14:51:29 +0530 Subject: [PATCH 06/16] Check web app's view mode when exiting fullscreen [Issue#] PLM P161223-02573 [Problem] Indicator is visible when user exits fullscreen after watching a video in Hotstar web app even if viewmodes="fullscreen" is mentioned in config.xml [Cause] When exit fullscreen callback is received, indicator is shown even if viewmode of webapp is fullscreen [Solution] Indicator is not shown if viewmode of webapp is fullscreen [Verification] 1) Build and install crosswalk-tizen rpm 2) Launch Hotstar webapp and play any video 3) Open fullscreen mode and exit fullscreen 4) Indicator should not be visible Change-Id: Ic7452d3da8f7e53ef4768b3f8ed619504fbc208e --- runtime/browser/native_window.cc | 7 ++++++- runtime/browser/native_window.h | 2 ++ runtime/browser/web_application.cc | 1 + 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/runtime/browser/native_window.cc b/runtime/browser/native_window.cc index 5712dff..9350c66 100755 --- a/runtime/browser/native_window.cc +++ b/runtime/browser/native_window.cc @@ -72,6 +72,7 @@ NativeWindow::NativeWindow() : window_(NULL), window_type_(Type::NORMAL), initialized_(false), + currentViewModeFullScreen_(false), focus_(NULL), content_(NULL), rotation_(0), @@ -271,6 +272,10 @@ void NativeWindow::SetAutoRotation() { rotation_ = elm_win_rotation_get(window_); } +void NativeWindow::SetCurrentViewModeFullScreen(bool mode) { + currentViewModeFullScreen_ = mode; +} + void NativeWindow::Show() { evas_object_show(window_); } @@ -285,7 +290,7 @@ void NativeWindow::InActive() { void NativeWindow::FullScreen(bool enable) { elm_win_indicator_opacity_set(window_, - enable ? ELM_WIN_INDICATOR_TRANSPARENT : ELM_WIN_INDICATOR_OPAQUE); + (enable || currentViewModeFullScreen_) ? ELM_WIN_INDICATOR_TRANSPARENT : ELM_WIN_INDICATOR_OPAQUE); } #ifdef MANUAL_ROTATE_FEATURE_SUPPORT diff --git a/runtime/browser/native_window.h b/runtime/browser/native_window.h index e939a01..7d23aa0 100755 --- a/runtime/browser/native_window.h +++ b/runtime/browser/native_window.h @@ -50,6 +50,7 @@ class NativeWindow { void SetRotationLock(int degree); void SetRotationLock(ScreenOrientation orientation); void SetAutoRotation(); + void SetCurrentViewModeFullScreen(bool mode); int AddRotationHandler(RotationHandler handler); void RemoveRotationHandler(int id); int rotation() const { return rotation_; } @@ -78,6 +79,7 @@ class NativeWindow { void DidFocusChanged(bool got); bool initialized_; + bool currentViewModeFullScreen_; Evas_Object* focus_; Evas_Object* content_; int rotation_; diff --git a/runtime/browser/web_application.cc b/runtime/browser/web_application.cc index 856c8ab..540b4e8 100755 --- a/runtime/browser/web_application.cc +++ b/runtime/browser/web_application.cc @@ -441,6 +441,7 @@ bool WebApplication::Initialize() { if (app_data_->widget_info() != NULL && app_data_->widget_info()->view_modes() == "fullscreen") { + window_->SetCurrentViewModeFullScreen(true); window_->FullScreen(true); } -- 2.7.4 From 193e6ee21adb9a80d4ef885c336ce2c54d5edc33 Mon Sep 17 00:00:00 2001 From: "jaekuk, lee" Date: Wed, 4 Jan 2017 11:13:00 +0900 Subject: [PATCH 07/16] Add a api of tizen version when creating new web view. Change-Id: Ica6df4f23e4a6637ae448e95080fcfb882add280 Signed-off-by: jaekuk, lee --- runtime/browser/web_application.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/runtime/browser/web_application.cc b/runtime/browser/web_application.cc index 856c8ab..4d8fe2c 100755 --- a/runtime/browser/web_application.cc +++ b/runtime/browser/web_application.cc @@ -579,6 +579,7 @@ void WebApplication::AppControl( ClearViewStack(); WebView* view = view_stack_.front(); SetupWebView(view); + SetupWebViewTizenApplicationInfo(view); view->SetDefaultEncoding(res->encoding()); view->LoadUrl(res->uri(), res->mime()); window_->SetContent(view->evas_object()); @@ -672,6 +673,7 @@ void WebApplication::OnCreatedNewWebView(WebView* /*view*/, WebView* new_view) { view_stack_.front()->SetVisibility(false); SetupWebView(new_view); + SetupWebViewTizenApplicationInfo(new_view); view_stack_.push_front(new_view); window_->SetContent(new_view->evas_object()); } -- 2.7.4 From 345ed487fb09774323ab7d23fbbf6a5bb1eec7f8 Mon Sep 17 00:00:00 2001 From: "jaekuk, lee" Date: Wed, 4 Jan 2017 11:13:00 +0900 Subject: [PATCH 08/16] Add a api of tizen version when creating new web view and when receiving a event of appcontrol. Change-Id: Ica6df4f23e4a6637ae448e95080fcfb882add280 Signed-off-by: jaekuk, lee --- runtime/browser/web_application.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/runtime/browser/web_application.cc b/runtime/browser/web_application.cc index 856c8ab..4d8fe2c 100755 --- a/runtime/browser/web_application.cc +++ b/runtime/browser/web_application.cc @@ -579,6 +579,7 @@ void WebApplication::AppControl( ClearViewStack(); WebView* view = view_stack_.front(); SetupWebView(view); + SetupWebViewTizenApplicationInfo(view); view->SetDefaultEncoding(res->encoding()); view->LoadUrl(res->uri(), res->mime()); window_->SetContent(view->evas_object()); @@ -672,6 +673,7 @@ void WebApplication::OnCreatedNewWebView(WebView* /*view*/, WebView* new_view) { view_stack_.front()->SetVisibility(false); SetupWebView(new_view); + SetupWebViewTizenApplicationInfo(new_view); view_stack_.push_front(new_view); window_->SetContent(new_view->evas_object()); } -- 2.7.4 From 20e92af566b0a619411521620a978069f7ac8543 Mon Sep 17 00:00:00 2001 From: "jaekuk, lee" Date: Thu, 5 Jan 2017 12:32:33 +0900 Subject: [PATCH 09/16] Modify prefix and suffix checking the allowed domain Change-Id: I960af6fd8254fcf071516f43f53f9650f0c357b2 Signed-off-by: jaekuk, lee --- common/resource_manager.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) mode change 100644 => 100755 common/resource_manager.cc diff --git a/common/resource_manager.cc b/common/resource_manager.cc old mode 100644 new mode 100755 index 203f454..8881428 --- a/common/resource_manager.cc +++ b/common/resource_manager.cc @@ -519,12 +519,12 @@ bool ResourceManager::CheckAllowNavigation(const std::string& url) { bool prefix_wild = false; bool suffix_wild = false; std::string a_domain = a_domain_info.domain(); - if (utils::StartsWith(a_domain, "*.")) { + if (utils::StartsWith(a_domain, "*")) { prefix_wild = true; // *.domain.com -> .domain.com a_domain = a_domain.substr(1); } - if (utils::EndsWith(a_domain, ".*")) { + if (utils::EndsWith(a_domain, "*")) { suffix_wild = true; // domain.* -> domain. a_domain = a_domain.substr(0, a_domain.length() - 1); -- 2.7.4 From cdda603905ece7c48b08917f083e5f83dc10bb16 Mon Sep 17 00:00:00 2001 From: Youngmin Yoo Date: Thu, 5 Jan 2017 12:58:18 +0900 Subject: [PATCH 10/16] Fix URI scheme parsing IP/Host on the internet ex) http://user:password@www.tizen.org:8080/market/Item?12345 url_ = http://user:password@www.tizen.org:8080/market/Item?12345 scheme_ = http domain_ = www.tizen.org user_ = user password_ = password Link : https://www.w3.org/Addressing/rfc1738.txt Bug : P161229-04063 Bug : http://suprem.sec.samsung.net/jira/browse/TWF-2753 Change-Id: I71fbc95c5b71cd36c370c3ed34fe6d8176cb21a7 Signed-off-by: Youngmin Yoo --- common/url.cc | 5 +++++ common/url.h | 10 ++++++---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/common/url.cc b/common/url.cc index adfbff1..898190c 100644 --- a/common/url.cc +++ b/common/url.cc @@ -109,9 +109,14 @@ void URLImpl::ExtractDomain() { size_t start_of_domain = scheme_.empty() ? 0 : scheme_.length() + kSchemeIdLen; size_t end_of_domain = url_.find_first_of('/', start_of_domain); + size_t at = url_.find_first_of('@', start_of_domain); + if (at < end_of_domain) { + start_of_domain = at + 1; + } domain_ = url_.substr(start_of_domain, end_of_domain == std::string::npos ? std::string::npos : end_of_domain - start_of_domain); + LOGGER(INFO) << "Extract Domain is " << domain_; } void URLImpl::ExtractDomainPort() { diff --git a/common/url.h b/common/url.h index 89ef348..222e738 100644 --- a/common/url.h +++ b/common/url.h @@ -38,12 +38,14 @@ class URLImpl; * => domain_, path_ * * If the url does not have specific data, an empty string will be stored - * in the corresponding variables. + * in the corresponding variables.(RFC 1738) * - * ex) http://user:password@www.google.co.kr:8080/market/Item?12345 - * url_ = http://user:password@www.google.co.kr:8080/market/Item?12345 + * ex) http://user:password@www.tizen.org:8080/market/Item?12345 + * url_ = http://user:password@www.tizen.org:8080/market/Item?12345 * scheme_ = http - * domain_ = user:password@www.google.co.kr + * user_ = user + * password_ = password + * domain_ = www.tizen.org * port_ = 8080 * path_ = /market/Item?12345 */ -- 2.7.4 From 7ba3ec0f4e4b83abf21ad2b9bf8fd46a65427383 Mon Sep 17 00:00:00 2001 From: "ws29.jung" Date: Thu, 5 Jan 2017 13:22:04 +0900 Subject: [PATCH 11/16] Fix Hardware Key action when popup is on This patch fix hardware key handling when popup is shown. Before this patch, hardware key handled in wrt before popup action is done when key is repidly tabbed. Now when popup is on, wrt will not trigger event. Bug: http://suprem.sec.samsung.net/jira/browse/TSAM-12331 Change-Id: I7b620e4f4349e8c54849ee9d24a66c0ccbe062f7 Signed-off-by: ws29.jung --- runtime/browser/web_view_impl.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/browser/web_view_impl.cc b/runtime/browser/web_view_impl.cc index ca2a92c..cc52275 100644 --- a/runtime/browser/web_view_impl.cc +++ b/runtime/browser/web_view_impl.cc @@ -993,7 +993,7 @@ void WebViewImpl::OnKeyEvent(Eext_Callback_Type key_type) { return; } - if (listener_) { + if (listener_ && !internal_popup_opened_) { listener_->OnHardwareKey(view_, keyname); } } -- 2.7.4 From a3b39d11bcfdb312ccbfde756457a9b1de87c946 Mon Sep 17 00:00:00 2001 From: "jaekuk, lee" Date: Thu, 5 Jan 2017 12:32:33 +0900 Subject: [PATCH 12/16] Modify prefix and suffix checking the allowed domain [P161229-05961]login page runs in browser Change-Id: I960af6fd8254fcf071516f43f53f9650f0c357b2 Signed-off-by: jaekuk, lee --- common/resource_manager.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) mode change 100644 => 100755 common/resource_manager.cc diff --git a/common/resource_manager.cc b/common/resource_manager.cc old mode 100644 new mode 100755 index 203f454..8881428 --- a/common/resource_manager.cc +++ b/common/resource_manager.cc @@ -519,12 +519,12 @@ bool ResourceManager::CheckAllowNavigation(const std::string& url) { bool prefix_wild = false; bool suffix_wild = false; std::string a_domain = a_domain_info.domain(); - if (utils::StartsWith(a_domain, "*.")) { + if (utils::StartsWith(a_domain, "*")) { prefix_wild = true; // *.domain.com -> .domain.com a_domain = a_domain.substr(1); } - if (utils::EndsWith(a_domain, ".*")) { + if (utils::EndsWith(a_domain, "*")) { suffix_wild = true; // domain.* -> domain. a_domain = a_domain.substr(0, a_domain.length() - 1); -- 2.7.4 From 4bd9dac4a614ade1d3f3171cba62a67b73341ea8 Mon Sep 17 00:00:00 2001 From: Youngsoo Choi Date: Wed, 4 Jan 2017 18:01:10 +0900 Subject: [PATCH 13/16] Refactor for unifying fragmented termination sequences There have been fragmented termination sequences of following exit scenarios. * h/w back key * exit pop up menu * exit command |pkgcmd -k| * uninstall command |pkgcmd -u| while webapp runs This CL makes those termination sequences go through a extended main loop. Also, removing view stacks is only handled from closing window callback and then the extended main loop quits to terminate webapp. The extneded main loop provides enough time for termination of renderer thread and prevents dead lock. Bug: http://suprem.sec.samsung.net/jira/browse/TWF-2765 Change-Id: I0f6e8092bd092c07a841c6cab20be22c67fe4928 Signed-off-by: Youngsoo Choi --- runtime/browser/runtime_process.cc | 1 + runtime/browser/web_application.cc | 47 +++++++++++--------------------------- runtime/browser/web_application.h | 1 - 3 files changed, 14 insertions(+), 35 deletions(-) diff --git a/runtime/browser/runtime_process.cc b/runtime/browser/runtime_process.cc index 1d01b99..859aa3a 100755 --- a/runtime/browser/runtime_process.cc +++ b/runtime/browser/runtime_process.cc @@ -133,6 +133,7 @@ int real_main(int argc, char* argv[]) { runtime::Runtime::MakeRuntime(appdata); ret = runtime->Exec(argc, argv); if (runtime->is_on_terminate_called) { + LOGGER(INFO) << "Defer termination of main loop"; ecore_main_loop_begin(); } runtime.reset(); diff --git a/runtime/browser/web_application.cc b/runtime/browser/web_application.cc index 856c8ab..ab45d1b 100755 --- a/runtime/browser/web_application.cc +++ b/runtime/browser/web_application.cc @@ -222,16 +222,8 @@ static void InitializeNotificationCallback(Ewk_Context* ewk_context, static Eina_Bool ExitAppIdlerCallback(void* data) { WebApplication* app = static_cast(data); - if (app) { - std::list vstack = app->view_stack(); - auto it = vstack.begin(); - - for (; it != vstack.end(); ++it) { - vstack.front()->SetVisibility(false); - (*it)->Suspend(); - ewk_view_page_close((*it)->evas_object()); - } - } + if (app) + app->Terminate(); return ECORE_CALLBACK_CANCEL; } @@ -296,7 +288,6 @@ WebApplication::WebApplication( ewk_context_( ewk_context_new_with_injected_bundle_path(INJECTED_BUNDLE_PATH)), has_ownership_of_ewk_context_(true), - is_terminated_by_callback_(false), window_(window), appid_(app_data->app_id()), app_data_(app_data), @@ -314,7 +305,6 @@ WebApplication::WebApplication( verbose_mode_(false), ewk_context_(context), has_ownership_of_ewk_context_(false), - is_terminated_by_callback_(false), window_(window), appid_(app_data->app_id()), app_data_(app_data), @@ -645,13 +635,13 @@ void WebApplication::Suspend() { } void WebApplication::Terminate() { - is_terminated_by_callback_ = false; if (terminator_) { terminator_(); } else { elm_exit(); } auto extension_server = extensions::XWalkExtensionServer::GetInstance(); + LOGGER(INFO) << "Shutdown extension server"; extension_server->Shutdown(); } @@ -677,13 +667,8 @@ void WebApplication::OnCreatedNewWebView(WebView* /*view*/, WebView* new_view) { } void WebApplication::RemoveWebViewFromStack(WebView* view) { - if (view_stack_.size() == 0) { - if (is_terminated_by_callback_) { - Terminate(); - } else { - return; - } - } + if (view_stack_.size() == 0) + return; WebView* current = view_stack_.front(); if (current == view) { @@ -696,17 +681,11 @@ void WebApplication::RemoveWebViewFromStack(WebView* view) { } if (view_stack_.size() == 0) { - if (is_terminated_by_callback_) { - // In order to prevent the crash issue due to the callback - // which occur after destroying WebApplication class, - // we have to set the 'SetEventListener' to NULL. - view->SetEventListener(NULL); - Terminate(); - } else { - view->Suspend(); - ewk_view_page_close(view->evas_object()); - return; - } + // In order to prevent the crash issue due to the callback + // which occur after destroying WebApplication class, + // we have to set the 'SetEventListener' to NULL. + view->SetEventListener(NULL); + Terminate(); } else if (current != view_stack_.front()) { view_stack_.front()->SetVisibility(true); window_->SetContent(view_stack_.front()->evas_object()); @@ -722,12 +701,12 @@ void WebApplication::RemoveWebViewFromStack(WebView* view) { } void WebApplication::OnClosedWebView(WebView* view) { - is_terminated_by_callback_ = true; // Reply to javascript dialog for preventing freeze issue. view->ReplyToJavascriptDialog(); RemoveWebViewFromStack(view); if (runtime::Runtime::is_on_terminate_called) { + LOGGER(INFO) << "Execute deferred termination of main loop"; ecore_main_loop_quit(); } } @@ -845,7 +824,7 @@ void WebApplication::OnHardwareKey(WebView* view, const std::string& keyname) { if(enabled) view->EvalJavascript(kBackKeyEventScript); if (!view->Backward()) { - RemoveWebViewFromStack(view_stack_.front()); + Terminate(); } } return; @@ -860,7 +839,7 @@ void WebApplication::OnHardwareKey(WebView* view, const std::string& keyname) { (app_data_->widget_info() != NULL && app_data_->widget_info()->view_modes() == "windowed")) { if (!view->Backward()) { - RemoveWebViewFromStack(view_stack_.front()); + Terminate(); } } } else if (enabled && kKeyNameMenu == keyname) { diff --git a/runtime/browser/web_application.h b/runtime/browser/web_application.h index 1c31d21..e72ad8d 100755 --- a/runtime/browser/web_application.h +++ b/runtime/browser/web_application.h @@ -132,7 +132,6 @@ class WebApplication : public WebView::EventListener { bool lang_changed_mode_; Ewk_Context* ewk_context_; bool has_ownership_of_ewk_context_; - bool is_terminated_by_callback_; NativeWindow* window_; std::string appid_; std::string app_data_path_; -- 2.7.4 From a81a7aea7bdecbcb1d6b5c92376a032450f6782a Mon Sep 17 00:00:00 2001 From: "ws29.jung" Date: Mon, 9 Jan 2017 14:25:07 +0900 Subject: [PATCH 14/16] Disable autotextsizing with 2.4 compatible app When app is launching, wrt check compatibiliy then disable autotextsizing setting with 2.4 compatibl webapp This patch is made to resolve different app appearance issue between 2.4 and 3.0. Bug: P161227-02523 Change-Id: Ib358d7aa0241a4fd462d362ce9a4f80f3477d4e9 Signed-off-by: ws29.jung --- runtime/browser/web_application.cc | 11 ++++++----- runtime/browser/web_application.h | 2 +- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/runtime/browser/web_application.cc b/runtime/browser/web_application.cc index d40f95a..31613dd 100755 --- a/runtime/browser/web_application.cc +++ b/runtime/browser/web_application.cc @@ -486,7 +486,7 @@ void WebApplication::Launch(std::unique_ptr appcontrol) { // Setup View WebView* view = new WebView(window_, ewk_context_); SetupWebView(view); - SetupWebViewTizenApplicationInfo(view); + SetupWebViewCompatibilitySettings(view); std::unique_ptr res = resource_manager_->GetStartResource(appcontrol.get()); @@ -570,7 +570,7 @@ void WebApplication::AppControl( ClearViewStack(); WebView* view = view_stack_.front(); SetupWebView(view); - SetupWebViewTizenApplicationInfo(view); + SetupWebViewCompatibilitySettings(view); view->SetDefaultEncoding(res->encoding()); view->LoadUrl(res->uri(), res->mime()); window_->SetContent(view->evas_object()); @@ -664,7 +664,7 @@ void WebApplication::OnCreatedNewWebView(WebView* /*view*/, WebView* new_view) { view_stack_.front()->SetVisibility(false); SetupWebView(new_view); - SetupWebViewTizenApplicationInfo(new_view); + SetupWebViewCompatibilitySettings(new_view); view_stack_.push_front(new_view); window_->SetContent(new_view->evas_object()); } @@ -1047,14 +1047,15 @@ void WebApplication::SetupWebView(WebView* view) { } } -void WebApplication::SetupWebViewTizenApplicationInfo(WebView* view) { +void WebApplication::SetupWebViewCompatibilitySettings(WebView* view) { if (tizenWebKitCompatibilityEnabled()) { Ewk_Settings* settings = ewk_view_settings_get(view->evas_object()); ewk_settings_tizen_compatibility_mode_set(settings, m_tizenCompatibilitySettings.m_major, m_tizenCompatibilitySettings.m_minor, m_tizenCompatibilitySettings.m_release); - } + ewk_settings_text_autosizing_enabled_set(settings, EINA_FALSE); + } } bool WebApplication::OnDidNavigation(WebView* /*view*/, diff --git a/runtime/browser/web_application.h b/runtime/browser/web_application.h index e72ad8d..751e809 100755 --- a/runtime/browser/web_application.h +++ b/runtime/browser/web_application.h @@ -114,7 +114,7 @@ class WebApplication : public WebView::EventListener { void SendAppControlEvent(); void LaunchInspector(common::AppControl* appcontrol); void SetupWebView(WebView* view); - void SetupWebViewTizenApplicationInfo(WebView* view); + void SetupWebViewCompatibilitySettings(WebView* view); void RemoveWebViewFromStack(WebView* view); void SetupTizenVersion(); -- 2.7.4 From 88e577caa2f01c84b3ff6f7a5643aaeb7b3a3435 Mon Sep 17 00:00:00 2001 From: "ws29.jung" Date: Mon, 9 Jan 2017 21:23:32 +0900 Subject: [PATCH 15/16] Prevent duplicated eventcallback call Unexpectly, there is some case which calls same function twice. To prevent these case, it is proper to set eventlistener to NULL when webview is pop/erased from view stack. Bug: http://suprem.sec.samsung.net/jira/browse/TSAM-12508 Change-Id: Ie1931bc9d20e3db0c3dde04f640b82e8b3fa17dc Signed-off-by: ws29.jung --- runtime/browser/web_application.cc | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/runtime/browser/web_application.cc b/runtime/browser/web_application.cc index 31613dd..9a5d50b 100755 --- a/runtime/browser/web_application.cc +++ b/runtime/browser/web_application.cc @@ -675,19 +675,23 @@ void WebApplication::RemoveWebViewFromStack(WebView* view) { WebView* current = view_stack_.front(); if (current == view) { + // In order to prevent the crash issue due to the callback + // which occur after destroying WebApplication class, + // we have to set the 'SetEventListener' to NULL. + view->SetEventListener(NULL); view_stack_.pop_front(); } else { auto found = std::find(view_stack_.begin(), view_stack_.end(), view); if (found != view_stack_.end()) { + // In order to prevent the crash issue due to the callback + // which occur after destroying WebApplication class, + // we have to set the 'SetEventListener' to NULL. + view->SetEventListener(NULL); view_stack_.erase(found); } } if (view_stack_.size() == 0) { - // In order to prevent the crash issue due to the callback - // which occur after destroying WebApplication class, - // we have to set the 'SetEventListener' to NULL. - view->SetEventListener(NULL); Terminate(); } else if (current != view_stack_.front()) { view_stack_.front()->SetVisibility(true); -- 2.7.4 From ccb5936a271fc9502fb3ba8b82373fa92d99df80 Mon Sep 17 00:00:00 2001 From: Youngsoo Choi Date: Wed, 4 Jan 2017 18:01:10 +0900 Subject: [PATCH 16/16] Assure proper termination using context session Current main loop quits when closing window callback is called. Btw, it does not assure proper termination of changing watch face because context session stops too early and callback can not be called and then dead lock happens. So, this CL extends the main loop until all the context sessions are finished and covers following termination scenarios. * h/w back key * exit pop up menu * exit command |pkgcmd -k| * uninstall command |pkgcmd -u| while webapp runs * changing watch face Bug: http://suprem.sec.samsung.net/jira/browse/TWF-2765 Change-Id: I1767ef5f14e393ffc59668b0b9925d781abfd2f5 Signed-off-by: Youngsoo Choi --- .../xwalk_extension_renderer_controller.cc | 7 +++ .../renderer/xwalk_extension_renderer_controller.h | 1 + runtime/browser/runtime_process.cc | 12 ++++- runtime/browser/web_application.cc | 63 +++++++++++++++++++--- runtime/browser/web_application.h | 2 + 5 files changed, 77 insertions(+), 8 deletions(-) diff --git a/extensions/renderer/xwalk_extension_renderer_controller.cc b/extensions/renderer/xwalk_extension_renderer_controller.cc index 59e45b7..01c1ece 100755 --- a/extensions/renderer/xwalk_extension_renderer_controller.cc +++ b/extensions/renderer/xwalk_extension_renderer_controller.cc @@ -22,6 +22,9 @@ namespace extensions { +// static +int XWalkExtensionRendererController::plugin_session_count = 0; + namespace { void CreateExtensionModules(XWalkExtensionClient* client, @@ -81,12 +84,16 @@ void XWalkExtensionRendererController::DidCreateScriptContext( CreateExtensionModules(extensions_client_.get(), module_system); module_system->Initialize(); + plugin_session_count++; + LOGGER(DEBUG) << "plugin_session_count : " << plugin_session_count; } void XWalkExtensionRendererController::WillReleaseScriptContext( v8::Handle context) { v8::Context::Scope contextScope(context); XWalkModuleSystem::ResetModuleSystemFromContext(context); + plugin_session_count--; + LOGGER(DEBUG) << "plugin_session_count : " << plugin_session_count; } void XWalkExtensionRendererController::OnReceivedIPCMessage( diff --git a/extensions/renderer/xwalk_extension_renderer_controller.h b/extensions/renderer/xwalk_extension_renderer_controller.h index 4927d21..95e3145 100755 --- a/extensions/renderer/xwalk_extension_renderer_controller.h +++ b/extensions/renderer/xwalk_extension_renderer_controller.h @@ -20,6 +20,7 @@ class XWalkExtensionClient; class XWalkExtensionRendererController { public: static XWalkExtensionRendererController& GetInstance(); + static int plugin_session_count; void DidCreateScriptContext(v8::Handle context); void WillReleaseScriptContext(v8::Handle context); diff --git a/runtime/browser/runtime_process.cc b/runtime/browser/runtime_process.cc index 859aa3a..83d7645 100755 --- a/runtime/browser/runtime_process.cc +++ b/runtime/browser/runtime_process.cc @@ -28,6 +28,7 @@ #include "common/command_line.h" #include "common/logger.h" #include "common/profiler.h" +#include "extensions/renderer/xwalk_extension_renderer_controller.h" #include "runtime/browser/runtime.h" #include "runtime/common/constants.h" #include "runtime/browser/prelauncher.h" @@ -35,6 +36,7 @@ #include "runtime/browser/ui_runtime.h" +using namespace extensions; bool g_prelaunch = false; #ifdef WATCH_FACE_FEATURE_SUPPORT @@ -132,16 +134,22 @@ int real_main(int argc, char* argv[]) { std::unique_ptr runtime = runtime::Runtime::MakeRuntime(appdata); ret = runtime->Exec(argc, argv); - if (runtime->is_on_terminate_called) { - LOGGER(INFO) << "Defer termination of main loop"; + if (ret) + LOGGER(ERROR) << "Exec returns non zero."; + LOGGER(DEBUG) << "plugin_session_count : " << + XWalkExtensionRendererController::plugin_session_count; + if (XWalkExtensionRendererController::plugin_session_count > 0) { + LOGGER(DEBUG) << "Defer termination of main loop"; ecore_main_loop_begin(); } runtime.reset(); } + LOGGER(DEBUG) << "ewk_shutdown"; ewk_shutdown(); elm_shutdown(); elm_exit(); + LOGGER(DEBUG) << "EXIT_SUCCESS"; return EXIT_SUCCESS; } diff --git a/runtime/browser/web_application.cc b/runtime/browser/web_application.cc index 9a5d50b..68143a8 100755 --- a/runtime/browser/web_application.cc +++ b/runtime/browser/web_application.cc @@ -37,6 +37,7 @@ #include "common/profiler.h" #include "common/resource_manager.h" #include "common/string_utils.h" +#include "extensions/renderer/xwalk_extension_renderer_controller.h" #include "runtime/browser/native_window.h" #include "runtime/browser/notification_manager.h" #include "runtime/browser/popup.h" @@ -51,6 +52,10 @@ #error INJECTED_BUNDLE_PATH is not set. #endif +#define TIMER_INTERVAL 0.1 + +using namespace extensions; + namespace runtime { namespace { @@ -222,8 +227,10 @@ static void InitializeNotificationCallback(Ewk_Context* ewk_context, static Eina_Bool ExitAppIdlerCallback(void* data) { WebApplication* app = static_cast(data); - if (app) + if (app) { + LOGGER(DEBUG) << "Terminate"; app->Terminate(); + } return ECORE_CALLBACK_CANCEL; } @@ -285,6 +292,7 @@ WebApplication::WebApplication( debug_mode_(false), verbose_mode_(false), lang_changed_mode_(false), + is_terminate_called_(false), ewk_context_( ewk_context_new_with_injected_bundle_path(INJECTED_BUNDLE_PATH)), has_ownership_of_ewk_context_(true), @@ -303,6 +311,7 @@ WebApplication::WebApplication( : launched_(false), debug_mode_(false), verbose_mode_(false), + is_terminate_called_(false), ewk_context_(context), has_ownership_of_ewk_context_(false), window_(window), @@ -637,23 +646,28 @@ void WebApplication::Suspend() { } void WebApplication::Terminate() { + is_terminate_called_ = true; if (terminator_) { + LOGGER(DEBUG) << "terminator_"; terminator_(); } else { + LOGGER(ERROR) << "There's no registered terminator."; elm_exit(); } auto extension_server = extensions::XWalkExtensionServer::GetInstance(); - LOGGER(INFO) << "Shutdown extension server"; + LOGGER(DEBUG) << "Shutdown extension server"; extension_server->Shutdown(); } void WebApplication::ClosePageFromOnTerminate() { + LOGGER(DEBUG); auto it = view_stack_.begin(); if (it != view_stack_.end()) { runtime::Runtime::is_on_terminate_called = true; for (; it != view_stack_.end(); ++it) { (*it)->ReplyToJavascriptDialog(); view_stack_.front()->SetVisibility(false); + LOGGER(DEBUG) << "ewk_view_page_close"; ewk_view_page_close((*it)->evas_object()); } } @@ -692,7 +706,13 @@ void WebApplication::RemoveWebViewFromStack(WebView* view) { } if (view_stack_.size() == 0) { - Terminate(); + // If |Terminate()| hasn't been called, + // main loop shouldn't be terminated here. + if (!is_terminate_called_) { + auto extension_server = XWalkExtensionServer::GetInstance(); + LOGGER(DEBUG) << "Shutdown extension server"; + extension_server->Shutdown(); + } } else if (current != view_stack_.front()) { view_stack_.front()->SetVisibility(true); window_->SetContent(view_stack_.front()->evas_object()); @@ -707,14 +727,43 @@ void WebApplication::RemoveWebViewFromStack(WebView* view) { view); } +Eina_Bool WebApplication::CheckPluginSession(void* user_data) +{ + WebApplication* that = static_cast(user_data); + if(XWalkExtensionRendererController::plugin_session_count > 0) { + LOGGER(ERROR) << "plugin_session_count : " << + XWalkExtensionRendererController::plugin_session_count; + return ECORE_CALLBACK_RENEW; + } + LOGGER(DEBUG) << "plugin_session_count : " << + XWalkExtensionRendererController::plugin_session_count; + LOGGER(DEBUG) << "Execute deferred termination of main loop"; + if (that->is_terminate_called_) { + ecore_main_loop_quit(); + } else { + if (that->terminator_) { + LOGGER(DEBUG) << "terminator_"; + that->terminator_(); + } else { + LOGGER(ERROR) << "There's no registered terminator."; + elm_exit(); + } + } + return ECORE_CALLBACK_CANCEL; +} + void WebApplication::OnClosedWebView(WebView* view) { + Ecore_Timer* timeout_id = NULL; // Reply to javascript dialog for preventing freeze issue. view->ReplyToJavascriptDialog(); RemoveWebViewFromStack(view); - if (runtime::Runtime::is_on_terminate_called) { - LOGGER(INFO) << "Execute deferred termination of main loop"; - ecore_main_loop_quit(); + LOGGER(DEBUG) << "plugin_session_count : " << + XWalkExtensionRendererController::plugin_session_count; + if (XWalkExtensionRendererController::plugin_session_count > 0) { + timeout_id = ecore_timer_add(TIMER_INTERVAL, CheckPluginSession, this); + if (!timeout_id) + LOGGER(ERROR) << "It's failed to create timer"; } } @@ -831,6 +880,7 @@ void WebApplication::OnHardwareKey(WebView* view, const std::string& keyname) { if(enabled) view->EvalJavascript(kBackKeyEventScript); if (!view->Backward()) { + LOGGER(DEBUG) << "Terminate"; Terminate(); } } @@ -846,6 +896,7 @@ void WebApplication::OnHardwareKey(WebView* view, const std::string& keyname) { (app_data_->widget_info() != NULL && app_data_->widget_info()->view_modes() == "windowed")) { if (!view->Backward()) { + LOGGER(DEBUG) << "Terminate"; Terminate(); } } diff --git a/runtime/browser/web_application.h b/runtime/browser/web_application.h index 751e809..48665e8 100755 --- a/runtime/browser/web_application.h +++ b/runtime/browser/web_application.h @@ -106,6 +106,7 @@ class WebApplication : public WebView::EventListener { #ifdef MANUAL_ROTATE_FEATURE_SUPPORT virtual void OnRotatePrepared(WebView* view); #endif // MANUAL_ROTATE_FEATURE_SUPPORT + static Eina_Bool CheckPluginSession(void* user_data); private: bool Initialize(); @@ -130,6 +131,7 @@ class WebApplication : public WebView::EventListener { bool debug_mode_; bool verbose_mode_; bool lang_changed_mode_; + bool is_terminate_called_; Ewk_Context* ewk_context_; bool has_ownership_of_ewk_context_; NativeWindow* window_; -- 2.7.4