linux (and some posix): multiprocess plugins compiling.
The goal of this change is to *not* make any behavioral change, but to instead just get all the plugin-related files linking on Linux with a bunch of NOTIMPLEMENTED()s in the appropriate places. It's enormous enough already without any refactorings or new features. Changes include: - Lots of gcc warning fixes. - Use portable replacements for Windows-specific functions (_strdup, etc.). - Use TransportDIB instead of just shared memory in the plugin messaging. Note that this is not fleshed out on Linux and on Windows it just hacks in the existing handles so there should be no functional change. - Fix --plugin-launcher to use cross-platform APIs. Review URL: http://codereview.chromium.org/79020 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@14338 0039d316-1c4b-4281-b951-d872f2087c98
Esse commit está contido em:
@@ -14,6 +14,12 @@
|
||||
|
||||
namespace base {
|
||||
|
||||
// Chromium code style is to not use malloc'd strings; this is only for use
|
||||
// for interaction with APIs that require it.
|
||||
inline char* strdup(const char* str) {
|
||||
return ::strdup(str);
|
||||
}
|
||||
|
||||
inline int strcasecmp(const char* string1, const char* string2) {
|
||||
return ::strcasecmp(string1, string2);
|
||||
}
|
||||
|
||||
@@ -14,6 +14,12 @@
|
||||
|
||||
namespace base {
|
||||
|
||||
// Chromium code style is to not use malloc'd strings; this is only for use
|
||||
// for interaction with APIs that require it.
|
||||
inline char* strdup(const char* str) {
|
||||
return _strdup(str);
|
||||
}
|
||||
|
||||
inline int strcasecmp(const char* s1, const char* s2) {
|
||||
return _stricmp(s1, s2);
|
||||
}
|
||||
|
||||
@@ -427,12 +427,16 @@ int ChromeMain(int argc, const char** argv) {
|
||||
if (process_type == switches::kRendererProcess) {
|
||||
rv = RendererMain(main_params);
|
||||
} else if (process_type == switches::kPluginProcess) {
|
||||
#if defined(OS_WIN)
|
||||
#if defined(OS_WIN) || defined(OS_LINUX)
|
||||
rv = PluginMain(main_params);
|
||||
#else
|
||||
NOTIMPLEMENTED();
|
||||
#endif
|
||||
} else if (process_type == switches::kWorkerProcess) {
|
||||
#if defined(OS_WIN)
|
||||
rv = WorkerMain(main_params);
|
||||
#else
|
||||
NOTIMPLEMENTED();
|
||||
#endif
|
||||
} else if (process_type.empty()) {
|
||||
#if defined(OS_LINUX)
|
||||
|
||||
@@ -390,8 +390,14 @@ bool PluginProcessHost::Init(const WebPluginInfo& info,
|
||||
#if defined(OS_WIN)
|
||||
process = sandbox::StartProcess(&cmd_line);
|
||||
#else
|
||||
// spawn child process
|
||||
base::LaunchApp(cmd_line, false, false, &process);
|
||||
// This code is duplicated with browser_render_process_host.cc, but
|
||||
// there's not a good place to de-duplicate it.
|
||||
base::file_handle_mapping_vector fds_to_map;
|
||||
int src_fd = -1, dest_fd = -1;
|
||||
channel().GetClientFileDescriptorMapping(&src_fd, &dest_fd);
|
||||
if (src_fd > -1)
|
||||
fds_to_map.push_back(std::pair<int, int>(src_fd, dest_fd));
|
||||
base::LaunchApp(cmd_line.argv(), fds_to_map, false, &process);
|
||||
#endif
|
||||
|
||||
if (!process)
|
||||
|
||||
@@ -326,6 +326,8 @@ bool BrowserRenderProcessHost::Init() {
|
||||
#if defined(OS_WIN)
|
||||
process = sandbox::StartProcess(&cmd_line);
|
||||
#else
|
||||
// NOTE: This code is duplicated with plugin_process_host.cc, but
|
||||
// there's not a good place to de-duplicate it.
|
||||
base::file_handle_mapping_vector fds_to_map;
|
||||
int src_fd = -1, dest_fd = -1;
|
||||
channel_->GetClientFileDescriptorMapping(&src_fd, &dest_fd);
|
||||
@@ -345,7 +347,7 @@ bool BrowserRenderProcessHost::Init() {
|
||||
WebCacheManager::GetInstance()->Add(pid());
|
||||
RendererSecurityPolicy::GetInstance()->Add(pid());
|
||||
|
||||
// Now that the process is created, set it's backgrounding accordingly.
|
||||
// Now that the process is created, set its backgrounding accordingly.
|
||||
SetBackgrounded(backgrounded_);
|
||||
|
||||
InitVisitedLinks();
|
||||
|
||||
+21
-6
@@ -1535,27 +1535,38 @@
|
||||
],
|
||||
},
|
||||
'conditions': [
|
||||
# Plugin code.
|
||||
['OS=="linux" or OS=="win"', {
|
||||
'dependencies': [
|
||||
'plugin',
|
||||
],
|
||||
}],
|
||||
# Linux-specific rules.
|
||||
['OS=="linux"', {
|
||||
'dependencies': [
|
||||
'../build/linux/system.gyp:gtk',
|
||||
],
|
||||
}],
|
||||
# Windows-specific rules.
|
||||
['OS=="win"', {
|
||||
'include_dirs': [
|
||||
'third_party/wtl/include',
|
||||
],
|
||||
'dependencies': [
|
||||
'plugin',
|
||||
],
|
||||
},],
|
||||
# As of yet unported-from-Windows code.
|
||||
['OS!="win"', {
|
||||
'sources!': [
|
||||
'renderer/plugin_channel_host.cc',
|
||||
'renderer/webplugin_delegate_proxy.cc',
|
||||
'renderer/webworker_proxy.cc',
|
||||
'renderer/webworker_proxy.h',
|
||||
],
|
||||
},],
|
||||
# As of yet unported-to-Mac code.
|
||||
['OS=="mac"', {
|
||||
'sources!': [
|
||||
'renderer/plugin_channel_host.cc',
|
||||
'renderer/webplugin_delegate_proxy.cc',
|
||||
]
|
||||
},],
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -2825,7 +2836,7 @@
|
||||
},
|
||||
],
|
||||
}], # OS=="win" or OS=="linux"
|
||||
['OS=="win"',
|
||||
['OS=="win" or OS=="linux"',
|
||||
{ 'targets': [
|
||||
{
|
||||
'target_name': 'plugin',
|
||||
@@ -2883,6 +2894,10 @@
|
||||
},],
|
||||
],
|
||||
},
|
||||
]}, # 'targets'
|
||||
], # OS=="win" or OS=="linux"
|
||||
['OS=="win"',
|
||||
{ 'targets': [
|
||||
{
|
||||
'target_name': 'worker',
|
||||
'type': '<(library)',
|
||||
|
||||
@@ -74,6 +74,8 @@ class ChildProcessHost : public ResourceDispatcherHost::Receiver,
|
||||
bool opening_channel() { return opening_channel_; }
|
||||
const std::wstring& channel_id() { return channel_id_; }
|
||||
|
||||
const IPC::Channel& channel() const { return *channel_; }
|
||||
|
||||
private:
|
||||
// Sends the given notification to the notification service on the UI thread.
|
||||
void Notify(NotificationType type);
|
||||
|
||||
@@ -94,7 +94,7 @@ class Channel : public Message::Sender {
|
||||
// If the kTestingChannelID flag is specified on the command line then
|
||||
// a named FIFO is used as the channel transport mechanism rather than a
|
||||
// socketpair() in which case this method returns -1 for both parameters.
|
||||
void GetClientFileDescriptorMapping(int *src_fd, int *dest_fd);
|
||||
void GetClientFileDescriptorMapping(int *src_fd, int *dest_fd) const;
|
||||
|
||||
// Call this method on the server side of the IPC Channel once a client is
|
||||
// connected in order to close the client side of the socketpair().
|
||||
|
||||
@@ -658,7 +658,7 @@ bool Channel::ChannelImpl::Send(Message* message) {
|
||||
}
|
||||
|
||||
void Channel::ChannelImpl::GetClientFileDescriptorMapping(int *src_fd,
|
||||
int *dest_fd) {
|
||||
int *dest_fd) const {
|
||||
DCHECK(mode_ == MODE_SERVER);
|
||||
*src_fd = client_pipe_;
|
||||
*dest_fd = kClientChannelFd;
|
||||
@@ -792,7 +792,7 @@ bool Channel::Send(Message* message) {
|
||||
return channel_impl_->Send(message);
|
||||
}
|
||||
|
||||
void Channel::GetClientFileDescriptorMapping(int *src_fd, int *dest_fd) {
|
||||
void Channel::GetClientFileDescriptorMapping(int *src_fd, int *dest_fd) const {
|
||||
return channel_impl_->GetClientFileDescriptorMapping(src_fd, dest_fd);
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ class Channel::ChannelImpl : public MessageLoopForIO::Watcher {
|
||||
void Close();
|
||||
void set_listener(Listener* listener) { listener_ = listener; }
|
||||
bool Send(Message* message);
|
||||
void GetClientFileDescriptorMapping(int *src_fd, int *dest_fd);
|
||||
void GetClientFileDescriptorMapping(int *src_fd, int *dest_fd) const;
|
||||
void OnClientConnected();
|
||||
|
||||
private:
|
||||
|
||||
@@ -286,7 +286,8 @@ void ChannelProxy::RemoveFilter(MessageFilter* filter) {
|
||||
// See the TODO regarding lazy initialization of the channel in
|
||||
// ChannelProxy::Init().
|
||||
// We assume that IPC::Channel::GetClientFileDescriptorMapping() is thread-safe.
|
||||
void ChannelProxy::GetClientFileDescriptorMapping(int *src_fd, int *dest_fd) {
|
||||
void ChannelProxy::GetClientFileDescriptorMapping(int *src_fd,
|
||||
int *dest_fd) const {
|
||||
Channel *channel = context_.get()->channel_;
|
||||
DCHECK(channel); // Channel must have been created first.
|
||||
channel->GetClientFileDescriptorMapping(src_fd, dest_fd);
|
||||
|
||||
@@ -117,7 +117,7 @@ class ChannelProxy : public Message::Sender {
|
||||
// Calls through to the underlying channel's methods.
|
||||
// TODO(playmobil): For now this is only implemented in the case of
|
||||
// create_pipe_now = true, we need to figure this out for the latter case.
|
||||
void GetClientFileDescriptorMapping(int *src_fd, int *dest_fd);
|
||||
void GetClientFileDescriptorMapping(int *src_fd, int *dest_fd) const;
|
||||
void OnClientConnected();
|
||||
#endif // defined(OS_POSIX)
|
||||
|
||||
|
||||
@@ -143,8 +143,8 @@ IPC_BEGIN_MESSAGES(Plugin)
|
||||
IPC_MESSAGE_ROUTED4(PluginMsg_UpdateGeometry,
|
||||
gfx::Rect /* window_rect */,
|
||||
gfx::Rect /* clip_rect */,
|
||||
base::SharedMemoryHandle /* windowless_buffer */,
|
||||
base::SharedMemoryHandle /* background_buffer */)
|
||||
TransportDIB::Id /* windowless_buffer */,
|
||||
TransportDIB::Id /* background_buffer */)
|
||||
|
||||
IPC_SYNC_MESSAGE_ROUTED0_0(PluginMsg_SetFocus)
|
||||
|
||||
|
||||
@@ -200,10 +200,12 @@ bool RLZTracker::RecordProductEvent(Product product, AccessPoint point,
|
||||
return false;
|
||||
}
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
// This depends on porting all the plugin IPC messages.
|
||||
bool IsPluginProcess() {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
@@ -244,10 +246,12 @@ void ProcessWatcher::EnsureProcessTerminated(int) {
|
||||
//--------------------------------------------------------------------------
|
||||
namespace webkit_glue {
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
bool IsDefaultPluginEnabled() {
|
||||
NOTIMPLEMENTED();
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
} // webkit_glue
|
||||
|
||||
|
||||
@@ -23,7 +23,8 @@ class Size;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// A TransportDIB is a block of memory that is used to transport pixels
|
||||
// from the renderer process to the browser.
|
||||
// between processes: from the renderer process to the browser, and
|
||||
// between renderer and plugin processes.
|
||||
// -----------------------------------------------------------------------------
|
||||
class TransportDIB {
|
||||
public:
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "base/file_path.h"
|
||||
#include "base/file_util.h"
|
||||
#include "base/message_loop.h"
|
||||
#include "base/process_util.h"
|
||||
#include "chrome/common/child_process.h"
|
||||
#include "chrome/common/chrome_constants.h"
|
||||
#include "chrome/common/chrome_plugin_lib.h"
|
||||
@@ -42,8 +43,8 @@ class PluginRequestHandlerProxy
|
||||
|
||||
PluginRequestHandlerProxy(ChromePluginLib* plugin,
|
||||
ScopableCPRequest* cprequest)
|
||||
: PluginHelper(plugin), cprequest_(cprequest), response_data_offset_(0),
|
||||
completed_(false), sync_(false), read_buffer_(NULL) {
|
||||
: PluginHelper(plugin), cprequest_(cprequest), sync_(false),
|
||||
response_data_offset_(0), completed_(false), read_buffer_(NULL) {
|
||||
load_flags_ = PluginResponseUtils::CPLoadFlagsToNetFlags(0);
|
||||
cprequest_->data = this; // see FromCPRequest().
|
||||
}
|
||||
@@ -150,7 +151,7 @@ class PluginRequestHandlerProxy
|
||||
"null", // main_frame_origin
|
||||
extra_headers_,
|
||||
load_flags_,
|
||||
GetCurrentProcessId(),
|
||||
base::GetCurrentProcId(),
|
||||
ResourceType::OBJECT,
|
||||
cprequest_->context,
|
||||
WebAppCacheContext::kNoAppCacheContextId,
|
||||
@@ -207,7 +208,6 @@ class PluginRequestHandlerProxy
|
||||
if (count > avail)
|
||||
count = avail;
|
||||
|
||||
int rv = CPERR_FAILURE;
|
||||
if (count) {
|
||||
// Data is ready now.
|
||||
memcpy(buf, &response_data_[0] + response_data_offset_, count);
|
||||
@@ -241,7 +241,7 @@ class PluginRequestHandlerProxy
|
||||
|
||||
scoped_refptr<net::HttpResponseHeaders> response_headers_;
|
||||
std::string response_data_;
|
||||
int response_data_offset_;
|
||||
size_t response_data_offset_;
|
||||
bool completed_;
|
||||
void* read_buffer_;
|
||||
uint32 read_buffer_size_;
|
||||
@@ -414,8 +414,7 @@ CPError STDCALL CPB_CreateRequest(CPID id, CPBrowsingContext context,
|
||||
CHECK(plugin);
|
||||
|
||||
ScopableCPRequest* cprequest = new ScopableCPRequest(url, method, context);
|
||||
PluginRequestHandlerProxy* handler =
|
||||
new PluginRequestHandlerProxy(plugin, cprequest);
|
||||
new PluginRequestHandlerProxy(plugin, cprequest);
|
||||
|
||||
*request = cprequest;
|
||||
return CPERR_SUCCESS;
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
|
||||
#include "base/waitable_event.h"
|
||||
#include "chrome/common/plugin_messages.h"
|
||||
#include "chrome/common/win_util.h"
|
||||
#include "chrome/plugin/npobject_util.h"
|
||||
#include "chrome/plugin/plugin_channel_base.h"
|
||||
#include "webkit/glue/webkit_glue.h"
|
||||
@@ -302,10 +301,10 @@ bool NPObjectProxy::NPRemoveProperty(NPObject *obj,
|
||||
}
|
||||
|
||||
void NPObjectProxy::NPPInvalidate(NPObject *obj) {
|
||||
bool result = false;
|
||||
NPObjectProxy* proxy = GetProxy(obj);
|
||||
if (!proxy) {
|
||||
return obj->_class->invalidate(obj);
|
||||
obj->_class->invalidate(obj);
|
||||
return;
|
||||
}
|
||||
|
||||
proxy->Send(new NPObjectMsg_Invalidate(proxy->route_id()));
|
||||
|
||||
@@ -110,9 +110,9 @@ class NPObjectProxy : public IPC::Channel::Listener,
|
||||
static void NPPInvalidate(NPObject *obj);
|
||||
static NPClass npclass_proxy_;
|
||||
|
||||
scoped_refptr<PluginChannelBase> channel_;
|
||||
int route_id_;
|
||||
intptr_t npobject_ptr_;
|
||||
scoped_refptr<PluginChannelBase> channel_;
|
||||
base::WaitableEvent* modal_dialog_event_;
|
||||
};
|
||||
|
||||
|
||||
@@ -16,8 +16,8 @@ NPObjectStub::NPObjectStub(
|
||||
PluginChannelBase* channel,
|
||||
int route_id,
|
||||
base::WaitableEvent* modal_dialog_event)
|
||||
: channel_(channel),
|
||||
npobject_(npobject),
|
||||
: npobject_(npobject),
|
||||
channel_(channel),
|
||||
route_id_(route_id),
|
||||
valid_(true),
|
||||
web_plugin_delegate_proxy_(NULL),
|
||||
|
||||
@@ -78,16 +78,16 @@ class NPObjectStub : public IPC::Channel::Listener,
|
||||
|
||||
private:
|
||||
NPObject* npobject_;
|
||||
int route_id_;
|
||||
scoped_refptr<PluginChannelBase> channel_;
|
||||
|
||||
base::WaitableEvent* modal_dialog_event_;
|
||||
int route_id_;
|
||||
|
||||
// These variables are used to ensure that the window script object is not
|
||||
// called after the plugin widget has gone away, as the frame manually
|
||||
// deallocates it and ignores the refcount to avoid leaks.
|
||||
bool valid_;
|
||||
WebPluginDelegateProxy* web_plugin_delegate_proxy_;
|
||||
|
||||
base::WaitableEvent* modal_dialog_event_;
|
||||
};
|
||||
|
||||
#endif // CHROME_PLUGIN_NPOBJECT_STUB_H_
|
||||
|
||||
@@ -4,15 +4,8 @@
|
||||
|
||||
#include "chrome/plugin/npobject_util.h"
|
||||
|
||||
// TODO(port) Just compile an empty file on posix so we can generate the
|
||||
// libplugin target needed by other targets. This whole file does compile (see
|
||||
// r9934), but it doesn't link because of undefined refs to files which aren't
|
||||
// compiling yet (e.g. npobject_proxy stuff).
|
||||
#if defined(OS_WIN)
|
||||
|
||||
#include "base/string_util.h"
|
||||
#include "chrome/common/plugin_messages.h"
|
||||
#include "chrome/common/win_util.h"
|
||||
|
||||
#include "chrome/plugin/npobject_proxy.h"
|
||||
#include "chrome/plugin/plugin_channel_base.h"
|
||||
#include "webkit/glue/plugins/nphostapi.h"
|
||||
@@ -133,7 +126,6 @@ bool IsPluginProcess() {
|
||||
return g_plugin_process;
|
||||
}
|
||||
|
||||
#if defined(OS_WIN)
|
||||
void CreateNPIdentifierParam(NPIdentifier id, NPIdentifier_Param* param) {
|
||||
param->identifier = id;
|
||||
}
|
||||
@@ -190,7 +182,7 @@ void CreateNPVariantParam(const NPVariant& variant,
|
||||
// (release==true), we should still do that.
|
||||
param->type = NPVARIANT_PARAM_OBJECT_ROUTING_ID;
|
||||
int route_id = channel->GenerateRouteID();
|
||||
NPObjectStub* object_stub = new NPObjectStub(
|
||||
new NPObjectStub(
|
||||
variant.value.objectValue, channel, route_id, modal_dialog_event);
|
||||
param->npobject_routing_id = route_id;
|
||||
param->npobject_pointer =
|
||||
@@ -235,7 +227,7 @@ void CreateNPVariant(const NPVariant_Param& param,
|
||||
case NPVARIANT_PARAM_STRING:
|
||||
result->type = NPVariantType_String;
|
||||
result->value.stringValue.UTF8Characters =
|
||||
static_cast<NPUTF8 *>(_strdup(param.string_value.c_str()));
|
||||
static_cast<NPUTF8 *>(base::strdup(param.string_value.c_str()));
|
||||
result->value.stringValue.UTF8Length =
|
||||
static_cast<int>(param.string_value.size());
|
||||
break;
|
||||
@@ -257,7 +249,3 @@ void CreateNPVariant(const NPVariant_Param& param,
|
||||
NOTREACHED();
|
||||
}
|
||||
}
|
||||
|
||||
#endif // defined(OS_WIN)
|
||||
|
||||
#endif // defined(OS_WIN)
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#if defined(OS_WIN)
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include "chrome/plugin/npobject_stub.h"
|
||||
|
||||
struct _NPVariant;
|
||||
@@ -51,13 +52,13 @@ void CreateNPVariantParam(const NPVariant& variant,
|
||||
bool release,
|
||||
base::WaitableEvent* modal_dialog_event);
|
||||
|
||||
#if defined(OS_WIN)
|
||||
// Creates an NPVariant from the marshalled object.
|
||||
void CreateNPVariant(const NPVariant_Param& param,
|
||||
PluginChannelBase* channel,
|
||||
NPVariant* result,
|
||||
base::WaitableEvent* modal_dialog_event);
|
||||
|
||||
#if defined(OS_WIN)
|
||||
// Given a plugin's HWND, returns an event associated with the WebContents
|
||||
// that's set when inside a messagebox. This tells the plugin process that
|
||||
// the message queue should be pumped (as what would happen if everything was
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include "chrome/plugin/plugin_channel.h"
|
||||
|
||||
#include "base/command_line.h"
|
||||
@@ -17,7 +15,7 @@
|
||||
PluginChannel* PluginChannel::GetPluginChannel(MessageLoop* ipc_message_loop) {
|
||||
static int next_id;
|
||||
std::wstring channel_name = StringPrintf(
|
||||
L"%d.r%d", GetCurrentProcessId(), ++next_id);
|
||||
L"%d.r%d", base::GetCurrentProcId(), ++next_id);
|
||||
|
||||
return static_cast<PluginChannel*>(PluginChannelBase::GetChannel(
|
||||
channel_name,
|
||||
@@ -27,7 +25,8 @@ PluginChannel* PluginChannel::GetPluginChannel(MessageLoop* ipc_message_loop) {
|
||||
false));
|
||||
}
|
||||
|
||||
PluginChannel::PluginChannel() : in_send_(0), off_the_record_(false) {
|
||||
PluginChannel::PluginChannel() : renderer_handle_(0), in_send_(0),
|
||||
off_the_record_(false) {
|
||||
SendUnblockingOnlyDuringDispatch();
|
||||
ChildProcess::current()->AddRefProcess();
|
||||
const CommandLine* command_line = CommandLine::ForCurrentProcess();
|
||||
@@ -35,6 +34,8 @@ PluginChannel::PluginChannel() : in_send_(0), off_the_record_(false) {
|
||||
}
|
||||
|
||||
PluginChannel::~PluginChannel() {
|
||||
if (renderer_handle_)
|
||||
base::CloseProcessHandle(renderer_handle_);
|
||||
ChildProcess::current()->ReleaseProcess();
|
||||
}
|
||||
|
||||
@@ -95,8 +96,8 @@ void PluginChannel::OnGenerateRouteID(int* route_id) {
|
||||
}
|
||||
|
||||
int PluginChannel::GenerateRouteID() {
|
||||
static LONG last_id = 0;
|
||||
return InterlockedIncrement(&last_id);
|
||||
static int last_id = 0;
|
||||
return ++last_id;
|
||||
}
|
||||
|
||||
void PluginChannel::OnChannelConnected(int32 peer_pid) {
|
||||
@@ -104,12 +105,13 @@ void PluginChannel::OnChannelConnected(int32 peer_pid) {
|
||||
if (!base::OpenProcessHandle(peer_pid, &handle)) {
|
||||
NOTREACHED();
|
||||
}
|
||||
renderer_handle_.Set(handle);
|
||||
renderer_handle_ = handle;
|
||||
PluginChannelBase::OnChannelConnected(peer_pid);
|
||||
}
|
||||
|
||||
void PluginChannel::OnChannelError() {
|
||||
renderer_handle_.Set(NULL);
|
||||
base::CloseProcessHandle(renderer_handle_);
|
||||
renderer_handle_ = 0;
|
||||
PluginChannelBase::OnChannelError();
|
||||
CleanUp();
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
#include <vector>
|
||||
#include "base/scoped_handle.h"
|
||||
#include "build/build_config.h"
|
||||
#include "chrome/plugin/plugin_channel_base.h"
|
||||
#include "chrome/plugin/webplugin_delegate_stub.h"
|
||||
|
||||
@@ -21,7 +22,7 @@ class PluginChannel : public PluginChannelBase {
|
||||
virtual bool Send(IPC::Message* msg);
|
||||
virtual void OnMessageReceived(const IPC::Message& message);
|
||||
|
||||
HANDLE renderer_handle() { return renderer_handle_.Get(); }
|
||||
base::ProcessHandle renderer_handle() const { return renderer_handle_; }
|
||||
int GenerateRouteID();
|
||||
|
||||
bool in_send() { return in_send_ != 0; }
|
||||
@@ -48,10 +49,10 @@ class PluginChannel : public PluginChannelBase {
|
||||
void OnDestroyInstance(int instance_id, IPC::Message* reply_msg);
|
||||
void OnGenerateRouteID(int* route_id);
|
||||
|
||||
std::vector<scoped_refptr<WebPluginDelegateStub>> plugin_stubs_;
|
||||
std::vector<scoped_refptr<WebPluginDelegateStub> > plugin_stubs_;
|
||||
|
||||
// Handle to the renderer process who is on the other side of the channel.
|
||||
ScopedHandle renderer_handle_;
|
||||
base::ProcessHandle renderer_handle_;
|
||||
|
||||
int in_send_; // Tracks if we're in a Send call.
|
||||
bool log_messages_; // True if we should log sent and received messages.
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include "chrome/plugin/plugin_channel_base.h"
|
||||
|
||||
#include "base/hash_tables.h"
|
||||
@@ -59,7 +57,7 @@ PluginChannelBase::~PluginChannelBase() {
|
||||
void PluginChannelBase::CleanupChannels() {
|
||||
// Make a copy of the references as we can't iterate the map since items will
|
||||
// be removed from it as we clean them up.
|
||||
std::vector<scoped_refptr<PluginChannelBase>> channels;
|
||||
std::vector<scoped_refptr<PluginChannelBase> > channels;
|
||||
for (PluginChannelMap::const_iterator iter = g_plugin_channels_.begin();
|
||||
iter != g_plugin_channels_.end();
|
||||
++iter) {
|
||||
|
||||
@@ -108,10 +108,13 @@ class PluginChannelBase : public IPC::Channel::Listener,
|
||||
// error. This flag is used to indicate the same.
|
||||
bool channel_valid_;
|
||||
|
||||
// Track whether we're within a dispatch; works like a refcount, 0 when we're
|
||||
// not.
|
||||
int in_dispatch_;
|
||||
|
||||
// If true, sync messages will only be marked as unblocking if the channel is
|
||||
// in the middle of dispatching a message.
|
||||
bool send_unblocking_only_during_dispatch_;
|
||||
int in_dispatch_;
|
||||
|
||||
DISALLOW_EVIL_CONSTRUCTORS(PluginChannelBase);
|
||||
};
|
||||
|
||||
@@ -6,22 +6,22 @@
|
||||
#include "base/message_loop.h"
|
||||
#include "base/string_util.h"
|
||||
#include "base/system_monitor.h"
|
||||
#include "build/build_config.h"
|
||||
#include "chrome/common/child_process.h"
|
||||
#include "chrome/common/chrome_constants.h"
|
||||
#include "chrome/common/chrome_switches.h"
|
||||
#include "chrome/common/logging_chrome.h"
|
||||
#include "chrome/common/main_function_params.h"
|
||||
#include "chrome/common/win_util.h"
|
||||
#include "chrome/plugin/plugin_thread.h"
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#include "chrome/common/win_util.h"
|
||||
#include "chrome/test/injection_test_dll.h"
|
||||
#include "sandbox/src/sandbox.h"
|
||||
#endif
|
||||
|
||||
// mainline routine for running as the plugin process
|
||||
// main() routine for running as the plugin process.
|
||||
int PluginMain(const MainFunctionParams& parameters) {
|
||||
const CommandLine& parsed_command_line = parameters.command_line_;
|
||||
sandbox::TargetServices* target_services =
|
||||
parameters.sandbox_info_.TargetServices();
|
||||
|
||||
// The main thread of the plugin services IO.
|
||||
MessageLoopForIO main_message_loop;
|
||||
std::wstring app_name = chrome::kBrowserAppName;
|
||||
@@ -30,6 +30,12 @@ int PluginMain(const MainFunctionParams& parameters) {
|
||||
// Initialize the SystemMonitor
|
||||
base::SystemMonitor::Start();
|
||||
|
||||
#if defined(OS_WIN)
|
||||
const CommandLine& parsed_command_line = parameters.command_line_;
|
||||
|
||||
sandbox::TargetServices* target_services =
|
||||
parameters.sandbox_info_.TargetServices();
|
||||
|
||||
CoInitialize(NULL);
|
||||
DLOG(INFO) << "Started plugin with " <<
|
||||
parsed_command_line.command_line_string();
|
||||
@@ -53,12 +59,15 @@ int PluginMain(const MainFunctionParams& parameters) {
|
||||
win_util::MessageBox(NULL, L"plugin starting...", title,
|
||||
MB_OK | MB_SETFOREGROUND);
|
||||
}
|
||||
#else
|
||||
NOTIMPLEMENTED() << " non-windows startup, plugin startup dialog etc.";
|
||||
#endif
|
||||
|
||||
{
|
||||
ChildProcess plugin_process(new PluginThread());
|
||||
if (!no_sandbox && target_services) {
|
||||
#if defined(OS_WIN)
|
||||
if (!no_sandbox && target_services)
|
||||
target_services->LowerToken();
|
||||
}
|
||||
|
||||
if (sandbox_test_module) {
|
||||
RunRendererTests run_security_tests =
|
||||
@@ -75,12 +84,14 @@ int PluginMain(const MainFunctionParams& parameters) {
|
||||
__debugbreak();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Load the accelerator table from the browser executable and tell the
|
||||
// message loop to use it when translating messages.
|
||||
MessageLoop::current()->Run();
|
||||
}
|
||||
|
||||
#if defined(OS_WIN)
|
||||
CoUninitialize();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2,12 +2,17 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include <windows.h>
|
||||
#include <objbase.h>
|
||||
|
||||
#include "chrome/plugin/plugin_thread.h"
|
||||
|
||||
#include "build/build_config.h"
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#include <windows.h>
|
||||
#include <objbase.h>
|
||||
#endif
|
||||
|
||||
#include "base/command_line.h"
|
||||
#include "base/process_util.h"
|
||||
#include "chrome/common/child_process.h"
|
||||
#include "chrome/common/chrome_plugin_lib.h"
|
||||
#include "chrome/common/chrome_switches.h"
|
||||
@@ -46,8 +51,12 @@ void PluginThread::OnControlMessageReceived(const IPC::Message& msg) {
|
||||
|
||||
void PluginThread::Init() {
|
||||
ChildThread::Init();
|
||||
|
||||
PatchNPNFunctions();
|
||||
#if defined(OS_WIN)
|
||||
CoInitialize(NULL);
|
||||
#endif
|
||||
|
||||
notification_service_.reset(new NotificationService);
|
||||
|
||||
// Preload the library to avoid loading, unloading then reloading
|
||||
@@ -68,17 +77,19 @@ void PluginThread::Init() {
|
||||
|
||||
void PluginThread::CleanUp() {
|
||||
if (preloaded_plugin_module_) {
|
||||
FreeLibrary(preloaded_plugin_module_);
|
||||
base::UnloadNativeLibrary(preloaded_plugin_module_);
|
||||
preloaded_plugin_module_ = NULL;
|
||||
}
|
||||
PluginChannelBase::CleanupChannels();
|
||||
NPAPI::PluginLib::UnloadAllPlugins();
|
||||
ChromePluginLib::UnloadAllPlugins();
|
||||
notification_service_.reset();
|
||||
#if defined(OS_WIN)
|
||||
CoUninitialize();
|
||||
#endif
|
||||
|
||||
if (webkit_glue::ShouldForcefullyTerminatePluginProcess())
|
||||
TerminateProcess(GetCurrentProcess(), 0);
|
||||
base::KillProcess(base::GetCurrentProcessHandle(), 0, /* wait= */ false);
|
||||
|
||||
// Call this last because it deletes the ResourceDispatcher, which is used
|
||||
// in some of the above cleanup.
|
||||
@@ -146,7 +157,12 @@ bool GetPluginFinderURL(std::string* plugin_finder_url) {
|
||||
}
|
||||
|
||||
bool IsDefaultPluginEnabled() {
|
||||
#if defined(OS_WIN)
|
||||
return true;
|
||||
#else
|
||||
NOTIMPLEMENTED();
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Dispatch the resolve proxy resquest to the right code, depending on which
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "base/native_library.h"
|
||||
#include "chrome/common/child_thread.h"
|
||||
#include "chrome/plugin/plugin_channel.h"
|
||||
#include "webkit/glue/plugins/plugin_lib.h"
|
||||
|
||||
class NotificationService;
|
||||
|
||||
|
||||
@@ -4,11 +4,11 @@
|
||||
|
||||
#include "chrome/plugin/webplugin_delegate_stub.h"
|
||||
|
||||
#include "build/build_config.h"
|
||||
|
||||
#include "base/command_line.h"
|
||||
#include "chrome/common/chrome_switches.h"
|
||||
#include "chrome/common/gfx/emf.h"
|
||||
#include "chrome/common/plugin_messages.h"
|
||||
#include "chrome/common/win_util.h"
|
||||
#include "chrome/plugin/npobject_stub.h"
|
||||
#include "chrome/plugin/plugin_channel.h"
|
||||
#include "chrome/plugin/plugin_thread.h"
|
||||
@@ -19,6 +19,11 @@
|
||||
#include "webkit/glue/webcursor.h"
|
||||
#include "webkit/glue/webplugin_delegate.h"
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#include "chrome/common/gfx/emf.h"
|
||||
#include "chrome/common/win_util.h"
|
||||
#endif
|
||||
|
||||
class FinishDestructionTask : public Task {
|
||||
public:
|
||||
FinishDestructionTask(WebPluginDelegate* delegate, WebPlugin* webplugin)
|
||||
@@ -124,8 +129,8 @@ void WebPluginDelegateStub::OnInit(const PluginMsg_Init_Params& params,
|
||||
}
|
||||
|
||||
const CommandLine& command_line = *CommandLine::ForCurrentProcess();
|
||||
FilePath path =
|
||||
FilePath(command_line.GetSwitchValue(switches::kPluginPath));
|
||||
FilePath path = FilePath::FromWStringHack(
|
||||
command_line.GetSwitchValue(switches::kPluginPath));
|
||||
delegate_ = WebPluginDelegate::Create(
|
||||
path, mime_type_, gfx::NativeViewFromId(params.containing_window));
|
||||
if (delegate_) {
|
||||
@@ -215,6 +220,7 @@ void WebPluginDelegateStub::OnDidPaint() {
|
||||
|
||||
void WebPluginDelegateStub::OnPrint(base::SharedMemoryHandle* shared_memory,
|
||||
size_t* size) {
|
||||
#if defined(OS_WIN)
|
||||
gfx::Emf emf;
|
||||
if (!emf.CreateDc(NULL, NULL)) {
|
||||
NOTREACHED();
|
||||
@@ -236,15 +242,20 @@ void WebPluginDelegateStub::OnPrint(base::SharedMemoryHandle* shared_memory,
|
||||
// Retrieve a copy of the data.
|
||||
bool success = emf.GetData(shared_buf.memory(), *size);
|
||||
DCHECK(success);
|
||||
#else
|
||||
// TODO(port): plugin printing.
|
||||
NOTIMPLEMENTED();
|
||||
#endif
|
||||
}
|
||||
|
||||
void WebPluginDelegateStub::OnUpdateGeometry(
|
||||
const gfx::Rect& window_rect,
|
||||
const gfx::Rect& clip_rect,
|
||||
const base::SharedMemoryHandle& windowless_buffer,
|
||||
const base::SharedMemoryHandle& background_buffer) {
|
||||
const TransportDIB::Id& windowless_buffer_id,
|
||||
const TransportDIB::Id& background_buffer_id) {
|
||||
webplugin_->UpdateGeometry(
|
||||
window_rect, clip_rect, windowless_buffer, background_buffer);
|
||||
window_rect, clip_rect,
|
||||
windowless_buffer_id, background_buffer_id);
|
||||
}
|
||||
|
||||
void WebPluginDelegateStub::OnGetPluginScriptableObject(int* route_id,
|
||||
@@ -259,7 +270,7 @@ void WebPluginDelegateStub::OnGetPluginScriptableObject(int* route_id,
|
||||
*npobject_ptr = reinterpret_cast<intptr_t>(object);
|
||||
// The stub will delete itself when the proxy tells it that it's released, or
|
||||
// otherwise when the channel is closed.
|
||||
NPObjectStub* stub = new NPObjectStub(
|
||||
new NPObjectStub(
|
||||
object, channel_.get(), *route_id, webplugin_->modal_dialog_event());
|
||||
|
||||
// Release ref added by GetPluginScriptableObject (our stub holds its own).
|
||||
@@ -315,6 +326,7 @@ void WebPluginDelegateStub::CreateSharedBuffer(
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined(OS_WIN)
|
||||
BOOL result = DuplicateHandle(GetCurrentProcess(),
|
||||
shared_buf->handle(),
|
||||
channel_->renderer_handle(),
|
||||
@@ -325,6 +337,10 @@ void WebPluginDelegateStub::CreateSharedBuffer(
|
||||
// If the calling function's shared_buf is on the stack, its destructor will
|
||||
// close the shared memory buffer handle. This is fine since we already
|
||||
// duplicated the handle to the renderer process so it will stay "alive".
|
||||
#else
|
||||
// TODO(port): this should use TransportDIB.
|
||||
NOTIMPLEMENTED();
|
||||
#endif
|
||||
}
|
||||
|
||||
void WebPluginDelegateStub::OnHandleURLRequestReply(
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "base/shared_memory.h"
|
||||
#include "base/task.h"
|
||||
#include "chrome/common/ipc_channel.h"
|
||||
#include "chrome/common/transport_dib.h"
|
||||
#include "third_party/npapi/bindings/npapi.h"
|
||||
|
||||
class GURL;
|
||||
@@ -66,8 +67,8 @@ class WebPluginDelegateStub : public IPC::Channel::Listener,
|
||||
|
||||
void OnUpdateGeometry(const gfx::Rect& window_rect,
|
||||
const gfx::Rect& clip_rect,
|
||||
const base::SharedMemoryHandle& windowless_buffer,
|
||||
const base::SharedMemoryHandle& background_buffer);
|
||||
const TransportDIB::Id& windowless_buffer,
|
||||
const TransportDIB::Id& background_buffer);
|
||||
void OnGetPluginScriptableObject(int* route_id, intptr_t* npobject_ptr);
|
||||
void OnSendJavaScriptStream(const std::string& url,
|
||||
const std::wstring& result,
|
||||
@@ -92,15 +93,15 @@ class WebPluginDelegateStub : public IPC::Channel::Listener,
|
||||
base::SharedMemory* shared_buf,
|
||||
base::SharedMemoryHandle* remote_handle);
|
||||
|
||||
int instance_id_;
|
||||
std::string mime_type_;
|
||||
int instance_id_;
|
||||
|
||||
scoped_refptr<PluginChannel> channel_;
|
||||
|
||||
WebPluginDelegate* delegate_;
|
||||
WebPluginProxy* webplugin_;
|
||||
|
||||
DISALLOW_EVIL_CONSTRUCTORS(WebPluginDelegateStub);
|
||||
DISALLOW_IMPLICIT_CONSTRUCTORS(WebPluginDelegateStub);
|
||||
};
|
||||
|
||||
#endif // CHROME_PLUGIN_WEBPLUGIN_DELEGATE_STUB_H_
|
||||
|
||||
@@ -4,15 +4,14 @@
|
||||
|
||||
#include "chrome/plugin/webplugin_proxy.h"
|
||||
|
||||
#include "base/gfx/gdi_util.h"
|
||||
#include "base/scoped_handle.h"
|
||||
#include "base/shared_memory.h"
|
||||
#include "base/singleton.h"
|
||||
#include "base/waitable_event.h"
|
||||
#include "build/build_config.h"
|
||||
#include "chrome/common/gfx/chrome_canvas.h"
|
||||
#include "chrome/common/plugin_messages.h"
|
||||
#include "chrome/common/url_constants.h"
|
||||
#include "chrome/common/win_util.h"
|
||||
#include "chrome/plugin/npobject_proxy.h"
|
||||
#include "chrome/plugin/npobject_util.h"
|
||||
#include "chrome/plugin/plugin_channel.h"
|
||||
@@ -21,6 +20,11 @@
|
||||
#include "skia/ext/platform_device.h"
|
||||
#include "webkit/glue/webplugin_delegate.h"
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#include "base/gfx/gdi_util.h"
|
||||
#include "chrome/common/win_util.h"
|
||||
#endif
|
||||
|
||||
typedef std::map<CPBrowsingContext, WebPluginProxy*> ContextMap;
|
||||
static ContextMap& GetContextMap() {
|
||||
return *Singleton<ContextMap>::get();
|
||||
@@ -37,8 +41,8 @@ WebPluginProxy::WebPluginProxy(
|
||||
plugin_element_(NULL),
|
||||
delegate_(delegate),
|
||||
waiting_for_paint_(false),
|
||||
#pragma warning(suppress: 4355) // can use this
|
||||
runnable_method_factory_(this) {
|
||||
ALLOW_THIS_IN_INITIALIZER_LIST(runnable_method_factory_(this))
|
||||
{
|
||||
}
|
||||
|
||||
WebPluginProxy::~WebPluginProxy() {
|
||||
@@ -256,9 +260,10 @@ void WebPluginProxy::HandleURLRequest(const char *method,
|
||||
return;
|
||||
}
|
||||
|
||||
if (!target && (0 == _strcmpi(method, "GET"))) {
|
||||
if (!target && (0 == base::strcasecmp(method, "GET"))) {
|
||||
// Please refer to https://bugzilla.mozilla.org/show_bug.cgi?id=366082
|
||||
// for more details on this.
|
||||
#if defined(OS_WIN)
|
||||
if (delegate_->GetQuirks() &
|
||||
WebPluginDelegate::PLUGIN_QUIRK_BLOCK_NONSTANDARD_GETURL_REQUESTS) {
|
||||
GURL request_url(url);
|
||||
@@ -268,6 +273,10 @@ void WebPluginProxy::HandleURLRequest(const char *method,
|
||||
return;
|
||||
}
|
||||
}
|
||||
#else
|
||||
// TODO(port): we need a GetQuirks() on our delegate impl.
|
||||
NOTIMPLEMENTED();
|
||||
#endif
|
||||
}
|
||||
|
||||
PluginHostMsg_URLRequest_Params params;
|
||||
@@ -291,6 +300,7 @@ void WebPluginProxy::HandleURLRequest(const char *method,
|
||||
}
|
||||
|
||||
void WebPluginProxy::Paint(const gfx::Rect& rect) {
|
||||
#if defined(OS_WIN)
|
||||
if (!windowless_hdc_)
|
||||
return;
|
||||
|
||||
@@ -317,21 +327,31 @@ void WebPluginProxy::Paint(const gfx::Rect& rect) {
|
||||
|
||||
SelectClipRgn(windowless_hdc_, NULL);
|
||||
DeleteObject(clip_region);
|
||||
#else
|
||||
// TODO(port): windowless painting.
|
||||
NOTIMPLEMENTED();
|
||||
#endif
|
||||
}
|
||||
|
||||
void WebPluginProxy::UpdateGeometry(
|
||||
const gfx::Rect& window_rect,
|
||||
const gfx::Rect& clip_rect,
|
||||
const base::SharedMemoryHandle& windowless_buffer,
|
||||
const base::SharedMemoryHandle& background_buffer) {
|
||||
const TransportDIB::Id& windowless_buffer_id,
|
||||
const TransportDIB::Id& background_buffer_id) {
|
||||
#if defined(OS_WIN)
|
||||
// TODO(port): this isn't correct usage of a TransportDIB; for now,
|
||||
// the caller temporarly just stuffs the handle into the HANDLE
|
||||
// field of the TransportDIB::Id so it should behave like the older
|
||||
// code.
|
||||
gfx::Rect old = delegate_->GetRect();
|
||||
gfx::Rect old_clip_rect = delegate_->GetClipRect();
|
||||
|
||||
bool moved = old.x() != window_rect.x() || old.y() != window_rect.y();
|
||||
delegate_->UpdateGeometry(window_rect, clip_rect);
|
||||
if (windowless_buffer) {
|
||||
if (windowless_buffer_id.handle) {
|
||||
// The plugin's rect changed, so now we have a new buffer to draw into.
|
||||
SetWindowlessBuffer(windowless_buffer, background_buffer);
|
||||
SetWindowlessBuffer(windowless_buffer_id.handle,
|
||||
background_buffer_id.handle);
|
||||
} else if (moved) {
|
||||
// The plugin moved, so update our world transform.
|
||||
UpdateTransform();
|
||||
@@ -342,8 +362,12 @@ void WebPluginProxy::UpdateGeometry(
|
||||
old_clip_rect.IsEmpty() && !damaged_rect_.IsEmpty()) {
|
||||
InvalidateRect(damaged_rect_);
|
||||
}
|
||||
#else
|
||||
NOTIMPLEMENTED();
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(OS_WIN)
|
||||
void WebPluginProxy::SetWindowlessBuffer(
|
||||
const base::SharedMemoryHandle& windowless_buffer,
|
||||
const base::SharedMemoryHandle& background_buffer) {
|
||||
@@ -411,6 +435,7 @@ void WebPluginProxy::UpdateTransform() {
|
||||
xf.eM22 = 1;
|
||||
SetWorldTransform(windowless_hdc_, &xf);
|
||||
}
|
||||
#endif
|
||||
|
||||
void WebPluginProxy::CancelDocumentLoad() {
|
||||
Send(new PluginHostMsg_CancelDocumentLoad(route_id_));
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "base/timer.h"
|
||||
#include "chrome/common/ipc_message.h"
|
||||
#include "chrome/common/chrome_plugin_api.h"
|
||||
#include "chrome/common/transport_dib.h"
|
||||
#include "webkit/glue/webplugin.h"
|
||||
|
||||
namespace base {
|
||||
@@ -87,8 +88,8 @@ class WebPluginProxy : public WebPlugin {
|
||||
|
||||
void UpdateGeometry(const gfx::Rect& window_rect,
|
||||
const gfx::Rect& clip_rect,
|
||||
const base::SharedMemoryHandle& windowless_buffer,
|
||||
const base::SharedMemoryHandle& background_buffer);
|
||||
const TransportDIB::Id& windowless_buffer,
|
||||
const TransportDIB::Id& background_buffer);
|
||||
|
||||
void CancelDocumentLoad();
|
||||
|
||||
@@ -107,6 +108,10 @@ class WebPluginProxy : public WebPlugin {
|
||||
private:
|
||||
bool Send(IPC::Message* msg);
|
||||
|
||||
// Handler for sending over the paint event to the plugin.
|
||||
void OnPaint(const gfx::Rect& damaged_rect);
|
||||
|
||||
#if defined(OS_WIN)
|
||||
// Updates the shared memory section where windowless plugins paint.
|
||||
void SetWindowlessBuffer(const base::SharedMemoryHandle& windowless_buffer,
|
||||
const base::SharedMemoryHandle& background_buffer);
|
||||
@@ -118,26 +123,25 @@ class WebPluginProxy : public WebPlugin {
|
||||
ScopedBitmap* bitmap,
|
||||
ScopedHDC* hdc);
|
||||
|
||||
// Handler for sending over the paint event to the plugin.
|
||||
void OnPaint(const gfx::Rect& damaged_rect);
|
||||
|
||||
// Called when a plugin's origin moves, so that we can update the world
|
||||
// transform of the local HDC.
|
||||
void UpdateTransform();
|
||||
#endif
|
||||
|
||||
typedef base::hash_map<int, WebPluginResourceClient*> ResourceClientMap;
|
||||
ResourceClientMap resource_clients_;
|
||||
|
||||
scoped_refptr<PluginChannel> channel_;
|
||||
int route_id_;
|
||||
uint32 cp_browsing_context_;
|
||||
NPObject* window_npobject_;
|
||||
NPObject* plugin_element_;
|
||||
WebPluginDelegate* delegate_;
|
||||
gfx::Rect damaged_rect_;
|
||||
bool waiting_for_paint_;
|
||||
uint32 cp_browsing_context_;
|
||||
scoped_ptr<base::WaitableEvent> modal_dialog_event_;
|
||||
|
||||
#if defined(OS_WIN)
|
||||
// Variables used for desynchronized windowless plugin painting. See note in
|
||||
// webplugin_delegate_proxy.h for how this works.
|
||||
|
||||
@@ -150,6 +154,7 @@ class WebPluginProxy : public WebPlugin {
|
||||
ScopedHandle background_shared_section_;
|
||||
ScopedBitmap background_bitmap_;
|
||||
ScopedHDC background_hdc_;
|
||||
#endif
|
||||
|
||||
ScopedRunnableMethodFactory<WebPluginProxy> runnable_method_factory_;
|
||||
};
|
||||
|
||||
@@ -1902,9 +1902,9 @@ WebPluginDelegate* RenderView::CreatePluginDelegate(
|
||||
|
||||
return proxy;
|
||||
#else
|
||||
// TODO(port): Plugins currently not supported
|
||||
NOTIMPLEMENTED();
|
||||
return NULL;
|
||||
// TODO(port): Plugins currently not supported
|
||||
NOTIMPLEMENTED();
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,11 @@
|
||||
|
||||
#include "chrome/renderer/webplugin_delegate_proxy.h"
|
||||
|
||||
#include "build/build_config.h"
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#include <atlbase.h>
|
||||
#endif
|
||||
|
||||
#include "base/logging.h"
|
||||
#include "base/ref_counted.h"
|
||||
@@ -13,12 +17,10 @@
|
||||
#include "base/gfx/native_widget_types.h"
|
||||
#include "chrome/app/chrome_dll_resource.h"
|
||||
#include "chrome/common/gfx/chrome_canvas.h"
|
||||
#include "chrome/common/gfx/emf.h"
|
||||
#include "chrome/common/l10n_util.h"
|
||||
#include "chrome/common/plugin_messages.h"
|
||||
#include "chrome/common/render_messages.h"
|
||||
#include "chrome/common/resource_bundle.h"
|
||||
#include "chrome/common/win_util.h"
|
||||
#include "chrome/plugin/npobject_proxy.h"
|
||||
#include "chrome/plugin/npobject_stub.h"
|
||||
#include "chrome/renderer/render_thread.h"
|
||||
@@ -31,6 +33,11 @@
|
||||
#include "webkit/glue/webplugin.h"
|
||||
#include "webkit/glue/webview.h"
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#include "chrome/common/gfx/emf.h"
|
||||
#include "chrome/common/win_util.h"
|
||||
#endif
|
||||
|
||||
// Proxy for WebPluginResourceClient. The object owns itself after creation,
|
||||
// deleting itself after its callback has been called.
|
||||
class ResourceClientProxy : public WebPluginResourceClient {
|
||||
@@ -58,7 +65,7 @@ class ResourceClientProxy : public WebPluginResourceClient {
|
||||
params.notify_data = notify_data_;
|
||||
params.stream = existing_stream;
|
||||
|
||||
multibyte_response_expected_ = (existing_stream != NULL);
|
||||
multibyte_response_expected_ = (existing_stream != 0);
|
||||
|
||||
channel_->Send(new PluginMsg_HandleURLRequestReply(instance_id_, params));
|
||||
}
|
||||
@@ -122,10 +129,10 @@ class ResourceClientProxy : public WebPluginResourceClient {
|
||||
return multibyte_response_expected_;
|
||||
}
|
||||
|
||||
private:
|
||||
int resource_id_;
|
||||
int instance_id_;
|
||||
private:
|
||||
scoped_refptr<PluginChannelHost> channel_;
|
||||
int instance_id_;
|
||||
int resource_id_;
|
||||
std::string url_;
|
||||
bool notify_needed_;
|
||||
intptr_t notify_data_;
|
||||
@@ -146,16 +153,16 @@ WebPluginDelegateProxy::WebPluginDelegateProxy(const std::string& mime_type,
|
||||
const std::string& clsid,
|
||||
RenderView* render_view)
|
||||
: render_view_(render_view),
|
||||
mime_type_(mime_type),
|
||||
clsid_(clsid),
|
||||
plugin_(NULL),
|
||||
windowless_(false),
|
||||
npobject_(NULL),
|
||||
mime_type_(mime_type),
|
||||
clsid_(clsid),
|
||||
send_deferred_update_geometry_(false),
|
||||
sad_plugin_(NULL),
|
||||
npobject_(NULL),
|
||||
window_script_object_(NULL),
|
||||
transparent_(false),
|
||||
invalidate_pending_(false) {
|
||||
sad_plugin_(NULL),
|
||||
invalidate_pending_(false),
|
||||
transparent_(false) {
|
||||
}
|
||||
|
||||
WebPluginDelegateProxy::~WebPluginDelegateProxy() {
|
||||
@@ -195,8 +202,8 @@ void WebPluginDelegateProxy::FlushGeometryUpdates() {
|
||||
Send(new PluginMsg_UpdateGeometry(instance_id_,
|
||||
plugin_rect_,
|
||||
deferred_clip_rect_,
|
||||
NULL,
|
||||
NULL));
|
||||
TransportDIB::Id(),
|
||||
TransportDIB::Id()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -319,8 +326,10 @@ void WebPluginDelegateProxy::InstallMissingPlugin() {
|
||||
void WebPluginDelegateProxy::OnMessageReceived(const IPC::Message& msg) {
|
||||
IPC_BEGIN_MESSAGE_MAP(WebPluginDelegateProxy, msg)
|
||||
IPC_MESSAGE_HANDLER(PluginHostMsg_SetWindow, OnSetWindow)
|
||||
#if defined(OS_WIN)
|
||||
IPC_MESSAGE_HANDLER(PluginHostMsg_SetWindowlessPumpEvent,
|
||||
OnSetWindowlessPumpEvent)
|
||||
#endif
|
||||
IPC_MESSAGE_HANDLER(PluginHostMsg_CancelResource, OnCancelResource)
|
||||
IPC_MESSAGE_HANDLER(PluginHostMsg_InvalidateRect, OnInvalidateRect)
|
||||
IPC_MESSAGE_HANDLER(PluginHostMsg_GetWindowScriptNPObject,
|
||||
@@ -359,8 +368,13 @@ void WebPluginDelegateProxy::UpdateGeometry(
|
||||
return;
|
||||
}
|
||||
|
||||
HANDLE transport_store_handle = NULL;
|
||||
HANDLE background_store_handle = NULL;
|
||||
// Be careful to explicitly call the default constructors for these ids,
|
||||
// as they can be POD on some platforms and we want them initialized.
|
||||
TransportDIB::Id transport_store_id = TransportDIB::Id();
|
||||
TransportDIB::Id background_store_id = TransportDIB::Id();
|
||||
|
||||
#if defined(OS_WIN)
|
||||
// TODO(port): use TransportDIB instead of allocating these directly.
|
||||
if (!backing_store_canvas_.get() ||
|
||||
(window_rect.width() != backing_store_canvas_->getDevice()->width() ||
|
||||
window_rect.height() != backing_store_canvas_->getDevice()->height())) {
|
||||
@@ -377,24 +391,32 @@ void WebPluginDelegateProxy::UpdateGeometry(
|
||||
return;
|
||||
}
|
||||
|
||||
transport_store_handle = transport_store_->handle();
|
||||
// TODO(port): once we use TransportDIB we will properly fill in these
|
||||
// ids; for now we just fill in the HANDLE field.
|
||||
transport_store_id.handle = transport_store_->handle();
|
||||
if (background_store_.get())
|
||||
background_store_handle = background_store_->handle();
|
||||
background_store_id.handle = background_store_->handle();
|
||||
}
|
||||
}
|
||||
#else
|
||||
// TODO(port): refactor our allocation of backing stores.
|
||||
NOTIMPLEMENTED();
|
||||
#endif
|
||||
|
||||
IPC::Message* msg = new PluginMsg_UpdateGeometry(
|
||||
instance_id_, window_rect, clip_rect,
|
||||
transport_store_handle, background_store_handle);
|
||||
transport_store_id, background_store_id);
|
||||
msg->set_unblock(true);
|
||||
Send(msg);
|
||||
}
|
||||
|
||||
#if defined(OS_WIN)
|
||||
// Copied from render_widget.cc
|
||||
static size_t GetPaintBufSize(const gfx::Rect& rect) {
|
||||
// TODO(darin): protect against overflow
|
||||
return 4 * rect.width() * rect.height();
|
||||
}
|
||||
#endif
|
||||
|
||||
void WebPluginDelegateProxy::ResetWindowlessBitmaps() {
|
||||
backing_store_.reset();
|
||||
@@ -408,7 +430,8 @@ void WebPluginDelegateProxy::ResetWindowlessBitmaps() {
|
||||
|
||||
bool WebPluginDelegateProxy::CreateBitmap(
|
||||
scoped_ptr<base::SharedMemory>* memory,
|
||||
scoped_ptr<skia::PlatformCanvasWin>* canvas) {
|
||||
scoped_ptr<skia::PlatformCanvas>* canvas) {
|
||||
#if defined(OS_WIN)
|
||||
size_t size = GetPaintBufSize(plugin_rect_);
|
||||
scoped_ptr<base::SharedMemory> new_shared_memory(new base::SharedMemory());
|
||||
if (!new_shared_memory->Create(L"", false, true, size))
|
||||
@@ -423,13 +446,19 @@ bool WebPluginDelegateProxy::CreateBitmap(
|
||||
memory->swap(new_shared_memory);
|
||||
canvas->swap(new_canvas);
|
||||
return true;
|
||||
#else
|
||||
// TODO(port): use TransportDIB properly.
|
||||
NOTIMPLEMENTED();
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
void WebPluginDelegateProxy::Paint(HDC hdc, const gfx::Rect& damaged_rect) {
|
||||
void WebPluginDelegateProxy::Paint(gfx::NativeDrawingContext context,
|
||||
const gfx::Rect& damaged_rect) {
|
||||
// If the plugin is no longer connected (channel crashed) draw a crashed
|
||||
// plugin bitmap
|
||||
if (!channel_host_->channel_valid()) {
|
||||
PaintSadPlugin(hdc, damaged_rect);
|
||||
PaintSadPlugin(context, damaged_rect);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -437,6 +466,8 @@ void WebPluginDelegateProxy::Paint(HDC hdc, const gfx::Rect& damaged_rect) {
|
||||
if (!windowless_)
|
||||
return;
|
||||
|
||||
// TODO(port): side-stepping some windowless plugin code for now.
|
||||
#if defined(OS_WIN)
|
||||
// We got a paint before the plugin's coordinates, so there's no buffer to
|
||||
// copy from.
|
||||
if (!backing_store_canvas_.get())
|
||||
@@ -447,12 +478,12 @@ void WebPluginDelegateProxy::Paint(HDC hdc, const gfx::Rect& damaged_rect) {
|
||||
gfx::Rect rect = damaged_rect.Intersect(plugin_rect_);
|
||||
|
||||
bool background_changed = false;
|
||||
if (background_store_canvas_.get() && BackgroundChanged(hdc, rect)) {
|
||||
if (background_store_canvas_.get() && BackgroundChanged(context, rect)) {
|
||||
background_changed = true;
|
||||
HDC background_hdc =
|
||||
background_store_canvas_->getTopPlatformDevice().getBitmapDC();
|
||||
BitBlt(background_hdc, rect.x()-plugin_rect_.x(), rect.y()-plugin_rect_.y(),
|
||||
rect.width(), rect.height(), hdc, rect.x(), rect.y(), SRCCOPY);
|
||||
rect.width(), rect.height(), context, rect.x(), rect.y(), SRCCOPY);
|
||||
}
|
||||
|
||||
gfx::Rect offset_rect = rect;
|
||||
@@ -463,7 +494,7 @@ void WebPluginDelegateProxy::Paint(HDC hdc, const gfx::Rect& damaged_rect) {
|
||||
}
|
||||
|
||||
HDC backing_hdc = backing_store_canvas_->getTopPlatformDevice().getBitmapDC();
|
||||
BitBlt(hdc, rect.x(), rect.y(), rect.width(), rect.height(), backing_hdc,
|
||||
BitBlt(context, rect.x(), rect.y(), rect.width(), rect.height(), backing_hdc,
|
||||
rect.x()-plugin_rect_.x(), rect.y()-plugin_rect_.y(), SRCCOPY);
|
||||
|
||||
if (invalidate_pending_) {
|
||||
@@ -473,8 +504,15 @@ void WebPluginDelegateProxy::Paint(HDC hdc, const gfx::Rect& damaged_rect) {
|
||||
invalidate_pending_ = false;
|
||||
Send(new PluginMsg_DidPaint(instance_id_));
|
||||
}
|
||||
#else
|
||||
// TODO(port): windowless plugin paint handling goes here.
|
||||
NOTIMPLEMENTED();
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(OS_WIN)
|
||||
// TODO(port): this should be portable; just avoiding windowless plugins for
|
||||
// now.
|
||||
bool WebPluginDelegateProxy::BackgroundChanged(
|
||||
HDC hdc,
|
||||
const gfx::Rect& rect) {
|
||||
@@ -519,8 +557,9 @@ bool WebPluginDelegateProxy::BackgroundChanged(
|
||||
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
void WebPluginDelegateProxy::Print(HDC hdc) {
|
||||
void WebPluginDelegateProxy::Print(gfx::NativeDrawingContext context) {
|
||||
base::SharedMemoryHandle shared_memory;
|
||||
size_t size;
|
||||
if (!Send(new PluginMsg_Print(instance_id_, &shared_memory, &size)))
|
||||
@@ -532,13 +571,18 @@ void WebPluginDelegateProxy::Print(HDC hdc) {
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined(OS_WIN)
|
||||
gfx::Emf emf;
|
||||
if (!emf.CreateFromData(memory.memory(), size)) {
|
||||
NOTREACHED();
|
||||
return;
|
||||
}
|
||||
// Playback the buffer.
|
||||
emf.Playback(hdc, NULL);
|
||||
emf.Playback(context, NULL);
|
||||
#else
|
||||
// TODO(port): plugin printing.
|
||||
NOTIMPLEMENTED();
|
||||
#endif
|
||||
}
|
||||
|
||||
NPObject* WebPluginDelegateProxy::GetPluginScriptableObject() {
|
||||
@@ -648,7 +692,7 @@ void WebPluginDelegateProxy::OnGetPluginElement(
|
||||
|
||||
// The stub will delete itself when the proxy tells it that it's released, or
|
||||
// otherwise when the channel is closed.
|
||||
NPObjectStub* stub = new NPObjectStub(
|
||||
new NPObjectStub(
|
||||
npobject, channel_host_.get(), route_id,
|
||||
render_view_->modal_dialog_event());
|
||||
*success = true;
|
||||
@@ -688,7 +732,9 @@ void WebPluginDelegateProxy::OnGetCPBrowsingContext(uint32* context) {
|
||||
*context = render_view_ ? render_view_->GetCPBrowsingContext() : 0;
|
||||
}
|
||||
|
||||
void WebPluginDelegateProxy::PaintSadPlugin(HDC hdc, const gfx::Rect& rect) {
|
||||
void WebPluginDelegateProxy::PaintSadPlugin(gfx::NativeDrawingContext hdc,
|
||||
const gfx::Rect& rect) {
|
||||
#if defined(OS_WIN)
|
||||
const int width = plugin_rect_.width();
|
||||
const int height = plugin_rect_.height();
|
||||
|
||||
@@ -713,19 +759,28 @@ void WebPluginDelegateProxy::PaintSadPlugin(HDC hdc, const gfx::Rect& rect) {
|
||||
|
||||
canvas.getTopPlatformDevice().drawToHDC(
|
||||
hdc, plugin_rect_.x(), plugin_rect_.y(), NULL);
|
||||
return;
|
||||
#else
|
||||
// TODO(port): it ought to be possible to refactor this to be shared between
|
||||
// platforms. It's just the final drawToHDC that kills us.
|
||||
NOTIMPLEMENTED();
|
||||
#endif
|
||||
}
|
||||
|
||||
void WebPluginDelegateProxy::CopyFromTransportToBacking(const gfx::Rect& rect) {
|
||||
if (!backing_store_canvas_.get())
|
||||
return;
|
||||
|
||||
#if defined(OS_WIN)
|
||||
// Copy the damaged rect from the transport bitmap to the backing store.
|
||||
HDC backing = backing_store_canvas_->getTopPlatformDevice().getBitmapDC();
|
||||
HDC transport = transport_store_canvas_->getTopPlatformDevice().getBitmapDC();
|
||||
BitBlt(backing, rect.x(), rect.y(), rect.width(), rect.height(),
|
||||
transport, rect.x(), rect.y(), SRCCOPY);
|
||||
backing_store_painted_ = backing_store_painted_.Union(rect);
|
||||
#else
|
||||
// TODO(port): probably some new code in TransportDIB should go here.
|
||||
NOTIMPLEMENTED();
|
||||
#endif
|
||||
}
|
||||
|
||||
void WebPluginDelegateProxy::OnHandleURLRequest(
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "base/ref_counted.h"
|
||||
#include "chrome/common/ipc_message.h"
|
||||
#include "chrome/renderer/plugin_channel_host.h"
|
||||
#include "skia/ext/platform_canvas.h"
|
||||
#include "webkit/glue/webplugin.h"
|
||||
#include "webkit/glue/webplugin_delegate.h"
|
||||
|
||||
@@ -27,10 +28,6 @@ class SharedMemory;
|
||||
class WaitableEvent;
|
||||
}
|
||||
|
||||
namespace skia {
|
||||
class PlatformCanvasWin;
|
||||
}
|
||||
|
||||
// An implementation of WebPluginDelegate that proxies all calls to
|
||||
// the plugin process.
|
||||
class WebPluginDelegateProxy : public WebPluginDelegate,
|
||||
@@ -57,8 +54,8 @@ class WebPluginDelegateProxy : public WebPluginDelegate,
|
||||
WebPlugin* plugin, bool load_manually);
|
||||
virtual void UpdateGeometry(const gfx::Rect& window_rect,
|
||||
const gfx::Rect& clip_rect);
|
||||
virtual void Paint(HDC hdc, const gfx::Rect& rect);
|
||||
virtual void Print(HDC hdc);
|
||||
virtual void Paint(gfx::NativeDrawingContext context, const gfx::Rect& rect);
|
||||
virtual void Print(gfx::NativeDrawingContext context);
|
||||
virtual NPObject* GetPluginScriptableObject();
|
||||
virtual void DidFinishLoadWithReason(NPReason reason);
|
||||
virtual void SetFocus();
|
||||
@@ -138,11 +135,16 @@ class WebPluginDelegateProxy : public WebPluginDelegate,
|
||||
intptr_t notify_data);
|
||||
|
||||
// Draw a graphic indicating a crashed plugin.
|
||||
void PaintSadPlugin(HDC hdc, const gfx::Rect& rect);
|
||||
void PaintSadPlugin(gfx::NativeDrawingContext context, const gfx::Rect& rect);
|
||||
|
||||
#if defined(OS_WIN)
|
||||
// Returns true if the given rectangle is different in the hdc and the
|
||||
// current background bitmap.
|
||||
bool BackgroundChanged(HDC hdc, const gfx::Rect& rect);
|
||||
#else
|
||||
// TODO(port): this should be portable; just avoiding windowless plugins for
|
||||
// now.
|
||||
#endif
|
||||
|
||||
// Copies the given rectangle from the transport bitmap to the backing store.
|
||||
void CopyFromTransportToBacking(const gfx::Rect& rect);
|
||||
@@ -152,7 +154,7 @@ class WebPluginDelegateProxy : public WebPluginDelegate,
|
||||
|
||||
// Creates a shared memory section and canvas.
|
||||
bool CreateBitmap(scoped_ptr<base::SharedMemory>* memory,
|
||||
scoped_ptr<skia::PlatformCanvasWin>* canvas);
|
||||
scoped_ptr<skia::PlatformCanvas>* canvas);
|
||||
|
||||
RenderView* render_view_;
|
||||
WebPlugin* plugin_;
|
||||
@@ -187,11 +189,11 @@ class WebPluginDelegateProxy : public WebPluginDelegate,
|
||||
// for transparent plugins, as they need the backgroud data during painting.
|
||||
bool transparent_;
|
||||
scoped_ptr<base::SharedMemory> backing_store_;
|
||||
scoped_ptr<skia::PlatformCanvasWin> backing_store_canvas_;
|
||||
scoped_ptr<skia::PlatformCanvas> backing_store_canvas_;
|
||||
scoped_ptr<base::SharedMemory> transport_store_;
|
||||
scoped_ptr<skia::PlatformCanvasWin> transport_store_canvas_;
|
||||
scoped_ptr<skia::PlatformCanvas> transport_store_canvas_;
|
||||
scoped_ptr<base::SharedMemory> background_store_;
|
||||
scoped_ptr<skia::PlatformCanvasWin> background_store_canvas_;
|
||||
scoped_ptr<skia::PlatformCanvas> background_store_canvas_;
|
||||
// This lets us know which portion of the backing store has been painted into.
|
||||
gfx::Rect backing_store_painted_;
|
||||
|
||||
|
||||
@@ -652,8 +652,10 @@ void WebPluginImpl::setFrameRect(const WebCore::IntRect& rect) {
|
||||
std::vector<gfx::Rect> cutout_rects;
|
||||
CalculateBounds(rect, &window_rect, &clip_rect, &cutout_rects);
|
||||
|
||||
// Notify the plugin that its parameters have changed.
|
||||
delegate_->UpdateGeometry(webkit_glue::FromIntRect(window_rect),
|
||||
webkit_glue::FromIntRect(clip_rect));
|
||||
|
||||
if (window_) {
|
||||
// Notify the window hosting the plugin (the WebViewDelegate) that
|
||||
// it needs to adjust the plugin, so that all the HWNDs can be moved
|
||||
|
||||
Referência em uma Nova Issue
Bloquear um usuário