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 21namespace extensions { 22 23AppWindowContentsImpl::AppWindowContentsImpl(AppWindow* host) : host_(host) {} 24 25AppWindowContentsImpl::~AppWindowContentsImpl() {} 26 27void 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 44void 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 63void 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 79void AppWindowContentsImpl::NativeWindowClosed() { 80 content::RenderViewHost* rvh = web_contents_->GetRenderViewHost(); 81 rvh->Send(new ExtensionMsg_AppWindowClosed(rvh->GetRoutingID())); 82} 83 84void 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 95content::WebContents* AppWindowContentsImpl::GetWebContents() const { 96 return web_contents_.get(); 97} 98 99bool 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 110WindowController* AppWindowContentsImpl::GetExtensionWindowController() const { 111 return NULL; 112} 113 114content::WebContents* AppWindowContentsImpl::GetAssociatedWebContents() const { 115 return web_contents_.get(); 116} 117 118void AppWindowContentsImpl::OnRequest( 119 const ExtensionHostMsg_Request_Params& params) { 120 extension_function_dispatcher_->Dispatch( 121 params, web_contents_->GetRenderViewHost()); 122} 123 124void AppWindowContentsImpl::UpdateDraggableRegions( 125 const std::vector<DraggableRegion>& regions) { 126 host_->UpdateDraggableRegions(regions); 127} 128 129void 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