summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoreroman@chromium.org <eroman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-04-13 20:17:49 +0000
committereroman@chromium.org <eroman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-04-13 20:17:49 +0000
commit2a9ee22f1e672099f70d59594258f093f5520a16 (patch)
treebcf1c08958b7850141e376fce82fbe9807648a82
parent92922a8e913115ad091c367e5ec3acde7f26fa81 (diff)
downloadchromium_src-2a9ee22f1e672099f70d59594258f093f5520a16.zip
chromium_src-2a9ee22f1e672099f70d59594258f093f5520a16.tar.gz
chromium_src-2a9ee22f1e672099f70d59594258f093f5520a16.tar.bz2
Revert 132218 - Convert plugin and GPU process to brokered handle duplication.
(Seems to be responsible for VMTest failure on ChromiumOS). BUG=119250 Review URL: https://chromiumcodereview.appspot.com/9958034 TBR=jschuh@chromium.org Review URL: https://chromiumcodereview.appspot.com/10081018 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@132254 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/common/chrome_content_client.cc9
-rw-r--r--content/browser/gpu/browser_gpu_channel_host_factory.cc18
-rw-r--r--content/browser/gpu/browser_gpu_channel_host_factory.h1
-rw-r--r--content/browser/gpu/gpu_process_host.cc33
-rw-r--r--content/browser/gpu/gpu_process_host.h4
-rw-r--r--content/browser/renderer_host/gpu_message_filter.cc22
-rw-r--r--content/browser/renderer_host/gpu_message_filter.h1
-rw-r--r--content/common/gpu/client/command_buffer_proxy_impl.cc24
-rw-r--r--content/common/gpu/client/gpu_channel_host.cc11
-rw-r--r--content/common/gpu/client/gpu_channel_host.h11
-rw-r--r--content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.cc2
-rw-r--r--content/common/gpu/gpu_channel.cc20
-rw-r--r--content/common/gpu/gpu_channel.h12
-rw-r--r--content/common/gpu/gpu_command_buffer_stub.cc33
-rw-r--r--content/common/gpu/gpu_messages.h10
-rw-r--r--content/common/gpu/media/dxva_video_decode_accelerator.cc18
-rw-r--r--content/common/gpu/media/dxva_video_decode_accelerator.h8
-rw-r--r--content/common/gpu/media/gpu_video_decode_accelerator.cc5
-rw-r--r--content/common/gpu/media/gpu_video_decode_accelerator.h3
-rw-r--r--content/common/gpu/media/video_decode_accelerator_unittest.cc2
-rw-r--r--content/common/np_channel_base.h3
-rw-r--r--content/common/sandbox_policy.cc64
-rw-r--r--content/plugin/plugin_channel.cc17
-rw-r--r--content/plugin/plugin_channel.h7
-rw-r--r--content/plugin/webplugin_proxy.cc23
-rw-r--r--content/renderer/render_thread_impl.cc7
-rw-r--r--content/renderer/webplugin_delegate_proxy.cc23
27 files changed, 248 insertions, 143 deletions
diff --git a/chrome/common/chrome_content_client.cc b/chrome/common/chrome_content_client.cc
index cbb47dd..b713f82 100644
--- a/chrome/common/chrome_content_client.cc
+++ b/chrome/common/chrome_content_client.cc
@@ -402,15 +402,6 @@ bool ChromeContentClient::SandboxPlugin(CommandLine* command_line,
return false;
}
- // Add policy for the plugin proxy window pump event
- // used by WebPluginDelegateProxy::HandleInputEvent().
- if (policy->AddRule(sandbox::TargetPolicy::SUBSYS_HANDLES,
- sandbox::TargetPolicy::HANDLES_DUP_ANY,
- L"Event") != sandbox::SBOX_ALL_OK) {
- NOTREACHED();
- return false;
- }
-
// Add the policy for the pipes.
if (policy->AddRule(sandbox::TargetPolicy::SUBSYS_NAMED_PIPES,
sandbox::TargetPolicy::NAMEDPIPES_ALLOW_ANY,
diff --git a/content/browser/gpu/browser_gpu_channel_host_factory.cc b/content/browser/gpu/browser_gpu_channel_host_factory.cc
index 35a5172..81b0a74 100644
--- a/content/browser/gpu/browser_gpu_channel_host_factory.cc
+++ b/content/browser/gpu/browser_gpu_channel_host_factory.cc
@@ -153,8 +153,10 @@ void BrowserGpuChannelHostFactory::EstablishGpuChannelOnIO(
void BrowserGpuChannelHostFactory::GpuChannelEstablishedOnIO(
EstablishRequest* request,
const IPC::ChannelHandle& channel_handle,
+ base::ProcessHandle gpu_process_handle,
const GPUInfo& gpu_info) {
request->channel_handle = channel_handle;
+ request->gpu_process_handle = gpu_process_handle;
request->gpu_info = gpu_info;
request->event.Signal();
}
@@ -189,12 +191,26 @@ GpuChannelHost* BrowserGpuChannelHostFactory::EstablishGpuChannelSync(
request.gpu_process_handle == base::kNullProcessHandle)
return NULL;
+ base::ProcessHandle browser_process_for_gpu;
+#if defined(OS_WIN)
+ // Create a process handle that the GPU process can use to access our handles.
+ DuplicateHandle(base::GetCurrentProcessHandle(),
+ base::GetCurrentProcessHandle(),
+ request.gpu_process_handle,
+ &browser_process_for_gpu,
+ PROCESS_DUP_HANDLE,
+ FALSE,
+ 0);
+#else
+ browser_process_for_gpu = base::GetCurrentProcessHandle();
+#endif
+
gpu_channel_ = new GpuChannelHost(this, gpu_host_id_, gpu_client_id_);
gpu_channel_->set_gpu_info(request.gpu_info);
content::GetContentClient()->SetGpuInfo(request.gpu_info);
// Connect to the GPU process if a channel name was received.
- gpu_channel_->Connect(request.channel_handle);
+ gpu_channel_->Connect(request.channel_handle, browser_process_for_gpu);
return gpu_channel_.get();
}
diff --git a/content/browser/gpu/browser_gpu_channel_host_factory.h b/content/browser/gpu/browser_gpu_channel_host_factory.h
index 2c58b99..cfb4e6a 100644
--- a/content/browser/gpu/browser_gpu_channel_host_factory.h
+++ b/content/browser/gpu/browser_gpu_channel_host_factory.h
@@ -65,6 +65,7 @@ class BrowserGpuChannelHostFactory : public GpuChannelHostFactory {
static void GpuChannelEstablishedOnIO(
EstablishRequest* request,
const IPC::ChannelHandle& channel_handle,
+ base::ProcessHandle gpu_process_handle,
const GPUInfo& gpu_info);
int gpu_client_id_;
diff --git a/content/browser/gpu/gpu_process_host.cc b/content/browser/gpu/gpu_process_host.cc
index 2546131..c4d4e4c 100644
--- a/content/browser/gpu/gpu_process_host.cc
+++ b/content/browser/gpu/gpu_process_host.cc
@@ -267,6 +267,7 @@ GpuProcessHost* GpuProcessHost::FromID(int host_id) {
GpuProcessHost::GpuProcessHost(int host_id, GpuProcessKind kind)
: host_id_(host_id),
+ gpu_process_(base::kNullProcessHandle),
in_process_(false),
software_rendering_(false),
kind_(kind),
@@ -337,6 +338,11 @@ GpuProcessHost::~GpuProcessHost() {
content::RESULT_CODE_LAST_CODE);
}
+#if defined(OS_WIN)
+ if (gpu_process_)
+ CloseHandle(gpu_process_);
+#endif
+
// In case we never started, clean up.
while (!queued_messages_.empty()) {
delete queued_messages_.front();
@@ -492,6 +498,10 @@ void GpuProcessHost::CreateViewCommandBuffer(
void GpuProcessHost::OnChannelEstablished(
const IPC::ChannelHandle& channel_handle) {
+ // The GPU process should have launched at this point and this object should
+ // have been notified of its process handle.
+ DCHECK(gpu_process_);
+
EstablishChannelCallback callback = channel_requests_.front();
channel_requests_.pop();
@@ -511,7 +521,7 @@ void GpuProcessHost::OnChannelEstablished(
return;
}
- callback.Run(channel_handle,
+ callback.Run(channel_handle, gpu_process_,
GpuDataManagerImpl::GetInstance()->GetGPUInfo());
}
@@ -613,6 +623,25 @@ void GpuProcessHost::OnAcceleratedSurfaceRelease(
#endif // OS_WIN && !USE_AURA
void GpuProcessHost::OnProcessLaunched() {
+ // Send the GPU process handle to the UI thread before it has to
+ // respond to any requests to establish a GPU channel. The response
+ // to such requests require that the GPU process handle be known.
+
+ base::ProcessHandle child_handle = in_process_ ?
+ base::GetCurrentProcessHandle() : process_->GetData().handle;
+
+#if defined(OS_WIN)
+ DuplicateHandle(base::GetCurrentProcessHandle(),
+ child_handle,
+ base::GetCurrentProcessHandle(),
+ &gpu_process_,
+ PROCESS_DUP_HANDLE,
+ FALSE,
+ 0);
+#else
+ gpu_process_ = child_handle;
+#endif
+
UMA_HISTOGRAM_TIMES("GPU.GPUProcessLaunchTime",
base::TimeTicks::Now() - init_start_time_);
}
@@ -745,7 +774,7 @@ void GpuProcessHost::EstablishChannelError(
const IPC::ChannelHandle& channel_handle,
base::ProcessHandle renderer_process_for_gpu,
const content::GPUInfo& gpu_info) {
- callback.Run(channel_handle, gpu_info);
+ callback.Run(channel_handle, renderer_process_for_gpu, gpu_info);
}
void GpuProcessHost::CreateCommandBufferError(
diff --git a/content/browser/gpu/gpu_process_host.h b/content/browser/gpu/gpu_process_host.h
index f101c6c..ae8d98b 100644
--- a/content/browser/gpu/gpu_process_host.h
+++ b/content/browser/gpu/gpu_process_host.h
@@ -41,6 +41,7 @@ class GpuProcessHost : public content::BrowserChildProcessHostDelegate,
};
typedef base::Callback<void(const IPC::ChannelHandle&,
+ base::ProcessHandle,
const content::GPUInfo&)>
EstablishChannelCallback;
@@ -164,6 +165,9 @@ class GpuProcessHost : public content::BrowserChildProcessHostDelegate,
// Qeueud messages to send when the process launches.
std::queue<IPC::Message*> queued_messages_;
+ // The handle for the GPU process or null if it is not known to be launched.
+ base::ProcessHandle gpu_process_;
+
// Whether we are running a GPU thread inside the browser process instead
// of a separate GPU process.
bool in_process_;
diff --git a/content/browser/renderer_host/gpu_message_filter.cc b/content/browser/renderer_host/gpu_message_filter.cc
index 75ad4fa..d563a91 100644
--- a/content/browser/renderer_host/gpu_message_filter.cc
+++ b/content/browser/renderer_host/gpu_message_filter.cc
@@ -173,11 +173,31 @@ void GpuMessageFilter::OnCreateViewCommandBuffer(
void GpuMessageFilter::EstablishChannelCallback(
IPC::Message* reply,
const IPC::ChannelHandle& channel,
+ base::ProcessHandle gpu_process_for_browser,
const content::GPUInfo& gpu_info) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ base::ProcessHandle renderer_process_for_gpu;
+ if (gpu_process_for_browser != 0) {
+#if defined(OS_WIN)
+ // Create a process handle that the renderer process can give to the GPU
+ // process to give it access to its handles.
+ DuplicateHandle(base::GetCurrentProcessHandle(),
+ peer_handle(),
+ gpu_process_for_browser,
+ &renderer_process_for_gpu,
+ PROCESS_DUP_HANDLE,
+ FALSE,
+ 0);
+#else
+ renderer_process_for_gpu = peer_handle();
+#endif
+ } else {
+ renderer_process_for_gpu = 0;
+ }
+
GpuHostMsg_EstablishGpuChannel::WriteReplyParams(
- reply, render_process_id_, channel, gpu_info);
+ reply, render_process_id_, channel, renderer_process_for_gpu, gpu_info);
Send(reply);
}
diff --git a/content/browser/renderer_host/gpu_message_filter.h b/content/browser/renderer_host/gpu_message_filter.h
index e7a73f1..aafeeca 100644
--- a/content/browser/renderer_host/gpu_message_filter.h
+++ b/content/browser/renderer_host/gpu_message_filter.h
@@ -58,6 +58,7 @@ class GpuMessageFilter : public content::BrowserMessageFilter,
// Helper callbacks for the message handlers.
void EstablishChannelCallback(IPC::Message* reply,
const IPC::ChannelHandle& channel,
+ base::ProcessHandle gpu_process_for_browser,
const content::GPUInfo& gpu_info);
void CreateCommandBufferCallback(IPC::Message* reply, int32 route_id);
diff --git a/content/common/gpu/client/command_buffer_proxy_impl.cc b/content/common/gpu/client/command_buffer_proxy_impl.cc
index 1bb1887..1a23eac 100644
--- a/content/common/gpu/client/command_buffer_proxy_impl.cc
+++ b/content/common/gpu/client/command_buffer_proxy_impl.cc
@@ -20,10 +20,6 @@
#include "gpu/command_buffer/common/command_buffer_shared.h"
#include "ui/gfx/size.h"
-#if defined(OS_WIN)
-#include "content/common/sandbox_policy.h"
-#endif
-
using gpu::Buffer;
CommandBufferProxyImpl::CommandBufferProxyImpl(
@@ -238,13 +234,7 @@ int32 CommandBufferProxyImpl::CreateTransferBuffer(
return -1;
base::SharedMemoryHandle handle = shm->handle();
-#if defined(OS_WIN)
- // Windows needs to explicitly duplicate the handle out to another process.
- if (!sandbox::BrokerDuplicateHandle(handle, channel_->gpu_pid(),
- &handle, FILE_MAP_WRITE, 0)) {
- return -1;
- }
-#elif defined(OS_POSIX)
+#if defined(OS_POSIX)
DCHECK(!handle.auto_close);
#endif
@@ -267,20 +257,10 @@ int32 CommandBufferProxyImpl::RegisterTransferBuffer(
if (last_state_.error != gpu::error::kNoError)
return -1;
- // Returns FileDescriptor with auto_close off.
- base::SharedMemoryHandle handle = shared_memory->handle();
-#if defined(OS_WIN)
- // Windows needs to explicitly duplicate the handle out to another process.
- if (!sandbox::BrokerDuplicateHandle(handle, channel_->gpu_pid(),
- &handle, FILE_MAP_WRITE, 0)) {
- return -1;
- }
-#endif
-
int32 id;
if (!Send(new GpuCommandBufferMsg_RegisterTransferBuffer(
route_id_,
- handle,
+ shared_memory->handle(), // Returns FileDescriptor with auto_close off.
size,
id_request,
&id))) {
diff --git a/content/common/gpu/client/gpu_channel_host.cc b/content/common/gpu/client/gpu_channel_host.cc
index cda0468..988feae 100644
--- a/content/common/gpu/client/gpu_channel_host.cc
+++ b/content/common/gpu/client/gpu_channel_host.cc
@@ -93,10 +93,10 @@ void GpuChannelHost::MessageFilter::OnChannelError() {
}
GpuChannelHost::GpuChannelHost(
- GpuChannelHostFactory* factory, int gpu_host_id, int client_id)
+ GpuChannelHostFactory* factory, int gpu_process_id, int client_id)
: factory_(factory),
+ gpu_process_id_(gpu_process_id),
client_id_(client_id),
- gpu_host_id_(gpu_host_id),
state_(kUnconnected) {
}
@@ -104,7 +104,8 @@ GpuChannelHost::~GpuChannelHost() {
}
void GpuChannelHost::Connect(
- const IPC::ChannelHandle& channel_handle) {
+ const IPC::ChannelHandle& channel_handle,
+ base::ProcessHandle client_process_for_gpu) {
DCHECK(factory_->IsMainThread());
// Open a channel to the GPU process. We pass NULL as the main listener here
// since we need to filter everything to route it to the right thread.
@@ -129,6 +130,10 @@ void GpuChannelHost::Connect(
// and receives the hello message from the GPU process. The messages get
// cached.
state_ = kConnected;
+
+ // Notify the GPU process of our process handle. This gives it the ability
+ // to map client handles into the GPU process.
+ Send(new GpuChannelMsg_Initialize(client_process_for_gpu));
}
void GpuChannelHost::set_gpu_info(const content::GPUInfo& gpu_info) {
diff --git a/content/common/gpu/client/gpu_channel_host.h b/content/common/gpu/client/gpu_channel_host.h
index b82efe9..0a88845 100644
--- a/content/common/gpu/client/gpu_channel_host.h
+++ b/content/common/gpu/client/gpu_channel_host.h
@@ -13,7 +13,6 @@
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
-#include "base/process.h"
#include "base/process_util.h"
#include "base/synchronization/lock.h"
#include "content/common/content_export.h"
@@ -84,12 +83,13 @@ class GpuChannelHost : public IPC::Message::Sender,
// Called on the render thread
GpuChannelHost(GpuChannelHostFactory* factory,
- int gpu_host_id,
+ int gpu_process_id,
int client_id);
virtual ~GpuChannelHost();
// Connect to GPU process channel.
- void Connect(const IPC::ChannelHandle& channel_handle);
+ void Connect(const IPC::ChannelHandle& channel_handle,
+ base::ProcessHandle client_process_for_gpu);
State state() const { return state_; }
@@ -152,8 +152,7 @@ class GpuChannelHost : public IPC::Message::Sender,
void ForciblyCloseChannel();
GpuChannelHostFactory* factory() const { return factory_; }
- int gpu_host_id() const { return gpu_host_id_; }
- base::ProcessId gpu_pid() const { return channel_->peer_pid(); }
+ int gpu_process_id() const { return gpu_process_id_; }
int client_id() const { return client_id_; }
private:
@@ -181,8 +180,8 @@ class GpuChannelHost : public IPC::Message::Sender,
};
GpuChannelHostFactory* factory_;
+ int gpu_process_id_;
int client_id_;
- int gpu_host_id_;
State state_;
diff --git a/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.cc b/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.cc
index aa9c645..32e4c2d 100644
--- a/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.cc
+++ b/content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.cc
@@ -484,7 +484,7 @@ void WebGraphicsContext3DCommandBufferImpl::Destroy() {
}
int WebGraphicsContext3DCommandBufferImpl::GetGPUProcessID() {
- return host_ ? host_->gpu_host_id() : 0;
+ return host_ ? host_->gpu_process_id() : 0;
}
int WebGraphicsContext3DCommandBufferImpl::GetChannelID() {
diff --git a/content/common/gpu/gpu_channel.cc b/content/common/gpu/gpu_channel.cc
index 96c3553..5568b17 100644
--- a/content/common/gpu/gpu_channel.cc
+++ b/content/common/gpu/gpu_channel.cc
@@ -40,6 +40,8 @@ GpuChannel::GpuChannel(GpuChannelManager* gpu_channel_manager,
bool software)
: gpu_channel_manager_(gpu_channel_manager),
client_id_(client_id),
+ renderer_process_(base::kNullProcessHandle),
+ renderer_pid_(base::kNullProcessId),
share_group_(share_group ? share_group : new gfx::GLShareGroup),
watchdog_(watchdog),
software_(software),
@@ -60,6 +62,10 @@ GpuChannel::GpuChannel(GpuChannelManager* gpu_channel_manager,
}
GpuChannel::~GpuChannel() {
+#if defined(OS_WIN)
+ if (renderer_process_)
+ CloseHandle(renderer_process_);
+#endif
}
bool GpuChannel::OnMessageReceived(const IPC::Message& message) {
@@ -107,6 +113,10 @@ void GpuChannel::OnChannelError() {
gpu_channel_manager_->RemoveChannel(client_id_);
}
+void GpuChannel::OnChannelConnected(int32 peer_pid) {
+ renderer_pid_ = peer_pid;
+}
+
bool GpuChannel::Send(IPC::Message* message) {
// The GPU process must never send a synchronous IPC message to the renderer
// process. This could result in deadlock.
@@ -201,6 +211,7 @@ bool GpuChannel::OnControlMessageReceived(const IPC::Message& msg) {
// here. This is so the reply can be delayed if the scheduler is unscheduled.
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(GpuChannel, msg)
+ IPC_MESSAGE_HANDLER(GpuChannelMsg_Initialize, OnInitialize)
IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuChannelMsg_CreateOffscreenCommandBuffer,
OnCreateOffscreenCommandBuffer)
IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuChannelMsg_DestroyCommandBuffer,
@@ -301,6 +312,15 @@ bool GpuChannel::ShouldPreferDiscreteGpu() const {
return num_contexts_preferring_discrete_gpu_ > 0;
}
+void GpuChannel::OnInitialize(base::ProcessHandle renderer_process) {
+ // Initialize should only happen once.
+ DCHECK(!renderer_process_);
+
+ // Verify that the renderer has passed its own process handle.
+ if (base::GetProcId(renderer_process) == renderer_pid_)
+ renderer_process_ = renderer_process;
+}
+
void GpuChannel::OnCreateOffscreenCommandBuffer(
const gfx::Size& size,
const GPUCreateCommandBufferConfig& init_params,
diff --git a/content/common/gpu/gpu_channel.h b/content/common/gpu/gpu_channel.h
index d9c5192..a92ed87 100644
--- a/content/common/gpu/gpu_channel.h
+++ b/content/common/gpu/gpu_channel.h
@@ -62,11 +62,14 @@ class GpuChannel : public IPC::Channel::Listener,
int TakeRendererFileDescriptor();
#endif // defined(OS_POSIX)
- base::ProcessId renderer_pid() const { return channel_->peer_pid(); }
+ base::ProcessHandle renderer_process() const {
+ return renderer_process_;
+ }
// IPC::Channel::Listener implementation:
virtual bool OnMessageReceived(const IPC::Message& msg) OVERRIDE;
virtual void OnChannelError() OVERRIDE;
+ virtual void OnChannelConnected(int32 peer_pid) OVERRIDE;
// IPC::Message::Sender implementation:
virtual bool Send(IPC::Message* msg) OVERRIDE;
@@ -116,6 +119,7 @@ class GpuChannel : public IPC::Channel::Listener,
void ScheduleDelayedWork(GpuCommandBufferStub *stub, int64 delay);
// Message handlers.
+ void OnInitialize(base::ProcessHandle renderer_process);
void OnCreateOffscreenCommandBuffer(
const gfx::Size& size,
const GPUCreateCommandBufferConfig& init_params,
@@ -145,6 +149,12 @@ class GpuChannel : public IPC::Channel::Listener,
// Uniquely identifies the channel within this GPU process.
std::string channel_id_;
+ // Handle to the renderer process that is on the other side of the channel.
+ base::ProcessHandle renderer_process_;
+
+ // The process id of the renderer process.
+ base::ProcessId renderer_pid_;
+
// Used to implement message routing functionality to CommandBuffer objects
MessageRouter router_;
diff --git a/content/common/gpu/gpu_command_buffer_stub.cc b/content/common/gpu/gpu_command_buffer_stub.cc
index 1f22bce..047fb95 100644
--- a/content/common/gpu/gpu_command_buffer_stub.cc
+++ b/content/common/gpu/gpu_command_buffer_stub.cc
@@ -23,10 +23,6 @@
#include "ui/gfx/gl/gl_bindings.h"
#include "ui/gfx/gl/gl_switches.h"
-#if defined(OS_WIN)
-#include "content/common/sandbox_policy.h"
-#endif
-
GpuCommandBufferStub::SurfaceState::SurfaceState(int32 surface_id,
bool visible,
base::TimeTicks last_used_time)
@@ -471,7 +467,17 @@ void GpuCommandBufferStub::OnRegisterTransferBuffer(
size_t size,
int32 id_request,
IPC::Message* reply_message) {
+#if defined(OS_WIN)
+ // Windows dups the shared memory handle it receives into the current process
+ // and closes it when this variable goes out of scope.
+ base::SharedMemory shared_memory(transfer_buffer,
+ false,
+ channel_->renderer_process());
+#else
+ // POSIX receives a dup of the shared memory handle and closes the dup when
+ // this variable goes out of scope.
base::SharedMemory shared_memory(transfer_buffer, false);
+#endif
if (command_buffer_.get()) {
int32 id = command_buffer_->RegisterTransferBuffer(&shared_memory,
@@ -500,22 +506,20 @@ void GpuCommandBufferStub::OnDestroyTransferBuffer(
void GpuCommandBufferStub::OnGetTransferBuffer(
int32 id,
IPC::Message* reply_message) {
+ // Fail if the renderer process has not provided its process handle.
+ if (!channel_->renderer_process())
+ return;
+
if (command_buffer_.get()) {
base::SharedMemoryHandle transfer_buffer = base::SharedMemoryHandle();
uint32 size = 0;
gpu::Buffer buffer = command_buffer_->GetTransferBuffer(id);
if (buffer.shared_memory) {
-#if defined(OS_WIN)
- transfer_buffer = NULL;
- sandbox::BrokerDuplicateHandle(buffer.shared_memory->handle(),
- channel_->renderer_pid(), &transfer_buffer, FILE_MAP_READ |
- FILE_MAP_WRITE, 0);
- CHECK(transfer_buffer != NULL);
-#else
- buffer.shared_memory->ShareToProcess(channel_->renderer_pid(),
+ // Assume service is responsible for duplicating the handle to the calling
+ // process.
+ buffer.shared_memory->ShareToProcess(channel_->renderer_process(),
&transfer_buffer);
-#endif
size = buffer.size;
}
@@ -553,7 +557,8 @@ void GpuCommandBufferStub::OnCreateVideoDecoder(
new GpuVideoDecodeAccelerator(this, decoder_route_id, this);
video_decoders_.AddWithID(decoder, decoder_route_id);
channel_->AddRoute(decoder_route_id, decoder);
- decoder->Initialize(profile, reply_message);
+ decoder->Initialize(profile, reply_message,
+ channel_->renderer_process());
}
void GpuCommandBufferStub::OnDestroyVideoDecoder(int decoder_route_id) {
diff --git a/content/common/gpu/gpu_messages.h b/content/common/gpu/gpu_messages.h
index d76491a..bd6ce94 100644
--- a/content/common/gpu/gpu_messages.h
+++ b/content/common/gpu/gpu_messages.h
@@ -216,10 +216,11 @@ IPC_MESSAGE_CONTROL0(GpuMsg_Hang)
// A renderer sends this when it wants to create a connection to the GPU
// process. The browser will create the GPU process if necessary, and will
// return a handle to the channel via a GpuChannelEstablished message.
-IPC_SYNC_MESSAGE_CONTROL1_3(GpuHostMsg_EstablishGpuChannel,
+IPC_SYNC_MESSAGE_CONTROL1_4(GpuHostMsg_EstablishGpuChannel,
content::CauseForGpuLaunch,
int /* client id */,
IPC::ChannelHandle /* handle to channel */,
+ base::ProcessHandle /* renderer_process_for_gpu */,
content::GPUInfo /* stats about GPU process*/)
// A renderer sends this to the browser process when it wants to
@@ -291,6 +292,13 @@ IPC_MESSAGE_CONTROL1(GpuHostMsg_AcceleratedSurfaceSuspend,
// GPU Channel Messages
// These are messages from a renderer process to the GPU process.
+// Initialize a channel between a renderer process and a GPU process. The
+// renderer passes its process handle to the GPU process, which gives gives the
+// GPU process the ability to map handles from the renderer process. This must
+// be the first message sent on a newly connected channel.
+IPC_MESSAGE_CONTROL1(GpuChannelMsg_Initialize,
+ base::ProcessHandle /* renderer_process_for_gpu */)
+
// Tells the GPU process to create a new command buffer that renders to an
// offscreen frame buffer.
IPC_SYNC_MESSAGE_CONTROL2_1(GpuChannelMsg_CreateOffscreenCommandBuffer,
diff --git a/content/common/gpu/media/dxva_video_decode_accelerator.cc b/content/common/gpu/media/dxva_video_decode_accelerator.cc
index 05afbad..10f5237 100644
--- a/content/common/gpu/media/dxva_video_decode_accelerator.cc
+++ b/content/common/gpu/media/dxva_video_decode_accelerator.cc
@@ -142,9 +142,20 @@ static IMFSample* CreateInputSample(const uint8* stream, int size,
static IMFSample* CreateSampleFromInputBuffer(
const media::BitstreamBuffer& bitstream_buffer,
+ base::ProcessHandle renderer_process,
DWORD stream_size,
DWORD alignment) {
- base::SharedMemory shm(bitstream_buffer.handle(), true);
+ HANDLE shared_memory_handle = NULL;
+ RETURN_ON_FAILURE(::DuplicateHandle(renderer_process,
+ bitstream_buffer.handle(),
+ base::GetCurrentProcessHandle(),
+ &shared_memory_handle,
+ 0,
+ FALSE,
+ DUPLICATE_SAME_ACCESS),
+ "Duplicate handle failed", NULL);
+
+ base::SharedMemory shm(shared_memory_handle, true);
RETURN_ON_FAILURE(shm.Map(bitstream_buffer.size()),
"Failed in base::SharedMemory::Map", NULL);
@@ -494,11 +505,13 @@ bool DXVAVideoDecodeAccelerator::CreateD3DDevManager() {
}
DXVAVideoDecodeAccelerator::DXVAVideoDecodeAccelerator(
- media::VideoDecodeAccelerator::Client* client)
+ media::VideoDecodeAccelerator::Client* client,
+ base::ProcessHandle renderer_process)
: client_(client),
egl_config_(NULL),
state_(kUninitialized),
pictures_requested_(false),
+ renderer_process_(renderer_process),
last_input_buffer_id_(-1),
inputs_before_decode_(0) {
memset(&input_stream_info_, 0, sizeof(input_stream_info_));
@@ -547,6 +560,7 @@ void DXVAVideoDecodeAccelerator::Decode(
base::win::ScopedComPtr<IMFSample> sample;
sample.Attach(CreateSampleFromInputBuffer(bitstream_buffer,
+ renderer_process_,
input_stream_info_.cbSize,
input_stream_info_.cbAlignment));
RETURN_AND_NOTIFY_ON_FAILURE(sample, "Failed to create input sample",
diff --git a/content/common/gpu/media/dxva_video_decode_accelerator.h b/content/common/gpu/media/dxva_video_decode_accelerator.h
index 876ea4b..9c7469e 100644
--- a/content/common/gpu/media/dxva_video_decode_accelerator.h
+++ b/content/common/gpu/media/dxva_video_decode_accelerator.h
@@ -39,8 +39,9 @@ class CONTENT_EXPORT DXVAVideoDecodeAccelerator
};
// Does not take ownership of |client| which must outlive |*this|.
- explicit DXVAVideoDecodeAccelerator(
- media::VideoDecodeAccelerator::Client* client);
+ DXVAVideoDecodeAccelerator(
+ media::VideoDecodeAccelerator::Client* client,
+ base::ProcessHandle renderer_process);
virtual ~DXVAVideoDecodeAccelerator();
// media::VideoDecodeAccelerator implementation.
@@ -186,6 +187,9 @@ class CONTENT_EXPORT DXVAVideoDecodeAccelerator
// Contains the id of the last input buffer received from the client.
int32 last_input_buffer_id_;
+ // Handle to the renderer process.
+ base::ProcessHandle renderer_process_;
+
// Ideally the reset token would be a stack variable which is used while
// creating the device manager. However it seems that the device manager
// holds onto the token and attempts to access it if the underlying device
diff --git a/content/common/gpu/media/gpu_video_decode_accelerator.cc b/content/common/gpu/media/gpu_video_decode_accelerator.cc
index 0ef9d87..224ba3a 100644
--- a/content/common/gpu/media/gpu_video_decode_accelerator.cc
+++ b/content/common/gpu/media/gpu_video_decode_accelerator.cc
@@ -116,7 +116,8 @@ void GpuVideoDecodeAccelerator::NotifyError(
void GpuVideoDecodeAccelerator::Initialize(
const media::VideoCodecProfile profile,
- IPC::Message* init_done_msg) {
+ IPC::Message* init_done_msg,
+ base::ProcessHandle renderer_process) {
DCHECK(!video_decode_accelerator_.get());
DCHECK(!init_done_msg_);
DCHECK(init_done_msg);
@@ -132,7 +133,7 @@ void GpuVideoDecodeAccelerator::Initialize(
}
DLOG(INFO) << "Initializing DXVA HW decoder for windows.";
DXVAVideoDecodeAccelerator* video_decoder =
- new DXVAVideoDecodeAccelerator(this);
+ new DXVAVideoDecodeAccelerator(this, renderer_process);
#else // OS_WIN
OmxVideoDecodeAccelerator* video_decoder =
new OmxVideoDecodeAccelerator(this);
diff --git a/content/common/gpu/media/gpu_video_decode_accelerator.h b/content/common/gpu/media/gpu_video_decode_accelerator.h
index 2d2e559..430dda8 100644
--- a/content/common/gpu/media/gpu_video_decode_accelerator.h
+++ b/content/common/gpu/media/gpu_video_decode_accelerator.h
@@ -47,7 +47,8 @@ class GpuVideoDecodeAccelerator
// The renderer process handle is valid as long as we have a channel between
// GPU process and the renderer.
void Initialize(const media::VideoCodecProfile profile,
- IPC::Message* init_done_msg);
+ IPC::Message* init_done_msg,
+ base::ProcessHandle renderer_process);
private:
diff --git a/content/common/gpu/media/video_decode_accelerator_unittest.cc b/content/common/gpu/media/video_decode_accelerator_unittest.cc
index 9dc6325..da73e34 100644
--- a/content/common/gpu/media/video_decode_accelerator_unittest.cc
+++ b/content/common/gpu/media/video_decode_accelerator_unittest.cc
@@ -655,7 +655,7 @@ void EglRenderingVDAClient::CreateDecoder() {
CHECK(decoder_deleted());
#if defined(OS_WIN)
scoped_refptr<DXVAVideoDecodeAccelerator> decoder =
- new DXVAVideoDecodeAccelerator(this);
+ new DXVAVideoDecodeAccelerator(this, base::GetCurrentProcessHandle());
#else // OS_WIN
scoped_refptr<OmxVideoDecodeAccelerator> decoder =
new OmxVideoDecodeAccelerator(this);
diff --git a/content/common/np_channel_base.h b/content/common/np_channel_base.h
index 8bacac3..c931949 100644
--- a/content/common/np_channel_base.h
+++ b/content/common/np_channel_base.h
@@ -12,7 +12,6 @@
#include "base/hash_tables.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
-#include "base/process.h"
#include "content/common/message_router.h"
#include "content/common/npobject_base.h"
#include "ipc/ipc_channel_handle.h"
@@ -76,7 +75,7 @@ class NPChannelBase : public IPC::Channel::Listener,
// IPC::Message::Sender implementation:
virtual bool Send(IPC::Message* msg) OVERRIDE;
- base::ProcessId peer_pid() { return channel_->peer_pid(); }
+ int peer_pid() { return peer_pid_; }
IPC::ChannelHandle channel_handle() const { return channel_handle_; }
// Returns the number of open NPObject channels in this process.
diff --git a/content/common/sandbox_policy.cc b/content/common/sandbox_policy.cc
index dc07070..11e8602 100644
--- a/content/common/sandbox_policy.cc
+++ b/content/common/sandbox_policy.cc
@@ -374,33 +374,21 @@ bool AddPolicyForGPU(CommandLine* cmd_line, sandbox::TargetPolicy* policy) {
if (result != sandbox::SBOX_ALL_OK)
return false;
- // GPU needs to copy sections to renderers.
- result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_HANDLES,
- sandbox::TargetPolicy::HANDLES_DUP_ANY,
- L"Section");
- if (result != sandbox::SBOX_ALL_OK)
- return false;
-
AddGenericDllEvictionPolicy(policy);
#endif
return true;
}
bool AddPolicyForRenderer(sandbox::TargetPolicy* policy) {
- // Renderers need to copy sections for plugin DIBs and GPU.
+ // Renderers need to copy sections for plugin DIBs.
sandbox::ResultCode result;
result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_HANDLES,
sandbox::TargetPolicy::HANDLES_DUP_ANY,
L"Section");
- if (result != sandbox::SBOX_ALL_OK)
- return false;
-
- // Renderers need to share events with plugins.
- result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_HANDLES,
- sandbox::TargetPolicy::HANDLES_DUP_ANY,
- L"Event");
- if (result != sandbox::SBOX_ALL_OK)
+ if (result != sandbox::SBOX_ALL_OK) {
+ NOTREACHED();
return false;
+ }
policy->SetJobLevel(sandbox::JOB_LOCKDOWN, 0);
@@ -463,33 +451,30 @@ bool BrokerDuplicateHandle(HANDLE source_handle,
HANDLE* target_handle,
DWORD desired_access,
DWORD options) {
- // If our process is the target just duplicate the handle.
- if (::GetCurrentProcessId() == target_process_id) {
- return !!::DuplicateHandle(::GetCurrentProcess(), source_handle,
- ::GetCurrentProcess(), target_handle,
- desired_access, FALSE, options);
-
- }
+ // Just use DuplicateHandle() if we aren't in the sandbox.
+ if (!g_target_services) {
+ base::win::ScopedHandle target_process(::OpenProcess(PROCESS_DUP_HANDLE,
+ FALSE,
+ target_process_id));
+ if (!target_process.IsValid())
+ return false;
+
+ if (!::DuplicateHandle(::GetCurrentProcess(), source_handle,
+ target_process, target_handle,
+ desired_access, FALSE,
+ options)) {
+ return false;
+ }
- // Try the broker next
- if (g_target_services &&
- g_target_services->DuplicateHandle(source_handle, target_process_id,
- target_handle, desired_access,
- options) == SBOX_ALL_OK) {
return true;
}
- // Finally, see if we already have access to the process.
- base::win::ScopedHandle target_process;
- target_process.Set(::OpenProcess(PROCESS_DUP_HANDLE, FALSE,
- target_process_id));
- if (target_process.IsValid()) {
- return !!::DuplicateHandle(::GetCurrentProcess(), source_handle,
- target_process, target_handle,
- desired_access, FALSE, options);
- }
-
- return false;
+ ResultCode result = g_target_services->DuplicateHandle(source_handle,
+ target_process_id,
+ target_handle,
+ desired_access,
+ options);
+ return SBOX_ALL_OK == result;
}
@@ -588,7 +573,6 @@ base::ProcessHandle StartProcessWithAccess(CommandLine* cmd_line,
policy->Release();
base::ProcessHandle process = 0;
base::LaunchProcess(*cmd_line, base::LaunchOptions(), &process);
- g_broker_services->AddTargetPeer(process);
return process;
}
diff --git a/content/plugin/plugin_channel.cc b/content/plugin/plugin_channel.cc
index 3f544da..dd60b67 100644
--- a/content/plugin/plugin_channel.cc
+++ b/content/plugin/plugin_channel.cc
@@ -161,7 +161,8 @@ void PluginChannel::NotifyRenderersOfPendingShutdown() {
}
PluginChannel::PluginChannel()
- : renderer_id_(-1),
+ : renderer_handle_(0),
+ renderer_id_(-1),
in_send_(0),
incognito_(false),
filter_(new MessageFilter()) {
@@ -172,6 +173,9 @@ PluginChannel::PluginChannel()
}
PluginChannel::~PluginChannel() {
+ if (renderer_handle_)
+ base::CloseProcessHandle(renderer_handle_);
+
MessageLoop::current()->PostDelayedTask(
FROM_HERE,
base::Bind(&PluginReleaseCallback),
@@ -281,7 +285,18 @@ base::WaitableEvent* PluginChannel::GetModalDialogEvent(
return filter_->GetModalDialogEvent(containing_window);
}
+void PluginChannel::OnChannelConnected(int32 peer_pid) {
+ base::ProcessHandle handle;
+ if (!base::OpenProcessHandle(peer_pid, &handle)) {
+ NOTREACHED();
+ }
+ renderer_handle_ = handle;
+ NPChannelBase::OnChannelConnected(peer_pid);
+}
+
void PluginChannel::OnChannelError() {
+ base::CloseProcessHandle(renderer_handle_);
+ renderer_handle_ = 0;
NPChannelBase::OnChannelError();
CleanUp();
}
diff --git a/content/plugin/plugin_channel.h b/content/plugin/plugin_channel.h
index 7be4d91..b83b133 100644
--- a/content/plugin/plugin_channel.h
+++ b/content/plugin/plugin_channel.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -36,6 +36,7 @@ class PluginChannel : public NPChannelBase {
virtual bool Send(IPC::Message* msg) OVERRIDE;
virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
+ base::ProcessHandle renderer_handle() const { return renderer_handle_; }
int renderer_id() { return renderer_id_; }
virtual int GenerateRouteID() OVERRIDE;
@@ -58,6 +59,7 @@ class PluginChannel : public NPChannelBase {
protected:
// IPC::Channel::Listener implementation:
+ virtual void OnChannelConnected(int32 peer_pid) OVERRIDE;
virtual void OnChannelError() OVERRIDE;
virtual void CleanUp() OVERRIDE;
@@ -86,6 +88,9 @@ class PluginChannel : public NPChannelBase {
std::vector<scoped_refptr<WebPluginDelegateStub> > plugin_stubs_;
+ // Handle to the renderer process who is on the other side of the channel.
+ base::ProcessHandle renderer_handle_;
+
// The id of the renderer who is on the other side of the channel.
int renderer_id_;
diff --git a/content/plugin/webplugin_proxy.cc b/content/plugin/webplugin_proxy.cc
index 704058d..919f847 100644
--- a/content/plugin/webplugin_proxy.cc
+++ b/content/plugin/webplugin_proxy.cc
@@ -35,10 +35,6 @@
#include "ui/base/x/x11_util_internal.h"
#endif
-#if defined(OS_WIN)
-#include "content/common/sandbox_policy.h"
-#endif
-
using WebKit::WebBindings;
using webkit::npapi::WebPluginResourceClient;
@@ -133,9 +129,10 @@ void WebPluginProxy::WillDestroyWindow(gfx::PluginWindowHandle window) {
#if defined(OS_WIN)
void WebPluginProxy::SetWindowlessPumpEvent(HANDLE pump_messages_event) {
HANDLE pump_messages_event_for_renderer = NULL;
- sandbox::BrokerDuplicateHandle(pump_messages_event, channel_->peer_pid(),
- &pump_messages_event_for_renderer,
- SYNCHRONIZE | EVENT_MODIFY_STATE, 0);
+ DuplicateHandle(GetCurrentProcess(), pump_messages_event,
+ channel_->renderer_handle(),
+ &pump_messages_event_for_renderer,
+ 0, FALSE, DUPLICATE_SAME_ACCESS);
DCHECK(pump_messages_event_for_renderer != NULL);
Send(new PluginHostMsg_SetWindowlessPumpEvent(
route_id_, pump_messages_event_for_renderer));
@@ -473,17 +470,25 @@ void WebPluginProxy::CreateCanvasFromHandle(
const TransportDIB::Handle& dib_handle,
const gfx::Rect& window_rect,
scoped_ptr<skia::PlatformCanvas>* canvas_out) {
+ // Create a canvas that will reference the shared bits. We have to handle
+ // errors here since we're mapping a large amount of memory that may not fit
+ // in our address space, or go wrong in some other way.
+ HANDLE section;
+ DuplicateHandle(channel_->renderer_handle(), dib_handle, GetCurrentProcess(),
+ &section,
+ STANDARD_RIGHTS_REQUIRED | FILE_MAP_READ | FILE_MAP_WRITE,
+ FALSE, 0);
scoped_ptr<skia::PlatformCanvas> canvas(new skia::PlatformCanvas);
if (!canvas->initialize(
window_rect.width(),
window_rect.height(),
true,
- dib_handle)) {
+ section)) {
canvas_out->reset();
}
canvas_out->reset(canvas.release());
// The canvas does not own the section so we need to close it now.
- CloseHandle(dib_handle);
+ CloseHandle(section);
}
void WebPluginProxy::SetWindowlessBuffers(
diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc
index f565201..a047050 100644
--- a/content/renderer/render_thread_impl.cc
+++ b/content/renderer/render_thread_impl.cc
@@ -909,15 +909,18 @@ GpuChannelHost* RenderThreadImpl::EstablishGpuChannelSync(
// Ask the browser for the channel name.
int client_id = 0;
IPC::ChannelHandle channel_handle;
+ base::ProcessHandle renderer_process_for_gpu;
content::GPUInfo gpu_info;
if (!Send(new GpuHostMsg_EstablishGpuChannel(cause_for_gpu_launch,
&client_id,
&channel_handle,
+ &renderer_process_for_gpu,
&gpu_info)) ||
+ channel_handle.name.empty() ||
#if defined(OS_POSIX)
channel_handle.socket.fd == -1 ||
#endif
- channel_handle.name.empty()) {
+ renderer_process_for_gpu == base::kNullProcessHandle) {
// Otherwise cancel the connection.
gpu_channel_ = NULL;
return NULL;
@@ -928,7 +931,7 @@ GpuChannelHost* RenderThreadImpl::EstablishGpuChannelSync(
content::GetContentClient()->SetGpuInfo(gpu_info);
// Connect to the GPU process if a channel name was received.
- gpu_channel_->Connect(channel_handle);
+ gpu_channel_->Connect(channel_handle, renderer_process_for_gpu);
return GetGpuChannel();
}
diff --git a/content/renderer/webplugin_delegate_proxy.cc b/content/renderer/webplugin_delegate_proxy.cc
index b6ff543..5bc6084 100644
--- a/content/renderer/webplugin_delegate_proxy.cc
+++ b/content/renderer/webplugin_delegate_proxy.cc
@@ -18,7 +18,6 @@
#include "base/logging.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
-#include "base/process.h"
#include "base/string_split.h"
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
@@ -61,10 +60,6 @@
#include "base/mac/mac_util.h"
#endif
-#if defined(OS_WIN)
-#include "content/common/sandbox_policy.h"
-#endif
-
using WebKit::WebBindings;
using WebKit::WebCursorInfo;
using WebKit::WebDragData;
@@ -489,8 +484,7 @@ void WebPluginDelegateProxy::OnChannelError() {
static void CopyTransportDIBHandleForMessage(
const TransportDIB::Handle& handle_in,
- TransportDIB::Handle* handle_out,
- base::ProcessId peer_pid) {
+ TransportDIB::Handle* handle_out) {
#if defined(OS_MACOSX)
// On Mac, TransportDIB::Handle is typedef'ed to FileDescriptor, and
// FileDescriptor message fields needs to remain valid until the message is
@@ -500,12 +494,6 @@ static void CopyTransportDIBHandleForMessage(
return;
}
handle_out->auto_close = true;
-#elif defined(OS_WIN)
- // On Windows we need to duplicate the handle for the plugin process.
- *handle_out = NULL;
- sandbox::BrokerDuplicateHandle(handle_in, peer_pid, handle_out,
- FILE_MAP_READ | FILE_MAP_WRITE, 0);
- CHECK(*handle_out != NULL);
#else
// Don't need to do anything special for other platforms.
*handle_out = handle_in;
@@ -532,18 +520,15 @@ void WebPluginDelegateProxy::SendUpdateGeometry(
{
if (transport_stores_[0].dib.get())
CopyTransportDIBHandleForMessage(transport_stores_[0].dib->handle(),
- &param.windowless_buffer0,
- channel_host_->peer_pid());
+ &param.windowless_buffer0);
if (transport_stores_[1].dib.get())
CopyTransportDIBHandleForMessage(transport_stores_[1].dib->handle(),
- &param.windowless_buffer1,
- channel_host_->peer_pid());
+ &param.windowless_buffer1);
if (background_store_.dib.get())
CopyTransportDIBHandleForMessage(background_store_.dib->handle(),
- &param.background_buffer,
- channel_host_->peer_pid());
+ &param.background_buffer);
}
IPC::Message* msg;