diff options
author | jam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-03-26 19:40:29 +0000 |
---|---|---|
committer | jam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-03-26 19:40:29 +0000 |
commit | 3c8bd9f45bfeb09acc2fbad3407e7b2c14d7c7be (patch) | |
tree | a4e06819ca0c59659ff8d4538c51bdbfd18e0873 | |
parent | 096d5cdd6c7b6930ca4a59bb965b5e4f6647f8e0 (diff) | |
download | chromium_src-3c8bd9f45bfeb09acc2fbad3407e7b2c14d7c7be.zip chromium_src-3c8bd9f45bfeb09acc2fbad3407e7b2c14d7c7be.tar.gz chromium_src-3c8bd9f45bfeb09acc2fbad3407e7b2c14d7c7be.tar.bz2 |
Expose whether we're in private browsing mode to plugins.I chose to implement this for multi-process mode only and not --single-process or --in-process-plugins, since I wanted to send this data from the browser process, not the renderer (in case it's exploited).
BUG=158
Review URL: http://codereview.chromium.org/52037
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@12588 0039d316-1c4b-4281-b951-d872f2087c98
22 files changed, 199 insertions, 11 deletions
diff --git a/chrome/browser/plugin_process_host.cc b/chrome/browser/plugin_process_host.cc index 7168e36..890a387 100644 --- a/chrome/browser/plugin_process_host.cc +++ b/chrome/browser/plugin_process_host.cc @@ -613,7 +613,8 @@ void PluginProcessHost::RequestPluginChannel( // plugin process (i.e. unblocks a Send() call like a sync message) otherwise // a deadlock can occur if the plugin creation request from the renderer is // a result of a sync message by the plugin process. - PluginProcessMsg_CreateChannel* msg = new PluginProcessMsg_CreateChannel(); + PluginProcessMsg_CreateChannel* msg = new PluginProcessMsg_CreateChannel( + renderer_message_filter->off_the_record()); msg->set_unblock(true); if (Send(msg)) { sent_requests_.push(ChannelRequest( diff --git a/chrome/browser/renderer_host/resource_message_filter.cc b/chrome/browser/renderer_host/resource_message_filter.cc index 73f7154..92faa44 100644 --- a/chrome/browser/renderer_host/resource_message_filter.cc +++ b/chrome/browser/renderer_host/resource_message_filter.cc @@ -117,7 +117,8 @@ ResourceMessageFilter::ResourceMessageFilter( media_request_context_(profile->GetRequestContextForMedia()), profile_(profile), render_widget_helper_(render_widget_helper), - audio_renderer_host_(audio_renderer_host) { + audio_renderer_host_(audio_renderer_host), + off_the_record_(profile->IsOffTheRecord()) { DCHECK(request_context_.get()); DCHECK(request_context_->cookie_store()); DCHECK(media_request_context_.get()); diff --git a/chrome/browser/renderer_host/resource_message_filter.h b/chrome/browser/renderer_host/resource_message_filter.h index 8023d43..42650f2 100644 --- a/chrome/browser/renderer_host/resource_message_filter.h +++ b/chrome/browser/renderer_host/resource_message_filter.h @@ -94,6 +94,7 @@ class ResourceMessageFilter : public IPC::ChannelProxy::MessageFilter, return resource_dispatcher_host_; } MessageLoop* ui_loop() { return render_widget_helper_->ui_loop(); } + bool off_the_record() { return off_the_record_; } // NotificationObserver implementation. virtual void Observe(NotificationType type, @@ -269,6 +270,9 @@ class ResourceMessageFilter : public IPC::ChannelProxy::MessageFilter, // Object that should take care of audio related resource requests. scoped_refptr<AudioRendererHost> audio_renderer_host_; + // Whether this process is used for off the record tabs. + bool off_the_record_; + DISALLOW_COPY_AND_ASSIGN(ResourceMessageFilter); }; diff --git a/chrome/common/plugin_messages_internal.h b/chrome/common/plugin_messages_internal.h index 6aaca34..b9c7a58 100644 --- a/chrome/common/plugin_messages_internal.h +++ b/chrome/common/plugin_messages_internal.h @@ -13,7 +13,8 @@ IPC_BEGIN_MESSAGES(PluginProcess) // Tells the plugin process to create a new channel for communication with a // renderer. The channel name is returned in a // PluginProcessHostMsg_ChannelCreated message. - IPC_MESSAGE_CONTROL0(PluginProcessMsg_CreateChannel) + IPC_MESSAGE_CONTROL1(PluginProcessMsg_CreateChannel, + bool /* off_the_record */) IPC_MESSAGE_CONTROL1(PluginProcessMsg_ShutdownResponse, bool /* ok to shutdown */) diff --git a/chrome/plugin/plugin_channel.cc b/chrome/plugin/plugin_channel.cc index 675a46f..125054a 100644 --- a/chrome/plugin/plugin_channel.cc +++ b/chrome/plugin/plugin_channel.cc @@ -27,7 +27,7 @@ PluginChannel* PluginChannel::GetPluginChannel(MessageLoop* ipc_message_loop) { false)); } -PluginChannel::PluginChannel() : in_send_(0) { +PluginChannel::PluginChannel() : in_send_(0), off_the_record_(false) { SendUnblockingOnlyDuringDispatch(); PluginProcess::current()->AddRefProcess(); const CommandLine* command_line = CommandLine::ForCurrentProcess(); diff --git a/chrome/plugin/plugin_channel.h b/chrome/plugin/plugin_channel.h index 22ebbfa..94d18f9 100644 --- a/chrome/plugin/plugin_channel.h +++ b/chrome/plugin/plugin_channel.h @@ -26,6 +26,9 @@ class PluginChannel : public PluginChannelBase { bool in_send() { return in_send_ != 0; } + bool off_the_record() { return off_the_record_; } + void set_off_the_record(bool value) { off_the_record_ = value; } + protected: // IPC::Channel::Listener implementation: virtual void OnChannelConnected(int32 peer_pid); @@ -52,6 +55,7 @@ class PluginChannel : public PluginChannelBase { int in_send_; // Tracks if we're in a Send call. bool log_messages_; // True if we should log sent and received messages. + bool off_the_record_; // True if the renderer is in off the record mode. DISALLOW_EVIL_CONSTRUCTORS(PluginChannel); }; diff --git a/chrome/plugin/plugin_thread.cc b/chrome/plugin/plugin_thread.cc index 5f26f71..10172e7 100644 --- a/chrome/plugin/plugin_thread.cc +++ b/chrome/plugin/plugin_thread.cc @@ -88,12 +88,14 @@ void PluginThread::CleanUp() { ChildThread::CleanUp(); } -void PluginThread::OnCreateChannel() { +void PluginThread::OnCreateChannel(bool off_the_record) { std::wstring channel_name; scoped_refptr<PluginChannel> channel = PluginChannel::GetPluginChannel(owner_loop()); - if (channel.get()) + if (channel.get()) { channel_name = channel->channel_name(); + channel->set_off_the_record(off_the_record); + } Send(new PluginProcessHostMsg_ChannelCreated(channel_name)); } diff --git a/chrome/plugin/plugin_thread.h b/chrome/plugin/plugin_thread.h index bcf926f..1550d5a 100644 --- a/chrome/plugin/plugin_thread.h +++ b/chrome/plugin/plugin_thread.h @@ -29,7 +29,7 @@ class PluginThread : public ChildThread { virtual void Init(); virtual void CleanUp(); - void OnCreateChannel(); + void OnCreateChannel(bool off_the_record); void OnShutdownResponse(bool ok_to_shutdown); void OnPluginMessage(const std::vector<uint8> &data); void OnBrowserShutdown(); diff --git a/chrome/plugin/webplugin_proxy.cc b/chrome/plugin/webplugin_proxy.cc index dbe9b5a..38310fb 100644 --- a/chrome/plugin/webplugin_proxy.cc +++ b/chrome/plugin/webplugin_proxy.cc @@ -439,3 +439,7 @@ void WebPluginProxy::OnPaint(const gfx::Rect& damaged_rect) { Paint(damaged_rect); Send(new PluginHostMsg_InvalidateRect(route_id_, damaged_rect)); } + +bool WebPluginProxy::IsOffTheRecord() { + return channel_->off_the_record(); +} diff --git a/chrome/plugin/webplugin_proxy.h b/chrome/plugin/webplugin_proxy.h index 78ca43c..cba1ac5 100644 --- a/chrome/plugin/webplugin_proxy.h +++ b/chrome/plugin/webplugin_proxy.h @@ -94,6 +94,8 @@ class WebPluginProxy : public WebPlugin { bool notify_needed, HANDLE notify_data); + bool IsOffTheRecord(); + base::WaitableEvent* modal_dialog_event() { return modal_dialog_event_.get(); } diff --git a/chrome/test/data/npapi/private.html b/chrome/test/data/npapi/private.html new file mode 100644 index 0000000..46cacde --- /dev/null +++ b/chrome/test/data/npapi/private.html @@ -0,0 +1,25 @@ +<html> + +<head> +<script src="npapi.js"></script> +</head> + + +<body> +<div id="statusPanel" style="border: 1px solid red; width: 100%"> +Test running.... +</div> + + +NPAPI Private Mode test<p> +Tests that a plugin can query the private browsing mode.<P> + +<embed type="application/vnd.npapi-test" + src="foo" + name="private" + id="1" + mode="np_embed" +> + +</body> +</html> diff --git a/chrome/test/ui/npapi_test_helper.cc b/chrome/test/ui/npapi_test_helper.cc index c6753d0..859d3df 100644 --- a/chrome/test/ui/npapi_test_helper.cc +++ b/chrome/test/ui/npapi_test_helper.cc @@ -31,6 +31,8 @@ #include "chrome/test/ui/npapi_test_helper.h" +#include "chrome/common/chrome_switches.h" + NPAPITester::NPAPITester() : UITest() { } @@ -59,3 +61,9 @@ void NPAPIVisiblePluginTester::SetUp() { show_window_ = true; NPAPITester::SetUp(); } + +// NPAPIIncognitoTester members. +void NPAPIIncognitoTester::SetUp() { + launch_arguments_.AppendSwitch(switches::kIncognito); + NPAPITester::SetUp(); +} diff --git a/chrome/test/ui/npapi_test_helper.h b/chrome/test/ui/npapi_test_helper.h index 26f4c67..7b79e0e 100644 --- a/chrome/test/ui/npapi_test_helper.h +++ b/chrome/test/ui/npapi_test_helper.h @@ -46,3 +46,9 @@ class NPAPIVisiblePluginTester : public NPAPITester { protected: virtual void SetUp(); }; + +// Helper class for NPAPI plugin UI tests which use incognito mode. +class NPAPIIncognitoTester : public NPAPITester { + protected: + virtual void SetUp(); +}; diff --git a/chrome/test/ui/npapi_uitest.cpp b/chrome/test/ui/npapi_uitest.cpp index 8d808be..7826878 100644 --- a/chrome/test/ui/npapi_uitest.cpp +++ b/chrome/test/ui/npapi_uitest.cpp @@ -76,7 +76,6 @@ TEST_F(NPAPITester, Arguments) { kTestCompleteSuccess, kShortWaitTimeout); } - // Test invoking many plugins within a single page. TEST_F(NPAPITester, ManyPlugins) { std::wstring test_case = L"many_plugins.html"; @@ -134,7 +133,6 @@ TEST_F(NPAPITester, GetJavaScriptURL) { kTestCompleteSuccess, kShortWaitTimeout); } - // Tests that if an NPObject is proxies back to its original process, the // original pointer is returned and not a proxy. If this fails the plugin // will crash. @@ -261,3 +259,25 @@ TEST_F(NPAPIVisiblePluginTester, OpenPopupWindowWithPlugin) { kTestCompleteCookie, kTestCompleteSuccess, action_timeout_ms()); } + +// Test checking the privacy mode is off. +TEST_F(NPAPITester, PrivateDisabled) { + if (UITest::in_process_renderer()) + return; + + GURL url = GetTestUrl(L"npapi", L"private.html"); + NavigateToURL(url); + WaitForFinish("private", "1", url, kTestCompleteCookie, + kTestCompleteSuccess, kShortWaitTimeout); +} + +// Test checking the privacy mode is on. +TEST_F(NPAPIIncognitoTester, PrivateEnabled) { + if (UITest::in_process_renderer()) + return; + + GURL url = GetTestUrl(L"npapi", L"private.html?secure"); + NavigateToURL(url); + WaitForFinish("private", "1", url, kTestCompleteCookie, + kTestCompleteSuccess, kShortWaitTimeout); +} diff --git a/third_party/npapi/bindings/npapi.h b/third_party/npapi/bindings/npapi.h index 27492d7..1035aa3 100644 --- a/third_party/npapi/bindings/npapi.h +++ b/third_party/npapi/bindings/npapi.h @@ -466,7 +466,9 @@ typedef enum { /* Get the NPObject wrapper for the plugins DOM element. */ NPNVPluginElementNPObject = 16, - NPNVSupportsWindowless = 17 + NPNVSupportsWindowless = 17, + + NPNVprivateModeBool = 18 #ifdef XP_MACOSX /* Used for negotiating drawing models */ diff --git a/webkit/glue/plugins/plugin_host.cc b/webkit/glue/plugins/plugin_host.cc index 2ecb48f..b0c199a 100644 --- a/webkit/glue/plugins/plugin_host.cc +++ b/webkit/glue/plugins/plugin_host.cc @@ -781,6 +781,14 @@ NPError NPN_GetValue(NPP id, NPNVariable variable, void *value) { rv = NPERR_NO_ERROR; break; } + case NPNVprivateModeBool: + { + NPBool* private_mode = reinterpret_cast<NPBool*>(value); + scoped_refptr<NPAPI::PluginInstance> plugin = FindInstance(id); + *private_mode = plugin->webplugin()->IsOffTheRecord(); + rv = NPERR_NO_ERROR; + break; + } case default_plugin::kMissingPluginStatusStart + default_plugin::MISSING_PLUGIN_AVAILABLE: // fall through diff --git a/webkit/glue/plugins/test/npapi_test_plugin.vcproj b/webkit/glue/plugins/test/npapi_test_plugin.vcproj index d52bba8..426885d 100644 --- a/webkit/glue/plugins/test/npapi_test_plugin.vcproj +++ b/webkit/glue/plugins/test/npapi_test_plugin.vcproj @@ -239,6 +239,14 @@ > </File> <File + RelativePath=".\plugin_private_test.cc" + > + </File> + <File + RelativePath=".\plugin_private_test.h" + > + </File> + <File RelativePath=".\plugin_test.cc" > </File> diff --git a/webkit/glue/plugins/test/plugin_client.cc b/webkit/glue/plugins/test/plugin_client.cc index e9cad4e..7b00e7c 100644 --- a/webkit/glue/plugins/test/plugin_client.cc +++ b/webkit/glue/plugins/test/plugin_client.cc @@ -9,11 +9,12 @@ #include "webkit/glue/plugins/test/plugin_execute_script_delete_test.h" #include "webkit/glue/plugins/test/plugin_get_javascript_url_test.h" #include "webkit/glue/plugins/test/plugin_geturl_test.h" +#include "webkit/glue/plugins/test/plugin_javascript_open_popup.h" #include "webkit/glue/plugins/test/plugin_new_fails_test.h" +#include "webkit/glue/plugins/test/plugin_private_test.h" #include "webkit/glue/plugins/test/plugin_npobject_lifetime_test.h" #include "webkit/glue/plugins/test/plugin_npobject_proxy_test.h" #include "webkit/glue/plugins/test/plugin_window_size_test.h" -#include "webkit/glue/plugins/test/plugin_javascript_open_popup.h" #include "third_party/npapi/bindings/npapi.h" #include "third_party/npapi/bindings/npruntime.h" @@ -142,6 +143,9 @@ NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16 mode, new_test = new NPAPIClient::ExecuteScriptDeleteTest(instance, NPAPIClient::PluginClient::HostFunctions(), argv[name_index]); windowless_plugin = true; + } else if (base::strcasecmp(argv[name_index], "private") == 0) { + new_test = new NPAPIClient::PrivateTest(instance, + NPAPIClient::PluginClient::HostFunctions()); } else { // If we don't have a test case for this, create a // generic one which basically never fails. diff --git a/webkit/glue/plugins/test/plugin_private_test.cc b/webkit/glue/plugins/test/plugin_private_test.cc new file mode 100644 index 0000000..65bbd89 --- /dev/null +++ b/webkit/glue/plugins/test/plugin_private_test.cc @@ -0,0 +1,57 @@ +// Copyright (c) 2009 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. + +#include "webkit/glue/plugins/test/plugin_private_test.h" + +#include "base/basictypes.h" +#include "base/string_util.h" +#include "webkit/glue/plugins/test/plugin_client.h" + +namespace NPAPIClient { + +PrivateTest::PrivateTest(NPP id, NPNetscapeFuncs *host_functions) + : PluginTest(id, host_functions) { +} + +NPError PrivateTest::New(uint16 mode, int16 argc, + const char* argn[], const char* argv[], + NPSavedData* saved) { + PluginTest::New(mode, argc, argn, argv, saved); + + NPBool private_mode = 0; + NPNetscapeFuncs* browser = NPAPIClient::PluginClient::HostFunctions(); + NPError result = browser->getvalue( + id(), NPNVprivateModeBool, &private_mode); + if (result != NPERR_NO_ERROR) { + SetError("Failed to read NPNVprivateModeBool value."); + } else { + NPIdentifier location = HostFunctions()->getstringidentifier("location"); + NPIdentifier href = HostFunctions()->getstringidentifier("href"); + + NPObject *window_obj = NULL; + HostFunctions()->getvalue(id(), NPNVWindowNPObject, &window_obj); + + NPVariant location_var; + HostFunctions()->getproperty(id(), window_obj, location, &location_var); + + NPVariant href_var; + HostFunctions()->getproperty(id(), NPVARIANT_TO_OBJECT(location_var), href, + &href_var); + std::string href_str(href_var.value.stringValue.UTF8Characters, + href_var.value.stringValue.UTF8Length); + bool private_expected = href_str.find("?private") != href_str.npos; + if (private_expected != private_expected) + SetError("NPNVprivateModeBool returned incorrect value."); + + HostFunctions()->releasevariantvalue(&href_var); + HostFunctions()->releasevariantvalue(&location_var); + HostFunctions()->releaseobject(window_obj); + } + + SignalTestCompleted(); + + return NPERR_NO_ERROR; +} + +} // namespace NPAPIClient diff --git a/webkit/glue/plugins/test/plugin_private_test.h b/webkit/glue/plugins/test/plugin_private_test.h new file mode 100644 index 0000000..db6b5d1 --- /dev/null +++ b/webkit/glue/plugins/test/plugin_private_test.h @@ -0,0 +1,25 @@ +// Copyright (c) 2009 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. + +#ifndef WEBKIT_PORT_PLUGINS_TEST_PLUGIN_PRIVATE_TEST_H_ +#define WEBKIT_PORT_PLUGINS_TEST_PLUGIN_PRIVATE_TEST_H_ + +#include "webkit/glue/plugins/test/plugin_test.h" + +namespace NPAPIClient { + +// The PluginPrivateTest tests that a plugin can query if the browser is in +// private browsing mode. +class PrivateTest : public PluginTest { + public: + PrivateTest(NPP id, NPNetscapeFuncs *host_functions); + + // Initialize this PluginTest based on the arguments from NPP_New. + virtual NPError New(uint16 mode, int16 argc, const char* argn[], + const char* argv[], NPSavedData* saved); +}; + +} // namespace NPAPIClient + +#endif // WEBKIT_PORT_PLUGINS_TEST_PLUGIN_PRIVATE_TEST_H_ diff --git a/webkit/glue/webplugin.h b/webkit/glue/webplugin.h index 814839a..f78deaa 100644 --- a/webkit/glue/webplugin.h +++ b/webkit/glue/webplugin.h @@ -144,6 +144,9 @@ class WebPlugin { bool notify_needed, HANDLE notify_data) = 0; + // Returns true iff in off the record (Incognito) mode. + virtual bool IsOffTheRecord() = 0; + private: DISALLOW_EVIL_CONSTRUCTORS(WebPlugin); }; diff --git a/webkit/glue/webplugin_impl.h b/webkit/glue/webplugin_impl.h index 02d9357..8e0b6d2 100644 --- a/webkit/glue/webplugin_impl.h +++ b/webkit/glue/webplugin_impl.h @@ -297,6 +297,9 @@ class WebPluginImpl : public WebPlugin, HANDLE existing_stream, bool notify_needed, HANDLE notify_data); + // Ignore in-process plugins mode for this flag. + bool IsOffTheRecord() { return false; } + // Handles HTTP multipart responses, i.e. responses received with a HTTP // status code of 206. void HandleHttpMultipartResponse(const WebCore::ResourceResponse& response, |