Add APIs for intercepting http request in web view. 04/254304/4
authorhuayong.xu <huayong.xu@samsung.com>
Fri, 26 Feb 2021 03:45:08 +0000 (11:45 +0800)
committerhuayong.xu <huayong.xu@samsung.com>
Wed, 31 Mar 2021 09:47:10 +0000 (17:47 +0800)
This patch is to add APIs for intercepting http request in web
view.

Change-Id: I214b9d03eaa69f67b80a62bf9dff923941570aff

automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-web-engine.cpp
automated-tests/src/dali-toolkit/utc-Dali-WebView.cpp
dali-toolkit/devel-api/controls/web-view/web-view.cpp
dali-toolkit/devel-api/controls/web-view/web-view.h
dali-toolkit/internal/controls/web-view/web-view-impl.cpp [changed mode: 0755->0644]
dali-toolkit/internal/controls/web-view/web-view-impl.h [changed mode: 0644->0755]

index 4c8ffb3..db94ec0 100755 (executable)
@@ -23,6 +23,7 @@
 #include <dali/devel-api/adaptor-framework/web-engine-context.h>
 #include <dali/devel-api/adaptor-framework/web-engine-cookie-manager.h>
 #include <dali/devel-api/adaptor-framework/web-engine-form-repost-decision.h>
+#include <dali/devel-api/adaptor-framework/web-engine-request-interceptor.h>
 #include <dali/devel-api/adaptor-framework/web-engine-settings.h>
 #include <dali/public-api/adaptor-framework/native-image-source.h>
 #include <dali/public-api/images/pixel-data.h>
@@ -195,7 +196,7 @@ private:
 class MockWebEngineBackForwardList : public Dali::WebEngineBackForwardList
 {
 public:
-  MockWebEngineBackForwardList( )
+  MockWebEngineBackForwardList()
     : mockItem(),
       pMockItem( &mockItem )
   {
@@ -231,6 +232,39 @@ public:
   void Reply(bool allowed) override {}
 };
 
+class MockWebEngineRequestInterceptor : public WebEngineRequestInterceptor
+{
+public:
+  MockWebEngineRequestInterceptor()
+  {
+  }
+
+  std::string GetUrl() const override
+  {
+    return "http://test.html";
+  }
+
+  bool Ignore() override
+  {
+    return true;
+  }
+
+  bool SetResponseStatus(int statusCode, const std::string &customedStatusText) override
+  {
+    return true;
+  }
+
+  bool AddResponseHeader(const std::string &fieldName, const std::string &fieldValue) override
+  {
+    return true;
+  }
+
+  bool AddResponseBody(const std::string &body, uint32_t length) override
+  {
+    return true;
+  }
+};
+
 class MockWebEngineSettings : public WebEngineSettings
 {
 public:
@@ -796,32 +830,40 @@ public:
     return mFrameRenderedSignal;
   }
 
-  std::string                                                mUrl;
-  std::vector< std::string >                                 mHistory;
-  size_t                                                     mCurrentPlusOnePos;
-  std::string                                                mUserAgent;
-  Dali::WebEnginePlugin::WebEnginePageLoadSignalType         mPageLoadStartedSignal;
-  Dali::WebEnginePlugin::WebEnginePageLoadSignalType         mPageLoadInProgressSignal;
-  Dali::WebEnginePlugin::WebEnginePageLoadSignalType         mPageLoadFinishedSignal;
-  Dali::WebEnginePlugin::WebEnginePageLoadErrorSignalType    mPageLoadErrorSignal;
-  std::vector<JavaScriptEvaluatedResultCallback>             mResultCallbacks;
-  bool                                                       mEvaluating;
-  float                                                      mPageZoomFactor;
-  float                                                      mTextZoomFactor;
-  float                                                      mScaleFactor;
+  Dali::WebEnginePlugin::WebEngineRequestInterceptorSignalType& RequestInterceptorSignal()
+  {
+    return mRequestInterceptorSignal;
+  }
+
+  std::string              mUrl;
+  std::vector<std::string> mHistory;
+  size_t                   mCurrentPlusOnePos;
+  std::string              mUserAgent;
 
+  Dali::WebEnginePlugin::WebEnginePageLoadSignalType           mPageLoadStartedSignal;
+  Dali::WebEnginePlugin::WebEnginePageLoadSignalType           mPageLoadInProgressSignal;
+  Dali::WebEnginePlugin::WebEnginePageLoadSignalType           mPageLoadFinishedSignal;
+  Dali::WebEnginePlugin::WebEnginePageLoadErrorSignalType      mPageLoadErrorSignal;
   Dali::WebEnginePlugin::WebEngineScrollEdgeReachedSignalType  mScrollEdgeReachedSignal;
-  Dali::Vector2                                                mScrollPosition;
-  Dali::Vector2                                                mScrollSize;
-  Dali::Vector2                                                mContentSize;
-  WebEngineBackForwardList*                                    mockWebEngineBackForwardList;
-  WebEngineContext*                                            mockWebEngineContext;
-  WebEngineCookieManager*                                      mockWebEngineCookieManager;
-  WebEngineSettings*                                           mockWebEngineSettings;
   Dali::WebEnginePlugin::WebEngineUrlChangedSignalType         mUrlChangedSignal;
   Dali::WebEnginePlugin::WebEngineFormRepostDecisionSignalType mFormRepostDecisionSignal;
   Dali::WebEnginePlugin::WebEngineFrameRenderedSignalType      mFrameRenderedSignal;
-
+  Dali::WebEnginePlugin::WebEngineRequestInterceptorSignalType mRequestInterceptorSignal;
+
+  bool  mEvaluating;
+  float mPageZoomFactor;
+  float mTextZoomFactor;
+  float mScaleFactor;
+
+  Dali::Vector2             mScrollPosition;
+  Dali::Vector2             mScrollSize;
+  Dali::Vector2             mContentSize;
+  WebEngineBackForwardList* mockWebEngineBackForwardList;
+  WebEngineContext*         mockWebEngineContext;
+  WebEngineCookieManager*   mockWebEngineCookieManager;
+  WebEngineSettings*        mockWebEngineSettings;
+
+  std::vector<JavaScriptEvaluatedResultCallback>              mResultCallbacks;
   Dali::WebEnginePlugin::JavaScriptAlertCallback              mJavaScriptAlertCallback;
   Dali::WebEnginePlugin::JavaScriptConfirmCallback            mJavaScriptConfirmCallback;
   Dali::WebEnginePlugin::JavaScriptPromptCallback             mJavaScriptPromptCallback;
@@ -874,8 +916,10 @@ bool OnLoadUrl()
     gInstance->mUrlChangedSignal.Emit( "http://new-test" );
 
     std::shared_ptr<Dali::WebEngineFormRepostDecision> decision(new MockWebEngineFormRepostDecision());
-    gInstance->mFormRepostDecisionSignal.Emit(decision);
+    gInstance->mFormRepostDecisionSignal.Emit(std::move(decision));
     gInstance->mFrameRenderedSignal.Emit();
+    std::shared_ptr<Dali::WebEngineRequestInterceptor> interceptor(new MockWebEngineRequestInterceptor());
+    gInstance->mRequestInterceptorSignal.Emit(std::move(interceptor));
   }
   return false;
 }
@@ -1440,7 +1484,12 @@ Dali::WebEnginePlugin::WebEngineFormRepostDecisionSignalType& WebEngine::FormRep
 
 Dali::WebEnginePlugin::WebEngineFrameRenderedSignalType& WebEngine::FrameRenderedSignal()
 {
-  return Internal::Adaptor::GetImplementation( *this ).FrameRenderedSignal();
+  return Internal::Adaptor::GetImplementation(*this).FrameRenderedSignal();
+}
+
+Dali::WebEnginePlugin::WebEngineRequestInterceptorSignalType& WebEngine::RequestInterceptorSignal()
+{
+  return Internal::Adaptor::GetImplementation(*this).RequestInterceptorSignal();
 }
 
 } // namespace Dali;
index 6058fdb..a97eb79 100755 (executable)
@@ -22,6 +22,7 @@
 #include "dali-toolkit-test-utils/toolkit-timer.h"
 
 #include <dali.h>
+#include <dali/devel-api/adaptor-framework/web-engine-request-interceptor.h>
 #include <dali/integration-api/events/hover-event-integ.h>
 #include <dali/integration-api/events/key-event-integ.h>
 #include <dali/integration-api/events/touch-event-integ.h>
@@ -64,6 +65,8 @@ static bool gWheelEventHandled = false;
 static int gFormRepostDecisionCallbackCalled = 0;
 static std::shared_ptr<Dali::Toolkit::WebFormRepostDecision> gFormRepostDecisionInstance;
 static int gFrameRenderedCallbackCalled = 0;
+static int gRequestInterceptorCallbackCalled = 0;
+static std::shared_ptr<Dali::WebEngineRequestInterceptor> gRequestInterceptorInstance = nullptr;
 
 struct CallbackFunctor
 {
@@ -176,6 +179,12 @@ static void OnFrameRendered(WebView)
   gFrameRenderedCallbackCalled++;
 }
 
+static void OnRequestInterceptor(WebView view, std::shared_ptr<Dali::WebEngineRequestInterceptor> interceptor)
+{
+  gRequestInterceptorCallbackCalled++;
+  gRequestInterceptorInstance = std::move(interceptor);
+}
+
 } // namespace
 
 void web_view_startup(void)
@@ -966,6 +975,40 @@ int UtcDaliWebViewVideoPlayingGeolocationPermission(void)
   END_TEST;
 }
 
+int UtcDaliWebViewHttpRequestInterceptor(void)
+{
+  ToolkitTestApplication application;
+
+  WebView view = WebView::New();
+  DALI_TEST_CHECK( view );
+
+  // load url.
+  ConnectionTracker* testTracker = new ConnectionTracker();
+  view.RequestInterceptorSignal().Connect( &OnRequestInterceptor );
+  bool signal1 = false;
+  view.ConnectSignal( testTracker, "requestInterceptor", CallbackFunctor(&signal1) );
+  DALI_TEST_EQUALS( gRequestInterceptorCallbackCalled, 0, TEST_LOCATION );
+  DALI_TEST_CHECK(gRequestInterceptorInstance == 0);
+
+  view.LoadUrl( TEST_URL1 );
+  Test::EmitGlobalTimerSignal();
+  DALI_TEST_EQUALS( gRequestInterceptorCallbackCalled, 1, TEST_LOCATION );
+  DALI_TEST_CHECK( signal1 );
+
+  // check request interceptor.
+  DALI_TEST_CHECK(gRequestInterceptorInstance != 0);
+  DALI_TEST_CHECK(gRequestInterceptorInstance->Ignore());
+  DALI_TEST_CHECK(gRequestInterceptorInstance->SetResponseStatus(400, "error"));
+  DALI_TEST_CHECK(gRequestInterceptorInstance->AddResponseHeader("key", "value"));
+  DALI_TEST_CHECK(gRequestInterceptorInstance->AddResponseBody("test", 4));
+  std::string testUrl("http://test.html");
+  DALI_TEST_EQUALS(gRequestInterceptorInstance->GetUrl(), testUrl, TEST_LOCATION);
+
+  gRequestInterceptorInstance = nullptr;
+
+  END_TEST;
+}
+
 int UtcDaliWebViewEvaluteJavaScript(void)
 {
   ToolkitTestApplication application;
index d87468c..504cabb 100755 (executable)
@@ -339,6 +339,11 @@ WebView::WebViewFrameRenderedSignalType& WebView::FrameRenderedSignal()
   return Dali::Toolkit::GetImpl(*this).FrameRenderedSignal();
 }
 
+WebView::WebViewRequestInterceptorSignalType& WebView::RequestInterceptorSignal()
+{
+  return Dali::Toolkit::GetImpl(*this).RequestInterceptorSignal();
+}
+
 WebView::WebView(Internal::WebView& implementation)
 : Control(implementation)
 {
index 716132e..a64e1ca 100755 (executable)
@@ -243,6 +243,11 @@ public:
    */
   using WebViewFrameRenderedSignalType = Signal<void(WebView)>;
 
+  /**
+   * @brief WebView signal type related with http request interceptor.
+   */
+  using WebViewRequestInterceptorSignalType = Signal<void(WebView, std::shared_ptr<Dali::WebEngineRequestInterceptor>)>;
+
 public:
   /**
    * @brief Creates an initialized WebView.
@@ -700,6 +705,13 @@ public:
    */
   WebViewFrameRenderedSignalType& FrameRenderedSignal();
 
+  /**
+   * @brief Connects to this signal to be notified when http request need be intercepted.
+   *
+   * @return A signal object to connect with.
+   */
+  WebViewRequestInterceptorSignalType& RequestInterceptorSignal();
+
 public: // Not intended for application developers
   /// @cond internal
   /**
old mode 100755 (executable)
new mode 100644 (file)
index 22ce395..74e498b
@@ -23,6 +23,7 @@
 #include <dali/devel-api/adaptor-framework/web-engine-context.h>
 #include <dali/devel-api/adaptor-framework/web-engine-cookie-manager.h>
 #include <dali/devel-api/adaptor-framework/web-engine-form-repost-decision.h>
+#include <dali/devel-api/adaptor-framework/web-engine-request-interceptor.h>
 #include <dali/devel-api/adaptor-framework/web-engine-settings.h>
 #include <dali/devel-api/common/stage.h>
 #include <dali/devel-api/scripting/enum-helper.h>
@@ -87,6 +88,7 @@ DALI_SIGNAL_REGISTRATION(Toolkit, WebView, "scrollEdgeReached",  SCROLL_EDGE_REA
 DALI_SIGNAL_REGISTRATION(Toolkit, WebView, "urlChanged",         URL_CHANGED_SIGNAL          )
 DALI_SIGNAL_REGISTRATION(Toolkit, WebView, "formRepostDecision", FORM_REPOST_DECISION_SIGNAL )
 DALI_SIGNAL_REGISTRATION(Toolkit, WebView, "frameRendered",      FRAME_RENDERED_SIGNAL       )
+DALI_SIGNAL_REGISTRATION(Toolkit, WebView, "requestInterceptor", REQUEST_INTERCEPTOR_SIGNAL  )
 
 DALI_TYPE_REGISTRATION_END()
 // clang-format on
@@ -216,6 +218,7 @@ void WebView::OnInitialize()
     mWebEngine.UrlChangedSignal().Connect(this, &WebView::OnUrlChanged);
     mWebEngine.FormRepostDecisionSignal().Connect(this, &WebView::OnFormRepostDecision);
     mWebEngine.FrameRenderedSignal().Connect(this, &WebView::OnFrameRendered);
+    mWebEngine.RequestInterceptorSignal().Connect(this, &WebView::OnInterceptRequest);
 
     mWebContext         = std::unique_ptr<Dali::Toolkit::WebContext>(new WebContext(mWebEngine.GetContext()));
     mWebCookieManager   = std::unique_ptr<Dali::Toolkit::WebCookieManager>(new WebCookieManager(mWebEngine.GetCookieManager()));
@@ -709,6 +712,11 @@ Dali::Toolkit::WebView::WebViewFrameRenderedSignalType& WebView::FrameRenderedSi
   return mFrameRenderedSignal;
 }
 
+Dali::Toolkit::WebView::WebViewRequestInterceptorSignalType& WebView::RequestInterceptorSignal()
+{
+  return mRequestInterceptorSignal;
+}
+
 void WebView::OnPageLoadStarted(const std::string& url)
 {
   if(!mPageLoadStartedSignal.Empty())
@@ -799,6 +807,15 @@ void WebView::OnScreenshotCaptured(Dali::PixelData pixel)
   }
 }
 
+void WebView::OnInterceptRequest(std::shared_ptr<Dali::WebEngineRequestInterceptor> interceptor)
+{
+  if(!mRequestInterceptorSignal.Empty())
+  {
+    Dali::Toolkit::WebView handle(GetOwner());
+    mRequestInterceptorSignal.Emit(handle, std::move(interceptor));
+  }
+}
+
 bool WebView::DoConnectSignal(BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor)
 {
   Dali::BaseHandle handle(object);
@@ -846,6 +863,11 @@ bool WebView::DoConnectSignal(BaseObject* object, ConnectionTrackerInterface* tr
     webView.FrameRenderedSignal().Connect(tracker, functor);
     connected = true;
   }
+  else if(0 == strcmp(signalName.c_str(), REQUEST_INTERCEPTOR_SIGNAL))
+  {
+    webView.RequestInterceptorSignal().Connect(tracker, functor);
+    connected = true;
+  }
 
   return connected;
 }
old mode 100644 (file)
new mode 100755 (executable)
index 6898afa..2630e47
@@ -339,6 +339,11 @@ public:
    */
   Dali::Toolkit::WebView::WebViewFrameRenderedSignalType& FrameRenderedSignal();
 
+  /**
+   * @copydoc Dali::Toolkit::WebView::RequestInterceptorSignal()
+   */
+  Dali::Toolkit::WebView::WebViewRequestInterceptorSignalType& RequestInterceptorSignal();
+
 public: // Properties
   /**
    * @brief Called when a property of an object of this type is set.
@@ -648,6 +653,12 @@ private:
    */
   void OnScreenshotCaptured(Dali::PixelData pixel);
 
+  /**
+   * @brief Callback function to be called when http request need be intercepted.
+   * @param [in] request The http request interceptor.
+   */
+  void OnInterceptRequest(std::shared_ptr<Dali::WebEngineRequestInterceptor> interceptor);
+
 private:
   std::string                 mUrl;
   Dali::Toolkit::Visual::Base mVisual;
@@ -662,12 +673,14 @@ private:
   Dali::Toolkit::WebView::WebViewScrollEdgeReachedSignalType  mScrollEdgeReachedSignal;
   Dali::Toolkit::WebView::WebViewFormRepostDecisionSignalType mFormRepostDecisionSignal;
   Dali::Toolkit::WebView::WebViewFrameRenderedSignalType      mFrameRenderedSignal;
+  Dali::Toolkit::WebView::WebViewRequestInterceptorSignalType mRequestInterceptorSignal;
 
   std::unique_ptr<Dali::Toolkit::WebContext>         mWebContext;
   std::unique_ptr<Dali::Toolkit::WebCookieManager>   mWebCookieManager;
   std::unique_ptr<Dali::Toolkit::WebSettings>        mWebSettings;
   std::unique_ptr<Dali::Toolkit::WebBackForwardList> mWebBackForwardList;
-  Dali::Toolkit::ImageView                           mFaviconView;
+
+  Dali::Toolkit::ImageView mFaviconView;
 
   Dali::PropertyNotification mPositionUpdateNotification;
   Dali::PropertyNotification mSizeUpdateNotification;