|did-frame-rendered| used for optimize launching time
[platform/framework/web/crosswalk-tizen.git] / atom / browser / api / atom_api_web_contents.cc
index 6ba23b3..fccae5a 100644 (file)
@@ -4,6 +4,7 @@
 
 #include "atom/browser/api/atom_api_web_contents.h"
 
+#include <Eina.h>
 #include <set>
 #include <string>
 
@@ -13,6 +14,7 @@
 #include "atom/browser/atom_browser_client.h"
 #include "atom/browser/atom_browser_context.h"
 #include "atom/browser/atom_browser_main_parts.h"
+#include "atom/browser/browser.h"
 #include "atom/browser/lib/bluetooth_chooser.h"
 #include "atom/browser/native_window.h"
 #include "atom/browser/net/atom_network_delegate.h"
 #include "net/url_request/url_request_context.h"
 #include "third_party/WebKit/public/platform/WebInputEvent.h"
 #include "third_party/WebKit/public/web/WebFindOptions.h"
+#include "tizen/common/env_variables.h"
 #include "ui/display/screen.h"
 
-#if !defined(OS_MACOSX)
+#if defined(USE_EFL)
+#include "tizen/extensions/common/xwalk_extension_server.h"
+#endif
+
+#if !defined(OS_MACOSX) && !defined(USE_EFL)
 #include "ui/aura/window.h"
 #endif
 
@@ -188,6 +195,7 @@ struct Converter<atom::api::WebContents::Type> {
     switch (val) {
       case Type::BACKGROUND_PAGE: type = "backgroundPage"; break;
       case Type::BROWSER_WINDOW: type = "window"; break;
+      case Type::BROWSER_VIEW: type = "browserView"; break;
       case Type::REMOTE: type = "remote"; break;
       case Type::WEB_VIEW: type = "webview"; break;
       case Type::OFF_SCREEN: type = "offscreen"; break;
@@ -202,10 +210,12 @@ struct Converter<atom::api::WebContents::Type> {
     std::string type;
     if (!ConvertFromV8(isolate, val, &type))
       return false;
-    if (type == "webview") {
-      *out = Type::WEB_VIEW;
-    } else if (type == "backgroundPage") {
+    if (type == "backgroundPage") {
       *out = Type::BACKGROUND_PAGE;
+    } else if (type == "browserView") {
+      *out = Type::BROWSER_VIEW;
+    } else if (type == "webview") {
+      *out = Type::WEB_VIEW;
     } else if (type == "offscreen") {
       *out = Type::OFF_SCREEN;
     } else {
@@ -240,7 +250,7 @@ content::ServiceWorkerContext* GetServiceWorkerContext(
 }
 
 // Called when CapturePage is done.
-void OnCapturePageDone(base::Callback<void(const gfx::Image&)> callback,
+void OnCapturePageDone(const base::Callback<void(const gfx::Image&)>& callback,
                        const SkBitmap& bitmap,
                        content::ReadbackResponse response) {
   callback.Run(gfx::Image::CreateFrom1xBitmap(bitmap));
@@ -273,7 +283,8 @@ WebContents::WebContents(v8::Isolate* isolate,
       type_(type),
       request_id_(0),
       background_throttling_(true),
-      enable_devtools_(true) {
+      enable_devtools_(true),
+      notify_ready_state_(false) {
   if (type == REMOTE) {
     web_contents->SetUserAgentOverride(GetBrowserContext()->GetUserAgent());
     Init(isolate);
@@ -306,6 +317,8 @@ WebContents::WebContents(v8::Isolate* isolate, const mate::Dictionary& options)
     type_ = WEB_VIEW;
   else if (options.Get("isBackgroundPage", &b) && b)
     type_ = BACKGROUND_PAGE;
+  else if (options.Get("isBrowserView", &b) && b)
+    type_ = BROWSER_VIEW;
   else if (options.Get("offscreen", &b) && b)
     type_ = OFF_SCREEN;
 
@@ -411,21 +424,26 @@ WebContents::~WebContents() {
     if (type_ == WEB_VIEW)
       guest_delegate_->Destroy();
 
-    // The WebContentsDestroyed will not be called automatically because we
-    // unsubscribe from webContents before destroying it. So we have to manually
-    // call it here to make sure "destroyed" event is emitted.
     RenderViewDeleted(web_contents()->GetRenderViewHost());
-    WebContentsDestroyed();
+    DestroyWebContents();
   }
 }
 
+void WebContents::DestroyWebContents() {
+  // This event is only for internal use, which is emitted when WebContents is
+  // being destroyed.
+  Emit("will-destroy");
+  ResetManagedWebContents();
+}
+
 bool WebContents::DidAddMessageToConsole(content::WebContents* source,
                                          int32_t level,
                                          const base::string16& message,
                                          int32_t line_no,
                                          const base::string16& source_id) {
   if (type_ == BROWSER_WINDOW || type_ == OFF_SCREEN) {
-    return false;
+    LOG(ERROR) << "Console Message : " << message << ", source:" << source_id << " (" << line_no << ")";
+    return true;
   } else {
     Emit("console-message", level, message, line_no, source_id);
     return true;
@@ -450,7 +468,8 @@ void WebContents::WebContentsCreated(content::WebContents* source_contents,
                                      const std::string& frame_name,
                                      const GURL& target_url,
                                      content::WebContents* new_contents) {
-  v8::Locker locker(isolate());
+  if (!::tizen::is_single_process)
+    v8::Locker locker(isolate());
   v8::HandleScope handle_scope(isolate());
   auto api_web_contents = CreateFrom(isolate(), new_contents, BROWSER_WINDOW);
   Emit("-web-contents-created", api_web_contents, target_url, frame_name);
@@ -462,7 +481,8 @@ void WebContents::AddNewContents(content::WebContents* source,
                                  const gfx::Rect& initial_rect,
                                  bool user_gesture,
                                  bool* was_blocked) {
-  v8::Locker locker(isolate());
+  if (!::tizen::is_single_process)
+    v8::Locker locker(isolate());
   v8::HandleScope handle_scope(isolate());
   auto api_web_contents = CreateFrom(isolate(), new_contents);
   if (Emit("-add-new-contents", api_web_contents, disposition, user_gesture,
@@ -511,7 +531,7 @@ void WebContents::MoveContents(content::WebContents* source,
 
 void WebContents::CloseContents(content::WebContents* source) {
   Emit("close");
-
+  LOG(ERROR) << __FUNCTION__;
   if ((type_ == BROWSER_WINDOW || type_ == OFF_SCREEN) && owner_window())
     owner_window()->CloseContents(source);
 }
@@ -614,7 +634,8 @@ void WebContents::FindReply(content::WebContents* web_contents,
   if (!final_update)
     return;
 
-  v8::Locker locker(isolate());
+  if (!::tizen::is_single_process)
+    v8::Locker locker(isolate());
   v8::HandleScope handle_scope(isolate());
   mate::Dictionary result = mate::Dictionary::CreateEmpty(isolate());
   result.Set("requestId", request_id);
@@ -669,6 +690,7 @@ void WebContents::RenderViewCreated(content::RenderViewHost* render_view_host) {
       render_view_host->GetRoutingID());
   if (impl)
     impl->disable_hidden_ = !background_throttling_;
+  atom::Browser::Get()->RenderViewCreated(render_view_host);
 }
 
 void WebContents::RenderViewDeleted(content::RenderViewHost* render_view_host) {
@@ -725,7 +747,23 @@ void WebContents::DidFailLoad(content::RenderFrameHost* render_frame_host,
   Emit("did-fail-load", error_code, error_description, url, is_main_frame);
 }
 
+void WebContents::DidRenderFrame() {
+  if (!notify_ready_state_) {
+    notify_ready_state_ = true;
+    Emit("did-frame-rendered");
+  }
+}
+
 void WebContents::DidStartLoading() {
+  notify_ready_state_ = false;
+#if defined(OS_TIZEN)
+  if (owner_window() && !owner_window()->IsVisible()) {
+    std::string scheme = web_contents()->GetURL().scheme();
+    if (std::string::npos != scheme.find("http")) {
+      owner_window()->Show();
+    }
+  }
+#endif
   Emit("did-start-loading");
 }
 
@@ -861,7 +899,8 @@ void WebContents::DevToolsFocused() {
 }
 
 void WebContents::DevToolsOpened() {
-  v8::Locker locker(isolate());
+  if (!::tizen::is_single_process)
+    v8::Locker locker(isolate());
   v8::HandleScope handle_scope(isolate());
   auto handle = WebContents::CreateFrom(
       isolate(), managed_web_contents()->GetDevToolsWebContents());
@@ -881,16 +920,57 @@ void WebContents::DevToolsOpened() {
 }
 
 void WebContents::DevToolsClosed() {
-  v8::Locker locker(isolate());
+  if (!::tizen::is_single_process)
+    v8::Locker locker(isolate());
   v8::HandleScope handle_scope(isolate());
   devtools_web_contents_.Reset();
 
   Emit("devtools-closed");
 }
 
+void WebContents::OnWrtPluginMessage(const Ewk_Wrt_Message_Data& data) {
+  Ewk_Wrt_Message_Data tmp = data;
+  HandleWrtPluginMessage(&tmp);
+}
+
+void WebContents::OnWrtPluginSyncMessage(const Ewk_Wrt_Message_Data& data,
+                                                    IPC::Message* reply) {
+  Ewk_Wrt_Message_Data tmp = data;
+  HandleWrtPluginMessage(&tmp);
+  AtomHostMsg_WrtSyncMessage::WriteReplyParams(reply, tmp.value);
+  Send(reply);
+}
+
+void WebContents::HandleWrtPluginMessage(Ewk_Wrt_Message_Data* msg) {
+  Eina_Stringshare* msg_type = ewk_ipc_wrt_message_data_type_get(msg);
+  LOG(INFO) << msg_type;
+#define TYPE_BEGIN(x) (!strncmp(msg_type, x, strlen(x)))
+#define TYPE_IS(x) (!strcmp(msg_type, x))
+  if (TYPE_BEGIN("xwalk://")) {
+    auto extension_server = extensions::XWalkExtensionServer::GetInstance();
+    extension_server->HandleIPCMessage(msg);
+  } else {
+    Eina_Stringshare* msg_id = msg->GetId();
+    Eina_Stringshare* msg_ref_id = msg->GetReferenceId();
+    Eina_Stringshare* msg_value = msg->GetValue();
+    if (TYPE_IS("tizen://exit")) {
+      atom::Browser::Get()->Quit();
+    }
+
+    eina_stringshare_del(msg_ref_id);
+    eina_stringshare_del(msg_id);
+    eina_stringshare_del(msg_value);
+  }
+#undef TYPE_IS
+#undef TYPE_BEGIN
+
+  eina_stringshare_del(msg_type);
+}
+
 bool WebContents::OnMessageReceived(const IPC::Message& message) {
   bool handled = true;
   IPC_BEGIN_MESSAGE_MAP(WebContents, message)
+    IPC_MESSAGE_HANDLER_DELAY_REPLY(WrtViewMsg_GetCSP, OnGetContentSecurityPolicy)
     IPC_MESSAGE_HANDLER(AtomViewHostMsg_Message, OnRendererMessage)
     IPC_MESSAGE_HANDLER_DELAY_REPLY(AtomViewHostMsg_Message_Sync,
                                     OnRendererMessageSync)
@@ -898,8 +978,11 @@ bool WebContents::OnMessageReceived(const IPC::Message& message) {
                                     OnSetTemporaryZoomLevel)
     IPC_MESSAGE_HANDLER_DELAY_REPLY(AtomViewHostMsg_GetZoomLevel,
                                     OnGetZoomLevel)
-    IPC_MESSAGE_HANDLER_CODE(ViewHostMsg_SetCursor, OnCursorChange,
-      handled = false)
+    IPC_MESSAGE_HANDLER(AtomHostMsg_WrtMessage, OnWrtPluginMessage)
+    IPC_MESSAGE_HANDLER_DELAY_REPLY(AtomHostMsg_WrtSyncMessage, OnWrtPluginSyncMessage)
+    // FIXME: Disable OnCursorChange due to stach_chk_fail crash.
+    // IPC_MESSAGE_HANDLER_CODE(ViewHostMsg_SetCursor, OnCursorChange,
+    //   handled = false)
     IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP()
 
@@ -919,10 +1002,6 @@ bool WebContents::OnMessageReceived(const IPC::Message& message) {
 // be destroyed on close, and WebContentsDestroyed would be called for it, so
 // we need to make sure the api::WebContents is also deleted.
 void WebContents::WebContentsDestroyed() {
-  // This event is only for internal use, which is emitted when WebContents is
-  // being destroyed.
-  Emit("will-destroy");
-
   // Cleanup relationships with other parts.
   RemoveFromWeakMap();
 
@@ -972,6 +1051,10 @@ void WebContents::LoadURL(const GURL& url, const mate::Dictionary& options) {
     return;
   }
 
+  if (!atom::Browser::Get()->ShouldAllowNavigation(url.spec())) {
+    return;
+  }
+
   content::NavigationController::LoadURLParams params(url);
 
   GURL http_referrer;
@@ -1049,6 +1132,7 @@ bool WebContents::IsWaitingForResponse() const {
 }
 
 void WebContents::Stop() {
+  LOG(ERROR) << __FUNCTION__;
   web_contents()->Stop();
 }
 
@@ -1354,11 +1438,15 @@ bool WebContents::IsFocused() const {
   auto view = web_contents()->GetRenderWidgetHostView();
   if (!view) return false;
 
+#if defined(USE_EFL)
+  NOTIMPLEMENTED();
+#else
   if (GetType() != BACKGROUND_PAGE) {
     auto window = web_contents()->GetNativeView()->GetToplevelWindow();
     if (window && !window->IsVisible())
       return false;
   }
+#endif
 
   return view->HasFocus();
 }
@@ -1634,6 +1722,14 @@ void WebContents::OnGetZoomLevel(IPC::Message* reply_msg) {
   Send(reply_msg);
 }
 
+void WebContents::OnGetContentSecurityPolicy(IPC::Message* reply_msg) {
+  std::string csp_rule;
+  std::string csp_report_rule;
+  atom::Browser::Get()->GetCSP(csp_rule, csp_report_rule);
+  WrtViewMsg_GetCSP::WriteReplyParams(reply_msg, csp_rule, csp_report_rule);
+  Send(reply_msg);
+}
+
 v8::Local<v8::Value> WebContents::GetWebPreferences(v8::Isolate* isolate) {
   WebContentsPreferences* web_preferences =
       WebContentsPreferences::FromWebContents(web_contents());