class utc_blink_ewk_policy_decision_suspend : public utc_blink_ewk_base {
protected:
-
- void PostSetUp()
- {
- evas_object_smart_callback_add(GetEwkWebView(), "policy,navigation,decide", policy_navigation_decide, this);
- }
-
- void PreTearDown()
+ utc_blink_ewk_policy_decision_suspend()
+ : policy_decision(NULL)
{
- evas_object_smart_callback_del(GetEwkWebView(), "policy,navigation,decide", policy_navigation_decide);
}
- void LoadFinished(Evas_Object* webview) {
- EventLoopStop(utc_blink_ewk_base::Success); // will noop if EventLoopStop was alraedy called
+ void LoadFinished(Evas_Object* webview)
+ {
+ EventLoopStop(utc_blink_ewk_base::Failure); // will noop if EventLoopStop was already called
}
- static void policy_navigation_decide(void* data, Evas_Object* webview, void* event_info)
+ static void policy_decision_suspend(utc_blink_ewk_policy_decision_suspend* owner, Evas_Object* webview, Ewk_Policy_Decision* policy_decision)
{
- utc_message("[policy_navigation_decide] :: \n");
- utc_blink_ewk_policy_decision_suspend *owner = static_cast<utc_blink_ewk_policy_decision_suspend*>(data);
- Ewk_Policy_Decision* policy_decision = (Ewk_Policy_Decision*)event_info;
+ utc_message("[policy_decision_suspend] :: \n");
+ ASSERT_TRUE(owner);
+ EXPECT_TRUE(policy_decision);
- if (policy_decision && ewk_policy_decision_suspend(policy_decision)) {
+ if (!owner->policy_decision) {
+ // We need to handle suspend here, as if suspend fails then policy_decision is treated as not decided and deleted
+ if (EINA_TRUE == ewk_policy_decision_suspend(policy_decision)) {
+ owner->policy_decision = policy_decision;
+ }
owner->EventLoopStop(utc_blink_ewk_base::Success);
}
}
+
+ static void fail_event_loop(utc_blink_ewk_policy_decision_suspend* owner, Evas_Object* webview, void*)
+ {
+ ASSERT_TRUE(owner);
+ owner->policy_decision = NULL;
+ owner->EventLoopStop(Failure);
+ }
+
+protected:
+ Ewk_Policy_Decision *policy_decision;
};
/**
* @brief Tests if suspend operation for policy decision is set properly
*/
-TEST_F(utc_blink_ewk_policy_decision_suspend, POS_TEST)
+TEST_F(utc_blink_ewk_policy_decision_suspend, SuspendNavigation)
+{
+ evas_object_smart_callback_auto sc(GetEwkWebView(), "policy,navigation,decide", ToSmartCallback(policy_decision_suspend), this);
+
+ ASSERT_EQ(EINA_TRUE, ewk_view_url_set(GetEwkWebView(), "http://www.google.com"));
+ // Wait for policy decision smart callback
+ ASSERT_EQ(Success, EventLoopStart());
+
+ ASSERT_FALSE(policy_decision);
+ // TODO: enable path below if we manage to support suspend for navigation
+ /*
+ ASSERT_TRUE(policy_decision) << "suspend failed - suspend for navigation may be not supported";
+
+ // we've suspended navigation - try waiting for load finished. It should timeout
+ ASSERT_EQ(Timeout, EventLoopStart(5.0));
+
+ // now resume it
+ ASSERT_EQ(EINA_TRUE, ewk_policy_decision_use(policy_decision));
+
+ // and wait till request finished - LoadFinished sets error to Failure
+ ASSERT_EQ(Failure, EventLoopStart());
+ */
+}
+
+TEST_F(utc_blink_ewk_policy_decision_suspend, SuspendNewWindow)
+{
+ evas_object_smart_callback_auto sc(GetEwkWebView(), "policy,newwindow,decide", ToSmartCallback(policy_decision_suspend), this);
+ evas_object_smart_callback_auto popup_blocked(GetEwkWebView(), "popup,blocked", ToSmartCallback(fail_event_loop), this);
+ evas_object_smart_callback_auto create_window(GetEwkWebView(), "create,window", ToSmartCallback(fail_event_loop), this);
+
+ ASSERT_EQ(EINA_TRUE, ewk_view_html_string_load(GetEwkWebView(), "<html><body>Page</body></html>", NULL, NULL));
+
+ // Wait for page to load
+ ASSERT_EQ(Failure, EventLoopStart());
+
+ // execute window.open
+ ewk_view_script_execute(GetEwkWebView(), "window.open('www.google.com');", NULL, NULL);
+ // Wait for policy,newwindow,decide callback
+ ASSERT_EQ(Success, EventLoopStart());
+
+ ASSERT_TRUE(policy_decision) << "suspend failed - suspend for newwindow may be not supported";
+
+ // we've suspended decision - we should not get create,window or popup,blocked smart callback
+ ASSERT_EQ(Timeout, EventLoopStart(5.0));
+
+ // Allow new window
+ ASSERT_EQ(EINA_TRUE, ewk_policy_decision_use(policy_decision));
+
+ // window,create will NULLify policy_decision to was called - it will be called synchronously from ewk_policy_decision_use
+ ASSERT_FALSE(policy_decision);
+}
+
+TEST_F(utc_blink_ewk_policy_decision_suspend, SuspendResponse)
{
- Eina_Bool result = ewk_view_url_set(GetEwkWebView(), "http://www.google.com");
- if (!result)
- FAIL();
+ evas_object_smart_callback_auto sc(GetEwkWebView(), "policy,response,decide", ToSmartCallback(policy_decision_suspend), this);
+
+ ASSERT_EQ(EINA_TRUE, ewk_view_url_set(GetEwkWebView(), "http://www.google.com"));
+ // Wait for policy decision smart callback
+ ASSERT_EQ(Success, EventLoopStart());
+
+ ASSERT_TRUE(policy_decision) << "suspend failed - suspend for response may be not supported";
+
+ // we've suspended navigation - try waiting for load finished. It should timeout
+ ASSERT_EQ(Timeout, EventLoopStart(5.0));
+
+ // now resume it
+ ASSERT_EQ(EINA_TRUE, ewk_policy_decision_use(policy_decision));
- utc_blink_ewk_base::MainLoopResult main_result = EventLoopStart();
- if (main_result != utc_blink_ewk_base::Success)
- FAIL();
+ // and wait till request finished - LoadFinished sets error to Failure
+ ASSERT_EQ(Failure, EventLoopStart());
}
/**
* @brief Tests if function works properly in case of NULL of a webview
*/
-TEST_F(utc_blink_ewk_policy_decision_suspend, NEG_TEST)
+TEST_F(utc_blink_ewk_policy_decision_suspend, InvalidArgs)
{
- utc_check_ne(ewk_policy_decision_suspend(0), EINA_TRUE);
+ ASSERT_EQ(EINA_FALSE, ewk_policy_decision_suspend(NULL));
}
}
void EWebView::InvokePolicyResponseCallback(tizen_webview::PolicyDecision* policy_decision) {
- set_policy_decision(policy_decision);
- SmartCallback<EWebViewCallbacks::PolicyResponseDecide>().call(policy_decision_.get());
+ SmartCallback<EWebViewCallbacks::PolicyResponseDecide>().call(policy_decision);
- // if app has not decided nor suspended, we act as if it was accepted.
- if (!policy_decision_->isDecided() && !policy_decision_->isSuspended())
- policy_decision_->Use();
+ if (policy_decision->isSuspended())
+ return;
+
+ if (!policy_decision->isDecided())
+ policy_decision->Use();
+
+ delete policy_decision;
}
void EWebView::InvokePolicyNavigationCallback(RenderViewHost* rvh,
SmartCallback<EWebViewCallbacks::SaveSessionData>().call();
- policy_decision_.reset(new tizen_webview::PolicyDecision(params, rvh));
+ scoped_ptr<PolicyDecision> policy_decision(new PolicyDecision(params, rvh));
+
+ SmartCallback<EWebViewCallbacks::NavigationPolicyDecision>().call(policy_decision.get());
- SmartCallback<EWebViewCallbacks::NavigationPolicyDecision>().call(policy_decision_.get());
+ CHECK(!policy_decision->isSuspended());
- // if app has not decided nor suspended, we act as if it was accepted.
- if (!policy_decision_->isDecided() && !policy_decision_->isSuspended())
- policy_decision_->Use();
+ // TODO: Navigation can't be suspended
+ // this aproach is synchronous and requires immediate response
+ // Maybe there is different approach (like resource throttle response mechanism) that allows us to
+ // suspend navigation
+ if (!policy_decision->isDecided())
+ policy_decision->Use();
- *handled = policy_decision_->GetImpl()->GetNavigationPolicyHandler()->GetDecision() == NavigationPolicyHandlerEfl::Handled;
+ *handled = policy_decision->GetImpl()->GetNavigationPolicyHandler()->GetDecision() == NavigationPolicyHandlerEfl::Handled;
}
void EWebView::HandleTouchEvents(tizen_webview::Touch_Event_Type type, const Eina_List *points, const Evas_Modifier *modifiers)