diff options
author | Ben Murdoch <benm@google.com> | 2010-11-18 18:32:45 +0000 |
---|---|---|
committer | Ben Murdoch <benm@google.com> | 2010-11-18 18:38:07 +0000 |
commit | 513209b27ff55e2841eac0e4120199c23acce758 (patch) | |
tree | aeba30bb08c5f47c57003544e378a377c297eee6 /webkit/glue | |
parent | 164f7496de0fbee436b385a79ead9e3cb81a50c1 (diff) | |
download | external_chromium-513209b27ff55e2841eac0e4120199c23acce758.zip external_chromium-513209b27ff55e2841eac0e4120199c23acce758.tar.gz external_chromium-513209b27ff55e2841eac0e4120199c23acce758.tar.bz2 |
Merge Chromium at r65505: Initial merge by git.
Change-Id: I31d8f1d8cd33caaf7f47ffa7350aef42d5fbdb45
Diffstat (limited to 'webkit/glue')
115 files changed, 2465 insertions, 1247 deletions
diff --git a/webkit/glue/dom_operations.cc b/webkit/glue/dom_operations.cc index aab6f36..2d0fb68 100644 --- a/webkit/glue/dom_operations.cc +++ b/webkit/glue/dom_operations.cc @@ -9,30 +9,28 @@ #include "base/compiler_specific.h" #include "base/string_number_conversions.h" #include "base/string_split.h" +#include "base/string_util.h" #include "third_party/WebKit/WebKit/chromium/public/WebAnimationController.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/WebFormElement.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/WebNode.h" #include "third_party/WebKit/WebKit/chromium/public/WebNodeCollection.h" #include "third_party/WebKit/WebKit/chromium/public/WebNodeList.h" +#include "third_party/WebKit/WebKit/chromium/public/WebString.h" #include "third_party/WebKit/WebKit/chromium/public/WebVector.h" #include "third_party/WebKit/WebKit/chromium/public/WebView.h" -#include "webkit/glue/form_data.h" -#include "webkit/glue/password_form_dom_manager.h" -#include "webkit/glue/webpasswordautocompletelistener_impl.h" using WebKit::WebAnimationController; using WebKit::WebDocument; using WebKit::WebElement; -using WebKit::WebFormElement; using WebKit::WebFrame; using WebKit::WebInputElement; using WebKit::WebNode; using WebKit::WebNodeCollection; using WebKit::WebNodeList; +using WebKit::WebString; using WebKit::WebVector; using WebKit::WebView; @@ -153,163 +151,6 @@ void GetAllSavableResourceLinksForFrame(WebFrame* current_frame, namespace webkit_glue { -// Map element name to a list of pointers to corresponding elements to simplify -// form filling. -typedef std::map<string16, WebKit::WebInputElement> - FormInputElementMap; - -// Utility struct for form lookup and autofill. When we parse the DOM to lookup -// a form, in addition to action and origin URL's we have to compare all -// necessary form elements. To avoid having to look these up again when we want -// to fill the form, the FindFormElements function stores the pointers -// in a FormElements* result, referenced to ensure they are safe to use. -struct FormElements { - WebFormElement form_element; - FormInputElementMap input_elements; - FormElements() { - } -}; - -typedef std::vector<FormElements*> FormElementsList; - -// Internal implementation of FillForm API. -static bool FillFormImpl(FormElements* fe, const FormData& data) { - if (!fe->form_element.autoComplete()) - return false; - - std::map<string16, string16> data_map; - for (size_t i = 0; i < data.fields.size(); i++) - data_map[data.fields[i].name()] = data.fields[i].value(); - - for (FormInputElementMap::iterator it = fe->input_elements.begin(); - it != fe->input_elements.end(); ++it) { - WebKit::WebInputElement& element = it->second; - if (!element.value().isEmpty()) // Don't overwrite pre-filled values. - continue; - if (element.isPasswordField() && - (!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(); - } - - return false; -} - -// Helper to search the given form element for the specified input elements -// in |data|, and add results to |result|. -static bool FindFormInputElements(WebFormElement* fe, - const FormData& data, - FormElements* result) { - // Loop through the list of elements we need to find on the form in - // order to autofill it. If we don't find any one of them, abort - // processing this form; it can't be the right one. - for (size_t j = 0; j < data.fields.size(); j++) { - WebVector<WebNode> temp_elements; - fe->getNamedElements(data.fields[j].name(), temp_elements); - if (temp_elements.isEmpty()) { - // We didn't find a required element. This is not the right form. - // Make sure no input elements from a partially matched form - // in this iteration remain in the result set. - // Note: clear will remove a reference from each InputElement. - result->input_elements.clear(); - return false; - } - // This element matched, add it to our temporary result. It's possible - // there are multiple matches, but for purposes of identifying the form - // one suffices and if some function needs to deal with multiple - // matching elements it can get at them through the FormElement*. - // Note: This assignment adds a reference to the InputElement. - result->input_elements[data.fields[j].name()] = - temp_elements[0].to<WebInputElement>(); - } - return true; -} - -// Helper to locate form elements identified by |data|. -static void FindFormElements(WebView* view, - const FormData& data, - FormElementsList* results) { - DCHECK(view); - DCHECK(results); - WebFrame* main_frame = view->mainFrame(); - if (!main_frame) - return; - - GURL::Replacements rep; - rep.ClearQuery(); - rep.ClearRef(); - - // Loop through each frame. - for (WebFrame* f = main_frame; f; f = f->traverseNext(false)) { - WebDocument doc = f->document(); - if (!doc.isHTMLDocument()) - continue; - - GURL full_origin(f->url()); - if (data.origin != full_origin.ReplaceComponents(rep)) - continue; - - WebVector<WebFormElement> forms; - f->forms(forms); - - for (size_t i = 0; i < forms.size(); ++i) { - WebFormElement fe = forms[i]; - // Action URL must match. - GURL full_action(f->document().completeURL(fe.action())); - if (data.action != full_action.ReplaceComponents(rep)) - continue; - - scoped_ptr<FormElements> curr_elements(new FormElements); - if (!FindFormInputElements(&fe, data, curr_elements.get())) - continue; - - // We found the right element. - // Note: this assignment adds a reference to |fe|. - curr_elements->form_element = fe; - results->push_back(curr_elements.release()); - } - } -} - -void FillPasswordForm(WebView* view, - const PasswordFormFillData& data) { - FormElementsList forms; - // We own the FormElements* in forms. - FindFormElements(view, data.basic_data, &forms); - FormElementsList::iterator iter; - for (iter = forms.begin(); iter != forms.end(); ++iter) { - scoped_ptr<FormElements> form_elements(*iter); - - // If wait_for_username is true, we don't want to initially fill the form - // until the user types in a valid username. - if (!data.wait_for_username) - FillFormImpl(form_elements.get(), data.basic_data); - - // Attach autocomplete listener to enable selecting alternate logins. - // First, get pointers to username element. - WebInputElement username_element = - form_elements->input_elements[data.basic_data.fields[0].name()]; - - // Get pointer to password element. (We currently only support single - // password forms). - WebInputElement password_element = - form_elements->input_elements[data.basic_data.fields[1].name()]; - - username_element.document().frame()->registerPasswordListener( - username_element, - new WebPasswordAutocompleteListenerImpl( - new WebInputElementDelegate(username_element), - new WebInputElementDelegate(password_element), - data)); - } -} - WebString GetSubResourceLinkFromElement(const WebElement& element) { const char* attribute_name = NULL; if (element.hasTagName("img") || diff --git a/webkit/glue/dom_operations.h b/webkit/glue/dom_operations.h index 1b6151b..951eb0f 100644 --- a/webkit/glue/dom_operations.h +++ b/webkit/glue/dom_operations.h @@ -21,13 +21,6 @@ class WebView; // A collection of operations that access the underlying WebKit DOM directly. namespace webkit_glue { -struct PasswordFormFillData; - -// Fill matching password forms and trigger autocomplete in the case of multiple -// matching logins. -void FillPasswordForm(WebKit::WebView* view, - const PasswordFormFillData& data); - // Structure for storage the result of getting all savable resource links // for current page. The consumer of the SavableResourcesResult is responsible // for keeping these pointers valid for the lifetime of the diff --git a/webkit/glue/media/buffered_data_source.cc b/webkit/glue/media/buffered_data_source.cc index 3456e3a..29c86ac 100644 --- a/webkit/glue/media/buffered_data_source.cc +++ b/webkit/glue/media/buffered_data_source.cc @@ -15,6 +15,7 @@ #include "net/http/http_response_headers.h" #include "webkit/glue/media/buffered_data_source.h" #include "webkit/glue/webkit_glue.h" +#include "webkit/glue/webmediaplayer_impl.h" namespace { @@ -126,7 +127,7 @@ void BufferedResourceLoader::Start(net::CompletionCallback* start_callback, bridge_.reset( bridge_factory_->CreateBridge( url_, - IsMediaCacheEnabled() ? net::LOAD_NORMAL : net::LOAD_BYPASS_CACHE, + net::LOAD_NORMAL, first_byte_position_, last_byte_position_)); @@ -521,31 +522,14 @@ void BufferedResourceLoader::NotifyNetworkEvent() { } ///////////////////////////////////////////////////////////////////////////// -// BufferedDataSource, static methods -bool BufferedDataSource::IsMediaFormatSupported( - const media::MediaFormat& media_format) { - std::string mime_type; - std::string url; - if (media_format.GetAsString(media::MediaFormat::kMimeType, &mime_type) && - media_format.GetAsString(media::MediaFormat::kURL, &url)) { - GURL gurl(url); - - // This data source doesn't support data:// protocol, so reject it - // explicitly. - if (IsProtocolSupportedForMedia(gurl) && !IsDataProtocol(gurl)) - return true; - } - return false; -} - -///////////////////////////////////////////////////////////////////////////// -// BufferedDataSource, protected +// BufferedDataSource BufferedDataSource::BufferedDataSource( MessageLoop* render_loop, webkit_glue::MediaResourceLoaderBridgeFactory* bridge_factory) : total_bytes_(kPositionNotSpecified), loaded_(false), streaming_(false), + single_origin_(true), bridge_factory_(bridge_factory), loader_(NULL), network_activity_(false), @@ -614,6 +598,13 @@ void BufferedDataSource::Initialize(const std::string& url, NewRunnableMethod(this, &BufferedDataSource::InitializeTask)); } +bool BufferedDataSource::IsUrlSupported(const std::string& url) { + GURL gurl(url); + + // This data source doesn't support data:// protocol so reject it. + return IsProtocolSupportedForMedia(gurl) && !IsDataProtocol(gurl); +} + void BufferedDataSource::Stop(media::FilterCallback* callback) { { AutoLock auto_lock(lock_); @@ -623,6 +614,7 @@ void BufferedDataSource::Stop(media::FilterCallback* callback) { callback->Run(); delete callback; } + render_loop_->PostTask(FROM_HERE, NewRunnableMethod(this, &BufferedDataSource::CleanupTask)); } @@ -655,6 +647,25 @@ bool BufferedDataSource::IsStreaming() { return streaming_; } +bool BufferedDataSource::HasSingleOrigin() { + DCHECK(MessageLoop::current() == render_loop_); + return single_origin_; +} + +void BufferedDataSource::Abort() { + DCHECK(MessageLoop::current() == render_loop_); + + // If we are told to abort, immediately return from any pending read + // with an error. + if (read_callback_.get()) { + { + AutoLock auto_lock(lock_); + DoneRead_Locked(net::ERR_FAILED); + } + CleanupTask(); + } +} + ///////////////////////////////////////////////////////////////////////////// // BufferedDataSource, render thread tasks void BufferedDataSource::InitializeTask() { @@ -720,7 +731,10 @@ void BufferedDataSource::ReadTask( void BufferedDataSource::CleanupTask() { DCHECK(MessageLoop::current() == render_loop_); - DCHECK(!stopped_on_render_loop_); + + // If we have already stopped, do nothing. + if (stopped_on_render_loop_) + return; // Stop the watch dog. watch_dog_timer_.Stop(); @@ -865,6 +879,9 @@ void BufferedDataSource::HttpInitialStartCallback(int error) { DCHECK(MessageLoop::current() == render_loop_); DCHECK(loader_.get()); + // Check if the request ended up at a different origin via redirect. + single_origin_ = url_.GetOrigin() == loader_->url().GetOrigin(); + int64 instance_size = loader_->instance_size(); bool partial_response = loader_->partial_response(); bool success = error == net::OK; @@ -929,6 +946,9 @@ void BufferedDataSource::NonHttpInitialStartCallback(int error) { DCHECK(MessageLoop::current() == render_loop_); DCHECK(loader_.get()); + // Check if the request ended up at a different origin via redirect. + single_origin_ = url_.GetOrigin() == loader_->url().GetOrigin(); + int64 instance_size = loader_->instance_size(); bool success = error == net::OK && instance_size != kPositionNotSpecified; diff --git a/webkit/glue/media/buffered_data_source.h b/webkit/glue/media/buffered_data_source.h index e7b2e47..2af9e84 100644 --- a/webkit/glue/media/buffered_data_source.h +++ b/webkit/glue/media/buffered_data_source.h @@ -13,7 +13,6 @@ #include "base/timer.h" #include "base/condition_variable.h" #include "googleurl/src/gurl.h" -#include "media/base/factory.h" #include "media/base/filters.h" #include "media/base/media_format.h" #include "media/base/pipeline.h" @@ -21,6 +20,8 @@ #include "net/base/completion_callback.h" #include "net/base/file_stream.h" #include "webkit/glue/media/media_resource_loader_bridge_factory.h" +#include "webkit/glue/media/web_data_source.h" +#include "webkit/glue/webmediaplayer_impl.h" namespace webkit_glue { ///////////////////////////////////////////////////////////////////////////// @@ -105,6 +106,9 @@ class BufferedResourceLoader : // Returns true if network is currently active. virtual bool network_activity() { return !completed_ && !deferred_; } + // Returns resulting URL. + virtual const GURL& url() { return url_; } + ///////////////////////////////////////////////////////////////////////////// // webkit_glue::ResourceLoaderBridge::Peer implementations. virtual void OnUploadProgress(uint64 position, uint64 size) {} @@ -122,7 +126,6 @@ class BufferedResourceLoader : const URLRequestStatus& status, const std::string& security_info, const base::Time& completion_time); - GURL GetURLForDebugging() const { return url_; } protected: friend class base::RefCountedThreadSafe<BufferedResourceLoader>; @@ -212,27 +215,18 @@ class BufferedResourceLoader : DISALLOW_COPY_AND_ASSIGN(BufferedResourceLoader); }; -class BufferedDataSource : public media::DataSource { +class BufferedDataSource : public WebDataSource { public: - // Methods called from pipeline thread - // Static methods for creating this class. - static media::FilterFactory* CreateFactory( - MessageLoop* message_loop, - webkit_glue::MediaResourceLoaderBridgeFactory* bridge_factory) { - return new media::FilterFactoryImpl2< - BufferedDataSource, - MessageLoop*, - webkit_glue::MediaResourceLoaderBridgeFactory*>( - message_loop, bridge_factory); - } + BufferedDataSource( + MessageLoop* render_loop, + webkit_glue::MediaResourceLoaderBridgeFactory* bridge_factory); - // media::FilterFactoryImpl2 implementation. - static bool IsMediaFormatSupported( - const media::MediaFormat& media_format); + virtual ~BufferedDataSource(); // media::MediaFilter implementation. virtual void Initialize(const std::string& url, media::FilterCallback* callback); + virtual bool IsUrlSupported(const std::string& url); virtual void Stop(media::FilterCallback* callback); virtual void SetPlaybackRate(float playback_rate); @@ -248,11 +242,11 @@ class BufferedDataSource : public media::DataSource { return media_format_; } + // webkit_glue::WebDataSource implementation. + virtual bool HasSingleOrigin(); + virtual void Abort(); + protected: - BufferedDataSource( - MessageLoop* render_loop, - webkit_glue::MediaResourceLoaderBridgeFactory* bridge_factory); - virtual ~BufferedDataSource(); // A factory method to create a BufferedResourceLoader based on the read // parameters. We can override this file to object a mock @@ -266,11 +260,6 @@ class BufferedDataSource : public media::DataSource { virtual base::TimeDelta GetTimeoutMilliseconds(); private: - friend class media::FilterFactoryImpl2< - BufferedDataSource, - MessageLoop*, - webkit_glue::MediaResourceLoaderBridgeFactory*>; - // Posted to perform initialization on render thread and start resource // loading. void InitializeTask(); @@ -349,6 +338,9 @@ class BufferedDataSource : public media::DataSource { // i.e. range request is not supported. bool streaming_; + // True if the media resource has a single origin. + bool single_origin_; + // A factory object to produce ResourceLoaderBridge. scoped_ptr<webkit_glue::MediaResourceLoaderBridgeFactory> bridge_factory_; diff --git a/webkit/glue/media/buffered_data_source_unittest.cc b/webkit/glue/media/buffered_data_source_unittest.cc index f032595..81103b2 100644 --- a/webkit/glue/media/buffered_data_source_unittest.cc +++ b/webkit/glue/media/buffered_data_source_unittest.cc @@ -27,6 +27,7 @@ using ::testing::Invoke; using ::testing::InvokeWithoutArgs; using ::testing::NotNull; using ::testing::Return; +using ::testing::ReturnRef; using ::testing::SetArgumentPointee; using ::testing::StrictMock; using ::testing::NiceMock; @@ -79,7 +80,6 @@ class BufferedResourceLoaderTest : public testing::Test { loader_ = new BufferedResourceLoader(&bridge_factory_, gurl_, first_position_, last_position_); - EXPECT_EQ(gurl_.spec(), loader_->GetURLForDebugging().spec()); } void SetLoaderBuffer(size_t forward_capacity, size_t backward_capacity) { @@ -526,6 +526,7 @@ class MockBufferedResourceLoader : public BufferedResourceLoader { MOCK_METHOD0(instance_size, int64()); MOCK_METHOD0(partial_response, bool()); MOCK_METHOD0(network_activity, bool()); + MOCK_METHOD0(url, const GURL&()); MOCK_METHOD0(GetBufferedFirstBytePosition, int64()); MOCK_METHOD0(GetBufferedLastBytePosition, int64()); @@ -539,15 +540,9 @@ class MockBufferedResourceLoader : public BufferedResourceLoader { // CreateResourceLoader() method. class MockBufferedDataSource : public BufferedDataSource { public: - // Static methods for creating this class. - static media::FilterFactory* CreateFactory( - MessageLoop* message_loop, - MediaResourceLoaderBridgeFactory* bridge_factory) { - return new media::FilterFactoryImpl2< - MockBufferedDataSource, - MessageLoop*, - MediaResourceLoaderBridgeFactory*>(message_loop, - bridge_factory); + MockBufferedDataSource( + MessageLoop* message_loop, MediaResourceLoaderBridgeFactory* factory) + : BufferedDataSource(message_loop, factory) { } virtual base::TimeDelta GetTimeoutMilliseconds() { @@ -558,18 +553,7 @@ class MockBufferedDataSource : public BufferedDataSource { MOCK_METHOD2(CreateResourceLoader, BufferedResourceLoader*( int64 first_position, int64 last_position)); - protected: - MockBufferedDataSource( - MessageLoop* message_loop, MediaResourceLoaderBridgeFactory* factory) - : BufferedDataSource(message_loop, factory) { - } - private: - friend class media::FilterFactoryImpl2< - MockBufferedDataSource, - MessageLoop*, - MediaResourceLoaderBridgeFactory*>; - DISALLOW_COPY_AND_ASSIGN(MockBufferedDataSource); }; @@ -579,8 +563,6 @@ class BufferedDataSourceTest : public testing::Test { message_loop_ = MessageLoop::current(); bridge_factory_.reset( new StrictMock<MockMediaResourceLoaderBridgeFactory>()); - factory_ = MockBufferedDataSource::CreateFactory(message_loop_, - bridge_factory_.get()); // Prepare test data. for (size_t i = 0; i < sizeof(data_); ++i) { @@ -619,14 +601,15 @@ class BufferedDataSourceTest : public testing::Test { url_format.SetAsString(media::MediaFormat::kMimeType, media::mime_type::kURL); url_format.SetAsString(media::MediaFormat::kURL, url); - data_source_ = factory_->Create<MockBufferedDataSource>(url_format); + data_source_ = new MockBufferedDataSource(MessageLoop::current(), + bridge_factory_.get()); CHECK(data_source_); // 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>(); + scoped_refptr<NiceMock<MockBufferedResourceLoader> > first_loader( + new NiceMock<MockBufferedResourceLoader>()); // Creates the mock loader to be injected. loader_ = first_loader; @@ -641,6 +624,8 @@ class BufferedDataSourceTest : public testing::Test { // to be created. if (partial_response && (error == net::ERR_INVALID_RESPONSE)) { // Verify that the initial loader is stopped. + EXPECT_CALL(*loader_, url()) + .WillRepeatedly(ReturnRef(gurl_)); EXPECT_CALL(*loader_, Stop()); // Replace loader_ with a new instance. @@ -655,11 +640,18 @@ class BufferedDataSourceTest : public testing::Test { } } + // Attach a static function that deletes the memory referred by the + // "callback" parameter. + ON_CALL(*loader_, Read(_, _, _ , _)) + .WillByDefault(DeleteArg<3>()); + StrictMock<media::MockFilterCallback> callback; - EXPECT_CALL(*loader_, instance_size()) - .WillRepeatedly(Return(instance_size)); - EXPECT_CALL(*loader_, partial_response()) - .WillRepeatedly(Return(partial_response)); + ON_CALL(*loader_, instance_size()) + .WillByDefault(Return(instance_size)); + ON_CALL(*loader_, partial_response()) + .WillByDefault(Return(partial_response)); + ON_CALL(*loader_, url()) + .WillByDefault(ReturnRef(gurl_)); if (initialized_ok) { // Expected loaded or not. EXPECT_CALL(host_, SetLoaded(loaded)); @@ -757,6 +749,27 @@ class BufferedDataSourceTest : public testing::Test { memcmp(buffer_, data_ + static_cast<int>(position), read_size)); } + void ReadDataSourceHang(int64 position, int size) { + EXPECT_TRUE(loader_); + + // Expect a call to read, but the call never returns. + EXPECT_CALL(*loader_, Read(position, size, NotNull(), NotNull())); + data_source_->Read( + position, size, buffer_, + NewCallback(this, &BufferedDataSourceTest::ReadCallback)); + message_loop_->RunAllPending(); + + // Now expect the read to return after aborting the data source. + EXPECT_CALL(*this, ReadCallback(_)); + EXPECT_CALL(*loader_, Stop()); + data_source_->Abort(); + message_loop_->RunAllPending(); + + // The loader has now been stopped. Set this to null so that when the + // DataSource is stopped, it does not expect a call to stop the loader. + loader_ = NULL; + } + void ReadDataSourceMiss(int64 position, int size) { EXPECT_TRUE(loader_); @@ -880,7 +893,6 @@ class BufferedDataSourceTest : public testing::Test { bridge_factory_; scoped_refptr<NiceMock<MockBufferedResourceLoader> > loader_; scoped_refptr<MockBufferedDataSource> data_source_; - scoped_refptr<media::FilterFactory> factory_; StrictMock<media::MockFilterHost> host_; GURL gurl_; @@ -946,6 +958,12 @@ TEST_F(BufferedDataSourceTest, ReadCacheMiss) { StopDataSource(); } +TEST_F(BufferedDataSourceTest, ReadHang) { + InitializeDataSource(kHttpUrl, net::OK, true, 25, LOADING); + ReadDataSourceHang(10, 10); + StopDataSource(); +} + TEST_F(BufferedDataSourceTest, ReadFailed) { InitializeDataSource(kHttpUrl, net::OK, true, 1024, LOADING); ReadDataSourceHit(10, 10, 10); diff --git a/webkit/glue/media/simple_data_source.cc b/webkit/glue/media/simple_data_source.cc index 0b09edf..291928e 100644 --- a/webkit/glue/media/simple_data_source.cc +++ b/webkit/glue/media/simple_data_source.cc @@ -28,25 +28,13 @@ bool IsDataProtocol(const GURL& url) { namespace webkit_glue { -bool SimpleDataSource::IsMediaFormatSupported( - const media::MediaFormat& media_format) { - std::string mime_type; - std::string url; - if (media_format.GetAsString(media::MediaFormat::kMimeType, &mime_type) && - media_format.GetAsString(media::MediaFormat::kURL, &url)) { - GURL gurl(url); - if (IsProtocolSupportedForMedia(gurl)) - return true; - } - return false; -} - SimpleDataSource::SimpleDataSource( MessageLoop* render_loop, webkit_glue::MediaResourceLoaderBridgeFactory* bridge_factory) : render_loop_(render_loop), bridge_factory_(bridge_factory), size_(-1), + single_origin_(true), state_(UNINITIALIZED) { DCHECK(render_loop); } @@ -125,7 +113,9 @@ bool SimpleDataSource::OnReceivedRedirect( const webkit_glue::ResourceResponseInfo& info, bool* has_new_first_party_for_cookies, GURL* new_first_party_for_cookies) { - SetURL(new_url); + DCHECK(MessageLoop::current() == render_loop_); + single_origin_ = url_.GetOrigin() == new_url.GetOrigin(); + // TODO(wtc): should we return a new first party for cookies URL? *has_new_first_party_for_cookies = false; return true; @@ -134,22 +124,24 @@ bool SimpleDataSource::OnReceivedRedirect( void SimpleDataSource::OnReceivedResponse( const webkit_glue::ResourceResponseInfo& info, bool content_filtered) { + DCHECK(MessageLoop::current() == render_loop_); size_ = info.content_length; } void SimpleDataSource::OnReceivedData(const char* data, int len) { + DCHECK(MessageLoop::current() == render_loop_); data_.append(data, len); } void SimpleDataSource::OnCompletedRequest(const URLRequestStatus& status, const std::string& security_info, const base::Time& completion_time) { + DCHECK(MessageLoop::current() == render_loop_); AutoLock auto_lock(lock_); // It's possible this gets called after Stop(), in which case |host_| is no // longer valid. - if (state_ == STOPPED) { + if (state_ == STOPPED) return; - } // Otherwise we should be initializing and have created a bridge. DCHECK_EQ(state_, INITIALIZING); @@ -158,16 +150,21 @@ void SimpleDataSource::OnCompletedRequest(const URLRequestStatus& status, // If we don't get a content length or the request has failed, report it // as a network error. - DCHECK(size_ == -1 || static_cast<size_t>(size_) == data_.length()); - if (size_ == -1) { + if (size_ == -1) size_ = data_.length(); - } + DCHECK(static_cast<size_t>(size_) == data_.length()); DoneInitialization_Locked(status.is_success()); } -GURL SimpleDataSource::GetURLForDebugging() const { - return url_; +bool SimpleDataSource::HasSingleOrigin() { + DCHECK(MessageLoop::current() == render_loop_); + return single_origin_; +} + +void SimpleDataSource::Abort() { + DCHECK(MessageLoop::current() == render_loop_); + NOTIMPLEMENTED(); } void SimpleDataSource::SetURL(const GURL& url) { @@ -179,8 +176,8 @@ void SimpleDataSource::SetURL(const GURL& url) { } void SimpleDataSource::StartTask() { - AutoLock auto_lock(lock_); DCHECK(MessageLoop::current() == render_loop_); + AutoLock auto_lock(lock_); // We may have stopped. if (state_ == STOPPED) @@ -205,6 +202,7 @@ void SimpleDataSource::StartTask() { } void SimpleDataSource::CancelTask() { + DCHECK(MessageLoop::current() == render_loop_); AutoLock auto_lock(lock_); DCHECK_EQ(state_, STOPPED); diff --git a/webkit/glue/media/simple_data_source.h b/webkit/glue/media/simple_data_source.h index d649c0d..ff1e247 100644 --- a/webkit/glue/media/simple_data_source.h +++ b/webkit/glue/media/simple_data_source.h @@ -12,31 +12,22 @@ #include "base/message_loop.h" #include "base/scoped_ptr.h" -#include "media/base/factory.h" #include "media/base/filters.h" #include "webkit/glue/media/media_resource_loader_bridge_factory.h" +#include "webkit/glue/media/web_data_source.h" class MessageLoop; class WebMediaPlayerDelegateImpl; namespace webkit_glue { -class SimpleDataSource : public media::DataSource, +class SimpleDataSource : public WebDataSource, public webkit_glue::ResourceLoaderBridge::Peer { public: - static media::FilterFactory* CreateFactory( - MessageLoop* message_loop, - webkit_glue::MediaResourceLoaderBridgeFactory* bridge_factory) { - return new media::FilterFactoryImpl2< - SimpleDataSource, - MessageLoop*, - webkit_glue::MediaResourceLoaderBridgeFactory*>(message_loop, - bridge_factory); - } - - // media::FilterFactoryImpl2 implementation. - static bool IsMediaFormatSupported( - const media::MediaFormat& media_format); + SimpleDataSource( + MessageLoop* render_loop, + webkit_glue::MediaResourceLoaderBridgeFactory* bridge_factory); + virtual ~SimpleDataSource(); // MediaFilter implementation. virtual void Stop(media::FilterCallback* callback); @@ -65,18 +56,12 @@ class SimpleDataSource : public media::DataSource, virtual void OnCompletedRequest(const URLRequestStatus& status, const std::string& security_info, const base::Time& completion_time); - virtual GURL GetURLForDebugging() const; - private: - friend class media::FilterFactoryImpl2< - SimpleDataSource, - MessageLoop*, - webkit_glue::MediaResourceLoaderBridgeFactory*>; - SimpleDataSource( - MessageLoop* render_loop, - webkit_glue::MediaResourceLoaderBridgeFactory* bridge_factory); - virtual ~SimpleDataSource(); + // webkit_glue::WebDataSource implementation. + virtual bool HasSingleOrigin(); + virtual void Abort(); + private: // Updates |url_| and |media_format_| with the given URL. void SetURL(const GURL& url); @@ -102,6 +87,7 @@ class SimpleDataSource : public media::DataSource, GURL url_; std::string data_; int64 size_; + bool single_origin_; // Simple state tracking variable. enum State { diff --git a/webkit/glue/media/simple_data_source_unittest.cc b/webkit/glue/media/simple_data_source_unittest.cc index 50c8910..537798f 100644 --- a/webkit/glue/media/simple_data_source_unittest.cc +++ b/webkit/glue/media/simple_data_source_unittest.cc @@ -42,8 +42,6 @@ class SimpleDataSourceTest : public testing::Test { bridge_factory_.reset( new NiceMock<MockMediaResourceLoaderBridgeFactory>()); bridge_.reset(new NiceMock<MockResourceLoaderBridge>()); - factory_ = SimpleDataSource::CreateFactory(MessageLoop::current(), - bridge_factory_.get()); for (int i = 0; i < kDataSize; ++i) { data_[i] = i; @@ -58,11 +56,8 @@ class SimpleDataSourceTest : public testing::Test { } void InitializeDataSource(const char* url) { - media::MediaFormat url_format; - url_format.SetAsString(media::MediaFormat::kMimeType, - media::mime_type::kURL); - url_format.SetAsString(media::MediaFormat::kURL, url); - data_source_ = factory_->Create<SimpleDataSource>(url_format); + data_source_ = new SimpleDataSource(MessageLoop::current(), + bridge_factory_.get()); CHECK(data_source_); // There is no need to provide a message loop to data source. @@ -167,7 +162,6 @@ class SimpleDataSourceTest : public testing::Test { scoped_ptr<MessageLoop> message_loop_; scoped_ptr<NiceMock<MockMediaResourceLoaderBridgeFactory> > bridge_factory_; scoped_ptr<NiceMock<MockResourceLoaderBridge> > bridge_; - scoped_refptr<media::FilterFactory> factory_; scoped_refptr<SimpleDataSource> data_source_; StrictMock<media::MockFilterHost> host_; StrictMock<media::MockFilterCallback> callback_; @@ -195,11 +189,9 @@ TEST_F(SimpleDataSourceTest, InitializeFile) { } TEST_F(SimpleDataSourceTest, InitializeData) { - media::MediaFormat url_format; - url_format.SetAsString(media::MediaFormat::kMimeType, - media::mime_type::kURL); - url_format.SetAsString(media::MediaFormat::kURL, kDataUrl); - data_source_ = factory_->Create<SimpleDataSource>(url_format); + data_source_ = new SimpleDataSource(MessageLoop::current(), + bridge_factory_.get()); + EXPECT_TRUE(data_source_->IsUrlSupported(kDataUrl)); CHECK(data_source_); // There is no need to provide a message loop to data source. @@ -217,15 +209,6 @@ TEST_F(SimpleDataSourceTest, InitializeData) { DestroyDataSource(); } -TEST_F(SimpleDataSourceTest, InitializeInvalid) { - media::MediaFormat url_format; - url_format.SetAsString(media::MediaFormat::kMimeType, - media::mime_type::kURL); - url_format.SetAsString(media::MediaFormat::kURL, kInvalidUrl); - data_source_ = factory_->Create<SimpleDataSource>(url_format); - EXPECT_FALSE(data_source_); -} - TEST_F(SimpleDataSourceTest, RequestFailed) { InitializeDataSource(kHttpUrl); RequestFailed(); diff --git a/webkit/glue/media/video_renderer_impl.cc b/webkit/glue/media/video_renderer_impl.cc index 16c9ef6..3bbd626 100644 --- a/webkit/glue/media/video_renderer_impl.cc +++ b/webkit/glue/media/video_renderer_impl.cc @@ -10,33 +10,13 @@ namespace webkit_glue { -VideoRendererImpl::VideoRendererImpl(WebMediaPlayerImpl::Proxy* proxy, - bool pts_logging) - : proxy_(proxy), - last_converted_frame_(NULL), +VideoRendererImpl::VideoRendererImpl(bool pts_logging) + : last_converted_frame_(NULL), pts_logging_(pts_logging) { - // TODO(hclam): decide whether to do the following line in this thread or - // in the render thread. - proxy_->SetVideoRenderer(this); } VideoRendererImpl::~VideoRendererImpl() {} -// static -media::FilterFactory* VideoRendererImpl::CreateFactory( - WebMediaPlayerImpl::Proxy* proxy, - bool pts_logging) { - return new media::FilterFactoryImpl2<VideoRendererImpl, - WebMediaPlayerImpl::Proxy*, - bool>(proxy, pts_logging); -} - -// static -bool VideoRendererImpl::IsMediaFormatSupported( - const media::MediaFormat& media_format) { - return ParseMediaFormat(media_format, NULL, NULL, NULL, NULL); -} - bool VideoRendererImpl::OnInitialize(media::VideoDecoder* decoder) { video_size_.SetSize(width(), height()); bitmap_.setConfig(SkBitmap::kARGB_8888_Config, width(), height()); @@ -60,6 +40,11 @@ void VideoRendererImpl::OnFrameAvailable() { proxy_->Repaint(); } +void VideoRendererImpl::SetWebMediaPlayerImplProxy( + WebMediaPlayerImpl::Proxy* proxy) { + proxy_ = proxy; +} + void VideoRendererImpl::SetRect(const gfx::Rect& rect) { } diff --git a/webkit/glue/media/video_renderer_impl.h b/webkit/glue/media/video_renderer_impl.h index 38e8851..34c67d3 100644 --- a/webkit/glue/media/video_renderer_impl.h +++ b/webkit/glue/media/video_renderer_impl.h @@ -24,39 +24,16 @@ namespace webkit_glue { class VideoRendererImpl : public WebVideoRenderer { public: + explicit VideoRendererImpl(bool pts_logging); + virtual ~VideoRendererImpl(); + // WebVideoRenderer implementation. + virtual void SetWebMediaPlayerImplProxy(WebMediaPlayerImpl::Proxy* proxy); virtual void SetRect(const gfx::Rect& rect); virtual void Paint(skia::PlatformCanvas* canvas, const gfx::Rect& dest_rect); virtual void GetCurrentFrame(scoped_refptr<media::VideoFrame>* frame_out); virtual void PutCurrentFrame(scoped_refptr<media::VideoFrame> frame); - // Static method for creating factory for this object. - static media::FilterFactory* CreateFactory(WebMediaPlayerImpl::Proxy* proxy, - bool pts_logging); - - // FilterFactoryImpl2 implementation. - static bool IsMediaFormatSupported(const media::MediaFormat& media_format); - - // TODO(scherkus): remove this mega-hack, see http://crbug.com/28207 - class FactoryFactory : public webkit_glue::WebVideoRendererFactoryFactory { - public: - FactoryFactory(bool pts_logging) - : webkit_glue::WebVideoRendererFactoryFactory(), - pts_logging_(pts_logging) { - } - - virtual media::FilterFactory* CreateFactory( - webkit_glue::WebMediaPlayerImpl::Proxy* proxy) { - return VideoRendererImpl::CreateFactory(proxy, pts_logging_); - } - - private: - // Whether we're logging video presentation timestamps (PTS). - bool pts_logging_; - - DISALLOW_COPY_AND_ASSIGN(FactoryFactory); - }; - protected: // Method called by VideoRendererBase during initialization. virtual bool OnInitialize(media::VideoDecoder* decoder); @@ -68,13 +45,6 @@ class VideoRendererImpl : public WebVideoRenderer { virtual void OnFrameAvailable(); private: - // Only the filter factories can create instances. - friend class media::FilterFactoryImpl2<VideoRendererImpl, - WebMediaPlayerImpl::Proxy*, - bool>; - VideoRendererImpl(WebMediaPlayerImpl::Proxy* proxy, bool pts_logging); - virtual ~VideoRendererImpl(); - // Determine the conditions to perform fast paint. Returns true if we can do // fast paint otherwise false. bool CanFastPaint(skia::PlatformCanvas* canvas, const gfx::Rect& dest_rect); diff --git a/webkit/glue/media/web_data_source.cc b/webkit/glue/media/web_data_source.cc new file mode 100644 index 0000000..a46d594 --- /dev/null +++ b/webkit/glue/media/web_data_source.cc @@ -0,0 +1,17 @@ +// 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 "media/base/filters.h" +#include "webkit/glue/media/web_data_source.h" + +namespace webkit_glue { + +WebDataSource::WebDataSource() + : media::DataSource() { +} + +WebDataSource::~WebDataSource() { +} + +} // namespace webkit_glue diff --git a/webkit/glue/media/web_data_source.h b/webkit/glue/media/web_data_source.h new file mode 100644 index 0000000..956ac9e --- /dev/null +++ b/webkit/glue/media/web_data_source.h @@ -0,0 +1,36 @@ +// 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_MEDIA_WEB_DATA_SOURCE_H_ +#define WEBKIT_GLUE_MEDIA_WEB_DATA_SOURCE_H_ + +#include "media/base/filters.h" + +namespace webkit_glue { + +// An interface that allows WebMediaPlayerImpl::Proxy to communicate with the +// DataSource in the pipeline. +class WebDataSource : public media::DataSource { + public: + WebDataSource(); + virtual ~WebDataSource(); + + // Returns true if the media resource has a single origin, false otherwise. + // + // Method called on the render thread. + virtual bool HasSingleOrigin() = 0; + + // This method is used to unblock any read calls that would cause the + // media pipeline to stall. + // + // Method called on the render thread. + virtual void Abort() = 0; + + private: + DISALLOW_COPY_AND_ASSIGN(WebDataSource); +}; + +} // namespace webkit_glue + +#endif // WEBKIT_GLUE_MEDIA_WEB_DATA_SOURCE_H_ diff --git a/webkit/glue/media/web_video_renderer.h b/webkit/glue/media/web_video_renderer.h index d8b47ad..efd3109 100644 --- a/webkit/glue/media/web_video_renderer.h +++ b/webkit/glue/media/web_video_renderer.h @@ -7,6 +7,7 @@ #include "media/base/video_frame.h" #include "media/filters/video_renderer_base.h" +#include "webkit/glue/webmediaplayer_impl.h" namespace webkit_glue { @@ -16,6 +17,9 @@ class WebVideoRenderer : public media::VideoRendererBase { WebVideoRenderer() : media::VideoRendererBase() {} virtual ~WebVideoRenderer() {} + // Saves the reference to WebMediaPlayerImpl::Proxy. + virtual void SetWebMediaPlayerImplProxy(WebMediaPlayerImpl::Proxy* proxy) = 0; + // This method is called with the same rect as the Paint() method and could // be used by future implementations to implement an improved color space + // scale code on a separate thread. Since we always do the stretch on the diff --git a/webkit/glue/multipart_response_delegate.cc b/webkit/glue/multipart_response_delegate.cc index 4839a91..99a9e4c 100644 --- a/webkit/glue/multipart_response_delegate.cc +++ b/webkit/glue/multipart_response_delegate.cc @@ -342,12 +342,6 @@ bool MultipartResponseDelegate::ReadContentRanges( return false; } - size_t byte_range_lower_bound_characters = - byte_range_lower_bound_end_offset - byte_range_lower_bound_start_offset; - std::string byte_range_lower_bound = - content_range.substr(byte_range_lower_bound_start_offset, - byte_range_lower_bound_characters); - size_t byte_range_upper_bound_start_offset = byte_range_lower_bound_end_offset + 1; @@ -357,16 +351,16 @@ bool MultipartResponseDelegate::ReadContentRanges( return false; } - size_t byte_range_upper_bound_characters = - byte_range_upper_bound_end_offset - byte_range_upper_bound_start_offset; - - std::string byte_range_upper_bound = - content_range.substr(byte_range_upper_bound_start_offset, - byte_range_upper_bound_characters); - - if (!base::StringToInt(byte_range_lower_bound, content_range_lower_bound)) + if (!base::StringToInt( + content_range.begin() + byte_range_lower_bound_start_offset, + content_range.begin() + byte_range_lower_bound_end_offset, + content_range_lower_bound)) return false; - if (!base::StringToInt(byte_range_upper_bound, content_range_upper_bound)) + + if (!base::StringToInt( + content_range.begin() + byte_range_upper_bound_start_offset, + content_range.begin() + byte_range_upper_bound_end_offset, + content_range_upper_bound)) return false; return true; } diff --git a/webkit/glue/plugins/DEPS b/webkit/glue/plugins/DEPS index 4ac8845..cfee702 100644 --- a/webkit/glue/plugins/DEPS +++ b/webkit/glue/plugins/DEPS @@ -1,4 +1,4 @@ include_rules = [ + "+ppapi", "+printing", - "+third_party/ppapi/c", ] diff --git a/webkit/glue/plugins/carbon_plugin_window_tracker_mac.cc b/webkit/glue/plugins/carbon_plugin_window_tracker_mac.cc index 6131b45..c4ae72d 100644 --- a/webkit/glue/plugins/carbon_plugin_window_tracker_mac.cc +++ b/webkit/glue/plugins/carbon_plugin_window_tracker_mac.cc @@ -14,7 +14,7 @@ CarbonPluginWindowTracker* CarbonPluginWindowTracker::SharedInstance() { } WindowRef CarbonPluginWindowTracker::CreateDummyWindowForDelegate( - WebPluginDelegateImpl* delegate) { + OpaquePluginRef delegate) { // The real size will be set by the plugin instance, once that size is known. Rect window_bounds = { 0, 0, 100, 100 }; WindowRef new_ref = NULL; @@ -28,7 +28,7 @@ WindowRef CarbonPluginWindowTracker::CreateDummyWindowForDelegate( return new_ref; } -WebPluginDelegateImpl* CarbonPluginWindowTracker::GetDelegateForDummyWindow( +OpaquePluginRef CarbonPluginWindowTracker::GetDelegateForDummyWindow( WindowRef window) const { WindowToDelegateMap::const_iterator i = window_to_delegate_map_.find(window); if (i != window_to_delegate_map_.end()) @@ -37,7 +37,7 @@ WebPluginDelegateImpl* CarbonPluginWindowTracker::GetDelegateForDummyWindow( } WindowRef CarbonPluginWindowTracker::GetDummyWindowForDelegate( - WebPluginDelegateImpl* delegate) const { + OpaquePluginRef delegate) const { DelegateToWindowMap::const_iterator i = delegate_to_window_map_.find(delegate); if (i != delegate_to_window_map_.end()) @@ -46,7 +46,7 @@ WindowRef CarbonPluginWindowTracker::GetDummyWindowForDelegate( } void CarbonPluginWindowTracker::DestroyDummyWindowForDelegate( - WebPluginDelegateImpl* delegate, WindowRef window) { + OpaquePluginRef delegate, WindowRef window) { DCHECK(GetDelegateForDummyWindow(window) == delegate); window_to_delegate_map_.erase(window); delegate_to_window_map_.erase(delegate); diff --git a/webkit/glue/plugins/carbon_plugin_window_tracker_mac.h b/webkit/glue/plugins/carbon_plugin_window_tracker_mac.h index 3e6ef2d..90fc318 100644 --- a/webkit/glue/plugins/carbon_plugin_window_tracker_mac.h +++ b/webkit/glue/plugins/carbon_plugin_window_tracker_mac.h @@ -10,7 +10,9 @@ #include "base/basictypes.h" -class WebPluginDelegateImpl; +// This is really a WebPluginDelegateImpl, but that class is private to the +// framework, and these functions are called from a dylib. +typedef void* OpaquePluginRef; // Creates and tracks the invisible windows that are necessary for // Carbon-event-model plugins. @@ -27,21 +29,21 @@ class __attribute__((visibility("default"))) CarbonPluginWindowTracker { static CarbonPluginWindowTracker* SharedInstance(); // Creates a new carbon window associated with |delegate|. - WindowRef CreateDummyWindowForDelegate(WebPluginDelegateImpl* delegate); + WindowRef CreateDummyWindowForDelegate(OpaquePluginRef delegate); // Returns the WebPluginDelegate associated with the given dummy window. - WebPluginDelegateImpl* GetDelegateForDummyWindow(WindowRef window) const; + OpaquePluginRef GetDelegateForDummyWindow(WindowRef window) const; // Returns the dummy window associated with |delegate|. - WindowRef GetDummyWindowForDelegate(WebPluginDelegateImpl* delegate) const; + WindowRef GetDummyWindowForDelegate(OpaquePluginRef delegate) const; // Destroys the dummy window for |delegate|. - void DestroyDummyWindowForDelegate(WebPluginDelegateImpl* delegate, + void DestroyDummyWindowForDelegate(OpaquePluginRef delegate, WindowRef window); private: - typedef std::map<WindowRef, WebPluginDelegateImpl*> WindowToDelegateMap; - typedef std::map<WebPluginDelegateImpl*, WindowRef> DelegateToWindowMap; + typedef std::map<WindowRef, OpaquePluginRef> WindowToDelegateMap; + typedef std::map<OpaquePluginRef, WindowRef> DelegateToWindowMap; WindowToDelegateMap window_to_delegate_map_; DelegateToWindowMap delegate_to_window_map_; diff --git a/webkit/glue/plugins/npapi_extension_thunk.cc b/webkit/glue/plugins/npapi_extension_thunk.cc index 4779535..05a9c5d 100644 --- a/webkit/glue/plugins/npapi_extension_thunk.cc +++ b/webkit/glue/plugins/npapi_extension_thunk.cc @@ -28,7 +28,7 @@ static NPAPI::PluginInstance* FindInstance(NPP id) { static NPError Device2DQueryCapability(NPP id, int32_t capability, int32_t* value) { - scoped_refptr<NPAPI::PluginInstance> plugin = FindInstance(id); + scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); if (plugin) { plugin->webplugin()->delegate()->Device2DQueryCapability(capability, value); return NPERR_NO_ERROR; @@ -40,7 +40,7 @@ static NPError Device2DQueryCapability(NPP id, int32_t capability, static NPError Device2DQueryConfig(NPP id, const NPDeviceConfig* request, NPDeviceConfig* obtain) { - scoped_refptr<NPAPI::PluginInstance> plugin = FindInstance(id); + scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); if (plugin) { return plugin->webplugin()->delegate()->Device2DQueryConfig( static_cast<const NPDeviceContext2DConfig*>(request), @@ -52,7 +52,7 @@ static NPError Device2DQueryConfig(NPP id, static NPError Device2DInitializeContext(NPP id, const NPDeviceConfig* config, NPDeviceContext* context) { - scoped_refptr<NPAPI::PluginInstance> plugin = FindInstance(id); + scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); if (plugin) { return plugin->webplugin()->delegate()->Device2DInitializeContext( static_cast<const NPDeviceContext2DConfig*>(config), @@ -65,7 +65,7 @@ static NPError Device2DSetStateContext(NPP id, NPDeviceContext* context, int32_t state, intptr_t value) { - scoped_refptr<NPAPI::PluginInstance> plugin = FindInstance(id); + scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); if (plugin) { return plugin->webplugin()->delegate()->Device2DSetStateContext( static_cast<NPDeviceContext2D*>(context), state, value); @@ -77,7 +77,7 @@ static NPError Device2DGetStateContext(NPP id, NPDeviceContext* context, int32_t state, intptr_t* value) { - scoped_refptr<NPAPI::PluginInstance> plugin = FindInstance(id); + scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); if (plugin) { return plugin->webplugin()->delegate()->Device2DGetStateContext( static_cast<NPDeviceContext2D*>(context), state, value); @@ -89,7 +89,7 @@ static NPError Device2DFlushContext(NPP id, NPDeviceContext* context, NPDeviceFlushContextCallbackPtr callback, void* user_data) { - scoped_refptr<NPAPI::PluginInstance> plugin = FindInstance(id); + scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); if (plugin) { NPError err = plugin->webplugin()->delegate()->Device2DFlushContext( id, static_cast<NPDeviceContext2D*>(context), callback, user_data); @@ -109,7 +109,7 @@ static NPError Device2DFlushContext(NPP id, static NPError Device2DDestroyContext(NPP id, NPDeviceContext* context) { - scoped_refptr<NPAPI::PluginInstance> plugin = FindInstance(id); + scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); if (plugin) { return plugin->webplugin()->delegate()->Device2DDestroyContext( static_cast<NPDeviceContext2D*>(context)); @@ -141,7 +141,7 @@ static NPError Device2DMapBuffer(NPP id, static NPError Device3DQueryCapability(NPP id, int32_t capability, int32_t* value) { - scoped_refptr<NPAPI::PluginInstance> plugin = FindInstance(id); + scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); if (plugin) { plugin->webplugin()->delegate()->Device3DQueryCapability(capability, value); return NPERR_NO_ERROR; @@ -153,7 +153,7 @@ static NPError Device3DQueryCapability(NPP id, int32_t capability, static NPError Device3DQueryConfig(NPP id, const NPDeviceConfig* request, NPDeviceConfig* obtain) { - scoped_refptr<NPAPI::PluginInstance> plugin = FindInstance(id); + scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); if (plugin) { return plugin->webplugin()->delegate()->Device3DQueryConfig( static_cast<const NPDeviceContext3DConfig*>(request), @@ -165,7 +165,7 @@ static NPError Device3DQueryConfig(NPP id, static NPError Device3DInitializeContext(NPP id, const NPDeviceConfig* config, NPDeviceContext* context) { - scoped_refptr<NPAPI::PluginInstance> plugin = FindInstance(id); + scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); if (plugin) { return plugin->webplugin()->delegate()->Device3DInitializeContext( static_cast<const NPDeviceContext3DConfig*>(config), @@ -178,7 +178,7 @@ static NPError Device3DSetStateContext(NPP id, NPDeviceContext* context, int32_t state, intptr_t value) { - scoped_refptr<NPAPI::PluginInstance> plugin = FindInstance(id); + scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); if (plugin) { return plugin->webplugin()->delegate()->Device3DSetStateContext( static_cast<NPDeviceContext3D*>(context), state, value); @@ -190,7 +190,7 @@ static NPError Device3DGetStateContext(NPP id, NPDeviceContext* context, int32_t state, intptr_t* value) { - scoped_refptr<NPAPI::PluginInstance> plugin = FindInstance(id); + scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); if (plugin) { return plugin->webplugin()->delegate()->Device3DGetStateContext( static_cast<NPDeviceContext3D*>(context), state, value); @@ -202,7 +202,7 @@ static NPError Device3DFlushContext(NPP id, NPDeviceContext* context, NPDeviceFlushContextCallbackPtr callback, void* user_data) { - scoped_refptr<NPAPI::PluginInstance> plugin = FindInstance(id); + scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); if (plugin) { return plugin->webplugin()->delegate()->Device3DFlushContext( id, static_cast<NPDeviceContext3D*>(context), callback, user_data); @@ -212,7 +212,7 @@ static NPError Device3DFlushContext(NPP id, static NPError Device3DDestroyContext(NPP id, NPDeviceContext* context) { - scoped_refptr<NPAPI::PluginInstance> plugin = FindInstance(id); + scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); if (plugin) { return plugin->webplugin()->delegate()->Device3DDestroyContext( static_cast<NPDeviceContext3D*>(context)); @@ -224,7 +224,7 @@ static NPError Device3DCreateBuffer(NPP id, NPDeviceContext* context, size_t size, int32_t* buffer_id) { - scoped_refptr<NPAPI::PluginInstance> plugin = FindInstance(id); + scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); if (plugin) { return plugin->webplugin()->delegate()->Device3DCreateBuffer( static_cast<NPDeviceContext3D*>(context), size, buffer_id); @@ -235,7 +235,7 @@ static NPError Device3DCreateBuffer(NPP id, static NPError Device3DDestroyBuffer(NPP id, NPDeviceContext* context, int32_t buffer_id) { - scoped_refptr<NPAPI::PluginInstance> plugin = FindInstance(id); + scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); if (plugin) { return plugin->webplugin()->delegate()->Device3DDestroyBuffer( static_cast<NPDeviceContext3D*>(context), buffer_id); @@ -247,7 +247,7 @@ static NPError Device3DMapBuffer(NPP id, NPDeviceContext* context, int32_t buffer_id, NPDeviceBuffer* buffer) { - scoped_refptr<NPAPI::PluginInstance> plugin = FindInstance(id); + scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); if (plugin) { return plugin->webplugin()->delegate()->Device3DMapBuffer( static_cast<NPDeviceContext3D*>(context), buffer_id, buffer); @@ -258,7 +258,7 @@ static NPError Device3DMapBuffer(NPP id, // Experimental 3D device API -------------------------------------------------- static NPError Device3DGetNumConfigs(NPP id, int32_t* num_configs) { - scoped_refptr<NPAPI::PluginInstance> plugin = FindInstance(id); + scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); if (plugin) { return plugin->webplugin()->delegate()->Device3DGetNumConfigs(num_configs); } @@ -268,7 +268,7 @@ static NPError Device3DGetNumConfigs(NPP id, int32_t* num_configs) { static NPError Device3DGetConfigAttribs(NPP id, int32_t config, int32_t* attrib_list) { - scoped_refptr<NPAPI::PluginInstance> plugin = FindInstance(id); + scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); if (plugin) { return plugin->webplugin()->delegate()->Device3DGetConfigAttribs( config, @@ -281,7 +281,7 @@ static NPError Device3DCreateContext(NPP id, int32_t config, const int32_t* attrib_list, NPDeviceContext** context) { - scoped_refptr<NPAPI::PluginInstance> plugin = FindInstance(id); + scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); if (plugin) { return plugin->webplugin()->delegate()->Device3DCreateContext( config, @@ -299,7 +299,7 @@ static NPError Device3DSynchronizeContext( int32_t* output_attrib_list, NPDeviceSynchronizeContextCallbackPtr callback, void* callback_data) { - scoped_refptr<NPAPI::PluginInstance> plugin = FindInstance(id); + scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); if (plugin) { return plugin->webplugin()->delegate()->Device3DSynchronizeContext( id, @@ -319,7 +319,7 @@ static NPError Device3DRegisterCallback( int32_t callback_type, NPDeviceGenericCallbackPtr callback, void* callback_data) { - scoped_refptr<NPAPI::PluginInstance> plugin = FindInstance(id); + scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); if (plugin) { return plugin->webplugin()->delegate()->Device3DRegisterCallback( id, @@ -335,7 +335,7 @@ static NPError Device3DRegisterCallback( static NPError DeviceAudioQueryCapability(NPP id, int32_t capability, int32_t* value) { - scoped_refptr<NPAPI::PluginInstance> plugin = FindInstance(id); + scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); if (plugin) { plugin->webplugin()->delegate()->DeviceAudioQueryCapability(capability, value); @@ -348,7 +348,7 @@ static NPError DeviceAudioQueryCapability(NPP id, int32_t capability, static NPError DeviceAudioQueryConfig(NPP id, const NPDeviceConfig* request, NPDeviceConfig* obtain) { - scoped_refptr<NPAPI::PluginInstance> plugin = FindInstance(id); + scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); if (plugin) { return plugin->webplugin()->delegate()->DeviceAudioQueryConfig( static_cast<const NPDeviceContextAudioConfig*>(request), @@ -360,7 +360,7 @@ static NPError DeviceAudioQueryConfig(NPP id, static NPError DeviceAudioInitializeContext(NPP id, const NPDeviceConfig* config, NPDeviceContext* context) { - scoped_refptr<NPAPI::PluginInstance> plugin = FindInstance(id); + scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); if (plugin) { return plugin->webplugin()->delegate()->DeviceAudioInitializeContext( static_cast<const NPDeviceContextAudioConfig*>(config), @@ -373,7 +373,7 @@ static NPError DeviceAudioSetStateContext(NPP id, NPDeviceContext* context, int32_t state, intptr_t value) { - scoped_refptr<NPAPI::PluginInstance> plugin = FindInstance(id); + scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); if (plugin) { return plugin->webplugin()->delegate()->DeviceAudioSetStateContext( static_cast<NPDeviceContextAudio*>(context), state, value); @@ -385,7 +385,7 @@ static NPError DeviceAudioGetStateContext(NPP id, NPDeviceContext* context, int32_t state, intptr_t* value) { - scoped_refptr<NPAPI::PluginInstance> plugin = FindInstance(id); + scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); return plugin->webplugin()->delegate()->DeviceAudioGetStateContext( static_cast<NPDeviceContextAudio*>(context), state, value); } @@ -394,14 +394,14 @@ static NPError DeviceAudioFlushContext(NPP id, NPDeviceContext* context, NPDeviceFlushContextCallbackPtr callback, void* user_data) { - scoped_refptr<NPAPI::PluginInstance> plugin = FindInstance(id); + scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); return plugin->webplugin()->delegate()->DeviceAudioFlushContext( id, static_cast<NPDeviceContextAudio*>(context), callback, user_data); } static NPError DeviceAudioDestroyContext(NPP id, NPDeviceContext* context) { - scoped_refptr<NPAPI::PluginInstance> plugin = FindInstance(id); + scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); return plugin->webplugin()->delegate()->DeviceAudioDestroyContext( static_cast<NPDeviceContextAudio*>(context)); } @@ -477,7 +477,7 @@ static NPError ChooseFile(NPP id, NPChooseFileMode mode, NPChooseFileCallback callback, void* user_data) { - scoped_refptr<NPAPI::PluginInstance> plugin = FindInstance(id); + scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); if (!plugin) return NPERR_GENERIC_ERROR; @@ -490,7 +490,7 @@ static NPError ChooseFile(NPP id, } static void NumberOfFindResultsChanged(NPP id, int total, bool final_result) { - scoped_refptr<NPAPI::PluginInstance> plugin = FindInstance(id); + scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); if (plugin) { plugin->webplugin()->delegate()->NumberOfFindResultsChanged( total, final_result); @@ -498,13 +498,13 @@ static void NumberOfFindResultsChanged(NPP id, int total, bool final_result) { } static void SelectedFindResultChanged(NPP id, int index) { - scoped_refptr<NPAPI::PluginInstance> plugin = FindInstance(id); + scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); if (plugin) plugin->webplugin()->delegate()->SelectedFindResultChanged(index); } static NPWidgetExtensions* GetWidgetExtensions(NPP id) { - scoped_refptr<NPAPI::PluginInstance> plugin = FindInstance(id); + scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); if (!plugin) return NULL; @@ -512,7 +512,7 @@ static NPWidgetExtensions* GetWidgetExtensions(NPP id) { } static NPError NPSetCursor(NPP id, NPCursorType type) { - scoped_refptr<NPAPI::PluginInstance> plugin = FindInstance(id); + scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); if (!plugin) return NPERR_GENERIC_ERROR; @@ -521,7 +521,7 @@ static NPError NPSetCursor(NPP id, NPCursorType type) { } static NPFontExtensions* GetFontExtensions(NPP id) { - scoped_refptr<NPAPI::PluginInstance> plugin = FindInstance(id); + scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); if (!plugin) return NULL; diff --git a/webkit/glue/plugins/pepper_audio.cc b/webkit/glue/plugins/pepper_audio.cc index 5a76670..d98ef1b 100644 --- a/webkit/glue/plugins/pepper_audio.cc +++ b/webkit/glue/plugins/pepper_audio.cc @@ -5,8 +5,9 @@ #include "webkit/glue/plugins/pepper_audio.h" #include "base/logging.h" -#include "third_party/ppapi/c/dev/ppb_audio_dev.h" -#include "third_party/ppapi/c/dev/ppb_audio_trusted_dev.h" +#include "ppapi/c/dev/ppb_audio_dev.h" +#include "ppapi/c/dev/ppb_audio_trusted_dev.h" +#include "webkit/glue/plugins/pepper_common.h" namespace pepper { @@ -50,9 +51,9 @@ uint32_t RecommendSampleFrameCount(uint32_t requested_sample_frame_count) { return requested_sample_frame_count; } -bool IsAudioConfig(PP_Resource resource) { +PP_Bool IsAudioConfig(PP_Resource resource) { scoped_refptr<AudioConfig> config = Resource::GetAs<AudioConfig>(resource); - return !!config; + return BoolToPPBool(!!config); } PP_AudioSampleRate_Dev GetSampleRate(PP_Resource config_id) { @@ -87,9 +88,9 @@ PP_Resource Create(PP_Instance instance_id, PP_Resource config_id, return audio->GetReference(); } -bool IsAudio(PP_Resource resource) { +PP_Bool IsAudio(PP_Resource resource) { scoped_refptr<Audio> audio = Resource::GetAs<Audio>(resource); - return !!audio; + return BoolToPPBool(!!audio); } PP_Resource GetCurrentConfiguration(PP_Resource audio_id) { @@ -97,14 +98,14 @@ PP_Resource GetCurrentConfiguration(PP_Resource audio_id) { return audio ? audio->GetCurrentConfiguration() : 0; } -bool StartPlayback(PP_Resource audio_id) { +PP_Bool StartPlayback(PP_Resource audio_id) { scoped_refptr<Audio> audio = Resource::GetAs<Audio>(audio_id); - return audio ? audio->StartPlayback() : false; + return audio ? BoolToPPBool(audio->StartPlayback()) : PP_FALSE; } -bool StopPlayback(PP_Resource audio_id) { +PP_Bool StopPlayback(PP_Resource audio_id) { scoped_refptr<Audio> audio = Resource::GetAs<Audio>(audio_id); - return audio ? audio->StopPlayback() : false; + return audio ? BoolToPPBool(audio->StopPlayback()) : PP_FALSE; } const PPB_Audio_Dev ppb_audio = { diff --git a/webkit/glue/plugins/pepper_audio.h b/webkit/glue/plugins/pepper_audio.h index 196eac4..ccba021 100644 --- a/webkit/glue/plugins/pepper_audio.h +++ b/webkit/glue/plugins/pepper_audio.h @@ -2,22 +2,22 @@ // 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_DEVICE_CONTEXT_AUDIO_H_ +#define WEBKIT_GLUE_PLUGINS_PEPPER_DEVICE_CONTEXT_AUDIO_H_ + #include "base/ref_counted.h" #include "base/scoped_ptr.h" #include "base/shared_memory.h" #include "base/simple_thread.h" #include "base/sync_socket.h" -#include "third_party/ppapi/c/dev/ppb_audio_dev.h" -#include "third_party/ppapi/c/dev/ppb_audio_config_dev.h" -#include "third_party/ppapi/c/dev/ppb_audio_trusted_dev.h" +#include "ppapi/c/dev/ppb_audio_dev.h" +#include "ppapi/c/dev/ppb_audio_config_dev.h" +#include "ppapi/c/dev/ppb_audio_trusted_dev.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" -#ifndef WEBKIT_GLUE_PLUGINS_PEPPER_DEVICE_CONTEXT_AUDIO_H_ -#define WEBKIT_GLUE_PLUGINS_PEPPER_DEVICE_CONTEXT_AUDIO_H_ - namespace pepper { class PluginInstance; diff --git a/webkit/glue/plugins/pepper_buffer.cc b/webkit/glue/plugins/pepper_buffer.cc index 1b9097d..cee10c9 100644 --- a/webkit/glue/plugins/pepper_buffer.cc +++ b/webkit/glue/plugins/pepper_buffer.cc @@ -8,10 +8,11 @@ #include "base/logging.h" #include "base/scoped_ptr.h" -#include "third_party/ppapi/c/dev/ppb_buffer_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 "ppapi/c/dev/ppb_buffer_dev.h" +#include "ppapi/c/pp_instance.h" +#include "ppapi/c/pp_module.h" +#include "ppapi/c/pp_resource.h" +#include "webkit/glue/plugins/pepper_common.h" #include "webkit/glue/plugins/pepper_plugin_instance.h" #include "webkit/glue/plugins/pepper_plugin_module.h" @@ -31,16 +32,16 @@ PP_Resource Create(PP_Module module_id, int32_t size) { return buffer->GetReference(); } -bool IsBuffer(PP_Resource resource) { - return !!Resource::GetAs<Buffer>(resource); +PP_Bool IsBuffer(PP_Resource resource) { + return BoolToPPBool(!!Resource::GetAs<Buffer>(resource)); } -bool Describe(PP_Resource resource, int32_t* size_in_bytes) { +PP_Bool Describe(PP_Resource resource, int32_t* size_in_bytes) { scoped_refptr<Buffer> buffer(Resource::GetAs<Buffer>(resource)); if (!buffer) - return false; + return PP_FALSE; buffer->Describe(size_in_bytes); - return true; + return PP_TRUE; } void* Map(PP_Resource resource) { diff --git a/webkit/glue/plugins/pepper_char_set.cc b/webkit/glue/plugins/pepper_char_set.cc index 043de41..1411d59 100644 --- a/webkit/glue/plugins/pepper_char_set.cc +++ b/webkit/glue/plugins/pepper_char_set.cc @@ -7,7 +7,7 @@ #include <stdlib.h> #include "base/i18n/icu_string_conversions.h" -#include "third_party/ppapi/c/dev/ppb_char_set_dev.h" +#include "ppapi/c/dev/ppb_char_set_dev.h" #include "unicode/ucnv.h" #include "unicode/ucnv_cb.h" #include "unicode/ucnv_err.h" diff --git a/webkit/glue/plugins/pepper_class.h b/webkit/glue/plugins/pepper_class.h new file mode 100644 index 0000000..35bd2c4 --- /dev/null +++ b/webkit/glue/plugins/pepper_class.h @@ -0,0 +1,66 @@ +// 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_CLASS_H_ +#define WEBKIT_GLUE_PLUGINS_PEPPER_CLASS_H_ + +#include "webkit/glue/plugins/pepper_resource.h" + +#include <string> + +#include "base/hash_tables.h" +#include "ppapi/c/ppb_class.h" + +namespace pepper { + +class PluginModule; + +class VarObjectClass : public Resource { + public: + struct Property { + explicit Property(const PP_ClassProperty& prop); + + const PP_ClassFunction method; + const PP_ClassFunction getter; + const PP_ClassFunction setter; + const bool writable; + const bool enumerable; + }; + + struct InstanceData; + + typedef base::hash_map<std::string, Property> PropertyMap; + + // Returns the PPB_Var interface for the plugin to use. + static const PPB_Class* GetInterface(); + + VarObjectClass(PluginModule* module, PP_ClassDestructor destruct, + PP_ClassFunction invoke, PP_ClassProperty* properties); + virtual ~VarObjectClass(); + + // Resource override. + virtual VarObjectClass* AsVarObjectClass() { return this; } + + const PropertyMap &properties() const { return properties_; } + + PP_ClassDestructor instance_native_destructor() { + return instance_native_destructor_; + } + + PP_ClassFunction instance_invoke() { + return instance_invoke_; + } + + private: + PropertyMap properties_; + PP_ClassDestructor instance_native_destructor_; + PP_ClassFunction instance_invoke_; + + DISALLOW_COPY_AND_ASSIGN(VarObjectClass); +}; + +} // namespace pepper + +#endif // WEBKIT_GLUE_PLUGINS_PEPPER_CLASS_H_ + diff --git a/webkit/glue/plugins/pepper_common.h b/webkit/glue/plugins/pepper_common.h new file mode 100644 index 0000000..be9fe3d --- /dev/null +++ b/webkit/glue/plugins/pepper_common.h @@ -0,0 +1,24 @@ +// 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_COMMON_H_ +#define WEBKIT_GLUE_PLUGINS_PEPPER_COMMON_H_ + +#include "ppapi/c/pp_bool.h" +#include "ppapi/c/pp_var.h" + +namespace pepper { + +inline PP_Bool BoolToPPBool(bool value) { + return value ? PP_TRUE : PP_FALSE; +} + +inline bool PPBoolToBool(PP_Bool value) { + return (PP_TRUE == value); +} + +} // namespace pepper + +#endif // WEBKIT_GLUE_PLUGINS_PEPPER_COMMON_H_ + diff --git a/webkit/glue/plugins/pepper_cursor_control.cc b/webkit/glue/plugins/pepper_cursor_control.cc index 687aa76..62b4e2f 100644 --- a/webkit/glue/plugins/pepper_cursor_control.cc +++ b/webkit/glue/plugins/pepper_cursor_control.cc @@ -6,10 +6,11 @@ #include "base/logging.h" #include "base/ref_counted.h" -#include "third_party/ppapi/c/dev/pp_cursor_type_dev.h" -#include "third_party/ppapi/c/dev/ppb_cursor_control_dev.h" -#include "third_party/ppapi/c/pp_point.h" -#include "third_party/ppapi/c/pp_resource.h" +#include "ppapi/c/dev/pp_cursor_type_dev.h" +#include "ppapi/c/dev/ppb_cursor_control_dev.h" +#include "ppapi/c/pp_point.h" +#include "ppapi/c/pp_resource.h" +#include "webkit/glue/plugins/pepper_common.h" #include "webkit/glue/plugins/pepper_image_data.h" #include "webkit/glue/plugins/pepper_plugin_instance.h" #include "webkit/glue/plugins/pepper_resource.h" @@ -18,59 +19,59 @@ namespace pepper { namespace { -bool SetCursor(PP_Instance instance_id, +PP_Bool SetCursor(PP_Instance instance_id, PP_CursorType_Dev type, PP_Resource custom_image_id, const PP_Point* hot_spot) { PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id); if (!instance) - return false; + return PP_FALSE; scoped_refptr<ImageData> custom_image( Resource::GetAs<ImageData>(custom_image_id)); if (custom_image.get()) { // TODO(neb): implement custom cursors. NOTIMPLEMENTED(); - return false; + return PP_FALSE; } - return instance->SetCursor(type); + return BoolToPPBool(instance->SetCursor(type)); } -bool LockCursor(PP_Instance instance_id) { +PP_Bool LockCursor(PP_Instance instance_id) { PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id); if (!instance) - return false; + return PP_FALSE; // TODO(neb): implement cursor locking. - return false; + return PP_FALSE; } -bool UnlockCursor(PP_Instance instance_id) { +PP_Bool UnlockCursor(PP_Instance instance_id) { PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id); if (!instance) - return false; + return PP_FALSE; // TODO(neb): implement cursor locking. - return false; + return PP_FALSE; } -bool HasCursorLock(PP_Instance instance_id) { +PP_Bool HasCursorLock(PP_Instance instance_id) { PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id); if (!instance) - return false; + return PP_FALSE; // TODO(neb): implement cursor locking. - return false; + return PP_FALSE; } -bool CanLockCursor(PP_Instance instance_id) { +PP_Bool CanLockCursor(PP_Instance instance_id) { PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id); if (!instance) - return false; + return PP_FALSE; // TODO(neb): implement cursor locking. - return false; + return PP_FALSE; } const PPB_CursorControl_Dev cursor_control_interface = { diff --git a/webkit/glue/plugins/pepper_directory_reader.cc b/webkit/glue/plugins/pepper_directory_reader.cc index bcf2533..c476b76 100644 --- a/webkit/glue/plugins/pepper_directory_reader.cc +++ b/webkit/glue/plugins/pepper_directory_reader.cc @@ -5,16 +5,43 @@ #include "webkit/glue/plugins/pepper_directory_reader.h" #include "base/logging.h" -#include "third_party/ppapi/c/pp_completion_callback.h" -#include "third_party/ppapi/c/dev/ppb_directory_reader_dev.h" -#include "third_party/ppapi/c/pp_errors.h" +#include "base/utf_string_conversions.h" +#include "ppapi/c/pp_completion_callback.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/dev/ppb_directory_reader_dev.h" +#include "webkit/glue/plugins/pepper_file_callbacks.h" +#include "webkit/glue/plugins/pepper_common.h" #include "webkit/glue/plugins/pepper_file_ref.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_resource_tracker.h" namespace pepper { namespace { +std::string FilePathStringToUTF8String(const FilePath::StringType& str) { +#if defined(OS_WIN) + return WideToUTF8(str); +#elif defined(OS_POSIX) + return str; +#else +#error "Unsupported platform." +#endif +} + +FilePath::StringType UTF8StringToFilePathString(const std::string& str) { +#if defined(OS_WIN) + return UTF8ToWide(str); +#elif defined(OS_POSIX) + return str; +#else +#error "Unsupported platform." +#endif +} + PP_Resource Create(PP_Resource directory_ref_id) { scoped_refptr<FileRef> directory_ref( Resource::GetAs<FileRef>(directory_ref_id)); @@ -25,8 +52,8 @@ PP_Resource Create(PP_Resource directory_ref_id) { return reader->GetReference(); } -bool IsDirectoryReader(PP_Resource resource) { - return !!Resource::GetAs<DirectoryReader>(resource); +PP_Bool IsDirectoryReader(PP_Resource resource) { + return BoolToPPBool(!!Resource::GetAs<DirectoryReader>(resource)); } int32_t GetNextEntry(PP_Resource reader_id, @@ -50,7 +77,9 @@ const PPB_DirectoryReader_Dev ppb_directoryreader = { DirectoryReader::DirectoryReader(FileRef* directory_ref) : Resource(directory_ref->module()), - directory_ref_(directory_ref) { + directory_ref_(directory_ref), + has_more_(true), + entry_(NULL) { } DirectoryReader::~DirectoryReader() { @@ -62,8 +91,66 @@ const PPB_DirectoryReader_Dev* DirectoryReader::GetInterface() { int32_t DirectoryReader::GetNextEntry(PP_DirectoryEntry_Dev* entry, PP_CompletionCallback callback) { - NOTIMPLEMENTED(); // TODO(darin): Implement me! - return PP_ERROR_FAILED; + if (directory_ref_->GetFileSystemType() == PP_FILESYSTEMTYPE_EXTERNAL) + return PP_ERROR_FAILED; + + entry_ = entry; + if (FillUpEntry()) { + entry_ = NULL; + return PP_OK; + } + + PluginInstance* instance = directory_ref_->GetFileSystem()->instance(); + if (!instance->delegate()->ReadDirectory( + directory_ref_->GetSystemPath(), + new FileCallbacks(instance->module()->AsWeakPtr(), + callback, NULL, NULL, this))) + return PP_ERROR_FAILED; + + return PP_ERROR_WOULDBLOCK; +} + +void DirectoryReader::AddNewEntries( + const std::vector<base::FileUtilProxy::Entry>& entries, bool has_more) { + DCHECK(!entries.empty()); + has_more_ = has_more; + std::string dir_path = directory_ref_->GetPath(); + if (dir_path[dir_path.size() - 1] != '/') + dir_path += '/'; + FilePath::StringType dir_file_path = UTF8StringToFilePathString(dir_path); + for (std::vector<base::FileUtilProxy::Entry>::const_iterator it = + entries.begin(); it != entries.end(); it++) { + base::FileUtilProxy::Entry entry; + entry.name = dir_file_path + it->name; + entry.is_directory = it->is_directory; + entries_.push(entry); + } + + FillUpEntry(); + entry_ = NULL; +} + +bool DirectoryReader::FillUpEntry() { + DCHECK(entry_); + if (!entries_.empty()) { + base::FileUtilProxy::Entry dir_entry = entries_.front(); + entries_.pop(); + if (entry_->file_ref) + ResourceTracker::Get()->UnrefResource(entry_->file_ref); + FileRef* file_ref = new FileRef(module(), directory_ref_->GetFileSystem(), + FilePathStringToUTF8String(dir_entry.name)); + entry_->file_ref = file_ref->GetReference(); + entry_->file_type = + (dir_entry.is_directory ? PP_FILETYPE_DIRECTORY : PP_FILETYPE_REGULAR); + return true; + } + + if (!has_more_) { + entry_->file_ref = 0; + return true; + } + + return false; } } // namespace pepper diff --git a/webkit/glue/plugins/pepper_directory_reader.h b/webkit/glue/plugins/pepper_directory_reader.h index a56d546..38496bb 100644 --- a/webkit/glue/plugins/pepper_directory_reader.h +++ b/webkit/glue/plugins/pepper_directory_reader.h @@ -5,6 +5,9 @@ #ifndef WEBKIT_GLUE_PLUGINS_PEPPER_DIRECTORY_READER_H_ #define WEBKIT_GLUE_PLUGINS_PEPPER_DIRECTORY_READER_H_ +#include <queue> + +#include "base/file_util_proxy.h" #include "webkit/glue/plugins/pepper_resource.h" struct PP_CompletionCallback; @@ -31,8 +34,16 @@ class DirectoryReader : public Resource { int32_t GetNextEntry(PP_DirectoryEntry_Dev* entry, PP_CompletionCallback callback); + void AddNewEntries(const std::vector<base::FileUtilProxy::Entry>& entries, + bool has_more); + private: + bool FillUpEntry(); + scoped_refptr<FileRef> directory_ref_; + std::queue<base::FileUtilProxy::Entry> entries_; + bool has_more_; + PP_DirectoryEntry_Dev* entry_; }; } // namespace pepper diff --git a/webkit/glue/plugins/pepper_error_util.cc b/webkit/glue/plugins/pepper_error_util.cc index 895626a..7472d4a 100644 --- a/webkit/glue/plugins/pepper_error_util.cc +++ b/webkit/glue/plugins/pepper_error_util.cc @@ -4,7 +4,7 @@ #include "webkit/glue/plugins/pepper_error_util.h" -#include "third_party/ppapi/c/pp_errors.h" +#include "ppapi/c/pp_errors.h" namespace pepper { diff --git a/webkit/glue/plugins/pepper_event_conversion.cc b/webkit/glue/plugins/pepper_event_conversion.cc index 5375f67..300592f 100644 --- a/webkit/glue/plugins/pepper_event_conversion.cc +++ b/webkit/glue/plugins/pepper_event_conversion.cc @@ -10,8 +10,9 @@ #include "base/string_util.h" #include "base/utf_string_conversions.h" #include "base/utf_string_conversion_utils.h" -#include "third_party/ppapi/c/pp_input_event.h" +#include "ppapi/c/pp_input_event.h" #include "third_party/WebKit/WebKit/chromium/public/WebInputEvent.h" +#include "webkit/glue/plugins/pepper_common.h" using WebKit::WebInputEvent; using WebKit::WebKeyboardEvent; @@ -142,7 +143,8 @@ void AppendMouseWheelEvent(const WebInputEvent& event, result.u.wheel.delta_y = mouse_wheel_event.deltaY; result.u.wheel.wheel_ticks_x = mouse_wheel_event.wheelTicksX; result.u.wheel.wheel_ticks_y = mouse_wheel_event.wheelTicksY; - result.u.wheel.scroll_by_page = !!mouse_wheel_event.scrollByPage; + result.u.wheel.scroll_by_page = + pepper::BoolToPPBool(!!mouse_wheel_event.scrollByPage); pp_events->push_back(result); } diff --git a/webkit/glue/plugins/pepper_file_callbacks.cc b/webkit/glue/plugins/pepper_file_callbacks.cc index 3c52a0f..e24927a 100644 --- a/webkit/glue/plugins/pepper_file_callbacks.cc +++ b/webkit/glue/plugins/pepper_file_callbacks.cc @@ -6,9 +6,10 @@ #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 "ppapi/c/dev/ppb_file_system_dev.h" +#include "ppapi/c/dev/pp_file_info_dev.h" +#include "ppapi/c/pp_errors.h" +#include "webkit/glue/plugins/pepper_directory_reader.h" #include "webkit/glue/plugins/pepper_error_util.h" #include "webkit/glue/plugins/pepper_file_system.h" #include "webkit/fileapi/file_system_types.h" @@ -18,13 +19,17 @@ namespace pepper { FileCallbacks::FileCallbacks(const base::WeakPtr<PluginModule>& module, PP_CompletionCallback callback, PP_FileInfo_Dev* info, - scoped_refptr<FileSystem> file_system) + scoped_refptr<FileSystem> file_system, + scoped_refptr<DirectoryReader> directory_reader) : module_(module), callback_(callback), info_(info), - file_system_(file_system) { + file_system_(file_system), + directory_reader_(directory_reader) { } +FileCallbacks::~FileCallbacks() {} + void FileCallbacks::DidSucceed() { if (!module_.get() || !callback_.func) return; @@ -53,8 +58,14 @@ void FileCallbacks::DidReadMetadata( } void FileCallbacks::DidReadDirectory( - const std::vector<base::file_util_proxy::Entry>&, bool) { - NOTREACHED(); + const std::vector<base::FileUtilProxy::Entry>& entries, bool has_more) { + if (!module_.get() || !callback_.func) + return; + + DCHECK(directory_reader_); + directory_reader_->AddNewEntries(entries, has_more); + + PP_RunCompletionCallback(&callback_, PP_OK); } void FileCallbacks::DidOpenFileSystem(const std::string&, diff --git a/webkit/glue/plugins/pepper_file_callbacks.h b/webkit/glue/plugins/pepper_file_callbacks.h index 407672e..d4a92f2 100644 --- a/webkit/glue/plugins/pepper_file_callbacks.h +++ b/webkit/glue/plugins/pepper_file_callbacks.h @@ -7,7 +7,7 @@ #include "base/platform_file.h" #include "base/weak_ptr.h" -#include "third_party/ppapi/c/pp_completion_callback.h" +#include "ppapi/c/pp_completion_callback.h" #include "webkit/fileapi/file_system_callback_dispatcher.h" struct PP_FileInfo_Dev; @@ -18,6 +18,7 @@ class FilePath; namespace pepper { +class DirectoryReader; class FileSystem; class PluginModule; @@ -27,13 +28,15 @@ class FileCallbacks : public fileapi::FileSystemCallbackDispatcher { FileCallbacks(const base::WeakPtr<PluginModule>& module, PP_CompletionCallback callback, PP_FileInfo_Dev* info, - scoped_refptr<FileSystem> file_system); + scoped_refptr<FileSystem> file_system, + scoped_refptr<DirectoryReader> directory_reader); + virtual ~FileCallbacks(); // 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); + const std::vector<base::FileUtilProxy::Entry>& entries, bool has_more); virtual void DidOpenFileSystem(const std::string&, const FilePath& root_path); virtual void DidFail(base::PlatformFileError error_code); @@ -42,10 +45,11 @@ class FileCallbacks : public fileapi::FileSystemCallbackDispatcher { private: void RunCallback(base::PlatformFileError error_code); - base::WeakPtr<pepper::PluginModule> module_; + base::WeakPtr<PluginModule> module_; PP_CompletionCallback callback_; PP_FileInfo_Dev* info_; scoped_refptr<FileSystem> file_system_; + scoped_refptr<DirectoryReader> directory_reader_; }; } // namespace pepper diff --git a/webkit/glue/plugins/pepper_file_chooser.cc b/webkit/glue/plugins/pepper_file_chooser.cc index 07524e9..fd3ade1 100644 --- a/webkit/glue/plugins/pepper_file_chooser.cc +++ b/webkit/glue/plugins/pepper_file_chooser.cc @@ -8,13 +8,14 @@ #include <vector> #include "base/logging.h" -#include "third_party/ppapi/c/pp_completion_callback.h" -#include "third_party/ppapi/c/pp_errors.h" +#include "ppapi/c/pp_completion_callback.h" +#include "ppapi/c/pp_errors.h" #include "third_party/WebKit/WebKit/chromium/public/WebCString.h" #include "third_party/WebKit/WebKit/chromium/public/WebFileChooserCompletion.h" #include "third_party/WebKit/WebKit/chromium/public/WebFileChooserParams.h" #include "third_party/WebKit/WebKit/chromium/public/WebString.h" #include "third_party/WebKit/WebKit/chromium/public/WebVector.h" +#include "webkit/glue/plugins/pepper_common.h" #include "webkit/glue/plugins/pepper_file_ref.h" #include "webkit/glue/plugins/pepper_plugin_delegate.h" #include "webkit/glue/plugins/pepper_plugin_instance.h" @@ -41,8 +42,8 @@ PP_Resource Create(PP_Instance instance_id, return chooser->GetReference(); } -bool IsFileChooser(PP_Resource resource) { - return !!Resource::GetAs<FileChooser>(resource); +PP_Bool IsFileChooser(PP_Resource resource) { + return BoolToPPBool(!!Resource::GetAs<FileChooser>(resource)); } int32_t Show(PP_Resource chooser_id, PP_CompletionCallback callback) { @@ -118,8 +119,10 @@ void FileChooser::StoreChosenFiles(const std::vector<std::string>& files) { next_chosen_file_index_ = 0; 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(), FilePath().AppendASCII(*it))); + it != end_it; it++) { + chosen_files_.push_back(make_scoped_refptr( + new FileRef(module(), FilePath().AppendASCII(*it)))); + } if (!completion_callback_.func) return; diff --git a/webkit/glue/plugins/pepper_file_chooser.h b/webkit/glue/plugins/pepper_file_chooser.h index eafdd0e..664f934 100644 --- a/webkit/glue/plugins/pepper_file_chooser.h +++ b/webkit/glue/plugins/pepper_file_chooser.h @@ -9,8 +9,8 @@ #include <vector> #include "base/scoped_ptr.h" -#include "third_party/ppapi/c/dev/ppb_file_chooser_dev.h" -#include "third_party/ppapi/c/pp_completion_callback.h" +#include "ppapi/c/dev/ppb_file_chooser_dev.h" +#include "ppapi/c/pp_completion_callback.h" #include "webkit/glue/plugins/pepper_resource.h" namespace pepper { diff --git a/webkit/glue/plugins/pepper_file_io.cc b/webkit/glue/plugins/pepper_file_io.cc index b979ac2..1d3d66e 100644 --- a/webkit/glue/plugins/pepper_file_io.cc +++ b/webkit/glue/plugins/pepper_file_io.cc @@ -11,10 +11,11 @@ #include "base/platform_file.h" #include "base/logging.h" #include "base/time.h" -#include "third_party/ppapi/c/dev/ppb_file_io_dev.h" -#include "third_party/ppapi/c/dev/ppb_file_io_trusted_dev.h" -#include "third_party/ppapi/c/pp_completion_callback.h" -#include "third_party/ppapi/c/pp_errors.h" +#include "ppapi/c/dev/ppb_file_io_dev.h" +#include "ppapi/c/dev/ppb_file_io_trusted_dev.h" +#include "ppapi/c/pp_completion_callback.h" +#include "ppapi/c/pp_errors.h" +#include "webkit/glue/plugins/pepper_common.h" #include "webkit/glue/plugins/pepper_file_ref.h" #include "webkit/glue/plugins/pepper_plugin_instance.h" #include "webkit/glue/plugins/pepper_plugin_module.h" @@ -33,8 +34,8 @@ PP_Resource Create(PP_Module module_id) { return file_io->GetReference(); } -bool IsFileIO(PP_Resource resource) { - return !!Resource::GetAs<FileIO>(resource); +PP_Bool IsFileIO(PP_Resource resource) { + return BoolToPPBool(!!Resource::GetAs<FileIO>(resource)); } int32_t Open(PP_Resource file_io_id, diff --git a/webkit/glue/plugins/pepper_file_io.h b/webkit/glue/plugins/pepper_file_io.h index 9fa24ba..6fee92d 100644 --- a/webkit/glue/plugins/pepper_file_io.h +++ b/webkit/glue/plugins/pepper_file_io.h @@ -9,9 +9,9 @@ #include "base/platform_file.h" #include "base/scoped_callback_factory.h" #include "base/scoped_ptr.h" -#include "third_party/ppapi/c/dev/pp_file_info_dev.h" -#include "third_party/ppapi/c/pp_completion_callback.h" -#include "third_party/ppapi/c/pp_time.h" +#include "ppapi/c/dev/pp_file_info_dev.h" +#include "ppapi/c/pp_completion_callback.h" +#include "ppapi/c/pp_time.h" #include "webkit/glue/plugins/pepper_plugin_delegate.h" #include "webkit/glue/plugins/pepper_resource.h" diff --git a/webkit/glue/plugins/pepper_file_ref.cc b/webkit/glue/plugins/pepper_file_ref.cc index 0a64678..67e39e3 100644 --- a/webkit/glue/plugins/pepper_file_ref.cc +++ b/webkit/glue/plugins/pepper_file_ref.cc @@ -5,7 +5,10 @@ #include "webkit/glue/plugins/pepper_file_ref.h" #include "base/string_util.h" -#include "third_party/ppapi/c/pp_errors.h" +#include "base/utf_string_conversions.h" +#include "ppapi/c/pp_errors.h" +#include "webkit/glue/plugins/pepper_common.h" +#include "webkit/glue/plugins/pepper_directory_reader.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" @@ -56,8 +59,8 @@ PP_Resource Create(PP_Resource file_system_id, const char* path) { return file_ref->GetReference(); } -bool IsFileRef(PP_Resource resource) { - return !!Resource::GetAs<FileRef>(resource); +PP_Bool IsFileRef(PP_Resource resource) { + return BoolToPPBool(!!Resource::GetAs<FileRef>(resource)); } PP_FileSystemType_Dev GetFileSystemType(PP_Resource file_ref_id) { @@ -101,7 +104,7 @@ PP_Resource GetParent(PP_Resource file_ref_id) { } int32_t MakeDirectory(PP_Resource directory_ref_id, - bool make_ancestors, + PP_Bool make_ancestors, PP_CompletionCallback callback) { scoped_refptr<FileRef> directory_ref( Resource::GetAs<FileRef>(directory_ref_id)); @@ -115,9 +118,9 @@ int32_t MakeDirectory(PP_Resource directory_ref_id, PluginInstance* instance = file_system->instance(); if (!instance->delegate()->MakeDirectory( - directory_ref->GetSystemPath(), make_ancestors, + directory_ref->GetSystemPath(), PPBoolToBool(make_ancestors), new FileCallbacks(instance->module()->AsWeakPtr(), - callback, NULL, NULL))) + callback, NULL, NULL, NULL))) return PP_ERROR_FAILED; return PP_ERROR_WOULDBLOCK; @@ -139,7 +142,7 @@ int32_t Query(PP_Resource file_ref_id, if (!instance->delegate()->Query( file_ref->GetSystemPath(), new FileCallbacks(instance->module()->AsWeakPtr(), - callback, info, file_system))) + callback, info, file_system, NULL))) return PP_ERROR_FAILED; return PP_ERROR_WOULDBLOCK; @@ -163,7 +166,7 @@ int32_t Touch(PP_Resource file_ref_id, file_ref->GetSystemPath(), base::Time::FromDoubleT(last_access_time), base::Time::FromDoubleT(last_modified_time), new FileCallbacks(instance->module()->AsWeakPtr(), - callback, NULL, NULL))) + callback, NULL, NULL, NULL))) return PP_ERROR_FAILED; return PP_ERROR_WOULDBLOCK; @@ -184,7 +187,7 @@ int32_t Delete(PP_Resource file_ref_id, if (!instance->delegate()->Delete( file_ref->GetSystemPath(), new FileCallbacks(instance->module()->AsWeakPtr(), - callback, NULL, NULL))) + callback, NULL, NULL, NULL))) return PP_ERROR_FAILED; return PP_ERROR_WOULDBLOCK; @@ -212,7 +215,7 @@ int32_t Rename(PP_Resource file_ref_id, if (!instance->delegate()->Rename( file_ref->GetSystemPath(), new_file_ref->GetSystemPath(), new FileCallbacks(instance->module()->AsWeakPtr(), - callback, NULL, NULL))) + callback, NULL, NULL, NULL))) return PP_ERROR_FAILED; return PP_ERROR_WOULDBLOCK; @@ -312,7 +315,19 @@ FilePath FileRef::GetSystemPath() const { if (GetFileSystemType() == PP_FILESYSTEMTYPE_EXTERNAL) return system_path_; - return file_system_->root_path().AppendASCII(virtual_path_); + // Since |virtual_path_| starts with a '/', it is considered an absolute path + // on POSIX systems. We need to remove the '/' before calling Append() or we + // will run into a DCHECK. + FilePath virtual_file_path( +#if defined(OS_WIN) + UTF8ToWide(virtual_path_.substr(1)) +#elif defined(OS_POSIX) + virtual_path_.substr(1) +#else +#error "Unsupported platform." +#endif + ); + return file_system_->root_path().Append(virtual_file_path); } } // namespace pepper diff --git a/webkit/glue/plugins/pepper_file_ref.h b/webkit/glue/plugins/pepper_file_ref.h index 4dd8826..88020c1 100644 --- a/webkit/glue/plugins/pepper_file_ref.h +++ b/webkit/glue/plugins/pepper_file_ref.h @@ -8,7 +8,7 @@ #include <string> #include "base/file_path.h" -#include "third_party/ppapi/c/dev/ppb_file_ref_dev.h" +#include "ppapi/c/dev/ppb_file_ref_dev.h" #include "webkit/glue/plugins/pepper_resource.h" namespace pepper { diff --git a/webkit/glue/plugins/pepper_file_system.cc b/webkit/glue/plugins/pepper_file_system.cc index 21321a5..9262798 100644 --- a/webkit/glue/plugins/pepper_file_system.cc +++ b/webkit/glue/plugins/pepper_file_system.cc @@ -5,13 +5,14 @@ #include "webkit/glue/plugins/pepper_file_system.h" #include "base/ref_counted.h" -#include "third_party/ppapi/c/dev/ppb_file_system_dev.h" -#include "third_party/ppapi/c/pp_completion_callback.h" +#include "ppapi/c/dev/ppb_file_system_dev.h" +#include "ppapi/c/pp_completion_callback.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_directory_reader.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" @@ -57,7 +58,7 @@ int32_t Open(PP_Resource file_system_id, instance->container()->element().document().frame()->url(), file_system_type, expected_size, new FileCallbacks(instance->module()->AsWeakPtr(), - callback, NULL, file_system))) + callback, NULL, file_system, NULL))) return PP_ERROR_FAILED; return PP_ERROR_WOULDBLOCK; diff --git a/webkit/glue/plugins/pepper_file_system.h b/webkit/glue/plugins/pepper_file_system.h index f883299..97f1c7d 100644 --- a/webkit/glue/plugins/pepper_file_system.h +++ b/webkit/glue/plugins/pepper_file_system.h @@ -7,7 +7,7 @@ #include "base/basictypes.h" #include "base/file_path.h" -#include "third_party/ppapi/c/dev/pp_file_info_dev.h" +#include "ppapi/c/dev/pp_file_info_dev.h" #include "webkit/glue/plugins/pepper_resource.h" struct PPB_FileSystem_Dev; diff --git a/webkit/glue/plugins/pepper_font.cc b/webkit/glue/plugins/pepper_font.cc index cad39f5..553c8ed 100644 --- a/webkit/glue/plugins/pepper_font.cc +++ b/webkit/glue/plugins/pepper_font.cc @@ -6,14 +6,15 @@ #include "base/logging.h" #include "base/utf_string_conversions.h" -#include "third_party/ppapi/c/dev/ppb_font_dev.h" -#include "third_party/ppapi/c/pp_rect.h" +#include "ppapi/c/dev/ppb_font_dev.h" +#include "ppapi/c/pp_rect.h" #include "third_party/WebKit/WebKit/chromium/public/WebFont.h" #include "third_party/WebKit/WebKit/chromium/public/WebFontDescription.h" #include "third_party/WebKit/WebKit/chromium/public/WebRect.h" #include "third_party/WebKit/WebKit/chromium/public/WebFloatPoint.h" #include "third_party/WebKit/WebKit/chromium/public/WebFloatRect.h" #include "third_party/WebKit/WebKit/chromium/public/WebTextRun.h" +#include "webkit/glue/plugins/pepper_common.h" #include "webkit/glue/plugins/pepper_image_data.h" #include "webkit/glue/plugins/pepper_plugin_module.h" #include "webkit/glue/plugins/pepper_string.h" @@ -87,8 +88,8 @@ WebFontDescription PPFontDescToWebFontDesc(const PP_FontDescription_Dev& font) { result.family = UTF8ToUTF16(face_name->value()); result.genericFamily = PP_FONTFAMILY_TO_WEB_FONTFAMILY(font.family); result.size = static_cast<float>(font.size); - result.italic = font.italic; - result.smallCaps = font.small_caps; + result.italic = PPBoolToBool(font.italic); + result.smallCaps = PPBoolToBool(font.small_caps); result.weight = static_cast<WebFontDescription::Weight>(font.weight); result.letterSpacing = static_cast<short>(font.letter_spacing); result.wordSpacing = static_cast<short>(font.word_spacing); @@ -102,7 +103,8 @@ bool PPTextRunToWebTextRun(const PP_TextRun_Dev* run, WebTextRun* output) { if (!text_string) return false; *output = WebTextRun(UTF8ToUTF16(text_string->value()), - run->rtl, run->override_direction); + PPBoolToBool(run->rtl), + PPBoolToBool(run->override_direction)); return true; } @@ -119,31 +121,31 @@ PP_Resource Create(PP_Module module_id, return font->GetReference(); } -bool IsFont(PP_Resource resource) { - return !!Resource::GetAs<Font>(resource).get(); +PP_Bool IsFont(PP_Resource resource) { + return BoolToPPBool(!!Resource::GetAs<Font>(resource).get()); } -bool Describe(PP_Resource font_id, +PP_Bool Describe(PP_Resource font_id, PP_FontDescription_Dev* description, PP_FontMetrics_Dev* metrics) { scoped_refptr<Font> font(Resource::GetAs<Font>(font_id)); if (!font.get()) - return false; - return font->Describe(description, metrics); + return PP_FALSE; + return BoolToPPBool(font->Describe(description, metrics)); } -bool DrawTextAt(PP_Resource font_id, +PP_Bool DrawTextAt(PP_Resource font_id, PP_Resource image_data, const PP_TextRun_Dev* text, const PP_Point* position, uint32_t color, const PP_Rect* clip, - bool image_data_is_opaque) { + PP_Bool image_data_is_opaque) { scoped_refptr<Font> font(Resource::GetAs<Font>(font_id)); if (!font.get()) - return false; - return font->DrawTextAt(image_data, text, position, color, clip, - image_data_is_opaque); + return PP_FALSE; + return BoolToPPBool(font->DrawTextAt(image_data, text, position, color, clip, + PPBoolToBool(image_data_is_opaque))); } int32_t MeasureText(PP_Resource font_id, const PP_TextRun_Dev* text) { @@ -211,8 +213,8 @@ bool Font::Describe(PP_FontDescription_Dev* description, description->family = static_cast<PP_FontFamily_Dev>(web_desc.genericFamily); description->size = static_cast<uint32_t>(web_desc.size); description->weight = static_cast<PP_FontWeight_Dev>(web_desc.weight); - description->italic = web_desc.italic; - description->small_caps = web_desc.smallCaps; + description->italic = BoolToPPBool(web_desc.italic); + description->small_caps = BoolToPPBool(web_desc.smallCaps); metrics->height = font_->height(); metrics->ascent = font_->ascent(); diff --git a/webkit/glue/plugins/pepper_font.h b/webkit/glue/plugins/pepper_font.h index 34fe521..3cc001c 100644 --- a/webkit/glue/plugins/pepper_font.h +++ b/webkit/glue/plugins/pepper_font.h @@ -6,7 +6,7 @@ #define WEBKIT_GLUE_PLUGINS_PEPPER_FONT_H_ #include "base/scoped_ptr.h" -#include "third_party/ppapi/c/dev/ppb_font_dev.h" +#include "ppapi/c/dev/ppb_font_dev.h" #include "webkit/glue/plugins/pepper_resource.h" namespace WebKit { diff --git a/webkit/glue/plugins/pepper_fullscreen_container.h b/webkit/glue/plugins/pepper_fullscreen_container.h index 5f67538..7d86320 100644 --- a/webkit/glue/plugins/pepper_fullscreen_container.h +++ b/webkit/glue/plugins/pepper_fullscreen_container.h @@ -23,6 +23,9 @@ class FullscreenContainer { // Invalidates a partial region of the plugin. virtual void InvalidateRect(const WebKit::WebRect&) = 0; + // Scrolls a partial region of the plugin in the given direction. + virtual void ScrollRect(int dx, int dy, const WebKit::WebRect&) = 0; + // Destroys the fullscreen window. This also destroys the FullscreenContainer // instance. virtual void Destroy() = 0; diff --git a/webkit/glue/plugins/pepper_graphics_2d.cc b/webkit/glue/plugins/pepper_graphics_2d.cc index a75da85..a8d5091 100644 --- a/webkit/glue/plugins/pepper_graphics_2d.cc +++ b/webkit/glue/plugins/pepper_graphics_2d.cc @@ -13,12 +13,13 @@ #include "gfx/point.h" #include "gfx/rect.h" #include "skia/ext/platform_canvas.h" -#include "third_party/ppapi/c/pp_errors.h" -#include "third_party/ppapi/c/pp_module.h" -#include "third_party/ppapi/c/pp_rect.h" -#include "third_party/ppapi/c/pp_resource.h" -#include "third_party/ppapi/c/ppb_graphics_2d.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/pp_module.h" +#include "ppapi/c/pp_rect.h" +#include "ppapi/c/pp_resource.h" +#include "ppapi/c/ppb_graphics_2d.h" #include "third_party/skia/include/core/SkBitmap.h" +#include "webkit/glue/plugins/pepper_common.h" #include "webkit/glue/plugins/pepper_image_data.h" #include "webkit/glue/plugins/pepper_plugin_instance.h" #include "webkit/glue/plugins/pepper_plugin_module.h" @@ -112,28 +113,28 @@ void ConvertImageData(ImageData* src_image, const SkIRect& src_rect, PP_Resource Create(PP_Module module_id, const PP_Size* size, - bool is_always_opaque) { + PP_Bool is_always_opaque) { PluginModule* module = ResourceTracker::Get()->GetModule(module_id); if (!module) return 0; scoped_refptr<Graphics2D> context(new Graphics2D(module)); - if (!context->Init(size->width, size->height, is_always_opaque)) + if (!context->Init(size->width, size->height, PPBoolToBool(is_always_opaque))) return 0; return context->GetReference(); } -bool IsGraphics2D(PP_Resource resource) { - return !!Resource::GetAs<Graphics2D>(resource); +PP_Bool IsGraphics2D(PP_Resource resource) { + return BoolToPPBool(!!Resource::GetAs<Graphics2D>(resource)); } -bool Describe(PP_Resource graphics_2d, +PP_Bool Describe(PP_Resource graphics_2d, PP_Size* size, - bool* is_always_opaque) { + PP_Bool* is_always_opaque) { scoped_refptr<Graphics2D> context( Resource::GetAs<Graphics2D>(graphics_2d)); if (!context) - return false; + return PP_FALSE; return context->Describe(size, is_always_opaque); } @@ -242,11 +243,11 @@ bool Graphics2D::Init(int width, int height, bool is_always_opaque) { return true; } -bool Graphics2D::Describe(PP_Size* size, bool* is_always_opaque) { +PP_Bool Graphics2D::Describe(PP_Size* size, PP_Bool* is_always_opaque) { size->width = image_data_->width(); size->height = image_data_->height(); - *is_always_opaque = false; // TODO(brettw) implement this. - return true; + *is_always_opaque = PP_FALSE; // TODO(brettw) implement this. + return PP_TRUE; } void Graphics2D::PaintImageData(PP_Resource image_data, @@ -334,7 +335,7 @@ int32_t Graphics2D::Flush(const PP_CompletionCallback& callback) { if (!callback.func) return PP_ERROR_BADARGUMENT; - gfx::Rect changed_rect; + bool nothing_visible = true; for (size_t i = 0; i < queued_operations_.size(); i++) { QueuedOperation& operation = queued_operations_[i]; gfx::Rect op_rect; @@ -354,26 +355,34 @@ int32_t Graphics2D::Flush(const PP_CompletionCallback& callback) { ExecuteReplaceContents(operation.replace_image, &op_rect); break; } - changed_rect = changed_rect.Union(op_rect); + + // We need the rect to be in terms of the current clip rect of the plugin + // since that's what will actually be painted. If we issue an invalidate + // for a clipped-out region, WebKit will do nothing and we won't get any + // ViewInitiatedPaint/ViewFlushedPaint calls, leaving our callback stranded. + gfx::Rect visible_changed_rect; + if (bound_instance_ && !op_rect.IsEmpty()) + visible_changed_rect = bound_instance_->clip().Intersect(op_rect); + + if (bound_instance_ && !visible_changed_rect.IsEmpty()) { + if (operation.type == QueuedOperation::SCROLL) { + bound_instance_->ScrollRect(operation.scroll_dx, operation.scroll_dy, + visible_changed_rect); + } else { + bound_instance_->InvalidateRect(visible_changed_rect); + } + nothing_visible = false; + } } queued_operations_.clear(); flushed_any_data_ = true; - // We need the rect to be in terms of the current clip rect of the plugin - // since that's what will actually be painted. If we issue an invalidate - // for a clipped-out region, WebKit will do nothing and we won't get any - // ViewInitiatedPaint/ViewFlushedPaint calls, leaving our callback stranded. - gfx::Rect visible_changed_rect; - if (bound_instance_ && !changed_rect.IsEmpty()) - visible_changed_rect = bound_instance_->clip().Intersect(changed_rect); - - if (bound_instance_ && !visible_changed_rect.IsEmpty()) { - unpainted_flush_callback_.Set(callback); - bound_instance_->InvalidateRect(visible_changed_rect); - } else { + if (nothing_visible) { // There's nothing visible to invalidate so just schedule the callback to // execute in the next round of the message loop. ScheduleOffscreenCallback(FlushCallbackData(callback)); + } else { + unpainted_flush_callback_.Set(callback); } return PP_ERROR_WOULDBLOCK; } diff --git a/webkit/glue/plugins/pepper_graphics_2d.h b/webkit/glue/plugins/pepper_graphics_2d.h index ff4cd16..78170ab 100644 --- a/webkit/glue/plugins/pepper_graphics_2d.h +++ b/webkit/glue/plugins/pepper_graphics_2d.h @@ -8,8 +8,8 @@ #include <vector> #include "base/basictypes.h" -#include "third_party/ppapi/c/pp_completion_callback.h" -#include "third_party/ppapi/c/ppb_graphics_2d.h" +#include "ppapi/c/pp_completion_callback.h" +#include "ppapi/c/ppb_graphics_2d.h" #include "third_party/WebKit/WebKit/chromium/public/WebCanvas.h" #include "webkit/glue/plugins/pepper_resource.h" @@ -42,7 +42,7 @@ class Graphics2D : public Resource { virtual Graphics2D* AsGraphics2D() { return this; } // PPB_Graphics2D functions. - bool Describe(PP_Size* size, bool* is_always_opaque); + PP_Bool Describe(PP_Size* size, PP_Bool* is_always_opaque); void PaintImageData(PP_Resource image_data, const PP_Point* top_left, const PP_Rect* src_rect); diff --git a/webkit/glue/plugins/pepper_graphics_3d.cc b/webkit/glue/plugins/pepper_graphics_3d.cc index 1ebc3ea..2dc4def 100644 --- a/webkit/glue/plugins/pepper_graphics_3d.cc +++ b/webkit/glue/plugins/pepper_graphics_3d.cc @@ -7,7 +7,8 @@ #include "gpu/command_buffer/common/command_buffer.h" #include "base/singleton.h" #include "base/thread_local.h" -#include "third_party/ppapi/c/dev/ppb_graphics_3d_dev.h" +#include "ppapi/c/dev/ppb_graphics_3d_dev.h" +#include "webkit/glue/plugins/pepper_common.h" #include "webkit/glue/plugins/pepper_plugin_instance.h" namespace pepper { @@ -22,24 +23,24 @@ typedef Singleton<base::ThreadLocalPointer<Graphics3D>, // Size of the transfer buffer. enum { kTransferBufferSize = 512 * 1024 }; -bool IsGraphics3D(PP_Resource resource) { - return !!Resource::GetAs<Graphics3D>(resource); +PP_Bool IsGraphics3D(PP_Resource resource) { + return BoolToPPBool(!!Resource::GetAs<Graphics3D>(resource)); } -bool GetConfigs(int32_t* configs, int32_t config_size, int32_t* num_config) { +PP_Bool GetConfigs(int32_t* configs, int32_t config_size, int32_t* num_config) { // TODO(neb): Implement me! - return false; + return PP_FALSE; } -bool ChooseConfig(const int32_t* attrib_list, int32_t* configs, - int32_t config_size, int32_t* num_config) { +PP_Bool ChooseConfig(const int32_t* attrib_list, int32_t* configs, + int32_t config_size, int32_t* num_config) { // TODO(neb): Implement me! - return false; + return PP_FALSE; } -bool GetConfigAttrib(int32_t config, int32_t attribute, int32_t* value) { +PP_Bool GetConfigAttrib(int32_t config, int32_t attribute, int32_t* value) { // TODO(neb): Implement me! - return false; + return PP_FALSE; } const char* QueryString(int32_t name) { @@ -80,29 +81,35 @@ void* GetProcAddress(const char* name) { return NULL; } -bool MakeCurrent(PP_Resource graphics3d) { +PP_Bool MakeCurrent(PP_Resource graphics3d) { if (!graphics3d) { Graphics3D::ResetCurrent(); - return true; + return PP_TRUE; } else { scoped_refptr<Graphics3D> context(Resource::GetAs<Graphics3D>(graphics3d)); - return context.get() && context->MakeCurrent(); + return BoolToPPBool(context.get() && context->MakeCurrent()); } } PP_Resource GetCurrentContext() { - Graphics3D* currentContext = Graphics3D::GetCurrent(); - return currentContext ? currentContext->GetReference() : 0; + Graphics3D* current_context = Graphics3D::GetCurrent(); + return current_context ? current_context->GetReference() : 0; } -bool SwapBuffers(PP_Resource graphics3d) { +PP_Bool SwapBuffers(PP_Resource graphics3d) { scoped_refptr<Graphics3D> context(Resource::GetAs<Graphics3D>(graphics3d)); - return context && context->SwapBuffers(); + return BoolToPPBool(context && context->SwapBuffers()); } uint32_t GetError() { - // TODO(neb): Figure out error checking. - return PP_GRAPHICS_3D_ERROR_SUCCESS; + // Technically, this should return the last error that occurred on the current + // thread, rather than an error associated with a particular context. + // TODO(apatrick): Fix this. + Graphics3D* current_context = Graphics3D::GetCurrent(); + if (!current_context) + return 0; + + return current_context->GetError(); } const PPB_Graphics3D_Dev ppb_graphics3d = { @@ -122,10 +129,8 @@ const PPB_Graphics3D_Dev ppb_graphics3d = { } // namespace Graphics3D::Graphics3D(PluginModule* module) - : Resource(module), - command_buffer_(NULL), - transfer_buffer_id_(0), - method_factory3d_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { + : Resource(module), + bound_instance_(NULL) { } const PPB_Graphics3D_Dev* Graphics3D::GetInterface() { @@ -153,103 +158,98 @@ bool Graphics3D::Init(PP_Instance instance_id, int32_t config, // Create and initialize the objects required to issue GLES2 calls. platform_context_.reset(instance->delegate()->CreateContext3D()); - if (!platform_context_.get()) + if (!platform_context_.get()) { + Destroy(); return false; + } - if (!platform_context_->Init(instance->position(), - instance->clip())) { - platform_context_.reset(); + if (!platform_context_->Init()) { + Destroy(); return false; } - command_buffer_ = platform_context_->GetCommandBuffer(); - gles2_helper_.reset(new gpu::gles2::GLES2CmdHelper(command_buffer_)); - gpu::Buffer buffer = command_buffer_->GetRingBuffer(); - if (gles2_helper_->Initialize(buffer.size)) { - transfer_buffer_id_ = - command_buffer_->CreateTransferBuffer(kTransferBufferSize); - gpu::Buffer transfer_buffer = - command_buffer_->GetTransferBuffer(transfer_buffer_id_); - if (transfer_buffer.ptr) { - gles2_implementation_.reset(new gpu::gles2::GLES2Implementation( - gles2_helper_.get(), - transfer_buffer.size, - transfer_buffer.ptr, - transfer_buffer_id_, - false)); - platform_context_->SetNotifyRepaintTask( - method_factory3d_.NewRunnableMethod(&Graphics3D::HandleRepaint, - instance_id)); - return true; - } + + gles2_implementation_ = platform_context_->GetGLES2Implementation(); + DCHECK(gles2_implementation_); + + return true; +} + +bool Graphics3D::BindToInstance(PluginInstance* new_instance) { + if (bound_instance_ == new_instance) + return true; // Rebinding the same device, nothing to do. + if (bound_instance_ && new_instance) + return false; // Can't change a bound device. + + if (new_instance) { + // Resize the backing texture to the size of the instance when it is bound. + platform_context_->ResizeBackingTexture(new_instance->position().size()); + + // This is a temporary hack. The SwapBuffers is issued to force the resize + // to take place before any subsequent rendering. This might lead to a + // partially rendered frame being displayed. It is also not thread safe + // since the SwapBuffers is written to the command buffer and that command + // buffer might be written to by another thread. + // TODO(apatrick): Figure out the semantics of binding and resizing. + platform_context_->SwapBuffers(); } - // Tear everything down if initialization failed. - Destroy(); - return false; + bound_instance_ = new_instance; + return true; } bool Graphics3D::MakeCurrent() { - if (!command_buffer_) + if (!platform_context_.get()) return false; CurrentContextKey::get()->Set(this); - // Don't request latest error status from service. Just use the locally - // cached information from the last flush. - // TODO(apatrick): I'm not sure if this should actually change the - // current context if it fails. For now it gets changed even if it fails - // becuase making GL calls with a NULL context crashes. - // TODO(neb): Figure out error checking. -// if (command_buffer_->GetCachedError() != gpu::error::kNoError) -// return false; + // TODO(apatrick): Return false on context lost. return true; } bool Graphics3D::SwapBuffers() { - if (!command_buffer_) + if (!platform_context_.get()) return false; - // Don't request latest error status from service. Just use the locally cached - // information from the last flush. - // TODO(neb): Figure out error checking. -// if (command_buffer_->GetCachedError() != gpu::error::kNoError) -// return false; + return platform_context_->SwapBuffers(); +} - gles2_implementation_->SwapBuffers(); - return true; +unsigned Graphics3D::GetError() { + if (!platform_context_.get()) + return 0; + + return platform_context_->GetError(); } -void Graphics3D::Destroy() { - if (GetCurrent() == this) { - ResetCurrent(); - } +void Graphics3D::ResizeBackingTexture(const gfx::Size& size) { + if (!platform_context_.get()) + return; - method_factory3d_.RevokeAll(); + platform_context_->ResizeBackingTexture(size); +} - gles2_implementation_.reset(); +void Graphics3D::SetSwapBuffersCallback(Callback0::Type* callback) { + if (!platform_context_.get()) + return; - if (command_buffer_ && transfer_buffer_id_ != 0) { - command_buffer_->DestroyTransferBuffer(transfer_buffer_id_); - transfer_buffer_id_ = 0; - } + platform_context_->SetSwapBuffersCallback(callback); +} - gles2_helper_.reset(); +unsigned Graphics3D::GetBackingTextureId() { + if (!platform_context_.get()) + return 0; - // Platform context owns the command buffer. - platform_context_.reset(); - command_buffer_ = NULL; + return platform_context_->GetBackingTextureId(); } -void Graphics3D::HandleRepaint(PP_Instance instance_id) { - PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id); - if (instance) { - instance->Graphics3DContextLost(); - if (platform_context_.get()) { - platform_context_->SetNotifyRepaintTask( - method_factory3d_.NewRunnableMethod(&Graphics3D::HandleRepaint, - instance_id)); - } +void Graphics3D::Destroy() { + if (GetCurrent() == this) { + ResetCurrent(); } + + gles2_implementation_ = NULL; + + platform_context_.reset(); } } // namespace pepper diff --git a/webkit/glue/plugins/pepper_graphics_3d.h b/webkit/glue/plugins/pepper_graphics_3d.h index 16258ed..5c00068 100644 --- a/webkit/glue/plugins/pepper_graphics_3d.h +++ b/webkit/glue/plugins/pepper_graphics_3d.h @@ -5,19 +5,19 @@ #ifndef WEBKIT_GLUE_PLUGINS_PEPPER_GRAPHICS_3D_H_ #define WEBKIT_GLUE_PLUGINS_PEPPER_GRAPHICS_3D_H_ +#include "base/callback.h" #include "base/scoped_ptr.h" +#include "gfx/size.h" #include "gpu/command_buffer/client/gles2_cmd_helper.h" #include "gpu/command_buffer/client/gles2_implementation.h" -#include "third_party/ppapi/c/pp_instance.h" +#include "ppapi/c/pp_instance.h" #include "webkit/glue/plugins/pepper_plugin_delegate.h" #include "webkit/glue/plugins/pepper_resource.h" -namespace gfx { -class Rect; -} // namespace gfx - namespace gpu { -class CommandBuffer; +namespace gles2 { +class GLES2Implementation; +} } // namespace gpu struct PPB_Graphics3D_Dev; @@ -48,35 +48,40 @@ class Graphics3D : public Resource { bool Init(PP_Instance instance_id, int32_t config, const int32_t* attrib_list); + // Associates this Graphics3D with the given plugin instance. You can pass + // NULL to clear the existing device. Returns true on success. In this case, + // the last rendered frame is displayed. + // TODO(apatrick): Figure out the best semantics here. + bool BindToInstance(PluginInstance* new_instance); + bool MakeCurrent(); bool SwapBuffers(); + unsigned GetError(); + + void ResizeBackingTexture(const gfx::Size& size); + + void SetSwapBuffersCallback(Callback0::Type* callback); + + unsigned GetBackingTextureId(); + gpu::gles2::GLES2Implementation* impl() { - return gles2_implementation_.get(); + return gles2_implementation_; } private: - void HandleRepaint(PP_Instance instance_id); void Destroy(); + // Non-owning pointer to the plugin instance this context is currently bound + // to, if any. If the context is currently unbound, this will be NULL. + PluginInstance* bound_instance_; + // PluginDelegate's 3D Context. Responsible for providing the command buffer. scoped_ptr<PluginDelegate::PlatformContext3D> platform_context_; - // Command buffer is owned by the platform context. - gpu::CommandBuffer* command_buffer_; - - // GLES2 Command Helper instance. - scoped_ptr<gpu::gles2::GLES2CmdHelper> gles2_helper_; - - // ID of the transfer buffer. - int32_t transfer_buffer_id_; - - // GLES2 Implementation instance. - scoped_ptr<gpu::gles2::GLES2Implementation> gles2_implementation_; - - // Runnable methods that must be cancelled when the 3D context is destroyed. - ScopedRunnableMethodFactory<Graphics3D> method_factory3d_; + // GLES2 Implementation instance. Owned by the platform context's GGL context. + gpu::gles2::GLES2Implementation* gles2_implementation_; }; } // namespace pepper diff --git a/webkit/glue/plugins/pepper_graphics_3d_gl.cc b/webkit/glue/plugins/pepper_graphics_3d_gl.cc index 897e459..2ce8de0 100644 --- a/webkit/glue/plugins/pepper_graphics_3d_gl.cc +++ b/webkit/glue/plugins/pepper_graphics_3d_gl.cc @@ -7,7 +7,7 @@ #include "webkit/glue/plugins/pepper_graphics_3d.h" #include "gpu/command_buffer/client/gles2_implementation.h" -#include "third_party/ppapi/c/dev/ppb_opengles_dev.h" +#include "ppapi/c/dev/ppb_opengles_dev.h" namespace pepper { diff --git a/webkit/glue/plugins/pepper_image_data.cc b/webkit/glue/plugins/pepper_image_data.cc index 2ee8b21..92d4364 100644 --- a/webkit/glue/plugins/pepper_image_data.cc +++ b/webkit/glue/plugins/pepper_image_data.cc @@ -10,12 +10,13 @@ #include "base/logging.h" #include "base/scoped_ptr.h" #include "skia/ext/platform_canvas.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/ppb_image_data.h" -#include "third_party/ppapi/c/trusted/ppb_image_data_trusted.h" +#include "ppapi/c/pp_instance.h" +#include "ppapi/c/pp_module.h" +#include "ppapi/c/pp_resource.h" +#include "ppapi/c/ppb_image_data.h" +#include "ppapi/c/trusted/ppb_image_data_trusted.h" #include "third_party/skia/include/core/SkColorPriv.h" +#include "webkit/glue/plugins/pepper_common.h" #include "webkit/glue/plugins/pepper_plugin_instance.h" #include "webkit/glue/plugins/pepper_plugin_module.h" @@ -27,38 +28,42 @@ PP_ImageDataFormat GetNativeImageDataFormat() { return ImageData::GetNativeImageDataFormat(); } -bool IsImageDataFormatSupported(PP_ImageDataFormat format) { - return ImageData::IsImageDataFormatSupported(format); +PP_Bool IsImageDataFormatSupported(PP_ImageDataFormat format) { + return BoolToPPBool(ImageData::IsImageDataFormatSupported(format)); } PP_Resource Create(PP_Module module_id, PP_ImageDataFormat format, const PP_Size* size, - bool init_to_zero) { + PP_Bool init_to_zero) { PluginModule* module = ResourceTracker::Get()->GetModule(module_id); if (!module) return 0; scoped_refptr<ImageData> data(new ImageData(module)); - if (!data->Init(format, size->width, size->height, init_to_zero)) + if (!data->Init(format, + size->width, + size->height, + PPBoolToBool(init_to_zero))) { return 0; + } return data->GetReference(); } -bool IsImageData(PP_Resource resource) { - return !!Resource::GetAs<ImageData>(resource); +PP_Bool IsImageData(PP_Resource resource) { + return BoolToPPBool(!!Resource::GetAs<ImageData>(resource)); } -bool Describe(PP_Resource resource, PP_ImageDataDesc* desc) { +PP_Bool Describe(PP_Resource resource, PP_ImageDataDesc* desc) { // Give predictable values on failure. memset(desc, 0, sizeof(PP_ImageDataDesc)); scoped_refptr<ImageData> image_data(Resource::GetAs<ImageData>(resource)); if (!image_data) - return false; + return PP_FALSE; image_data->Describe(desc); - return true; + return PP_TRUE; } void* Map(PP_Resource resource) { @@ -74,10 +79,10 @@ void Unmap(PP_Resource resource) { image_data->Unmap(); } -uint64_t GetNativeMemoryHandle2(PP_Resource resource) { +uint64_t GetNativeMemoryHandle2(PP_Resource resource, uint32_t* byte_count) { scoped_refptr<ImageData> image_data(Resource::GetAs<ImageData>(resource)); if (image_data) - return image_data->GetNativeMemoryHandle(); + return image_data->GetNativeMemoryHandle(byte_count); return 0; } @@ -184,8 +189,8 @@ void ImageData::Unmap() { // in the future to save some memory. } -uint64 ImageData::GetNativeMemoryHandle() const { - return platform_image_->GetSharedMemoryHandle(); +uint64 ImageData::GetNativeMemoryHandle(uint32* byte_count) const { + return platform_image_->GetSharedMemoryHandle(byte_count); } const SkBitmap* ImageData::GetMappedBitmap() const { diff --git a/webkit/glue/plugins/pepper_image_data.h b/webkit/glue/plugins/pepper_image_data.h index f8c713a..473d4aa 100644 --- a/webkit/glue/plugins/pepper_image_data.h +++ b/webkit/glue/plugins/pepper_image_data.h @@ -7,7 +7,7 @@ #include "base/basictypes.h" #include "base/scoped_ptr.h" -#include "third_party/ppapi/c/ppb_image_data.h" +#include "ppapi/c/ppb_image_data.h" #include "webkit/glue/plugins/pepper_plugin_delegate.h" #include "webkit/glue/plugins/pepper_resource.h" @@ -64,7 +64,7 @@ class ImageData : public Resource { void Unmap(); // PPB_ImageDataTrusted implementation. - uint64 GetNativeMemoryHandle() const; + uint64 GetNativeMemoryHandle(uint32* byte_count) const; // The mapped bitmap and canvas will be NULL if the image is not mapped. skia::PlatformCanvas* mapped_canvas() const { return mapped_canvas_.get(); } diff --git a/webkit/glue/plugins/pepper_plugin_delegate.h b/webkit/glue/plugins/pepper_plugin_delegate.h index 7738fbf..5e6f9a2 100644 --- a/webkit/glue/plugins/pepper_plugin_delegate.h +++ b/webkit/glue/plugins/pepper_plugin_delegate.h @@ -13,10 +13,11 @@ #include "base/shared_memory.h" #include "base/sync_socket.h" #include "base/task.h" +#include "gfx/size.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 "ppapi/c/pp_completion_callback.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/pp_stdint.h" #include "webkit/fileapi/file_system_types.h" #include "webkit/glue/plugins/pepper_dir_contents.h" @@ -37,7 +38,9 @@ class Rect; } namespace gpu { -class CommandBuffer; +namespace gles2 { +class GLES2Implementation; +} } namespace skia { @@ -75,9 +78,10 @@ class PluginDelegate { virtual skia::PlatformCanvas* Map() = 0; // Returns the platform-specific shared memory handle of the data backing - // this image. This is used by NativeClient to send the image to the - // out-of-process plugin. Returns 0 on failure. - virtual intptr_t GetSharedMemoryHandle() const = 0; + // this image. This is used by PPAPI proxying to send the image to the + // out-of-process plugin. On success, the size in bytes will be placed into + // |*bytes_count|. Returns 0 on failure. + virtual intptr_t GetSharedMemoryHandle(uint32* byte_count) const = 0; virtual TransportDIB* GetTransportDIB() const = 0; }; @@ -87,14 +91,30 @@ class PluginDelegate { virtual ~PlatformContext3D() {} // Initialize the context. - virtual bool Init(const gfx::Rect& position, const gfx::Rect& clip) = 0; + virtual bool Init() = 0; + + // Present the rendered frame to the compositor. + virtual bool SwapBuffers() = 0; + + // Get the last EGL error. + virtual unsigned GetError() = 0; - // This call will return the address of the command buffer object that is - // constructed in Initialize() and is valid until this context is destroyed. - virtual gpu::CommandBuffer* GetCommandBuffer() = 0; + // Resize the backing texture used as a back buffer by OpenGL. + virtual void ResizeBackingTexture(const gfx::Size& size) = 0; - // Sets the function to be called on repaint. - virtual void SetNotifyRepaintTask(Task* task) = 0; + // Set an optional callback that will be invoked when the side effects of + // a SwapBuffers call become visible to the compositor. Takes ownership + // of the callback. + virtual void SetSwapBuffersCallback(Callback0::Type* callback) = 0; + + // If the plugin instance is backed by an OpenGL, return its ID in the + // compositors namespace. Otherwise return 0. Returns 0 by default. + virtual unsigned GetBackingTextureId() = 0; + + // This call will return the address of the GLES2 implementation for this + // context that is constructed in Initialize() and is valid until this + // context is destroyed. + virtual gpu::gles2::GLES2Implementation* GetGLES2Implementation() = 0; }; class PlatformAudio { @@ -198,6 +218,9 @@ class PluginDelegate { virtual bool Rename(const FilePath& file_path, const FilePath& new_file_path, fileapi::FileSystemCallbackDispatcher* dispatcher) = 0; + virtual bool ReadDirectory( + const FilePath& directory_path, + fileapi::FileSystemCallbackDispatcher* dispatcher) = 0; virtual base::PlatformFileError OpenModuleLocalFile( const std::string& module_name, diff --git a/webkit/glue/plugins/pepper_plugin_instance.cc b/webkit/glue/plugins/pepper_plugin_instance.cc index 54a1f42..47ea900 100644 --- a/webkit/glue/plugins/pepper_plugin_instance.cc +++ b/webkit/glue/plugins/pepper_plugin_instance.cc @@ -18,24 +18,24 @@ #include "gfx/gdi_util.h" #endif #include "gfx/skia_util.h" +#include "ppapi/c/dev/ppb_find_dev.h" +#include "ppapi/c/dev/ppb_fullscreen_dev.h" +#include "ppapi/c/dev/ppb_zoom_dev.h" +#include "ppapi/c/dev/ppp_find_dev.h" +#include "ppapi/c/dev/ppp_selection_dev.h" +#include "ppapi/c/dev/ppp_zoom_dev.h" +#include "ppapi/c/pp_input_event.h" +#include "ppapi/c/pp_instance.h" +#include "ppapi/c/pp_rect.h" +#include "ppapi/c/pp_resource.h" +#include "ppapi/c/pp_var.h" +#include "ppapi/c/ppb_core.h" +#include "ppapi/c/ppb_instance.h" +#include "ppapi/c/ppp_instance.h" #include "printing/native_metafile.h" #include "printing/units.h" #include "skia/ext/vector_platform_device.h" #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" -#include "third_party/ppapi/c/pp_rect.h" -#include "third_party/ppapi/c/pp_resource.h" -#include "third_party/ppapi/c/pp_var.h" -#include "third_party/ppapi/c/ppb_core.h" -#include "third_party/ppapi/c/ppb_instance.h" -#include "third_party/ppapi/c/ppp_instance.h" #include "third_party/WebKit/WebKit/chromium/public/WebBindings.h" #include "third_party/WebKit/WebKit/chromium/public/WebCursorInfo.h" #include "third_party/WebKit/WebKit/chromium/public/WebDocument.h" @@ -44,9 +44,13 @@ #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/WebString.h" +#include "third_party/WebKit/WebKit/chromium/public/WebURLRequest.h" #include "third_party/WebKit/WebKit/chromium/public/WebView.h" #include "webkit/glue/plugins/pepper_buffer.h" +#include "webkit/glue/plugins/pepper_common.h" #include "webkit/glue/plugins/pepper_graphics_2d.h" +#include "webkit/glue/plugins/pepper_graphics_3d.h" #include "webkit/glue/plugins/pepper_event_conversion.h" #include "webkit/glue/plugins/pepper_fullscreen_container.h" #include "webkit/glue/plugins/pepper_image_data.h" @@ -60,9 +64,12 @@ using WebKit::WebBindings; using WebKit::WebCanvas; using WebKit::WebCursorInfo; +using WebKit::WebDocument; using WebKit::WebFrame; using WebKit::WebInputEvent; using WebKit::WebPluginContainer; +using WebKit::WebString; +using WebKit::WebURLRequest; using WebKit::WebView; namespace pepper { @@ -155,18 +162,18 @@ PP_Var GetOwnerElementObject(PP_Instance instance_id) { return instance->GetOwnerElementObject(); } -bool BindGraphics(PP_Instance instance_id, PP_Resource device_id) { +PP_Bool BindGraphics(PP_Instance instance_id, PP_Resource graphics_id) { PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id); if (!instance) - return false; - return instance->BindGraphics(device_id); + return PP_FALSE; + return BoolToPPBool(instance->BindGraphics(graphics_id)); } -bool IsFullFrame(PP_Instance instance_id) { +PP_Bool IsFullFrame(PP_Instance instance_id) { PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id); if (!instance) - return false; - return instance->full_frame(); + return PP_FALSE; + return BoolToPPBool(instance->full_frame()); } PP_Var ExecuteScript(PP_Instance instance_id, @@ -188,14 +195,14 @@ const PPB_Instance ppb_instance = { void NumberOfFindResultsChanged(PP_Instance instance_id, int32_t total, - bool final_result) { + PP_Bool final_result) { PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id); if (!instance) return; DCHECK_NE(instance->find_identifier(), -1); instance->delegate()->NumberOfFindResultsChanged( - instance->find_identifier(), total, final_result); + instance->find_identifier(), total, PPBoolToBool(final_result)); } void SelectedFindResultChanged(PP_Instance instance_id, @@ -214,18 +221,18 @@ const PPB_Find_Dev ppb_find = { &SelectedFindResultChanged, }; -bool IsFullscreen(PP_Instance instance_id) { +PP_Bool IsFullscreen(PP_Instance instance_id) { PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id); if (!instance) - return false; - return instance->IsFullscreen(); + return PP_FALSE; + return BoolToPPBool(instance->IsFullscreen()); } -bool SetFullscreen(PP_Instance instance_id, bool fullscreen) { +PP_Bool SetFullscreen(PP_Instance instance_id, PP_Bool fullscreen) { PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id); if (!instance) - return false; - return instance->SetFullscreen(fullscreen); + return PP_FALSE; + return BoolToPPBool(instance->SetFullscreen(PPBoolToBool(fullscreen))); } const PPB_Fullscreen_Dev ppb_fullscreen = { @@ -238,6 +245,15 @@ void ZoomChanged(PP_Instance instance_id, double factor) { if (!instance) return; double zoom_level = WebView::zoomFactorToZoomLevel(factor); + // The conversino from zoom level to factor, and back, can introduce rounding + // errors. i.e. WebKit originally tells us 3.0, but by the time we tell the + // plugin and it tells us back, the level becomes 3.000000000004. Need to + // round or else otherwise if the user zooms out, it will go to 3.0 instead of + // 2.0. + int rounded = + static_cast<int>(zoom_level + (zoom_level > 0 ? 0.001 : -0.001)); + if (abs(rounded - zoom_level) < 0.001) + zoom_level = rounded; instance->container()->zoomLevelChanged(zoom_level); } @@ -295,6 +311,8 @@ PluginInstance::PluginInstance(PluginDelegate* delegate, } PluginInstance::~PluginInstance() { + FOR_EACH_OBSERVER(Observer, observers_, InstanceDestroyed(this)); + delegate_->InstanceDeleted(this); module_->InstanceDeleted(this); @@ -321,11 +339,19 @@ const PPB_Zoom_Dev* PluginInstance::GetZoomInterface() { return &ppb_zoom; } +void PluginInstance::AddObserver(Observer* observer) { + observers_.AddObserver(observer); +} + +void PluginInstance::RemoveObserver(Observer* observer) { + observers_.RemoveObserver(observer); +} + void PluginInstance::Paint(WebCanvas* canvas, const gfx::Rect& plugin_rect, const gfx::Rect& paint_rect) { - if (bound_graphics_2d_) - bound_graphics_2d_->Paint(canvas, plugin_rect, paint_rect); + if (bound_graphics_2d()) + bound_graphics_2d()->Paint(canvas, plugin_rect, paint_rect); } void PluginInstance::InvalidateRect(const gfx::Rect& rect) { @@ -344,6 +370,31 @@ void PluginInstance::InvalidateRect(const gfx::Rect& rect) { } } +void PluginInstance::ScrollRect(int dx, int dy, const gfx::Rect& rect) { + if (fullscreen_container_) { + fullscreen_container_->ScrollRect(dx, dy, rect); + } else { + if (full_frame_) { + container_->scrollRect(dx, dy, rect); + } else { + // Can't do optimized scrolling since there could be other elements on top + // of us. + InvalidateRect(rect); + } + } +} + +unsigned PluginInstance::GetBackingTextureId() { + if (!bound_graphics_3d()) + return 0; + + return bound_graphics_3d()->GetBackingTextureId(); +} + +void PluginInstance::CommitBackingTexture() { + container_->commitBackingTexture(); +} + PP_Var PluginInstance::GetWindowObject() { if (!container_) return PP_MakeUndefined(); @@ -362,35 +413,44 @@ PP_Var PluginInstance::GetOwnerElementObject() { container_->scriptableObjectForElement()); } -bool PluginInstance::BindGraphics(PP_Resource device_id) { - if (!device_id) { +bool PluginInstance::BindGraphics(PP_Resource graphics_id) { + if (!graphics_id) { // Special-case clearing the current device. - if (bound_graphics_2d_) { - bound_graphics_2d_->BindToInstance(NULL); - bound_graphics_2d_ = NULL; + if (bound_graphics_.get()) { + if (bound_graphics_2d()) { + bound_graphics_2d()->BindToInstance(NULL); + } else if (bound_graphics_.get()) { + bound_graphics_3d()->SetSwapBuffersCallback(NULL); + bound_graphics_3d()->BindToInstance(NULL); + } InvalidateRect(gfx::Rect()); } + bound_graphics_ = NULL; return true; } - scoped_refptr<Graphics2D> device_2d = Resource::GetAs<Graphics2D>(device_id); + scoped_refptr<Graphics2D> graphics_2d = + Resource::GetAs<Graphics2D>(graphics_id); + scoped_refptr<Graphics3D> graphics_3d = + Resource::GetAs<Graphics3D>(graphics_id); - if (device_2d) { - if (!device_2d->BindToInstance(this)) + if (graphics_2d) { + if (!graphics_2d->BindToInstance(this)) return false; // Can't bind to more than one instance. + bound_graphics_ = graphics_2d; // See http://crbug.com/49403: this can be further optimized by keeping the // old device around and painting from it. - if (bound_graphics_2d_.get()) { + if (bound_graphics_2d()) { // Start the new image with the content of the old image until the plugin // repaints. const SkBitmap* old_backing_bitmap = - bound_graphics_2d_->image_data()->GetMappedBitmap(); + bound_graphics_2d()->image_data()->GetMappedBitmap(); SkRect old_size = SkRect::MakeWH( SkScalar(static_cast<float>(old_backing_bitmap->width())), SkScalar(static_cast<float>(old_backing_bitmap->height()))); - SkCanvas canvas(*device_2d->image_data()->GetMappedBitmap()); + SkCanvas canvas(*graphics_2d->image_data()->GetMappedBitmap()); canvas.drawBitmap(*old_backing_bitmap, 0, 0); // Fill in any extra space with white. @@ -398,8 +458,14 @@ bool PluginInstance::BindGraphics(PP_Resource device_id) { canvas.drawARGB(255, 255, 255, 255); } - bound_graphics_2d_ = device_2d; // BindToInstance will have invalidated the plugin if necessary. + } else if (graphics_3d) { + if (!graphics_3d->BindToInstance(this)) + return false; + + bound_graphics_ = graphics_3d; + bound_graphics_3d()->SetSwapBuffersCallback( + NewCallback(this, &PluginInstance::CommitBackingTexture)); } return true; @@ -474,13 +540,16 @@ bool PluginInstance::Initialize(WebPluginContainer* container, argc++; } - return instance_interface_->DidCreate(pp_instance(), - argc, argn.get(), argv.get()); + return PPBoolToBool(instance_interface_->DidCreate(pp_instance(), + argc, + argn.get(), + argv.get())); } bool PluginInstance::HandleDocumentLoad(URLLoader* loader) { Resource::ScopedResourceId resource(loader); - return instance_interface_->HandleDocumentLoad(pp_instance(), resource.id); + return PPBoolToBool(instance_interface_->HandleDocumentLoad(pp_instance(), + resource.id)); } bool PluginInstance::HandleInputEvent(const WebKit::WebInputEvent& event, @@ -490,8 +559,10 @@ 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(pp_instance(), &pp_events[i]); + for (size_t i = 0; i < pp_events.size(); i++) { + rv |= PPBoolToBool(instance_interface_->HandleInputEvent(pp_instance(), + &pp_events[i])); + } if (cursor_.get()) *cursor_info = *cursor_; @@ -504,7 +575,17 @@ PP_Var PluginInstance::GetInstanceObject() { void PluginInstance::ViewChanged(const gfx::Rect& position, const gfx::Rect& clip) { + if (position.size() != position_.size() && bound_graphics_3d()) { + // TODO(apatrick): This is a hack to force the back buffer to resize. + // It is obviously wrong to call SwapBuffers when a partial frame has + // potentially been rendered. Plan is to embed resize commands in the + // command buffer just before ViewChanged is called. + bound_graphics_3d()->ResizeBackingTexture(position.size()); + bound_graphics_3d()->SwapBuffers(); + } + position_ = position; + if (clip.IsEmpty()) { // WebKit can give weird (x,y) positions for empty clip rects (since the // position technically doesn't matter). But we want to make these @@ -527,8 +608,10 @@ void PluginInstance::SetWebKitFocus(bool has_focus) { bool old_plugin_focus = PluginHasFocus(); has_webkit_focus_ = has_focus; - if (PluginHasFocus() != old_plugin_focus) - instance_interface_->DidChangeFocus(pp_instance(), PluginHasFocus()); + if (PluginHasFocus() != old_plugin_focus) { + instance_interface_->DidChangeFocus(pp_instance(), + BoolToPPBool(PluginHasFocus())); + } } void PluginInstance::SetContentAreaFocus(bool has_focus) { @@ -537,18 +620,20 @@ void PluginInstance::SetContentAreaFocus(bool has_focus) { bool old_plugin_focus = PluginHasFocus(); has_content_area_focus_ = has_focus; - if (PluginHasFocus() != old_plugin_focus) - instance_interface_->DidChangeFocus(pp_instance(), PluginHasFocus()); + if (PluginHasFocus() != old_plugin_focus) { + instance_interface_->DidChangeFocus(pp_instance(), + BoolToPPBool(PluginHasFocus())); + } } void PluginInstance::ViewInitiatedPaint() { - if (bound_graphics_2d_) - bound_graphics_2d_->ViewInitiatedPaint(); + if (bound_graphics_2d()) + bound_graphics_2d()->ViewInitiatedPaint(); } void PluginInstance::ViewFlushedPaint() { - if (bound_graphics_2d_) - bound_graphics_2d_->ViewFlushedPaint(); + if (bound_graphics_2d()) + bound_graphics_2d()->ViewFlushedPaint(); } bool PluginInstance::GetBitmapForOptimizedPluginPaint( @@ -558,23 +643,25 @@ bool PluginInstance::GetBitmapForOptimizedPluginPaint( gfx::Rect* clip) { if (!always_on_top_) return false; - if (!bound_graphics_2d_ || !bound_graphics_2d_->is_always_opaque()) + if (!bound_graphics_2d() || !bound_graphics_2d()->is_always_opaque()) return false; // We specifically want to compare against the area covered by the backing // store when seeing if we cover the given paint bounds, since the backing // store could be smaller than the declared plugin area. - ImageData* image_data = bound_graphics_2d_->image_data(); + ImageData* image_data = bound_graphics_2d()->image_data(); gfx::Rect plugin_backing_store_rect(position_.origin(), gfx::Size(image_data->width(), image_data->height())); - gfx::Rect plugin_paint_rect = plugin_backing_store_rect.Intersect(clip_); + gfx::Rect clip_page(clip_); + clip_page.Offset(position_.origin()); + gfx::Rect plugin_paint_rect = plugin_backing_store_rect.Intersect(clip_page); if (!plugin_paint_rect.Contains(paint_bounds)) return false; *dib = image_data->platform_image()->GetTransportDIB(); *location = plugin_backing_store_rect; - *clip = clip_; + *clip = clip_page; return true; } @@ -582,7 +669,8 @@ string16 PluginInstance::GetSelectedText(bool html) { if (!LoadSelectionInterface()) return string16(); - PP_Var rv = plugin_selection_interface_->GetSelectedText(pp_instance(), html); + PP_Var rv = plugin_selection_interface_->GetSelectedText(pp_instance(), + BoolToPPBool(html)); scoped_refptr<StringVar> string(StringVar::FromPPVar(rv)); Var::PluginReleasePPVar(rv); // Release the ref the plugin transfered to us. if (!string) @@ -608,7 +696,7 @@ string16 PluginInstance::GetLinkAtPosition(const gfx::Point& point) { void PluginInstance::Zoom(double factor, bool text_only) { if (!LoadZoomInterface()) return; - plugin_zoom_interface_->Zoom(pp_instance(), factor, text_only); + plugin_zoom_interface_->Zoom(pp_instance(), factor, BoolToPPBool(text_only)); } bool PluginInstance::StartFind(const string16& search_text, @@ -617,15 +705,17 @@ bool PluginInstance::StartFind(const string16& search_text, if (!LoadFindInterface()) return false; find_identifier_ = identifier; - return plugin_find_interface_->StartFind( - pp_instance(), - UTF16ToUTF8(search_text.c_str()).c_str(), - case_sensitive); + return PPBoolToBool( + plugin_find_interface_->StartFind( + pp_instance(), + UTF16ToUTF8(search_text.c_str()).c_str(), + BoolToPPBool(case_sensitive))); } void PluginInstance::SelectFindResult(bool forward) { if (LoadFindInterface()) - plugin_find_interface_->SelectFindResult(pp_instance(), forward); + plugin_find_interface_->SelectFindResult(pp_instance(), + BoolToPPBool(forward)); } void PluginInstance::StopFind() { @@ -731,7 +821,7 @@ int PluginInstance::PrintBegin(const gfx::Rect& printable_area, RectToPPRect(printable_area, &print_settings.printable_area); print_settings.dpi = printer_dpi; print_settings.orientation = PP_PRINTORIENTATION_NORMAL; - print_settings.grayscale = false; + print_settings.grayscale = PP_FALSE; print_settings.format = format; int num_pages = plugin_print_interface_->Begin(pp_instance(), &print_settings); @@ -795,16 +885,6 @@ void PluginInstance::PrintEnd() { #endif // defined(OS_LINUX) } -void PluginInstance::Graphics3DContextLost() { - if (!plugin_graphics_3d_interface_) { - plugin_graphics_3d_interface_ = - reinterpret_cast<const PPP_Graphics3D_Dev*>(module_->GetPluginInterface( - PPP_GRAPHICS_3D_DEV_INTERFACE)); - } - if (plugin_graphics_3d_interface_) - plugin_graphics_3d_interface_->Graphics3DContextLost(pp_instance()); -} - bool PluginInstance::IsFullscreen() { return fullscreen_container_ != NULL; } @@ -830,6 +910,26 @@ bool PluginInstance::SetFullscreen(bool fullscreen) { return true; } +bool PluginInstance::NavigateToURL(const char* url, const char* target) { + if (!url || !target || !container_) + return false; + + WebDocument document = container_->element().document(); + GURL complete_url = document.completeURL(WebString::fromUTF8(url)); + // Don't try to deal with the security issues of javascript. + if (complete_url.SchemeIs("javascript")) + return false; + + WebURLRequest request(complete_url); + document.frame()->setReferrerForRequest(request, GURL()); + request.setHTTPMethod(WebString::fromUTF8("GET")); + request.setFirstPartyForCookies(document.firstPartyForCookies()); + + WebString target_str = WebString::fromUTF8(target); + container_->loadFrameRequest(request, target_str, false, NULL); + return true; +} + bool PluginInstance::PrintPDFOutput(PP_Resource print_output, WebKit::WebCanvas* canvas) { scoped_refptr<Buffer> buffer(Resource::GetAs<Buffer>(print_output)); @@ -1055,5 +1155,18 @@ void PluginInstance::DrawSkBitmapToCanvas( } #endif // defined(OS_MACOSX) +Graphics2D* PluginInstance::bound_graphics_2d() const { + if (bound_graphics_.get() == NULL) + return NULL; + + return bound_graphics_->Cast<Graphics2D>(); +} + +Graphics3D* PluginInstance::bound_graphics_3d() const { + if (bound_graphics_.get() == NULL) + return NULL; + + return bound_graphics_->Cast<Graphics3D>(); +} } // namespace pepper diff --git a/webkit/glue/plugins/pepper_plugin_instance.h b/webkit/glue/plugins/pepper_plugin_instance.h index e0cc25d..bd99843 100644 --- a/webkit/glue/plugins/pepper_plugin_instance.h +++ b/webkit/glue/plugins/pepper_plugin_instance.h @@ -9,15 +9,16 @@ #include <vector> #include "base/basictypes.h" +#include "base/observer_list.h" #include "base/ref_counted.h" #include "base/scoped_ptr.h" #include "base/string16.h" #include "gfx/rect.h" -#include "third_party/ppapi/c/dev/pp_cursor_type_dev.h" -#include "third_party/ppapi/c/dev/ppp_graphics_3d_dev.h" -#include "third_party/ppapi/c/dev/ppp_printing_dev.h" -#include "third_party/ppapi/c/pp_instance.h" -#include "third_party/ppapi/c/pp_resource.h" +#include "ppapi/c/dev/pp_cursor_type_dev.h" +#include "ppapi/c/dev/ppp_graphics_3d_dev.h" +#include "ppapi/c/dev/ppp_printing_dev.h" +#include "ppapi/c/pp_instance.h" +#include "ppapi/c/pp_resource.h" #include "third_party/skia/include/core/SkBitmap.h" #include "third_party/WebKit/WebKit/chromium/public/WebCanvas.h" @@ -48,9 +49,11 @@ class WebPluginContainer; namespace pepper { class Graphics2D; +class Graphics3D; class ImageData; class PluginDelegate; class PluginModule; +class Resource; class URLLoader; class FullscreenContainer; @@ -60,6 +63,14 @@ class FullscreenContainer; // ResourceTracker. class PluginInstance : public base::RefCounted<PluginInstance> { public: + class Observer { + public: + // Indicates that the instance is being destroyed. This will be called from + // the instance's destructor so don't do anything in this callback that + // uses the instance. + virtual void InstanceDestroyed(PluginInstance* instance) = 0; + }; + PluginInstance(PluginDelegate* delegate, PluginModule* module, const PPP_Instance* instance_interface); @@ -89,6 +100,12 @@ class PluginInstance : public base::RefCounted<PluginInstance> { // nonzero. PP_Instance pp_instance() const { return pp_instance_; } + // Other classes can register an observer for instance events. These pointers + // are NOT owned by the Instance. If the object implementing the observer + // goes away, it must take care to unregister itself. + void AddObserver(Observer* observer); + void RemoveObserver(Observer* observer); + // Paints the current backing store to the web page. void Paint(WebKit::WebCanvas* canvas, const gfx::Rect& plugin_rect, @@ -100,10 +117,23 @@ class PluginInstance : public base::RefCounted<PluginInstance> { // invalidate the entire plugin. void InvalidateRect(const gfx::Rect& rect); + // Schedules a scroll of the plugin. This uses optimized scrolling only for + // full-frame plugins, as otherwise there could be other elements on top. The + // slow path can also be triggered if there is an overlapping frame. + void ScrollRect(int dx, int dy, const gfx::Rect& rect); + + // If the plugin instance is backed by a texture, return its texture ID in the + // compositor's namespace. Otherwise return 0. Returns 0 by default. + virtual unsigned GetBackingTextureId(); + + // Commit the backing texture to the screen once the side effects some + // rendering up to an offscreen SwapBuffers are visible. + void CommitBackingTexture(); + // PPB_Instance implementation. PP_Var GetWindowObject(); PP_Var GetOwnerElementObject(); - bool BindGraphics(PP_Resource device_id); + bool BindGraphics(PP_Resource graphics_id); bool full_frame() const { return full_frame_; } bool SetCursor(PP_CursorType_Dev type); PP_Var ExecuteScript(PP_Var script, PP_Var* exception); @@ -160,6 +190,9 @@ class PluginInstance : public base::RefCounted<PluginInstance> { bool IsFullscreen(); bool SetFullscreen(bool fullscreen); + // Implementation of PPB_Private2. + bool NavigateToURL(const char* url, const char* target); + private: bool LoadFindInterface(); bool LoadPrivateInterface(); @@ -187,6 +220,14 @@ class PluginInstance : public base::RefCounted<PluginInstance> { const gfx::Rect& dest_rect, int canvas_height); #endif // OS_MACOSX + // Get the bound graphics context as a concrete 2D graphics context or returns + // null if the context is not 2D. + Graphics2D* bound_graphics_2d() const; + + // Get the bound graphics context as a concrete 3D graphics context or returns + // null if the context is not 3D. + Graphics3D* bound_graphics_3d() const; + PluginDelegate* delegate_; scoped_refptr<PluginModule> module_; const PPP_Instance* instance_interface_; @@ -210,6 +251,9 @@ class PluginInstance : public base::RefCounted<PluginInstance> { // be (0, 0, w, h) regardless of scroll position. gfx::Rect clip_; + // The current device context for painting in 2D or 3D. + scoped_refptr<Resource> bound_graphics_; + // We track two types of focus, one from WebKit, which is the focus among // all elements of the page, one one from the browser, which is whether the // tab/window has focus. We tell the plugin it has focus only when both of @@ -217,9 +261,6 @@ class PluginInstance : public base::RefCounted<PluginInstance> { bool has_webkit_focus_; bool has_content_area_focus_; - // The current device context for painting in 2D. - scoped_refptr<Graphics2D> bound_graphics_2d_; - // The id of the current find operation, or -1 if none is in process. int find_identifier_; @@ -266,6 +307,9 @@ class PluginInstance : public base::RefCounted<PluginInstance> { // Plugin container for fullscreen mode. NULL if not in fullscreen mode. FullscreenContainer* fullscreen_container_; + // Non-owning pointers to all active observers. + ObserverList<Observer, false> observers_; + DISALLOW_COPY_AND_ASSIGN(PluginInstance); }; diff --git a/webkit/glue/plugins/pepper_plugin_module.cc b/webkit/glue/plugins/pepper_plugin_module.cc index 13390d5..662055a 100644 --- a/webkit/glue/plugins/pepper_plugin_module.cc +++ b/webkit/glue/plugins/pepper_plugin_module.cc @@ -12,43 +12,47 @@ #include "base/logging.h" #include "base/scoped_ptr.h" #include "base/time.h" -#include "third_party/ppapi/c/dev/ppb_buffer_dev.h" -#include "third_party/ppapi/c/dev/ppb_char_set_dev.h" -#include "third_party/ppapi/c/dev/ppb_cursor_control_dev.h" -#include "third_party/ppapi/c/dev/ppb_directory_reader_dev.h" -#include "third_party/ppapi/c/dev/ppb_file_io_dev.h" -#include "third_party/ppapi/c/dev/ppb_file_io_trusted_dev.h" -#include "third_party/ppapi/c/dev/ppb_file_system_dev.h" -#include "third_party/ppapi/c/dev/ppb_find_dev.h" -#include "third_party/ppapi/c/dev/ppb_font_dev.h" -#include "third_party/ppapi/c/dev/ppb_fullscreen_dev.h" -#include "third_party/ppapi/c/dev/ppb_graphics_3d_dev.h" -#include "third_party/ppapi/c/dev/ppb_opengles_dev.h" -#include "third_party/ppapi/c/dev/ppb_scrollbar_dev.h" -#include "third_party/ppapi/c/dev/ppb_testing_dev.h" -#include "third_party/ppapi/c/dev/ppb_transport_dev.h" -#include "third_party/ppapi/c/dev/ppb_url_loader_dev.h" -#include "third_party/ppapi/c/dev/ppb_url_loader_trusted_dev.h" -#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" -#include "third_party/ppapi/c/pp_var.h" -#include "third_party/ppapi/c/ppb_core.h" -#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/ppp.h" -#include "third_party/ppapi/c/ppp_instance.h" +#include "ppapi/c/dev/ppb_buffer_dev.h" +#include "ppapi/c/dev/ppb_char_set_dev.h" +#include "ppapi/c/dev/ppb_cursor_control_dev.h" +#include "ppapi/c/dev/ppb_directory_reader_dev.h" +#include "ppapi/c/dev/ppb_file_io_dev.h" +#include "ppapi/c/dev/ppb_file_io_trusted_dev.h" +#include "ppapi/c/dev/ppb_file_system_dev.h" +#include "ppapi/c/dev/ppb_find_dev.h" +#include "ppapi/c/dev/ppb_font_dev.h" +#include "ppapi/c/dev/ppb_fullscreen_dev.h" +#include "ppapi/c/dev/ppb_graphics_3d_dev.h" +#include "ppapi/c/dev/ppb_opengles_dev.h" +#include "ppapi/c/dev/ppb_scrollbar_dev.h" +#include "ppapi/c/dev/ppb_testing_dev.h" +#include "ppapi/c/dev/ppb_transport_dev.h" +#include "ppapi/c/dev/ppb_url_loader_dev.h" +#include "ppapi/c/dev/ppb_url_loader_trusted_dev.h" +#include "ppapi/c/dev/ppb_url_request_info_dev.h" +#include "ppapi/c/dev/ppb_url_response_info_dev.h" +#include "ppapi/c/dev/ppb_url_util_dev.h" +#include "ppapi/c/dev/ppb_var_deprecated.h" +#include "ppapi/c/dev/ppb_video_decoder_dev.h" +#include "ppapi/c/dev/ppb_widget_dev.h" +#include "ppapi/c/dev/ppb_zoom_dev.h" +#include "ppapi/c/trusted/ppb_image_data_trusted.h" +#include "ppapi/c/pp_module.h" +#include "ppapi/c/pp_resource.h" +#include "ppapi/c/pp_var.h" +#include "ppapi/c/ppb_class.h" +#include "ppapi/c/ppb_core.h" +#include "ppapi/c/ppb_graphics_2d.h" +#include "ppapi/c/ppb_image_data.h" +#include "ppapi/c/ppb_instance.h" +#include "ppapi/c/ppb_var.h" +#include "ppapi/c/ppp.h" +#include "ppapi/c/ppp_instance.h" #include "webkit/glue/plugins/pepper_audio.h" #include "webkit/glue/plugins/pepper_buffer.h" +#include "webkit/glue/plugins/pepper_common.h" #include "webkit/glue/plugins/pepper_char_set.h" +#include "webkit/glue/plugins/pepper_class.h" #include "webkit/glue/plugins/pepper_cursor_control.h" #include "webkit/glue/plugins/pepper_directory_reader.h" #include "webkit/glue/plugins/pepper_file_chooser.h" @@ -140,8 +144,8 @@ void CallOnMainThread(int delay_in_msec, delay_in_msec); } -bool IsMainThread() { - return GetMainThreadMessageLoop()->BelongsToCurrentThread(); +PP_Bool IsMainThread() { + return BoolToPPBool(GetMainThreadMessageLoop()->BelongsToCurrentThread()); } const PPB_Core core_interface = { @@ -157,14 +161,14 @@ const PPB_Core core_interface = { // PPB_Testing ----------------------------------------------------------------- -bool ReadImageData(PP_Resource device_context_2d, +PP_Bool ReadImageData(PP_Resource device_context_2d, PP_Resource image, const PP_Point* top_left) { scoped_refptr<Graphics2D> context( Resource::GetAs<Graphics2D>(device_context_2d)); if (!context.get()) - return false; - return context->ReadImageData(image, top_left); + return PP_FALSE; + return BoolToPPBool(context->ReadImageData(image, top_left)); } void RunMessageLoop() { @@ -199,6 +203,8 @@ const void* GetInterface(const char* name) { return &core_interface; if (strcmp(name, PPB_VAR_DEPRECATED_INTERFACE) == 0) return Var::GetDeprecatedInterface(); + if (strcmp(name, PPB_VAR_INTERFACE) == 0) + return Var::GetInterface(); if (strcmp(name, PPB_INSTANCE_INTERFACE) == 0) return PluginInstance::GetInterface(); if (strcmp(name, PPB_IMAGEDATA_INTERFACE) == 0) @@ -267,6 +273,8 @@ const void* GetInterface(const char* name) { return GetCursorControlInterface(); if (strcmp(name, PPB_ZOOM_DEV_INTERFACE) == 0) return PluginInstance::GetZoomInterface(); + if (strcmp(name, PPB_CLASS_INTERFACE) == 0) + return VarObjectClass::GetInterface(); // Only support the testing interface when the command line switch is // specified. This allows us to prevent people from (ab)using this interface diff --git a/webkit/glue/plugins/pepper_plugin_module.h b/webkit/glue/plugins/pepper_plugin_module.h index 4ac13c3..cf7defb 100644 --- a/webkit/glue/plugins/pepper_plugin_module.h +++ b/webkit/glue/plugins/pepper_plugin_module.h @@ -12,8 +12,8 @@ #include "base/native_library.h" #include "base/ref_counted.h" #include "base/weak_ptr.h" -#include "third_party/ppapi/c/pp_module.h" -#include "third_party/ppapi/c/ppb.h" +#include "ppapi/c/pp_module.h" +#include "ppapi/c/ppb.h" class FilePath; typedef struct NPObject NPObject; diff --git a/webkit/glue/plugins/pepper_plugin_object.cc b/webkit/glue/plugins/pepper_plugin_object.cc index b655f83..2705809 100644 --- a/webkit/glue/plugins/pepper_plugin_object.cc +++ b/webkit/glue/plugins/pepper_plugin_object.cc @@ -5,16 +5,21 @@ #include "webkit/glue/plugins/pepper_plugin_object.h" #include "base/logging.h" +#include "base/ref_counted.h" #include "base/scoped_ptr.h" #include "base/string_number_conversions.h" #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 "ppapi/c/dev/ppb_var_deprecated.h" +#include "ppapi/c/dev/ppp_class_deprecated.h" +#include "ppapi/c/pp_resource.h" +#include "ppapi/c/pp_var.h" +#include "ppapi/c/ppb_class.h" #include "third_party/WebKit/WebKit/chromium/public/WebBindings.h" +#include "webkit/glue/plugins/pepper_class.h" #include "webkit/glue/plugins/pepper_plugin_module.h" +#include "webkit/glue/plugins/pepper_resource.h" #include "webkit/glue/plugins/pepper_string.h" #include "webkit/glue/plugins/pepper_var.h" @@ -27,7 +32,7 @@ namespace { const char kInvalidValueException[] = "Error: Invalid value"; const char kInvalidPluginValue[] = "Error: Plugin returned invalid value."; -// --------------------------------------------------------------------------- +// ----------------------------------------------------------------------------- // Utilities // Converts the given PP_Var to an NPVariant, returning true on success. @@ -109,6 +114,25 @@ class PPVarArrayFromNPVariantArray { DISALLOW_COPY_AND_ASSIGN(PPVarArrayFromNPVariantArray); }; +// PPVarFromNPObject ----------------------------------------------------------- + +// Converts an NPObject tp PP_Var, and scopes the ownership of the PP_Var. This +// is used when converting 'this' pointer from WebKit to the plugin. +class PPVarFromNPObject { + public: + PPVarFromNPObject(PluginModule* module, NPObject* object) + : var_(ObjectVar::NPObjectToPPVar(module, object)) { + } + ~PPVarFromNPObject() { + Var::PluginReleasePPVar(var_); + } + PP_Var var() const { return var_; } + private: + const PP_Var var_; + + DISALLOW_COPY_AND_ASSIGN(PPVarFromNPObject); +}; + // PPResultAndExceptionToNPResult ---------------------------------------------- // Convenience object for converting a PPAPI call that can throw an exception @@ -127,15 +151,14 @@ class PPVarArrayFromNPVariantArray { class PPResultAndExceptionToNPResult { public: // The object_var parameter is the object to associate any exception with. - // It may not be NULL. This class does not take a ref, so it must remain - // valid for the lifetime of this object. + // It may not be NULL. // // The np_result parameter is the NPAPI result output parameter. This may be // NULL if there is no NPVariant result (like for HasProperty). If this is // specified, you must call SetResult() to set it. If it is not, you must // call CheckExceptionForNoResult to do the exception checking with no result // conversion. - PPResultAndExceptionToNPResult(PluginObject* object_var, + PPResultAndExceptionToNPResult(NPObject* object_var, NPVariant* np_result) : object_var_(object_var), np_result_(np_result), @@ -181,8 +204,7 @@ class PPResultAndExceptionToNPResult { ThrowException(); success_ = false; } else if (!PPVarToNPVariant(result, np_result_)) { - WebBindings::setException(object_var_->GetNPObject(), - kInvalidPluginValue); + WebBindings::setException(object_var_, kInvalidPluginValue); success_ = false; } else { success_ = true; @@ -226,12 +248,11 @@ class PPResultAndExceptionToNPResult { void ThrowException() { scoped_refptr<StringVar> string(StringVar::FromPPVar(exception_)); if (string) { - WebBindings::setException(object_var_->GetNPObject(), - string->value().c_str()); + WebBindings::setException(object_var_, string->value().c_str()); } } - PluginObject* object_var_; // Non-owning ref (see constructor). + NPObject* object_var_; // Non-owning ref (see constructor). NPVariant* np_result_; // Output value, possibly NULL (see constructor). PP_Var exception_; // Exception set by the PPAPI call. We own a ref to it. bool success_; // See the success() function above. @@ -316,7 +337,8 @@ bool WrapperClass_HasMethod(NPObject* object, NPIdentifier method_name) { if (!accessor.is_valid()) return false; - PPResultAndExceptionToNPResult result_converter(accessor.object(), NULL); + PPResultAndExceptionToNPResult result_converter( + accessor.object()->GetNPObject(), NULL); bool rv = accessor.object()->ppp_class()->HasMethod( accessor.object()->ppp_class_data(), accessor.identifier(), result_converter.exception()); @@ -331,7 +353,8 @@ bool WrapperClass_Invoke(NPObject* object, NPIdentifier method_name, if (!accessor.is_valid()) return false; - PPResultAndExceptionToNPResult result_converter(accessor.object(), result); + PPResultAndExceptionToNPResult result_converter( + accessor.object()->GetNPObject(), result); PPVarArrayFromNPVariantArray args(accessor.object()->module(), argc, argv); return result_converter.SetResult(accessor.object()->ppp_class()->Call( @@ -346,7 +369,7 @@ bool WrapperClass_InvokeDefault(NPObject* np_object, const NPVariant* argv, return false; PPVarArrayFromNPVariantArray args(obj->module(), argc, argv); - PPResultAndExceptionToNPResult result_converter(obj, result); + PPResultAndExceptionToNPResult result_converter(obj->GetNPObject(), result); result_converter.SetResult(obj->ppp_class()->Call( obj->ppp_class_data(), PP_MakeUndefined(), argc, args.array(), @@ -354,27 +377,13 @@ bool WrapperClass_InvokeDefault(NPObject* np_object, const NPVariant* argv, return result_converter.success(); } - - - - - - - - - - - - - - - bool WrapperClass_HasProperty(NPObject* object, NPIdentifier property_name) { NPObjectAccessorWithIdentifier accessor(object, property_name, true); if (!accessor.is_valid()) return false; - PPResultAndExceptionToNPResult result_converter(accessor.object(), NULL); + PPResultAndExceptionToNPResult result_converter( + accessor.object()->GetNPObject(), NULL); bool rv = accessor.object()->ppp_class()->HasProperty( accessor.object()->ppp_class_data(), accessor.identifier(), result_converter.exception()); @@ -388,7 +397,8 @@ bool WrapperClass_GetProperty(NPObject* object, NPIdentifier property_name, if (!accessor.is_valid()) return false; - PPResultAndExceptionToNPResult result_converter(accessor.object(), result); + PPResultAndExceptionToNPResult result_converter( + accessor.object()->GetNPObject(), result); return result_converter.SetResult(accessor.object()->ppp_class()->GetProperty( accessor.object()->ppp_class_data(), accessor.identifier(), result_converter.exception())); @@ -400,7 +410,8 @@ bool WrapperClass_SetProperty(NPObject* object, NPIdentifier property_name, if (!accessor.is_valid()) return false; - PPResultAndExceptionToNPResult result_converter(accessor.object(), NULL); + PPResultAndExceptionToNPResult result_converter( + accessor.object()->GetNPObject(), NULL); PP_Var value_var = Var::NPVariantToPPVar(accessor.object()->module(), value); accessor.object()->ppp_class()->SetProperty( accessor.object()->ppp_class_data(), accessor.identifier(), value_var, @@ -414,7 +425,8 @@ bool WrapperClass_RemoveProperty(NPObject* object, NPIdentifier property_name) { if (!accessor.is_valid()) return false; - PPResultAndExceptionToNPResult result_converter(accessor.object(), NULL); + PPResultAndExceptionToNPResult result_converter( + accessor.object()->GetNPObject(), NULL); accessor.object()->ppp_class()->RemoveProperty( accessor.object()->ppp_class_data(), accessor.identifier(), result_converter.exception()); @@ -431,7 +443,7 @@ bool WrapperClass_Enumerate(NPObject* object, NPIdentifier** values, uint32_t property_count = 0; PP_Var* properties = NULL; // Must be freed! - PPResultAndExceptionToNPResult result_converter(obj, NULL); + PPResultAndExceptionToNPResult result_converter(obj->GetNPObject(), NULL); obj->ppp_class()->GetAllPropertyNames(obj->ppp_class_data(), &property_count, &properties, result_converter.exception()); @@ -482,7 +494,7 @@ bool WrapperClass_Construct(NPObject* object, const NPVariant* argv, return false; PPVarArrayFromNPVariantArray args(obj->module(), argc, argv); - PPResultAndExceptionToNPResult result_converter(obj, result); + PPResultAndExceptionToNPResult result_converter(obj->GetNPObject(), result); return result_converter.SetResult(obj->ppp_class()->Construct( obj->ppp_class_data(), argc, args.array(), result_converter.exception())); @@ -506,7 +518,7 @@ const NPClass wrapper_class = { } // namespace -// PluginObject ------------------------------------------------------------- +// PluginObject ---------------------------------------------------------------- struct PluginObject::NPObjectWrapper : public NPObject { // Points to the var object that owns this wrapper. This value may be NULL @@ -598,4 +610,278 @@ NPObject* PluginObject::AllocateObjectWrapper() { return wrapper; } +// VarObjectClass::InstanceData ----------------------------------------------- + +struct VarObjectClass::InstanceData : public NPObject { + InstanceData() : native_data(NULL) {} + + scoped_refptr<VarObjectClass> object_class; + void* native_data; +}; + +// VarObjectClass::Property --------------------------------------------------- + +VarObjectClass::Property::Property(const PP_ClassProperty& prop) + : method(prop.method), + getter(prop.getter), + setter(prop.setter), + writable(!(prop.modifiers & PP_OBJECTPROPERTY_MODIFIER_READONLY)), + enumerable(!(prop.modifiers & PP_OBJECTPROPERTY_MODIFIER_DONTENUM)) { +} + + +// VarObjectAccessorWithIdentifier --------------------------------------------- + +// Helper class for the new (PPB_Class) NPObject wrapper. This converts a call +// from WebKit where it gives us an NPObject and an NPIdentifier to an +// easily-accessible InstanceData (corresponding to the NPObject) and +// std::string and Property (corresponding to the NPIdentifier). +class VarObjectAccessorWithIdentifier { + public: + VarObjectAccessorWithIdentifier(NPObject* object, NPIdentifier identifier) + : exists_(false), + instance_(static_cast<VarObjectClass::InstanceData*>(object)), + property_(NULL) { + if (instance_) { + const NPUTF8* string_value = NULL; + int32_t int_value = 0; + bool is_string = false; + WebBindings::extractIdentifierData(identifier, string_value, int_value, + is_string); + if (is_string) { + property_name_ = string_value; + + const VarObjectClass::PropertyMap& properties = + instance_->object_class->properties(); + VarObjectClass::PropertyMap::const_iterator it = + properties.find(property_name_); + if (it != properties.end()) { + property_ = &it->second; + exists_ = true; + } + } + } + } + + // Return true if the object is valid, the identifier is valid, and the + // property with said name exists. + bool exists() const { return exists_; } + bool is_method() const { return exists() && property_->method; } + bool is_readable() const { return exists() && property_->getter; } + bool is_writable() const { + return exists() && property_->setter && property_->writable; + } + const VarObjectClass::InstanceData* instance() const { return instance_; } + const VarObjectClass::Property* property() const { return property_; } + PluginModule* module() const { + return instance_ ? instance_->object_class->module() : NULL; + } + + private: + bool exists_; + const VarObjectClass::InstanceData* instance_; + std::string property_name_; + const VarObjectClass::Property* property_; + + DISALLOW_COPY_AND_ASSIGN(VarObjectAccessorWithIdentifier); +}; + +// NPObject implementation in terms of PPB_Class ------------------------------- + +namespace { + +NPObject* VarObjectClassAllocate(NPP npp, NPClass* the_class) { + return new VarObjectClass::InstanceData; +} + +void VarObjectClassDeallocate(NPObject* object) { + VarObjectClass::InstanceData* instance = + static_cast<VarObjectClass::InstanceData*>(object); + if (instance->object_class->instance_native_destructor()) + instance->object_class->instance_native_destructor()(instance->native_data); + delete instance; +} + +bool VarObjectClassHasMethod(NPObject* np_obj, NPIdentifier name) { + VarObjectAccessorWithIdentifier accessor(np_obj, name); + return accessor.is_method(); +} + +bool VarObjectClassInvoke(NPObject* np_obj, NPIdentifier name, + const NPVariant* args, uint32 arg_count, + NPVariant* result) { + VarObjectAccessorWithIdentifier accessor(np_obj, name); + if (!accessor.is_method()) + return false; + + PPResultAndExceptionToNPResult result_converter(np_obj, result); + PPVarArrayFromNPVariantArray arguments(accessor.module(), arg_count, args); + PPVarFromNPObject self(accessor.module(), np_obj); + + return result_converter.SetResult(accessor.property()->method( + accessor.instance()->native_data, self.var(), arguments.array(), arg_count, + result_converter.exception())); +} + +bool VarObjectClassInvokeDefault(NPObject* np_obj, + const NPVariant* args, + uint32 arg_count, + NPVariant* result) { + VarObjectClass::InstanceData* instance = + static_cast<VarObjectClass::InstanceData*>(np_obj); + if (!instance || !instance->object_class->instance_invoke()) + return false; + + PPResultAndExceptionToNPResult result_converter(np_obj, result); + PPVarArrayFromNPVariantArray arguments(instance->object_class->module(), + arg_count, args); + PPVarFromNPObject self(instance->object_class->module(), np_obj); + + return result_converter.SetResult(instance->object_class->instance_invoke()( + instance->native_data, self.var(), arguments.array(), arg_count, + result_converter.exception())); +} + +bool VarObjectClassHasProperty(NPObject* np_obj, NPIdentifier name) { + VarObjectAccessorWithIdentifier accessor(np_obj, name); + return accessor.is_readable(); +} + +bool VarObjectClassGetProperty(NPObject* np_obj, NPIdentifier name, + NPVariant* result) { + VarObjectAccessorWithIdentifier accessor(np_obj, name); + if (!accessor.is_readable()) { + return false; + } + + PPResultAndExceptionToNPResult result_converter(np_obj, result); + PPVarFromNPObject self(accessor.module(), np_obj); + + return result_converter.SetResult(accessor.property()->getter( + accessor.instance()->native_data, self.var(), 0, 0, + result_converter.exception())); +} + +bool VarObjectClassSetProperty(NPObject* np_obj, NPIdentifier name, + const NPVariant* variant) { + VarObjectAccessorWithIdentifier accessor(np_obj, name); + if (!accessor.is_writable()) { + return false; + } + + PPResultAndExceptionToNPResult result_converter(np_obj, NULL); + PPVarArrayFromNPVariantArray arguments(accessor.module(), 1, variant); + PPVarFromNPObject self(accessor.module(), np_obj); + + // Ignore return value. + Var::PluginReleasePPVar(accessor.property()->setter( + accessor.instance()->native_data, self.var(), arguments.array(), 1, + result_converter.exception())); + + return result_converter.CheckExceptionForNoResult(); +} + +bool VarObjectClassEnumerate(NPObject *np_obj, NPIdentifier **value, + uint32_t *count) { + VarObjectClass::InstanceData* instance = + static_cast<VarObjectClass::InstanceData*>(np_obj); + *count = 0; + *value = NULL; + if (!instance) + return false; + + const VarObjectClass::PropertyMap& properties = + instance->object_class->properties(); + + // Don't bother calculating the size of enumerable properties, just allocate + // enough for all and then fill it partially. + *value = static_cast<NPIdentifier*>( + malloc(sizeof(NPIdentifier) * properties.size())); + + NPIdentifier* inserter = *value; + for (VarObjectClass::PropertyMap::const_iterator i = properties.begin(); + i != properties.end(); ++i) + if (i->second.enumerable) + *inserter++ = WebBindings::getStringIdentifier(i->first.c_str()); + + *count = inserter - *value; + return true; +} + +NPClass objectclassvar_class = { + NP_CLASS_STRUCT_VERSION, + &VarObjectClassAllocate, + &VarObjectClassDeallocate, + NULL, + &VarObjectClassHasMethod, + &VarObjectClassInvoke, + &VarObjectClassInvokeDefault, + &VarObjectClassHasProperty, + &VarObjectClassGetProperty, + &VarObjectClassSetProperty, + NULL, + &VarObjectClassEnumerate, +}; + +// PPB_Class interface --------------------------------------------------------- + +PP_Resource Create(PP_Module module, PP_ClassDestructor destruct, + PP_ClassFunction invoke, PP_ClassProperty* properties) { + PluginModule* plugin_module = ResourceTracker::Get()->GetModule(module); + if (!properties || !plugin_module) + return 0; + scoped_refptr<VarObjectClass> cls = new VarObjectClass(plugin_module, + destruct, + invoke, + properties); + if (!cls) + return 0; + return cls->GetReference(); +} + +PP_Var Instantiate(PP_Resource class_object, void* native_data, + PP_Var* exception) { + scoped_refptr<VarObjectClass> object_class = + Resource::GetAs<VarObjectClass>(class_object); + if (!object_class) + return PP_MakeUndefined(); + NPObject* obj = WebBindings::createObject(NULL, &objectclassvar_class); + VarObjectClass::InstanceData* instance_data = + static_cast<VarObjectClass::InstanceData*>(obj); + instance_data->object_class = object_class; + instance_data->native_data = native_data; + return ObjectVar::NPObjectToPPVar(object_class->module(), obj); +} + +} // namespace + +// VarObjectClass -------------------------------------------------------------- + +VarObjectClass::VarObjectClass(PluginModule* module, + PP_ClassDestructor destruct, + PP_ClassFunction invoke, + PP_ClassProperty* properties) + : Resource(module), + instance_native_destructor_(destruct), + instance_invoke_(invoke) { + PP_ClassProperty* prop = properties; + while (prop->name) { + properties_.insert(std::make_pair(std::string(prop->name), + Property(*prop))); + ++prop; + } +} + +// static +const PPB_Class* VarObjectClass::GetInterface() { + static PPB_Class interface = { + &Create, + &Instantiate + }; + return &interface; +} + +// virtual +VarObjectClass::~VarObjectClass() { } + } // namespace pepper diff --git a/webkit/glue/plugins/pepper_private.cc b/webkit/glue/plugins/pepper_private.cc index 0bf5328..bd1c77b 100644 --- a/webkit/glue/plugins/pepper_private.cc +++ b/webkit/glue/plugins/pepper_private.cc @@ -6,15 +6,16 @@ #include "webkit/glue/plugins/pepper_private.h" +#include "unicode/usearch.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 "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" @@ -258,6 +259,12 @@ void HistogramPDFPageCount(int count) { UMA_HISTOGRAM_COUNTS_10000("PDF.PageCount", count); } +void UserMetricsRecordAction(PP_Var action) { + scoped_refptr<StringVar> action_str(StringVar::FromPPVar(action)); + if (action_str) + webkit_glue::UserMetricsRecordAction(action_str->value()); +} + const PPB_Private ppb_private = { &GetLocalizedString, &GetResourceImage, @@ -267,7 +274,8 @@ const PPB_Private ppb_private = { &DidStartLoading, &DidStopLoading, &SetContentRestriction, - &HistogramPDFPageCount + &HistogramPDFPageCount, + &UserMetricsRecordAction }; } // namespace diff --git a/webkit/glue/plugins/pepper_private2.cc b/webkit/glue/plugins/pepper_private2.cc index a96ef30..8492b65 100644 --- a/webkit/glue/plugins/pepper_private2.cc +++ b/webkit/glue/plugins/pepper_private2.cc @@ -10,8 +10,8 @@ #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 "ppapi/c/dev/pp_file_info_dev.h" +#include "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" @@ -210,6 +210,15 @@ void FreeModuleLocalDirContents(PP_Module module, delete contents; } +bool NavigateToURL(PP_Instance pp_instance, + const char* url, + const char* target) { + PluginInstance* instance = ResourceTracker::Get()->GetInstance(pp_instance); + if (!instance) + return false; + return instance->NavigateToURL(url, target); +} + const PPB_Private2 ppb_private2 = { &SetInstanceAlwaysOnTop, &Private2::DrawGlyphs, @@ -221,6 +230,7 @@ const PPB_Private2 ppb_private2 = { &QueryModuleLocalFile, &GetModuleLocalDirContents, &FreeModuleLocalDirContents, + &NavigateToURL, }; } // namespace diff --git a/webkit/glue/plugins/pepper_private2.h b/webkit/glue/plugins/pepper_private2.h index a8a4b6e..64a766f 100644 --- a/webkit/glue/plugins/pepper_private2.h +++ b/webkit/glue/plugins/pepper_private2.h @@ -6,8 +6,8 @@ #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 "ppapi/c/pp_point.h" +#include "ppapi/c/pp_rect.h" #include "webkit/glue/plugins/pepper_resource.h" struct PP_FontDescription_Dev; diff --git a/webkit/glue/plugins/pepper_private2_linux.cc b/webkit/glue/plugins/pepper_private2_linux.cc index 4beb6b6..ed2c04a 100644 --- a/webkit/glue/plugins/pepper_private2_linux.cc +++ b/webkit/glue/plugins/pepper_private2_linux.cc @@ -5,9 +5,9 @@ #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 "ppapi/c/pp_point.h" +#include "ppapi/c/pp_rect.h" +#include "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" diff --git a/webkit/glue/plugins/pepper_resource.cc b/webkit/glue/plugins/pepper_resource.cc index cf7a7fe..851d6e7 100644 --- a/webkit/glue/plugins/pepper_resource.cc +++ b/webkit/glue/plugins/pepper_resource.cc @@ -25,6 +25,10 @@ PP_Resource Resource::GetReference() { return resource_id_; } +PP_Resource Resource::GetReferenceNoAddRef() const { + return resource_id_; +} + void Resource::StoppedTracking() { DCHECK(resource_id_ != 0); resource_id_ = 0; diff --git a/webkit/glue/plugins/pepper_resource.h b/webkit/glue/plugins/pepper_resource.h index 32dbf0b..3c4ebca 100644 --- a/webkit/glue/plugins/pepper_resource.h +++ b/webkit/glue/plugins/pepper_resource.h @@ -7,7 +7,7 @@ #include "base/basictypes.h" #include "base/ref_counted.h" -#include "third_party/ppapi/c/pp_resource.h" +#include "ppapi/c/pp_resource.h" #include "webkit/glue/plugins/pepper_resource_tracker.h" namespace pepper { @@ -36,6 +36,7 @@ namespace pepper { F(URLRequestInfo) \ F(URLResponseInfo) \ F(Var) \ + F(VarObjectClass) \ F(VideoDecoder) \ F(Widget) @@ -69,6 +70,18 @@ class Resource : public base::RefCountedThreadSafe<Resource> { // reference to the plugin. PP_Resource GetReference(); + // Returns the resource ID of this object OR NULL IF THERE IS NONE ASSIGNED. + // This will happen if the plugin doesn't have a reference to the given + // resource. The resource will not be addref'ed. + // + // This should only be used as an input parameter to the plugin for status + // updates in the proxy layer, where if the plugin has no reference, it will + // just give up since nothing needs to be updated. + // + // Generally you should use GetReference instead. This is why it has this + // obscure name rather than pp_resource(). + PP_Resource GetReferenceNoAddRef() const; + // When you need to ensure that a resource has a reference, but you do not // want to increase the refcount (for example, if you need to call a plugin // callback function with a reference), you can use this class. For example: @@ -93,7 +106,6 @@ class Resource : public base::RefCountedThreadSafe<Resource> { 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 // access this member directly, because it is possible that the plugin holds // no references to the object, and therefore the resource_id_ is zero. Use diff --git a/webkit/glue/plugins/pepper_resource_tracker.cc b/webkit/glue/plugins/pepper_resource_tracker.cc index 2e18cd8..ba6f8f0 100644 --- a/webkit/glue/plugins/pepper_resource_tracker.cc +++ b/webkit/glue/plugins/pepper_resource_tracker.cc @@ -9,7 +9,7 @@ #include "base/logging.h" #include "base/rand_util.h" -#include "third_party/ppapi/c/pp_resource.h" +#include "ppapi/c/pp_resource.h" #include "webkit/glue/plugins/pepper_resource.h" namespace pepper { @@ -66,6 +66,16 @@ bool ResourceTracker::UnrefResource(PP_Resource res) { } } +void ResourceTracker::ForceDeletePluginResourceRefs(PP_Resource res) { + ResourceMap::iterator i = live_resources_.find(res); + if (i != live_resources_.end()) + return; // Nothing to do. + + i->second.second = 0; + i->second.first->StoppedTracking(); + live_resources_.erase(i); +} + uint32 ResourceTracker::GetLiveObjectsForModule(PluginModule* module) const { // Since this is for testing only, we'll just go through all of them and // count. diff --git a/webkit/glue/plugins/pepper_resource_tracker.h b/webkit/glue/plugins/pepper_resource_tracker.h index 5c27ebd..ad25d1a 100644 --- a/webkit/glue/plugins/pepper_resource_tracker.h +++ b/webkit/glue/plugins/pepper_resource_tracker.h @@ -12,11 +12,9 @@ #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; +#include "ppapi/c/pp_instance.h" +#include "ppapi/c/pp_module.h" +#include "ppapi/c/pp_resource.h" namespace pepper { @@ -49,6 +47,16 @@ class ResourceTracker { bool AddRefResource(PP_Resource res); bool UnrefResource(PP_Resource res); + // Forces the plugin refcount of the given resource to 0. This can be used to + // delete an object the plugin has leaked or whose lifetime is otherwise + // exceeded. + // + // Note that this may not necessarily delete the resource object since the + // regular refcount is maintained separately from the plugin refcount and + // random components in the Pepper implementation could still have + // references to it. + void ForceDeletePluginResourceRefs(PP_Resource res); + // Returns the number of resources associated with this module. // // This is slow, use only for testing. diff --git a/webkit/glue/plugins/pepper_scrollbar.cc b/webkit/glue/plugins/pepper_scrollbar.cc index 88a3f9b..2b96259 100644 --- a/webkit/glue/plugins/pepper_scrollbar.cc +++ b/webkit/glue/plugins/pepper_scrollbar.cc @@ -6,12 +6,13 @@ #include "base/logging.h" #include "base/message_loop.h" +#include "ppapi/c/dev/ppp_scrollbar_dev.h" #include "skia/ext/platform_canvas.h" -#include "third_party/ppapi/c/dev/ppp_scrollbar_dev.h" #include "third_party/WebKit/WebKit/chromium/public/WebInputEvent.h" #include "third_party/WebKit/WebKit/chromium/public/WebRect.h" #include "third_party/WebKit/WebKit/chromium/public/WebScrollbar.h" #include "third_party/WebKit/WebKit/chromium/public/WebVector.h" +#include "webkit/glue/plugins/pepper_common.h" #include "webkit/glue/plugins/pepper_event_conversion.h" #include "webkit/glue/plugins/pepper_image_data.h" #include "webkit/glue/plugins/pepper_plugin_instance.h" @@ -30,17 +31,18 @@ namespace pepper { namespace { -PP_Resource Create(PP_Instance instance_id, bool vertical) { +PP_Resource Create(PP_Instance instance_id, PP_Bool vertical) { PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id); if (!instance) return 0; - scoped_refptr<Scrollbar> scrollbar(new Scrollbar(instance, vertical)); + scoped_refptr<Scrollbar> scrollbar(new Scrollbar(instance, + PPBoolToBool(vertical))); return scrollbar->GetReference(); } -bool IsScrollbar(PP_Resource resource) { - return !!Resource::GetAs<Scrollbar>(resource); +PP_Bool IsScrollbar(PP_Resource resource) { + return BoolToPPBool(!!Resource::GetAs<Scrollbar>(resource)); } uint32_t GetThickness() { diff --git a/webkit/glue/plugins/pepper_scrollbar.h b/webkit/glue/plugins/pepper_scrollbar.h index e8ac480..c444bb3 100644 --- a/webkit/glue/plugins/pepper_scrollbar.h +++ b/webkit/glue/plugins/pepper_scrollbar.h @@ -8,7 +8,7 @@ #include <vector> #include "gfx/rect.h" -#include "third_party/ppapi/c/dev/ppb_scrollbar_dev.h" +#include "ppapi/c/dev/ppb_scrollbar_dev.h" #include "third_party/WebKit/WebKit/chromium/public/WebRect.h" #include "third_party/WebKit/WebKit/chromium/public/WebScrollbarClient.h" #include "webkit/glue/plugins/pepper_widget.h" diff --git a/webkit/glue/plugins/pepper_transport.cc b/webkit/glue/plugins/pepper_transport.cc index ed5e05f..29a4495 100644 --- a/webkit/glue/plugins/pepper_transport.cc +++ b/webkit/glue/plugins/pepper_transport.cc @@ -6,7 +6,8 @@ #include "base/singleton.h" #include "base/thread_local.h" -#include "third_party/ppapi/c/dev/ppb_transport_dev.h" +#include "ppapi/c/dev/ppb_transport_dev.h" +#include "webkit/glue/plugins/pepper_common.h" #include "webkit/glue/plugins/pepper_plugin_instance.h" #include "webkit/glue/plugins/pepper_plugin_module.h" @@ -25,15 +26,15 @@ PP_Resource CreateTransport(PP_Module module, } // Returns whether or not resource is Transport -bool IsTransport(PP_Resource resource) { - return !!Resource::GetAs<Transport>(resource); +PP_Bool IsTransport(PP_Resource resource) { + return BoolToPPBool(!!Resource::GetAs<Transport>(resource)); } // Returns whether the transport is currently writable // (i.e. can send data to the remote peer) -bool IsWritable(PP_Resource transport) { +PP_Bool IsWritable(PP_Resource transport) { // TODO(juberti): impelement me - return false; + return PP_FALSE; } diff --git a/webkit/glue/plugins/pepper_transport.h b/webkit/glue/plugins/pepper_transport.h index 1e6e56f..fbba691 100644 --- a/webkit/glue/plugins/pepper_transport.h +++ b/webkit/glue/plugins/pepper_transport.h @@ -6,7 +6,7 @@ #define WEBKIT_GLUE_PLUGINS_PEPPER_TRANSPORT_H_ #include "base/scoped_ptr.h" -#include "third_party/ppapi/c/pp_instance.h" +#include "ppapi/c/pp_instance.h" #include "webkit/glue/plugins/pepper_plugin_delegate.h" #include "webkit/glue/plugins/pepper_resource.h" diff --git a/webkit/glue/plugins/pepper_url_loader.cc b/webkit/glue/plugins/pepper_url_loader.cc index 62fe176..c9a580a 100644 --- a/webkit/glue/plugins/pepper_url_loader.cc +++ b/webkit/glue/plugins/pepper_url_loader.cc @@ -5,10 +5,10 @@ #include "webkit/glue/plugins/pepper_url_loader.h" #include "base/logging.h" -#include "third_party/ppapi/c/pp_completion_callback.h" -#include "third_party/ppapi/c/pp_errors.h" -#include "third_party/ppapi/c/dev/ppb_url_loader_dev.h" -#include "third_party/ppapi/c/dev/ppb_url_loader_trusted_dev.h" +#include "ppapi/c/pp_completion_callback.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/dev/ppb_url_loader_dev.h" +#include "ppapi/c/dev/ppb_url_loader_trusted_dev.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" @@ -16,12 +16,16 @@ #include "third_party/WebKit/WebKit/chromium/public/WebKitClient.h" #include "third_party/WebKit/WebKit/chromium/public/WebPluginContainer.h" #include "third_party/WebKit/WebKit/chromium/public/WebSecurityOrigin.h" +#include "third_party/WebKit/WebKit/chromium/public/WebURLLoader.h" #include "third_party/WebKit/WebKit/chromium/public/WebURLRequest.h" #include "third_party/WebKit/WebKit/chromium/public/WebURLResponse.h" +#include "webkit/appcache/web_application_cache_host_impl.h" +#include "webkit/glue/plugins/pepper_common.h" #include "webkit/glue/plugins/pepper_plugin_instance.h" #include "webkit/glue/plugins/pepper_url_request_info.h" #include "webkit/glue/plugins/pepper_url_response_info.h" +using appcache::WebApplicationCacheHostImpl; using WebKit::WebFrame; using WebKit::WebString; using WebKit::WebURL; @@ -48,8 +52,8 @@ PP_Resource Create(PP_Instance instance_id) { return loader->GetReference(); } -bool IsURLLoader(PP_Resource resource) { - return !!Resource::GetAs<URLLoader>(resource); +PP_Bool IsURLLoader(PP_Resource resource) { + return BoolToPPBool(!!Resource::GetAs<URLLoader>(resource)); } int32_t Open(PP_Resource loader_id, @@ -76,28 +80,26 @@ int32_t FollowRedirect(PP_Resource loader_id, return loader->FollowRedirect(callback); } -bool GetUploadProgress(PP_Resource loader_id, +PP_Bool GetUploadProgress(PP_Resource loader_id, int64_t* bytes_sent, int64_t* total_bytes_to_be_sent) { scoped_refptr<URLLoader> loader(Resource::GetAs<URLLoader>(loader_id)); if (!loader) - return false; + return PP_FALSE; - *bytes_sent = loader->bytes_sent(); - *total_bytes_to_be_sent = loader->total_bytes_to_be_sent(); - return true; + return BoolToPPBool(loader->GetUploadProgress(bytes_sent, + total_bytes_to_be_sent)); } -bool GetDownloadProgress(PP_Resource loader_id, - int64_t* bytes_received, - int64_t* total_bytes_to_be_received) { +PP_Bool GetDownloadProgress(PP_Resource loader_id, + int64_t* bytes_received, + int64_t* total_bytes_to_be_received) { scoped_refptr<URLLoader> loader(Resource::GetAs<URLLoader>(loader_id)); if (!loader) - return false; + return PP_FALSE; - *bytes_received = loader->bytes_received(); - *total_bytes_to_be_received = loader->total_bytes_to_be_received(); - return true; + return BoolToPPBool(loader->GetDownloadProgress(bytes_received, + total_bytes_to_be_received)); } PP_Resource GetResponseInfo(PP_Resource loader_id) { @@ -161,10 +163,23 @@ void GrantUniversalAccess(PP_Resource loader_id) { loader->GrantUniversalAccess(); } +void SetStatusCallback(PP_Resource loader_id, + PP_URLLoaderTrusted_StatusCallback cb) { + scoped_refptr<URLLoader> loader(Resource::GetAs<URLLoader>(loader_id)); + if (!loader) + return; + loader->SetStatusCallback(cb); +} + const PPB_URLLoaderTrusted_Dev ppb_urlloadertrusted = { - &GrantUniversalAccess + &GrantUniversalAccess, + &SetStatusCallback }; +WebKit::WebFrame* GetFrame(PluginInstance* instance) { + return instance->container()->element().document().frame(); +} + } // namespace URLLoader::URLLoader(PluginInstance* instance, bool main_document_loader) @@ -179,10 +194,16 @@ URLLoader::URLLoader(PluginInstance* instance, bool main_document_loader) user_buffer_(NULL), user_buffer_size_(0), done_status_(PP_ERROR_WOULDBLOCK), - has_universal_access_(false) { + record_download_progress_(false), + record_upload_progress_(false), + has_universal_access_(false), + status_callback_(NULL) { + instance->AddObserver(this); } URLLoader::~URLLoader() { + if (instance_) + instance_->RemoveObserver(this); } // static @@ -204,32 +225,79 @@ int32_t URLLoader::Open(URLRequestInfo* request, if (!callback.func) return PP_ERROR_BADARGUMENT; - WebFrame* frame = instance_->container()->element().document().frame(); + WebFrame* frame = GetFrame(instance_); if (!frame) return PP_ERROR_FAILED; WebURLRequest web_request(request->ToWebURLRequest(frame)); - // Check if we are allowed to access this URL. - if (!has_universal_access_ && - !frame->securityOrigin().canRequest(web_request.url())) - return PP_ERROR_NOACCESS; + int32_t rv = CanRequest(frame, web_request.url()); + if (rv != PP_OK) + return rv; frame->dispatchWillSendRequest(web_request); + // Sets the appcache host id to allow retrieval from the appcache. + if (WebApplicationCacheHostImpl* appcache_host = + WebApplicationCacheHostImpl::FromFrame(frame)) { + appcache_host->willStartSubResourceRequest(web_request); + } + loader_.reset(WebKit::webKitClient()->createURLLoader()); if (!loader_.get()) return PP_ERROR_FAILED; + loader_->loadAsynchronously(web_request, this); + request_info_ = scoped_refptr<URLRequestInfo>(request); pending_callback_ = callback; + record_download_progress_ = request->record_download_progress(); + record_upload_progress_ = request->record_upload_progress(); // Notify completion when we receive a redirect or response headers. return PP_ERROR_WOULDBLOCK; } int32_t URLLoader::FollowRedirect(PP_CompletionCallback callback) { - NOTIMPLEMENTED(); // TODO(darin): Implement me. - return PP_ERROR_FAILED; + if (pending_callback_.func) + return PP_ERROR_INPROGRESS; + + // We only support non-blocking calls. + if (!callback.func) + return PP_ERROR_BADARGUMENT; + + WebURL redirect_url = GURL(response_info_->redirect_url()); + + int32_t rv = CanRequest(GetFrame(instance_), redirect_url); + if (rv != PP_OK) + return rv; + + pending_callback_ = callback; + loader_->setDefersLoading(false); // Allow the redirect to continue. + return PP_ERROR_WOULDBLOCK; +} + +bool URLLoader::GetUploadProgress(int64_t* bytes_sent, + int64_t* total_bytes_to_be_sent) { + if (!record_upload_progress_) { + *bytes_sent = 0; + *total_bytes_to_be_sent = 0; + return false; + } + *bytes_sent = bytes_sent_; + *total_bytes_to_be_sent = total_bytes_to_be_sent_; + return true; +} + +bool URLLoader::GetDownloadProgress(int64_t* bytes_received, + int64_t* total_bytes_to_be_received) { + if (!record_download_progress_) { + *bytes_received = 0; + *total_bytes_to_be_received = 0; + return false; + } + *bytes_received = bytes_received_; + *total_bytes_to_be_received = total_bytes_to_be_received_; + return true; } int32_t URLLoader::ReadResponseBody(char* buffer, int32_t bytes_to_read, @@ -290,10 +358,24 @@ void URLLoader::GrantUniversalAccess() { has_universal_access_ = true; } +void URLLoader::SetStatusCallback(PP_URLLoaderTrusted_StatusCallback cb) { + status_callback_ = cb; +} + void URLLoader::willSendRequest(WebURLLoader* loader, WebURLRequest& new_request, const WebURLResponse& redirect_response) { - NOTIMPLEMENTED(); // TODO(darin): Allow the plugin to inspect redirects. + if (!request_info_->follow_redirects()) { + SaveResponse(redirect_response); + loader_->setDefersLoading(true); + RunCallback(PP_OK); + } else { + int32_t rv = CanRequest(GetFrame(instance_), new_request.url()); + if (rv != PP_OK) { + loader_->setDefersLoading(true); + RunCallback(rv); + } + } } void URLLoader::didSendData(WebURLLoader* loader, @@ -302,16 +384,16 @@ void URLLoader::didSendData(WebURLLoader* loader, // TODO(darin): Bounds check input? bytes_sent_ = static_cast<int64_t>(bytes_sent); total_bytes_to_be_sent_ = static_cast<int64_t>(total_bytes_to_be_sent); + UpdateStatus(); } void URLLoader::didReceiveResponse(WebURLLoader* loader, const WebURLResponse& response) { - scoped_refptr<URLResponseInfo> response_info(new URLResponseInfo(module())); - if (response_info->Initialize(response)) - response_info_ = response_info; + SaveResponse(response); // Sets -1 if the content length is unknown. total_bytes_to_be_received_ = response.expectedContentLength(); + UpdateStatus(); RunCallback(PP_OK); } @@ -319,6 +401,7 @@ void URLLoader::didReceiveResponse(WebURLLoader* loader, void URLLoader::didDownloadData(WebURLLoader* loader, int data_length) { bytes_received_ += data_length; + UpdateStatus(); } void URLLoader::didReceiveData(WebURLLoader* loader, @@ -345,6 +428,40 @@ void URLLoader::didFail(WebURLLoader* loader, const WebURLError& error) { RunCallback(done_status_); } +void URLLoader::InstanceDestroyed(PluginInstance* instance) { + // When the instance is destroyed, we force delete any associated loads. + DCHECK(instance == instance_); + instance_ = NULL; + + // Normally the only ref to this class will be from the plugin which + // ForceDeletePluginResourceRefs will free. We don't want our object to be + // deleted out from under us until the function completes. + scoped_refptr<URLLoader> death_grip(this); + + // Force delete any plugin refs to us. If the instance is being deleted, we + // don't want to allow the requests to continue to use bandwidth and send us + // callbacks (for which we might have no plugin). + ResourceTracker *tracker = ResourceTracker::Get(); + PP_Resource loader_resource = GetReferenceNoAddRef(); + if (loader_resource) + tracker->ForceDeletePluginResourceRefs(loader_resource); + + // Also force free the response from the plugin, both the plugin's ref(s) + // and ours. + if (response_info_.get()) { + PP_Resource response_info_resource = response_info_->GetReferenceNoAddRef(); + if (response_info_resource) + tracker->ForceDeletePluginResourceRefs(response_info_resource); + response_info_ = NULL; + } + + // Free the WebKit request. + loader_.reset(); + + // Often, |this| will be deleted at the end of this function when death_grip + // goes out of scope. +} + void URLLoader::RunCallback(int32_t result) { if (!pending_callback_.func) return; @@ -368,4 +485,44 @@ size_t URLLoader::FillUserBuffer() { return bytes_to_copy; } +void URLLoader::SaveResponse(const WebKit::WebURLResponse& response) { + scoped_refptr<URLResponseInfo> response_info(new URLResponseInfo(module())); + if (response_info->Initialize(response)) + response_info_ = response_info; +} + +// Checks that the client can request the URL. Returns a PPAPI error code. +int32_t URLLoader::CanRequest(const WebKit::WebFrame* frame, + const WebKit::WebURL& url) { + if (!has_universal_access_ && + !frame->securityOrigin().canRequest(url)) + return PP_ERROR_NOACCESS; + + return PP_OK; +} + +void URLLoader::UpdateStatus() { + if (status_callback_ && + (record_download_progress_ || record_upload_progress_)) { + PP_Resource pp_resource = GetReferenceNoAddRef(); + if (pp_resource) { + // The PP_Resource on the plugin will be NULL if the plugin has no + // reference to this object. That's fine, because then we don't need to + // call UpdateStatus. + // + // Here we go through some effort to only send the exact information that + // the requestor wanted in the request flags. It would be just as + // efficient to send all of it, but we don't want people to rely on + // getting download progress when they happen to set the upload progress + // flag. + status_callback_( + instance_->pp_instance(), pp_resource, + record_upload_progress_ ? bytes_sent_ : -1, + record_upload_progress_ ? total_bytes_to_be_sent_ : -1, + record_download_progress_ ? bytes_received_ : -1, + record_download_progress_ ? total_bytes_to_be_received_ : -1); + } + } +} + } // namespace pepper diff --git a/webkit/glue/plugins/pepper_url_loader.h b/webkit/glue/plugins/pepper_url_loader.h index e613475..dd91708 100644 --- a/webkit/glue/plugins/pepper_url_loader.h +++ b/webkit/glue/plugins/pepper_url_loader.h @@ -8,21 +8,29 @@ #include <deque> #include "base/scoped_ptr.h" -#include "third_party/ppapi/c/pp_completion_callback.h" -#include "third_party/WebKit/WebKit/chromium/public/WebURLLoader.h" +#include "ppapi/c/pp_completion_callback.h" +#include "ppapi/c/dev/ppb_url_loader_trusted_dev.h" #include "third_party/WebKit/WebKit/chromium/public/WebURLLoaderClient.h" +#include "webkit/glue/plugins/pepper_plugin_instance.h" #include "webkit/glue/plugins/pepper_resource.h" struct PPB_URLLoader_Dev; struct PPB_URLLoaderTrusted_Dev; +namespace WebKit { +class WebFrame; +class WebURL; +} + namespace pepper { class PluginInstance; class URLRequestInfo; class URLResponseInfo; -class URLLoader : public Resource, public WebKit::WebURLLoaderClient { +class URLLoader : public Resource, + public WebKit::WebURLLoaderClient, + public PluginInstance::Observer { public: URLLoader(PluginInstance* instance, bool main_document_loader); virtual ~URLLoader(); @@ -41,6 +49,10 @@ class URLLoader : public Resource, public WebKit::WebURLLoaderClient { // PPB_URLLoader implementation. int32_t Open(URLRequestInfo* request, PP_CompletionCallback callback); int32_t FollowRedirect(PP_CompletionCallback callback); + bool GetUploadProgress(int64_t* bytes_sent, + int64_t* total_bytes_to_be_sent); + bool GetDownloadProgress(int64_t* bytes_received, + int64_t* total_bytes_to_be_received); int32_t ReadResponseBody(char* buffer, int32_t bytes_to_read, PP_CompletionCallback callback); int32_t FinishStreamingToFile(PP_CompletionCallback callback); @@ -48,6 +60,7 @@ class URLLoader : public Resource, public WebKit::WebURLLoaderClient { // PPB_URLLoaderTrusted implementation. void GrantUniversalAccess(); + void SetStatusCallback(PP_URLLoaderTrusted_StatusCallback cb); // WebKit::WebURLLoaderClient implementation. virtual void willSendRequest(WebKit::WebURLLoader* loader, @@ -68,25 +81,36 @@ class URLLoader : public Resource, public WebKit::WebURLLoaderClient { virtual void didFail(WebKit::WebURLLoader* loader, const WebKit::WebURLError& error); - URLResponseInfo* response_info() const { return response_info_; } + // PluginInstance::Observer implementation. + void InstanceDestroyed(PluginInstance* instance); - // Progress counters. - int64_t bytes_sent() const { return bytes_sent_; } - int64_t total_bytes_to_be_sent() const { return total_bytes_to_be_sent_; } - int64_t bytes_received() const { return bytes_received_; } - int64_t total_bytes_to_be_received() const { - return total_bytes_to_be_received_; - } + URLResponseInfo* response_info() const { return response_info_; } private: void RunCallback(int32_t result); size_t FillUserBuffer(); - scoped_refptr<PluginInstance> instance_; + // Converts a WebURLResponse to a URLResponseInfo and saves it. + void SaveResponse(const WebKit::WebURLResponse& response); + + int32_t CanRequest(const WebKit::WebFrame* frame, const WebKit::WebURL& url); + + // Calls the status_callback_ (if any) with the current upload and download + // progress. Call this function if you update any of these values to + // synchronize an out-of-process plugin's state. + void UpdateStatus(); + + // This will be NULL if the instance has been deleted but this URLLoader was + // somehow leaked. In general, you should not need to check this for NULL. + // However, if you see a NULL pointer crash, that means somebody is holding + // a reference to this object longer than the PluginInstance's lifetime. + 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<URLRequestInfo> request_info_; scoped_refptr<URLResponseInfo> response_info_; PP_CompletionCallback pending_callback_; std::deque<char> buffer_; @@ -97,7 +121,13 @@ class URLLoader : public Resource, public WebKit::WebURLLoaderClient { char* user_buffer_; size_t user_buffer_size_; int32_t done_status_; + + bool record_download_progress_; + bool record_upload_progress_; + bool has_universal_access_; + + PP_URLLoaderTrusted_StatusCallback status_callback_; }; } // namespace pepper diff --git a/webkit/glue/plugins/pepper_url_request_info.cc b/webkit/glue/plugins/pepper_url_request_info.cc index dd8f7a6..ae0c280 100644 --- a/webkit/glue/plugins/pepper_url_request_info.cc +++ b/webkit/glue/plugins/pepper_url_request_info.cc @@ -8,13 +8,14 @@ #include "base/string_util.h" #include "googleurl/src/gurl.h" #include "net/http/http_util.h" -#include "third_party/ppapi/c/pp_var.h" +#include "ppapi/c/pp_var.h" #include "third_party/WebKit/WebKit/chromium/public/WebData.h" #include "third_party/WebKit/WebKit/chromium/public/WebDocument.h" #include "third_party/WebKit/WebKit/chromium/public/WebFrame.h" #include "third_party/WebKit/WebKit/chromium/public/WebHTTPBody.h" #include "third_party/WebKit/WebKit/chromium/public/WebURL.h" #include "third_party/WebKit/WebKit/chromium/public/WebURLRequest.h" +#include "webkit/glue/plugins/pepper_common.h" #include "webkit/glue/plugins/pepper_file_ref.h" #include "webkit/glue/plugins/pepper_plugin_module.h" #include "webkit/glue/plugins/pepper_string.h" @@ -38,12 +39,12 @@ const char* const kIgnoredRequestHeaders[] = { "content-length" }; -bool IsIgnoredRequestHeader(const std::string& name) { +PP_Bool IsIgnoredRequestHeader(const std::string& name) { for (size_t i = 0; i < arraysize(kIgnoredRequestHeaders); ++i) { if (LowerCaseEqualsASCII(name, kIgnoredRequestHeaders[i])) - return true; + return PP_TRUE; } - return false; + return PP_FALSE; } PP_Resource Create(PP_Module module_id) { @@ -56,40 +57,47 @@ PP_Resource Create(PP_Module module_id) { return request->GetReference(); } -bool IsURLRequestInfo(PP_Resource resource) { - return !!Resource::GetAs<URLRequestInfo>(resource); +PP_Bool IsURLRequestInfo(PP_Resource resource) { + return BoolToPPBool(!!Resource::GetAs<URLRequestInfo>(resource)); } -bool SetProperty(PP_Resource request_id, - PP_URLRequestProperty_Dev property, - PP_Var var) { +PP_Bool SetProperty(PP_Resource request_id, + PP_URLRequestProperty_Dev property, + PP_Var var) { scoped_refptr<URLRequestInfo> request( Resource::GetAs<URLRequestInfo>(request_id)); if (!request) - return false; + return PP_FALSE; - if (var.type == PP_VARTYPE_BOOL) - return request->SetBooleanProperty(property, var.value.as_bool); + if (var.type == PP_VARTYPE_BOOL) { + return BoolToPPBool( + request->SetBooleanProperty(property, + PPBoolToBool(var.value.as_bool))); + } if (var.type == PP_VARTYPE_STRING) { scoped_refptr<StringVar> string(StringVar::FromPPVar(var)); - if (string) - return request->SetStringProperty(property, string->value()); + if (string) { + return BoolToPPBool(request->SetStringProperty(property, + string->value())); + } } - return false; + return PP_FALSE; } -bool AppendDataToBody(PP_Resource request_id, const char* data, uint32_t len) { +PP_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; + return PP_FALSE; - return request->AppendDataToBody(std::string(data, len)); + return BoolToPPBool(request->AppendDataToBody(std::string(data, len))); } -bool AppendFileToBody(PP_Resource request_id, +PP_Bool AppendFileToBody(PP_Resource request_id, PP_Resource file_ref_id, int64_t start_offset, int64_t number_of_bytes, @@ -97,16 +105,16 @@ bool AppendFileToBody(PP_Resource request_id, scoped_refptr<URLRequestInfo> request( Resource::GetAs<URLRequestInfo>(request_id)); if (!request) - return false; + return PP_FALSE; scoped_refptr<FileRef> file_ref(Resource::GetAs<FileRef>(file_ref_id)); if (!file_ref) - return false; + return PP_FALSE; - return request->AppendFileToBody(file_ref, - start_offset, - number_of_bytes, - expected_last_modified_time); + return BoolToPPBool(request->AppendFileToBody(file_ref, + start_offset, + number_of_bytes, + expected_last_modified_time)); } const PPB_URLRequestInfo_Dev ppb_urlrequestinfo = { @@ -146,7 +154,10 @@ struct URLRequestInfo::BodyItem { URLRequestInfo::URLRequestInfo(PluginModule* module) : Resource(module), - stream_to_file_(false) { + stream_to_file_(false), + follow_redirects_(true), + record_download_progress_(false), + record_upload_progress_(false) { } URLRequestInfo::~URLRequestInfo() { @@ -163,8 +174,17 @@ bool URLRequestInfo::SetBooleanProperty(PP_URLRequestProperty_Dev property, case PP_URLREQUESTPROPERTY_STREAMTOFILE: stream_to_file_ = value; return true; + case PP_URLREQUESTPROPERTY_FOLLOWREDIRECTS: + follow_redirects_ = value; + return true; + case PP_URLREQUESTPROPERTY_RECORDDOWNLOADPROGRESS: + record_download_progress_ = value; + return true; + case PP_URLREQUESTPROPERTY_RECORDUPLOADPROGRESS: + record_upload_progress_ = value; + return true; default: - NOTIMPLEMENTED(); // TODO(darin): Implement me! + //NOTIMPLEMENTED(); // TODO(darin): Implement me! return false; } } diff --git a/webkit/glue/plugins/pepper_url_request_info.h b/webkit/glue/plugins/pepper_url_request_info.h index 2d394d5..4fd4e26 100644 --- a/webkit/glue/plugins/pepper_url_request_info.h +++ b/webkit/glue/plugins/pepper_url_request_info.h @@ -9,7 +9,7 @@ #include <vector> #include "base/ref_counted.h" -#include "third_party/ppapi/c/dev/ppb_url_request_info_dev.h" +#include "ppapi/c/dev/ppb_url_request_info_dev.h" #include "webkit/glue/plugins/pepper_file_ref.h" #include "webkit/glue/plugins/pepper_resource.h" @@ -44,6 +44,11 @@ class URLRequestInfo : public Resource { WebKit::WebURLRequest ToWebURLRequest(WebKit::WebFrame* frame) const; + bool follow_redirects() { return follow_redirects_; } + + bool record_download_progress() const { return record_download_progress_; } + bool record_upload_progress() const { return record_upload_progress_; } + private: struct BodyItem; typedef std::vector<BodyItem> Body; @@ -52,7 +57,11 @@ class URLRequestInfo : public Resource { std::string method_; std::string headers_; Body body_; + bool stream_to_file_; + bool follow_redirects_; + bool record_download_progress_; + bool record_upload_progress_; }; } // namespace pepper diff --git a/webkit/glue/plugins/pepper_url_response_info.cc b/webkit/glue/plugins/pepper_url_response_info.cc index 8af3385..2e7202f 100644 --- a/webkit/glue/plugins/pepper_url_response_info.cc +++ b/webkit/glue/plugins/pepper_url_response_info.cc @@ -5,11 +5,12 @@ #include "webkit/glue/plugins/pepper_url_response_info.h" #include "base/logging.h" -#include "third_party/ppapi/c/pp_var.h" +#include "ppapi/c/pp_var.h" #include "third_party/WebKit/WebKit/chromium/public/WebHTTPHeaderVisitor.h" #include "third_party/WebKit/WebKit/chromium/public/WebString.h" #include "third_party/WebKit/WebKit/chromium/public/WebURL.h" #include "third_party/WebKit/WebKit/chromium/public/WebURLResponse.h" +#include "webkit/glue/plugins/pepper_common.h" #include "webkit/glue/plugins/pepper_file_ref.h" #include "webkit/glue/plugins/pepper_var.h" #include "webkit/glue/webkit_glue.h" @@ -38,8 +39,8 @@ class HeaderFlattener : public WebHTTPHeaderVisitor { std::string buffer_; }; -bool IsURLResponseInfo(PP_Resource resource) { - return !!Resource::GetAs<URLResponseInfo>(resource); +PP_Bool IsURLResponseInfo(PP_Resource resource) { + return BoolToPPBool(!!Resource::GetAs<URLResponseInfo>(resource)); } PP_Var GetProperty(PP_Resource response_id, @@ -72,6 +73,10 @@ const PPB_URLResponseInfo_Dev ppb_urlresponseinfo = { &GetBody }; +bool IsRedirect(int32_t status) { + return status >= 300 && status <= 399; +} + } // namespace URLResponseInfo::URLResponseInfo(PluginModule* module) @@ -91,19 +96,33 @@ PP_Var URLResponseInfo::GetProperty(PP_URLResponseProperty_Dev property) { switch (property) { case PP_URLRESPONSEPROPERTY_URL: return StringVar::StringToPPVar(module(), url_); + case PP_URLRESPONSEPROPERTY_REDIRECTURL: + if (IsRedirect(status_code_)) + return StringVar::StringToPPVar(module(), redirect_url_); + break; + case PP_URLRESPONSEPROPERTY_REDIRECTMETHOD: + if (IsRedirect(status_code_)) + return StringVar::StringToPPVar(module(), status_text_); + break; case PP_URLRESPONSEPROPERTY_STATUSCODE: return PP_MakeInt32(status_code_); + case PP_URLRESPONSEPROPERTY_STATUSLINE: + return StringVar::StringToPPVar(module(), status_text_); case PP_URLRESPONSEPROPERTY_HEADERS: return StringVar::StringToPPVar(module(), headers_); - default: - NOTIMPLEMENTED(); // TODO(darin): Implement me! - return PP_MakeUndefined(); } + // The default is to return an undefined PP_Var. + return PP_MakeUndefined(); } bool URLResponseInfo::Initialize(const WebURLResponse& response) { url_ = response.url().spec(); status_code_ = response.httpStatusCode(); + status_text_ = response.httpStatusText().utf8(); + if (IsRedirect(status_code_)) { + redirect_url_ = response.httpHeaderField( + WebString::fromUTF8("Location")).utf8(); + } HeaderFlattener flattener; response.visitHTTPHeaderFields(&flattener); diff --git a/webkit/glue/plugins/pepper_url_response_info.h b/webkit/glue/plugins/pepper_url_response_info.h index d8e1321..ff3a832 100644 --- a/webkit/glue/plugins/pepper_url_response_info.h +++ b/webkit/glue/plugins/pepper_url_response_info.h @@ -7,7 +7,7 @@ #include <string> -#include "third_party/ppapi/c/dev/ppb_url_response_info_dev.h" +#include "ppapi/c/dev/ppb_url_response_info_dev.h" #include "webkit/glue/plugins/pepper_resource.h" namespace WebKit { @@ -35,10 +35,14 @@ class URLResponseInfo : public Resource { FileRef* body() { return body_; } + std::string redirect_url() { return redirect_url_; } + private: std::string url_; std::string headers_; int32_t status_code_; + std::string status_text_; + std::string redirect_url_; scoped_refptr<FileRef> body_; }; diff --git a/webkit/glue/plugins/pepper_url_util.cc b/webkit/glue/plugins/pepper_url_util.cc index a182b92..2f97e6c 100644 --- a/webkit/glue/plugins/pepper_url_util.cc +++ b/webkit/glue/plugins/pepper_url_util.cc @@ -5,7 +5,7 @@ #include "webkit/glue/plugins/pepper_url_util.h" #include "googleurl/src/gurl.h" -#include "third_party/ppapi/c/dev/ppb_url_util_dev.h" +#include "ppapi/c/dev/ppb_url_util_dev.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" @@ -13,6 +13,7 @@ #include "third_party/WebKit/WebKit/chromium/public/WebPluginContainer.h" #include "third_party/WebKit/WebKit/chromium/public/WebSecurityOrigin.h" #include "third_party/WebKit/WebKit/chromium/public/WebURL.h" +#include "webkit/glue/plugins/pepper_common.h" #include "webkit/glue/plugins/pepper_plugin_instance.h" #include "webkit/glue/plugins/pepper_string.h" #include "webkit/glue/plugins/pepper_var.h" @@ -115,46 +116,46 @@ PP_Var ResolveRelativeToDocument(PP_Instance instance_id, components); } -bool IsSameSecurityOrigin(PP_Var url_a, PP_Var url_b) { +PP_Bool IsSameSecurityOrigin(PP_Var url_a, PP_Var url_b) { scoped_refptr<StringVar> url_a_string(StringVar::FromPPVar(url_a)); scoped_refptr<StringVar> url_b_string(StringVar::FromPPVar(url_b)); if (!url_a_string || !url_b_string) - return false; + return PP_FALSE; GURL gurl_a(url_a_string->value()); GURL gurl_b(url_b_string->value()); if (!gurl_a.is_valid() || !gurl_b.is_valid()) - return false; + return PP_FALSE; - return gurl_a.GetOrigin() == gurl_b.GetOrigin(); + return BoolToPPBool(gurl_a.GetOrigin() == gurl_b.GetOrigin()); } -bool DocumentCanRequest(PP_Instance instance, PP_Var url) { +PP_Bool DocumentCanRequest(PP_Instance instance, PP_Var url) { scoped_refptr<StringVar> url_string(StringVar::FromPPVar(url)); if (!url_string) - return false; + return PP_FALSE; WebKit::WebSecurityOrigin security_origin; if (!SecurityOriginForInstance(instance, &security_origin)) - return false; + return PP_FALSE; GURL gurl(url_string->value()); if (!gurl.is_valid()) - return false; + return PP_FALSE; - return security_origin.canRequest(gurl); + return BoolToPPBool(security_origin.canRequest(gurl)); } -bool DocumentCanAccessDocument(PP_Instance active, PP_Instance target) { +PP_Bool DocumentCanAccessDocument(PP_Instance active, PP_Instance target) { WebKit::WebSecurityOrigin active_origin; if (!SecurityOriginForInstance(active, &active_origin)) - return false; + return PP_FALSE; WebKit::WebSecurityOrigin target_origin; if (!SecurityOriginForInstance(active, &target_origin)) - return false; + return PP_FALSE; - return active_origin.canAccess(target_origin); + return BoolToPPBool(active_origin.canAccess(target_origin)); } } // namespace diff --git a/webkit/glue/plugins/pepper_var.cc b/webkit/glue/plugins/pepper_var.cc index 6daece9..db83229 100644 --- a/webkit/glue/plugins/pepper_var.cc +++ b/webkit/glue/plugins/pepper_var.cc @@ -4,12 +4,17 @@ #include "webkit/glue/plugins/pepper_var.h" +#include <limits> + #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 "ppapi/c/dev/ppb_var_deprecated.h" +#include "ppapi/c/ppb_var.h" +#include "ppapi/c/pp_var.h" #include "third_party/WebKit/WebKit/chromium/public/WebBindings.h" +#include "webkit/glue/plugins/pepper_common.h" +#include "webkit/glue/plugins/pepper_plugin_instance.h" #include "webkit/glue/plugins/pepper_plugin_module.h" #include "webkit/glue/plugins/pepper_plugin_object.h" #include "v8/include/v8.h" @@ -154,6 +159,63 @@ class ObjectAccessorWithIdentifierTryCatch : public ObjectAccessorTryCatch { DISALLOW_COPY_AND_ASSIGN(ObjectAccessorWithIdentifierTryCatch); }; +PP_Var RunJSFunction(PP_Var scope_var, + const char* function_script, + PP_Var* argv, + unsigned argc, + PP_Var* exception) { + TryCatch try_catch(NULL, exception); + if (try_catch.has_exception()) + return PP_MakeUndefined(); + + scoped_refptr<ObjectVar> obj = ObjectVar::FromPPVar(scope_var); + if (!obj) { + try_catch.SetInvalidObjectException(); + return PP_MakeUndefined(); + } + + try_catch.set_module(obj->module()); + + scoped_array<NPVariant> args; + if (argc) { + args.reset(new NPVariant[argc]); + for (uint32_t i = 0; i < argc; ++i) { + if (!PPVarToNPVariantNoCopy(argv[i], &args[i])) { + // This argument was invalid, throw an exception & give up. + try_catch.SetException(kInvalidValueException); + return PP_MakeUndefined(); + } + } + } + + NPVariant function_var; + VOID_TO_NPVARIANT(function_var); + NPString function_string = { function_script, strlen(function_script) }; + if (!WebBindings::evaluate(NULL, obj->np_object(), &function_string, + &function_var)) { + try_catch.SetException(kInvalidValueException); + return PP_MakeUndefined(); + } + DCHECK(NPVARIANT_IS_OBJECT(function_var)); + DCHECK(!try_catch.has_exception()); + + NPVariant result_var; + VOID_TO_NPVARIANT(result_var); + PP_Var result; + + if (WebBindings::invokeDefault(NULL, NPVARIANT_TO_OBJECT(function_var), + args.get(), argc, &result_var)) { + result = Var::NPVariantToPPVar(obj->module(), &result_var); + } else { + DCHECK(try_catch.has_exception()); + result = PP_MakeUndefined(); + } + + WebBindings::releaseVariantValue(&function_var); + WebBindings::releaseVariantValue(&result_var); + return result; +} + // PPB_Var methods ------------------------------------------------------------- PP_Var VarFromUtf8(PP_Module module_id, const char* data, uint32_t len) { @@ -175,14 +237,118 @@ const char* VarToUtf8(PP_Var var, uint32_t* len) { return str->value().data(); } -bool HasProperty(PP_Var var, - PP_Var name, - PP_Var* exception) { +PP_Var ConvertType(PP_Instance instance, + struct PP_Var var, + PP_VarType new_type, + PP_Var* exception) { + TryCatch try_catch(NULL, exception); + if (try_catch.has_exception()) + return PP_MakeUndefined(); + + if (var.type == new_type) + return var; + + PluginInstance* plugin_instance = + ResourceTracker::Get()->GetInstance(instance); + if (!plugin_instance) { + try_catch.SetInvalidObjectException(); + return PP_MakeUndefined(); + } + + try_catch.set_module(plugin_instance->module()); + PP_Var object = plugin_instance->GetWindowObject(); + + PP_Var params[] = { + var, + PP_MakeInt32(new_type), + PP_MakeInt32(PP_VARTYPE_NULL), + PP_MakeInt32(PP_VARTYPE_BOOL), + PP_MakeInt32(PP_VARTYPE_INT32), + PP_MakeInt32(PP_VARTYPE_DOUBLE), + PP_MakeInt32(PP_VARTYPE_STRING), + PP_MakeInt32(PP_VARTYPE_OBJECT) + }; + PP_Var result = RunJSFunction(object, + "(function(v, new_type, type_null, type_bool, type_int32, type_double," + " type_string, type_object) {" + " switch(new_type) {" + " case type_null: return null;" + " case type_bool: return Boolean(v);" + " case type_int32: case type_double: return Number(v);" + " case type_string: return String(v);" + " case type_object: return Object(v);" + " default: return undefined;" + " }})", + params, sizeof(params) / sizeof(PP_Var), exception); + + // Massage Number into the correct type. + if (new_type == PP_VARTYPE_INT32 && result.type == PP_VARTYPE_DOUBLE) { + double value = result.value.as_double; + // Exclusive test wouldn't deal with NaNs correctly. + if (value >= std::numeric_limits<int32_t>::max() + && value <= std::numeric_limits<int32_t>::min()) + result = PP_MakeInt32(static_cast<int32_t>(value)); + else + result = PP_MakeInt32(0); + } else if (new_type == PP_VARTYPE_DOUBLE && result.type == PP_VARTYPE_INT32) { + result = PP_MakeDouble(result.value.as_int); + } + + Var::PluginReleasePPVar(object); + return result; +} + +PP_Var BoolToPPVar(bool value) { + return PP_MakeBool(BoolToPPBool(value)); +} + +void DefineProperty(struct PP_Var object, + struct PP_ObjectProperty property, + PP_Var* exception) { + PP_Var params[] = { + object, property.name, + BoolToPPVar(!!(property.modifiers & PP_OBJECTPROPERTY_MODIFIER_HASVALUE)), + property.value, + BoolToPPVar(property.getter.type == PP_VARTYPE_OBJECT), + property.getter, + BoolToPPVar(property.setter.type == PP_VARTYPE_OBJECT), + property.setter, + BoolToPPVar(!!(property.modifiers & PP_OBJECTPROPERTY_MODIFIER_READONLY)), + BoolToPPVar(!!(property.modifiers & PP_OBJECTPROPERTY_MODIFIER_DONTDELETE)), + BoolToPPVar(!!(property.modifiers & PP_OBJECTPROPERTY_MODIFIER_DONTENUM)) + }; + + RunJSFunction(object, + "(function(o, name," + " has_value, value," + " has_getter, getter," + " has_setter, setter," + " modifier_readonly, modifier_dontdelete, modifier_dontenum) {" + " prop = { 'enumerable': !modifier_dontenum," + " 'configurable': !modifier_dontdelete };" + " if (has_value && !modifier_readonly) prop.writable = true;" + " if (has_value) prop.value = value;" + " if (has_getter) prop.get = getter;" + " if (has_setter) prop.set = setter;" + " return Object.defineProperty(o, name, prop); })", + params, sizeof(params) / sizeof(PP_Var), exception); +} + +PP_Bool HasProperty(PP_Var var, + PP_Var name, + PP_Var* exception) { ObjectAccessorWithIdentifierTryCatch accessor(var, name, exception); if (accessor.has_exception()) - return false; - return WebBindings::hasProperty(NULL, accessor.object()->np_object(), - accessor.identifier()); + return PP_FALSE; + return BoolToPPBool(WebBindings::hasProperty(NULL, + accessor.object()->np_object(), + accessor.identifier())); +} + +bool HasPropertyDeprecated(PP_Var var, + PP_Var name, + PP_Var* exception) { + return PPBoolToBool(HasProperty(var, name, exception)); } bool HasMethodDeprecated(PP_Var var, @@ -264,9 +430,22 @@ void SetPropertyDeprecated(PP_Var var, accessor.SetException(kUnableToSetPropertyException); } -void DeleteProperty(PP_Var var, - PP_Var name, - PP_Var* exception) { +PP_Bool DeleteProperty(PP_Var var, + PP_Var name, + PP_Var* exception) { + ObjectAccessorWithIdentifierTryCatch accessor(var, name, exception); + if (accessor.has_exception()) + return PP_FALSE; + + return BoolToPPBool( + WebBindings::removeProperty(NULL, + accessor.object()->np_object(), + accessor.identifier())); +} + +void DeletePropertyDeprecated(PP_Var var, + PP_Var name, + PP_Var* exception) { ObjectAccessorWithIdentifierTryCatch accessor(var, name, exception); if (accessor.has_exception()) return; @@ -276,6 +455,48 @@ void DeleteProperty(PP_Var var, accessor.SetException(kUnableToRemovePropertyException); } +PP_Bool IsCallable(struct PP_Var object) { + PP_Var result = RunJSFunction(object, + "(function() { return typeof(this) == 'function' })", NULL, 0, NULL); + if (result.type == PP_VARTYPE_BOOL) + return result.value.as_bool; + return PP_FALSE; +} + +struct PP_Var Call(struct PP_Var object, + struct PP_Var this_object, + uint32_t argc, + struct PP_Var* argv, + struct PP_Var* exception) { + ObjectAccessorTryCatch accessor(object, exception); + if (accessor.has_exception()) + return PP_MakeUndefined(); + + scoped_array<NPVariant> args; + if (argc) { + args.reset(new NPVariant[argc]); + for (uint32_t i = 0; i < argc; ++i) { + if (!PPVarToNPVariantNoCopy(argv[i], &args[i])) { + // This argument was invalid, throw an exception & give up. + accessor.SetException(kInvalidValueException); + return PP_MakeUndefined(); + } + } + } + + NPVariant result; + if (!WebBindings::invokeDefault(NULL, accessor.object()->np_object(), + args.get(), argc, &result)) { + // An exception may have been raised. + accessor.SetException(kUnableToCallMethodException); + return PP_MakeUndefined(); + } + + PP_Var ret = Var::NPVariantToPPVar(accessor.module(), &result); + WebBindings::releaseVariantValue(&result); + return ret; +} + PP_Var CallDeprecated(PP_Var var, PP_Var method_name, uint32_t argc, @@ -392,18 +613,35 @@ const PPB_Var_Deprecated var_deprecated_interface = { &Var::PluginReleasePPVar, &VarFromUtf8, &VarToUtf8, - &HasProperty, + &HasPropertyDeprecated, &HasMethodDeprecated, &GetProperty, &EnumerateProperties, &SetPropertyDeprecated, - &DeleteProperty, + &DeletePropertyDeprecated, &CallDeprecated, &Construct, &IsInstanceOfDeprecated, &CreateObjectDeprecated }; +const PPB_Var var_interface = { + &Var::PluginAddRefPPVar, + &Var::PluginReleasePPVar, + &VarFromUtf8, + &VarToUtf8, + &ConvertType, + &DefineProperty, + &HasProperty, + &GetProperty, + &DeleteProperty, + &EnumerateProperties, + &IsCallable, + &Call, + &Construct, +}; + + } // namespace // Var ------------------------------------------------------------------------- @@ -422,7 +660,7 @@ PP_Var Var::NPVariantToPPVar(PluginModule* module, const NPVariant* variant) { case NPVariantType_Null: return PP_MakeNull(); case NPVariantType_Bool: - return PP_MakeBool(NPVARIANT_TO_BOOLEAN(*variant)); + return BoolToPPVar(NPVARIANT_TO_BOOLEAN(*variant)); case NPVariantType_Int32: return PP_MakeInt32(NPVARIANT_TO_INT32(*variant)); case NPVariantType_Double: @@ -492,6 +730,10 @@ const PPB_Var_Deprecated* Var::GetDeprecatedInterface() { return &var_deprecated_interface; } +const PPB_Var* Var::GetInterface() { + return &var_interface; +} + // StringVar ------------------------------------------------------------------- StringVar::StringVar(PluginModule* module, const char* str, uint32 len) diff --git a/webkit/glue/plugins/pepper_var.h b/webkit/glue/plugins/pepper_var.h index 0eb1807..8929448 100644 --- a/webkit/glue/plugins/pepper_var.h +++ b/webkit/glue/plugins/pepper_var.h @@ -10,6 +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; @@ -82,6 +83,9 @@ class Var : public Resource { // Returns the PPB_Var_Deprecated interface for the plugin to use. static const PPB_Var_Deprecated* GetDeprecatedInterface(); + // Returns the PPB_Var interface for the plugin to use. + static const PPB_Var* GetInterface(); + protected: // This can only be constructed as a StringVar or an ObjectVar. explicit Var(PluginModule* module); diff --git a/webkit/glue/plugins/pepper_video_decoder.cc b/webkit/glue/plugins/pepper_video_decoder.cc index 3ca0ab2..cd4d3b5 100644 --- a/webkit/glue/plugins/pepper_video_decoder.cc +++ b/webkit/glue/plugins/pepper_video_decoder.cc @@ -5,10 +5,11 @@ #include "webkit/glue/plugins/pepper_video_decoder.h" #include "base/logging.h" -#include "third_party/ppapi/c/dev/pp_video_dev.h" -#include "third_party/ppapi/c/dev/ppb_video_decoder_dev.h" -#include "third_party/ppapi/c/pp_completion_callback.h" -#include "third_party/ppapi/c/pp_errors.h" +#include "ppapi/c/dev/pp_video_dev.h" +#include "ppapi/c/dev/ppb_video_decoder_dev.h" +#include "ppapi/c/pp_completion_callback.h" +#include "ppapi/c/pp_errors.h" +#include "webkit/glue/plugins/pepper_common.h" #include "webkit/glue/plugins/pepper_file_ref.h" #include "webkit/glue/plugins/pepper_plugin_instance.h" #include "webkit/glue/plugins/pepper_resource_tracker.h" @@ -17,7 +18,7 @@ namespace pepper { namespace { -bool GetConfig(PP_Instance instance_id, +PP_Bool GetConfig(PP_Instance instance_id, PP_VideoCodecId_Dev codec, PP_VideoConfig_Dev* configs, int32_t config_size, @@ -25,7 +26,7 @@ bool GetConfig(PP_Instance instance_id, PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id); *num_config = 0; if (!instance) - return false; + return PP_FALSE; // Get configs based on codec. @@ -35,7 +36,7 @@ bool GetConfig(PP_Instance instance_id, // Update *num_config. - return true; + return PP_TRUE; } PP_Resource Create(PP_Instance instance_id, @@ -52,15 +53,15 @@ PP_Resource Create(PP_Instance instance_id, return decoder->GetReference(); } -bool Decode(PP_Resource decoder_id, +PP_Bool Decode(PP_Resource decoder_id, PP_VideoCompressedDataBuffer_Dev* input_buffer) { scoped_refptr<VideoDecoder> decoder( Resource::GetAs<VideoDecoder>(decoder_id)); if (!decoder) - return false; + return PP_FALSE; decoder->Decode(*input_buffer); - return true; + return PP_TRUE; } int32_t Flush(PP_Resource decoder_id, PP_CompletionCallback callback) { @@ -72,14 +73,14 @@ int32_t Flush(PP_Resource decoder_id, PP_CompletionCallback callback) { return decoder->Flush(callback); } -bool ReturnUncompressedDataBuffer(PP_Resource decoder_id, +PP_Bool ReturnUncompressedDataBuffer(PP_Resource decoder_id, PP_VideoUncompressedDataBuffer_Dev* buffer) { scoped_refptr<VideoDecoder> decoder( Resource::GetAs<VideoDecoder>(decoder_id)); if (!decoder) - return false; + return PP_FALSE; - return decoder->ReturnUncompressedDataBuffer(*buffer); + return BoolToPPBool(decoder->ReturnUncompressedDataBuffer(*buffer)); } const PPB_VideoDecoder_Dev ppb_videodecoder = { diff --git a/webkit/glue/plugins/pepper_webplugin_impl.cc b/webkit/glue/plugins/pepper_webplugin_impl.cc index 2e8eb3f..8da398f 100644 --- a/webkit/glue/plugins/pepper_webplugin_impl.cc +++ b/webkit/glue/plugins/pepper_webplugin_impl.cc @@ -7,7 +7,7 @@ #include <cmath> #include "base/message_loop.h" -#include "third_party/ppapi/c/pp_var.h" +#include "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" @@ -109,6 +109,10 @@ void WebPluginImpl::updateGeometry( instance_->ViewChanged(plugin_rect_, clip_rect); } +unsigned WebPluginImpl::getBackingTextureId() { + return instance_->GetBackingTextureId(); +} + void WebPluginImpl::updateFocus(bool focused) { instance_->SetWebKitFocus(focused); } diff --git a/webkit/glue/plugins/pepper_webplugin_impl.h b/webkit/glue/plugins/pepper_webplugin_impl.h index 15ee784..8922143 100644 --- a/webkit/glue/plugins/pepper_webplugin_impl.h +++ b/webkit/glue/plugins/pepper_webplugin_impl.h @@ -46,6 +46,7 @@ class WebPluginImpl : public WebKit::WebPlugin { const WebKit::WebRect& clip_rect, const WebKit::WebVector<WebKit::WebRect>& cut_outs_rects, bool is_visible); + virtual unsigned getBackingTextureId(); virtual void updateFocus(bool focused); virtual void updateVisibility(bool visible); virtual bool acceptsInputEvents(); diff --git a/webkit/glue/plugins/pepper_widget.cc b/webkit/glue/plugins/pepper_widget.cc index 7002576..e704e8c 100644 --- a/webkit/glue/plugins/pepper_widget.cc +++ b/webkit/glue/plugins/pepper_widget.cc @@ -5,10 +5,11 @@ #include "webkit/glue/plugins/pepper_widget.h" #include "base/logging.h" -#include "third_party/ppapi/c/dev/ppb_widget_dev.h" -#include "third_party/ppapi/c/dev/ppp_widget_dev.h" -#include "third_party/ppapi/c/pp_completion_callback.h" -#include "third_party/ppapi/c/pp_errors.h" +#include "ppapi/c/dev/ppb_widget_dev.h" +#include "ppapi/c/dev/ppp_widget_dev.h" +#include "ppapi/c/pp_completion_callback.h" +#include "ppapi/c/pp_errors.h" +#include "webkit/glue/plugins/pepper_common.h" #include "webkit/glue/plugins/pepper_image_data.h" #include "webkit/glue/plugins/pepper_plugin_instance.h" #include "webkit/glue/plugins/pepper_plugin_module.h" @@ -17,30 +18,30 @@ namespace pepper { namespace { -bool IsWidget(PP_Resource resource) { - return !!Resource::GetAs<Widget>(resource); +PP_Bool IsWidget(PP_Resource resource) { + return BoolToPPBool(!!Resource::GetAs<Widget>(resource)); } -bool Paint(PP_Resource resource, const PP_Rect* rect, PP_Resource image_id) { +PP_Bool Paint(PP_Resource resource, const PP_Rect* rect, PP_Resource image_id) { scoped_refptr<Widget> widget(Resource::GetAs<Widget>(resource)); if (!widget) - return false; + return PP_FALSE; scoped_refptr<ImageData> image(Resource::GetAs<ImageData>(image_id)); if (!image) - return false; + return PP_FALSE; - return widget->Paint(rect, image); + return BoolToPPBool(widget->Paint(rect, image)); } -bool HandleEvent(PP_Resource resource, const PP_InputEvent* event) { +PP_Bool HandleEvent(PP_Resource resource, const PP_InputEvent* event) { scoped_refptr<Widget> widget(Resource::GetAs<Widget>(resource)); - return widget && widget->HandleEvent(event); + return BoolToPPBool(widget && widget->HandleEvent(event)); } -bool GetLocation(PP_Resource resource, PP_Rect* location) { +PP_Bool GetLocation(PP_Resource resource, PP_Rect* location) { scoped_refptr<Widget> widget(Resource::GetAs<Widget>(resource)); - return widget && widget->GetLocation(location); + return BoolToPPBool(widget && widget->GetLocation(location)); } void SetLocation(PP_Resource resource, const PP_Rect* location) { diff --git a/webkit/glue/plugins/pepper_widget.h b/webkit/glue/plugins/pepper_widget.h index 47826e3..cf937bd 100644 --- a/webkit/glue/plugins/pepper_widget.h +++ b/webkit/glue/plugins/pepper_widget.h @@ -6,7 +6,7 @@ #define WEBKIT_GLUE_PLUGINS_PEPPER_WIDGET_H_ #include "base/scoped_ptr.h" -#include "third_party/ppapi/c/pp_rect.h" +#include "ppapi/c/pp_rect.h" #include "webkit/glue/plugins/pepper_resource.h" struct PPB_Widget_Dev; diff --git a/webkit/glue/plugins/plugin_group.cc b/webkit/glue/plugins/plugin_group.cc index ee3155e..5dddbce 100644 --- a/webkit/glue/plugins/plugin_group.cc +++ b/webkit/glue/plugins/plugin_group.cc @@ -34,7 +34,7 @@ static const PluginGroupDefinition kGroupDefinitions[] = { "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", + { "shockwave", "Shockwave", "Shockwave for Director", "", "", "11.5.9.615", "http://www.adobe.com/shockwave/download/" } }; @@ -56,7 +56,7 @@ static const PluginGroupDefinition kGroupDefinitions[] = { "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", + { "shockwave", "Shockwave", "Shockwave for Director", "", "", "11.5.9.615", "http://www.adobe.com/shockwave/download/" }, { "divx-player", "DivX Player", "DivX Web Player", "", "", "1.4.3.4", "http://download.divx.com/divx/autoupdate/player/" diff --git a/webkit/glue/plugins/plugin_host.cc b/webkit/glue/plugins/plugin_host.cc index add6c03..7cf93ed 100644 --- a/webkit/glue/plugins/plugin_host.cc +++ b/webkit/glue/plugins/plugin_host.cc @@ -15,7 +15,10 @@ #include "base/sys_string_conversions.h" #include "base/utf_string_conversions.h" #include "net/base/net_util.h" +#include "third_party/npapi/bindings/npapi_extensions.h" +#include "third_party/npapi/bindings/npruntime.h" #include "third_party/WebKit/WebKit/chromium/public/WebBindings.h" +#include "third_party/WebKit/WebKit/chromium/public/WebKit.h" #include "webkit/glue/webkit_glue.h" #include "webkit/glue/plugins/default_plugin_shared.h" #include "webkit/glue/plugins/npapi_extension_thunk.h" @@ -25,8 +28,6 @@ #include "webkit/glue/plugins/plugin_stream_url.h" #include "webkit/glue/plugins/webplugin_delegate.h" #include "webkit/glue/plugins/webplugininfo.h" -#include "third_party/npapi/bindings/npapi_extensions.h" -#include "third_party/npapi/bindings/npruntime.h" using WebKit::WebBindings; @@ -34,7 +35,6 @@ using WebKit::WebBindings; // The caller must take a reference if needed. static NPAPI::PluginInstance* FindInstance(NPP id) { if (id == NULL) { - NOTREACHED(); return NULL; } return reinterpret_cast<NPAPI::PluginInstance*>(id->ndata); @@ -280,7 +280,7 @@ extern "C" { // Allocates memory from the host's memory space. void* NPN_MemAlloc(uint32_t size) { - scoped_refptr<NPAPI::PluginHost> host = NPAPI::PluginHost::Singleton(); + scoped_refptr<NPAPI::PluginHost> host(NPAPI::PluginHost::Singleton()); if (host != NULL) { // Note: We must use the same allocator/deallocator // that is used by the javascript library, as some of the @@ -293,7 +293,7 @@ void* NPN_MemAlloc(uint32_t size) { // Deallocates memory from the host's memory space void NPN_MemFree(void* ptr) { - scoped_refptr<NPAPI::PluginHost> host = NPAPI::PluginHost::Singleton(); + scoped_refptr<NPAPI::PluginHost> host(NPAPI::PluginHost::Singleton()); if (host != NULL) { if (ptr != NULL && ptr != reinterpret_cast<void*>(-1)) free(ptr); @@ -308,9 +308,8 @@ uint32_t NPN_MemFlush(uint32_t size) { // This is for dynamic discovery of new plugins. // Should force a re-scan of the plugins directory to load new ones. -void NPN_ReloadPlugins(NPBool reloadPages) { - // TODO: implement me - DVLOG(1) << "NPN_ReloadPlugin is not implemented yet."; +void NPN_ReloadPlugins(NPBool reload_pages) { + WebKit::resetPluginCache(reload_pages ? true : false); } // Requests a range of bytes for a seekable stream. @@ -318,8 +317,8 @@ NPError NPN_RequestRead(NPStream* stream, NPByteRange* range_list) { if (!stream || !range_list) return NPERR_GENERIC_ERROR; - scoped_refptr<NPAPI::PluginInstance> plugin = - reinterpret_cast<NPAPI::PluginInstance*>(stream->ndata); + scoped_refptr<NPAPI::PluginInstance> plugin( + reinterpret_cast<NPAPI::PluginInstance*>(stream->ndata)); if (!plugin.get()) return NPERR_GENERIC_ERROR; @@ -336,9 +335,8 @@ static NPError GetURLNotify(NPP id, if (!url) return NPERR_INVALID_URL; - scoped_refptr<NPAPI::PluginInstance> plugin = FindInstance(id); + scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); if (!plugin.get()) { - NOTREACHED(); return NPERR_GENERIC_ERROR; } @@ -401,7 +399,7 @@ static NPError PostURLNotify(NPP id, if (!url) return NPERR_INVALID_URL; - scoped_refptr<NPAPI::PluginInstance> plugin = FindInstance(id); + scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); if (!plugin.get()) { NOTREACHED(); return NPERR_GENERIC_ERROR; @@ -548,7 +546,7 @@ NPError NPN_DestroyStream(NPP id, NPStream* stream, NPReason reason) { // // - scoped_refptr<NPAPI::PluginInstance> plugin = FindInstance(id); + scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); if (plugin.get() == NULL) { NOTREACHED(); return NPERR_GENERIC_ERROR; @@ -610,8 +608,7 @@ void NPN_InvalidateRect(NPP id, NPRect *invalidRect) { // plug-ins at regularly timed intervals. To force a paint message, the // plug-in can call NPN_ForceRedraw after calling this method. - scoped_refptr<NPAPI::PluginInstance> plugin = FindInstance(id); - DCHECK(plugin.get() != NULL); + scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); if (plugin.get() && plugin->webplugin()) { if (invalidRect) { #if defined(OS_WIN) @@ -644,7 +641,7 @@ void NPN_InvalidateRegion(NPP id, NPRegion invalidRegion) { // TODO: this is overkill--add platform-specific region handling (at the // very least, fetch the region's bounding box and pass it to InvalidateRect). - scoped_refptr<NPAPI::PluginInstance> plugin = FindInstance(id); + scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); DCHECK(plugin.get() != NULL); if (plugin.get() && plugin->webplugin()) plugin->webplugin()->Invalidate(); @@ -673,7 +670,7 @@ NPError NPN_GetValue(NPP id, NPNVariable variable, void* value) { switch (static_cast<int>(variable)) { case NPNVWindowNPObject: { - scoped_refptr<NPAPI::PluginInstance> plugin = FindInstance(id); + scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); NPObject *np_object = plugin->webplugin()->GetWindowScriptNPObject(); // Return value is expected to be retained, as // described here: @@ -689,7 +686,7 @@ NPError NPN_GetValue(NPP id, NPNVariable variable, void* value) { break; } case NPNVPluginElementNPObject: { - scoped_refptr<NPAPI::PluginInstance> plugin = FindInstance(id); + scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); NPObject *np_object = plugin->webplugin()->GetPluginElement(); // Return value is expected to be retained, as // described here: @@ -743,7 +740,7 @@ NPError NPN_GetValue(NPP id, NPNVariable variable, void* value) { } case NPNVprivateModeBool: { NPBool* private_mode = reinterpret_cast<NPBool*>(value); - scoped_refptr<NPAPI::PluginInstance> plugin = FindInstance(id); + scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); *private_mode = plugin->webplugin()->IsOffTheRecord(); rv = NPERR_NO_ERROR; break; @@ -758,7 +755,7 @@ NPError NPN_GetValue(NPP id, NPNVariable variable, void* value) { // we still need to worry about future standard change that may conflict // with the variable definition, in order to avoid duplicate case clauses // in this big switch statement. - scoped_refptr<NPAPI::PluginInstance> plugin = FindInstance(id); + scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); if (plugin->plugin_lib()->plugin_info().path.value() == kDefaultPluginLibraryName) { plugin->webplugin()->OnMissingPluginStatus( @@ -769,7 +766,7 @@ NPError NPN_GetValue(NPP id, NPNVariable variable, void* value) { #if defined(OS_MACOSX) case NPNVpluginDrawingModel: { // return the drawing model that was negotiated when we initialized. - scoped_refptr<NPAPI::PluginInstance> plugin = FindInstance(id); + scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); *reinterpret_cast<int*>(value) = plugin->drawing_model(); rv = NPERR_NO_ERROR; break; @@ -838,7 +835,7 @@ NPError NPN_GetValue(NPP id, NPNVariable variable, void* value) { NPError NPN_SetValue(NPP id, NPPVariable variable, void* value) { // Allows the plugin to set various modes - scoped_refptr<NPAPI::PluginInstance> plugin = FindInstance(id); + scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); switch(variable) { case NPPVpluginWindowBool: { // Sets windowless mode for display of the plugin @@ -923,13 +920,13 @@ void* NPN_GetJavaPeer(NPP) { } void NPN_PushPopupsEnabledState(NPP id, NPBool enabled) { - scoped_refptr<NPAPI::PluginInstance> plugin = FindInstance(id); + scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); if (plugin) plugin->PushPopupsEnabledState(enabled ? true : false); } void NPN_PopPopupsEnabledState(NPP id) { - scoped_refptr<NPAPI::PluginInstance> plugin = FindInstance(id); + scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); if (plugin) plugin->PopPopupsEnabledState(); } @@ -937,7 +934,7 @@ void NPN_PopPopupsEnabledState(NPP id) { void NPN_PluginThreadAsyncCall(NPP id, void (*func)(void*), void* user_data) { - scoped_refptr<NPAPI::PluginInstance> plugin = FindInstance(id); + scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); if (plugin) plugin->PluginThreadAsyncCall(func, user_data); } @@ -965,7 +962,7 @@ NPError NPN_GetValueForURL(NPP id, break; } case NPNURLVCookie: { - scoped_refptr<NPAPI::PluginInstance> plugin = FindInstance(id); + scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); if (!plugin) return NPERR_GENERIC_ERROR; @@ -1005,7 +1002,7 @@ NPError NPN_SetValueForURL(NPP id, switch (variable) { case NPNURLVCookie: { - scoped_refptr<NPAPI::PluginInstance> plugin = FindInstance(id); + scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); if (!plugin) return NPERR_GENERIC_ERROR; @@ -1051,7 +1048,7 @@ uint32_t NPN_ScheduleTimer(NPP id, uint32_t interval, NPBool repeat, void (*func)(NPP id, uint32_t timer_id)) { - scoped_refptr<NPAPI::PluginInstance> plugin = FindInstance(id); + scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); if (!plugin) return 0; @@ -1059,7 +1056,7 @@ uint32_t NPN_ScheduleTimer(NPP id, } void NPN_UnscheduleTimer(NPP id, uint32_t timer_id) { - scoped_refptr<NPAPI::PluginInstance> plugin = FindInstance(id); + scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); if (plugin) plugin->UnscheduleTimer(timer_id); } @@ -1068,7 +1065,7 @@ NPError NPN_PopUpContextMenu(NPP id, NPMenu* menu) { if (!menu) return NPERR_INVALID_PARAM; - scoped_refptr<NPAPI::PluginInstance> plugin = FindInstance(id); + scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); if (plugin.get()) { return plugin->PopUpContextMenu(menu); } @@ -1080,7 +1077,7 @@ NPBool NPN_ConvertPoint(NPP id, double sourceX, double sourceY, NPCoordinateSpace sourceSpace, double *destX, double *destY, NPCoordinateSpace destSpace) { - scoped_refptr<NPAPI::PluginInstance> plugin = FindInstance(id); + scoped_refptr<NPAPI::PluginInstance> plugin(FindInstance(id)); if (plugin.get()) { return plugin->ConvertPoint(sourceX, sourceY, sourceSpace, destX, destY, destSpace); diff --git a/webkit/glue/plugins/plugin_instance.cc b/webkit/glue/plugins/plugin_instance.cc index f7b3bf7..b271e4d 100644 --- a/webkit/glue/plugins/plugin_instance.cc +++ b/webkit/glue/plugins/plugin_instance.cc @@ -91,7 +91,7 @@ PluginStreamUrl* PluginInstance::CreateStream(unsigned long resource_id, } void PluginInstance::AddStream(PluginStream* stream) { - open_streams_.push_back(stream); + open_streams_.push_back(make_scoped_refptr(stream)); } void PluginInstance::RemoveStream(PluginStream* stream) { @@ -178,6 +178,11 @@ void PluginInstance::DidFinishLoadWithReason( NPP_URLNotify(url.spec().c_str(), reason, notify_data); } +unsigned PluginInstance::GetBackingTextureId() { + // By default the plugin instance is not backed by an OpenGL texture. + return 0; +} + // NPAPI methods NPError PluginInstance::NPP_New(unsigned short mode, short argc, diff --git a/webkit/glue/plugins/plugin_instance.h b/webkit/glue/plugins/plugin_instance.h index 0dd3ee4..c853bfa 100644 --- a/webkit/glue/plugins/plugin_instance.h +++ b/webkit/glue/plugins/plugin_instance.h @@ -161,6 +161,10 @@ class PluginInstance : public base::RefCountedThreadSafe<PluginInstance> { bool use_mozilla_user_agent() { return use_mozilla_user_agent_; } void set_use_mozilla_user_agent() { use_mozilla_user_agent_ = true; } + // If the plugin instance is backed by a texture, return its ID in the + // compositor's namespace. Otherwise return 0. Returns 0 by default. + virtual unsigned GetBackingTextureId(); + // Helper that implements NPN_PluginThreadAsyncCall semantics void PluginThreadAsyncCall(void (*func)(void *), void *userData); diff --git a/webkit/glue/plugins/plugin_lib.cc b/webkit/glue/plugins/plugin_lib.cc index 6c95274..ee613c1 100644 --- a/webkit/glue/plugins/plugin_lib.cc +++ b/webkit/glue/plugins/plugin_lib.cc @@ -74,7 +74,7 @@ PluginLib::PluginLib(const WebPluginInfo& info, skip_unload_(false) { base::StatsCounter(kPluginLibrariesLoadedCounter).Increment(); memset(static_cast<void*>(&plugin_funcs_), 0, sizeof(plugin_funcs_)); - g_loaded_libs->push_back(this); + g_loaded_libs->push_back(make_scoped_refptr(this)); if (entry_points) { internal_ = true; diff --git a/webkit/glue/plugins/plugin_lib_unittest.cc b/webkit/glue/plugins/plugin_lib_unittest.cc index 5ac6bdc..45c4bb6 100644 --- a/webkit/glue/plugins/plugin_lib_unittest.cc +++ b/webkit/glue/plugins/plugin_lib_unittest.cc @@ -25,7 +25,7 @@ TEST(PluginLibLoading, UnloadAllPlugins) { PluginLibTest::CreatePluginLib(FilePath())); // Try with a single plugin lib. - scoped_refptr<PluginLibTest> plugin_lib1 = new PluginLibTest(); + scoped_refptr<PluginLibTest> plugin_lib1(new PluginLibTest()); NPAPI::PluginLib::UnloadAllPlugins(); // Need to create it again, it should have been destroyed above. @@ -34,7 +34,7 @@ TEST(PluginLibLoading, UnloadAllPlugins) { // Try with two plugin libs. plugin_lib1 = new PluginLibTest(); - scoped_refptr<PluginLibTest> plugin_lib2 = new PluginLibTest(); + scoped_refptr<PluginLibTest> plugin_lib2(new PluginLibTest()); NPAPI::PluginLib::UnloadAllPlugins(); // Need to create it again, it should have been destroyed above. diff --git a/webkit/glue/plugins/plugin_list_posix.cc b/webkit/glue/plugins/plugin_list_posix.cc index 72891d1..682381c 100644 --- a/webkit/glue/plugins/plugin_list_posix.cc +++ b/webkit/glue/plugins/plugin_list_posix.cc @@ -262,8 +262,7 @@ bool PluginList::ShouldLoadPlugin(const WebPluginInfo& info, // TODO(evanm): prefer the newest version of flash, etc. here? - LOG_IF(INFO, PluginList::DebugPluginLoading()) - << "Using " << info.path.value(); + VLOG_IF(1, PluginList::DebugPluginLoading()) << "Using " << info.path.value(); return true; } diff --git a/webkit/glue/plugins/plugin_web_event_converter_mac.mm b/webkit/glue/plugins/plugin_web_event_converter_mac.mm index 030ed06..12d5cc6 100644 --- a/webkit/glue/plugins/plugin_web_event_converter_mac.mm +++ b/webkit/glue/plugins/plugin_web_event_converter_mac.mm @@ -16,23 +16,14 @@ using WebKit::WebMouseWheelEvent; namespace { // Returns true if the caps lock flag should be set for the given event. -// TODO: Ideally the event itself would know about the caps lock key; see -// <http://crbug.com/38226>. This function is only a temporary workaround that -// guesses based on live state. bool CapsLockIsActive(const WebInputEvent& event) { - NSUInteger current_flags = [[NSApp currentEvent] modifierFlags]; - bool caps_lock_on = (current_flags & NSAlphaShiftKeyMask) ? true : false; - // If this a caps lock keypress, then the event stream state can be wrong. - // Luckily, the weird event stream for caps lock makes it easy to tell whether - // caps lock is being turned on or off. - if (event.type == WebInputEvent::KeyDown || - event.type == WebInputEvent::KeyUp) { - const WebKeyboardEvent* key_event = - static_cast<const WebKeyboardEvent*>(&event); - if (key_event->nativeKeyCode == 57) - caps_lock_on = (event.type == WebInputEvent::KeyDown); - } - return caps_lock_on; + // Only key events have accurate information for the caps lock flag; see + // <https://bugs.webkit.org/show_bug.cgi?id=46518>. + // For other types, use the live state. + if (WebInputEvent::isKeyboardEventType(event.type)) + return (event.modifiers & WebInputEvent::CapsLockOn) != 0; + else + return ([[NSApp currentEvent] modifierFlags] & NSAlphaShiftKeyMask) != 0; } } // namespace diff --git a/webkit/glue/plugins/ppb_private.h b/webkit/glue/plugins/ppb_private.h index 07b32ec..0f2c448 100644 --- a/webkit/glue/plugins/ppb_private.h +++ b/webkit/glue/plugins/ppb_private.h @@ -5,11 +5,11 @@ #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" +#include "ppapi/c/dev/ppb_font_dev.h" +#include "ppapi/c/pp_instance.h" +#include "ppapi/c/pp_module.h" +#include "ppapi/c/pp_resource.h" +#include "ppapi/c/pp_var.h" #define PPB_PRIVATE_INTERFACE "PPB_Private;1" @@ -126,6 +126,9 @@ struct PPB_Private { // Use UMA so we know average pdf page count. void (*HistogramPDFPageCount)(int count); + + // Notifies the browser that the given action has been performed. + void (*UserMetricsRecordAction)(PP_Var action); }; #endif // WEBKIT_GLUE_PLUGINS_PPB_PRIVATE_H_ diff --git a/webkit/glue/plugins/ppb_private2.h b/webkit/glue/plugins/ppb_private2.h index 0b0df98..acf7831 100644 --- a/webkit/glue/plugins/ppb_private2.h +++ b/webkit/glue/plugins/ppb_private2.h @@ -9,15 +9,15 @@ #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" +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/pp_instance.h" +#include "ppapi/c/pp_module.h" +#include "ppapi/c/pp_point.h" +#include "ppapi/c/pp_rect.h" +#include "ppapi/c/pp_resource.h" +#include "ppapi/c/pp_var.h" -#define PPB_PRIVATE2_INTERFACE "PPB_Private2;3" +#define PPB_PRIVATE2_INTERFACE "PPB_Private2;4" #ifdef _WIN32 typedef HANDLE PP_FileHandle; @@ -105,6 +105,13 @@ struct PPB_Private2 { // Frees the data allocated by GetModuleLocalDirContents. void (*FreeModuleLocalDirContents)(PP_Module module, PP_DirContents_Dev* contents); + + // Navigate to URL. May open a new tab if target is not "_self". Return true + // if success. This differs from javascript:window.open() in that it bypasses + // the popup blocker, even when this is not called from an event handler. + bool (*NavigateToURL)(PP_Instance instance, + const char* url, + const char* target); }; #endif // WEBKIT_GLUE_PLUGINS_PPB_PRIVATE2_H_ diff --git a/webkit/glue/plugins/ppp_private.h b/webkit/glue/plugins/ppp_private.h index 4bc3812..7f5921e 100644 --- a/webkit/glue/plugins/ppp_private.h +++ b/webkit/glue/plugins/ppp_private.h @@ -5,9 +5,9 @@ #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" +#include "ppapi/c/pp_instance.h" +#include "ppapi/c/pp_point.h" +#include "ppapi/c/pp_var.h" #define PPP_PRIVATE_INTERFACE "PPP_Private;1" diff --git a/webkit/glue/plugins/test/plugin_create_instance_in_paint.cc b/webkit/glue/plugins/test/plugin_create_instance_in_paint.cc index 0bea703..305e86f 100644 --- a/webkit/glue/plugins/test/plugin_create_instance_in_paint.cc +++ b/webkit/glue/plugins/test/plugin_create_instance_in_paint.cc @@ -46,6 +46,7 @@ NPError CreateInstanceInPaintTest::SetWindow(NPWindow* pNPWindow) { WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_VISIBLE , 0, 0, 100, 100, parent, 0, GetModuleHandle(NULL), 0); DCHECK(window_); + // TODO: this property leaks. ::SetProp(window_, L"Plugin_Instance", this); } } else if (test_id() == "2") { diff --git a/webkit/glue/plugins/test/plugin_get_javascript_url_test.cc b/webkit/glue/plugins/test/plugin_get_javascript_url_test.cc index cc6bc19..344cae3 100644 --- a/webkit/glue/plugins/test/plugin_get_javascript_url_test.cc +++ b/webkit/glue/plugins/test/plugin_get_javascript_url_test.cc @@ -45,6 +45,7 @@ NPError ExecuteGetJavascriptUrlTest::SetWindow(NPWindow* pNPWindow) { #ifdef OS_WIN HWND window_handle = reinterpret_cast<HWND>(pNPWindow->window); if (!::GetProp(window_handle, L"Plugin_Instance")) { + // TODO: this propery leaks. ::SetProp(window_handle, L"Plugin_Instance", this); // We attempt to retreive the NPObject for the plugin instance identified // by the NPObjectLifetimeTestInstance2 class as it may not have been diff --git a/webkit/glue/plugins/test/plugin_npobject_lifetime_test.cc b/webkit/glue/plugins/test/plugin_npobject_lifetime_test.cc index 10b3239..7277211 100644 --- a/webkit/glue/plugins/test/plugin_npobject_lifetime_test.cc +++ b/webkit/glue/plugins/test/plugin_npobject_lifetime_test.cc @@ -27,6 +27,7 @@ NPError NPObjectLifetimeTest::SetWindow(NPWindow* pNPWindow) { HWND window_handle = reinterpret_cast<HWND>(pNPWindow->window); if (!::GetProp(window_handle, L"Plugin_Instance")) { + // TODO: this propery leaks. ::SetProp(window_handle, L"Plugin_Instance", this); // We attempt to retreive the NPObject for the plugin instance identified // by the NPObjectLifetimeTestInstance2 class as it may not have been diff --git a/webkit/glue/plugins/test/plugin_setup_test.cc b/webkit/glue/plugins/test/plugin_setup_test.cc new file mode 100644 index 0000000..e4c4903 --- /dev/null +++ b/webkit/glue/plugins/test/plugin_setup_test.cc @@ -0,0 +1,22 @@ +// 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 "base/basictypes.h" +#include "base/string_util.h" + +#include "webkit/glue/plugins/test/plugin_setup_test.h" + +namespace NPAPIClient { + +PluginSetupTest::PluginSetupTest(NPP id, NPNetscapeFuncs *host_functions) + : PluginTest(id, host_functions) { +} + +NPError PluginSetupTest::SetWindow(NPWindow* pNPWindow) { + this->SignalTestCompleted(); + + return NPERR_NO_ERROR; +} + +} // namespace NPAPIClient diff --git a/webkit/glue/plugins/test/plugin_setup_test.h b/webkit/glue/plugins/test/plugin_setup_test.h new file mode 100644 index 0000000..b01bc42 --- /dev/null +++ b/webkit/glue/plugins/test/plugin_setup_test.h @@ -0,0 +1,24 @@ +// 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_TEST_PLUGIN_SETUP_TEST_H__ +#define WEBKIT_GLUE_PLUGINS_TEST_PLUGIN_SETUP_TEST_H__ + +#include "webkit/glue/plugins/test/plugin_test.h" + +namespace NPAPIClient { + +// A very simple test that just sets up a new plug-in. +class PluginSetupTest : public PluginTest { + public: + // Constructor. + PluginSetupTest(NPP id, NPNetscapeFuncs *host_functions); + + // NPAPI SetWindow handler. + virtual NPError SetWindow(NPWindow* pNPWindow); +}; + +} // namespace NPAPIClient + +#endif // WEBKIT_GLUE_PLUGINS_TEST_PLUGIN_SETUP_TEST_H__ diff --git a/webkit/glue/plugins/test/plugin_test_factory.cc b/webkit/glue/plugins/test/plugin_test_factory.cc index 62a3977..ea9b290 100644 --- a/webkit/glue/plugins/test/plugin_test_factory.cc +++ b/webkit/glue/plugins/test/plugin_test_factory.cc @@ -15,6 +15,7 @@ #include "webkit/glue/plugins/test/plugin_npobject_proxy_test.h" #include "webkit/glue/plugins/test/plugin_private_test.h" #include "webkit/glue/plugins/test/plugin_schedule_timer_test.h" +#include "webkit/glue/plugins/test/plugin_setup_test.h" #include "webkit/glue/plugins/test/plugin_thread_async_call_test.h" #include "webkit/glue/plugins/test/plugin_window_size_test.h" #if defined(OS_WIN) @@ -91,6 +92,9 @@ PluginTest* CreatePluginTest(const std::string& test_name, test_name == "invoke_js_function_on_create") { new_test = new WindowedPluginTest(instance, host_functions); #endif + } else if (test_name == "setup") { + // "plugin" is the name for plugin documents. + new_test = new PluginSetupTest(instance, host_functions); } return new_test; diff --git a/webkit/glue/plugins/test/plugin_windowed_test.cc b/webkit/glue/plugins/test/plugin_windowed_test.cc index 461fc20..0c46d68 100644 --- a/webkit/glue/plugins/test/plugin_windowed_test.cc +++ b/webkit/glue/plugins/test/plugin_windowed_test.cc @@ -62,6 +62,7 @@ NPError WindowedPluginTest::SetWindow(NPWindow* pNPWindow) { WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_VISIBLE , 0, 0, 100, 100, parent, 0, GetModuleHandle(NULL), 0); DCHECK(window_); + // TODO: this propery leaks. ::SetProp(window_, L"Plugin_Instance", this); } diff --git a/webkit/glue/plugins/webplugin_delegate_impl.cc b/webkit/glue/plugins/webplugin_delegate_impl.cc index c54bbc8..6907c6f 100644 --- a/webkit/glue/plugins/webplugin_delegate_impl.cc +++ b/webkit/glue/plugins/webplugin_delegate_impl.cc @@ -32,8 +32,8 @@ WebPluginDelegateImpl* WebPluginDelegateImpl::Create( const FilePath& filename, const std::string& mime_type, gfx::PluginWindowHandle containing_view) { - scoped_refptr<NPAPI::PluginLib> plugin_lib = - NPAPI::PluginLib::CreatePluginLib(filename); + scoped_refptr<NPAPI::PluginLib> plugin_lib( + NPAPI::PluginLib::CreatePluginLib(filename)); if (plugin_lib.get() == NULL) return NULL; @@ -41,8 +41,8 @@ WebPluginDelegateImpl* WebPluginDelegateImpl::Create( if (err != NPERR_NO_ERROR) return NULL; - scoped_refptr<NPAPI::PluginInstance> instance = - plugin_lib->CreateInstance(mime_type); + scoped_refptr<NPAPI::PluginInstance> instance( + plugin_lib->CreateInstance(mime_type)); return new WebPluginDelegateImpl(containing_view, instance.get()); } diff --git a/webkit/glue/plugins/webplugin_impl.cc b/webkit/glue/plugins/webplugin_impl.cc index 704145b..80774ff 100644 --- a/webkit/glue/plugins/webplugin_impl.cc +++ b/webkit/glue/plugins/webplugin_impl.cc @@ -36,12 +36,14 @@ #include "third_party/WebKit/WebKit/chromium/public/WebURLLoaderClient.h" #include "third_party/WebKit/WebKit/chromium/public/WebURLResponse.h" #include "third_party/WebKit/WebKit/chromium/public/WebView.h" +#include "webkit/appcache/web_application_cache_host_impl.h" #include "webkit/glue/multipart_response_delegate.h" #include "webkit/glue/plugins/plugin_host.h" #include "webkit/glue/plugins/plugin_instance.h" #include "webkit/glue/plugins/webplugin_delegate.h" #include "webkit/glue/plugins/webplugin_page_delegate.h" +using appcache::WebApplicationCacheHostImpl; using WebKit::WebCanvas; using WebKit::WebConsoleMessage; using WebKit::WebCookieJar; @@ -325,6 +327,11 @@ void WebPluginImpl::updateGeometry( first_geometry_update_ = false; } +unsigned WebPluginImpl::getBackingTextureId() { + // Regular plugins do not have a backing texture. + return 0; +} + void WebPluginImpl::updateFocus(bool focused) { if (accepts_input_events_) delegate_->SetFocus(focused); @@ -1115,6 +1122,13 @@ bool WebPluginImpl::InitiateHTTPRequest(unsigned long resource_id, // Sets the routing id to associate the ResourceRequest with the RenderView. webframe_->dispatchWillSendRequest(info.request); + + // Sets the appcache host id to allow retrieval from the appcache. + if (WebApplicationCacheHostImpl* appcache_host = + WebApplicationCacheHostImpl::FromFrame(webframe_)) { + appcache_host->willStartSubResourceRequest(info.request); + } + if (WebDevToolsAgent* devtools_agent = GetDevToolsAgent()) { devtools_agent->identifierForInitialRequest(resource_id, webframe_, info.request); diff --git a/webkit/glue/plugins/webplugin_impl.h b/webkit/glue/plugins/webplugin_impl.h index cb0970b..58289d6 100644 --- a/webkit/glue/plugins/webplugin_impl.h +++ b/webkit/glue/plugins/webplugin_impl.h @@ -73,6 +73,7 @@ class WebPluginImpl : public WebPlugin, virtual void updateGeometry( const WebKit::WebRect& frame_rect, const WebKit::WebRect& clip_rect, const WebKit::WebVector<WebKit::WebRect>& cut_outs, bool is_visible); + virtual unsigned getBackingTextureId(); virtual void updateFocus(bool focused); virtual void updateVisibility(bool visible); virtual bool acceptsInputEvents(); diff --git a/webkit/glue/resource_loader_bridge.h b/webkit/glue/resource_loader_bridge.h index 2634383..52447b4 100644 --- a/webkit/glue/resource_loader_bridge.h +++ b/webkit/glue/resource_loader_bridge.h @@ -306,10 +306,6 @@ class ResourceLoaderBridge { virtual void OnCompletedRequest(const URLRequestStatus& status, const std::string& security_info, const base::Time& completion_time) = 0; - - // Returns the URL of the request, which allows us to display it in - // debugging situations. - virtual GURL GetURLForDebugging() const = 0; }; // use Create() for construction, but anybody can delete at any time, diff --git a/webkit/glue/site_isolation_metrics.cc b/webkit/glue/site_isolation_metrics.cc index 58d8717..ecc1464 100644 --- a/webkit/glue/site_isolation_metrics.cc +++ b/webkit/glue/site_isolation_metrics.cc @@ -135,7 +135,7 @@ void SiteIsolationMetrics::LogMimeTypeForCrossOriginRequest( // Now focus on non-frame, non-plugin requests. if (target_type != WebURLRequest::TargetIsMainFrame && - target_type != WebURLRequest::TargetIsSubFrame && + target_type != WebURLRequest::TargetIsSubframe && target_type != WebURLRequest::TargetIsObject) { // If it is part of a MIME type we might block, log the MIME type. std::string mime_type = response.mimeType().utf8(); diff --git a/webkit/glue/webaccessibility.cc b/webkit/glue/webaccessibility.cc index 70827c1..0888a62 100644 --- a/webkit/glue/webaccessibility.cc +++ b/webkit/glue/webaccessibility.cc @@ -19,6 +19,7 @@ #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/WebSize.h" #include "third_party/WebKit/WebKit/chromium/public/WebString.h" using WebKit::WebAccessibilityCache; @@ -296,15 +297,17 @@ WebAccessibility::WebAccessibility() } WebAccessibility::WebAccessibility(const WebKit::WebAccessibilityObject& src, - WebKit::WebAccessibilityCache* cache) { - Init(src, cache); + WebKit::WebAccessibilityCache* cache, + bool include_children) { + Init(src, cache, include_children); } WebAccessibility::~WebAccessibility() { } void WebAccessibility::Init(const WebKit::WebAccessibilityObject& src, - WebKit::WebAccessibilityCache* cache) { + WebKit::WebAccessibilityCache* cache, + bool include_children) { name = src.title(); value = src.stringValue(); role = ConvertRole(src.roleValue()); @@ -366,22 +369,28 @@ void WebAccessibility::Init(const WebKit::WebAccessibilityObject& src, const WebKit::WebDocumentType& doctype = document.doctype(); if (!doctype.isNull()) attributes[ATTR_DOC_DOCTYPE] = doctype.name(); + + const gfx::Size& scroll_offset = document.frame()->scrollOffset(); + attributes[ATTR_DOC_SCROLLX] = base::IntToString16(scroll_offset.width()); + attributes[ATTR_DOC_SCROLLY] = base::IntToString16(scroll_offset.height()); } // Add the source object to the cache and store its id. id = cache->addOrGetId(src); - // Recursively create children. - int child_count = src.childCount(); - for (int i = 0; i < child_count; i++) { - WebAccessibilityObject child = src.childAt(i); - - // The child may be invalid due to issues in webkit accessibility code. - // Don't add children are invalid thus preventing a crash. - // https://bugs.webkit.org/show_bug.cgi?id=44149 - // TODO(ctguil): We may want to remove this check as webkit stabilizes. - if (child.isValid()) - children.push_back(WebAccessibility(child, cache)); + if (include_children) { + // Recursively create children. + int child_count = src.childCount(); + for (int i = 0; i < child_count; i++) { + WebAccessibilityObject child = src.childAt(i); + + // The child may be invalid due to issues in webkit accessibility code. + // Don't add children are invalid thus preventing a crash. + // https://bugs.webkit.org/show_bug.cgi?id=44149 + // TODO(ctguil): We may want to remove this check as webkit stabilizes. + if (child.isValid()) + children.push_back(WebAccessibility(child, cache, include_children)); + } } } diff --git a/webkit/glue/webaccessibility.h b/webkit/glue/webaccessibility.h index cc92939..a8e4b11 100644 --- a/webkit/glue/webaccessibility.h +++ b/webkit/glue/webaccessibility.h @@ -162,6 +162,8 @@ struct WebAccessibility { ATTR_DOC_TITLE, ATTR_DOC_MIMETYPE, ATTR_DOC_DOCTYPE, + ATTR_DOC_SCROLLX, + ATTR_DOC_SCROLLY, // Editable text attributes ATTR_TEXT_SEL_START, @@ -185,14 +187,18 @@ struct WebAccessibility { // nodes as needed to complete the tree. Adds |src| to |cache| and // stores its cache ID. WebAccessibility(const WebKit::WebAccessibilityObject& src, - WebKit::WebAccessibilityCache* cache); + WebKit::WebAccessibilityCache* cache, + bool include_children); ~WebAccessibility(); + private: // Initialize an already-created struct, same as the constructor a void Init(const WebKit::WebAccessibilityObject& src, - WebKit::WebAccessibilityCache* cache); + WebKit::WebAccessibilityCache* cache, + bool include_children); + public: // This is a simple serializable struct. All member variables should be // copyable. int32 id; diff --git a/webkit/glue/webfileutilities_impl.cc b/webkit/glue/webfileutilities_impl.cc index a77184d..6cea225 100644 --- a/webkit/glue/webfileutilities_impl.cc +++ b/webkit/glue/webfileutilities_impl.cc @@ -24,6 +24,10 @@ WebFileUtilitiesImpl::WebFileUtilitiesImpl() WebFileUtilitiesImpl::~WebFileUtilitiesImpl() { } +void WebFileUtilitiesImpl::revealFolderInOS(const WebString& path) { + NOTREACHED(); +} + bool WebFileUtilitiesImpl::fileExists(const WebString& path) { FilePath::StringType file_path = WebStringToFilePathString(path); return file_util::PathExists(FilePath(file_path)); diff --git a/webkit/glue/webfileutilities_impl.h b/webkit/glue/webfileutilities_impl.h index 5867396..c1ef986 100644 --- a/webkit/glue/webfileutilities_impl.h +++ b/webkit/glue/webfileutilities_impl.h @@ -16,6 +16,7 @@ class WebFileUtilitiesImpl : public WebKit::WebFileUtilities { virtual ~WebFileUtilitiesImpl(); // WebFileUtilities methods: + virtual void revealFolderInOS(const WebKit::WebString& path); virtual bool fileExists(const WebKit::WebString& path); virtual bool deleteFile(const WebKit::WebString& path); virtual bool deleteEmptyDirectory(const WebKit::WebString& path); diff --git a/webkit/glue/webkit_glue.cc b/webkit/glue/webkit_glue.cc index a58ff1b..c7a7d10 100644 --- a/webkit/glue/webkit_glue.cc +++ b/webkit/glue/webkit_glue.cc @@ -422,14 +422,4 @@ int GetGlyphPageCount() { return WebGlyphCache::pageCount(); } -bool g_enable_media_cache = false; - -bool IsMediaCacheEnabled() { - return g_enable_media_cache; -} - -void SetMediaCacheEnabled(bool enabled) { - g_enable_media_cache = enabled; -} - } // namespace webkit_glue diff --git a/webkit/glue/webkit_glue.gypi b/webkit/glue/webkit_glue.gypi index 8249fb5..99fb8b8 100644 --- a/webkit/glue/webkit_glue.gypi +++ b/webkit/glue/webkit_glue.gypi @@ -152,7 +152,7 @@ '<(DEPTH)/third_party/icu/icu.gyp:icui18n', '<(DEPTH)/third_party/icu/icu.gyp:icuuc', '<(DEPTH)/third_party/npapi/npapi.gyp:npapi', - '<(DEPTH)/third_party/ppapi/ppapi.gyp:ppapi_c', + '<(DEPTH)/ppapi/ppapi.gyp:ppapi_c', 'webkit_resources', 'webkit_strings', 'webkit_user_agent', @@ -175,6 +175,8 @@ 'media/simple_data_source.h', 'media/video_renderer_impl.cc', 'media/video_renderer_impl.h', + 'media/web_data_source.cc', + 'media/web_data_source.h', 'media/web_video_renderer.h', 'plugins/carbon_plugin_window_tracker_mac.h', 'plugins/carbon_plugin_window_tracker_mac.cc', @@ -193,6 +195,7 @@ 'plugins/pepper_buffer.h', 'plugins/pepper_char_set.cc', 'plugins/pepper_char_set.h', + 'plugins/pepper_class.h', 'plugins/pepper_cursor_control.cc', 'plugins/pepper_cursor_control.h', 'plugins/pepper_directory_reader.cc', diff --git a/webkit/glue/webkit_glue.h b/webkit/glue/webkit_glue.h index 380bf36..6cc55b2 100644 --- a/webkit/glue/webkit_glue.h +++ b/webkit/glue/webkit_glue.h @@ -1,4 +1,4 @@ -// Copyright (c) 2006-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. @@ -146,11 +146,6 @@ WebKit::WebCanvas* ToWebCanvas(skia::PlatformCanvas*); // used to get memory usage statistics. int GetGlyphPageCount(); -// Methods to query and enable media cache. -// TODO(hclam): Remove these methods when the cache is stable enough. -bool IsMediaCacheEnabled(); -void SetMediaCacheEnabled(bool enabled); - //---- END FUNCTIONS IMPLEMENTED BY WEBKIT/GLUE ------------------------------- @@ -274,6 +269,9 @@ bool IsSingleProcess(); // Enables/Disables Spdy for requests afterwards. Used for benchmarking. void EnableSpdy(bool enable); +// Notifies the browser that the given action has been performed. +void UserMetricsRecordAction(const std::string& action); + #if defined(OS_LINUX) // Return a read-only file descriptor to the font which best matches the given // properties or -1 on failure. diff --git a/webkit/glue/webkitclient_impl.cc b/webkit/glue/webkitclient_impl.cc index 648f3bd..0c5766a 100644 --- a/webkit/glue/webkitclient_impl.cc +++ b/webkit/glue/webkitclient_impl.cc @@ -12,6 +12,7 @@ #include <vector> +#include "base/debug/trace_event.h" #include "base/lock.h" #include "base/message_loop.h" #include "base/metrics/stats_counters.h" @@ -22,7 +23,6 @@ #include "base/string_util.h" #include "base/time.h" #include "base/utf_string_conversions.h" -#include "base/trace_event.h" #include "grit/webkit_resources.h" #include "grit/webkit_strings.h" #include "third_party/WebKit/WebKit/chromium/public/WebCookie.h" @@ -156,6 +156,10 @@ static int ToMessageID(WebLocalizedString::Name name) { return IDS_KEYGEN_HIGH_GRADE_KEY; case WebLocalizedString::KeygenMenuMediumGradeKeySize: return IDS_KEYGEN_MED_GRADE_KEY; + // TODO(tkent): Remove default: when we merge the next + // WebLocalizedString.h change. + default: + break; } return -1; } diff --git a/webkit/glue/webmediaplayer_impl.cc b/webkit/glue/webmediaplayer_impl.cc index e4aca5a..919cf2e 100644 --- a/webkit/glue/webmediaplayer_impl.cc +++ b/webkit/glue/webmediaplayer_impl.cc @@ -21,6 +21,9 @@ #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/WebVideoFrame.h" +#include "webkit/glue/media/buffered_data_source.h" +#include "webkit/glue/media/media_resource_loader_bridge_factory.h" +#include "webkit/glue/media/simple_data_source.h" #include "webkit/glue/media/video_renderer_impl.h" #include "webkit/glue/media/web_video_renderer.h" #include "webkit/glue/webvideoframe_impl.h" @@ -86,10 +89,15 @@ void WebMediaPlayerImpl::Proxy::Repaint() { } void WebMediaPlayerImpl::Proxy::SetVideoRenderer( - WebVideoRenderer* video_renderer) { + scoped_refptr<WebVideoRenderer> video_renderer) { video_renderer_ = video_renderer; } +void WebMediaPlayerImpl::Proxy::SetDataSource( + scoped_refptr<WebDataSource> data_source) { + data_source_ = data_source; +} + void WebMediaPlayerImpl::Proxy::Paint(skia::PlatformCanvas* canvas, const gfx::Rect& dest_rect) { DCHECK(MessageLoop::current() == render_loop_); @@ -105,10 +113,26 @@ void WebMediaPlayerImpl::Proxy::SetSize(const gfx::Rect& rect) { } } +bool WebMediaPlayerImpl::Proxy::HasSingleOrigin() { + DCHECK(MessageLoop::current() == render_loop_); + if (data_source_) { + return data_source_->HasSingleOrigin(); + } + return true; +} + +void WebMediaPlayerImpl::Proxy::AbortDataSource() { + DCHECK(MessageLoop::current() == render_loop_); + if (data_source_) { + data_source_->Abort(); + } +} + void WebMediaPlayerImpl::Proxy::Detach() { DCHECK(MessageLoop::current() == render_loop_); webmediaplayer_ = NULL; video_renderer_ = NULL; + data_source_ = NULL; } void WebMediaPlayerImpl::Proxy::PipelineInitializationCallback() { @@ -198,14 +222,17 @@ void WebMediaPlayerImpl::Proxy::PutCurrentFrame( ///////////////////////////////////////////////////////////////////////////// // WebMediaPlayerImpl implementation -WebMediaPlayerImpl::WebMediaPlayerImpl(WebKit::WebMediaPlayerClient* client, - media::FilterFactoryCollection* factory, - WebVideoRendererFactoryFactory* - video_renderer_factory) +WebMediaPlayerImpl::WebMediaPlayerImpl( + WebKit::WebMediaPlayerClient* client, + media::MediaFilterCollection* collection, + MediaResourceLoaderBridgeFactory* bridge_factory_simple, + MediaResourceLoaderBridgeFactory* bridge_factory_buffered, + bool use_simple_data_source, + scoped_refptr<WebVideoRenderer> web_video_renderer) : network_state_(WebKit::WebMediaPlayer::Empty), ready_state_(WebKit::WebMediaPlayer::HaveNothing), main_loop_(NULL), - filter_factory_(factory), + filter_collection_(collection), pipeline_thread_("PipelineThread"), paused_(true), playback_rate_(0.0f), @@ -215,10 +242,6 @@ WebMediaPlayerImpl::WebMediaPlayerImpl(WebKit::WebMediaPlayerClient* client, DCHECK(!main_loop_); main_loop_ = MessageLoop::current(); - // Make sure this gets deleted. - scoped_ptr<WebVideoRendererFactoryFactory> - scoped_video_renderer_factory(video_renderer_factory); - // Create the pipeline and its thread. if (!pipeline_thread_.Start()) { NOTREACHED() << "Could not start PipelineThread"; @@ -232,6 +255,8 @@ WebMediaPlayerImpl::WebMediaPlayerImpl(WebKit::WebMediaPlayerClient* client, // Creates the proxy. proxy_ = new Proxy(main_loop_, this); + web_video_renderer->SetWebMediaPlayerImplProxy(proxy_); + proxy_->SetVideoRenderer(web_video_renderer); // Set our pipeline callbacks. pipeline_->SetPipelineEndedCallback(NewCallback(proxy_.get(), @@ -241,12 +266,28 @@ WebMediaPlayerImpl::WebMediaPlayerImpl(WebKit::WebMediaPlayerClient* client, pipeline_->SetNetworkEventCallback(NewCallback(proxy_.get(), &WebMediaPlayerImpl::Proxy::NetworkEventCallback)); + // A simple data source that keeps all data in memory. + scoped_refptr<SimpleDataSource> simple_data_source( + new SimpleDataSource(MessageLoop::current(), bridge_factory_simple)); + + // A sophisticated data source that does memory caching. + scoped_refptr<BufferedDataSource> buffered_data_source( + new BufferedDataSource(MessageLoop::current(), bridge_factory_buffered)); + proxy_->SetDataSource(buffered_data_source); + + if (use_simple_data_source) { + filter_collection_->AddFilter(simple_data_source); + filter_collection_->AddFilter(buffered_data_source); + } else { + filter_collection_->AddFilter(buffered_data_source); + filter_collection_->AddFilter(simple_data_source); + } + // Add in the default filter factories. - filter_factory_->AddFactory(media::FFmpegDemuxer::CreateFilterFactory()); - filter_factory_->AddFactory(media::FFmpegAudioDecoder::CreateFactory()); - filter_factory_->AddFactory(media::FFmpegVideoDecoder::CreateFactory(NULL)); - filter_factory_->AddFactory(media::NullAudioRenderer::CreateFilterFactory()); - filter_factory_->AddFactory(video_renderer_factory->CreateFactory(proxy_)); + filter_collection_->AddFilter(new media::FFmpegDemuxer()); + filter_collection_->AddFilter(new media::FFmpegAudioDecoder()); + filter_collection_->AddFilter(new media::FFmpegVideoDecoder(NULL)); + filter_collection_->AddFilter(new media::NullAudioRenderer()); } WebMediaPlayerImpl::~WebMediaPlayerImpl() { @@ -270,7 +311,7 @@ void WebMediaPlayerImpl::load(const WebKit::WebURL& url) { SetNetworkState(WebKit::WebMediaPlayer::Loading); SetReadyState(WebKit::WebMediaPlayer::HaveNothing); pipeline_->Start( - filter_factory_.get(), + filter_collection_.release(), url.spec(), NewCallback(proxy_.get(), &WebMediaPlayerImpl::Proxy::PipelineInitializationCallback)); @@ -564,9 +605,8 @@ void WebMediaPlayerImpl::paint(WebCanvas* canvas, } bool WebMediaPlayerImpl::hasSingleSecurityOrigin() const { - // TODO(scherkus): we'll need to do something smarter here if/when we start to - // support formats that contain references to external resources (i.e., MP4s - // containing links to other MP4s). See http://crbug.com/25432 + if (proxy_) + return proxy_->HasSingleOrigin(); return true; } @@ -593,8 +633,8 @@ WebKit::WebVideoFrame* WebMediaPlayerImpl::getCurrentFrame() { void WebMediaPlayerImpl::putCurrentFrame( WebKit::WebVideoFrame* web_video_frame) { if (web_video_frame) { - scoped_refptr<media::VideoFrame> video_frame = - WebVideoFrameImpl::toVideoFrame(web_video_frame); + scoped_refptr<media::VideoFrame> video_frame( + WebVideoFrameImpl::toVideoFrame(web_video_frame)); proxy_->PutCurrentFrame(video_frame); delete web_video_frame; } @@ -727,6 +767,11 @@ void WebMediaPlayerImpl::SetReadyState( void WebMediaPlayerImpl::Destroy() { DCHECK(MessageLoop::current() == main_loop_); + // Tell the data source to abort any pending reads so that the pipeline is + // not blocked when issuing stop commands to the other filters. + if (proxy_) + proxy_->AbortDataSource(); + // Make sure to kill the pipeline so there's no more media threads running. // Note: stopping the pipeline might block for a long time. pipeline_->Stop(NewCallback(this, diff --git a/webkit/glue/webmediaplayer_impl.h b/webkit/glue/webmediaplayer_impl.h index eefe1a9..23f4148 100644 --- a/webkit/glue/webmediaplayer_impl.h +++ b/webkit/glue/webmediaplayer_impl.h @@ -68,14 +68,11 @@ class GURL; -namespace media { -class FilterFactoryCollection; -} - namespace webkit_glue { +class MediaResourceLoaderBridgeFactory; +class WebDataSource; class WebVideoRenderer; -class WebVideoRendererFactoryFactory; class WebMediaPlayerImpl : public WebKit::WebMediaPlayer, public MessageLoop::DestructionObserver { @@ -93,19 +90,21 @@ class WebMediaPlayerImpl : public WebKit::WebMediaPlayer, Proxy(MessageLoop* render_loop, WebMediaPlayerImpl* webmediaplayer); - // Public methods called from the video renderer. + // Methods for MediaFilter -> WebMediaPlayerImpl communication. void Repaint(); - void SetVideoRenderer(WebVideoRenderer* video_renderer); + void SetVideoRenderer(scoped_refptr<WebVideoRenderer> video_renderer); + void SetDataSource(scoped_refptr<WebDataSource> data_source); - // Public methods called from WebMediaPlayerImpl. + // Methods for WebMediaPlayerImpl -> MediaFilter communication. void Paint(skia::PlatformCanvas* canvas, const gfx::Rect& dest_rect); void SetSize(const gfx::Rect& rect); void Detach(); void GetCurrentFrame(scoped_refptr<media::VideoFrame>* frame_out); void PutCurrentFrame(scoped_refptr<media::VideoFrame> frame); + bool HasSingleOrigin(); + void AbortDataSource(); - // Public methods called from the pipeline via callback issued by - // WebMediaPlayerImpl. + // Methods for PipelineImpl -> WebMediaPlayerImpl communication. void PipelineInitializationCallback(); void PipelineSeekCallback(); void PipelineEndedCallback(); @@ -141,6 +140,7 @@ class WebMediaPlayerImpl : public WebKit::WebMediaPlayer, // The render message loop where WebKit lives. MessageLoop* render_loop_; WebMediaPlayerImpl* webmediaplayer_; + scoped_refptr<WebDataSource> data_source_; scoped_refptr<WebVideoRenderer> video_renderer_; Lock lock_; @@ -148,9 +148,9 @@ class WebMediaPlayerImpl : public WebKit::WebMediaPlayer, }; // Construct a WebMediaPlayerImpl with reference to the client, and media - // filter factory collection. By providing the filter factory collection - // the implementor can provide more specific media filters that does resource - // loading and rendering. |factory| should contain filter factories for: + // filter collection. By providing the filter collection the implementor can + // provide more specific media filters that does resource loading and + // rendering. |collection| should contain filter factories for: // 1. Data source // 2. Audio renderer // 3. Video renderer (optional) @@ -165,14 +165,15 @@ class WebMediaPlayerImpl : public WebKit::WebMediaPlayer, // provided by WebKit to perform renderering. The simple data source does // resource loading by loading the whole resource object into memory. Null // audio renderer is a fake audio device that plays silence. Provider of the - // |factory| can override the default filters by adding extra filters to - // |factory| before calling this method. + // |collection| can override the default filters by adding extra filters to + // |collection| before calling this method. // - // |video_renderer_factory| is used to construct a factory that should create - // a subclass of WebVideoRenderer. Is deleted by WebMediaPlayerImpl. WebMediaPlayerImpl(WebKit::WebMediaPlayerClient* client, - media::FilterFactoryCollection* factory, - WebVideoRendererFactoryFactory* video_renderer_factory); + media::MediaFilterCollection* collection, + MediaResourceLoaderBridgeFactory* bridge_factory_simple, + MediaResourceLoaderBridgeFactory* bridge_factory_buffered, + bool use_simple_data_source, + scoped_refptr<WebVideoRenderer> web_video_renderer); virtual ~WebMediaPlayerImpl(); virtual void load(const WebKit::WebURL& url); @@ -278,8 +279,8 @@ class WebMediaPlayerImpl : public WebKit::WebMediaPlayer, // for DCHECKs so methods calls won't execute in the wrong thread. MessageLoop* main_loop_; - // A collection of factories for creating filters. - scoped_refptr<media::FilterFactoryCollection> filter_factory_; + // A collection of filters. + scoped_ptr<media::MediaFilterCollection> filter_collection_; // The actual pipeline and the thread it runs on. scoped_refptr<media::PipelineImpl> pipeline_; @@ -315,29 +316,6 @@ class WebMediaPlayerImpl : public WebKit::WebMediaPlayer, DISALLOW_COPY_AND_ASSIGN(WebMediaPlayerImpl); }; -// TODO(scherkus): WebMediaPlayerImpl creates and injects its Proxy into a -// video renderer factory, so we need to (unfortunately) have a factory of a -// factory so we can receive the proxy pointer without violating the -// separation of renderer code from webkit glue code. This is part of a -// longer-term plan to rethink our FilterFactory strategy (refer to -// http://crbug.com/28207). -// -// Either that or we rethink this Proxy business as a short-term solution. -class WebVideoRendererFactoryFactory { - public: - WebVideoRendererFactoryFactory() {} - virtual ~WebVideoRendererFactoryFactory() {} - - // Creates a FilterFactory which should be capable of creating a - // WebVideoRenderer subclass. - virtual media::FilterFactory* CreateFactory( - WebMediaPlayerImpl::Proxy* proxy) = 0; - - private: - DISALLOW_COPY_AND_ASSIGN(WebVideoRendererFactoryFactory); -}; - - } // namespace webkit_glue #endif // WEBKIT_GLUE_WEBMEDIAPLAYER_IMPL_H_ diff --git a/webkit/glue/weburlloader_impl.cc b/webkit/glue/weburlloader_impl.cc index 374f132..9f7c325 100644 --- a/webkit/glue/weburlloader_impl.cc +++ b/webkit/glue/weburlloader_impl.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2006-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. @@ -293,7 +293,6 @@ class WebURLLoaderImpl::Context : public base::RefCounted<Context>, const URLRequestStatus& status, const std::string& security_info, const base::Time& completion_time); - virtual GURL GetURLForDebugging() const; private: friend class base::RefCounted<Context>; @@ -563,7 +562,8 @@ void WebURLLoaderImpl::Context::OnReceivedResponse( std::string content_type; info.headers->EnumerateHeader(NULL, "content-type", &content_type); - std::string boundary = net::GetHeaderParamValue(content_type, "boundary"); + std::string boundary = net::GetHeaderParamValue( + content_type, "boundary", net::QuoteRule::REMOVE_OUTER_QUOTES); TrimString(boundary, " \"", &boundary); // If there's no boundary, just handle the request normally. In the gecko @@ -658,10 +658,6 @@ void WebURLLoaderImpl::Context::OnCompletedRequest( Release(); } -GURL WebURLLoaderImpl::Context::GetURLForDebugging() const { - return request_.url(); -} - void WebURLLoaderImpl::Context::HandleDataURL() { ResourceResponseInfo info; URLRequestStatus status; |