diff options
author | Iain Merrick <husky@google.com> | 2010-11-01 12:19:54 +0000 |
---|---|---|
committer | Iain Merrick <husky@google.com> | 2010-11-03 10:21:10 +0000 |
commit | 731df977c0511bca2206b5f333555b1205ff1f43 (patch) | |
tree | 0e750b949b3f00a1ac11fda25d3c2de512f2b465 /webkit | |
parent | 5add15e10e7bb80512f2c597ca57221314abe577 (diff) | |
download | external_chromium-731df977c0511bca2206b5f333555b1205ff1f43.zip external_chromium-731df977c0511bca2206b5f333555b1205ff1f43.tar.gz external_chromium-731df977c0511bca2206b5f333555b1205ff1f43.tar.bz2 |
Merge Chromium at r63472 : Initial merge by git.
Change-Id: Ifb9ee821af006a5f2211e81471be93ae440a1f5a
Diffstat (limited to 'webkit')
126 files changed, 3993 insertions, 1379 deletions
diff --git a/webkit/glue/dom_operations.cc b/webkit/glue/dom_operations.cc index 22e0e75..aab6f36 100644 --- a/webkit/glue/dom_operations.cc +++ b/webkit/glue/dom_operations.cc @@ -190,6 +190,9 @@ static bool FillFormImpl(FormElements* fe, const FormData& data) { (!element.isEnabledFormControl() || element.hasAttribute("readonly"))) { continue; // Don't fill uneditable password fields. } + if (!element.isValidValue(data_map[it->first])) + continue; + element.setValue(data_map[it->first]); element.setAutofilled(true); element.dispatchFormControlChangeEvent(); @@ -425,6 +428,10 @@ static gfx::Size ParseIconSize(const string16& text) { ParseSingleIconSize(sizes[1])); } +WebApplicationInfo::WebApplicationInfo() {} + +WebApplicationInfo::~WebApplicationInfo() {} + bool ParseIconSizes(const string16& text, std::vector<gfx::Size>* sizes, bool* is_any) { diff --git a/webkit/glue/dom_operations.h b/webkit/glue/dom_operations.h index 20084f7..1b6151b 100644 --- a/webkit/glue/dom_operations.h +++ b/webkit/glue/dom_operations.h @@ -64,6 +64,9 @@ bool GetAllSavableResourceLinksForCurrentPage(WebKit::WebView* view, // Structure used when installing a web page as an app. Populated via // GetApplicationInfo. struct WebApplicationInfo { + WebApplicationInfo(); + ~WebApplicationInfo(); + struct IconInfo { GURL url; int width; @@ -134,10 +137,11 @@ WebKit::WebString GetSubResourceLinkFromElement( // Puts the meta-elements of |document| that have the attribute |attribute_name| // with a value of |attribute_value| in |meta_elements|. -void GetMetaElementsWithAttribute(WebKit::WebDocument* document, - const string16& attribute_name, - const string16& atribute_value, - std::vector<WebKit::WebElement>* meta_elements); +void GetMetaElementsWithAttribute( + WebKit::WebDocument* document, + const string16& attribute_name, + const string16& atribute_value, + std::vector<WebKit::WebElement>* meta_elements); } // namespace webkit_glue diff --git a/webkit/glue/form_field.h b/webkit/glue/form_field.h index 56d8969..1ed8d68 100644 --- a/webkit/glue/form_field.h +++ b/webkit/glue/form_field.h @@ -22,7 +22,7 @@ class FormField { const string16& value, const string16& form_control_type, int size); - ~FormField(); + virtual ~FormField(); const string16& label() const { return label_; } const string16& name() const { return name_; } @@ -67,7 +67,7 @@ class FormField { }; // So we can compare FormFields with EXPECT_EQ(). -std::ostream& operator<<(std::ostream& os, const FormField& profile); +std::ostream& operator<<(std::ostream& os, const FormField& field); } // namespace webkit_glue diff --git a/webkit/glue/glue_serialize_unittest.cc b/webkit/glue/glue_serialize_unittest.cc index 34ce09f..342696d 100644 --- a/webkit/glue/glue_serialize_unittest.cc +++ b/webkit/glue/glue_serialize_unittest.cc @@ -11,9 +11,9 @@ #include "third_party/WebKit/WebKit/chromium/public/WebPoint.h" #include "third_party/WebKit/WebKit/chromium/public/WebVector.h" #include "webkit/glue/glue_serialize.h" +#include "webkit/glue/web_io_operators.h" using WebKit::WebData; -using WebKit::WebFileInfo; using WebKit::WebHistoryItem; using WebKit::WebHTTPBody; using WebKit::WebPoint; diff --git a/webkit/glue/idb_bindings.cc b/webkit/glue/idb_bindings.cc index fd26130..4af085f 100644 --- a/webkit/glue/idb_bindings.cc +++ b/webkit/glue/idb_bindings.cc @@ -20,35 +20,11 @@ using WebKit::WebIDBKey; using WebKit::WebIDBKeyPath; using WebKit::WebSerializedScriptValue; -namespace { - -class LocalContext { - public: - LocalContext() - : context_(v8::Context::New()) { - context_->Enter(); - } - - virtual ~LocalContext() { - context_->Exit(); - context_.Dispose(); - } - - private: - v8::Locker lock_; - v8::HandleScope scope_; - v8::Persistent<v8::Context> context_; - - DISALLOW_COPY_AND_ASSIGN(LocalContext); -}; - -} // namespace - bool IDBKeysFromValuesAndKeyPath( const std::vector<WebSerializedScriptValue>& serialized_script_values, const string16& idb_key_path, std::vector<WebIDBKey>* values) { - LocalContext env; + v8::Locker lock; WebIDBKeyPath web_idb_key_path = WebIDBKeyPath::create(idb_key_path); bool error = web_idb_key_path.parseError() != 0; // TODO(bulach): what to do when we have a parse error? For now, setting diff --git a/webkit/glue/media/buffered_data_source.cc b/webkit/glue/media/buffered_data_source.cc index f4aad57..3456e3a 100644 --- a/webkit/glue/media/buffered_data_source.cc +++ b/webkit/glue/media/buffered_data_source.cc @@ -235,7 +235,7 @@ void BufferedResourceLoader::SetAllowDefer(bool is_allowed) { // webkit_glue::ResourceLoaderBridge::Peer implementations bool BufferedResourceLoader::OnReceivedRedirect( const GURL& new_url, - const webkit_glue::ResourceLoaderBridge::ResponseInfo& info, + const webkit_glue::ResourceResponseInfo& info, bool* has_new_first_party_for_cookies, GURL* new_first_party_for_cookies) { DCHECK(bridge_.get()); @@ -259,7 +259,7 @@ bool BufferedResourceLoader::OnReceivedRedirect( } void BufferedResourceLoader::OnReceivedResponse( - const webkit_glue::ResourceLoaderBridge::ResponseInfo& info, + const webkit_glue::ResourceResponseInfo& info, bool content_filtered) { DCHECK(bridge_.get()); @@ -479,7 +479,7 @@ void BufferedResourceLoader::ReadInternal() { } bool BufferedResourceLoader::VerifyPartialResponse( - const ResourceLoaderBridge::ResponseInfo& info) { + const ResourceResponseInfo& info) { int64 first_byte_position, last_byte_position, instance_size; if (!info.headers->GetContentRange(&first_byte_position, &last_byte_position, @@ -560,7 +560,8 @@ BufferedDataSource::BufferedDataSource( render_loop_(render_loop), stop_signal_received_(false), stopped_on_render_loop_(false), - media_is_paused_(true) { + media_is_paused_(true), + using_range_request_(true) { } BufferedDataSource::~BufferedDataSource() { @@ -879,6 +880,17 @@ void BufferedDataSource::HttpInitialStartCallback(int error) { loader_->Stop(); } + if (error == net::ERR_INVALID_RESPONSE && using_range_request_) { + // Assuming that the Range header was causing the problem. Retry without + // the Range header. + using_range_request_ = false; + loader_ = CreateResourceLoader(-1, -1); + loader_->Start( + NewCallback(this, &BufferedDataSource::HttpInitialStartCallback), + NewCallback(this, &BufferedDataSource::NetworkEventCallback)); + return; + } + // We need to prevent calling to filter host and running the callback if // we have received the stop signal. We need to lock down the whole callback // method to prevent bad things from happening. The reason behind this is diff --git a/webkit/glue/media/buffered_data_source.h b/webkit/glue/media/buffered_data_source.h index b520418..e7b2e47 100644 --- a/webkit/glue/media/buffered_data_source.h +++ b/webkit/glue/media/buffered_data_source.h @@ -110,11 +110,11 @@ class BufferedResourceLoader : virtual void OnUploadProgress(uint64 position, uint64 size) {} virtual bool OnReceivedRedirect( const GURL& new_url, - const webkit_glue::ResourceLoaderBridge::ResponseInfo& info, + const webkit_glue::ResourceResponseInfo& info, bool* has_new_first_party_for_cookies, GURL* new_first_party_for_cookies); virtual void OnReceivedResponse( - const webkit_glue::ResourceLoaderBridge::ResponseInfo& info, + const webkit_glue::ResourceResponseInfo& info, bool content_filtered); virtual void OnDownloadedData(int len) {} virtual void OnReceivedData(const char* data, int len); @@ -150,7 +150,7 @@ class BufferedResourceLoader : void ReadInternal(); // If we have made a range request, verify the response from the server. - bool VerifyPartialResponse(const ResourceLoaderBridge::ResponseInfo& info); + bool VerifyPartialResponse(const ResourceResponseInfo& info); // Done with read. Invokes the read callback and reset parameters for the // read request. @@ -406,6 +406,10 @@ class BufferedDataSource : public media::DataSource { // the message loop doesn't hold a reference for the watch dog task. base::RepeatingTimer<BufferedDataSource> watch_dog_timer_; + // Keeps track of whether we used a Range header in the initialization + // request. + bool using_range_request_; + DISALLOW_COPY_AND_ASSIGN(BufferedDataSource); }; diff --git a/webkit/glue/media/buffered_data_source_unittest.cc b/webkit/glue/media/buffered_data_source_unittest.cc index 7254c92..f032595 100644 --- a/webkit/glue/media/buffered_data_source_unittest.cc +++ b/webkit/glue/media/buffered_data_source_unittest.cc @@ -29,6 +29,7 @@ using ::testing::NotNull; using ::testing::Return; using ::testing::SetArgumentPointee; using ::testing::StrictMock; +using ::testing::NiceMock; using ::testing::WithArgs; namespace { @@ -99,7 +100,7 @@ class BufferedResourceLoaderTest : public testing::Test { void FullResponse(int64 instance_size) { EXPECT_CALL(*this, StartCallback(net::OK)); - ResourceLoaderBridge::ResponseInfo info; + ResourceResponseInfo info; std::string header = base::StringPrintf("HTTP/1.1 200 OK\n" "Content-Length: %" PRId64, instance_size); @@ -116,7 +117,7 @@ class BufferedResourceLoaderTest : public testing::Test { int64 instance_size) { EXPECT_CALL(*this, StartCallback(net::OK)); int64 content_length = last_position - first_position + 1; - ResourceLoaderBridge::ResponseInfo info; + ResourceResponseInfo info; std::string header = base::StringPrintf("HTTP/1.1 206 Partial Content\n" "Content-Range: bytes " "%" PRId64 "-%" PRId64 "/%" PRId64, @@ -213,7 +214,7 @@ TEST_F(BufferedResourceLoaderTest, MissingHttpHeader) { EXPECT_CALL(*bridge_, OnDestroy()) .WillOnce(Invoke(this, &BufferedResourceLoaderTest::ReleaseBridge)); - ResourceLoaderBridge::ResponseInfo info; + ResourceResponseInfo info; loader_->OnReceivedResponse(info, false); } @@ -228,7 +229,7 @@ TEST_F(BufferedResourceLoaderTest, BadHttpResponse) { EXPECT_CALL(*bridge_, OnDestroy()) .WillOnce(Invoke(this, &BufferedResourceLoaderTest::ReleaseBridge)); - ResourceLoaderBridge::ResponseInfo info; + ResourceResponseInfo info; info.headers = new net::HttpResponseHeaders("HTTP/1.1 404 Not Found\n"); loader_->OnReceivedResponse(info, false); } @@ -268,7 +269,7 @@ TEST_F(BufferedResourceLoaderTest, InvalidPartialResponse) { EXPECT_CALL(*bridge_, OnDestroy()) .WillOnce(Invoke(this, &BufferedResourceLoaderTest::ReleaseBridge)); - ResourceLoaderBridge::ResponseInfo info; + ResourceResponseInfo info; std::string header = base::StringPrintf("HTTP/1.1 206 Partial Content\n" "Content-Range: bytes %d-%d/%d", 1, 10, 1024); @@ -597,6 +598,17 @@ class BufferedDataSourceTest : public testing::Test { } } + void ExpectCreateAndStartResourceLoader(int start_error) { + EXPECT_CALL(*data_source_, CreateResourceLoader(_, _)) + .WillOnce(Return(loader_.get())); + + EXPECT_CALL(*loader_, Start(NotNull(), NotNull())) + .WillOnce( + DoAll(Assign(&error_, start_error), + Invoke(this, + &BufferedDataSourceTest::InvokeStartCallback))); + } + void InitializeDataSource(const char* url, int error, bool partial_response, int64 instance_size, NetworkState networkState) { @@ -613,21 +625,34 @@ class BufferedDataSourceTest : public testing::Test { // There is no need to provide a message loop to data source. data_source_->set_host(&host_); + scoped_refptr<NiceMock<MockBufferedResourceLoader> > first_loader = + new NiceMock<MockBufferedResourceLoader>(); + // Creates the mock loader to be injected. - loader_ = new StrictMock<MockBufferedResourceLoader>(); + loader_ = first_loader; + bool initialized_ok = (error == net::OK); bool loaded = networkState == LOADED; { InSequence s; - EXPECT_CALL(*data_source_, CreateResourceLoader(_, _)) - .WillOnce(Return(loader_.get())); - - // The initial response loader will be started. - EXPECT_CALL(*loader_, Start(NotNull(), NotNull())) - .WillOnce( - DoAll(Assign(&error_, error), - Invoke(this, - &BufferedDataSourceTest::InvokeStartCallback))); + ExpectCreateAndStartResourceLoader(error); + + // In the case of an invalid partial response we expect a second loader + // to be created. + if (partial_response && (error == net::ERR_INVALID_RESPONSE)) { + // Verify that the initial loader is stopped. + EXPECT_CALL(*loader_, Stop()); + + // Replace loader_ with a new instance. + loader_ = new NiceMock<MockBufferedResourceLoader>(); + + // Create and start Make sure Start() is called the new loader. + ExpectCreateAndStartResourceLoader(net::OK); + + // Update initialization variable since we know the second loader will + // return OK. + initialized_ok = true; + } } StrictMock<media::MockFilterCallback> callback; @@ -635,7 +660,7 @@ class BufferedDataSourceTest : public testing::Test { .WillRepeatedly(Return(instance_size)); EXPECT_CALL(*loader_, partial_response()) .WillRepeatedly(Return(partial_response)); - if (error == net::OK) { + if (initialized_ok) { // Expected loaded or not. EXPECT_CALL(host_, SetLoaded(loaded)); @@ -663,7 +688,7 @@ class BufferedDataSourceTest : public testing::Test { data_source_->Initialize(url, callback.NewCallback()); message_loop_->RunAllPending(); - if (error == net::OK) { + if (initialized_ok) { // Verify the size of the data source. int64 size; if (instance_size != -1 && (loaded || partial_response)) { @@ -746,8 +771,8 @@ class BufferedDataSourceTest : public testing::Test { } // 2. Then the current loader will be stop and destroyed. - StrictMock<MockBufferedResourceLoader> *new_loader = - new StrictMock<MockBufferedResourceLoader>(); + NiceMock<MockBufferedResourceLoader> *new_loader = + new NiceMock<MockBufferedResourceLoader>(); EXPECT_CALL(*data_source_, CreateResourceLoader(position, -1)) .WillOnce(Return(new_loader)); @@ -810,8 +835,8 @@ class BufferedDataSourceTest : public testing::Test { } // 2. Then the current loader will be stop and destroyed. - StrictMock<MockBufferedResourceLoader> *new_loader = - new StrictMock<MockBufferedResourceLoader>(); + NiceMock<MockBufferedResourceLoader> *new_loader = + new NiceMock<MockBufferedResourceLoader>(); EXPECT_CALL(*data_source_, CreateResourceLoader(position, -1)) .WillOnce(Return(new_loader)); @@ -853,7 +878,7 @@ class BufferedDataSourceTest : public testing::Test { scoped_ptr<StrictMock<MockMediaResourceLoaderBridgeFactory> > bridge_factory_; - scoped_refptr<StrictMock<MockBufferedResourceLoader> > loader_; + scoped_refptr<NiceMock<MockBufferedResourceLoader> > loader_; scoped_refptr<MockBufferedDataSource> data_source_; scoped_refptr<media::FilterFactory> factory_; @@ -889,6 +914,13 @@ TEST_F(BufferedDataSourceTest, RangeRequestNotSupported) { StopDataSource(); } +// Test the case where we get a 206 response, but no Content-Range header. +TEST_F(BufferedDataSourceTest, MissingContentRange) { + InitializeDataSource(kHttpUrl, net::ERR_INVALID_RESPONSE, true, 1024, + LOADING); + StopDataSource(); +} + TEST_F(BufferedDataSourceTest, MissingContentLengthAndRangeRequestNotSupported) { InitializeDataSource(kHttpUrl, net::OK, false, -1, LOADING); diff --git a/webkit/glue/media/media_resource_loader_bridge_factory.cc b/webkit/glue/media/media_resource_loader_bridge_factory.cc index 9d8d547..3fb9d65 100644 --- a/webkit/glue/media/media_resource_loader_bridge_factory.cc +++ b/webkit/glue/media/media_resource_loader_bridge_factory.cc @@ -32,6 +32,8 @@ MediaResourceLoaderBridgeFactory::MediaResourceLoaderBridgeFactory( routing_id_(routing_id) { } +MediaResourceLoaderBridgeFactory::~MediaResourceLoaderBridgeFactory() {} + ResourceLoaderBridge* MediaResourceLoaderBridgeFactory::CreateBridge( const GURL& url, int load_flags, @@ -54,6 +56,8 @@ ResourceLoaderBridge* MediaResourceLoaderBridgeFactory::CreateBridge( return webkit_glue::ResourceLoaderBridge::Create(request_info); } +MediaResourceLoaderBridgeFactory::MediaResourceLoaderBridgeFactory() {} + // static const std::string MediaResourceLoaderBridgeFactory::GenerateHeaders ( int64 first_byte_position, int64 last_byte_position) { diff --git a/webkit/glue/media/media_resource_loader_bridge_factory.h b/webkit/glue/media/media_resource_loader_bridge_factory.h index 5f09235..ccacdc6 100644 --- a/webkit/glue/media/media_resource_loader_bridge_factory.h +++ b/webkit/glue/media/media_resource_loader_bridge_factory.h @@ -24,7 +24,7 @@ class MediaResourceLoaderBridgeFactory { int appcache_host_id, int32 routing_id); - virtual ~MediaResourceLoaderBridgeFactory() {} + virtual ~MediaResourceLoaderBridgeFactory(); // Factory method to create a ResourceLoaderBridge with the following // parameters: @@ -40,8 +40,7 @@ class MediaResourceLoaderBridgeFactory { protected: // An empty constructor only used by inherited classes. - MediaResourceLoaderBridgeFactory() { - } + MediaResourceLoaderBridgeFactory(); private: FRIEND_TEST_ALL_PREFIXES(MediaResourceLoaderBridgeFactoryTest, diff --git a/webkit/glue/media/simple_data_source.cc b/webkit/glue/media/simple_data_source.cc index 56deaeb..0b09edf 100644 --- a/webkit/glue/media/simple_data_source.cc +++ b/webkit/glue/media/simple_data_source.cc @@ -122,7 +122,7 @@ bool SimpleDataSource::IsStreaming() { bool SimpleDataSource::OnReceivedRedirect( const GURL& new_url, - const webkit_glue::ResourceLoaderBridge::ResponseInfo& info, + const webkit_glue::ResourceResponseInfo& info, bool* has_new_first_party_for_cookies, GURL* new_first_party_for_cookies) { SetURL(new_url); @@ -132,7 +132,7 @@ bool SimpleDataSource::OnReceivedRedirect( } void SimpleDataSource::OnReceivedResponse( - const webkit_glue::ResourceLoaderBridge::ResponseInfo& info, + const webkit_glue::ResourceResponseInfo& info, bool content_filtered) { size_ = info.content_length; } diff --git a/webkit/glue/media/simple_data_source.h b/webkit/glue/media/simple_data_source.h index d238f61..d649c0d 100644 --- a/webkit/glue/media/simple_data_source.h +++ b/webkit/glue/media/simple_data_source.h @@ -54,11 +54,11 @@ class SimpleDataSource : public media::DataSource, virtual void OnUploadProgress(uint64 position, uint64 size) {} virtual bool OnReceivedRedirect( const GURL& new_url, - const webkit_glue::ResourceLoaderBridge::ResponseInfo& info, + const webkit_glue::ResourceResponseInfo& info, bool* has_new_first_party_for_cookies, GURL* new_first_party_for_cookies); virtual void OnReceivedResponse( - const webkit_glue::ResourceLoaderBridge::ResponseInfo& info, + const webkit_glue::ResourceResponseInfo& info, bool content_filtered); virtual void OnDownloadedData(int len) {} virtual void OnReceivedData(const char* data, int len); diff --git a/webkit/glue/media/simple_data_source_unittest.cc b/webkit/glue/media/simple_data_source_unittest.cc index d05bb72..50c8910 100644 --- a/webkit/glue/media/simple_data_source_unittest.cc +++ b/webkit/glue/media/simple_data_source_unittest.cc @@ -81,7 +81,7 @@ class SimpleDataSourceTest : public testing::Test { } void RequestSucceeded(bool is_loaded) { - ResourceLoaderBridge::ResponseInfo info; + ResourceResponseInfo info; info.content_length = kDataSize; data_source_->OnReceivedResponse(info, false); diff --git a/webkit/glue/media/video_renderer_impl.cc b/webkit/glue/media/video_renderer_impl.cc index 6d7323d..16c9ef6 100644 --- a/webkit/glue/media/video_renderer_impl.cc +++ b/webkit/glue/media/video_renderer_impl.cc @@ -20,6 +20,8 @@ VideoRendererImpl::VideoRendererImpl(WebMediaPlayerImpl::Proxy* proxy, proxy_->SetVideoRenderer(this); } +VideoRendererImpl::~VideoRendererImpl() {} + // static media::FilterFactory* VideoRendererImpl::CreateFactory( WebMediaPlayerImpl::Proxy* proxy, @@ -86,10 +88,8 @@ void VideoRendererImpl::Paint(skia::PlatformCanvas* canvas, // on low-end devices. When profiled on an Intel Atom N280 @ 1.66GHz this // code had a ~63 microsecond perf hit when logging to a file (not stdout), // which is neglible enough for measuring playback performance. - if (pts_logging_) { - LOG(INFO) << "pts=" - << video_frame->GetTimestamp().InMicroseconds(); - } + if (pts_logging_) + VLOG(1) << "pts=" << video_frame->GetTimestamp().InMicroseconds(); } PutCurrentFrame(video_frame); diff --git a/webkit/glue/media/video_renderer_impl.h b/webkit/glue/media/video_renderer_impl.h index 39ce1b2..38e8851 100644 --- a/webkit/glue/media/video_renderer_impl.h +++ b/webkit/glue/media/video_renderer_impl.h @@ -73,7 +73,7 @@ class VideoRendererImpl : public WebVideoRenderer { WebMediaPlayerImpl::Proxy*, bool>; VideoRendererImpl(WebMediaPlayerImpl::Proxy* proxy, bool pts_logging); - virtual ~VideoRendererImpl() {} + virtual ~VideoRendererImpl(); // Determine the conditions to perform fast paint. Returns true if we can do // fast paint otherwise false. diff --git a/webkit/glue/multipart_response_delegate_unittest.cc b/webkit/glue/multipart_response_delegate_unittest.cc index ffacfb3..fab798c 100644 --- a/webkit/glue/multipart_response_delegate_unittest.cc +++ b/webkit/glue/multipart_response_delegate_unittest.cc @@ -623,7 +623,7 @@ TEST(MultipartResponseTest, MultipartPayloadSet) { client.received_response_); EXPECT_EQ(string("response data"), client.data_); - EXPECT_EQ(false, client.response_.isMultipartPayload()); + EXPECT_FALSE(client.response_.isMultipartPayload()); string data2( "Content-type: text/plain\n\n" @@ -634,7 +634,7 @@ TEST(MultipartResponseTest, MultipartPayloadSet) { client.received_response_); EXPECT_EQ(string("response data2"), client.data_); - EXPECT_EQ(true, client.response_.isMultipartPayload()); + EXPECT_TRUE(client.response_.isMultipartPayload()); } } // namespace diff --git a/webkit/glue/plugins/gtk_plugin_container_manager.cc b/webkit/glue/plugins/gtk_plugin_container_manager.cc index f26b44c..2f82b24 100644 --- a/webkit/glue/plugins/gtk_plugin_container_manager.cc +++ b/webkit/glue/plugins/gtk_plugin_container_manager.cc @@ -11,6 +11,10 @@ #include "webkit/glue/plugins/gtk_plugin_container.h" #include "webkit/glue/plugins/webplugin.h" +GtkPluginContainerManager::GtkPluginContainerManager() : host_widget_(NULL) {} + +GtkPluginContainerManager::~GtkPluginContainerManager() {} + GtkWidget* GtkPluginContainerManager::CreatePluginContainer( gfx::PluginWindowHandle id) { DCHECK(host_widget_); diff --git a/webkit/glue/plugins/gtk_plugin_container_manager.h b/webkit/glue/plugins/gtk_plugin_container_manager.h index c33099d..7f7db8d 100644 --- a/webkit/glue/plugins/gtk_plugin_container_manager.h +++ b/webkit/glue/plugins/gtk_plugin_container_manager.h @@ -19,7 +19,8 @@ struct WebPluginGeometry; // Helper class that creates and manages plugin containers (GtkSocket). class GtkPluginContainerManager { public: - GtkPluginContainerManager() : host_widget_(NULL) { } + GtkPluginContainerManager(); + ~GtkPluginContainerManager(); // Sets the widget that will host the plugin containers. Must be a GtkFixed. void set_host_widget(GtkWidget *widget) { host_widget_ = widget; } diff --git a/webkit/glue/plugins/pepper_audio.cc b/webkit/glue/plugins/pepper_audio.cc index 3babc2f..5a76670 100644 --- a/webkit/glue/plugins/pepper_audio.cc +++ b/webkit/glue/plugins/pepper_audio.cc @@ -12,22 +12,52 @@ namespace pepper { namespace { -// PPB_AudioConfig functions +// PPB_AudioConfig ------------------------------------------------------------- -PP_Resource CreateStereo16bit(PP_Module module_id, uint32_t sample_rate, +uint32_t RecommendSampleFrameCount(uint32_t requested_sample_frame_count); + +PP_Resource CreateStereo16bit(PP_Module module_id, + PP_AudioSampleRate_Dev sample_rate, uint32_t sample_frame_count) { - PluginModule* module = PluginModule::FromPPModule(module_id); + PluginModule* module = ResourceTracker::Get()->GetModule(module_id); if (!module) return 0; - scoped_refptr<AudioConfig> config(new AudioConfig(module, sample_rate, + // TODO(brettw): Currently we don't actually check what the hardware + // supports, so just allow sample rates of the "guaranteed working" ones. + if (sample_rate != PP_AUDIOSAMPLERATE_44100 && + sample_rate != PP_AUDIOSAMPLERATE_48000) + return 0; + + // TODO(brettw): Currently we don't actually query to get a value from the + // hardware, so just validate the range. + if (RecommendSampleFrameCount(sample_frame_count) != sample_frame_count) + return 0; + + scoped_refptr<AudioConfig> config(new AudioConfig(module, + sample_rate, sample_frame_count)); return config->GetReference(); } -uint32_t GetSampleRate(PP_Resource config_id) { +uint32_t RecommendSampleFrameCount(uint32_t requested_sample_frame_count) { + // TODO(brettw) Currently we don't actually query to get a value from the + // hardware, so we always return the input for in-range values. + if (requested_sample_frame_count < PP_AUDIOMINSAMPLEFRAMECOUNT) + return PP_AUDIOMINSAMPLEFRAMECOUNT; + if (requested_sample_frame_count > PP_AUDIOMAXSAMPLEFRAMECOUNT) + return PP_AUDIOMAXSAMPLEFRAMECOUNT; + return requested_sample_frame_count; +} + +bool IsAudioConfig(PP_Resource resource) { + scoped_refptr<AudioConfig> config = Resource::GetAs<AudioConfig>(resource); + return !!config; +} + +PP_AudioSampleRate_Dev GetSampleRate(PP_Resource config_id) { scoped_refptr<AudioConfig> config = Resource::GetAs<AudioConfig>(config_id); - return config ? config->sample_rate() : 0; + return config ? config->sample_rate() : PP_AUDIOSAMPLERATE_NONE; } uint32_t GetSampleFrameCount(PP_Resource config_id) { @@ -35,11 +65,19 @@ uint32_t GetSampleFrameCount(PP_Resource config_id) { return config ? config->sample_frame_count() : 0; } -// PPB_Audio functions +const PPB_AudioConfig_Dev ppb_audioconfig = { + &CreateStereo16bit, + &RecommendSampleFrameCount, + &IsAudioConfig, + &GetSampleRate, + &GetSampleFrameCount +}; + +// PPB_Audio ------------------------------------------------------------------- PP_Resource Create(PP_Instance instance_id, PP_Resource config_id, PPB_Audio_Callback callback, void* user_data) { - PluginInstance* instance = PluginInstance::FromPPInstance(instance_id); + PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id); if (!instance) return 0; // TODO(neb): Require callback to be present for untrusted plugins. @@ -49,6 +87,11 @@ PP_Resource Create(PP_Instance instance_id, PP_Resource config_id, return audio->GetReference(); } +bool IsAudio(PP_Resource resource) { + scoped_refptr<Audio> audio = Resource::GetAs<Audio>(resource); + return !!audio; +} + PP_Resource GetCurrentConfiguration(PP_Resource audio_id) { scoped_refptr<Audio> audio = Resource::GetAs<Audio>(audio_id); return audio ? audio->GetCurrentConfiguration() : 0; @@ -64,7 +107,15 @@ bool StopPlayback(PP_Resource audio_id) { return audio ? audio->StopPlayback() : false; } -// PPB_AudioTrusted functions +const PPB_Audio_Dev ppb_audio = { + &Create, + &IsAudio, + &GetCurrentConfiguration, + &StartPlayback, + &StopPlayback, +}; + +// PPB_AudioTrusted ------------------------------------------------------------ PP_Resource GetBuffer(PP_Resource audio_id) { // TODO(neb): Implement me! @@ -76,19 +127,6 @@ int GetOSDescriptor(PP_Resource audio_id) { return -1; } -const PPB_AudioConfig_Dev ppb_audioconfig = { - &CreateStereo16bit, - &GetSampleRate, - &GetSampleFrameCount -}; - -const PPB_Audio_Dev ppb_audio = { - &Create, - &GetCurrentConfiguration, - &StartPlayback, - &StopPlayback, -}; - const PPB_AudioTrusted_Dev ppb_audiotrusted = { &GetBuffer, &GetOSDescriptor @@ -96,8 +134,11 @@ const PPB_AudioTrusted_Dev ppb_audiotrusted = { } // namespace -AudioConfig::AudioConfig(PluginModule* module, int32_t sample_rate, - int32_t sample_frame_count) +// AudioConfig ----------------------------------------------------------------- + +AudioConfig::AudioConfig(PluginModule* module, + PP_AudioSampleRate_Dev sample_rate, + uint32_t sample_frame_count) : Resource(module), sample_rate_(sample_rate), sample_frame_count_(sample_frame_count) { @@ -107,10 +148,22 @@ const PPB_AudioConfig_Dev* AudioConfig::GetInterface() { return &ppb_audioconfig; } +size_t AudioConfig::BufferSize() { + // TODO(audio): as more options become available, we'll need to + // have additional code here to correctly calculate the size in + // bytes of an audio buffer. For now, only support two channel + // int16_t sample buffers. + const int kChannels = 2; + const int kSizeOfSample = sizeof(int16_t); + return static_cast<size_t>(sample_frame_count_ * kSizeOfSample * kChannels); +} + AudioConfig* AudioConfig::AsAudioConfig() { return this; } +// Audio ----------------------------------------------------------------------- + Audio::Audio(PluginModule* module) : Resource(module), playing_(false), @@ -133,7 +186,6 @@ Audio::~Audio() { // Shared memory destructor will unmap the memory automatically. } - const PPB_Audio_Dev* Audio::GetInterface() { return &ppb_audio; } @@ -211,6 +263,7 @@ void Audio::StreamCreated(base::SharedMemoryHandle shared_memory_handle, void Audio::Run() { int pending_data; void* buffer = shared_memory_->memory(); + size_t buffer_size_in_bytes = config_->BufferSize(); while (sizeof(pending_data) == socket_->Receive(&pending_data, sizeof(pending_data)) && @@ -218,7 +271,7 @@ void Audio::Run() { // Exit the thread on pause. if (pending_data < 0) return; - callback_(buffer, user_data_); + callback_(buffer, buffer_size_in_bytes, user_data_); } } diff --git a/webkit/glue/plugins/pepper_audio.h b/webkit/glue/plugins/pepper_audio.h index d9a9e86..196eac4 100644 --- a/webkit/glue/plugins/pepper_audio.h +++ b/webkit/glue/plugins/pepper_audio.h @@ -25,20 +25,21 @@ class PluginModule; class AudioConfig : public Resource { public: - AudioConfig(PluginModule* module, int32_t sample_rate, - int32_t sample_frame_count); - + AudioConfig(PluginModule* module, + PP_AudioSampleRate_Dev sample_rate, + uint32_t sample_frame_count); + size_t BufferSize(); static const PPB_AudioConfig_Dev* GetInterface(); - uint32_t sample_rate() { return sample_rate_; } + PP_AudioSampleRate_Dev sample_rate() { return sample_rate_; } uint32_t sample_frame_count() { return sample_frame_count_; } private: // Resource override. virtual AudioConfig* AsAudioConfig(); - int sample_rate_; - int sample_frame_count_; + PP_AudioSampleRate_Dev sample_rate_; + uint32_t sample_frame_count_; }; class Audio : public Resource, diff --git a/webkit/glue/plugins/pepper_buffer.cc b/webkit/glue/plugins/pepper_buffer.cc index c3acef8..1b9097d 100644 --- a/webkit/glue/plugins/pepper_buffer.cc +++ b/webkit/glue/plugins/pepper_buffer.cc @@ -20,7 +20,7 @@ namespace pepper { namespace { PP_Resource Create(PP_Module module_id, int32_t size) { - PluginModule* module = PluginModule::FromPPModule(module_id); + PluginModule* module = ResourceTracker::Get()->GetModule(module_id); if (!module) return 0; diff --git a/webkit/glue/plugins/pepper_char_set.cc b/webkit/glue/plugins/pepper_char_set.cc index 1e5fc0a..043de41 100644 --- a/webkit/glue/plugins/pepper_char_set.cc +++ b/webkit/glue/plugins/pepper_char_set.cc @@ -141,9 +141,9 @@ uint16_t* CharSetToUTF16(const char* input, uint32_t input_len, } PP_Var GetDefaultCharSet(PP_Module pp_module) { - PluginModule* module = PluginModule::FromPPModule(pp_module); + PluginModule* module = ResourceTracker::Get()->GetModule(pp_module); if (!module) - return PP_MakeVoid(); + return PP_MakeUndefined(); std::string encoding = module->GetSomeInstance()->delegate()->GetDefaultEncoding(); diff --git a/webkit/glue/plugins/pepper_cursor_control.cc b/webkit/glue/plugins/pepper_cursor_control.cc index de3c166..687aa76 100644 --- a/webkit/glue/plugins/pepper_cursor_control.cc +++ b/webkit/glue/plugins/pepper_cursor_control.cc @@ -22,7 +22,7 @@ bool SetCursor(PP_Instance instance_id, PP_CursorType_Dev type, PP_Resource custom_image_id, const PP_Point* hot_spot) { - PluginInstance* instance = PluginInstance::FromPPInstance(instance_id); + PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id); if (!instance) return false; @@ -38,7 +38,7 @@ bool SetCursor(PP_Instance instance_id, } bool LockCursor(PP_Instance instance_id) { - PluginInstance* instance = PluginInstance::FromPPInstance(instance_id); + PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id); if (!instance) return false; @@ -47,7 +47,7 @@ bool LockCursor(PP_Instance instance_id) { } bool UnlockCursor(PP_Instance instance_id) { - PluginInstance* instance = PluginInstance::FromPPInstance(instance_id); + PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id); if (!instance) return false; @@ -56,7 +56,7 @@ bool UnlockCursor(PP_Instance instance_id) { } bool HasCursorLock(PP_Instance instance_id) { - PluginInstance* instance = PluginInstance::FromPPInstance(instance_id); + PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id); if (!instance) return false; @@ -65,7 +65,7 @@ bool HasCursorLock(PP_Instance instance_id) { } bool CanLockCursor(PP_Instance instance_id) { - PluginInstance* instance = PluginInstance::FromPPInstance(instance_id); + PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id); if (!instance) return false; diff --git a/webkit/glue/plugins/pepper_dir_contents.h b/webkit/glue/plugins/pepper_dir_contents.h new file mode 100644 index 0000000..661c577 --- /dev/null +++ b/webkit/glue/plugins/pepper_dir_contents.h @@ -0,0 +1,18 @@ +// Copyright (c) 2010 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_GLUE_PLUGINS_PEPPER_DIR_CONTENTS_H_ +#define WEBKIT_GLUE_PLUGINS_PEPPER_DIR_CONTENTS_H_ + +#include <vector> +#include "base/file_path.h" + +struct PepperDirEntry { + FilePath name; + bool is_dir; +}; + +typedef std::vector<PepperDirEntry> PepperDirContents; + +#endif // WEBKIT_GLUE_PLUGINS_PEPPER_DIR_CONTENTS_H_ diff --git a/webkit/glue/plugins/pepper_error_util.cc b/webkit/glue/plugins/pepper_error_util.cc index a1b5c06..895626a 100644 --- a/webkit/glue/plugins/pepper_error_util.cc +++ b/webkit/glue/plugins/pepper_error_util.cc @@ -17,6 +17,7 @@ int PlatformFileErrorToPepperError(base::PlatformFileError error_code) { case base::PLATFORM_FILE_ERROR_NOT_FOUND: return PP_ERROR_FILENOTFOUND; case base::PLATFORM_FILE_ERROR_ACCESS_DENIED: + case base::PLATFORM_FILE_ERROR_SECURITY: return PP_ERROR_NOACCESS; case base::PLATFORM_FILE_ERROR_NO_MEMORY: return PP_ERROR_NOMEMORY; diff --git a/webkit/glue/plugins/pepper_event_conversion.cc b/webkit/glue/plugins/pepper_event_conversion.cc index b88041e..5375f67 100644 --- a/webkit/glue/plugins/pepper_event_conversion.cc +++ b/webkit/glue/plugins/pepper_event_conversion.cc @@ -56,7 +56,10 @@ PP_InputEvent GetPPEventWithCommonFieldsAndType( PP_InputEvent result; memset(&result, 0, sizeof(PP_InputEvent)); result.type = ConvertEventTypes(web_event.type); - result.time_stamp_seconds = web_event.timeStampSeconds; + // TODO(brettw) http://code.google.com/p/chromium/issues/detail?id=57448 + // This should use a tick count rather than the wall clock time that WebKit + // uses. + result.time_stamp = web_event.timeStampSeconds; return result; } @@ -159,7 +162,7 @@ WebKeyboardEvent* BuildKeyEvent(const PP_InputEvent& event) { default: NOTREACHED(); } - key_event->timeStampSeconds = event.time_stamp_seconds; + key_event->timeStampSeconds = event.time_stamp; key_event->modifiers = event.u.key.modifier; key_event->windowsKeyCode = event.u.key.key_code; return key_event; @@ -168,7 +171,7 @@ WebKeyboardEvent* BuildKeyEvent(const PP_InputEvent& event) { WebKeyboardEvent* BuildCharEvent(const PP_InputEvent& event) { WebKeyboardEvent* key_event = new WebKeyboardEvent(); key_event->type = WebInputEvent::Char; - key_event->timeStampSeconds = event.time_stamp_seconds; + key_event->timeStampSeconds = event.time_stamp; key_event->modifiers = event.u.character.modifier; // Make sure to not read beyond the buffer in case some bad code doesn't @@ -209,7 +212,7 @@ WebMouseEvent* BuildMouseEvent(const PP_InputEvent& event) { default: NOTREACHED(); } - mouse_event->timeStampSeconds = event.time_stamp_seconds; + mouse_event->timeStampSeconds = event.time_stamp; mouse_event->modifiers = event.u.mouse.modifier; mouse_event->button = static_cast<WebMouseEvent::Button>(event.u.mouse.button); @@ -222,7 +225,7 @@ WebMouseEvent* BuildMouseEvent(const PP_InputEvent& event) { WebMouseWheelEvent* BuildMouseWheelEvent(const PP_InputEvent& event) { WebMouseWheelEvent* mouse_wheel_event = new WebMouseWheelEvent(); mouse_wheel_event->type = WebInputEvent::MouseWheel; - mouse_wheel_event->timeStampSeconds = event.time_stamp_seconds; + mouse_wheel_event->timeStampSeconds = event.time_stamp; mouse_wheel_event->modifiers = event.u.wheel.modifier; mouse_wheel_event->deltaX = event.u.wheel.delta_x; mouse_wheel_event->deltaY = event.u.wheel.delta_y; diff --git a/webkit/glue/plugins/pepper_file_callbacks.cc b/webkit/glue/plugins/pepper_file_callbacks.cc new file mode 100644 index 0000000..3c52a0f --- /dev/null +++ b/webkit/glue/plugins/pepper_file_callbacks.cc @@ -0,0 +1,88 @@ +// Copyright (c) 2010 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/pepper_file_callbacks.h" + +#include "base/file_path.h" +#include "base/logging.h" +#include "third_party/ppapi/c/dev/ppb_file_system_dev.h" +#include "third_party/ppapi/c/dev/pp_file_info_dev.h" +#include "third_party/ppapi/c/pp_errors.h" +#include "webkit/glue/plugins/pepper_error_util.h" +#include "webkit/glue/plugins/pepper_file_system.h" +#include "webkit/fileapi/file_system_types.h" + +namespace pepper { + +FileCallbacks::FileCallbacks(const base::WeakPtr<PluginModule>& module, + PP_CompletionCallback callback, + PP_FileInfo_Dev* info, + scoped_refptr<FileSystem> file_system) + : module_(module), + callback_(callback), + info_(info), + file_system_(file_system) { +} + +void FileCallbacks::DidSucceed() { + if (!module_.get() || !callback_.func) + return; + + PP_RunCompletionCallback(&callback_, PP_OK); +} + +void FileCallbacks::DidReadMetadata( + const base::PlatformFileInfo& file_info) { + if (!module_.get() || !callback_.func) + return; + + DCHECK(info_); + DCHECK(file_system_); + info_->size = file_info.size; + info_->creation_time = file_info.creation_time.ToDoubleT(); + info_->last_access_time = file_info.last_accessed.ToDoubleT(); + info_->last_modified_time = file_info.last_modified.ToDoubleT(); + info_->system_type = file_system_->type(); + if (file_info.is_directory) + info_->type = PP_FILETYPE_DIRECTORY; + else + info_->type = PP_FILETYPE_REGULAR; + + PP_RunCompletionCallback(&callback_, PP_OK); +} + +void FileCallbacks::DidReadDirectory( + const std::vector<base::file_util_proxy::Entry>&, bool) { + NOTREACHED(); +} + +void FileCallbacks::DidOpenFileSystem(const std::string&, + const FilePath& root_path) { + if (!module_.get() || !callback_.func) + return; + + DCHECK(file_system_); + file_system_->set_root_path(root_path); + file_system_->set_opened(true); + + PP_RunCompletionCallback(&callback_, PP_OK); +} + +void FileCallbacks::DidFail(base::PlatformFileError error_code) { + RunCallback(error_code); +} + +void FileCallbacks::DidWrite(int64 bytes, bool complete) { + NOTREACHED(); +} + +void FileCallbacks::RunCallback(base::PlatformFileError error_code) { + if (!module_.get() || !callback_.func) + return; + + PP_RunCompletionCallback( + &callback_, pepper::PlatformFileErrorToPepperError(error_code)); +} + +} // namespace pepper diff --git a/webkit/glue/plugins/pepper_file_callbacks.h b/webkit/glue/plugins/pepper_file_callbacks.h new file mode 100644 index 0000000..407672e --- /dev/null +++ b/webkit/glue/plugins/pepper_file_callbacks.h @@ -0,0 +1,53 @@ +// Copyright (c) 2010 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_GLUE_PLUGINS_PEPPER_FILE_CALLBACKS_H_ +#define WEBKIT_GLUE_PLUGINS_PEPPER_FILE_CALLBACKS_H_ + +#include "base/platform_file.h" +#include "base/weak_ptr.h" +#include "third_party/ppapi/c/pp_completion_callback.h" +#include "webkit/fileapi/file_system_callback_dispatcher.h" + +struct PP_FileInfo_Dev; + +namespace base { +class FilePath; +} + +namespace pepper { + +class FileSystem; +class PluginModule; + +// Instances of this class are deleted by FileSystemDispatcher. +class FileCallbacks : public fileapi::FileSystemCallbackDispatcher { + public: + FileCallbacks(const base::WeakPtr<PluginModule>& module, + PP_CompletionCallback callback, + PP_FileInfo_Dev* info, + scoped_refptr<FileSystem> file_system); + + // FileSystemCallbackDispatcher implementation. + virtual void DidSucceed(); + virtual void DidReadMetadata(const base::PlatformFileInfo& file_info); + virtual void DidReadDirectory( + const std::vector<base::file_util_proxy::Entry>&, bool); + virtual void DidOpenFileSystem(const std::string&, + const FilePath& root_path); + virtual void DidFail(base::PlatformFileError error_code); + virtual void DidWrite(int64 bytes, bool complete); + + private: + void RunCallback(base::PlatformFileError error_code); + + base::WeakPtr<pepper::PluginModule> module_; + PP_CompletionCallback callback_; + PP_FileInfo_Dev* info_; + scoped_refptr<FileSystem> file_system_; +}; + +} // namespace pepper + +#endif // WEBKIT_GLUE_PLUGINS_PEPPER_FILE_CALLBACKS_H_ diff --git a/webkit/glue/plugins/pepper_file_chooser.cc b/webkit/glue/plugins/pepper_file_chooser.cc index 138efd7..07524e9 100644 --- a/webkit/glue/plugins/pepper_file_chooser.cc +++ b/webkit/glue/plugins/pepper_file_chooser.cc @@ -33,7 +33,7 @@ namespace { PP_Resource Create(PP_Instance instance_id, const PP_FileChooserOptions_Dev* options) { - PluginInstance* instance = PluginInstance::FromPPInstance(instance_id); + PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id); if (!instance) return 0; @@ -119,8 +119,7 @@ void FileChooser::StoreChosenFiles(const std::vector<std::string>& files) { std::vector<std::string>::const_iterator end_it = files.end(); for (std::vector<std::string>::const_iterator it = files.begin(); it != end_it; it++) - chosen_files_.push_back( - new FileRef(module(), PP_FILESYSTEMTYPE_LOCALPERSISTENT, *it, "")); + chosen_files_.push_back(new FileRef(module(), FilePath().AppendASCII(*it))); if (!completion_callback_.func) return; diff --git a/webkit/glue/plugins/pepper_file_io.cc b/webkit/glue/plugins/pepper_file_io.cc index 9090f88..b979ac2 100644 --- a/webkit/glue/plugins/pepper_file_io.cc +++ b/webkit/glue/plugins/pepper_file_io.cc @@ -25,7 +25,7 @@ namespace pepper { namespace { PP_Resource Create(PP_Module module_id) { - PluginModule* module = PluginModule::FromPPModule(module_id); + PluginModule* module = ResourceTracker::Get()->GetModule(module_id); if (!module) return 0; @@ -225,12 +225,11 @@ int32_t FileIO::Open(FileRef* file_ref, flags |= base::PLATFORM_FILE_WRITE; flags |= base::PLATFORM_FILE_WRITE_ATTRIBUTES; } + if (open_flags & PP_FILEOPENFLAG_TRUNCATE) { - DCHECK(flags & PP_FILEOPENFLAG_WRITE); + DCHECK(open_flags & PP_FILEOPENFLAG_WRITE); flags |= base::PLATFORM_FILE_TRUNCATE; - } - - if (open_flags & PP_FILEOPENFLAG_CREATE) { + } else if (open_flags & PP_FILEOPENFLAG_CREATE) { if (open_flags & PP_FILEOPENFLAG_EXCLUSIVE) flags |= base::PLATFORM_FILE_CREATE; else @@ -238,9 +237,9 @@ int32_t FileIO::Open(FileRef* file_ref, } else flags |= base::PLATFORM_FILE_OPEN; - file_system_type_ = file_ref->file_system_type(); + file_system_type_ = file_ref->GetFileSystemType(); if (!delegate_->AsyncOpenFile( - file_ref->system_path(), flags, + file_ref->GetSystemPath(), flags, callback_factory_.NewCallback(&FileIO::AsyncOpenFileCallback))) return PP_ERROR_FAILED; diff --git a/webkit/glue/plugins/pepper_file_io.h b/webkit/glue/plugins/pepper_file_io.h index bda8ed6..9fa24ba 100644 --- a/webkit/glue/plugins/pepper_file_io.h +++ b/webkit/glue/plugins/pepper_file_io.h @@ -16,7 +16,6 @@ #include "webkit/glue/plugins/pepper_resource.h" struct PP_CompletionCallback; -struct PP_FileInfo_Dev; struct PPB_FileIO_Dev; struct PPB_FileIOTrusted_Dev; diff --git a/webkit/glue/plugins/pepper_file_ref.cc b/webkit/glue/plugins/pepper_file_ref.cc index 7cb65a4..0a64678 100644 --- a/webkit/glue/plugins/pepper_file_ref.cc +++ b/webkit/glue/plugins/pepper_file_ref.cc @@ -4,12 +4,14 @@ #include "webkit/glue/plugins/pepper_file_ref.h" -#include "base/base_paths.h" -#include "base/path_service.h" #include "base/string_util.h" +#include "third_party/ppapi/c/pp_errors.h" +#include "webkit/glue/plugins/pepper_file_callbacks.h" +#include "webkit/glue/plugins/pepper_file_system.h" +#include "webkit/glue/plugins/pepper_plugin_delegate.h" #include "webkit/glue/plugins/pepper_plugin_instance.h" +#include "webkit/glue/plugins/pepper_plugin_module.h" #include "webkit/glue/plugins/pepper_var.h" -#include "webkit/glue/plugins/pepper_resource_tracker.h" namespace pepper { @@ -34,35 +36,26 @@ void TrimTrailingSlash(std::string* path) { path->erase(path->size() - 1, 1); } -PP_Resource CreateFileRef(PP_Instance instance_id, - PP_FileSystemType_Dev fs_type, - const char* path) { - PluginInstance* instance = PluginInstance::FromPPInstance(instance_id); - if (!instance) +PP_Resource Create(PP_Resource file_system_id, const char* path) { + scoped_refptr<FileSystem> file_system( + Resource::GetAs<FileSystem>(file_system_id)); + if (!file_system) return 0; - std::string origin; // TODO(darin): Extract from PluginInstance. + if (!file_system->instance()) + return 0; std::string validated_path(path); if (!IsValidLocalPath(validated_path)) return 0; TrimTrailingSlash(&validated_path); - FileRef* file_ref = new FileRef(instance->module(), - fs_type, - validated_path, - origin); + FileRef* file_ref = new FileRef(file_system->instance()->module(), + file_system, + validated_path); return file_ref->GetReference(); } -PP_Resource CreatePersistentFileRef(PP_Instance instance_id, const char* path) { - return CreateFileRef(instance_id, PP_FILESYSTEMTYPE_LOCALPERSISTENT, path); -} - -PP_Resource CreateTemporaryFileRef(PP_Instance instance_id, const char* path) { - return CreateFileRef(instance_id, PP_FILESYSTEMTYPE_LOCALTEMPORARY, path); -} - bool IsFileRef(PP_Resource resource) { return !!Resource::GetAs<FileRef>(resource); } @@ -71,25 +64,25 @@ PP_FileSystemType_Dev GetFileSystemType(PP_Resource file_ref_id) { scoped_refptr<FileRef> file_ref(Resource::GetAs<FileRef>(file_ref_id)); if (!file_ref) return PP_FILESYSTEMTYPE_EXTERNAL; - return file_ref->file_system_type(); + return file_ref->GetFileSystemType(); } PP_Var GetName(PP_Resource file_ref_id) { scoped_refptr<FileRef> file_ref(Resource::GetAs<FileRef>(file_ref_id)); if (!file_ref) - return PP_MakeVoid(); + return PP_MakeUndefined(); return StringVar::StringToPPVar(file_ref->module(), file_ref->GetName()); } PP_Var GetPath(PP_Resource file_ref_id) { scoped_refptr<FileRef> file_ref(Resource::GetAs<FileRef>(file_ref_id)); if (!file_ref) - return PP_MakeVoid(); + return PP_MakeUndefined(); - if (file_ref->file_system_type() == PP_FILESYSTEMTYPE_EXTERNAL) - return PP_MakeVoid(); + if (file_ref->GetFileSystemType() == PP_FILESYSTEMTYPE_EXTERNAL) + return PP_MakeUndefined(); - return StringVar::StringToPPVar(file_ref->module(), file_ref->path()); + return StringVar::StringToPPVar(file_ref->module(), file_ref->GetPath()); } PP_Resource GetParent(PP_Resource file_ref_id) { @@ -97,7 +90,7 @@ PP_Resource GetParent(PP_Resource file_ref_id) { if (!file_ref) return 0; - if (file_ref->file_system_type() == PP_FILESYSTEMTYPE_EXTERNAL) + if (file_ref->GetFileSystemType() == PP_FILESYSTEMTYPE_EXTERNAL) return 0; scoped_refptr<FileRef> parent_ref(file_ref->GetParent()); @@ -107,34 +100,158 @@ PP_Resource GetParent(PP_Resource file_ref_id) { return parent_ref->GetReference(); } +int32_t MakeDirectory(PP_Resource directory_ref_id, + bool make_ancestors, + PP_CompletionCallback callback) { + scoped_refptr<FileRef> directory_ref( + Resource::GetAs<FileRef>(directory_ref_id)); + if (!directory_ref) + return PP_ERROR_BADRESOURCE; + + scoped_refptr<FileSystem> file_system = directory_ref->GetFileSystem(); + if (!file_system || !file_system->opened() || + (file_system->type() == PP_FILESYSTEMTYPE_EXTERNAL)) + return PP_ERROR_NOACCESS; + + PluginInstance* instance = file_system->instance(); + if (!instance->delegate()->MakeDirectory( + directory_ref->GetSystemPath(), make_ancestors, + new FileCallbacks(instance->module()->AsWeakPtr(), + callback, NULL, NULL))) + return PP_ERROR_FAILED; + + return PP_ERROR_WOULDBLOCK; +} + +int32_t Query(PP_Resource file_ref_id, + PP_FileInfo_Dev* info, + PP_CompletionCallback callback) { + scoped_refptr<FileRef> file_ref(Resource::GetAs<FileRef>(file_ref_id)); + if (!file_ref) + return PP_ERROR_BADRESOURCE; + + scoped_refptr<FileSystem> file_system = file_ref->GetFileSystem(); + if (!file_system || !file_system->opened() || + (file_system->type() == PP_FILESYSTEMTYPE_EXTERNAL)) + return PP_ERROR_NOACCESS; + + PluginInstance* instance = file_system->instance(); + if (!instance->delegate()->Query( + file_ref->GetSystemPath(), + new FileCallbacks(instance->module()->AsWeakPtr(), + callback, info, file_system))) + return PP_ERROR_FAILED; + + return PP_ERROR_WOULDBLOCK; +} + +int32_t Touch(PP_Resource file_ref_id, + PP_Time last_access_time, + PP_Time last_modified_time, + PP_CompletionCallback callback) { + scoped_refptr<FileRef> file_ref(Resource::GetAs<FileRef>(file_ref_id)); + if (!file_ref) + return PP_ERROR_BADRESOURCE; + + scoped_refptr<FileSystem> file_system = file_ref->GetFileSystem(); + if (!file_system || !file_system->opened() || + (file_system->type() == PP_FILESYSTEMTYPE_EXTERNAL)) + return PP_ERROR_NOACCESS; + + PluginInstance* instance = file_system->instance(); + if (!instance->delegate()->Touch( + file_ref->GetSystemPath(), base::Time::FromDoubleT(last_access_time), + base::Time::FromDoubleT(last_modified_time), + new FileCallbacks(instance->module()->AsWeakPtr(), + callback, NULL, NULL))) + return PP_ERROR_FAILED; + + return PP_ERROR_WOULDBLOCK; +} + +int32_t Delete(PP_Resource file_ref_id, + PP_CompletionCallback callback) { + scoped_refptr<FileRef> file_ref(Resource::GetAs<FileRef>(file_ref_id)); + if (!file_ref) + return PP_ERROR_BADRESOURCE; + + scoped_refptr<FileSystem> file_system = file_ref->GetFileSystem(); + if (!file_system || !file_system->opened() || + (file_system->type() == PP_FILESYSTEMTYPE_EXTERNAL)) + return PP_ERROR_NOACCESS; + + PluginInstance* instance = file_system->instance(); + if (!instance->delegate()->Delete( + file_ref->GetSystemPath(), + new FileCallbacks(instance->module()->AsWeakPtr(), + callback, NULL, NULL))) + return PP_ERROR_FAILED; + + return PP_ERROR_WOULDBLOCK; +} + +int32_t Rename(PP_Resource file_ref_id, + PP_Resource new_file_ref_id, + PP_CompletionCallback callback) { + scoped_refptr<FileRef> file_ref(Resource::GetAs<FileRef>(file_ref_id)); + if (!file_ref) + return PP_ERROR_BADRESOURCE; + + scoped_refptr<FileRef> new_file_ref( + Resource::GetAs<FileRef>(new_file_ref_id)); + if (!new_file_ref) + return PP_ERROR_BADRESOURCE; + + scoped_refptr<FileSystem> file_system = file_ref->GetFileSystem(); + if (!file_system || !file_system->opened() || + (file_system != new_file_ref->GetFileSystem()) || + (file_system->type() == PP_FILESYSTEMTYPE_EXTERNAL)) + return PP_ERROR_NOACCESS; + + PluginInstance* instance = file_system->instance(); + if (!instance->delegate()->Rename( + file_ref->GetSystemPath(), new_file_ref->GetSystemPath(), + new FileCallbacks(instance->module()->AsWeakPtr(), + callback, NULL, NULL))) + return PP_ERROR_FAILED; + + return PP_ERROR_WOULDBLOCK; +} + const PPB_FileRef_Dev ppb_fileref = { - &CreatePersistentFileRef, - &CreateTemporaryFileRef, + &Create, &IsFileRef, &GetFileSystemType, &GetName, &GetPath, - &GetParent + &GetParent, + &MakeDirectory, + &Query, + &Touch, + &Delete, + &Rename }; } // namespace +FileRef::FileRef() + : Resource(NULL), + file_system_(NULL) { +} + FileRef::FileRef(PluginModule* module, - PP_FileSystemType_Dev file_system_type, - const std::string& validated_path, - const std::string& origin) + scoped_refptr<FileSystem> file_system, + const std::string& validated_path) : Resource(module), - fs_type_(file_system_type), - path_(validated_path), - origin_(origin) { - // TODO(darin): Need to initialize system_path_. + file_system_(file_system), + virtual_path_(validated_path) { } FileRef::FileRef(PluginModule* module, const FilePath& external_file_path) : Resource(module), - system_path_(external_file_path), - fs_type_(PP_FILESYSTEMTYPE_EXTERNAL) { + file_system_(NULL), + system_path_(external_file_path) { } FileRef::~FileRef() { @@ -146,48 +263,56 @@ const PPB_FileRef_Dev* FileRef::GetInterface() { } std::string FileRef::GetName() const { - if (path_.size() == 1 && path_[0] == '/') - return path_; + if (GetFileSystemType() == PP_FILESYSTEMTYPE_EXTERNAL) + return std::string(); + + if (virtual_path_.size() == 1 && virtual_path_[0] == '/') + return virtual_path_; // There should always be a leading slash at least! - size_t pos = path_.rfind('/'); + size_t pos = virtual_path_.rfind('/'); DCHECK(pos != std::string::npos); - return path_.substr(pos + 1); + return virtual_path_.substr(pos + 1); } scoped_refptr<FileRef> FileRef::GetParent() { - if (path_.size() == 1 && path_[0] == '/') - return this; + if (GetFileSystemType() == PP_FILESYSTEMTYPE_EXTERNAL) + return new FileRef(); // There should always be a leading slash at least! - size_t pos = path_.rfind('/'); + size_t pos = virtual_path_.rfind('/'); DCHECK(pos != std::string::npos); // If the path is "/foo", then we want to include the slash. if (pos == 0) pos++; - std::string parent_path = path_.substr(0, pos); + std::string parent_path = virtual_path_.substr(0, pos); - FileRef* parent_ref = new FileRef(module(), fs_type_, parent_path, origin_); + FileRef* parent_ref = new FileRef(module(), file_system_, parent_path); return parent_ref; } -// static -FileRef* FileRef::GetInaccessibleFileRef(PluginModule* module) { - FilePath inaccessible_path; - if (!PathService::Get(base::FILE_MODULE, &inaccessible_path)) - return NULL; - return new FileRef(module, inaccessible_path); +scoped_refptr<FileSystem> FileRef::GetFileSystem() const { + return file_system_; } -// static -FileRef* FileRef::GetNonexistentFileRef(PluginModule* module) { - FilePath dir_module_path; - if (!PathService::Get(base::DIR_MODULE, &dir_module_path)) - return NULL; - return new FileRef(module, dir_module_path.Append( - FILE_PATH_LITERAL("nonexistent_file"))); +PP_FileSystemType_Dev FileRef::GetFileSystemType() const { + if (!file_system_) + return PP_FILESYSTEMTYPE_EXTERNAL; + + return file_system_->type(); +} + +std::string FileRef::GetPath() const { + return virtual_path_; +} + +FilePath FileRef::GetSystemPath() const { + if (GetFileSystemType() == PP_FILESYSTEMTYPE_EXTERNAL) + return system_path_; + + return file_system_->root_path().AppendASCII(virtual_path_); } } // namespace pepper diff --git a/webkit/glue/plugins/pepper_file_ref.h b/webkit/glue/plugins/pepper_file_ref.h index 0ab0e65..4dd8826 100644 --- a/webkit/glue/plugins/pepper_file_ref.h +++ b/webkit/glue/plugins/pepper_file_ref.h @@ -13,14 +13,16 @@ namespace pepper { +class FileSystem; +class PluginInstance; class PluginModule; class FileRef : public Resource { public: + FileRef(); FileRef(PluginModule* module, - PP_FileSystemType_Dev file_system_type, - const std::string& validated_path, - const std::string& origin); + scoped_refptr<FileSystem> file_system, + const std::string& validated_path); FileRef(PluginModule* module, const FilePath& external_file_path); virtual ~FileRef(); @@ -36,28 +38,23 @@ class FileRef : public Resource { std::string GetName() const; scoped_refptr<FileRef> GetParent(); - PP_FileSystemType_Dev file_system_type() const { return fs_type_; } + // Returns the file system to which this FileRef belongs. + scoped_refptr<FileSystem> GetFileSystem() const; + + // Returns the type of the file system to which this FileRef belongs. + PP_FileSystemType_Dev GetFileSystemType() const; // Returns the virtual path (i.e., the path that the pepper plugin sees) // corresponding to this file. - const std::string& path() const { return path_; } + std::string GetPath() const; // Returns the system path corresponding to this file. - const FilePath& system_path() const { return system_path_; } - - // Returns a FileRef instance pointing to a file that should not be - // accessible by the plugin. Should be used for testing only. - static FileRef* GetInaccessibleFileRef(PluginModule* module); - - // Returns a FileRef instance pointing to a nonexistent file. - // Should be used for testing only. - static FileRef* GetNonexistentFileRef(PluginModule* module); + FilePath GetSystemPath() const; private: + scoped_refptr<FileSystem> file_system_; + std::string virtual_path_; // UTF-8 encoded FilePath system_path_; - PP_FileSystemType_Dev fs_type_; - std::string path_; // UTF-8 encoded. - std::string origin_; }; } // namespace pepper diff --git a/webkit/glue/plugins/pepper_file_system.cc b/webkit/glue/plugins/pepper_file_system.cc index 82a2fc8..21321a5 100644 --- a/webkit/glue/plugins/pepper_file_system.cc +++ b/webkit/glue/plugins/pepper_file_system.cc @@ -4,244 +4,79 @@ #include "webkit/glue/plugins/pepper_file_system.h" -#include "base/logging.h" #include "base/ref_counted.h" -#include "base/weak_ptr.h" #include "third_party/ppapi/c/dev/ppb_file_system_dev.h" #include "third_party/ppapi/c/pp_completion_callback.h" -#include "third_party/ppapi/c/pp_time.h" -#include "webkit/fileapi/file_system_callback_dispatcher.h" -#include "webkit/glue/plugins/pepper_resource.h" -#include "webkit/glue/plugins/pepper_error_util.h" -#include "webkit/glue/plugins/pepper_file_ref.h" +#include "third_party/WebKit/WebKit/chromium/public/WebDocument.h" +#include "third_party/WebKit/WebKit/chromium/public/WebElement.h" +#include "third_party/WebKit/WebKit/chromium/public/WebFrame.h" +#include "third_party/WebKit/WebKit/chromium/public/WebPluginContainer.h" +#include "webkit/fileapi/file_system_types.h" +#include "webkit/glue/plugins/pepper_file_callbacks.h" #include "webkit/glue/plugins/pepper_plugin_delegate.h" #include "webkit/glue/plugins/pepper_plugin_instance.h" #include "webkit/glue/plugins/pepper_plugin_module.h" #include "webkit/glue/plugins/pepper_resource.h" +#include "webkit/glue/plugins/pepper_resource_tracker.h" namespace pepper { namespace { -// Instances of this class are deleted when RunCallback() is called. -class StatusCallback : public fileapi::FileSystemCallbackDispatcher { - public: - StatusCallback(base::WeakPtr<pepper::PluginModule> module, - PP_CompletionCallback callback) - : module_(module), - callback_(callback) { - } - - // FileSystemCallbackDispatcher implementation. - virtual void DidSucceed() { - RunCallback(base::PLATFORM_FILE_OK); - } - - virtual void DidReadMetadata(const base::PlatformFileInfo&) { - NOTREACHED(); - } - - virtual void DidReadDirectory( - const std::vector<base::file_util_proxy::Entry>&, bool) { - NOTREACHED(); - } - - virtual void DidOpenFileSystem(const std::string&, const FilePath&) { - NOTREACHED(); - } - - virtual void DidFail(base::PlatformFileError error_code) { - RunCallback(error_code); - } - - private: - void RunCallback(base::PlatformFileError error_code) { - if (!module_.get() || !callback_.func) - return; - - PP_RunCompletionCallback( - &callback_, pepper::PlatformFileErrorToPepperError(error_code)); - - delete this; - } - - base::WeakPtr<pepper::PluginModule> module_; - PP_CompletionCallback callback_; -}; - -// Instances of this class are deleted when RunCallback() is called. -class QueryInfoCallback : public fileapi::FileSystemCallbackDispatcher { - public: - QueryInfoCallback(base::WeakPtr<pepper::PluginModule> module, - PP_CompletionCallback callback, - PP_FileInfo_Dev* info, - PP_FileSystemType_Dev file_system_type) - : module_(module), - callback_(callback), - info_(info), - file_system_type_(file_system_type) { - DCHECK(info_); - } - - // FileSystemCallbackDispatcher implementation. - virtual void DidSucceed() { - NOTREACHED(); - } - - virtual void DidReadMetadata(const base::PlatformFileInfo& file_info) { - RunCallback(base::PLATFORM_FILE_OK, file_info); - } - - virtual void DidReadDirectory( - const std::vector<base::file_util_proxy::Entry>&, bool) { - NOTREACHED(); - } - - virtual void DidOpenFileSystem(const std::string&, const FilePath&) { - NOTREACHED(); - } - - virtual void DidFail(base::PlatformFileError error_code) { - RunCallback(error_code, base::PlatformFileInfo()); - } - - private: - void RunCallback(base::PlatformFileError error_code, - const base::PlatformFileInfo& file_info) { - if (!module_.get() || !callback_.func) - return; - - if (error_code == base::PLATFORM_FILE_OK) { - info_->size = file_info.size; - info_->creation_time = file_info.creation_time.ToDoubleT(); - info_->last_access_time = file_info.last_accessed.ToDoubleT(); - info_->last_modified_time = file_info.last_modified.ToDoubleT(); - info_->system_type = file_system_type_; - if (file_info.is_directory) - info_->type = PP_FILETYPE_DIRECTORY; - else - info_->type = PP_FILETYPE_REGULAR; - } - PP_RunCompletionCallback( - &callback_, pepper::PlatformFileErrorToPepperError(error_code)); - - delete this; - } - - base::WeakPtr<pepper::PluginModule> module_; - PP_CompletionCallback callback_; - PP_FileInfo_Dev* info_; - PP_FileSystemType_Dev file_system_type_; -}; - -int32_t MakeDirectory(PP_Resource directory_ref_id, - bool make_ancestors, - PP_CompletionCallback callback) { - scoped_refptr<FileRef> directory_ref( - Resource::GetAs<FileRef>(directory_ref_id)); - if (!directory_ref) - return PP_ERROR_BADRESOURCE; - - if (directory_ref->file_system_type() == PP_FILESYSTEMTYPE_EXTERNAL) - return PP_ERROR_FAILED; - - PluginModule* module = directory_ref->module(); - if (!module->GetSomeInstance()->delegate()->MakeDirectory( - directory_ref->system_path(), make_ancestors, - new StatusCallback(module->AsWeakPtr(), callback))) - return PP_ERROR_FAILED; +PP_Resource Create(PP_Instance instance, PP_FileSystemType_Dev type) { + PluginInstance* plugin_instance = + ResourceTracker::Get()->GetInstance(instance); + if (!plugin_instance) + return 0; - return PP_ERROR_WOULDBLOCK; + FileSystem* file_system = new FileSystem(plugin_instance, type); + return file_system->GetReference(); } -int32_t Query(PP_Resource file_ref_id, - PP_FileInfo_Dev* info, - PP_CompletionCallback callback) { - scoped_refptr<FileRef> file_ref(Resource::GetAs<FileRef>(file_ref_id)); - if (!file_ref) +int32_t Open(PP_Resource file_system_id, + int64 expected_size, + PP_CompletionCallback callback) { + scoped_refptr<FileSystem> file_system( + Resource::GetAs<FileSystem>(file_system_id)); + if (!file_system) return PP_ERROR_BADRESOURCE; - PluginModule* module = file_ref->module(); - if (!module->GetSomeInstance()->delegate()->Query( - file_ref->system_path(), - new QueryInfoCallback(module->AsWeakPtr(), callback, - info, file_ref->file_system_type()))) - return PP_ERROR_FAILED; - - return PP_ERROR_WOULDBLOCK; -} + if (file_system->opened()) + return PP_OK; -int32_t Touch(PP_Resource file_ref_id, - PP_Time last_access_time, - PP_Time last_modified_time, - PP_CompletionCallback callback) { - scoped_refptr<FileRef> file_ref(Resource::GetAs<FileRef>(file_ref_id)); - if (!file_ref) - return PP_ERROR_BADRESOURCE; - - PluginModule* module = file_ref->module(); - if (!module->GetSomeInstance()->delegate()->Touch( - file_ref->system_path(), base::Time::FromDoubleT(last_access_time), - base::Time::FromDoubleT(last_modified_time), - new StatusCallback(module->AsWeakPtr(), callback))) + if ((file_system->type() != PP_FILESYSTEMTYPE_LOCALPERSISTENT) && + (file_system->type() != PP_FILESYSTEMTYPE_LOCALTEMPORARY)) return PP_ERROR_FAILED; - return PP_ERROR_WOULDBLOCK; -} - -int32_t Delete(PP_Resource file_ref_id, - PP_CompletionCallback callback) { - scoped_refptr<FileRef> file_ref(Resource::GetAs<FileRef>(file_ref_id)); - if (!file_ref) - return PP_ERROR_BADRESOURCE; - - if (file_ref->file_system_type() == PP_FILESYSTEMTYPE_EXTERNAL) - return PP_ERROR_FAILED; - - PluginModule* module = file_ref->module(); - if (!module->GetSomeInstance()->delegate()->Delete( - file_ref->system_path(), - new StatusCallback(module->AsWeakPtr(), callback))) - return PP_ERROR_FAILED; - - return PP_ERROR_WOULDBLOCK; -} - -int32_t Rename(PP_Resource file_ref_id, - PP_Resource new_file_ref_id, - PP_CompletionCallback callback) { - scoped_refptr<FileRef> file_ref(Resource::GetAs<FileRef>(file_ref_id)); - if (!file_ref) - return PP_ERROR_BADRESOURCE; - - scoped_refptr<FileRef> new_file_ref( - Resource::GetAs<FileRef>(new_file_ref_id)); - if (!new_file_ref) - return PP_ERROR_BADRESOURCE; - - if ((file_ref->file_system_type() == PP_FILESYSTEMTYPE_EXTERNAL) || - (file_ref->file_system_type() != new_file_ref->file_system_type())) - return PP_ERROR_FAILED; - - PluginModule* module = file_ref->module(); - if (!module->GetSomeInstance()->delegate()->Rename( - file_ref->system_path(), new_file_ref->system_path(), - new StatusCallback(module->AsWeakPtr(), callback))) + PluginInstance* instance = file_system->instance(); + fileapi::FileSystemType file_system_type = + (file_system->type() == PP_FILESYSTEMTYPE_LOCALTEMPORARY ? + fileapi::kFileSystemTypeTemporary : + fileapi::kFileSystemTypePersistent); + if (!instance->delegate()->OpenFileSystem( + instance->container()->element().document().frame()->url(), + file_system_type, expected_size, + new FileCallbacks(instance->module()->AsWeakPtr(), + callback, NULL, file_system))) return PP_ERROR_FAILED; return PP_ERROR_WOULDBLOCK; } const PPB_FileSystem_Dev ppb_filesystem = { - &MakeDirectory, - &Query, - &Touch, - &Delete, - &Rename + &Create, + &Open }; } // namespace +FileSystem::FileSystem(PluginInstance* instance, PP_FileSystemType_Dev type) + : Resource(instance->module()), + instance_(instance), + type_(type), + opened_(false) { +} + const PPB_FileSystem_Dev* FileSystem::GetInterface() { return &ppb_filesystem; } diff --git a/webkit/glue/plugins/pepper_file_system.h b/webkit/glue/plugins/pepper_file_system.h index 1abfc52..f883299 100644 --- a/webkit/glue/plugins/pepper_file_system.h +++ b/webkit/glue/plugins/pepper_file_system.h @@ -6,19 +6,37 @@ #define WEBKIT_GLUE_PLUGINS_PEPPER_FILE_SYSTEM_H_ #include "base/basictypes.h" +#include "base/file_path.h" +#include "third_party/ppapi/c/dev/pp_file_info_dev.h" +#include "webkit/glue/plugins/pepper_resource.h" struct PPB_FileSystem_Dev; namespace pepper { -class FileSystem { +class PluginInstance; + +class FileSystem : public Resource { public: // Returns a pointer to the interface implementing PPB_FileSystem that is // exposed to the plugin. static const PPB_FileSystem_Dev* GetInterface(); + FileSystem(PluginInstance* instance, PP_FileSystemType_Dev type); + FileSystem* AsFileSystem() { return this; } + + PluginInstance* instance() { return instance_; } + PP_FileSystemType_Dev type() { return type_; } + const FilePath& root_path() const { return root_path_; } + void set_root_path(const FilePath& root_path) { root_path_ = root_path; } + bool opened() const { return opened_; } + void set_opened(bool opened) { opened_ = opened; } + private: - DISALLOW_IMPLICIT_CONSTRUCTORS(FileSystem); + PluginInstance* instance_; + PP_FileSystemType_Dev type_; + FilePath root_path_; + bool opened_; }; } // namespace pepper diff --git a/webkit/glue/plugins/pepper_font.cc b/webkit/glue/plugins/pepper_font.cc index 82bf369..cad39f5 100644 --- a/webkit/glue/plugins/pepper_font.cc +++ b/webkit/glue/plugins/pepper_font.cc @@ -33,7 +33,8 @@ namespace { bool IsPPFontDescriptionValid(const PP_FontDescription_Dev& desc) { // Check validity of UTF-8. - if (desc.face.type != PP_VARTYPE_STRING && desc.face.type != PP_VARTYPE_VOID) + if (desc.face.type != PP_VARTYPE_STRING && + desc.face.type != PP_VARTYPE_UNDEFINED) return false; // Check enum ranges. @@ -107,7 +108,7 @@ bool PPTextRunToWebTextRun(const PP_TextRun_Dev* run, WebTextRun* output) { PP_Resource Create(PP_Module module_id, const PP_FontDescription_Dev* description) { - PluginModule* module = PluginModule::FromPPModule(module_id); + PluginModule* module = ResourceTracker::Get()->GetModule(module_id); if (!module) return 0; @@ -198,7 +199,7 @@ const PPB_Font_Dev* Font::GetInterface() { bool Font::Describe(PP_FontDescription_Dev* description, PP_FontMetrics_Dev* metrics) { - if (description->face.type != PP_VARTYPE_VOID) + if (description->face.type != PP_VARTYPE_UNDEFINED) return false; WebFontDescription web_desc = font_->fontDescription(); diff --git a/webkit/glue/plugins/pepper_graphics_2d.cc b/webkit/glue/plugins/pepper_graphics_2d.cc index 5011f87..a75da85 100644 --- a/webkit/glue/plugins/pepper_graphics_2d.cc +++ b/webkit/glue/plugins/pepper_graphics_2d.cc @@ -25,7 +25,7 @@ #if defined(OS_MACOSX) #include "base/mac_util.h" -#include "base/scoped_cftyperef.h" +#include "base/mac/scoped_cftyperef.h" #endif namespace pepper { @@ -63,10 +63,57 @@ bool ValidateAndConvertRect(const PP_Rect* rect, return true; } +// Converts BGRA <-> RGBA. +void ConvertBetweenBGRAandRGBA(const uint32_t* input, + int pixel_length, + uint32_t* output) { + for (int i = 0; i < pixel_length; i++) { + const unsigned char* pixel_in = + reinterpret_cast<const unsigned char*>(&input[i]); + unsigned char* pixel_out = reinterpret_cast<unsigned char*>(&output[i]); + pixel_out[0] = pixel_in[2]; + pixel_out[1] = pixel_in[1]; + pixel_out[2] = pixel_in[0]; + pixel_out[3] = pixel_in[3]; + } +} + +// Converts ImageData from PP_IMAGEDATAFORMAT_BGRA_PREMUL to +// PP_IMAGEDATAFORMAT_RGBA_PREMUL, or reverse. +void ConvertImageData(ImageData* src_image, const SkIRect& src_rect, + ImageData* dest_image, const SkRect& dest_rect) { + DCHECK(src_image->format() != dest_image->format()); + DCHECK(ImageData::IsImageDataFormatSupported(src_image->format())); + DCHECK(ImageData::IsImageDataFormatSupported(dest_image->format())); + + const SkBitmap* src_bitmap = src_image->GetMappedBitmap(); + const SkBitmap* dest_bitmap = dest_image->GetMappedBitmap(); + if (src_rect.width() == src_image->width() && + dest_rect.width() == dest_image->width()) { + // Fast path if the full line needs to be converted. + ConvertBetweenBGRAandRGBA( + src_bitmap->getAddr32(static_cast<int>(src_rect.fLeft), + static_cast<int>(src_rect.fTop)), + src_rect.width() * src_rect.height(), + dest_bitmap->getAddr32(static_cast<int>(dest_rect.fLeft), + static_cast<int>(dest_rect.fTop))); + } else { + // Slow path where we convert line by line. + for (int y = 0; y < src_rect.height(); y++) { + ConvertBetweenBGRAandRGBA( + src_bitmap->getAddr32(static_cast<int>(src_rect.fLeft), + static_cast<int>(src_rect.fTop + y)), + src_rect.width(), + dest_bitmap->getAddr32(static_cast<int>(dest_rect.fLeft), + static_cast<int>(dest_rect.fTop + y))); + } + } +} + PP_Resource Create(PP_Module module_id, const PP_Size* size, bool is_always_opaque) { - PluginModule* module = PluginModule::FromPPModule(module_id); + PluginModule* module = ResourceTracker::Get()->GetModule(module_id); if (!module) return 0; @@ -80,49 +127,46 @@ bool IsGraphics2D(PP_Resource resource) { return !!Resource::GetAs<Graphics2D>(resource); } -bool Describe(PP_Resource device_context, +bool Describe(PP_Resource graphics_2d, PP_Size* size, bool* is_always_opaque) { scoped_refptr<Graphics2D> context( - Resource::GetAs<Graphics2D>(device_context)); + Resource::GetAs<Graphics2D>(graphics_2d)); if (!context) return false; return context->Describe(size, is_always_opaque); } -bool PaintImageData(PP_Resource device_context, - PP_Resource image, +void PaintImageData(PP_Resource graphics_2d, + PP_Resource image_data, const PP_Point* top_left, const PP_Rect* src_rect) { scoped_refptr<Graphics2D> context( - Resource::GetAs<Graphics2D>(device_context)); - if (!context) - return false; - return context->PaintImageData(image, top_left, src_rect); + Resource::GetAs<Graphics2D>(graphics_2d)); + if (context) + context->PaintImageData(image_data, top_left, src_rect); } -bool Scroll(PP_Resource device_context, +void Scroll(PP_Resource graphics_2d, const PP_Rect* clip_rect, const PP_Point* amount) { scoped_refptr<Graphics2D> context( - Resource::GetAs<Graphics2D>(device_context)); - if (!context) - return false; - return context->Scroll(clip_rect, amount); + Resource::GetAs<Graphics2D>(graphics_2d)); + if (context) + context->Scroll(clip_rect, amount); } -bool ReplaceContents(PP_Resource device_context, PP_Resource image) { +void ReplaceContents(PP_Resource graphics_2d, PP_Resource image_data) { scoped_refptr<Graphics2D> context( - Resource::GetAs<Graphics2D>(device_context)); - if (!context) - return false; - return context->ReplaceContents(image); + Resource::GetAs<Graphics2D>(graphics_2d)); + if (context) + context->ReplaceContents(image_data); } -int32_t Flush(PP_Resource device_context, +int32_t Flush(PP_Resource graphics_2d, PP_CompletionCallback callback) { scoped_refptr<Graphics2D> context( - Resource::GetAs<Graphics2D>(device_context)); + Resource::GetAs<Graphics2D>(graphics_2d)); if (!context) return PP_ERROR_BADRESOURCE; return context->Flush(callback); @@ -189,8 +233,8 @@ const PPB_Graphics2D* Graphics2D::GetInterface() { bool Graphics2D::Init(int width, int height, bool is_always_opaque) { // The underlying ImageData will validate the dimensions. image_data_ = new ImageData(module()); - if (!image_data_->Init(PP_IMAGEDATAFORMAT_BGRA_PREMUL, width, height, true) || - !image_data_->Map()) { + if (!image_data_->Init(ImageData::GetNativeImageDataFormat(), width, height, + true) || !image_data_->Map()) { image_data_ = NULL; return false; } @@ -205,22 +249,23 @@ bool Graphics2D::Describe(PP_Size* size, bool* is_always_opaque) { return true; } -bool Graphics2D::PaintImageData(PP_Resource image, +void Graphics2D::PaintImageData(PP_Resource image_data, const PP_Point* top_left, const PP_Rect* src_rect) { if (!top_left) - return false; + return; - scoped_refptr<ImageData> image_resource(Resource::GetAs<ImageData>(image)); + scoped_refptr<ImageData> image_resource( + Resource::GetAs<ImageData>(image_data)); if (!image_resource) - return false; + return; QueuedOperation operation(QueuedOperation::PAINT); operation.paint_image = image_resource; if (!ValidateAndConvertRect(src_rect, image_resource->width(), image_resource->height(), &operation.paint_src_rect)) - return false; + return; // Validate the bitmap position using the previously-validated rect, there // should be no painted area outside of the image. @@ -229,25 +274,24 @@ bool Graphics2D::PaintImageData(PP_Resource image, if (x64 + static_cast<int64>(operation.paint_src_rect.x()) < 0 || x64 + static_cast<int64>(operation.paint_src_rect.right()) > image_data_->width()) - return false; + return; if (y64 + static_cast<int64>(operation.paint_src_rect.y()) < 0 || y64 + static_cast<int64>(operation.paint_src_rect.bottom()) > image_data_->height()) - return false; + return; operation.paint_x = top_left->x; operation.paint_y = top_left->y; queued_operations_.push_back(operation); - return true; } -bool Graphics2D::Scroll(const PP_Rect* clip_rect, const PP_Point* amount) { +void Graphics2D::Scroll(const PP_Rect* clip_rect, const PP_Point* amount) { QueuedOperation operation(QueuedOperation::SCROLL); if (!ValidateAndConvertRect(clip_rect, image_data_->width(), image_data_->height(), &operation.scroll_clip_rect)) - return false; + return; // If we're being asked to scroll by more than the clip rect size, just // ignore this scroll command and say it worked. @@ -255,31 +299,29 @@ bool Graphics2D::Scroll(const PP_Rect* clip_rect, const PP_Point* amount) { int32 dy = amount->y; if (dx <= -image_data_->width() || dx >= image_data_->width() || dx <= -image_data_->height() || dy >= image_data_->height()) - return true; + return; operation.scroll_dx = dx; operation.scroll_dy = dy; queued_operations_.push_back(operation); - return false; } -bool Graphics2D::ReplaceContents(PP_Resource image) { - scoped_refptr<ImageData> image_resource(Resource::GetAs<ImageData>(image)); +void Graphics2D::ReplaceContents(PP_Resource image_data) { + scoped_refptr<ImageData> image_resource( + Resource::GetAs<ImageData>(image_data)); if (!image_resource) - return false; - if (image_resource->format() != PP_IMAGEDATAFORMAT_BGRA_PREMUL) - return false; + return; + if (!ImageData::IsImageDataFormatSupported(image_resource->format())) + return; if (image_resource->width() != image_data_->width() || image_resource->height() != image_data_->height()) - return false; + return; QueuedOperation operation(QueuedOperation::REPLACE); operation.replace_image = image_resource; queued_operations_.push_back(operation); - - return true; } int32_t Graphics2D::Flush(const PP_CompletionCallback& callback) { @@ -342,7 +384,7 @@ bool Graphics2D::ReadImageData(PP_Resource image, scoped_refptr<ImageData> image_resource(Resource::GetAs<ImageData>(image)); if (!image_resource) return false; - if (image_resource->format() != PP_IMAGEDATAFORMAT_BGRA_PREMUL) + if (!ImageData::IsImageDataFormatSupported(image_resource->format())) return false; // Must be in the right format. // Validate the bitmap position. @@ -360,7 +402,6 @@ bool Graphics2D::ReadImageData(PP_Resource image, ImageDataAutoMapper auto_mapper(image_resource); if (!auto_mapper.is_valid()) return false; - skia::PlatformCanvas* dest_canvas = image_resource->mapped_canvas(); SkIRect src_irect = { x, y, x + image_resource->width(), @@ -370,11 +411,18 @@ bool Graphics2D::ReadImageData(PP_Resource image, SkIntToScalar(image_resource->width()), SkIntToScalar(image_resource->height()) }; - // We want to replace the contents of the bitmap rather than blend. - SkPaint paint; - paint.setXfermodeMode(SkXfermode::kSrc_Mode); - dest_canvas->drawBitmapRect(*image_data_->GetMappedBitmap(), - &src_irect, dest_rect, &paint); + if (image_resource->format() != image_data_->format()) { + // Convert the image data if the format does not match. + ConvertImageData(image_data_, src_irect, image_resource.get(), dest_rect); + } else { + skia::PlatformCanvas* dest_canvas = image_resource->mapped_canvas(); + + // We want to replace the contents of the bitmap rather than blend. + SkPaint paint; + paint.setXfermodeMode(SkXfermode::kSrc_Mode); + dest_canvas->drawBitmapRect(*image_data_->GetMappedBitmap(), + &src_irect, dest_rect, &paint); + } return true; } @@ -421,11 +469,11 @@ void Graphics2D::Paint(WebKit::WebCanvas* canvas, #if defined(OS_MACOSX) SkAutoLockPixels lock(backing_bitmap); - scoped_cftyperef<CGDataProviderRef> data_provider( + base::mac::ScopedCFTypeRef<CGDataProviderRef> data_provider( CGDataProviderCreateWithData( NULL, backing_bitmap.getAddr32(0, 0), backing_bitmap.rowBytes() * backing_bitmap.height(), NULL)); - scoped_cftyperef<CGImageRef> image( + base::mac::ScopedCFTypeRef<CGImageRef> image( CGImageCreate( backing_bitmap.width(), backing_bitmap.height(), 8, 32, backing_bitmap.rowBytes(), @@ -510,14 +558,19 @@ void Graphics2D::ExecutePaintImageData(ImageData* image, SkIntToScalar(invalidated_rect->right()), SkIntToScalar(invalidated_rect->bottom()) }; - // We're guaranteed to have a mapped canvas since we mapped it in Init(). - skia::PlatformCanvas* backing_canvas = image_data_->mapped_canvas(); + if (image->format() != image_data_->format()) { + // Convert the image data if the format does not match. + ConvertImageData(image, src_irect, image_data_, dest_rect); + } else { + // We're guaranteed to have a mapped canvas since we mapped it in Init(). + skia::PlatformCanvas* backing_canvas = image_data_->mapped_canvas(); - // We want to replace the contents of the bitmap rather than blend. - SkPaint paint; - paint.setXfermodeMode(SkXfermode::kSrc_Mode); - backing_canvas->drawBitmapRect(*image->GetMappedBitmap(), - &src_irect, dest_rect, &paint); + // We want to replace the contents of the bitmap rather than blend. + SkPaint paint; + paint.setXfermodeMode(SkXfermode::kSrc_Mode); + backing_canvas->drawBitmapRect(*image->GetMappedBitmap(), + &src_irect, dest_rect, &paint); + } } void Graphics2D::ExecuteScroll(const gfx::Rect& clip, int dx, int dy, @@ -529,7 +582,19 @@ void Graphics2D::ExecuteScroll(const gfx::Rect& clip, int dx, int dy, void Graphics2D::ExecuteReplaceContents(ImageData* image, gfx::Rect* invalidated_rect) { - image_data_->Swap(image); + if (image->format() != image_data_->format()) { + DCHECK(image->width() == image_data_->width() && + image->height() == image_data_->height()); + // Convert the image data if the format does not match. + SkIRect src_irect = { 0, 0, image->width(), image->height() }; + SkRect dest_rect = { SkIntToScalar(0), + SkIntToScalar(0), + SkIntToScalar(image_data_->width()), + SkIntToScalar(image_data_->height()) }; + ConvertImageData(image, src_irect, image_data_, dest_rect); + } else { + image_data_->Swap(image); + } *invalidated_rect = gfx::Rect(0, 0, image_data_->width(), image_data_->height()); } diff --git a/webkit/glue/plugins/pepper_graphics_2d.h b/webkit/glue/plugins/pepper_graphics_2d.h index 3af84de..ff4cd16 100644 --- a/webkit/glue/plugins/pepper_graphics_2d.h +++ b/webkit/glue/plugins/pepper_graphics_2d.h @@ -43,11 +43,11 @@ class Graphics2D : public Resource { // PPB_Graphics2D functions. bool Describe(PP_Size* size, bool* is_always_opaque); - bool PaintImageData(PP_Resource image, + void PaintImageData(PP_Resource image_data, const PP_Point* top_left, const PP_Rect* src_rect); - bool Scroll(const PP_Rect* clip_rect, const PP_Point* amount); - bool ReplaceContents(PP_Resource image); + void Scroll(const PP_Rect* clip_rect, const PP_Point* amount); + void ReplaceContents(PP_Resource image_data); int32_t Flush(const PP_CompletionCallback& callback); bool ReadImageData(PP_Resource image, const PP_Point* top_left); diff --git a/webkit/glue/plugins/pepper_graphics_3d.cc b/webkit/glue/plugins/pepper_graphics_3d.cc index 18e5cd1..1ebc3ea 100644 --- a/webkit/glue/plugins/pepper_graphics_3d.cc +++ b/webkit/glue/plugins/pepper_graphics_3d.cc @@ -62,7 +62,7 @@ PP_Resource CreateContext(PP_Instance instance_id, int32_t config, const int32_t* attrib_list) { DCHECK_EQ(0, share_context); - PluginInstance* instance = PluginInstance::FromPPInstance(instance_id); + PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id); if (!instance) { return 0; } @@ -146,7 +146,7 @@ Graphics3D::~Graphics3D() { bool Graphics3D::Init(PP_Instance instance_id, int32_t config, const int32_t* attrib_list) { - PluginInstance* instance = PluginInstance::FromPPInstance(instance_id); + PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id); if (!instance) { return false; } @@ -241,7 +241,7 @@ void Graphics3D::Destroy() { } void Graphics3D::HandleRepaint(PP_Instance instance_id) { - PluginInstance* instance = PluginInstance::FromPPInstance(instance_id); + PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id); if (instance) { instance->Graphics3DContextLost(); if (platform_context_.get()) { diff --git a/webkit/glue/plugins/pepper_image_data.cc b/webkit/glue/plugins/pepper_image_data.cc index aeb2c88..2ee8b21 100644 --- a/webkit/glue/plugins/pepper_image_data.cc +++ b/webkit/glue/plugins/pepper_image_data.cc @@ -15,6 +15,7 @@ #include "third_party/ppapi/c/pp_resource.h" #include "third_party/ppapi/c/ppb_image_data.h" #include "third_party/ppapi/c/trusted/ppb_image_data_trusted.h" +#include "third_party/skia/include/core/SkColorPriv.h" #include "webkit/glue/plugins/pepper_plugin_instance.h" #include "webkit/glue/plugins/pepper_plugin_module.h" @@ -23,14 +24,18 @@ namespace pepper { namespace { PP_ImageDataFormat GetNativeImageDataFormat() { - return PP_IMAGEDATAFORMAT_BGRA_PREMUL; + return ImageData::GetNativeImageDataFormat(); +} + +bool IsImageDataFormatSupported(PP_ImageDataFormat format) { + return ImageData::IsImageDataFormatSupported(format); } PP_Resource Create(PP_Module module_id, PP_ImageDataFormat format, const PP_Size* size, bool init_to_zero) { - PluginModule* module = PluginModule::FromPPModule(module_id); + PluginModule* module = ResourceTracker::Get()->GetModule(module_id); if (!module) return 0; @@ -78,6 +83,7 @@ uint64_t GetNativeMemoryHandle2(PP_Resource resource) { const PPB_ImageData ppb_imagedata = { &GetNativeImageDataFormat, + &IsImageDataFormatSupported, &Create, &IsImageData, &Describe, @@ -93,6 +99,7 @@ const PPB_ImageDataTrusted ppb_imagedata_trusted = { ImageData::ImageData(PluginModule* module) : Resource(module), + format_(PP_IMAGEDATAFORMAT_BGRA_PREMUL), width_(0), height_(0) { } @@ -110,12 +117,28 @@ const PPB_ImageDataTrusted* ImageData::GetTrustedInterface() { return &ppb_imagedata_trusted; } +// static +PP_ImageDataFormat ImageData::GetNativeImageDataFormat() { + if (SK_B32_SHIFT == 0) + return PP_IMAGEDATAFORMAT_BGRA_PREMUL; + else if (SK_R32_SHIFT == 0) + return PP_IMAGEDATAFORMAT_RGBA_PREMUL; + else + return PP_IMAGEDATAFORMAT_BGRA_PREMUL; // Default to something on failure. +} + +// static +bool ImageData::IsImageDataFormatSupported(PP_ImageDataFormat format) { + return format == PP_IMAGEDATAFORMAT_BGRA_PREMUL || + format == PP_IMAGEDATAFORMAT_RGBA_PREMUL; +} + bool ImageData::Init(PP_ImageDataFormat format, int width, int height, bool init_to_zero) { // TODO(brettw) this should be called only on the main thread! // TODO(brettw) use init_to_zero when we implement caching. - if (format != PP_IMAGEDATAFORMAT_BGRA_PREMUL) + if (!IsImageDataFormatSupported(format)) return false; // Only support this one format for now. if (width <= 0 || height <= 0) return false; @@ -125,13 +148,14 @@ bool ImageData::Init(PP_ImageDataFormat format, platform_image_.reset( module()->GetSomeInstance()->delegate()->CreateImage2D(width, height)); + format_ = format; width_ = width; height_ = height; return !!platform_image_.get(); } void ImageData::Describe(PP_ImageDataDesc* desc) const { - desc->format = PP_IMAGEDATAFORMAT_BGRA_PREMUL; + desc->format = format_; desc->size.width = width_; desc->size.height = height_; desc->stride = width_ * 4; @@ -173,6 +197,7 @@ const SkBitmap* ImageData::GetMappedBitmap() const { void ImageData::Swap(ImageData* other) { swap(other->platform_image_, platform_image_); swap(other->mapped_canvas_, mapped_canvas_); + std::swap(other->format_, format_); std::swap(other->width_, width_); std::swap(other->height_, height_); } diff --git a/webkit/glue/plugins/pepper_image_data.h b/webkit/glue/plugins/pepper_image_data.h index f2a110b..f8c713a 100644 --- a/webkit/glue/plugins/pepper_image_data.h +++ b/webkit/glue/plugins/pepper_image_data.h @@ -28,11 +28,8 @@ class ImageData : public Resource { int width() const { return width_; } int height() const { return height_; } - // Returns the image format. Currently there is only one format so this - // always returns the same thing. But if you care about the formation, you - // should probably check this so when we support multiple formats, we can't - // forget to update your code. - PP_ImageDataFormat format() const { return PP_IMAGEDATAFORMAT_BGRA_PREMUL; } + // Returns the image format. + PP_ImageDataFormat format() const { return format_; } // Returns true if this image is mapped. False means that the image is either // invalid or not mapped. See ImageDataAutoMapper below. @@ -47,6 +44,14 @@ class ImageData : public Resource { static const PPB_ImageData* GetInterface(); static const PPB_ImageDataTrusted* GetTrustedInterface(); + // Returns the image data format used by the browser. If the plugin uses the + // same format, there is no conversion. Otherwise the browser will be in + // charge of converting from a supported format to its native format. + static PP_ImageDataFormat GetNativeImageDataFormat(); + + // Returns true if the format is supported by the browser. + static bool IsImageDataFormatSupported(PP_ImageDataFormat format); + // Resource overrides. virtual ImageData* AsImageData() { return this; } @@ -76,6 +81,7 @@ class ImageData : public Resource { // When the device is mapped, this is the image. Null when umapped. scoped_ptr<skia::PlatformCanvas> mapped_canvas_; + PP_ImageDataFormat format_; int width_; int height_; diff --git a/webkit/glue/plugins/pepper_plugin_delegate.h b/webkit/glue/plugins/pepper_plugin_delegate.h index 1bb4bed..7738fbf 100644 --- a/webkit/glue/plugins/pepper_plugin_delegate.h +++ b/webkit/glue/plugins/pepper_plugin_delegate.h @@ -13,11 +13,15 @@ #include "base/shared_memory.h" #include "base/sync_socket.h" #include "base/task.h" +#include "googleurl/src/gurl.h" #include "third_party/ppapi/c/pp_completion_callback.h" #include "third_party/ppapi/c/pp_errors.h" #include "third_party/ppapi/c/pp_stdint.h" +#include "webkit/fileapi/file_system_types.h" +#include "webkit/glue/plugins/pepper_dir_contents.h" class AudioMessageFilter; +class GURL; namespace base { class MessageLoopProxy; @@ -156,12 +160,12 @@ class PluginDelegate { PlatformAudio::Client* client) = 0; // Notifies that the number of find results has changed. - virtual void DidChangeNumberOfFindResults(int identifier, - int total, - bool final_result) = 0; + virtual void NumberOfFindResultsChanged(int identifier, + int total, + bool final_result) = 0; // Notifies that the index of the currently selected item has been updated. - virtual void DidChangeSelectedFindResult(int identifier, int index) = 0; + virtual void SelectedFindResultChanged(int identifier, int index) = 0; // Runs a file chooser. virtual bool RunFileChooser( @@ -174,6 +178,11 @@ class PluginDelegate { virtual bool AsyncOpenFile(const FilePath& path, int flags, AsyncOpenFileCallback* callback) = 0; + virtual bool OpenFileSystem( + const GURL& url, + fileapi::FileSystemType type, + long long size, + fileapi::FileSystemCallbackDispatcher* dispatcher) = 0; virtual bool MakeDirectory( const FilePath& path, bool recursive, @@ -190,6 +199,31 @@ class PluginDelegate { const FilePath& new_file_path, fileapi::FileSystemCallbackDispatcher* dispatcher) = 0; + virtual base::PlatformFileError OpenModuleLocalFile( + const std::string& module_name, + const FilePath& path, + int flags, + base::PlatformFile* file) = 0; + virtual base::PlatformFileError RenameModuleLocalFile( + const std::string& module_name, + const FilePath& path_from, + const FilePath& path_to) = 0; + virtual base::PlatformFileError DeleteModuleLocalFileOrDir( + const std::string& module_name, + const FilePath& path, + bool recursive) = 0; + virtual base::PlatformFileError CreateModuleLocalDir( + const std::string& module_name, + const FilePath& path) = 0; + virtual base::PlatformFileError QueryModuleLocalFile( + const std::string& module_name, + const FilePath& path, + base::PlatformFileInfo* info) = 0; + virtual base::PlatformFileError GetModuleLocalDirContents( + const std::string& module_name, + const FilePath& path, + PepperDirContents* contents) = 0; + // Returns a MessageLoopProxy instance associated with the message loop // of the file thread in this renderer. virtual scoped_refptr<base::MessageLoopProxy> @@ -202,6 +236,21 @@ class PluginDelegate { // Returns a string with the name of the default 8-bit char encoding. virtual std::string GetDefaultEncoding() = 0; + + // Sets the mininum and maximium zoom factors. + virtual void ZoomLimitsChanged(double minimum_factor, + double maximum_factor) = 0; + + // Retrieves the proxy information for the given URL in PAC format. On error, + // this will return an empty string. + virtual std::string ResolveProxy(const GURL& url) = 0; + + // Tell the browser when resource loading starts/ends. + virtual void DidStartLoading() = 0; + virtual void DidStopLoading() = 0; + + // Sets restrictions on how the content can be used (i.e. no print/copy). + virtual void SetContentRestriction(int restrictions) = 0; }; } // namespace pepper diff --git a/webkit/glue/plugins/pepper_plugin_instance.cc b/webkit/glue/plugins/pepper_plugin_instance.cc index b4ccd89..54a1f42 100644 --- a/webkit/glue/plugins/pepper_plugin_instance.cc +++ b/webkit/glue/plugins/pepper_plugin_instance.cc @@ -5,10 +5,10 @@ #include "webkit/glue/plugins/pepper_plugin_instance.h" #include "base/logging.h" -#include "base/histogram.h" +#include "base/metrics/histogram.h" #if defined(OS_MACOSX) #include "base/mac_util.h" -#include "base/scoped_cftyperef.h" +#include "base/mac/scoped_cftyperef.h" #endif #include "base/scoped_ptr.h" #include "base/utf_string_conversions.h" @@ -24,7 +24,9 @@ #include "skia/ext/platform_canvas.h" #include "third_party/ppapi/c/dev/ppb_find_dev.h" #include "third_party/ppapi/c/dev/ppb_fullscreen_dev.h" +#include "third_party/ppapi/c/dev/ppb_zoom_dev.h" #include "third_party/ppapi/c/dev/ppp_find_dev.h" +#include "third_party/ppapi/c/dev/ppp_selection_dev.h" #include "third_party/ppapi/c/dev/ppp_zoom_dev.h" #include "third_party/ppapi/c/pp_input_event.h" #include "third_party/ppapi/c/pp_instance.h" @@ -42,6 +44,7 @@ #include "third_party/WebKit/WebKit/chromium/public/WebInputEvent.h" #include "third_party/WebKit/WebKit/chromium/public/WebPluginContainer.h" #include "third_party/WebKit/WebKit/chromium/public/WebRect.h" +#include "third_party/WebKit/WebKit/chromium/public/WebView.h" #include "webkit/glue/plugins/pepper_buffer.h" #include "webkit/glue/plugins/pepper_graphics_2d.h" #include "webkit/glue/plugins/pepper_event_conversion.h" @@ -52,6 +55,7 @@ #include "webkit/glue/plugins/pepper_string.h" #include "webkit/glue/plugins/pepper_url_loader.h" #include "webkit/glue/plugins/pepper_var.h" +#include "webkit/glue/plugins/ppp_private.h" using WebKit::WebBindings; using WebKit::WebCanvas; @@ -59,6 +63,7 @@ using WebKit::WebCursorInfo; using WebKit::WebFrame; using WebKit::WebInputEvent; using WebKit::WebPluginContainer; +using WebKit::WebView; namespace pepper { @@ -137,28 +142,28 @@ void RectToPPRect(const gfx::Rect& input, PP_Rect* output) { } PP_Var GetWindowObject(PP_Instance instance_id) { - PluginInstance* instance = PluginInstance::FromPPInstance(instance_id); + PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id); if (!instance) - return PP_MakeVoid(); + return PP_MakeUndefined(); return instance->GetWindowObject(); } PP_Var GetOwnerElementObject(PP_Instance instance_id) { - PluginInstance* instance = PluginInstance::FromPPInstance(instance_id); + PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id); if (!instance) - return PP_MakeVoid(); + return PP_MakeUndefined(); return instance->GetOwnerElementObject(); } bool BindGraphics(PP_Instance instance_id, PP_Resource device_id) { - PluginInstance* instance = PluginInstance::FromPPInstance(instance_id); + PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id); if (!instance) return false; return instance->BindGraphics(device_id); } bool IsFullFrame(PP_Instance instance_id) { - PluginInstance* instance = PluginInstance::FromPPInstance(instance_id); + PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id); if (!instance) return false; return instance->full_frame(); @@ -167,9 +172,9 @@ bool IsFullFrame(PP_Instance instance_id) { PP_Var ExecuteScript(PP_Instance instance_id, PP_Var script, PP_Var* exception) { - PluginInstance* instance = PluginInstance::FromPPInstance(instance_id); + PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id); if (!instance) - return PP_MakeVoid(); + return PP_MakeUndefined(); return instance->ExecuteScript(script, exception); } @@ -184,23 +189,23 @@ const PPB_Instance ppb_instance = { void NumberOfFindResultsChanged(PP_Instance instance_id, int32_t total, bool final_result) { - PluginInstance* instance = PluginInstance::FromPPInstance(instance_id); + PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id); if (!instance) return; DCHECK_NE(instance->find_identifier(), -1); - instance->delegate()->DidChangeNumberOfFindResults( + instance->delegate()->NumberOfFindResultsChanged( instance->find_identifier(), total, final_result); } void SelectedFindResultChanged(PP_Instance instance_id, int32_t index) { - PluginInstance* instance = PluginInstance::FromPPInstance(instance_id); + PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id); if (!instance) return; DCHECK_NE(instance->find_identifier(), -1); - instance->delegate()->DidChangeSelectedFindResult( + instance->delegate()->SelectedFindResultChanged( instance->find_identifier(), index); } @@ -210,14 +215,14 @@ const PPB_Find_Dev ppb_find = { }; bool IsFullscreen(PP_Instance instance_id) { - PluginInstance* instance = PluginInstance::FromPPInstance(instance_id); + PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id); if (!instance) return false; return instance->IsFullscreen(); } bool SetFullscreen(PP_Instance instance_id, bool fullscreen) { - PluginInstance* instance = PluginInstance::FromPPInstance(instance_id); + PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id); if (!instance) return false; return instance->SetFullscreen(fullscreen); @@ -228,6 +233,33 @@ const PPB_Fullscreen_Dev ppb_fullscreen = { &SetFullscreen, }; +void ZoomChanged(PP_Instance instance_id, double factor) { + PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id); + if (!instance) + return; + double zoom_level = WebView::zoomFactorToZoomLevel(factor); + instance->container()->zoomLevelChanged(zoom_level); +} + +void ZoomLimitsChanged(PP_Instance instance_id, + double minimum_factor, + double maximium_factor) { + if (minimum_factor > maximium_factor) { + NOTREACHED(); + return; + } + + PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id); + if (!instance) + return; + instance->delegate()->ZoomLimitsChanged(minimum_factor, maximium_factor); +} + +const PPB_Zoom_Dev ppb_zoom = { + &ZoomChanged, + &ZoomLimitsChanged +}; + } // namespace PluginInstance::PluginInstance(PluginDelegate* delegate, @@ -236,12 +268,15 @@ PluginInstance::PluginInstance(PluginDelegate* delegate, : delegate_(delegate), module_(module), instance_interface_(instance_interface), + pp_instance_(0), container_(NULL), full_frame_(false), has_webkit_focus_(false), has_content_area_focus_(false), find_identifier_(-1), plugin_find_interface_(NULL), + plugin_private_interface_(NULL), + plugin_selection_interface_(NULL), plugin_zoom_interface_(NULL), #if defined (OS_LINUX) num_pages_(0), @@ -251,6 +286,8 @@ PluginInstance::PluginInstance(PluginDelegate* delegate, plugin_graphics_3d_interface_(NULL), always_on_top_(false), fullscreen_container_(NULL) { + pp_instance_ = ResourceTracker::Get()->AddInstance(this); + memset(¤t_print_settings_, 0, sizeof(current_print_settings_)); DCHECK(delegate); module_->InstanceCreated(this); @@ -260,6 +297,8 @@ PluginInstance::PluginInstance(PluginDelegate* delegate, PluginInstance::~PluginInstance() { delegate_->InstanceDeleted(this); module_->InstanceDeleted(this); + + ResourceTracker::Get()->InstanceDeleted(pp_instance_); } // static @@ -268,11 +307,6 @@ const PPB_Instance* PluginInstance::GetInterface() { } // static -PluginInstance* PluginInstance::FromPPInstance(PP_Instance instance) { - return reinterpret_cast<PluginInstance*>(instance); -} - -// static const PPB_Find_Dev* PluginInstance::GetFindInterface() { return &ppb_find; } @@ -282,8 +316,9 @@ const PPB_Fullscreen_Dev* PluginInstance::GetFullscreenInterface() { return &ppb_fullscreen; } -PP_Instance PluginInstance::GetPPInstance() { - return reinterpret_cast<intptr_t>(this); +// static +const PPB_Zoom_Dev* PluginInstance::GetZoomInterface() { + return &ppb_zoom; } void PluginInstance::Paint(WebCanvas* canvas, @@ -311,18 +346,18 @@ void PluginInstance::InvalidateRect(const gfx::Rect& rect) { PP_Var PluginInstance::GetWindowObject() { if (!container_) - return PP_MakeVoid(); + return PP_MakeUndefined(); WebFrame* frame = container_->element().document().frame(); if (!frame) - return PP_MakeVoid(); + return PP_MakeUndefined(); return ObjectVar::NPObjectToPPVar(module(), frame->windowObject()); } PP_Var PluginInstance::GetOwnerElementObject() { if (!container_) - return PP_MakeVoid(); + return PP_MakeUndefined(); return ObjectVar::NPObjectToPPVar(module(), container_->scriptableObjectForElement()); } @@ -378,13 +413,13 @@ bool PluginInstance::SetCursor(PP_CursorType_Dev type) { PP_Var PluginInstance::ExecuteScript(PP_Var script, PP_Var* exception) { TryCatch try_catch(module(), exception); if (try_catch.has_exception()) - return PP_MakeVoid(); + return PP_MakeUndefined(); // Convert the script into an inconvenient NPString object. scoped_refptr<StringVar> script_string(StringVar::FromPPVar(script)); if (!script_string) { try_catch.SetException("Script param to ExecuteScript must be a string."); - return PP_MakeVoid(); + return PP_MakeUndefined(); } NPString np_script; np_script.UTF8Characters = script_string->value().c_str(); @@ -394,7 +429,7 @@ PP_Var PluginInstance::ExecuteScript(PP_Var script, PP_Var* exception) { WebFrame* frame = container_->element().document().frame(); if (!frame) { try_catch.SetException("No frame to execute script in."); - return PP_MakeVoid(); + return PP_MakeUndefined(); } NPVariant result; @@ -405,7 +440,7 @@ PP_Var PluginInstance::ExecuteScript(PP_Var script, PP_Var* exception) { // doesn't actually catch this exception. try_catch.SetException("Exception caught"); WebBindings::releaseVariantValue(&result); - return PP_MakeVoid(); + return PP_MakeUndefined(); } PP_Var ret = Var::NPVariantToPPVar(module_, &result); @@ -414,7 +449,7 @@ PP_Var PluginInstance::ExecuteScript(PP_Var script, PP_Var* exception) { } void PluginInstance::Delete() { - instance_interface_->Delete(GetPPInstance()); + instance_interface_->DidDestroy(pp_instance()); if (fullscreen_container_) { fullscreen_container_->Destroy(); @@ -430,9 +465,6 @@ bool PluginInstance::Initialize(WebPluginContainer* container, container_ = container; full_frame_ = full_frame; - if (!instance_interface_->New(GetPPInstance())) - return false; - size_t argc = 0; scoped_array<const char*> argn(new const char*[arg_names.size()]); scoped_array<const char*> argv(new const char*[arg_names.size()]); @@ -442,13 +474,13 @@ bool PluginInstance::Initialize(WebPluginContainer* container, argc++; } - return instance_interface_->Initialize(GetPPInstance(), - argc, argn.get(), argv.get()); + return instance_interface_->DidCreate(pp_instance(), + argc, argn.get(), argv.get()); } bool PluginInstance::HandleDocumentLoad(URLLoader* loader) { Resource::ScopedResourceId resource(loader); - return instance_interface_->HandleDocumentLoad(GetPPInstance(), resource.id); + return instance_interface_->HandleDocumentLoad(pp_instance(), resource.id); } bool PluginInstance::HandleInputEvent(const WebKit::WebInputEvent& event, @@ -459,7 +491,7 @@ bool PluginInstance::HandleInputEvent(const WebKit::WebInputEvent& event, // Each input event may generate more than one PP_InputEvent. bool rv = false; for (size_t i = 0; i < pp_events.size(); i++) - rv |= instance_interface_->HandleInputEvent(GetPPInstance(), &pp_events[i]); + rv |= instance_interface_->HandleInputEvent(pp_instance(), &pp_events[i]); if (cursor_.get()) *cursor_info = *cursor_; @@ -467,7 +499,7 @@ bool PluginInstance::HandleInputEvent(const WebKit::WebInputEvent& event, } PP_Var PluginInstance::GetInstanceObject() { - return instance_interface_->GetInstanceObject(GetPPInstance()); + return instance_interface_->GetInstanceObject(pp_instance()); } void PluginInstance::ViewChanged(const gfx::Rect& position, @@ -486,7 +518,7 @@ void PluginInstance::ViewChanged(const gfx::Rect& position, PP_Rect pp_position, pp_clip; RectToPPRect(position_, &pp_position); RectToPPRect(clip_, &pp_clip); - instance_interface_->ViewChanged(GetPPInstance(), &pp_position, &pp_clip); + instance_interface_->DidChangeView(pp_instance(), &pp_position, &pp_clip); } void PluginInstance::SetWebKitFocus(bool has_focus) { @@ -496,7 +528,7 @@ void PluginInstance::SetWebKitFocus(bool has_focus) { bool old_plugin_focus = PluginHasFocus(); has_webkit_focus_ = has_focus; if (PluginHasFocus() != old_plugin_focus) - instance_interface_->FocusChanged(GetPPInstance(), PluginHasFocus()); + instance_interface_->DidChangeFocus(pp_instance(), PluginHasFocus()); } void PluginInstance::SetContentAreaFocus(bool has_focus) { @@ -506,7 +538,7 @@ void PluginInstance::SetContentAreaFocus(bool has_focus) { bool old_plugin_focus = PluginHasFocus(); has_content_area_focus_ = has_focus; if (PluginHasFocus() != old_plugin_focus) - instance_interface_->FocusChanged(GetPPInstance(), PluginHasFocus()); + instance_interface_->DidChangeFocus(pp_instance(), PluginHasFocus()); } void PluginInstance::ViewInitiatedPaint() { @@ -547,7 +579,25 @@ bool PluginInstance::GetBitmapForOptimizedPluginPaint( } string16 PluginInstance::GetSelectedText(bool html) { - PP_Var rv = instance_interface_->GetSelectedText(GetPPInstance(), html); + if (!LoadSelectionInterface()) + return string16(); + + PP_Var rv = plugin_selection_interface_->GetSelectedText(pp_instance(), html); + scoped_refptr<StringVar> string(StringVar::FromPPVar(rv)); + Var::PluginReleasePPVar(rv); // Release the ref the plugin transfered to us. + if (!string) + return string16(); + return UTF8ToUTF16(string->value()); +} + +string16 PluginInstance::GetLinkAtPosition(const gfx::Point& point) { + if (!LoadPrivateInterface()) + return string16(); + + PP_Point p; + p.x = point.x(); + p.y = point.y(); + PP_Var rv = plugin_private_interface_->GetLinkAtPosition(pp_instance(), p); scoped_refptr<StringVar> string(StringVar::FromPPVar(rv)); Var::PluginReleasePPVar(rv); // Release the ref the plugin transfered to us. if (!string) @@ -555,10 +605,10 @@ string16 PluginInstance::GetSelectedText(bool html) { return UTF8ToUTF16(string->value()); } -void PluginInstance::Zoom(float factor, bool text_only) { +void PluginInstance::Zoom(double factor, bool text_only) { if (!LoadZoomInterface()) return; - plugin_zoom_interface_->Zoom(GetPPInstance(), factor, text_only); + plugin_zoom_interface_->Zoom(pp_instance(), factor, text_only); } bool PluginInstance::StartFind(const string16& search_text, @@ -568,21 +618,21 @@ bool PluginInstance::StartFind(const string16& search_text, return false; find_identifier_ = identifier; return plugin_find_interface_->StartFind( - GetPPInstance(), + pp_instance(), UTF16ToUTF8(search_text.c_str()).c_str(), case_sensitive); } void PluginInstance::SelectFindResult(bool forward) { if (LoadFindInterface()) - plugin_find_interface_->SelectFindResult(GetPPInstance(), forward); + plugin_find_interface_->SelectFindResult(pp_instance(), forward); } void PluginInstance::StopFind() { if (!LoadFindInterface()) return; find_identifier_ = -1; - plugin_find_interface_->StopFind(GetPPInstance()); + plugin_find_interface_->StopFind(pp_instance()); } bool PluginInstance::LoadFindInterface() { @@ -595,6 +645,26 @@ bool PluginInstance::LoadFindInterface() { return !!plugin_find_interface_; } +bool PluginInstance::LoadPrivateInterface() { + if (!plugin_private_interface_) { + plugin_private_interface_ = + reinterpret_cast<const PPP_Private*>(module_->GetPluginInterface( + PPP_PRIVATE_INTERFACE)); + } + + return !!plugin_private_interface_; +} + +bool PluginInstance::LoadSelectionInterface() { + if (!plugin_selection_interface_) { + plugin_selection_interface_ = + reinterpret_cast<const PPP_Selection_Dev*>(module_->GetPluginInterface( + PPP_SELECTION_DEV_INTERFACE)); + } + + return !!plugin_selection_interface_; +} + bool PluginInstance::LoadZoomInterface() { if (!plugin_zoom_interface_) { plugin_zoom_interface_ = @@ -620,7 +690,7 @@ bool PluginInstance::GetPreferredPrintOutputFormat( return false; uint32_t format_count = 0; PP_PrintOutputFormat_Dev* supported_formats = - plugin_print_interface_->QuerySupportedFormats(GetPPInstance(), + plugin_print_interface_->QuerySupportedFormats(pp_instance(), &format_count); if (!supported_formats) return false; @@ -663,7 +733,7 @@ int PluginInstance::PrintBegin(const gfx::Rect& printable_area, print_settings.orientation = PP_PRINTORIENTATION_NORMAL; print_settings.grayscale = false; print_settings.format = format; - int num_pages = plugin_print_interface_->Begin(GetPPInstance(), + int num_pages = plugin_print_interface_->Begin(pp_instance(), &print_settings); if (!num_pages) return 0; @@ -694,7 +764,7 @@ bool PluginInstance::PrintPage(int page_number, WebKit::WebCanvas* canvas) { #endif // defined(OS_LINUX) PP_Resource print_output = - plugin_print_interface_->PrintPages(GetPPInstance(), &page_range, 1); + plugin_print_interface_->PrintPages(pp_instance(), &page_range, 1); if (!print_output) return false; @@ -715,7 +785,7 @@ bool PluginInstance::PrintPage(int page_number, WebKit::WebCanvas* canvas) { void PluginInstance::PrintEnd() { DCHECK(plugin_print_interface_); if (plugin_print_interface_) - plugin_print_interface_->End(GetPPInstance()); + plugin_print_interface_->End(pp_instance()); memset(¤t_print_settings_, 0, sizeof(current_print_settings_)); #if defined(OS_MACOSX) last_printed_page_ = NULL; @@ -732,7 +802,7 @@ void PluginInstance::Graphics3DContextLost() { PPP_GRAPHICS_3D_DEV_INTERFACE)); } if (plugin_graphics_3d_interface_) - plugin_graphics_3d_interface_->Graphics3DContextLost(GetPPInstance()); + plugin_graphics_3d_interface_->Graphics3DContextLost(pp_instance()); } bool PluginInstance::IsFullscreen() { @@ -743,7 +813,7 @@ bool PluginInstance::SetFullscreen(bool fullscreen) { bool is_fullscreen = (fullscreen_container_ != NULL); if (fullscreen == is_fullscreen) return true; - LOG(INFO) << "Setting fullscreen to " << (fullscreen ? "on" : "off"); + VLOG(1) << "Setting fullscreen to " << (fullscreen ? "on" : "off"); if (fullscreen) { fullscreen_container_ = delegate_->CreateFullscreenContainer(this); } else { @@ -957,11 +1027,11 @@ void PluginInstance::DrawSkBitmapToCanvas( int canvas_height) { SkAutoLockPixels lock(bitmap); DCHECK(bitmap.getConfig() == SkBitmap::kARGB_8888_Config); - scoped_cftyperef<CGDataProviderRef> data_provider( + base::mac::ScopedCFTypeRef<CGDataProviderRef> data_provider( CGDataProviderCreateWithData( NULL, bitmap.getAddr32(0, 0), bitmap.rowBytes() * bitmap.height(), NULL)); - scoped_cftyperef<CGImageRef> image( + base::mac::ScopedCFTypeRef<CGImageRef> image( CGImageCreate( bitmap.width(), bitmap.height(), 8, 32, bitmap.rowBytes(), diff --git a/webkit/glue/plugins/pepper_plugin_instance.h b/webkit/glue/plugins/pepper_plugin_instance.h index 4eb956f..e0cc25d 100644 --- a/webkit/glue/plugins/pepper_plugin_instance.h +++ b/webkit/glue/plugins/pepper_plugin_instance.h @@ -25,8 +25,11 @@ struct PP_Var; struct PPB_Instance; struct PPB_Find_Dev; struct PPB_Fullscreen_Dev; +struct PPB_Zoom_Dev; struct PPP_Find_Dev; struct PPP_Instance; +struct PPP_Private; +struct PPP_Selection_Dev; struct PPP_Zoom_Dev; class SkBitmap; @@ -51,6 +54,10 @@ class PluginModule; class URLLoader; class FullscreenContainer; +// Represents one time a plugin appears on one web page. +// +// Note: to get from a PP_Instance to a PluginInstance*, use the +// ResourceTracker. class PluginInstance : public base::RefCounted<PluginInstance> { public: PluginInstance(PluginDelegate* delegate, @@ -60,13 +67,11 @@ class PluginInstance : public base::RefCounted<PluginInstance> { static const PPB_Instance* GetInterface(); - // Converts the given instance ID to an actual instance object. - static PluginInstance* FromPPInstance(PP_Instance instance); - // Returns a pointer to the interface implementing PPB_Find that is // exposed to the plugin. static const PPB_Find_Dev* GetFindInterface(); static const PPB_Fullscreen_Dev* GetFullscreenInterface(); + static const PPB_Zoom_Dev* GetZoomInterface(); PluginDelegate* delegate() const { return delegate_; } PluginModule* module() const { return module_.get(); } @@ -80,7 +85,9 @@ class PluginInstance : public base::RefCounted<PluginInstance> { void set_always_on_top(bool on_top) { always_on_top_ = on_top; } - PP_Instance GetPPInstance(); + // Returns the PP_Instance uniquely identifying this instance. Guaranteed + // nonzero. + PP_Instance pp_instance() const { return pp_instance_; } // Paints the current backing store to the web page. void Paint(WebKit::WebCanvas* canvas, @@ -134,7 +141,8 @@ class PluginInstance : public base::RefCounted<PluginInstance> { gfx::Rect* clip); string16 GetSelectedText(bool html); - void Zoom(float factor, bool text_only); + string16 GetLinkAtPosition(const gfx::Point& point); + void Zoom(double factor, bool text_only); bool StartFind(const string16& search_text, bool case_sensitive, int identifier); @@ -154,6 +162,8 @@ class PluginInstance : public base::RefCounted<PluginInstance> { private: bool LoadFindInterface(); + bool LoadPrivateInterface(); + bool LoadSelectionInterface(); bool LoadZoomInterface(); // Determines if we think the plugin has focus, both content area and webkit @@ -181,6 +191,8 @@ class PluginInstance : public base::RefCounted<PluginInstance> { scoped_refptr<PluginModule> module_; const PPP_Instance* instance_interface_; + PP_Instance pp_instance_; + // NULL until we have been initialized. WebKit::WebPluginContainer* container_; @@ -211,8 +223,10 @@ class PluginInstance : public base::RefCounted<PluginInstance> { // The id of the current find operation, or -1 if none is in process. int find_identifier_; - // The plugin find and zoom interfaces. + // The plugin-provided interfaces. const PPP_Find_Dev* plugin_find_interface_; + const PPP_Private* plugin_private_interface_; + const PPP_Selection_Dev* plugin_selection_interface_; const PPP_Zoom_Dev* plugin_zoom_interface_; // This is only valid between a successful PrintBegin call and a PrintEnd diff --git a/webkit/glue/plugins/pepper_plugin_module.cc b/webkit/glue/plugins/pepper_plugin_module.cc index 251023f..13390d5 100644 --- a/webkit/glue/plugins/pepper_plugin_module.cc +++ b/webkit/glue/plugins/pepper_plugin_module.cc @@ -32,8 +32,10 @@ #include "third_party/ppapi/c/dev/ppb_url_request_info_dev.h" #include "third_party/ppapi/c/dev/ppb_url_response_info_dev.h" #include "third_party/ppapi/c/dev/ppb_url_util_dev.h" +#include "third_party/ppapi/c/dev/ppb_var_deprecated.h" #include "third_party/ppapi/c/dev/ppb_video_decoder_dev.h" #include "third_party/ppapi/c/dev/ppb_widget_dev.h" +#include "third_party/ppapi/c/dev/ppb_zoom_dev.h" #include "third_party/ppapi/c/trusted/ppb_image_data_trusted.h" #include "third_party/ppapi/c/pp_module.h" #include "third_party/ppapi/c/pp_resource.h" @@ -42,7 +44,6 @@ #include "third_party/ppapi/c/ppb_graphics_2d.h" #include "third_party/ppapi/c/ppb_image_data.h" #include "third_party/ppapi/c/ppb_instance.h" -#include "third_party/ppapi/c/ppb_var.h" #include "third_party/ppapi/c/ppp.h" #include "third_party/ppapi/c/ppp_instance.h" #include "webkit/glue/plugins/pepper_audio.h" @@ -123,6 +124,13 @@ double GetTime() { return base::Time::Now().ToDoubleT(); } +double GetTickTime() { + // TODO(brettw) http://code.google.com/p/chromium/issues/detail?id=57448 + // This should be a tick timer rather than wall clock time, but needs to + // match message times, which also currently use wall clock time. + return GetTime(); +} + void CallOnMainThread(int delay_in_msec, PP_CompletionCallback callback, int32_t result) { @@ -142,6 +150,7 @@ const PPB_Core core_interface = { &MemAlloc, &MemFree, &GetTime, + &GetTickTime, &CallOnMainThread, &IsMainThread }; @@ -170,33 +179,17 @@ void QuitMessageLoop() { } uint32_t GetLiveObjectCount(PP_Module module_id) { - PluginModule* module = PluginModule::FromPPModule(module_id); + PluginModule* module = ResourceTracker::Get()->GetModule(module_id); if (!module) return static_cast<uint32_t>(-1); return ResourceTracker::Get()->GetLiveObjectsForModule(module); } -PP_Resource GetInaccessibleFileRef(PP_Module module_id) { - PluginModule* module = PluginModule::FromPPModule(module_id); - if (!module) - return static_cast<uint32_t>(-1); - return FileRef::GetInaccessibleFileRef(module)->GetReference(); -} - -PP_Resource GetNonexistentFileRef(PP_Module module_id) { - PluginModule* module = PluginModule::FromPPModule(module_id); - if (!module) - return static_cast<uint32_t>(-1); - return FileRef::GetNonexistentFileRef(module)->GetReference(); -} - const PPB_Testing_Dev testing_interface = { &ReadImageData, &RunMessageLoop, &QuitMessageLoop, - &GetLiveObjectCount, - &GetInaccessibleFileRef, - &GetNonexistentFileRef + &GetLiveObjectCount }; // GetInterface ---------------------------------------------------------------- @@ -204,8 +197,8 @@ const PPB_Testing_Dev testing_interface = { const void* GetInterface(const char* name) { if (strcmp(name, PPB_CORE_INTERFACE) == 0) return &core_interface; - if (strcmp(name, PPB_VAR_INTERFACE) == 0) - return Var::GetInterface(); + if (strcmp(name, PPB_VAR_DEPRECATED_INTERFACE) == 0) + return Var::GetDeprecatedInterface(); if (strcmp(name, PPB_INSTANCE_INTERFACE) == 0) return PluginInstance::GetInterface(); if (strcmp(name, PPB_IMAGEDATA_INTERFACE) == 0) @@ -272,6 +265,8 @@ const void* GetInterface(const char* name) { return CharSet::GetInterface(); if (strcmp(name, PPB_CURSOR_CONTROL_DEV_INTERFACE) == 0) return GetCursorControlInterface(); + if (strcmp(name, PPB_ZOOM_DEV_INTERFACE) == 0) + return PluginInstance::GetZoomInterface(); // Only support the testing interface when the command line switch is // specified. This allows us to prevent people from (ab)using this interface @@ -288,6 +283,7 @@ const void* GetInterface(const char* name) { PluginModule::PluginModule() : initialized_(false), library_(NULL) { + pp_module_ = ResourceTracker::Get()->AddModule(this); GetMainThreadMessageLoop(); // Initialize the main thread message loop. GetLivePluginSet()->insert(this); } @@ -315,6 +311,8 @@ PluginModule::~PluginModule() { if (library_) base::UnloadNativeLibrary(library_); + + ResourceTracker::Get()->ModuleDeleted(pp_module_); } // static @@ -339,14 +337,6 @@ scoped_refptr<PluginModule> PluginModule::CreateInternalModule( } // static -PluginModule* PluginModule::FromPPModule(PP_Module module) { - PluginModule* lib = reinterpret_cast<PluginModule*>(module); - if (GetLivePluginSet()->find(lib) == GetLivePluginSet()->end()) - return NULL; // Invalid plugin. - return lib; -} - -// static const PPB_Core* PluginModule::GetCore() { return &core_interface; } @@ -356,7 +346,7 @@ bool PluginModule::InitFromEntryPoints(const EntryPoints& entry_points) { return true; // Attempt to run the initialization funciton. - int retval = entry_points.initialize_module(GetPPModule(), &GetInterface); + int retval = entry_points.initialize_module(pp_module(), &GetInterface); if (retval != 0) { LOG(WARNING) << "PPP_InitializeModule returned failure " << retval; return false; @@ -420,10 +410,6 @@ bool PluginModule::LoadEntryPoints(const base::NativeLibrary& library, return true; } -PP_Module PluginModule::GetPPModule() const { - return reinterpret_cast<intptr_t>(this); -} - PluginInstance* PluginModule::CreateInstance(PluginDelegate* delegate) { const PPP_Instance* plugin_instance_interface = reinterpret_cast<const PPP_Instance*>(GetPluginInterface( diff --git a/webkit/glue/plugins/pepper_plugin_module.h b/webkit/glue/plugins/pepper_plugin_module.h index a560c56..4ac13c3 100644 --- a/webkit/glue/plugins/pepper_plugin_module.h +++ b/webkit/glue/plugins/pepper_plugin_module.h @@ -27,6 +27,11 @@ class PluginDelegate; class PluginInstance; class PluginObject; +// Represents one plugin library loaded into one renderer. This library may +// have multiple instances. +// +// Note: to get from a PP_Instance to a PluginInstance*, use the +// ResourceTracker. class PluginModule : public base::RefCounted<PluginModule>, public base::SupportsWeakPtr<PluginModule> { public: @@ -52,13 +57,12 @@ class PluginModule : public base::RefCounted<PluginModule>, static scoped_refptr<PluginModule> CreateInternalModule( EntryPoints entry_points); - // Converts the given module ID to an actual module object. Will return NULL - // if the module is invalid. - static PluginModule* FromPPModule(PP_Module module); - static const PPB_Core* GetCore(); - PP_Module GetPPModule() const; + PP_Module pp_module() const { return pp_module_; } + + void set_name(const std::string& name) { name_ = name; } + const std::string& name() const { return name_; } PluginInstance* CreateInstance(PluginDelegate* delegate); @@ -100,6 +104,8 @@ class PluginModule : public base::RefCounted<PluginModule>, static bool LoadEntryPoints(const base::NativeLibrary& library, EntryPoints* entry_points); + PP_Module pp_module_; + bool initialized_; // Holds a reference to the base::NativeLibrary handle if this PluginModule @@ -112,6 +118,9 @@ class PluginModule : public base::RefCounted<PluginModule>, // implementation. EntryPoints entry_points_; + // The name of the module. + std::string name_; + // Non-owning pointers to all instances associated with this module. When // there are no more instances, this object should be deleted. typedef std::set<PluginInstance*> PluginInstanceSet; diff --git a/webkit/glue/plugins/pepper_plugin_object.cc b/webkit/glue/plugins/pepper_plugin_object.cc index c0a7cd6..b655f83 100644 --- a/webkit/glue/plugins/pepper_plugin_object.cc +++ b/webkit/glue/plugins/pepper_plugin_object.cc @@ -10,9 +10,9 @@ #include "base/string_util.h" #include "third_party/npapi/bindings/npapi.h" #include "third_party/npapi/bindings/npruntime.h" +#include "third_party/ppapi/c/dev/ppb_var_deprecated.h" +#include "third_party/ppapi/c/dev/ppp_class_deprecated.h" #include "third_party/ppapi/c/pp_var.h" -#include "third_party/ppapi/c/ppb_var.h" -#include "third_party/ppapi/c/ppp_class.h" #include "third_party/WebKit/WebKit/chromium/public/WebBindings.h" #include "webkit/glue/plugins/pepper_plugin_module.h" #include "webkit/glue/plugins/pepper_string.h" @@ -38,7 +38,7 @@ const char kInvalidPluginValue[] = "Error: Plugin returned invalid value."; // an object. bool PPVarToNPVariant(PP_Var var, NPVariant* result) { switch (var.type) { - case PP_VARTYPE_VOID: + case PP_VARTYPE_UNDEFINED: VOID_TO_NPVARIANT(*result); break; case PP_VARTYPE_NULL: @@ -139,7 +139,7 @@ class PPResultAndExceptionToNPResult { NPVariant* np_result) : object_var_(object_var), np_result_(np_result), - exception_(PP_MakeVoid()), + exception_(PP_MakeUndefined()), success_(false), checked_exception_(false) { } @@ -154,7 +154,7 @@ class PPResultAndExceptionToNPResult { } // Returns true if an exception has been set. - bool has_exception() const { return exception_.type != PP_VARTYPE_VOID; } + bool has_exception() const { return exception_.type != PP_VARTYPE_UNDEFINED; } // Returns a pointer to the exception. You would pass this to the PPAPI // function as the exception parameter. If it is set to non-void, this object @@ -267,11 +267,11 @@ class NPObjectAccessorWithIdentifier { NPIdentifier identifier, bool allow_integer_identifier) : object_(PluginObject::FromNPObject(object)), - identifier_(PP_MakeVoid()) { + identifier_(PP_MakeUndefined()) { if (object_) { identifier_ = Var::NPIdentifierToPPVar(object_->module(), identifier); if (identifier_.type == PP_VARTYPE_INT32 && !allow_integer_identifier) - identifier_.type = PP_VARTYPE_VOID; // Make the identifier invalid. + identifier_.type = PP_VARTYPE_UNDEFINED; // Mark it invalid. } } @@ -281,7 +281,7 @@ class NPObjectAccessorWithIdentifier { // Returns true if both the object and identifier are valid. bool is_valid() const { - return object_ && identifier_.type != PP_VARTYPE_VOID; + return object_ && identifier_.type != PP_VARTYPE_UNDEFINED; } PluginObject* object() { return object_; } @@ -294,7 +294,7 @@ class NPObjectAccessorWithIdentifier { DISALLOW_COPY_AND_ASSIGN(NPObjectAccessorWithIdentifier); }; -// NPObject implementation in terms of PPP_Class ------------------------------- +// NPObject implementation in terms of PPP_Class_Deprecated -------------------- NPObject* WrapperClass_Allocate(NPP npp, NPClass* unused) { return PluginObject::AllocateObjectWrapper(); @@ -349,7 +349,7 @@ bool WrapperClass_InvokeDefault(NPObject* np_object, const NPVariant* argv, PPResultAndExceptionToNPResult result_converter(obj, result); result_converter.SetResult(obj->ppp_class()->Call( - obj->ppp_class_data(), PP_MakeVoid(), argc, args.array(), + obj->ppp_class_data(), PP_MakeUndefined(), argc, args.array(), result_converter.exception())); return result_converter.success(); } @@ -518,7 +518,7 @@ struct PluginObject::NPObjectWrapper : public NPObject { PluginObject::PluginObject(PluginModule* module, NPObjectWrapper* object_wrapper, - const PPP_Class* ppp_class, + const PPP_Class_Deprecated* ppp_class, void* ppp_class_data) : module_(module), object_wrapper_(object_wrapper), @@ -542,7 +542,7 @@ PluginObject::~PluginObject() { } PP_Var PluginObject::Create(PluginModule* module, - const PPP_Class* ppp_class, + const PPP_Class_Deprecated* ppp_class, void* ppp_class_data) { // This will internally end up calling our AllocateObjectWrapper via the // WrapperClass_Allocated function which will have created an object wrapper @@ -568,7 +568,7 @@ NPObject* PluginObject::GetNPObject() const { // static bool PluginObject::IsInstanceOf(NPObject* np_object, - const PPP_Class* ppp_class, + const PPP_Class_Deprecated* ppp_class, void** ppp_class_data) { // Validate that this object is implemented by our wrapper class before // trying to get the PluginObject. diff --git a/webkit/glue/plugins/pepper_plugin_object.h b/webkit/glue/plugins/pepper_plugin_object.h index 7715a81..e31c1b1 100644 --- a/webkit/glue/plugins/pepper_plugin_object.h +++ b/webkit/glue/plugins/pepper_plugin_object.h @@ -10,7 +10,7 @@ #include "base/basictypes.h" struct PP_Var; -struct PPP_Class; +struct PPP_Class_Deprecated; typedef struct NPObject NPObject; typedef struct _NPVariant NPVariant; @@ -25,12 +25,12 @@ class PluginObject { // Allocates a new PluginObject and returns it as a PP_Var with a // refcount of 1. static PP_Var Create(PluginModule* module, - const PPP_Class* ppp_class, + const PPP_Class_Deprecated* ppp_class, void* ppp_class_data); PluginModule* module() const { return module_; } - const PPP_Class* ppp_class() { return ppp_class_; } + const PPP_Class_Deprecated* ppp_class() { return ppp_class_; } void* ppp_class_data() { return ppp_class_data_; }; NPObject* GetNPObject() const; @@ -40,7 +40,7 @@ class PluginObject { // returns true and places the class data into |*ppp_class_data| (which can // optionally be NULL if no class data is desired). static bool IsInstanceOf(NPObject* np_object, - const PPP_Class* ppp_class, + const PPP_Class_Deprecated* ppp_class, void** ppp_class_data); // Converts the given NPObject to the corresponding ObjectVar. @@ -65,7 +65,7 @@ class PluginObject { // incremented on it, and this class will take ownership of that reference. PluginObject(PluginModule* module, NPObjectWrapper* object_wrapper, - const PPP_Class* ppp_class, + const PPP_Class_Deprecated* ppp_class, void* ppp_class_data); PluginModule* module_; @@ -78,7 +78,7 @@ class PluginObject { // owns us. NPObjectWrapper* object_wrapper_; - const PPP_Class* ppp_class_; + const PPP_Class_Deprecated* ppp_class_; void* ppp_class_data_; DISALLOW_COPY_AND_ASSIGN(PluginObject); diff --git a/webkit/glue/plugins/pepper_private.cc b/webkit/glue/plugins/pepper_private.cc index e35006b..0bf5328 100644 --- a/webkit/glue/plugins/pepper_private.cc +++ b/webkit/glue/plugins/pepper_private.cc @@ -7,24 +7,34 @@ #include "webkit/glue/plugins/pepper_private.h" #include "app/resource_bundle.h" +#include "base/metrics/histogram.h" #include "base/utf_string_conversions.h" #include "grit/webkit_resources.h" #include "grit/webkit_strings.h" #include "skia/ext/platform_canvas.h" +#include "third_party/ppapi/c/pp_resource.h" #include "third_party/skia/include/core/SkBitmap.h" +#include "third_party/icu/public/i18n/unicode/usearch.h" #include "webkit/glue/webkit_glue.h" #include "webkit/glue/plugins/pepper_image_data.h" +#include "webkit/glue/plugins/pepper_plugin_delegate.h" +#include "webkit/glue/plugins/pepper_plugin_instance.h" #include "webkit/glue/plugins/pepper_plugin_module.h" #include "webkit/glue/plugins/pepper_var.h" #include "webkit/glue/plugins/ppb_private.h" +#include "webkit/glue/plugins/pepper_var.h" namespace pepper { #if defined(OS_LINUX) class PrivateFontFile : public Resource { public: - PrivateFontFile(PluginModule* module, int fd) : Resource(module), fd_(fd) {} - virtual ~PrivateFontFile() {} + PrivateFontFile(PluginModule* module, int fd) + : Resource(module), + fd_(fd) { + } + virtual ~PrivateFontFile() { + } // Resource overrides. PrivateFontFile* AsPrivateFontFile() { return this; } @@ -74,13 +84,18 @@ static const ResourceImageInfo kResourceImageMap[] = { }; PP_Var GetLocalizedString(PP_Module module_id, PP_ResourceString string_id) { - PluginModule* module = PluginModule::FromPPModule(module_id); + PluginModule* module = ResourceTracker::Get()->GetModule(module_id); if (!module) - return PP_MakeVoid(); + return PP_MakeUndefined(); std::string rv; - if (string_id == PP_RESOURCESTRING_PDFGETPASSWORD) + if (string_id == PP_RESOURCESTRING_PDFGETPASSWORD) { rv = UTF16ToUTF8(webkit_glue::GetLocalizedString(IDS_PDF_NEED_PASSWORD)); + } else if (string_id == PP_RESOURCESTRING_PDFLOADING) { + rv = UTF16ToUTF8(webkit_glue::GetLocalizedString(IDS_PDF_PAGE_LOADING)); + } else { + NOTREACHED(); + } return StringVar::StringToPPVar(module, rv); } @@ -99,11 +114,11 @@ PP_Resource GetResourceImage(PP_Module module_id, PP_ResourceImage image_id) { SkBitmap* res_bitmap = ResourceBundle::GetSharedInstance().GetBitmapNamed(res_id); - PluginModule* module = PluginModule::FromPPModule(module_id); + PluginModule* module = ResourceTracker::Get()->GetModule(module_id); if (!module) return 0; scoped_refptr<pepper::ImageData> image_data(new pepper::ImageData(module)); - if (!image_data->Init(PP_IMAGEDATAFORMAT_BGRA_PREMUL, + if (!image_data->Init(ImageData::GetNativeImageDataFormat(), res_bitmap->width(), res_bitmap->height(), false)) { return 0; } @@ -124,16 +139,22 @@ PP_Resource GetResourceImage(PP_Module module_id, PP_ResourceImage image_id) { PP_Resource GetFontFileWithFallback( PP_Module module_id, - const PP_PrivateFontFileDescription* description) { + const PP_FontDescription_Dev* description, + PP_PrivateFontCharset charset) { #if defined(OS_LINUX) - PluginModule* module = PluginModule::FromPPModule(module_id); + PluginModule* module = ResourceTracker::Get()->GetModule(module_id); if (!module) return 0; - int fd = webkit_glue::MatchFontWithFallback(description->face, - description->weight >= 700, - description->italic, - description->charset); + scoped_refptr<StringVar> face_name(StringVar::FromPPVar(description->face)); + if (!face_name) + return 0; + + int fd = webkit_glue::MatchFontWithFallback( + face_name->value().c_str(), + description->weight >= PP_FONTWEIGHT_BOLD, + description->italic, + charset); if (fd == -1) return 0; @@ -162,11 +183,91 @@ bool GetFontTableForPrivateFontFile(PP_Resource font_file, #endif } +void SearchString(PP_Module module, + const unsigned short* input_string, + const unsigned short* input_term, + bool case_sensitive, + PP_PrivateFindResult** results, + int* count) { + const char16* string = reinterpret_cast<const char16*>(input_string); + const char16* term = reinterpret_cast<const char16*>(input_term); + + UErrorCode status = U_ZERO_ERROR; + UStringSearch* searcher = usearch_open( + term, -1, string, -1, webkit_glue::GetWebKitLocale().c_str(), 0, + &status); + DCHECK(status == U_ZERO_ERROR || status == U_USING_FALLBACK_WARNING || + status == U_USING_DEFAULT_WARNING); + UCollationStrength strength = case_sensitive ? UCOL_TERTIARY : UCOL_PRIMARY; + + UCollator* collator = usearch_getCollator(searcher); + if (ucol_getStrength(collator) != strength) { + ucol_setStrength(collator, strength); + usearch_reset(searcher); + } + + status = U_ZERO_ERROR; + int match_start = usearch_first(searcher, &status); + DCHECK(status == U_ZERO_ERROR); + + std::vector<PP_PrivateFindResult> pp_results; + while (match_start != USEARCH_DONE) { + size_t matched_length = usearch_getMatchedLength(searcher); + PP_PrivateFindResult result; + result.start_index = match_start; + result.length = matched_length; + pp_results.push_back(result); + match_start = usearch_next(searcher, &status); + DCHECK(status == U_ZERO_ERROR); + } + + *count = pp_results.size(); + if (*count) { + *results = reinterpret_cast<PP_PrivateFindResult*>( + malloc(*count * sizeof(PP_PrivateFindResult))); + memcpy(*results, &pp_results[0], *count * sizeof(PP_PrivateFindResult)); + } else { + *results = NULL; + } + + usearch_close(searcher); +} + +void DidStartLoading(PP_Instance instance_id) { + PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id); + if (!instance) + return; + instance->delegate()->DidStartLoading(); +} + +void DidStopLoading(PP_Instance instance_id) { + PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id); + if (!instance) + return; + instance->delegate()->DidStopLoading(); +} + +void SetContentRestriction(PP_Instance instance_id, int restrictions) { + PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id); + if (!instance) + return; + instance->delegate()->SetContentRestriction(restrictions); +} + +void HistogramPDFPageCount(int count) { + UMA_HISTOGRAM_COUNTS_10000("PDF.PageCount", count); +} + const PPB_Private ppb_private = { &GetLocalizedString, &GetResourceImage, &GetFontFileWithFallback, &GetFontTableForPrivateFontFile, + &SearchString, + &DidStartLoading, + &DidStopLoading, + &SetContentRestriction, + &HistogramPDFPageCount }; } // namespace diff --git a/webkit/glue/plugins/pepper_private2.cc b/webkit/glue/plugins/pepper_private2.cc index 9a740aa..a96ef30 100644 --- a/webkit/glue/plugins/pepper_private2.cc +++ b/webkit/glue/plugins/pepper_private2.cc @@ -4,22 +4,223 @@ #include "webkit/glue/plugins/pepper_private2.h" +#include <string.h> + +#include "base/file_path.h" +#include "base/stringprintf.h" +#include "base/utf_string_conversions.h" +#include "googleurl/src/gurl.h" +#include "third_party/ppapi/c/dev/pp_file_info_dev.h" +#include "third_party/ppapi/c/dev/ppb_file_io_dev.h" +#include "webkit/glue/plugins/pepper_error_util.h" +#include "webkit/glue/plugins/pepper_plugin_delegate.h" #include "webkit/glue/plugins/pepper_plugin_instance.h" +#include "webkit/glue/plugins/pepper_plugin_module.h" +#include "webkit/glue/plugins/pepper_var.h" #include "webkit/glue/plugins/ppb_private2.h" namespace pepper { namespace { +PluginInstance* GetSomeInstance(PP_Module pp_module) { + PluginModule* module = ResourceTracker::Get()->GetModule(pp_module); + if (!module) + return NULL; + + return module->GetSomeInstance(); +} + void SetInstanceAlwaysOnTop(PP_Instance pp_instance, bool on_top) { - PluginInstance* instance = PluginInstance::FromPPInstance(pp_instance); + PluginInstance* instance = ResourceTracker::Get()->GetInstance(pp_instance); if (!instance) return; instance->set_always_on_top(on_top); } +PP_Var GetProxyForURL(PP_Module pp_module, const char* url) { + PluginInstance* instance = GetSomeInstance(pp_module); + if (!instance) + return PP_MakeUndefined(); + + GURL gurl(url); + if (!gurl.is_valid()) + return PP_MakeUndefined(); + + std::string proxy_host = instance->delegate()->ResolveProxy(gurl); + if (proxy_host.empty()) + return PP_MakeUndefined(); // No proxy. + return StringVar::StringToPPVar(instance->module(), proxy_host); +} + +FilePath GetFilePathFromUTF8(const char* path) { +#if defined(OS_WIN) + return FilePath(UTF8ToUTF16(path)); +#else + return FilePath(path); +#endif +} + +int32_t OpenModuleLocalFile(PP_Module module, + const char* path, + int32_t mode, + PP_FileHandle* file) { + PluginInstance* instance = GetSomeInstance(module); + if (!instance) + return PP_ERROR_FAILED; + + int flags = 0; + if (mode & PP_FILEOPENFLAG_READ) + flags |= base::PLATFORM_FILE_READ; + if (mode & PP_FILEOPENFLAG_WRITE) { + flags |= base::PLATFORM_FILE_WRITE; + flags |= base::PLATFORM_FILE_WRITE_ATTRIBUTES; + } + if (mode & PP_FILEOPENFLAG_TRUNCATE) { + DCHECK(mode & PP_FILEOPENFLAG_WRITE); + flags |= base::PLATFORM_FILE_TRUNCATE; + } + + if (mode & PP_FILEOPENFLAG_CREATE) { + if (mode & PP_FILEOPENFLAG_EXCLUSIVE) + flags |= base::PLATFORM_FILE_CREATE; + else + flags |= base::PLATFORM_FILE_OPEN_ALWAYS; + } else { + flags |= base::PLATFORM_FILE_OPEN; + } + + base::PlatformFile base_file; + base::PlatformFileError result = instance->delegate()->OpenModuleLocalFile( + instance->module()->name(), + GetFilePathFromUTF8(path), + flags, + &base_file); + *file = base_file; + return PlatformFileErrorToPepperError(result); +} + + +int32_t RenameModuleLocalFile(PP_Module module, + const char* path_from, + const char* path_to) { + PluginInstance* instance = GetSomeInstance(module); + if (!instance) + return PP_ERROR_FAILED; + + base::PlatformFileError result = instance->delegate()->RenameModuleLocalFile( + instance->module()->name(), + GetFilePathFromUTF8(path_from), + GetFilePathFromUTF8(path_to)); + return PlatformFileErrorToPepperError(result); +} + +int32_t DeleteModuleLocalFileOrDir(PP_Module module, + const char* path, + bool recursive) { + PluginInstance* instance = GetSomeInstance(module); + if (!instance) + return PP_ERROR_FAILED; + + base::PlatformFileError result = + instance->delegate()->DeleteModuleLocalFileOrDir( + instance->module()->name(), GetFilePathFromUTF8(path), recursive); + return PlatformFileErrorToPepperError(result); +} + +int32_t CreateModuleLocalDir(PP_Module module, const char* path) { + PluginInstance* instance = GetSomeInstance(module); + if (!instance) + return PP_ERROR_FAILED; + + base::PlatformFileError result = instance->delegate()->CreateModuleLocalDir( + instance->module()->name(), GetFilePathFromUTF8(path)); + return PlatformFileErrorToPepperError(result); +} + +int32_t QueryModuleLocalFile(PP_Module module, + const char* path, + PP_FileInfo_Dev* info) { + PluginInstance* instance = GetSomeInstance(module); + if (!instance) + return PP_ERROR_FAILED; + + base::PlatformFileInfo file_info; + base::PlatformFileError result = instance->delegate()->QueryModuleLocalFile( + instance->module()->name(), GetFilePathFromUTF8(path), &file_info); + if (result == base::PLATFORM_FILE_OK) { + info->size = file_info.size; + info->creation_time = file_info.creation_time.ToDoubleT(); + info->last_access_time = file_info.last_accessed.ToDoubleT(); + info->last_modified_time = file_info.last_modified.ToDoubleT(); + info->system_type = PP_FILESYSTEMTYPE_EXTERNAL; + if (file_info.is_directory) + info->type = PP_FILETYPE_DIRECTORY; + else + info->type = PP_FILETYPE_REGULAR; + } + return PlatformFileErrorToPepperError(result); +} + +int32_t GetModuleLocalDirContents(PP_Module module, + const char* path, + PP_DirContents_Dev** contents) { + PluginInstance* instance = GetSomeInstance(module); + if (!instance) + return PP_ERROR_FAILED; + + *contents = NULL; + PepperDirContents pepper_contents; + base::PlatformFileError result = + instance->delegate()->GetModuleLocalDirContents( + instance->module()->name(), + GetFilePathFromUTF8(path), + &pepper_contents); + + if (result != base::PLATFORM_FILE_OK) + return PlatformFileErrorToPepperError(result); + + *contents = new PP_DirContents_Dev; + size_t count = pepper_contents.size(); + (*contents)->count = count; + (*contents)->entries = new PP_DirEntry_Dev[count]; + for (size_t i = 0; i < count; ++i) { + PP_DirEntry_Dev& entry = (*contents)->entries[i]; +#if defined(OS_WIN) + const std::string& name = UTF16ToUTF8(pepper_contents[i].name.value()); +#else + const std::string& name = pepper_contents[i].name.value(); +#endif + size_t size = name.size() + 1; + char* name_copy = new char[size]; + memcpy(name_copy, name.c_str(), size); + entry.name = name_copy; + entry.is_dir = pepper_contents[i].is_dir; + } + return PP_OK; +} + +void FreeModuleLocalDirContents(PP_Module module, + PP_DirContents_Dev* contents) { + DCHECK(contents); + for (int32_t i = 0; i < contents->count; ++i) { + delete [] contents->entries[i].name; + } + delete [] contents->entries; + delete contents; +} + const PPB_Private2 ppb_private2 = { - &SetInstanceAlwaysOnTop + &SetInstanceAlwaysOnTop, + &Private2::DrawGlyphs, + &GetProxyForURL, + &OpenModuleLocalFile, + &RenameModuleLocalFile, + &DeleteModuleLocalFileOrDir, + &CreateModuleLocalDir, + &QueryModuleLocalFile, + &GetModuleLocalDirContents, + &FreeModuleLocalDirContents, }; } // namespace diff --git a/webkit/glue/plugins/pepper_private2.h b/webkit/glue/plugins/pepper_private2.h index 492669a..a8a4b6e 100644 --- a/webkit/glue/plugins/pepper_private2.h +++ b/webkit/glue/plugins/pepper_private2.h @@ -5,8 +5,12 @@ #ifndef WEBKIT_GLUE_PLUGINS_PEPPER_PRIVATE2_H_ #define WEBKIT_GLUE_PLUGINS_PEPPER_PRIVATE2_H_ +#include "build/build_config.h" +#include "third_party/ppapi/c/pp_point.h" +#include "third_party/ppapi/c/pp_rect.h" #include "webkit/glue/plugins/pepper_resource.h" +struct PP_FontDescription_Dev; struct PPB_Private2; namespace pepper { @@ -16,6 +20,21 @@ class Private2 { // Returns a pointer to the interface implementing PPB_Private2 that is // exposed to the plugin. static const PPB_Private2* GetInterface(); + + static bool DrawGlyphs(PP_Resource pp_image_data, + const PP_FontDescription_Dev* font_desc, + uint32_t color, + PP_Point position, + PP_Rect clip, + float transformation[3][3], + uint32_t glyph_count, + uint16_t glyph_indices[], + PP_Point glyph_advances[]) +#if defined(OS_LINUX) + ; +#else + { return false; } +#endif }; } // namespace pepper diff --git a/webkit/glue/plugins/pepper_private2_linux.cc b/webkit/glue/plugins/pepper_private2_linux.cc new file mode 100644 index 0000000..4beb6b6 --- /dev/null +++ b/webkit/glue/plugins/pepper_private2_linux.cc @@ -0,0 +1,110 @@ +// Copyright (c) 2010 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/pepper_private2.h" + +#include "skia/ext/platform_canvas.h" +#include "third_party/ppapi/c/pp_point.h" +#include "third_party/ppapi/c/pp_rect.h" +#include "third_party/ppapi/c/dev/ppb_font_dev.h" +#include "third_party/skia/include/core/SkCanvas.h" +#include "third_party/skia/include/core/SkMatrix.h" +#include "third_party/skia/include/core/SkPaint.h" +#include "third_party/skia/include/core/SkPoint.h" +#include "third_party/skia/include/core/SkTemplates.h" +#include "third_party/skia/include/core/SkTypeface.h" +#include "webkit/glue/plugins/pepper_image_data.h" +#include "webkit/glue/plugins/pepper_var.h" + +namespace pepper { + +bool Private2::DrawGlyphs(PP_Resource pp_image_data, + const PP_FontDescription_Dev* font_desc, + uint32_t color, + PP_Point position, + PP_Rect clip, + float transformation[3][3], + uint32_t glyph_count, + uint16_t glyph_indices[], + PP_Point glyph_advances[]) { + scoped_refptr<ImageData> image_resource( + Resource::GetAs<ImageData>(pp_image_data)); + if (!image_resource.get()) + return false; + ImageDataAutoMapper mapper(image_resource); + if (!mapper.is_valid()) + return false; + + // Set up the typeface. + scoped_refptr<StringVar> face_name(StringVar::FromPPVar(font_desc->face)); + if (!face_name) + return false; + int style = SkTypeface::kNormal; + if (font_desc->weight >= PP_FONTWEIGHT_BOLD) + style |= SkTypeface::kBold; + if (font_desc->italic) + style |= SkTypeface::kItalic; + SkTypeface* typeface = + SkTypeface::CreateFromName(face_name->value().c_str(), + static_cast<SkTypeface::Style>(style)); + if (!typeface) + return false; + + // Set up the canvas. + SkCanvas* canvas = image_resource->mapped_canvas(); + canvas->save(); + + // Clip is applied in pixels before the transform. + SkRect clip_rect = { clip.point.x, clip.point.y, + clip.point.x + clip.size.width, + clip.point.y + clip.size.height }; + canvas->clipRect(clip_rect); + + // -- Do not return early below this. The canvas needs restoring and the + // typeface will leak if it's not assigned to the paint (it's refcounted and + // the refcount is currently 0). + + // Convert & set the matrix. + SkMatrix matrix; + matrix.set(SkMatrix::kMScaleX, SkFloatToScalar(transformation[0][0])); + matrix.set(SkMatrix::kMSkewX, SkFloatToScalar(transformation[0][1])); + matrix.set(SkMatrix::kMTransX, SkFloatToScalar(transformation[0][2])); + matrix.set(SkMatrix::kMSkewY, SkFloatToScalar(transformation[1][0])); + matrix.set(SkMatrix::kMScaleY, SkFloatToScalar(transformation[1][1])); + matrix.set(SkMatrix::kMTransY, SkFloatToScalar(transformation[1][2])); + matrix.set(SkMatrix::kMPersp0, SkFloatToScalar(transformation[2][0])); + matrix.set(SkMatrix::kMPersp1, SkFloatToScalar(transformation[2][1])); + matrix.set(SkMatrix::kMPersp2, SkFloatToScalar(transformation[2][2])); + canvas->concat(matrix); + + SkPaint paint; + paint.setColor(color); + paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); + paint.setAntiAlias(true); + paint.setHinting(SkPaint::kFull_Hinting); + paint.setTextSize(SkIntToScalar(font_desc->size)); + paint.setTypeface(typeface); // Takes a ref and manages lifetime. + paint.setSubpixelText(true); + paint.setLCDRenderText(true); + + SkScalar x = SkIntToScalar(position.x); + SkScalar y = SkIntToScalar(position.y); + + // Build up the skia advances. + SkAutoSTMalloc<32, SkPoint> storage(glyph_count); + SkPoint* sk_positions = storage.get(); + for (uint32_t i = 0; i < glyph_count; i++) { + sk_positions[i].set(x, y); + x += SkFloatToScalar(glyph_advances[i].x); + y += SkFloatToScalar(glyph_advances[i].y); + } + + canvas->drawPosText(glyph_indices, glyph_count * 2, sk_positions, paint); + + canvas->restore(); + return true; +} + +} // namespace pepper + diff --git a/webkit/glue/plugins/pepper_resource.h b/webkit/glue/plugins/pepper_resource.h index cab6f32..32dbf0b 100644 --- a/webkit/glue/plugins/pepper_resource.h +++ b/webkit/glue/plugins/pepper_resource.h @@ -12,29 +12,37 @@ namespace pepper { -class Buffer; -class Audio; -class AudioConfig; -class DirectoryReader; -class FileChooser; -class FileIO; -class FileRef; -class Font; -class Graphics2D; -class Graphics3D; -class ImageData; -class ObjectVar; -class PluginModule; -class PrivateFontFile; -class Scrollbar; -class StringVar; -class Transport; -class URLLoader; -class URLRequestInfo; -class URLResponseInfo; -class Var; -class VideoDecoder; -class Widget; +// If you inherit from resource, make sure you add the class name here. +#define FOR_ALL_RESOURCES(F) \ + F(Audio) \ + F(AudioConfig) \ + F(Buffer) \ + F(DirectoryReader) \ + F(FileChooser) \ + F(FileIO) \ + F(FileRef) \ + F(FileSystem) \ + F(Font) \ + F(Graphics2D) \ + F(Graphics3D) \ + F(ImageData) \ + F(ObjectVar) \ + F(PluginModule) \ + F(PrivateFontFile) \ + F(Scrollbar) \ + F(StringVar) \ + F(Transport) \ + F(URLLoader) \ + F(URLRequestInfo) \ + F(URLResponseInfo) \ + F(Var) \ + F(VideoDecoder) \ + F(Widget) + +// Forward declaration of Resource classes. +#define DECLARE_RESOURCE_CLASS(RESOURCE) class RESOURCE; +FOR_ALL_RESOURCES(DECLARE_RESOURCE_CLASS) +#undef DECLARE_RESOURCE_CLASS class Resource : public base::RefCountedThreadSafe<Resource> { public: @@ -80,28 +88,10 @@ class Resource : public base::RefCountedThreadSafe<Resource> { // Type-specific getters for individual resource types. These will return // NULL if the resource does not match the specified type. Used by the Cast() // function. - virtual Audio* AsAudio() { return NULL; } - virtual AudioConfig* AsAudioConfig() { return NULL; } - virtual Buffer* AsBuffer() { return NULL; } - virtual DirectoryReader* AsDirectoryReader() { return NULL; } - virtual FileChooser* AsFileChooser() { return NULL; } - virtual FileIO* AsFileIO() { return NULL; } - virtual FileRef* AsFileRef() { return NULL; } - virtual Font* AsFont() { return NULL; } - virtual Graphics2D* AsGraphics2D() { return NULL; } - virtual Graphics3D* AsGraphics3D() { return NULL; } - virtual ImageData* AsImageData() { return NULL; } - virtual ObjectVar* AsObjectVar() { return NULL; } - virtual PrivateFontFile* AsPrivateFontFile() { return NULL; } - virtual Scrollbar* AsScrollbar() { return NULL; } - virtual StringVar* AsStringVar() { return NULL; } - virtual Transport* AsTransport() { return NULL; } - virtual URLLoader* AsURLLoader() { return NULL; } - virtual URLRequestInfo* AsURLRequestInfo() { return NULL; } - virtual URLResponseInfo* AsURLResponseInfo() { return NULL; } - virtual Var* AsVar() { return NULL; } - virtual VideoDecoder* AsVideoDecoder() { return NULL; } - virtual Widget* AsWidget() { return NULL; } + #define DEFINE_TYPE_GETTER(RESOURCE) \ + virtual RESOURCE* As##RESOURCE() { return NULL; } + FOR_ALL_RESOURCES(DEFINE_TYPE_GETTER) + #undef DEFINE_TYPE_GETTER private: // If referenced by a plugin, holds the id of this resource object. Do not @@ -129,30 +119,10 @@ class Resource : public base::RefCountedThreadSafe<Resource> { return As##Type(); \ } -DEFINE_RESOURCE_CAST(Audio) -DEFINE_RESOURCE_CAST(AudioConfig) -DEFINE_RESOURCE_CAST(Buffer) -DEFINE_RESOURCE_CAST(DirectoryReader) -DEFINE_RESOURCE_CAST(FileChooser) -DEFINE_RESOURCE_CAST(FileIO) -DEFINE_RESOURCE_CAST(FileRef) -DEFINE_RESOURCE_CAST(Font) -DEFINE_RESOURCE_CAST(Graphics2D) -DEFINE_RESOURCE_CAST(Graphics3D) -DEFINE_RESOURCE_CAST(ImageData) -DEFINE_RESOURCE_CAST(ObjectVar) -DEFINE_RESOURCE_CAST(PrivateFontFile) -DEFINE_RESOURCE_CAST(Scrollbar) -DEFINE_RESOURCE_CAST(StringVar); -DEFINE_RESOURCE_CAST(Transport) -DEFINE_RESOURCE_CAST(URLLoader) -DEFINE_RESOURCE_CAST(URLRequestInfo) -DEFINE_RESOURCE_CAST(URLResponseInfo) -DEFINE_RESOURCE_CAST(Var) -DEFINE_RESOURCE_CAST(VideoDecoder) -DEFINE_RESOURCE_CAST(Widget) - +FOR_ALL_RESOURCES(DEFINE_RESOURCE_CAST) #undef DEFINE_RESOURCE_CAST + +#undef FOR_ALL_RESOURCES } // namespace pepper #endif // WEBKIT_GLUE_PLUGINS_PEPPER_RESOURCE_H_ diff --git a/webkit/glue/plugins/pepper_resource_tracker.cc b/webkit/glue/plugins/pepper_resource_tracker.cc index 9ee54f8..2e18cd8 100644 --- a/webkit/glue/plugins/pepper_resource_tracker.cc +++ b/webkit/glue/plugins/pepper_resource_tracker.cc @@ -8,6 +8,7 @@ #include <set> #include "base/logging.h" +#include "base/rand_util.h" #include "third_party/ppapi/c/pp_resource.h" #include "webkit/glue/plugins/pepper_resource.h" @@ -79,4 +80,78 @@ uint32 ResourceTracker::GetLiveObjectsForModule(PluginModule* module) const { return count; } +PP_Instance ResourceTracker::AddInstance(PluginInstance* instance) { +#ifndef NDEBUG + // Make sure we're not adding one more than once. + for (InstanceMap::const_iterator i = instance_map_.begin(); + i != instance_map_.end(); ++i) + DCHECK(i->second != instance); +#endif + + // Use a random 64-bit number for the instance ID. This helps prevent some + // mischeif where you could misallocate resources if you gave a different + // instance ID. + // + // See also AddModule below. + // + // Need to make sure the random number isn't a duplicate or 0. + PP_Instance new_instance; + do { + new_instance = static_cast<PP_Instance>(base::RandUint64()); + } while (!new_instance || + instance_map_.find(new_instance) != instance_map_.end()); + instance_map_[new_instance] = instance; + return new_instance; +} + +void ResourceTracker::InstanceDeleted(PP_Instance instance) { + InstanceMap::iterator found = instance_map_.find(instance); + if (found == instance_map_.end()) { + NOTREACHED(); + return; + } + instance_map_.erase(found); +} + +PluginInstance* ResourceTracker::GetInstance(PP_Instance instance) { + InstanceMap::iterator found = instance_map_.find(instance); + if (found == instance_map_.end()) + return NULL; + return found->second; +} + +PP_Module ResourceTracker::AddModule(PluginModule* module) { +#ifndef NDEBUG + // Make sure we're not adding one more than once. + for (ModuleMap::const_iterator i = module_map_.begin(); + i != module_map_.end(); ++i) + DCHECK(i->second != module); +#endif + + // See AddInstance above. + PP_Module new_module; + do { + new_module = static_cast<PP_Module>(base::RandUint64()); + } while (!new_module || + module_map_.find(new_module) != module_map_.end()); + module_map_[new_module] = module; + return new_module; +} + +void ResourceTracker::ModuleDeleted(PP_Module module) { + ModuleMap::iterator found = module_map_.find(module); + if (found == module_map_.end()) { + NOTREACHED(); + return; + } + module_map_.erase(found); +} + +PluginModule* ResourceTracker::GetModule(PP_Module module) { + ModuleMap::iterator found = module_map_.find(module); + if (found == module_map_.end()) + return NULL; + return found->second; +} + } // namespace pepper diff --git a/webkit/glue/plugins/pepper_resource_tracker.h b/webkit/glue/plugins/pepper_resource_tracker.h index 59f02d2..5c27ebd 100644 --- a/webkit/glue/plugins/pepper_resource_tracker.h +++ b/webkit/glue/plugins/pepper_resource_tracker.h @@ -5,18 +5,22 @@ #ifndef WEBKIT_GLUE_PLUGINS_PEPPER_RESOURCE_TRACKER_H_ #define WEBKIT_GLUE_PLUGINS_PEPPER_RESOURCE_TRACKER_H_ +#include <map> #include <utility> #include "base/basictypes.h" #include "base/hash_tables.h" #include "base/ref_counted.h" #include "base/singleton.h" +#include "third_party/ppapi/c/pp_instance.h" +#include "third_party/ppapi/c/pp_module.h" #include "third_party/ppapi/c/pp_resource.h" typedef struct NPObject NPObject; namespace pepper { +class PluginInstance; class PluginModule; class Resource; @@ -31,6 +35,8 @@ class ResourceTracker { return Singleton<ResourceTracker>::get(); } + // PP_Resources -------------------------------------------------------------- + // The returned pointer will be NULL if there is no resource. Note that this // return value is a scoped_refptr so that we ensure the resource is valid // from the point of the lookup to the point that the calling code needs it. @@ -48,6 +54,34 @@ class ResourceTracker { // This is slow, use only for testing. uint32 GetLiveObjectsForModule(PluginModule* module) const; + // PP_Modules ---------------------------------------------------------------- + + // Adds a new plugin module to the list of tracked module, and returns a new + // module handle to identify it. + PP_Module AddModule(PluginModule* module); + + // Called when a plugin modulde was deleted and should no longer be tracked. + // The given handle should be one generated by AddModule. + void ModuleDeleted(PP_Module module); + + // Returns a pointer to the plugin modulde object associated with the given + // modulde handle. The return value will be NULL if the handle is invalid. + PluginModule* GetModule(PP_Module module); + + // PP_Instances -------------------------------------------------------------- + + // Adds a new plugin instance to the list of tracked instances, and returns a + // new instance handle to identify it. + PP_Instance AddInstance(PluginInstance* instance); + + // Called when a plugin instance was deleted and should no longer be tracked. + // The given handle should be one generated by AddInstance. + void InstanceDeleted(PP_Instance instance); + + // Returns a pointer to the plugin instance object associated with the given + // instance handle. The return value will be NULL if the handle is invalid. + PluginInstance* GetInstance(PP_Instance instance); + private: friend struct DefaultSingletonTraits<ResourceTracker>; friend class Resource; @@ -74,6 +108,16 @@ class ResourceTracker { typedef base::hash_map<PP_Resource, ResourceAndRefCount> ResourceMap; ResourceMap live_resources_; + // Tracks all live instances. The pointers are non-owning, the PluginInstance + // destructor will notify us when the instance is deleted. + typedef std::map<PP_Instance, PluginInstance*> InstanceMap; + InstanceMap instance_map_; + + // Tracks all live modules. The pointers are non-owning, the PluginModule + // destructor will notify us when the module is deleted. + typedef std::map<PP_Module, PluginModule*> ModuleMap; + ModuleMap module_map_; + DISALLOW_COPY_AND_ASSIGN(ResourceTracker); }; diff --git a/webkit/glue/plugins/pepper_scrollbar.cc b/webkit/glue/plugins/pepper_scrollbar.cc index a8943d2..88a3f9b 100644 --- a/webkit/glue/plugins/pepper_scrollbar.cc +++ b/webkit/glue/plugins/pepper_scrollbar.cc @@ -19,7 +19,7 @@ #include "webkit/glue/webkit_glue.h" #if defined(OS_WIN) -#include "base/win_util.h" +#include "base/win/windows_version.h" #endif using WebKit::WebInputEvent; @@ -31,7 +31,7 @@ namespace pepper { namespace { PP_Resource Create(PP_Instance instance_id, bool vertical) { - PluginInstance* instance = PluginInstance::FromPPInstance(instance_id); + PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id); if (!instance) return 0; @@ -164,7 +164,7 @@ bool Scrollbar::Paint(const PP_Rect* rect, ImageData* image) { scrollbar_->paint(webkit_glue::ToWebCanvas(canvas), gfx_rect); #if defined(OS_WIN) - if (win_util::GetWinVersion() == win_util::WINVERSION_XP) { + if (base::win::GetVersion() == base::win::VERSION_XP) { canvas->getTopPlatformDevice().makeOpaque( gfx_rect.x(), gfx_rect.y(), gfx_rect.width(), gfx_rect.height()); } @@ -196,7 +196,7 @@ void Scrollbar::valueChanged(WebKit::WebScrollbar* scrollbar) { return; ScopedResourceId resource(this); ppp_scrollbar->ValueChanged( - instance()->GetPPInstance(), resource.id, scrollbar_->value()); + instance()->pp_instance(), resource.id, scrollbar_->value()); } void Scrollbar::invalidateScrollbarRect(WebKit::WebScrollbar* scrollbar, diff --git a/webkit/glue/plugins/pepper_string.cc b/webkit/glue/plugins/pepper_string.cc new file mode 100644 index 0000000..53c8943 --- /dev/null +++ b/webkit/glue/plugins/pepper_string.cc @@ -0,0 +1,13 @@ +// Copyright (c) 2010 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/pepper_string.h" + +namespace pepper { + +String::String(const char* str, uint32 len) : value_(str, len) {} + +String::~String() {} + +} // namespace pepper diff --git a/webkit/glue/plugins/pepper_string.h b/webkit/glue/plugins/pepper_string.h index 1fc43c4..fa1ab2f 100644 --- a/webkit/glue/plugins/pepper_string.h +++ b/webkit/glue/plugins/pepper_string.h @@ -14,8 +14,8 @@ namespace pepper { class String : public base::RefCountedThreadSafe<String> { public: - String(const char* str, uint32 len) : value_(str, len) { - } + String(const char* str, uint32 len); + virtual ~String(); const std::string& value() const { return value_; } diff --git a/webkit/glue/plugins/pepper_url_loader.cc b/webkit/glue/plugins/pepper_url_loader.cc index 4169c00..62fe176 100644 --- a/webkit/glue/plugins/pepper_url_loader.cc +++ b/webkit/glue/plugins/pepper_url_loader.cc @@ -40,12 +40,11 @@ namespace pepper { namespace { PP_Resource Create(PP_Instance instance_id) { - PluginInstance* instance = PluginInstance::FromPPInstance(instance_id); + PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id); if (!instance) return 0; - URLLoader* loader = new URLLoader(instance); - + URLLoader* loader = new URLLoader(instance, false); return loader->GetReference(); } @@ -168,9 +167,10 @@ const PPB_URLLoaderTrusted_Dev ppb_urlloadertrusted = { } // namespace -URLLoader::URLLoader(PluginInstance* instance) +URLLoader::URLLoader(PluginInstance* instance, bool main_document_loader) : Resource(instance->module()), instance_(instance), + main_document_loader_(main_document_loader), pending_callback_(), bytes_sent_(0), total_bytes_to_be_sent_(-1), @@ -217,10 +217,8 @@ int32_t URLLoader::Open(URLRequestInfo* request, frame->dispatchWillSendRequest(web_request); loader_.reset(WebKit::webKitClient()->createURLLoader()); - if (!loader_.get()) { - loader_.reset(); + if (!loader_.get()) return PP_ERROR_FAILED; - } loader_->loadAsynchronously(web_request, this); pending_callback_ = callback; @@ -280,7 +278,12 @@ int32_t URLLoader::FinishStreamingToFile(PP_CompletionCallback callback) { } void URLLoader::Close() { - NOTIMPLEMENTED(); // TODO(darin): Implement me. + if (loader_.get()) { + loader_->cancel(); + } else if (main_document_loader_) { + WebFrame* frame = instance_->container()->element().document().frame(); + frame->stopLoading(); + } } void URLLoader::GrantUniversalAccess() { diff --git a/webkit/glue/plugins/pepper_url_loader.h b/webkit/glue/plugins/pepper_url_loader.h index 4919de7..e613475 100644 --- a/webkit/glue/plugins/pepper_url_loader.h +++ b/webkit/glue/plugins/pepper_url_loader.h @@ -24,7 +24,7 @@ class URLResponseInfo; class URLLoader : public Resource, public WebKit::WebURLLoaderClient { public: - explicit URLLoader(PluginInstance* instance); + URLLoader(PluginInstance* instance, bool main_document_loader); virtual ~URLLoader(); // Returns a pointer to the interface implementing PPB_URLLoader that is @@ -83,6 +83,9 @@ class URLLoader : public Resource, public WebKit::WebURLLoaderClient { size_t FillUserBuffer(); scoped_refptr<PluginInstance> instance_; + // If true, then the plugin instance is a full-frame plugin and we're just + // wrapping the main document's loader (i.e. loader_ is null). + bool main_document_loader_; scoped_ptr<WebKit::WebURLLoader> loader_; scoped_refptr<URLResponseInfo> response_info_; PP_CompletionCallback pending_callback_; diff --git a/webkit/glue/plugins/pepper_url_request_info.cc b/webkit/glue/plugins/pepper_url_request_info.cc index 4edbe83..dd8f7a6 100644 --- a/webkit/glue/plugins/pepper_url_request_info.cc +++ b/webkit/glue/plugins/pepper_url_request_info.cc @@ -47,7 +47,7 @@ bool IsIgnoredRequestHeader(const std::string& name) { } PP_Resource Create(PP_Module module_id) { - PluginModule* module = PluginModule::FromPPModule(module_id); + PluginModule* module = ResourceTracker::Get()->GetModule(module_id); if (!module) return 0; @@ -80,17 +80,13 @@ bool SetProperty(PP_Resource request_id, return false; } -bool AppendDataToBody(PP_Resource request_id, PP_Var var) { +bool AppendDataToBody(PP_Resource request_id, const char* data, uint32_t len) { scoped_refptr<URLRequestInfo> request( Resource::GetAs<URLRequestInfo>(request_id)); if (!request) return false; - scoped_refptr<StringVar> data(StringVar::FromPPVar(var)); - if (!data) - return false; - - return request->AppendDataToBody(data->value()); + return request->AppendDataToBody(std::string(data, len)); } bool AppendFileToBody(PP_Resource request_id, @@ -123,6 +119,31 @@ const PPB_URLRequestInfo_Dev ppb_urlrequestinfo = { } // namespace +struct URLRequestInfo::BodyItem { + BodyItem(const std::string& data) + : data(data), + start_offset(0), + number_of_bytes(-1), + expected_last_modified_time(0.0) { + } + + BodyItem(FileRef* file_ref, + int64_t start_offset, + int64_t number_of_bytes, + PP_Time expected_last_modified_time) + : file_ref(file_ref), + start_offset(start_offset), + number_of_bytes(number_of_bytes), + expected_last_modified_time(expected_last_modified_time) { + } + + std::string data; + scoped_refptr<FileRef> file_ref; + int64_t start_offset; + int64_t number_of_bytes; + PP_Time expected_last_modified_time; +}; + URLRequestInfo::URLRequestInfo(PluginModule* module) : Resource(module), stream_to_file_(false) { @@ -217,7 +238,8 @@ WebURLRequest URLRequestInfo::ToWebURLRequest(WebFrame* frame) const { for (size_t i = 0; i < body_.size(); ++i) { if (body_[i].file_ref) { http_body.appendFileRange( - webkit_glue::FilePathToWebString(body_[i].file_ref->system_path()), + webkit_glue::FilePathToWebString( + body_[i].file_ref->GetSystemPath()), body_[i].start_offset, body_[i].number_of_bytes, body_[i].expected_last_modified_time); diff --git a/webkit/glue/plugins/pepper_url_request_info.h b/webkit/glue/plugins/pepper_url_request_info.h index 7220531..2d394d5 100644 --- a/webkit/glue/plugins/pepper_url_request_info.h +++ b/webkit/glue/plugins/pepper_url_request_info.h @@ -45,31 +45,7 @@ class URLRequestInfo : public Resource { WebKit::WebURLRequest ToWebURLRequest(WebKit::WebFrame* frame) const; private: - struct BodyItem { - BodyItem(const std::string& data) - : data(data), - start_offset(0), - number_of_bytes(-1), - expected_last_modified_time(0.0) { - } - - BodyItem(FileRef* file_ref, - int64_t start_offset, - int64_t number_of_bytes, - PP_Time expected_last_modified_time) - : file_ref(file_ref), - start_offset(start_offset), - number_of_bytes(number_of_bytes), - expected_last_modified_time(expected_last_modified_time) { - } - - std::string data; - scoped_refptr<FileRef> file_ref; - int64_t start_offset; - int64_t number_of_bytes; - PP_Time expected_last_modified_time; - }; - + struct BodyItem; typedef std::vector<BodyItem> Body; std::string url_; diff --git a/webkit/glue/plugins/pepper_url_response_info.cc b/webkit/glue/plugins/pepper_url_response_info.cc index 79042ba..8af3385 100644 --- a/webkit/glue/plugins/pepper_url_response_info.cc +++ b/webkit/glue/plugins/pepper_url_response_info.cc @@ -47,7 +47,7 @@ PP_Var GetProperty(PP_Resource response_id, scoped_refptr<URLResponseInfo> response( Resource::GetAs<URLResponseInfo>(response_id)); if (!response) - return PP_MakeVoid(); + return PP_MakeUndefined(); return response->GetProperty(property); } @@ -97,7 +97,7 @@ PP_Var URLResponseInfo::GetProperty(PP_URLResponseProperty_Dev property) { return StringVar::StringToPPVar(module(), headers_); default: NOTIMPLEMENTED(); // TODO(darin): Implement me! - return PP_MakeVoid(); + return PP_MakeUndefined(); } } diff --git a/webkit/glue/plugins/pepper_url_util.cc b/webkit/glue/plugins/pepper_url_util.cc index 3f9a54f..a182b92 100644 --- a/webkit/glue/plugins/pepper_url_util.cc +++ b/webkit/glue/plugins/pepper_url_util.cc @@ -60,7 +60,7 @@ PP_Var GenerateUrlReturn(PluginModule* module, const GURL& url, // unchanged. bool SecurityOriginForInstance(PP_Instance instance_id, WebKit::WebSecurityOrigin* security_origin) { - PluginInstance* instance = PluginInstance::FromPPInstance(instance_id); + PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id); if (!instance) return false; @@ -100,7 +100,7 @@ PP_Var ResolveRelativeToUrl(PP_Var base_url, PP_Var ResolveRelativeToDocument(PP_Instance instance_id, PP_Var relative, PP_UrlComponents_Dev* components) { - PluginInstance* instance = PluginInstance::FromPPInstance(instance_id); + PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id); if (!instance) return PP_MakeNull(); diff --git a/webkit/glue/plugins/pepper_var.cc b/webkit/glue/plugins/pepper_var.cc index b4ba014..6daece9 100644 --- a/webkit/glue/plugins/pepper_var.cc +++ b/webkit/glue/plugins/pepper_var.cc @@ -7,8 +7,8 @@ #include "base/logging.h" #include "base/scoped_ptr.h" #include "base/string_util.h" +#include "third_party/ppapi/c/dev/ppb_var_deprecated.h" #include "third_party/ppapi/c/pp_var.h" -#include "third_party/ppapi/c/ppb_var.h" #include "third_party/WebKit/WebKit/chromium/public/WebBindings.h" #include "webkit/glue/plugins/pepper_plugin_module.h" #include "webkit/glue/plugins/pepper_plugin_object.h" @@ -43,7 +43,7 @@ const char kUnableToConstructException[] = "Error: Unable to construct"; // the PP_Var remains valid while the resultant NPVariant is in use. bool PPVarToNPVariantNoCopy(PP_Var var, NPVariant* result) { switch (var.type) { - case PP_VARTYPE_VOID: + case PP_VARTYPE_UNDEFINED: VOID_TO_NPVARIANT(*result); break; case PP_VARTYPE_NULL: @@ -157,7 +157,7 @@ class ObjectAccessorWithIdentifierTryCatch : public ObjectAccessorTryCatch { // PPB_Var methods ------------------------------------------------------------- PP_Var VarFromUtf8(PP_Module module_id, const char* data, uint32_t len) { - PluginModule* module = PluginModule::FromPPModule(module_id); + PluginModule* module = ResourceTracker::Get()->GetModule(module_id); if (!module) return PP_MakeNull(); return StringVar::StringToPPVar(module, data, len); @@ -185,9 +185,9 @@ bool HasProperty(PP_Var var, accessor.identifier()); } -bool HasMethod(PP_Var var, - PP_Var name, - PP_Var* exception) { +bool HasMethodDeprecated(PP_Var var, + PP_Var name, + PP_Var* exception) { ObjectAccessorWithIdentifierTryCatch accessor(var, name, exception); if (accessor.has_exception()) return false; @@ -200,14 +200,14 @@ PP_Var GetProperty(PP_Var var, PP_Var* exception) { ObjectAccessorWithIdentifierTryCatch accessor(var, name, exception); if (accessor.has_exception()) - return PP_MakeVoid(); + return PP_MakeUndefined(); NPVariant result; if (!WebBindings::getProperty(NULL, accessor.object()->np_object(), accessor.identifier(), &result)) { // An exception may have been raised. accessor.SetException(kUnableToGetPropertyException); - return PP_MakeVoid(); + return PP_MakeUndefined(); } PP_Var ret = Var::NPVariantToPPVar(accessor.object()->module(), &result); @@ -215,7 +215,7 @@ PP_Var GetProperty(PP_Var var, return ret; } -void GetAllPropertyNames(PP_Var var, +void EnumerateProperties(PP_Var var, uint32_t* property_count, PP_Var** properties, PP_Var* exception) { @@ -246,10 +246,10 @@ void GetAllPropertyNames(PP_Var var, free(identifiers); } -void SetProperty(PP_Var var, - PP_Var name, - PP_Var value, - PP_Var* exception) { +void SetPropertyDeprecated(PP_Var var, + PP_Var name, + PP_Var value, + PP_Var* exception) { ObjectAccessorWithIdentifierTryCatch accessor(var, name, exception); if (accessor.has_exception()) return; @@ -264,7 +264,7 @@ void SetProperty(PP_Var var, accessor.SetException(kUnableToSetPropertyException); } -void RemoveProperty(PP_Var var, +void DeleteProperty(PP_Var var, PP_Var name, PP_Var* exception) { ObjectAccessorWithIdentifierTryCatch accessor(var, name, exception); @@ -276,28 +276,28 @@ void RemoveProperty(PP_Var var, accessor.SetException(kUnableToRemovePropertyException); } -PP_Var Call(PP_Var var, - PP_Var method_name, - uint32_t argc, - PP_Var* argv, - PP_Var* exception) { +PP_Var CallDeprecated(PP_Var var, + PP_Var method_name, + uint32_t argc, + PP_Var* argv, + PP_Var* exception) { ObjectAccessorTryCatch accessor(var, exception); if (accessor.has_exception()) - return PP_MakeVoid(); + return PP_MakeUndefined(); NPIdentifier identifier; - if (method_name.type == PP_VARTYPE_VOID) { + if (method_name.type == PP_VARTYPE_UNDEFINED) { identifier = NULL; } else if (method_name.type == PP_VARTYPE_STRING) { // Specifically allow only string functions to be called. identifier = Var::PPVarToNPIdentifier(method_name); if (!identifier) { accessor.SetException(kInvalidPropertyException); - return PP_MakeVoid(); + return PP_MakeUndefined(); } } else { accessor.SetException(kInvalidPropertyException); - return PP_MakeVoid(); + return PP_MakeUndefined(); } scoped_array<NPVariant> args; @@ -307,7 +307,7 @@ PP_Var Call(PP_Var var, if (!PPVarToNPVariantNoCopy(argv[i], &args[i])) { // This argument was invalid, throw an exception & give up. accessor.SetException(kInvalidValueException); - return PP_MakeVoid(); + return PP_MakeUndefined(); } } } @@ -326,7 +326,7 @@ PP_Var Call(PP_Var var, if (!ok) { // An exception may have been raised. accessor.SetException(kUnableToCallMethodException); - return PP_MakeVoid(); + return PP_MakeUndefined(); } PP_Var ret = Var::NPVariantToPPVar(accessor.module(), &result); @@ -340,7 +340,7 @@ PP_Var Construct(PP_Var var, PP_Var* exception) { ObjectAccessorTryCatch accessor(var, exception); if (accessor.has_exception()) - return PP_MakeVoid(); + return PP_MakeUndefined(); scoped_array<NPVariant> args; if (argc) { @@ -349,7 +349,7 @@ PP_Var Construct(PP_Var var, if (!PPVarToNPVariantNoCopy(argv[i], &args[i])) { // This argument was invalid, throw an exception & give up. accessor.SetException(kInvalidValueException); - return PP_MakeVoid(); + return PP_MakeUndefined(); } } } @@ -359,7 +359,7 @@ PP_Var Construct(PP_Var var, args.get(), argc, &result)) { // An exception may have been raised. accessor.SetException(kUnableToConstructException); - return PP_MakeVoid(); + return PP_MakeUndefined(); } PP_Var ret = Var::NPVariantToPPVar(accessor.module(), &result); @@ -367,9 +367,9 @@ PP_Var Construct(PP_Var var, return ret; } -bool IsInstanceOf(PP_Var var, - const PPP_Class* ppp_class, - void** ppp_class_data) { +bool IsInstanceOfDeprecated(PP_Var var, + const PPP_Class_Deprecated* ppp_class, + void** ppp_class_data) { scoped_refptr<ObjectVar> object(ObjectVar::FromPPVar(var)); if (!object) return false; // Not an object at all. @@ -378,30 +378,30 @@ bool IsInstanceOf(PP_Var var, ppp_class, ppp_class_data); } -PP_Var CreateObject(PP_Module module_id, - const PPP_Class* ppp_class, - void* ppp_class_data) { - PluginModule* module = PluginModule::FromPPModule(module_id); +PP_Var CreateObjectDeprecated(PP_Module module_id, + const PPP_Class_Deprecated* ppp_class, + void* ppp_class_data) { + PluginModule* module = ResourceTracker::Get()->GetModule(module_id); if (!module) return PP_MakeNull(); return PluginObject::Create(module, ppp_class, ppp_class_data); } -const PPB_Var var_interface = { +const PPB_Var_Deprecated var_deprecated_interface = { &Var::PluginAddRefPPVar, &Var::PluginReleasePPVar, &VarFromUtf8, &VarToUtf8, &HasProperty, - &HasMethod, + &HasMethodDeprecated, &GetProperty, - &GetAllPropertyNames, - &SetProperty, - &RemoveProperty, - &Call, + &EnumerateProperties, + &SetPropertyDeprecated, + &DeleteProperty, + &CallDeprecated, &Construct, - &IsInstanceOf, - &CreateObject + &IsInstanceOfDeprecated, + &CreateObjectDeprecated }; } // namespace @@ -418,7 +418,7 @@ Var::~Var() { PP_Var Var::NPVariantToPPVar(PluginModule* module, const NPVariant* variant) { switch (variant->type) { case NPVariantType_Void: - return PP_MakeVoid(); + return PP_MakeUndefined(); case NPVariantType_Null: return PP_MakeNull(); case NPVariantType_Bool: @@ -436,7 +436,7 @@ PP_Var Var::NPVariantToPPVar(PluginModule* module, const NPVariant* variant) { return ObjectVar::NPObjectToPPVar(module, NPVARIANT_TO_OBJECT(*variant)); } NOTREACHED(); - return PP_MakeVoid(); + return PP_MakeUndefined(); } // static @@ -488,8 +488,8 @@ void Var::PluginReleasePPVar(PP_Var var) { } // static -const PPB_Var* Var::GetInterface() { - return &var_interface; +const PPB_Var_Deprecated* Var::GetDeprecatedInterface() { + return &var_deprecated_interface; } // StringVar ------------------------------------------------------------------- @@ -550,7 +550,7 @@ PP_Var ObjectVar::NPObjectToPPVar(PluginModule* module, NPObject* object) { object_var = new ObjectVar(module, object); if (!object_var) - return PP_MakeVoid(); + return PP_MakeUndefined(); // Convert to a PP_Var, GetReference will AddRef for us. PP_Var result; @@ -570,7 +570,7 @@ scoped_refptr<ObjectVar> ObjectVar::FromPPVar(PP_Var var) { TryCatch::TryCatch(PluginModule* module, PP_Var* exception) : module_(module), - has_exception_(exception && exception->type != PP_VARTYPE_VOID), + has_exception_(exception && exception->type != PP_VARTYPE_UNDEFINED), exception_(exception) { WebBindings::pushExceptionHandler(&TryCatch::Catch, this); } diff --git a/webkit/glue/plugins/pepper_var.h b/webkit/glue/plugins/pepper_var.h index b618029..0eb1807 100644 --- a/webkit/glue/plugins/pepper_var.h +++ b/webkit/glue/plugins/pepper_var.h @@ -10,7 +10,7 @@ #include "webkit/glue/plugins/pepper_resource.h" struct PP_Var; -struct PPB_Var; +struct PPB_Var_Deprecated; typedef struct NPObject NPObject; typedef struct _NPVariant NPVariant; typedef void* NPIdentifier; @@ -79,8 +79,8 @@ class Var : public Resource { static void PluginAddRefPPVar(PP_Var var); static void PluginReleasePPVar(PP_Var var); - // Returns the PPB_Var interface for the plugin to use. - static const PPB_Var* GetInterface(); + // Returns the PPB_Var_Deprecated interface for the plugin to use. + static const PPB_Var_Deprecated* GetDeprecatedInterface(); protected: // This can only be constructed as a StringVar or an ObjectVar. diff --git a/webkit/glue/plugins/pepper_video_decoder.cc b/webkit/glue/plugins/pepper_video_decoder.cc index ed572b3..3ca0ab2 100644 --- a/webkit/glue/plugins/pepper_video_decoder.cc +++ b/webkit/glue/plugins/pepper_video_decoder.cc @@ -22,7 +22,7 @@ bool GetConfig(PP_Instance instance_id, PP_VideoConfig_Dev* configs, int32_t config_size, int32_t *num_config) { - PluginInstance* instance = PluginInstance::FromPPInstance(instance_id); + PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id); *num_config = 0; if (!instance) return false; @@ -40,7 +40,7 @@ bool GetConfig(PP_Instance instance_id, PP_Resource Create(PP_Instance instance_id, const PP_VideoDecoderConfig_Dev* decoder_config) { - PluginInstance* instance = PluginInstance::FromPPInstance(instance_id); + PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id); if (!instance) return 0; diff --git a/webkit/glue/plugins/pepper_webplugin_impl.cc b/webkit/glue/plugins/pepper_webplugin_impl.cc index 32903b0..2e8eb3f 100644 --- a/webkit/glue/plugins/pepper_webplugin_impl.cc +++ b/webkit/glue/plugins/pepper_webplugin_impl.cc @@ -4,10 +4,14 @@ #include "webkit/glue/plugins/pepper_webplugin_impl.h" +#include <cmath> + #include "base/message_loop.h" #include "third_party/ppapi/c/pp_var.h" #include "third_party/WebKit/WebKit/chromium/public/WebPluginParams.h" +#include "third_party/WebKit/WebKit/chromium/public/WebPoint.h" #include "third_party/WebKit/WebKit/chromium/public/WebRect.h" +#include "third_party/WebKit/WebKit/chromium/public/WebView.h" #include "webkit/glue/plugins/pepper_plugin_instance.h" #include "webkit/glue/plugins/pepper_plugin_module.h" #include "webkit/glue/plugins/pepper_url_loader.h" @@ -16,12 +20,22 @@ using WebKit::WebCanvas; using WebKit::WebPluginContainer; using WebKit::WebPluginParams; +using WebKit::WebPoint; using WebKit::WebRect; using WebKit::WebString; +using WebKit::WebURL; using WebKit::WebVector; +using WebKit::WebView; namespace pepper { +struct WebPluginImpl::InitData { + scoped_refptr<PluginModule> module; + base::WeakPtr<PluginDelegate> delegate; + std::vector<std::string> arg_names; + std::vector<std::string> arg_values; +}; + WebPluginImpl::WebPluginImpl( PluginModule* plugin_module, const WebPluginParams& params, @@ -117,7 +131,7 @@ void WebPluginImpl::didReceiveResponse( const WebKit::WebURLResponse& response) { DCHECK(!document_loader_); - document_loader_ = new URLLoader(instance_); + document_loader_ = new URLLoader(instance_, true); document_loader_->didReceiveResponse(NULL, response); if (!instance_->HandleDocumentLoad(document_loader_)) @@ -157,16 +171,20 @@ bool WebPluginImpl::hasSelection() const { return !selectionAsText().isEmpty(); } -WebKit::WebString WebPluginImpl::selectionAsText() const { +WebString WebPluginImpl::selectionAsText() const { return instance_->GetSelectedText(false); } -WebKit::WebString WebPluginImpl::selectionAsMarkup() const { +WebString WebPluginImpl::selectionAsMarkup() const { return instance_->GetSelectedText(true); } -void WebPluginImpl::setZoomFactor(float scale, bool text_only) { - instance_->Zoom(scale, text_only); +WebURL WebPluginImpl::linkAtPosition(const WebPoint& position) const { + return GURL(instance_->GetLinkAtPosition(position)); +} + +void WebPluginImpl::setZoomLevel(double level, bool text_only) { + instance_->Zoom(WebView::zoomLevelToZoomFactor(level), text_only); } bool WebPluginImpl::startFind(const WebKit::WebString& search_text, diff --git a/webkit/glue/plugins/pepper_webplugin_impl.h b/webkit/glue/plugins/pepper_webplugin_impl.h index 9d2f313..15ee784 100644 --- a/webkit/glue/plugins/pepper_webplugin_impl.h +++ b/webkit/glue/plugins/pepper_webplugin_impl.h @@ -63,7 +63,8 @@ class WebPluginImpl : public WebKit::WebPlugin { virtual bool hasSelection() const; virtual WebKit::WebString selectionAsText() const; virtual WebKit::WebString selectionAsMarkup() const; - virtual void setZoomFactor(float scale, bool text_only); + virtual WebKit::WebURL linkAtPosition(const WebKit::WebPoint& position) const; + virtual void setZoomLevel(double level, bool text_only); virtual bool startFind(const WebKit::WebString& search_text, bool case_sensitive, int identifier); @@ -75,12 +76,7 @@ class WebPluginImpl : public WebKit::WebPlugin { virtual bool printPage(int page_number, WebKit::WebCanvas* canvas); virtual void printEnd(); - struct InitData { - scoped_refptr<PluginModule> module; - base::WeakPtr<PluginDelegate> delegate; - std::vector<std::string> arg_names; - std::vector<std::string> arg_values; - }; + struct InitData; scoped_ptr<InitData> init_data_; // Cleared upon successful initialization. // True if the instance represents the entire document in a frame instead of diff --git a/webkit/glue/plugins/pepper_widget.cc b/webkit/glue/plugins/pepper_widget.cc index 1ba5280..7002576 100644 --- a/webkit/glue/plugins/pepper_widget.cc +++ b/webkit/glue/plugins/pepper_widget.cc @@ -88,7 +88,7 @@ void Widget::Invalidate(const PP_Rect* dirty) { if (!widget) return; ScopedResourceId resource(this); - widget->Invalidate(instance_->GetPPInstance(), resource.id, dirty); + widget->Invalidate(instance_->pp_instance(), resource.id, dirty); } } // namespace pepper diff --git a/webkit/glue/plugins/plugin_group.cc b/webkit/glue/plugins/plugin_group.cc new file mode 100644 index 0000000..ee3155e --- /dev/null +++ b/webkit/glue/plugins/plugin_group.cc @@ -0,0 +1,419 @@ +// Copyright (c) 2010 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/plugin_group.h" + +#include "base/linked_ptr.h" +#include "base/string_util.h" +#include "base/sys_string_conversions.h" +#include "base/utf_string_conversions.h" +#include "base/values.h" +#include "base/version.h" +#include "webkit/glue/plugins/plugin_list.h" +#include "webkit/glue/plugins/webplugininfo.h" + +const char* PluginGroup::kAdobeReader8GroupName = "Adobe Reader 8"; +const char* PluginGroup::kAdobeReader9GroupName = "Adobe Reader 9"; + +#if defined(OS_MACOSX) +// Plugin Groups for Mac. +// Plugins are listed here as soon as vulnerabilities and solutions +// (new versions) are published. +// TODO(panayiotis): Get the Real Player version on Mac, somehow. +static const PluginGroupDefinition kGroupDefinitions[] = { + { "apple-quicktime", "Quicktime", "QuickTime Plug-in", "", "", "7.6.6", + "http://www.apple.com/quicktime/download/" }, + { "java-runtime-environment", "Java", "Java", "", "", "", + "http://support.apple.com/kb/HT1338" }, + { "adobe-flash-player", "Flash", "Shockwave Flash", "", "", "10.1.85", + "http://get.adobe.com/flashplayer/" }, + { "silverlight-3", "Silverlight 3", "Silverlight", "0", "4", "3.0.50106.0", + "http://www.microsoft.com/getsilverlight/" }, + { "silverlight-4", "Silverlight 4", "Silverlight", "4", "5", "", + "http://www.microsoft.com/getsilverlight/" }, + { "flip4mac", "Flip4Mac", "Flip4Mac", "", "", "2.2.1", + "http://www.telestream.net/flip4mac-wmv/overview.htm" }, + { "shockwave", "Shockwave", "Shockwave for Director", "", "", "11.5.8.612", + "http://www.adobe.com/shockwave/download/" } +}; + +#elif defined(OS_WIN) +// TODO(panayiotis): We should group "RealJukebox NS Plugin" with the rest of +// the RealPlayer files. +static const PluginGroupDefinition kGroupDefinitions[] = { + { "apple-quicktime", "Quicktime", "QuickTime Plug-in", "", "", "7.6.8", + "http://www.apple.com/quicktime/download/" }, + { "java-runtime-environment", "Java 6", "Java", "", "6", "6.0.220", + "http://www.java.com/" }, + { "adobe-reader", PluginGroup::kAdobeReader9GroupName, "Adobe Acrobat", "9", + "10", "9.4.0", "http://get.adobe.com/reader/" }, + { "adobe-reader-8", PluginGroup::kAdobeReader8GroupName, "Adobe Acrobat", "0", + "9", "8.2.5", "http://get.adobe.com/reader/" }, + { "adobe-flash-player", "Flash", "Shockwave Flash", "", "", "10.1.85", + "http://get.adobe.com/flashplayer/" }, + { "silverlight-3", "Silverlight 3", "Silverlight", "0", "4", "3.0.50106.0", + "http://www.microsoft.com/getsilverlight/" }, + { "silverlight-4", "Silverlight 4", "Silverlight", "4", "5", "", + "http://www.microsoft.com/getsilverlight/" }, + { "shockwave", "Shockwave", "Shockwave for Director", "", "", "11.5.8.612", + "http://www.adobe.com/shockwave/download/" }, + { "divx-player", "DivX Player", "DivX Web Player", "", "", "1.4.3.4", + "http://download.divx.com/divx/autoupdate/player/" + "DivXWebPlayerInstaller.exe" }, + // These are here for grouping, no vulnerabilies known. + { "windows-media-player", "Windows Media Player", "Windows Media Player", + "", "", "", "" }, + { "microsoft-office", "Microsoft Office", "Microsoft Office", + "", "", "", "" }, + // TODO(panayiotis): The vulnerable versions are + // (v >= 6.0.12.1040 && v <= 6.0.12.1663) + // || v == 6.0.12.1698 || v == 6.0.12.1741 + { "realplayer", "RealPlayer", "RealPlayer", "", "", "", + "http://www.adobe.com/shockwave/download/" }, +}; + +#else +static const PluginGroupDefinition kGroupDefinitions[] = {}; +#endif + +/*static*/ +std::set<string16>* PluginGroup::policy_disabled_plugin_patterns_; + +/*static*/ +const PluginGroupDefinition* PluginGroup::GetPluginGroupDefinitions() { + return kGroupDefinitions; +} + +/*static*/ +size_t PluginGroup::GetPluginGroupDefinitionsSize() { + // TODO(viettrungluu): |arraysize()| doesn't work with zero-size arrays. + return ARRAYSIZE_UNSAFE(kGroupDefinitions); +} + +/*static*/ +void PluginGroup::SetPolicyDisabledPluginPatterns( + const std::set<string16>& set) { + if (!policy_disabled_plugin_patterns_) + policy_disabled_plugin_patterns_ = new std::set<string16>(set); + else + *policy_disabled_plugin_patterns_ = set; +} + +/*static*/ +bool PluginGroup::IsPluginNameDisabledByPolicy(const string16& plugin_name) { + if (!policy_disabled_plugin_patterns_) + return false; + + std::set<string16>::const_iterator pattern( + policy_disabled_plugin_patterns_->begin()); + while (pattern != policy_disabled_plugin_patterns_->end()) { + if (MatchPattern(plugin_name, *pattern)) + return true; + ++pattern; + } + + return false; +} + +/*static*/ +bool PluginGroup::IsPluginPathDisabledByPolicy(const FilePath& plugin_path) { + std::vector<WebPluginInfo> plugins; + NPAPI::PluginList::Singleton()->GetPlugins(false, &plugins); + for (std::vector<WebPluginInfo>::const_iterator it = plugins.begin(); + it != plugins.end(); + ++it) { + if (FilePath::CompareEqualIgnoreCase(it->path.value(), + plugin_path.value()) && IsPluginNameDisabledByPolicy(it->name)) { + return true; + } + } + return false; +} + +PluginGroup::PluginGroup(const string16& group_name, + const string16& name_matcher, + const std::string& version_range_low, + const std::string& version_range_high, + const std::string& min_version, + const std::string& update_url, + const std::string& identifier) + : identifier_(identifier), + group_name_(group_name), + name_matcher_(name_matcher), + version_range_low_str_(version_range_low), + version_range_high_str_(version_range_high), + update_url_(update_url), + enabled_(false), + min_version_str_(min_version), + version_(Version::GetVersionFromString("0")) { + if (!version_range_low.empty()) + version_range_low_.reset(Version::GetVersionFromString(version_range_low)); + if (!version_range_high.empty()) { + version_range_high_.reset( + Version::GetVersionFromString(version_range_high)); + } + if (!min_version.empty()) + min_version_.reset(Version::GetVersionFromString(min_version)); +} + +PluginGroup* PluginGroup::FromPluginGroupDefinition( + const PluginGroupDefinition& definition) { + return new PluginGroup(ASCIIToUTF16(definition.name), + ASCIIToUTF16(definition.name_matcher), + definition.version_matcher_low, + definition.version_matcher_high, + definition.min_version, + definition.update_url, + definition.identifier); +} + +PluginGroup::~PluginGroup() { } + +PluginGroup* PluginGroup::FromWebPluginInfo(const WebPluginInfo& wpi) { + // Create a matcher from the name of this plugin. +#if defined(OS_POSIX) + std::string identifier = wpi.path.BaseName().value(); +#elif defined(OS_WIN) + std::string identifier = base::SysWideToUTF8(wpi.path.BaseName().value()); +#endif + return new PluginGroup(wpi.name, wpi.name, std::string(), std::string(), + std::string(), std::string(), identifier); +} + +PluginGroup* PluginGroup::CopyOrCreatePluginGroup( + const WebPluginInfo& info) { + static PluginMap* hardcoded_plugin_groups = NULL; + if (!hardcoded_plugin_groups) { + PluginMap* groups = new PluginMap(); + const PluginGroupDefinition* definitions = GetPluginGroupDefinitions(); + for (size_t i = 0; i < GetPluginGroupDefinitionsSize(); ++i) { + PluginGroup* definition_group = PluginGroup::FromPluginGroupDefinition( + definitions[i]); + std::string identifier = definition_group->identifier(); + DCHECK(groups->find(identifier) == groups->end()); + (*groups)[identifier] = linked_ptr<PluginGroup>(definition_group); + } + hardcoded_plugin_groups = groups; + } + + // See if this plugin matches any of the hardcoded groups. + PluginGroup* hardcoded_group = FindGroupMatchingPlugin( + *hardcoded_plugin_groups, info); + if (hardcoded_group) { + // Make a copy. + return hardcoded_group->Copy(); + } else { + // Not found in our hardcoded list, create a new one. + return PluginGroup::FromWebPluginInfo(info); + } +} + +PluginGroup* PluginGroup::FindGroupMatchingPlugin( + const PluginMap& plugin_groups, + const WebPluginInfo& plugin) { + for (std::map<std::string, linked_ptr<PluginGroup> >::const_iterator it = + plugin_groups.begin(); + it != plugin_groups.end(); + ++it) { + if (it->second->Match(plugin)) + return it->second.get(); + } + return NULL; +} + +bool PluginGroup::Match(const WebPluginInfo& plugin) const { + if (name_matcher_.empty()) { + return false; + } + + // Look for the name matcher anywhere in the plugin name. + if (plugin.name.find(name_matcher_) == string16::npos) { + return false; + } + + if (version_range_low_.get() == NULL || + version_range_high_.get() == NULL) { + return true; + } + + // There's a version range, we must be in it. + scoped_ptr<Version> plugin_version( + Version::GetVersionFromString(UTF16ToWide(plugin.version))); + if (plugin_version.get() == NULL) { + // No version could be extracted, assume we don't match the range. + return false; + } + + // We match if we are in the range: [low, high) + return (version_range_low_->CompareTo(*plugin_version) <= 0 && + version_range_high_->CompareTo(*plugin_version) > 0); +} + +Version* PluginGroup::CreateVersionFromString(const string16& version_string) { + // Remove spaces and ')' from the version string, + // Replace any instances of 'r', ',' or '(' with a dot. + std::wstring version = UTF16ToWide(version_string); + RemoveChars(version, L") ", &version); + std::replace(version.begin(), version.end(), 'r', '.'); + std::replace(version.begin(), version.end(), ',', '.'); + std::replace(version.begin(), version.end(), '(', '.'); + + return Version::GetVersionFromString(version); +} + +void PluginGroup::UpdateActivePlugin(const WebPluginInfo& plugin) { + // A group is enabled if any of the files are enabled. + if (plugin.enabled) { + if (!enabled_) { + // If this is the first enabled plugin, use its description. + enabled_ = true; + UpdateDescriptionAndVersion(plugin); + } + } else { + // If this is the first plugin and it's disabled, + // use its description for now. + if (description_.empty()) + UpdateDescriptionAndVersion(plugin); + } +} + +void PluginGroup::UpdateDescriptionAndVersion(const WebPluginInfo& plugin) { + description_ = plugin.desc; + if (Version* new_version = CreateVersionFromString(plugin.version)) + version_.reset(new_version); + else + version_.reset(Version::GetVersionFromString("0")); +} + +void PluginGroup::AddPlugin(const WebPluginInfo& plugin, int position) { + web_plugin_infos_.push_back(plugin); + // The position of this plugin relative to the global list of plugins. + web_plugin_positions_.push_back(position); + UpdateActivePlugin(plugin); +} + +string16 PluginGroup::GetGroupName() const { + if (!group_name_.empty()) + return group_name_; + DCHECK_EQ(1u, web_plugin_infos_.size()); + FilePath::StringType path = + web_plugin_infos_[0].path.BaseName().RemoveExtension().value(); +#if defined(OS_POSIX) + return UTF8ToUTF16(path); +#elif defined(OS_WIN) + return WideToUTF16(path); +#endif +} + +DictionaryValue* PluginGroup::GetSummary() const { + DictionaryValue* result = new DictionaryValue(); + result->SetString("name", GetGroupName()); + result->SetBoolean("enabled", enabled_); + return result; +} + +DictionaryValue* PluginGroup::GetDataForUI() const { + string16 name = GetGroupName(); + DictionaryValue* result = new DictionaryValue(); + result->SetString("name", name); + result->SetString("description", description_); + result->SetString("version", version_->GetString()); + result->SetString("update_url", update_url_); + result->SetBoolean("critical", IsVulnerable()); + + bool group_disabled_by_policy = IsPluginNameDisabledByPolicy(name); + ListValue* plugin_files = new ListValue(); + bool all_plugins_disabled_by_policy = true; + for (size_t i = 0; i < web_plugin_infos_.size(); ++i) { + const WebPluginInfo& web_plugin = web_plugin_infos_[i]; + int priority = web_plugin_positions_[i]; + DictionaryValue* plugin_file = new DictionaryValue(); + plugin_file->SetString("name", web_plugin.name); + plugin_file->SetString("description", web_plugin.desc); + plugin_file->SetString("path", web_plugin.path.value()); + plugin_file->SetString("version", web_plugin.version); + bool plugin_disabled_by_policy = group_disabled_by_policy || + IsPluginNameDisabledByPolicy(web_plugin.name); + if (plugin_disabled_by_policy) { + plugin_file->SetString("enabledMode", "disabledByPolicy"); + } else { + all_plugins_disabled_by_policy = false; + plugin_file->SetString("enabledMode", + web_plugin.enabled ? "enabled" : "disabledByUser"); + } + plugin_file->SetInteger("priority", priority); + + ListValue* mime_types = new ListValue(); + for (std::vector<WebPluginMimeType>::const_iterator type_it = + web_plugin.mime_types.begin(); + type_it != web_plugin.mime_types.end(); + ++type_it) { + DictionaryValue* mime_type = new DictionaryValue(); + mime_type->SetString("mimeType", type_it->mime_type); + mime_type->SetString("description", type_it->description); + + ListValue* file_extensions = new ListValue(); + for (std::vector<std::string>::const_iterator ext_it = + type_it->file_extensions.begin(); + ext_it != type_it->file_extensions.end(); + ++ext_it) { + file_extensions->Append(new StringValue(*ext_it)); + } + mime_type->Set("fileExtensions", file_extensions); + + mime_types->Append(mime_type); + } + plugin_file->Set("mimeTypes", mime_types); + + plugin_files->Append(plugin_file); + } + + if (group_disabled_by_policy || all_plugins_disabled_by_policy) { + result->SetString("enabledMode", "disabledByPolicy"); + } else { + result->SetString("enabledMode", enabled_ ? "enabled" : "disabledByUser"); + } + result->Set("plugin_files", plugin_files); + + return result; +} + +// Returns true if the latest version of this plugin group is vulnerable. +bool PluginGroup::IsVulnerable() const { + if (min_version_.get() == NULL || version_->GetString() == "0") { + return false; + } + return version_->CompareTo(*min_version_) < 0; +} + +void PluginGroup::DisableOutdatedPlugins() { + if (!min_version_.get()) + return; + + description_ = string16(); + enabled_ = false; + + for (std::vector<WebPluginInfo>::iterator it = + web_plugin_infos_.begin(); + it != web_plugin_infos_.end(); ++it) { + scoped_ptr<Version> version(CreateVersionFromString(it->version)); + if (version.get() && version->CompareTo(*min_version_) < 0) { + it->enabled = false; + NPAPI::PluginList::Singleton()->DisablePlugin(it->path); + } + UpdateActivePlugin(*it); + } +} + +void PluginGroup::Enable(bool enable) { + for (std::vector<WebPluginInfo>::const_iterator it = + web_plugin_infos_.begin(); + it != web_plugin_infos_.end(); ++it) { + if (enable && !IsPluginNameDisabledByPolicy(it->name)) { + NPAPI::PluginList::Singleton()->EnablePlugin(it->path); + } else { + NPAPI::PluginList::Singleton()->DisablePlugin(it->path); + } + } +} diff --git a/webkit/glue/plugins/plugin_group.h b/webkit/glue/plugins/plugin_group.h new file mode 100644 index 0000000..2281437 --- /dev/null +++ b/webkit/glue/plugins/plugin_group.h @@ -0,0 +1,184 @@ +// Copyright (c) 2010 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_GLUE_PLUGINS_PLUGIN_GROUP_H_ +#define WEBKIT_GLUE_PLUGINS_PLUGIN_GROUP_H_ +#pragma once + +#include <map> +#include <set> +#include <vector> + +#include "base/gtest_prod_util.h" +#include "base/scoped_ptr.h" +#include "base/string16.h" + +class DictionaryValue; +class FilePath; +class Version; +struct WebPluginInfo; + +namespace NPAPI { + class PluginList; +}; + +template <typename T> +class linked_ptr; + +// Hard-coded definitions of plugin groups. +struct PluginGroupDefinition { + const char* identifier; // Unique identifier for this group. + const char* name; // Name of this group. + const char* name_matcher; // Substring matcher for the plugin name. + const char* version_matcher_low; // Matchers for the plugin version. + const char* version_matcher_high; + const char* min_version; // Minimum secure version. + const char* update_url; // Location of latest secure version. +}; + +// A PluginGroup can match a range of versions of a specific plugin (as defined +// by matching a substring of its name). +// It contains all WebPluginInfo structs (at least one) matching its definition. +// In addition, it knows about a security "baseline", i.e. the minimum version +// of a plugin that is needed in order not to exhibit known security +// vulnerabilities. + +class PluginGroup { + public: + // Used by about:plugins to disable Reader plugin when internal PDF viewer is + // enabled. + static const char* kAdobeReader8GroupName; + static const char* kAdobeReader9GroupName; + + typedef std::map<std::string, linked_ptr<PluginGroup> > PluginMap; + + // Creates a PluginGroup from a PluginGroupDefinition. + static PluginGroup* FromPluginGroupDefinition( + const PluginGroupDefinition& definition); + + ~PluginGroup(); + + // Creates a PluginGroup from a WebPluginInfo -- when no hard-coded + // definition is found. + static PluginGroup* FromWebPluginInfo(const WebPluginInfo& wpi); + + // Find a plugin group matching |info| in the list of hardcoded plugins and + // returns a copy of it if found, or a new group matching exactly this plugin + // otherwise. + // The caller should take ownership of the return PluginGroup. + static PluginGroup* CopyOrCreatePluginGroup(const WebPluginInfo& info); + + // Configures the set of plugin name patterns for disabling plugins via + // enterprise configuration management. + static void SetPolicyDisabledPluginPatterns(const std::set<string16>& set); + + // Tests to see if a plugin is on the blacklist using its name as + // the lookup key. + static bool IsPluginNameDisabledByPolicy(const string16& plugin_name); + + // Tests to see if a plugin is on the blacklist using its path as + // the lookup key. + static bool IsPluginPathDisabledByPolicy(const FilePath& plugin_path); + + // Find the PluginGroup matching a Plugin in a list of plugin groups. Returns + // NULL if no matching PluginGroup is found. + static PluginGroup* FindGroupMatchingPlugin( + const std::map<std::string, linked_ptr<PluginGroup> >& plugin_groups, + const WebPluginInfo& plugin); + + // Creates a copy of this plugin group. + PluginGroup* Copy() { + return new PluginGroup(group_name_, name_matcher_, version_range_low_str_, + version_range_high_str_, min_version_str_, + update_url_, identifier_); + } + + // Returns true if the given plugin matches this group. + bool Match(const WebPluginInfo& plugin) const; + + // Adds the given plugin to this group. Provide the position of the + // plugin as given by PluginList so we can display its priority. + void AddPlugin(const WebPluginInfo& plugin, int position); + + // Enables/disables this group. This enables/disables all plugins in the + // group. + void Enable(bool enable); + + // Returns whether the plugin group is enabled or not. + bool Enabled() const { return enabled_; } + + // Returns a unique identifier for this group, if one is defined, or the empty + // string otherwise. + const std::string& identifier() const { return identifier_; } + + // Returns this group's name, or the filename without extension if the name + // is empty. + string16 GetGroupName() const; + + // Returns the description of the highest-priority plug-in in the group. + const string16& description() const { return description_; } + + // Returns a DictionaryValue with data to display in the UI. + DictionaryValue* GetDataForUI() const; + + // Returns a DictionaryValue with data to save in the preferences. + DictionaryValue* GetSummary() const; + + // Returns the update URL. + std::string GetUpdateURL() const { return update_url_; } + + // Returns true if the highest-priority plugin in this group has known + // security problems. + bool IsVulnerable() const; + + // Disables all plugins in this group that are older than the + // minimum version. + void DisableOutdatedPlugins(); + + private: + FRIEND_TEST_ALL_PREFIXES(PluginGroupTest, PluginGroupDefinition); + + static const PluginGroupDefinition* GetPluginGroupDefinitions(); + static size_t GetPluginGroupDefinitionsSize(); + + PluginGroup(const string16& group_name, + const string16& name_matcher, + const std::string& version_range_low, + const std::string& version_range_high, + const std::string& min_version, + const std::string& update_url, + const std::string& identifier); + + Version* CreateVersionFromString(const string16& version_string); + + // Set the description and version for this plugin group from the + // given plug-in. + void UpdateDescriptionAndVersion(const WebPluginInfo& plugin); + + // Updates the active plugin in the group. The active plugin is the first + // enabled one, or if all plugins are disabled, simply the first one. + void UpdateActivePlugin(const WebPluginInfo& plugin); + + static std::set<string16>* policy_disabled_plugin_patterns_; + + std::string identifier_; + string16 group_name_; + string16 name_matcher_; + std::string version_range_low_str_; + std::string version_range_high_str_; + scoped_ptr<Version> version_range_low_; + scoped_ptr<Version> version_range_high_; + string16 description_; + std::string update_url_; + bool enabled_; + std::string min_version_str_; + scoped_ptr<Version> min_version_; + scoped_ptr<Version> version_; + std::vector<WebPluginInfo> web_plugin_infos_; + std::vector<int> web_plugin_positions_; + + DISALLOW_COPY_AND_ASSIGN(PluginGroup); +}; + +#endif // WEBKIT_GLUE_PLUGINS_PLUGIN_GROUP_H_ diff --git a/webkit/glue/plugins/plugin_group_unittest.cc b/webkit/glue/plugins/plugin_group_unittest.cc new file mode 100644 index 0000000..467c273 --- /dev/null +++ b/webkit/glue/plugins/plugin_group_unittest.cc @@ -0,0 +1,181 @@ +// Copyright (c) 2010 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/plugin_group.h" + +#include <string> +#include <vector> + +#include "base/scoped_ptr.h" +#include "base/string_util.h" +#include "base/utf_string_conversions.h" +#include "base/values.h" +#include "base/version.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "webkit/glue/plugins/webplugininfo.h" + +static const PluginGroupDefinition kPluginDef = { + "myplugin", "MyPlugin", "MyPlugin", "", "", "3.0.44", "http://latest/" }; +static const PluginGroupDefinition kPluginDef3 = { + "myplugin-3", "MyPlugin 3", "MyPlugin", "0", "4", "3.0.44", "http://latest" }; +static const PluginGroupDefinition kPluginDef4 = { + "myplugin-4", "MyPlugin 4", "MyPlugin", "4", "5", "4.0.44", "http://latest" }; +static const PluginGroupDefinition kPluginDefNotVulnerable = { + "myplugin-latest", "MyPlugin", "MyPlugin", "", "", "", "http://latest" }; + +// name, path, version, desc, mime_types, enabled. +static WebPluginInfo kPlugin2043 = WebPluginInfo( + ASCIIToUTF16("MyPlugin"), ASCIIToUTF16("2.0.43"), + ASCIIToUTF16("MyPlugin version 2.0.43")); +static WebPluginInfo kPlugin3043 = WebPluginInfo( + ASCIIToUTF16("MyPlugin"), ASCIIToUTF16("3.0.43"), + ASCIIToUTF16("MyPlugin version 3.0.43")); +static WebPluginInfo kPlugin3044 = WebPluginInfo( + ASCIIToUTF16("MyPlugin"), ASCIIToUTF16("3.0.44"), + ASCIIToUTF16("MyPlugin version 3.0.44")); +static WebPluginInfo kPlugin3045 = WebPluginInfo( + ASCIIToUTF16("MyPlugin"), ASCIIToUTF16("3.0.45"), + ASCIIToUTF16("MyPlugin version 3.0.45")); +static WebPluginInfo kPlugin4043 = WebPluginInfo( + ASCIIToUTF16("MyPlugin"), ASCIIToUTF16("4.0.43"), + ASCIIToUTF16("MyPlugin version 4.0.43")); + +class PluginGroupTest : public testing::Test { + protected: + virtual void TearDown() { + PluginGroup::SetPolicyDisabledPluginPatterns(std::set<string16>()); + } +}; + +TEST(PluginGroupTest, PluginGroupMatch) { + scoped_ptr<PluginGroup> group(PluginGroup::FromPluginGroupDefinition( + kPluginDef3)); + EXPECT_TRUE(group->Match(kPlugin3045)); + group->AddPlugin(kPlugin3045, 0); + EXPECT_FALSE(group->IsVulnerable()); +} + +TEST(PluginGroupTest, PluginGroupMatchCorrectVersion) { + scoped_ptr<PluginGroup> group(PluginGroup::FromPluginGroupDefinition( + kPluginDef3)); + EXPECT_TRUE(group->Match(kPlugin2043)); + EXPECT_TRUE(group->Match(kPlugin3043)); + EXPECT_FALSE(group->Match(kPlugin4043)); + + group.reset(PluginGroup::FromPluginGroupDefinition(kPluginDef4)); + EXPECT_FALSE(group->Match(kPlugin2043)); + EXPECT_FALSE(group->Match(kPlugin3043)); + EXPECT_TRUE(group->Match(kPlugin4043)); +} + +TEST(PluginGroupTest, PluginGroupDescription) { + string16 desc3043(ASCIIToUTF16("MyPlugin version 3.0.43")); + string16 desc3045(ASCIIToUTF16("MyPlugin version 3.0.45")); + WebPluginInfo plugin3043(kPlugin3043); + WebPluginInfo plugin3045(kPlugin3045); + + { + scoped_ptr<PluginGroup> group(PluginGroup::FromPluginGroupDefinition( + kPluginDef3)); + EXPECT_TRUE(group->Match(plugin3043)); + group->AddPlugin(plugin3043, 0); + EXPECT_EQ(desc3043, group->description()); + EXPECT_TRUE(group->IsVulnerable()); + EXPECT_TRUE(group->Match(plugin3045)); + group->AddPlugin(plugin3045, 1); + EXPECT_EQ(desc3043, group->description()); + EXPECT_TRUE(group->IsVulnerable()); + } + + { + // Disable the first plugin. + plugin3043.enabled = false; + scoped_ptr<PluginGroup> group(PluginGroup::FromPluginGroupDefinition( + kPluginDef3)); + EXPECT_TRUE(group->Match(plugin3043)); + group->AddPlugin(plugin3043, 0); + EXPECT_EQ(desc3043, group->description()); + EXPECT_TRUE(group->IsVulnerable()); + EXPECT_TRUE(group->Match(plugin3045)); + group->AddPlugin(plugin3045, 1); + EXPECT_EQ(desc3045, group->description()); + EXPECT_FALSE(group->IsVulnerable()); + } + + { + // Disable the second plugin. + plugin3045.enabled = false; + scoped_ptr<PluginGroup> group(PluginGroup::FromPluginGroupDefinition( + kPluginDef3)); + EXPECT_TRUE(group->Match(plugin3043)); + group->AddPlugin(plugin3043, 1); + EXPECT_EQ(desc3043, group->description()); + EXPECT_TRUE(group->IsVulnerable()); + EXPECT_TRUE(group->Match(plugin3045)); + group->AddPlugin(plugin3045, 0); + EXPECT_EQ(desc3043, group->description()); + EXPECT_TRUE(group->IsVulnerable()); + } +} + +TEST(PluginGroupTest, PluginGroupDefinition) { + const PluginGroupDefinition* definitions = + PluginGroup::GetPluginGroupDefinitions(); + for (size_t i = 0; i < PluginGroup::GetPluginGroupDefinitionsSize(); ++i) { + scoped_ptr<PluginGroup> def_group( + PluginGroup::FromPluginGroupDefinition(definitions[i])); + ASSERT_TRUE(def_group.get() != NULL); + EXPECT_FALSE(def_group->Match(kPlugin2043)); + } +} + +TEST(PluginGroupTest, DisableOutdated) { + scoped_ptr<PluginGroup> group(PluginGroup::FromPluginGroupDefinition( + kPluginDef3)); + group->AddPlugin(kPlugin3043, 0); + group->AddPlugin(kPlugin3045, 1); + EXPECT_EQ(ASCIIToUTF16("MyPlugin version 3.0.43"), group->description()); + EXPECT_TRUE(group->IsVulnerable()); + + group->DisableOutdatedPlugins(); + EXPECT_EQ(ASCIIToUTF16("MyPlugin version 3.0.45"), group->description()); + EXPECT_FALSE(group->IsVulnerable()); +} + +TEST(PluginGroupTest, VersionExtraction) { + // Some real-world plugin versions (spaces, commata, parentheses, 'r', oh my) + const char* versions[][2] = { + { "7.6.6 (1671)", "7.6.6.1671" }, // Quicktime + { "2, 0, 0, 254", "2.0.0.254" }, // DivX + { "3, 0, 0, 0", "3.0.0.0" }, // Picasa + { "1, 0, 0, 1", "1.0.0.1" }, // Earth + { "10,0,45,2", "10.0.45.2" }, // Flash + { "11.5.7r609", "11.5.7.609"} // Shockwave + }; + + for (size_t i = 0; i < arraysize(versions); i++) { + const WebPluginInfo plugin = WebPluginInfo( + ASCIIToUTF16("Blah Plugin"), ASCIIToUTF16(versions[i][0]), string16()); + scoped_ptr<PluginGroup> group(PluginGroup::FromWebPluginInfo(plugin)); + EXPECT_TRUE(group->Match(plugin)); + group->AddPlugin(plugin, 0); + scoped_ptr<DictionaryValue> data(group->GetDataForUI()); + std::string version; + data->GetString("version", &version); + EXPECT_EQ(versions[i][1], version); + } +} + +TEST(PluginGroupTest, DisabledByPolicy) { + std::set<string16> disabled_plugins; + disabled_plugins.insert(ASCIIToUTF16("Disable this!")); + disabled_plugins.insert(ASCIIToUTF16("*Google*")); + PluginGroup::SetPolicyDisabledPluginPatterns(disabled_plugins); + + EXPECT_FALSE(PluginGroup::IsPluginNameDisabledByPolicy(ASCIIToUTF16("42"))); + EXPECT_TRUE(PluginGroup::IsPluginNameDisabledByPolicy( + ASCIIToUTF16("Disable this!"))); + EXPECT_TRUE(PluginGroup::IsPluginNameDisabledByPolicy( + ASCIIToUTF16("Google Earth"))); +} diff --git a/webkit/glue/plugins/plugin_host.cc b/webkit/glue/plugins/plugin_host.cc index a1a6d5f..add6c03 100644 --- a/webkit/glue/plugins/plugin_host.cc +++ b/webkit/glue/plugins/plugin_host.cc @@ -310,7 +310,7 @@ uint32_t NPN_MemFlush(uint32_t size) { // Should force a re-scan of the plugins directory to load new ones. void NPN_ReloadPlugins(NPBool reloadPages) { // TODO: implement me - DLOG(INFO) << "NPN_ReloadPlugin is not implemented yet."; + DVLOG(1) << "NPN_ReloadPlugin is not implemented yet."; } // Requests a range of bytes for a seekable stream. @@ -526,7 +526,7 @@ NPError NPN_NewStream(NPP id, // Browser should put this stream into a window target. // // TODO: implement me - DLOG(INFO) << "NPN_NewStream is not implemented yet."; + DVLOG(1) << "NPN_NewStream is not implemented yet."; return NPERR_GENERIC_ERROR; } @@ -534,7 +534,7 @@ int32_t NPN_Write(NPP id, NPStream* stream, int32_t len, void* buffer) { // Writes data to an existing Plugin-created stream. // TODO: implement me - DLOG(INFO) << "NPN_Write is not implemented yet."; + DVLOG(1) << "NPN_Write is not implemented yet."; return NPERR_GENERIC_ERROR; } @@ -594,7 +594,7 @@ void NPN_Status(NPP id, const char* message) { // Displays a message on the status line of the browser window. // TODO: implement me - DLOG(INFO) << "NPN_Status is not implemented yet."; + DVLOG(1) << "NPN_Status is not implemented yet."; } void NPN_InvalidateRect(NPP id, NPRect *invalidRect) { @@ -797,16 +797,21 @@ NPError NPN_GetValue(NPP id, NPNVariable variable, void* value) { rv = NPERR_NO_ERROR; break; } - case NPNVsupportsCoreAnimationBool: - case NPNVsupportsInvalidatingCoreAnimationBool: { + case NPNVsupportsCoreAnimationBool: { // We only support the Core Animation model on 10.6 and higher // TODO(stuartmorgan): Once existing CA plugins have implemented the - // invalidating version, remove support for the other version. + // invalidating version, remove support for this one. NPBool* supports_model = reinterpret_cast<NPBool*>(value); *supports_model = SupportsSharingAcceleratedSurfaces() ? true : false; rv = NPERR_NO_ERROR; break; } + case NPNVsupportsInvalidatingCoreAnimationBool: { + NPBool* supports_model = reinterpret_cast<NPBool*>(value); + *supports_model = true; + rv = NPERR_NO_ERROR; + break; + } case NPNVsupportsOpenGLBool: { // This drawing model was never widely supported, and we don't plan to // support it. @@ -824,7 +829,7 @@ NPError NPN_GetValue(NPP id, NPNVariable variable, void* value) { rv = NPAPI::GetPepperExtensionsFunctions(value); break; default: - DLOG(INFO) << "NPN_GetValue(" << variable << ") is not implemented yet."; + DVLOG(1) << "NPN_GetValue(" << variable << ") is not implemented yet."; break; } return rv; @@ -859,24 +864,22 @@ NPError NPN_SetValue(NPP id, NPPVariable variable, void* value) { // Specifies whether you are pushing or popping the JSContext off. // the stack // TODO: implement me - DLOG(INFO) << - "NPN_SetValue(NPPVJavascriptPushCallerBool) is not implemented."; + DVLOG(1) << "NPN_SetValue(NPPVJavascriptPushCallerBool) is not " + "implemented."; return NPERR_GENERIC_ERROR; case NPPVpluginKeepLibraryInMemory: // Tells browser that plugin library should live longer than usual. // TODO: implement me - DLOG(INFO) << - "NPN_SetValue(NPPVpluginKeepLibraryInMemory) is not implemented."; + DVLOG(1) << "NPN_SetValue(NPPVpluginKeepLibraryInMemory) is not " + "implemented."; return NPERR_GENERIC_ERROR; #if defined(OS_MACOSX) case NPPVpluginDrawingModel: { int model = reinterpret_cast<int>(value); - if (model == NPDrawingModelCoreGraphics) { - plugin->set_drawing_model(static_cast<NPDrawingModel>(model)); - return NPERR_NO_ERROR; - } else if ((model == NPDrawingModelCoreAnimation || - model == NPDrawingModelInvalidatingCoreAnimation) && - SupportsSharingAcceleratedSurfaces()) { + if (model == NPDrawingModelCoreGraphics || + model == NPDrawingModelInvalidatingCoreAnimation || + (model == NPDrawingModelCoreAnimation && + SupportsSharingAcceleratedSurfaces())) { plugin->set_drawing_model(static_cast<NPDrawingModel>(model)); return NPERR_NO_ERROR; } @@ -899,7 +902,7 @@ NPError NPN_SetValue(NPP id, NPPVariable variable, void* value) { #endif default: // TODO: implement me - DLOG(INFO) << "NPN_SetValue(" << variable << ") is not implemented."; + DVLOG(1) << "NPN_SetValue(" << variable << ") is not implemented."; break; } @@ -909,13 +912,13 @@ NPError NPN_SetValue(NPP id, NPPVariable variable, void* value) { void* NPN_GetJavaEnv() { // TODO: implement me - DLOG(INFO) << "NPN_GetJavaEnv is not implemented."; + DVLOG(1) << "NPN_GetJavaEnv is not implemented."; return NULL; } void* NPN_GetJavaPeer(NPP) { // TODO: implement me - DLOG(INFO) << "NPN_GetJavaPeer is not implemented."; + DVLOG(1) << "NPN_GetJavaPeer is not implemented."; return NULL; } diff --git a/webkit/glue/plugins/plugin_lib.cc b/webkit/glue/plugins/plugin_lib.cc index 9a0770e..6c95274 100644 --- a/webkit/glue/plugins/plugin_lib.cc +++ b/webkit/glue/plugins/plugin_lib.cc @@ -6,7 +6,7 @@ #include "base/logging.h" #include "base/message_loop.h" -#include "base/stats_counters.h" +#include "base/metrics/stats_counters.h" #include "base/string_util.h" #include "webkit/glue/webkit_glue.h" #include "webkit/glue/plugins/plugin_instance.h" @@ -72,7 +72,7 @@ PluginLib::PluginLib(const WebPluginInfo& info, saved_data_(0), instance_count_(0), skip_unload_(false) { - StatsCounter(kPluginLibrariesLoadedCounter).Increment(); + base::StatsCounter(kPluginLibrariesLoadedCounter).Increment(); memset(static_cast<void*>(&plugin_funcs_), 0, sizeof(plugin_funcs_)); g_loaded_libs->push_back(this); @@ -87,7 +87,7 @@ PluginLib::PluginLib(const WebPluginInfo& info, } PluginLib::~PluginLib() { - StatsCounter(kPluginLibrariesLoadedCounter).Decrement(); + base::StatsCounter(kPluginLibrariesLoadedCounter).Decrement(); if (saved_data_ != 0) { // TODO - delete the savedData object here } @@ -143,13 +143,13 @@ void PluginLib::PreventLibraryUnload() { PluginInstance* PluginLib::CreateInstance(const std::string& mime_type) { PluginInstance* new_instance = new PluginInstance(this, mime_type); instance_count_++; - StatsCounter(kPluginInstancesActiveCounter).Increment(); + base::StatsCounter(kPluginInstancesActiveCounter).Increment(); DCHECK_NE(static_cast<PluginInstance*>(NULL), new_instance); return new_instance; } void PluginLib::CloseInstance() { - StatsCounter(kPluginInstancesActiveCounter).Decrement(); + base::StatsCounter(kPluginInstancesActiveCounter).Decrement(); instance_count_--; // If a plugin is running in its own process it will get unloaded on process // shutdown. diff --git a/webkit/glue/plugins/plugin_lib_mac.mm b/webkit/glue/plugins/plugin_lib_mac.mm index 07da77c..89444c8 100644 --- a/webkit/glue/plugins/plugin_lib_mac.mm +++ b/webkit/glue/plugins/plugin_lib_mac.mm @@ -6,8 +6,8 @@ #include "webkit/glue/plugins/plugin_lib.h" +#include "base/mac/scoped_cftyperef.h" #include "base/native_library.h" -#include "base/scoped_cftyperef.h" #include "base/scoped_ptr.h" #include "base/string_split.h" #include "base/string_util.h" @@ -19,8 +19,9 @@ static const short kSTRTypeDefinitionResourceID = 128; static const short kSTRTypeDescriptionResourceID = 127; static const short kSTRPluginDescriptionResourceID = 126; -namespace NPAPI -{ +using base::mac::ScopedCFTypeRef; + +namespace NPAPI { namespace { @@ -161,7 +162,7 @@ bool GetSTRResource(CFBundleRef bundle, short res_id, pointer += sizeof(short); for (short i = 0; i < num_strings; ++i) { // Despite being 8-bits wide, these are legacy encoded. Make a round trip. - scoped_cftyperef<CFStringRef> str(CFStringCreateWithPascalStringNoCopy( + ScopedCFTypeRef<CFStringRef> str(CFStringCreateWithPascalStringNoCopy( kCFAllocatorDefault, (unsigned char*)pointer, GetApplicationTextEncoding(), // is this right? @@ -200,8 +201,8 @@ bool ReadSTRPluginInfo(const FilePath& filename, CFBundleRef bundle, mime.mime_type = StringToLowerASCII(type_strings[2*i]); if (have_type_descs && i < type_descs.size()) mime.description = UTF8ToUTF16(type_descs[i]); - SplitString(StringToLowerASCII(type_strings[2*i+1]), ',', - &mime.file_extensions); + base::SplitString( + StringToLowerASCII(type_strings[2*i+1]), ',', &mime.file_extensions); info->mime_types.push_back(mime); } @@ -309,13 +310,13 @@ bool PluginLib::ReadWebPluginInfo(const FilePath &filename, // // Strictly speaking, only STR# 128 is required. - scoped_cftyperef<CFURLRef> bundle_url(CFURLCreateFromFileSystemRepresentation( + ScopedCFTypeRef<CFURLRef> bundle_url(CFURLCreateFromFileSystemRepresentation( kCFAllocatorDefault, (const UInt8*)filename.value().c_str(), filename.value().length(), true)); if (!bundle_url) return false; - scoped_cftyperef<CFBundleRef> bundle(CFBundleCreate(kCFAllocatorDefault, - bundle_url.get())); + ScopedCFTypeRef<CFBundleRef> bundle(CFBundleCreate(kCFAllocatorDefault, + bundle_url.get())); if (!bundle) return false; diff --git a/webkit/glue/plugins/plugin_lib_posix.cc b/webkit/glue/plugins/plugin_lib_posix.cc index fb813b6..ac937e1 100644 --- a/webkit/glue/plugins/plugin_lib_posix.cc +++ b/webkit/glue/plugins/plugin_lib_posix.cc @@ -235,7 +235,7 @@ void PluginLib::ParseMIMEDescription( if (end == std::string::npos) break; const std::string extensions = description.substr(ofs, end - ofs); - SplitString(extensions, ',', &mime_type.file_extensions); + base::SplitString(extensions, ',', &mime_type.file_extensions); ofs = end + 1; end = description.find(';', ofs); diff --git a/webkit/glue/plugins/plugin_list.cc b/webkit/glue/plugins/plugin_list.cc index b2a7634..4b3ce27 100644 --- a/webkit/glue/plugins/plugin_list.cc +++ b/webkit/glue/plugins/plugin_list.cc @@ -11,6 +11,7 @@ #include "base/logging.h" #include "base/string_split.h" #include "base/string_util.h" +#include "base/sys_string_conversions.h" #include "base/utf_string_conversions.h" #include "googleurl/src/gurl.h" #include "net/base/mime_util.h" @@ -23,12 +24,19 @@ namespace NPAPI { base::LazyInstance<PluginList> g_singleton(base::LINKER_INITIALIZED); +static LoadPluginsFromDiskHookFunc g_load_plugins_hook; + // static PluginList* PluginList::Singleton() { return g_singleton.Pointer(); } // static +void PluginList::SetPluginLoadHook(LoadPluginsFromDiskHookFunc hook) { + g_load_plugins_hook = hook; +} + +// static bool PluginList::DebugPluginLoading() { return CommandLine::ForCurrentProcess()->HasSwitch( switches::kDebugPluginLoading); @@ -108,9 +116,9 @@ bool PluginList::CreateWebPluginInfo(const PluginVersionInfo& pvi, WebPluginInfo* info) { std::vector<std::string> mime_types, file_extensions; std::vector<string16> descriptions; - SplitString(WideToUTF8(pvi.mime_types), '|', &mime_types); - SplitString(WideToUTF8(pvi.file_extensions), '|', &file_extensions); - SplitString(WideToUTF16(pvi.type_descriptions), '|', &descriptions); + base::SplitString(WideToUTF8(pvi.mime_types), '|', &mime_types); + base::SplitString(WideToUTF8(pvi.file_extensions), '|', &file_extensions); + base::SplitString(WideToUTF16(pvi.type_descriptions), '|', &descriptions); info->mime_types.clear(); @@ -130,7 +138,7 @@ bool PluginList::CreateWebPluginInfo(const PluginVersionInfo& pvi, WebPluginMimeType mime_type; mime_type.mime_type = StringToLowerASCII(mime_types[i]); if (file_extensions.size() > i) - SplitString(file_extensions[i], ',', &mime_type.file_extensions); + base::SplitString(file_extensions[i], ',', &mime_type.file_extensions); if (descriptions.size() > i) { mime_type.description = descriptions[i]; @@ -154,10 +162,21 @@ bool PluginList::CreateWebPluginInfo(const PluginVersionInfo& pvi, } PluginList::PluginList() - : plugins_loaded_(false), plugins_need_refresh_(false) { + : plugins_loaded_(false), + plugins_need_refresh_(false), + disable_outdated_plugins_(false) { PlatformInit(); } +bool PluginList::ShouldDisableGroup(const string16& group_name) { + AutoLock lock(lock_); + if (PluginGroup::IsPluginNameDisabledByPolicy(group_name)) { + disabled_groups_.insert(group_name); + return true; + } + return disabled_groups_.count(group_name) > 0; +} + void PluginList::LoadPlugins(bool refresh) { // Don't want to hold the lock while loading new plugins, so we don't block // other methods if they're called on other threads. @@ -177,6 +196,9 @@ void PluginList::LoadPlugins(bool refresh) { internal_plugins = internal_plugins_; } + if (g_load_plugins_hook) + g_load_plugins_hook(); + std::vector<WebPluginInfo> new_plugins; std::set<FilePath> visited_plugins; @@ -216,15 +238,37 @@ void PluginList::LoadPlugins(bool refresh) { if (webkit_glue::IsDefaultPluginEnabled()) LoadPlugin(FilePath(kDefaultPluginLibraryName), &new_plugins); + // Disable all of the plugins and plugin groups that are disabled by policy. + // There's currenly a bug that makes it impossible to correctly re-enable + // plugins or plugin-groups to their original, "pre-policy" state, so + // plugins and groups are only changed to a more "safe" state after a policy + // change, i.e. from enabled to disabled. See bug 54681. + PluginMap plugin_groups; + GetPluginGroups(&new_plugins, &plugin_groups); + for (PluginMap::const_iterator it = plugin_groups.begin(); + it != plugin_groups.end(); ++it) { + PluginGroup* group = it->second.get(); + string16 group_name = group->GetGroupName(); + if (ShouldDisableGroup(group_name)) { + it->second->Enable(false); + } + + if (disable_outdated_plugins_) { + group->DisableOutdatedPlugins(); + if (!group->Enabled()) { + AutoLock lock(lock_); + disabled_groups_.insert(group_name); + } + } + } + // Only update the data now since loading plugins can take a while. AutoLock lock(lock_); - // Go through and mark new plugins in the disabled list as, well, disabled. - for (std::vector<WebPluginInfo>::iterator it = new_plugins.begin(); - it != new_plugins.end(); - ++it) { - if (disabled_plugins_.find(it->path) != disabled_plugins_.end()) - it->enabled = false; + // Mark disabled plugins as such. + for (size_t i = 0; i < new_plugins.size(); ++i) { + if (disabled_plugins_.count(new_plugins[i].path)) + new_plugins[i].enabled = false; } plugins_ = new_plugins; @@ -263,65 +307,6 @@ void PluginList::LoadPlugin(const FilePath& path, plugins->push_back(plugin_info); } -bool PluginList::FindPlugin(const std::string& mime_type, - bool allow_wildcard, - WebPluginInfo* info) { - DCHECK(mime_type == StringToLowerASCII(mime_type)); - - LoadPlugins(false); - AutoLock lock(lock_); - for (size_t i = 0; i < plugins_.size(); ++i) { - if (plugins_[i].enabled && - SupportsType(plugins_[i], mime_type, allow_wildcard)) { - *info = plugins_[i]; - return true; - } - } - - return false; -} - -bool PluginList::FindDisabledPlugin(const std::string& mime_type, - bool allow_wildcard, - WebPluginInfo* info) { - DCHECK(mime_type == StringToLowerASCII(mime_type)); - - LoadPlugins(false); - AutoLock lock(lock_); - for (size_t i = 0; i < plugins_.size(); ++i) { - if (!plugins_[i].enabled && - SupportsType(plugins_[i], mime_type, allow_wildcard)) { - *info = plugins_[i]; - return true; - } - } - - return false; -} - -bool PluginList::FindPlugin(const GURL &url, - std::string* actual_mime_type, - WebPluginInfo* info) { - LoadPlugins(false); - AutoLock lock(lock_); - std::string path = url.path(); - std::string::size_type last_dot = path.rfind('.'); - if (last_dot == std::string::npos) - return false; - - std::string extension = StringToLowerASCII(std::string(path, last_dot+1)); - - for (size_t i = 0; i < plugins_.size(); ++i) { - if (plugins_[i].enabled && - SupportsExtension(plugins_[i], extension, actual_mime_type)) { - *info = plugins_[i]; - return true; - } - } - - return false; -} - bool PluginList::SupportsType(const WebPluginInfo& info, const std::string &mime_type, bool allow_wildcard) { @@ -380,20 +365,111 @@ void PluginList::GetEnabledPlugins(bool refresh, } } +void PluginList::GetPluginInfoArray(const GURL& url, + const std::string& mime_type, + bool allow_wildcard, + std::vector<WebPluginInfo>* info, + std::vector<std::string>* actual_mime_types) +{ + DCHECK(mime_type == StringToLowerASCII(mime_type)); + DCHECK(info); + + LoadPlugins(false); + AutoLock lock(lock_); + info->clear(); + if (actual_mime_types) + actual_mime_types->clear(); + + std::set<FilePath> visited_plugins; + + // Add in enabled plugins by mime type. + WebPluginInfo default_plugin; + for (size_t i = 0; i < plugins_.size(); ++i) { + if (plugins_[i].enabled && + SupportsType(plugins_[i], mime_type, allow_wildcard)) { + FilePath path = plugins_[i].path; + if (path.value() != kDefaultPluginLibraryName && + visited_plugins.insert(path).second) { + info->push_back(plugins_[i]); + if (actual_mime_types) + actual_mime_types->push_back(mime_type); + } + } + } + + // Add in enabled plugins by url. + std::string path = url.path(); + std::string::size_type last_dot = path.rfind('.'); + if (last_dot != std::string::npos) { + std::string extension = StringToLowerASCII(std::string(path, last_dot+1)); + std::string actual_mime_type; + for (size_t i = 0; i < plugins_.size(); ++i) { + if (plugins_[i].enabled && + SupportsExtension(plugins_[i], extension, &actual_mime_type)) { + FilePath path = plugins_[i].path; + if (path.value() != kDefaultPluginLibraryName && + visited_plugins.insert(path).second) { + info->push_back(plugins_[i]); + if (actual_mime_types) + actual_mime_types->push_back(actual_mime_type); + } + } + } + } + + // Add in disabled plugins by mime type. + for (size_t i = 0; i < plugins_.size(); ++i) { + if (!plugins_[i].enabled && + SupportsType(plugins_[i], mime_type, allow_wildcard)) { + FilePath path = plugins_[i].path; + if (path.value() != kDefaultPluginLibraryName && + visited_plugins.insert(path).second) { + info->push_back(plugins_[i]); + if (actual_mime_types) + actual_mime_types->push_back(mime_type); + } + } + } + + // Add the default plugin at the end if it supports the mime type given, + // and the default plugin is enabled. + if (!plugins_.empty() && webkit_glue::IsDefaultPluginEnabled()) { + const WebPluginInfo& default_info = plugins_.back(); + if (SupportsType(default_info, mime_type, allow_wildcard)) { + info->push_back(default_info); + if (actual_mime_types) + actual_mime_types->push_back(mime_type); + } + } +} + bool PluginList::GetPluginInfo(const GURL& url, const std::string& mime_type, bool allow_wildcard, WebPluginInfo* info, std::string* actual_mime_type) { - bool found = FindPlugin(mime_type, allow_wildcard, info); - if (!found || (info->path.value() == kDefaultPluginLibraryName)) { - if (FindPlugin(url, actual_mime_type, info) || - FindDisabledPlugin(mime_type, allow_wildcard, info)) { - found = true; + DCHECK(info); + std::vector<WebPluginInfo> info_list; + + // GetPluginInfoArray has slightly less work to do if we can pass + // NULL for the mime type list... + if (actual_mime_type) { + std::vector<std::string> mime_type_list; + GetPluginInfoArray( + url, mime_type, allow_wildcard, &info_list, &mime_type_list); + if (!info_list.empty()) { + *info = info_list[0]; + *actual_mime_type = mime_type_list[0]; + return true; + } + } else { + GetPluginInfoArray(url, mime_type, allow_wildcard, &info_list, NULL); + if (!info_list.empty()) { + *info = info_list[0]; + return true; } } - - return found; + return false; } bool PluginList::GetPluginInfoByPath(const FilePath& plugin_path, @@ -410,6 +486,47 @@ bool PluginList::GetPluginInfoByPath(const FilePath& plugin_path, return false; } +void PluginList::GetPluginGroups(bool load_if_necessary, + PluginMap* plugin_groups) { + if (load_if_necessary) + LoadPlugins(false); + + AutoLock lock(lock_); + GetPluginGroups(&plugins_, plugin_groups); +} + +// static +void PluginList::GetPluginGroups(const std::vector<WebPluginInfo>* plugins, + PluginMap* plugin_groups) { + plugin_groups->clear(); + // We first search for an existing group that matches our name, + // and only create a new group if we can't find any. + for (size_t i = 0; i < plugins->size(); ++i) { + const WebPluginInfo& web_plugin = (*plugins)[i]; + PluginGroup* group = PluginGroup::FindGroupMatchingPlugin( + *plugin_groups, web_plugin); + if (!group) { + group = PluginGroup::CopyOrCreatePluginGroup(web_plugin); + std::string identifier = group->identifier(); + // If the identifier is not unique, use the full path. This means that we + // probably won't be able to search for this group by identifier, but at + // least it's going to be in the set of plugin groups, and if there + // is already a plug-in with the same filename, it's probably going to + // handle the same MIME types (and it has a higher priority), so this one + // is not going to run anyway. + if (plugin_groups->find(identifier) != plugin_groups->end()) +#if defined(OS_POSIX) + identifier = web_plugin.path.value(); +#elif defined(OS_WIN) + identifier = base::SysWideToUTF8(web_plugin.path.value()); +#endif + DCHECK(plugin_groups->find(identifier) == plugin_groups->end()); + (*plugin_groups)[identifier] = linked_ptr<PluginGroup>(group); + } + group->AddPlugin(web_plugin, i); + } +} + bool PluginList::EnablePlugin(const FilePath& filename) { AutoLock lock(lock_); @@ -459,6 +576,46 @@ bool PluginList::DisablePlugin(const FilePath& filename) { return did_disable; } +bool PluginList::EnableGroup(bool enable, const string16& group_name) { + bool did_change = false; + { + AutoLock lock(lock_); + + std::set<string16>::iterator entry = disabled_groups_.find(group_name); + if (enable) { + if (entry == disabled_groups_.end()) + return did_change; // Early exit if group not in disabled list. + disabled_groups_.erase(entry); // Remove from disabled list. + } else { + if (entry != disabled_groups_.end()) + return did_change; // Early exit if group already in disabled list. + disabled_groups_.insert(group_name); + } + } + + PluginMap plugin_groups; + GetPluginGroups(false, &plugin_groups); + for (PluginMap::const_iterator it = plugin_groups.begin(); + it != plugin_groups.end(); ++it) { + if (it->second->GetGroupName() == group_name) { + if (it->second->Enabled() != enable) { + it->second->Enable(enable); + did_change = true; + break; + } + } + } + + return did_change; +} + +void PluginList::DisableOutdatedPluginGroups() { + disable_outdated_plugins_ = true; +} + +PluginList::~PluginList() { +} + void PluginList::Shutdown() { // TODO } diff --git a/webkit/glue/plugins/plugin_list.h b/webkit/glue/plugins/plugin_list.h index ce9da28..25b903b 100644 --- a/webkit/glue/plugins/plugin_list.h +++ b/webkit/glue/plugins/plugin_list.h @@ -5,6 +5,7 @@ #ifndef WEBKIT_GLUE_PLUGINS_PLUGIN_LIST_H_ #define WEBKIT_GLUE_PLUGINS_PLUGIN_LIST_H_ +#include <map> #include <set> #include <string> #include <vector> @@ -12,8 +13,10 @@ #include "base/basictypes.h" #include "base/file_path.h" +#include "base/linked_ptr.h" #include "base/lock.h" #include "third_party/npapi/bindings/nphostapi.h" +#include "webkit/glue/plugins/plugin_group.h" #include "webkit/glue/plugins/webplugininfo.h" class GURL; @@ -60,6 +63,8 @@ struct PluginVersionInfo { PluginEntryPoints entry_points; }; +typedef void (*LoadPluginsFromDiskHookFunc)(); + // The PluginList is responsible for loading our NPAPI based plugins. It does // so in whatever manner is appropriate for the platform. On Windows, it loads // plugins from a known directory by looking for DLLs which start with "NP", @@ -73,6 +78,9 @@ class PluginList { // Gets the one instance of the PluginList. static PluginList* Singleton(); + // Set a hook that is called whenever we load plugins from the disk. + static void SetPluginLoadHook(LoadPluginsFromDiskHookFunc hook); + // Returns true if we're in debug-plugin-loading mode. This is controlled // by a command line switch. static bool DebugPluginLoading(); @@ -125,12 +133,24 @@ class PluginList { // Get all the enabled plugins. void GetEnabledPlugins(bool refresh, std::vector<WebPluginInfo>* plugins); - // Returns true if a plugin is found for the given url and mime type - // (including disabled plugins, for which |info->enabled| is false). - // The mime type which corresponds to the URL is optionally returned - // back. - // The allow_wildcard parameter controls whether this function returns - // plugins which support wildcard mime types (* as the mime type). + // Returns a list in |info| containing plugins that are found for + // the given url and mime type (including disabled plugins, for + // which |info->enabled| is false). The mime type which corresponds + // to the URL is optionally returned back in |actual_mime_types| (if + // it is non-NULL), one for each of the plugin info objects found. + // The |allow_wildcard| parameter controls whether this function + // returns plugins which support wildcard mime types (* as the mime + // type). The |info| parameter is required to be non-NULL. The + // list is in order of "most desirable" to "least desirable", + // meaning that the default plugin is at the end of the list. + void GetPluginInfoArray(const GURL& url, + const std::string& mime_type, + bool allow_wildcard, + std::vector<WebPluginInfo>* info, + std::vector<std::string>* actual_mime_types); + + // Returns the first item from the list returned in GetPluginInfo in |info|. + // Returns true if it found a match. |actual_mime_type| may be NULL. bool GetPluginInfo(const GURL& url, const std::string& mime_type, bool allow_wildcard, @@ -142,6 +162,14 @@ class PluginList { bool GetPluginInfoByPath(const FilePath& plugin_path, WebPluginInfo* info); + typedef std::map<std::string, linked_ptr<PluginGroup> > PluginMap; + + // Fill the map from identifier to plugin group for all plugin groups. If + // |load_if_necessary| is set, the plugins will be loaded if they haven't + // already been loaded, or if Refresh() has been called in the meantime; + // otherwise a possibly empty or stale list may be returned. + void GetPluginGroups(bool load_if_necessary, PluginMap* plugin_groups); + // Load a specific plugin with full path. void LoadPlugin(const FilePath& filename, std::vector<WebPluginInfo>* plugins); @@ -159,6 +187,21 @@ class PluginList { // will be disabled. bool DisablePlugin(const FilePath& filename); + // Enable/disable a plugin group, specified by group_name. Returns |true| iff + // a plugin currently in the plugin list was actually enabled/disabled as a + // result; regardless of return value, if a plugin is found in the future with + // the given name, it will be enabled/disabled. Note that plugins are enabled + // by default as far as |PluginList| is concerned. + bool EnableGroup(bool enable, const string16& name); + + // Disable all plugins groups that are known to be outdated, according to + // the information hardcoded in PluginGroup, to make sure that they can't + // be loaded on a web page and instead show a UI to update to the latest + // version. + void DisableOutdatedPluginGroups(); + + ~PluginList(); + private: // Constructors are private for singletons PluginList(); @@ -180,23 +223,15 @@ class PluginList { bool ShouldLoadPlugin(const WebPluginInfo& info, std::vector<WebPluginInfo>* plugins); - // Find a plugin by mime type; only searches enabled plugins. - // The allow_wildcard parameter controls whether this function returns - // plugins which support wildcard mime types (* as the mime type) - bool FindPlugin(const std::string &mime_type, - bool allow_wildcard, - WebPluginInfo* info); + // Return whether a plug-in group with the given name should be disabled, + // either because it already is on the list of disabled groups, or because it + // is blacklisted by a policy. In the latter case, add the plugin group to the + // list of disabled groups as well. + bool ShouldDisableGroup(const string16& group_name); - // Just like |FindPlugin| but it only looks at the disabled plug-ins. - bool FindDisabledPlugin(const std::string &mime_type, - bool allow_wildcard, - WebPluginInfo* info); - - // Find a plugin by extension; only searches enabled plugins. Returns the - // corresponding mime type. - bool FindPlugin(const GURL &url, - std::string* actual_mime_type, - WebPluginInfo* info); + // Like GetPluginGroups above, but works on a given vector of plugins. + static void GetPluginGroups(const std::vector<WebPluginInfo>* plugins, + PluginMap* plugin_groups); // Returns true if the given WebPluginInfo supports "mime-type". // mime_type should be all lower case. @@ -261,6 +296,11 @@ class PluginList { // Path names of plugins to disable (the default is to enable them all). std::set<FilePath> disabled_plugins_; + // Group names disable (the default is to enable them all). + std::set<string16> disabled_groups_; + + bool disable_outdated_plugins_; + // Need synchronization for the above members since this object can be // accessed on multiple threads. Lock lock_; diff --git a/webkit/glue/plugins/plugin_list_posix.cc b/webkit/glue/plugins/plugin_list_posix.cc index b23909b..72891d1 100644 --- a/webkit/glue/plugins/plugin_list_posix.cc +++ b/webkit/glue/plugins/plugin_list_posix.cc @@ -133,7 +133,7 @@ void PluginList::GetPluginDirectories(std::vector<FilePath>* plugin_dirs) { const char* moz_plugin_path = getenv("MOZ_PLUGIN_PATH"); if (moz_plugin_path) { std::vector<std::string> paths; - SplitString(moz_plugin_path, ':', &paths); + base::SplitString(moz_plugin_path, ':', &paths); for (size_t i = 0; i < paths.size(); ++i) plugin_dirs->push_back(FilePath(paths[i])); } diff --git a/webkit/glue/plugins/plugin_list_win.cc b/webkit/glue/plugins/plugin_list_win.cc index b5ded9e..4869262 100644 --- a/webkit/glue/plugins/plugin_list_win.cc +++ b/webkit/glue/plugins/plugin_list_win.cc @@ -12,11 +12,11 @@ #include "base/command_line.h" #include "base/file_util.h" #include "base/path_service.h" -#include "base/registry.h" #include "base/scoped_ptr.h" #include "base/string_number_conversions.h" #include "base/string_split.h" #include "base/string_util.h" +#include "base/win/registry.h" #include "webkit/glue/plugins/plugin_constants_win.h" #include "webkit/glue/plugins/plugin_lib.h" #include "webkit/glue/webkit_glue.h" @@ -67,7 +67,7 @@ bool GetInstalledPath(const TCHAR* app, FilePath* out) { reg_path.append(L"\\"); reg_path.append(app); - RegKey key(HKEY_LOCAL_MACHINE, reg_path.c_str(), KEY_READ); + base::win::RegKey key(HKEY_LOCAL_MACHINE, reg_path.c_str(), KEY_READ); std::wstring path; if (key.ReadValue(kRegistryPath, &path)) { *out = FilePath(path); @@ -82,13 +82,13 @@ void GetPluginsInRegistryDirectory( HKEY root_key, const std::wstring& registry_folder, std::set<FilePath>* plugin_dirs) { - for (RegistryKeyIterator iter(root_key, registry_folder.c_str()); + for (base::win::RegistryKeyIterator iter(root_key, registry_folder.c_str()); iter.Valid(); ++iter) { // Use the registry to gather plugin across the file system. std::wstring reg_path = registry_folder; reg_path.append(L"\\"); reg_path.append(iter.Name()); - RegKey key(root_key, reg_path.c_str(), KEY_READ); + base::win::RegKey key(root_key, reg_path.c_str(), KEY_READ); std::wstring path; if (key.ReadValue(kRegistryPath, &path)) @@ -99,11 +99,12 @@ void GetPluginsInRegistryDirectory( // Enumerate through the registry key to find all installed FireFox paths. // FireFox 3 beta and version 2 can coexist. See bug: 1025003 void GetFirefoxInstalledPaths(std::vector<FilePath>* out) { - RegistryKeyIterator it(HKEY_LOCAL_MACHINE, kRegistryFirefoxInstalled); + base::win::RegistryKeyIterator it(HKEY_LOCAL_MACHINE, + kRegistryFirefoxInstalled); for (; it.Valid(); ++it) { std::wstring full_path = std::wstring(kRegistryFirefoxInstalled) + L"\\" + it.Name() + L"\\Main"; - RegKey key(HKEY_LOCAL_MACHINE, full_path.c_str(), KEY_READ); + base::win::RegKey key(HKEY_LOCAL_MACHINE, full_path.c_str(), KEY_READ); std::wstring install_dir; if (!key.ReadValue(L"Install Directory", &install_dir)) continue; @@ -180,7 +181,8 @@ void GetWindowsMediaDirectory(std::set<FilePath>* plugin_dirs) { void GetJavaDirectory(std::set<FilePath>* plugin_dirs) { // Load the new NPAPI Java plugin // 1. Open the main JRE key under HKLM - RegKey java_key(HKEY_LOCAL_MACHINE, kRegistryJava, KEY_QUERY_VALUE); + base::win::RegKey java_key(HKEY_LOCAL_MACHINE, kRegistryJava, + KEY_QUERY_VALUE); // 2. Read the current Java version std::wstring java_version; @@ -304,13 +306,13 @@ bool HaveSharedMimeType(const WebPluginInfo& plugin1, // version is newer than a's, or false if it's equal or older. bool IsNewerVersion(const std::wstring& a, const std::wstring& b) { std::vector<std::wstring> a_ver, b_ver; - SplitString(a, ',', &a_ver); - SplitString(b, ',', &b_ver); + base::SplitString(a, ',', &a_ver); + base::SplitString(b, ',', &b_ver); if (a_ver.size() == 1 && b_ver.size() == 1) { a_ver.clear(); b_ver.clear(); - SplitString(a, '.', &a_ver); - SplitString(b, '.', &b_ver); + base::SplitString(a, '.', &a_ver); + base::SplitString(b, '.', &b_ver); } if (a_ver.size() != b_ver.size()) return false; @@ -371,7 +373,7 @@ bool PluginList::ShouldLoadPlugin(const WebPluginInfo& info, // and don't depend on XPCOM. if (filename == kJavaPlugin1 || filename == kJavaPlugin2) { std::vector<std::wstring> ver; - SplitString(info.version, '.', &ver); + base::SplitString(info.version, '.', &ver); int major, minor, update; if (ver.size() == 4 && base::StringToInt(ver[0], &major) && diff --git a/webkit/glue/plugins/plugin_web_event_converter_mac.h b/webkit/glue/plugins/plugin_web_event_converter_mac.h index 02f113a..ec5b86f 100644 --- a/webkit/glue/plugins/plugin_web_event_converter_mac.h +++ b/webkit/glue/plugins/plugin_web_event_converter_mac.h @@ -25,12 +25,6 @@ class PluginWebEventConverter { // could not be converted. virtual bool InitWithEvent(const WebKit::WebInputEvent& web_event); - // Sets a zoom level to apply to mouse coordinates. Must be called after - // InitWithEvent. - // TODO(stuartmorgan): Re-evaluate whether this is necessary when - // http://crbug.com/9996 is fixed. - virtual void SetZoomLevel(float zoom) = 0; - // Returns a pointer to a plugin event--suitable for passing to // NPP_HandleEvent--corresponding to the the web event this converter was // created with. The pointer is valid only as long as this object is. diff --git a/webkit/glue/plugins/plugin_web_event_converter_mac.mm b/webkit/glue/plugins/plugin_web_event_converter_mac.mm index d8b5c05..030ed06 100644 --- a/webkit/glue/plugins/plugin_web_event_converter_mac.mm +++ b/webkit/glue/plugins/plugin_web_event_converter_mac.mm @@ -49,8 +49,6 @@ class CarbonPluginWebEventConverter : public PluginWebEventConverter { virtual bool InitWithEvent(const WebInputEvent& web_event); - virtual void SetZoomLevel(float zooom); - virtual void* plugin_event() { return &carbon_event_; } protected: @@ -77,12 +75,6 @@ bool CarbonPluginWebEventConverter::InitWithEvent( return PluginWebEventConverter::InitWithEvent(web_event); } -void CarbonPluginWebEventConverter::SetZoomLevel(float zoom) { - // Nothing to do here; because the event is built using the WebMouseEvent's - // global coordinates, and the dummy window is in the right place, zoom has - // no effect. -} - bool CarbonPluginWebEventConverter::ConvertKeyboardEvent( const WebKeyboardEvent& key_event) { // TODO: Figure out how to handle Unicode input to plugins, if that's @@ -185,8 +177,6 @@ public: virtual bool InitWithEvent(const WebInputEvent& web_event); - virtual void SetZoomLevel(float zoom); - virtual void* plugin_event() { return &cocoa_event_; } protected: @@ -212,24 +202,6 @@ bool CocoaPluginWebEventConverter::InitWithEvent( return PluginWebEventConverter::InitWithEvent(web_event); } -void CocoaPluginWebEventConverter::SetZoomLevel(float zoom) { - // Make sure we are dealing with a mouse event. - if (!(cocoa_event_.type != NPCocoaEventMouseDown || - cocoa_event_.type != NPCocoaEventMouseUp || - cocoa_event_.type != NPCocoaEventMouseMoved || - cocoa_event_.type != NPCocoaEventMouseEntered || - cocoa_event_.type != NPCocoaEventMouseExited || - cocoa_event_.type != NPCocoaEventMouseDragged || - cocoa_event_.type != NPCocoaEventScrollWheel)) { - NOTREACHED(); - return; - } - cocoa_event_.data.mouse.pluginX = - round(cocoa_event_.data.mouse.pluginX * zoom); - cocoa_event_.data.mouse.pluginY = - round(cocoa_event_.data.mouse.pluginY * zoom); -} - bool CocoaPluginWebEventConverter::ConvertKeyboardEvent( const WebKeyboardEvent& key_event) { cocoa_event_.data.key.keyCode = key_event.nativeKeyCode; diff --git a/webkit/glue/plugins/ppb_private.h b/webkit/glue/plugins/ppb_private.h index 218f73a..07b32ec 100644 --- a/webkit/glue/plugins/ppb_private.h +++ b/webkit/glue/plugins/ppb_private.h @@ -5,13 +5,20 @@ #ifndef WEBKIT_GLUE_PLUGINS_PPB_PRIVATE_H_ #define WEBKIT_GLUE_PLUGINS_PPB_PRIVATE_H_ +#include "third_party/ppapi/c/dev/ppb_font_dev.h" +#include "third_party/ppapi/c/pp_instance.h" #include "third_party/ppapi/c/pp_module.h" +#include "third_party/ppapi/c/pp_resource.h" #include "third_party/ppapi/c/pp_var.h" #define PPB_PRIVATE_INTERFACE "PPB_Private;1" +// From the public PPB_Font_Dev file. +struct PP_FontDescription_Dev; + typedef enum { PP_RESOURCESTRING_PDFGETPASSWORD = 0, + PP_RESOURCESTRING_PDFLOADING = 1 } PP_ResourceString; typedef enum { @@ -41,17 +48,6 @@ typedef enum { } PP_ResourceImage; typedef enum { - PP_PRIVATEFONTPITCH_DEFAULT = 0, - PP_PRIVATEFONTPITCH_FIXED = 1 -} PP_PrivateFontPitch; - -typedef enum { - PP_PRIVATEFONTFAMILY_DEFAULT = 0, - PP_PRIVATEFONTFAMILY_ROMAN = 1, - PP_PRIVATEFONTFAMILY_SCRIPT = 2 -} PP_PrivateFontFamily; - -typedef enum { PP_PRIVATEFONTCHARSET_ANSI = 0, PP_PRIVATEFONTCHARSET_DEFAULT = 1, PP_PRIVATEFONTCHARSET_SYMBOL = 2, @@ -77,9 +73,11 @@ struct PP_PrivateFontFileDescription { const char* face; uint32_t weight; bool italic; - PP_PrivateFontPitch pitch; - PP_PrivateFontFamily family; - PP_PrivateFontCharset charset; +}; + +struct PP_PrivateFindResult { + int start_index; + int length; }; struct PPB_Private { @@ -91,10 +89,13 @@ struct PPB_Private { PP_ResourceImage image_id); // Returns a resource identifying a font file corresponding to the given font - // request after applying the browser-specific fallback. Linux only. + // request after applying the browser-specific fallback. + // + // Currently Linux-only. PP_Resource (*GetFontFileWithFallback)( PP_Module module, - const PP_PrivateFontFileDescription* description); + const PP_FontDescription_Dev* description, + PP_PrivateFontCharset charset); // Given a resource previously returned by GetFontFileWithFallback, returns // a pointer to the requested font table. Linux only. @@ -102,6 +103,29 @@ struct PPB_Private { uint32_t table, void* output, uint32_t* output_length); + + // Search the given string using ICU. Use PPB_Core's MemFree on results when + // done. + void (*SearchString)( + PP_Module module, + const unsigned short* string, + const unsigned short* term, + bool case_sensitive, + PP_PrivateFindResult** results, + int* count); + + // Since WebFrame doesn't know about Pepper requests, it'll think the page has + // finished loading even if there are outstanding requests by the plugin. + // Take this out once WebFrame knows about requests by pepper plugins. + void (*DidStartLoading)(PP_Instance instance); + void (*DidStopLoading)(PP_Instance instance); + + // Sets content restriction for a full-page plugin (i.e. can't copy/print). + // The value is a bitfield of ContentRestriction enums. + void (*SetContentRestriction)(PP_Instance instance, int restrictions); + + // Use UMA so we know average pdf page count. + void (*HistogramPDFPageCount)(int count); }; #endif // WEBKIT_GLUE_PLUGINS_PPB_PRIVATE_H_ diff --git a/webkit/glue/plugins/ppb_private2.h b/webkit/glue/plugins/ppb_private2.h index ca45471..0b0df98 100644 --- a/webkit/glue/plugins/ppb_private2.h +++ b/webkit/glue/plugins/ppb_private2.h @@ -5,17 +5,106 @@ #ifndef WEBKIT_GLUE_PLUGINS_PPB_PRIVATE2_H_ #define WEBKIT_GLUE_PLUGINS_PPB_PRIVATE2_H_ +#ifdef _WIN32 +#include <windows.h> +#endif + +#include "third_party/ppapi/c/pp_errors.h" #include "third_party/ppapi/c/pp_instance.h" #include "third_party/ppapi/c/pp_module.h" +#include "third_party/ppapi/c/pp_point.h" +#include "third_party/ppapi/c/pp_rect.h" +#include "third_party/ppapi/c/pp_resource.h" #include "third_party/ppapi/c/pp_var.h" -#define PPB_PRIVATE2_INTERFACE "PPB_Private2;1" +#define PPB_PRIVATE2_INTERFACE "PPB_Private2;3" + +#ifdef _WIN32 +typedef HANDLE PP_FileHandle; +static const PP_FileHandle PP_kInvalidFileHandle = NULL; +#else +typedef int PP_FileHandle; +static const PP_FileHandle PP_kInvalidFileHandle = -1; +#endif + +struct PP_FontDescription_Dev; +struct PP_FileInfo_Dev; + +struct PP_DirEntry_Dev { + const char* name; + bool is_dir; +}; + +struct PP_DirContents_Dev { + int32_t count; + PP_DirEntry_Dev* entries; +}; struct PPB_Private2 { // Sets or clears the rendering hint that the given plugin instance is always // on top of page content. Somewhat more optimized painting can be used in // this case. void (*SetInstanceAlwaysOnTop)(PP_Instance instance, bool on_top); + + bool (*DrawGlyphs)(PP_Resource pp_image_data, + const PP_FontDescription_Dev* font_desc, + uint32_t color, + PP_Point position, + PP_Rect clip, + float transformation[3][3], + uint32_t glyph_count, + uint16_t glyph_indices[], + PP_Point glyph_advances[]); + + // Retrieves the proxy that will be used for the given URL. The result will + // be a string in PAC format, or an undefined var on error. + PP_Var (*GetProxyForURL)(PP_Module module, const char* url); + + // Opens a module-local file, returning a file descriptor (posix) or a HANDLE + // (win32) into file. Module-local file paths (here and below) are + // '/'-separated UTF-8 strings, relative to a module-specific root. The return + // value is the ppapi error, PP_OK if success, one of the PP_ERROR_* in case + // of failure. + int32_t (*OpenModuleLocalFile)(PP_Module module, + const char* path, + int32_t mode, + PP_FileHandle* file); + + // Renames a module-local file. The return value is the ppapi error, PP_OK if + // success, one of the PP_ERROR_* in case of failure. + int32_t (*RenameModuleLocalFile)(PP_Module module, + const char* path_from, + const char* path_to); + + // Deletes a module-local file or directory. If recursive is set and the path + // points to a directory, deletes all the contents of the directory. The + // return value is the ppapi error, PP_OK if success, one of the PP_ERROR_* in + // case of failure. + int32_t (*DeleteModuleLocalFileOrDir)(PP_Module module, + const char* path, + bool recursive); + + // Creates a module-local directory. The return value is the ppapi error, + // PP_OK if success, one of the PP_ERROR_* in case of failure. + int32_t (*CreateModuleLocalDir)(PP_Module module, const char* path); + + // Queries information about a module-local file. The return value is the + // ppapi error, PP_OK if success, one of the PP_ERROR_* in case of failure. + int32_t (*QueryModuleLocalFile)(PP_Module module, + const char* path, + PP_FileInfo_Dev* info); + + // Gets the list of files contained in a module-local directory. The return + // value is the ppapi error, PP_OK if success, one of the PP_ERROR_* in case + // of failure. If non-NULL, the returned contents should be freed with + // FreeModuleLocalDirContents. + int32_t (*GetModuleLocalDirContents)(PP_Module module, + const char* path, + PP_DirContents_Dev** contents); + + // Frees the data allocated by GetModuleLocalDirContents. + void (*FreeModuleLocalDirContents)(PP_Module module, + PP_DirContents_Dev* contents); }; #endif // WEBKIT_GLUE_PLUGINS_PPB_PRIVATE2_H_ diff --git a/webkit/glue/plugins/ppp_private.h b/webkit/glue/plugins/ppp_private.h new file mode 100644 index 0000000..4bc3812 --- /dev/null +++ b/webkit/glue/plugins/ppp_private.h @@ -0,0 +1,20 @@ +// Copyright (c) 2010 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_GLUE_PLUGINS_PPP_PRIVATE_H_ +#define WEBKIT_GLUE_PLUGINS_PPP_PRIVATE_H_ + +#include "third_party/ppapi/c/pp_instance.h" +#include "third_party/ppapi/c/pp_point.h" +#include "third_party/ppapi/c/pp_var.h" + +#define PPP_PRIVATE_INTERFACE "PPP_Private;1" + +struct PPP_Private { + // Returns an absolute URL if the position is over a link. + PP_Var (*GetLinkAtPosition)(PP_Instance instance, + PP_Point point); +}; + +#endif // WEBKIT_GLUE_PLUGINS_PPP_PRIVATE_H_ diff --git a/webkit/glue/plugins/webplugin.h b/webkit/glue/plugins/webplugin.h index 19c6cb0..36426fa 100644 --- a/webkit/glue/plugins/webplugin.h +++ b/webkit/glue/plugins/webplugin.h @@ -29,6 +29,9 @@ namespace webkit_glue { class WebPluginDelegate; class WebPluginParentView; class WebPluginResourceClient; +#if defined(OS_MACOSX) +class WebPluginAcceleratedSurface; +#endif // Describes the new location for a plugin window. struct WebPluginGeometry { @@ -146,24 +149,19 @@ class WebPlugin { bool defer) = 0; #if defined(OS_MACOSX) + // Enables/disables plugin IME. + virtual void SetImeEnabled(bool enabled) {}; + // Synthesize a fake window handle for the plug-in to identify the instance // to the browser, allowing mapping to a surface for hardware accelleration // of plug-in content. The browser generates the handle which is then set on // the plug-in. |opaque| indicates whether the content should be treated as // opaque or translucent. + // TODO(stuartmorgan): Move this into WebPluginProxy. virtual void BindFakePluginWindowHandle(bool opaque) {} - // Tell the browser (via the renderer) to invalidate because the - // accelerated buffers have changed. - virtual void AcceleratedFrameBuffersDidSwap(gfx::PluginWindowHandle window) {} - - // Tell the renderer and browser to associate the given plugin handle with - // |accelerated_surface_identifier|. The geometry is used to resize any - // native "window" (which on the Mac is a CALayer). - virtual void SetAcceleratedSurface(gfx::PluginWindowHandle window, - int32 width, - int32 height, - uint64 accelerated_surface_identifier) {} + // Returns the accelerated surface abstraction for accelerated plugins. + virtual WebPluginAcceleratedSurface* GetAcceleratedSurface() { return NULL; } #endif // Gets the WebPluginDelegate that implements the interface. diff --git a/webkit/glue/plugins/webplugin_accelerated_surface_mac.h b/webkit/glue/plugins/webplugin_accelerated_surface_mac.h new file mode 100644 index 0000000..ba3f8ca --- /dev/null +++ b/webkit/glue/plugins/webplugin_accelerated_surface_mac.h @@ -0,0 +1,43 @@ +// Copyright (c) 2006-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_GLUE_WEBPLUGIN_ACCELERATED_SURFACE_MAC_H_ +#define WEBKIT_GLUE_WEBPLUGIN_ACCELERATED_SURFACE_MAC_H_ +#pragma once + +#include "gfx/native_widget_types.h" +#include "gfx/size.h" + +// Avoid having to include OpenGL headers here. +typedef struct _CGLContextObject* CGLContextObj; + +namespace webkit_glue { + +// Interface class for interacting with an accelerated plugin surface, used +// for the Core Animation flavors of plugin drawing on the Mac. +class WebPluginAcceleratedSurface { + public: + virtual ~WebPluginAcceleratedSurface() {} + + // Sets the window handle used throughout the browser to identify this + // surface. + virtual void SetWindowHandle(gfx::PluginWindowHandle window) = 0; + + // Sets the size of the surface. + virtual void SetSize(const gfx::Size& size) = 0; + + // Returns the context used to draw into this surface. + virtual CGLContextObj context() = 0; + + // Readies the surface for drawing. Must be called before any drawing session. + virtual void StartDrawing() = 0; + + // Ends a drawing session. Changes to the surface may not be reflected until + // this is called. + virtual void EndDrawing() = 0; +}; + +} // namespace webkit_glue + +#endif // WEBKIT_GLUE_WEBPLUGIN_ACCELERATED_SURFACE_MAC_H_ diff --git a/webkit/glue/plugins/webplugin_delegate_impl.cc b/webkit/glue/plugins/webplugin_delegate_impl.cc index 5374546..c54bbc8 100644 --- a/webkit/glue/plugins/webplugin_delegate_impl.cc +++ b/webkit/glue/plugins/webplugin_delegate_impl.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 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. @@ -11,7 +11,6 @@ #include "base/message_loop.h" #include "base/process_util.h" #include "base/scoped_ptr.h" -#include "base/stats_counters.h" #include "base/string_util.h" #include "third_party/WebKit/WebKit/chromium/public/WebInputEvent.h" #include "webkit/glue/plugins/plugin_constants_win.h" diff --git a/webkit/glue/plugins/webplugin_delegate_impl.h b/webkit/glue/plugins/webplugin_delegate_impl.h index 650d398..30a4a58 100644 --- a/webkit/glue/plugins/webplugin_delegate_impl.h +++ b/webkit/glue/plugins/webplugin_delegate_impl.h @@ -11,6 +11,7 @@ #include <list> #include "base/ref_counted.h" +#include "base/scoped_ptr.h" #include "base/task.h" #include "base/time.h" #include "base/timer.h" @@ -20,10 +21,6 @@ #include "webkit/glue/plugins/webplugin_delegate.h" #include "webkit/glue/webcursor.h" -#if defined(OS_MACOSX) -#include "app/surface/accelerated_surface_mac.h" -#endif - #if defined(USE_X11) #include "app/x11_util.h" @@ -52,6 +49,9 @@ class QuickDrawDrawingManager; class CALayer; class CARenderer; #endif +namespace webkit_glue { +class WebPluginAcceleratedSurface; +} #endif // An implementation of WebPluginDelegate that runs in the plugin process, @@ -161,6 +161,8 @@ class WebPluginDelegateImpl : public webkit_glue::WebPluginDelegate { // Frames are in screen coordinates. void WindowFrameChanged(const gfx::Rect& window_frame, const gfx::Rect& view_frame); + // Informs the plugin that IME composition has been confirmed. + void ImeCompositionConfirmed(const string16& text); // Informs the delegate that the plugin set a Carbon ThemeCursor. void SetThemeCursor(ThemeCursor cursor); // Informs the delegate that the plugin set a Carbon Cursor. @@ -385,20 +387,15 @@ class WebPluginDelegateImpl : public webkit_glue::WebPluginDelegate { void SetContentAreaOrigin(const gfx::Point& origin); // Updates everything that depends on the plugin's absolute screen location. void PluginScreenLocationChanged(); + // Updates anything that depends on plugin visibility. + void PluginVisibilityChanged(); - // Returns the apparent zoom ratio for the given event, as inferred from our - // current knowledge about about where on screen the plugin is. - // This is a temporary workaround for <http://crbug.com/9996>; once that is - // fixed we should have correct event coordinates (or an explicit - // notification of zoom level). - float ApparentEventZoomLevel(const WebKit::WebMouseEvent& event); + // Enables/disables IME. + void SetImeEnabled(bool enabled); // Informs the browser about the updated accelerated drawing surface. void UpdateAcceleratedSurface(); - // Updates anything that depends on plugin visibility. - void PluginVisibilityChanged(); - // Uses a CARenderer to draw the plug-in's layer in our OpenGL surface. void DrawLayerInSurface(); @@ -432,7 +429,7 @@ class WebPluginDelegateImpl : public webkit_glue::WebPluginDelegate { #endif CALayer* layer_; // Used for CA drawing mode. Weak, retained by plug-in. - AcceleratedSurface* surface_; + webkit_glue::WebPluginAcceleratedSurface* surface_; // Weak ref. CARenderer* renderer_; // Renders layer_ to surface_. scoped_ptr<base::RepeatingTimer<WebPluginDelegateImpl> > redraw_timer_; @@ -447,6 +444,8 @@ class WebPluginDelegateImpl : public webkit_glue::WebPluginDelegate { gfx::Rect cached_clip_rect_; + bool ime_enabled_; + scoped_ptr<ExternalDragTracker> external_drag_tracker_; #endif // OS_MACOSX diff --git a/webkit/glue/plugins/webplugin_delegate_impl_gtk.cc b/webkit/glue/plugins/webplugin_delegate_impl_gtk.cc index 3d112fa..bceda0e 100644 --- a/webkit/glue/plugins/webplugin_delegate_impl_gtk.cc +++ b/webkit/glue/plugins/webplugin_delegate_impl_gtk.cc @@ -14,7 +14,7 @@ #include "base/file_util.h" #include "base/message_loop.h" #include "base/process_util.h" -#include "base/stats_counters.h" +#include "base/metrics/stats_counters.h" #include "base/string_util.h" #include "gfx/blit.h" #include "skia/ext/platform_canvas.h" @@ -443,8 +443,8 @@ void WebPluginDelegateImpl::WindowlessPaint(cairo_t* context, } // Tell the plugin to paint into the pixmap. - static StatsRate plugin_paint("Plugin.Paint"); - StatsScope<StatsRate> scope(plugin_paint); + static base::StatsRate plugin_paint("Plugin.Paint"); + base::StatsScope<base::StatsRate> scope(plugin_paint); NPError err = instance()->NPP_HandleEvent(&np_event); DCHECK_EQ(err, NPERR_NO_ERROR); @@ -474,8 +474,8 @@ void WebPluginDelegateImpl::WindowlessPaint(cairo_t* context, event.drawable = GDK_PIXMAP_XID(pixmap_); // Tell the plugin to paint into the pixmap. - static StatsRate plugin_paint("Plugin.Paint"); - StatsScope<StatsRate> scope(plugin_paint); + static base::StatsRate plugin_paint("Plugin.Paint"); + base::StatsScope<base::StatsRate> scope(plugin_paint); NPError err = instance()->NPP_HandleEvent(&np_event); DCHECK_EQ(err, NPERR_NO_ERROR); diff --git a/webkit/glue/plugins/webplugin_delegate_impl_mac.mm b/webkit/glue/plugins/webplugin_delegate_impl_mac.mm index 614f1d2..cca8695 100644 --- a/webkit/glue/plugins/webplugin_delegate_impl_mac.mm +++ b/webkit/glue/plugins/webplugin_delegate_impl_mac.mm @@ -13,10 +13,11 @@ #include "base/file_util.h" #include "base/message_loop.h" +#include "base/metrics/stats_counters.h" #include "base/scoped_ptr.h" -#include "base/stats_counters.h" #include "base/string_util.h" #include "base/utf_string_conversions.h" +#include "base/sys_string_conversions.h" #include "third_party/WebKit/WebKit/chromium/public/WebInputEvent.h" #include "webkit/glue/plugins/plugin_instance.h" #include "webkit/glue/plugins/plugin_lib.h" @@ -24,6 +25,7 @@ #include "webkit/glue/plugins/plugin_stream_url.h" #include "webkit/glue/plugins/plugin_web_event_converter_mac.h" #include "webkit/glue/plugins/webplugin.h" +#include "webkit/glue/plugins/webplugin_accelerated_surface_mac.h" #include "webkit/glue/webkit_glue.h" #ifndef NP_NO_CARBON @@ -262,6 +264,7 @@ WebPluginDelegateImpl::WebPluginDelegateImpl( initial_window_focus_(false), container_is_visible_(false), have_called_set_window_(false), + ime_enabled_(false), external_drag_tracker_(new ExternalDragTracker()), handle_event_depth_(0), first_set_window_call_(true), @@ -359,9 +362,9 @@ bool WebPluginDelegateImpl::PlatformInitialize() { if (instance()->event_model() != NPEventModelCocoa) return false; window_.type = NPWindowTypeDrawable; - // Ask the plug-in for the CALayer it created for rendering content. Have - // the renderer tell the browser to create a "windowed plugin" to host - // the IOSurface. + // Ask the plug-in for the CALayer it created for rendering content. + // Create a surface to host it, and request a "window" handle to identify + // the surface. CALayer* layer = nil; NPError err = instance()->NPP_GetValue(NPPVpluginCoreAnimationLayer, reinterpret_cast<void*>(&layer)); @@ -371,8 +374,8 @@ bool WebPluginDelegateImpl::PlatformInitialize() { redraw_timer_.reset(new base::RepeatingTimer<WebPluginDelegateImpl>); } layer_ = layer; - surface_ = new AcceleratedSurface; - surface_->Initialize(NULL, true); + surface_ = plugin_->GetAcceleratedSurface(); + renderer_ = [[CARenderer rendererWithCGLContext:surface_->context() options:NULL] retain]; [renderer_ setLayer:layer_]; @@ -421,11 +424,6 @@ void WebPluginDelegateImpl::PlatformDestroyInstance() { [renderer_ release]; renderer_ = nil; layer_ = nil; - if (surface_) { - surface_->Destroy(); - delete surface_; - surface_ = NULL; - } } void WebPluginDelegateImpl::UpdateGeometryAndContext( @@ -577,7 +575,13 @@ bool WebPluginDelegateImpl::PlatformHandleInputEvent( event_scope.reset(new NPAPI::ScopedCurrentPluginEvent( instance(), static_cast<NPCocoaEvent*>(plugin_event))); } - bool handled = instance()->NPP_HandleEvent(plugin_event) != 0; + int16_t handle_response = instance()->NPP_HandleEvent(plugin_event); + bool handled = handle_response != kNPEventNotHandled; + + if (handled && event.type == WebInputEvent::KeyDown) { + // Update IME state as requested by the plugin. + SetImeEnabled(handle_response == kNPEventStartIME); + } // Plugins don't give accurate information about whether or not they handled // events, so browsers on the Mac ignore the return value. @@ -654,8 +658,8 @@ void WebPluginDelegateImpl::WindowlessPaint(gfx::NativeDrawingContext context, return; DCHECK(buffer_context_ == context); - static StatsRate plugin_paint("Plugin.Paint"); - StatsScope<StatsRate> scope(plugin_paint); + static base::StatsRate plugin_paint("Plugin.Paint"); + base::StatsScope<base::StatsRate> scope(plugin_paint); // Plugin invalidates trigger asynchronous paints with the original // invalidation rect; the plugin may be resized before the paint is handled, @@ -782,6 +786,9 @@ void WebPluginDelegateImpl::SetWindowHasFocus(bool has_focus) { return; containing_window_has_focus_ = has_focus; + if (!has_focus) + SetImeEnabled(false); + #ifndef NP_NO_QUICKDRAW // Make sure controls repaint with the correct look. if (quirks_ & PLUGIN_QUIRK_ALLOW_FASTER_QUICKDRAW_PATH) @@ -818,6 +825,9 @@ bool WebPluginDelegateImpl::PlatformSetPluginHasFocus(bool focused) { if (!have_called_set_window_) return false; + if (!focused) + SetImeEnabled(false); + ScopedActiveDelegate active_delegate(this); switch (instance()->event_model()) { @@ -882,6 +892,20 @@ void WebPluginDelegateImpl::WindowFrameChanged(const gfx::Rect& window_frame, SetContentAreaOrigin(gfx::Point(view_frame.x(), view_frame.y())); } +void WebPluginDelegateImpl::ImeCompositionConfirmed(const string16& text) { + if (instance()->event_model() != NPEventModelCocoa) { + DLOG(ERROR) << "IME text receieved in Carbon event model"; + return; + } + + NPCocoaEvent text_event; + memset(&text_event, 0, sizeof(NPCocoaEvent)); + text_event.type = NPCocoaEventTextInput; + text_event.data.text.text = + reinterpret_cast<NPNSString*>(base::SysUTF16ToNSString(text)); + instance()->NPP_HandleEvent(&text_event); +} + void WebPluginDelegateImpl::SetThemeCursor(ThemeCursor cursor) { current_windowless_cursor_.InitFromThemeCursor(cursor); } @@ -940,6 +964,15 @@ void WebPluginDelegateImpl::PluginVisibilityChanged() { } } +void WebPluginDelegateImpl::SetImeEnabled(bool enabled) { + if (instance()->event_model() != NPEventModelCocoa) + return; + if (enabled == ime_enabled_) + return; + ime_enabled_ = enabled; + plugin_->SetImeEnabled(enabled); +} + #pragma mark - #pragma mark Core Animation Support @@ -948,9 +981,7 @@ void WebPluginDelegateImpl::DrawLayerInSurface() { if (!windowed_handle()) return; - surface_->MakeCurrent(); - - surface_->Clear(window_rect_); + surface_->StartDrawing(); [renderer_ beginFrameAtTime:CACurrentMediaTime() timeStamp:NULL]; if (CGRectIsEmpty([renderer_ updateBounds])) { @@ -963,34 +994,30 @@ void WebPluginDelegateImpl::DrawLayerInSurface() { [renderer_ render]; [renderer_ endFrame]; - surface_->SwapBuffers(); - plugin_->AcceleratedFrameBuffersDidSwap(windowed_handle()); + surface_->EndDrawing(); } -// Update the size of the IOSurface to match the current size of the plug-in, -// then tell the browser host view so it can adjust its bookkeeping and CALayer -// appropriately. +// Update the size of the surface to match the current size of the plug-in. void WebPluginDelegateImpl::UpdateAcceleratedSurface() { // Will only have a window handle when using a Core Animation drawing model. if (!windowed_handle() || !layer_) return; + [CATransaction begin]; + [CATransaction setValue:[NSNumber numberWithInt:0] + forKey:kCATransactionAnimationDuration]; [layer_ setFrame:CGRectMake(0, 0, window_rect_.width(), window_rect_.height())]; - [renderer_ setBounds:[layer_ bounds]]; + [CATransaction commit]; - uint64 io_surface_id = surface_->SetSurfaceSize(window_rect_.size()); - if (io_surface_id) { - plugin_->SetAcceleratedSurface(windowed_handle(), - window_rect_.width(), - window_rect_.height(), - io_surface_id); - } + [renderer_ setBounds:[layer_ bounds]]; + surface_->SetSize(window_rect_.size()); } void WebPluginDelegateImpl::set_windowed_handle( gfx::PluginWindowHandle handle) { windowed_handle_ = handle; + surface_->SetWindowHandle(handle); UpdateAcceleratedSurface(); // Kick off the drawing timer, if necessary. PluginVisibilityChanged(); diff --git a/webkit/glue/plugins/webplugin_delegate_impl_win.cc b/webkit/glue/plugins/webplugin_delegate_impl_win.cc index 9cdc7db..da7a68f 100644 --- a/webkit/glue/plugins/webplugin_delegate_impl_win.cc +++ b/webkit/glue/plugins/webplugin_delegate_impl_win.cc @@ -8,18 +8,18 @@ #include <string> #include <vector> +#include "app/win/iat_patch_function.h" #include "base/file_util.h" -#include "base/iat_patch.h" #include "base/lazy_instance.h" #include "base/message_loop.h" -#include "base/registry.h" +#include "base/metrics/stats_counters.h" #include "base/scoped_ptr.h" -#include "base/stats_counters.h" #include "base/string_number_conversions.h" #include "base/string_split.h" #include "base/string_util.h" #include "base/stringprintf.h" -#include "base/win_util.h" +#include "base/win/registry.h" +#include "base/win/windows_version.h" #include "skia/ext/platform_canvas.h" #include "third_party/WebKit/WebKit/chromium/public/WebInputEvent.h" #include "webkit/glue/plugins/default_plugin_shared.h" @@ -70,15 +70,15 @@ base::LazyInstance<std::map<HWND, WNDPROC> > g_window_handle_proc_map( // Helper object for patching the TrackPopupMenu API. -base::LazyInstance<iat_patch::IATPatchFunction> g_iat_patch_track_popup_menu( +base::LazyInstance<app::win::IATPatchFunction> g_iat_patch_track_popup_menu( base::LINKER_INITIALIZED); // Helper object for patching the SetCursor API. -base::LazyInstance<iat_patch::IATPatchFunction> g_iat_patch_set_cursor( +base::LazyInstance<app::win::IATPatchFunction> g_iat_patch_set_cursor( base::LINKER_INITIALIZED); // Helper object for patching the RegEnumKeyExW API. -base::LazyInstance<iat_patch::IATPatchFunction> g_iat_patch_reg_enum_key_ex_w( +base::LazyInstance<app::win::IATPatchFunction> g_iat_patch_reg_enum_key_ex_w( base::LINKER_INITIALIZED); // http://crbug.com/16114 @@ -289,7 +289,7 @@ WebPluginDelegateImpl::WebPluginDelegateImpl( } else if (filename == kAcrobatReaderPlugin) { // Check for the version number above or equal 9. std::vector<std::wstring> version; - SplitString(plugin_info.version, L'.', &version); + base::SplitString(plugin_info.version, L'.', &version); if (version.size() > 0) { int major; base::StringToInt(version[0], &major); @@ -415,8 +415,8 @@ bool WebPluginDelegateImpl::PlatformInitialize() { // name of the current process. We do it in the installer for admin users, // for the rest patch this function. if ((quirks_ & PLUGIN_QUIRK_PATCH_REGENUMKEYEXW) && - win_util::GetWinVersion() == win_util::WINVERSION_XP && - !RegKey().Open(HKEY_LOCAL_MACHINE, + base::win::GetVersion() == base::win::VERSION_XP && + !base::win::RegKey().Open(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\MediaPlayer\\ShimInclusionList\\chrome.exe", KEY_READ) && !g_iat_patch_reg_enum_key_ex_w.Pointer()->is_patched()) { @@ -1020,6 +1020,8 @@ void WebPluginDelegateImpl::WindowlessPaint(HDC hdc, damage_rect_win.right = damage_rect_win.left + damage_rect.width(); damage_rect_win.bottom = damage_rect_win.top + damage_rect.height(); + // Save away the old HDC as this could be a nested invocation. + void* old_dc = window_.window; window_.window = hdc; NPEvent paint_event; @@ -1027,9 +1029,10 @@ void WebPluginDelegateImpl::WindowlessPaint(HDC hdc, // NOTE: NPAPI is not 64bit safe. It puts pointers into 32bit values. paint_event.wParam = PtrToUlong(hdc); paint_event.lParam = PtrToUlong(&damage_rect_win); - static StatsRate plugin_paint("Plugin.Paint"); - StatsScope<StatsRate> scope(plugin_paint); + static base::StatsRate plugin_paint("Plugin.Paint"); + base::StatsScope<base::StatsRate> scope(plugin_paint); instance()->NPP_HandleEvent(&paint_event); + window_.window = old_dc; } void WebPluginDelegateImpl::WindowlessSetWindow() { diff --git a/webkit/glue/plugins/webplugin_impl.cc b/webkit/glue/plugins/webplugin_impl.cc index 80bc197..704145b 100644 --- a/webkit/glue/plugins/webplugin_impl.cc +++ b/webkit/glue/plugins/webplugin_impl.cc @@ -4,6 +4,7 @@ #include "webkit/glue/plugins/webplugin_impl.h" +#include "base/linked_ptr.h" #include "base/logging.h" #include "base/message_loop.h" #include "base/string_util.h" @@ -207,6 +208,14 @@ void GetResponseInfo(const WebURLResponse& response, // WebKit::WebPlugin ---------------------------------------------------------- +struct WebPluginImpl::ClientInfo { + unsigned long id; + WebPluginResourceClient* client; + WebKit::WebURLRequest request; + bool pending_failure_notification; + linked_ptr<WebKit::WebURLLoader> loader; +}; + bool WebPluginImpl::initialize(WebPluginContainer* container) { if (!page_delegate_) return false; diff --git a/webkit/glue/plugins/webplugin_impl.h b/webkit/glue/plugins/webplugin_impl.h index 5fe96d2..cb0970b 100644 --- a/webkit/glue/plugins/webplugin_impl.h +++ b/webkit/glue/plugins/webplugin_impl.h @@ -11,7 +11,6 @@ #include "base/basictypes.h" #include "base/file_path.h" -#include "base/linked_ptr.h" #include "base/task.h" #include "base/weak_ptr.h" #include "gfx/native_widget_types.h" @@ -256,13 +255,7 @@ class WebPluginImpl : public WebPlugin, // Delayed task for downloading the plugin source URL. void OnDownloadPluginSrcUrl(); - struct ClientInfo { - unsigned long id; - WebPluginResourceClient* client; - WebKit::WebURLRequest request; - bool pending_failure_notification; - linked_ptr<WebKit::WebURLLoader> loader; - }; + struct ClientInfo; // Helper functions WebPluginResourceClient* GetClientFromLoader(WebKit::WebURLLoader* loader); diff --git a/webkit/glue/plugins/webplugininfo.cc b/webkit/glue/plugins/webplugininfo.cc new file mode 100644 index 0000000..7d2b4e4 --- /dev/null +++ b/webkit/glue/plugins/webplugininfo.cc @@ -0,0 +1,44 @@ +// Copyright (c) 2010 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/webplugininfo.h" + +WebPluginMimeType::WebPluginMimeType() {} + +WebPluginMimeType::~WebPluginMimeType() {} + +WebPluginInfo::WebPluginInfo() : enabled(false) {} + +WebPluginInfo::WebPluginInfo(const WebPluginInfo& rhs) + : name(rhs.name), + path(rhs.path), + version(rhs.version), + desc(rhs.desc), + mime_types(rhs.mime_types), + enabled(rhs.enabled) { +} + +WebPluginInfo::~WebPluginInfo() {} + +WebPluginInfo& WebPluginInfo::operator=(const WebPluginInfo& rhs) { + name = rhs.name; + path = rhs.path; + version = rhs.version; + desc = rhs.desc; + mime_types = rhs.mime_types; + enabled = rhs.enabled; + return *this; +} + +WebPluginInfo::WebPluginInfo(const string16& fake_name, + const string16& fake_version, + const string16& fake_desc) + : name(fake_name), + path(), + version(fake_version), + desc(fake_desc), + mime_types(), + enabled(true) { +} + diff --git a/webkit/glue/plugins/webplugininfo.h b/webkit/glue/plugins/webplugininfo.h index 9d2ab6e..34eff3d 100644 --- a/webkit/glue/plugins/webplugininfo.h +++ b/webkit/glue/plugins/webplugininfo.h @@ -13,6 +13,9 @@ // Describes a mime type entry for a plugin. struct WebPluginMimeType { + WebPluginMimeType(); + ~WebPluginMimeType(); + // The name of the mime type (e.g., "application/x-shockwave-flash"). std::string mime_type; @@ -25,6 +28,16 @@ struct WebPluginMimeType { // Describes an available NPAPI plugin. struct WebPluginInfo { + WebPluginInfo(); + WebPluginInfo(const WebPluginInfo& rhs); + ~WebPluginInfo(); + WebPluginInfo& operator=(const WebPluginInfo& rhs); + + // Special constructor only used during unit testing: + WebPluginInfo(const string16& fake_name, + const string16& fake_version, + const string16& fake_desc); + // The name of the plugin (i.e. Flash). string16 name; diff --git a/webkit/glue/plugins/webview_plugin.cc b/webkit/glue/plugins/webview_plugin.cc index 231bd37..feb5720 100644 --- a/webkit/glue/plugins/webview_plugin.cc +++ b/webkit/glue/plugins/webview_plugin.cc @@ -4,17 +4,17 @@ #include "webkit/glue/plugins/webview_plugin.h" -#include "base/histogram.h" #include "base/message_loop.h" +#include "base/metrics/histogram.h" #include "third_party/WebKit/WebKit/chromium/public/WebCursorInfo.h" #include "third_party/WebKit/WebKit/chromium/public/WebFrame.h" #include "third_party/WebKit/WebKit/chromium/public/WebPluginContainer.h" -#include "third_party/WebKit/WebKit/chromium/public/WebSettings.h" #include "third_party/WebKit/WebKit/chromium/public/WebSize.h" #include "third_party/WebKit/WebKit/chromium/public/WebURL.h" #include "third_party/WebKit/WebKit/chromium/public/WebURLRequest.h" #include "third_party/WebKit/WebKit/chromium/public/WebURLResponse.h" #include "third_party/WebKit/WebKit/chromium/public/WebView.h" +#include "webkit/glue/webpreferences.h" #if WEBKIT_USING_CG #include <CoreGraphics/CGContext.h> @@ -48,6 +48,18 @@ WebViewPlugin::WebViewPlugin(WebViewPlugin::Delegate* delegate) web_view_->initializeMainFrame(this); } +// static +WebViewPlugin* WebViewPlugin::Create(WebViewPlugin::Delegate* delegate, + const WebPreferences& preferences, + const std::string& html_data, + const GURL& url) { + WebViewPlugin* plugin = new WebViewPlugin(delegate); + WebView* web_view = plugin->web_view(); + preferences.Apply(web_view); + web_view->mainFrame()->loadHTMLString(html_data, url); + return plugin; +} + WebViewPlugin::~WebViewPlugin() { web_view_->close(); } @@ -78,8 +90,10 @@ bool WebViewPlugin::initialize(WebPluginContainer* container) { } void WebViewPlugin::destroy() { - delegate_->WillDestroyPlugin(); - delegate_ = NULL; + if (delegate_) { + delegate_->WillDestroyPlugin(); + delegate_ = NULL; + } container_ = NULL; MessageLoop::current()->DeleteSoon(FROM_HERE, this); } diff --git a/webkit/glue/plugins/webview_plugin.h b/webkit/glue/plugins/webview_plugin.h index 757a012..9695aa2 100644 --- a/webkit/glue/plugins/webview_plugin.h +++ b/webkit/glue/plugins/webview_plugin.h @@ -15,6 +15,8 @@ #include "third_party/WebKit/WebKit/chromium/public/WebURLResponse.h" #include "third_party/WebKit/WebKit/chromium/public/WebViewClient.h" +struct WebPreferences; + // This class implements the WebPlugin interface by forwarding drawing and // handling input events to a WebView. // It can be used as a placeholder for an actual plugin, using HTML for the UI. @@ -39,6 +41,14 @@ class WebViewPlugin: public WebKit::WebPlugin, public WebKit::WebViewClient, explicit WebViewPlugin(Delegate* delegate); + // Convenience method to set up a new WebViewPlugin using |preferences| + // and displaying |html_data|. |url| should be a (fake) chrome:// URL; it is + // only used for navigation and never actually resolved. + static WebViewPlugin* Create(Delegate* delegate, + const WebPreferences& preferences, + const std::string& html_data, + const GURL& url); + WebKit::WebView* web_view() { return web_view_; } WebKit::WebPluginContainer* container() { return container_; } diff --git a/webkit/glue/resource_fetcher_unittest.cc b/webkit/glue/resource_fetcher_unittest.cc index 70c316b..3ac004e 100644 --- a/webkit/glue/resource_fetcher_unittest.cc +++ b/webkit/glue/resource_fetcher_unittest.cc @@ -149,7 +149,8 @@ class FetcherDelegate { FetcherDelegate* FetcherDelegate::instance_ = NULL; // Test a fetch from the test server. -TEST_F(ResourceFetcherTests, ResourceFetcherDownload) { +// Flaky, http://crbug.com/51622. +TEST_F(ResourceFetcherTests, FLAKY_ResourceFetcherDownload) { ASSERT_TRUE(test_server_.Start()); WebFrame* frame = test_shell_->webView()->mainFrame(); @@ -178,7 +179,8 @@ TEST_F(ResourceFetcherTests, ResourceFetcherDownload) { EXPECT_TRUE(delegate->data().find("Not Found.") != std::string::npos); } -TEST_F(ResourceFetcherTests, ResourceFetcherDidFail) { +// Flaky, http://crbug.com/51622. +TEST_F(ResourceFetcherTests, FLAKY_ResourceFetcherDidFail) { ASSERT_TRUE(test_server_.Start()); WebFrame* frame = test_shell_->webView()->mainFrame(); diff --git a/webkit/glue/resource_loader_bridge.cc b/webkit/glue/resource_loader_bridge.cc index ab19082..fe4db75 100644 --- a/webkit/glue/resource_loader_bridge.cc +++ b/webkit/glue/resource_loader_bridge.cc @@ -9,6 +9,42 @@ namespace webkit_glue { +ResourceLoadTimingInfo::ResourceLoadTimingInfo() + : proxy_start(-1), + proxy_end(-1), + dns_start(-1), + dns_end(-1), + connect_start(-1), + connect_end(-1), + ssl_start(-1), + ssl_end(-1), + send_start(0), + send_end(0), + receive_headers_start(0), + receive_headers_end(0) { +} + +ResourceLoadTimingInfo::~ResourceLoadTimingInfo() { +} + +ResourceDevToolsInfo::ResourceDevToolsInfo() {} + +ResourceDevToolsInfo::~ResourceDevToolsInfo() {} + +ResourceResponseInfo::ResourceResponseInfo() + : content_length(-1), + appcache_id(appcache::kNoCacheId), + connection_id(0), + connection_reused(false), + was_fetched_via_spdy(false), + was_npn_negotiated(false), + was_alternate_protocol_available(false), + was_fetched_via_proxy(false) { +} + +ResourceResponseInfo::~ResourceResponseInfo() { +} + ResourceLoaderBridge::RequestInfo::RequestInfo() : load_flags(0), requestor_pid(0), @@ -22,38 +58,6 @@ ResourceLoaderBridge::RequestInfo::RequestInfo() ResourceLoaderBridge::RequestInfo::~RequestInfo() { } -ResourceLoaderBridge::LoadTimingInfo::LoadTimingInfo() { - proxy_start = -1; - proxy_end = -1; - dns_start = -1; - dns_end = -1; - connect_start = -1; - connect_end = -1; - ssl_start = -1; - ssl_end = -1; - send_start = 0; - send_end = 0; - receive_headers_start = 0; - receive_headers_end = 0; -} - -ResourceLoaderBridge::LoadTimingInfo::~LoadTimingInfo() { -} - -ResourceLoaderBridge::ResponseInfo::ResponseInfo() { - content_length = -1; - appcache_id = appcache::kNoCacheId; - was_fetched_via_spdy = false; - was_npn_negotiated = false; - connection_id = 0; - connection_reused = false; - was_alternate_protocol_available = false; - was_fetched_via_proxy = false; -} - -ResourceLoaderBridge::ResponseInfo::~ResponseInfo() { -} - ResourceLoaderBridge::SyncLoadResponse::SyncLoadResponse() { } diff --git a/webkit/glue/resource_loader_bridge.h b/webkit/glue/resource_loader_bridge.h index eae1404..2634383 100644 --- a/webkit/glue/resource_loader_bridge.h +++ b/webkit/glue/resource_loader_bridge.h @@ -17,6 +17,9 @@ #ifndef WEBKIT_GLUE_RESOURCE_LOADER_BRIDGE_H_ #define WEBKIT_GLUE_RESOURCE_LOADER_BRIDGE_H_ +#include <utility> +#include <vector> + #include "build/build_config.h" #if defined(OS_POSIX) #include "base/file_descriptor_posix.h" @@ -24,7 +27,9 @@ #include "base/file_path.h" #include "base/platform_file.h" #include "base/ref_counted.h" +#include "base/scoped_ptr.h" #include "base/time.h" +#include "base/values.h" #include "googleurl/src/gurl.h" #include "net/url_request/url_request_status.h" #include "webkit/glue/resource_type.h" @@ -35,6 +40,148 @@ class HttpResponseHeaders; namespace webkit_glue { +// Structure containing timing information for the request. It addresses +// http://groups.google.com/group/http-archive-specification/web/har-1-1-spec +// and http://dev.w3.org/2006/webapi/WebTiming/ needs. +// +// All the values for starts and ends are given in milliseconds and are +// offsets with respect to the given base time. +struct ResourceLoadTimingInfo { + ResourceLoadTimingInfo(); + ~ResourceLoadTimingInfo(); + + // All the values in this struct are given as offsets in milliseconds wrt + // this base time. + base::Time base_time; + + // The time that proxy processing started. For requests with no proxy phase, + // this time is -1. + int32 proxy_start; + + // The time that proxy processing ended. For reused sockets this time + // is -1. + int32 proxy_end; + + // The time that DNS lookup started. For reused sockets this time is -1. + int32 dns_start; + + // The time that DNS lookup ended. For reused sockets this time is -1. + int32 dns_end; + + // The time that establishing connection started. Connect time includes + // DNS, blocking, TCP, TCP retries and SSL time. + int32 connect_start; + + // The time that establishing connection ended. Connect time includes + // DNS, blocking, TCP, TCP retries and SSL time. + int32 connect_end; + + // The time at which SSL handshake started. For non-HTTPS requests this + // is 0. + int32 ssl_start; + + // The time at which SSL handshake ended. For non-HTTPS requests this is 0. + int32 ssl_end; + + // The time that HTTP request started. For non-HTTP requests this is 0. + int32 send_start; + + // The time that HTTP request ended. For non-HTTP requests this is 0. + int32 send_end; + + // The time at which receiving HTTP headers started. For non-HTTP requests + // this is 0. + int32 receive_headers_start; + + // The time at which receiving HTTP headers ended. For non-HTTP requests + // this is 0. + int32 receive_headers_end; +}; + +struct ResourceDevToolsInfo : base::RefCounted<ResourceDevToolsInfo> { + typedef std::vector<std::pair<std::string, std::string> > + HeadersVector; + + ResourceDevToolsInfo(); + ~ResourceDevToolsInfo(); + + HeadersVector request_headers; + HeadersVector response_headers; +}; + +struct ResourceResponseInfo { + ResourceResponseInfo(); + ~ResourceResponseInfo(); + + // The time at which the request was made that resulted in this response. + // For cached responses, this time could be "far" in the past. + base::Time request_time; + + // The time at which the response headers were received. For cached + // responses, this time could be "far" in the past. + base::Time response_time; + + // The response headers or NULL if the URL type does not support headers. + scoped_refptr<net::HttpResponseHeaders> headers; + + // The mime type of the response. This may be a derived value. + std::string mime_type; + + // The character encoding of the response or none if not applicable to the + // response's mime type. This may be a derived value. + std::string charset; + + // An opaque string carrying security information pertaining to this + // response. This may include information about the SSL connection used. + std::string security_info; + + // Content length if available. -1 if not available + int64 content_length; + + // The appcache this response was loaded from, or kNoCacheId. + int64 appcache_id; + + // The manifest url of the appcache this response was loaded from. + // Note: this value is only populated for main resource requests. + GURL appcache_manifest_url; + + // Connection identifier from the underlying network stack. In case there + // is no associated connection, contains 0. + uint32 connection_id; + + // Determines whether physical connection reused. + bool connection_reused; + + // Detailed timing information used by the WebTiming, HAR and Developer + // Tools. + ResourceLoadTimingInfo load_timing; + + // Actual request and response headers, as obtained from the network stack. + // Only present if request had LOAD_REPORT_RAW_HEADERS in load_flags, and + // requesting renderer had CanReadRowCookies permission. + scoped_refptr<ResourceDevToolsInfo> devtools_info; + + // The path to a file that will contain the response body. It may only + // contain a portion of the response body at the time that the ResponseInfo + // becomes available. + FilePath download_file_path; + + // True if the response was delivered using SPDY. + bool was_fetched_via_spdy; + + // True if the response was delivered after NPN is negotiated. + bool was_npn_negotiated; + + // True if response could use alternate protocol. However, browser will + // ignore the alternate protocol when spdy is not enabled on browser side. + bool was_alternate_protocol_available; + + // True if the response was fetched via an explicit proxy (as opposed to a + // transparent proxy). The proxy could be any type of proxy, HTTP or SOCKS. + // Note: we cannot tell if a transparent proxy may have been involved. + bool was_fetched_via_proxy; +}; + class ResourceLoaderBridge { public: // Structure used when calling ResourceLoaderBridge::Create(). @@ -89,135 +236,9 @@ class ResourceLoaderBridge { bool download_to_file; }; - // Structure containing timing information for the request. It addresses - // http://groups.google.com/group/http-archive-specification/web/har-1-1-spec - // and http://dev.w3.org/2006/webapi/WebTiming/ needs. - // - // All the values for starts and ends are given in milliseconds and are - // offsets with respect to the given base time. - struct LoadTimingInfo { - LoadTimingInfo(); - ~LoadTimingInfo(); - - // All the values in this struct are given as offsets in milliseconds wrt - // this base time. - base::Time base_time; - - // The time that proxy processing started. For requests with no proxy phase, - // this time is -1. - int32 proxy_start; - - // The time that proxy processing ended. For reused sockets this time - // is -1. - int32 proxy_end; - - // The time that DNS lookup started. For reused sockets this time is -1. - int32 dns_start; - - // The time that DNS lookup ended. For reused sockets this time is -1. - int32 dns_end; - - // The time that establishing connection started. Connect time includes - // DNS, blocking, TCP, TCP retries and SSL time. - int32 connect_start; - - // The time that establishing connection ended. Connect time includes - // DNS, blocking, TCP, TCP retries and SSL time. - int32 connect_end; - - // The time at which SSL handshake started. For non-HTTPS requests this - // is 0. - int32 ssl_start; - - // The time at which SSL handshake ended. For non-HTTPS requests this is 0. - int32 ssl_end; - - // The time that HTTP request started. For non-HTTP requests this is 0. - int32 send_start; - - // The time that HTTP request ended. For non-HTTP requests this is 0. - int32 send_end; - - // The time at which receiving HTTP headers started. For non-HTTP requests - // this is 0. - int32 receive_headers_start; - - // The time at which receiving HTTP headers ended. For non-HTTP requests - // this is 0. - int32 receive_headers_end; - }; - - struct ResponseInfo { - ResponseInfo(); - ~ResponseInfo(); - - // The time at which the request was made that resulted in this response. - // For cached responses, this time could be "far" in the past. - base::Time request_time; - - // The time at which the response headers were received. For cached - // responses, this time could be "far" in the past. - base::Time response_time; - - // The response headers or NULL if the URL type does not support headers. - scoped_refptr<net::HttpResponseHeaders> headers; - - // The mime type of the response. This may be a derived value. - std::string mime_type; - - // The character encoding of the response or none if not applicable to the - // response's mime type. This may be a derived value. - std::string charset; - - // An opaque string carrying security information pertaining to this - // response. This may include information about the SSL connection used. - std::string security_info; - - // Content length if available. -1 if not available - int64 content_length; - - // The appcache this response was loaded from, or kNoCacheId. - int64 appcache_id; - - // The manifest url of the appcache this response was loaded from. - // Note: this value is only populated for main resource requests. - GURL appcache_manifest_url; - - // Connection identifier from the underlying network stack. In case there - // is no associated connection, contains 0. - uint32 connection_id; - - // Determines whether physical connection reused. - bool connection_reused; - - // Detailed timing information used by the WebTiming, HAR and Developer - // Tools. - LoadTimingInfo load_timing; - - // The path to a file that will contain the response body. It may only - // contain a portion of the response body at the time that the ResponseInfo - // becomes available. - FilePath download_file_path; - - // True if the response was delivered using SPDY. - bool was_fetched_via_spdy; - - // True if the response was delivered after NPN is negotiated. - bool was_npn_negotiated; - - // True if response could use alternate protocol. However, browser will - // ignore the alternate protocol when spdy is not enabled on browser side. - bool was_alternate_protocol_available; - - // True if the response was fetched via an explicit proxy (as opposed to a - // transparent proxy). The proxy could be any type of proxy, HTTP or SOCKS. - // Note: we cannot tell if a transparent proxy may have been involved. - bool was_fetched_via_proxy; - }; - // See the SyncLoad method declared below. (The name of this struct is not // suffixed with "Info" because it also contains the response data.) - struct SyncLoadResponse : ResponseInfo { + struct SyncLoadResponse : ResourceResponseInfo { SyncLoadResponse(); ~SyncLoadResponse(); @@ -255,7 +276,7 @@ class ResourceLoaderBridge { // output parameter *new_first_party_for_cookies contains the new URL that // should be consulted for the third-party cookie blocking policy. virtual bool OnReceivedRedirect(const GURL& new_url, - const ResponseInfo& info, + const ResourceResponseInfo& info, bool* has_new_first_party_for_cookies, GURL* new_first_party_for_cookies) = 0; @@ -263,7 +284,7 @@ class ResourceLoaderBridge { // been followed). |content_filtered| is set to true if the contents is // altered or replaced (usually for security reasons when the resource is // deemed unsafe). - virtual void OnReceivedResponse(const ResponseInfo& info, + virtual void OnReceivedResponse(const ResourceResponseInfo& info, bool content_filtered) = 0; // Called when a chunk of response data is downloaded. This method may be diff --git a/webkit/glue/site_isolation_metrics.cc b/webkit/glue/site_isolation_metrics.cc index 912263f..58d8717 100644 --- a/webkit/glue/site_isolation_metrics.cc +++ b/webkit/glue/site_isolation_metrics.cc @@ -7,7 +7,7 @@ #include <set> #include "base/hash_tables.h" -#include "base/histogram.h" +#include "base/metrics/histogram.h" #include "net/base/mime_sniffer.h" #include "third_party/WebKit/WebKit/chromium/public/WebFrame.h" #include "third_party/WebKit/WebKit/chromium/public/WebSecurityOrigin.h" diff --git a/webkit/glue/web_io_operators.cc b/webkit/glue/web_io_operators.cc new file mode 100644 index 0000000..9a53212 --- /dev/null +++ b/webkit/glue/web_io_operators.cc @@ -0,0 +1,33 @@ +// Copyright (c) 2010 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/web_io_operators.h" + +#include "gfx/point.h" +#include "gfx/rect.h" +#include "third_party/WebKit/WebKit/chromium/public/WebPoint.h" +#include "third_party/WebKit/WebKit/chromium/public/WebRect.h" + +#if defined(WCHAR_T_IS_UTF32) +#include "base/string16.h" +#include "third_party/WebKit/WebKit/chromium/public/WebString.h" +#endif // defined(WCHAR_T_IS_UTF32) + +namespace WebKit { + +#if defined(WCHAR_T_IS_UTF32) +std::ostream& operator<<(std::ostream& out, const WebString& s) { + return out << static_cast<string16>(s); +} +#endif // defined(WCHAR_T_IS_UTF32) + +std::ostream& operator<<(std::ostream& out, const WebPoint& p) { + return out << static_cast<gfx::Point>(p); +} + +std::ostream& operator<<(std::ostream& out, const WebRect& p) { + return out << static_cast<gfx::Rect>(p); +} + +} // namespace WebKit diff --git a/webkit/glue/web_io_operators.h b/webkit/glue/web_io_operators.h new file mode 100644 index 0000000..e60ef72 --- /dev/null +++ b/webkit/glue/web_io_operators.h @@ -0,0 +1,27 @@ +// Copyright (c) 2010 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_GLUE_WEB_IO_OPERATORS_H_ +#define WEBKIT_GLUE_WEB_IO_OPERATORS_H_ + +#include <iosfwd> + +#include "build/build_config.h" + +namespace WebKit { + +#if defined(WCHAR_T_IS_UTF32) +class WebString; +std::ostream& operator<<(std::ostream& out, const WebString& s); +#endif // defined(WCHAR_T_IS_UTF32) + +struct WebPoint; +std::ostream& operator<<(std::ostream& out, const WebPoint& p); + +struct WebRect; +std::ostream& operator<<(std::ostream& out, const WebRect& p); + +} // namespace WebKit + +#endif // WEBKIT_GLUE_WEB_IO_OPERATORS_H_ diff --git a/webkit/glue/webaccessibility.cc b/webkit/glue/webaccessibility.cc index 0d96685..70827c1 100644 --- a/webkit/glue/webaccessibility.cc +++ b/webkit/glue/webaccessibility.cc @@ -4,7 +4,9 @@ #include "webkit/glue/webaccessibility.h" +#include "base/string_number_conversions.h" #include "base/string_util.h" +#include "base/utf_string_conversions.h" #include "third_party/WebKit/WebKit/chromium/public/WebAccessibilityCache.h" #include "third_party/WebKit/WebKit/chromium/public/WebAccessibilityObject.h" #include "third_party/WebKit/WebKit/chromium/public/WebAccessibilityRole.h" @@ -12,7 +14,9 @@ #include "third_party/WebKit/WebKit/chromium/public/WebDocument.h" #include "third_party/WebKit/WebKit/chromium/public/WebDocumentType.h" #include "third_party/WebKit/WebKit/chromium/public/WebElement.h" +#include "third_party/WebKit/WebKit/chromium/public/WebFormControlElement.h" #include "third_party/WebKit/WebKit/chromium/public/WebFrame.h" +#include "third_party/WebKit/WebKit/chromium/public/WebInputElement.h" #include "third_party/WebKit/WebKit/chromium/public/WebNamedNodeMap.h" #include "third_party/WebKit/WebKit/chromium/public/WebNode.h" #include "third_party/WebKit/WebKit/chromium/public/WebString.h" @@ -332,11 +336,24 @@ void WebAccessibility::Init(const WebKit::WebAccessibilityObject& src, element.attributes().attributeItem(i).localName(), element.attributes().attributeItem(i).value())); } + + if (element.isFormControlElement()) { + WebKit::WebFormControlElement form_element = + element.to<WebKit::WebFormControlElement>(); + if (form_element.formControlType() == ASCIIToUTF16("text")) { + WebKit::WebInputElement input_element = + form_element.to<WebKit::WebInputElement>(); + attributes[ATTR_TEXT_SEL_START] = base::IntToString16( + input_element.selectionStart()); + attributes[ATTR_TEXT_SEL_END] = base::IntToString16( + input_element.selectionEnd()); + } + } } if (role == WebAccessibility::ROLE_DOCUMENT || role == WebAccessibility::ROLE_WEB_AREA) { - WebKit::WebDocument document = src.document(); + const WebKit::WebDocument& document = src.document(); if (name.empty()) name = document.title(); attributes[ATTR_DOC_TITLE] = document.title(); @@ -346,7 +363,7 @@ void WebAccessibility::Init(const WebKit::WebAccessibilityObject& src, else attributes[ATTR_DOC_MIMETYPE] = WebKit::WebString("text/html"); - WebKit::WebDocumentType doctype = document.doctype(); + const WebKit::WebDocumentType& doctype = document.doctype(); if (!doctype.isNull()) attributes[ATTR_DOC_DOCTYPE] = doctype.name(); } diff --git a/webkit/glue/webaccessibility.h b/webkit/glue/webaccessibility.h index 09a9473..cc92939 100644 --- a/webkit/glue/webaccessibility.h +++ b/webkit/glue/webaccessibility.h @@ -163,6 +163,10 @@ struct WebAccessibility { ATTR_DOC_MIMETYPE, ATTR_DOC_DOCTYPE, + // Editable text attributes + ATTR_TEXT_SEL_START, + ATTR_TEXT_SEL_END, + // Attributes that could apply to any node. ATTR_ACTION, ATTR_DESCRIPTION, diff --git a/webkit/glue/webcursor_mac.mm b/webkit/glue/webcursor_mac.mm index a6e7fc0..6b2729e 100644 --- a/webkit/glue/webcursor_mac.mm +++ b/webkit/glue/webcursor_mac.mm @@ -9,7 +9,7 @@ #include "base/logging.h" #include "base/nsimage_cache_mac.h" -#include "base/scoped_cftyperef.h" +#include "base/mac/scoped_cftyperef.h" #include "third_party/WebKit/WebKit/chromium/public/WebCursorInfo.h" #include "third_party/WebKit/WebKit/chromium/public/WebImage.h" #include "third_party/WebKit/WebKit/chromium/public/WebSize.h" @@ -33,11 +33,12 @@ NSCursor* LoadCursor(const char* name, int x, int y) { CGImageRef CreateCGImageFromCustomData(const std::vector<char>& custom_data, const gfx::Size& custom_size) { - scoped_cftyperef<CGColorSpaceRef> cg_color(CGColorSpaceCreateDeviceRGB()); + base::mac::ScopedCFTypeRef<CGColorSpaceRef> cg_color( + CGColorSpaceCreateDeviceRGB()); // This is safe since we're not going to draw into the context we're creating. void* data = const_cast<char*>(&custom_data[0]); // The settings here match SetCustomData() below; keep in sync. - scoped_cftyperef<CGContextRef> context( + base::mac::ScopedCFTypeRef<CGContextRef> context( CGBitmapContextCreate(data, custom_size.width(), custom_size.height(), @@ -56,7 +57,7 @@ NSCursor* CreateCustomCursor(const std::vector<char>& custom_data, // results in an infinite loop. This CHECK ensures that we crash instead. CHECK(!custom_data.empty()); - scoped_cftyperef<CGImageRef> cg_image( + base::mac::ScopedCFTypeRef<CGImageRef> cg_image( CreateCGImageFromCustomData(custom_data, custom_size)); NSBitmapImageRep* ns_bitmap = @@ -258,7 +259,7 @@ void WebCursor::InitFromCursor(const Cursor* cursor) { } } - scoped_cftyperef<CGImageRef> cg_image( + base::mac::ScopedCFTypeRef<CGImageRef> cg_image( CreateCGImageFromCustomData(raw_data, custom_size)); WebKit::WebCursorInfo cursor_info; @@ -322,7 +323,7 @@ void WebCursor::SetCustomData(const WebImage& image) { if (image.isNull()) return; - scoped_cftyperef<CGColorSpaceRef> cg_color( + base::mac::ScopedCFTypeRef<CGColorSpaceRef> cg_color( CGColorSpaceCreateDeviceRGB()); const WebSize& image_dimensions = image.size(); @@ -337,7 +338,7 @@ void WebCursor::SetCustomData(const WebImage& image) { // These settings match up with the code in CreateCustomCursor() above; keep // them in sync. // TODO(avi): test to ensure that the flags here are correct for RGBA - scoped_cftyperef<CGContextRef> context( + base::mac::ScopedCFTypeRef<CGContextRef> context( CGBitmapContextCreate(&custom_data_[0], image_width, image_height, @@ -354,7 +355,7 @@ void WebCursor::ImageFromCustomData(WebImage* image) const { if (custom_data_.empty()) return; - scoped_cftyperef<CGImageRef> cg_image( + base::mac::ScopedCFTypeRef<CGImageRef> cg_image( CreateCGImageFromCustomData(custom_data_, custom_size_)); *image = cg_image.get(); } diff --git a/webkit/glue/webdropdata.cc b/webkit/glue/webdropdata.cc index ea9e6c6..cda887d 100644 --- a/webkit/glue/webdropdata.cc +++ b/webkit/glue/webdropdata.cc @@ -28,12 +28,12 @@ WebDropData::WebDropData(const WebDragData& drag_data) plain_text(drag_data.plainText()), text_html(drag_data.htmlText()), html_base_url(drag_data.htmlBaseURL()), - file_description_filename(drag_data.fileContentFileName()) { - if (drag_data.hasFileNames()) { - WebVector<WebString> fileNames; - drag_data.fileNames(fileNames); - for (size_t i = 0; i < fileNames.size(); ++i) - filenames.push_back(fileNames[i]); + file_description_filename(drag_data.fileContentFilename()) { + if (drag_data.containsFilenames()) { + WebVector<WebString> filenames_copy; + drag_data.filenames(filenames_copy); + for (size_t i = 0; i < filenames_copy.size(); ++i) + filenames.push_back(filenames_copy[i]); } WebData contents = drag_data.fileContent(); if (!contents.isEmpty()) @@ -53,11 +53,11 @@ WebDragData WebDropData::ToDragData() const { result.setURL(url); result.setURLTitle(url_title); result.setFileExtension(file_extension); - result.setFileNames(filenames); + result.setFilenames(filenames); result.setPlainText(plain_text); result.setHTMLText(text_html); result.setHTMLBaseURL(html_base_url); - result.setFileContentFileName(file_description_filename); + result.setFileContentFilename(file_description_filename); result.setFileContent(WebData(file_contents.data(), file_contents.size())); return result; } diff --git a/webkit/glue/webkit_glue.cc b/webkit/glue/webkit_glue.cc index 661b87b..a58ff1b 100644 --- a/webkit/glue/webkit_glue.cc +++ b/webkit/glue/webkit_glue.cc @@ -321,6 +321,8 @@ WebKit::WebFileError PlatformFileErrorToWebFileError( case base::PLATFORM_FILE_ERROR_INVALID_OPERATION: case base::PLATFORM_FILE_ERROR_EXISTS: case base::PLATFORM_FILE_ERROR_NOT_A_DIRECTORY: + case base::PLATFORM_FILE_ERROR_NOT_A_FILE: + case base::PLATFORM_FILE_ERROR_NOT_EMPTY: return WebKit::WebFileErrorInvalidModification; case base::PLATFORM_FILE_ERROR_ACCESS_DENIED: return WebKit::WebFileErrorNoModificationAllowed; @@ -328,6 +330,10 @@ WebKit::WebFileError PlatformFileErrorToWebFileError( return WebKit::WebFileErrorInvalidState; case base::PLATFORM_FILE_ERROR_ABORT: return WebKit::WebFileErrorAbort; + case base::PLATFORM_FILE_ERROR_SECURITY: + return WebKit::WebFileErrorSecurity; + case base::PLATFORM_FILE_ERROR_NO_SPACE: + return WebKit::WebFileErrorQuotaExceeded; default: return WebKit::WebFileErrorInvalidModification; } diff --git a/webkit/glue/webkit_glue.gypi b/webkit/glue/webkit_glue.gypi index f5d03c4..8249fb5 100644 --- a/webkit/glue/webkit_glue.gypi +++ b/webkit/glue/webkit_glue.gypi @@ -197,10 +197,12 @@ 'plugins/pepper_cursor_control.h', 'plugins/pepper_directory_reader.cc', 'plugins/pepper_directory_reader.h', - 'plugins/pepper_error_util.cc', - 'plugins/pepper_error_util.h', + 'plugins/pepper_error_util.cc', + 'plugins/pepper_error_util.h', 'plugins/pepper_event_conversion.cc', 'plugins/pepper_event_conversion.h', + 'plugins/pepper_file_callbacks.cc', + 'plugins/pepper_file_callbacks.h', 'plugins/pepper_file_chooser.cc', 'plugins/pepper_file_chooser.h', 'plugins/pepper_file_io.cc', @@ -226,12 +228,15 @@ 'plugins/pepper_private.h', 'plugins/pepper_private2.cc', 'plugins/pepper_private2.h', + 'plugins/pepper_private2_linux.cc', 'plugins/pepper_resource_tracker.cc', 'plugins/pepper_resource_tracker.h', 'plugins/pepper_resource.cc', 'plugins/pepper_resource.h', 'plugins/pepper_scrollbar.cc', 'plugins/pepper_scrollbar.h', + 'plugins/pepper_string.cc', + 'plugins/pepper_string.h', 'plugins/pepper_transport.cc', 'plugins/pepper_transport.h', 'plugins/pepper_url_loader.cc', @@ -251,6 +256,8 @@ 'plugins/pepper_widget.cc', 'plugins/pepper_widget.h', 'plugins/plugin_constants_win.h', + 'plugins/plugin_group.cc', + 'plugins/plugin_group.h', 'plugins/plugin_host.cc', 'plugins/plugin_host.h', 'plugins/plugin_instance.cc', @@ -288,6 +295,7 @@ 'plugins/webplugin.h', 'plugins/webplugin_2d_device_delegate.h', 'plugins/webplugin_3d_device_delegate.h', + 'plugins/webplugin_accelerated_surface_mac.h', 'plugins/webplugin_delegate.h', 'plugins/webplugin_delegate_impl.cc', 'plugins/webplugin_delegate_impl.h', @@ -296,6 +304,7 @@ 'plugins/webplugin_delegate_impl_win.cc', 'plugins/webplugin_impl.cc', 'plugins/webplugin_impl.h', + 'plugins/webplugininfo.cc', 'plugins/webplugininfo.h', 'alt_error_page_resource_fetcher.cc', 'alt_error_page_resource_fetcher.h', @@ -345,6 +354,8 @@ 'webaccessibility.h', 'webclipboard_impl.cc', 'webclipboard_impl.h', + 'web_io_operators.cc', + 'web_io_operators.h', 'webcookie.cc', 'webcookie.h', 'webcursor.cc', @@ -375,6 +386,7 @@ 'websocketstreamhandle_delegate.h', 'websocketstreamhandle_impl.cc', 'websocketstreamhandle_impl.h', + 'webthemeengine_impl_linux.cc', 'webthemeengine_impl_win.cc', 'weburlloader_impl.cc', 'weburlloader_impl.h', @@ -426,7 +438,7 @@ ], }, }], - ['enable_gpu==1 and inside_chromium_build==1', { + ['enable_gpu==1', { 'sources': [ 'plugins/pepper_graphics_3d_gl.cc', 'plugins/pepper_graphics_3d.cc', @@ -458,6 +470,10 @@ '<(DEPTH)/third_party/WebKit/WebKit/chromium/WebKit.gyp:webkit', '<(DEPTH)/v8/tools/gyp/v8.gyp:v8', ], + 'export_dependent_settings': [ + '<(DEPTH)/third_party/WebKit/WebKit/chromium/WebKit.gyp:webkit', + '<(DEPTH)/v8/tools/gyp/v8.gyp:v8', + ], }], ], }], diff --git a/webkit/glue/webkitclient_impl.cc b/webkit/glue/webkitclient_impl.cc index c65d176..648f3bd 100644 --- a/webkit/glue/webkitclient_impl.cc +++ b/webkit/glue/webkitclient_impl.cc @@ -14,10 +14,10 @@ #include "base/lock.h" #include "base/message_loop.h" +#include "base/metrics/stats_counters.h" #include "base/process_util.h" #include "base/platform_file.h" #include "base/singleton.h" -#include "base/stats_counters.h" #include "base/string_number_conversions.h" #include "base/string_util.h" #include "base/time.h" @@ -171,7 +171,7 @@ WebKitClientImpl::~WebKitClientImpl() { } WebThemeEngine* WebKitClientImpl::themeEngine() { -#if defined(OS_WIN) +#if defined(OS_WIN) || defined(OS_LINUX) return &theme_engine_; #else return NULL; @@ -217,11 +217,11 @@ void WebKitClientImpl::getPluginList(bool refresh, } void WebKitClientImpl::decrementStatsCounter(const char* name) { - StatsCounter(name).Decrement(); + base::StatsCounter(name).Decrement(); } void WebKitClientImpl::incrementStatsCounter(const char* name) { - StatsCounter(name).Increment(); + base::StatsCounter(name).Increment(); } void WebKitClientImpl::traceEventBegin(const char* name, void* id, diff --git a/webkit/glue/webkitclient_impl.h b/webkit/glue/webkitclient_impl.h index 607677f..68d0eaf 100644 --- a/webkit/glue/webkitclient_impl.h +++ b/webkit/glue/webkitclient_impl.h @@ -10,8 +10,11 @@ #include "third_party/WebKit/WebKit/chromium/public/WebKitClient.h" #if defined(OS_WIN) #include "webkit/glue/webthemeengine_impl_win.h" +#elif defined(OS_LINUX) +#include "webkit/glue/webthemeengine_impl_linux.h" #endif + class MessageLoop; namespace webkit_glue { @@ -71,7 +74,7 @@ class WebKitClientImpl : public WebKit::WebKitClient { double shared_timer_fire_time_; int shared_timer_suspended_; // counter -#if defined(OS_WIN) +#if defined(OS_WIN) || defined(OS_LINUX) WebThemeEngineImpl theme_engine_; #endif }; diff --git a/webkit/glue/webmediaplayer_impl.cc b/webkit/glue/webmediaplayer_impl.cc index d5c667d..e4aca5a 100644 --- a/webkit/glue/webmediaplayer_impl.cc +++ b/webkit/glue/webmediaplayer_impl.cc @@ -244,7 +244,7 @@ WebMediaPlayerImpl::WebMediaPlayerImpl(WebKit::WebMediaPlayerClient* client, // Add in the default filter factories. filter_factory_->AddFactory(media::FFmpegDemuxer::CreateFilterFactory()); filter_factory_->AddFactory(media::FFmpegAudioDecoder::CreateFactory()); - filter_factory_->AddFactory(media::FFmpegVideoDecoder::CreateFactory()); + filter_factory_->AddFactory(media::FFmpegVideoDecoder::CreateFactory(NULL)); filter_factory_->AddFactory(media::NullAudioRenderer::CreateFilterFactory()); filter_factory_->AddFactory(video_renderer_factory->CreateFactory(proxy_)); } diff --git a/webkit/glue/webpasswordautocompletelistener_impl.cc b/webkit/glue/webpasswordautocompletelistener_impl.cc index fc15af0..280ce43 100644 --- a/webkit/glue/webpasswordautocompletelistener_impl.cc +++ b/webkit/glue/webpasswordautocompletelistener_impl.cc @@ -33,6 +33,10 @@ bool WebInputElementDelegate::IsEditable() const { return element_.isEnabledFormControl() && !element_.hasAttribute("readonly"); } +bool WebInputElementDelegate::IsValidValue(const string16& value) { + return element_.isValidValue(value); +} + void WebInputElementDelegate::SetValue(const string16& value) { element_.setValue(value); } @@ -53,7 +57,7 @@ void WebInputElementDelegate::SetSelectionRange(size_t start, size_t end) { element_.setSelectionRange(start, end); } -void WebInputElementDelegate::RefreshAutofillPopup( +void WebInputElementDelegate::RefreshAutoFillPopup( const std::vector<string16>& suggestions) { WebView* webview = element_.document().frame()->view(); if (webview) { @@ -74,6 +78,13 @@ void WebInputElementDelegate::RefreshAutofillPopup( } } +void WebInputElementDelegate::HideAutoFillPopup() { + WebView* webview = element_.document().frame()->view(); + if (webview) { + webview->hidePopups(); + } +} + WebPasswordAutocompleteListenerImpl::WebPasswordAutocompleteListenerImpl( WebInputElementDelegate* username_delegate, WebInputElementDelegate* password_delegate, @@ -100,14 +111,19 @@ void WebPasswordAutocompleteListenerImpl::didBlurInputElement( // If enabled, set the password field to match the current username. if (data_.basic_data.fields[0].value() == user_input16) { - // Preferred username/login is selected. - password_delegate_->SetValue(data_.basic_data.fields[1].value()); - password_delegate_->SetAutofilled(true); + if (password_delegate_->IsValidValue(data_.basic_data.fields[1].value())) { + // Preferred username/login is selected. + password_delegate_->SetValue(data_.basic_data.fields[1].value()); + password_delegate_->SetAutofilled(true); + } } else if (data_.additional_logins.find(user_input16) != data_.additional_logins.end()) { - // One of the extra username/logins is selected. - password_delegate_->SetValue(data_.additional_logins[user_input16]); - password_delegate_->SetAutofilled(true); + if (password_delegate_->IsValidValue( + data_.additional_logins[user_input16])) { + // One of the extra username/logins is selected. + password_delegate_->SetValue(data_.additional_logins[user_input16]); + password_delegate_->SetAutofilled(true); + } } } @@ -131,8 +147,8 @@ void WebPasswordAutocompleteListenerImpl::performInlineAutocomplete( password_delegate_->SetAutofilled(false); } - if (show_suggestions) - showSuggestionPopup(user_input16); + if (show_suggestions && !showSuggestionPopup(user_input16)) + username_delegate_->HideAutoFillPopup(); if (backspace_or_delete_pressed) return; // Don't inline autocomplete when the user deleted something. @@ -166,7 +182,7 @@ bool WebPasswordAutocompleteListenerImpl::showSuggestionPopup( if (suggestions.empty()) return false; - username_delegate_->RefreshAutofillPopup(suggestions); + username_delegate_->RefreshAutoFillPopup(suggestions); return true; } @@ -176,13 +192,18 @@ bool WebPasswordAutocompleteListenerImpl::TryToMatch(const string16& input, if (!StartsWith(username, input, false)) return false; + if (!username_delegate_->IsValidValue(username)) + return false; + // Input matches the username, fill in required values. username_delegate_->SetValue(username); username_delegate_->SetSelectionRange(input.length(), username.length()); username_delegate_->SetAutofilled(true); - if (password_delegate_->IsEditable()) + if (password_delegate_->IsEditable() && + password_delegate_->IsValidValue(password)) { password_delegate_->SetValue(password); - password_delegate_->SetAutofilled(true); + password_delegate_->SetAutofilled(true); + } return true; } diff --git a/webkit/glue/webpasswordautocompletelistener_impl.h b/webkit/glue/webpasswordautocompletelistener_impl.h index 8180a47..6badcb7 100644 --- a/webkit/glue/webpasswordautocompletelistener_impl.h +++ b/webkit/glue/webpasswordautocompletelistener_impl.h @@ -29,11 +29,13 @@ class WebInputElementDelegate { // These are virtual to support unit testing. virtual bool IsEditable() const; + virtual bool IsValidValue(const string16& value); virtual void SetValue(const string16& value); virtual bool IsAutofilled() const; virtual void SetAutofilled(bool autofilled); virtual void SetSelectionRange(size_t start, size_t end); - virtual void RefreshAutofillPopup(const std::vector<string16>& suggestions); + virtual void RefreshAutoFillPopup(const std::vector<string16>& suggestions); + virtual void HideAutoFillPopup(); private: // The underlying DOM element we're wrapping. diff --git a/webkit/glue/webpasswordautocompletelistener_unittest.cc b/webkit/glue/webpasswordautocompletelistener_unittest.cc index 0ce2916..5de593c 100644 --- a/webkit/glue/webpasswordautocompletelistener_unittest.cc +++ b/webkit/glue/webpasswordautocompletelistener_unittest.cc @@ -28,6 +28,7 @@ class TestWebInputElementDelegate : public WebInputElementDelegate { selection_start_(0), selection_end_(0), is_editable_(true), + is_valid_(true), is_autofilled_(false) { } @@ -36,6 +37,10 @@ class TestWebInputElementDelegate : public WebInputElementDelegate { return is_editable_; } + virtual bool IsValidValue(const string16& value) { + return is_valid_; + } + virtual void SetValue(const string16& value) { value_ = value; } @@ -56,6 +61,10 @@ class TestWebInputElementDelegate : public WebInputElementDelegate { is_editable_ = editable; } + void set_is_valid(bool valid) { + is_valid_ = valid; + } + string16 value() const { return value_; } @@ -73,6 +82,7 @@ class TestWebInputElementDelegate : public WebInputElementDelegate { size_t selection_start_; size_t selection_end_; bool is_editable_; + bool is_valid_; bool is_autofilled_; }; @@ -289,4 +299,45 @@ TEST_F(PasswordManagerAutocompleteTests, TestPasswordClearOnEdit) { EXPECT_TRUE(password_delegate_->value().empty()); } +// Tests that filling with invalid value for input element does not fill. +TEST_F(PasswordManagerAutocompleteTests, TestValidValueConditions) { + WebKit::WebPasswordAutocompleteListener* listener = CreateListener(false); + + // User enters a known login that validates ok. + username_delegate_->set_is_valid(true); + password_delegate_->set_is_valid(true); + username_delegate_->SetValue(string16()); + password_delegate_->SetValue(string16()); + listener->performInlineAutocomplete(ASCIIToUTF16("alice"), false, false); + // We are autofilled. + EXPECT_EQ(username1_, username_delegate_->value()); + EXPECT_TRUE(username_delegate_->IsAutofilled()); + EXPECT_EQ(password1_, password_delegate_->value()); + EXPECT_TRUE(password_delegate_->IsAutofilled()); + + // User enters a known login that does not validate. + username_delegate_->set_is_valid(false); + password_delegate_->set_is_valid(true); + username_delegate_->SetValue(string16()); + password_delegate_->SetValue(string16()); + listener->performInlineAutocomplete(ASCIIToUTF16("alice"), false, false); + // We are not autofilled. + EXPECT_EQ(string16(), username_delegate_->value()); + EXPECT_FALSE(username_delegate_->IsAutofilled()); + EXPECT_EQ(string16(), password_delegate_->value()); + EXPECT_FALSE(password_delegate_->IsAutofilled()); + + // User enters a known login that validates ok, but password does not. + username_delegate_->set_is_valid(true); + password_delegate_->set_is_valid(false); + username_delegate_->SetValue(string16()); + password_delegate_->SetValue(string16()); + listener->performInlineAutocomplete(ASCIIToUTF16("alice"), false, false); + // We are autofilled. + EXPECT_EQ(username1_, username_delegate_->value()); + EXPECT_TRUE(username_delegate_->IsAutofilled()); + EXPECT_EQ(string16(), password_delegate_->value()); + EXPECT_FALSE(password_delegate_->IsAutofilled()); +} + } // namespace diff --git a/webkit/glue/webpreferences.cc b/webkit/glue/webpreferences.cc index ddf4ddb..ecb2c38 100644 --- a/webkit/glue/webpreferences.cc +++ b/webkit/glue/webpreferences.cc @@ -20,6 +20,55 @@ using WebKit::WebString; using WebKit::WebURL; using WebKit::WebView; +WebPreferences::WebPreferences() + : standard_font_family(L"Times New Roman"), + fixed_font_family(L"Courier New"), + serif_font_family(L"Times New Roman"), + sans_serif_font_family(L"Arial"), + cursive_font_family(L"Script"), + fantasy_font_family(), // Not sure what to use on Windows. + default_font_size(16), + default_fixed_font_size(13), + minimum_font_size(1), + minimum_logical_font_size(6), + default_encoding("ISO-8859-1"), + javascript_enabled(true), + web_security_enabled(true), + javascript_can_open_windows_automatically(true), + loads_images_automatically(true), + plugins_enabled(true), + dom_paste_enabled(false), // enables execCommand("paste") + developer_extras_enabled(false), // Requires extra work by embedder + site_specific_quirks_enabled(false), + shrinks_standalone_images_to_fit(true), + uses_universal_detector(false), // Disabled: page cycler regression + text_areas_are_resizable(true), + java_enabled(true), + allow_scripts_to_close_windows(false), + uses_page_cache(false), + remote_fonts_enabled(true), + javascript_can_access_clipboard(false), + xss_auditor_enabled(false), + local_storage_enabled(false), + databases_enabled(false), + application_cache_enabled(false), + tabs_to_links(true), + caret_browsing_enabled(false), + hyperlink_auditing_enabled(true), + user_style_sheet_enabled(false), + author_and_user_styles_enabled(true), + allow_universal_access_from_file_urls(false), + allow_file_access_from_file_urls(false), + experimental_webgl_enabled(false), + show_composited_layer_borders(false), + accelerated_compositing_enabled(false), + accelerated_2d_canvas_enabled(false), + memory_info_enabled(false) { +} + +WebPreferences::~WebPreferences() { +} + void WebPreferences::Apply(WebView* web_view) const { WebSettings* settings = web_view->settings(); settings->setStandardFontFamily(WideToUTF16Hack(standard_font_family)); diff --git a/webkit/glue/webpreferences.h b/webkit/glue/webpreferences.h index bc6d477..e9f0c01 100644 --- a/webkit/glue/webpreferences.h +++ b/webkit/glue/webpreferences.h @@ -72,51 +72,8 @@ struct WebPreferences { // We try to keep the default values the same as the default values in // chrome, except for the cases where it would require lots of extra work for // the embedder to use the same default value. - WebPreferences() - : standard_font_family(L"Times New Roman"), - fixed_font_family(L"Courier New"), - serif_font_family(L"Times New Roman"), - sans_serif_font_family(L"Arial"), - cursive_font_family(L"Script"), - fantasy_font_family(), // Not sure what to use on Windows. - default_font_size(16), - default_fixed_font_size(13), - minimum_font_size(1), - minimum_logical_font_size(6), - default_encoding("ISO-8859-1"), - javascript_enabled(true), - web_security_enabled(true), - javascript_can_open_windows_automatically(true), - loads_images_automatically(true), - plugins_enabled(true), - dom_paste_enabled(false), // enables execCommand("paste") - developer_extras_enabled(false), // Requires extra work by embedder - site_specific_quirks_enabled(false), - shrinks_standalone_images_to_fit(true), - uses_universal_detector(false), // Disabled: page cycler regression - text_areas_are_resizable(true), - java_enabled(true), - allow_scripts_to_close_windows(false), - uses_page_cache(false), - remote_fonts_enabled(true), - javascript_can_access_clipboard(false), - xss_auditor_enabled(false), - local_storage_enabled(false), - databases_enabled(false), - application_cache_enabled(false), - tabs_to_links(true), - caret_browsing_enabled(false), - hyperlink_auditing_enabled(false), - user_style_sheet_enabled(false), - author_and_user_styles_enabled(true), - allow_universal_access_from_file_urls(false), - allow_file_access_from_file_urls(false), - experimental_webgl_enabled(false), - show_composited_layer_borders(false), - accelerated_compositing_enabled(false), - accelerated_2d_canvas_enabled(false), - memory_info_enabled(false) { - } + WebPreferences(); + ~WebPreferences(); void Apply(WebKit::WebView* web_view) const; }; diff --git a/webkit/glue/websocketstreamhandle_impl.cc b/webkit/glue/websocketstreamhandle_impl.cc index 60faea2..6a56393 100644 --- a/webkit/glue/websocketstreamhandle_impl.cc +++ b/webkit/glue/websocketstreamhandle_impl.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 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. @@ -72,7 +72,7 @@ WebSocketStreamHandleImpl::Context::Context(WebSocketStreamHandleImpl* handle) } void WebSocketStreamHandleImpl::Context::Connect(const WebKit::WebURL& url) { - LOG(INFO) << "Connect url=" << url; + VLOG(1) << "Connect url=" << url; DCHECK(!bridge_); bridge_ = WebSocketStreamHandleBridge::Create(handle_, this); AddRef(); // Will be released by DidClose(). @@ -80,14 +80,14 @@ void WebSocketStreamHandleImpl::Context::Connect(const WebKit::WebURL& url) { } bool WebSocketStreamHandleImpl::Context::Send(const WebKit::WebData& data) { - LOG(INFO) << "Send data.size=" << data.size(); + VLOG(1) << "Send data.size=" << data.size(); DCHECK(bridge_); return bridge_->Send( std::vector<char>(data.data(), data.data() + data.size())); } void WebSocketStreamHandleImpl::Context::Close() { - LOG(INFO) << "Close"; + VLOG(1) << "Close"; if (bridge_) bridge_->Close(); } @@ -105,7 +105,7 @@ void WebSocketStreamHandleImpl::Context::Detach() { void WebSocketStreamHandleImpl::Context::DidOpenStream( WebKit::WebSocketStreamHandle* web_handle, int max_amount_send_allowed) { - LOG(INFO) << "DidOpen"; + VLOG(1) << "DidOpen"; if (client_) client_->didOpenStream(handle_, max_amount_send_allowed); } @@ -124,7 +124,7 @@ void WebSocketStreamHandleImpl::Context::DidReceiveData( void WebSocketStreamHandleImpl::Context::DidClose( WebKit::WebSocketStreamHandle* web_handle) { - LOG(INFO) << "DidClose"; + VLOG(1) << "DidClose"; bridge_ = NULL; WebSocketStreamHandleImpl* handle = handle_; handle_ = NULL; @@ -151,7 +151,7 @@ WebSocketStreamHandleImpl::~WebSocketStreamHandleImpl() { void WebSocketStreamHandleImpl::connect( const WebKit::WebURL& url, WebKit::WebSocketStreamHandleClient* client) { - LOG(INFO) << "connect url=" << url; + VLOG(1) << "connect url=" << url; DCHECK(!context_->client()); context_->set_client(client); diff --git a/webkit/glue/webthemeengine_impl_linux.cc b/webkit/glue/webthemeengine_impl_linux.cc new file mode 100644 index 0000000..d5cc9b4 --- /dev/null +++ b/webkit/glue/webthemeengine_impl_linux.cc @@ -0,0 +1,100 @@ +// Copyright (c) 2010 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/webthemeengine_impl_linux.h" + +#include "gfx/native_theme_linux.h" +#include "skia/ext/platform_canvas.h" +#include "third_party/WebKit/WebKit/chromium/public/WebRect.h" +#include "third_party/WebKit/WebKit/chromium/public/WebSize.h" + +using WebKit::WebCanvas; +using WebKit::WebColor; +using WebKit::WebRect; + +namespace webkit_glue { + +static gfx::Rect WebRectToRect(const WebRect& rect) { + return gfx::Rect(rect.x, rect.y, rect.width, rect.height); +} + +static gfx::NativeThemeLinux::Part NativeThemePart( + WebKit::WebThemeEngine::Part part) { + switch (part) { + case WebKit::WebThemeEngine::PartScrollbarDownArrow: + return gfx::NativeThemeLinux::kScrollbarDownArrow; + case WebKit::WebThemeEngine::PartScrollbarLeftArrow: + return gfx::NativeThemeLinux::kScrollbarLeftArrow; + case WebKit::WebThemeEngine::PartScrollbarRightArrow: + return gfx::NativeThemeLinux::kScrollbarRightArrow; + case WebKit::WebThemeEngine::PartScrollbarUpArrow: + return gfx::NativeThemeLinux::kScrollbarUpArrow; + case WebKit::WebThemeEngine::PartScrollbarHorizontalThumb: + return gfx::NativeThemeLinux::kScrollbarHorizontalThumb; + case WebKit::WebThemeEngine::PartScrollbarVerticalThumb: + return gfx::NativeThemeLinux::kScrollbarVerticalThumb; + case WebKit::WebThemeEngine::PartScrollbarHoriztonalTrack: + return gfx::NativeThemeLinux::kScrollbarHorizontalTrack; + case WebKit::WebThemeEngine::PartScrollbarVerticalTrack: + return gfx::NativeThemeLinux::kScrollbarVerticalTrack; + default: + return gfx::NativeThemeLinux::kScrollbarDownArrow; + } +} + +static gfx::NativeThemeLinux::State NativeThemeState( + WebKit::WebThemeEngine::State state) { + switch (state) { + case WebKit::WebThemeEngine::StateDisabled: + return gfx::NativeThemeLinux::kDisabled; + case WebKit::WebThemeEngine::StateHover: + return gfx::NativeThemeLinux::kHover; + case WebKit::WebThemeEngine::StateNormal: + return gfx::NativeThemeLinux::kNormal; + case WebKit::WebThemeEngine::StatePressed: + return gfx::NativeThemeLinux::kPressed; + default: + return gfx::NativeThemeLinux::kDisabled; + } +} + +static void GetNativeThemeExtraParams( + WebKit::WebThemeEngine::Part part, + WebKit::WebThemeEngine::State state, + const WebKit::WebThemeEngine::ExtraParams* extra_params, + gfx::NativeThemeLinux::ExtraParams* native_theme_extra_params) { + if (part == WebKit::WebThemeEngine::PartScrollbarHoriztonalTrack || + part == WebKit::WebThemeEngine::PartScrollbarVerticalTrack) { + native_theme_extra_params->scrollbar_track.track_x = + extra_params->scrollbarTrack.trackX; + native_theme_extra_params->scrollbar_track.track_y = + extra_params->scrollbarTrack.trackY; + native_theme_extra_params->scrollbar_track.track_width = + extra_params->scrollbarTrack.trackWidth; + native_theme_extra_params->scrollbar_track.track_height = + extra_params->scrollbarTrack.trackHeight; + } +} + +WebKit::WebSize WebThemeEngineImpl::getSize(WebKit::WebThemeEngine::Part part) { + return gfx::NativeThemeLinux::instance()->GetSize(NativeThemePart(part)); +} + +void WebThemeEngineImpl::paint( + WebKit::WebCanvas* canvas, + WebKit::WebThemeEngine::Part part, + WebKit::WebThemeEngine::State state, + const WebKit::WebRect& rect, + const WebKit::WebThemeEngine::ExtraParams* extra_params) { + gfx::NativeThemeLinux::ExtraParams native_theme_extra_params; + GetNativeThemeExtraParams( + part, state, extra_params, &native_theme_extra_params); + gfx::NativeThemeLinux::instance()->Paint( + canvas, + NativeThemePart(part), + NativeThemeState(state), + WebRectToRect(rect), + native_theme_extra_params); +} +} // namespace webkit_glue diff --git a/webkit/glue/webthemeengine_impl_linux.h b/webkit/glue/webthemeengine_impl_linux.h new file mode 100644 index 0000000..265b80c --- /dev/null +++ b/webkit/glue/webthemeengine_impl_linux.h @@ -0,0 +1,26 @@ +// Copyright (c) 2010 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 WEBTHEMEENGINE_IMPL_LINUX_H_ +#define WEBTHEMEENGINE_IMPL_LINUX_H_ + +#include "third_party/WebKit/WebKit/chromium/public/linux/WebThemeEngine.h" + +namespace webkit_glue { + +class WebThemeEngineImpl : public WebKit::WebThemeEngine { + public: + // WebThemeEngine methods: + virtual WebKit::WebSize getSize(WebKit::WebThemeEngine::Part); + virtual void paint( + WebKit::WebCanvas*, + WebKit::WebThemeEngine::Part, + WebKit::WebThemeEngine::State, + const WebKit::WebRect&, + const WebKit::WebThemeEngine::ExtraParams*); +}; + +} // namespace webkit_glue + +#endif // WEBTHEMEENGINE_IMPL_LINUX_H_ diff --git a/webkit/glue/webthemeengine_impl_win.h b/webkit/glue/webthemeengine_impl_win.h index 533ea19..6e749c4 100644 --- a/webkit/glue/webthemeengine_impl_win.h +++ b/webkit/glue/webthemeengine_impl_win.h @@ -5,7 +5,7 @@ #ifndef WEBTHEMEENGINE_IMPL_WIN_H_ #define WEBTHEMEENGINE_IMPL_WIN_H_ -#include "third_party/WebKit/WebKit/chromium/public/WebThemeEngine.h" +#include "third_party/WebKit/WebKit/chromium/public/win/WebThemeEngine.h" namespace webkit_glue { diff --git a/webkit/glue/weburlloader_impl.cc b/webkit/glue/weburlloader_impl.cc index aa63fc2..374f132 100644 --- a/webkit/glue/weburlloader_impl.cc +++ b/webkit/glue/weburlloader_impl.cc @@ -18,6 +18,7 @@ #include "net/base/net_util.h" #include "net/http/http_response_headers.h" #include "third_party/WebKit/WebKit/chromium/public/WebHTTPHeaderVisitor.h" +#include "third_party/WebKit/WebKit/chromium/public/WebResourceRawHeaders.h" #include "third_party/WebKit/WebKit/chromium/public/WebSecurityPolicy.h" #include "third_party/WebKit/WebKit/chromium/public/WebURL.h" #include "third_party/WebKit/WebKit/chromium/public/WebURLError.h" @@ -36,6 +37,7 @@ using base::TimeDelta; using WebKit::WebData; using WebKit::WebHTTPBody; using WebKit::WebHTTPHeaderVisitor; +using WebKit::WebResourceRawHeaders; using WebKit::WebSecurityPolicy; using WebKit::WebString; using WebKit::WebURL; @@ -142,7 +144,7 @@ ResourceType::Type FromTargetType(WebURLRequest::TargetType type) { // Extracts the information from a data: url. bool GetInfoFromDataURL(const GURL& url, - ResourceLoaderBridge::ResponseInfo* info, + ResourceResponseInfo* info, std::string* data, URLRequestStatus* status) { std::string mime_type; std::string charset; @@ -163,9 +165,11 @@ bool GetInfoFromDataURL(const GURL& url, return false; } +typedef ResourceDevToolsInfo::HeadersVector HeadersVector; + void PopulateURLResponse( const GURL& url, - const ResourceLoaderBridge::ResponseInfo& info, + const ResourceResponseInfo& info, WebURLResponse* response) { response->setURL(url); response->setResponseTime(info.response_time.ToDoubleT()); @@ -188,7 +192,7 @@ void PopulateURLResponse( WebURLLoadTiming timing; timing.initialize(); - const ResourceLoaderBridge::LoadTimingInfo& timing_info = info.load_timing; + const ResourceLoadTimingInfo& timing_info = info.load_timing; timing.setRequestTime(timing_info.base_time.ToDoubleT()); timing.setProxyStart(timing_info.proxy_start); timing.setProxyEnd(timing_info.proxy_end); @@ -203,6 +207,25 @@ void PopulateURLResponse( timing.setReceiveHeadersEnd(timing_info.receive_headers_end); response->setLoadTiming(timing); + if (info.devtools_info.get()) { + WebResourceRawHeaders rawHeaders; + + const HeadersVector& request_headers = info.devtools_info->request_headers; + for (HeadersVector::const_iterator it = request_headers .begin(); + it != request_headers.end(); ++it) { + rawHeaders.addRequestHeader(WebString::fromUTF8(it->first), + WebString::fromUTF8(it->second)); + } + const HeadersVector& response_headers = + info.devtools_info->response_headers; + for (HeadersVector::const_iterator it = response_headers.begin(); + it != response_headers.end(); ++it) { + rawHeaders.addResponseHeader(WebString::fromUTF8(it->first), + WebString::fromUTF8(it->second)); + } + response->setResourceRawHeaders(rawHeaders); + } + const net::HttpResponseHeaders* headers = info.headers; if (!headers) return; @@ -258,11 +281,11 @@ class WebURLLoaderImpl::Context : public base::RefCounted<Context>, virtual void OnUploadProgress(uint64 position, uint64 size); virtual bool OnReceivedRedirect( const GURL& new_url, - const ResourceLoaderBridge::ResponseInfo& info, + const ResourceResponseInfo& info, bool* has_new_first_party_for_cookies, GURL* new_first_party_for_cookies); virtual void OnReceivedResponse( - const ResourceLoaderBridge::ResponseInfo& info, bool content_filtered); + const ResourceResponseInfo& info, bool content_filtered); virtual void OnDownloadedData(int len); virtual void OnReceivedData(const char* data, int len); virtual void OnReceivedCachedMetadata(const char* data, int len); @@ -364,6 +387,8 @@ void WebURLLoaderImpl::Context::Start( load_flags |= net::LOAD_ENABLE_UPLOAD_PROGRESS; if (request.reportLoadTiming()) load_flags |= net::LOAD_ENABLE_LOAD_TIMING; + if (request.reportRawHeaders()) + load_flags |= net::LOAD_REPORT_RAW_HEADERS; if (!request.allowCookies() || !request.allowStoredCredentials()) { load_flags |= net::LOAD_DO_NOT_SAVE_COOKIES; @@ -373,7 +398,6 @@ void WebURLLoaderImpl::Context::Start( if (!request.allowStoredCredentials()) load_flags |= net::LOAD_DO_NOT_SEND_AUTH_DATA; - // TODO(jcampan): in the non out-of-process plugin case the request does not // have a requestor_pid. Find a better place to set this. int requestor_pid = request.requestorProcessID(); @@ -464,7 +488,7 @@ void WebURLLoaderImpl::Context::OnUploadProgress(uint64 position, uint64 size) { bool WebURLLoaderImpl::Context::OnReceivedRedirect( const GURL& new_url, - const ResourceLoaderBridge::ResponseInfo& info, + const ResourceResponseInfo& info, bool* has_new_first_party_for_cookies, GURL* new_first_party_for_cookies) { if (!client_) @@ -478,6 +502,7 @@ bool WebURLLoaderImpl::Context::OnReceivedRedirect( // request that resulted from the redirect. WebURLRequest new_request(new_url); new_request.setFirstPartyForCookies(request_.firstPartyForCookies()); + new_request.setDownloadToFile(request_.downloadToFile()); WebString referrer_string = WebString::fromUTF8("Referer"); WebString referrer = request_.httpHeaderField(referrer_string); @@ -503,7 +528,7 @@ bool WebURLLoaderImpl::Context::OnReceivedRedirect( } void WebURLLoaderImpl::Context::OnReceivedResponse( - const ResourceLoaderBridge::ResponseInfo& info, + const ResourceResponseInfo& info, bool content_filtered) { if (!client_) return; @@ -638,7 +663,7 @@ GURL WebURLLoaderImpl::Context::GetURLForDebugging() const { } void WebURLLoaderImpl::Context::HandleDataURL() { - ResourceLoaderBridge::ResponseInfo info; + ResourceResponseInfo info; URLRequestStatus status; std::string data; diff --git a/webkit/glue/webvideoframe_impl.cc b/webkit/glue/webvideoframe_impl.cc index f50eded..bfb1d53 100644 --- a/webkit/glue/webvideoframe_impl.cc +++ b/webkit/glue/webvideoframe_impl.cc @@ -25,6 +25,8 @@ WebVideoFrameImpl::WebVideoFrameImpl( : video_frame_(video_frame) { } +WebVideoFrameImpl::~WebVideoFrameImpl() {} + #define COMPILE_ASSERT_MATCHING_ENUM(webkit_name, chromium_name) \ COMPILE_ASSERT(int(WebKit::WebVideoFrame::webkit_name) == \ int(media::VideoFrame::chromium_name), \ @@ -90,7 +92,7 @@ const void* WebVideoFrameImpl::data(unsigned plane) const { unsigned WebVideoFrameImpl::texture(unsigned plane) const { if (video_frame_.get()) return video_frame_->gl_texture(plane); - return NULL; + return 0; } } // namespace webkit_glue diff --git a/webkit/glue/webvideoframe_impl.h b/webkit/glue/webvideoframe_impl.h index dfaac03..5454089 100644 --- a/webkit/glue/webvideoframe_impl.h +++ b/webkit/glue/webvideoframe_impl.h @@ -18,6 +18,7 @@ class WebVideoFrameImpl : public WebVideoFrame { static media::VideoFrame* toVideoFrame(WebVideoFrame* web_video_frame); WebVideoFrameImpl(scoped_refptr<media::VideoFrame> video_frame); + virtual ~WebVideoFrameImpl(); virtual WebVideoFrame::SurfaceType surfaceType() const; virtual WebVideoFrame::Format format() const; virtual unsigned width() const; |