Bringup new window functionality 40/285940/3
authorGajendra N <gajendra.n@samsung.com>
Wed, 21 Dec 2022 06:01:06 +0000 (11:31 +0530)
committerGajendra N <gajendra.n@samsung.com>
Fri, 23 Dec 2022 07:27:29 +0000 (12:57 +0530)
Changes:
1) Update overriden interfaces and callbacks as per upstream changes.
2) Remove duplicated upstream code in WebContentsImplEfl and clean up
   unnecessary code.
3) Use WebContentsImpl::CreateWithOpener to support both offscreen
   and onscreen flow.
4) Fixes crashes while exiting browser when new window is opened.
5) Fixes efl_webview_app new window displayed in smaller size.

With this patch, window.open() opens new window on ubrowser.

References:
https://review.tizen.org/gerrit/270768
https://review.tizen.org/gerrit/271690
https://review.tizen.org/gerrit/271801
https://review.tizen.org/gerrit/277423
https://review.tizen.org/gerrit/277789
https://review.tizen.org/gerrit/279009

Change-Id: I2ec856782e7df77161b005b5da00a0858b8a80aa
Signed-off-by: Gajendra N <gajendra.n@samsung.com>
16 files changed:
content/browser/web_contents/web_contents_impl.cc
content/browser/web_contents/web_contents_impl.h
tizen_src/chromium_impl/content/browser/web_contents/web_contents_impl_efl.cc
tizen_src/chromium_impl/content/browser/web_contents/web_contents_impl_efl.h
tizen_src/chromium_impl/content/public/browser/web_contents_efl_delegate.h
tizen_src/ewk/efl_integration/content_browser_client_efl.cc
tizen_src/ewk/efl_integration/content_browser_client_efl.h
tizen_src/ewk/efl_integration/eweb_view.cc
tizen_src/ewk/efl_integration/eweb_view.h
tizen_src/ewk/efl_integration/private/ewk_policy_decision_private.cc
tizen_src/ewk/efl_integration/private/ewk_policy_decision_private.h
tizen_src/ewk/efl_integration/web_contents_delegate_efl.cc
tizen_src/ewk/efl_integration/web_contents_delegate_efl.h
tizen_src/ewk/efl_integration/web_contents_efl_delegate_ewk.cc
tizen_src/ewk/efl_integration/web_contents_efl_delegate_ewk.h
tizen_src/ewk/efl_webview_app/app.c

index 327ac57..dd3aa11 100644 (file)
 
 #include "base/base_switches.h"
 #include "base/path_service.h"
-#include "tizen_src/chromium_impl/content/common/paths_efl.h"
-#include "tizen_src/chromium_impl/efl/window_factory.h"
-#include "tizen_src/chromium_impl/ui/ozone/platform/efl/efl_screen.h"
+#include "content/browser/web_contents/web_contents_impl_efl.h"
+#include "content/common/paths_efl.h"
+#include "efl/window_factory.h"
 #include "ui/gl/gl_shared_context_efl.h"
+#include "ui/ozone/platform/efl/efl_screen.h"
 #endif
 
 namespace content {
@@ -1104,8 +1105,22 @@ std::unique_ptr<WebContentsImpl> WebContentsImpl::CreateWithOpener(
   FrameTreeNode* opener = nullptr;
   if (opener_rfh)
     opener = opener_rfh->frame_tree_node();
+#if defined(USE_EFL)
+  std::unique_ptr<WebContentsImpl> new_contents;
+  auto* command_line = base::CommandLine::ForCurrentProcess();
+  auto* opener_contents = static_cast<WebContentsImpl*>(
+      WebContents::FromRenderFrameHost(opener_rfh));
+  if (command_line->HasSwitch(switches::kEnableOffscreenRendering) &&
+      opener_contents && opener_contents->ToWebContentsImplEfl()) {
+    new_contents.reset(WebContentsImplEfl::CreateWebContentsForNewWindow(
+        params.browser_context, opener_rfh));
+  } else {
+    new_contents.reset(new WebContentsImpl(params.browser_context));
+  }
+#else
   std::unique_ptr<WebContentsImpl> new_contents(
       new WebContentsImpl(params.browser_context));
+#endif
   new_contents->SetOpenerForNewContents(opener, params.opener_suppressed);
 
   // If the opener is sandboxed, a new popup must inherit the opener's sandbox
index f601711..3082d02 100644 (file)
@@ -224,6 +224,8 @@ class CONTENT_EXPORT WebContentsImpl : public WebContents,
                     blink::FramePolicy primary_main_frame_policy);
 
 #if defined(USE_EFL)
+  virtual WebContentsImplEfl* ToWebContentsImplEfl() { return nullptr; }
+
   void CreateEflNativeView();
   Evas_Object* GetEflNativeView() const { return efl_native_view_; }
   void set_ewk_view(void* ewk_view) { ewk_view_ = ewk_view; }
index 2a4e06f..60e7f33 100644 (file)
 
 namespace content {
 
-bool FindMatchingProcess(int render_process_id,
-                         bool* did_match_process,
-                         FrameTreeNode* node) {
-  if (node->current_frame_host()->GetProcess()->GetID() == render_process_id) {
-    *did_match_process = true;
-    return false;
-  }
-  return true;
-}
-
 WebContentsImplEfl::WebContentsImplEfl(BrowserContext* browser_context,
                                        void* platform_data)
     : WebContentsImpl(browser_context), platform_data_(platform_data) {}
 
+WebContentsImplEfl::~WebContentsImplEfl() = default;
+
 void WebContentsImplEfl::SetEflDelegate(WebContentsEflDelegate* delegate) {
   efl_delegate_.reset(delegate);
 }
@@ -91,297 +83,64 @@ void WebContentsImplEfl::SetUserAgentOverride(
     const blink::UserAgentOverride& ua_override,
     bool override_in_new_tabs) {}
 
-#if !defined(EWK_BRINGUP)  // FIXME: m67 bringup
-// FIXME: EWK_BRINGUP definition should be removed.
-void WebContentsImplEfl::CreateNewWindow(
-    SiteInstance* source_site_instance,
-    int32_t route_id,
-    int32_t main_frame_route_id,
-    int32_t main_frame_widget_route_id,
+WebContentsImpl* WebContentsImplEfl::CreateWebContentsForNewWindow(
+    BrowserContext* browser_context,
+    RenderFrameHostImpl* opener_rfh) {
+  WebContentsImplEfl* parent_contents = static_cast<WebContentsImplEfl*>(
+      WebContents::FromRenderFrameHost(opener_rfh));
+  WebContentsImpl* contents = new WebContentsImplEfl(
+      browser_context, parent_contents->GetPlatformDataForNewWindow());
+  parent_contents->SetWebContentsForNewWindow(contents);
+  return contents;
+}
+
+FrameTree* WebContentsImplEfl::CreateNewWindow(
+    RenderFrameHostImpl* opener,
     const mojom::CreateNewWindowParams& params,
+    bool is_new_browsing_instance,
+    bool has_user_gesture,
     SessionStorageNamespace* session_storage_namespace) {
-  // We usually create the new window in the same BrowsingInstance (group of
-  // script-related windows), by passing in the current SiteInstance.  However,
-  // if the opener is being suppressed (in a non-guest), we create a new
-  // SiteInstance in its own BrowsingInstance.
-  bool is_guest = BrowserPluginGuest::IsGuest(this);
-
-  if (is_guest && BrowserPluginGuestMode::UseCrossProcessFramesForGuests()) {
-    // TODO(lazyboy): CreateNewWindow doesn't work for OOPIF-based <webview>
-    // yet.
-    NOTREACHED();
-  }
-
-  // If the opener is to be suppressed, the new window can be in any process.
-  // Since routing ids are process specific, we must not have one passed in
-  // as argument here.
-  DCHECK(!params.opener_suppressed || route_id == MSG_ROUTING_NONE);
-
-  scoped_refptr<SiteInstance> site_instance =
-      params.opener_suppressed && !is_guest
-          ? SiteInstance::CreateForURL(GetBrowserContext(), params.target_url)
-          : source_site_instance;
-
-  // A message to create a new window can only come from a process for a frame
-  // in this WebContents' FrameTree. If any other process sends the request, it
-  // is invalid and the process must be terminated.
-  int render_process_id = source_site_instance->GetProcess()->GetID();
-  bool did_match_process = false;
-  for (FrameTreeNode* node : frame_tree_.Nodes())
-    base::BindOnce(&FindMatchingProcess, render_process_id, &did_match_process,
-                   node);
-
-  if (!did_match_process) {
-    RenderProcessHost* rph = source_site_instance->GetProcess();
-    base::ProcessHandle process_handle = rph->GetHandle();
-    if (process_handle != base::kNullProcessHandle) {
-      RecordAction(
-          base::UserMetricsAction("Terminate_ProcessMismatch_CreateNewWindow"));
-      rph->Shutdown(RESULT_CODE_KILLED, false);
+  // Added for EFL implementation
+  LOG(INFO) << __FUNCTION__ << ", opener:" << opener
+            << ", target url: " << params.target_url;
+  WebContents* new_contents = nullptr;
+  WebContentsEflDelegate::WebContentsCreateCallback callback =
+      base::BindRepeating(&WebContentsImplEfl::HandleNewWebContentsCreate,
+                          base::Unretained(this), opener, std::cref(params),
+                          is_new_browsing_instance, has_user_gesture,
+                          base::RetainedRef(session_storage_namespace),
+                          &new_contents);
+
+  if (efl_delegate_) {
+    if (efl_delegate_->WebContentsCreateAsync(std::move(callback))) {
+      DCHECK(new_contents);
+      return &(
+          static_cast<WebContentsImpl*>(new_contents)->GetPrimaryFrameTree());
+    } else {
+      return nullptr;
     }
-    return;
   }
-
-  // We must assign the SessionStorageNamespace before calling Init().
-  //
-  // http://crbug.com/142685
-  const std::string& partition_id =
-      GetContentClient()->browser()->GetStoragePartitionIdForSite(
-          GetBrowserContext(), site_instance->GetSiteURL());
-  StoragePartition* partition = BrowserContext::GetStoragePartition(
-      GetBrowserContext(), site_instance.get());
-  DOMStorageContextWrapper* dom_storage_context =
-      static_cast<DOMStorageContextWrapper*>(partition->GetDOMStorageContext());
-  SessionStorageNamespaceImpl* session_storage_namespace_impl =
-      static_cast<SessionStorageNamespaceImpl*>(session_storage_namespace);
-  CHECK(session_storage_namespace_impl->IsFromContext(dom_storage_context));
-
-  // Added for EFL implementation
-  scoped_refptr<SessionStorageNamespace> ssn = session_storage_namespace;
-  base::OnceCallback<void(bool)> callback = base::BindOnce(
-      &WebContentsImplEfl::HandleNewWindowRequest, base::Unretained(this),
-      render_process_id, route_id, main_frame_route_id, params, ssn);
-  if (efl_delegate_ &&
-      efl_delegate_->ShouldCreateWebContentsAsync(callback, params.target_url))
-    return;
   // End of EFL port specific code.
 
-  if (delegate_ &&
-      !delegate_->ShouldCreateWebContents(
-          this, route_id, main_frame_route_id, main_frame_widget_route_id,
-          params.window_container_type, params.frame_name, params.target_url,
-          partition_id, session_storage_namespace)) {
-    CancelWindowRequest(render_process_id, route_id, main_frame_route_id);
-    return;
-  }
-
-  // Added for EFL implementation of WebContentsImp. In non EFL version
+  // Added for EFL implementation of WebContentsImpl. In non EFL version
   // contents of HandleNewWebContentsCreate would come here.
-  callback.Run(true);
-}
-#endif  // !defined(EWK_BRINGUP)
-
-void WebContentsImplEfl::CancelWindowRequest(int32_t render_process_id,
-                                             int32_t route_id,
-                                             int32_t main_frame_route_id) {
-  if (route_id != MSG_ROUTING_NONE) {
-#if !defined(EWK_BRINGUP)  // FIXME: m71 bringup
-    RenderViewHost* rvh = RenderViewHost::FromID(render_process_id, route_id);
-
-    // If the embedder didn't create a WebContents for this route, we need to
-    // delete the RenderView that had already been created.
-    if (rvh)
-      rvh->Send(new ViewMsg_Close(route_id));
-#endif
-  }
-
-#if !defined(EWK_BRINGUP)  // FIXME: m85 bringup
-  if (ResourceDispatcherHostImpl::Get()) {
-    ResourceDispatcherHostImpl::Get()->ResumeBlockedRequestsForRoute(
-        GlobalFrameRoutingId(render_process_id, route_id));
-    ResourceDispatcherHostImpl::Get()->ResumeBlockedRequestsForRoute(
-        GlobalFrameRoutingId(render_process_id, main_frame_route_id));
-  }
-#endif
-}
-
-#if !defined(EWK_BRINGUP)  // FIXME: m67 bringup
-// FIXME: EWK_BRINGUP definition should be removed.
-// This function does not exist in WebContentsImpl. The decision regarding
-// new WebContents request is always made synchronously.
-void WebContentsImplEfl::HandleNewWindowRequest(
-    int32_t render_process_id,
-    int32_t route_id,
-    int32_t main_frame_route_id,
-    const mojom::CreateNewWindowParams& params,
-    scoped_refptr<SessionStorageNamespace> session_storage_namespace,
-    bool create) {
-  if (create) {
-    scoped_refptr<SessionStorageNamespace> ssn = session_storage_namespace;
-    WebContentsEflDelegate::WebContentsCreateCallback callback =
-        base::BindRepeating(&WebContentsImplEfl::HandleNewWebContentsCreate,
-                            base::Unretained(this), render_process_id, route_id,
-                            main_frame_route_id, params, ssn);
-    if (efl_delegate_ && efl_delegate_->WebContentsCreateAsync(callback))
-      return;
-
-    callback.Run(NULL);
-  } else {
-    CancelWindowRequest(render_process_id, route_id, main_frame_route_id);
-  }
+  std::move(callback).Run(nullptr);
+  return &(static_cast<WebContentsImpl*>(new_contents)->GetPrimaryFrameTree());
 }
 
 WebContents* WebContentsImplEfl::HandleNewWebContentsCreate(
-    int32_t render_process_id,
-    int32_t route_id,
-    int32_t main_frame_route_id,
+    RenderFrameHostImpl* opener,
     const mojom::CreateNewWindowParams& params,
-    scoped_refptr<SessionStorageNamespace> session_storage_namespace,
+    bool is_new_browsing_instance,
+    bool has_user_gesture,
+    SessionStorageNamespace* session_storage_namespace,
+    WebContents** new_contents_out,
     void* platform_data) {
-  bool is_guest = BrowserPluginGuest::IsGuest(this);
-  scoped_refptr<SiteInstance> site_instance =
-      params.opener_suppressed && !is_guest
-          ? SiteInstance::CreateForURL(GetBrowserContext(), params.target_url)
-          : GetSiteInstance();
-
-  const std::string& partition_id =
-      GetContentClient()->browser()->GetStoragePartitionIdForSite(
-          GetBrowserContext(), site_instance->GetSiteURL());
-
-  // Create the new web contents. This will automatically create the new
-  // WebContentsView. In the future, we may want to create the view separately.
-  CreateParams create_params(GetBrowserContext(), site_instance.get());
-  create_params.routing_id = route_id;
-  create_params.main_frame_routing_id = main_frame_route_id;
-  create_params.main_frame_name = params.frame_name;
-  create_params.opener_render_process_id = render_process_id;
-  create_params.opener_render_frame_id = params.opener_render_frame_id;
-  create_params.opener_suppressed = params.opener_suppressed;
-  if (params.disposition == NEW_BACKGROUND_TAB)
-    create_params.initially_hidden = true;
-  create_params.renderer_initiated_creation =
-      main_frame_route_id != MSG_ROUTING_NONE;
-
-  WebContentsImplEfl* new_contents = nullptr;
-  if (!is_guest) {
-    create_params.context = view_->GetNativeView();
-    create_params.initial_size = GetContainerBounds().size();
-    // Added for EFL port
-    new_contents =
-        new WebContentsImplEfl(create_params.browser_context, platform_data);
-
-    FrameTreeNode* opener = nullptr;
-    if (create_params.opener_render_frame_id != MSG_ROUTING_NONE) {
-      RenderFrameHostImpl* opener_rfh =
-          RenderFrameHostImpl::FromID(create_params.opener_render_process_id,
-                                      create_params.opener_render_frame_id);
-      if (opener_rfh)
-        opener = opener_rfh->frame_tree_node();
-    }
-
-    if (!create_params.opener_suppressed && opener) {
-      new_contents->GetFrameTree()->root()->SetOpener(opener);
-      new_contents->created_with_opener_ = true;
-    }
-    new_contents->Init(create_params);
-    // End of EFL port specific code.
-  } else {
-    // TODO(t.czekala): WebContents and BrowserPluginGuest are integrated and
-    // it should be checked if we can create WebContentsImplEfl in this scenario
-    NOTREACHED();
-  }
-  new_contents->GetController().SetSessionStorageNamespace(
-      partition_id, session_storage_namespace.get());
-
-  // Added for EFL port
-  new_contents->platform_data_ = platform_data;
-  if (efl_delegate_)
-    efl_delegate_->SetUpSmartObject(platform_data,
-                                    new_contents->GetNativeView());
-  // End of EFL port specific code.
-
-  // If the new frame has a name, make sure any SiteInstances that can find
-  // this named frame have proxies for it.  Must be called after
-  // SetSessionStorageNamespace, since this calls CreateRenderView, which uses
-  // GetSessionStorageNamespace.
-  if (!params.frame_name.empty())
-    new_contents->GetRenderManager()->CreateProxiesForNewNamedFrame();
-
-  // Save the window for later if we're not suppressing the opener (since it
-  // will be shown immediately).
-  if (!params.opener_suppressed) {
-    if (!is_guest) {
-      WebContentsView* new_view = new_contents->view_.get();
-
-      // TODO(brettw): It seems bogus that we have to call this function on the
-      // newly created object and give it one of its own member variables.
-      new_view->CreateViewForWidget(
-          new_contents->GetRenderViewHost()->GetWidget(), false);
-    }
-    // Save the created window associated with the route so we can show it
-    // later.
-    DCHECK_NE(MSG_ROUTING_NONE, route_id);
-    pending_contents_[std::make_pair(render_process_id, route_id)] =
-        new_contents;
-    AddDestructionObserver(new_contents);
-  }
-
-  if (delegate_) {
-    delegate_->WebContentsCreated(this, params.opener_render_frame_id,
-                                  params.frame_name, params.target_url,
-                                  new_contents);
-  }
-
-  if (params.opener_suppressed) {
-    // When the opener is suppressed, the original renderer cannot access the
-    // new window.  As a result, we need to show and navigate the window here.
-    bool was_blocked = false;
-    if (delegate_) {
-      gfx::Rect initial_rect;
-      delegate_->AddNewContents(this, new_contents, params.disposition,
-                                initial_rect, params.user_gesture,
-                                &was_blocked);
-    }
-    if (!was_blocked) {
-      OpenURLParams open_params(params.target_url, Referrer(), CURRENT_TAB,
-                                ui::PAGE_TRANSITION_LINK,
-                                true /* is_renderer_initiated */);
-      open_params.user_gesture = params.user_gesture;
-
-      if (delegate_ && !is_guest &&
-          !delegate_->ShouldResumeRequestsForCreatedWindow()) {
-        // We are in asynchronous add new contents path, delay opening url
-        new_contents->delayed_open_url_params_.reset(
-            new OpenURLParams(open_params));
-      } else {
-        new_contents->OpenURL(open_params);
-      }
-    }
-  }
-
-  return new_contents;
-}
-#endif  // !defined(EWK_BRINGUP)
-
-void WebContentsImplEfl::UpdateTitleForEntry(NavigationEntry* entry,
-                                             const std::u16string& title) {
-#if !defined(EWK_BRINGUP)  // FIXME: m67 bringup
-  // FIXME: EWK_BRINGUP definition should be removed.
-  bool updated = WebContentsImpl::UpdateTitleForEntry(entry, title);
-  // inform view even if the title didn't change to keep EWK consistency
-  if (!updated) {
-    // For file URLs without a title, use the pathname instead. In the case of a
-    // synthesized title, we don't want the update to count toward the "one set
-    // per page of the title to history."
-    std::u16string final_title;
-    if (entry && entry->GetURL().SchemeIsFile() && title.empty())
-      final_title = base::UTF8ToUTF16(entry->GetURL().ExtractFileName());
-    else
-      base::TrimWhitespace(title, base::TRIM_ALL, &final_title);
-
-    view_->SetPageTitle(final_title);
-  }
-#endif  // !defined(EWK_BRINGUP)
+  platform_data_for_new_window_ = platform_data;
+  WebContentsImpl::CreateNewWindow(opener, params, is_new_browsing_instance,
+                                   has_user_gesture, session_storage_namespace);
+  *new_contents_out = web_contents_for_new_window_;
+  return web_contents_for_new_window_;
 }
 
 }  // namespace content
index 1621f64..9fdebb9 100644 (file)
@@ -17,23 +17,33 @@ class WebContentsEflDelegate;
 class CONTENT_EXPORT WebContentsImplEfl : public WebContentsImpl {
  public:
   // See WebContents::Create for a description of these parameters.
-  WebContentsImplEfl(BrowserContext* browser_context,
-                     void* platform_data);
-
-#if !defined(EWK_BRINGUP)  // FIXME: m67 bringup
-  // FIXME: EWK_BRINGUP definition should be removed.
-  void CreateNewWindow(
-      SiteInstance* source_site_instance,
-      int32_t route_id,
-      int32_t main_frame_route_id,
-      int32_t main_frame_widget_route_id,
+  WebContentsImplEfl(BrowserContext* browser_context, void* platform_data);
+  ~WebContentsImplEfl() override;
+
+  WebContentsImplEfl(const WebContentsImplEfl&) = delete;
+  WebContentsImplEfl& operator=(const WebContentsImplEfl&) = delete;
+
+  FrameTree* CreateNewWindow(
+      RenderFrameHostImpl* opener,
       const mojom::CreateNewWindowParams& params,
+      bool is_new_browsing_instance,
+      bool has_user_gesture,
       SessionStorageNamespace* session_storage_namespace) override;
-#endif  // !defined(EWK_BRINGUP)
 
   void* GetPlatformData() const { return platform_data_; }
+  WebContentsImplEfl* ToWebContentsImplEfl() override { return this; }
+  void* GetPlatformDataForNewWindow() { return platform_data_for_new_window_; }
+
+  static WebContentsImpl* CreateWebContentsForNewWindow(
+      BrowserContext* browser_context,
+      RenderFrameHostImpl* opener_rfh);
+
+  void SetWebContentsForNewWindow(WebContentsImpl* web_contents) {
+    web_contents_for_new_window_ = web_contents;
+  }
 
   void SetEflDelegate(WebContentsEflDelegate*);
+  WebContentsEflDelegate* GetEflDelegate() { return efl_delegate_.get(); }
 
   // Overrides for WebContents
   std::unique_ptr<WebContents> Clone() override;
@@ -46,37 +56,20 @@ class CONTENT_EXPORT WebContentsImplEfl : public WebContentsImpl {
   friend class WebContentsImpl;
   friend class WebContents;
 
-  void CancelWindowRequest(int32_t render_process_id,
-                           int32_t route_id,
-                           int32_t main_frame_route_id);
-
-#if !defined(EWK_BRINGUP)  // FIXME: m67 bringup
-  // FIXME: EWK_BRINGUP definition should be removed.
-  void HandleNewWindowRequest(
-      int32_t render_process_id,
-      int32_t route_id,
-      int32_t main_frame_route_id,
-      const mojom::CreateNewWindowParams& params,
-      scoped_refptr<SessionStorageNamespace> session_storage_namespace,
-      bool create);
-
   WebContents* HandleNewWebContentsCreate(
-      int32_t render_process_id,
-      int32_t route_id,
-      int32_t main_frame_route_id,
+      RenderFrameHostImpl* opener,
       const mojom::CreateNewWindowParams& params,
-      scoped_refptr<SessionStorageNamespace> session_storage_namespace,
+      bool is_new_browsing_instance,
+      bool has_user_gesture,
+      SessionStorageNamespace* session_storage_namespace,
+      WebContents** new_contents_out,
       void* platform_data);
-#endif  // !defined(EWK_BRINGUP)
 
-  void UpdateTitleForEntry(NavigationEntry* entry,
-                           const std::u16string& title) override;
-
-  void* platform_data_;
+  void* platform_data_ = nullptr;
+  void* platform_data_for_new_window_ = nullptr;
+  WebContentsImpl* web_contents_for_new_window_ = nullptr;
 
   std::unique_ptr<WebContentsEflDelegate> efl_delegate_;
-
-  // DISALLOW_COPY_AND_ASSIGN(WebContentsImplEfl);
 };
 
 } // namespace content
index 148b056..1e808bd 100644 (file)
@@ -26,19 +26,6 @@ class CONTENT_EXPORT WebContentsEflDelegate {
   typedef base::RepeatingCallback<WebContents*(void*)>
       WebContentsCreateCallback;
 
-  // Callback allowing the embedder to resume or block new window request. The
-  // argument specifies if the request should be allowed (true) or blocked
-  // (false).
-  typedef base::OnceCallback<void(bool)> NewWindowDecideCallback;
-
-  // Allows delegate to asynchronously control whether a WebContents should be
-  // created. The function should return true if the implementation intends to
-  // use this functionality. In such case the synchronous version of this
-  // function ShouldCreateWebContents will not be called. The embedder must
-  // call the callback function at some point.
-  virtual bool ShouldCreateWebContentsAsync(NewWindowDecideCallback,
-                                            const GURL&) = 0;
-
   // Allows the delegate to control new web contents creation in an
   // asynchronous manner. The function is called with a callback object the
   // delegate may keep if it wants to delay creation of new web contents. In
index e3dc2e8..7e68c82 100644 (file)
@@ -159,7 +159,7 @@ bool ContentBrowserClientEfl::CanCreateWindow(
     RenderFrameHost* opener,
     const GURL& opener_url,
     const GURL& opener_top_level_frame_url,
-    const GURL& source_origin,
+    const url::Origin& source_origin,
     content::mojom::WindowContainerType container_type,
     const GURL& target_url,
     const Referrer& referrer,
@@ -180,13 +180,22 @@ bool ContentBrowserClientEfl::CanCreateWindow(
   }
 #endif
 
-  // TODO: shouldn't we call policy,decision,new,window smart callback here?
-
   // User_gesture is modified on renderer side to true if javascript
   // is allowed to open windows without user gesture. If we've got user gesture
   // we also allow javascript access.
   *no_javascript_access = false;
-  return true;
+
+  auto* web_contents = WebContents::FromRenderFrameHost(opener);
+  auto* web_view =
+      WebViewFromWebContents(WebContents::FromRenderFrameHost(opener));
+  auto policy_decision = std::make_unique<_Ewk_Policy_Decision>(web_view);
+  policy_decision->ParseUrl(target_url);
+  web_view->SmartCallback<EWebViewCallbacks::NewWindowPolicyDecision>().call(
+      policy_decision.get());
+
+  // Policy of new window has to be decided immediately.
+  DCHECK(!policy_decision->isSuspended());
+  return policy_decision->CanCreateWindow();
 }
 
 void ContentBrowserClientEfl::DispatchPopupBlockedOnUIThread(
index 9dd0776..6159164 100644 (file)
@@ -44,7 +44,7 @@ class ContentBrowserClientEfl : public ContentBrowserClient {
   bool CanCreateWindow(RenderFrameHost* opener,
                        const GURL& opener_url,
                        const GURL& opener_top_level_frame_url,
-                       const GURL& source_origin,
+                       const url::Origin& source_origin,
                        mojom::WindowContainerType container_type,
                        const GURL& target_url,
                        const Referrer& referrer,
@@ -53,7 +53,7 @@ class ContentBrowserClientEfl : public ContentBrowserClient {
                        const blink::mojom::WindowFeatures& features,
                        bool user_gesture,
                        bool opener_suppressed,
-                       bool* no_javascript_access);
+                       bool* no_javascript_access) override;
 
   scoped_refptr<QuotaPermissionContext> CreateQuotaPermissionContext() override;
 
index cfea836..57d0171 100644 (file)
@@ -324,14 +324,14 @@ Eina_Bool EWebView::HasFocus() const {
   return rwhva()->offscreen_helper()->HasFocus() ? EINA_TRUE : EINA_FALSE;
 }
 
-void EWebView::CreateNewWindow(
+bool EWebView::CreateNewWindow(
     content::WebContentsEflDelegate::WebContentsCreateCallback cb) {
   create_new_window_web_contents_cb_ = cb;
   Evas_Object* new_object = NULL;
   SmartCallback<EWebViewCallbacks::CreateNewWindow>().call(&new_object);
   create_new_window_web_contents_cb_ =
       base::BindRepeating(&NullCreateWebContents);
-  DCHECK(new_object);
+  return !!new_object;
 }
 
 // static
index 36aa94c..7da9db9 100644 (file)
@@ -180,7 +180,7 @@ class EWebView {
   // call this once after created and before use
   void Initialize();
 
-  void CreateNewWindow(
+  bool CreateNewWindow(
       content::WebContentsEflDelegate::WebContentsCreateCallback);
   static Evas_Object* GetHostWindowDelegate(const content::WebContents*);
 
index 97644fa..0172c8a 100644 (file)
@@ -93,11 +93,8 @@ _Ewk_Policy_Decision::_Ewk_Policy_Decision(const NavigationPolicyParams& params,
     SetAuthorizationIfNecessary(params.url);
 }
 
-_Ewk_Policy_Decision::_Ewk_Policy_Decision(
-    EWebView* view,
-    content::WebContentsEflDelegate::NewWindowDecideCallback callback)
+_Ewk_Policy_Decision::_Ewk_Policy_Decision(EWebView* view)
     : web_view_(view),
-      window_create_callback_(std::move(callback)),
       response_headers_(NULL),
       decision_type_(EWK_POLICY_DECISION_USE),
       navigation_type_(EWK_POLICY_NAVIGATION_TYPE_OTHER),
@@ -132,7 +129,7 @@ void _Ewk_Policy_Decision::Use() {
           NavigationPolicyHandlerEfl::Unhandled);
       break;
     case POLICY_NEWWINDOW:
-      std::move(window_create_callback_).Run(true);
+      can_create_window_ = true;
       break;
     default:
       NOTREACHED();
@@ -155,7 +152,7 @@ void _Ewk_Policy_Decision::Ignore() {
           NavigationPolicyHandlerEfl::Handled);
       break;
     case _Ewk_Policy_Decision::POLICY_NEWWINDOW:
-      std::move(window_create_callback_).Run(false);
+      can_create_window_ = false;
       break;
     default:
       NOTREACHED();
@@ -177,7 +174,7 @@ void _Ewk_Policy_Decision::Download() {
       navigation_policy_handler_->DownloadNavigation();
       break;
     case _Ewk_Policy_Decision::POLICY_NEWWINDOW:
-      std::move(window_create_callback_).Run(false);
+      can_create_window_ = false;
       break;
     default:
       NOTREACHED();
index 0e37d24..f5dc3c5 100644 (file)
@@ -9,11 +9,9 @@
 
 #include <string>
 
-#include "base/callback.h"
 #include "base/memory/ref_counted.h"
 #include "browser/navigation_policy_handler_efl.h"
 #include "browser/policy_response_delegate_efl.h"
-#include "content/public/browser/web_contents_efl_delegate.h"
 #include "public/ewk_policy_decision.h"
 
 // Basic type of authorization - 'type username:password'
@@ -47,11 +45,10 @@ class _Ewk_Policy_Decision {
   */
   explicit _Ewk_Policy_Decision(const NavigationPolicyParams &params, content::RenderViewHost* rvh);
 
- /**
-  * Constructs _Ewk_Policy_Decision with navigation type POLICY_NEWWINDOW
-  */
-  explicit _Ewk_Policy_Decision(EWebView* view,
-      content::WebContentsEflDelegate::NewWindowDecideCallback);
+  /**
+   * Constructs _Ewk_Policy_Decision with navigation type POLICY_NEWWINDOW
+   */
+  explicit _Ewk_Policy_Decision(EWebView* view);
 
   ~_Ewk_Policy_Decision();
 
@@ -62,6 +59,7 @@ class _Ewk_Policy_Decision {
 
   bool isDecided() const { return is_decided_; }
   bool isSuspended() const { return is_suspended_; }
+  bool CanCreateWindow() const { return can_create_window_; }
   Ewk_Policy_Navigation_Type GetNavigationType() const { return navigation_type_; }
   const char* GetCookie() const;
   const char* GetAuthUser() const;
@@ -105,7 +103,6 @@ private:
   scoped_refptr<PolicyResponseDelegateEfl> policy_response_delegate_;
   std::unique_ptr<NavigationPolicyHandlerEfl> navigation_policy_handler_;
   std::unique_ptr<_Ewk_Frame> frame_;
-  content::WebContentsEflDelegate::NewWindowDecideCallback window_create_callback_;
   std::string cookie_;
   std::string url_;
   std::string http_method_;
@@ -121,6 +118,7 @@ private:
   std::string auth_user_;
   std::string auth_password_;
   PolicyType type_;
+  bool can_create_window_ = true;
 };
 
 #endif // ewk_policy_decision_private_h
index 0db907b..ce8ec4a 100644 (file)
@@ -117,8 +117,8 @@ WebContentsDelegateEfl::WebContentsDelegateEfl(EWebView* view)
 WebContentsDelegateEfl::~WebContentsDelegateEfl() {
   // It's important to delete web_contents_ before dialog_manager_
   // destructor of web contents uses dialog_manager_
-
-  delete dialog_manager_;
+  if (dialog_manager_)
+    delete dialog_manager_;
 }
 
 WebContents* WebContentsDelegateEfl::OpenURLFromTab(
@@ -196,13 +196,31 @@ void WebContentsDelegateEfl::DidStartNavigation(
   web_view_->SmartCallback<EWebViewCallbacks::ProvisionalLoadStarted>().call();
 }
 
+void WebContentsDelegateEfl::AddNewContents(
+    WebContents* source,
+    std::unique_ptr<WebContents> new_contents,
+    const GURL& target_url,
+    WindowOpenDisposition disposition,
+    const blink::mojom::WindowFeatures& window_features,
+    bool user_gesture,
+    bool* was_blocked) {
+  // Initialize the delegate for the new contents here using source's delegate
+  // as it will be needed to create a new window with the pre-created
+  // new contents in case the opener is suppressed. Otherwise, the delegate
+  // had already been initialized in EWebView::InitializeContent()
+  if (!new_contents->GetDelegate())
+    new_contents->SetDelegate(this);
+
+  // EWebView takes the ownership of new WebContents in
+  // EWebView::InitializeContent(). So, we can release the ownership of new
+  // WebContents here.
+  std::ignore = new_contents.release();
+}
+
 bool WebContentsDelegateEfl::ShouldCreateWebContents(
     WebContents* web_contents,
     RenderFrameHost* opener,
     SiteInstance* source_site_instance,
-    int32_t route_id,
-    int32_t main_frame_route_id,
-    int32_t main_frame_widget_route_id,
     mojom::WindowContainerType window_container_type,
     const GURL& opener_url,
     const std::string& frame_name,
index 49344fc..51a7eeb 100644 (file)
@@ -34,26 +34,31 @@ class WebContentsDelegateEfl : public WebContentsDelegate,
   WebContentsDelegateEfl(EWebView*);
   ~WebContentsDelegateEfl() override;
 
-  // Overridden from WebContentsDelegate:
+  // WebContentsDelegate overrides.
   WebContents* OpenURLFromTab(WebContents* source,
                               const OpenURLParams& params) override;
   void NavigationStateChanged(WebContents* source,
                               InvalidateTypes changed_flags) override;
   void LoadingStateChanged(WebContents* source,
                            bool to_different_document) override;
+  void AddNewContents(WebContents* source,
+                      std::unique_ptr<WebContents> new_contents,
+                      const GURL& target_url,
+                      WindowOpenDisposition disposition,
+                      const blink::mojom::WindowFeatures& window_features,
+                      bool user_gesture,
+                      bool* was_blocked) override;
   bool ShouldCreateWebContents(
       WebContents* web_contents,
       RenderFrameHost* opener,
       SiteInstance* source_site_instance,
-      int32_t route_id,
-      int32_t main_frame_route_id,
-      int32_t main_frame_widget_route_id,
       mojom::WindowContainerType window_container_type,
       const GURL& opener_url,
       const std::string& frame_name,
       const GURL& target_url,
       const std::string& partition_id,
       SessionStorageNamespace* session_storage_namespace);
+
   void CloseContents(WebContents* source) override;
   void EnterFullscreenModeForTab(
       RenderFrameHost* requesting_frame,
@@ -223,7 +228,7 @@ class WebContentsDelegateEfl : public WebContentsDelegate,
 
   std::unique_ptr<ContentSecurityPolicy> pending_content_security_policy_;
   bool document_created_;
-  JavaScriptDialogManagerEfl* dialog_manager_;
+  JavaScriptDialogManagerEfl* dialog_manager_ = nullptr;
   std::unique_ptr<FaviconDownloader> favicon_downloader_;
   base::WeakPtrFactory<WebContentsDelegateEfl> weak_ptr_factory_;
   std::unique_ptr<_Ewk_Certificate_Policy_Decision>
index 469a3b1..d050fc8 100644 (file)
@@ -12,28 +12,9 @@ WebContentsEflDelegateEwk::WebContentsEflDelegateEwk(EWebView* wv)
     : web_view_(wv) {
 }
 
-bool WebContentsEflDelegateEwk::ShouldCreateWebContentsAsync(
-    content::WebContentsEflDelegate::NewWindowDecideCallback callback,
-    const GURL& target_url) {
-  // this method is called ONLY when creating new window - no matter what type
-  std::unique_ptr<_Ewk_Policy_Decision> pd(
-      new _Ewk_Policy_Decision(web_view_, std::move(callback)));
-  pd->ParseUrl(target_url);
-  web_view_->SmartCallback<EWebViewCallbacks::NewWindowPolicyDecision>().call(pd.get());
-
-  if (pd->isSuspended()) {
-    // it will be deleted later after it's used/ignored/downloaded
-    std::ignore = pd.release();
-  } else if (!pd->isDecided()) {
-    pd->Use();
-  }
-  return true;
-}
-
 bool WebContentsEflDelegateEwk::WebContentsCreateAsync(
     content::WebContentsEflDelegate::WebContentsCreateCallback callback) {
-  web_view_->CreateNewWindow(std::move(callback));
-  return true;
+  return web_view_->CreateNewWindow(std::move(callback));
 }
 
 void WebContentsEflDelegateEwk::SetUpSmartObject(void* platform_data, void* native_view) {
index d6a3acd..a7d6905 100644 (file)
@@ -13,9 +13,6 @@ class WebContentsEflDelegateEwk : public content::WebContentsEflDelegate {
  public:
   WebContentsEflDelegateEwk(EWebView*);
 
-  bool ShouldCreateWebContentsAsync(
-      NewWindowDecideCallback, const GURL&) override;
-
   bool WebContentsCreateAsync(WebContentsCreateCallback) override;
 
   void SetUpSmartObject(void*platform_data, void* native_view) override;
index f98652c..8c0eeef 100644 (file)
@@ -32,6 +32,7 @@
 static Ecore_Evas* ee;
 static Evas* e;
 static Evas_Object* view;
+static Evas_Object* view_nw = NULL;
 static Evas_Object *popup;
 
 uint64_t current_notification_id;
@@ -107,6 +108,7 @@ static void __hit_test_request_cb(Evas_Object* o, int x, int y, int hit_test_mod
 static void __webprocess_crashed_cb(void* data, Evas_Object* obj, void* event_info);
 
 static void on_evas_resize(Ecore_Evas*);
+static void on_evas_resize_nw(Ecore_Evas*);
 static void __notification_show_cb(Ewk_Notification*, void* event_info);
 static Eina_Bool __notification_permission_cb(Evas_Object*, Ewk_Notification_Permission_Request*, void*);
 static void __notification_cancel_cb(uint64_t notification_id, void* event_info);
@@ -595,6 +597,8 @@ int main(int argc, char** argv)
   ewk_context_unref(context);
   // deleting view will release context
   evas_object_del(view);
+  if (view_nw)
+    evas_object_del(view_nw);
   ewk_shutdown();
 
   free(start_url);
@@ -609,6 +613,13 @@ static void on_evas_resize(Ecore_Evas* ee)
   evas_object_resize(view, width, height);
 }
 
+static void on_evas_resize_nw(Ecore_Evas* ee)
+{
+  int width, height;
+  ecore_evas_geometry_get(ee, NULL, NULL, &width, &height);
+  evas_object_resize(view_nw, width, height);
+}
+
 void __ewk_cookie_manager_async_hostnames_get_cb(Eina_List *hostnames, Ewk_Error *error, void *event_info)
 {
   printf ("APP.C callback called __ewk_cookie_manager_async_hostnames_get_cb \n");
@@ -763,8 +774,8 @@ void __create_window_cb(void *data, Evas_Object *obj, void *event_info)
   printf ("APP.C callback called __create_window_cb \n");
 
   // We have no information about preferred size with the current API.
-  const int default_width = 300;
-  const int default_height =  400;
+  const int default_width = 800;
+  const int default_height = 600;
 
 #if defined(USE_WAYLAND)
   Ecore_Evas* ee = ecore_evas_new("wayland_egl", 0, 0, default_width, default_height, 0);
@@ -773,19 +784,25 @@ void __create_window_cb(void *data, Evas_Object *obj, void *event_info)
 #endif
   Evas* e = ecore_evas_get(ee);
 
-  Evas_Object* view = ewk_view_add(e);
-  evas_object_resize(view, default_width, default_height);
-  evas_object_show(view);
-  evas_object_focus_set(view, EINA_TRUE);
+  view_nw = ewk_view_add(e);
+  evas_object_resize(view_nw, default_width, default_height);
+  evas_object_show(view_nw);
+  evas_object_focus_set(view_nw, EINA_TRUE);
   ecore_evas_show(ee);
+  ecore_evas_fullscreen_set(ee, EINA_TRUE);
+  ecore_evas_callback_resize_set(ee, &on_evas_resize_nw);
 
-  evas_object_smart_callback_add(view, "close,window", __window_closed_cb, 0);
+  evas_object_smart_callback_add(view_nw, "close,window", __window_closed_cb, 0);
 
   // Override default handler because it terminates the event loop.
   ecore_evas_callback_delete_request_set(ee, delete_popup_window);
 
+#if defined(OS_TIZEN_TV_PRODUCT)
+  _create_mouse_cursor(e);
+#endif
+
   Evas_Object** result = (Evas_Object**) event_info;
-  *result = view;
+  *result = view_nw;
 }
 
 void __window_closed_cb(void *data, Evas_Object *view, void *event_info)