#include "atom/browser/api/atom_api_web_contents.h"
+#include <Eina.h>
#include <set>
#include <string>
#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 "chrome/browser/printing/print_preview_message_handler.h"
#include "chrome/browser/printing/print_view_manager_basic.h"
#include "chrome/browser/ssl/security_state_tab_helper.h"
+#include "content/browser/frame_host/navigation_entry_impl.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/common/view_messages.h"
#include "content/public/browser/navigation_details.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/navigation_handle.h"
+#include "content/public/browser/notification_details.h"
+#include "content/public/browser/notification_source.h"
+#include "content/public/browser/notification_types.h"
#include "content/public/browser/plugin_service.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.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
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;
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 {
}
// 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));
}
+// Set the background color of RenderWidgetHostView.
+void SetBackgroundColor(content::WebContents* web_contents) {
+ const auto view = web_contents->GetRenderWidgetHostView();
+ if (view) {
+ WebContentsPreferences* web_preferences =
+ WebContentsPreferences::FromWebContents(web_contents);
+ std::string color_name;
+ if (web_preferences->web_preferences()->GetString(options::kBackgroundColor,
+ &color_name)) {
+ view->SetBackgroundColor(ParseHexColor(color_name));
+ } else {
+ view->SetBackgroundColor(SK_ColorTRANSPARENT);
+ }
+ }
+}
+
} // namespace
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);
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;
content::WebContents *web_contents,
mate::Handle<api::Session> session,
const mate::Dictionary& options) {
- Observe(web_contents);
+ content::WebContentsObserver::Observe(web_contents);
InitWithWebContents(web_contents, session->browser_context());
managed_web_contents()->GetView()->SetDelegate(this);
SetOwnerWindow(owner_window);
}
+ const content::NavigationController* controller =
+ &web_contents->GetController();
+ registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_PENDING,
+ content::Source<content::NavigationController>(controller));
+
Init(isolate);
AttachAsUserData(web_contents);
}
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;
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);
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,
void WebContents::CloseContents(content::WebContents* source) {
Emit("close");
-
+ LOG(ERROR) << __FUNCTION__;
if ((type_ == BROWSER_WINDOW || type_ == OFF_SCREEN) && owner_window())
owner_window()->CloseContents(source);
}
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);
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) {
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");
}
details.headers.get());
}
+void WebContents::DidStartNavigation(
+ content::NavigationHandle* navigation_handle) {
+ if (!navigation_handle->IsInMainFrame() || navigation_handle->IsSamePage())
+ return;
+
+ if (deferred_load_url_.id) {
+ auto web_contents = navigation_handle->GetWebContents();
+ auto& controller = web_contents->GetController();
+ int id = controller.GetPendingEntry()->GetUniqueID();
+ if (id == deferred_load_url_.id) {
+ if (!deferred_load_url_.params.url.is_empty()) {
+ auto params = deferred_load_url_.params;
+ deferred_load_url_.id = 0;
+ deferred_load_url_.params =
+ content::NavigationController::LoadURLParams(GURL());
+ controller.LoadURLWithParams(params);
+ SetBackgroundColor(web_contents);
+ } else {
+ deferred_load_url_.id = 0;
+ }
+ }
+ }
+}
+
void WebContents::DidFinishNavigation(
content::NavigationHandle* navigation_handle) {
bool is_main_frame = navigation_handle->IsInMainFrame();
Emit("page-favicon-updated", unique_urls);
}
+void WebContents::Observe(int type,
+ const content::NotificationSource& source,
+ const content::NotificationDetails& details) {
+ switch (type) {
+ case content::NOTIFICATION_NAV_ENTRY_PENDING: {
+ content::NavigationEntry* entry =
+ content::Details<content::NavigationEntry>(details).ptr();
+ content::NavigationEntryImpl* entry_impl =
+ static_cast<content::NavigationEntryImpl*>(entry);
+ // In NavigatorImpl::DidStartMainFrameNavigation when there is no
+ // browser side pending entry available it creates a new one based
+ // on existing pending entry, hence we track the unique id here
+ // instead in WebContents::LoadURL with controller.GetPendingEntry()
+ // TODO(deepak1556): Remove once we have
+ // https://codereview.chromium.org/2661743002.
+ if (entry_impl->frame_tree_node_id() == -1) {
+ deferred_load_url_.id = entry->GetUniqueID();
+ }
+ break;
+ }
+ default:
+ NOTREACHED();
+ break;
+ }
+}
+
void WebContents::DevToolsReloadPage() {
Emit("devtools-reload-page");
}
}
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());
}
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)
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()
// 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();
return;
}
+ if (!atom::Browser::Get()->ShouldAllowNavigation(url.spec())) {
+ return;
+ }
+
content::NavigationController::LoadURLParams params(url);
GURL http_referrer;
params.load_type = content::NavigationController::LOAD_TYPE_HTTP_POST;
}
+ GURL base_url_for_data_url;
+ if (options.Get("baseURLForDataURL", &base_url_for_data_url)) {
+ params.base_url_for_data_url = base_url_for_data_url;
+ params.load_type = content::NavigationController::LOAD_TYPE_DATA;
+ }
+
params.transition_type = ui::PAGE_TRANSITION_TYPED;
params.should_clear_history_list = true;
params.override_user_agent = content::NavigationController::UA_OVERRIDE_TRUE;
- web_contents()->GetController().LoadURLWithParams(params);
- // Set the background color of RenderWidgetHostView.
+ if (deferred_load_url_.id) {
+ deferred_load_url_.params = params;
+ return;
+ }
+
+ web_contents()->GetController().LoadURLWithParams(params);
// We have to call it right after LoadURL because the RenderViewHost is only
// created after loading a page.
- const auto view = web_contents()->GetRenderWidgetHostView();
- if (view) {
- WebContentsPreferences* web_preferences =
- WebContentsPreferences::FromWebContents(web_contents());
- std::string color_name;
- if (web_preferences->web_preferences()->GetString(options::kBackgroundColor,
- &color_name)) {
- view->SetBackgroundColor(ParseHexColor(color_name));
- } else {
- view->SetBackgroundColor(SK_ColorTRANSPARENT);
- }
- }
+ SetBackgroundColor(web_contents());
}
void WebContents::DownloadURL(const GURL& url) {
}
void WebContents::Stop() {
+ LOG(ERROR) << __FUNCTION__;
web_contents()->Stop();
}
web_contents()->GetController().GoToOffset(offset);
}
+const std::string WebContents::GetWebRTCIPHandlingPolicy() const {
+ return web_contents()->
+ GetMutableRendererPrefs()->webrtc_ip_handling_policy;
+}
+
+void WebContents::SetWebRTCIPHandlingPolicy(
+ const std::string& webrtc_ip_handling_policy) {
+ if (GetWebRTCIPHandlingPolicy() == webrtc_ip_handling_policy)
+ return;
+ web_contents()->GetMutableRendererPrefs()->webrtc_ip_handling_policy =
+ webrtc_ip_handling_policy;
+
+ content::RenderViewHost* host = web_contents()->GetRenderViewHost();
+ if (host)
+ host->SyncRendererPrefs();
+}
+
bool WebContents::IsCrashed() const {
return web_contents()->IsCrashed();
}
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();
}
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());
.SetMethod("copyImageAt", &WebContents::CopyImageAt)
.SetMethod("capturePage", &WebContents::CapturePage)
.SetMethod("setEmbedder", &WebContents::SetEmbedder)
+ .SetMethod("setWebRTCIPHandlingPolicy",
+ &WebContents::SetWebRTCIPHandlingPolicy)
+ .SetMethod("getWebRTCIPHandlingPolicy",
+ &WebContents::GetWebRTCIPHandlingPolicy)
.SetProperty("id", &WebContents::ID)
.SetProperty("session", &WebContents::Session)
.SetProperty("hostWebContents", &WebContents::HostWebContents)