1 // Copyright 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "extensions/browser/app_window/app_window_contents.h" 6 7 #include <string> 8 #include <utility> 9 10 #include "content/public/browser/browser_context.h" 11 #include "content/public/browser/browser_thread.h" 12 #include "content/public/browser/render_process_host.h" 13 #include "content/public/browser/render_view_host.h" 14 #include "content/public/browser/resource_dispatcher_host.h" 15 #include "content/public/browser/site_instance.h" 16 #include "content/public/browser/web_contents.h" 17 #include "content/public/common/renderer_preferences.h" 18 #include "extensions/browser/app_window/native_app_window.h" 19 #include "extensions/common/extension_messages.h" 20 21 namespace extensions { 22 23 AppWindowContentsImpl::AppWindowContentsImpl(AppWindow* host) : host_(host) {} 24 25 AppWindowContentsImpl::~AppWindowContentsImpl() {} 26 27 void AppWindowContentsImpl::Initialize(content::BrowserContext* context, 28 const GURL& url) { 29 url_ = url; 30 31 extension_function_dispatcher_.reset( 32 new ExtensionFunctionDispatcher(context, this)); 33 34 web_contents_.reset( 35 content::WebContents::Create(content::WebContents::CreateParams( 36 context, content::SiteInstance::CreateForURL(context, url_)))); 37 38 Observe(web_contents_.get()); 39 web_contents_->GetMutableRendererPrefs()-> 40 browser_handles_all_top_level_requests = true; 41 web_contents_->GetRenderViewHost()->SyncRendererPrefs(); 42 } 43 44 void AppWindowContentsImpl::LoadContents(int32 creator_process_id) { 45 // If the new view is in the same process as the creator, block the created 46 // RVH from loading anything until the background page has had a chance to 47 // do any initialization it wants. If it's a different process, the new RVH 48 // shouldn't communicate with the background page anyway (e.g. sandboxed). 49 if (web_contents_->GetRenderViewHost()->GetProcess()->GetID() == 50 creator_process_id) { 51 SuspendRenderViewHost(web_contents_->GetRenderViewHost()); 52 } else { 53 VLOG(1) << "AppWindow created in new process (" 54 << web_contents_->GetRenderViewHost()->GetProcess()->GetID() 55 << ") != creator (" << creator_process_id << "). Routing disabled."; 56 } 57 58 web_contents_->GetController().LoadURL( 59 url_, content::Referrer(), ui::PAGE_TRANSITION_LINK, 60 std::string()); 61 } 62 63 void AppWindowContentsImpl::NativeWindowChanged( 64 NativeAppWindow* native_app_window) { 65 base::ListValue args; 66 base::DictionaryValue* dictionary = new base::DictionaryValue(); 67 args.Append(dictionary); 68 host_->GetSerializedState(dictionary); 69 70 content::RenderViewHost* rvh = web_contents_->GetRenderViewHost(); 71 rvh->Send(new ExtensionMsg_MessageInvoke(rvh->GetRoutingID(), 72 host_->extension_id(), 73 "app.window", 74 "updateAppWindowProperties", 75 args, 76 false)); 77 } 78 79 void AppWindowContentsImpl::NativeWindowClosed() { 80 content::RenderViewHost* rvh = web_contents_->GetRenderViewHost(); 81 rvh->Send(new ExtensionMsg_AppWindowClosed(rvh->GetRoutingID())); 82 } 83 84 void AppWindowContentsImpl::DispatchWindowShownForTests() const { 85 base::ListValue args; 86 content::RenderViewHost* rvh = web_contents_->GetRenderViewHost(); 87 rvh->Send(new ExtensionMsg_MessageInvoke(rvh->GetRoutingID(), 88 host_->extension_id(), 89 "app.window", 90 "appWindowShownForTests", 91 args, 92 false)); 93 } 94 95 content::WebContents* AppWindowContentsImpl::GetWebContents() const { 96 return web_contents_.get(); 97 } 98 99 bool AppWindowContentsImpl::OnMessageReceived(const IPC::Message& message) { 100 bool handled = true; 101 IPC_BEGIN_MESSAGE_MAP(AppWindowContentsImpl, message) 102 IPC_MESSAGE_HANDLER(ExtensionHostMsg_Request, OnRequest) 103 IPC_MESSAGE_HANDLER(ExtensionHostMsg_UpdateDraggableRegions, 104 UpdateDraggableRegions) 105 IPC_MESSAGE_UNHANDLED(handled = false) 106 IPC_END_MESSAGE_MAP() 107 return handled; 108 } 109 110 WindowController* AppWindowContentsImpl::GetExtensionWindowController() const { 111 return NULL; 112 } 113 114 content::WebContents* AppWindowContentsImpl::GetAssociatedWebContents() const { 115 return web_contents_.get(); 116 } 117 118 void AppWindowContentsImpl::OnRequest( 119 const ExtensionHostMsg_Request_Params& params) { 120 extension_function_dispatcher_->Dispatch( 121 params, web_contents_->GetRenderViewHost()); 122 } 123 124 void AppWindowContentsImpl::UpdateDraggableRegions( 125 const std::vector<DraggableRegion>& regions) { 126 host_->UpdateDraggableRegions(regions); 127 } 128 129 void AppWindowContentsImpl::SuspendRenderViewHost( 130 content::RenderViewHost* rvh) { 131 DCHECK(rvh); 132 content::BrowserThread::PostTask( 133 content::BrowserThread::IO, FROM_HERE, 134 base::Bind(&content::ResourceDispatcherHost::BlockRequestsForRoute, 135 base::Unretained(content::ResourceDispatcherHost::Get()), 136 rvh->GetProcess()->GetID(), rvh->GetRoutingID())); 137 } 138 139 } // namespace extensions 140