diff options
author | Jocelyn Turcotte <jocelyn.turcotte@digia.com> | 2014-08-08 14:30:41 +0200 |
---|---|---|
committer | Jocelyn Turcotte <jocelyn.turcotte@digia.com> | 2014-08-12 13:49:54 +0200 |
commit | ab0a50979b9eb4dfa3320eff7e187e41efedf7a9 (patch) | |
tree | 498dfb8a97ff3361a9f7486863a52bb4e26bb898 /chromium/content/renderer/pepper | |
parent | 4ce69f7403811819800e7c5ae1318b2647e778d1 (diff) |
Update Chromium to beta version 37.0.2062.68
Change-Id: I188e3b5aff1bec75566014291b654eb19f5bc8ca
Reviewed-by: Andras Becsi <andras.becsi@digia.com>
Diffstat (limited to 'chromium/content/renderer/pepper')
134 files changed, 7047 insertions, 4251 deletions
diff --git a/chromium/content/renderer/pepper/DEPS b/chromium/content/renderer/pepper/DEPS index 0b8e33db085..677f3096b40 100644 --- a/chromium/content/renderer/pepper/DEPS +++ b/chromium/content/renderer/pepper/DEPS @@ -6,6 +6,7 @@ include_rules = [ "+media/audio", "+media/base", "+media/video", + "+third_party/libyuv", "+ui/base/ime", "+ui/base/range", ] diff --git a/chromium/content/renderer/pepper/audio_helper.cc b/chromium/content/renderer/pepper/audio_helper.cc index 018f7809c9a..2ce1ae44d64 100644 --- a/chromium/content/renderer/pepper/audio_helper.cc +++ b/chromium/content/renderer/pepper/audio_helper.cc @@ -15,11 +15,9 @@ namespace content { // AudioHelper ----------------------------------------------------------------- -AudioHelper::AudioHelper() : shared_memory_size_for_create_callback_(0) { -} +AudioHelper::AudioHelper() : shared_memory_size_for_create_callback_(0) {} -AudioHelper::~AudioHelper() { -} +AudioHelper::~AudioHelper() {} int32_t AudioHelper::GetSyncSocketImpl(int* sync_socket) { if (socket_for_create_callback_) { @@ -28,7 +26,7 @@ int32_t AudioHelper::GetSyncSocketImpl(int* sync_socket) { #elif defined(OS_WIN) *sync_socket = reinterpret_cast<int>(socket_for_create_callback_->handle()); #else - #error "Platform not supported." +#error "Platform not supported." #endif return PP_OK; } @@ -40,10 +38,10 @@ int32_t AudioHelper::GetSharedMemoryImpl(int* shm_handle, uint32_t* shm_size) { #if defined(OS_POSIX) *shm_handle = shared_memory_for_create_callback_->handle().fd; #elif defined(OS_WIN) - *shm_handle = reinterpret_cast<int>( - shared_memory_for_create_callback_->handle()); + *shm_handle = + reinterpret_cast<int>(shared_memory_for_create_callback_->handle()); #else - #error "Platform not supported." +#error "Platform not supported." #endif *shm_size = shared_memory_size_for_create_callback_; return PP_OK; @@ -51,12 +49,11 @@ int32_t AudioHelper::GetSharedMemoryImpl(int* shm_handle, uint32_t* shm_size) { return PP_ERROR_FAILED; } -void AudioHelper::StreamCreated( - base::SharedMemoryHandle shared_memory_handle, - size_t shared_memory_size, - base::SyncSocket::Handle socket_handle) { +void AudioHelper::StreamCreated(base::SharedMemoryHandle shared_memory_handle, + size_t shared_memory_size, + base::SyncSocket::Handle socket_handle) { if (TrackedCallback::IsPending(create_callback_)) { - // Trusted side of proxy can specify a callback to recieve handles. In + // Trusted side of proxy can specify a callback to receive handles. In // this case we don't need to map any data or start the thread since it // will be handled by the proxy. shared_memory_for_create_callback_.reset( diff --git a/chromium/content/renderer/pepper/audio_helper.h b/chromium/content/renderer/pepper/audio_helper.h index a111325467f..94f94fcfb4c 100644 --- a/chromium/content/renderer/pepper/audio_helper.h +++ b/chromium/content/renderer/pepper/audio_helper.h @@ -26,8 +26,7 @@ class AudioHelper { size_t shared_memory_size_, base::SyncSocket::Handle socket); - void SetCreateCallback( - scoped_refptr<ppapi::TrackedCallback> create_callback); + void SetCreateCallback(scoped_refptr<ppapi::TrackedCallback> create_callback); protected: // TODO(viettrungluu): This is all very poorly thought out. Refactor. diff --git a/chromium/content/renderer/pepper/common.h b/chromium/content/renderer/pepper/common.h index 9b440bfba87..02df9ef6ac8 100644 --- a/chromium/content/renderer/pepper/common.h +++ b/chromium/content/renderer/pepper/common.h @@ -10,15 +10,10 @@ namespace content { -inline PP_Bool BoolToPPBool(bool value) { - return value ? PP_TRUE : PP_FALSE; -} +inline PP_Bool BoolToPPBool(bool value) { return value ? PP_TRUE : PP_FALSE; } -inline bool PPBoolToBool(PP_Bool value) { - return (PP_TRUE == value); -} +inline bool PPBoolToBool(PP_Bool value) { return (PP_TRUE == value); } } // namespace content #endif // CONTENT_RENDERER_PEPPER_COMMON_H_ - diff --git a/chromium/content/renderer/pepper/content_decryptor_delegate.cc b/chromium/content/renderer/pepper/content_decryptor_delegate.cc index 49790db2b7b..8692c1ce643 100644 --- a/chromium/content/renderer/pepper/content_decryptor_delegate.cc +++ b/chromium/content/renderer/pepper/content_decryptor_delegate.cc @@ -7,11 +7,12 @@ #include "base/callback_helpers.h" #include "base/debug/trace_event.h" #include "base/message_loop/message_loop_proxy.h" -#include "base/safe_numerics.h" +#include "base/numerics/safe_conversions.h" #include "content/renderer/pepper/ppb_buffer_impl.h" #include "media/base/audio_buffer.h" #include "media/base/audio_decoder_config.h" -#include "media/base/bind_to_loop.h" +#include "media/base/bind_to_current_loop.h" +#include "media/base/cdm_promise.h" #include "media/base/channel_layout.h" #include "media/base/data_buffer.h" #include "media/base/decoder_buffer.h" @@ -26,6 +27,11 @@ #include "ppapi/thunk/ppb_buffer_api.h" #include "ui/gfx/rect.h" +using media::CdmPromise; +using media::Decryptor; +using media::MediaKeys; +using media::NewSessionCdmPromise; +using media::SimpleCdmPromise; using ppapi::ArrayBufferVar; using ppapi::PpapiGlobals; using ppapi::ScopedPPResource; @@ -42,7 +48,8 @@ namespace { // reference-count of 0. If |data| is NULL, sets |*resource| to NULL. Returns // true upon success and false if any error happened. bool MakeBufferResource(PP_Instance instance, - const uint8* data, uint32_t size, + const uint8* data, + uint32_t size, scoped_refptr<PPB_Buffer_Impl>* resource) { TRACE_EVENT0("media", "ContentDecryptorDelegate - MakeBufferResource"); DCHECK(resource); @@ -105,7 +112,6 @@ static bool MakeEncryptedBlockInfo( const media::DecryptConfig* decrypt_config = encrypted_buffer->decrypt_config(); - block_info->data_offset = decrypt_config->data_offset(); if (!CopyStringToArray(decrypt_config->key_id(), block_info->key_id) || !CopyStringToArray(decrypt_config->iv(), block_info->iv)) @@ -145,6 +151,8 @@ PP_VideoCodec MediaVideoCodecToPpVideoCodec(media::VideoCodec codec) { return PP_VIDEOCODEC_VP8; case media::kCodecH264: return PP_VIDEOCODEC_H264; + case media::kCodecVP9: + return PP_VIDEOCODEC_VP9; default: return PP_VIDEOCODEC_UNKNOWN; } @@ -153,8 +161,11 @@ PP_VideoCodec MediaVideoCodecToPpVideoCodec(media::VideoCodec codec) { PP_VideoCodecProfile MediaVideoCodecProfileToPpVideoCodecProfile( media::VideoCodecProfile profile) { switch (profile) { + // TODO(xhwang): VP8 and VP9 do not have profiles. Clean up + // media::VideoCodecProfile and remove these two cases. case media::VP8PROFILE_MAIN: - return PP_VIDEOCODECPROFILE_VP8_MAIN; + case media::VP9PROFILE_MAIN: + return PP_VIDEOCODECPROFILE_NOT_NEEDED; case media::H264PROFILE_BASELINE: return PP_VIDEOCODECPROFILE_H264_BASELINE; case media::H264PROFILE_MAIN: @@ -186,31 +197,31 @@ PP_DecryptedFrameFormat MediaVideoFormatToPpDecryptedFrameFormat( } } -media::Decryptor::Status PpDecryptResultToMediaDecryptorStatus( +Decryptor::Status PpDecryptResultToMediaDecryptorStatus( PP_DecryptResult result) { switch (result) { case PP_DECRYPTRESULT_SUCCESS: - return media::Decryptor::kSuccess; + return Decryptor::kSuccess; case PP_DECRYPTRESULT_DECRYPT_NOKEY: - return media::Decryptor::kNoKey; + return Decryptor::kNoKey; case PP_DECRYPTRESULT_NEEDMOREDATA: - return media::Decryptor::kNeedMoreData; + return Decryptor::kNeedMoreData; case PP_DECRYPTRESULT_DECRYPT_ERROR: - return media::Decryptor::kError; + return Decryptor::kError; case PP_DECRYPTRESULT_DECODE_ERROR: - return media::Decryptor::kError; + return Decryptor::kError; default: NOTREACHED(); - return media::Decryptor::kError; + return Decryptor::kError; } } PP_DecryptorStreamType MediaDecryptorStreamTypeToPpStreamType( - media::Decryptor::StreamType stream_type) { + Decryptor::StreamType stream_type) { switch (stream_type) { - case media::Decryptor::kAudio: + case Decryptor::kAudio: return PP_DECRYPTORSTREAMTYPE_AUDIO; - case media::Decryptor::kVideo: + case Decryptor::kVideo: return PP_DECRYPTORSTREAMTYPE_VIDEO; default: NOTREACHED(); @@ -239,6 +250,42 @@ media::SampleFormat PpDecryptedSampleFormatToMediaSampleFormat( } } +PP_SessionType MediaSessionTypeToPpSessionType( + MediaKeys::SessionType session_type) { + switch (session_type) { + case MediaKeys::TEMPORARY_SESSION: + return PP_SESSIONTYPE_TEMPORARY; + case MediaKeys::PERSISTENT_SESSION: + return PP_SESSIONTYPE_PERSISTENT; + default: + NOTREACHED(); + return PP_SESSIONTYPE_TEMPORARY; + } +} + +MediaKeys::Exception PpExceptionTypeToMediaException( + PP_CdmExceptionCode exception_code) { + switch (exception_code) { + case PP_CDMEXCEPTIONCODE_NOTSUPPORTEDERROR: + return MediaKeys::NOT_SUPPORTED_ERROR; + case PP_CDMEXCEPTIONCODE_INVALIDSTATEERROR: + return MediaKeys::INVALID_STATE_ERROR; + case PP_CDMEXCEPTIONCODE_INVALIDACCESSERROR: + return MediaKeys::INVALID_ACCESS_ERROR; + case PP_CDMEXCEPTIONCODE_QUOTAEXCEEDEDERROR: + return MediaKeys::QUOTA_EXCEEDED_ERROR; + case PP_CDMEXCEPTIONCODE_UNKNOWNERROR: + return MediaKeys::UNKNOWN_ERROR; + case PP_CDMEXCEPTIONCODE_CLIENTERROR: + return MediaKeys::CLIENT_ERROR; + case PP_CDMEXCEPTIONCODE_OUTPUTERROR: + return MediaKeys::OUTPUT_ERROR; + default: + NOTREACHED(); + return MediaKeys::UNKNOWN_ERROR; + } +} + } // namespace ContentDecryptorDelegate::ContentDecryptorDelegate( @@ -247,82 +294,102 @@ ContentDecryptorDelegate::ContentDecryptorDelegate( : pp_instance_(pp_instance), plugin_decryption_interface_(plugin_decryption_interface), next_decryption_request_id_(1), - pending_audio_decrypt_request_id_(0), - pending_video_decrypt_request_id_(0), - pending_audio_decoder_init_request_id_(0), - pending_video_decoder_init_request_id_(0), - pending_audio_decode_request_id_(0), - pending_video_decode_request_id_(0), audio_samples_per_second_(0), audio_channel_count_(0), + audio_channel_layout_(media::CHANNEL_LAYOUT_NONE), + next_promise_id_(1), weak_ptr_factory_(this) { weak_this_ = weak_ptr_factory_.GetWeakPtr(); } ContentDecryptorDelegate::~ContentDecryptorDelegate() { + SatisfyAllPendingCallbacksOnError(); } -void ContentDecryptorDelegate::Initialize(const std::string& key_system) { +void ContentDecryptorDelegate::Initialize( + const std::string& key_system, + const media::SessionMessageCB& session_message_cb, + const media::SessionReadyCB& session_ready_cb, + const media::SessionClosedCB& session_closed_cb, + const media::SessionErrorCB& session_error_cb, + const base::Closure& fatal_plugin_error_cb) { DCHECK(!key_system.empty()); DCHECK(key_system_.empty()); key_system_ = key_system; - plugin_decryption_interface_->Initialize( - pp_instance_, - StringVar::StringToPPVar(key_system_)); -} - -void ContentDecryptorDelegate::SetSessionEventCallbacks( - const media::SessionCreatedCB& session_created_cb, - const media::SessionMessageCB& session_message_cb, - const media::SessionReadyCB& session_ready_cb, - const media::SessionClosedCB& session_closed_cb, - const media::SessionErrorCB& session_error_cb) { - session_created_cb_ = session_created_cb; session_message_cb_ = session_message_cb; session_ready_cb_ = session_ready_cb; session_closed_cb_ = session_closed_cb; session_error_cb_ = session_error_cb; + fatal_plugin_error_cb_ = fatal_plugin_error_cb; + + plugin_decryption_interface_->Initialize( + pp_instance_, StringVar::StringToPPVar(key_system_)); +} + +void ContentDecryptorDelegate::InstanceCrashed() { + fatal_plugin_error_cb_.Run(); + SatisfyAllPendingCallbacksOnError(); } -bool ContentDecryptorDelegate::CreateSession(uint32 session_id, - const std::string& type, - const uint8* init_data, - int init_data_length) { +void ContentDecryptorDelegate::CreateSession( + const std::string& init_data_type, + const uint8* init_data, + int init_data_length, + MediaKeys::SessionType session_type, + scoped_ptr<NewSessionCdmPromise> promise) { + uint32_t promise_id = SavePromise(promise.PassAs<CdmPromise>()); PP_Var init_data_array = PpapiGlobals::Get()->GetVarTracker()->MakeArrayBufferPPVar( init_data_length, init_data); + plugin_decryption_interface_->CreateSession( + pp_instance_, + promise_id, + StringVar::StringToPPVar(init_data_type), + init_data_array, + MediaSessionTypeToPpSessionType(session_type)); +} - plugin_decryption_interface_->CreateSession(pp_instance_, - session_id, - StringVar::StringToPPVar(type), - init_data_array); - return true; +void ContentDecryptorDelegate::LoadSession( + const std::string& web_session_id, + scoped_ptr<NewSessionCdmPromise> promise) { + uint32_t promise_id = SavePromise(promise.PassAs<CdmPromise>()); + plugin_decryption_interface_->LoadSession( + pp_instance_, promise_id, StringVar::StringToPPVar(web_session_id)); } -bool ContentDecryptorDelegate::UpdateSession(uint32 session_id, - const uint8* response, - int response_length) { +void ContentDecryptorDelegate::UpdateSession( + const std::string& web_session_id, + const uint8* response, + int response_length, + scoped_ptr<SimpleCdmPromise> promise) { + uint32_t promise_id = SavePromise(promise.PassAs<CdmPromise>()); PP_Var response_array = PpapiGlobals::Get()->GetVarTracker()->MakeArrayBufferPPVar( response_length, response); plugin_decryption_interface_->UpdateSession( - pp_instance_, session_id, response_array); - return true; + pp_instance_, + promise_id, + StringVar::StringToPPVar(web_session_id), + response_array); } -bool ContentDecryptorDelegate::ReleaseSession(uint32 session_id) { - plugin_decryption_interface_->ReleaseSession(pp_instance_, session_id); - return true; +void ContentDecryptorDelegate::ReleaseSession( + const std::string& web_session_id, + scoped_ptr<SimpleCdmPromise> promise) { + uint32_t promise_id = SavePromise(promise.PassAs<CdmPromise>()); + plugin_decryption_interface_->ReleaseSession( + pp_instance_, promise_id, StringVar::StringToPPVar(web_session_id)); } // TODO(xhwang): Remove duplication of code in Decrypt(), // DecryptAndDecodeAudio() and DecryptAndDecodeVideo(). bool ContentDecryptorDelegate::Decrypt( - media::Decryptor::StreamType stream_type, + Decryptor::StreamType stream_type, const scoped_refptr<media::DecoderBuffer>& encrypted_buffer, - const media::Decryptor::DecryptCB& decrypt_cb) { + const Decryptor::DecryptCB& decrypt_cb) { DVLOG(3) << "Decrypt() - stream_type: " << stream_type; + // |{audio|video}_input_resource_| is not being used by the plugin // now because there is only one pending audio/video decrypt request at any // time. This is enforced by the media pipeline. @@ -346,17 +413,11 @@ bool ContentDecryptorDelegate::Decrypt( // There is only one pending decrypt request at any time per stream. This is // enforced by the media pipeline. switch (stream_type) { - case media::Decryptor::kAudio: - DCHECK_EQ(pending_audio_decrypt_request_id_, 0u); - DCHECK(pending_audio_decrypt_cb_.is_null()); - pending_audio_decrypt_request_id_ = request_id; - pending_audio_decrypt_cb_ = decrypt_cb; + case Decryptor::kAudio: + audio_decrypt_cb_.Set(request_id, decrypt_cb); break; - case media::Decryptor::kVideo: - DCHECK_EQ(pending_video_decrypt_request_id_, 0u); - DCHECK(pending_video_decrypt_cb_.is_null()); - pending_video_decrypt_request_id_ = request_id; - pending_video_decrypt_cb_ = decrypt_cb; + case Decryptor::kVideo: + video_decrypt_cb_.Set(request_id, decrypt_cb); break; default: NOTREACHED(); @@ -365,33 +426,29 @@ bool ContentDecryptorDelegate::Decrypt( SetBufferToFreeInTrackingInfo(&block_info.tracking_info); - plugin_decryption_interface_->Decrypt(pp_instance_, - pp_resource, - &block_info); + plugin_decryption_interface_->Decrypt(pp_instance_, pp_resource, &block_info); return true; } bool ContentDecryptorDelegate::CancelDecrypt( - media::Decryptor::StreamType stream_type) { + Decryptor::StreamType stream_type) { DVLOG(3) << "CancelDecrypt() - stream_type: " << stream_type; - media::Decryptor::DecryptCB decrypt_cb; + Decryptor::DecryptCB decrypt_cb; switch (stream_type) { - case media::Decryptor::kAudio: + case Decryptor::kAudio: // Release the shared memory as it can still be in use by the plugin. // The next Decrypt() call will need to allocate a new shared memory // buffer. audio_input_resource_ = NULL; - pending_audio_decrypt_request_id_ = 0; - decrypt_cb = base::ResetAndReturn(&pending_audio_decrypt_cb_); + decrypt_cb = audio_decrypt_cb_.ResetAndReturn(); break; - case media::Decryptor::kVideo: + case Decryptor::kVideo: // Release the shared memory as it can still be in use by the plugin. // The next Decrypt() call will need to allocate a new shared memory // buffer. video_input_resource_ = NULL; - pending_video_decrypt_request_id_ = 0; - decrypt_cb = base::ResetAndReturn(&pending_video_decrypt_cb_); + decrypt_cb = video_decrypt_cb_.ResetAndReturn(); break; default: NOTREACHED(); @@ -399,14 +456,14 @@ bool ContentDecryptorDelegate::CancelDecrypt( } if (!decrypt_cb.is_null()) - decrypt_cb.Run(media::Decryptor::kSuccess, NULL); + decrypt_cb.Run(Decryptor::kSuccess, NULL); return true; } bool ContentDecryptorDelegate::InitializeAudioDecoder( const media::AudioDecoderConfig& decoder_config, - const media::Decryptor::DecoderInitCB& init_cb) { + const Decryptor::DecoderInitCB& init_cb) { PP_AudioDecoderConfig pp_decoder_config; pp_decoder_config.codec = MediaAudioCodecToPpAudioCodec(decoder_config.codec()); @@ -418,6 +475,7 @@ bool ContentDecryptorDelegate::InitializeAudioDecoder( audio_samples_per_second_ = pp_decoder_config.samples_per_second; audio_channel_count_ = pp_decoder_config.channel_count; + audio_channel_layout_ = decoder_config.channel_layout(); scoped_refptr<PPB_Buffer_Impl> extra_data_resource; if (!MakeBufferResource(pp_instance_, @@ -428,20 +486,15 @@ bool ContentDecryptorDelegate::InitializeAudioDecoder( } ScopedPPResource pp_resource(extra_data_resource.get()); - DCHECK_EQ(pending_audio_decoder_init_request_id_, 0u); - DCHECK(pending_audio_decoder_init_cb_.is_null()); - pending_audio_decoder_init_request_id_ = pp_decoder_config.request_id; - pending_audio_decoder_init_cb_ = init_cb; - - plugin_decryption_interface_->InitializeAudioDecoder(pp_instance_, - &pp_decoder_config, - pp_resource); + audio_decoder_init_cb_.Set(pp_decoder_config.request_id, init_cb); + plugin_decryption_interface_->InitializeAudioDecoder( + pp_instance_, &pp_decoder_config, pp_resource); return true; } bool ContentDecryptorDelegate::InitializeVideoDecoder( const media::VideoDecoderConfig& decoder_config, - const media::Decryptor::DecoderInitCB& init_cb) { + const Decryptor::DecoderInitCB& init_cb) { PP_VideoDecoderConfig pp_decoder_config; pp_decoder_config.codec = MediaVideoCodecToPpVideoCodec(decoder_config.codec()); @@ -462,24 +515,20 @@ bool ContentDecryptorDelegate::InitializeVideoDecoder( } ScopedPPResource pp_resource(extra_data_resource.get()); - DCHECK_EQ(pending_video_decoder_init_request_id_, 0u); - DCHECK(pending_video_decoder_init_cb_.is_null()); - pending_video_decoder_init_request_id_ = pp_decoder_config.request_id; - pending_video_decoder_init_cb_ = init_cb; - + video_decoder_init_cb_.Set(pp_decoder_config.request_id, init_cb); natural_size_ = decoder_config.natural_size(); - plugin_decryption_interface_->InitializeVideoDecoder(pp_instance_, - &pp_decoder_config, - pp_resource); + plugin_decryption_interface_->InitializeVideoDecoder( + pp_instance_, &pp_decoder_config, pp_resource); return true; } bool ContentDecryptorDelegate::DeinitializeDecoder( - media::Decryptor::StreamType stream_type) { + Decryptor::StreamType stream_type) { CancelDecode(stream_type); - natural_size_ = gfx::Size(); + if (stream_type == Decryptor::kVideo) + natural_size_ = gfx::Size(); // TODO(tomfinegan): Add decoder deinitialize request tracking, and get // stream type from media stack. @@ -488,8 +537,7 @@ bool ContentDecryptorDelegate::DeinitializeDecoder( return true; } -bool ContentDecryptorDelegate::ResetDecoder( - media::Decryptor::StreamType stream_type) { +bool ContentDecryptorDelegate::ResetDecoder(Decryptor::StreamType stream_type) { CancelDecode(stream_type); // TODO(tomfinegan): Add decoder reset request tracking. @@ -500,14 +548,13 @@ bool ContentDecryptorDelegate::ResetDecoder( bool ContentDecryptorDelegate::DecryptAndDecodeAudio( const scoped_refptr<media::DecoderBuffer>& encrypted_buffer, - const media::Decryptor::AudioDecodeCB& audio_decode_cb) { + const Decryptor::AudioDecodeCB& audio_decode_cb) { // |audio_input_resource_| is not being used by the plugin now // because there is only one pending audio decode request at any time. // This is enforced by the media pipeline. scoped_refptr<PPB_Buffer_Impl> encrypted_resource; - if (!MakeMediaBufferResource(media::Decryptor::kAudio, - encrypted_buffer, - &encrypted_resource)) { + if (!MakeMediaBufferResource( + Decryptor::kAudio, encrypted_buffer, &encrypted_resource)) { return false; } @@ -529,29 +576,23 @@ bool ContentDecryptorDelegate::DecryptAndDecodeAudio( // enforced by the media pipeline. If this DCHECK is violated, our buffer // reuse policy is not valid, and we may have race problems for the shared // buffer. - DCHECK_EQ(pending_audio_decode_request_id_, 0u); - DCHECK(pending_audio_decode_cb_.is_null()); - pending_audio_decode_request_id_ = request_id; - pending_audio_decode_cb_ = audio_decode_cb; + audio_decode_cb_.Set(request_id, audio_decode_cb); ScopedPPResource pp_resource(encrypted_resource.get()); - plugin_decryption_interface_->DecryptAndDecode(pp_instance_, - PP_DECRYPTORSTREAMTYPE_AUDIO, - pp_resource, - &block_info); + plugin_decryption_interface_->DecryptAndDecode( + pp_instance_, PP_DECRYPTORSTREAMTYPE_AUDIO, pp_resource, &block_info); return true; } bool ContentDecryptorDelegate::DecryptAndDecodeVideo( const scoped_refptr<media::DecoderBuffer>& encrypted_buffer, - const media::Decryptor::VideoDecodeCB& video_decode_cb) { + const Decryptor::VideoDecodeCB& video_decode_cb) { // |video_input_resource_| is not being used by the plugin now // because there is only one pending video decode request at any time. // This is enforced by the media pipeline. scoped_refptr<PPB_Buffer_Impl> encrypted_resource; - if (!MakeMediaBufferResource(media::Decryptor::kVideo, - encrypted_buffer, - &encrypted_resource)) { + if (!MakeMediaBufferResource( + Decryptor::kVideo, encrypted_buffer, &encrypted_resource)) { return false; } @@ -575,111 +616,144 @@ bool ContentDecryptorDelegate::DecryptAndDecodeVideo( // media pipeline. If this DCHECK is violated, our buffer // reuse policy is not valid, and we may have race problems for the shared // buffer. - DCHECK_EQ(pending_video_decode_request_id_, 0u); - DCHECK(pending_video_decode_cb_.is_null()); - pending_video_decode_request_id_ = request_id; - pending_video_decode_cb_ = video_decode_cb; + video_decode_cb_.Set(request_id, video_decode_cb); // TODO(tomfinegan): Need to get stream type from media stack. ScopedPPResource pp_resource(encrypted_resource.get()); - plugin_decryption_interface_->DecryptAndDecode(pp_instance_, - PP_DECRYPTORSTREAMTYPE_VIDEO, - pp_resource, - &block_info); + plugin_decryption_interface_->DecryptAndDecode( + pp_instance_, PP_DECRYPTORSTREAMTYPE_VIDEO, pp_resource, &block_info); return true; } -void ContentDecryptorDelegate::OnSessionCreated(uint32 session_id, - PP_Var web_session_id_var) { - if (session_created_cb_.is_null()) - return; +void ContentDecryptorDelegate::OnPromiseResolved(uint32 promise_id) { + scoped_ptr<CdmPromise> promise = TakePromise(promise_id); + if (promise) { + SimpleCdmPromise* simple_promise( + static_cast<SimpleCdmPromise*>(promise.get())); + simple_promise->resolve(); + } +} - StringVar* session_id_string = StringVar::FromPPVar(web_session_id_var); +void ContentDecryptorDelegate::OnPromiseResolvedWithSession( + uint32 promise_id, + PP_Var web_session_id) { + scoped_ptr<CdmPromise> promise = TakePromise(promise_id); - if (!session_id_string) { - OnSessionError(session_id, media::MediaKeys::kUnknownError, 0); - return; + StringVar* web_session_id_string = StringVar::FromPPVar(web_session_id); + DCHECK(web_session_id_string); + + if (promise) { + NewSessionCdmPromise* session_promise( + static_cast<NewSessionCdmPromise*>(promise.get())); + session_promise->resolve(web_session_id_string->value()); } +} - session_created_cb_.Run(session_id, session_id_string->value()); +void ContentDecryptorDelegate::OnPromiseRejected( + uint32 promise_id, + PP_CdmExceptionCode exception_code, + uint32 system_code, + PP_Var error_description) { + StringVar* error_description_string = StringVar::FromPPVar(error_description); + DCHECK(error_description_string); + + scoped_ptr<CdmPromise> promise = TakePromise(promise_id); + if (promise) { + promise->reject(PpExceptionTypeToMediaException(exception_code), + system_code, + error_description_string->value()); + } } -void ContentDecryptorDelegate::OnSessionMessage(uint32 session_id, - PP_Var message_var, - PP_Var default_url_var) { +void ContentDecryptorDelegate::OnSessionMessage(PP_Var web_session_id, + PP_Var message, + PP_Var destination_url) { if (session_message_cb_.is_null()) return; - ArrayBufferVar* message_array_buffer = ArrayBufferVar::FromPPVar(message_var); + StringVar* web_session_id_string = StringVar::FromPPVar(web_session_id); + DCHECK(web_session_id_string); - std::vector<uint8> message; + ArrayBufferVar* message_array_buffer = ArrayBufferVar::FromPPVar(message); + std::vector<uint8> message_vector; if (message_array_buffer) { const uint8* data = static_cast<const uint8*>(message_array_buffer->Map()); - message.assign(data, data + message_array_buffer->ByteLength()); + message_vector.assign(data, data + message_array_buffer->ByteLength()); } - StringVar* default_url_string = StringVar::FromPPVar(default_url_var); + StringVar* destination_url_string = StringVar::FromPPVar(destination_url); + DCHECK(destination_url_string); - if (!default_url_string) { - OnSessionError(session_id, media::MediaKeys::kUnknownError, 0); - return; + GURL verified_gurl = GURL(destination_url_string->value()); + if (!verified_gurl.is_valid() && !verified_gurl.is_empty()) { + DLOG(WARNING) << "SessionMessage default_url is invalid : " + << verified_gurl.possibly_invalid_spec(); + verified_gurl = GURL::EmptyGURL(); // Replace invalid destination_url. } - session_message_cb_.Run(session_id, message, default_url_string->value()); + session_message_cb_.Run( + web_session_id_string->value(), message_vector, verified_gurl); } -void ContentDecryptorDelegate::OnSessionReady(uint32 session_id) { +void ContentDecryptorDelegate::OnSessionReady(PP_Var web_session_id) { if (session_ready_cb_.is_null()) return; - session_ready_cb_.Run(session_id); + StringVar* web_session_id_string = StringVar::FromPPVar(web_session_id); + DCHECK(web_session_id_string); + + session_ready_cb_.Run(web_session_id_string->value()); } -void ContentDecryptorDelegate::OnSessionClosed(uint32 session_id) { +void ContentDecryptorDelegate::OnSessionClosed(PP_Var web_session_id) { if (session_closed_cb_.is_null()) return; - session_closed_cb_.Run(session_id); + StringVar* web_session_id_string = StringVar::FromPPVar(web_session_id); + DCHECK(web_session_id_string); + + session_closed_cb_.Run(web_session_id_string->value()); } -void ContentDecryptorDelegate::OnSessionError(uint32 session_id, - int32_t media_error, - int32_t system_code) { +void ContentDecryptorDelegate::OnSessionError( + PP_Var web_session_id, + PP_CdmExceptionCode exception_code, + uint32 system_code, + PP_Var error_description) { if (session_error_cb_.is_null()) return; - session_error_cb_.Run(session_id, - static_cast<media::MediaKeys::KeyError>(media_error), - system_code); + StringVar* web_session_id_string = StringVar::FromPPVar(web_session_id); + DCHECK(web_session_id_string); + + StringVar* error_description_string = StringVar::FromPPVar(error_description); + DCHECK(error_description_string); + + session_error_cb_.Run(web_session_id_string->value(), + PpExceptionTypeToMediaException(exception_code), + system_code, + error_description_string->value()); } void ContentDecryptorDelegate::DecoderInitializeDone( - PP_DecryptorStreamType decoder_type, - uint32_t request_id, - PP_Bool success) { + PP_DecryptorStreamType decoder_type, + uint32_t request_id, + PP_Bool success) { if (decoder_type == PP_DECRYPTORSTREAMTYPE_AUDIO) { // If the request ID is not valid or does not match what's saved, do // nothing. - if (request_id == 0 || - request_id != pending_audio_decoder_init_request_id_) + if (request_id == 0 || !audio_decoder_init_cb_.Matches(request_id)) return; - DCHECK(!pending_audio_decoder_init_cb_.is_null()); - pending_audio_decoder_init_request_id_ = 0; - base::ResetAndReturn( - &pending_audio_decoder_init_cb_).Run(PP_ToBool(success)); + audio_decoder_init_cb_.ResetAndReturn().Run(PP_ToBool(success)); } else { - if (request_id == 0 || - request_id != pending_video_decoder_init_request_id_) + if (request_id == 0 || !video_decoder_init_cb_.Matches(request_id)) return; - if (!success) - natural_size_ = gfx::Size(); + if (!success) + natural_size_ = gfx::Size(); - DCHECK(!pending_video_decoder_init_cb_.is_null()); - pending_video_decoder_init_request_id_ = 0; - base::ResetAndReturn( - &pending_video_decoder_init_cb_).Run(PP_ToBool(success)); + video_decoder_init_cb_.ResetAndReturn().Run(PP_ToBool(success)); } } @@ -711,47 +785,43 @@ void ContentDecryptorDelegate::DeliverBlock( return; } - media::Decryptor::DecryptCB decrypt_cb; - if (request_id == pending_audio_decrypt_request_id_) { - DCHECK(!pending_audio_decrypt_cb_.is_null()); - pending_audio_decrypt_request_id_ = 0; - decrypt_cb = base::ResetAndReturn(&pending_audio_decrypt_cb_); - } else if (request_id == pending_video_decrypt_request_id_) { - DCHECK(!pending_video_decrypt_cb_.is_null()); - pending_video_decrypt_request_id_ = 0; - decrypt_cb = base::ResetAndReturn(&pending_video_decrypt_cb_); + Decryptor::DecryptCB decrypt_cb; + if (audio_decrypt_cb_.Matches(request_id)) { + decrypt_cb = audio_decrypt_cb_.ResetAndReturn(); + } else if (video_decrypt_cb_.Matches(request_id)) { + decrypt_cb = video_decrypt_cb_.ResetAndReturn(); } else { DVLOG(1) << "DeliverBlock() - request_id " << request_id << " not found"; return; } - media::Decryptor::Status status = + Decryptor::Status status = PpDecryptResultToMediaDecryptorStatus(block_info->result); - if (status != media::Decryptor::kSuccess) { + if (status != Decryptor::kSuccess) { decrypt_cb.Run(status, NULL); return; } EnterResourceNoLock<PPB_Buffer_API> enter(decrypted_block, true); if (!enter.succeeded()) { - decrypt_cb.Run(media::Decryptor::kError, NULL); + decrypt_cb.Run(Decryptor::kError, NULL); return; } BufferAutoMapper mapper(enter.object()); if (!mapper.data() || !mapper.size() || mapper.size() < block_info->data_size) { - decrypt_cb.Run(media::Decryptor::kError, NULL); + decrypt_cb.Run(Decryptor::kError, NULL); return; } // TODO(tomfinegan): Find a way to take ownership of the shared memory // managed by the PPB_Buffer_Dev, and avoid the extra copy. scoped_refptr<media::DecoderBuffer> decrypted_buffer( - media::DecoderBuffer::CopyFrom( - static_cast<uint8*>(mapper.data()), block_info->data_size)); - decrypted_buffer->set_timestamp(base::TimeDelta::FromMicroseconds( - block_info->tracking_info.timestamp)); - decrypt_cb.Run(media::Decryptor::kSuccess, decrypted_buffer); + media::DecoderBuffer::CopyFrom(static_cast<uint8*>(mapper.data()), + block_info->data_size)); + decrypted_buffer->set_timestamp( + base::TimeDelta::FromMicroseconds(block_info->tracking_info.timestamp)); + decrypt_cb.Run(Decryptor::kSuccess, decrypted_buffer); } // Use a non-class-member function here so that if for some reason @@ -796,7 +866,7 @@ void ContentDecryptorDelegate::DeliverFrame( DVLOG(2) << "DeliverFrame() - request_id: " << request_id; // If the request ID is not valid or does not match what's saved, do nothing. - if (request_id == 0 || request_id != pending_video_decode_request_id_) { + if (request_id == 0 || !video_decode_cb_.Matches(request_id)) { DVLOG(1) << "DeliverFrame() - request_id " << request_id << " not found"; FreeBuffer(frame_info->tracking_info.buffer_id); return; @@ -805,14 +875,11 @@ void ContentDecryptorDelegate::DeliverFrame( TRACE_EVENT_ASYNC_END0( "media", "ContentDecryptorDelegate::DecryptAndDecodeVideo", request_id); - DCHECK(!pending_video_decode_cb_.is_null()); - pending_video_decode_request_id_ = 0; - media::Decryptor::VideoDecodeCB video_decode_cb = - base::ResetAndReturn(&pending_video_decode_cb_); + Decryptor::VideoDecodeCB video_decode_cb = video_decode_cb_.ResetAndReturn(); - media::Decryptor::Status status = + Decryptor::Status status = PpDecryptResultToMediaDecryptorStatus(frame_info->result); - if (status != media::Decryptor::kSuccess) { + if (status != Decryptor::kSuccess) { DCHECK(!frame_info->tracking_info.buffer_id); video_decode_cb.Run(status, NULL); return; @@ -822,7 +889,7 @@ void ContentDecryptorDelegate::DeliverFrame( uint8* frame_data = GetMappedBuffer(decrypted_frame, &ppb_buffer); if (!frame_data) { FreeBuffer(frame_info->tracking_info.buffer_id); - video_decode_cb.Run(media::Decryptor::kError, NULL); + video_decode_cb.Run(Decryptor::kError, NULL); return; } @@ -843,15 +910,14 @@ void ContentDecryptorDelegate::DeliverFrame( frame_data + frame_info->plane_offsets[PP_DECRYPTEDFRAMEPLANES_V], base::TimeDelta::FromMicroseconds( frame_info->tracking_info.timestamp), - media::BindToLoop( - base::MessageLoopProxy::current(), + media::BindToCurrentLoop( base::Bind(&BufferNoLongerNeeded, ppb_buffer, base::Bind(&ContentDecryptorDelegate::FreeBuffer, weak_this_, frame_info->tracking_info.buffer_id)))); - video_decode_cb.Run(media::Decryptor::kSuccess, decoded_frame); + video_decode_cb.Run(Decryptor::kSuccess, decoded_frame); } void ContentDecryptorDelegate::DeliverSamples( @@ -865,21 +931,18 @@ void ContentDecryptorDelegate::DeliverSamples( DVLOG(2) << "DeliverSamples() - request_id: " << request_id; // If the request ID is not valid or does not match what's saved, do nothing. - if (request_id == 0 || request_id != pending_audio_decode_request_id_) { + if (request_id == 0 || !audio_decode_cb_.Matches(request_id)) { DVLOG(1) << "DeliverSamples() - request_id " << request_id << " not found"; return; } - DCHECK(!pending_audio_decode_cb_.is_null()); - pending_audio_decode_request_id_ = 0; - media::Decryptor::AudioDecodeCB audio_decode_cb = - base::ResetAndReturn(&pending_audio_decode_cb_); + Decryptor::AudioDecodeCB audio_decode_cb = audio_decode_cb_.ResetAndReturn(); - const media::Decryptor::AudioBuffers empty_frames; + const Decryptor::AudioBuffers empty_frames; - media::Decryptor::Status status = + Decryptor::Status status = PpDecryptResultToMediaDecryptorStatus(sample_info->result); - if (status != media::Decryptor::kSuccess) { + if (status != Decryptor::kSuccess) { audio_decode_cb.Run(status, empty_frames); return; } @@ -887,42 +950,38 @@ void ContentDecryptorDelegate::DeliverSamples( media::SampleFormat sample_format = PpDecryptedSampleFormatToMediaSampleFormat(sample_info->format); - media::Decryptor::AudioBuffers audio_frame_list; + Decryptor::AudioBuffers audio_frame_list; if (!DeserializeAudioFrames(audio_frames, sample_info->data_size, sample_format, &audio_frame_list)) { NOTREACHED() << "CDM did not serialize the buffer correctly."; - audio_decode_cb.Run(media::Decryptor::kError, empty_frames); + audio_decode_cb.Run(Decryptor::kError, empty_frames); return; } - audio_decode_cb.Run(media::Decryptor::kSuccess, audio_frame_list); + audio_decode_cb.Run(Decryptor::kSuccess, audio_frame_list); } // TODO(xhwang): Try to remove duplicate logic here and in CancelDecrypt(). -void ContentDecryptorDelegate::CancelDecode( - media::Decryptor::StreamType stream_type) { +void ContentDecryptorDelegate::CancelDecode(Decryptor::StreamType stream_type) { switch (stream_type) { - case media::Decryptor::kAudio: + case Decryptor::kAudio: // Release the shared memory as it can still be in use by the plugin. // The next DecryptAndDecode() call will need to allocate a new shared // memory buffer. audio_input_resource_ = NULL; - pending_audio_decode_request_id_ = 0; - if (!pending_audio_decode_cb_.is_null()) - base::ResetAndReturn(&pending_audio_decode_cb_).Run( - media::Decryptor::kSuccess, media::Decryptor::AudioBuffers()); + if (!audio_decode_cb_.is_null()) + audio_decode_cb_.ResetAndReturn().Run(Decryptor::kSuccess, + Decryptor::AudioBuffers()); break; - case media::Decryptor::kVideo: + case Decryptor::kVideo: // Release the shared memory as it can still be in use by the plugin. // The next DecryptAndDecode() call will need to allocate a new shared // memory buffer. video_input_resource_ = NULL; - pending_video_decode_request_id_ = 0; - if (!pending_video_decode_cb_.is_null()) - base::ResetAndReturn(&pending_video_decode_cb_).Run( - media::Decryptor::kSuccess, NULL); + if (!video_decode_cb_.is_null()) + video_decode_cb_.ResetAndReturn().Run(Decryptor::kSuccess, NULL); break; default: NOTREACHED(); @@ -930,7 +989,7 @@ void ContentDecryptorDelegate::CancelDecode( } bool ContentDecryptorDelegate::MakeMediaBufferResource( - media::Decryptor::StreamType stream_type, + Decryptor::StreamType stream_type, const scoped_refptr<media::DecoderBuffer>& encrypted_buffer, scoped_refptr<PPB_Buffer_Impl>* resource) { TRACE_EVENT0("media", "ContentDecryptorDelegate::MakeMediaBufferResource"); @@ -941,11 +1000,10 @@ bool ContentDecryptorDelegate::MakeMediaBufferResource( return true; } - DCHECK(stream_type == media::Decryptor::kAudio || - stream_type == media::Decryptor::kVideo); + DCHECK(stream_type == Decryptor::kAudio || stream_type == Decryptor::kVideo); scoped_refptr<PPB_Buffer_Impl>& media_resource = - (stream_type == media::Decryptor::kAudio) ? audio_input_resource_ : - video_input_resource_; + (stream_type == Decryptor::kAudio) ? audio_input_resource_ + : video_input_resource_; const size_t data_size = static_cast<size_t>(encrypted_buffer->data_size()); if (!media_resource.get() || media_resource->size() < data_size) { @@ -964,11 +1022,11 @@ bool ContentDecryptorDelegate::MakeMediaBufferResource( media_resource_size *= 2; DVLOG(2) << "Size of media buffer for " - << ((stream_type == media::Decryptor::kAudio) ? "audio" : "video") + << ((stream_type == Decryptor::kAudio) ? "audio" : "video") << " stream bumped to " << media_resource_size << " bytes to fit input."; - media_resource = PPB_Buffer_Impl::CreateResource(pp_instance_, - media_resource_size); + media_resource = + PPB_Buffer_Impl::CreateResource(pp_instance_, media_resource_size); if (!media_resource.get()) return false; } @@ -1004,7 +1062,7 @@ bool ContentDecryptorDelegate::DeserializeAudioFrames( PP_Resource audio_frames, size_t data_size, media::SampleFormat sample_format, - media::Decryptor::AudioBuffers* frames) { + Decryptor::AudioBuffers* frames) { DCHECK(frames); EnterResourceNoLock<PPB_Buffer_API> enter(audio_frames, true); if (!enter.succeeded()) @@ -1024,10 +1082,12 @@ bool ContentDecryptorDelegate::DeserializeAudioFrames( const int audio_bytes_per_frame = media::SampleFormatToBytesPerChannel(sample_format) * audio_channel_count_; + if (audio_bytes_per_frame <= 0) + return false; // Allocate space for the channel pointers given to AudioBuffer. - std::vector<const uint8*> channel_ptrs( - audio_channel_count_, static_cast<const uint8*>(NULL)); + std::vector<const uint8*> channel_ptrs(audio_channel_count_, + static_cast<const uint8*>(NULL)); do { int64 timestamp = 0; int64 frame_size = -1; @@ -1046,7 +1106,7 @@ bool ContentDecryptorDelegate::DeserializeAudioFrames( // We should *not* have empty frames in the list. if (frame_size <= 0 || - bytes_left < base::checked_numeric_cast<size_t>(frame_size)) { + bytes_left < base::checked_cast<size_t>(frame_size)) { return false; } @@ -1059,12 +1119,12 @@ bool ContentDecryptorDelegate::DeserializeAudioFrames( const int frame_count = frame_size / audio_bytes_per_frame; scoped_refptr<media::AudioBuffer> frame = media::AudioBuffer::CopyFrom( sample_format, + audio_channel_layout_, audio_channel_count_, + audio_samples_per_second_, frame_count, &channel_ptrs[0], - base::TimeDelta::FromMicroseconds(timestamp), - base::TimeDelta::FromMicroseconds(audio_samples_per_second_ / - frame_count)); + base::TimeDelta::FromMicroseconds(timestamp)); frames->push_back(frame); cur += frame_size; @@ -1074,4 +1134,52 @@ bool ContentDecryptorDelegate::DeserializeAudioFrames( return true; } +void ContentDecryptorDelegate::SatisfyAllPendingCallbacksOnError() { + if (!audio_decoder_init_cb_.is_null()) + audio_decoder_init_cb_.ResetAndReturn().Run(false); + + if (!video_decoder_init_cb_.is_null()) + video_decoder_init_cb_.ResetAndReturn().Run(false); + + audio_input_resource_ = NULL; + video_input_resource_ = NULL; + + if (!audio_decrypt_cb_.is_null()) + audio_decrypt_cb_.ResetAndReturn().Run(media::Decryptor::kError, NULL); + + if (!video_decrypt_cb_.is_null()) + video_decrypt_cb_.ResetAndReturn().Run(media::Decryptor::kError, NULL); + + if (!audio_decode_cb_.is_null()) { + const media::Decryptor::AudioBuffers empty_frames; + audio_decode_cb_.ResetAndReturn().Run(media::Decryptor::kError, + empty_frames); + } + + if (!video_decode_cb_.is_null()) + video_decode_cb_.ResetAndReturn().Run(media::Decryptor::kError, NULL); + + // Reject all outstanding promises. + for (PromiseMap::iterator it = promises_.begin(); it != promises_.end(); + ++it) { + it->second->reject( + media::MediaKeys::UNKNOWN_ERROR, 0, "Failure calling plugin."); + } + promises_.clear(); +} + +uint32_t ContentDecryptorDelegate::SavePromise(scoped_ptr<CdmPromise> promise) { + uint32_t promise_id = next_promise_id_++; + promises_.add(promise_id, promise.Pass()); + return promise_id; +} + +scoped_ptr<CdmPromise> ContentDecryptorDelegate::TakePromise( + uint32_t promise_id) { + PromiseMap::iterator it = promises_.find(promise_id); + if (it == promises_.end()) + return scoped_ptr<CdmPromise>(); + return promises_.take_and_erase(it); +} + } // namespace content diff --git a/chromium/content/renderer/pepper/content_decryptor_delegate.h b/chromium/content/renderer/pepper/content_decryptor_delegate.h index 352817dd011..182d6a66257 100644 --- a/chromium/content/renderer/pepper/content_decryptor_delegate.h +++ b/chromium/content/renderer/pepper/content_decryptor_delegate.h @@ -5,13 +5,18 @@ #ifndef CONTENT_RENDERER_PEPPER_CONTENT_DECRYPTOR_DELEGATE_H_ #define CONTENT_RENDERER_PEPPER_CONTENT_DECRYPTOR_DELEGATE_H_ +#include <map> #include <queue> #include <string> #include "base/basictypes.h" +#include "base/callback_helpers.h" #include "base/compiler_specific.h" +#include "base/containers/scoped_ptr_hash_map.h" #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" +#include "media/base/cdm_promise.h" +#include "media/base/channel_layout.h" #include "media/base/decryptor.h" #include "media/base/media_keys.h" #include "media/base/sample_format.h" @@ -39,24 +44,30 @@ class ContentDecryptorDelegate { const PPP_ContentDecryptor_Private* plugin_decryption_interface); ~ContentDecryptorDelegate(); - void Initialize(const std::string& key_system); + // This object should not be accessed after |fatal_plugin_error_cb| is called. + void Initialize(const std::string& key_system, + const media::SessionMessageCB& session_message_cb, + const media::SessionReadyCB& session_ready_cb, + const media::SessionClosedCB& session_closed_cb, + const media::SessionErrorCB& session_error_cb, + const base::Closure& fatal_plugin_error_cb); - void SetSessionEventCallbacks( - const media::SessionCreatedCB& session_created_cb, - const media::SessionMessageCB& session_message_cb, - const media::SessionReadyCB& session_ready_cb, - const media::SessionClosedCB& session_closed_cb, - const media::SessionErrorCB& session_error_cb); + void InstanceCrashed(); // Provides access to PPP_ContentDecryptor_Private. - bool CreateSession(uint32 session_id, - const std::string& type, + void CreateSession(const std::string& init_data_type, const uint8* init_data, - int init_data_length); - bool UpdateSession(uint32 session_id, + int init_data_length, + media::MediaKeys::SessionType session_type, + scoped_ptr<media::NewSessionCdmPromise> promise); + void LoadSession(const std::string& web_session_id, + scoped_ptr<media::NewSessionCdmPromise> promise); + void UpdateSession(const std::string& web_session_id, const uint8* response, - int response_length); - bool ReleaseSession(uint32 session_id); + int response_length, + scoped_ptr<media::SimpleCdmPromise> promise); + void ReleaseSession(const std::string& web_session_id, + scoped_ptr<media::SimpleCdmPromise> promise); bool Decrypt(media::Decryptor::StreamType stream_type, const scoped_refptr<media::DecoderBuffer>& encrypted_buffer, const media::Decryptor::DecryptCB& decrypt_cb); @@ -80,15 +91,21 @@ class ContentDecryptorDelegate { const media::Decryptor::VideoDecodeCB& video_decode_cb); // PPB_ContentDecryptor_Private dispatching methods. - void OnSessionCreated(uint32 session_id, PP_Var web_session_id_var); - void OnSessionMessage(uint32 session_id, + void OnPromiseResolved(uint32 promise_id); + void OnPromiseResolvedWithSession(uint32 promise_id, PP_Var web_session_id); + void OnPromiseRejected(uint32 promise_id, + PP_CdmExceptionCode exception_code, + uint32 system_code, + PP_Var error_description); + void OnSessionMessage(PP_Var web_session_id, PP_Var message, PP_Var destination_url); - void OnSessionReady(uint32 session_id); - void OnSessionClosed(uint32 session_id); - void OnSessionError(uint32 session_id, - int32_t media_error, - int32_t system_code); + void OnSessionReady(PP_Var web_session_id); + void OnSessionClosed(PP_Var web_session_id); + void OnSessionError(PP_Var web_session_id, + PP_CdmExceptionCode exception_code, + uint32 system_code, + PP_Var error_description); void DeliverBlock(PP_Resource decrypted_block, const PP_DecryptedBlockInfo* block_info); void DecoderInitializeDone(PP_DecryptorStreamType decoder_type, @@ -104,6 +121,41 @@ class ContentDecryptorDelegate { const PP_DecryptedSampleInfo* sample_info); private: + // The following types keep track of Promises. The index is the promise_id, + // so that returning results can be matched to the corresponding promise. + typedef base::ScopedPtrHashMap<uint32_t, media::CdmPromise> PromiseMap; + + template <typename Callback> + class TrackableCallback { + public: + TrackableCallback() : id_(0u) {} + ~TrackableCallback() { + // Callbacks must be satisfied. + DCHECK_EQ(id_, 0u); + DCHECK(is_null()); + }; + + bool Matches(uint32_t id) const { return id == id_; } + + bool is_null() const { return cb_.is_null(); } + + void Set(uint32_t id, const Callback& cb) { + DCHECK_EQ(id_, 0u); + DCHECK(cb_.is_null()); + id_ = id; + cb_ = cb; + } + + Callback ResetAndReturn() { + id_ = 0; + return base::ResetAndReturn(&cb_); + } + + private: + uint32_t id_; + Callback cb_; + }; + // Cancels the pending decrypt-and-decode callback for |stream_type|. void CancelDecode(media::Decryptor::StreamType stream_type); @@ -133,6 +185,16 @@ class ContentDecryptorDelegate { media::SampleFormat sample_format, media::Decryptor::AudioBuffers* frames); + void SatisfyAllPendingCallbacksOnError(); + + // Takes ownership of |promise| and returns an identifier to be passed via + // Pepper. + uint32_t SavePromise(scoped_ptr<media::CdmPromise> promise); + + // Find the promise for a specified |promise_id|. Caller is responsible to + // delete the CdmPromise<> once done with it. + scoped_ptr<media::CdmPromise> TakePromise(uint32_t promise_id); + const PP_Instance pp_instance_; const PPP_ContentDecryptor_Private* const plugin_decryption_interface_; @@ -140,12 +202,15 @@ class ContentDecryptorDelegate { std::string key_system_; // Callbacks for firing session events. - media::SessionCreatedCB session_created_cb_; media::SessionMessageCB session_message_cb_; media::SessionReadyCB session_ready_cb_; media::SessionClosedCB session_closed_cb_; media::SessionErrorCB session_error_cb_; + // Callback to notify that unexpected error happened and |this| should not + // be used anymore. + base::Closure fatal_plugin_error_cb_; + gfx::Size natural_size_; // Request ID for tracking pending content decryption callbacks. @@ -154,23 +219,12 @@ class ContentDecryptorDelegate { // of request IDs. uint32_t next_decryption_request_id_; - uint32_t pending_audio_decrypt_request_id_; - media::Decryptor::DecryptCB pending_audio_decrypt_cb_; - - uint32_t pending_video_decrypt_request_id_; - media::Decryptor::DecryptCB pending_video_decrypt_cb_; - - uint32_t pending_audio_decoder_init_request_id_; - media::Decryptor::DecoderInitCB pending_audio_decoder_init_cb_; - - uint32_t pending_video_decoder_init_request_id_; - media::Decryptor::DecoderInitCB pending_video_decoder_init_cb_; - - uint32_t pending_audio_decode_request_id_; - media::Decryptor::AudioDecodeCB pending_audio_decode_cb_; - - uint32_t pending_video_decode_request_id_; - media::Decryptor::VideoDecodeCB pending_video_decode_cb_; + TrackableCallback<media::Decryptor::DecryptCB> audio_decrypt_cb_; + TrackableCallback<media::Decryptor::DecryptCB> video_decrypt_cb_; + TrackableCallback<media::Decryptor::DecoderInitCB> audio_decoder_init_cb_; + TrackableCallback<media::Decryptor::DecoderInitCB> video_decoder_init_cb_; + TrackableCallback<media::Decryptor::AudioDecodeCB> audio_decode_cb_; + TrackableCallback<media::Decryptor::VideoDecodeCB> video_decode_cb_; // Cached audio and video input buffers. See MakeMediaBufferResource. scoped_refptr<PPB_Buffer_Impl> audio_input_resource_; @@ -181,6 +235,11 @@ class ContentDecryptorDelegate { // Keep track of audio parameters. int audio_samples_per_second_; int audio_channel_count_; + media::ChannelLayout audio_channel_layout_; + + // Keep track of outstanding promises. Maps have ownership of the promises. + uint32_t next_promise_id_; + PromiseMap promises_; base::WeakPtr<ContentDecryptorDelegate> weak_this_; base::WeakPtrFactory<ContentDecryptorDelegate> weak_ptr_factory_; diff --git a/chromium/content/renderer/pepper/content_renderer_pepper_host_factory.cc b/chromium/content/renderer/pepper/content_renderer_pepper_host_factory.cc index 0bd3fdf8729..07afe47fa82 100644 --- a/chromium/content/renderer/pepper/content_renderer_pepper_host_factory.cc +++ b/chromium/content/renderer/pepper/content_renderer_pepper_host_factory.cc @@ -9,13 +9,17 @@ #include "content/public/common/content_client.h" #include "content/public/renderer/content_renderer_client.h" #include "content/renderer/pepper/pepper_audio_input_host.h" +#include "content/renderer/pepper/pepper_compositor_host.h" #include "content/renderer/pepper/pepper_file_chooser_host.h" #include "content/renderer/pepper/pepper_file_ref_renderer_host.h" #include "content/renderer/pepper/pepper_file_system_host.h" #include "content/renderer/pepper/pepper_graphics_2d_host.h" +#include "content/renderer/pepper/pepper_media_stream_video_track_host.h" +#include "content/renderer/pepper/pepper_plugin_instance_impl.h" #include "content/renderer/pepper/pepper_truetype_font_host.h" #include "content/renderer/pepper/pepper_url_loader_host.h" #include "content/renderer/pepper/pepper_video_capture_host.h" +#include "content/renderer/pepper/pepper_video_decoder_host.h" #include "content/renderer/pepper/pepper_video_destination_host.h" #include "content/renderer/pepper/pepper_video_source_host.h" #include "content/renderer/pepper/pepper_websocket_host.h" @@ -40,9 +44,7 @@ namespace content { #if defined(ENABLE_WEBRTC) namespace { -#if defined(ENABLE_WEBRTC) -bool CanUseMediaStreamAPI(const RendererPpapiHost* host, - PP_Instance instance) { +bool CanUseMediaStreamAPI(const RendererPpapiHost* host, PP_Instance instance) { blink::WebPluginContainer* container = host->GetContainerForInstance(instance); if (!container) @@ -53,18 +55,15 @@ bool CanUseMediaStreamAPI(const RendererPpapiHost* host, GetContentClient()->renderer(); return content_renderer_client->AllowPepperMediaStreamAPI(document_url); } -#endif // defined(ENABLE_WEBRTC) } // namespace #endif // defined(ENABLE_WEBRTC) ContentRendererPepperHostFactory::ContentRendererPepperHostFactory( RendererPpapiHostImpl* host) - : host_(host) { -} + : host_(host) {} -ContentRendererPepperHostFactory::~ContentRendererPepperHostFactory() { -} +ContentRendererPepperHostFactory::~ContentRendererPepperHostFactory() {} scoped_ptr<ResourceHost> ContentRendererPepperHostFactory::CreateResourceHost( ppapi::host::PpapiHost* host, @@ -77,14 +76,22 @@ scoped_ptr<ResourceHost> ContentRendererPepperHostFactory::CreateResourceHost( if (!host_->IsValidInstance(instance)) return scoped_ptr<ResourceHost>(); + PepperPluginInstanceImpl* instance_impl = + host_->GetPluginInstanceImpl(instance); + if (!instance_impl->render_frame()) + return scoped_ptr<ResourceHost>(); + // Public interfaces. switch (message.type()) { - case PpapiHostMsg_FileRef_CreateInternal::ID: { + case PpapiHostMsg_Compositor_Create::ID: { + return scoped_ptr<ResourceHost>( + new PepperCompositorHost(host_, instance, params.pp_resource())); + } + case PpapiHostMsg_FileRef_CreateForFileAPI::ID: { PP_Resource file_system; std::string internal_path; - if (!UnpackMessage<PpapiHostMsg_FileRef_CreateInternal>(message, - &file_system, - &internal_path)) { + if (!UnpackMessage<PpapiHostMsg_FileRef_CreateForFileAPI>( + message, &file_system, &internal_path)) { NOTREACHED(); return scoped_ptr<ResourceHost>(); } @@ -104,24 +111,34 @@ scoped_ptr<ResourceHost> ContentRendererPepperHostFactory::CreateResourceHost( case PpapiHostMsg_Graphics2D_Create::ID: { PP_Size size; PP_Bool is_always_opaque; - if (!UnpackMessage<PpapiHostMsg_Graphics2D_Create>(message, &size, - &is_always_opaque)) { + if (!UnpackMessage<PpapiHostMsg_Graphics2D_Create>( + message, &size, &is_always_opaque)) { NOTREACHED(); return scoped_ptr<ResourceHost>(); } scoped_refptr<PPB_ImageData_Impl> image_data(new PPB_ImageData_Impl( instance, ppapi::PPB_ImageData_Shared::PLATFORM)); return scoped_ptr<ResourceHost>( - PepperGraphics2DHost::Create(host_, instance, params.pp_resource(), - size, is_always_opaque, image_data)); + PepperGraphics2DHost::Create(host_, + instance, + params.pp_resource(), + size, + is_always_opaque, + image_data)); } case PpapiHostMsg_URLLoader_Create::ID: return scoped_ptr<ResourceHost>(new PepperURLLoaderHost( host_, false, instance, params.pp_resource())); + case PpapiHostMsg_VideoDecoder_Create::ID: + return scoped_ptr<ResourceHost>( + new PepperVideoDecoderHost(host_, instance, params.pp_resource())); case PpapiHostMsg_WebSocket_Create::ID: - return scoped_ptr<ResourceHost>(new PepperWebSocketHost( - host_, instance, params.pp_resource())); + return scoped_ptr<ResourceHost>( + new PepperWebSocketHost(host_, instance, params.pp_resource())); #if defined(ENABLE_WEBRTC) + case PpapiHostMsg_MediaStreamVideoTrack_Create::ID: + return scoped_ptr<ResourceHost>(new PepperMediaStreamVideoTrackHost( + host_, instance, params.pp_resource())); // These private MediaStream interfaces are exposed as if they were public // so they can be used by NaCl plugins. However, they are available only // for whitelisted apps. @@ -131,8 +148,8 @@ scoped_ptr<ResourceHost> ContentRendererPepperHostFactory::CreateResourceHost( host_, instance, params.pp_resource())); case PpapiHostMsg_VideoSource_Create::ID: if (CanUseMediaStreamAPI(host_, instance)) - return scoped_ptr<ResourceHost>(new PepperVideoSourceHost( - host_, instance, params.pp_resource())); + return scoped_ptr<ResourceHost>( + new PepperVideoSourceHost(host_, instance, params.pp_resource())); #endif // defined(ENABLE_WEBRTC) } @@ -140,29 +157,28 @@ scoped_ptr<ResourceHost> ContentRendererPepperHostFactory::CreateResourceHost( if (GetPermissions().HasPermission(ppapi::PERMISSION_DEV)) { switch (message.type()) { case PpapiHostMsg_AudioInput_Create::ID: - return scoped_ptr<ResourceHost>(new PepperAudioInputHost( - host_, instance, params.pp_resource())); + return scoped_ptr<ResourceHost>( + new PepperAudioInputHost(host_, instance, params.pp_resource())); case PpapiHostMsg_FileChooser_Create::ID: - return scoped_ptr<ResourceHost>(new PepperFileChooserHost( - host_, instance, params.pp_resource())); + return scoped_ptr<ResourceHost>( + new PepperFileChooserHost(host_, instance, params.pp_resource())); case PpapiHostMsg_TrueTypeFont_Create::ID: { SerializedTrueTypeFontDesc desc; - if (!UnpackMessage<PpapiHostMsg_TrueTypeFont_Create>(message, - &desc)) { + if (!UnpackMessage<PpapiHostMsg_TrueTypeFont_Create>(message, &desc)) { NOTREACHED(); return scoped_ptr<ResourceHost>(); } // Check that the family name is valid UTF-8 before passing it to the // host OS. - if (IsStringUTF8(desc.family)) { + if (base::IsStringUTF8(desc.family)) { return scoped_ptr<ResourceHost>(new PepperTrueTypeFontHost( host_, instance, params.pp_resource(), desc)); } break; // Drop through and return null host. } case PpapiHostMsg_VideoCapture_Create::ID: { - PepperVideoCaptureHost* host = new PepperVideoCaptureHost( - host_, instance, params.pp_resource()); + PepperVideoCaptureHost* host = + new PepperVideoCaptureHost(host_, instance, params.pp_resource()); if (!host->Init()) { delete host; return scoped_ptr<ResourceHost>(); diff --git a/chromium/content/renderer/pepper/content_renderer_pepper_host_factory.h b/chromium/content/renderer/pepper/content_renderer_pepper_host_factory.h index cc790fa4c63..8618b8b886d 100644 --- a/chromium/content/renderer/pepper/content_renderer_pepper_host_factory.h +++ b/chromium/content/renderer/pepper/content_renderer_pepper_host_factory.h @@ -20,8 +20,7 @@ class RenderViewImpl; class ContentRendererPepperHostFactory : public ppapi::host::HostFactory { public: - explicit ContentRendererPepperHostFactory( - RendererPpapiHostImpl* host); + explicit ContentRendererPepperHostFactory(RendererPpapiHostImpl* host); virtual ~ContentRendererPepperHostFactory(); virtual scoped_ptr<ppapi::host::ResourceHost> CreateResourceHost( diff --git a/chromium/content/renderer/pepper/event_conversion.cc b/chromium/content/renderer/pepper/event_conversion.cc index b7c06016f77..d08e3d5553d 100644 --- a/chromium/content/renderer/pepper/event_conversion.cc +++ b/chromium/content/renderer/pepper/event_conversion.cc @@ -14,6 +14,7 @@ #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversion_utils.h" #include "base/strings/utf_string_conversions.h" +#include "content/common/input/web_touch_event_traits.h" #include "content/renderer/pepper/common.h" #include "content/renderer/pepper/usb_key_code_conversion.h" #include "ppapi/c/pp_input_event.h" @@ -43,43 +44,43 @@ namespace { // not matching, we'll need to write conversion code to preserve the Pepper // values (since plugins will be depending on them). COMPILE_ASSERT(static_cast<int>(PP_INPUTEVENT_MODIFIER_SHIFTKEY) == - static_cast<int>(WebInputEvent::ShiftKey), + static_cast<int>(WebInputEvent::ShiftKey), ShiftKeyMatches); COMPILE_ASSERT(static_cast<int>(PP_INPUTEVENT_MODIFIER_CONTROLKEY) == - static_cast<int>(WebInputEvent::ControlKey), + static_cast<int>(WebInputEvent::ControlKey), ControlKeyMatches); COMPILE_ASSERT(static_cast<int>(PP_INPUTEVENT_MODIFIER_ALTKEY) == - static_cast<int>(WebInputEvent::AltKey), + static_cast<int>(WebInputEvent::AltKey), AltKeyMatches); COMPILE_ASSERT(static_cast<int>(PP_INPUTEVENT_MODIFIER_METAKEY) == - static_cast<int>(WebInputEvent::MetaKey), + static_cast<int>(WebInputEvent::MetaKey), MetaKeyMatches); COMPILE_ASSERT(static_cast<int>(PP_INPUTEVENT_MODIFIER_ISKEYPAD) == - static_cast<int>(WebInputEvent::IsKeyPad), + static_cast<int>(WebInputEvent::IsKeyPad), KeyPadMatches); COMPILE_ASSERT(static_cast<int>(PP_INPUTEVENT_MODIFIER_ISAUTOREPEAT) == - static_cast<int>(WebInputEvent::IsAutoRepeat), + static_cast<int>(WebInputEvent::IsAutoRepeat), AutoRepeatMatches); COMPILE_ASSERT(static_cast<int>(PP_INPUTEVENT_MODIFIER_LEFTBUTTONDOWN) == - static_cast<int>(WebInputEvent::LeftButtonDown), + static_cast<int>(WebInputEvent::LeftButtonDown), LeftButtonMatches); COMPILE_ASSERT(static_cast<int>(PP_INPUTEVENT_MODIFIER_MIDDLEBUTTONDOWN) == - static_cast<int>(WebInputEvent::MiddleButtonDown), + static_cast<int>(WebInputEvent::MiddleButtonDown), MiddleButtonMatches); COMPILE_ASSERT(static_cast<int>(PP_INPUTEVENT_MODIFIER_RIGHTBUTTONDOWN) == - static_cast<int>(WebInputEvent::RightButtonDown), + static_cast<int>(WebInputEvent::RightButtonDown), RightButtonMatches); COMPILE_ASSERT(static_cast<int>(PP_INPUTEVENT_MODIFIER_CAPSLOCKKEY) == - static_cast<int>(WebInputEvent::CapsLockOn), + static_cast<int>(WebInputEvent::CapsLockOn), CapsLockMatches); COMPILE_ASSERT(static_cast<int>(PP_INPUTEVENT_MODIFIER_NUMLOCKKEY) == - static_cast<int>(WebInputEvent::NumLockOn), + static_cast<int>(WebInputEvent::NumLockOn), NumLockMatches); COMPILE_ASSERT(static_cast<int>(PP_INPUTEVENT_MODIFIER_ISLEFT) == - static_cast<int>(WebInputEvent::IsLeft), + static_cast<int>(WebInputEvent::IsLeft), LeftMatches); COMPILE_ASSERT(static_cast<int>(PP_INPUTEVENT_MODIFIER_ISRIGHT) == - static_cast<int>(WebInputEvent::IsRight), + static_cast<int>(WebInputEvent::IsRight), RightMatches); PP_InputEvent_Type ConvertEventTypes(WebInputEvent::Type wetype) { @@ -127,7 +128,6 @@ InputEventData GetEventWithCommonFieldsAndType(const WebInputEvent& web_event) { InputEventData result; result.event_type = ConvertEventTypes(web_event.type); result.event_time_stamp = EventTimeToPPTimeTicks(web_event.timeStampSeconds); - result.usb_key_code = 0; return result; } @@ -138,7 +138,6 @@ void AppendKeyEvent(const WebInputEvent& event, InputEventData result = GetEventWithCommonFieldsAndType(event); result.event_modifiers = key_event.modifiers; result.key_code = key_event.windowsKeyCode; - result.usb_key_code = UsbKeyCodeForKeyboardEvent(key_event); result.code = CodeForKeyboardEvent(key_event); result_events->push_back(result); } @@ -174,20 +173,19 @@ void AppendCharEvent(const WebInputEvent& event, void AppendMouseEvent(const WebInputEvent& event, std::vector<InputEventData>* result_events) { COMPILE_ASSERT(static_cast<int>(WebMouseEvent::ButtonNone) == - static_cast<int>(PP_INPUTEVENT_MOUSEBUTTON_NONE), + static_cast<int>(PP_INPUTEVENT_MOUSEBUTTON_NONE), MouseNone); COMPILE_ASSERT(static_cast<int>(WebMouseEvent::ButtonLeft) == - static_cast<int>(PP_INPUTEVENT_MOUSEBUTTON_LEFT), + static_cast<int>(PP_INPUTEVENT_MOUSEBUTTON_LEFT), MouseLeft); COMPILE_ASSERT(static_cast<int>(WebMouseEvent::ButtonRight) == - static_cast<int>(PP_INPUTEVENT_MOUSEBUTTON_RIGHT), + static_cast<int>(PP_INPUTEVENT_MOUSEBUTTON_RIGHT), MouseRight); COMPILE_ASSERT(static_cast<int>(WebMouseEvent::ButtonMiddle) == - static_cast<int>(PP_INPUTEVENT_MOUSEBUTTON_MIDDLE), + static_cast<int>(PP_INPUTEVENT_MOUSEBUTTON_MIDDLE), MouseMiddle); - const WebMouseEvent& mouse_event = - static_cast<const WebMouseEvent&>(event); + const WebMouseEvent& mouse_event = static_cast<const WebMouseEvent&>(event); InputEventData result = GetEventWithCommonFieldsAndType(event); result.event_modifiers = mouse_event.modifiers; if (mouse_event.type == WebInputEvent::MouseDown || @@ -218,7 +216,8 @@ void AppendMouseWheelEvent(const WebInputEvent& event, result_events->push_back(result); } -void SetPPTouchPoints(const WebTouchPoint* touches, uint32_t touches_length, +void SetPPTouchPoints(const WebTouchPoint* touches, + uint32_t touches_length, std::vector<PP_TouchPoint>* result) { for (uint32_t i = 0; i < touches_length; i++) { const WebTouchPoint& touch_point = touches[i]; @@ -240,11 +239,13 @@ void AppendTouchEvent(const WebInputEvent& event, reinterpret_cast<const WebTouchEvent&>(event); InputEventData result = GetEventWithCommonFieldsAndType(event); - SetPPTouchPoints(touch_event.touches, touch_event.touchesLength, - &result.touches); - SetPPTouchPoints(touch_event.changedTouches, touch_event.changedTouchesLength, + SetPPTouchPoints( + touch_event.touches, touch_event.touchesLength, &result.touches); + SetPPTouchPoints(touch_event.changedTouches, + touch_event.changedTouchesLength, &result.changed_touches); - SetPPTouchPoints(touch_event.targetTouches, touch_event.targetTouchesLength, + SetPPTouchPoints(touch_event.targetTouches, + touch_event.targetTouchesLength, &result.target_touches); result_events->push_back(result); @@ -262,8 +263,9 @@ void SetWebTouchPoints(const std::vector<PP_TouchPoint>& pp_touches, WebTouchPoint* web_touches, uint32_t* web_touches_length) { - for (uint32_t i = 0; i < pp_touches.size() && - i < WebTouchEvent::touchesLengthCap; i++) { + for (uint32_t i = 0; + i < pp_touches.size() && i < WebTouchEvent::touchesLengthCap; + i++) { WebTouchPoint pt; const PP_TouchPoint& pp_pt = pp_touches[i]; pt.id = pp_pt.id; @@ -290,48 +292,55 @@ void SetWebTouchPoints(const std::vector<PP_TouchPoint>& pp_touches, WebTouchEvent* BuildTouchEvent(const InputEventData& event) { WebTouchEvent* web_event = new WebTouchEvent(); WebTouchPoint::State state = WebTouchPoint::StateUndefined; + WebInputEvent::Type type = WebInputEvent::Undefined; switch (event.event_type) { case PP_INPUTEVENT_TYPE_TOUCHSTART: - web_event->type = WebInputEvent::TouchStart; + type = WebInputEvent::TouchStart; state = WebTouchPoint::StatePressed; break; case PP_INPUTEVENT_TYPE_TOUCHMOVE: - web_event->type = WebInputEvent::TouchMove; + type = WebInputEvent::TouchMove; state = WebTouchPoint::StateMoved; break; case PP_INPUTEVENT_TYPE_TOUCHEND: - web_event->type = WebInputEvent::TouchEnd; + type = WebInputEvent::TouchEnd; state = WebTouchPoint::StateReleased; break; case PP_INPUTEVENT_TYPE_TOUCHCANCEL: - web_event->type = WebInputEvent::TouchCancel; + type = WebInputEvent::TouchCancel; state = WebTouchPoint::StateCancelled; break; default: NOTREACHED(); } + WebTouchEventTraits::ResetType( + type, PPTimeTicksToEventTime(event.event_time_stamp), web_event); TouchStateMap states_map; for (uint32_t i = 0; i < event.changed_touches.size(); i++) states_map[event.changed_touches[i].id] = state; - web_event->timeStampSeconds = PPTimeTicksToEventTime(event.event_time_stamp); - - SetWebTouchPoints(event.changed_touches, states_map, + SetWebTouchPoints(event.changed_touches, + states_map, web_event->changedTouches, &web_event->changedTouchesLength); - SetWebTouchPoints(event.touches, states_map, web_event->touches, - &web_event->touchesLength); + SetWebTouchPoints( + event.touches, states_map, web_event->touches, &web_event->touchesLength); - SetWebTouchPoints(event.target_touches, states_map, web_event->targetTouches, + SetWebTouchPoints(event.target_touches, + states_map, + web_event->targetTouches, &web_event->targetTouchesLength); if (web_event->type == WebInputEvent::TouchEnd || web_event->type == WebInputEvent::TouchCancel) { - SetWebTouchPoints(event.changed_touches, states_map, - web_event->touches, &web_event->touchesLength); - SetWebTouchPoints(event.changed_touches, states_map, + SetWebTouchPoints(event.changed_touches, + states_map, + web_event->touches, + &web_event->touchesLength); + SetWebTouchPoints(event.changed_touches, + states_map, web_event->targetTouches, &web_event->targetTouchesLength); } @@ -370,13 +379,11 @@ WebKeyboardEvent* BuildCharEvent(const InputEventData& event) { // Make sure to not read beyond the buffer in case some bad code doesn't // NULL-terminate it (this is called from plugins). size_t text_length_cap = WebKeyboardEvent::textLengthCap; - base::string16 text16 = UTF8ToUTF16(event.character_text); + base::string16 text16 = base::UTF8ToUTF16(event.character_text); memset(key_event->text, 0, text_length_cap); memset(key_event->unmodifiedText, 0, text_length_cap); - for (size_t i = 0; - i < std::min(text_length_cap, text16.size()); - ++i) + for (size_t i = 0; i < std::min(text_length_cap, text16.size()); ++i) key_event->text[i] = text16[i]; return key_event; } @@ -408,8 +415,7 @@ WebMouseEvent* BuildMouseEvent(const InputEventData& event) { mouse_event->timeStampSeconds = PPTimeTicksToEventTime(event.event_time_stamp); mouse_event->modifiers = event.event_modifiers; - mouse_event->button = - static_cast<WebMouseEvent::Button>(event.mouse_button); + mouse_event->button = static_cast<WebMouseEvent::Button>(event.mouse_button); if (mouse_event->type == WebInputEvent::MouseMove) { if (mouse_event->modifiers & WebInputEvent::LeftButtonDown) mouse_event->button = WebMouseEvent::ButtonLeft; @@ -441,27 +447,27 @@ WebMouseWheelEvent* BuildMouseWheelEvent(const InputEventData& event) { } #if !defined(OS_WIN) -#define VK_RETURN 0x0D - -#define VK_PRIOR 0x21 -#define VK_NEXT 0x22 -#define VK_END 0x23 -#define VK_HOME 0x24 -#define VK_LEFT 0x25 -#define VK_UP 0x26 -#define VK_RIGHT 0x27 -#define VK_DOWN 0x28 -#define VK_SNAPSHOT 0x2C -#define VK_INSERT 0x2D -#define VK_DELETE 0x2E - -#define VK_APPS 0x5D - -#define VK_F1 0x70 +#define VK_RETURN 0x0D + +#define VK_PRIOR 0x21 +#define VK_NEXT 0x22 +#define VK_END 0x23 +#define VK_HOME 0x24 +#define VK_LEFT 0x25 +#define VK_UP 0x26 +#define VK_RIGHT 0x27 +#define VK_DOWN 0x28 +#define VK_SNAPSHOT 0x2C +#define VK_INSERT 0x2D +#define VK_DELETE 0x2E + +#define VK_APPS 0x5D + +#define VK_F1 0x70 #endif // Convert a character string to a Windows virtual key code. Adapted from -// src/third_party/WebKit/Tools/DumpRenderTree/chromium/EventSender.cpp. This +// src/content/shell/renderer/test_runner/event_sender.cc. This // is used by CreateSimulatedWebInputEvents to convert keyboard events. void GetKeyCode(const std::string& char_text, WebUChar* code, @@ -517,7 +523,7 @@ void GetKeyCode(const std::string& char_text, *needs_shift_modifier = (vk_code & 0xFF) >= 'A' && (vk_code & 0xFF) <= 'Z'; if ((vk_code & 0xFF) >= 'a' && (vk_code & 0xFF) <= 'z') - vk_code -= 'a' - 'A'; + vk_code -= 'a' - 'A'; *generate_char = true; } } @@ -608,7 +614,7 @@ WebInputEvent* CreateWebInputEvent(const InputEventData& event) { } // Generate a coherent sequence of input events to simulate a user event. -// From src/third_party/WebKit/Tools/DumpRenderTree/chromium/EventSender.cpp. +// From src/content/shell/renderer/test_runner/event_sender.cc. std::vector<linked_ptr<WebInputEvent> > CreateSimulatedWebInputEvents( const ppapi::InputEventData& event, int plugin_x, @@ -641,7 +647,7 @@ std::vector<linked_ptr<WebInputEvent> > CreateSimulatedWebInputEvents( case PP_INPUTEVENT_TYPE_RAWKEYDOWN: case PP_INPUTEVENT_TYPE_KEYDOWN: case PP_INPUTEVENT_TYPE_KEYUP: { - // Windows key down events should always be "raw" to avoid an ASSERT. +// Windows key down events should always be "raw" to avoid an ASSERT. #if defined(OS_WIN) WebKeyboardEvent* web_keyboard_event = static_cast<WebKeyboardEvent*>(original_event.get()); diff --git a/chromium/content/renderer/pepper/event_conversion.h b/chromium/content/renderer/pepper/event_conversion.h index 81aa6b3acf7..59b8678ada8 100644 --- a/chromium/content/renderer/pepper/event_conversion.h +++ b/chromium/content/renderer/pepper/event_conversion.h @@ -28,7 +28,7 @@ namespace content { // The generated events will be filled into the given vector. On failure, no // events will ge generated and the vector will be empty. void CreateInputEventData(const blink::WebInputEvent& event, - std::vector<ppapi::InputEventData >* pp_events); + std::vector<ppapi::InputEventData>* pp_events); // Creates a WebInputEvent from the given PP_InputEvent. If it fails, returns // NULL. The caller owns the created object on success. diff --git a/chromium/content/renderer/pepper/fake_pepper_plugin_instance.cc b/chromium/content/renderer/pepper/fake_pepper_plugin_instance.cc index af0ba49c0ee..e00c1eeed2f 100644 --- a/chromium/content/renderer/pepper/fake_pepper_plugin_instance.cc +++ b/chromium/content/renderer/pepper/fake_pepper_plugin_instance.cc @@ -11,25 +11,17 @@ namespace content { FakePepperPluginInstance::~FakePepperPluginInstance() {} -content::RenderView* FakePepperPluginInstance::GetRenderView() { - return NULL; -} +content::RenderView* FakePepperPluginInstance::GetRenderView() { return NULL; } blink::WebPluginContainer* FakePepperPluginInstance::GetContainer() { return NULL; } -v8::Isolate* FakePepperPluginInstance::GetIsolate() const { - return NULL; -} +v8::Isolate* FakePepperPluginInstance::GetIsolate() const { return NULL; } -ppapi::VarTracker* FakePepperPluginInstance::GetVarTracker() { - return NULL; -} +ppapi::VarTracker* FakePepperPluginInstance::GetVarTracker() { return NULL; } -const GURL& FakePepperPluginInstance::GetPluginURL() { - return gurl_; -} +const GURL& FakePepperPluginInstance::GetPluginURL() { return gurl_; } base::FilePath FakePepperPluginInstance::GetModulePath() { return base::FilePath(); @@ -51,9 +43,7 @@ PP_ExternalPluginResult FakePepperPluginInstance::SwitchToOutOfProcessProxy( void FakePepperPluginInstance::SetAlwaysOnTop(bool on_top) {} -bool FakePepperPluginInstance::IsFullPagePlugin() { - return false; -} +bool FakePepperPluginInstance::IsFullPagePlugin() { return false; } bool FakePepperPluginInstance::FlashSetFullscreen(bool fullscreen, bool delay_report) { @@ -78,4 +68,12 @@ int FakePepperPluginInstance::MakePendingFileRefRendererHost( void FakePepperPluginInstance::SetEmbedProperty(PP_Var key, PP_Var value) {} +void FakePepperPluginInstance::SetSelectedText( + const base::string16& selected_text) {} + +void FakePepperPluginInstance::SetLinkUnderCursor(const std::string& url) {} +void FakePepperPluginInstance::SetTextInputType(ui::TextInputType type) {} +void FakePepperPluginInstance::PostMessageToJavaScript(PP_Var message) {} + + } // namespace content diff --git a/chromium/content/renderer/pepper/fake_pepper_plugin_instance.h b/chromium/content/renderer/pepper/fake_pepper_plugin_instance.h index f492b33facb..99a0cee43a4 100644 --- a/chromium/content/renderer/pepper/fake_pepper_plugin_instance.h +++ b/chromium/content/renderer/pepper/fake_pepper_plugin_instance.h @@ -36,9 +36,13 @@ class FakePepperPluginInstance : public PepperPluginInstance { virtual int32_t Navigate(const ppapi::URLRequestInfoData& request, const char* target, bool from_user_action) OVERRIDE; - virtual int MakePendingFileRefRendererHost( - const base::FilePath& path) OVERRIDE; + virtual int MakePendingFileRefRendererHost(const base::FilePath& path) + OVERRIDE; virtual void SetEmbedProperty(PP_Var key, PP_Var value) OVERRIDE; + virtual void SetSelectedText(const base::string16& selected_text) OVERRIDE; + virtual void SetLinkUnderCursor(const std::string& url) OVERRIDE; + virtual void SetTextInputType(ui::TextInputType type) OVERRIDE; + virtual void PostMessageToJavaScript(PP_Var message) OVERRIDE; private: GURL gurl_; diff --git a/chromium/content/renderer/pepper/gfx_conversion.h b/chromium/content/renderer/pepper/gfx_conversion.h index 3b504bac7fe..1c1fa11a333 100644 --- a/chromium/content/renderer/pepper/gfx_conversion.h +++ b/chromium/content/renderer/pepper/gfx_conversion.h @@ -10,6 +10,7 @@ #include "ppapi/c/pp_size.h" #include "ui/gfx/point.h" #include "ui/gfx/rect.h" +#include "ui/gfx/rect_f.h" #include "ui/gfx/size.h" // Conversions for graphics types between our gfx library and PPAPI. @@ -29,6 +30,10 @@ inline gfx::Rect PP_ToGfxRect(const PP_Rect& r) { return gfx::Rect(r.point.x, r.point.y, r.size.width, r.size.height); } +inline gfx::RectF PP_ToGfxRectF(const PP_FloatRect& r) { + return gfx::RectF(r.point.x, r.point.y, r.size.width, r.size.height); +} + inline PP_Rect PP_FromGfxRect(const gfx::Rect& r) { return PP_MakeRectFromXYWH(r.x(), r.y(), r.width(), r.height()); } diff --git a/chromium/content/renderer/pepper/host_array_buffer_var.cc b/chromium/content/renderer/pepper/host_array_buffer_var.cc index d8d4cec8bf9..ad8e97b46bf 100644 --- a/chromium/content/renderer/pepper/host_array_buffer_var.cc +++ b/chromium/content/renderer/pepper/host_array_buffer_var.cc @@ -24,13 +24,10 @@ namespace content { HostArrayBufferVar::HostArrayBufferVar(uint32 size_in_bytes) : buffer_(WebArrayBuffer::create(size_in_bytes, 1 /* element_size */)), - valid_(true) { -} + valid_(true) {} HostArrayBufferVar::HostArrayBufferVar(const WebArrayBuffer& buffer) - : buffer_(buffer), - valid_(true) { -} + : buffer_(buffer), valid_(true) {} HostArrayBufferVar::HostArrayBufferVar(uint32 size_in_bytes, base::SharedMemoryHandle handle) @@ -43,8 +40,7 @@ HostArrayBufferVar::HostArrayBufferVar(uint32 size_in_bytes, } } -HostArrayBufferVar::~HostArrayBufferVar() { -} +HostArrayBufferVar::~HostArrayBufferVar() {} void* HostArrayBufferVar::Map() { if (!valid_) @@ -56,17 +52,16 @@ void HostArrayBufferVar::Unmap() { // We do not used shared memory on the host side. Nothing to do. } -uint32 HostArrayBufferVar::ByteLength() { - return buffer_.byteLength(); -} +uint32 HostArrayBufferVar::ByteLength() { return buffer_.byteLength(); } bool HostArrayBufferVar::CopyToNewShmem( PP_Instance instance, int* host_shm_handle_id, base::SharedMemoryHandle* plugin_shm_handle) { scoped_ptr<base::SharedMemory> shm( - RenderThread::Get()->HostAllocateSharedMemoryBuffer(ByteLength()). - release()); + RenderThread::Get() + ->HostAllocateSharedMemoryBuffer(ByteLength()) + .release()); if (!shm) return false; @@ -79,7 +74,7 @@ bool HostArrayBufferVar::CopyToNewShmem( HostGlobals* hg = HostGlobals::Get(); PluginModule* pm = hg->GetModule(hg->GetModuleForInstance(instance)); base::ProcessId p = pm->GetPeerProcessId(); - if (p == base::kNullProcessId) { + if (p == base::kNullProcessId) { // In-process, clone for ourselves. p = base::GetCurrentProcId(); } diff --git a/chromium/content/renderer/pepper/host_array_buffer_var.h b/chromium/content/renderer/pepper/host_array_buffer_var.h index 13bd80630de..12ae7291221 100644 --- a/chromium/content/renderer/pepper/host_array_buffer_var.h +++ b/chromium/content/renderer/pepper/host_array_buffer_var.h @@ -25,10 +25,10 @@ class HostArrayBufferVar : public ppapi::ArrayBufferVar { virtual void* Map() OVERRIDE; virtual void Unmap() OVERRIDE; virtual uint32 ByteLength() OVERRIDE; - virtual bool CopyToNewShmem( - PP_Instance instance, - int* host_shm_handle_id, - base::SharedMemoryHandle* plugin_shm_handle) OVERRIDE; + virtual bool CopyToNewShmem(PP_Instance instance, + int* host_shm_handle_id, + base::SharedMemoryHandle* plugin_shm_handle) + OVERRIDE; blink::WebArrayBuffer& webkit_buffer() { return buffer_; } diff --git a/chromium/content/renderer/pepper/host_dispatcher_wrapper.cc b/chromium/content/renderer/pepper/host_dispatcher_wrapper.cc index 8707d94b1a8..606d2815c41 100644 --- a/chromium/content/renderer/pepper/host_dispatcher_wrapper.cc +++ b/chromium/content/renderer/pepper/host_dispatcher_wrapper.cc @@ -11,7 +11,7 @@ #include "content/renderer/pepper/plugin_module.h" #include "content/renderer/pepper/renderer_ppapi_host_impl.h" #include "content/renderer/pepper/renderer_restrict_dispatch_group.h" -#include "content/renderer/render_view_impl.h" +#include "content/renderer/render_frame_impl.h" namespace content { @@ -25,11 +25,9 @@ HostDispatcherWrapper::HostDispatcherWrapper( peer_pid_(peer_pid), plugin_child_id_(plugin_child_id), permissions_(perms), - is_external_(is_external) { -} + is_external_(is_external) {} -HostDispatcherWrapper::~HostDispatcherWrapper() { -} +HostDispatcherWrapper::~HostDispatcherWrapper() {} bool HostDispatcherWrapper::Init(const IPC::ChannelHandle& channel_handle, PP_GetInterface_Func local_get_interface, @@ -76,14 +74,14 @@ void HostDispatcherWrapper::AddInstance(PP_Instance instance) { // always give us an instance we can find in the map otherwise, but that // isn't true for browser tag support. if (host) { - RenderView* render_view = host->GetRenderViewForInstance(instance); + RenderFrame* render_frame = host->GetRenderFrameForInstance(instance); PepperPluginInstance* plugin_instance = host->GetPluginInstance(instance); - render_view->Send(new ViewHostMsg_DidCreateOutOfProcessPepperInstance( + render_frame->Send(new ViewHostMsg_DidCreateOutOfProcessPepperInstance( plugin_child_id_, instance, PepperRendererInstanceData( 0, // The render process id will be supplied in the browser. - render_view->GetRoutingID(), + render_frame->GetRoutingID(), host->GetDocumentURL(instance), plugin_instance->GetPluginURL()), is_external_)); @@ -97,11 +95,11 @@ void HostDispatcherWrapper::RemoveInstance(PP_Instance instance) { RendererPpapiHostImpl::GetForPPInstance(instance); // TODO(brettw) remove null check as described in AddInstance. if (host) { - RenderView* render_view = host->GetRenderViewForInstance(instance); - render_view->Send(new ViewHostMsg_DidDeleteOutOfProcessPepperInstance( - plugin_child_id_, - instance, - is_external_)); + RenderFrame* render_frame = host->GetRenderFrameForInstance(instance); + if (render_frame) { + render_frame->Send(new ViewHostMsg_DidDeleteOutOfProcessPepperInstance( + plugin_child_id_, instance, is_external_)); + } } } diff --git a/chromium/content/renderer/pepper/host_globals.cc b/chromium/content/renderer/pepper/host_globals.cc index 31c5f0bd410..c8c44fa560f 100644 --- a/chromium/content/renderer/pepper/host_globals.cc +++ b/chromium/content/renderer/pepper/host_globals.cc @@ -22,7 +22,7 @@ #include "third_party/WebKit/public/web/WebConsoleMessage.h" #include "third_party/WebKit/public/web/WebDocument.h" #include "third_party/WebKit/public/web/WebElement.h" -#include "third_party/WebKit/public/web/WebFrame.h" +#include "third_party/WebKit/public/web/WebLocalFrame.h" #include "third_party/WebKit/public/web/WebPluginContainer.h" using ppapi::CheckIdType; @@ -30,22 +30,29 @@ using ppapi::MakeTypedId; using ppapi::PPIdType; using ppapi::ResourceTracker; using blink::WebConsoleMessage; +using blink::WebLocalFrame; +using blink::WebPluginContainer; using blink::WebString; namespace content { namespace { -typedef std::set<blink::WebPluginContainer*> ContainerSet; +typedef std::set<WebPluginContainer*> ContainerSet; // Adds all WebPluginContainers associated with the given module to the set. -void GetAllContainersForModule(PluginModule* module, - ContainerSet* containers) { - const PluginModule::PluginInstanceSet& instances = - module->GetAllInstances(); +void GetAllContainersForModule(PluginModule* module, ContainerSet* containers) { + const PluginModule::PluginInstanceSet& instances = module->GetAllInstances(); for (PluginModule::PluginInstanceSet::const_iterator i = instances.begin(); - i != instances.end(); ++i) - containers->insert((*i)->container()); + i != instances.end(); + ++i) { + WebPluginContainer* container = (*i)->container(); + // If "Delete" is called on an instance, the instance sets its container to + // NULL, but the instance may actually outlive its container. Callers of + // GetAllContainersForModule only want to know about valid containers. + if (container) + containers->insert(container); + } } WebConsoleMessage::Level LogLevelToWebLogLevel(PP_LogLevel level) { @@ -70,7 +77,7 @@ WebConsoleMessage MakeLogMessage(PP_LogLevel level, result.append(": "); result.append(message); return WebConsoleMessage(LogLevelToWebLogLevel(level), - WebString(UTF8ToUTF16(result))); + WebString(base::UTF8ToUTF16(result))); } } // namespace @@ -96,9 +103,7 @@ ppapi::ResourceTracker* HostGlobals::GetResourceTracker() { return &resource_tracker_; } -ppapi::VarTracker* HostGlobals::GetVarTracker() { - return &host_var_tracker_; -} +ppapi::VarTracker* HostGlobals::GetVarTracker() { return &host_var_tracker_; } ppapi::CallbackTracker* HostGlobals::GetCallbackTrackerForInstance( PP_Instance instance) { @@ -145,8 +150,11 @@ void HostGlobals::LogWithSource(PP_Instance instance, PepperPluginInstanceImpl* instance_object = HostGlobals::Get()->GetInstance(instance); if (instance_object) { - instance_object->container()->element().document().frame()-> - addMessageToConsole(MakeLogMessage(level, source, value)); + instance_object->container() + ->element() + .document() + .frame() + ->addMessageToConsole(MakeLogMessage(level, source, value)); } else { BroadcastLogWithSource(0, level, source, value); } @@ -166,30 +174,33 @@ void HostGlobals::BroadcastLogWithSource(PP_Module pp_module, } else { // Unknown module, get containers for all modules. for (ModuleMap::const_iterator i = module_map_.begin(); - i != module_map_.end(); ++i) { + i != module_map_.end(); + ++i) { GetAllContainersForModule(i->second, &containers); } } WebConsoleMessage message = MakeLogMessage(level, source, value); - for (ContainerSet::iterator i = containers.begin(); - i != containers.end(); ++i) - (*i)->element().document().frame()->addMessageToConsole(message); + for (ContainerSet::iterator i = containers.begin(); i != containers.end(); + ++i) { + WebLocalFrame* frame = (*i)->element().document().frame(); + if (frame) + frame->addMessageToConsole(message); + } } base::TaskRunner* HostGlobals::GetFileTaskRunner() { return RenderThreadImpl::current()->GetFileThreadMessageLoopProxy().get(); } -ppapi::MessageLoopShared* HostGlobals::GetCurrentMessageLoop() { - return NULL; -} +ppapi::MessageLoopShared* HostGlobals::GetCurrentMessageLoop() { return NULL; } PP_Module HostGlobals::AddModule(PluginModule* module) { #ifndef NDEBUG // Make sure we're not adding one more than once. for (ModuleMap::const_iterator i = module_map_.begin(); - i != module_map_.end(); ++i) + i != module_map_.end(); + ++i) DCHECK(i->second != module); #endif @@ -198,8 +209,7 @@ PP_Module HostGlobals::AddModule(PluginModule* module) { do { new_module = MakeTypedId(static_cast<PP_Module>(base::RandUint64()), ppapi::PP_ID_TYPE_MODULE); - } while (!new_module || - module_map_.find(new_module) != module_map_.end()); + } while (!new_module || module_map_.find(new_module) != module_map_.end()); module_map_[new_module] = module; return new_module; } @@ -265,8 +275,6 @@ PepperPluginInstanceImpl* HostGlobals::GetInstance(PP_Instance instance) { return found->second; } -bool HostGlobals::IsHostGlobals() const { - return true; -} +bool HostGlobals::IsHostGlobals() const { return true; } } // namespace content diff --git a/chromium/content/renderer/pepper/host_globals.h b/chromium/content/renderer/pepper/host_globals.h index 9d1b289d506..f91a65c7818 100644 --- a/chromium/content/renderer/pepper/host_globals.h +++ b/chromium/content/renderer/pepper/host_globals.h @@ -35,8 +35,8 @@ class HostGlobals : public ppapi::PpapiGlobals { virtual ppapi::VarTracker* GetVarTracker() OVERRIDE; virtual ppapi::CallbackTracker* GetCallbackTrackerForInstance( PP_Instance instance) OVERRIDE; - virtual ppapi::thunk::PPB_Instance_API* GetInstanceAPI( - PP_Instance instance) OVERRIDE; + virtual ppapi::thunk::PPB_Instance_API* GetInstanceAPI(PP_Instance instance) + OVERRIDE; virtual ppapi::thunk::ResourceCreationAPI* GetResourceCreationAPI( PP_Instance instance) OVERRIDE; virtual PP_Module GetModuleForInstance(PP_Instance instance) OVERRIDE; @@ -53,9 +53,7 @@ class HostGlobals : public ppapi::PpapiGlobals { virtual ppapi::MessageLoopShared* GetCurrentMessageLoop() OVERRIDE; virtual base::TaskRunner* GetFileTaskRunner() OVERRIDE; - HostVarTracker* host_var_tracker() { - return &host_var_tracker_; - } + HostVarTracker* host_var_tracker() { return &host_var_tracker_; } // PP_Modules ---------------------------------------------------------------- @@ -111,4 +109,4 @@ class HostGlobals : public ppapi::PpapiGlobals { } // namespace content -#endif // CONTENT_RENDERER_PEPPER_HOST_GLOBALS_H_ +#endif // CONTENT_RENDERER_PEPPER_HOST_GLOBALS_H_ diff --git a/chromium/content/renderer/pepper/host_resource_var.cc b/chromium/content/renderer/pepper/host_resource_var.cc index 810a949965e..f67f4d65c7c 100644 --- a/chromium/content/renderer/pepper/host_resource_var.cc +++ b/chromium/content/renderer/pepper/host_resource_var.cc @@ -20,9 +20,7 @@ HostResourceVar::HostResourceVar(int pending_renderer_host_id, pending_browser_host_id_(0), creation_message_(new IPC::Message(creation_message)) {} -PP_Resource HostResourceVar::GetPPResource() const { - return pp_resource_; -} +PP_Resource HostResourceVar::GetPPResource() const { return pp_resource_; } int HostResourceVar::GetPendingRendererHostId() const { return pending_renderer_host_id_; diff --git a/chromium/content/renderer/pepper/host_resource_var.h b/chromium/content/renderer/pepper/host_resource_var.h index cc6b0577f4d..1e8928a94f5 100644 --- a/chromium/content/renderer/pepper/host_resource_var.h +++ b/chromium/content/renderer/pepper/host_resource_var.h @@ -38,9 +38,7 @@ class HostResourceVar : public ppapi::ResourceVar { virtual const IPC::Message* GetCreationMessage() const OVERRIDE; virtual bool IsPending() const OVERRIDE; - void set_pending_browser_host_id(int id) { - pending_browser_host_id_ = id; - } + void set_pending_browser_host_id(int id) { pending_browser_host_id_ = id; } protected: virtual ~HostResourceVar(); diff --git a/chromium/content/renderer/pepper/host_var_tracker.cc b/chromium/content/renderer/pepper/host_var_tracker.cc index 27f2977b08e..700fbaf28be 100644 --- a/chromium/content/renderer/pepper/host_var_tracker.cc +++ b/chromium/content/renderer/pepper/host_var_tracker.cc @@ -17,12 +17,9 @@ using ppapi::NPObjectVar; namespace content { HostVarTracker::HostVarTracker() - : VarTracker(SINGLE_THREADED), - last_shared_memory_map_id_(0) { -} + : VarTracker(SINGLE_THREADED), last_shared_memory_map_id_(0) {} -HostVarTracker::~HostVarTracker() { -} +HostVarTracker::~HostVarTracker() {} ArrayBufferVar* HostVarTracker::CreateArrayBuffer(uint32 size_in_bytes) { return new HostArrayBufferVar(size_in_bytes); @@ -37,28 +34,29 @@ ArrayBufferVar* HostVarTracker::CreateShmArrayBuffer( void HostVarTracker::AddNPObjectVar(NPObjectVar* object_var) { CheckThreadingPreconditions(); - InstanceMap::iterator found_instance = instance_map_.find( - object_var->pp_instance()); + InstanceMap::iterator found_instance = + instance_map_.find(object_var->pp_instance()); if (found_instance == instance_map_.end()) { // Lazily create the instance map. DCHECK(object_var->pp_instance() != 0); - found_instance = instance_map_.insert(std::make_pair( - object_var->pp_instance(), - linked_ptr<NPObjectToNPObjectVarMap>(new NPObjectToNPObjectVarMap))). - first; + found_instance = + instance_map_.insert(std::make_pair( + object_var->pp_instance(), + linked_ptr<NPObjectToNPObjectVarMap>( + new NPObjectToNPObjectVarMap))).first; } NPObjectToNPObjectVarMap* np_object_map = found_instance->second.get(); - DCHECK(np_object_map->find(object_var->np_object()) == - np_object_map->end()) << "NPObjectVar already in map"; + DCHECK(np_object_map->find(object_var->np_object()) == np_object_map->end()) + << "NPObjectVar already in map"; np_object_map->insert(std::make_pair(object_var->np_object(), object_var)); } void HostVarTracker::RemoveNPObjectVar(NPObjectVar* object_var) { CheckThreadingPreconditions(); - InstanceMap::iterator found_instance = instance_map_.find( - object_var->pp_instance()); + InstanceMap::iterator found_instance = + instance_map_.find(object_var->pp_instance()); if (found_instance == instance_map_.end()) { NOTREACHED() << "NPObjectVar has invalid instance."; return; diff --git a/chromium/content/renderer/pepper/host_var_tracker.h b/chromium/content/renderer/pepper/host_var_tracker.h index 5ab4df458ba..6abbf869765 100644 --- a/chromium/content/renderer/pepper/host_var_tracker.h +++ b/chromium/content/renderer/pepper/host_var_tracker.h @@ -51,8 +51,7 @@ class HostVarTracker : public ppapi::VarTracker { // Returns the number of NPObjectVar's associated with the given instance. // Returns 0 if the instance isn't known. - CONTENT_EXPORT int GetLiveNPObjectVarsForInstance( - PP_Instance instance) const; + CONTENT_EXPORT int GetLiveNPObjectVarsForInstance(PP_Instance instance) const; // VarTracker public implementation. virtual PP_Var MakeResourcePPVarFromMessage( @@ -73,10 +72,11 @@ class HostVarTracker : public ppapi::VarTracker { private: // VarTracker private implementation. - virtual ppapi::ArrayBufferVar* CreateArrayBuffer( - uint32 size_in_bytes) OVERRIDE; + virtual ppapi::ArrayBufferVar* CreateArrayBuffer(uint32 size_in_bytes) + OVERRIDE; virtual ppapi::ArrayBufferVar* CreateShmArrayBuffer( - uint32 size_in_bytes, base::SharedMemoryHandle handle) OVERRIDE; + uint32 size_in_bytes, + base::SharedMemoryHandle handle) OVERRIDE; // Clear the reference count of the given object and remove it from // live_vars_. diff --git a/chromium/content/renderer/pepper/host_var_tracker_unittest.cc b/chromium/content/renderer/pepper/host_var_tracker_unittest.cc index 048680558d7..07b759dce69 100644 --- a/chromium/content/renderer/pepper/host_var_tracker_unittest.cc +++ b/chromium/content/renderer/pepper/host_var_tracker_unittest.cc @@ -31,19 +31,8 @@ void TrackedClassDeallocate(NPObject* npobject) { } NPClass g_tracked_npclass = { - NP_CLASS_STRUCT_VERSION, - NULL, - &TrackedClassDeallocate, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, -}; + NP_CLASS_STRUCT_VERSION, NULL, &TrackedClassDeallocate, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, }; // Returns a new tracked NPObject with a refcount of 1. You'll want to put this // in a NPObjectReleaser to free this ref when the test completes. @@ -56,27 +45,21 @@ NPObject* NewTrackedNPObject() { return object; } -class ReleaseNPObject { - public: - void operator()(NPObject* o) const { - blink::WebBindings::releaseObject(o); - } +struct ReleaseNPObject { + void operator()(NPObject* o) const { blink::WebBindings::releaseObject(o); } }; // Handles automatically releasing a reference to the NPObject on destruction. // It's assumed the input has a ref already taken. -typedef scoped_ptr_malloc<NPObject, ReleaseNPObject> NPObjectReleaser; +typedef scoped_ptr<NPObject, ReleaseNPObject> NPObjectReleaser; } // namespace class HostVarTrackerTest : public PpapiUnittest { public: - HostVarTrackerTest() { - } + HostVarTrackerTest() {} - HostVarTracker& tracker() { - return *HostGlobals::Get()->host_var_tracker(); - } + HostVarTracker& tracker() { return *HostGlobals::Get()->host_var_tracker(); } }; TEST_F(HostVarTrackerTest, DeleteObjectVarWithInstance) { @@ -119,8 +102,7 @@ TEST_F(HostVarTrackerTest, ReuseVar) { } // Remove both of the refs we made above. - ppapi::VarTracker* var_tracker = - ppapi::PpapiGlobals::Get()->GetVarTracker(); + ppapi::VarTracker* var_tracker = ppapi::PpapiGlobals::Get()->GetVarTracker(); var_tracker->ReleaseVar(static_cast<int32_t>(pp_object2.value.as_id)); var_tracker->ReleaseVar(static_cast<int32_t>(pp_object1.value.as_id)); diff --git a/chromium/content/renderer/pepper/message_channel.cc b/chromium/content/renderer/pepper/message_channel.cc index 51132a6dc42..2fd4410bda3 100644 --- a/chromium/content/renderer/pepper/message_channel.cc +++ b/chromium/content/renderer/pepper/message_channel.cc @@ -23,7 +23,7 @@ #include "third_party/WebKit/public/web/WebDocument.h" #include "third_party/WebKit/public/web/WebDOMMessageEvent.h" #include "third_party/WebKit/public/web/WebElement.h" -#include "third_party/WebKit/public/web/WebFrame.h" +#include "third_party/WebKit/public/web/WebLocalFrame.h" #include "third_party/WebKit/public/web/WebNode.h" #include "third_party/WebKit/public/web/WebPluginContainer.h" #include "third_party/WebKit/public/web/WebSerializedScriptValue.h" @@ -31,6 +31,7 @@ using ppapi::ArrayBufferVar; using ppapi::PpapiGlobals; +using ppapi::ScopedPPVar; using ppapi::StringVar; using blink::WebBindings; using blink::WebElement; @@ -44,18 +45,21 @@ namespace content { namespace { const char kPostMessage[] = "postMessage"; -const char kV8ToVarConversionError[] = "Failed to convert a PostMessage " +const char kPostMessageAndAwaitResponse[] = "postMessageAndAwaitResponse"; +const char kV8ToVarConversionError[] = + "Failed to convert a PostMessage " "argument from a JavaScript value to a PP_Var. It may have cycles or be of " "an unsupported type."; -const char kVarToV8ConversionError[] = "Failed to convert a PostMessage " +const char kVarToV8ConversionError[] = + "Failed to convert a PostMessage " "argument from a PP_Var to a Javascript value. It may have cycles or be of " "an unsupported type."; // Helper function to get the MessageChannel that is associated with an // NPObject*. MessageChannel* ToMessageChannel(NPObject* object) { - return static_cast<MessageChannel::MessageChannelNPObject*>(object)-> - message_channel.get(); + return static_cast<MessageChannel::MessageChannelNPObject*>(object) + ->message_channel.get(); } NPObject* ToPassThroughObject(NPObject* object) { @@ -63,55 +67,17 @@ NPObject* ToPassThroughObject(NPObject* object) { return channel ? channel->passthrough_object() : NULL; } -// Helper function to determine if a given identifier is equal to kPostMessage. -bool IdentifierIsPostMessage(NPIdentifier identifier) { - return WebBindings::getStringIdentifier(kPostMessage) == identifier; +// Return true iff |identifier| is equal to |string|. +bool IdentifierIs(NPIdentifier identifier, const char string[]) { + return WebBindings::getStringIdentifier(string) == identifier; } -// Copy a PP_Var in to a PP_Var that is appropriate for sending via postMessage. -// This currently just copies the value. For a string Var, the result is a -// PP_Var with the a copy of |var|'s string contents and a reference count of 1. -PP_Var CopyPPVar(const PP_Var& var) { - switch (var.type) { - case PP_VARTYPE_UNDEFINED: - case PP_VARTYPE_NULL: - case PP_VARTYPE_BOOL: - case PP_VARTYPE_INT32: - case PP_VARTYPE_DOUBLE: - return var; - case PP_VARTYPE_STRING: { - StringVar* string = StringVar::FromPPVar(var); - if (!string) - return PP_MakeUndefined(); - return StringVar::StringToPPVar(string->value()); - } - case PP_VARTYPE_ARRAY_BUFFER: { - ArrayBufferVar* buffer = ArrayBufferVar::FromPPVar(var); - if (!buffer) - return PP_MakeUndefined(); - PP_Var new_buffer_var = PpapiGlobals::Get()->GetVarTracker()-> - MakeArrayBufferPPVar(buffer->ByteLength()); - DCHECK(new_buffer_var.type == PP_VARTYPE_ARRAY_BUFFER); - if (new_buffer_var.type != PP_VARTYPE_ARRAY_BUFFER) - return PP_MakeUndefined(); - ArrayBufferVar* new_buffer = ArrayBufferVar::FromPPVar(new_buffer_var); - DCHECK(new_buffer); - if (!new_buffer) - return PP_MakeUndefined(); - memcpy(new_buffer->Map(), buffer->Map(), buffer->ByteLength()); - return new_buffer_var; - } - case PP_VARTYPE_OBJECT: - case PP_VARTYPE_ARRAY: - case PP_VARTYPE_DICTIONARY: - case PP_VARTYPE_RESOURCE: - // These types are not supported by PostMessage in-process. In some rare - // cases with the NaCl plugin, they may be sent but they will be dropped - // anyway (see crbug.com/318837 for details). - return PP_MakeUndefined(); - } - NOTREACHED(); - return PP_MakeUndefined(); +bool HasDevChannelPermission(NPObject* channel_object) { + MessageChannel* channel = ToMessageChannel(channel_object); + if (!channel) + return false; + return channel->instance()->module()->permissions().HasPermission( + ppapi::PERMISSION_DEV_CHANNEL); } //------------------------------------------------------------------------------ @@ -134,10 +100,12 @@ bool MessageChannelHasMethod(NPObject* np_obj, NPIdentifier name) { if (!np_obj) return false; - // We only handle a function called postMessage. - if (IdentifierIsPostMessage(name)) + if (IdentifierIs(name, kPostMessage)) return true; - + if (IdentifierIs(name, kPostMessageAndAwaitResponse) && + HasDevChannelPermission(np_obj)) { + return true; + } // Other method names we will pass to the passthrough object, if we have one. NPObject* passthrough = ToPassThroughObject(np_obj); if (passthrough) @@ -145,27 +113,34 @@ bool MessageChannelHasMethod(NPObject* np_obj, NPIdentifier name) { return false; } -bool MessageChannelInvoke(NPObject* np_obj, NPIdentifier name, - const NPVariant* args, uint32 arg_count, +bool MessageChannelInvoke(NPObject* np_obj, + NPIdentifier name, + const NPVariant* args, + uint32 arg_count, NPVariant* result) { if (!np_obj) return false; - // We only handle a function called postMessage. - if (IdentifierIsPostMessage(name) && (arg_count == 1)) { - MessageChannel* message_channel = ToMessageChannel(np_obj); - if (message_channel) { - message_channel->NPVariantToPPVar(&args[0]); - return true; - } else { - return false; - } + MessageChannel* message_channel = ToMessageChannel(np_obj); + if (!message_channel) + return false; + + // Check to see if we should handle this function ourselves. + if (IdentifierIs(name, kPostMessage) && (arg_count == 1)) { + message_channel->PostMessageToNative(&args[0]); + return true; + } else if (IdentifierIs(name, kPostMessageAndAwaitResponse) && + (arg_count == 1) && + HasDevChannelPermission(np_obj)) { + message_channel->PostBlockingMessageToNative(&args[0], result); + return true; } + // Other method calls we will pass to the passthrough object, if we have one. NPObject* passthrough = ToPassThroughObject(np_obj); if (passthrough) { - return WebBindings::invoke(NULL, passthrough, name, args, arg_count, - result); + return WebBindings::invoke( + NULL, passthrough, name, args, arg_count, result); } return false; } @@ -180,8 +155,8 @@ bool MessageChannelInvokeDefault(NPObject* np_obj, // Invoke on the passthrough object, if we have one. NPObject* passthrough = ToPassThroughObject(np_obj); if (passthrough) { - return WebBindings::invokeDefault(NULL, passthrough, args, arg_count, - result); + return WebBindings::invokeDefault( + NULL, passthrough, args, arg_count, result); } return false; } @@ -203,15 +178,19 @@ bool MessageChannelHasProperty(NPObject* np_obj, NPIdentifier name) { return false; } -bool MessageChannelGetProperty(NPObject* np_obj, NPIdentifier name, +bool MessageChannelGetProperty(NPObject* np_obj, + NPIdentifier name, NPVariant* result) { if (!np_obj) return false; - // Don't allow getting the postMessage function. - if (IdentifierIsPostMessage(name)) + // Don't allow getting the postMessage functions. + if (IdentifierIs(name, kPostMessage)) return false; - + if (IdentifierIs(name, kPostMessageAndAwaitResponse) && + HasDevChannelPermission(np_obj)) { + return false; + } MessageChannel* message_channel = ToMessageChannel(np_obj); if (message_channel) { if (message_channel->GetReadOnlyProperty(name, result)) @@ -225,15 +204,19 @@ bool MessageChannelGetProperty(NPObject* np_obj, NPIdentifier name, return false; } -bool MessageChannelSetProperty(NPObject* np_obj, NPIdentifier name, +bool MessageChannelSetProperty(NPObject* np_obj, + NPIdentifier name, const NPVariant* variant) { if (!np_obj) return false; - // Don't allow setting the postMessage function. - if (IdentifierIsPostMessage(name)) + // Don't allow setting the postMessage functions. + if (IdentifierIs(name, kPostMessage)) return false; - + if (IdentifierIs(name, kPostMessageAndAwaitResponse) && + HasDevChannelPermission(np_obj)) { + return false; + } // Invoke on the passthrough object, if we have one. NPObject* passthrough = ToPassThroughObject(np_obj); if (passthrough) @@ -241,8 +224,9 @@ bool MessageChannelSetProperty(NPObject* np_obj, NPIdentifier name, return false; } -bool MessageChannelEnumerate(NPObject *np_obj, NPIdentifier **value, - uint32_t *count) { +bool MessageChannelEnumerate(NPObject* np_obj, + NPIdentifier** value, + uint32_t* count) { if (!np_obj) return false; @@ -258,7 +242,7 @@ bool MessageChannelEnumerate(NPObject *np_obj, NPIdentifier **value, return false; NPIdentifier* new_array = static_cast<NPIdentifier*>( std::malloc(sizeof(NPIdentifier) * (*count + 1))); - std::memcpy(new_array, *value, sizeof(NPIdentifier)*(*count)); + std::memcpy(new_array, *value, sizeof(NPIdentifier) * (*count)); new_array[*count] = WebBindings::getStringIdentifier(kPostMessage); std::free(*value); *value = new_array; @@ -275,38 +259,35 @@ bool MessageChannelEnumerate(NPObject *np_obj, NPIdentifier **value, } NPClass message_channel_class = { - NP_CLASS_STRUCT_VERSION, - &MessageChannelAllocate, - &MessageChannelDeallocate, - NULL, - &MessageChannelHasMethod, - &MessageChannelInvoke, - &MessageChannelInvokeDefault, - &MessageChannelHasProperty, - &MessageChannelGetProperty, - &MessageChannelSetProperty, - NULL, - &MessageChannelEnumerate, -}; + NP_CLASS_STRUCT_VERSION, &MessageChannelAllocate, + &MessageChannelDeallocate, NULL, + &MessageChannelHasMethod, &MessageChannelInvoke, + &MessageChannelInvokeDefault, &MessageChannelHasProperty, + &MessageChannelGetProperty, &MessageChannelSetProperty, + NULL, &MessageChannelEnumerate, }; } // namespace // MessageChannel -------------------------------------------------------------- struct MessageChannel::VarConversionResult { - VarConversionResult(const ppapi::ScopedPPVar& r, bool s) - : result(r), - success(s), - conversion_completed(true) {} - VarConversionResult() - : success(false), - conversion_completed(false) {} - ppapi::ScopedPPVar result; - bool success; - bool conversion_completed; + VarConversionResult() : success_(false), conversion_completed_(false) {} + void ConversionCompleted(const ScopedPPVar& var, + bool success) { + conversion_completed_ = true; + var_ = var; + success_ = success; + } + const ScopedPPVar& var() const { return var_; } + bool success() const { return success_; } + bool conversion_completed() const { return conversion_completed_; } + + private: + ScopedPPVar var_; + bool success_; + bool conversion_completed_; }; -MessageChannel::MessageChannelNPObject::MessageChannelNPObject() { -} +MessageChannel::MessageChannelNPObject::MessageChannelNPObject() {} MessageChannel::MessageChannelNPObject::~MessageChannelNPObject() {} @@ -325,58 +306,36 @@ MessageChannel::MessageChannel(PepperPluginInstanceImpl* instance) np_object_->message_channel = weak_ptr_factory_.GetWeakPtr(); } -void MessageChannel::NPVariantToPPVar(const NPVariant* variant) { - converted_var_queue_.push_back(VarConversionResult()); - std::list<VarConversionResult>::iterator result_iterator = - --converted_var_queue_.end(); - switch (variant->type) { - case NPVariantType_Void: - NPVariantToPPVarComplete(result_iterator, - ppapi::ScopedPPVar(PP_MakeUndefined()), true); - return; - case NPVariantType_Null: - NPVariantToPPVarComplete(result_iterator, - ppapi::ScopedPPVar(PP_MakeNull()), true); - return; - case NPVariantType_Bool: - NPVariantToPPVarComplete(result_iterator, - ppapi::ScopedPPVar( - PP_MakeBool(PP_FromBool(NPVARIANT_TO_BOOLEAN(*variant)))), - true); - return; - case NPVariantType_Int32: - NPVariantToPPVarComplete(result_iterator, - ppapi::ScopedPPVar( - PP_MakeInt32(NPVARIANT_TO_INT32(*variant))), - true); - return; - case NPVariantType_Double: - NPVariantToPPVarComplete(result_iterator, - ppapi::ScopedPPVar( - PP_MakeDouble(NPVARIANT_TO_DOUBLE(*variant))), - true); - return; - case NPVariantType_String: - NPVariantToPPVarComplete(result_iterator, - ppapi::ScopedPPVar(ppapi::ScopedPPVar::PassRef(), - StringVar::StringToPPVar( - NPVARIANT_TO_STRING(*variant).UTF8Characters, - NPVARIANT_TO_STRING(*variant).UTF8Length)), - true); - return; - case NPVariantType_Object: { - // Calling WebBindings::toV8Value creates a wrapper around NPVariant so it - // shouldn't result in a deep copy. - v8::Handle<v8::Value> v8_value = WebBindings::toV8Value(variant); - V8VarConverter(instance_->pp_instance()).FromV8Value( - v8_value, v8::Isolate::GetCurrent()->GetCurrentContext(), - base::Bind(&MessageChannel::NPVariantToPPVarComplete, - weak_ptr_factory_.GetWeakPtr(), result_iterator)); - return; +void MessageChannel::EnqueuePluginMessage(const NPVariant* variant) { + plugin_message_queue_.push_back(VarConversionResult()); + if (variant->type == NPVariantType_Object) { + // Convert NPVariantType_Object in to an appropriate PP_Var like Dictionary, + // Array, etc. Note NPVariantToVar would convert to an "Object" PP_Var, + // which we don't support for Messaging. + + // Calling WebBindings::toV8Value creates a wrapper around NPVariant so it + // won't result in a deep copy. + v8::Handle<v8::Value> v8_value = WebBindings::toV8Value(variant); + V8VarConverter v8_var_converter(instance_->pp_instance()); + V8VarConverter::VarResult conversion_result = + v8_var_converter.FromV8Value( + v8_value, + v8::Isolate::GetCurrent()->GetCurrentContext(), + base::Bind(&MessageChannel::FromV8ValueComplete, + weak_ptr_factory_.GetWeakPtr(), + &plugin_message_queue_.back())); + if (conversion_result.completed_synchronously) { + plugin_message_queue_.back().ConversionCompleted( + conversion_result.var, + conversion_result.success); } + } else { + plugin_message_queue_.back().ConversionCompleted( + ScopedPPVar(ScopedPPVar::PassRef(), + NPVariantToPPVar(instance(), variant)), + true); + DCHECK(plugin_message_queue_.back().var().get().type != PP_VARTYPE_OBJECT); } - NPVariantToPPVarComplete(result_iterator, - ppapi::ScopedPPVar(PP_MakeUndefined()), false); } void MessageChannel::PostMessageToJavaScript(PP_Var message_data) { @@ -398,101 +357,81 @@ void MessageChannel::PostMessageToJavaScript(PP_Var message_data) { v8::Context::Scope context_scope(context); v8::Handle<v8::Value> v8_val; - if (!V8VarConverter(instance_->pp_instance()).ToV8Value( - message_data, context, &v8_val)) { + if (!V8VarConverter(instance_->pp_instance()) + .ToV8Value(message_data, context, &v8_val)) { PpapiGlobals::Get()->LogWithSource(instance_->pp_instance(), - PP_LOGLEVEL_ERROR, std::string(), kVarToV8ConversionError); + PP_LOGLEVEL_ERROR, + std::string(), + kVarToV8ConversionError); return; } - // This is for backward compatibility. It usually makes sense for us to return - // a string object rather than a string primitive because it allows multiple - // references to the same string (as with PP_Var strings). However, prior to - // implementing dictionary and array, vars we would return a string primitive - // here. Changing it to an object now will break existing code that uses - // strict comparisons for strings returned from PostMessage. e.g. x === "123" - // will no longer return true. So if the only value to return is a string - // object, just return the string primitive. - if (v8_val->IsStringObject()) - v8_val = v8_val->ToString(); - WebSerializedScriptValue serialized_val = WebSerializedScriptValue::serialize(v8_val); - if (instance_->module()->IsProxied()) { - if (early_message_queue_state_ != SEND_DIRECTLY) { - // We can't just PostTask here; the messages would arrive out of - // order. Instead, we queue them up until we're ready to post - // them. - early_message_queue_.push_back(serialized_val); - } else { - // The proxy sent an asynchronous message, so the plugin is already - // unblocked. Therefore, there's no need to PostTask. - DCHECK(early_message_queue_.size() == 0); - PostMessageToJavaScriptImpl(serialized_val); - } + if (early_message_queue_state_ != SEND_DIRECTLY) { + // We can't just PostTask here; the messages would arrive out of + // order. Instead, we queue them up until we're ready to post + // them. + early_message_queue_.push_back(serialized_val); } else { - base::MessageLoop::current()->PostTask( - FROM_HERE, - base::Bind(&MessageChannel::PostMessageToJavaScriptImpl, - weak_ptr_factory_.GetWeakPtr(), - serialized_val)); + // The proxy sent an asynchronous message, so the plugin is already + // unblocked. Therefore, there's no need to PostTask. + DCHECK(early_message_queue_.empty()); + PostMessageToJavaScriptImpl(serialized_val); } } -void MessageChannel::StopQueueingJavaScriptMessages() { +void MessageChannel::Start() { // We PostTask here instead of draining the message queue directly // since we haven't finished initializing the PepperWebPluginImpl yet, so // the plugin isn't available in the DOM. - early_message_queue_state_ = DRAIN_PENDING; base::MessageLoop::current()->PostTask( FROM_HERE, base::Bind(&MessageChannel::DrainEarlyMessageQueue, weak_ptr_factory_.GetWeakPtr())); } -void MessageChannel::QueueJavaScriptMessages() { - if (early_message_queue_state_ == DRAIN_PENDING) - early_message_queue_state_ = DRAIN_CANCELLED; - else - early_message_queue_state_ = QUEUE_MESSAGES; +void MessageChannel::FromV8ValueComplete(VarConversionResult* result_holder, + const ScopedPPVar& result, + bool success) { + result_holder->ConversionCompleted(result, success); + DrainCompletedPluginMessages(); } -void MessageChannel::NPVariantToPPVarComplete( - const std::list<VarConversionResult>::iterator& result_iterator, - const ppapi::ScopedPPVar& result, - bool success) { - *result_iterator = VarConversionResult(result, success); - std::list<VarConversionResult>::iterator it = converted_var_queue_.begin(); - while (it != converted_var_queue_.end() && it->conversion_completed) { - if (it->success) { - PostMessageToNative(it->result.get()); +void MessageChannel::DrainCompletedPluginMessages() { + if (early_message_queue_state_ == QUEUE_MESSAGES) + return; + + while (!plugin_message_queue_.empty() && + plugin_message_queue_.front().conversion_completed()) { + const VarConversionResult& front = plugin_message_queue_.front(); + if (front.success()) { + instance_->HandleMessage(front.var()); } else { PpapiGlobals::Get()->LogWithSource(instance()->pp_instance(), - PP_LOGLEVEL_ERROR, std::string(), kV8ToVarConversionError); + PP_LOGLEVEL_ERROR, + std::string(), + kV8ToVarConversionError); } - - converted_var_queue_.erase(it++); + plugin_message_queue_.pop_front(); } } void MessageChannel::DrainEarlyMessageQueue() { + DCHECK(early_message_queue_state_ == QUEUE_MESSAGES); + // Take a reference on the PluginInstance. This is because JavaScript code // may delete the plugin, which would destroy the PluginInstance and its // corresponding MessageChannel. scoped_refptr<PepperPluginInstanceImpl> instance_ref(instance_); - - if (early_message_queue_state_ == DRAIN_CANCELLED) { - early_message_queue_state_ = QUEUE_MESSAGES; - return; - } - DCHECK(early_message_queue_state_ == DRAIN_PENDING); - while (!early_message_queue_.empty()) { PostMessageToJavaScriptImpl(early_message_queue_.front()); early_message_queue_.pop_front(); } early_message_queue_state_ = SEND_DIRECTLY; + + DrainCompletedPluginMessages(); } void MessageChannel::PostMessageToJavaScriptImpl( @@ -508,13 +447,13 @@ void MessageChannel::PostMessageToJavaScriptImpl( WebDOMEvent event = container->element().document().createEvent("MessageEvent"); WebDOMMessageEvent msg_event = event.to<WebDOMMessageEvent>(); - msg_event.initMessageEvent("message", // type - false, // canBubble - false, // cancelable + msg_event.initMessageEvent("message", // type + false, // canBubble + false, // cancelable message_data, // data - "", // origin [*] - NULL, // source [*] - ""); // lastEventId + "", // origin [*] + NULL, // source [*] + ""); // lastEventId // [*] Note that the |origin| is only specified for cross-document and server- // sent messages, while |source| is only specified for cross-document // messages: @@ -523,30 +462,86 @@ void MessageChannel::PostMessageToJavaScriptImpl( // at least, postMessage on Workers does not provide the origin or source. // TODO(dmichael): Add origin if we change to a more iframe-like origin // policy (see crbug.com/81537) - container->element().dispatchEvent(msg_event); } -void MessageChannel::PostMessageToNative(PP_Var message_data) { - if (instance_->module()->IsProxied()) { - // In the proxied case, the copy will happen via serializiation, and the - // message is asynchronous. Therefore there's no need to copy the Var, nor - // to PostTask. - PostMessageToNativeImpl(message_data); - } else { - // Make a copy of the message data for the Task we will run. - PP_Var var_copy(CopyPPVar(message_data)); - - base::MessageLoop::current()->PostTask( - FROM_HERE, - base::Bind(&MessageChannel::PostMessageToNativeImpl, - weak_ptr_factory_.GetWeakPtr(), - var_copy)); - } +void MessageChannel::PostMessageToNative(const NPVariant* message_data) { + EnqueuePluginMessage(message_data); + DrainCompletedPluginMessages(); } -void MessageChannel::PostMessageToNativeImpl(PP_Var message_data) { - instance_->HandleMessage(message_data); +void MessageChannel::PostBlockingMessageToNative(const NPVariant* message_data, + NPVariant* np_result) { + if (early_message_queue_state_ == QUEUE_MESSAGES) { + WebBindings::setException( + np_object_, + "Attempted to call a synchronous method on a plugin that was not " + "yet loaded."); + return; + } + + // If the queue of messages to the plugin is non-empty, we're still waiting on + // pending Var conversions. This means at some point in the past, JavaScript + // called postMessage (the async one) and passed us something with a browser- + // side host (e.g., FileSystem) and we haven't gotten a response from the + // browser yet. We can't currently support sending a sync message if the + // plugin does this, because it will break the ordering of the messages + // arriving at the plugin. + // TODO(dmichael): Fix this. + // See https://code.google.com/p/chromium/issues/detail?id=367896#c4 + if (!plugin_message_queue_.empty()) { + WebBindings::setException( + np_object_, + "Failed to convert parameter synchronously, because a prior " + "call to postMessage contained a type which required asynchronous " + "transfer which has not completed. Not all types are supported yet by " + "postMessageAndAwaitResponse. See crbug.com/367896."); + return; + } + ScopedPPVar param; + if (message_data->type == NPVariantType_Object) { + // Convert NPVariantType_Object in to an appropriate PP_Var like Dictionary, + // Array, etc. Note NPVariantToVar would convert to an "Object" PP_Var, + // which we don't support for Messaging. + v8::Handle<v8::Value> v8_value = WebBindings::toV8Value(message_data); + V8VarConverter v8_var_converter(instance_->pp_instance()); + bool success = v8_var_converter.FromV8ValueSync( + v8_value, + v8::Isolate::GetCurrent()->GetCurrentContext(), + ¶m); + if (!success) { + WebBindings::setException( + np_object_, + "Failed to convert the given parameter to a PP_Var to send to " + "the plugin."); + return; + } + } else { + param = ScopedPPVar(ScopedPPVar::PassRef(), + NPVariantToPPVar(instance(), message_data)); + } + ScopedPPVar pp_result; + bool was_handled = instance_->HandleBlockingMessage(param, &pp_result); + if (!was_handled) { + WebBindings::setException( + np_object_, + "The plugin has not registered a handler for synchronous messages. " + "See the documentation for PPB_Messaging::RegisterMessageHandler " + "and PPP_MessageHandler."); + return; + } + v8::Handle<v8::Value> v8_val; + if (!V8VarConverter(instance_->pp_instance()).ToV8Value( + pp_result.get(), + v8::Isolate::GetCurrent()->GetCurrentContext(), + &v8_val)) { + WebBindings::setException( + np_object_, + "Failed to convert the plugin's result to a JavaScript type."); + return; + } + // Success! Convert the result to an NPVariant. + WebBindings::toNPVariant(v8_val, NULL, np_result); } MessageChannel::~MessageChannel() { @@ -572,8 +567,8 @@ void MessageChannel::SetPassthroughObject(NPObject* passthrough) { } bool MessageChannel::GetReadOnlyProperty(NPIdentifier key, - NPVariant *value) const { - std::map<NPIdentifier, ppapi::ScopedPPVar>::const_iterator it = + NPVariant* value) const { + std::map<NPIdentifier, ScopedPPVar>::const_iterator it = internal_properties_.find(key); if (it != internal_properties_.end()) { if (value) @@ -584,7 +579,7 @@ bool MessageChannel::GetReadOnlyProperty(NPIdentifier key, } void MessageChannel::SetReadOnlyProperty(PP_Var key, PP_Var value) { - internal_properties_[PPVarToNPIdentifier(key)] = ppapi::ScopedPPVar(value); + internal_properties_[PPVarToNPIdentifier(key)] = ScopedPPVar(value); } } // namespace content diff --git a/chromium/content/renderer/pepper/message_channel.h b/chromium/content/renderer/pepper/message_channel.h index e0020e688c1..8c744a04419 100644 --- a/chromium/content/renderer/pepper/message_channel.h +++ b/chromium/content/renderer/pepper/message_channel.h @@ -53,37 +53,33 @@ class MessageChannel { explicit MessageChannel(PepperPluginInstanceImpl* instance); ~MessageChannel(); - // Converts an NPVariant to a PP_Var. This occurs asynchronously and - // NPVariantToPPVarComplete will be called upon completion. - void NPVariantToPPVar(const NPVariant* variant); - // Post a message to the onmessage handler for this channel's instance // asynchronously. void PostMessageToJavaScript(PP_Var message_data); - // Post a message to the PPP_Instance HandleMessage function for this - // channel's instance. - void PostMessageToNative(PP_Var message_data); + + // Post a message to the plugin's HandleMessage function for this channel's + // instance. + void PostMessageToNative(const NPVariant* message_data); + // Post a message to the plugin's HandleBlocking Message function for this + // channel's instance synchronously, and return a result. + void PostBlockingMessageToNative(const NPVariant* message_data, + NPVariant* np_result); // Return the NPObject* to which we should forward any calls which aren't // related to postMessage. Note that this can be NULL; it only gets set if // there is a scriptable 'InstanceObject' associated with this channel's // instance. - NPObject* passthrough_object() { - return passthrough_object_; - } + NPObject* passthrough_object() { return passthrough_object_; } void SetPassthroughObject(NPObject* passthrough); NPObject* np_object() { return np_object_; } - PepperPluginInstanceImpl* instance() { - return instance_; - } + PepperPluginInstanceImpl* instance() { return instance_; } - // Messages sent to JavaScript are queued by default. After the DOM is - // set up for the plugin, users of MessageChannel should call - // StopQueueingJavaScriptMessages to start dispatching messages to JavaScript. - void QueueJavaScriptMessages(); - void StopQueueingJavaScriptMessages(); + // Messages are queued initially. After the PepperPluginInstanceImpl is ready + // to send and handle messages, users of MessageChannel should call + // Start(). + void Start(); bool GetReadOnlyProperty(NPIdentifier key, NPVariant* value) const; void SetReadOnlyProperty(PP_Var key, PP_Var value); @@ -92,13 +88,12 @@ class MessageChannel { // Struct for storing the result of a NPVariant being converted to a PP_Var. struct VarConversionResult; - // This is called when an NPVariant is finished being converted. - // |result_iteartor| is an iterator into |converted_var_queue_| where the - // result should be stored. - void NPVariantToPPVarComplete( - const std::list<VarConversionResult>::iterator& result_iterator, - const ppapi::ScopedPPVar& result, - bool success); + void EnqueuePluginMessage(const NPVariant* variant); + + void FromV8ValueComplete(VarConversionResult* result_holder, + const ppapi::ScopedPPVar& result_var, + bool success); + void DrainCompletedPluginMessages(); PepperPluginInstanceImpl* instance_; @@ -122,22 +117,22 @@ class MessageChannel { void DrainEarlyMessageQueue(); - // TODO(teravest): Remove all the tricky DRAIN_CANCELLED logic once - // PluginInstance::ResetAsProxied() is gone. std::deque<blink::WebSerializedScriptValue> early_message_queue_; enum EarlyMessageQueueState { - QUEUE_MESSAGES, // Queue JS messages. - SEND_DIRECTLY, // Post JS messages directly. - DRAIN_PENDING, // Drain queue, then transition to DIRECT. - DRAIN_CANCELLED // Preempt drain, go back to QUEUE. + QUEUE_MESSAGES, // Queue JS messages. + SEND_DIRECTLY, // Post JS messages directly. }; EarlyMessageQueueState early_message_queue_state_; - // This queue stores vars that have been converted from NPVariants. Because - // conversion can happen asynchronously, the queue stores the var until all - // previous vars have been converted before calling PostMessage to ensure that - // the order in which messages are processed is preserved. - std::list<VarConversionResult> converted_var_queue_; + // This queue stores vars that are being sent to the plugin. Because + // conversion can happen asynchronously for object types, the queue stores + // the var until all previous vars have been converted and sent. This + // preserves the order in which JS->plugin messages are processed. + // + // Note we rely on raw VarConversionResult* pointers remaining valid after + // calls to push_back or pop_front; hence why we're using list. (deque would + // probably also work, but is less clearly specified). + std::list<VarConversionResult> plugin_message_queue_; std::map<NPIdentifier, ppapi::ScopedPPVar> internal_properties_; diff --git a/chromium/content/renderer/pepper/mock_renderer_ppapi_host.cc b/chromium/content/renderer/pepper/mock_renderer_ppapi_host.cc index 2354f0bd385..0f7b6e85573 100644 --- a/chromium/content/renderer/pepper/mock_renderer_ppapi_host.cc +++ b/chromium/content/renderer/pepper/mock_renderer_ppapi_host.cc @@ -16,11 +16,9 @@ MockRendererPpapiHost::MockRendererPpapiHost(RenderView* render_view, render_view_(render_view), pp_instance_(instance), has_user_gesture_(false), - plugin_instance_(new FakePepperPluginInstance) { -} + plugin_instance_(new FakePepperPluginInstance) {} -MockRendererPpapiHost::~MockRendererPpapiHost() { -} +MockRendererPpapiHost::~MockRendererPpapiHost() {} ppapi::host::PpapiHost* MockRendererPpapiHost::GetPpapiHost() { return &ppapi_host_; @@ -79,8 +77,14 @@ IPC::PlatformFileForTransit MockRendererPpapiHost::ShareHandleWithRemote( return IPC::InvalidPlatformFileForTransit(); } -bool MockRendererPpapiHost::IsRunningInProcess() const { - return false; +bool MockRendererPpapiHost::IsRunningInProcess() const { return false; } + +std::string MockRendererPpapiHost::GetPluginName() const { + return std::string(); +} + +void MockRendererPpapiHost::SetToExternalPluginHost() { + NOTIMPLEMENTED(); } void MockRendererPpapiHost::CreateBrowserResourceHosts( diff --git a/chromium/content/renderer/pepper/mock_renderer_ppapi_host.h b/chromium/content/renderer/pepper/mock_renderer_ppapi_host.h index c9d282ac99e..62c9d650f1b 100644 --- a/chromium/content/renderer/pepper/mock_renderer_ppapi_host.h +++ b/chromium/content/renderer/pepper/mock_renderer_ppapi_host.h @@ -22,8 +22,7 @@ class MockRendererPpapiHost : public RendererPpapiHost { public: // This function takes the RenderView and instance that the mock resource // host will be associated with. - MockRendererPpapiHost(RenderView* render_view, - PP_Instance instance); + MockRendererPpapiHost(RenderView* render_view, PP_Instance instance); virtual ~MockRendererPpapiHost(); ppapi::proxy::ResourceMessageTestSink& sink() { return sink_; } @@ -35,29 +34,31 @@ class MockRendererPpapiHost : public RendererPpapiHost { // RendererPpapiHost. virtual ppapi::host::PpapiHost* GetPpapiHost() OVERRIDE; virtual bool IsValidInstance(PP_Instance instance) const OVERRIDE; - virtual PepperPluginInstance* GetPluginInstance( - PP_Instance instance) const OVERRIDE; - virtual RenderFrame* GetRenderFrameForInstance( - PP_Instance instance) const OVERRIDE; - virtual RenderView* GetRenderViewForInstance( - PP_Instance instance) const OVERRIDE; + virtual PepperPluginInstance* GetPluginInstance(PP_Instance instance) const + OVERRIDE; + virtual RenderFrame* GetRenderFrameForInstance(PP_Instance instance) const + OVERRIDE; + virtual RenderView* GetRenderViewForInstance(PP_Instance instance) const + OVERRIDE; virtual blink::WebPluginContainer* GetContainerForInstance( PP_Instance instance) const OVERRIDE; virtual base::ProcessId GetPluginPID() const OVERRIDE; virtual bool HasUserGesture(PP_Instance instance) const OVERRIDE; virtual int GetRoutingIDForWidget(PP_Instance instance) const OVERRIDE; - virtual gfx::Point PluginPointToRenderFrame( - PP_Instance instance, - const gfx::Point& pt) const OVERRIDE; + virtual gfx::Point PluginPointToRenderFrame(PP_Instance instance, + const gfx::Point& pt) const + OVERRIDE; virtual IPC::PlatformFileForTransit ShareHandleWithRemote( base::PlatformFile handle, bool should_close_source) OVERRIDE; virtual bool IsRunningInProcess() const OVERRIDE; + virtual std::string GetPluginName() const OVERRIDE; + virtual void SetToExternalPluginHost() OVERRIDE; virtual void CreateBrowserResourceHosts( PP_Instance instance, const std::vector<IPC::Message>& nested_msgs, - const base::Callback<void( - const std::vector<int>&)>& callback) const OVERRIDE; + const base::Callback<void(const std::vector<int>&)>& callback) const + OVERRIDE; virtual GURL GetDocumentURL(PP_Instance instance) const OVERRIDE; private: diff --git a/chromium/content/renderer/pepper/npapi_glue.cc b/chromium/content/renderer/pepper/npapi_glue.cc index 8489c4d3fbd..990d3302e89 100644 --- a/chromium/content/renderer/pepper/npapi_glue.cc +++ b/chromium/content/renderer/pepper/npapi_glue.cc @@ -20,7 +20,7 @@ #include "third_party/WebKit/public/web/WebBindings.h" #include "third_party/WebKit/public/web/WebDocument.h" #include "third_party/WebKit/public/web/WebElement.h" -#include "third_party/WebKit/public/web/WebFrame.h" +#include "third_party/WebKit/public/web/WebLocalFrame.h" #include "third_party/WebKit/public/web/WebPluginContainer.h" #include "v8/include/v8.h" @@ -30,7 +30,7 @@ using ppapi::StringVar; using ppapi::Var; using blink::WebArrayBuffer; using blink::WebBindings; -using blink::WebFrame; +using blink::WebLocalFrame; using blink::WebPluginContainer; namespace content { @@ -65,7 +65,6 @@ PP_Var NPObjectToPPVarImpl(PepperPluginInstanceImpl* instance, return object_var->GetPPVar(); } - } // namespace // Utilities ------------------------------------------------------------------- @@ -179,7 +178,7 @@ PP_Var NPObjectToPPVar(PepperPluginInstanceImpl* instance, NPObject* object) { // the DOM (but the PluginInstance is not destroyed yet). if (!container) return PP_MakeUndefined(); - WebFrame* frame = container->element().document().frame(); + WebLocalFrame* frame = container->element().document().frame(); if (!frame) return PP_MakeUndefined(); @@ -211,8 +210,7 @@ PPResultAndExceptionToNPResult::PPResultAndExceptionToNPResult( np_result_(np_result), exception_(PP_MakeUndefined()), success_(false), - checked_exception_(false) { -} + checked_exception_(false) {} PPResultAndExceptionToNPResult::~PPResultAndExceptionToNPResult() { // The user should have called SetResult or CheckExceptionForNoResult @@ -228,7 +226,7 @@ PPResultAndExceptionToNPResult::~PPResultAndExceptionToNPResult() { // the JS engine. It will update the success flag and return it. bool PPResultAndExceptionToNPResult::SetResult(PP_Var result) { DCHECK(!checked_exception_); // Don't call more than once. - DCHECK(np_result_); // Should be expecting a result. + DCHECK(np_result_); // Should be expecting a result. checked_exception_ = true; @@ -256,7 +254,7 @@ bool PPResultAndExceptionToNPResult::SetResult(PP_Var result) { // The success flag will be returned. bool PPResultAndExceptionToNPResult::CheckExceptionForNoResult() { DCHECK(!checked_exception_); // Don't call more than once. - DCHECK(!np_result_); // Can't have a result when doing this. + DCHECK(!np_result_); // Can't have a result when doing this. checked_exception_ = true; @@ -306,8 +304,7 @@ PPVarArrayFromNPVariantArray::~PPVarArrayFromNPVariantArray() { PPVarFromNPObject::PPVarFromNPObject(PepperPluginInstanceImpl* instance, NPObject* object) - : var_(NPObjectToPPVar(instance, object)) { -} + : var_(NPObjectToPPVar(instance, object)) {} PPVarFromNPObject::~PPVarFromNPObject() { PpapiGlobals::Get()->GetVarTracker()->ReleaseVar(var_); @@ -340,14 +337,14 @@ TryCatch::TryCatch(PP_Var* exception) WebBindings::pushExceptionHandler(&TryCatch::Catch, this); } -TryCatch::~TryCatch() { - WebBindings::popExceptionHandler(); -} +TryCatch::~TryCatch() { WebBindings::popExceptionHandler(); } void TryCatch::SetException(const char* message) { if (!has_exception()) { has_exception_ = true; if (exception_) { + if (!message) + message = "Unknown exception."; *exception_ = ppapi::StringVar::StringToPPVar(message, strlen(message)); } } diff --git a/chromium/content/renderer/pepper/npapi_glue.h b/chromium/content/renderer/pepper/npapi_glue.h index c2d23c87f23..7bcbbff969b 100644 --- a/chromium/content/renderer/pepper/npapi_glue.h +++ b/chromium/content/renderer/pepper/npapi_glue.h @@ -64,8 +64,8 @@ PP_Var NPIdentifierToPPVar(NPIdentifier id); // Note: this could easily be changed to take a PP_Instance instead if that // makes certain calls in the future easier. Currently all callers have a // PluginInstance so that's what we use here. -CONTENT_EXPORT PP_Var NPObjectToPPVar(PepperPluginInstanceImpl* instance, - NPObject* object); +CONTENT_EXPORT PP_Var + NPObjectToPPVar(PepperPluginInstanceImpl* instance, NPObject* object); // This version creates a default v8::Context rather than using the one from // the container of |instance|. It is only for use in unit tests, where we don't @@ -112,9 +112,7 @@ class PPResultAndExceptionToNPResult { // Returns true if everything succeeded with no exception. This is valid only // after calling SetResult/CheckExceptionForNoResult. - bool success() const { - return success_; - } + bool success() const { return success_; } // Call this with the return value of the PPAPI function. It will convert // the result to the NPVariant output parameter and pass any exception on to @@ -139,7 +137,7 @@ class PPResultAndExceptionToNPResult { 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. + bool success_; // See the success() function above. bool checked_exception_; // SetResult/CheckExceptionForNoResult was called. DISALLOW_COPY_AND_ASSIGN(PPResultAndExceptionToNPResult); diff --git a/chromium/content/renderer/pepper/npobject_var.cc b/chromium/content/renderer/pepper/npobject_var.cc index c45d0d2822a..50ccf87b4df 100644 --- a/chromium/content/renderer/pepper/npobject_var.cc +++ b/chromium/content/renderer/pepper/npobject_var.cc @@ -16,10 +16,8 @@ namespace ppapi { // NPObjectVar ----------------------------------------------------------------- -NPObjectVar::NPObjectVar(PP_Instance instance, - NPObject* np_object) - : pp_instance_(instance), - np_object_(np_object) { +NPObjectVar::NPObjectVar(PP_Instance instance, NPObject* np_object) + : pp_instance_(instance), np_object_(np_object) { WebBindings::retainObject(np_object_); content::HostGlobals::Get()->host_var_tracker()->AddNPObjectVar(this); } @@ -30,13 +28,9 @@ NPObjectVar::~NPObjectVar() { WebBindings::releaseObject(np_object_); } -NPObjectVar* NPObjectVar::AsNPObjectVar() { - return this; -} +NPObjectVar* NPObjectVar::AsNPObjectVar() { return this; } -PP_VarType NPObjectVar::GetType() const { - return PP_VARTYPE_OBJECT; -} +PP_VarType NPObjectVar::GetType() const { return PP_VARTYPE_OBJECT; } void NPObjectVar::InstanceDeleted() { DCHECK(pp_instance_); diff --git a/chromium/content/renderer/pepper/pepper_audio_input_host.cc b/chromium/content/renderer/pepper/pepper_audio_input_host.cc index 19aa2b1b285..a86e1775d34 100644 --- a/chromium/content/renderer/pepper/pepper_audio_input_host.cc +++ b/chromium/content/renderer/pepper/pepper_audio_input_host.cc @@ -39,24 +39,19 @@ base::PlatformFile ConvertSharedMemoryHandle( } // namespace -PepperAudioInputHost::PepperAudioInputHost( - RendererPpapiHostImpl* host, - PP_Instance instance, - PP_Resource resource) +PepperAudioInputHost::PepperAudioInputHost(RendererPpapiHostImpl* host, + PP_Instance instance, + PP_Resource resource) : ResourceHost(host->GetPpapiHost(), instance, resource), renderer_ppapi_host_(host), audio_input_(NULL), - enumeration_helper_( - this, - PepperMediaDeviceManager::GetForRenderView( - host->GetRenderViewForInstance(pp_instance())), - PP_DEVICETYPE_DEV_AUDIOCAPTURE, - host->GetDocumentURL(instance)) { -} + enumeration_helper_(this, + PepperMediaDeviceManager::GetForRenderView( + host->GetRenderViewForInstance(pp_instance())), + PP_DEVICETYPE_DEV_AUDIOCAPTURE, + host->GetDocumentURL(instance)) {} -PepperAudioInputHost::~PepperAudioInputHost() { - Close(); -} +PepperAudioInputHost::~PepperAudioInputHost() { Close(); } int32_t PepperAudioInputHost::OnResourceMessageReceived( const IPC::Message& msg, @@ -65,13 +60,12 @@ int32_t PepperAudioInputHost::OnResourceMessageReceived( if (enumeration_helper_.HandleResourceMessage(msg, context, &result)) return result; - IPC_BEGIN_MESSAGE_MAP(PepperAudioInputHost, msg) + PPAPI_BEGIN_MESSAGE_MAP(PepperAudioInputHost, msg) PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_AudioInput_Open, OnOpen) PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_AudioInput_StartOrStop, - OnStartOrStop); - PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_AudioInput_Close, - OnClose); - IPC_END_MESSAGE_MAP() + OnStartOrStop) + PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_AudioInput_Close, OnClose) + PPAPI_END_MESSAGE_MAP() return PP_ERROR_FAILED; } @@ -83,16 +77,17 @@ void PepperAudioInputHost::StreamCreated( } void PepperAudioInputHost::StreamCreationFailed() { - OnOpenComplete(PP_ERROR_FAILED, base::SharedMemory::NULLHandle(), 0, + OnOpenComplete(PP_ERROR_FAILED, + base::SharedMemory::NULLHandle(), + 0, base::SyncSocket::kInvalidHandle); } -int32_t PepperAudioInputHost::OnOpen( - ppapi::host::HostMessageContext* context, - const std::string& device_id, - PP_AudioSampleRate sample_rate, - uint32_t sample_frame_count) { - if (open_context_) +int32_t PepperAudioInputHost::OnOpen(ppapi::host::HostMessageContext* context, + const std::string& device_id, + PP_AudioSampleRate sample_rate, + uint32_t sample_frame_count) { + if (open_context_.is_valid()) return PP_ERROR_INPROGRESS; if (audio_input_) return PP_ERROR_FAILED; @@ -106,14 +101,15 @@ int32_t PepperAudioInputHost::OnOpen( RenderViewImpl* render_view = static_cast<RenderViewImpl*>( renderer_ppapi_host_->GetRenderViewForInstance(pp_instance())); - audio_input_ = PepperPlatformAudioInput::Create( - render_view->AsWeakPtr(), device_id, - document_url, - static_cast<int>(sample_rate), - static_cast<int>(sample_frame_count), this); + audio_input_ = + PepperPlatformAudioInput::Create(render_view->AsWeakPtr(), + device_id, + document_url, + static_cast<int>(sample_rate), + static_cast<int>(sample_frame_count), + this); if (audio_input_) { - open_context_.reset(new ppapi::host::ReplyMessageContext( - context->MakeReplyMessageContext())); + open_context_ = context->MakeReplyMessageContext(); return PP_OK_COMPLETIONPENDING; } else { return PP_ERROR_FAILED; @@ -147,7 +143,7 @@ void PepperAudioInputHost::OnOpenComplete( base::SyncSocket scoped_socket(socket_handle); base::SharedMemory scoped_shared_memory(shared_memory_handle, false); - if (!open_context_) { + if (!open_context_.is_valid()) { NOTREACHED(); return; } @@ -173,12 +169,9 @@ void PepperAudioInputHost::OnOpenComplete( // inconvenient to clean up. Our IPC code will automatically handle this for // us, as long as the remote side always closes the handles it receives, even // in the failure case. - open_context_->params.set_result(result); - open_context_->params.AppendHandle(serialized_socket_handle); - open_context_->params.AppendHandle(serialized_shared_memory_handle); - - host()->SendReply(*open_context_, PpapiPluginMsg_AudioInput_OpenReply()); - open_context_.reset(); + open_context_.params.AppendHandle(serialized_socket_handle); + open_context_.params.AppendHandle(serialized_shared_memory_handle); + SendOpenReply(result); } int32_t PepperAudioInputHost::GetRemoteHandles( @@ -206,12 +199,14 @@ void PepperAudioInputHost::Close() { audio_input_->ShutDown(); audio_input_ = NULL; - if (open_context_) { - open_context_->params.set_result(PP_ERROR_ABORTED); - host()->SendReply(*open_context_, PpapiPluginMsg_AudioInput_OpenReply()); - open_context_.reset(); - } + if (open_context_.is_valid()) + SendOpenReply(PP_ERROR_ABORTED); } -} // namespace content +void PepperAudioInputHost::SendOpenReply(int32_t result) { + open_context_.params.set_result(result); + host()->SendReply(open_context_, PpapiPluginMsg_AudioInput_OpenReply()); + open_context_ = ppapi::host::ReplyMessageContext(); +} +} // namespace content diff --git a/chromium/content/renderer/pepper/pepper_audio_input_host.h b/chromium/content/renderer/pepper/pepper_audio_input_host.h index 70c430329f9..40f98b0db7f 100644 --- a/chromium/content/renderer/pepper/pepper_audio_input_host.h +++ b/chromium/content/renderer/pepper/pepper_audio_input_host.h @@ -44,8 +44,7 @@ class PepperAudioInputHost : public ppapi::host::ResourceHost { const std::string& device_id, PP_AudioSampleRate sample_rate, uint32_t sample_frame_count); - int32_t OnStartOrStop(ppapi::host::HostMessageContext* context, - bool capture); + int32_t OnStartOrStop(ppapi::host::HostMessageContext* context, bool capture); int32_t OnClose(ppapi::host::HostMessageContext* context); void OnOpenComplete(int32_t result, @@ -61,10 +60,12 @@ class PepperAudioInputHost : public ppapi::host::ResourceHost { void Close(); + void SendOpenReply(int32_t result); + // Non-owning pointer. RendererPpapiHostImpl* renderer_ppapi_host_; - scoped_ptr<ppapi::host::ReplyMessageContext> open_context_; + ppapi::host::ReplyMessageContext open_context_; // Audio input object that we delegate audio IPC through. // We don't own this pointer but are responsible for calling Shutdown on it. diff --git a/chromium/content/renderer/pepper/pepper_broker.cc b/chromium/content/renderer/pepper/pepper_broker.cc index 44861965e00..851408f0b27 100644 --- a/chromium/content/renderer/pepper/pepper_broker.cc +++ b/chromium/content/renderer/pepper/pepper_broker.cc @@ -23,7 +23,7 @@ namespace content { namespace { base::SyncSocket::Handle DuplicateHandle(base::SyncSocket::Handle handle) { - base::SyncSocket::Handle out_handle = base::kInvalidPlatformFileValue; + base::SyncSocket::Handle out_handle = base::SyncSocket::kInvalidHandle; #if defined(OS_WIN) DWORD options = DUPLICATE_SAME_ACCESS; if (!::DuplicateHandle(::GetCurrentProcess(), @@ -33,25 +33,23 @@ base::SyncSocket::Handle DuplicateHandle(base::SyncSocket::Handle handle) { 0, FALSE, options)) { - out_handle = base::kInvalidPlatformFileValue; + out_handle = base::SyncSocket::kInvalidHandle; } #elif defined(OS_POSIX) // If asked to close the source, we can simply re-use the source fd instead of // dup()ing and close()ing. out_handle = ::dup(handle); #else - #error Not implemented. +#error Not implemented. #endif return out_handle; } } // namespace -PepperBrokerDispatcherWrapper::PepperBrokerDispatcherWrapper() { -} +PepperBrokerDispatcherWrapper::PepperBrokerDispatcherWrapper() {} -PepperBrokerDispatcherWrapper::~PepperBrokerDispatcherWrapper() { -} +PepperBrokerDispatcherWrapper::~PepperBrokerDispatcherWrapper() {} bool PepperBrokerDispatcherWrapper::Init( base::ProcessId broker_pid, @@ -66,8 +64,7 @@ bool PepperBrokerDispatcherWrapper::Init( #endif dispatcher_delegate_.reset(new PepperProxyChannelDelegateImpl); - dispatcher_.reset( - new ppapi::proxy::BrokerHostDispatcher()); + dispatcher_.reset(new ppapi::proxy::BrokerHostDispatcher()); if (!dispatcher_->InitBrokerWithChannel(dispatcher_delegate_.get(), broker_pid, @@ -92,8 +89,8 @@ int32_t PepperBrokerDispatcherWrapper::SendHandleToBroker( return PP_ERROR_FAILED; int32_t result; - if (!dispatcher_->Send( - new PpapiMsg_ConnectToPlugin(instance, foreign_socket_handle, &result))) { + if (!dispatcher_->Send(new PpapiMsg_ConnectToPlugin( + instance, foreign_socket_handle, &result))) { // The plugin did not receive the handle, so it must be closed. // The easiest way to clean it up is to just put it in an object // and then close it. This failure case is not performance critical. @@ -191,7 +188,7 @@ void PepperBroker::OnBrokerPermissionResult(PPB_Broker_Impl* client, if (!result) { // Report failure. client->BrokerConnected( - ppapi::PlatformFileToInt(base::kInvalidPlatformFileValue), + ppapi::PlatformFileToInt(base::SyncSocket::kInvalidHandle), PP_ERROR_NOACCESS); pending_connects_.erase(entry); return; @@ -209,20 +206,19 @@ void PepperBroker::OnBrokerPermissionResult(PPB_Broker_Impl* client, entry->second.is_authorized = true; } -PepperBroker::PendingConnection::PendingConnection() : is_authorized(false) { -} +PepperBroker::PendingConnection::PendingConnection() : is_authorized(false) {} -PepperBroker::PendingConnection::~PendingConnection() { -} +PepperBroker::PendingConnection::~PendingConnection() {} void PepperBroker::ReportFailureToClients(int error_code) { DCHECK_NE(PP_OK, error_code); for (ClientMap::iterator i = pending_connects_.begin(); - i != pending_connects_.end(); ++i) { + i != pending_connects_.end(); + ++i) { base::WeakPtr<PPB_Broker_Impl>& weak_ptr = i->second.client; if (weak_ptr.get()) { weak_ptr->BrokerConnected( - ppapi::PlatformFileToInt(base::kInvalidPlatformFileValue), + ppapi::PlatformFileToInt(base::SyncSocket::kInvalidHandle), error_code); } } @@ -230,7 +226,7 @@ void PepperBroker::ReportFailureToClients(int error_code) { } void PepperBroker::ConnectPluginToBroker(PPB_Broker_Impl* client) { - base::SyncSocket::Handle plugin_handle = base::kInvalidPlatformFileValue; + base::SyncSocket::Handle plugin_handle = base::SyncSocket::kInvalidHandle; int32_t result = PP_OK; // The socket objects will be deleted when this function exits, closing the diff --git a/chromium/content/renderer/pepper/pepper_broker.h b/chromium/content/renderer/pepper/pepper_broker.h index a363780f171..0703597e308 100644 --- a/chromium/content/renderer/pepper/pepper_broker.h +++ b/chromium/content/renderer/pepper/pepper_broker.h @@ -43,7 +43,7 @@ class CONTENT_EXPORT PepperBrokerDispatcherWrapper { scoped_ptr<ppapi::proxy::ProxyChannel::Delegate> dispatcher_delegate_; }; -class PepperBroker : public base::RefCountedThreadSafe<PepperBroker>{ +class PepperBroker : public base::RefCountedThreadSafe<PepperBroker> { public: explicit PepperBroker(PluginModule* plugin_module); @@ -62,8 +62,7 @@ class PepperBroker : public base::RefCountedThreadSafe<PepperBroker>{ // Called when we know whether permission to access the PPAPI broker was // granted. - void OnBrokerPermissionResult(PPB_Broker_Impl* client, - bool result); + void OnBrokerPermissionResult(PPB_Broker_Impl* client, bool result); private: friend class base::RefCountedThreadSafe<PepperBroker>; diff --git a/chromium/content/renderer/pepper/pepper_browser_connection.cc b/chromium/content/renderer/pepper/pepper_browser_connection.cc index dfb24298131..892506ede2f 100644 --- a/chromium/content/renderer/pepper/pepper_browser_connection.cc +++ b/chromium/content/renderer/pepper/pepper_browser_connection.cc @@ -19,11 +19,9 @@ namespace content { PepperBrowserConnection::PepperBrowserConnection(RenderFrame* render_frame) : RenderFrameObserver(render_frame), RenderFrameObserverTracker<PepperBrowserConnection>(render_frame), - next_sequence_number_(1) { -} + next_sequence_number_(1) {} -PepperBrowserConnection::~PepperBrowserConnection() { -} +PepperBrowserConnection::~PepperBrowserConnection() {} bool PepperBrowserConnection::OnMessageReceived(const IPC::Message& msg) { // Check if the message is an in-process reply. @@ -41,16 +39,14 @@ bool PepperBrowserConnection::OnMessageReceived(const IPC::Message& msg) { void PepperBrowserConnection::DidCreateInProcessInstance( PP_Instance instance, - int render_view_id, + int render_frame_id, const GURL& document_url, const GURL& plugin_url) { Send(new ViewHostMsg_DidCreateInProcessInstance( instance, // Browser provides the render process id. - PepperRendererInstanceData(0, - render_view_id, - document_url, - plugin_url))); + PepperRendererInstanceData( + 0, render_frame_id, document_url, plugin_url))); } void PepperBrowserConnection::DidDeleteInProcessInstance(PP_Instance instance) { @@ -66,11 +62,7 @@ void PepperBrowserConnection::SendBrowserCreate( pending_create_map_[sequence_number] = callback; ppapi::proxy::ResourceMessageCallParams params(0, sequence_number); Send(new PpapiHostMsg_CreateResourceHostsFromHost( - routing_id(), - child_process_id, - params, - instance, - nested_msgs)); + routing_id(), child_process_id, params, instance, nested_msgs)); } void PepperBrowserConnection::OnMsgCreateResourceHostsFromHostReply( diff --git a/chromium/content/renderer/pepper/pepper_browser_connection.h b/chromium/content/renderer/pepper/pepper_browser_connection.h index cfc5603cff9..c79a6ec1e1a 100644 --- a/chromium/content/renderer/pepper/pepper_browser_connection.h +++ b/chromium/content/renderer/pepper/pepper_browser_connection.h @@ -49,7 +49,7 @@ class PepperBrowserConnection // Called when the renderer creates an in-process instance. void DidCreateInProcessInstance(PP_Instance instance, - int render_view_id, + int render_frame_id, const GURL& document_url, const GURL& plugin_url); diff --git a/chromium/content/renderer/pepper/pepper_compositor_host.cc b/chromium/content/renderer/pepper/pepper_compositor_host.cc new file mode 100644 index 00000000000..f7e32b65f48 --- /dev/null +++ b/chromium/content/renderer/pepper/pepper_compositor_host.cc @@ -0,0 +1,385 @@ +// Copyright 2014 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 "content/renderer/pepper/pepper_compositor_host.h" + +#include "base/logging.h" +#include "base/memory/shared_memory.h" +#include "cc/layers/layer.h" +#include "cc/layers/solid_color_layer.h" +#include "cc/layers/texture_layer.h" +#include "cc/resources/texture_mailbox.h" +#include "cc/trees/layer_tree_host.h" +#include "content/public/renderer/renderer_ppapi_host.h" +#include "content/renderer/pepper/gfx_conversion.h" +#include "content/renderer/pepper/host_globals.h" +#include "content/renderer/pepper/pepper_plugin_instance_impl.h" +#include "content/renderer/pepper/ppb_image_data_impl.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/host/dispatch_host_message.h" +#include "ppapi/host/ppapi_host.h" +#include "ppapi/proxy/ppapi_messages.h" +#include "ppapi/thunk/enter.h" +#include "ppapi/thunk/ppb_image_data_api.h" +#include "third_party/khronos/GLES2/gl2.h" +#include "ui/gfx/transform.h" + +using ppapi::host::HostMessageContext; +using ppapi::thunk::EnterResourceNoLock; +using ppapi::thunk::PPB_ImageData_API; + +namespace content { + +namespace { + +int32_t VerifyCommittedLayer( + const ppapi::CompositorLayerData* old_layer, + const ppapi::CompositorLayerData* new_layer, + scoped_ptr<base::SharedMemory>* image_shm) { + if (!new_layer->is_valid()) + return PP_ERROR_BADARGUMENT; + + if (new_layer->color) { + // Make sure the old layer is a color layer too. + if (old_layer && !old_layer->color) + return PP_ERROR_BADARGUMENT; + return PP_OK; + } + + if (new_layer->texture) { + if (old_layer) { + // Make sure the old layer is a texture layer too. + if (!new_layer->texture) + return PP_ERROR_BADARGUMENT; + // The mailbox should be same, if the resource_id is not changed. + if (new_layer->common.resource_id == old_layer->common.resource_id) { + if (new_layer->texture->mailbox != old_layer->texture->mailbox) + return PP_ERROR_BADARGUMENT; + return PP_OK; + } + } + if (!new_layer->texture->mailbox.Verify()) + return PP_ERROR_BADARGUMENT; + return PP_OK; + } + + if (new_layer->image) { + if (old_layer) { + // Make sure the old layer is an image layer too. + if (!new_layer->image) + return PP_ERROR_BADARGUMENT; + // The image data resource should be same, if the resource_id is not + // changed. + if (new_layer->common.resource_id == old_layer->common.resource_id) { + if (new_layer->image->resource != old_layer->image->resource) + return PP_ERROR_BADARGUMENT; + return PP_OK; + } + } + EnterResourceNoLock<PPB_ImageData_API> enter(new_layer->image->resource, + true); + if (enter.failed()) + return PP_ERROR_BADRESOURCE; + + // TODO(penghuang): support all kinds of image. + PP_ImageDataDesc desc; + if (enter.object()->Describe(&desc) != PP_TRUE || + desc.stride != desc.size.width * 4 || + desc.format != PP_IMAGEDATAFORMAT_RGBA_PREMUL) { + return PP_ERROR_BADARGUMENT; + } + + int handle; + uint32_t byte_count; + if (enter.object()->GetSharedMemory(&handle, &byte_count) != PP_OK) + return PP_ERROR_FAILED; + +#if defined(OS_WIN) + base::SharedMemoryHandle shm_handle; + if (!::DuplicateHandle(::GetCurrentProcess(), + reinterpret_cast<base::SharedMemoryHandle>(handle), + ::GetCurrentProcess(), + &shm_handle, + 0, + FALSE, + DUPLICATE_SAME_ACCESS)) { + return PP_ERROR_FAILED; + } +#else + base::SharedMemoryHandle shm_handle(dup(handle), false); +#endif + image_shm->reset(new base::SharedMemory(shm_handle, true)); + if (!(*image_shm)->Map(desc.stride * desc.size.height)) { + image_shm->reset(); + return PP_ERROR_NOMEMORY; + } + return PP_OK; + } + + return PP_ERROR_BADARGUMENT; +} + +} // namespace + +PepperCompositorHost::LayerData::LayerData( + const scoped_refptr<cc::Layer>& cc, + const ppapi::CompositorLayerData& pp) : cc_layer(cc), pp_layer(pp) {} + +PepperCompositorHost::LayerData::~LayerData() {} + +PepperCompositorHost::PepperCompositorHost( + RendererPpapiHost* host, + PP_Instance instance, + PP_Resource resource) + : ResourceHost(host->GetPpapiHost(), instance, resource), + bound_instance_(NULL), + weak_factory_(this) { + layer_ = cc::Layer::Create(); + // TODO(penghuang): SetMasksToBounds() can be expensive if the layer is + // transformed. Possibly better could be to explicitly clip the child layers + // (by modifying their bounds). + layer_->SetMasksToBounds(true); + layer_->SetIsDrawable(true); +} + +PepperCompositorHost::~PepperCompositorHost() { + // Unbind from the instance when destroyed if we're still bound. + if (bound_instance_) + bound_instance_->BindGraphics(bound_instance_->pp_instance(), 0); +} + +bool PepperCompositorHost::BindToInstance( + PepperPluginInstanceImpl* new_instance) { + if (new_instance && new_instance->pp_instance() != pp_instance()) + return false; // Can't bind other instance's contexts. + 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. + bound_instance_ = new_instance; + if (!bound_instance_) + SendCommitLayersReplyIfNecessary(); + + return true; +} + +void PepperCompositorHost::ViewInitiatedPaint() { + SendCommitLayersReplyIfNecessary(); +} + +void PepperCompositorHost::ViewFlushedPaint() {} + +void PepperCompositorHost::ImageReleased( + int32_t id, + const scoped_ptr<base::SharedMemory>& shared_memory, + uint32_t sync_point, + bool is_lost) { + ResourceReleased(id, sync_point, is_lost); +} + +void PepperCompositorHost::ResourceReleased(int32_t id, + uint32_t sync_point, + bool is_lost) { + host()->SendUnsolicitedReply( + pp_resource(), + PpapiPluginMsg_Compositor_ReleaseResource(id, sync_point, is_lost)); +} + +void PepperCompositorHost::SendCommitLayersReplyIfNecessary() { + if (!commit_layers_reply_context_.is_valid()) + return; + host()->SendReply(commit_layers_reply_context_, + PpapiPluginMsg_Compositor_CommitLayersReply()); + commit_layers_reply_context_ = ppapi::host::ReplyMessageContext(); +} + +void PepperCompositorHost::UpdateLayer( + const scoped_refptr<cc::Layer>& layer, + const ppapi::CompositorLayerData* old_layer, + const ppapi::CompositorLayerData* new_layer, + scoped_ptr<base::SharedMemory> image_shm) { + // Always update properties on cc::Layer, because cc::Layer + // will ignore any setting with unchanged value. + layer->SetIsDrawable(true); + layer->SetBlendMode(SkXfermode::kSrcOver_Mode); + layer->SetOpacity(new_layer->common.opacity); + layer->SetBounds(PP_ToGfxSize(new_layer->common.size)); + layer->SetTransformOrigin(gfx::Point3F(new_layer->common.size.width / 2, + new_layer->common.size.height / 2, + 0.0f)); + + gfx::Transform transform(gfx::Transform::kSkipInitialization); + transform.matrix().setColMajorf(new_layer->common.transform.matrix); + layer->SetTransform(transform); + + // Consider a (0,0,0,0) rect as no clip rect. + if (new_layer->common.clip_rect.point.x != 0 || + new_layer->common.clip_rect.point.y != 0 || + new_layer->common.clip_rect.size.width != 0 || + new_layer->common.clip_rect.size.height != 0) { + scoped_refptr<cc::Layer> clip_parent = layer->parent(); + if (clip_parent == layer_) { + // Create a clip parent layer, if it does not exist. + clip_parent = cc::Layer::Create(); + clip_parent->SetMasksToBounds(true); + clip_parent->SetIsDrawable(true); + layer_->ReplaceChild(layer, clip_parent); + clip_parent->AddChild(layer); + } + gfx::Point position = PP_ToGfxPoint(new_layer->common.clip_rect.point); + clip_parent->SetPosition(position); + clip_parent->SetBounds(PP_ToGfxSize(new_layer->common.clip_rect.size)); + layer->SetPosition(gfx::Point(-position.x(), -position.y())); + } else if (layer->parent() != layer_) { + // Remove the clip parent layer. + layer_->ReplaceChild(layer->parent(), layer); + layer->SetPosition(gfx::Point()); + } + + if (new_layer->color) { + layer->SetBackgroundColor(SkColorSetARGBMacro( + new_layer->color->alpha * 255, + new_layer->color->red * 255, + new_layer->color->green * 255, + new_layer->color->blue * 255)); + return; + } + + if (new_layer->texture) { + scoped_refptr<cc::TextureLayer> texture_layer( + static_cast<cc::TextureLayer*>(layer.get())); + if (!old_layer || + new_layer->common.resource_id != old_layer->common.resource_id) { + cc::TextureMailbox mailbox(new_layer->texture->mailbox, + GL_TEXTURE_2D, + new_layer->texture->sync_point); + texture_layer->SetTextureMailbox(mailbox, + cc::SingleReleaseCallback::Create( + base::Bind(&PepperCompositorHost::ResourceReleased, + weak_factory_.GetWeakPtr(), + new_layer->common.resource_id)));; + } + texture_layer->SetPremultipliedAlpha(new_layer->texture->premult_alpha); + gfx::RectF rect = PP_ToGfxRectF(new_layer->texture->source_rect); + texture_layer->SetUV(rect.origin(), rect.bottom_right()); + return; + } + + if (new_layer->image) { + if (!old_layer || + new_layer->common.resource_id != old_layer->common.resource_id) { + scoped_refptr<cc::TextureLayer> image_layer( + static_cast<cc::TextureLayer*>(layer.get())); + EnterResourceNoLock<PPB_ImageData_API> enter(new_layer->image->resource, + true); + DCHECK(enter.succeeded()); + + // TODO(penghuang): support all kinds of image. + PP_ImageDataDesc desc; + PP_Bool rv = enter.object()->Describe(&desc); + DCHECK_EQ(rv, PP_TRUE); + DCHECK_EQ(desc.stride, desc.size.width * 4); + DCHECK_EQ(desc.format, PP_IMAGEDATAFORMAT_RGBA_PREMUL); + + cc::TextureMailbox mailbox(image_shm.get(), + PP_ToGfxSize(desc.size)); + image_layer->SetTextureMailbox(mailbox, + cc::SingleReleaseCallback::Create( + base::Bind(&PepperCompositorHost::ImageReleased, + weak_factory_.GetWeakPtr(), + new_layer->common.resource_id, + base::Passed(&image_shm)))); + + // ImageData is always premultiplied alpha. + image_layer->SetPremultipliedAlpha(true); + } + return; + } + // Should not be reached. + NOTREACHED(); +} + +int32_t PepperCompositorHost::OnResourceMessageReceived( + const IPC::Message& msg, + HostMessageContext* context) { + PPAPI_BEGIN_MESSAGE_MAP(PepperCompositorHost, msg) + PPAPI_DISPATCH_HOST_RESOURCE_CALL( + PpapiHostMsg_Compositor_CommitLayers, OnHostMsgCommitLayers) + PPAPI_END_MESSAGE_MAP() + return ppapi::host::ResourceHost::OnResourceMessageReceived(msg, context); +} + +bool PepperCompositorHost::IsCompositorHost() { + return true; +} + +int32_t PepperCompositorHost::OnHostMsgCommitLayers( + HostMessageContext* context, + const std::vector<ppapi::CompositorLayerData>& layers, + bool reset) { + if (commit_layers_reply_context_.is_valid()) + return PP_ERROR_INPROGRESS; + + scoped_ptr<scoped_ptr<base::SharedMemory>[]> image_shms; + if (layers.size() > 0) { + image_shms.reset(new scoped_ptr<base::SharedMemory>[layers.size()]); + if (!image_shms) + return PP_ERROR_NOMEMORY; + // Verfiy the layers first, if an error happens, we will return the error to + // plugin and keep current layers set by the previous CommitLayers() + // unchanged. + for (size_t i = 0; i < layers.size(); ++i) { + const ppapi::CompositorLayerData* old_layer = NULL; + if (!reset && i < layers_.size()) + old_layer = &layers_[i].pp_layer; + int32_t rv = VerifyCommittedLayer(old_layer, &layers[i], &image_shms[i]); + if (rv != PP_OK) + return rv; + } + } + + // ResetLayers() has been called, we need rebuild layer stack. + if (reset) { + layer_->RemoveAllChildren(); + layers_.clear(); + } + + for (size_t i = 0; i < layers.size(); ++i) { + const ppapi::CompositorLayerData* pp_layer = &layers[i]; + LayerData* data = i >= layers_.size() ? NULL : &layers_[i]; + DCHECK(!data || data->cc_layer); + scoped_refptr<cc::Layer> cc_layer = data ? data->cc_layer : NULL; + ppapi::CompositorLayerData* old_layer = data ? &data->pp_layer : NULL; + + if (!cc_layer) { + if (pp_layer->color) + cc_layer = cc::SolidColorLayer::Create(); + else if (pp_layer->texture || pp_layer->image) + cc_layer = cc::TextureLayer::CreateForMailbox(NULL); + layer_->AddChild(cc_layer); + } + + UpdateLayer(cc_layer, old_layer, pp_layer, image_shms[i].Pass()); + + if (old_layer) + *old_layer = *pp_layer; + else + layers_.push_back(LayerData(cc_layer, *pp_layer)); + } + + // We need to force a commit for each CommitLayers() call, even if no layers + // changed since the last call to CommitLayers(). This is so + // WiewInitiatedPaint() will always be called. + if (layer_->layer_tree_host()) + layer_->layer_tree_host()->SetNeedsCommit(); + + // If the host is not bound to the instance, return PP_OK immediately. + if (!bound_instance_) + return PP_OK; + + commit_layers_reply_context_ = context->MakeReplyMessageContext(); + return PP_OK_COMPLETIONPENDING; +} + +} // namespace content diff --git a/chromium/content/renderer/pepper/pepper_compositor_host.h b/chromium/content/renderer/pepper/pepper_compositor_host.h new file mode 100644 index 00000000000..de2f72bac25 --- /dev/null +++ b/chromium/content/renderer/pepper/pepper_compositor_host.h @@ -0,0 +1,102 @@ +// Copyright 2014 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 CONTENT_RENDERER_PEPPER_PEPPER_COMPOSITOR_H_ +#define CONTENT_RENDERER_PEPPER_PEPPER_COMPOSITOR_H_ + +#include "base/compiler_specific.h" +#include "base/memory/scoped_ptr.h" +#include "base/memory/weak_ptr.h" +#include "ppapi/host/host_message_context.h" +#include "ppapi/host/resource_host.h" +#include "ppapi/shared_impl/compositor_layer_data.h" + +namespace base { +class SharedMemory; +} // namespace + +namespace cc { +class Layer; +} // namespace cc + +namespace content { + +class PepperPluginInstanceImpl; +class RendererPpapiHost; + +class PepperCompositorHost : public ppapi::host::ResourceHost { + public: + PepperCompositorHost(RendererPpapiHost* host, + PP_Instance instance, + PP_Resource resource); + // Associates this device with the given plugin instance. You can pass NULL + // to clear the existing device. Returns true on success. In this case, a + // repaint of the page will also be scheduled. Failure means that the device + // is already bound to a different instance, and nothing will happen. + bool BindToInstance(PepperPluginInstanceImpl* new_instance); + + const scoped_refptr<cc::Layer> layer() { return layer_; }; + + void ViewInitiatedPaint(); + void ViewFlushedPaint(); + + private: + virtual ~PepperCompositorHost(); + + void ImageReleased(int32_t id, + const scoped_ptr<base::SharedMemory>& shared_memory, + uint32_t sync_point, + bool is_lost); + void ResourceReleased(int32_t id, + uint32_t sync_point, + bool is_lost); + void SendCommitLayersReplyIfNecessary(); + void UpdateLayer(const scoped_refptr<cc::Layer>& layer, + const ppapi::CompositorLayerData* old_layer, + const ppapi::CompositorLayerData* new_layer, + scoped_ptr<base::SharedMemory> image_shm); + + // ResourceMessageHandler overrides: + virtual int32_t OnResourceMessageReceived( + const IPC::Message& msg, + ppapi::host::HostMessageContext* context) OVERRIDE; + + // ppapi::host::ResourceHost overrides: + virtual bool IsCompositorHost() OVERRIDE; + + // Message handlers: + int32_t OnHostMsgCommitLayers( + ppapi::host::HostMessageContext* context, + const std::vector<ppapi::CompositorLayerData>& layers, + bool reset); + + // 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. + PepperPluginInstanceImpl* bound_instance_; + + // The toplevel cc::Layer. It is the parent of other cc::Layers. + scoped_refptr<cc::Layer> layer_; + + // A list of layers. It is used for updating layers' properties in + // subsequent CommitLayers() calls. + struct LayerData { + LayerData(const scoped_refptr<cc::Layer>& cc, + const ppapi::CompositorLayerData& pp); + ~LayerData(); + + scoped_refptr<cc::Layer> cc_layer; + ppapi::CompositorLayerData pp_layer; + }; + std::vector<LayerData> layers_; + + ppapi::host::ReplyMessageContext commit_layers_reply_context_; + + base::WeakPtrFactory<PepperCompositorHost> weak_factory_; + + DISALLOW_COPY_AND_ASSIGN(PepperCompositorHost); +}; + +} // namespace content + +#endif // CONTENT_RENDERER_PEPPER_PEPPER_COMPOSITOR_H_ diff --git a/chromium/content/renderer/pepper/pepper_device_enumeration_host_helper.cc b/chromium/content/renderer/pepper/pepper_device_enumeration_host_helper.cc index 28beb20936e..d983f4a5816 100644 --- a/chromium/content/renderer/pepper/pepper_device_enumeration_host_helper.cc +++ b/chromium/content/renderer/pepper/pepper_device_enumeration_host_helper.cc @@ -26,9 +26,8 @@ class PepperDeviceEnumerationHostHelper::ScopedRequest : public base::SupportsWeakPtr<ScopedRequest> { public: // |owner| must outlive this object. - ScopedRequest( - PepperDeviceEnumerationHostHelper* owner, - const Delegate::EnumerateDevicesCallback& callback) + ScopedRequest(PepperDeviceEnumerationHostHelper* owner, + const Delegate::EnumerateDevicesCallback& callback) : owner_(owner), callback_(callback), requested_(false), @@ -98,11 +97,9 @@ PepperDeviceEnumerationHostHelper::PepperDeviceEnumerationHostHelper( : resource_host_(resource_host), delegate_(delegate), device_type_(device_type), - document_url_(document_url) { -} + document_url_(document_url) {} -PepperDeviceEnumerationHostHelper::~PepperDeviceEnumerationHostHelper() { -} +PepperDeviceEnumerationHostHelper::~PepperDeviceEnumerationHostHelper() {} bool PepperDeviceEnumerationHostHelper::HandleResourceMessage( const IPC::Message& msg, @@ -118,7 +115,7 @@ int32_t PepperDeviceEnumerationHostHelper::InternalHandleResourceMessage( HostMessageContext* context, bool* handled) { *handled = true; - IPC_BEGIN_MESSAGE_MAP(PepperDeviceEnumerationHostHelper, msg) + PPAPI_BEGIN_MESSAGE_MAP(PepperDeviceEnumerationHostHelper, msg) PPAPI_DISPATCH_HOST_RESOURCE_CALL_0( PpapiHostMsg_DeviceEnumeration_EnumerateDevices, OnEnumerateDevices) PPAPI_DISPATCH_HOST_RESOURCE_CALL( @@ -127,7 +124,7 @@ int32_t PepperDeviceEnumerationHostHelper::InternalHandleResourceMessage( PPAPI_DISPATCH_HOST_RESOURCE_CALL_0( PpapiHostMsg_DeviceEnumeration_StopMonitoringDeviceChange, OnStopMonitoringDeviceChange) - IPC_END_MESSAGE_MAP() + PPAPI_END_MESSAGE_MAP() *handled = false; return PP_ERROR_FAILED; @@ -135,7 +132,7 @@ int32_t PepperDeviceEnumerationHostHelper::InternalHandleResourceMessage( int32_t PepperDeviceEnumerationHostHelper::OnEnumerateDevices( HostMessageContext* context) { - if (enumerate_devices_context_) + if (enumerate_devices_context_.is_valid()) return PP_ERROR_INPROGRESS; enumerate_.reset(new ScopedRequest( @@ -145,8 +142,7 @@ int32_t PepperDeviceEnumerationHostHelper::OnEnumerateDevices( if (!enumerate_->requested()) return PP_ERROR_FAILED; - enumerate_devices_context_.reset( - new ppapi::host::ReplyMessageContext(context->MakeReplyMessageContext())); + enumerate_devices_context_ = context->MakeReplyMessageContext(); return PP_OK_COMPLETIONPENDING; } @@ -156,7 +152,8 @@ int32_t PepperDeviceEnumerationHostHelper::OnMonitorDeviceChange( monitor_.reset(new ScopedRequest( this, base::Bind(&PepperDeviceEnumerationHostHelper::OnNotifyDeviceChange, - base::Unretained(this), callback_id))); + base::Unretained(this), + callback_id))); return monitor_->requested() ? PP_OK : PP_ERROR_FAILED; } @@ -170,15 +167,15 @@ int32_t PepperDeviceEnumerationHostHelper::OnStopMonitoringDeviceChange( void PepperDeviceEnumerationHostHelper::OnEnumerateDevicesComplete( int /* request_id */, const std::vector<ppapi::DeviceRefData>& devices) { - DCHECK(enumerate_devices_context_.get()); + DCHECK(enumerate_devices_context_.is_valid()); enumerate_.reset(NULL); - enumerate_devices_context_->params.set_result(PP_OK); + enumerate_devices_context_.params.set_result(PP_OK); resource_host_->host()->SendReply( - *enumerate_devices_context_, + enumerate_devices_context_, PpapiPluginMsg_DeviceEnumeration_EnumerateDevicesReply(devices)); - enumerate_devices_context_.reset(); + enumerate_devices_context_ = ppapi::host::ReplyMessageContext(); } void PepperDeviceEnumerationHostHelper::OnNotifyDeviceChange( @@ -187,9 +184,8 @@ void PepperDeviceEnumerationHostHelper::OnNotifyDeviceChange( const std::vector<ppapi::DeviceRefData>& devices) { resource_host_->host()->SendUnsolicitedReply( resource_host_->pp_resource(), - PpapiPluginMsg_DeviceEnumeration_NotifyDeviceChange( - callback_id, - devices)); + PpapiPluginMsg_DeviceEnumeration_NotifyDeviceChange(callback_id, + devices)); } } // namespace content diff --git a/chromium/content/renderer/pepper/pepper_device_enumeration_host_helper.h b/chromium/content/renderer/pepper/pepper_device_enumeration_host_helper.h index 4142dec758e..088d4661c0e 100644 --- a/chromium/content/renderer/pepper/pepper_device_enumeration_host_helper.h +++ b/chromium/content/renderer/pepper/pepper_device_enumeration_host_helper.h @@ -12,17 +12,17 @@ #include "base/memory/scoped_ptr.h" #include "content/common/content_export.h" #include "ppapi/c/dev/ppb_device_ref_dev.h" +#include "ppapi/host/host_message_context.h" #include "url/gurl.h" namespace ppapi { struct DeviceRefData; namespace host { -struct HostMessageContext; -struct ReplyMessageContext; class ResourceHost; } -} + +} // namespace ppapi namespace IPC { class Message; @@ -42,8 +42,8 @@ class CONTENT_EXPORT PepperDeviceEnumerationHostHelper { virtual ~Delegate() {} typedef base::Callback< - void (int /* request_id */, - const std::vector<ppapi::DeviceRefData>& /* devices */)> + void(int /* request_id */, + const std::vector<ppapi::DeviceRefData>& /* devices */)> EnumerateDevicesCallback; // Enumerates devices of the specified type. The request ID passed into the @@ -87,10 +87,9 @@ class CONTENT_EXPORT PepperDeviceEnumerationHostHelper { void OnEnumerateDevicesComplete( int request_id, const std::vector<ppapi::DeviceRefData>& devices); - void OnNotifyDeviceChange( - uint32_t callback_id, - int request_id, - const std::vector<ppapi::DeviceRefData>& devices); + void OnNotifyDeviceChange(uint32_t callback_id, + int request_id, + const std::vector<ppapi::DeviceRefData>& devices); // Non-owning pointers. ppapi::host::ResourceHost* resource_host_; @@ -102,7 +101,7 @@ class CONTENT_EXPORT PepperDeviceEnumerationHostHelper { scoped_ptr<ScopedRequest> enumerate_; scoped_ptr<ScopedRequest> monitor_; - scoped_ptr<ppapi::host::ReplyMessageContext> enumerate_devices_context_; + ppapi::host::ReplyMessageContext enumerate_devices_context_; DISALLOW_COPY_AND_ASSIGN(PepperDeviceEnumerationHostHelper); }; diff --git a/chromium/content/renderer/pepper/pepper_device_enumeration_host_helper_unittest.cc b/chromium/content/renderer/pepper/pepper_device_enumeration_host_helper_unittest.cc index 298e953bf64..a9b2579ce66 100644 --- a/chromium/content/renderer/pepper/pepper_device_enumeration_host_helper_unittest.cc +++ b/chromium/content/renderer/pepper/pepper_device_enumeration_host_helper_unittest.cc @@ -26,17 +26,14 @@ namespace { class TestDelegate : public PepperDeviceEnumerationHostHelper::Delegate { public: - TestDelegate() : last_used_id_(0) { - } + TestDelegate() : last_used_id_(0) {} - virtual ~TestDelegate() { - CHECK(callbacks_.empty()); - } + virtual ~TestDelegate() { CHECK(callbacks_.empty()); } - virtual int EnumerateDevices( - PP_DeviceType_Dev /* type */, - const GURL& /* document_url */, - const EnumerateDevicesCallback& callback) OVERRIDE { + virtual int EnumerateDevices(PP_DeviceType_Dev /* type */, + const GURL& /* document_url */, + const EnumerateDevicesCallback& callback) + OVERRIDE { last_used_id_++; callbacks_[last_used_id_] = callback; return last_used_id_; @@ -78,10 +75,10 @@ class PepperDeviceEnumerationHostHelperTest : public testing::Test { PepperDeviceEnumerationHostHelperTest() : ppapi_host_(&sink_, ppapi::PpapiPermissions()), resource_host_(&ppapi_host_, 12345, 67890), - device_enumeration_(&resource_host_, &delegate_, + device_enumeration_(&resource_host_, + &delegate_, PP_DEVICETYPE_DEV_AUDIOCAPTURE, - GURL("http://example.com")) { - } + GURL("http://example.com")) {} virtual ~PepperDeviceEnumerationHostHelperTest() {} @@ -91,8 +88,8 @@ class PepperDeviceEnumerationHostHelperTest : public testing::Test { resource_host_.pp_resource(), 123); ppapi::host::HostMessageContext context(call_params); int32_t result = PP_ERROR_FAILED; - ASSERT_TRUE(device_enumeration_.HandleResourceMessage( - msg, &context, &result)); + ASSERT_TRUE( + device_enumeration_.HandleResourceMessage(msg, &context, &result)); EXPECT_EQ(PP_OK, result); } @@ -103,7 +100,8 @@ class PepperDeviceEnumerationHostHelperTest : public testing::Test { IPC::Message reply_msg; ASSERT_TRUE(sink_.GetFirstResourceReplyMatching( PpapiPluginMsg_DeviceEnumeration_NotifyDeviceChange::ID, - &reply_params, &reply_msg)); + &reply_params, + &reply_msg)); sink_.ClearMessages(); EXPECT_EQ(PP_OK, reply_params.result()); @@ -112,7 +110,7 @@ class PepperDeviceEnumerationHostHelperTest : public testing::Test { std::vector<ppapi::DeviceRefData> reply_data; ASSERT_TRUE(ppapi::UnpackMessage< PpapiPluginMsg_DeviceEnumeration_NotifyDeviceChange>( - reply_msg, &reply_callback_id, &reply_data)); + reply_msg, &reply_callback_id, &reply_data)); EXPECT_EQ(callback_id, reply_callback_id); EXPECT_EQ(expected, reply_data); } @@ -135,8 +133,8 @@ TEST_F(PepperDeviceEnumerationHostHelperTest, EnumerateDevices) { resource_host_.pp_resource(), 123); ppapi::host::HostMessageContext context(call_params); int32_t result = PP_ERROR_FAILED; - ASSERT_TRUE(device_enumeration_.HandleResourceMessage(msg, &context, - &result)); + ASSERT_TRUE( + device_enumeration_.HandleResourceMessage(msg, &context, &result)); EXPECT_EQ(PP_OK_COMPLETIONPENDING, result); EXPECT_EQ(1U, delegate_.GetRegisteredCallbackCount()); @@ -163,15 +161,16 @@ TEST_F(PepperDeviceEnumerationHostHelperTest, EnumerateDevices) { IPC::Message reply_msg; ASSERT_TRUE(sink_.GetFirstResourceReplyMatching( PpapiPluginMsg_DeviceEnumeration_EnumerateDevicesReply::ID, - &reply_params, &reply_msg)); + &reply_params, + &reply_msg)); EXPECT_EQ(call_params.sequence(), reply_params.sequence()); EXPECT_EQ(PP_OK, reply_params.result()); std::vector<ppapi::DeviceRefData> reply_data; ASSERT_TRUE(ppapi::UnpackMessage< - PpapiPluginMsg_DeviceEnumeration_EnumerateDevicesReply>( - reply_msg, &reply_data)); + PpapiPluginMsg_DeviceEnumeration_EnumerateDevicesReply>(reply_msg, + &reply_data)); EXPECT_EQ(data, reply_data); } @@ -225,8 +224,8 @@ TEST_F(PepperDeviceEnumerationHostHelperTest, MonitorDeviceChange) { resource_host_.pp_resource(), 123); ppapi::host::HostMessageContext context(call_params); int32_t result = PP_ERROR_FAILED; - ASSERT_TRUE(device_enumeration_.HandleResourceMessage( - msg, &context, &result)); + ASSERT_TRUE( + device_enumeration_.HandleResourceMessage(msg, &context, &result)); EXPECT_EQ(PP_OK, result); EXPECT_EQ(0U, delegate_.GetRegisteredCallbackCount()); diff --git a/chromium/content/renderer/pepper/pepper_file_chooser_host.cc b/chromium/content/renderer/pepper/pepper_file_chooser_host.cc index ca13f5a7949..d067c201e39 100644 --- a/chromium/content/renderer/pepper/pepper_file_chooser_host.cc +++ b/chromium/content/renderer/pepper/pepper_file_chooser_host.cc @@ -24,9 +24,8 @@ namespace content { class PepperFileChooserHost::CompletionHandler : public blink::WebFileChooserCompletion { public: - CompletionHandler(const base::WeakPtr<PepperFileChooserHost>& host) - : host_(host) { - } + explicit CompletionHandler(const base::WeakPtr<PepperFileChooserHost>& host) + : host_(host) {} virtual ~CompletionHandler() {} @@ -50,8 +49,7 @@ class PepperFileChooserHost::CompletionHandler std::vector<PepperFileChooserHost::ChosenFileInfo> files; for (size_t i = 0; i < file_names.size(); i++) { files.push_back(PepperFileChooserHost::ChosenFileInfo( - file_names[i].path.utf8(), - file_names[i].displayName.utf8())); + file_names[i].path.utf8(), file_names[i].displayName.utf8())); } host_->StoreChosenFiles(files); } @@ -69,30 +67,24 @@ class PepperFileChooserHost::CompletionHandler PepperFileChooserHost::ChosenFileInfo::ChosenFileInfo( const std::string& path, const std::string& display_name) - : path(path), - display_name(display_name) { -} - + : path(path), display_name(display_name) {} -PepperFileChooserHost::PepperFileChooserHost( - RendererPpapiHost* host, - PP_Instance instance, - PP_Resource resource) +PepperFileChooserHost::PepperFileChooserHost(RendererPpapiHost* host, + PP_Instance instance, + PP_Resource resource) : ResourceHost(host->GetPpapiHost(), instance, resource), renderer_ppapi_host_(host), handler_(NULL), - weak_factory_(this) { -} + weak_factory_(this) {} -PepperFileChooserHost::~PepperFileChooserHost() { -} +PepperFileChooserHost::~PepperFileChooserHost() {} int32_t PepperFileChooserHost::OnResourceMessageReceived( const IPC::Message& msg, ppapi::host::HostMessageContext* context) { - IPC_BEGIN_MESSAGE_MAP(PepperFileChooserHost, msg) + PPAPI_BEGIN_MESSAGE_MAP(PepperFileChooserHost, msg) PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FileChooser_Show, OnShow) - IPC_END_MESSAGE_MAP() + PPAPI_END_MESSAGE_MAP() return PP_ERROR_FAILED; } @@ -103,12 +95,12 @@ void PepperFileChooserHost::StoreChosenFiles( std::vector<std::string> display_names; for (size_t i = 0; i < files.size(); i++) { #if defined(OS_WIN) - base::FilePath file_path(UTF8ToWide(files[i].path)); + base::FilePath file_path(base::UTF8ToWide(files[i].path)); #else base::FilePath file_path(files[i].path); #endif file_paths.push_back(file_path); - create_msgs.push_back(PpapiHostMsg_FileRef_CreateExternal(file_path)); + create_msgs.push_back(PpapiHostMsg_FileRef_CreateForRawFS(file_path)); display_names.push_back(files[i].display_name); } @@ -141,7 +133,7 @@ int32_t PepperFileChooserHost::OnShow( if (!host()->permissions().HasPermission( ppapi::PERMISSION_BYPASS_USER_GESTURE) && - !renderer_ppapi_host_->HasUserGesture(pp_instance())) { + !renderer_ppapi_host_->HasUserGesture(pp_instance())) { return PP_ERROR_NO_USER_GESTURE; } @@ -155,8 +147,8 @@ int32_t PepperFileChooserHost::OnShow( } std::vector<blink::WebString> mine_types(accept_mime_types.size()); for (size_t i = 0; i < accept_mime_types.size(); i++) { - mine_types[i] = blink::WebString::fromUTF8( - accept_mime_types[i].data(), accept_mime_types[i].size()); + mine_types[i] = blink::WebString::fromUTF8(accept_mime_types[i].data(), + accept_mime_types[i].size()); } params.acceptTypes = mine_types; params.directory = false; @@ -183,11 +175,8 @@ void PepperFileChooserHost::DidCreateResourceHosts( std::vector<ppapi::FileRefCreateInfo> chosen_files; for (size_t i = 0; i < browser_ids.size(); ++i) { - PepperFileRefRendererHost* renderer_host = - new PepperFileRefRendererHost(renderer_ppapi_host_, - pp_instance(), - 0, - file_paths[i]); + PepperFileRefRendererHost* renderer_host = new PepperFileRefRendererHost( + renderer_ppapi_host_, pp_instance(), 0, file_paths[i]); int renderer_id = renderer_ppapi_host_->GetPpapiHost()->AddPendingResourceHost( scoped_ptr<ppapi::host::ResourceHost>(renderer_host)); @@ -204,4 +193,3 @@ void PepperFileChooserHost::DidCreateResourceHosts( } } // namespace content - diff --git a/chromium/content/renderer/pepper/pepper_file_chooser_host_unittest.cc b/chromium/content/renderer/pepper/pepper_file_chooser_host_unittest.cc index 0afde5be3fd..3868b54d8a2 100644 --- a/chromium/content/renderer/pepper/pepper_file_chooser_host_unittest.cc +++ b/chromium/content/renderer/pepper/pepper_file_chooser_host_unittest.cc @@ -31,8 +31,7 @@ namespace { class PepperFileChooserHostTest : public RenderViewTest { public: - PepperFileChooserHostTest() - : pp_instance_(123456) {} + PepperFileChooserHostTest() : pp_instance_(123456) {} virtual void SetUp() { SetContentClient(&client_); @@ -59,7 +58,7 @@ class PepperFileChooserHostTest : public RenderViewTest { // For testing to convert our hardcoded file paths to 8-bit. std::string FilePathToUTF8(const base::FilePath::StringType& path) { #if defined(OS_WIN) - return UTF16ToUTF8(path); + return base::UTF16ToUTF8(path); #else return path; #endif @@ -97,7 +96,7 @@ TEST_F(PepperFileChooserHostTest, Show) { // Basic validation of request. EXPECT_EQ(FileChooserParams::Open, chooser_params.mode); ASSERT_EQ(1u, chooser_params.accept_types.size()); - EXPECT_EQ(accept[0], UTF16ToUTF8(chooser_params.accept_types[0])); + EXPECT_EQ(accept[0], base::UTF16ToUTF8(chooser_params.accept_types[0])); // Send a chooser reply to the render view. Note our reply path has to have a // path separator so we include both a Unix and a Windows one. @@ -121,8 +120,8 @@ TEST_F(PepperFileChooserHostTest, Show) { EXPECT_EQ(call_params.sequence(), reply_params.sequence()); EXPECT_EQ(PP_OK, reply_params.result()); PpapiPluginMsg_FileChooser_ShowReply::Schema::Param reply_msg_param; - ASSERT_TRUE(PpapiPluginMsg_FileChooser_ShowReply::Read(&reply_msg, - &reply_msg_param)); + ASSERT_TRUE( + PpapiPluginMsg_FileChooser_ShowReply::Read(&reply_msg, &reply_msg_param)); const std::vector<ppapi::FileRefCreateInfo>& chooser_results = reply_msg_param.a; ASSERT_EQ(1u, chooser_results.size()); diff --git a/chromium/content/renderer/pepper/pepper_file_ref_renderer_host.cc b/chromium/content/renderer/pepper/pepper_file_ref_renderer_host.cc index 0f1442b7996..386f53e97e0 100644 --- a/chromium/content/renderer/pepper/pepper_file_ref_renderer_host.cc +++ b/chromium/content/renderer/pepper/pepper_file_ref_renderer_host.cc @@ -43,8 +43,7 @@ PepperFileRefRendererHost::PepperFileRefRendererHost( file_system_type_ = PP_FILESYSTEMTYPE_INVALID; } -PepperFileRefRendererHost::~PepperFileRefRendererHost() { -} +PepperFileRefRendererHost::~PepperFileRefRendererHost() {} PP_FileSystemType PepperFileRefRendererHost::GetFileSystemType() const { return file_system_type_; @@ -69,15 +68,13 @@ base::FilePath PepperFileRefRendererHost::GetExternalFilePath() const { } int32_t PepperFileRefRendererHost::OnResourceMessageReceived( - const IPC::Message& msg, - ppapi::host::HostMessageContext* context) { + const IPC::Message& msg, + ppapi::host::HostMessageContext* context) { // We don't handle any messages from the plugin in this host. NOTREACHED(); return PP_ERROR_FAILED; } -bool PepperFileRefRendererHost::IsFileRefHost() { - return true; -} +bool PepperFileRefRendererHost::IsFileRefHost() { return true; } } // namespace content diff --git a/chromium/content/renderer/pepper/pepper_file_ref_renderer_host.h b/chromium/content/renderer/pepper/pepper_file_ref_renderer_host.h index 0e33816e479..9cfc65f657d 100644 --- a/chromium/content/renderer/pepper/pepper_file_ref_renderer_host.h +++ b/chromium/content/renderer/pepper/pepper_file_ref_renderer_host.h @@ -22,8 +22,7 @@ namespace content { -class PepperFileRefRendererHost - : public ppapi::host::ResourceHost { +class PepperFileRefRendererHost : public ppapi::host::ResourceHost { public: PepperFileRefRendererHost(RendererPpapiHost* host, PP_Instance instance, diff --git a/chromium/content/renderer/pepper/pepper_file_system_host.cc b/chromium/content/renderer/pepper/pepper_file_system_host.cc index be5cead8240..036d319a612 100644 --- a/chromium/content/renderer/pepper/pepper_file_system_host.cc +++ b/chromium/content/renderer/pepper/pepper_file_system_host.cc @@ -33,8 +33,7 @@ PepperFileSystemHost::PepperFileSystemHost(RendererPpapiHost* host, type_(type), opened_(false), called_open_(false), - weak_factory_(this) { -} + weak_factory_(this) {} PepperFileSystemHost::PepperFileSystemHost(RendererPpapiHost* host, PP_Instance instance, @@ -47,29 +46,24 @@ PepperFileSystemHost::PepperFileSystemHost(RendererPpapiHost* host, opened_(true), root_url_(root_url), called_open_(true), - weak_factory_(this) { -} + weak_factory_(this) {} -PepperFileSystemHost::~PepperFileSystemHost() { -} +PepperFileSystemHost::~PepperFileSystemHost() {} int32_t PepperFileSystemHost::OnResourceMessageReceived( const IPC::Message& msg, ppapi::host::HostMessageContext* context) { - IPC_BEGIN_MESSAGE_MAP(PepperFileSystemHost, msg) - PPAPI_DISPATCH_HOST_RESOURCE_CALL( - PpapiHostMsg_FileSystem_Open, - OnHostMsgOpen) + PPAPI_BEGIN_MESSAGE_MAP(PepperFileSystemHost, msg) + PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FileSystem_Open, + OnHostMsgOpen) PPAPI_DISPATCH_HOST_RESOURCE_CALL( PpapiHostMsg_FileSystem_InitIsolatedFileSystem, OnHostMsgInitIsolatedFileSystem) - IPC_END_MESSAGE_MAP() + PPAPI_END_MESSAGE_MAP() return PP_ERROR_FAILED; } -bool PepperFileSystemHost::IsFileSystemHost() { - return true; -} +bool PepperFileSystemHost::IsFileSystemHost() { return true; } void PepperFileSystemHost::DidOpenFileSystem( const std::string& /* name_unused */, @@ -81,9 +75,8 @@ void PepperFileSystemHost::DidOpenFileSystem( reply_context_ = ppapi::host::ReplyMessageContext(); } -void PepperFileSystemHost::DidFailOpenFileSystem( - base::PlatformFileError error) { - int32 pp_error = ppapi::PlatformFileErrorToPepperError(error); +void PepperFileSystemHost::DidFailOpenFileSystem(base::File::Error error) { + int32 pp_error = ppapi::FileErrorToPepperError(error); opened_ = (pp_error == PP_OK); reply_context_.params.set_result(pp_error); host()->SendReply(reply_context_, PpapiPluginMsg_FileSystem_OpenReply()); diff --git a/chromium/content/renderer/pepper/pepper_file_system_host.h b/chromium/content/renderer/pepper/pepper_file_system_host.h index 0e0be311c1c..e1657a1d50b 100644 --- a/chromium/content/renderer/pepper/pepper_file_system_host.h +++ b/chromium/content/renderer/pepper/pepper_file_system_host.h @@ -8,6 +8,7 @@ #include <string> #include "base/basictypes.h" +#include "base/files/file.h" #include "base/memory/weak_ptr.h" #include "ppapi/c/pp_file_info.h" #include "ppapi/c/private/ppb_isolated_file_system_private.h" @@ -54,7 +55,7 @@ class PepperFileSystemHost private: // Callback for OpenFileSystem. void DidOpenFileSystem(const std::string& name_unused, const GURL& root); - void DidFailOpenFileSystem(base::PlatformFileError error); + void DidFailOpenFileSystem(base::File::Error error); int32_t OnHostMsgOpen(ppapi::host::HostMessageContext* context, int64_t expected_size); diff --git a/chromium/content/renderer/pepper/pepper_graphics_2d_host.cc b/chromium/content/renderer/pepper/pepper_graphics_2d_host.cc index 51034591b8b..a33b994d81b 100644 --- a/chromium/content/renderer/pepper/pepper_graphics_2d_host.cc +++ b/chromium/content/renderer/pepper/pepper_graphics_2d_host.cc @@ -8,13 +8,16 @@ #include "base/debug/trace_event.h" #include "base/logging.h" #include "base/message_loop/message_loop.h" +#include "cc/resources/shared_bitmap.h" #include "cc/resources/texture_mailbox.h" +#include "content/child/child_shared_bitmap_manager.h" #include "content/public/renderer/render_thread.h" #include "content/public/renderer/renderer_ppapi_host.h" #include "content/renderer/pepper/common.h" #include "content/renderer/pepper/gfx_conversion.h" #include "content/renderer/pepper/pepper_plugin_instance_impl.h" #include "content/renderer/pepper/ppb_image_data_impl.h" +#include "content/renderer/render_thread_impl.h" #include "ppapi/c/pp_bool.h" #include "ppapi/c/pp_errors.h" #include "ppapi/c/pp_rect.h" @@ -53,29 +56,30 @@ const int64 kOffscreenCallbackDelayMs = 1000 / 30; // 30 fps // NULL to indicate it should be the entire image. If the rect is outside of // the image, this will do nothing and return false. bool ValidateAndConvertRect(const PP_Rect* rect, - int image_width, int image_height, + int image_width, + int image_height, gfx::Rect* dest) { if (!rect) { // Use the entire image area. *dest = gfx::Rect(0, 0, image_width, image_height); } else { // Validate the passed-in area. - if (rect->point.x < 0 || rect->point.y < 0 || - rect->size.width <= 0 || rect->size.height <= 0) + if (rect->point.x < 0 || rect->point.y < 0 || rect->size.width <= 0 || + rect->size.height <= 0) return false; // Check the max bounds, being careful of overflow. if (static_cast<int64>(rect->point.x) + - static_cast<int64>(rect->size.width) > + static_cast<int64>(rect->size.width) > static_cast<int64>(image_width)) return false; if (static_cast<int64>(rect->point.y) + - static_cast<int64>(rect->size.height) > + static_cast<int64>(rect->size.height) > static_cast<int64>(image_height)) return false; - *dest = gfx::Rect(rect->point.x, rect->point.y, - rect->size.width, rect->size.height); + *dest = gfx::Rect( + rect->point.x, rect->point.y, rect->size.width, rect->size.height); } return true; } @@ -98,8 +102,10 @@ void ConvertBetweenBGRAandRGBA(const uint32_t* input, // Converts ImageData from PP_IMAGEDATAFORMAT_BGRA_PREMUL to // PP_IMAGEDATAFORMAT_RGBA_PREMUL, or reverse. It's assumed that the // destination image is always mapped (so will have non-NULL data). -void ConvertImageData(PPB_ImageData_Impl* src_image, const SkIRect& src_rect, - PPB_ImageData_Impl* dest_image, const SkRect& dest_rect) { +void ConvertImageData(PPB_ImageData_Impl* src_image, + const SkIRect& src_rect, + PPB_ImageData_Impl* dest_image, + const SkRect& dest_rect) { ImageDataAutoMapper auto_mapper(src_image); DCHECK(src_image->format() != dest_image->format()); @@ -133,20 +139,10 @@ void ConvertImageData(PPB_ImageData_Impl* src_image, const SkIRect& src_rect, } // namespace struct PepperGraphics2DHost::QueuedOperation { - enum Type { - PAINT, - SCROLL, - REPLACE, - SET_OFFSET - }; + enum Type { PAINT, SCROLL, REPLACE, }; QueuedOperation(Type t) - : type(t), - paint_x(0), - paint_y(0), - scroll_dx(0), - scroll_dy(0) { - } + : type(t), paint_x(0), paint_y(0), scroll_dx(0), scroll_dy(0) {} Type type; @@ -161,9 +157,6 @@ struct PepperGraphics2DHost::QueuedOperation { // Valid when type == REPLACE. scoped_refptr<PPB_ImageData_Impl> replace_image; - - // Valid when type == SET_OFFSET. - gfx::Point offset; }; // static @@ -176,7 +169,8 @@ PepperGraphics2DHost* PepperGraphics2DHost::Create( scoped_refptr<PPB_ImageData_Impl> backing_store) { PepperGraphics2DHost* resource_host = new PepperGraphics2DHost(host, instance, resource); - if (!resource_host->Init(size.width, size.height, + if (!resource_host->Init(size.width, + size.height, PP_ToBool(is_always_opaque), backing_store)) { delete resource_host; @@ -196,8 +190,7 @@ PepperGraphics2DHost::PepperGraphics2DHost(RendererPpapiHost* host, is_always_opaque_(false), scale_(1.0f), is_running_in_process_(host->IsRunningInProcess()), - texture_mailbox_modified_(true), - resize_mode_(PP_GRAPHICS2D_DEV_RESIZEMODE_DEFAULT) {} + texture_mailbox_modified_(true) {} PepperGraphics2DHost::~PepperGraphics2DHost() { // Unbind from the instance when destroyed if we're still bound. @@ -213,7 +206,9 @@ bool PepperGraphics2DHost::Init( // The underlying PPB_ImageData_Impl will validate the dimensions. image_data_ = backing_store; if (!image_data_->Init(PPB_ImageData_Impl::GetNativeImageDataFormat(), - width, height, true) || + width, + height, + true) || !image_data_->Map()) { image_data_ = NULL; return false; @@ -226,38 +221,24 @@ bool PepperGraphics2DHost::Init( int32_t PepperGraphics2DHost::OnResourceMessageReceived( const IPC::Message& msg, ppapi::host::HostMessageContext* context) { - IPC_BEGIN_MESSAGE_MAP(PepperGraphics2DHost, msg) - PPAPI_DISPATCH_HOST_RESOURCE_CALL( - PpapiHostMsg_Graphics2D_PaintImageData, - OnHostMsgPaintImageData) - PPAPI_DISPATCH_HOST_RESOURCE_CALL( - PpapiHostMsg_Graphics2D_Scroll, - OnHostMsgScroll) - PPAPI_DISPATCH_HOST_RESOURCE_CALL( - PpapiHostMsg_Graphics2D_ReplaceContents, - OnHostMsgReplaceContents) - PPAPI_DISPATCH_HOST_RESOURCE_CALL( - PpapiHostMsg_Graphics2D_Flush, - OnHostMsgFlush) - PPAPI_DISPATCH_HOST_RESOURCE_CALL( - PpapiHostMsg_Graphics2D_Dev_SetScale, - OnHostMsgSetScale) - PPAPI_DISPATCH_HOST_RESOURCE_CALL( - PpapiHostMsg_Graphics2D_SetOffset, - OnHostMsgSetOffset) - PPAPI_DISPATCH_HOST_RESOURCE_CALL( - PpapiHostMsg_Graphics2D_SetResizeMode, - OnHostMsgSetResizeMode) - PPAPI_DISPATCH_HOST_RESOURCE_CALL( - PpapiHostMsg_Graphics2D_ReadImageData, - OnHostMsgReadImageData) - IPC_END_MESSAGE_MAP() + PPAPI_BEGIN_MESSAGE_MAP(PepperGraphics2DHost, msg) + PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_Graphics2D_PaintImageData, + OnHostMsgPaintImageData) + PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_Graphics2D_Scroll, + OnHostMsgScroll) + PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_Graphics2D_ReplaceContents, + OnHostMsgReplaceContents) + PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_Graphics2D_Flush, + OnHostMsgFlush) + PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_Graphics2D_SetScale, + OnHostMsgSetScale) + PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_Graphics2D_ReadImageData, + OnHostMsgReadImageData) + PPAPI_END_MESSAGE_MAP() return PP_ERROR_FAILED; } -bool PepperGraphics2DHost::IsGraphics2DHost() { - return true; -} +bool PepperGraphics2DHost::IsGraphics2DHost() { return true; } bool PepperGraphics2DHost::ReadImageData(PP_Resource image, const PP_Point* top_left) { @@ -267,33 +248,30 @@ bool PepperGraphics2DHost::ReadImageData(PP_Resource image, return false; PPB_ImageData_Impl* image_resource = static_cast<PPB_ImageData_Impl*>(enter.object()); - if (!PPB_ImageData_Impl::IsImageDataFormatSupported( - image_resource->format())) + if (!PPB_ImageData_Impl::IsImageDataFormatSupported(image_resource->format())) return false; // Must be in the right format. // Validate the bitmap position. int x = top_left->x; if (x < 0 || static_cast<int64>(x) + static_cast<int64>(image_resource->width()) > - image_data_->width()) + image_data_->width()) return false; int y = top_left->y; if (y < 0 || static_cast<int64>(y) + static_cast<int64>(image_resource->height()) > - image_data_->height()) + image_data_->height()) return false; ImageDataAutoMapper auto_mapper(image_resource); if (!auto_mapper.is_valid()) return false; - SkIRect src_irect = { x, y, - x + image_resource->width(), - y + image_resource->height() }; - SkRect dest_rect = { SkIntToScalar(0), - SkIntToScalar(0), - SkIntToScalar(image_resource->width()), - SkIntToScalar(image_resource->height()) }; + SkIRect src_irect = {x, y, x + image_resource->width(), + y + image_resource->height()}; + SkRect dest_rect = {SkIntToScalar(0), SkIntToScalar(0), + SkIntToScalar(image_resource->width()), + SkIntToScalar(image_resource->height())}; if (image_resource->format() != image_data_->format()) { // Convert the image data if the format does not match. @@ -304,8 +282,8 @@ bool PepperGraphics2DHost::ReadImageData(PP_Resource image, // We want to replace the contents of the bitmap rather than blend. SkPaint paint; paint.setXfermodeMode(SkXfermode::kSrc_Mode); - dest_canvas->drawBitmapRect(*image_data_->GetMappedBitmap(), - &src_irect, dest_rect, &paint); + dest_canvas->drawBitmapRect( + *image_data_->GetMappedBitmap(), &src_irect, dest_rect, &paint); } return true; } @@ -352,8 +330,8 @@ void PepperGraphics2DHost::Paint(blink::WebCanvas* canvas, SkAutoCanvasRestore auto_restore(canvas, true); canvas->clipRect(sk_invalidate_rect); gfx::Size pixel_image_size(image_data_->width(), image_data_->height()); - gfx::Size image_size = gfx::ToFlooredSize( - gfx::ScaleSize(pixel_image_size, scale_)); + gfx::Size image_size = + gfx::ToFlooredSize(gfx::ScaleSize(pixel_image_size, scale_)); PepperPluginInstance* plugin_instance = renderer_ppapi_host_->GetPluginInstance(pp_instance()); @@ -381,7 +359,7 @@ void PepperGraphics2DHost::Paint(blink::WebCanvas* canvas, // Copy to device independent bitmap when target canvas doesn't support // platform paint. if (!skia::SupportsPlatformPaint(canvas)) - backing_bitmap.copyTo(&image, SkBitmap::kARGB_8888_Config); + backing_bitmap.copyTo(&image, kPMColor_SkColorType); else image = backing_bitmap; @@ -397,21 +375,15 @@ void PepperGraphics2DHost::Paint(blink::WebCanvas* canvas, SkPoint pixel_origin = origin; - gfx::PointF resize_scale(GetResizeScale()); - gfx::PointF scale(ScalePoint(resize_scale, scale_)); - if ((scale.x() != 1.0f || scale.y() != 1.0f) && - scale.x() > 0.0f && scale.y() > 0.0f) { - canvas->scale(scale.x(), scale.y()); - pixel_origin.set(pixel_origin.x() * (1.0f / scale.x()), - pixel_origin.y() * (1.0f / scale.y())); + if (scale_ != 1.0f && scale_ > 0.0f) { + canvas->scale(scale_, scale_); + pixel_origin.set(pixel_origin.x() * (1.0f / scale_), + pixel_origin.y() * (1.0f / scale_)); } - pixel_origin.offset(SkIntToScalar(plugin_offset_.x()), - SkIntToScalar(plugin_offset_.y())); canvas->drawBitmap(image, pixel_origin.x(), pixel_origin.y(), &paint); } -void PepperGraphics2DHost::ViewInitiatedPaint() { -} +void PepperGraphics2DHost::ViewInitiatedPaint() {} void PepperGraphics2DHost::ViewFlushedPaint() { TRACE_EVENT0("pepper", "PepperGraphics2DHost::ViewFlushedPaint"); @@ -421,22 +393,11 @@ void PepperGraphics2DHost::ViewFlushedPaint() { } } -void PepperGraphics2DHost::DidChangeView(const ppapi::ViewData& view_data) { - gfx::Size old_plugin_size = current_plugin_size_; - current_plugin_size_ = PP_ToGfxSize(view_data.rect.size); -} - -void PepperGraphics2DHost::SetScale(float scale) { - scale_ = scale; -} +void PepperGraphics2DHost::SetScale(float scale) { scale_ = scale; } -float PepperGraphics2DHost::GetScale() const { - return scale_; -} +float PepperGraphics2DHost::GetScale() const { return scale_; } -bool PepperGraphics2DHost::IsAlwaysOpaque() const { - return is_always_opaque_; -} +bool PepperGraphics2DHost::IsAlwaysOpaque() const { return is_always_opaque_; } PPB_ImageData_Impl* PepperGraphics2DHost::ImageData() { return image_data_.get(); @@ -448,21 +409,6 @@ gfx::Size PepperGraphics2DHost::Size() const { return gfx::Size(image_data_->width(), image_data_->height()); } -gfx::PointF PepperGraphics2DHost::GetResizeScale() const { - switch (resize_mode_) { - case PP_GRAPHICS2D_DEV_RESIZEMODE_DEFAULT: - return gfx::PointF(1.0f, 1.0f); - case PP_GRAPHICS2D_DEV_RESIZEMODE_STRETCH: - if (flushed_plugin_size_.IsEmpty()) - return gfx::PointF(1.0f, 1.0f); - return gfx::PointF( - 1.0f * current_plugin_size_.width() / flushed_plugin_size_.width(), - 1.0f * current_plugin_size_.height() / flushed_plugin_size_.height()); - } - NOTREACHED(); - return gfx::PointF(1.0f, 1.0f); -} - int32_t PepperGraphics2DHost::OnHostMsgPaintImageData( ppapi::host::HostMessageContext* context, const ppapi::HostResource& image_data, @@ -490,11 +436,11 @@ int32_t PepperGraphics2DHost::OnHostMsgPaintImageData( int64 y64 = static_cast<int64>(top_left.y); if (x64 + static_cast<int64>(operation.paint_src_rect.x()) < 0 || x64 + static_cast<int64>(operation.paint_src_rect.right()) > - image_data_->width()) + image_data_->width()) return PP_ERROR_BADARGUMENT; if (y64 + static_cast<int64>(operation.paint_src_rect.y()) < 0 || y64 + static_cast<int64>(operation.paint_src_rect.bottom()) > - image_data_->height()) + image_data_->height()) return PP_ERROR_BADARGUMENT; operation.paint_x = top_left.x; operation.paint_y = top_left.y; @@ -540,8 +486,7 @@ int32_t PepperGraphics2DHost::OnHostMsgReplaceContents( PPB_ImageData_Impl* image_resource = static_cast<PPB_ImageData_Impl*>(enter.object()); - if (!PPB_ImageData_Impl::IsImageDataFormatSupported( - image_resource->format())) + if (!PPB_ImageData_Impl::IsImageDataFormatSupported(image_resource->format())) return PP_ERROR_BADARGUMENT; if (image_resource->width() != image_data_->width() || @@ -556,26 +501,28 @@ int32_t PepperGraphics2DHost::OnHostMsgReplaceContents( int32_t PepperGraphics2DHost::OnHostMsgFlush( ppapi::host::HostMessageContext* context, - const ppapi::ViewData& view_data) { + const std::vector<ui::LatencyInfo>& latency_info) { // Don't allow more than one pending flush at a time. if (HasPendingFlush()) return PP_ERROR_INPROGRESS; + if (bound_instance_) + bound_instance_->AddLatencyInfo(latency_info); + PP_Resource old_image_data = 0; flush_reply_context_ = context->MakeReplyMessageContext(); if (is_running_in_process_) - return Flush(NULL, PP_ToGfxSize(view_data.rect.size)); + return Flush(NULL); // Reuse image data when running out of process. - int32_t result = Flush(&old_image_data, PP_ToGfxSize(view_data.rect.size)); + int32_t result = Flush(&old_image_data); if (old_image_data) { // If the Graphics2D has an old image data it's not using any more, send // it back to the plugin for possible re-use. See ppb_image_data_proxy.cc // for a description how this process works. ppapi::HostResource old_image_data_host_resource; - old_image_data_host_resource.SetHostResource(pp_instance(), - old_image_data); + old_image_data_host_resource.SetHostResource(pp_instance(), old_image_data); host()->Send(new PpapiMsg_PPBImageData_NotifyUnusedImageData( ppapi::API_ID_PPB_IMAGE_DATA, old_image_data_host_resource)); } @@ -593,22 +540,6 @@ int32_t PepperGraphics2DHost::OnHostMsgSetScale( return PP_ERROR_BADARGUMENT; } -int32_t PepperGraphics2DHost::OnHostMsgSetOffset( - ppapi::host::HostMessageContext* context, - const PP_Point& offset) { - QueuedOperation operation(QueuedOperation::SET_OFFSET); - operation.offset = PP_ToGfxPoint(offset); - queued_operations_.push_back(operation); - return PP_OK; -} - -int32_t PepperGraphics2DHost::OnHostMsgSetResizeMode( - ppapi::host::HostMessageContext* context, - PP_Graphics2D_Dev_ResizeMode resize_mode) { - resize_mode_ = resize_mode; - return PP_OK; -} - int32_t PepperGraphics2DHost::OnHostMsgReadImageData( ppapi::host::HostMessageContext* context, PP_Resource image, @@ -617,8 +548,8 @@ int32_t PepperGraphics2DHost::OnHostMsgReadImageData( return ReadImageData(image, &top_left) ? PP_OK : PP_ERROR_FAILED; } -void ReleaseCallback(scoped_ptr<base::SharedMemory> memory, - unsigned sync_point, +void ReleaseCallback(scoped_ptr<cc::SharedBitmap> bitmap, + uint32 sync_point, bool lost_resource) {} bool PepperGraphics2DHost::PrepareTextureMailbox( @@ -628,18 +559,21 @@ bool PepperGraphics2DHost::PrepareTextureMailbox( return false; // TODO(jbauman): Send image_data_ through mailbox to avoid copy. gfx::Size pixel_image_size(image_data_->width(), image_data_->height()); - int buffer_size = pixel_image_size.GetArea() * 4; - scoped_ptr<base::SharedMemory> memory = - RenderThread::Get()->HostAllocateSharedMemoryBuffer(buffer_size); - if (!memory || !memory->Map(buffer_size)) + scoped_ptr<cc::SharedBitmap> shared_bitmap = + RenderThreadImpl::current() + ->shared_bitmap_manager() + ->AllocateSharedBitmap(pixel_image_size); + if (!shared_bitmap) return false; void* src = image_data_->Map(); - memcpy(memory->memory(), src, buffer_size); + memcpy(shared_bitmap->pixels(), + src, + cc::SharedBitmap::CheckedSizeInBytes(pixel_image_size)); image_data_->Unmap(); - *mailbox = cc::TextureMailbox(memory.get(), pixel_image_size); + *mailbox = cc::TextureMailbox(shared_bitmap->memory(), pixel_image_size); *release_callback = cc::SingleReleaseCallback::Create( - base::Bind(&ReleaseCallback, base::Passed(&memory))); + base::Bind(&ReleaseCallback, base::Passed(&shared_bitmap))); texture_mailbox_modified_ = false; return true; } @@ -648,15 +582,13 @@ void PepperGraphics2DHost::AttachedToNewLayer() { texture_mailbox_modified_ = true; } -int32_t PepperGraphics2DHost::Flush(PP_Resource* old_image_data, - const gfx::Size& flushed_plugin_size) { +int32_t PepperGraphics2DHost::Flush(PP_Resource* old_image_data) { bool done_replace_contents = false; bool no_update_visible = true; bool is_plugin_visible = true; for (size_t i = 0; i < queued_operations_.size(); i++) { QueuedOperation& operation = queued_operations_[i]; gfx::Rect op_rect; - gfx::Rect old_op_rect; switch (operation.type) { case QueuedOperation::PAINT: ExecutePaintImageData(operation.paint_image.get(), @@ -667,7 +599,8 @@ int32_t PepperGraphics2DHost::Flush(PP_Resource* old_image_data, break; case QueuedOperation::SCROLL: ExecuteScroll(operation.scroll_clip_rect, - operation.scroll_dx, operation.scroll_dy, + operation.scroll_dx, + operation.scroll_dy, &op_rect); break; case QueuedOperation::REPLACE: @@ -680,32 +613,21 @@ int32_t PepperGraphics2DHost::Flush(PP_Resource* old_image_data, done_replace_contents ? NULL : old_image_data); done_replace_contents = true; break; - case QueuedOperation::SET_OFFSET: - old_op_rect = gfx::Rect(plugin_offset_.x(), plugin_offset_.y(), - image_data_->width(), image_data_->height()); - plugin_offset_ = operation.offset; - // The offset is applied below for |op_rect|. - op_rect = gfx::Rect(image_data_->width(), image_data_->height()); - break; } - op_rect.Offset(plugin_offset_.x(), plugin_offset_.y()); - // For correctness with accelerated compositing, we must issue an invalidate // on the full op_rect even if it is partially or completely off-screen. // However, if we issue an invalidate for a clipped-out region, WebKit will // do nothing and we won't get any ViewFlushedPaint calls, leaving our // callback stranded. So we still need to check whether the repainted area // is visible to determine how to deal with the callback. - if (bound_instance_ && (!op_rect.IsEmpty() || !old_op_rect.IsEmpty())) { + if (bound_instance_ && !op_rect.IsEmpty()) { gfx::Point scroll_delta(operation.scroll_dx, operation.scroll_dy); - if (!ConvertToLogicalPixels(scale_, &old_op_rect, NULL)) { - NOTREACHED(); - } if (!ConvertToLogicalPixels(scale_, &op_rect, - operation.type == QueuedOperation::SCROLL ? - &scroll_delta : NULL)) { + operation.type == QueuedOperation::SCROLL + ? &scroll_delta + : NULL)) { // Conversion requires falling back to InvalidateRect. operation.type = QueuedOperation::PAINT; } @@ -715,29 +637,24 @@ int32_t PepperGraphics2DHost::Flush(PP_Resource* old_image_data, // Set |no_update_visible| to false if the change overlaps the visible // area. - if (!gfx::IntersectRects(clip, op_rect).IsEmpty() || - !gfx::IntersectRects(clip, old_op_rect).IsEmpty()) { + if (!gfx::IntersectRects(clip, op_rect).IsEmpty()) { no_update_visible = false; } // Notify the plugin of the entire change (op_rect), even if it is // partially or completely off-screen. if (operation.type == QueuedOperation::SCROLL) { - bound_instance_->ScrollRect(scroll_delta.x(), scroll_delta.y(), - op_rect); - DCHECK(old_op_rect.IsEmpty()); + bound_instance_->ScrollRect( + scroll_delta.x(), scroll_delta.y(), op_rect); } else { if (!op_rect.IsEmpty()) bound_instance_->InvalidateRect(op_rect); - if (!old_op_rect.IsEmpty()) - bound_instance_->InvalidateRect(old_op_rect); } texture_mailbox_modified_ = true; } } queued_operations_.clear(); - flushed_plugin_size_ = flushed_plugin_size; if (!bound_instance_) { // As promised in the API, we always schedule callback when unbound. ScheduleOffscreenFlushAck(); @@ -754,25 +671,26 @@ int32_t PepperGraphics2DHost::Flush(PP_Resource* old_image_data, } void PepperGraphics2DHost::ExecutePaintImageData(PPB_ImageData_Impl* image, - int x, int y, - const gfx::Rect& src_rect, - gfx::Rect* invalidated_rect) { + int x, + int y, + const gfx::Rect& src_rect, + gfx::Rect* invalidated_rect) { // Ensure the source image is mapped to read from it. ImageDataAutoMapper auto_mapper(image); if (!auto_mapper.is_valid()) return; // Portion within the source image to cut out. - SkIRect src_irect = { src_rect.x(), src_rect.y(), - src_rect.right(), src_rect.bottom() }; + SkIRect src_irect = {src_rect.x(), src_rect.y(), src_rect.right(), + src_rect.bottom()}; // Location within the backing store to copy to. *invalidated_rect = src_rect; invalidated_rect->Offset(x, y); - SkRect dest_rect = { SkIntToScalar(invalidated_rect->x()), - SkIntToScalar(invalidated_rect->y()), - SkIntToScalar(invalidated_rect->right()), - SkIntToScalar(invalidated_rect->bottom()) }; + SkRect dest_rect = {SkIntToScalar(invalidated_rect->x()), + SkIntToScalar(invalidated_rect->y()), + SkIntToScalar(invalidated_rect->right()), + SkIntToScalar(invalidated_rect->bottom())}; if (image->format() != image_data_->format()) { // Convert the image data if the format does not match. @@ -784,31 +702,30 @@ void PepperGraphics2DHost::ExecutePaintImageData(PPB_ImageData_Impl* image, // We want to replace the contents of the bitmap rather than blend. SkPaint paint; paint.setXfermodeMode(SkXfermode::kSrc_Mode); - backing_canvas->drawBitmapRect(*image->GetMappedBitmap(), - &src_irect, dest_rect, &paint); + backing_canvas->drawBitmapRect( + *image->GetMappedBitmap(), &src_irect, dest_rect, &paint); } } void PepperGraphics2DHost::ExecuteScroll(const gfx::Rect& clip, - int dx, int dy, - gfx::Rect* invalidated_rect) { - gfx::ScrollCanvas(image_data_->GetCanvas(), - clip, gfx::Vector2d(dx, dy)); + int dx, + int dy, + gfx::Rect* invalidated_rect) { + gfx::ScrollCanvas(image_data_->GetCanvas(), clip, gfx::Vector2d(dx, dy)); *invalidated_rect = clip; } void PepperGraphics2DHost::ExecuteReplaceContents(PPB_ImageData_Impl* image, - gfx::Rect* invalidated_rect, - PP_Resource* old_image_data) { + gfx::Rect* invalidated_rect, + PP_Resource* old_image_data) { if (image->format() != image_data_->format()) { DCHECK(image->width() == image_data_->width() && image->height() == image_data_->height()); // Convert the image data if the format does not match. - SkIRect src_irect = { 0, 0, image->width(), image->height() }; - SkRect dest_rect = { SkIntToScalar(0), - SkIntToScalar(0), - SkIntToScalar(image_data_->width()), - SkIntToScalar(image_data_->height()) }; + SkIRect src_irect = {0, 0, image->width(), image->height()}; + SkRect dest_rect = {SkIntToScalar(0), SkIntToScalar(0), + SkIntToScalar(image_data_->width()), + SkIntToScalar(image_data_->height())}; ConvertImageData(image, src_irect, image_data_.get(), dest_rect); } else { // The passed-in image may not be mapped in our process, and we need to @@ -820,13 +737,12 @@ void PepperGraphics2DHost::ExecuteReplaceContents(PPB_ImageData_Impl* image, *old_image_data = image_data_->GetReference(); image_data_ = image; } - *invalidated_rect = gfx::Rect(0, 0, - image_data_->width(), image_data_->height()); + *invalidated_rect = + gfx::Rect(0, 0, image_data_->width(), image_data_->height()); } void PepperGraphics2DHost::SendFlushAck() { - host()->SendReply(flush_reply_context_, - PpapiPluginMsg_Graphics2D_FlushAck()); + host()->SendReply(flush_reply_context_, PpapiPluginMsg_Graphics2D_FlushAck()); } void PepperGraphics2DHost::SendOffscreenFlushAck() { @@ -843,8 +759,7 @@ void PepperGraphics2DHost::ScheduleOffscreenFlushAck() { offscreen_flush_pending_ = true; base::MessageLoop::current()->PostDelayedTask( FROM_HERE, - base::Bind(&PepperGraphics2DHost::SendOffscreenFlushAck, - AsWeakPtr()), + base::Bind(&PepperGraphics2DHost::SendOffscreenFlushAck, AsWeakPtr()), base::TimeDelta::FromMilliseconds(kOffscreenCallbackDelayMs)); } @@ -854,8 +769,8 @@ bool PepperGraphics2DHost::HasPendingFlush() const { // static bool PepperGraphics2DHost::ConvertToLogicalPixels(float scale, - gfx::Rect* op_rect, - gfx::Point* delta) { + gfx::Rect* op_rect, + gfx::Point* delta) { if (scale == 1.0f || scale <= 0.0f) return true; diff --git a/chromium/content/renderer/pepper/pepper_graphics_2d_host.h b/chromium/content/renderer/pepper/pepper_graphics_2d_host.h index cda286a2df8..25df4d179a9 100644 --- a/chromium/content/renderer/pepper/pepper_graphics_2d_host.h +++ b/chromium/content/renderer/pepper/pepper_graphics_2d_host.h @@ -11,11 +11,11 @@ #include "base/compiler_specific.h" #include "base/memory/weak_ptr.h" #include "content/common/content_export.h" -#include "ppapi/c/dev/ppb_graphics_2d_dev.h" #include "ppapi/c/ppb_graphics_2d.h" #include "ppapi/host/host_message_context.h" #include "ppapi/host/resource_host.h" #include "third_party/WebKit/public/platform/WebCanvas.h" +#include "ui/events/latency_info.h" #include "ui/gfx/point.h" #include "ui/gfx/size.h" @@ -33,7 +33,7 @@ struct ViewData; } namespace content { - + class PepperPluginInstanceImpl; class PPB_ImageData_Impl; class RendererPpapiHost; @@ -58,8 +58,7 @@ class CONTENT_EXPORT PepperGraphics2DHost ppapi::host::HostMessageContext* context) OVERRIDE; virtual bool IsGraphics2DHost() OVERRIDE; - bool ReadImageData(PP_Resource image, - const PP_Point* top_left); + bool ReadImageData(PP_Resource image, const PP_Point* top_left); // Assciates this device with the given plugin instance. You can pass NULL // to clear the existing device. Returns true on success. In this case, a // repaint of the page will also be scheduled. Failure means that the device @@ -80,20 +79,12 @@ class CONTENT_EXPORT PepperGraphics2DHost void ViewInitiatedPaint(); void ViewFlushedPaint(); - void DidChangeView(const ppapi::ViewData& view_data); - void SetScale(float scale); float GetScale() const; bool IsAlwaysOpaque() const; PPB_ImageData_Impl* ImageData(); gfx::Size Size() const; - // The amount to resize the backing store by when painting to the canvas. - // This is used to stretch the backing store when resizing the plugin element. - gfx::PointF GetResizeScale() const; - // The offset of the backing store into the plugin element. - gfx::Point plugin_offset() const { return plugin_offset_; } - private: PepperGraphics2DHost(RendererPpapiHost* host, PP_Instance instance, @@ -116,21 +107,16 @@ class CONTENT_EXPORT PepperGraphics2DHost int32_t OnHostMsgReplaceContents(ppapi::host::HostMessageContext* context, const ppapi::HostResource& image_data); int32_t OnHostMsgFlush(ppapi::host::HostMessageContext* context, - const ppapi::ViewData& view_data); + const std::vector<ui::LatencyInfo>& latency_info); int32_t OnHostMsgSetScale(ppapi::host::HostMessageContext* context, float scale); - int32_t OnHostMsgSetOffset(ppapi::host::HostMessageContext* context, - const PP_Point& offset); - int32_t OnHostMsgSetResizeMode(ppapi::host::HostMessageContext* context, - PP_Graphics2D_Dev_ResizeMode resize_mode); int32_t OnHostMsgReadImageData(ppapi::host::HostMessageContext* context, PP_Resource image, const PP_Point& top_left); // If |old_image_data| is not NULL, a previous used ImageData object will be // reused. This is used by ReplaceContents. - int32_t Flush(PP_Resource* old_image_data, - const gfx::Size& flushed_plugin_size); + int32_t Flush(PP_Resource* old_image_data); // Called internally to execute the different queued commands. The // parameters to these functions will have already been validated. The last @@ -138,10 +124,13 @@ class CONTENT_EXPORT PepperGraphics2DHost // the update that requires invalidation. If there were no pixels changed, // this rect can be untouched. void ExecutePaintImageData(PPB_ImageData_Impl* image, - int x, int y, + int x, + int y, const gfx::Rect& src_rect, gfx::Rect* invalidated_rect); - void ExecuteScroll(const gfx::Rect& clip, int dx, int dy, + void ExecuteScroll(const gfx::Rect& clip, + int dx, + int dy, gfx::Rect* invalidated_rect); void ExecuteReplaceContents(PPB_ImageData_Impl* image, gfx::Rect* invalidated_rect, @@ -204,21 +193,6 @@ class CONTENT_EXPORT PepperGraphics2DHost bool texture_mailbox_modified_; bool is_using_texture_layer_; - // The offset into the plugin area at which to draw the contents of the - // graphics context. - gfx::Point plugin_offset_; - - // The size of the plugin element from the plugin's perspective at the last - // time Flush() was called. Because the plugin runs in a separate process and - // the size of the plugin element in the renderer is updated asynchronously, - // it may believe that the plugin element is a different size to what it - // actually is. - gfx::Size flushed_plugin_size_; - // The current size of the plugin element. - gfx::Size current_plugin_size_; - - PP_Graphics2D_Dev_ResizeMode resize_mode_; - friend class PepperGraphics2DHostTest; DISALLOW_COPY_AND_ASSIGN(PepperGraphics2DHost); }; diff --git a/chromium/content/renderer/pepper/pepper_graphics_2d_host_unittest.cc b/chromium/content/renderer/pepper/pepper_graphics_2d_host_unittest.cc index b17dfa71886..8914a3d8011 100644 --- a/chromium/content/renderer/pepper/pepper_graphics_2d_host_unittest.cc +++ b/chromium/content/renderer/pepper/pepper_graphics_2d_host_unittest.cc @@ -15,6 +15,7 @@ #include "testing/gtest/include/gtest/gtest.h" #include "third_party/WebKit/public/platform/WebCanvas.h" #include "third_party/skia/include/core/SkCanvas.h" +#include "ui/events/latency_info.h" #include "ui/gfx/point.h" #include "ui/gfx/rect.h" @@ -30,9 +31,7 @@ class PepperGraphics2DHostTest : public testing::Test { return PepperGraphics2DHost::ConvertToLogicalPixels(scale, op_rect, delta); } - PepperGraphics2DHostTest() - : message_loop_(base::MessageLoop::TYPE_DEFAULT), - renderer_ppapi_host_(NULL, 12345) {} + PepperGraphics2DHostTest() : renderer_ppapi_host_(NULL, 12345) {} virtual ~PepperGraphics2DHostTest() { ppapi::ProxyAutoLock proxy_lock; @@ -43,13 +42,15 @@ class PepperGraphics2DHostTest : public testing::Test { const PP_Size& backing_store_size, const PP_Rect& plugin_rect) { renderer_view_data_.rect = plugin_rect; - PluginViewUpdated(); test_globals_.GetResourceTracker()->DidCreateInstance(instance); scoped_refptr<PPB_ImageData_Impl> backing_store( new PPB_ImageData_Impl(instance, PPB_ImageData_Impl::ForTest())); - host_.reset(PepperGraphics2DHost::Create( - &renderer_ppapi_host_, instance, 12345, backing_store_size, PP_FALSE, - backing_store)); + host_.reset(PepperGraphics2DHost::Create(&renderer_ppapi_host_, + instance, + 12345, + backing_store_size, + PP_FALSE, + backing_store)); DCHECK(host_.get()); } @@ -57,18 +58,15 @@ class PepperGraphics2DHostTest : public testing::Test { ppapi::HostResource image_data_resource; image_data_resource.SetHostResource(image_data->pp_instance(), image_data->pp_resource()); - host_->OnHostMsgPaintImageData(NULL, image_data_resource, - PP_Point(), false, PP_Rect()); - } - - void SetOffset(const PP_Point& point) { - host_->OnHostMsgSetOffset(NULL, point); + host_->OnHostMsgPaintImageData( + NULL, image_data_resource, PP_Point(), false, PP_Rect()); } void Flush() { ppapi::host::HostMessageContext context( ppapi::proxy::ResourceMessageCallParams(host_->pp_resource(), 0)); - host_->OnHostMsgFlush(&context, plugin_view_data_); + std::vector<ui::LatencyInfo> latency; + host_->OnHostMsgFlush(&context, latency); host_->ViewFlushedPaint(); host_->SendOffscreenFlushAck(); } @@ -76,23 +74,11 @@ class PepperGraphics2DHostTest : public testing::Test { void PaintToWebCanvas(SkBitmap* bitmap) { scoped_ptr<WebCanvas> canvas(new WebCanvas(*bitmap)); gfx::Rect plugin_rect(PP_ToGfxRect(renderer_view_data_.rect)); - host_->Paint(canvas.get(), plugin_rect, + host_->Paint(canvas.get(), + plugin_rect, gfx::Rect(0, 0, plugin_rect.width(), plugin_rect.height())); } - void DidChangeView(const PP_Rect& plugin_rect) { - renderer_view_data_.rect = plugin_rect; - host_->DidChangeView(renderer_view_data_); - } - - void PluginViewUpdated() { - plugin_view_data_ = renderer_view_data_; - } - - void SetResizeMode(PP_Graphics2D_Dev_ResizeMode resize_mode) { - host_->OnHostMsgSetResizeMode(NULL, resize_mode); - } - void ResetPageBitmap(SkBitmap* bitmap) { PP_Rect plugin_rect = renderer_view_data_.rect; int width = plugin_rect.point.x + plugin_rect.size.width; @@ -107,7 +93,6 @@ class PepperGraphics2DHostTest : public testing::Test { private: ppapi::ViewData renderer_view_data_; - ppapi::ViewData plugin_view_data_; scoped_ptr<PepperGraphics2DHost> host_; base::MessageLoop message_loop_; MockRendererPpapiHost renderer_ppapi_host_; @@ -130,41 +115,39 @@ TEST_F(PepperGraphics2DHostTest, ConvertToLogicalPixels) { int dy2; float scale; bool result; - } tests[] = { - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1.0, true }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2.0, true }, - { 0, 0, 4, 4, 0, 0, 2, 2, 0, 0, 0, 0, 0.5, true }, - { 1, 1, 4, 4, 0, 0, 3, 3, 0, 0, 0, 0, 0.5, false }, - { 53, 75, 100, 100, 53, 75, 100, 100, 0, 0, 0, 0, 1.0, true }, - { 53, 75, 100, 100, 106, 150, 200, 200, 0, 0, 0, 0, 2.0, true }, - { 53, 75, 100, 100, 26, 37, 51, 51, 0, 0, 0, 0, 0.5, false }, - { 53, 74, 100, 100, 26, 37, 51, 50, 0, 0, 0, 0, 0.5, false }, - { -1, -1, 100, 100, -1, -1, 51, 51, 0, 0, 0, 0, 0.5, false }, - { -2, -2, 100, 100, -1, -1, 50, 50, 4, -4, 2, -2, 0.5, true }, - { -101, -100, 50, 50, -51, -50, 26, 25, 0, 0, 0, 0, 0.5, false }, - { 10, 10, 20, 20, 5, 5, 10, 10, 0, 0, 0, 0, 0.5, true }, - // Cannot scroll due to partial coverage on sides - { 11, 10, 20, 20, 5, 5, 11, 10, 0, 0, 0, 0, 0.5, false }, - // Can scroll since backing store is actually smaller/scaling up - { 11, 20, 100, 100, 22, 40, 200, 200, 7, 3, 14, 6, 2.0, true }, - // Can scroll due to delta and bounds being aligned - { 10, 10, 20, 20, 5, 5, 10, 10, 6, 4, 3, 2, 0.5, true }, - // Cannot scroll due to dx - { 10, 10, 20, 20, 5, 5, 10, 10, 5, 4, 2, 2, 0.5, false }, - // Cannot scroll due to dy - { 10, 10, 20, 20, 5, 5, 10, 10, 6, 3, 3, 1, 0.5, false }, - // Cannot scroll due to top - { 10, 11, 20, 20, 5, 5, 10, 11, 6, 4, 3, 2, 0.5, false }, - // Cannot scroll due to left - { 7, 10, 20, 20, 3, 5, 11, 10, 6, 4, 3, 2, 0.5, false }, - // Cannot scroll due to width - { 10, 10, 21, 20, 5, 5, 11, 10, 6, 4, 3, 2, 0.5, false }, - // Cannot scroll due to height - { 10, 10, 20, 51, 5, 5, 10, 26, 6, 4, 3, 2, 0.5, false }, - // Check negative scroll deltas - { 10, 10, 20, 20, 5, 5, 10, 10, -6, -4, -3, -2, 0.5, true }, - { 10, 10, 20, 20, 5, 5, 10, 10, -6, -3, -3, -1, 0.5, false }, - }; + } tests[] = {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1.0, true}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2.0, true}, + {0, 0, 4, 4, 0, 0, 2, 2, 0, 0, 0, 0, 0.5, true}, + {1, 1, 4, 4, 0, 0, 3, 3, 0, 0, 0, 0, 0.5, false}, + {53, 75, 100, 100, 53, 75, 100, 100, 0, 0, 0, 0, 1.0, true}, + {53, 75, 100, 100, 106, 150, 200, 200, 0, 0, 0, 0, 2.0, true}, + {53, 75, 100, 100, 26, 37, 51, 51, 0, 0, 0, 0, 0.5, false}, + {53, 74, 100, 100, 26, 37, 51, 50, 0, 0, 0, 0, 0.5, false}, + {-1, -1, 100, 100, -1, -1, 51, 51, 0, 0, 0, 0, 0.5, false}, + {-2, -2, 100, 100, -1, -1, 50, 50, 4, -4, 2, -2, 0.5, true}, + {-101, -100, 50, 50, -51, -50, 26, 25, 0, 0, 0, 0, 0.5, false}, + {10, 10, 20, 20, 5, 5, 10, 10, 0, 0, 0, 0, 0.5, true}, + // Cannot scroll due to partial coverage on sides + {11, 10, 20, 20, 5, 5, 11, 10, 0, 0, 0, 0, 0.5, false}, + // Can scroll since backing store is actually smaller/scaling up + {11, 20, 100, 100, 22, 40, 200, 200, 7, 3, 14, 6, 2.0, true}, + // Can scroll due to delta and bounds being aligned + {10, 10, 20, 20, 5, 5, 10, 10, 6, 4, 3, 2, 0.5, true}, + // Cannot scroll due to dx + {10, 10, 20, 20, 5, 5, 10, 10, 5, 4, 2, 2, 0.5, false}, + // Cannot scroll due to dy + {10, 10, 20, 20, 5, 5, 10, 10, 6, 3, 3, 1, 0.5, false}, + // Cannot scroll due to top + {10, 11, 20, 20, 5, 5, 10, 11, 6, 4, 3, 2, 0.5, false}, + // Cannot scroll due to left + {7, 10, 20, 20, 3, 5, 11, 10, 6, 4, 3, 2, 0.5, false}, + // Cannot scroll due to width + {10, 10, 21, 20, 5, 5, 11, 10, 6, 4, 3, 2, 0.5, false}, + // Cannot scroll due to height + {10, 10, 20, 51, 5, 5, 10, 26, 6, 4, 3, 2, 0.5, false}, + // Check negative scroll deltas + {10, 10, 20, 20, 5, 5, 10, 10, -6, -4, -3, -2, 0.5, true}, + {10, 10, 20, 20, 5, 5, 10, 10, -6, -3, -3, -1, 0.5, false}, }; for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { gfx::Rect r1(tests[i].x1, tests[i].y1, tests[i].w1, tests[i].h1); gfx::Rect r2(tests[i].x2, tests[i].y2, tests[i].w2, tests[i].h2); @@ -183,212 +166,4 @@ TEST_F(PepperGraphics2DHostTest, ConvertToLogicalPixels) { } } -TEST_F(PepperGraphics2DHostTest, SetOffset) { - ppapi::ProxyAutoLock proxy_lock; - - // Initialize the backing store. - PP_Instance instance = 12345; - PP_Size backing_store_size = { 300, 300 }; - PP_Rect plugin_rect = PP_MakeRectFromXYWH(0, 0, 500, 500); - Init(instance, backing_store_size, plugin_rect); - - // Paint the entire backing store red. - scoped_refptr<PPB_ImageData_Impl> image_data( - new PPB_ImageData_Impl(instance, PPB_ImageData_Impl::ForTest())); - image_data->Init(PPB_ImageData_Impl::GetNativeImageDataFormat(), - backing_store_size.width, - backing_store_size.height, - true); - { - ImageDataAutoMapper auto_mapper(image_data.get()); - image_data->GetMappedBitmap()->eraseColor( - SkColorSetARGBMacro(255, 255, 0, 0)); - } - PaintImageData(image_data.get()); - Flush(); - - // Set up the actual and expected bitmaps/canvas. - SkBitmap actual_bitmap; - ResetPageBitmap(&actual_bitmap); - SkBitmap expected_bitmap; - ResetPageBitmap(&expected_bitmap); - - // Paint the backing store to the canvas. - PaintToWebCanvas(&actual_bitmap); - expected_bitmap.eraseArea( - SkIRect::MakeWH(backing_store_size.width, backing_store_size.height), - SkColorSetARGBMacro(255, 255, 0, 0)); - EXPECT_EQ(memcmp(expected_bitmap.getAddr(0, 0), - actual_bitmap.getAddr(0, 0), - expected_bitmap.getSize()), 0); - - // Set the offset. - PP_Point offset = { 20, 20 }; - SetOffset(offset); - ResetPageBitmap(&actual_bitmap); - PaintToWebCanvas(&actual_bitmap); - // No flush has occurred so the result should be the same. - EXPECT_EQ(memcmp(expected_bitmap.getAddr(0, 0), - actual_bitmap.getAddr(0, 0), - expected_bitmap.getSize()), 0); - - // Flush the offset and the location of the rectangle should have shifted. - Flush(); - ResetPageBitmap(&actual_bitmap); - PaintToWebCanvas(&actual_bitmap); - ResetPageBitmap(&expected_bitmap); - expected_bitmap.eraseArea( - SkIRect::MakeXYWH(offset.x, offset.y, - backing_store_size.width, backing_store_size.height), - SkColorSetARGBMacro(255, 255, 0, 0)); - EXPECT_EQ(memcmp(expected_bitmap.getAddr(0, 0), - actual_bitmap.getAddr(0, 0), - expected_bitmap.getSize()), 0); -} - -TEST_F(PepperGraphics2DHostTest, ResizeModeDefault) { - ppapi::ProxyAutoLock proxy_lock; - - // Initialize the backing store. - PP_Instance instance = 12345; - PP_Size backing_store_size = { 300, 300 }; - PP_Rect plugin_rect = PP_MakeRectFromXYWH(0, 0, 300, 300); - Init(instance, backing_store_size, plugin_rect); - - // Paint the entire backing store red. - scoped_refptr<PPB_ImageData_Impl> image_data( - new PPB_ImageData_Impl(instance, PPB_ImageData_Impl::ForTest())); - image_data->Init(PPB_ImageData_Impl::GetNativeImageDataFormat(), - backing_store_size.width, - backing_store_size.height, - true); - { - ImageDataAutoMapper auto_mapper(image_data.get()); - image_data->GetMappedBitmap()->eraseColor( - SkColorSetARGBMacro(255, 255, 0, 0)); - } - PaintImageData(image_data.get()); - Flush(); - - // Set up the actual and expected bitmaps/canvas. - SkBitmap actual_bitmap; - ResetPageBitmap(&actual_bitmap); - SkBitmap expected_bitmap; - ResetPageBitmap(&expected_bitmap); - - // Paint the backing store to the canvas. - PaintToWebCanvas(&actual_bitmap); - expected_bitmap.eraseArea( - SkIRect::MakeWH(backing_store_size.width, backing_store_size.height), - SkColorSetARGBMacro(255, 255, 0, 0)); - EXPECT_EQ(memcmp(expected_bitmap.getAddr(0, 0), - actual_bitmap.getAddr(0, 0), - expected_bitmap.getSize()), 0); - - // Resize the plugin. - DidChangeView(PP_MakeRectFromXYWH(0, 0, 500, 500)); - // Paint the backing store again, it shouldn't have changed. - ResetPageBitmap(&actual_bitmap); - PaintToWebCanvas(&actual_bitmap); - ResetPageBitmap(&expected_bitmap); - expected_bitmap.eraseArea( - SkIRect::MakeWH(backing_store_size.width, backing_store_size.height), - SkColorSetARGBMacro(255, 255, 0, 0)); - EXPECT_EQ(memcmp(expected_bitmap.getAddr(0, 0), - actual_bitmap.getAddr(0, 0), - expected_bitmap.getSize()), 0); - - // Let the plugin know about the updated view and reflush the original image. - PluginViewUpdated(); - PaintImageData(image_data.get()); - Flush(); - // Paint the backing store again, it shouldn't have changed. - ResetPageBitmap(&actual_bitmap); - PaintToWebCanvas(&actual_bitmap); - EXPECT_EQ(memcmp(expected_bitmap.getAddr(0, 0), - actual_bitmap.getAddr(0, 0), - expected_bitmap.getSize()), 0); -} - -TEST_F(PepperGraphics2DHostTest, ResizeModeStretch) { - ppapi::ProxyAutoLock proxy_lock; - - // Initialize the backing store. - PP_Instance instance = 12345; - PP_Size backing_store_size = { 300, 300 }; - PP_Rect plugin_rect = PP_MakeRectFromXYWH(0, 0, 300, 300); - Init(instance, backing_store_size, plugin_rect); - SetResizeMode(PP_GRAPHICS2D_DEV_RESIZEMODE_STRETCH); - - // Paint the entire backing store red. - scoped_refptr<PPB_ImageData_Impl> image_data( - new PPB_ImageData_Impl(instance, PPB_ImageData_Impl::ForTest())); - image_data->Init(PPB_ImageData_Impl::GetNativeImageDataFormat(), - backing_store_size.width, - backing_store_size.height, - true); - { - ImageDataAutoMapper auto_mapper(image_data.get()); - image_data->GetMappedBitmap()->eraseColor( - SkColorSetARGBMacro(255, 255, 0, 0)); - } - PaintImageData(image_data.get()); - Flush(); - - // Set up the actual and expected bitmaps/canvas. - SkBitmap actual_bitmap; - ResetPageBitmap(&actual_bitmap); - SkBitmap expected_bitmap; - ResetPageBitmap(&expected_bitmap); - - // Paint the backing store to the canvas. - PaintToWebCanvas(&actual_bitmap); - expected_bitmap.eraseArea( - SkIRect::MakeWH(backing_store_size.width, backing_store_size.height), - SkColorSetARGBMacro(255, 255, 0, 0)); - EXPECT_EQ(memcmp(expected_bitmap.getAddr(0, 0), - actual_bitmap.getAddr(0, 0), - expected_bitmap.getSize()), 0); - - // Resize the plugin. - plugin_rect = PP_MakeRectFromXYWH(0, 0, 500, 500); - DidChangeView(plugin_rect); - ResetPageBitmap(&actual_bitmap); - ResetPageBitmap(&expected_bitmap); - - // Paint the backing store again, it should be stretched even though no new - // image has been flushed. - PaintToWebCanvas(&actual_bitmap); - expected_bitmap.eraseColor(SkColorSetARGBMacro(255, 255, 0, 0)); - EXPECT_EQ(memcmp(expected_bitmap.getAddr(0, 0), - actual_bitmap.getAddr(0, 0), - expected_bitmap.getSize()), 0); - - // Re-flush the original image data and paint it, it should be stretched as - // well. - PaintImageData(image_data.get()); - Flush(); - ResetPageBitmap(&actual_bitmap); - PaintToWebCanvas(&actual_bitmap); - EXPECT_EQ(memcmp(expected_bitmap.getAddr(0, 0), - actual_bitmap.getAddr(0, 0), - expected_bitmap.getSize()), 0); - - // Let the plugin know about the updated view. - PluginViewUpdated(); - - // Now flush the image data again, it should be at the original size. - PaintImageData(image_data.get()); - Flush(); - ResetPageBitmap(&actual_bitmap); - PaintToWebCanvas(&actual_bitmap); - ResetPageBitmap(&expected_bitmap); - expected_bitmap.eraseArea( - SkIRect::MakeWH(backing_store_size.width, backing_store_size.height), - SkColorSetARGBMacro(255, 255, 0, 0)); - EXPECT_EQ(memcmp(expected_bitmap.getAddr(0, 0), - actual_bitmap.getAddr(0, 0), - expected_bitmap.getSize()), 0); -} - } // namespace content diff --git a/chromium/content/renderer/pepper/pepper_hung_plugin_filter.cc b/chromium/content/renderer/pepper/pepper_hung_plugin_filter.cc index ba4af0e22bb..942dd6e7ecd 100644 --- a/chromium/content/renderer/pepper/pepper_hung_plugin_filter.cc +++ b/chromium/content/renderer/pepper/pepper_hung_plugin_filter.cc @@ -35,8 +35,7 @@ PepperHungPluginFilter::PepperHungPluginFilter( io_loop_(ChildProcess::current()->io_message_loop_proxy()), pending_sync_message_count_(0), hung_plugin_showing_(false), - timer_task_pending_(false) { -} + timer_task_pending_(false) {} void PepperHungPluginFilter::BeginBlockOnSyncMessage() { base::AutoLock lock(lock_); @@ -56,8 +55,7 @@ void PepperHungPluginFilter::EndBlockOnSyncMessage() { MayHaveBecomeUnhung(); } -void PepperHungPluginFilter::OnFilterAdded(IPC::Channel* channel) { -} +void PepperHungPluginFilter::OnFilterAdded(IPC::Sender* sender) {} void PepperHungPluginFilter::OnFilterRemoved() { base::AutoLock lock(lock_); @@ -85,7 +83,8 @@ void PepperHungPluginFilter::EnsureTimerScheduled() { return; timer_task_pending_ = true; - io_loop_->PostDelayedTask(FROM_HERE, + io_loop_->PostDelayedTask( + FROM_HERE, base::Bind(&PepperHungPluginFilter::OnHangTimer, this), base::TimeDelta::FromSeconds(kHungThresholdSec)); } @@ -107,12 +106,13 @@ base::TimeTicks PepperHungPluginFilter::GetHungTime() const { DCHECK(!last_message_received_.is_null()); // Always considered hung at the hard threshold. - base::TimeTicks hard_time = began_blocking_time_ + + base::TimeTicks hard_time = + began_blocking_time_ + base::TimeDelta::FromSeconds(kBlockedHardThresholdSec); // Hung after a soft threshold from last message of any sort. - base::TimeTicks soft_time = last_message_received_ + - base::TimeDelta::FromSeconds(kHungThresholdSec); + base::TimeTicks soft_time = + last_message_received_ + base::TimeDelta::FromSeconds(kHungThresholdSec); return std::min(soft_time, hard_time); } @@ -140,7 +140,8 @@ void PepperHungPluginFilter::OnHangTimer() { // would not have scheduled one (we only have one out-standing timer at // a time). timer_task_pending_ = true; - io_loop_->PostDelayedTask(FROM_HERE, + io_loop_->PostDelayedTask( + FROM_HERE, base::Bind(&PepperHungPluginFilter::OnHangTimer, this), delay); return; diff --git a/chromium/content/renderer/pepper/pepper_hung_plugin_filter.h b/chromium/content/renderer/pepper/pepper_hung_plugin_filter.h index ee83674800f..e7457fd1132 100644 --- a/chromium/content/renderer/pepper/pepper_hung_plugin_filter.h +++ b/chromium/content/renderer/pepper/pepper_hung_plugin_filter.h @@ -43,7 +43,7 @@ class PepperHungPluginFilter virtual void EndBlockOnSyncMessage() OVERRIDE; // MessageFilter implementation. - virtual void OnFilterAdded(IPC::Channel* channel) OVERRIDE; + virtual void OnFilterAdded(IPC::Sender* sender) OVERRIDE; virtual void OnFilterRemoved() OVERRIDE; virtual void OnChannelError() OVERRIDE; virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; diff --git a/chromium/content/renderer/pepper/pepper_in_process_resource_creation.cc b/chromium/content/renderer/pepper/pepper_in_process_resource_creation.cc index 23ed785ac5f..596f149cc18 100644 --- a/chromium/content/renderer/pepper/pepper_in_process_resource_creation.cc +++ b/chromium/content/renderer/pepper/pepper_in_process_resource_creation.cc @@ -43,12 +43,9 @@ namespace content { PepperInProcessResourceCreation::PepperInProcessResourceCreation( RendererPpapiHostImpl* host_impl, PepperPluginInstanceImpl* instance) - : ResourceCreationImpl(instance), - host_impl_(host_impl) { -} + : ResourceCreationImpl(instance), host_impl_(host_impl) {} -PepperInProcessResourceCreation::~PepperInProcessResourceCreation() { -} +PepperInProcessResourceCreation::~PepperInProcessResourceCreation() {} PP_Resource PepperInProcessResourceCreation::CreateBrowserFont( PP_Instance instance, @@ -58,10 +55,10 @@ PP_Resource PepperInProcessResourceCreation::CreateBrowserFont( ppapi::Preferences prefs( host_impl_->GetRenderViewForInstance(instance)->GetWebkitPreferences()); return (new BrowserFontResource_Trusted( - host_impl_->in_process_router()->GetPluginConnection(instance), - instance, - *description, - prefs))->GetReference(); + host_impl_->in_process_router()->GetPluginConnection(instance), + instance, + *description, + prefs))->GetReference(); } PP_Resource PepperInProcessResourceCreation::CreateFileChooser( @@ -72,17 +69,17 @@ PP_Resource PepperInProcessResourceCreation::CreateFileChooser( ppapi::StringVar::FromPPVar(accept_types); std::string str = string_var.get() ? string_var->value() : std::string(); return (new ppapi::proxy::FileChooserResource( - host_impl_->in_process_router()->GetPluginConnection(instance), - instance, - mode, - str.c_str()))->GetReference(); + host_impl_->in_process_router()->GetPluginConnection(instance), + instance, + mode, + str.c_str()))->GetReference(); } PP_Resource PepperInProcessResourceCreation::CreateFileIO( PP_Instance instance) { return (new ppapi::proxy::FileIOResource( - host_impl_->in_process_router()->GetPluginConnection(instance), - instance))->GetReference(); + host_impl_->in_process_router()->GetPluginConnection(instance), + instance))->GetReference(); } PP_Resource PepperInProcessResourceCreation::CreateFileRef( @@ -98,8 +95,9 @@ PP_Resource PepperInProcessResourceCreation::CreateFileSystem( PP_Instance instance, PP_FileSystemType type) { return (new ppapi::proxy::FileSystemResource( - host_impl_->in_process_router()->GetPluginConnection(instance), - instance, type))->GetReference(); + host_impl_->in_process_router()->GetPluginConnection(instance), + instance, + type))->GetReference(); } PP_Resource PepperInProcessResourceCreation::CreateGraphics2D( @@ -107,15 +105,17 @@ PP_Resource PepperInProcessResourceCreation::CreateGraphics2D( const PP_Size* size, PP_Bool is_always_opaque) { return (new ppapi::proxy::Graphics2DResource( - host_impl_->in_process_router()->GetPluginConnection(instance), - instance, *size, is_always_opaque))->GetReference(); + host_impl_->in_process_router()->GetPluginConnection(instance), + instance, + *size, + is_always_opaque))->GetReference(); } PP_Resource PepperInProcessResourceCreation::CreatePrinting( PP_Instance instance) { return (new ppapi::proxy::PrintingResource( - host_impl_->in_process_router()->GetPluginConnection(instance), - instance))->GetReference(); + host_impl_->in_process_router()->GetPluginConnection(instance), + instance))->GetReference(); } PP_Resource PepperInProcessResourceCreation::CreateTrueTypeFont( @@ -128,22 +128,23 @@ PP_Resource PepperInProcessResourceCreation::CreateTrueTypeFont( PP_Resource PepperInProcessResourceCreation::CreateURLLoader( PP_Instance instance) { return (new ppapi::proxy::URLLoaderResource( - host_impl_->in_process_router()->GetPluginConnection(instance), - instance))->GetReference(); + host_impl_->in_process_router()->GetPluginConnection(instance), + instance))->GetReference(); } PP_Resource PepperInProcessResourceCreation::CreateURLRequestInfo( PP_Instance instance) { return (new ppapi::proxy::URLRequestInfoResource( - host_impl_->in_process_router()->GetPluginConnection(instance), - instance, ppapi::URLRequestInfoData()))->GetReference(); + host_impl_->in_process_router()->GetPluginConnection(instance), + instance, + ppapi::URLRequestInfoData()))->GetReference(); } PP_Resource PepperInProcessResourceCreation::CreateWebSocket( PP_Instance instance) { return (new ppapi::proxy::WebSocketResource( - host_impl_->in_process_router()->GetPluginConnection(instance), - instance))->GetReference(); + host_impl_->in_process_router()->GetPluginConnection(instance), + instance))->GetReference(); } } // namespace content diff --git a/chromium/content/renderer/pepper/pepper_in_process_resource_creation.h b/chromium/content/renderer/pepper/pepper_in_process_resource_creation.h index 847aac11493..2718912da07 100644 --- a/chromium/content/renderer/pepper/pepper_in_process_resource_creation.h +++ b/chromium/content/renderer/pepper/pepper_in_process_resource_creation.h @@ -44,31 +44,25 @@ class PepperInProcessResourceCreation : public ResourceCreationImpl { virtual PP_Resource CreateBrowserFont( PP_Instance instance, const PP_BrowserFont_Trusted_Description* description) OVERRIDE; - virtual PP_Resource CreateFileChooser( - PP_Instance instance, - PP_FileChooserMode_Dev mode, - const PP_Var& accept_types) OVERRIDE; + virtual PP_Resource CreateFileChooser(PP_Instance instance, + PP_FileChooserMode_Dev mode, + const PP_Var& accept_types) OVERRIDE; virtual PP_Resource CreateFileIO(PP_Instance instance) OVERRIDE; - virtual PP_Resource CreateFileRef( - PP_Instance instance, - const ppapi::FileRefCreateInfo& create_info) OVERRIDE; + virtual PP_Resource CreateFileRef(PP_Instance instance, + const ppapi::FileRefCreateInfo& create_info) + OVERRIDE; virtual PP_Resource CreateFileSystem(PP_Instance instance, PP_FileSystemType type) OVERRIDE; - virtual PP_Resource CreateGraphics2D( - PP_Instance pp_instance, - const PP_Size* size, - PP_Bool is_always_opaque) OVERRIDE; - virtual PP_Resource CreatePrinting( - PP_Instance instance) OVERRIDE; + virtual PP_Resource CreateGraphics2D(PP_Instance pp_instance, + const PP_Size* size, + PP_Bool is_always_opaque) OVERRIDE; + virtual PP_Resource CreatePrinting(PP_Instance instance) OVERRIDE; virtual PP_Resource CreateTrueTypeFont( PP_Instance instance, const struct PP_TrueTypeFontDesc_Dev* desc) OVERRIDE; - virtual PP_Resource CreateURLLoader( - PP_Instance instance) OVERRIDE; - virtual PP_Resource CreateURLRequestInfo( - PP_Instance instance) OVERRIDE; - virtual PP_Resource CreateWebSocket( - PP_Instance instance) OVERRIDE; + virtual PP_Resource CreateURLLoader(PP_Instance instance) OVERRIDE; + virtual PP_Resource CreateURLRequestInfo(PP_Instance instance) OVERRIDE; + virtual PP_Resource CreateWebSocket(PP_Instance instance) OVERRIDE; private: // Non-owning pointer to the host for the current plugin. diff --git a/chromium/content/renderer/pepper/pepper_in_process_router.cc b/chromium/content/renderer/pepper/pepper_in_process_router.cc index 45755e1d4d8..9194f12fb7f 100644 --- a/chromium/content/renderer/pepper/pepper_in_process_router.cc +++ b/chromium/content/renderer/pepper/pepper_in_process_router.cc @@ -34,25 +34,20 @@ class PepperInProcessRouter::Channel : public IPC::Sender { base::Callback<bool(IPC::Message*)> callback_; }; -PepperInProcessRouter::PepperInProcessRouter( - RendererPpapiHostImpl* host_impl) +PepperInProcessRouter::PepperInProcessRouter(RendererPpapiHostImpl* host_impl) : host_impl_(host_impl), pending_message_id_(0), reply_result_(false), weak_factory_(this) { - browser_channel_.reset( - new Channel(base::Bind(&PepperInProcessRouter::SendToBrowser, - base::Unretained(this)))); - host_to_plugin_router_.reset( - new Channel(base::Bind(&PepperInProcessRouter::SendToPlugin, - base::Unretained(this)))); - plugin_to_host_router_.reset( - new Channel(base::Bind(&PepperInProcessRouter::SendToHost, - base::Unretained(this)))); + browser_channel_.reset(new Channel(base::Bind( + &PepperInProcessRouter::SendToBrowser, base::Unretained(this)))); + host_to_plugin_router_.reset(new Channel(base::Bind( + &PepperInProcessRouter::SendToPlugin, base::Unretained(this)))); + plugin_to_host_router_.reset(new Channel( + base::Bind(&PepperInProcessRouter::SendToHost, base::Unretained(this)))); } -PepperInProcessRouter::~PepperInProcessRouter() { -} +PepperInProcessRouter::~PepperInProcessRouter() {} IPC::Sender* PepperInProcessRouter::GetPluginToRendererSender() { return plugin_to_host_router_.get(); @@ -68,9 +63,8 @@ ppapi::proxy::Connection PepperInProcessRouter::GetPluginConnection( RenderFrame* frame = host_impl_->GetRenderFrameForInstance(instance); if (frame) routing_id = frame->GetRoutingID(); - return ppapi::proxy::Connection(browser_channel_.get(), - plugin_to_host_router_.get(), - routing_id); + return ppapi::proxy::Connection( + browser_channel_.get(), plugin_to_host_router_.get(), routing_id); } // static @@ -81,15 +75,15 @@ bool PepperInProcessRouter::OnPluginMsgReceived(const IPC::Message& msg) { if (msg.type() == PpapiPluginMsg_ResourceReply::ID) { // Resource reply from the renderer (no routing id). - if (!UnpackMessage<PpapiPluginMsg_ResourceReply>(msg, &reply_params, - &nested_msg)) { + if (!UnpackMessage<PpapiPluginMsg_ResourceReply>( + msg, &reply_params, &nested_msg)) { NOTREACHED(); return false; } } else if (msg.type() == PpapiHostMsg_InProcessResourceReply::ID) { // Resource reply from the browser (has a routing id). - if (!UnpackMessage<PpapiHostMsg_InProcessResourceReply>(msg, &reply_params, - &nested_msg)) { + if (!UnpackMessage<PpapiHostMsg_InProcessResourceReply>( + msg, &reply_params, &nested_msg)) { NOTREACHED(); return false; } @@ -171,7 +165,7 @@ void PepperInProcessRouter::DispatchPluginMsg(IPC::Message* msg) { DCHECK(handled); } -bool PepperInProcessRouter::SendToBrowser(IPC::Message *msg) { +bool PepperInProcessRouter::SendToBrowser(IPC::Message* msg) { return RenderThread::Get()->Send(msg); } diff --git a/chromium/content/renderer/pepper/pepper_in_process_router.h b/chromium/content/renderer/pepper/pepper_in_process_router.h index 77b19881174..73865fc3135 100644 --- a/chromium/content/renderer/pepper/pepper_in_process_router.h +++ b/chromium/content/renderer/pepper/pepper_in_process_router.h @@ -69,11 +69,11 @@ class PepperInProcessRouter { static bool OnPluginMsgReceived(const IPC::Message& msg); private: - bool SendToHost(IPC::Message *msg); - bool SendToPlugin(IPC::Message *msg); + bool SendToHost(IPC::Message* msg); + bool SendToPlugin(IPC::Message* msg); void DispatchHostMsg(IPC::Message* msg); void DispatchPluginMsg(IPC::Message* msg); - bool SendToBrowser(IPC::Message *msg); + bool SendToBrowser(IPC::Message* msg); RendererPpapiHostImpl* host_impl_; diff --git a/chromium/content/renderer/pepper/pepper_media_device_manager.cc b/chromium/content/renderer/pepper/pepper_media_device_manager.cc index 9704980e3a1..b36df317788 100644 --- a/chromium/content/renderer/pepper/pepper_media_device_manager.cc +++ b/chromium/content/renderer/pepper/pepper_media_device_manager.cc @@ -24,7 +24,7 @@ ppapi::DeviceRefData FromStreamDeviceInfo(const StreamDeviceInfo& info) { } // namespace PepperMediaDeviceManager* PepperMediaDeviceManager::GetForRenderView( - RenderView* render_view) { + RenderView* render_view) { PepperMediaDeviceManager* handler = PepperMediaDeviceManager::Get(render_view); if (!handler) @@ -35,8 +35,7 @@ PepperMediaDeviceManager* PepperMediaDeviceManager::GetForRenderView( PepperMediaDeviceManager::PepperMediaDeviceManager(RenderView* render_view) : RenderViewObserver(render_view), RenderViewObserverTracker<PepperMediaDeviceManager>(render_view), - next_id_(1) { -} + next_id_(1) {} PepperMediaDeviceManager::~PepperMediaDeviceManager() { DCHECK(enumerate_callbacks_.empty()); @@ -52,17 +51,18 @@ int PepperMediaDeviceManager::EnumerateDevices( #if defined(ENABLE_WEBRTC) GetRenderViewImpl()->media_stream_dispatcher()->EnumerateDevices( - request_id, AsWeakPtr(), + request_id, + AsWeakPtr(), PepperMediaDeviceManager::FromPepperDeviceType(type), - document_url.GetOrigin()); + document_url.GetOrigin(), + false); #else base::MessageLoop::current()->PostTask( FROM_HERE, - base::Bind( - &PepperMediaDeviceManager::OnDevicesEnumerated, - AsWeakPtr(), - request_id, - StreamDeviceInfoArray())); + base::Bind(&PepperMediaDeviceManager::OnDevicesEnumerated, + AsWeakPtr(), + request_id, + StreamDeviceInfoArray())); #endif return request_id; @@ -83,22 +83,20 @@ void PepperMediaDeviceManager::StopEnumerateDevices(int request_id) { #endif } -int PepperMediaDeviceManager::OpenDevice( - PP_DeviceType_Dev type, - const std::string& device_id, - const GURL& document_url, - const OpenDeviceCallback& callback) { +int PepperMediaDeviceManager::OpenDevice(PP_DeviceType_Dev type, + const std::string& device_id, + const GURL& document_url, + const OpenDeviceCallback& callback) { open_callbacks_[next_id_] = callback; int request_id = next_id_++; #if defined(ENABLE_WEBRTC) - GetRenderViewImpl()->media_stream_dispatcher()-> - OpenDevice( - request_id, - AsWeakPtr(), - device_id, - PepperMediaDeviceManager::FromPepperDeviceType(type), - document_url.GetOrigin()); + GetRenderViewImpl()->media_stream_dispatcher()->OpenDevice( + request_id, + AsWeakPtr(), + device_id, + PepperMediaDeviceManager::FromPepperDeviceType(type), + document_url.GetOrigin()); #else base::MessageLoop::current()->PostTask( FROM_HERE, @@ -114,8 +112,8 @@ void PepperMediaDeviceManager::CancelOpenDevice(int request_id) { open_callbacks_.erase(request_id); #if defined(ENABLE_WEBRTC) - GetRenderViewImpl()->media_stream_dispatcher()->CancelOpenDevice( - request_id, AsWeakPtr()); + GetRenderViewImpl()->media_stream_dispatcher()->CancelOpenDevice(request_id, + AsWeakPtr()); #endif } @@ -148,16 +146,15 @@ void PepperMediaDeviceManager::OnStreamGenerated( int request_id, const std::string& label, const StreamDeviceInfoArray& audio_device_array, - const StreamDeviceInfoArray& video_device_array) { -} + const StreamDeviceInfoArray& video_device_array) {} -void PepperMediaDeviceManager::OnStreamGenerationFailed(int request_id) { -} +void PepperMediaDeviceManager::OnStreamGenerationFailed( + int request_id, + content::MediaStreamRequestResult result) {} void PepperMediaDeviceManager::OnDeviceStopped( const std::string& label, - const StreamDeviceInfo& device_info) { -} + const StreamDeviceInfo& device_info) {} void PepperMediaDeviceManager::OnDevicesEnumerated( int request_id, @@ -173,8 +170,9 @@ void PepperMediaDeviceManager::OnDevicesEnumerated( std::vector<ppapi::DeviceRefData> devices; devices.reserve(device_array.size()); - for (StreamDeviceInfoArray::const_iterator info = - device_array.begin(); info != device_array.end(); ++info) { + for (StreamDeviceInfoArray::const_iterator info = device_array.begin(); + info != device_array.end(); + ++info) { devices.push_back(FromStreamDeviceInfo(*info)); } callback.Run(request_id, devices); @@ -223,10 +221,9 @@ PP_DeviceType_Dev PepperMediaDeviceManager::FromMediaStreamType( } } -void PepperMediaDeviceManager::NotifyDeviceOpened( - int request_id, - bool succeeded, - const std::string& label) { +void PepperMediaDeviceManager::NotifyDeviceOpened(int request_id, + bool succeeded, + const std::string& label) { OpenCallbackMap::iterator iter = open_callbacks_.find(request_id); if (iter == open_callbacks_.end()) { // The callback may have been unregistered. diff --git a/chromium/content/renderer/pepper/pepper_media_device_manager.h b/chromium/content/renderer/pepper/pepper_media_device_manager.h index ff67101d4a9..6fa7d7a044b 100644 --- a/chromium/content/renderer/pepper/pepper_media_device_manager.h +++ b/chromium/content/renderer/pepper/pepper_media_device_manager.h @@ -27,15 +27,15 @@ class PepperMediaDeviceManager virtual ~PepperMediaDeviceManager(); // PepperDeviceEnumerationHostHelper::Delegate implementation: - virtual int EnumerateDevices( - PP_DeviceType_Dev type, - const GURL& document_url, - const EnumerateDevicesCallback& callback) OVERRIDE; + virtual int EnumerateDevices(PP_DeviceType_Dev type, + const GURL& document_url, + const EnumerateDevicesCallback& callback) + OVERRIDE; virtual void StopEnumerateDevices(int request_id) OVERRIDE; - typedef base::Callback<void (int /* request_id */, - bool /* succeeded */, - const std::string& /* label */)> + typedef base::Callback<void(int /* request_id */, + bool /* succeeded */, + const std::string& /* label */)> OpenDeviceCallback; // Opens the specified device. The request ID passed into the callback will be @@ -60,16 +60,17 @@ class PepperMediaDeviceManager const std::string& label, const StreamDeviceInfoArray& audio_device_array, const StreamDeviceInfoArray& video_device_array) OVERRIDE; - virtual void OnStreamGenerationFailed(int request_id) OVERRIDE; + virtual void OnStreamGenerationFailed( + int request_id, + content::MediaStreamRequestResult result) OVERRIDE; virtual void OnDeviceStopped(const std::string& label, const StreamDeviceInfo& device_info) OVERRIDE; - virtual void OnDevicesEnumerated( - int request_id, - const StreamDeviceInfoArray& device_array) OVERRIDE; - virtual void OnDeviceOpened( - int request_id, - const std::string& label, - const StreamDeviceInfo& device_info) OVERRIDE; + virtual void OnDevicesEnumerated(int request_id, + const StreamDeviceInfoArray& device_array) + OVERRIDE; + virtual void OnDeviceOpened(int request_id, + const std::string& label, + const StreamDeviceInfo& device_info) OVERRIDE; virtual void OnDeviceOpenFailed(int request_id) OVERRIDE; // Stream type conversion. diff --git a/chromium/content/renderer/pepper/pepper_media_stream_audio_track_host.cc b/chromium/content/renderer/pepper/pepper_media_stream_audio_track_host.cc new file mode 100644 index 00000000000..d972c2c061e --- /dev/null +++ b/chromium/content/renderer/pepper/pepper_media_stream_audio_track_host.cc @@ -0,0 +1,265 @@ +// Copyright 2014 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 "content/renderer/pepper/pepper_media_stream_audio_track_host.h" + +#include <algorithm> + +#include "base/bind.h" +#include "base/location.h" +#include "base/logging.h" +#include "base/macros.h" +#include "base/message_loop/message_loop_proxy.h" +#include "base/numerics/safe_math.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/ppb_audio_buffer.h" +#include "ppapi/host/dispatch_host_message.h" +#include "ppapi/host/host_message_context.h" +#include "ppapi/proxy/ppapi_messages.h" +#include "ppapi/shared_impl/media_stream_audio_track_shared.h" +#include "ppapi/shared_impl/media_stream_buffer.h" + +using media::AudioParameters; +using ppapi::host::HostMessageContext; +using ppapi::MediaStreamAudioTrackShared; + +namespace { + +// Max audio buffer duration in milliseconds. +const uint32_t kMaxDuration = 10; + +const int32_t kDefaultNumberOfBuffers = 4; +const int32_t kMaxNumberOfBuffers = 1000; // 10 sec + +// Returns true if the |sample_rate| is supported in +// |PP_AudioBuffer_SampleRate|, otherwise false. +PP_AudioBuffer_SampleRate GetPPSampleRate(int sample_rate) { + switch (sample_rate) { + case 8000: + return PP_AUDIOBUFFER_SAMPLERATE_8000; + case 16000: + return PP_AUDIOBUFFER_SAMPLERATE_16000; + case 22050: + return PP_AUDIOBUFFER_SAMPLERATE_22050; + case 32000: + return PP_AUDIOBUFFER_SAMPLERATE_32000; + case 44100: + return PP_AUDIOBUFFER_SAMPLERATE_44100; + case 48000: + return PP_AUDIOBUFFER_SAMPLERATE_48000; + case 96000: + return PP_AUDIOBUFFER_SAMPLERATE_96000; + case 192000: + return PP_AUDIOBUFFER_SAMPLERATE_192000; + default: + return PP_AUDIOBUFFER_SAMPLERATE_UNKNOWN; + } +} + +} // namespace + +namespace content { + +PepperMediaStreamAudioTrackHost::AudioSink::AudioSink( + PepperMediaStreamAudioTrackHost* host) + : host_(host), + buffer_data_size_(0), + main_message_loop_proxy_(base::MessageLoopProxy::current()), + weak_factory_(this), + number_of_buffers_(kDefaultNumberOfBuffers), + bytes_per_second_(0) {} + +PepperMediaStreamAudioTrackHost::AudioSink::~AudioSink() { + DCHECK_EQ(main_message_loop_proxy_, base::MessageLoopProxy::current()); +} + +void PepperMediaStreamAudioTrackHost::AudioSink::EnqueueBuffer(int32_t index) { + DCHECK_EQ(main_message_loop_proxy_, base::MessageLoopProxy::current()); + DCHECK_GE(index, 0); + DCHECK_LT(index, host_->buffer_manager()->number_of_buffers()); + base::AutoLock lock(lock_); + buffers_.push_back(index); +} + +void PepperMediaStreamAudioTrackHost::AudioSink::Configure( + int32_t number_of_buffers) { + DCHECK_EQ(main_message_loop_proxy_, base::MessageLoopProxy::current()); + bool changed = false; + if (number_of_buffers != number_of_buffers_) + changed = true; + number_of_buffers_ = number_of_buffers; + + // Initialize later in OnSetFormat if bytes_per_second_ is not know yet. + if (changed && bytes_per_second_ > 0) + InitBuffers(); +} + +void PepperMediaStreamAudioTrackHost::AudioSink::SetFormatOnMainThread( + int bytes_per_second) { + bytes_per_second_ = bytes_per_second; + InitBuffers(); +} + +void PepperMediaStreamAudioTrackHost::AudioSink::InitBuffers() { + DCHECK_EQ(main_message_loop_proxy_, base::MessageLoopProxy::current()); + // The size is slightly bigger than necessary, because 8 extra bytes are + // added into the struct. Also see |MediaStreamBuffer|. + base::CheckedNumeric<int32_t> buffer_size = bytes_per_second_; + buffer_size *= kMaxDuration; + buffer_size /= base::Time::kMillisecondsPerSecond; + buffer_size += sizeof(ppapi::MediaStreamBuffer::Audio); + bool result = host_->InitBuffers(number_of_buffers_, + buffer_size.ValueOrDie(), + kRead); + // TODO(penghuang): Send PP_ERROR_NOMEMORY to plugin. + CHECK(result); + base::AutoLock lock(lock_); + buffers_.clear(); + for (int32_t i = 0; i < number_of_buffers_; ++i) { + int32_t index = host_->buffer_manager()->DequeueBuffer(); + DCHECK_GE(index, 0); + buffers_.push_back(index); + } +} + +void PepperMediaStreamAudioTrackHost::AudioSink:: + SendEnqueueBufferMessageOnMainThread(int32_t index) { + DCHECK_EQ(main_message_loop_proxy_, base::MessageLoopProxy::current()); + host_->SendEnqueueBufferMessageToPlugin(index); +} + +void PepperMediaStreamAudioTrackHost::AudioSink::OnData(const int16* audio_data, + int sample_rate, + int number_of_channels, + int number_of_frames) { + DCHECK(audio_thread_checker_.CalledOnValidThread()); + DCHECK(audio_data); + DCHECK_EQ(sample_rate, audio_params_.sample_rate()); + DCHECK_EQ(number_of_channels, audio_params_.channels()); + DCHECK_EQ(number_of_frames, audio_params_.frames_per_buffer()); + int32_t index = -1; + { + base::AutoLock lock(lock_); + if (!buffers_.empty()) { + index = buffers_.front(); + buffers_.pop_front(); + } + } + + if (index != -1) { + // TODO(penghuang): support re-sampling, etc. + ppapi::MediaStreamBuffer::Audio* buffer = + &(host_->buffer_manager()->GetBufferPointer(index)->audio); + buffer->header.size = host_->buffer_manager()->buffer_size(); + buffer->header.type = ppapi::MediaStreamBuffer::TYPE_AUDIO; + buffer->timestamp = timestamp_.InMillisecondsF(); + buffer->sample_rate = static_cast<PP_AudioBuffer_SampleRate>(sample_rate); + buffer->number_of_channels = number_of_channels; + buffer->number_of_samples = number_of_channels * number_of_frames; + buffer->data_size = buffer_data_size_; + memcpy(buffer->data, audio_data, buffer_data_size_); + + main_message_loop_proxy_->PostTask( + FROM_HERE, + base::Bind(&AudioSink::SendEnqueueBufferMessageOnMainThread, + weak_factory_.GetWeakPtr(), + index)); + } + timestamp_ += buffer_duration_; +} + +void PepperMediaStreamAudioTrackHost::AudioSink::OnSetFormat( + const AudioParameters& params) { + DCHECK(params.IsValid()); + DCHECK_LE(params.GetBufferDuration().InMilliseconds(), kMaxDuration); + DCHECK_EQ(params.bits_per_sample(), 16); + DCHECK_NE(GetPPSampleRate(params.sample_rate()), + PP_AUDIOBUFFER_SAMPLERATE_UNKNOWN); + + audio_params_ = params; + + // TODO(penghuang): support setting format more than once. + buffer_duration_ = params.GetBufferDuration(); + buffer_data_size_ = params.GetBytesPerBuffer(); + + if (original_audio_params_.IsValid()) { + DCHECK_EQ(params.sample_rate(), original_audio_params_.sample_rate()); + DCHECK_EQ(params.bits_per_sample(), + original_audio_params_.bits_per_sample()); + DCHECK_EQ(params.channels(), original_audio_params_.channels()); + } else { + audio_thread_checker_.DetachFromThread(); + original_audio_params_ = params; + + main_message_loop_proxy_->PostTask( + FROM_HERE, + base::Bind(&AudioSink::SetFormatOnMainThread, + weak_factory_.GetWeakPtr(), + params.GetBytesPerSecond())); + } +} + +PepperMediaStreamAudioTrackHost::PepperMediaStreamAudioTrackHost( + RendererPpapiHost* host, + PP_Instance instance, + PP_Resource resource, + const blink::WebMediaStreamTrack& track) + : PepperMediaStreamTrackHostBase(host, instance, resource), + track_(track), + connected_(false), + audio_sink_(this) { + DCHECK(!track_.isNull()); +} + +PepperMediaStreamAudioTrackHost::~PepperMediaStreamAudioTrackHost() { + OnClose(); +} + +int32_t PepperMediaStreamAudioTrackHost::OnResourceMessageReceived( + const IPC::Message& msg, + HostMessageContext* context) { + PPAPI_BEGIN_MESSAGE_MAP(PepperMediaStreamAudioTrackHost, msg) + PPAPI_DISPATCH_HOST_RESOURCE_CALL( + PpapiHostMsg_MediaStreamAudioTrack_Configure, OnHostMsgConfigure) + PPAPI_END_MESSAGE_MAP() + return PepperMediaStreamTrackHostBase::OnResourceMessageReceived(msg, + context); +} + +int32_t PepperMediaStreamAudioTrackHost::OnHostMsgConfigure( + HostMessageContext* context, + const MediaStreamAudioTrackShared::Attributes& attributes) { + if (!MediaStreamAudioTrackShared::VerifyAttributes(attributes)) + return PP_ERROR_BADARGUMENT; + + int32_t buffers = attributes.buffers + ? std::min(kMaxNumberOfBuffers, attributes.buffers) + : kDefaultNumberOfBuffers; + audio_sink_.Configure(buffers); + + context->reply_msg = PpapiPluginMsg_MediaStreamAudioTrack_ConfigureReply(); + return PP_OK; +} + +void PepperMediaStreamAudioTrackHost::OnClose() { + if (connected_) { + MediaStreamAudioSink::RemoveFromAudioTrack(&audio_sink_, track_); + connected_ = false; + } +} + +void PepperMediaStreamAudioTrackHost::OnNewBufferEnqueued() { + int32_t index = buffer_manager()->DequeueBuffer(); + DCHECK_GE(index, 0); + audio_sink_.EnqueueBuffer(index); +} + +void PepperMediaStreamAudioTrackHost::DidConnectPendingHostToResource() { + if (!connected_) { + MediaStreamAudioSink::AddToAudioTrack(&audio_sink_, track_); + connected_ = true; + } +} + +} // namespace content diff --git a/chromium/content/renderer/pepper/pepper_media_stream_audio_track_host.h b/chromium/content/renderer/pepper/pepper_media_stream_audio_track_host.h new file mode 100644 index 00000000000..348103c9928 --- /dev/null +++ b/chromium/content/renderer/pepper/pepper_media_stream_audio_track_host.h @@ -0,0 +1,150 @@ +// Copyright 2014 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 CONTENT_RENDERER_PEPPER_PEPPER_MEDIA_STREAM_AUDIO_TRACK_HOST_H_ +#define CONTENT_RENDERER_PEPPER_PEPPER_MEDIA_STREAM_AUDIO_TRACK_HOST_H_ + +#include <deque> + +#include "base/compiler_specific.h" +#include "base/memory/scoped_ptr.h" +#include "base/memory/weak_ptr.h" +#include "base/synchronization/lock.h" +#include "base/threading/thread_checker.h" +#include "content/public/renderer/media_stream_audio_sink.h" +#include "content/renderer/pepper/pepper_media_stream_track_host_base.h" +#include "media/audio/audio_parameters.h" +#include "ppapi/shared_impl/media_stream_audio_track_shared.h" +#include "third_party/WebKit/public/platform/WebMediaStreamTrack.h" + +namespace base { +class MessageLoopProxy; +} // namespace base + +namespace content { + +class PepperMediaStreamAudioTrackHost : public PepperMediaStreamTrackHostBase { + public: + PepperMediaStreamAudioTrackHost(RendererPpapiHost* host, + PP_Instance instance, + PP_Resource resource, + const blink::WebMediaStreamTrack& track); + + private: + // A helper class for receiving audio samples in the audio thread. + // This class is created and destroyed on the renderer main thread. + class AudioSink : public MediaStreamAudioSink { + public: + explicit AudioSink(PepperMediaStreamAudioTrackHost* host); + virtual ~AudioSink(); + + // Enqueues a free buffer index into |buffers_| which will be used for + // sending audio samples to plugin. + // This function is called on the main thread. + void EnqueueBuffer(int32_t index); + + // This function is called on the main thread. + void Configure(int32_t number_of_buffers); + + private: + // Initializes buffers on the main thread. + void SetFormatOnMainThread(int bytes_per_second); + + void InitBuffers(); + + // Send enqueue buffer message on the main thread. + void SendEnqueueBufferMessageOnMainThread(int32_t index); + + // MediaStreamAudioSink overrides: + // These two functions should be called on the audio thread. + virtual void OnData(const int16* audio_data, + int sample_rate, + int number_of_channels, + int number_of_frames) OVERRIDE; + virtual void OnSetFormat(const media::AudioParameters& params) OVERRIDE; + + // Unowned host which is available during the AudioSink's lifespan. + // It is mainly used in the main thread. But the audio thread will use + // host_->buffer_manager() to read some buffer properties. It is safe + // because the buffer_manager()'s properties will not be changed after + // initialization. + PepperMediaStreamAudioTrackHost* host_; + + // Timestamp of the next received audio buffer. + // Access only on the audio thread. + base::TimeDelta timestamp_; + + // Duration of one audio buffer. + // Access only on the audio thread. + base::TimeDelta buffer_duration_; + + // The current audio parameters. + // Access only on the audio thread. + media::AudioParameters audio_params_; + + // The original audio parameters which is set in the first time of + // OnSetFormat being called. + // Access only on the audio thread. + media::AudioParameters original_audio_params_; + + // The audio data size of one audio buffer in bytes. + // Access only on the audio thread. + uint32_t buffer_data_size_; + + // A lock to protect the index queue |buffers_|. + base::Lock lock_; + + // A queue for free buffer indices. + std::deque<int32_t> buffers_; + + scoped_refptr<base::MessageLoopProxy> main_message_loop_proxy_; + + base::ThreadChecker audio_thread_checker_; + + base::WeakPtrFactory<AudioSink> weak_factory_; + + // Number of buffers. + int32_t number_of_buffers_; + + // Number of bytes per second. + int bytes_per_second_; + + DISALLOW_COPY_AND_ASSIGN(AudioSink); + }; + + virtual ~PepperMediaStreamAudioTrackHost(); + + // ResourceMessageHandler overrides: + virtual int32_t OnResourceMessageReceived( + const IPC::Message& msg, + ppapi::host::HostMessageContext* context) OVERRIDE; + + // Message handlers: + int32_t OnHostMsgConfigure( + ppapi::host::HostMessageContext* context, + const ppapi::MediaStreamAudioTrackShared::Attributes& attributes); + + // PepperMediaStreamTrackHostBase overrides: + virtual void OnClose() OVERRIDE; + + // MediaStreamBufferManager::Delegate overrides: + virtual void OnNewBufferEnqueued() OVERRIDE; + + // ResourceHost overrides: + virtual void DidConnectPendingHostToResource() OVERRIDE; + + blink::WebMediaStreamTrack track_; + + // True if |audio_sink_| has been added to |blink::WebMediaStreamTrack| + // as a sink. + bool connected_; + + AudioSink audio_sink_; + + DISALLOW_COPY_AND_ASSIGN(PepperMediaStreamAudioTrackHost); +}; + +} // namespace content + +#endif // CONTENT_RENDERER_PEPPER_PEPPER_MEDIA_STREAM_AUDIO_TRACK_HOST_H_ diff --git a/chromium/content/renderer/pepper/pepper_media_stream_track_host_base.cc b/chromium/content/renderer/pepper/pepper_media_stream_track_host_base.cc new file mode 100644 index 00000000000..9ad40a9cf08 --- /dev/null +++ b/chromium/content/renderer/pepper/pepper_media_stream_track_host_base.cc @@ -0,0 +1,124 @@ +// Copyright 2014 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 "content/renderer/pepper/pepper_media_stream_track_host_base.h" + +#include "base/logging.h" +#include "base/numerics/safe_math.h" +#include "content/public/renderer/render_thread.h" +#include "content/public/renderer/renderer_ppapi_host.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/host/dispatch_host_message.h" +#include "ppapi/host/host_message_context.h" +#include "ppapi/host/ppapi_host.h" +#include "ppapi/proxy/ppapi_messages.h" +#include "ppapi/shared_impl/media_stream_buffer.h" + +using ppapi::host::HostMessageContext; +using ppapi::proxy::SerializedHandle; + +namespace content { + +PepperMediaStreamTrackHostBase::PepperMediaStreamTrackHostBase( + RendererPpapiHost* host, + PP_Instance instance, + PP_Resource resource) + : ResourceHost(host->GetPpapiHost(), instance, resource), + host_(host), + buffer_manager_(this) {} + +PepperMediaStreamTrackHostBase::~PepperMediaStreamTrackHostBase() {} + +bool PepperMediaStreamTrackHostBase::InitBuffers(int32_t number_of_buffers, + int32_t buffer_size, + TrackType track_type) { + DCHECK_GT(number_of_buffers, 0); + DCHECK_GT(buffer_size, + static_cast<int32_t>(sizeof(ppapi::MediaStreamBuffer::Header))); + // Make each buffer 4 byte aligned. + base::CheckedNumeric<int32_t> buffer_size_aligned = buffer_size; + buffer_size_aligned += (4 - buffer_size % 4); + + // TODO(penghuang): |HostAllocateSharedMemoryBuffer| uses sync IPC. We should + // avoid it. + base::CheckedNumeric<int32_t> size = number_of_buffers * buffer_size_aligned; + if (!size.IsValid()) + return false; + + content::RenderThread* render_thread = content::RenderThread::Get(); + scoped_ptr<base::SharedMemory> shm( + render_thread->HostAllocateSharedMemoryBuffer(size.ValueOrDie()).Pass()); + if (!shm) + return false; + + base::SharedMemoryHandle shm_handle = shm->handle(); + if (!buffer_manager_.SetBuffers(number_of_buffers, + buffer_size_aligned.ValueOrDie(), + shm.Pass(), + true)) { + return false; + } + + base::PlatformFile platform_file = +#if defined(OS_WIN) + shm_handle; +#elif defined(OS_POSIX) + shm_handle.fd; +#else +#error Not implemented. +#endif + SerializedHandle handle(host_->ShareHandleWithRemote(platform_file, false), + size.ValueOrDie()); + bool readonly = (track_type == kRead); + host()->SendUnsolicitedReplyWithHandles( + pp_resource(), + PpapiPluginMsg_MediaStreamTrack_InitBuffers( + number_of_buffers, + buffer_size_aligned.ValueOrDie(), + readonly), + std::vector<SerializedHandle>(1, handle)); + return true; +} + +void PepperMediaStreamTrackHostBase::SendEnqueueBufferMessageToPlugin( + int32_t index) { + DCHECK_GE(index, 0); + DCHECK_LT(index, buffer_manager_.number_of_buffers()); + host()->SendUnsolicitedReply( + pp_resource(), PpapiPluginMsg_MediaStreamTrack_EnqueueBuffer(index)); +} + +void PepperMediaStreamTrackHostBase::SendEnqueueBuffersMessageToPlugin( + const std::vector<int32_t>& indices) { + DCHECK_GE(indices.size(), 0U); + host()->SendUnsolicitedReply(pp_resource(), + PpapiPluginMsg_MediaStreamTrack_EnqueueBuffers(indices)); +} + +int32_t PepperMediaStreamTrackHostBase::OnResourceMessageReceived( + const IPC::Message& msg, + HostMessageContext* context) { + PPAPI_BEGIN_MESSAGE_MAP(PepperMediaStreamTrackHostBase, msg) + PPAPI_DISPATCH_HOST_RESOURCE_CALL( + PpapiHostMsg_MediaStreamTrack_EnqueueBuffer, OnHostMsgEnqueueBuffer) + PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_MediaStreamTrack_Close, + OnHostMsgClose) + PPAPI_END_MESSAGE_MAP() + return ppapi::host::ResourceHost::OnResourceMessageReceived(msg, context); +} + +int32_t PepperMediaStreamTrackHostBase::OnHostMsgEnqueueBuffer( + HostMessageContext* context, + int32_t index) { + buffer_manager_.EnqueueBuffer(index); + return PP_OK; +} + +int32_t PepperMediaStreamTrackHostBase::OnHostMsgClose( + HostMessageContext* context) { + OnClose(); + return PP_OK; +} + +} // namespace content diff --git a/chromium/content/renderer/pepper/pepper_media_stream_track_host_base.h b/chromium/content/renderer/pepper/pepper_media_stream_track_host_base.h new file mode 100644 index 00000000000..37ebd611515 --- /dev/null +++ b/chromium/content/renderer/pepper/pepper_media_stream_track_host_base.h @@ -0,0 +1,73 @@ +// Copyright 2014 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 CONTENT_RENDERER_PEPPER_PEPPER_MEDIA_STREAM_TRACK_HOST_BASE_H_ +#define CONTENT_RENDERER_PEPPER_PEPPER_MEDIA_STREAM_TRACK_HOST_BASE_H_ + +#include "base/compiler_specific.h" +#include "content/common/content_export.h" +#include "ppapi/host/resource_host.h" +#include "ppapi/shared_impl/media_stream_buffer_manager.h" + +namespace content { + +class RendererPpapiHost; + +class PepperMediaStreamTrackHostBase + : public ppapi::host::ResourceHost, + public ppapi::MediaStreamBufferManager::Delegate { + protected: + PepperMediaStreamTrackHostBase(RendererPpapiHost* host, + PP_Instance instance, + PP_Resource resource); + virtual ~PepperMediaStreamTrackHostBase(); + + enum TrackType { + kRead, + kWrite + }; + bool InitBuffers(int32_t number_of_buffers, + int32_t buffer_size, + TrackType track_type); + + ppapi::MediaStreamBufferManager* buffer_manager() { return &buffer_manager_; } + + // Sends a buffer index to the corresponding MediaStreamTrackResourceBase + // via an IPC message. The resource adds the buffer index into its + // |buffer_manager_| for reading or writing. + // Also see |MediaStreamBufferManager|. + void SendEnqueueBufferMessageToPlugin(int32_t index); + + // Sends a set of buffer indices to the corresponding + // MediaStreamTrackResourceBase via an IPC message. + // The resource adds the buffer indices into its + // |frame_buffer_| for reading or writing. Also see |MediaStreamFrameBuffer|. + void SendEnqueueBuffersMessageToPlugin(const std::vector<int32_t>& indices); + + // ResourceMessageHandler overrides: + virtual int32_t OnResourceMessageReceived( + const IPC::Message& msg, + ppapi::host::HostMessageContext* context) OVERRIDE; + + // Message handlers: + virtual int32_t OnHostMsgEnqueueBuffer( + ppapi::host::HostMessageContext* context, int32_t index); + + private: + // Subclasses must implement this method to clean up when the track is closed. + virtual void OnClose() = 0; + + // Message handlers: + int32_t OnHostMsgClose(ppapi::host::HostMessageContext* context); + + RendererPpapiHost* host_; + + ppapi::MediaStreamBufferManager buffer_manager_; + + DISALLOW_COPY_AND_ASSIGN(PepperMediaStreamTrackHostBase); +}; + +} // namespace content + +#endif // CONTENT_RENDERER_PEPPER_PEPPER_MEDIA_STREAM_TRACK_HOST_BASE_H_ diff --git a/chromium/content/renderer/pepper/pepper_media_stream_video_track_host.cc b/chromium/content/renderer/pepper/pepper_media_stream_video_track_host.cc new file mode 100644 index 00000000000..5df6f2df9a5 --- /dev/null +++ b/chromium/content/renderer/pepper/pepper_media_stream_video_track_host.cc @@ -0,0 +1,545 @@ +// Copyright 2014 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 "content/renderer/pepper/pepper_media_stream_video_track_host.h" + +#include "base/base64.h" +#include "base/logging.h" +#include "base/rand_util.h" +#include "base/strings/utf_string_conversions.h" +#include "content/renderer/media/media_stream_video_track.h" +#include "media/base/bind_to_current_loop.h" +#include "media/base/yuv_convert.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/ppb_media_stream_video_track.h" +#include "ppapi/c/ppb_video_frame.h" +#include "ppapi/host/dispatch_host_message.h" +#include "ppapi/host/host_message_context.h" +#include "ppapi/proxy/ppapi_messages.h" +#include "ppapi/shared_impl/media_stream_buffer.h" + +// IS_ALIGNED is also defined in +// third_party/libjingle/overrides/talk/base/basictypes.h +// TODO(ronghuawu): Avoid undef. +#undef IS_ALIGNED +#include "third_party/libyuv/include/libyuv.h" + +using media::VideoFrame; +using ppapi::host::HostMessageContext; +using ppapi::MediaStreamVideoTrackShared; + +namespace { + +const int32_t kDefaultNumberOfBuffers = 4; +const int32_t kMaxNumberOfBuffers = 8; +// Filter mode for scaling frames. +const libyuv::FilterMode kFilterMode = libyuv::kFilterBox; + +const char kPepperVideoSourceName[] = "PepperVideoSourceName"; + +// Default config for output mode. +const int kDefaultOutputFrameRate = 30; + +media::VideoPixelFormat ToPixelFormat(PP_VideoFrame_Format format) { + switch (format) { + case PP_VIDEOFRAME_FORMAT_YV12: + return media::PIXEL_FORMAT_YV12; + case PP_VIDEOFRAME_FORMAT_I420: + return media::PIXEL_FORMAT_I420; + default: + DVLOG(1) << "Unsupported pixel format " << format; + return media::PIXEL_FORMAT_UNKNOWN; + } +} + +PP_VideoFrame_Format ToPpapiFormat(VideoFrame::Format format) { + switch (format) { + case VideoFrame::YV12: + return PP_VIDEOFRAME_FORMAT_YV12; + case VideoFrame::I420: + return PP_VIDEOFRAME_FORMAT_I420; + default: + DVLOG(1) << "Unsupported pixel format " << format; + return PP_VIDEOFRAME_FORMAT_UNKNOWN; + } +} + +VideoFrame::Format FromPpapiFormat(PP_VideoFrame_Format format) { + switch (format) { + case PP_VIDEOFRAME_FORMAT_YV12: + return VideoFrame::YV12; + case PP_VIDEOFRAME_FORMAT_I420: + return VideoFrame::I420; + default: + DVLOG(1) << "Unsupported pixel format " << format; + return VideoFrame::UNKNOWN; + } +} + +// Compute size base on the size of frame received from MediaStreamVideoSink +// and size specified by plugin. +gfx::Size GetTargetSize(const gfx::Size& source, const gfx::Size& plugin) { + return gfx::Size(plugin.width() ? plugin.width() : source.width(), + plugin.height() ? plugin.height() : source.height()); +} + +// Compute format base on the format of frame received from MediaStreamVideoSink +// and format specified by plugin. +PP_VideoFrame_Format GetTargetFormat(PP_VideoFrame_Format source, + PP_VideoFrame_Format plugin) { + return plugin != PP_VIDEOFRAME_FORMAT_UNKNOWN ? plugin : source; +} + +void ConvertFromMediaVideoFrame(const scoped_refptr<media::VideoFrame>& src, + PP_VideoFrame_Format dst_format, + const gfx::Size& dst_size, + uint8_t* dst) { + CHECK(src->format() == VideoFrame::YV12 || src->format() == VideoFrame::I420); + if (dst_format == PP_VIDEOFRAME_FORMAT_BGRA) { + if (src->coded_size() == dst_size) { + libyuv::I420ToARGB(src->data(VideoFrame::kYPlane), + src->stride(VideoFrame::kYPlane), + src->data(VideoFrame::kUPlane), + src->stride(VideoFrame::kUPlane), + src->data(VideoFrame::kVPlane), + src->stride(VideoFrame::kVPlane), + dst, + dst_size.width() * 4, + dst_size.width(), + dst_size.height()); + } else { + media::ScaleYUVToRGB32(src->data(VideoFrame::kYPlane), + src->data(VideoFrame::kUPlane), + src->data(VideoFrame::kVPlane), + dst, + src->coded_size().width(), + src->coded_size().height(), + dst_size.width(), + dst_size.height(), + src->stride(VideoFrame::kYPlane), + src->stride(VideoFrame::kUPlane), + dst_size.width() * 4, + media::YV12, + media::ROTATE_0, + media::FILTER_BILINEAR); + } + } else if (dst_format == PP_VIDEOFRAME_FORMAT_YV12 || + dst_format == PP_VIDEOFRAME_FORMAT_I420) { + static const size_t kPlanesOrder[][3] = { + {VideoFrame::kYPlane, VideoFrame::kVPlane, + VideoFrame::kUPlane}, // YV12 + {VideoFrame::kYPlane, VideoFrame::kUPlane, + VideoFrame::kVPlane}, // I420 + }; + const int plane_order = (dst_format == PP_VIDEOFRAME_FORMAT_YV12) ? 0 : 1; + int dst_width = dst_size.width(); + int dst_height = dst_size.height(); + libyuv::ScalePlane(src->data(kPlanesOrder[plane_order][0]), + src->stride(kPlanesOrder[plane_order][0]), + src->coded_size().width(), + src->coded_size().height(), + dst, + dst_width, + dst_width, + dst_height, + kFilterMode); + dst += dst_width * dst_height; + const int src_halfwidth = (src->coded_size().width() + 1) >> 1; + const int src_halfheight = (src->coded_size().height() + 1) >> 1; + const int dst_halfwidth = (dst_width + 1) >> 1; + const int dst_halfheight = (dst_height + 1) >> 1; + libyuv::ScalePlane(src->data(kPlanesOrder[plane_order][1]), + src->stride(kPlanesOrder[plane_order][1]), + src_halfwidth, + src_halfheight, + dst, + dst_halfwidth, + dst_halfwidth, + dst_halfheight, + kFilterMode); + dst += dst_halfwidth * dst_halfheight; + libyuv::ScalePlane(src->data(kPlanesOrder[plane_order][2]), + src->stride(kPlanesOrder[plane_order][2]), + src_halfwidth, + src_halfheight, + dst, + dst_halfwidth, + dst_halfwidth, + dst_halfheight, + kFilterMode); + } else { + NOTREACHED(); + } +} + +} // namespace + +namespace content { + +// Internal class used for delivering video frames on the IO-thread to +// the MediaStreamVideoSource implementation. +class PepperMediaStreamVideoTrackHost::FrameDeliverer + : public base::RefCountedThreadSafe<FrameDeliverer> { + public: + FrameDeliverer( + const scoped_refptr<base::MessageLoopProxy>& io_message_loop_proxy, + const VideoCaptureDeliverFrameCB& new_frame_callback); + + void DeliverVideoFrame(const scoped_refptr<media::VideoFrame>& frame, + const media::VideoCaptureFormat& format); + + private: + friend class base::RefCountedThreadSafe<FrameDeliverer>; + virtual ~FrameDeliverer(); + + void DeliverFrameOnIO(const scoped_refptr<media::VideoFrame>& frame, + const media::VideoCaptureFormat& format); + + scoped_refptr<base::MessageLoopProxy> io_message_loop_; + VideoCaptureDeliverFrameCB new_frame_callback_; + + DISALLOW_COPY_AND_ASSIGN(FrameDeliverer); +}; + +PepperMediaStreamVideoTrackHost::FrameDeliverer::FrameDeliverer( + const scoped_refptr<base::MessageLoopProxy>& io_message_loop_proxy, + const VideoCaptureDeliverFrameCB& new_frame_callback) + : io_message_loop_(io_message_loop_proxy), + new_frame_callback_(new_frame_callback) { +} + +PepperMediaStreamVideoTrackHost::FrameDeliverer::~FrameDeliverer() { +} + +void PepperMediaStreamVideoTrackHost::FrameDeliverer::DeliverVideoFrame( + const scoped_refptr<media::VideoFrame>& frame, + const media::VideoCaptureFormat& format) { + io_message_loop_->PostTask( + FROM_HERE, + base::Bind(&FrameDeliverer::DeliverFrameOnIO, + this, frame, format)); +} + +void PepperMediaStreamVideoTrackHost::FrameDeliverer::DeliverFrameOnIO( + const scoped_refptr<media::VideoFrame>& frame, + const media::VideoCaptureFormat& format) { + DCHECK(io_message_loop_->BelongsToCurrentThread()); + // The time when this frame is generated is unknown so give a null value to + // |estimated_capture_time|. + new_frame_callback_.Run(frame, format, base::TimeTicks()); +} + +PepperMediaStreamVideoTrackHost::PepperMediaStreamVideoTrackHost( + RendererPpapiHost* host, + PP_Instance instance, + PP_Resource resource, + const blink::WebMediaStreamTrack& track) + : PepperMediaStreamTrackHostBase(host, instance, resource), + track_(track), + connected_(false), + number_of_buffers_(kDefaultNumberOfBuffers), + source_frame_format_(PP_VIDEOFRAME_FORMAT_UNKNOWN), + plugin_frame_format_(PP_VIDEOFRAME_FORMAT_UNKNOWN), + frame_data_size_(0), + type_(kRead), + output_started_(false), + weak_factory_(this) { + DCHECK(!track_.isNull()); +} + +PepperMediaStreamVideoTrackHost::PepperMediaStreamVideoTrackHost( + RendererPpapiHost* host, + PP_Instance instance, + PP_Resource resource) + : PepperMediaStreamTrackHostBase(host, instance, resource), + connected_(false), + number_of_buffers_(kDefaultNumberOfBuffers), + source_frame_format_(PP_VIDEOFRAME_FORMAT_UNKNOWN), + plugin_frame_format_(PP_VIDEOFRAME_FORMAT_UNKNOWN), + frame_data_size_(0), + type_(kWrite), + output_started_(false), + weak_factory_(this) { + InitBlinkTrack(); + DCHECK(!track_.isNull()); +} + +bool PepperMediaStreamVideoTrackHost::IsMediaStreamVideoTrackHost() { + return true; +} + +PepperMediaStreamVideoTrackHost::~PepperMediaStreamVideoTrackHost() { + OnClose(); +} + +void PepperMediaStreamVideoTrackHost::InitBuffers() { + gfx::Size size = GetTargetSize(source_frame_size_, plugin_frame_size_); + DCHECK(!size.IsEmpty()); + + PP_VideoFrame_Format format = + GetTargetFormat(source_frame_format_, plugin_frame_format_); + DCHECK_NE(format, PP_VIDEOFRAME_FORMAT_UNKNOWN); + + if (format == PP_VIDEOFRAME_FORMAT_BGRA) { + frame_data_size_ = size.width() * size.height() * 4; + } else { + frame_data_size_ = + VideoFrame::AllocationSize(FromPpapiFormat(format), size); + } + + DCHECK_GT(frame_data_size_, 0U); + int32_t buffer_size = + sizeof(ppapi::MediaStreamBuffer::Video) + frame_data_size_; + bool result = PepperMediaStreamTrackHostBase::InitBuffers(number_of_buffers_, + buffer_size, + type_); + CHECK(result); + + if (type_ == kWrite) { + for (int32_t i = 0; i < buffer_manager()->number_of_buffers(); ++i) { + ppapi::MediaStreamBuffer::Video* buffer = + &(buffer_manager()->GetBufferPointer(i)->video); + buffer->header.size = buffer_manager()->buffer_size(); + buffer->header.type = ppapi::MediaStreamBuffer::TYPE_VIDEO; + buffer->format = format; + buffer->size.width = size.width(); + buffer->size.height = size.height(); + buffer->data_size = frame_data_size_; + } + + // Make all the frames avaiable to the plugin. + std::vector<int32_t> indices = buffer_manager()->DequeueBuffers(); + SendEnqueueBuffersMessageToPlugin(indices); + } +} + +void PepperMediaStreamVideoTrackHost::OnClose() { + if (connected_) { + MediaStreamVideoSink::RemoveFromVideoTrack(this, track_); + weak_factory_.InvalidateWeakPtrs(); + connected_ = false; + } +} + +int32_t PepperMediaStreamVideoTrackHost::OnHostMsgEnqueueBuffer( + ppapi::host::HostMessageContext* context, int32_t index) { + if (type_ == kRead) { + return PepperMediaStreamTrackHostBase::OnHostMsgEnqueueBuffer(context, + index); + } else { + return SendFrameToTrack(index); + } +} + +int32_t PepperMediaStreamVideoTrackHost::SendFrameToTrack(int32_t index) { + DCHECK_EQ(type_, kWrite); + + if (output_started_) { + // Sends the frame to blink video track. + ppapi::MediaStreamBuffer::Video* pp_frame = + &(buffer_manager()->GetBufferPointer(index)->video); + + int32 y_stride = plugin_frame_size_.width(); + int32 uv_stride = (plugin_frame_size_.width() + 1) / 2; + uint8* y_data = static_cast<uint8*>(pp_frame->data); + // Default to I420 + uint8* u_data = y_data + plugin_frame_size_.GetArea(); + uint8* v_data = y_data + (plugin_frame_size_.GetArea() * 5 / 4); + if (plugin_frame_format_ == PP_VIDEOFRAME_FORMAT_YV12) { + // Swap u and v for YV12. + uint8* tmp = u_data; + u_data = v_data; + v_data = tmp; + } + + int64 ts_ms = static_cast<int64>(pp_frame->timestamp * + base::Time::kMillisecondsPerSecond); + scoped_refptr<VideoFrame> frame = media::VideoFrame::WrapExternalYuvData( + FromPpapiFormat(plugin_frame_format_), + plugin_frame_size_, + gfx::Rect(plugin_frame_size_), + plugin_frame_size_, + y_stride, + uv_stride, + uv_stride, + y_data, + u_data, + v_data, + base::TimeDelta::FromMilliseconds(ts_ms), + base::Closure()); + + frame_deliverer_->DeliverVideoFrame( + frame, + media::VideoCaptureFormat(plugin_frame_size_, + kDefaultOutputFrameRate, + ToPixelFormat(plugin_frame_format_))); + } + + // Makes the frame available again for plugin. + SendEnqueueBufferMessageToPlugin(index); + return PP_OK; +} + +void PepperMediaStreamVideoTrackHost::OnVideoFrame( + const scoped_refptr<VideoFrame>& frame, + const media::VideoCaptureFormat& format, + const base::TimeTicks& estimated_capture_time) { + DCHECK(frame); + // TODO(penghuang): Check |frame->end_of_stream()| and close the track. + PP_VideoFrame_Format ppformat = ToPpapiFormat(frame->format()); + if (ppformat == PP_VIDEOFRAME_FORMAT_UNKNOWN) + return; + + if (source_frame_size_.IsEmpty()) { + source_frame_size_ = frame->coded_size(); + source_frame_format_ = ppformat; + InitBuffers(); + } + + int32_t index = buffer_manager()->DequeueBuffer(); + // Drop frames if the underlying buffer is full. + if (index < 0) { + DVLOG(1) << "A frame is dropped."; + return; + } + + CHECK(frame->coded_size() == source_frame_size_) << "Frame size is changed"; + CHECK_EQ(ppformat, source_frame_format_) << "Frame format is changed."; + + gfx::Size size = GetTargetSize(source_frame_size_, plugin_frame_size_); + ppformat = + GetTargetFormat(source_frame_format_, plugin_frame_format_); + ppapi::MediaStreamBuffer::Video* buffer = + &(buffer_manager()->GetBufferPointer(index)->video); + buffer->header.size = buffer_manager()->buffer_size(); + buffer->header.type = ppapi::MediaStreamBuffer::TYPE_VIDEO; + buffer->timestamp = frame->timestamp().InSecondsF(); + buffer->format = ppformat; + buffer->size.width = size.width(); + buffer->size.height = size.height(); + buffer->data_size = frame_data_size_; + ConvertFromMediaVideoFrame(frame, ppformat, size, buffer->data); + + SendEnqueueBufferMessageToPlugin(index); +} + +void PepperMediaStreamVideoTrackHost::GetCurrentSupportedFormats( + int max_requested_width, int max_requested_height, + const VideoCaptureDeviceFormatsCB& callback) { + if (type_ != kWrite) { + DVLOG(1) << "GetCurrentSupportedFormats is only supported in output mode."; + callback.Run(media::VideoCaptureFormats()); + return; + } + + media::VideoCaptureFormats formats; + formats.push_back( + media::VideoCaptureFormat(plugin_frame_size_, + kDefaultOutputFrameRate, + ToPixelFormat(plugin_frame_format_))); + callback.Run(formats); +} + +void PepperMediaStreamVideoTrackHost::StartSourceImpl( + const media::VideoCaptureParams& params, + const VideoCaptureDeliverFrameCB& frame_callback) { + output_started_ = true; + frame_deliverer_ = new FrameDeliverer(io_message_loop(), frame_callback); +} + +void PepperMediaStreamVideoTrackHost::StopSourceImpl() { + output_started_ = false; + frame_deliverer_ = NULL; +} + +void PepperMediaStreamVideoTrackHost::DidConnectPendingHostToResource() { + if (!connected_) { + MediaStreamVideoSink::AddToVideoTrack( + this, + media::BindToCurrentLoop( + base::Bind( + &PepperMediaStreamVideoTrackHost::OnVideoFrame, + weak_factory_.GetWeakPtr())), + track_); + connected_ = true; + } +} + +int32_t PepperMediaStreamVideoTrackHost::OnResourceMessageReceived( + const IPC::Message& msg, + HostMessageContext* context) { + PPAPI_BEGIN_MESSAGE_MAP(PepperMediaStreamVideoTrackHost, msg) + PPAPI_DISPATCH_HOST_RESOURCE_CALL( + PpapiHostMsg_MediaStreamVideoTrack_Configure, OnHostMsgConfigure) + PPAPI_END_MESSAGE_MAP() + return PepperMediaStreamTrackHostBase::OnResourceMessageReceived(msg, + context); +} + +int32_t PepperMediaStreamVideoTrackHost::OnHostMsgConfigure( + HostMessageContext* context, + const MediaStreamVideoTrackShared::Attributes& attributes) { + CHECK(MediaStreamVideoTrackShared::VerifyAttributes(attributes)); + + bool changed = false; + gfx::Size new_size(attributes.width, attributes.height); + if (GetTargetSize(source_frame_size_, plugin_frame_size_) != + GetTargetSize(source_frame_size_, new_size)) { + changed = true; + } + plugin_frame_size_ = new_size; + + int32_t buffers = attributes.buffers + ? std::min(kMaxNumberOfBuffers, attributes.buffers) + : kDefaultNumberOfBuffers; + if (buffers != number_of_buffers_) + changed = true; + number_of_buffers_ = buffers; + + if (GetTargetFormat(source_frame_format_, plugin_frame_format_) != + GetTargetFormat(source_frame_format_, attributes.format)) { + changed = true; + } + plugin_frame_format_ = attributes.format; + + // If the first frame has been received, we will re-initialize buffers with + // new settings. Otherwise, we will initialize buffer when we receive + // the first frame, because plugin can only provide part of attributes + // which are not enough to initialize buffers. + if (changed && (type_ == kWrite || !source_frame_size_.IsEmpty())) + InitBuffers(); + + // TODO(ronghuawu): Ask the owner of DOMMediaStreamTrackToResource why + // source id instead of track id is used there. + const std::string id = track_.source().id().utf8(); + context->reply_msg = PpapiPluginMsg_MediaStreamVideoTrack_ConfigureReply(id); + return PP_OK; +} + +void PepperMediaStreamVideoTrackHost::InitBlinkTrack() { + std::string source_id; + base::Base64Encode(base::RandBytesAsString(64), &source_id); + blink::WebMediaStreamSource webkit_source; + webkit_source.initialize(base::UTF8ToUTF16(source_id), + blink::WebMediaStreamSource::TypeVideo, + base::UTF8ToUTF16(kPepperVideoSourceName)); + webkit_source.setExtraData(this); + + const bool enabled = true; + blink::WebMediaConstraints constraints; + constraints.initialize(); + track_ = MediaStreamVideoTrack::CreateVideoTrack( + this, constraints, + base::Bind( + &PepperMediaStreamVideoTrackHost::OnTrackStarted, + base::Unretained(this)), + enabled); +} + +void PepperMediaStreamVideoTrackHost::OnTrackStarted( + MediaStreamSource* source, bool success) { + DVLOG(3) << "OnTrackStarted result: " << success; +} + +} // namespace content diff --git a/chromium/content/renderer/pepper/pepper_media_stream_video_track_host.h b/chromium/content/renderer/pepper/pepper_media_stream_video_track_host.h new file mode 100644 index 00000000000..178eaefbd10 --- /dev/null +++ b/chromium/content/renderer/pepper/pepper_media_stream_video_track_host.h @@ -0,0 +1,130 @@ +// Copyright 2014 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 CONTENT_RENDERER_PEPPER_PEPPER_MEDIA_STREAM_VIDEO_TRACK_HOST_H_ +#define CONTENT_RENDERER_PEPPER_PEPPER_MEDIA_STREAM_VIDEO_TRACK_HOST_H_ + +#include "base/compiler_specific.h" +#include "base/memory/weak_ptr.h" +#include "content/public/renderer/media_stream_video_sink.h" +#include "content/renderer/media/media_stream_video_source.h" +#include "content/renderer/pepper/pepper_media_stream_track_host_base.h" +#include "media/base/video_frame.h" +#include "ppapi/c/ppb_video_frame.h" +#include "ppapi/shared_impl/media_stream_video_track_shared.h" +#include "third_party/WebKit/public/platform/WebMediaStreamTrack.h" +#include "ui/gfx/size.h" + +namespace content { + +class PepperMediaStreamVideoTrackHost : public PepperMediaStreamTrackHostBase, + public MediaStreamVideoSink, + public MediaStreamVideoSource { + public: + // Input mode constructor. + // In input mode, this class passes video frames from |track| to the + // associated pepper plugin. + PepperMediaStreamVideoTrackHost(RendererPpapiHost* host, + PP_Instance instance, + PP_Resource resource, + const blink::WebMediaStreamTrack& track); + + // Output mode constructor. + // In output mode, this class passes video frames from the associated + // pepper plugin to a newly created blink::WebMediaStreamTrack. + PepperMediaStreamVideoTrackHost(RendererPpapiHost* host, + PP_Instance instance, + PP_Resource resource); + + virtual bool IsMediaStreamVideoTrackHost() OVERRIDE; + + blink::WebMediaStreamTrack track() { return track_; } + + private: + + virtual ~PepperMediaStreamVideoTrackHost(); + + void InitBuffers(); + + // PepperMediaStreamTrackHostBase overrides: + virtual void OnClose() OVERRIDE; + virtual int32_t OnHostMsgEnqueueBuffer( + ppapi::host::HostMessageContext* context, int32_t index) OVERRIDE; + + // Sends frame with |index| to |track_|. + int32_t SendFrameToTrack(int32_t index); + + void OnVideoFrame(const scoped_refptr<media::VideoFrame>& frame, + const media::VideoCaptureFormat& format, + const base::TimeTicks& estimated_capture_time); + + // MediaStreamVideoSource overrides: + virtual void GetCurrentSupportedFormats( + int max_requested_width, + int max_requested_height, + const VideoCaptureDeviceFormatsCB& callback) OVERRIDE; + + virtual void StartSourceImpl( + const media::VideoCaptureParams& params, + const VideoCaptureDeliverFrameCB& frame_callback) OVERRIDE; + + virtual void StopSourceImpl() OVERRIDE; + + // ResourceHost overrides: + virtual void DidConnectPendingHostToResource() OVERRIDE; + + // ResourceMessageHandler overrides: + virtual int32_t OnResourceMessageReceived( + const IPC::Message& msg, + ppapi::host::HostMessageContext* context) OVERRIDE; + + // Message handlers: + int32_t OnHostMsgConfigure( + ppapi::host::HostMessageContext* context, + const ppapi::MediaStreamVideoTrackShared::Attributes& attributes); + + void InitBlinkTrack(); + void OnTrackStarted(MediaStreamSource* source, bool success); + + blink::WebMediaStreamTrack track_; + + // True if it has been added to |blink::WebMediaStreamTrack| as a sink. + bool connected_; + + // Number of buffers. + int32_t number_of_buffers_; + + // Size of frames which are received from MediaStreamVideoSink. + gfx::Size source_frame_size_; + + // Plugin specified frame size. + gfx::Size plugin_frame_size_; + + // Format of frames which are received from MediaStreamVideoSink. + PP_VideoFrame_Format source_frame_format_; + + // Plugin specified frame format. + PP_VideoFrame_Format plugin_frame_format_; + + // The size of frame pixels in bytes. + uint32_t frame_data_size_; + + // TODO(ronghuawu): Remove |type_| and split PepperMediaStreamVideoTrackHost + // into 2 classes for read and write. + TrackType type_; + bool output_started_; + + // Internal class used for delivering video frames on the IO-thread to + // the MediaStreamVideoSource implementation. + class FrameDeliverer; + scoped_refptr<FrameDeliverer> frame_deliverer_; + + base::WeakPtrFactory<PepperMediaStreamVideoTrackHost> weak_factory_; + + DISALLOW_COPY_AND_ASSIGN(PepperMediaStreamVideoTrackHost); +}; + +} // namespace content + +#endif // CONTENT_RENDERER_PEPPER_PEPPER_MEDIA_STREAM_VIDEO_TRACK_HOST_H_ diff --git a/chromium/content/renderer/pepper/pepper_platform_audio_input.cc b/chromium/content/renderer/pepper/pepper_platform_audio_input.cc index 3110eaf08b7..ed2bbcfc4fb 100644 --- a/chromium/content/renderer/pepper/pepper_platform_audio_input.cc +++ b/chromium/content/renderer/pepper/pepper_platform_audio_input.cc @@ -30,8 +30,12 @@ PepperPlatformAudioInput* PepperPlatformAudioInput::Create( PepperAudioInputHost* client) { scoped_refptr<PepperPlatformAudioInput> audio_input( new PepperPlatformAudioInput()); - if (audio_input->Initialize(render_view, device_id, document_url, - sample_rate, frames_per_buffer, client)) { + if (audio_input->Initialize(render_view, + device_id, + document_url, + sample_rate, + frames_per_buffer, + client)) { // Balanced by Release invoked in // PepperPlatformAudioInput::ShutDownOnIOThread(). audio_input->AddRef(); @@ -93,8 +97,12 @@ void PepperPlatformAudioInput::OnStreamCreated( // cleaned up on the main thread. main_message_loop_proxy_->PostTask( FROM_HERE, - base::Bind(&PepperPlatformAudioInput::OnStreamCreated, this, - handle, socket_handle, length, total_segments)); + base::Bind(&PepperPlatformAudioInput::OnStreamCreated, + this, + handle, + socket_handle, + length, + total_segments)); } else { // Must dereference the client only on the main thread. Shutdown may have // occurred while the request was in-flight, so we need to NULL check. @@ -111,12 +119,9 @@ void PepperPlatformAudioInput::OnStreamCreated( void PepperPlatformAudioInput::OnVolume(double volume) {} void PepperPlatformAudioInput::OnStateChanged( - media::AudioInputIPCDelegate::State state) { -} + media::AudioInputIPCDelegate::State state) {} -void PepperPlatformAudioInput::OnIPCClosed() { - ipc_.reset(); -} +void PepperPlatformAudioInput::OnIPCClosed() { ipc_.reset(); } PepperPlatformAudioInput::~PepperPlatformAudioInput() { // Make sure we have been shut down. Warning: this may happen on the I/O @@ -136,8 +141,7 @@ PepperPlatformAudioInput::PepperPlatformAudioInput() io_message_loop_proxy_(ChildProcess::current()->io_message_loop_proxy()), create_stream_sent_(false), pending_open_device_(false), - pending_open_device_id_(-1) { -} + pending_open_device_id_(-1) {} bool PepperPlatformAudioInput::Initialize( const base::WeakPtr<RenderViewImpl>& render_view, @@ -151,15 +155,19 @@ bool PepperPlatformAudioInput::Initialize( if (!render_view.get() || !client) return false; - ipc_ = RenderThreadImpl::current()->audio_input_message_filter()-> - CreateAudioInputIPC(render_view->GetRoutingID()); + ipc_ = RenderThreadImpl::current() + ->audio_input_message_filter() + ->CreateAudioInputIPC(render_view->GetRoutingID()); render_view_ = render_view; client_ = client; params_.Reset(media::AudioParameters::AUDIO_PCM_LINEAR, - media::CHANNEL_LAYOUT_MONO, ppapi::kAudioInputChannels, 0, - sample_rate, ppapi::kBitsPerAudioInputSample, + media::CHANNEL_LAYOUT_MONO, + ppapi::kAudioInputChannels, + 0, + sample_rate, + ppapi::kBitsPerAudioInputSample, frames_per_buffer); // We need to open the device and obtain the label and session ID before @@ -208,8 +216,7 @@ void PepperPlatformAudioInput::ShutDownOnIOThread() { StopCaptureOnIOThread(); main_message_loop_proxy_->PostTask( - FROM_HERE, - base::Bind(&PepperPlatformAudioInput::CloseDevice, this)); + FROM_HERE, base::Bind(&PepperPlatformAudioInput::CloseDevice, this)); Release(); // Release for the delegate, balances out the reference taken in // PepperPlatformAudioInput::Create. @@ -233,7 +240,8 @@ void PepperPlatformAudioInput::OnDeviceOpened(int request_id, io_message_loop_proxy_->PostTask( FROM_HERE, base::Bind(&PepperPlatformAudioInput::InitializeOnIOThread, - this, session_id)); + this, + session_id)); } else { // Shutdown has occurred. CloseDevice(); diff --git a/chromium/content/renderer/pepper/pepper_platform_audio_input.h b/chromium/content/renderer/pepper/pepper_platform_audio_input.h index 47b9ebb00cc..56a701aeeb7 100644 --- a/chromium/content/renderer/pepper/pepper_platform_audio_input.h +++ b/chromium/content/renderer/pepper/pepper_platform_audio_input.h @@ -64,8 +64,8 @@ class PepperPlatformAudioInput int length, int total_segments) OVERRIDE; virtual void OnVolume(double volume) OVERRIDE; - virtual void OnStateChanged( - media::AudioInputIPCDelegate::State state) OVERRIDE; + virtual void OnStateChanged(media::AudioInputIPCDelegate::State state) + OVERRIDE; virtual void OnIPCClosed() OVERRIDE; protected: @@ -76,13 +76,12 @@ class PepperPlatformAudioInput PepperPlatformAudioInput(); - bool Initialize( - const base::WeakPtr<RenderViewImpl>& render_view, - const std::string& device_id, - const GURL& document_url, - int sample_rate, - int frames_per_buffer, - PepperAudioInputHost* client); + bool Initialize(const base::WeakPtr<RenderViewImpl>& render_view, + const std::string& device_id, + const GURL& document_url, + int sample_rate, + int frames_per_buffer, + PepperAudioInputHost* client); // I/O thread backends to above functions. void InitializeOnIOThread(int session_id); @@ -90,9 +89,7 @@ class PepperPlatformAudioInput void StopCaptureOnIOThread(); void ShutDownOnIOThread(); - void OnDeviceOpened(int request_id, - bool succeeded, - const std::string& label); + void OnDeviceOpened(int request_id, bool succeeded, const std::string& label); void CloseDevice(); void NotifyStreamCreationFailed(); diff --git a/chromium/content/renderer/pepper/pepper_platform_audio_output.cc b/chromium/content/renderer/pepper/pepper_platform_audio_output.cc index 715a459f485..7d65685cafa 100644 --- a/chromium/content/renderer/pepper/pepper_platform_audio_output.cc +++ b/chromium/content/renderer/pepper/pepper_platform_audio_output.cc @@ -23,11 +23,15 @@ PepperPlatformAudioOutput* PepperPlatformAudioOutput::Create( int sample_rate, int frames_per_buffer, int source_render_view_id, + int source_render_frame_id, AudioHelper* client) { scoped_refptr<PepperPlatformAudioOutput> audio_output( new PepperPlatformAudioOutput()); - if (audio_output->Initialize(sample_rate, frames_per_buffer, - source_render_view_id, client)) { + if (audio_output->Initialize(sample_rate, + frames_per_buffer, + source_render_view_id, + source_render_frame_id, + client)) { // Balanced by Release invoked in // PepperPlatformAudioOutput::ShutDownOnIOThread(). audio_output->AddRef(); @@ -66,8 +70,7 @@ void PepperPlatformAudioOutput::ShutDown() { } void PepperPlatformAudioOutput::OnStateChanged( - media::AudioOutputIPCDelegate::State state) { -} + media::AudioOutputIPCDelegate::State state) {} void PepperPlatformAudioOutput::OnStreamCreated( base::SharedMemoryHandle handle, @@ -83,21 +86,23 @@ void PepperPlatformAudioOutput::OnStreamCreated( DCHECK(length); if (base::MessageLoopProxy::current().get() == - main_message_loop_proxy_.get()) { + main_message_loop_proxy_.get()) { // Must dereference the client only on the main thread. Shutdown may have // occurred while the request was in-flight, so we need to NULL check. if (client_) client_->StreamCreated(handle, length, socket_handle); } else { - main_message_loop_proxy_->PostTask(FROM_HERE, - base::Bind(&PepperPlatformAudioOutput::OnStreamCreated, this, handle, - socket_handle, length)); + main_message_loop_proxy_->PostTask( + FROM_HERE, + base::Bind(&PepperPlatformAudioOutput::OnStreamCreated, + this, + handle, + socket_handle, + length)); } } -void PepperPlatformAudioOutput::OnIPCClosed() { - ipc_.reset(); -} +void PepperPlatformAudioOutput::OnIPCClosed() { ipc_.reset(); } PepperPlatformAudioOutput::~PepperPlatformAudioOutput() { // Make sure we have been shut down. Warning: this will usually happen on @@ -112,28 +117,29 @@ PepperPlatformAudioOutput::PepperPlatformAudioOutput() io_message_loop_proxy_(ChildProcess::current()->io_message_loop_proxy()) { } -bool PepperPlatformAudioOutput::Initialize( - int sample_rate, - int frames_per_buffer, - int source_render_view_id, - AudioHelper* client) { +bool PepperPlatformAudioOutput::Initialize(int sample_rate, + int frames_per_buffer, + int source_render_view_id, + int source_render_frame_id, + AudioHelper* client) { DCHECK(client); client_ = client; RenderThreadImpl* const render_thread = RenderThreadImpl::current(); - ipc_ = render_thread->audio_message_filter()-> - CreateAudioOutputIPC(source_render_view_id); + ipc_ = render_thread->audio_message_filter()->CreateAudioOutputIPC( + source_render_view_id, source_render_frame_id); CHECK(ipc_); - media::AudioParameters params( - media::AudioParameters::AUDIO_PCM_LOW_LATENCY, - media::CHANNEL_LAYOUT_STEREO, sample_rate, - ppapi::kBitsPerAudioOutputSample, frames_per_buffer); + media::AudioParameters params(media::AudioParameters::AUDIO_PCM_LOW_LATENCY, + media::CHANNEL_LAYOUT_STEREO, + sample_rate, + ppapi::kBitsPerAudioOutputSample, + frames_per_buffer); io_message_loop_proxy_->PostTask( FROM_HERE, - base::Bind(&PepperPlatformAudioOutput::InitializeOnIOThread, this, - params)); + base::Bind( + &PepperPlatformAudioOutput::InitializeOnIOThread, this, params)); return true; } diff --git a/chromium/content/renderer/pepper/pepper_platform_audio_output.h b/chromium/content/renderer/pepper/pepper_platform_audio_output.h index 775309b7e87..725d42f03a8 100644 --- a/chromium/content/renderer/pepper/pepper_platform_audio_output.h +++ b/chromium/content/renderer/pepper/pepper_platform_audio_output.h @@ -30,6 +30,7 @@ class PepperPlatformAudioOutput static PepperPlatformAudioOutput* Create(int sample_rate, int frames_per_buffer, int source_render_view_id, + int source_render_frame_id, AudioHelper* client); // The following three methods are all called on main thread. @@ -47,8 +48,8 @@ class PepperPlatformAudioOutput void ShutDown(); // media::AudioOutputIPCDelegate implementation. - virtual void OnStateChanged( - media::AudioOutputIPCDelegate::State state) OVERRIDE; + virtual void OnStateChanged(media::AudioOutputIPCDelegate::State state) + OVERRIDE; virtual void OnStreamCreated(base::SharedMemoryHandle handle, base::SyncSocket::Handle socket_handle, int length) OVERRIDE; @@ -65,6 +66,7 @@ class PepperPlatformAudioOutput bool Initialize(int sample_rate, int frames_per_buffer, int source_render_view_id, + int source_render_frame_id, AudioHelper* client); // I/O thread backends to above functions. diff --git a/chromium/content/renderer/pepper/pepper_platform_context_3d.cc b/chromium/content/renderer/pepper/pepper_platform_context_3d.cc deleted file mode 100644 index 6c3408bd429..00000000000 --- a/chromium/content/renderer/pepper/pepper_platform_context_3d.cc +++ /dev/null @@ -1,178 +0,0 @@ -// Copyright (c) 2012 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 "content/renderer/pepper/pepper_platform_context_3d.h" - -#include "base/bind.h" -#include "content/common/gpu/client/context_provider_command_buffer.h" -#include "content/common/gpu/client/gpu_channel_host.h" -#include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h" -#include "content/renderer/render_thread_impl.h" -#include "gpu/command_buffer/client/gles2_cmd_helper.h" -#include "gpu/command_buffer/client/gles2_implementation.h" -#include "ppapi/c/pp_graphics_3d.h" -#include "ui/gl/gpu_preference.h" -#include "url/gurl.h" - -namespace content { - -PlatformContext3D::PlatformContext3D() - : has_alpha_(false), - command_buffer_(NULL), - weak_ptr_factory_(this) { -} - -PlatformContext3D::~PlatformContext3D() { - if (command_buffer_) { - DCHECK(channel_.get()); - channel_->DestroyCommandBuffer(command_buffer_); - command_buffer_ = NULL; - } - - channel_ = NULL; -} - -bool PlatformContext3D::Init(const int32* attrib_list, - PlatformContext3D* share_context) { - // Ignore initializing more than once. - if (command_buffer_) - return true; - - RenderThreadImpl* render_thread = RenderThreadImpl::current(); - if (!render_thread) - return false; - - gfx::GpuPreference gpu_preference = gfx::PreferDiscreteGpu; - - channel_ = render_thread->EstablishGpuChannelSync( - CAUSE_FOR_GPU_LAUNCH_PEPPERPLATFORMCONTEXT3DIMPL_INITIALIZE); - if (!channel_.get()) - return false; - - gfx::Size surface_size; - std::vector<int32> attribs; - // TODO(alokp): Change GpuChannelHost::CreateOffscreenCommandBuffer() - // interface to accept width and height in the attrib_list so that - // we do not need to filter for width and height here. - if (attrib_list) { - for (const int32_t* attr = attrib_list; - attr[0] != PP_GRAPHICS3DATTRIB_NONE; - attr += 2) { - switch (attr[0]) { - case PP_GRAPHICS3DATTRIB_WIDTH: - surface_size.set_width(attr[1]); - break; - case PP_GRAPHICS3DATTRIB_HEIGHT: - surface_size.set_height(attr[1]); - break; - case PP_GRAPHICS3DATTRIB_GPU_PREFERENCE: - gpu_preference = - (attr[1] == PP_GRAPHICS3DATTRIB_GPU_PREFERENCE_LOW_POWER) ? - gfx::PreferIntegratedGpu : gfx::PreferDiscreteGpu; - break; - case PP_GRAPHICS3DATTRIB_ALPHA_SIZE: - has_alpha_ = attr[1] > 0; - // fall-through - default: - attribs.push_back(attr[0]); - attribs.push_back(attr[1]); - break; - } - } - attribs.push_back(PP_GRAPHICS3DATTRIB_NONE); - } - - CommandBufferProxyImpl* share_buffer = NULL; - if (share_context) { - PlatformContext3D* share_impl = - static_cast<PlatformContext3D*>(share_context); - share_buffer = share_impl->command_buffer_; - } - - command_buffer_ = channel_->CreateOffscreenCommandBuffer( - surface_size, - share_buffer, - attribs, - GURL::EmptyGURL(), - gpu_preference); - if (!command_buffer_) - return false; - if (!command_buffer_->Initialize()) - return false; - std::vector<gpu::Mailbox> names; - if (!command_buffer_->GenerateMailboxNames(1, &names)) - return false; - DCHECK_EQ(names.size(), 1u); - if (!command_buffer_->ProduceFrontBuffer(names[0])) - return false; - mailbox_ = names[0]; - sync_point_ = command_buffer_->InsertSyncPoint(); - - command_buffer_->SetChannelErrorCallback( - base::Bind(&PlatformContext3D::OnContextLost, - weak_ptr_factory_.GetWeakPtr())); - command_buffer_->SetOnConsoleMessageCallback( - base::Bind(&PlatformContext3D::OnConsoleMessage, - weak_ptr_factory_.GetWeakPtr())); - - return true; -} - -void PlatformContext3D::GetBackingMailbox(gpu::Mailbox* mailbox, - uint32* sync_point) { - *mailbox = mailbox_; - *sync_point = sync_point_; -} - -void PlatformContext3D::InsertSyncPointForBackingMailbox() { - DCHECK(command_buffer_); - sync_point_ = command_buffer_->InsertSyncPoint(); -} - -bool PlatformContext3D::IsOpaque() { - DCHECK(command_buffer_); - return !has_alpha_; -} - -gpu::CommandBuffer* PlatformContext3D::GetCommandBuffer() { - return command_buffer_; -} - -gpu::GpuControl* PlatformContext3D::GetGpuControl() { - return command_buffer_; -} - -int PlatformContext3D::GetCommandBufferRouteId() { - DCHECK(command_buffer_); - return command_buffer_->GetRouteID(); -} - -void PlatformContext3D::SetContextLostCallback(const base::Closure& task) { - context_lost_callback_ = task; -} - -void PlatformContext3D::SetOnConsoleMessageCallback( - const ConsoleMessageCallback& task) { - console_message_callback_ = task; -} - -void PlatformContext3D::Echo(const base::Closure& task) { - command_buffer_->Echo(task); -} - -void PlatformContext3D::OnContextLost() { - DCHECK(command_buffer_); - - if (!context_lost_callback_.is_null()) - context_lost_callback_.Run(); -} - -void PlatformContext3D::OnConsoleMessage(const std::string& msg, int id) { - DCHECK(command_buffer_); - - if (!console_message_callback_.is_null()) - console_message_callback_.Run(msg, id); -} - -} // namespace content diff --git a/chromium/content/renderer/pepper/pepper_platform_context_3d.h b/chromium/content/renderer/pepper/pepper_platform_context_3d.h deleted file mode 100644 index dcd42caa611..00000000000 --- a/chromium/content/renderer/pepper/pepper_platform_context_3d.h +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright (c) 2012 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 CONTENT_RENDERER_PEPPER_PEPPER_PLATFORM_CONTEXT_3D_H_ -#define CONTENT_RENDERER_PEPPER_PEPPER_PLATFORM_CONTEXT_3D_H_ - -#include "base/callback.h" -#include "base/compiler_specific.h" -#include "base/memory/ref_counted.h" -#include "base/memory/weak_ptr.h" -#include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h" -#include "gpu/command_buffer/common/mailbox.h" - -class CommandBufferProxy; -namespace gpu { -class CommandBuffer; -struct Mailbox; -} // namespace gpu - -namespace content { -class ContextProviderCommandBuffer; -class GpuChannelHost; - -class PlatformContext3D { - public: - explicit PlatformContext3D(); - ~PlatformContext3D(); - - // Initialize the context. - bool Init(const int32* attrib_list, PlatformContext3D* share_context); - - // Retrieves the mailbox name for the front buffer backing the context. - void GetBackingMailbox(gpu::Mailbox* mailbox, uint32* sync_point); - - // Inserts a new sync point to associate with the backing mailbox, that should - // be waited on before using the mailbox. - void InsertSyncPointForBackingMailbox(); - - // Returns true if the backing texture is always opaque. - bool IsOpaque(); - - // This call will return the address of the command buffer for this context - // that is constructed in Initialize() and is valid until this context is - // destroyed. - gpu::CommandBuffer* GetCommandBuffer(); - - // Returns the GpuControl class that services out-of-band messages. - gpu::GpuControl* GetGpuControl(); - - // If the command buffer is routed in the GPU channel, return the route id. - // Otherwise return 0. - int GetCommandBufferRouteId(); - - // Set an optional callback that will be invoked when the context is lost - // (e.g. gpu process crash). Takes ownership of the callback. - typedef base::Callback<void(const std::string&, int)> - ConsoleMessageCallback; - void SetContextLostCallback(const base::Closure& callback); - - // Set an optional callback that will be invoked when the GPU process - // sends a console message. - void SetOnConsoleMessageCallback(const ConsoleMessageCallback& callback); - - // Run the callback once the channel has been flushed. - void Echo(const base::Closure& task); - - private: - bool InitRaw(); - void OnContextLost(); - void OnConsoleMessage(const std::string& msg, int id); - - scoped_refptr<GpuChannelHost> channel_; - gpu::Mailbox mailbox_; - uint32 sync_point_; - bool has_alpha_; - CommandBufferProxyImpl* command_buffer_; - base::Closure context_lost_callback_; - ConsoleMessageCallback console_message_callback_; - base::WeakPtrFactory<PlatformContext3D> weak_ptr_factory_; -}; - -} // namespace content - -#endif // CONTENT_RENDERER_PEPPER_PEPPER_PLATFORM_CONTEXT_3D_H_ diff --git a/chromium/content/renderer/pepper/pepper_platform_video_capture.cc b/chromium/content/renderer/pepper/pepper_platform_video_capture.cc index dc58ad44e68..74eea87f684 100644 --- a/chromium/content/renderer/pepper/pepper_platform_video_capture.cc +++ b/chromium/content/renderer/pepper/pepper_platform_video_capture.cc @@ -12,7 +12,7 @@ #include "content/renderer/pepper/pepper_video_capture_host.h" #include "content/renderer/render_thread_impl.h" #include "content/renderer/render_view_impl.h" -#include "media/video/capture/video_capture_proxy.h" +#include "media/base/bind_to_current_loop.h" #include "url/gurl.h" namespace content { @@ -25,13 +25,10 @@ PepperPlatformVideoCapture::PepperPlatformVideoCapture( : render_view_(render_view), device_id_(device_id), session_id_(0), - handler_proxy_(new media::VideoCaptureHandlerProxy( - this, base::MessageLoopProxy::current())), handler_(handler), - video_capture_(NULL), - unbalanced_start_(false), pending_open_device_(false), - pending_open_device_id_(-1) { + pending_open_device_id_(-1), + weak_factory_(this) { // We need to open the device and obtain the label and session ID before // initializing. if (render_view_.get()) { @@ -39,57 +36,45 @@ PepperPlatformVideoCapture::PepperPlatformVideoCapture( PP_DEVICETYPE_DEV_VIDEOCAPTURE, device_id, document_url, - base::Bind(&PepperPlatformVideoCapture::OnDeviceOpened, this)); + base::Bind(&PepperPlatformVideoCapture::OnDeviceOpened, + weak_factory_.GetWeakPtr())); pending_open_device_ = true; } } void PepperPlatformVideoCapture::StartCapture( - media::VideoCapture::EventHandler* handler, const media::VideoCaptureParams& params) { - DCHECK(handler == handler_); - - if (unbalanced_start_) + DCHECK(thread_checker_.CalledOnValidThread()); + if (!stop_capture_cb_.is_null()) return; - - if (video_capture_) { - unbalanced_start_ = true; - AddRef(); // Will be balanced in OnRemoved(). - video_capture_->StartCapture(handler_proxy_.get(), params); - } -} - -void PepperPlatformVideoCapture::StopCapture( - media::VideoCapture::EventHandler* handler) { - DCHECK(handler == handler_); - if (!unbalanced_start_) + VideoCaptureImplManager* manager = + RenderThreadImpl::current()->video_capture_impl_manager(); + stop_capture_cb_ = + manager->StartCapture(session_id_, + params, + media::BindToCurrentLoop(base::Bind( + &PepperPlatformVideoCapture::OnStateUpdate, + weak_factory_.GetWeakPtr())), + media::BindToCurrentLoop(base::Bind( + &PepperPlatformVideoCapture::OnFrameReady, + weak_factory_.GetWeakPtr()))); +} + +void PepperPlatformVideoCapture::StopCapture() { + DCHECK(thread_checker_.CalledOnValidThread()); + if (stop_capture_cb_.is_null()) return; - - if (video_capture_) { - unbalanced_start_ = false; - video_capture_->StopCapture(handler_proxy_.get()); - } -} - -bool PepperPlatformVideoCapture::CaptureStarted() { - return handler_proxy_->state().started; -} - -int PepperPlatformVideoCapture::CaptureFrameRate() { - return handler_proxy_->state().frame_rate; + stop_capture_cb_.Run(); + stop_capture_cb_.Reset(); } void PepperPlatformVideoCapture::DetachEventHandler() { handler_ = NULL; - StopCapture(NULL); - - if (video_capture_) { - VideoCaptureImplManager* manager = - RenderThreadImpl::current()->video_capture_impl_manager(); - manager->RemoveDevice(session_id_, handler_proxy_.get()); - video_capture_ = NULL; + StopCapture(); + if (!release_device_cb_.is_null()) { + release_device_cb_.Run(); + release_device_cb_.Reset(); } - if (render_view_.get()) { if (!label_.empty()) { GetMediaDeviceManager()->CloseDevice(label_); @@ -103,53 +88,13 @@ void PepperPlatformVideoCapture::DetachEventHandler() { } } -void PepperPlatformVideoCapture::OnStarted(VideoCapture* capture) { - if (handler_) - handler_->OnStarted(capture); -} - -void PepperPlatformVideoCapture::OnStopped(VideoCapture* capture) { - if (handler_) - handler_->OnStopped(capture); -} - -void PepperPlatformVideoCapture::OnPaused(VideoCapture* capture) { - if (handler_) - handler_->OnPaused(capture); -} - -void PepperPlatformVideoCapture::OnError(VideoCapture* capture, - int error_code) { - if (handler_) - handler_->OnError(capture, error_code); -} - -void PepperPlatformVideoCapture::OnRemoved(VideoCapture* capture) { - if (handler_) - handler_->OnRemoved(capture); - - Release(); // Balance the AddRef() in StartCapture(). -} - -void PepperPlatformVideoCapture::OnFrameReady( - VideoCapture* capture, - const scoped_refptr<media::VideoFrame>& frame) { - if (handler_) - handler_->OnFrameReady(capture, frame); -} - PepperPlatformVideoCapture::~PepperPlatformVideoCapture() { - DCHECK(!video_capture_); + DCHECK(stop_capture_cb_.is_null()); + DCHECK(release_device_cb_.is_null()); DCHECK(label_.empty()); DCHECK(!pending_open_device_); } -void PepperPlatformVideoCapture::Initialize() { - VideoCaptureImplManager* manager = - RenderThreadImpl::current()->video_capture_impl_manager(); - video_capture_ = manager->AddDevice(session_id_, handler_proxy_.get()); -} - void PepperPlatformVideoCapture::OnDeviceOpened(int request_id, bool succeeded, const std::string& label) { @@ -161,15 +106,45 @@ void PepperPlatformVideoCapture::OnDeviceOpened(int request_id, label_ = label; session_id_ = GetMediaDeviceManager()->GetSessionID( PP_DEVICETYPE_DEV_VIDEOCAPTURE, label); - Initialize(); + VideoCaptureImplManager* manager = + RenderThreadImpl::current()->video_capture_impl_manager(); + release_device_cb_ = manager->UseDevice(session_id_); } if (handler_) - handler_->OnInitialized(this, succeeded); + handler_->OnInitialized(succeeded); +} + +void PepperPlatformVideoCapture::OnStateUpdate(VideoCaptureState state) { + if (!handler_) + return; + switch (state) { + case VIDEO_CAPTURE_STATE_STARTED: + handler_->OnStarted(); + break; + case VIDEO_CAPTURE_STATE_STOPPED: + handler_->OnStopped(); + break; + case VIDEO_CAPTURE_STATE_PAUSED: + handler_->OnPaused(); + break; + case VIDEO_CAPTURE_STATE_ERROR: + handler_->OnError(); + break; + default: + NOTREACHED() << "Unexpected state: " << state << "."; + } +} + +void PepperPlatformVideoCapture::OnFrameReady( + const scoped_refptr<media::VideoFrame>& frame, + const media::VideoCaptureFormat& format, + const base::TimeTicks& estimated_capture_time) { + if (handler_ && !stop_capture_cb_.is_null()) + handler_->OnFrameReady(frame, format); } -PepperMediaDeviceManager* - PepperPlatformVideoCapture::GetMediaDeviceManager() { +PepperMediaDeviceManager* PepperPlatformVideoCapture::GetMediaDeviceManager() { return PepperMediaDeviceManager::GetForRenderView(render_view_.get()); } diff --git a/chromium/content/renderer/pepper/pepper_platform_video_capture.h b/chromium/content/renderer/pepper/pepper_platform_video_capture.h index 609eaa34e11..e31b8c7d6a9 100644 --- a/chromium/content/renderer/pepper/pepper_platform_video_capture.h +++ b/chromium/content/renderer/pepper/pepper_platform_video_capture.h @@ -8,65 +8,43 @@ #include <string> #include "base/basictypes.h" +#include "base/callback.h" #include "base/compiler_specific.h" #include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" -#include "media/video/capture/video_capture.h" +#include "base/threading/thread_checker.h" +#include "base/time/time.h" +#include "content/common/media/video_capture.h" #include "media/video/capture/video_capture_types.h" class GURL; -namespace media { -class VideoCaptureHandlerProxy; -} - namespace content { class PepperMediaDeviceManager; class PepperVideoCaptureHost; class RenderViewImpl; -class PepperPlatformVideoCapture - : public media::VideoCapture, - public base::RefCounted<PepperPlatformVideoCapture>, - public media::VideoCapture::EventHandler { +// This object must only be used on the thread it's constructed on. +class PepperPlatformVideoCapture { public: - PepperPlatformVideoCapture( - const base::WeakPtr<RenderViewImpl>& render_view, - const std::string& device_id, - const GURL& document_url, - PepperVideoCaptureHost* handler); + PepperPlatformVideoCapture(const base::WeakPtr<RenderViewImpl>& render_view, + const std::string& device_id, + const GURL& document_url, + PepperVideoCaptureHost* handler); + virtual ~PepperPlatformVideoCapture(); // Detaches the event handler and stops sending notifications to it. void DetachEventHandler(); - // media::VideoCapture implementation. - virtual void StartCapture( - media::VideoCapture::EventHandler* handler, - const media::VideoCaptureParams& params) OVERRIDE; - virtual void StopCapture(media::VideoCapture::EventHandler* handler) OVERRIDE; - virtual bool CaptureStarted() OVERRIDE; - virtual int CaptureFrameRate() OVERRIDE; - - // media::VideoCapture::EventHandler implementation - virtual void OnStarted(VideoCapture* capture) OVERRIDE; - virtual void OnStopped(VideoCapture* capture) OVERRIDE; - virtual void OnPaused(VideoCapture* capture) OVERRIDE; - virtual void OnError(VideoCapture* capture, int error_code) OVERRIDE; - virtual void OnRemoved(VideoCapture* capture) OVERRIDE; - virtual void OnFrameReady( - VideoCapture* capture, - const scoped_refptr<media::VideoFrame>& frame) OVERRIDE; - - protected: - friend class base::RefCounted<PepperPlatformVideoCapture>; - virtual ~PepperPlatformVideoCapture(); + void StartCapture(const media::VideoCaptureParams& params); + void StopCapture(); private: - void Initialize(); - - void OnDeviceOpened(int request_id, - bool succeeded, - const std::string& label); + void OnDeviceOpened(int request_id, bool succeeded, const std::string& label); + void OnStateUpdate(VideoCaptureState state); + void OnFrameReady(const scoped_refptr<media::VideoFrame>& frame, + const media::VideoCaptureFormat& format, + const base::TimeTicks& estimated_capture_time); PepperMediaDeviceManager* GetMediaDeviceManager(); @@ -75,22 +53,20 @@ class PepperPlatformVideoCapture std::string device_id_; std::string label_; int session_id_; - - scoped_ptr<media::VideoCaptureHandlerProxy> handler_proxy_; + base::Closure release_device_cb_; + base::Closure stop_capture_cb_; PepperVideoCaptureHost* handler_; - media::VideoCapture* video_capture_; - - // StartCapture() must be balanced by StopCapture(), otherwise this object - // will leak. - bool unbalanced_start_; - // Whether we have a pending request to open a device. We have to make sure // there isn't any pending request before this object goes away. bool pending_open_device_; int pending_open_device_id_; + base::ThreadChecker thread_checker_; + + base::WeakPtrFactory<PepperPlatformVideoCapture> weak_factory_; + DISALLOW_COPY_AND_ASSIGN(PepperPlatformVideoCapture); }; diff --git a/chromium/content/renderer/pepper/pepper_plugin_instance_impl.cc b/chromium/content/renderer/pepper/pepper_plugin_instance_impl.cc index 405d6ceb4c4..4aaad86e0db 100644 --- a/chromium/content/renderer/pepper/pepper_plugin_instance_impl.cc +++ b/chromium/content/renderer/pepper/pepper_plugin_instance_impl.cc @@ -16,11 +16,16 @@ #include "base/strings/utf_offset_string_conversions.h" #include "base/strings/utf_string_conversions.h" #include "base/time/time.h" +#include "cc/base/latency_info_swap_promise.h" #include "cc/layers/texture_layer.h" +#include "cc/trees/layer_tree_host.h" #include "content/common/content_constants_internal.h" +#include "content/common/input/web_input_event_traits.h" #include "content/public/common/content_switches.h" #include "content/public/common/page_zoom.h" #include "content/public/renderer/content_renderer_client.h" +#include "content/renderer/compositor_bindings/web_layer_impl.h" +#include "content/renderer/gpu/render_widget_compositor.h" #include "content/renderer/pepper/common.h" #include "content/renderer/pepper/content_decryptor_delegate.h" #include "content/renderer/pepper/event_conversion.h" @@ -31,17 +36,16 @@ #include "content/renderer/pepper/message_channel.h" #include "content/renderer/pepper/npapi_glue.h" #include "content/renderer/pepper/pepper_browser_connection.h" +#include "content/renderer/pepper/pepper_compositor_host.h" #include "content/renderer/pepper/pepper_file_ref_renderer_host.h" #include "content/renderer/pepper/pepper_graphics_2d_host.h" #include "content/renderer/pepper/pepper_in_process_router.h" -#include "content/renderer/pepper/pepper_platform_context_3d.h" #include "content/renderer/pepper/pepper_url_loader_host.h" #include "content/renderer/pepper/plugin_module.h" #include "content/renderer/pepper/plugin_object.h" #include "content/renderer/pepper/ppb_buffer_impl.h" #include "content/renderer/pepper/ppb_graphics_3d_impl.h" #include "content/renderer/pepper/ppb_image_data_impl.h" -#include "content/renderer/pepper/ppp_pdf.h" #include "content/renderer/pepper/renderer_ppapi_host_impl.h" #include "content/renderer/pepper/url_request_info_util.h" #include "content/renderer/pepper/url_response_info_util.h" @@ -52,9 +56,7 @@ #include "content/renderer/render_widget_fullscreen_pepper.h" #include "content/renderer/sad_plugin.h" #include "media/base/audio_hardware_config.h" -#include "ppapi/c/dev/ppb_find_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_text_input_dev.h" #include "ppapi/c/dev/ppp_zoom_dev.h" @@ -66,9 +68,14 @@ #include "ppapi/c/ppp_instance.h" #include "ppapi/c/ppp_messaging.h" #include "ppapi/c/ppp_mouse_lock.h" +#include "ppapi/c/private/ppb_find_private.h" +#include "ppapi/c/private/ppp_find_private.h" #include "ppapi/c/private/ppp_instance_private.h" +#include "ppapi/c/private/ppp_pdf.h" #include "ppapi/host/ppapi_host.h" #include "ppapi/proxy/ppapi_messages.h" +#include "ppapi/proxy/serialized_var.h" +#include "ppapi/proxy/uma_private_resource.h" #include "ppapi/proxy/url_loader_resource.h" #include "ppapi/shared_impl/ppapi_permissions.h" #include "ppapi/shared_impl/ppapi_preferences.h" @@ -79,6 +86,7 @@ #include "ppapi/shared_impl/ppp_instance_combined.h" #include "ppapi/shared_impl/resource.h" #include "ppapi/shared_impl/scoped_pp_resource.h" +#include "ppapi/shared_impl/scoped_pp_var.h" #include "ppapi/shared_impl/time_conversion.h" #include "ppapi/shared_impl/url_request_info_data.h" #include "ppapi/shared_impl/var.h" @@ -91,6 +99,7 @@ #include "skia/ext/platform_device.h" #include "third_party/WebKit/public/platform/WebCursorInfo.h" #include "third_party/WebKit/public/platform/WebGamepads.h" +#include "third_party/WebKit/public/platform/WebRect.h" #include "third_party/WebKit/public/platform/WebString.h" #include "third_party/WebKit/public/platform/WebURL.h" #include "third_party/WebKit/public/platform/WebURLError.h" @@ -100,8 +109,8 @@ #include "third_party/WebKit/public/web/WebDataSource.h" #include "third_party/WebKit/public/web/WebDocument.h" #include "third_party/WebKit/public/web/WebElement.h" -#include "third_party/WebKit/public/web/WebFrame.h" #include "third_party/WebKit/public/web/WebInputEvent.h" +#include "third_party/WebKit/public/web/WebLocalFrame.h" #include "third_party/WebKit/public/web/WebPluginContainer.h" #include "third_party/WebKit/public/web/WebPrintParams.h" #include "third_party/WebKit/public/web/WebPrintScalingOption.h" @@ -109,6 +118,7 @@ #include "third_party/WebKit/public/web/WebSecurityOrigin.h" #include "third_party/WebKit/public/web/WebUserGestureIndicator.h" #include "third_party/WebKit/public/web/WebView.h" +#include "third_party/khronos/GLES2/gl2.h" #include "third_party/skia/include/core/SkCanvas.h" #include "third_party/skia/include/core/SkRect.h" #include "ui/gfx/image/image_skia.h" @@ -117,7 +127,6 @@ #include "ui/gfx/rect_conversions.h" #include "ui/gfx/scoped_ns_graphics_context_save_gstate_mac.h" #include "v8/include/v8.h" -#include "webkit/renderer/compositor_bindings/web_layer_impl.h" #if defined(OS_CHROMEOS) #include "ui/events/keycodes/keyboard_codes_posix.h" @@ -143,6 +152,7 @@ using ppapi::PPB_View_Shared; using ppapi::PPP_Instance_Combined; using ppapi::Resource; using ppapi::ScopedPPResource; +using ppapi::ScopedPPVar; using ppapi::StringVar; using ppapi::TrackedCallback; using ppapi::thunk::EnterResourceNoLock; @@ -161,6 +171,7 @@ using blink::WebDocument; using blink::WebElement; using blink::WebFrame; using blink::WebInputEvent; +using blink::WebLocalFrame; using blink::WebPlugin; using blink::WebPluginContainer; using blink::WebPrintParams; @@ -180,12 +191,21 @@ namespace content { #if defined(OS_WIN) // Exported by pdf.dll -typedef bool (*RenderPDFPageToDCProc)( - const unsigned char* pdf_buffer, int buffer_size, int page_number, HDC dc, - int dpi_x, int dpi_y, int bounds_origin_x, int bounds_origin_y, - int bounds_width, int bounds_height, bool fit_to_bounds, - bool stretch_to_bounds, bool keep_aspect_ratio, bool center_in_bounds, - bool autorotate); +typedef bool (*RenderPDFPageToDCProc)(const unsigned char* pdf_buffer, + int buffer_size, + int page_number, + HDC dc, + int dpi_x, + int dpi_y, + int bounds_origin_x, + int bounds_origin_y, + int bounds_width, + int bounds_height, + bool fit_to_bounds, + bool stretch_to_bounds, + bool keep_aspect_ratio, + bool center_in_bounds, + bool autorotate); void DrawEmptyRectangle(HDC dc) { // TODO(sanjeevr): This is a temporary hack. If we output a JPEG @@ -201,22 +221,24 @@ void DrawEmptyRectangle(HDC dc) { namespace { // Check PP_TextInput_Type and ui::TextInputType are kept in sync. -COMPILE_ASSERT(int(ui::TEXT_INPUT_TYPE_NONE) == \ - int(PP_TEXTINPUT_TYPE_NONE), mismatching_enums); -COMPILE_ASSERT(int(ui::TEXT_INPUT_TYPE_TEXT) == \ - int(PP_TEXTINPUT_TYPE_TEXT), mismatching_enums); -COMPILE_ASSERT(int(ui::TEXT_INPUT_TYPE_PASSWORD) == \ - int(PP_TEXTINPUT_TYPE_PASSWORD), mismatching_enums); -COMPILE_ASSERT(int(ui::TEXT_INPUT_TYPE_SEARCH) == \ - int(PP_TEXTINPUT_TYPE_SEARCH), mismatching_enums); -COMPILE_ASSERT(int(ui::TEXT_INPUT_TYPE_EMAIL) == \ - int(PP_TEXTINPUT_TYPE_EMAIL), mismatching_enums); -COMPILE_ASSERT(int(ui::TEXT_INPUT_TYPE_NUMBER) == \ - int(PP_TEXTINPUT_TYPE_NUMBER), mismatching_enums); -COMPILE_ASSERT(int(ui::TEXT_INPUT_TYPE_TELEPHONE) == \ - int(PP_TEXTINPUT_TYPE_TELEPHONE), mismatching_enums); -COMPILE_ASSERT(int(ui::TEXT_INPUT_TYPE_URL) == \ - int(PP_TEXTINPUT_TYPE_URL), mismatching_enums); +COMPILE_ASSERT(int(ui::TEXT_INPUT_TYPE_NONE) == int(PP_TEXTINPUT_TYPE_NONE), + mismatching_enums); +COMPILE_ASSERT(int(ui::TEXT_INPUT_TYPE_TEXT) == int(PP_TEXTINPUT_TYPE_TEXT), + mismatching_enums); +COMPILE_ASSERT(int(ui::TEXT_INPUT_TYPE_PASSWORD) == + int(PP_TEXTINPUT_TYPE_PASSWORD), + mismatching_enums); +COMPILE_ASSERT(int(ui::TEXT_INPUT_TYPE_SEARCH) == int(PP_TEXTINPUT_TYPE_SEARCH), + mismatching_enums); +COMPILE_ASSERT(int(ui::TEXT_INPUT_TYPE_EMAIL) == int(PP_TEXTINPUT_TYPE_EMAIL), + mismatching_enums); +COMPILE_ASSERT(int(ui::TEXT_INPUT_TYPE_NUMBER) == int(PP_TEXTINPUT_TYPE_NUMBER), + mismatching_enums); +COMPILE_ASSERT(int(ui::TEXT_INPUT_TYPE_TELEPHONE) == + int(PP_TEXTINPUT_TYPE_TELEPHONE), + mismatching_enums); +COMPILE_ASSERT(int(ui::TEXT_INPUT_TYPE_URL) == int(PP_TEXTINPUT_TYPE_URL), + mismatching_enums); // The default text input type is to regard the plugin always accept text input. // This is for allowing users to use input methods even on completely-IME- @@ -225,15 +247,14 @@ COMPILE_ASSERT(int(ui::TEXT_INPUT_TYPE_URL) == \ // that they don't accept texts. const ui::TextInputType kPluginDefaultTextInputType = ui::TEXT_INPUT_TYPE_TEXT; -#define COMPILE_ASSERT_MATCHING_ENUM(webkit_name, np_name) \ - COMPILE_ASSERT(static_cast<int>(WebCursorInfo::webkit_name) \ - == static_cast<int>(np_name), \ - mismatching_enums) +#define COMPILE_ASSERT_MATCHING_ENUM(webkit_name, np_name) \ + COMPILE_ASSERT(static_cast<int>(WebCursorInfo::webkit_name) == \ + static_cast<int>(np_name), \ + mismatching_enums) -#define COMPILE_ASSERT_PRINT_SCALING_MATCHING_ENUM(webkit_name, pp_name) \ - COMPILE_ASSERT(static_cast<int>(webkit_name) \ - == static_cast<int>(pp_name), \ - mismatching_enums) +#define COMPILE_ASSERT_PRINT_SCALING_MATCHING_ENUM(webkit_name, pp_name) \ + COMPILE_ASSERT(static_cast<int>(webkit_name) == static_cast<int>(pp_name), \ + mismatching_enums) // <embed>/<object> attributes. const char kWidth[] = "width"; @@ -310,7 +331,8 @@ COMPILE_ASSERT_PRINT_SCALING_MATCHING_ENUM( blink::WebPrintScalingOptionFitToPrintableArea, PP_PRINTSCALINGOPTION_FIT_TO_PRINTABLE_AREA); COMPILE_ASSERT_PRINT_SCALING_MATCHING_ENUM( - blink::WebPrintScalingOptionSourceSize, PP_PRINTSCALINGOPTION_SOURCE_SIZE); + blink::WebPrintScalingOptionSourceSize, + PP_PRINTSCALINGOPTION_SOURCE_SIZE); // Sets |*security_origin| to be the WebKit security origin associated with the // document containing the given plugin instance. On success, returns true. If @@ -331,9 +353,9 @@ bool SecurityOriginForInstance(PP_Instance instance_id, // Convert the given vector to an array of C-strings. The strings in the // returned vector are only guaranteed valid so long as the vector of strings // is not modified. -scoped_ptr<const char*[]> StringVectorToArgArray( +scoped_ptr<const char* []> StringVectorToArgArray( const std::vector<std::string>& vector) { - scoped_ptr<const char*[]> array(new const char*[vector.size()]); + scoped_ptr<const char * []> array(new const char* [vector.size()]); for (size_t i = 0; i < vector.size(); ++i) array[i] = vector[i].c_str(); return array.Pass(); @@ -375,12 +397,10 @@ class PluginInstanceLockTarget : public MouseLockDispatcher::LockTarget { plugin_->OnLockMouseACK(succeeded); } - virtual void OnMouseLockLost() OVERRIDE { - plugin_->OnMouseLockLost(); - } + virtual void OnMouseLockLost() OVERRIDE { plugin_->OnMouseLockLost(); } - virtual bool HandleMouseLockedInputEvent( - const blink::WebMouseEvent &event) OVERRIDE { + virtual bool HandleMouseLockedInputEvent(const blink::WebMouseEvent& event) + OVERRIDE { plugin_->HandleMouseLockedInputEvent(event); return true; } @@ -389,6 +409,22 @@ class PluginInstanceLockTarget : public MouseLockDispatcher::LockTarget { PepperPluginInstanceImpl* plugin_; }; +void InitLatencyInfo(ui::LatencyInfo* new_latency, + const ui::LatencyInfo* old_latency, + blink::WebInputEvent::Type type, + int64 input_sequence) { + new_latency->AddLatencyNumber( + ui::INPUT_EVENT_LATENCY_BEGIN_PLUGIN_COMPONENT, + 0, + input_sequence); + new_latency->TraceEventType(WebInputEventTraits::GetName(type)); + if (old_latency) { + new_latency->CopyLatencyFrom(*old_latency, + ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT); + new_latency->CopyLatencyFrom(*old_latency, + ui::INPUT_EVENT_LATENCY_UI_COMPONENT); + } +} } // namespace @@ -404,28 +440,27 @@ PepperPluginInstanceImpl* PepperPluginInstanceImpl::Create( PPP_Instance_Combined::Create(get_plugin_interface_func); if (!ppp_instance_combined) return NULL; - return new PepperPluginInstanceImpl(render_frame, module, - ppp_instance_combined, container, - plugin_url); + return new PepperPluginInstanceImpl( + render_frame, module, ppp_instance_combined, container, plugin_url); } PepperPluginInstanceImpl::ExternalDocumentLoader::ExternalDocumentLoader() - : finished_loading_(false) { -} + : finished_loading_(false) {} -PepperPluginInstanceImpl::ExternalDocumentLoader::~ExternalDocumentLoader() { -} +PepperPluginInstanceImpl::ExternalDocumentLoader::~ExternalDocumentLoader() {} void PepperPluginInstanceImpl::ExternalDocumentLoader::ReplayReceivedData( WebURLLoaderClient* document_loader) { - for (std::list<std::string>::iterator it = data_.begin(); - it != data_.end(); ++it) { - document_loader->didReceiveData(NULL, it->c_str(), it->length(), - 0 /* encoded_data_length */); + for (std::list<std::string>::iterator it = data_.begin(); it != data_.end(); + ++it) { + document_loader->didReceiveData( + NULL, it->c_str(), it->length(), 0 /* encoded_data_length */); } if (finished_loading_) { - document_loader->didFinishLoading(NULL, - 0 /* finish_time */); + document_loader->didFinishLoading( + NULL, + 0 /* finish_time */, + blink::WebURLLoaderClient::kUnknownEncodedDataLength); } if (error_.get()) { document_loader->didFail(NULL, *error_); @@ -442,7 +477,8 @@ void PepperPluginInstanceImpl::ExternalDocumentLoader::didReceiveData( void PepperPluginInstanceImpl::ExternalDocumentLoader::didFinishLoading( WebURLLoader* loader, - double finish_time) { + double finish_time, + int64_t total_encoded_data_length) { DCHECK(!finished_loading_); finished_loading_ = true; } @@ -455,11 +491,9 @@ void PepperPluginInstanceImpl::ExternalDocumentLoader::didFail( } PepperPluginInstanceImpl::GamepadImpl::GamepadImpl() - : Resource(ppapi::Resource::Untracked()) { -} + : Resource(ppapi::Resource::Untracked()) {} -PepperPluginInstanceImpl::GamepadImpl::~GamepadImpl() { -} +PepperPluginInstanceImpl::GamepadImpl::~GamepadImpl() {} PPB_Gamepad_API* PepperPluginInstanceImpl::GamepadImpl::AsPPB_Gamepad_API() { return this; @@ -470,8 +504,7 @@ void PepperPluginInstanceImpl::GamepadImpl::Sample( PP_GamepadsSampleData* data) { blink::WebGamepads webkit_data; RenderThreadImpl::current()->SampleGamepads(&webkit_data); - ConvertWebKitGamepadData( - bit_cast<ppapi::WebKitGamepads>(webkit_data), data); + ConvertWebKitGamepadData(bit_cast<ppapi::WebKitGamepads>(webkit_data), data); } PepperPluginInstanceImpl::PepperPluginInstanceImpl( @@ -480,22 +513,24 @@ PepperPluginInstanceImpl::PepperPluginInstanceImpl( ppapi::PPP_Instance_Combined* instance_interface, WebPluginContainer* container, const GURL& plugin_url) - : render_frame_(render_frame), + : RenderFrameObserver(render_frame), + render_frame_(render_frame), module_(module), instance_interface_(instance_interface), pp_instance_(0), container_(container), layer_bound_to_fullscreen_(false), + layer_is_hardware_(false), plugin_url_(plugin_url), full_frame_(false), sent_initial_did_change_view_(false), bound_graphics_2d_platform_(NULL), + bound_compositor_(NULL), has_webkit_focus_(false), has_content_area_focus_(false), find_identifier_(-1), plugin_find_interface_(NULL), plugin_input_event_interface_(NULL), - plugin_messaging_interface_(NULL), plugin_mouse_lock_interface_(NULL), plugin_pdf_interface_(NULL), plugin_private_interface_(NULL), @@ -503,9 +538,9 @@ PepperPluginInstanceImpl::PepperPluginInstanceImpl( plugin_textinput_interface_(NULL), plugin_zoom_interface_(NULL), checked_for_plugin_input_event_interface_(false), - checked_for_plugin_messaging_interface_(false), checked_for_plugin_pdf_interface_(false), gamepad_impl_(new GamepadImpl()), + uma_private_impl_(NULL), plugin_print_interface_(NULL), plugin_graphics_3d_interface_(NULL), always_on_top_(false), @@ -527,6 +562,8 @@ PepperPluginInstanceImpl::PepperPluginInstanceImpl( npp_(new NPP_t), isolate_(v8::Isolate::GetCurrent()), is_deleted_(false), + last_input_number_(0), + is_tracking_latency_(false), view_change_weak_ptr_factory_(this), weak_factory_(this) { pp_instance_ = HostGlobals::Get()->AddInstance(this); @@ -535,7 +572,27 @@ PepperPluginInstanceImpl::PepperPluginInstanceImpl( module_->InstanceCreated(this); if (render_frame) { // NULL in tests - render_frame->PepperInstanceCreated(this); + render_frame->render_view()->PepperInstanceCreated(this); + // Bind a callback now so that we can inform the RenderViewImpl when we are + // destroyed. This works around a temporary problem stemming from work to + // move parts of RenderViewImpl in to RenderFrameImpl (see + // crbug.com/245126). If destruction happens in this order: + // 1) RenderFrameImpl + // 2) PepperPluginInstanceImpl + // 3) RenderViewImpl + // Then after 1), the PepperPluginInstanceImpl doesn't have any way to talk + // to the RenderViewImpl. But when the instance is destroyed, it still + // needs to inform the RenderViewImpl that it has gone away, otherwise + // between (2) and (3), the RenderViewImpl will still have the dead + // instance in its active set, and so might make calls on the deleted + // instance. See crbug.com/343576 for more information. Once the plugin + // calls move entirely from RenderViewImpl in to RenderFrameImpl, this + // can be a little bit simplified by instead making a direct call on + // RenderFrameImpl in the destructor (but only if render_frame_ is valid). + instance_deleted_callback_ = + base::Bind(&RenderViewImpl::PepperInstanceDeleted, + render_frame->render_view()->AsWeakPtr(), + base::Unretained(this)); view_data_.is_page_visible = !render_frame_->GetRenderWidget()->is_hidden(); // Set the initial focus. @@ -546,7 +603,7 @@ PepperPluginInstanceImpl::PepperPluginInstanceImpl( PepperBrowserConnection::Get(render_frame_); browser_connection->DidCreateInProcessInstance( pp_instance(), - render_frame_->render_view()->GetRoutingID(), + render_frame_->GetRoutingID(), container_->element().document().url(), GetPluginURL()); } @@ -571,14 +628,15 @@ PepperPluginInstanceImpl::~PepperPluginInstanceImpl() { PluginObjectSet plugin_object_copy; live_plugin_objects_.swap(plugin_object_copy); for (PluginObjectSet::iterator i = plugin_object_copy.begin(); - i != plugin_object_copy.end(); ++i) + i != plugin_object_copy.end(); + ++i) delete *i; if (TrackedCallback::IsPending(lock_mouse_callback_)) lock_mouse_callback_->Abort(); - if (render_frame_) - render_frame_->PepperInstanceDeleted(this); + if (!instance_deleted_callback_.is_null()) + instance_deleted_callback_.Run(); if (!module_->IsProxied() && render_frame_) { PepperBrowserConnection* browser_connection = @@ -606,6 +664,11 @@ PepperPluginInstanceImpl::~PepperPluginInstanceImpl() { void PepperPluginInstanceImpl::Delete() { is_deleted_ = true; + if (render_frame_ && + render_frame_->render_view()->plugin_find_handler() == this) { + render_frame_->render_view()->set_plugin_find_handler(NULL); + } + // Keep a reference on the stack. See NOTE above. scoped_refptr<PepperPluginInstanceImpl> ref(this); // Force the MessageChannel to release its "passthrough object" which should @@ -636,9 +699,7 @@ void PepperPluginInstanceImpl::Delete() { container_ = NULL; } -bool PepperPluginInstanceImpl::is_deleted() const { - return is_deleted_; -} +bool PepperPluginInstanceImpl::is_deleted() const { return is_deleted_; } void PepperPluginInstanceImpl::Paint(WebCanvas* canvas, const gfx::Rect& plugin_rect, @@ -664,19 +725,22 @@ void PepperPluginInstanceImpl::InvalidateRect(const gfx::Rect& rect) { else fullscreen_container_->InvalidateRect(rect); } else { - if (!container_ || - view_data_.rect.size.width == 0 || view_data_.rect.size.height == 0) + if (!container_ || view_data_.rect.size.width == 0 || + view_data_.rect.size.height == 0) return; // Nothing to do. if (rect.IsEmpty()) container_->invalidate(); else container_->invalidateRect(rect); } - if (texture_layer_) { + + cc::Layer* layer = + texture_layer_ ? texture_layer_.get() : compositor_layer_.get(); + if (layer) { if (rect.IsEmpty()) { - texture_layer_->SetNeedsDisplay(); + layer->SetNeedsDisplay(); } else { - texture_layer_->SetNeedsDisplayRect(rect); + layer->SetNeedsDisplayRect(rect); } } } @@ -684,7 +748,9 @@ void PepperPluginInstanceImpl::InvalidateRect(const gfx::Rect& rect) { void PepperPluginInstanceImpl::ScrollRect(int dx, int dy, const gfx::Rect& rect) { - if (texture_layer_) { + cc::Layer* layer = + texture_layer_ ? texture_layer_.get() : compositor_layer_.get(); + if (layer) { InvalidateRect(rect); } else if (fullscreen_container_) { fullscreen_container_->ScrollRect(dx, dy, rect); @@ -700,20 +766,16 @@ void PepperPluginInstanceImpl::ScrollRect(int dx, } } -static void IgnoreCallback(unsigned, bool) {} - void PepperPluginInstanceImpl::CommitBackingTexture() { if (!texture_layer_.get()) return; - PlatformContext3D* context = bound_graphics_3d_->platform_context(); gpu::Mailbox mailbox; uint32 sync_point = 0; - context->GetBackingMailbox(&mailbox, &sync_point); + bound_graphics_3d_->GetBackingMailbox(&mailbox, &sync_point); DCHECK(!mailbox.IsZero()); DCHECK_NE(sync_point, 0u); - texture_layer_->SetTextureMailbox( - cc::TextureMailbox(mailbox, sync_point), - cc::SingleReleaseCallback::Create(base::Bind(&IgnoreCallback))); + texture_layer_->SetTextureMailboxWithoutReleaseCallback( + cc::TextureMailbox(mailbox, GL_TEXTURE_2D, sync_point)); texture_layer_->SetNeedsDisplay(); } @@ -728,15 +790,21 @@ void PepperPluginInstanceImpl::InstanceCrashed() { BindGraphics(pp_instance(), 0); InvalidateRect(gfx::Rect()); - render_frame_->PluginCrashed(module_->path(), module_->GetPeerProcessId()); + if (content_decryptor_delegate_) { + content_decryptor_delegate_->InstanceCrashed(); + content_decryptor_delegate_.reset(); + } + + if (render_frame_) + render_frame_->PluginCrashed(module_->path(), module_->GetPeerProcessId()); UnSetAndDeleteLockTargetAdapter(); } static void SetGPUHistogram(const ppapi::Preferences& prefs, const std::vector<std::string>& arg_names, const std::vector<std::string>& arg_values) { - // Calculate a histogram to let us determine how likely people are to try to - // run Stage3D content on machines that have it blacklisted. +// Calculate a histogram to let us determine how likely people are to try to +// run Stage3D content on machines that have it blacklisted. #if defined(OS_WIN) bool needs_gpu = false; bool is_xp = base::win::GetVersion() <= base::win::VERSION_XP; @@ -758,8 +826,8 @@ static void SetGPUHistogram(const ppapi::Preferences& prefs, // 5 : No 3D content and GPU is not blacklisted on XP // 6 : 3D content but GPU is blacklisted on XP // 7 : 3D content and GPU is not blacklisted on XP - UMA_HISTOGRAM_ENUMERATION("Flash.UsesGPU", - is_xp * 4 + needs_gpu * 2 + prefs.is_webgl_supported, 8); + UMA_HISTOGRAM_ENUMERATION( + "Flash.UsesGPU", is_xp * 4 + needs_gpu * 2 + prefs.is_webgl_supported, 8); #endif } @@ -767,6 +835,8 @@ bool PepperPluginInstanceImpl::Initialize( const std::vector<std::string>& arg_names, const std::vector<std::string>& arg_values, bool full_frame) { + if (!render_frame_) + return false; message_channel_.reset(new MessageChannel(this)); full_frame_ = full_frame; @@ -774,20 +844,25 @@ bool PepperPluginInstanceImpl::Initialize( UpdateTouchEventRequest(); container_->setWantsWheelEvents(IsAcceptingWheelEvents()); - SetGPUHistogram(ppapi::Preferences( - render_frame_->render_view()->webkit_preferences()), - arg_names, arg_values); + SetGPUHistogram( + ppapi::Preferences(render_frame_->render_view()->webkit_preferences()), + arg_names, + arg_values); argn_ = arg_names; argv_ = arg_values; - scoped_ptr<const char*[]> argn_array(StringVectorToArgArray(argn_)); - scoped_ptr<const char*[]> argv_array(StringVectorToArgArray(argv_)); - bool success = PP_ToBool(instance_interface_->DidCreate(pp_instance(), - argn_.size(), - argn_array.get(), - argv_array.get())); - if (success) - message_channel_->StopQueueingJavaScriptMessages(); + scoped_ptr<const char * []> argn_array(StringVectorToArgArray(argn_)); + scoped_ptr<const char * []> argv_array(StringVectorToArgArray(argv_)); + bool success = PP_ToBool(instance_interface_->DidCreate( + pp_instance(), argn_.size(), argn_array.get(), argv_array.get())); + // If this is a plugin that hosts external plugins, we should delay messages + // so that the child plugin that's created later will receive all the + // messages. (E.g., NaCl trusted plugin starting a child NaCl app.) + // + // A host for external plugins will call ResetAsProxied later, at which point + // we can Start() the message_channel_. + if (success && (!module_->renderer_ppapi_host()->IsExternalPluginHost())) + message_channel_->Start(); return success; } @@ -847,20 +922,24 @@ bool PepperPluginInstanceImpl::HandleDocumentLoad( } bool PepperPluginInstanceImpl::SendCompositionEventToPlugin( - PP_InputEvent_Type type, const base::string16& text) { + PP_InputEvent_Type type, + const base::string16& text) { std::vector<blink::WebCompositionUnderline> empty; return SendCompositionEventWithUnderlineInformationToPlugin( - type, text, empty, static_cast<int>(text.size()), + type, + text, + empty, + static_cast<int>(text.size()), static_cast<int>(text.size())); } -bool PepperPluginInstanceImpl:: - SendCompositionEventWithUnderlineInformationToPlugin( - PP_InputEvent_Type type, - const base::string16& text, - const std::vector<blink::WebCompositionUnderline>& underlines, - int selection_start, - int selection_end) { +bool +PepperPluginInstanceImpl::SendCompositionEventWithUnderlineInformationToPlugin( + PP_InputEvent_Type type, + const base::string16& text, + const std::vector<blink::WebCompositionUnderline>& underlines, + int selection_start, + int selection_end) { // Keep a reference on the stack. See NOTE above. scoped_refptr<PepperPluginInstanceImpl> ref(this); @@ -874,8 +953,8 @@ bool PepperPluginInstanceImpl:: ppapi::InputEventData event; event.event_type = type; - event.event_time_stamp = ppapi::TimeTicksToPPTimeTicks( - base::TimeTicks::Now()); + event.event_time_stamp = + ppapi::TimeTicksToPPTimeTicks(base::TimeTicks::Now()); // Convert UTF16 text to UTF8 with offset conversion. std::vector<size_t> utf16_offsets; @@ -889,14 +968,16 @@ bool PepperPluginInstanceImpl:: event.character_text = base::UTF16ToUTF8AndAdjustOffsets(text, &utf8_offsets); // Set the converted selection range. - event.composition_selection_start = (utf8_offsets[0] == std::string::npos ? - event.character_text.size() : utf8_offsets[0]); - event.composition_selection_end = (utf8_offsets[1] == std::string::npos ? - event.character_text.size() : utf8_offsets[1]); + event.composition_selection_start = + (utf8_offsets[0] == std::string::npos ? event.character_text.size() + : utf8_offsets[0]); + event.composition_selection_end = + (utf8_offsets[1] == std::string::npos ? event.character_text.size() + : utf8_offsets[1]); // Set the converted segmentation points. // Be sure to add 0 and size(), and remove duplication or errors. - std::set<size_t> offset_set(utf8_offsets.begin()+2, utf8_offsets.end()); + std::set<size_t> offset_set(utf8_offsets.begin() + 2, utf8_offsets.end()); offset_set.insert(0); offset_set.insert(event.character_text.size()); offset_set.erase(std::string::npos); @@ -909,7 +990,7 @@ bool PepperPluginInstanceImpl:: std::vector<uint32_t>::iterator it = std::find(event.composition_segment_offsets.begin(), event.composition_segment_offsets.end(), - utf8_offsets[2*i+2]); + utf8_offsets[2 * i + 2]); if (it != event.composition_segment_offsets.end()) { event.composition_target_segment = it - event.composition_segment_offsets.begin(); @@ -952,7 +1033,10 @@ bool PepperPluginInstanceImpl::HandleCompositionUpdate( int selection_end) { return SendCompositionEventWithUnderlineInformationToPlugin( PP_INPUTEVENT_TYPE_IME_COMPOSITION_UPDATE, - text, underlines, selection_start, selection_end); + text, + underlines, + selection_start, + selection_end); } bool PepperPluginInstanceImpl::HandleCompositionEnd( @@ -962,8 +1046,7 @@ bool PepperPluginInstanceImpl::HandleCompositionEnd( } bool PepperPluginInstanceImpl::HandleTextInput(const base::string16& text) { - return SendCompositionEventToPlugin(PP_INPUTEVENT_TYPE_IME_TEXT, - text); + return SendCompositionEventToPlugin(PP_INPUTEVENT_TYPE_IME_TEXT, text); } void PepperPluginInstanceImpl::GetSurroundingText(base::string16* text, @@ -980,7 +1063,7 @@ void PepperPluginInstanceImpl::GetSurroundingText(base::string16* text, bool PepperPluginInstanceImpl::IsPluginAcceptingCompositionEvents() const { return (filtered_input_event_mask_ & PP_INPUTEVENT_CLASS_IME) || - (input_event_mask_ & PP_INPUTEVENT_CLASS_IME); + (input_event_mask_ & PP_INPUTEVENT_CLASS_IME); } gfx::Rect PepperPluginInstanceImpl::GetCaretBounds() const { @@ -988,7 +1071,8 @@ gfx::Rect PepperPluginInstanceImpl::GetCaretBounds() const { // If it is never set by the plugin, use the bottom left corner. return gfx::Rect(view_data_.rect.point.x, view_data_.rect.point.y + view_data_.rect.size.height, - 0, 0); + 0, + 0); } // TODO(kinaba) Take CSS transformation into accont. @@ -1006,6 +1090,8 @@ bool PepperPluginInstanceImpl::HandleInputEvent( WebCursorInfo* cursor_info) { TRACE_EVENT0("ppapi", "PepperPluginInstanceImpl::HandleInputEvent"); + if (!render_frame_) + return false; if (WebInputEvent::isMouseEventType(event.type)) { render_frame_->PepperDidReceiveMouseEvent(this); } @@ -1030,7 +1116,7 @@ bool PepperPluginInstanceImpl::HandleInputEvent( if ((filtered_input_event_mask_ & event_class) || (input_event_mask_ & event_class)) { // Actually send the event. - std::vector< ppapi::InputEventData > events; + std::vector<ppapi::InputEventData> events; CreateInputEventData(event, &events); // Allow the user gesture to be pending after the plugin handles the @@ -1044,15 +1130,27 @@ bool PepperPluginInstanceImpl::HandleInputEvent( pending_user_gesture_token_.setOutOfProcess(); } + const ui::LatencyInfo* current_event_latency_info = NULL; + if (render_frame_->GetRenderWidget()) { + current_event_latency_info = + render_frame_->GetRenderWidget()->current_event_latency_info(); + } + // Each input event may generate more than one PP_InputEvent. for (size_t i = 0; i < events.size(); i++) { + if (is_tracking_latency_) { + InitLatencyInfo(&events[i].latency_info, + current_event_latency_info, + event.type, + last_input_number_++); + } if (filtered_input_event_mask_ & event_class) events[i].is_filtered = true; else rv = true; // Unfiltered events are assumed to be handled. scoped_refptr<PPB_InputEvent_Shared> event_resource( - new PPB_InputEvent_Shared(ppapi::OBJECT_IS_IMPL, - pp_instance(), events[i])); + new PPB_InputEvent_Shared( + ppapi::OBJECT_IS_IMPL, pp_instance(), events[i])); rv |= PP_ToBool(plugin_input_event_interface_->HandleInputEvent( pp_instance(), event_resource->pp_resource())); @@ -1065,13 +1163,47 @@ bool PepperPluginInstanceImpl::HandleInputEvent( return rv; } -void PepperPluginInstanceImpl::HandleMessage(PP_Var message) { +void PepperPluginInstanceImpl::HandleMessage(ScopedPPVar message) { TRACE_EVENT0("ppapi", "PepperPluginInstanceImpl::HandleMessage"); - // Keep a reference on the stack. See NOTE above. - scoped_refptr<PepperPluginInstanceImpl> ref(this); - if (!LoadMessagingInterface()) + ppapi::proxy::HostDispatcher* dispatcher = + ppapi::proxy::HostDispatcher::GetForInstance(pp_instance()); + if (!dispatcher || (message.get().type == PP_VARTYPE_OBJECT)) { + // The dispatcher should always be valid, and MessageChannel should never + // send an 'object' var over PPP_Messaging. + NOTREACHED(); return; - plugin_messaging_interface_->HandleMessage(pp_instance(), message); + } + dispatcher->Send(new PpapiMsg_PPPMessaging_HandleMessage( + ppapi::API_ID_PPP_MESSAGING, + pp_instance(), + ppapi::proxy::SerializedVarSendInputShmem(dispatcher, message.get(), + pp_instance()))); +} + +bool PepperPluginInstanceImpl::HandleBlockingMessage(ScopedPPVar message, + ScopedPPVar* result) { + TRACE_EVENT0("ppapi", "PepperPluginInstanceImpl::HandleBlockingMessage"); + ppapi::proxy::HostDispatcher* dispatcher = + ppapi::proxy::HostDispatcher::GetForInstance(pp_instance()); + if (!dispatcher || (message.get().type == PP_VARTYPE_OBJECT)) { + // The dispatcher should always be valid, and MessageChannel should never + // send an 'object' var over PPP_Messaging. + NOTREACHED(); + return false; + } + ppapi::proxy::ReceiveSerializedVarReturnValue msg_reply; + bool was_handled = false; + dispatcher->Send(new PpapiMsg_PPPMessageHandler_HandleBlockingMessage( + ppapi::API_ID_PPP_MESSAGING, + pp_instance(), + ppapi::proxy::SerializedVarSendInputShmem(dispatcher, message.get(), + pp_instance()), + &msg_reply, + &was_handled)); + *result = ScopedPPVar(ScopedPPVar::PassRef(), msg_reply.Return(dispatcher)); + TRACE_EVENT0("ppapi", + "PepperPluginInstanceImpl::HandleBlockingMessage return."); + return was_handled; } PP_Var PepperPluginInstanceImpl::GetInstanceObject() { @@ -1102,8 +1234,13 @@ void PepperPluginInstanceImpl::ViewChanged( view_data_.rect = PP_FromGfxRect(position); view_data_.clip_rect = PP_FromGfxRect(clip); view_data_.device_scale = container_->deviceScaleFactor(); - view_data_.css_scale = container_->pageZoomFactor() * - container_->pageScaleFactor(); + view_data_.css_scale = + container_->pageZoomFactor() * container_->pageScaleFactor(); + + gfx::Size scroll_offset = + container_->element().document().frame()->scrollOffset(); + view_data_.scroll_offset = PP_MakePoint(scroll_offset.width(), + scroll_offset.height()); if (desired_fullscreen_state_ || view_data_.is_fullscreen) { WebElement element = container_->element(); @@ -1178,6 +1315,8 @@ void PepperPluginInstanceImpl::ViewInitiatedPaint() { bound_graphics_2d_platform_->ViewInitiatedPaint(); else if (bound_graphics_3d_.get()) bound_graphics_3d_->ViewInitiatedPaint(); + else if (bound_compositor_) + bound_compositor_->ViewInitiatedPaint(); } void PepperPluginInstanceImpl::ViewFlushedPaint() { @@ -1187,79 +1326,55 @@ void PepperPluginInstanceImpl::ViewFlushedPaint() { bound_graphics_2d_platform_->ViewFlushedPaint(); else if (bound_graphics_3d_.get()) bound_graphics_3d_->ViewFlushedPaint(); + else if (bound_compositor_) + bound_compositor_->ViewFlushedPaint(); } -bool PepperPluginInstanceImpl::GetBitmapForOptimizedPluginPaint( - const gfx::Rect& paint_bounds, - TransportDIB** dib, - gfx::Rect* location, - gfx::Rect* clip, - float* scale_factor) { - if (!always_on_top_) - return false; - if (!bound_graphics_2d_platform_ || - !bound_graphics_2d_platform_->IsAlwaysOpaque()) { - return false; - } +void PepperPluginInstanceImpl::SetSelectedText( + const base::string16& selected_text) { + selected_text_ = selected_text; +} - // 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. - PPB_ImageData_Impl* image_data = bound_graphics_2d_platform_->ImageData(); - // ImageDatas created by NaCl don't have a TransportDIB, so can't be - // optimized this way. - if (!image_data->GetTransportDIB()) - return false; +void PepperPluginInstanceImpl::SetLinkUnderCursor(const std::string& url) { + link_under_cursor_ = base::UTF8ToUTF16(url); +} - gfx::Point plugin_origin = PP_ToGfxPoint(view_data_.rect.point); - gfx::Vector2d plugin_offset = plugin_origin.OffsetFromOrigin(); - // Convert |paint_bounds| to be relative to the left-top corner of the plugin. - gfx::Rect relative_paint_bounds(paint_bounds); - relative_paint_bounds.Offset(-plugin_offset); - - gfx::Rect pixel_plugin_backing_store_rect( - 0, 0, image_data->width(), image_data->height()); - float scale = bound_graphics_2d_platform_->GetScale(); - gfx::Rect plugin_backing_store_rect = gfx::ToEnclosedRect( - gfx::ScaleRect(pixel_plugin_backing_store_rect, scale)); - - gfx::Rect clip_page = PP_ToGfxRect(view_data_.clip_rect); - gfx::Rect plugin_paint_rect = - gfx::IntersectRects(plugin_backing_store_rect, clip_page); - if (!plugin_paint_rect.Contains(relative_paint_bounds)) - return false; +void PepperPluginInstanceImpl::SetTextInputType(ui::TextInputType type) { + text_input_type_ = type; + render_frame_->PepperTextInputTypeChanged(this); +} - // Don't do optimized painting if the area to paint intersects with the - // cut-out rects, otherwise we will paint over them. - for (std::vector<gfx::Rect>::const_iterator iter = cut_outs_rects_.begin(); - iter != cut_outs_rects_.end(); ++iter) { - if (relative_paint_bounds.Intersects(*iter)) - return false; - } +void PepperPluginInstanceImpl::PostMessageToJavaScript(PP_Var message) { + message_channel_->PostMessageToJavaScript(message); +} - *dib = image_data->GetTransportDIB(); - plugin_backing_store_rect.Offset(plugin_offset); - *location = plugin_backing_store_rect; - clip_page.Offset(plugin_offset); - *clip = clip_page; - // The plugin scale factor is inverted, e.g. for a device scale factor of 2x - // the plugin scale factor is 0.5. - *scale_factor = 1.0 / scale; - return true; +int32_t PepperPluginInstanceImpl::RegisterMessageHandler( + PP_Instance instance, + void* user_data, + const PPP_MessageHandler_0_1* handler, + PP_Resource message_loop) { + // Not supported in-process. + NOTIMPLEMENTED(); + return PP_ERROR_FAILED; +} + +void PepperPluginInstanceImpl::UnregisterMessageHandler(PP_Instance instance) { + // Not supported in-process. + NOTIMPLEMENTED(); } base::string16 PepperPluginInstanceImpl::GetSelectedText(bool html) { // Keep a reference on the stack. See NOTE above. scoped_refptr<PepperPluginInstanceImpl> ref(this); if (!LoadSelectionInterface()) - return base::string16(); + return selected_text_; PP_Var rv = plugin_selection_interface_->GetSelectedText(pp_instance(), PP_FromBool(html)); StringVar* string = StringVar::FromPPVar(rv); base::string16 selection; if (string) - selection = UTF8ToUTF16(string->value()); + selection = base::UTF8ToUTF16(string->value()); // Release the ref the plugin transfered to us. HostGlobals::Get()->GetVarTracker()->ReleaseVar(rv); return selection; @@ -1269,17 +1384,25 @@ base::string16 PepperPluginInstanceImpl::GetLinkAtPosition( const gfx::Point& point) { // Keep a reference on the stack. See NOTE above. scoped_refptr<PepperPluginInstanceImpl> ref(this); - if (!LoadPdfInterface()) - return base::string16(); + if (!LoadPdfInterface()) { + // TODO(koz): Change the containing function to GetLinkUnderCursor(). We can + // return |link_under_cursor_| here because this is only ever called with + // the current mouse coordinates. + return link_under_cursor_; + } PP_Point p; p.x = point.x(); p.y = point.y(); PP_Var rv = plugin_pdf_interface_->GetLinkAtPosition(pp_instance(), p); + // If the plugin returns undefined for this function it has switched to + // providing us with the link under the cursor eagerly. + if (rv.type == PP_VARTYPE_UNDEFINED) + return link_under_cursor_; StringVar* string = StringVar::FromPPVar(rv); base::string16 link; if (string) - link = UTF8ToUTF16(string->value()); + link = base::UTF8ToUTF16(string->value()); // Release the ref the plugin transfered to us. PpapiGlobals::Get()->GetVarTracker()->ReleaseVar(rv); return link; @@ -1312,10 +1435,9 @@ bool PepperPluginInstanceImpl::StartFind(const base::string16& search_text, return false; find_identifier_ = identifier; return PP_ToBool( - plugin_find_interface_->StartFind( - pp_instance(), - UTF16ToUTF8(search_text.c_str()).c_str(), - PP_FromBool(case_sensitive))); + plugin_find_interface_->StartFind(pp_instance(), + base::UTF16ToUTF8(search_text).c_str(), + PP_FromBool(case_sensitive))); } void PepperPluginInstanceImpl::SelectFindResult(bool forward) { @@ -1336,10 +1458,11 @@ void PepperPluginInstanceImpl::StopFind() { } bool PepperPluginInstanceImpl::LoadFindInterface() { + if (!module_->permissions().HasPermission(ppapi::PERMISSION_PRIVATE)) + return false; if (!plugin_find_interface_) { - plugin_find_interface_ = - static_cast<const PPP_Find_Dev*>(module_->GetPluginInterface( - PPP_FIND_DEV_INTERFACE)); + plugin_find_interface_ = static_cast<const PPP_Find_Private*>( + module_->GetPluginInterface(PPP_FIND_PRIVATE_INTERFACE)); } return !!plugin_find_interface_; @@ -1348,28 +1471,16 @@ bool PepperPluginInstanceImpl::LoadFindInterface() { bool PepperPluginInstanceImpl::LoadInputEventInterface() { if (!checked_for_plugin_input_event_interface_) { checked_for_plugin_input_event_interface_ = true; - plugin_input_event_interface_ = - static_cast<const PPP_InputEvent*>(module_->GetPluginInterface( - PPP_INPUT_EVENT_INTERFACE)); + plugin_input_event_interface_ = static_cast<const PPP_InputEvent*>( + module_->GetPluginInterface(PPP_INPUT_EVENT_INTERFACE)); } return !!plugin_input_event_interface_; } -bool PepperPluginInstanceImpl::LoadMessagingInterface() { - if (!checked_for_plugin_messaging_interface_) { - checked_for_plugin_messaging_interface_ = true; - plugin_messaging_interface_ = - static_cast<const PPP_Messaging*>(module_->GetPluginInterface( - PPP_MESSAGING_INTERFACE)); - } - return !!plugin_messaging_interface_; -} - bool PepperPluginInstanceImpl::LoadMouseLockInterface() { if (!plugin_mouse_lock_interface_) { - plugin_mouse_lock_interface_ = - static_cast<const PPP_MouseLock*>(module_->GetPluginInterface( - PPP_MOUSELOCK_INTERFACE)); + plugin_mouse_lock_interface_ = static_cast<const PPP_MouseLock*>( + module_->GetPluginInterface(PPP_MOUSELOCK_INTERFACE)); } return !!plugin_mouse_lock_interface_; @@ -1378,9 +1489,8 @@ bool PepperPluginInstanceImpl::LoadMouseLockInterface() { bool PepperPluginInstanceImpl::LoadPdfInterface() { if (!checked_for_plugin_pdf_interface_) { checked_for_plugin_pdf_interface_ = true; - plugin_pdf_interface_ = - static_cast<const PPP_Pdf_1*>(module_->GetPluginInterface( - PPP_PDF_INTERFACE_1)); + plugin_pdf_interface_ = static_cast<const PPP_Pdf_1*>( + module_->GetPluginInterface(PPP_PDF_INTERFACE_1)); } return !!plugin_pdf_interface_; @@ -1406,8 +1516,8 @@ bool PepperPluginInstanceImpl::LoadPrivateInterface() { // // If this is *not* a NaCl plugin, original_module_ will never be set; we talk // to the "real" module. - scoped_refptr<PluginModule> module = original_module_ ? original_module_ : - module_; + scoped_refptr<PluginModule> module = + original_module_ ? original_module_ : module_; // Only check for the interface if the plugin has private permission. if (!module->permissions().HasPermission(ppapi::PERMISSION_PRIVATE)) return false; @@ -1421,18 +1531,16 @@ bool PepperPluginInstanceImpl::LoadPrivateInterface() { bool PepperPluginInstanceImpl::LoadSelectionInterface() { if (!plugin_selection_interface_) { - plugin_selection_interface_ = - static_cast<const PPP_Selection_Dev*>(module_->GetPluginInterface( - PPP_SELECTION_DEV_INTERFACE)); + plugin_selection_interface_ = static_cast<const PPP_Selection_Dev*>( + module_->GetPluginInterface(PPP_SELECTION_DEV_INTERFACE)); } return !!plugin_selection_interface_; } bool PepperPluginInstanceImpl::LoadTextInputInterface() { if (!plugin_textinput_interface_) { - plugin_textinput_interface_ = - static_cast<const PPP_TextInput_Dev*>(module_->GetPluginInterface( - PPP_TEXTINPUT_DEV_INTERFACE)); + plugin_textinput_interface_ = static_cast<const PPP_TextInput_Dev*>( + module_->GetPluginInterface(PPP_TEXTINPUT_DEV_INTERFACE)); } return !!plugin_textinput_interface_; @@ -1440,14 +1548,39 @@ bool PepperPluginInstanceImpl::LoadTextInputInterface() { bool PepperPluginInstanceImpl::LoadZoomInterface() { if (!plugin_zoom_interface_) { - plugin_zoom_interface_ = - static_cast<const PPP_Zoom_Dev*>(module_->GetPluginInterface( - PPP_ZOOM_DEV_INTERFACE)); + plugin_zoom_interface_ = static_cast<const PPP_Zoom_Dev*>( + module_->GetPluginInterface(PPP_ZOOM_DEV_INTERFACE)); } return !!plugin_zoom_interface_; } +void PepperPluginInstanceImpl::UpdateLayerTransform() { + if (!bound_graphics_2d_platform_ || !texture_layer_) { + // Currently the transform is only applied for Graphics2D. + return; + } + // Set the UV coordinates of the texture based on the size of the Graphics2D + // context. By default a texture gets scaled to the size of the layer. But + // if the size of the Graphics2D context doesn't match the size of the plugin + // then it will be incorrectly stretched. This also affects how the plugin + // is painted when it is being resized. If the Graphics2D contents are + // stretched when a plugin is resized while waiting for a new frame from the + // plugin to be rendered, then flickering behavior occurs as in + // crbug.com/353453. + gfx::SizeF graphics_2d_size_in_dip = + gfx::ScaleSize(bound_graphics_2d_platform_->Size(), + bound_graphics_2d_platform_->GetScale()); + gfx::Size plugin_size_in_dip(view_data_.rect.size.width, + view_data_.rect.size.height); + + texture_layer_->SetUV( + gfx::PointF(0.0f, 0.0f), + gfx::PointF( + plugin_size_in_dip.width() / graphics_2d_size_in_dip.width(), + plugin_size_in_dip.height() / graphics_2d_size_in_dip.height())); +} + bool PepperPluginInstanceImpl::PluginHasFocus() const { return flash_fullscreen_ || (has_webkit_focus_ && has_content_area_focus_); } @@ -1459,8 +1592,11 @@ void PepperPluginInstanceImpl::SendFocusChangeNotification() { // plugin behavior described at the NOTE above Delete(). scoped_refptr<PepperPluginInstanceImpl> ref(this); + if (!render_frame_) + return; + bool has_focus = PluginHasFocus(); - render_frame_->PepperFocusChanged(this, has_focus); + render_frame_->render_view()->PepperFocusChanged(this, has_focus); // instance_interface_ may have been cleared in Delete() if the // PepperWebPluginImpl is destroyed. @@ -1471,14 +1607,15 @@ void PepperPluginInstanceImpl::SendFocusChangeNotification() { void PepperPluginInstanceImpl::UpdateTouchEventRequest() { bool raw_touch = (filtered_input_event_mask_ & PP_INPUTEVENT_CLASS_TOUCH) || (input_event_mask_ & PP_INPUTEVENT_CLASS_TOUCH); - container_->requestTouchEventType(raw_touch ? - blink::WebPluginContainer::TouchEventRequestTypeRaw : - blink::WebPluginContainer::TouchEventRequestTypeSynthesizedMouse); + container_->requestTouchEventType( + raw_touch + ? blink::WebPluginContainer::TouchEventRequestTypeRaw + : blink::WebPluginContainer::TouchEventRequestTypeSynthesizedMouse); } bool PepperPluginInstanceImpl::IsAcceptingWheelEvents() const { return (filtered_input_event_mask_ & PP_INPUTEVENT_CLASS_WHEEL) || - (input_event_mask_ & PP_INPUTEVENT_CLASS_WHEEL); + (input_event_mask_ & PP_INPUTEVENT_CLASS_WHEEL); } void PepperPluginInstanceImpl::ScheduleAsyncDidChangeView() { @@ -1514,18 +1651,16 @@ void PepperPluginInstanceImpl::SendDidChangeView() { last_sent_view_data_ = view_data_; ScopedPPResource resource( ScopedPPResource::PassRef(), - (new PPB_View_Shared(ppapi::OBJECT_IS_IMPL, - pp_instance(), view_data_))->GetReference()); + (new PPB_View_Shared(ppapi::OBJECT_IS_IMPL, pp_instance(), view_data_)) + ->GetReference()); - if (bound_graphics_2d_platform_) - bound_graphics_2d_platform_->DidChangeView(view_data_); + UpdateLayerTransform(); // It's possible that Delete() has been called but the renderer hasn't // released its reference to this object yet. if (instance_interface_) { - instance_interface_->DidChangeView(pp_instance(), resource, - &view_data_.rect, - &view_data_.clip_rect); + instance_interface_->DidChangeView( + pp_instance(), resource, &view_data_.rect, &view_data_.clip_rect); } } @@ -1582,11 +1717,10 @@ int PepperPluginInstanceImpl::PrintBegin(const WebPrintParams& print_params) { print_settings.dpi = print_params.printerDPI; print_settings.orientation = PP_PRINTORIENTATION_NORMAL; print_settings.grayscale = PP_FALSE; - print_settings.print_scaling_option = static_cast<PP_PrintScalingOption_Dev>( - print_params.printScalingOption); + print_settings.print_scaling_option = + static_cast<PP_PrintScalingOption_Dev>(print_params.printScalingOption); print_settings.format = format; - num_pages = plugin_print_interface_->Begin(pp_instance(), - &print_settings); + num_pages = plugin_print_interface_->Begin(pp_instance(), &print_settings); if (!num_pages) return 0; current_print_settings_ = print_settings; @@ -1604,7 +1738,8 @@ bool PepperPluginInstanceImpl::PrintPage(int page_number, // The canvas only has a metafile on it for print preview. bool save_for_later = (printing::MetafileSkiaWrapper::GetMetafileFromCanvas(*canvas) != NULL); -#if defined(OS_MACOSX) || defined(OS_WIN) +#if defined(OS_MACOSX) || \ + (defined(OS_WIN) && !defined(WIN_PDF_METAFILE_FOR_PRINTING)) save_for_later = save_for_later && skia::IsPreviewMetafile(*canvas); #endif if (save_for_later) { @@ -1673,9 +1808,9 @@ void PepperPluginInstanceImpl::RotateView(WebPlugin::RotationType type) { if (!LoadPdfInterface()) return; PP_PrivatePageTransformType transform_type = - type == WebPlugin::RotationType90Clockwise ? - PP_PRIVATEPAGETRANSFORMTYPE_ROTATE_90_CW : - PP_PRIVATEPAGETRANSFORMTYPE_ROTATE_90_CCW; + type == WebPlugin::RotationType90Clockwise + ? PP_PRIVATEPAGETRANSFORMTYPE_ROTATE_90_CW + : PP_PRIVATEPAGETRANSFORMTYPE_ROTATE_90_CCW; plugin_pdf_interface_->Transform(pp_instance(), transform_type); // NOTE: plugin instance may have been deleted. } @@ -1698,9 +1833,11 @@ bool PepperPluginInstanceImpl::SetFullscreen(bool fullscreen) { if (fullscreen == IsFullscreenOrPending()) return false; - if (fullscreen && - !render_frame_->render_view()->renderer_preferences(). - plugin_fullscreen_allowed) + if (!render_frame_) + return false; + if (fullscreen && !render_frame_->render_view() + ->renderer_preferences() + .plugin_fullscreen_allowed) return false; // Check whether we are trying to switch while the state is in transition. @@ -1740,7 +1877,7 @@ void PepperPluginInstanceImpl::UpdateFlashFullscreenState( return; } - UpdateLayer(); + UpdateLayer(false); bool old_plugin_focus = PluginHasFocus(); flash_fullscreen_ = flash_fullscreen; @@ -1767,7 +1904,7 @@ bool PepperPluginInstanceImpl::IsViewAccelerated() { return false; WebDocument document = container_->element().document(); - WebFrame* frame = document.frame(); + WebLocalFrame* frame = document.frame(); if (!frame) return false; WebView* view = frame->view(); @@ -1794,9 +1931,8 @@ bool PepperPluginInstanceImpl::PrintPDFOutput(PP_Resource print_output, HMODULE pdf_module = GetModuleHandle(L"pdf.dll"); if (!pdf_module) return false; - RenderPDFPageToDCProc render_proc = - reinterpret_cast<RenderPDFPageToDCProc>( - GetProcAddress(pdf_module, "RenderPDFPageToDC")); + RenderPDFPageToDCProc render_proc = reinterpret_cast<RenderPDFPageToDCProc>( + GetProcAddress(pdf_module, "RenderPDFPageToDC")); if (!render_proc) return false; #endif // defined(OS_WIN) @@ -1813,7 +1949,7 @@ bool PepperPluginInstanceImpl::PrintPDFOutput(PP_Resource print_output, ret = metafile->InitFromData(mapper.data(), mapper.size()); #elif defined(OS_WIN) printing::Metafile* metafile = - printing::MetafileSkiaWrapper::GetMetafileFromCanvas(*canvas); + printing::MetafileSkiaWrapper::GetMetafileFromCanvas(*canvas); if (metafile) { // We only have a metafile when doing print preview, so we just want to // pass the PDF off to preview. @@ -1824,10 +1960,10 @@ bool PepperPluginInstanceImpl::PrintPDFOutput(PP_Resource print_output, HDC dc = skia::BeginPlatformPaint(canvas); DrawEmptyRectangle(dc); gfx::Size size_in_pixels; - size_in_pixels.set_width(printing::ConvertUnit( - current_print_settings_.printable_area.size.width, - static_cast<int>(printing::kPointsPerInch), - current_print_settings_.dpi)); + size_in_pixels.set_width( + printing::ConvertUnit(current_print_settings_.printable_area.size.width, + static_cast<int>(printing::kPointsPerInch), + current_print_settings_.dpi)); size_in_pixels.set_height(printing::ConvertUnit( current_print_settings_.printable_area.size.height, static_cast<int>(printing::kPointsPerInch), @@ -1842,10 +1978,10 @@ bool PepperPluginInstanceImpl::PrintPDFOutput(PP_Resource print_output, // original coordinates and we'll be able to print in full resolution. // Before playback we'll need to counter the scaling up that will happen // in the browser (printed_document_win.cc). - double dynamic_scale = gfx::CalculatePageScale(dc, size_in_pixels.width(), - size_in_pixels.height()); + double dynamic_scale = gfx::CalculatePageScale( + dc, size_in_pixels.width(), size_in_pixels.height()); double page_scale = static_cast<double>(printing::kPointsPerInch) / - static_cast<double>(current_print_settings_.dpi); + static_cast<double>(current_print_settings_.dpi); if (dynamic_scale < page_scale) { page_scale = dynamic_scale; @@ -1855,10 +1991,21 @@ bool PepperPluginInstanceImpl::PrintPDFOutput(PP_Resource print_output, gfx::ScaleDC(dc, page_scale); - ret = render_proc(static_cast<unsigned char*>(mapper.data()), mapper.size(), - 0, dc, current_print_settings_.dpi, - current_print_settings_.dpi, 0, 0, size_in_pixels.width(), - size_in_pixels.height(), true, false, true, true, true); + ret = render_proc(static_cast<unsigned char*>(mapper.data()), + mapper.size(), + 0, + dc, + current_print_settings_.dpi, + current_print_settings_.dpi, + 0, + 0, + size_in_pixels.width(), + size_in_pixels.height(), + true, + false, + true, + true, + true); skia::EndPlatformPaint(canvas); } #endif // defined(OS_WIN) @@ -1869,46 +2016,48 @@ bool PepperPluginInstanceImpl::PrintPDFOutput(PP_Resource print_output, #endif } -void PepperPluginInstanceImpl::UpdateLayer() { +void PepperPluginInstanceImpl::UpdateLayer(bool device_changed) { if (!container_) return; gpu::Mailbox mailbox; uint32 sync_point = 0; if (bound_graphics_3d_.get()) { - PlatformContext3D* context = bound_graphics_3d_->platform_context(); - context->GetBackingMailbox(&mailbox, &sync_point); + bound_graphics_3d_->GetBackingMailbox(&mailbox, &sync_point); DCHECK_EQ(mailbox.IsZero(), sync_point == 0); } bool want_3d_layer = !mailbox.IsZero(); - bool want_2d_layer = bound_graphics_2d_platform_ && - CommandLine::ForCurrentProcess()->HasSwitch( - switches::kEnableSoftwareCompositing); - bool want_layer = want_3d_layer || want_2d_layer; + bool want_2d_layer = !!bound_graphics_2d_platform_; + bool want_texture_layer = want_3d_layer || want_2d_layer; + bool want_compositor_layer = !!bound_compositor_; - if ((want_layer == !!texture_layer_.get()) && + if (!device_changed && + (want_texture_layer == !!texture_layer_.get()) && (want_3d_layer == layer_is_hardware_) && + (want_compositor_layer == !!compositor_layer_) && layer_bound_to_fullscreen_ == !!fullscreen_container_) { + UpdateLayerTransform(); return; } - if (texture_layer_) { + if (texture_layer_ || compositor_layer_) { if (!layer_bound_to_fullscreen_) container_->setWebLayer(NULL); else if (fullscreen_container_) fullscreen_container_->SetLayer(NULL); web_layer_.reset(); texture_layer_ = NULL; + compositor_layer_ = NULL; } - if (want_layer) { + + if (want_texture_layer) { bool opaque = false; if (want_3d_layer) { DCHECK(bound_graphics_3d_.get()); texture_layer_ = cc::TextureLayer::CreateForMailbox(NULL); opaque = bound_graphics_3d_->IsOpaque(); - texture_layer_->SetTextureMailbox( - cc::TextureMailbox(mailbox, sync_point), - cc::SingleReleaseCallback::Create(base::Bind(&IgnoreCallback))); + texture_layer_->SetTextureMailboxWithoutReleaseCallback( + cc::TextureMailbox(mailbox, GL_TEXTURE_2D, sync_point)); } else { DCHECK(bound_graphics_2d_platform_); texture_layer_ = cc::TextureLayer::CreateForMailbox(this); @@ -1916,24 +2065,29 @@ void PepperPluginInstanceImpl::UpdateLayer() { opaque = bound_graphics_2d_platform_->IsAlwaysOpaque(); texture_layer_->SetFlipped(false); } - web_layer_.reset(new webkit::WebLayerImpl(texture_layer_)); + + // Ignore transparency in fullscreen, since that's what Flash always + // wants to do, and that lets it not recreate a context if + // wmode=transparent was specified. + opaque = opaque || fullscreen_container_; + texture_layer_->SetContentsOpaque(opaque); + web_layer_.reset(new WebLayerImpl(texture_layer_)); + } else if (want_compositor_layer) { + compositor_layer_ = bound_compositor_->layer(); + web_layer_.reset(new WebLayerImpl(compositor_layer_)); + } + + if (web_layer_) { if (fullscreen_container_) { fullscreen_container_->SetLayer(web_layer_.get()); - // Ignore transparency in fullscreen, since that's what Flash always - // wants to do, and that lets it not recreate a context if - // wmode=transparent was specified. - texture_layer_->SetContentsOpaque(true); } else { container_->setWebLayer(web_layer_.get()); - texture_layer_->SetContentsOpaque(opaque); } } + layer_bound_to_fullscreen_ = !!fullscreen_container_; layer_is_hardware_ = want_3d_layer; -} - -unsigned PepperPluginInstanceImpl::PrepareTexture() { - return 0; + UpdateLayerTransform(); } bool PepperPluginInstanceImpl::PrepareTextureMailbox( @@ -1942,8 +2096,25 @@ bool PepperPluginInstanceImpl::PrepareTextureMailbox( bool use_shared_memory) { if (!bound_graphics_2d_platform_) return false; - return bound_graphics_2d_platform_->PrepareTextureMailbox( - mailbox, release_callback); + return bound_graphics_2d_platform_->PrepareTextureMailbox(mailbox, + release_callback); +} + +void PepperPluginInstanceImpl::OnDestruct() { render_frame_ = NULL; } + +void PepperPluginInstanceImpl::AddLatencyInfo( + const std::vector<ui::LatencyInfo>& latency_info) { + if (render_frame_ && render_frame_->GetRenderWidget()) { + RenderWidgetCompositor* compositor = + render_frame_->GetRenderWidget()->compositor(); + if (compositor) { + for (size_t i = 0; i < latency_info.size(); i++) { + scoped_ptr<cc::SwapPromise> swap_promise( + new cc::LatencyInfoSwapPromise(latency_info[i])); + compositor->QueueSwapPromise(swap_promise.Pass()); + } + } + } } void PepperPluginInstanceImpl::AddPluginObject(PluginObject* plugin_object) { @@ -2007,7 +2178,8 @@ void PepperPluginInstanceImpl::SimulateInputEvent( view_data_.rect.point.x + view_data_.rect.size.width / 2, view_data_.rect.point.y + view_data_.rect.size.height / 2); for (std::vector<linked_ptr<WebInputEvent> >::iterator it = events.begin(); - it != events.end(); ++it) { + it != events.end(); + ++it) { web_view->handleInputEvent(*it->get()); } } @@ -2024,8 +2196,10 @@ bool PepperPluginInstanceImpl::SimulateIMEEvent( SimulateImeSetCompositionEvent(input_event); break; case PP_INPUTEVENT_TYPE_IME_TEXT: + if (!render_frame_) + return false; render_frame_->SimulateImeConfirmComposition( - UTF8ToUTF16(input_event.character_text), gfx::Range()); + base::UTF8ToUTF16(input_event.character_text), gfx::Range()); break; default: return false; @@ -2035,6 +2209,9 @@ bool PepperPluginInstanceImpl::SimulateIMEEvent( void PepperPluginInstanceImpl::SimulateImeSetCompositionEvent( const InputEventData& input_event) { + if (!render_frame_) + return; + std::vector<size_t> offsets; offsets.push_back(input_event.composition_selection_start); offsets.push_back(input_event.composition_selection_end); @@ -2060,14 +2237,13 @@ void PepperPluginInstanceImpl::SimulateImeSetCompositionEvent( } ContentDecryptorDelegate* - PepperPluginInstanceImpl::GetContentDecryptorDelegate() { +PepperPluginInstanceImpl::GetContentDecryptorDelegate() { if (content_decryptor_delegate_) return content_decryptor_delegate_.get(); const PPP_ContentDecryptor_Private* plugin_decryption_interface = static_cast<const PPP_ContentDecryptor_Private*>( - module_->GetPluginInterface( - PPP_CONTENTDECRYPTOR_PRIVATE_INTERFACE)); + module_->GetPluginInterface(PPP_CONTENTDECRYPTOR_PRIVATE_INTERFACE)); if (!plugin_decryption_interface) return NULL; @@ -2090,10 +2266,14 @@ PP_Bool PepperPluginInstanceImpl::BindGraphics(PP_Instance instance, bound_graphics_2d_platform_->BindToInstance(NULL); bound_graphics_2d_platform_ = NULL; } + if (bound_compositor_) { + bound_compositor_->BindToInstance(NULL); + bound_compositor_ = NULL; + } // Special-case clearing the current device. if (!device) { - UpdateLayer(); + UpdateLayer(true); InvalidateRect(gfx::Rect()); return PP_TRUE; } @@ -2108,20 +2288,34 @@ PP_Bool PepperPluginInstanceImpl::BindGraphics(PP_Instance instance, RendererPpapiHost::GetForPPInstance(instance)->GetPpapiHost(); ppapi::host::ResourceHost* host = ppapi_host->GetResourceHost(device); PepperGraphics2DHost* graphics_2d = NULL; + PepperCompositorHost* compositor = NULL; if (host) { - if (host->IsGraphics2DHost()) + if (host->IsGraphics2DHost()) { graphics_2d = static_cast<PepperGraphics2DHost*>(host); - DLOG_IF(ERROR, !graphics_2d) << "Resource is not PepperGraphics2DHost."; + } else if (host->IsCompositorHost()) { + compositor = static_cast<PepperCompositorHost*>(host); + } else { + DLOG(ERROR) << + "Resource is not PepperCompositorHost or PepperGraphics2DHost."; + } } EnterResourceNoLock<PPB_Graphics3D_API> enter_3d(device, false); - PPB_Graphics3D_Impl* graphics_3d = enter_3d.succeeded() ? - static_cast<PPB_Graphics3D_Impl*>(enter_3d.object()) : NULL; - - if (graphics_2d) { + PPB_Graphics3D_Impl* graphics_3d = + enter_3d.succeeded() + ? static_cast<PPB_Graphics3D_Impl*>(enter_3d.object()) + : NULL; + + if (compositor) { + if (compositor->BindToInstance(this)) { + bound_compositor_ = compositor; + UpdateLayer(true); + return PP_TRUE; + } + } else if (graphics_2d) { if (graphics_2d->BindToInstance(this)) { bound_graphics_2d_platform_ = graphics_2d; - UpdateLayer(); + UpdateLayer(true); return PP_TRUE; } } else if (graphics_3d) { @@ -2130,7 +2324,7 @@ PP_Bool PepperPluginInstanceImpl::BindGraphics(PP_Instance instance, if (graphics_3d->pp_instance() == pp_instance() && graphics_3d->BindToInstance(true)) { bound_graphics_3d_ = graphics_3d; - UpdateLayer(); + UpdateLayer(true); return PP_TRUE; } } @@ -2155,7 +2349,7 @@ PP_Var PepperPluginInstanceImpl::GetWindowObject(PP_Instance instance) { if (!container_) return PP_MakeUndefined(); - WebFrame* frame = container_->element().document().frame(); + WebLocalFrame* frame = container_->element().document().frame(); if (!frame) return PP_MakeUndefined(); @@ -2190,7 +2384,7 @@ PP_Var PepperPluginInstanceImpl::ExecuteScript(PP_Instance instance, np_script.UTF8Length = script_string->value().length(); // Get the current frame to pass to the evaluate function. - WebFrame* frame = container_->element().document().frame(); + WebLocalFrame* frame = container_->element().document().frame(); if (!frame) { try_catch.SetException("No frame to execute script in."); return PP_MakeUndefined(); @@ -2200,11 +2394,11 @@ PP_Var PepperPluginInstanceImpl::ExecuteScript(PP_Instance instance, bool ok = false; if (IsProcessingUserGesture()) { blink::WebScopedUserGesture user_gesture(CurrentUserGestureToken()); - ok = WebBindings::evaluate(NULL, frame->windowObject(), &np_script, - &result); + ok = + WebBindings::evaluate(NULL, frame->windowObject(), &np_script, &result); } else { - ok = WebBindings::evaluate(NULL, frame->windowObject(), &np_script, - &result); + ok = + WebBindings::evaluate(NULL, frame->windowObject(), &np_script, &result); } if (!ok) { // TryCatch doesn't catch the exceptions properly. Since this is only for @@ -2232,6 +2426,8 @@ uint32_t PepperPluginInstanceImpl::GetAudioHardwareOutputBufferSize( } PP_Var PepperPluginInstanceImpl::GetDefaultCharSet(PP_Instance instance) { + if (!render_frame_) + return PP_MakeUndefined(); return StringVar::StringToPPVar( render_frame_->render_view()->webkit_preferences().default_encoding); } @@ -2240,36 +2436,54 @@ PP_Var PepperPluginInstanceImpl::GetDefaultCharSet(PP_Instance instance) { // PPP_ContentDecryptor_Private calls made on |content_decryptor_delegate_|. // Therefore, |content_decryptor_delegate_| must have been initialized when // the following methods are called. -void PepperPluginInstanceImpl::SessionCreated(PP_Instance instance, - uint32_t session_id, - PP_Var web_session_id_var) { - content_decryptor_delegate_->OnSessionCreated(session_id, web_session_id_var); +void PepperPluginInstanceImpl::PromiseResolved(PP_Instance instance, + uint32 promise_id) { + content_decryptor_delegate_->OnPromiseResolved(promise_id); +} + +void PepperPluginInstanceImpl::PromiseResolvedWithSession( + PP_Instance instance, + uint32 promise_id, + PP_Var web_session_id_var) { + content_decryptor_delegate_->OnPromiseResolvedWithSession(promise_id, + web_session_id_var); +} + +void PepperPluginInstanceImpl::PromiseRejected( + PP_Instance instance, + uint32 promise_id, + PP_CdmExceptionCode exception_code, + uint32 system_code, + PP_Var error_description_var) { + content_decryptor_delegate_->OnPromiseRejected( + promise_id, exception_code, system_code, error_description_var); } void PepperPluginInstanceImpl::SessionMessage(PP_Instance instance, - uint32_t session_id, + PP_Var web_session_id_var, PP_Var message_var, - PP_Var destination_url) { + PP_Var destination_url_var) { content_decryptor_delegate_->OnSessionMessage( - session_id, message_var, destination_url); + web_session_id_var, message_var, destination_url_var); } void PepperPluginInstanceImpl::SessionReady(PP_Instance instance, - uint32_t session_id) { - content_decryptor_delegate_->OnSessionReady(session_id); + PP_Var web_session_id_var) { + content_decryptor_delegate_->OnSessionReady(web_session_id_var); } void PepperPluginInstanceImpl::SessionClosed(PP_Instance instance, - uint32_t session_id) { - content_decryptor_delegate_->OnSessionClosed(session_id); + PP_Var web_session_id_var) { + content_decryptor_delegate_->OnSessionClosed(web_session_id_var); } void PepperPluginInstanceImpl::SessionError(PP_Instance instance, - uint32_t session_id, - int32_t media_error, - int32_t system_code) { + PP_Var web_session_id_var, + PP_CdmExceptionCode exception_code, + uint32 system_code, + PP_Var error_description_var) { content_decryptor_delegate_->OnSessionError( - session_id, media_error, system_code); + web_session_id_var, exception_code, system_code, error_description_var); } void PepperPluginInstanceImpl::DeliverBlock( @@ -2303,7 +2517,6 @@ void PepperPluginInstanceImpl::DecoderResetDone( content_decryptor_delegate_->DecoderResetDone(decoder_type, request_id); } - void PepperPluginInstanceImpl::DeliverFrame( PP_Instance instance, PP_Resource decrypted_frame, @@ -2318,20 +2531,55 @@ void PepperPluginInstanceImpl::DeliverSamples( content_decryptor_delegate_->DeliverSamples(audio_frames, sample_info); } +void PepperPluginInstanceImpl::SetPluginToHandleFindRequests( + PP_Instance instance) { + if (!LoadFindInterface()) + return; + bool is_main_frame = + render_frame_ && + render_frame_->GetRenderView()->GetMainRenderFrame() == render_frame_; + if (!is_main_frame) + return; + render_frame_->render_view()->set_plugin_find_handler(this); +} + void PepperPluginInstanceImpl::NumberOfFindResultsChanged( PP_Instance instance, int32_t total, PP_Bool final_result) { DCHECK_NE(find_identifier_, -1); - render_frame_->reportFindInPageMatchCount( - find_identifier_, total, PP_ToBool(final_result)); + if (render_frame_) { + render_frame_->reportFindInPageMatchCount( + find_identifier_, total, PP_ToBool(final_result)); + } } void PepperPluginInstanceImpl::SelectedFindResultChanged(PP_Instance instance, int32_t index) { DCHECK_NE(find_identifier_, -1); - render_frame_->reportFindInPageSelection( - find_identifier_, index + 1, blink::WebRect()); + if (render_frame_) { + render_frame_->reportFindInPageSelection( + find_identifier_, index + 1, blink::WebRect()); + } +} + +void PepperPluginInstanceImpl::SetTickmarks(PP_Instance instance, + const PP_Rect* tickmarks, + uint32_t count) { + if (!render_frame_ || !render_frame_->GetWebFrame()) + return; + + blink::WebVector<blink::WebRect> tickmarks_converted( + static_cast<size_t>(count)); + for (uint32 i = 0; i < count; ++i) { + tickmarks_converted[i] = blink::WebRect(tickmarks[i].point.x, + tickmarks[i].point.y, + tickmarks[i].size.width, + tickmarks[i].size.height); + ; + } + blink::WebFrame* frame = render_frame_->GetWebFrame(); + frame->setTickmarks(tickmarks_converted); } PP_Bool PepperPluginInstanceImpl::IsFullscreen(PP_Instance instance) { @@ -2357,7 +2605,7 @@ ppapi::Resource* PepperPluginInstanceImpl::GetSingletonResource( switch (id) { case ppapi::BROKER_SINGLETON_ID: case ppapi::BROWSER_FONT_SINGLETON_ID: - case ppapi::EXTENSIONS_COMMON_SINGLETON_ID: + case ppapi::FILE_MAPPING_SINGLETON_ID: case ppapi::FLASH_CLIPBOARD_SINGLETON_ID: case ppapi::FLASH_FILE_SINGLETON_ID: case ppapi::FLASH_FULLSCREEN_SINGLETON_ID: @@ -2370,6 +2618,17 @@ ppapi::Resource* PepperPluginInstanceImpl::GetSingletonResource( return NULL; case ppapi::GAMEPAD_SINGLETON_ID: return gamepad_impl_.get(); + case ppapi::UMA_SINGLETON_ID: { + if (!uma_private_impl_) { + RendererPpapiHostImpl* host_impl = module_->renderer_ppapi_host(); + if (host_impl->in_process_router()) { + uma_private_impl_ = new ppapi::proxy::UMAPrivateResource( + host_impl->in_process_router()->GetPluginConnection(instance), + instance); + } + } + return uma_private_impl_.get(); + } } NOTREACHED(); @@ -2400,6 +2659,11 @@ void PepperPluginInstanceImpl::ClearInputEventRequest(PP_Instance instance, RequestInputEventsHelper(event_classes); } +void PepperPluginInstanceImpl::StartTrackingLatency(PP_Instance instance) { + if (module_->permissions().HasPermission(ppapi::PERMISSION_PRIVATE)) + is_tracking_latency_ = true; +} + void PepperPluginInstanceImpl::ZoomChanged(PP_Instance instance, double factor) { // We only want to tell the page to change its zoom if the whole page is the @@ -2412,19 +2676,21 @@ void PepperPluginInstanceImpl::ZoomChanged(PP_Instance instance, void PepperPluginInstanceImpl::ZoomLimitsChanged(PP_Instance instance, double minimum_factor, double maximum_factor) { + if (!render_frame_) + return; if (minimum_factor > maximum_factor) { NOTREACHED(); return; } double minimum_level = ZoomFactorToZoomLevel(minimum_factor); double maximum_level = ZoomFactorToZoomLevel(maximum_factor); - render_frame_->render_view()->webview()->zoomLimitsChanged( - minimum_level, maximum_level); + render_frame_->render_view()->webview()->zoomLimitsChanged(minimum_level, + maximum_level); } void PepperPluginInstanceImpl::PostMessage(PP_Instance instance, PP_Var message) { - message_channel_->PostMessageToJavaScript(message); + PostMessageToJavaScript(message); } PP_Bool PepperPluginInstanceImpl::SetCursor(PP_Instance instance, @@ -2457,8 +2723,7 @@ PP_Bool PepperPluginInstanceImpl::SetCursor(PP_Instance instance, const SkBitmap* bitmap = image_data->GetMappedBitmap(); // Make a deep copy, so that the cursor remains valid even after the original // image data gets freed. - if (!bitmap->copyTo(&custom_cursor->customImage.getSkBitmap(), - bitmap->config())) { + if (!bitmap->copyTo(&custom_cursor->customImage.getSkBitmap())) { return PP_FALSE; } @@ -2502,17 +2767,20 @@ void PepperPluginInstanceImpl::UnlockMouse(PP_Instance instance) { void PepperPluginInstanceImpl::SetTextInputType(PP_Instance instance, PP_TextInput_Type type) { + if (!render_frame_) + return; int itype = type; if (itype < 0 || itype > ui::TEXT_INPUT_TYPE_URL) itype = ui::TEXT_INPUT_TYPE_NONE; - text_input_type_ = static_cast<ui::TextInputType>(itype); - render_frame_->PepperTextInputTypeChanged(this); + SetTextInputType(static_cast<ui::TextInputType>(itype)); } void PepperPluginInstanceImpl::UpdateCaretPosition( PP_Instance instance, const PP_Rect& caret, const PP_Rect& bounding_box) { + if (!render_frame_) + return; text_input_caret_ = PP_ToGfxRect(caret); text_input_caret_bounds_ = PP_ToGfxRect(bounding_box); text_input_caret_set_ = true; @@ -2520,7 +2788,8 @@ void PepperPluginInstanceImpl::UpdateCaretPosition( } void PepperPluginInstanceImpl::CancelCompositionText(PP_Instance instance) { - render_frame_->PepperCancelComposition(this); + if (render_frame_) + render_frame_->PepperCancelComposition(this); } void PepperPluginInstanceImpl::SelectionChanged(PP_Instance instance) { @@ -2543,6 +2812,8 @@ void PepperPluginInstanceImpl::UpdateSurroundingText(PP_Instance instance, const char* text, uint32_t caret, uint32_t anchor) { + if (!render_frame_) + return; surrounding_text_ = text; selection_caret_ = caret; selection_anchor_ = anchor; @@ -2560,8 +2831,7 @@ PP_Var PepperPluginInstanceImpl::ResolveRelativeToDocument( WebElement plugin_element = container()->element(); GURL document_url = plugin_element.document().baseURL(); return ppapi::PPB_URLUtil_Shared::GenerateURLReturn( - document_url.Resolve(relative_string->value()), - components); + document_url.Resolve(relative_string->value()), components); } PP_Bool PepperPluginInstanceImpl::DocumentCanRequest(PP_Instance instance, @@ -2606,8 +2876,7 @@ PP_Var PepperPluginInstanceImpl::GetDocumentURL( PP_Var PepperPluginInstanceImpl::GetPluginInstanceURL( PP_Instance instance, PP_URLComponents_Dev* components) { - return ppapi::PPB_URLUtil_Shared::GenerateURLReturn(plugin_url_, - components); + return ppapi::PPB_URLUtil_Shared::GenerateURLReturn(plugin_url_, components); } PP_Var PepperPluginInstanceImpl::GetPluginReferrerURL( @@ -2617,7 +2886,7 @@ PP_Var PepperPluginInstanceImpl::GetPluginReferrerURL( if (!full_frame_) return ppapi::PPB_URLUtil_Shared::GenerateURLReturn(document.url(), components); - WebFrame* frame = document.frame(); + WebLocalFrame* frame = document.frame(); if (!frame) return PP_MakeUndefined(); const WebURLRequest& request = frame->dataSource()->originalRequest(); @@ -2635,9 +2904,6 @@ PP_ExternalPluginResult PepperPluginInstanceImpl::ResetAsProxied( original_module_ = module_; module_ = module; - // Don't send any messages to the plugin until DidCreate() has finished. - message_channel_->QueueJavaScriptMessages(); - // For NaCl instances, remember the NaCl plugin instance interface, so we // can shut it down by calling its DidDestroy in our Delete() method. original_instance_interface_.reset(instance_interface_.release()); @@ -2659,8 +2925,6 @@ PP_ExternalPluginResult PepperPluginInstanceImpl::ResetAsProxied( plugin_find_interface_ = NULL; plugin_input_event_interface_ = NULL; checked_for_plugin_input_event_interface_ = false; - plugin_messaging_interface_ = NULL; - checked_for_plugin_messaging_interface_ = false; plugin_mouse_lock_interface_ = NULL; plugin_pdf_interface_ = NULL; checked_for_plugin_pdf_interface_ = false; @@ -2670,12 +2934,12 @@ PP_ExternalPluginResult PepperPluginInstanceImpl::ResetAsProxied( plugin_zoom_interface_ = NULL; // Re-send the DidCreate event via the proxy. - scoped_ptr<const char*[]> argn_array(StringVectorToArgArray(argn_)); - scoped_ptr<const char*[]> argv_array(StringVectorToArgArray(argv_)); - if (!instance_interface_->DidCreate(pp_instance(), argn_.size(), - argn_array.get(), argv_array.get())) + scoped_ptr<const char * []> argn_array(StringVectorToArgArray(argn_)); + scoped_ptr<const char * []> argv_array(StringVectorToArgArray(argv_)); + if (!instance_interface_->DidCreate( + pp_instance(), argn_.size(), argn_array.get(), argv_array.get())) return PP_EXTERNAL_PLUGIN_ERROR_INSTANCE; - message_channel_->StopQueueingJavaScriptMessages(); + message_channel_->Start(); // Clear sent_initial_did_change_view_ and cancel any pending DidChangeView // event. This way, SendDidChangeView will send the "current" view @@ -2701,37 +2965,30 @@ PP_ExternalPluginResult PepperPluginInstanceImpl::ResetAsProxied( bool PepperPluginInstanceImpl::IsValidInstanceOf(PluginModule* module) { DCHECK(module); - return module == module_.get() || - module == original_module_.get(); + return module == module_.get() || module == original_module_.get(); } -NPP PepperPluginInstanceImpl::instanceNPP() { - return npp_.get(); -} +NPP PepperPluginInstanceImpl::instanceNPP() { return npp_.get(); } PepperPluginInstance* PepperPluginInstance::Get(PP_Instance instance_id) { return HostGlobals::Get()->GetInstance(instance_id); } RenderView* PepperPluginInstanceImpl::GetRenderView() { - return render_frame_->render_view(); + return render_frame_ ? render_frame_->render_view() : NULL; } blink::WebPluginContainer* PepperPluginInstanceImpl::GetContainer() { return container_; } -v8::Isolate* PepperPluginInstanceImpl::GetIsolate() const { - return isolate_; -} +v8::Isolate* PepperPluginInstanceImpl::GetIsolate() const { return isolate_; } ppapi::VarTracker* PepperPluginInstanceImpl::GetVarTracker() { return HostGlobals::Get()->GetVarTracker(); } -const GURL& PepperPluginInstanceImpl::GetPluginURL() { - return plugin_url_; -} +const GURL& PepperPluginInstanceImpl::GetPluginURL() { return plugin_url_; } base::FilePath PepperPluginInstanceImpl::GetModulePath() { return module_->path(); @@ -2744,14 +3001,12 @@ PP_Resource PepperPluginInstanceImpl::CreateImage(gfx::ImageSkia* source_image, if (image_skia_rep.is_null() || image_skia_rep.scale() != scale) return 0; - scoped_refptr<PPB_ImageData_Impl> image_data(new PPB_ImageData_Impl( - pp_instance(), - PPB_ImageData_Impl::PLATFORM)); - if (!image_data->Init( - PPB_ImageData_Impl::GetNativeImageDataFormat(), - image_skia_rep.pixel_width(), - image_skia_rep.pixel_height(), - false)) { + scoped_refptr<PPB_ImageData_Impl> image_data( + new PPB_ImageData_Impl(pp_instance(), PPB_ImageData_Impl::PLATFORM)); + if (!image_data->Init(PPB_ImageData_Impl::GetNativeImageDataFormat(), + image_skia_rep.pixel_width(), + image_skia_rep.pixel_height(), + false)) { return 0; } @@ -2781,14 +3036,13 @@ PP_ExternalPluginResult PepperPluginInstanceImpl::SwitchToOutOfProcessProxy( module_->CreateModuleForExternalPluginInstance()); RendererPpapiHostImpl* renderer_ppapi_host = - external_plugin_module->CreateOutOfProcessModule( - render_frame_, - file_path, - permissions, - channel_handle, - plugin_pid, - plugin_child_id, - true); + external_plugin_module->CreateOutOfProcessModule(render_frame_, + file_path, + permissions, + channel_handle, + plugin_pid, + plugin_child_id, + true); if (!renderer_ppapi_host) { DLOG(ERROR) << "CreateExternalPluginModule() failed"; return PP_EXTERNAL_PLUGIN_ERROR_MODULE; @@ -2806,13 +3060,13 @@ void PepperPluginInstanceImpl::DoSetCursor(WebCursorInfo* cursor) { cursor_.reset(cursor); if (fullscreen_container_) { fullscreen_container_->DidChangeCursor(*cursor); - } else { + } else if (render_frame_) { render_frame_->PepperDidChangeCursor(this, *cursor); } } bool PepperPluginInstanceImpl::IsFullPagePlugin() { - WebFrame* frame = container()->element().document().frame(); + WebLocalFrame* frame = container()->element().document().frame(); return frame->view()->mainFrame()->document().isPluginDocument(); } @@ -2828,9 +3082,11 @@ bool PepperPluginInstanceImpl::FlashSetFullscreen(bool fullscreen, if (fullscreen == FlashIsFullscreenOrPending()) return true; - if (fullscreen && - !render_frame_->render_view()->renderer_preferences(). - plugin_fullscreen_allowed) + if (!render_frame_) + return false; + if (fullscreen && !render_frame_->render_view() + ->renderer_preferences() + .plugin_fullscreen_allowed) return false; // Unbind current 2D or 3D graphics context. @@ -2839,7 +3095,7 @@ bool PepperPluginInstanceImpl::FlashSetFullscreen(bool fullscreen, DCHECK(!fullscreen_container_); fullscreen_container_ = render_frame_->CreatePepperFullscreenContainer(this); - UpdateLayer(); + UpdateLayer(false); } else { DCHECK(fullscreen_container_); fullscreen_container_->Destroy(); @@ -2872,17 +3128,15 @@ int32_t PepperPluginInstanceImpl::Navigate( return PP_ERROR_FAILED; WebDocument document = container_->element().document(); - WebFrame* frame = document.frame(); + WebLocalFrame* frame = document.frame(); if (!frame) return PP_ERROR_FAILED; ppapi::URLRequestInfoData completed_request = request; WebURLRequest web_request; - if (!CreateWebURLRequest(pp_instance_, - &completed_request, - frame, - &web_request)) { + if (!CreateWebURLRequest( + pp_instance_, &completed_request, frame, &web_request)) { return PP_ERROR_FAILED; } web_request.setFirstPartyForCookies(document.firstPartyForCookies()); @@ -2904,8 +3158,7 @@ int32_t PepperPluginInstanceImpl::Navigate( } // Only GETs and POSTs are supported. - if (web_request.httpMethod() != "GET" && - web_request.httpMethod() != "POST") + if (web_request.httpMethod() != "GET" && web_request.httpMethod() != "POST") return PP_ERROR_BADARGUMENT; WebString target_str = WebString::fromUTF8(target); @@ -2922,8 +3175,7 @@ int PepperPluginInstanceImpl::MakePendingFileRefRendererHost( scoped_ptr<ppapi::host::ResourceHost>(file_ref_host)); } -void PepperPluginInstanceImpl::SetEmbedProperty(PP_Var key, - PP_Var value) { +void PepperPluginInstanceImpl::SetEmbedProperty(PP_Var key, PP_Var value) { message_channel_->SetReadOnlyProperty(key, value); } @@ -2932,8 +3184,7 @@ bool PepperPluginInstanceImpl::CanAccessMainFrame() const { return false; blink::WebDocument containing_document = container_->element().document(); - if (!containing_document.frame() || - !containing_document.frame()->view() || + if (!containing_document.frame() || !containing_document.frame()->view() || !containing_document.frame()->view()->mainFrame()) { return false; } @@ -2955,6 +3206,8 @@ void PepperPluginInstanceImpl::KeepSizeAttributesBeforeFullscreen() { } void PepperPluginInstanceImpl::SetSizeAttributesForFullscreen() { + if (!render_frame_) + return; blink::WebScreenInfo info = render_frame_->GetRenderWidget()->screenInfo(); screen_size_for_fullscreen_ = gfx::Size(info.rect.width, info.rect.height); std::string width = StringPrintf("%d", screen_size_for_fullscreen_.width()); @@ -2997,7 +3250,7 @@ bool PepperPluginInstanceImpl::LockMouse() { } MouseLockDispatcher::LockTarget* - PepperPluginInstanceImpl::GetOrCreateLockTargetAdapter() { +PepperPluginInstanceImpl::GetOrCreateLockTargetAdapter() { if (!lock_target_.get()) { lock_target_.reset(new PluginInstanceLockTarget(this)); } @@ -3009,9 +3262,10 @@ MouseLockDispatcher* PepperPluginInstanceImpl::GetMouseLockDispatcher() { RenderWidgetFullscreenPepper* container = static_cast<RenderWidgetFullscreenPepper*>(fullscreen_container_); return container->mouse_lock_dispatcher(); - } else { + } else if (render_frame_) { return render_frame_->render_view()->mouse_lock_dispatcher(); } + return NULL; } void PepperPluginInstanceImpl::UnSetAndDeleteLockTargetAdapter() { @@ -3025,6 +3279,9 @@ void PepperPluginInstanceImpl::DidDataFromWebURLResponse( const blink::WebURLResponse& response, int pending_host_id, const ppapi::URLResponseInfoData& data) { + if (is_deleted_) + return; + RendererPpapiHostImpl* host_impl = module_->renderer_ppapi_host(); if (host_impl->in_process_router()) { @@ -3033,11 +3290,13 @@ void PepperPluginInstanceImpl::DidDataFromWebURLResponse( scoped_refptr<ppapi::proxy::URLLoaderResource> loader_resource( new ppapi::proxy::URLLoaderResource( host_impl->in_process_router()->GetPluginConnection(pp_instance()), - pp_instance(), pending_host_id, data)); + pp_instance(), + pending_host_id, + data)); PP_Resource loader_pp_resource = loader_resource->GetReference(); - if (!instance_interface_->HandleDocumentLoad( - pp_instance(), loader_pp_resource)) + if (!instance_interface_->HandleDocumentLoad(pp_instance(), + loader_pp_resource)) loader_resource->Close(); // We don't pass a ref into the plugin, if it wants one, it will have taken // an additional one. diff --git a/chromium/content/renderer/pepper/pepper_plugin_instance_impl.h b/chromium/content/renderer/pepper/pepper_plugin_instance_impl.h index 0ed093f9d52..ee66136bd4a 100644 --- a/chromium/content/renderer/pepper/pepper_plugin_instance_impl.h +++ b/chromium/content/renderer/pepper/pepper_plugin_instance_impl.h @@ -10,19 +10,20 @@ #include <string> #include <vector> +#include "base/callback.h" #include "base/compiler_specific.h" #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" #include "base/strings/string16.h" #include "cc/layers/content_layer_client.h" +#include "cc/layers/layer.h" #include "cc/layers/texture_layer_client.h" #include "content/common/content_export.h" #include "content/public/renderer/pepper_plugin_instance.h" +#include "content/public/renderer/render_frame_observer.h" #include "content/renderer/mouse_lock_dispatcher.h" -#include "content/renderer/pepper/ppp_pdf.h" #include "ppapi/c/dev/pp_cursor_type_dev.h" -#include "ppapi/c/dev/ppp_find_dev.h" #include "ppapi/c/dev/ppp_printing_dev.h" #include "ppapi/c/dev/ppp_selection_dev.h" #include "ppapi/c/dev/ppp_text_input_dev.h" @@ -36,10 +37,11 @@ #include "ppapi/c/ppb_input_event.h" #include "ppapi/c/ppp_graphics_3d.h" #include "ppapi/c/ppp_input_event.h" -#include "ppapi/c/ppp_messaging.h" #include "ppapi/c/ppp_mouse_lock.h" #include "ppapi/c/private/ppb_content_decryptor_private.h" +#include "ppapi/c/private/ppp_find_private.h" #include "ppapi/c/private/ppp_instance_private.h" +#include "ppapi/c/private/ppp_pdf.h" #include "ppapi/shared_impl/ppb_instance_shared.h" #include "ppapi/shared_impl/ppb_view_shared.h" #include "ppapi/shared_impl/singleton_resource_id.h" @@ -54,6 +56,7 @@ #include "third_party/WebKit/public/web/WebPlugin.h" #include "third_party/WebKit/public/web/WebUserGestureToken.h" #include "ui/base/ime/text_input_type.h" +#include "ui/events/latency_info.h" #include "ui/gfx/rect.h" #include "url/gurl.h" @@ -88,6 +91,7 @@ namespace ppapi { class Resource; struct InputEventData; struct PPP_Instance_Combined; +class ScopedPPVar; } namespace v8 { @@ -99,6 +103,7 @@ namespace content { class ContentDecryptorDelegate; class FullscreenContainer; class MessageChannel; +class PepperCompositorHost; class PepperGraphics2DHost; class PluginModule; class PluginObject; @@ -116,17 +121,17 @@ class CONTENT_EXPORT PepperPluginInstanceImpl : public base::RefCounted<PepperPluginInstanceImpl>, public NON_EXPORTED_BASE(PepperPluginInstance), public ppapi::PPB_Instance_Shared, - public NON_EXPORTED_BASE(cc::TextureLayerClient) { + public NON_EXPORTED_BASE(cc::TextureLayerClient), + public RenderFrameObserver { public: // Create and return a PepperPluginInstanceImpl object which supports the most // recent version of PPP_Instance possible by querying the given // get_plugin_interface function. If the plugin does not support any valid // PPP_Instance interface, returns NULL. - static PepperPluginInstanceImpl* Create( - RenderFrameImpl* render_frame, - PluginModule* module, - blink::WebPluginContainer* container, - const GURL& plugin_url); + static PepperPluginInstanceImpl* Create(RenderFrameImpl* render_frame, + PluginModule* module, + blink::WebPluginContainer* container, + const GURL& plugin_url); RenderFrameImpl* render_frame() const { return render_frame_; } PluginModule* module() const { return module_.get(); } MessageChannel& message_channel() { return *message_channel_; } @@ -185,7 +190,8 @@ class CONTENT_EXPORT PepperPluginInstanceImpl bool HandleInputEvent(const blink::WebInputEvent& event, blink::WebCursorInfo* cursor_info); PP_Var GetInstanceObject(); - void ViewChanged(const gfx::Rect& position, const gfx::Rect& clip, + void ViewChanged(const gfx::Rect& position, + const gfx::Rect& clip, const std::vector<gfx::Rect>& cut_outs_rects); // Handlers for composition events. @@ -217,17 +223,6 @@ class CONTENT_EXPORT PepperPluginInstanceImpl void ViewInitiatedPaint(); void ViewFlushedPaint(); - // If this plugin can be painted merely by copying the backing store to the - // screen, and the plugin bounds encloses the given paint bounds, returns - // true. In this case, the location, clipping, and ID of the backing store - // will be filled into the given output parameters. - bool GetBitmapForOptimizedPluginPaint( - const gfx::Rect& paint_bounds, - TransportDIB** dib, - gfx::Rect* dib_bounds, - gfx::Rect* clip, - float* scale_factor); - // Tracks all live PluginObjects. void AddPluginObject(PluginObject* plugin_object); void RemovePluginObject(PluginObject* plugin_object); @@ -305,8 +300,14 @@ class CONTENT_EXPORT PepperPluginInstanceImpl // already in fullscreen mode). bool SetFullscreen(bool fullscreen); - // Implementation of PPP_Messaging. - void HandleMessage(PP_Var message); + // Send the message on to the plugin. + void HandleMessage(ppapi::ScopedPPVar message); + + // Send the message synchronously to the plugin, and get a result. Returns + // true if the plugin handled the message, false if it didn't. The plugin + // won't handle the message if it has not registered a PPP_MessageHandler. + bool HandleBlockingMessage(ppapi::ScopedPPVar message, + ppapi::ScopedPPVar* result); // Returns true if the plugin is processing a user gesture. bool IsProcessingUserGesture(); @@ -329,8 +330,7 @@ class CONTENT_EXPORT PepperPluginInstanceImpl // Simulates an IME event at the level of RenderView which sends it back up to // the plugin as if it came from the user. bool SimulateIMEEvent(const ppapi::InputEventData& input_event); - void SimulateImeSetCompositionEvent( - const ppapi::InputEventData& input_event); + void SimulateImeSetCompositionEvent(const ppapi::InputEventData& input_event); // The document loader is valid when the plugin is "full-frame" and in this // case is non-NULL as long as the corresponding loader resource is alive. @@ -367,9 +367,13 @@ class CONTENT_EXPORT PepperPluginInstanceImpl virtual int32_t Navigate(const ppapi::URLRequestInfoData& request, const char* target, bool from_user_action) OVERRIDE; - virtual int MakePendingFileRefRendererHost( - const base::FilePath& path) OVERRIDE; + virtual int MakePendingFileRefRendererHost(const base::FilePath& path) + OVERRIDE; virtual void SetEmbedProperty(PP_Var key, PP_Var value) OVERRIDE; + virtual void SetSelectedText(const base::string16& selected_text) OVERRIDE; + virtual void SetLinkUnderCursor(const std::string& url) OVERRIDE; + virtual void SetTextInputType(ui::TextInputType type) OVERRIDE; + virtual void PostMessageToJavaScript(PP_Var message) OVERRIDE; // PPB_Instance_API implementation. virtual PP_Bool BindGraphics(PP_Instance instance, @@ -387,36 +391,46 @@ class CONTENT_EXPORT PepperPluginInstanceImpl virtual uint32_t GetAudioHardwareOutputBufferSize(PP_Instance instance) OVERRIDE; virtual PP_Var GetDefaultCharSet(PP_Instance instance) OVERRIDE; + virtual void SetPluginToHandleFindRequests(PP_Instance) OVERRIDE; virtual void NumberOfFindResultsChanged(PP_Instance instance, int32_t total, PP_Bool final_result) OVERRIDE; virtual void SelectedFindResultChanged(PP_Instance instance, int32_t index) OVERRIDE; + virtual void SetTickmarks(PP_Instance instance, + const PP_Rect* tickmarks, + uint32_t count) OVERRIDE; virtual PP_Bool IsFullscreen(PP_Instance instance) OVERRIDE; virtual PP_Bool SetFullscreen(PP_Instance instance, PP_Bool fullscreen) OVERRIDE; - virtual PP_Bool GetScreenSize(PP_Instance instance, PP_Size* size) - OVERRIDE; + virtual PP_Bool GetScreenSize(PP_Instance instance, PP_Size* size) OVERRIDE; virtual ppapi::Resource* GetSingletonResource(PP_Instance instance, - ppapi::SingletonResourceID id) OVERRIDE; + ppapi::SingletonResourceID id) + OVERRIDE; virtual int32_t RequestInputEvents(PP_Instance instance, uint32_t event_classes) OVERRIDE; virtual int32_t RequestFilteringInputEvents(PP_Instance instance, uint32_t event_classes) OVERRIDE; virtual void ClearInputEventRequest(PP_Instance instance, uint32_t event_classes) OVERRIDE; + virtual void StartTrackingLatency(PP_Instance instance) OVERRIDE; virtual void ZoomChanged(PP_Instance instance, double factor) OVERRIDE; virtual void ZoomLimitsChanged(PP_Instance instance, double minimum_factor, double maximum_factor) OVERRIDE; virtual void PostMessage(PP_Instance instance, PP_Var message) OVERRIDE; + virtual int32_t RegisterMessageHandler(PP_Instance instance, + void* user_data, + const PPP_MessageHandler_0_1* handler, + PP_Resource message_loop) OVERRIDE; + virtual void UnregisterMessageHandler(PP_Instance instance) OVERRIDE; virtual PP_Bool SetCursor(PP_Instance instance, PP_MouseCursor_Type type, PP_Resource image, const PP_Point* hot_spot) OVERRIDE; - virtual int32_t LockMouse( - PP_Instance instance, - scoped_refptr<ppapi::TrackedCallback> callback) OVERRIDE; + virtual int32_t LockMouse(PP_Instance instance, + scoped_refptr<ppapi::TrackedCallback> callback) + OVERRIDE; virtual void UnlockMouse(PP_Instance instance) OVERRIDE; virtual void SetTextInputType(PP_Instance instance, PP_TextInput_Type type) OVERRIDE; @@ -429,37 +443,46 @@ class CONTENT_EXPORT PepperPluginInstanceImpl const char* text, uint32_t caret, uint32_t anchor) OVERRIDE; - virtual PP_Var ResolveRelativeToDocument( - PP_Instance instance, - PP_Var relative, - PP_URLComponents_Dev* components) OVERRIDE; + virtual PP_Var ResolveRelativeToDocument(PP_Instance instance, + PP_Var relative, + PP_URLComponents_Dev* components) + OVERRIDE; virtual PP_Bool DocumentCanRequest(PP_Instance instance, PP_Var url) OVERRIDE; virtual PP_Bool DocumentCanAccessDocument(PP_Instance instance, PP_Instance target) OVERRIDE; virtual PP_Var GetDocumentURL(PP_Instance instance, PP_URLComponents_Dev* components) OVERRIDE; - virtual PP_Var GetPluginInstanceURL( - PP_Instance instance, - PP_URLComponents_Dev* components) OVERRIDE; - virtual PP_Var GetPluginReferrerURL( - PP_Instance instance, - PP_URLComponents_Dev* components) OVERRIDE; + virtual PP_Var GetPluginInstanceURL(PP_Instance instance, + PP_URLComponents_Dev* components) + OVERRIDE; + virtual PP_Var GetPluginReferrerURL(PP_Instance instance, + PP_URLComponents_Dev* components) + OVERRIDE; // PPB_ContentDecryptor_Private implementation. - virtual void SessionCreated(PP_Instance instance, - uint32_t session_id, - PP_Var web_session_id_var) OVERRIDE; + virtual void PromiseResolved(PP_Instance instance, + uint32 promise_id) OVERRIDE; + virtual void PromiseResolvedWithSession(PP_Instance instance, + uint32 promise_id, + PP_Var web_session_id_var) OVERRIDE; + virtual void PromiseRejected(PP_Instance instance, + uint32 promise_id, + PP_CdmExceptionCode exception_code, + uint32 system_code, + PP_Var error_description_var) OVERRIDE; virtual void SessionMessage(PP_Instance instance, - uint32_t session_id, - PP_Var message, - PP_Var destination_url) OVERRIDE; - virtual void SessionReady(PP_Instance instance, uint32_t session_id) OVERRIDE; + PP_Var web_session_id_var, + PP_Var message_var, + PP_Var destination_url_var) OVERRIDE; + virtual void SessionReady(PP_Instance instance, + PP_Var web_session_id_var) OVERRIDE; virtual void SessionClosed(PP_Instance instance, - uint32_t session_id) OVERRIDE; + PP_Var web_session_id_var) OVERRIDE; virtual void SessionError(PP_Instance instance, - uint32_t session_id, - int32_t media_error, - int32_t system_code) OVERRIDE; + PP_Var web_session_id_var, + PP_CdmExceptionCode exception_code, + uint32 system_code, + PP_Var error_description_var) OVERRIDE; virtual void DeliverBlock(PP_Instance instance, PP_Resource decrypted_block, const PP_DecryptedBlockInfo* block_info) OVERRIDE; @@ -476,10 +499,10 @@ class CONTENT_EXPORT PepperPluginInstanceImpl virtual void DeliverFrame(PP_Instance instance, PP_Resource decrypted_frame, const PP_DecryptedFrameInfo* frame_info) OVERRIDE; - virtual void DeliverSamples( - PP_Instance instance, - PP_Resource audio_frames, - const PP_DecryptedSampleInfo* sample_info) OVERRIDE; + virtual void DeliverSamples(PP_Instance instance, + PP_Resource audio_frames, + const PP_DecryptedSampleInfo* sample_info) + OVERRIDE; // Reset this instance as proxied. Assigns the instance a new module, resets // cached interfaces to point to the out-of-process proxy and re-sends @@ -500,12 +523,16 @@ class CONTENT_EXPORT PepperPluginInstanceImpl struct _NPP* instanceNPP(); // cc::TextureLayerClient implementation. - virtual unsigned PrepareTexture() OVERRIDE; virtual bool PrepareTextureMailbox( cc::TextureMailbox* mailbox, scoped_ptr<cc::SingleReleaseCallback>* release_callback, bool use_shared_memory) OVERRIDE; + // RenderFrameObserver + virtual void OnDestruct() OVERRIDE; + + void AddLatencyInfo(const std::vector<ui::LatencyInfo>& latency_info); + private: friend class base::RefCounted<PepperPluginInstanceImpl>; friend class PpapiUnittest; @@ -528,7 +555,8 @@ class CONTENT_EXPORT PepperPluginInstanceImpl int data_length, int encoded_data_length); virtual void didFinishLoading(blink::WebURLLoader* loader, - double finish_time); + double finish_time, + int64_t total_encoded_data_length); virtual void didFail(blink::WebURLLoader* loader, const blink::WebURLError& error); @@ -548,6 +576,7 @@ class CONTENT_EXPORT PepperPluginInstanceImpl virtual ppapi::thunk::PPB_Gamepad_API* AsPPB_Gamepad_API() OVERRIDE; virtual void Sample(PP_Instance instance, PP_GamepadsSampleData* data) OVERRIDE; + private: virtual ~GamepadImpl(); }; @@ -564,7 +593,6 @@ class CONTENT_EXPORT PepperPluginInstanceImpl bool LoadFindInterface(); bool LoadInputEventInterface(); - bool LoadMessagingInterface(); bool LoadMouseLockInterface(); bool LoadPdfInterface(); bool LoadPrintInterface(); @@ -573,6 +601,9 @@ class CONTENT_EXPORT PepperPluginInstanceImpl bool LoadTextInputInterface(); bool LoadZoomInterface(); + // Update any transforms that should be applied to the texture layer. + void UpdateLayerTransform(); + // Determines if we think the plugin has focus, both content area and webkit // (see has_webkit_focus_ below). bool PluginHasFocus() const; @@ -604,7 +635,10 @@ class CONTENT_EXPORT PepperPluginInstanceImpl // - we are not in Flash full-screen mode (or transitioning to it) // Otherwise it destroys the layer. // It does either operation lazily. - void UpdateLayer(); + // device_changed: true if the bound device has been changed, and + // UpdateLayer() will be forced to recreate the layer and attaches to the + // container. + void UpdateLayer(bool device_changed); // Internal helper function for PrintPage(). bool PrintPageHelper(PP_PrintPageNumberRange_Dev* page_ranges, @@ -614,9 +648,8 @@ class CONTENT_EXPORT PepperPluginInstanceImpl void DoSetCursor(blink::WebCursorInfo* cursor); // Internal helper functions for HandleCompositionXXX(). - bool SendCompositionEventToPlugin( - PP_InputEvent_Type type, - const base::string16& text); + bool SendCompositionEventToPlugin(PP_InputEvent_Type type, + const base::string16& text); bool SendCompositionEventWithUnderlineInformationToPlugin( PP_InputEvent_Type type, const base::string16& text, @@ -647,12 +680,12 @@ class CONTENT_EXPORT PepperPluginInstanceImpl MouseLockDispatcher::LockTarget* GetOrCreateLockTargetAdapter(); void UnSetAndDeleteLockTargetAdapter(); - void DidDataFromWebURLResponse( - const blink::WebURLResponse& response, - int pending_host_id, - const ppapi::URLResponseInfoData& data); + void DidDataFromWebURLResponse(const blink::WebURLResponse& response, + int pending_host_id, + const ppapi::URLResponseInfoData& data); RenderFrameImpl* render_frame_; + base::Closure instance_deleted_callback_; scoped_refptr<PluginModule> module_; scoped_ptr<ppapi::PPP_Instance_Combined> instance_interface_; // If this is the NaCl plugin, we create a new module when we switch to the @@ -665,6 +698,7 @@ class CONTENT_EXPORT PepperPluginInstanceImpl // NULL until we have been initialized. blink::WebPluginContainer* container_; + scoped_refptr<cc::Layer> compositor_layer_; scoped_refptr<cc::TextureLayer> texture_layer_; scoped_ptr<blink::WebLayer> web_layer_; bool layer_bound_to_fullscreen_; @@ -688,9 +722,10 @@ class CONTENT_EXPORT PepperPluginInstanceImpl // same as the default values. bool sent_initial_did_change_view_; - // The current device context for painting in 2D and 3D. + // The current device context for painting in 2D, 3D or compositor. scoped_refptr<PPB_Graphics3D_Impl> bound_graphics_3d_; PepperGraphics2DHost* bound_graphics_2d_platform_; + PepperCompositorHost* bound_compositor_; // 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 @@ -707,9 +742,8 @@ class CONTENT_EXPORT PepperPluginInstanceImpl // The plugin-provided interfaces. // When adding PPP interfaces, make sure to reset them in ResetAsProxied. - const PPP_Find_Dev* plugin_find_interface_; + const PPP_Find_Private* plugin_find_interface_; const PPP_InputEvent* plugin_input_event_interface_; - const PPP_Messaging* plugin_messaging_interface_; const PPP_MouseLock* plugin_mouse_lock_interface_; const PPP_Pdf* plugin_pdf_interface_; const PPP_Instance_Private* plugin_private_interface_; @@ -721,7 +755,6 @@ class CONTENT_EXPORT PepperPluginInstanceImpl // corresponding interfaces, so that we can ask only once. // When adding flags, make sure to reset them in ResetAsProxied. bool checked_for_plugin_input_event_interface_; - bool checked_for_plugin_messaging_interface_; bool checked_for_plugin_pdf_interface_; // This is only valid between a successful PrintBegin call and a PrintEnd @@ -747,6 +780,7 @@ class CONTENT_EXPORT PepperPluginInstanceImpl std::vector<PP_PrintPageNumberRange_Dev> ranges_; scoped_refptr<ppapi::Resource> gamepad_impl_; + scoped_refptr<ppapi::Resource> uma_private_impl_; // The plugin print interface. const PPP_Printing_Dev* plugin_print_interface_; @@ -843,6 +877,9 @@ class CONTENT_EXPORT PepperPluginInstanceImpl // calls and handles PPB_ContentDecryptor_Private calls. scoped_ptr<ContentDecryptorDelegate> content_decryptor_delegate_; + // The link currently under the cursor. + base::string16 link_under_cursor_; + // Dummy NPP value used when calling in to WebBindings, to allow the bindings // to correctly track NPObjects belonging to this plugin instance. scoped_ptr<struct _NPP> npp_; @@ -855,6 +892,13 @@ class CONTENT_EXPORT PepperPluginInstanceImpl bool is_deleted_; + // The text that is currently selected in the plugin. + base::string16 selected_text_; + + int64 last_input_number_; + + bool is_tracking_latency_; + // We use a weak ptr factory for scheduling DidChangeView events so that we // can tell whether updates are pending and consolidate them. When there's // already a weak ptr pending (HasWeakPtrs is true), code should update the diff --git a/chromium/content/renderer/pepper/pepper_plugin_registry.cc b/chromium/content/renderer/pepper/pepper_plugin_registry.cc index 5939ce16d23..11ec935c4e9 100644 --- a/chromium/content/renderer/pepper/pepper_plugin_registry.cc +++ b/chromium/content/renderer/pepper/pepper_plugin_registry.cc @@ -82,7 +82,8 @@ void PepperPluginRegistry::PluginModuleDead(PluginModule* dead_module) { // Modules aren't destroyed very often and there are normally at most a // couple of them. So for now we just do a brute-force search. for (NonOwningModuleMap::iterator i = live_modules_.begin(); - i != live_modules_.end(); ++i) { + i != live_modules_.end(); + ++i) { if (i->second == dead_module) { live_modules_.erase(i); return; @@ -100,8 +101,7 @@ PepperPluginRegistry::~PepperPluginRegistry() { DCHECK(live_modules_.empty()); } -PepperPluginRegistry::PepperPluginRegistry() { -} +PepperPluginRegistry::PepperPluginRegistry() {} void PepperPluginRegistry::Initialize() { ComputePepperPluginList(&plugin_list_); @@ -115,19 +115,20 @@ void PepperPluginRegistry::Initialize() { if (current.is_out_of_process) continue; // Out of process plugins need no special pre-initialization. - scoped_refptr<PluginModule> module = new PluginModule( - current.name, current.path, - ppapi::PpapiPermissions(current.permissions)); + scoped_refptr<PluginModule> module = + new PluginModule(current.name, + current.path, + ppapi::PpapiPermissions(current.permissions)); AddLiveModule(current.path, module.get()); if (current.is_internal) { if (!module->InitAsInternalPlugin(current.internal_entry_points)) { - DLOG(ERROR) << "Failed to load pepper module: " << current.path.value(); + DVLOG(1) << "Failed to load pepper module: " << current.path.value(); continue; } } else { // Preload all external plugins we're not running out of process. if (!module->InitAsLibrary(current.path)) { - DLOG(ERROR) << "Failed to load pepper module: " << current.path.value(); + DVLOG(1) << "Failed to load pepper module: " << current.path.value(); continue; } } diff --git a/chromium/content/renderer/pepper/pepper_proxy_channel_delegate_impl.cc b/chromium/content/renderer/pepper/pepper_proxy_channel_delegate_impl.cc index 738a3249cb7..f48e732eb84 100644 --- a/chromium/content/renderer/pepper/pepper_proxy_channel_delegate_impl.cc +++ b/chromium/content/renderer/pepper/pepper_proxy_channel_delegate_impl.cc @@ -9,8 +9,7 @@ namespace content { -PepperProxyChannelDelegateImpl::~PepperProxyChannelDelegateImpl() { -} +PepperProxyChannelDelegateImpl::~PepperProxyChannelDelegateImpl() {} base::MessageLoopProxy* PepperProxyChannelDelegateImpl::GetIPCMessageLoop() { // This is called only in the renderer so we know we have a child process. @@ -28,8 +27,7 @@ PepperProxyChannelDelegateImpl::ShareHandleWithRemote( base::PlatformFile handle, base::ProcessId remote_pid, bool should_close_source) { - return BrokerGetFileHandleForProcess(handle, remote_pid, - should_close_source); + return BrokerGetFileHandleForProcess(handle, remote_pid, should_close_source); } } // namespace content diff --git a/chromium/content/renderer/pepper/pepper_truetype_font_host.cc b/chromium/content/renderer/pepper/pepper_truetype_font_host.cc index ea9bb12b686..fc993935443 100644 --- a/chromium/content/renderer/pepper/pepper_truetype_font_host.cc +++ b/chromium/content/renderer/pepper/pepper_truetype_font_host.cc @@ -26,11 +26,9 @@ PepperTrueTypeFontHost::PepperTrueTypeFontHost( : ResourceHost(host->GetPpapiHost(), instance, resource), renderer_ppapi_host_(host), font_(PepperTrueTypeFont::Create(desc)), - weak_factory_(this) { -} + weak_factory_(this) {} -PepperTrueTypeFontHost::~PepperTrueTypeFontHost() { -} +PepperTrueTypeFontHost::~PepperTrueTypeFontHost() {} int32_t PepperTrueTypeFontHost::OnResourceMessageReceived( const IPC::Message& msg, @@ -38,14 +36,14 @@ int32_t PepperTrueTypeFontHost::OnResourceMessageReceived( if (!host()->permissions().HasPermission(ppapi::PERMISSION_DEV)) return PP_ERROR_FAILED; - IPC_BEGIN_MESSAGE_MAP(PepperTrueTypeFontHost, msg) + PPAPI_BEGIN_MESSAGE_MAP(PepperTrueTypeFontHost, msg) PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_TrueTypeFont_Describe, OnHostMsgDescribe) PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_TrueTypeFont_GetTableTags, OnHostMsgGetTableTags) PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_TrueTypeFont_GetTable, OnHostMsgGetTable) - IPC_END_MESSAGE_MAP() + PPAPI_END_MESSAGE_MAP() return PP_ERROR_FAILED; } @@ -69,9 +67,8 @@ int32_t PepperTrueTypeFontHost::OnHostMsgGetTableTags( std::vector<uint32_t> tags; ReplyMessageContext reply_context = context->MakeReplyMessageContext(); reply_context.params.set_result(font_->GetTableTags(&tags)); - host()->SendReply( - reply_context, - PpapiPluginMsg_TrueTypeFont_GetTableTagsReply(tags)); + host()->SendReply(reply_context, + PpapiPluginMsg_TrueTypeFont_GetTableTagsReply(tags)); return PP_OK_COMPLETIONPENDING; } diff --git a/chromium/content/renderer/pepper/pepper_truetype_font_linux.cc b/chromium/content/renderer/pepper/pepper_truetype_font_linux.cc index 53abf132057..c54a5148a1a 100644 --- a/chromium/content/renderer/pepper/pepper_truetype_font_linux.cc +++ b/chromium/content/renderer/pepper/pepper_truetype_font_linux.cc @@ -4,12 +4,13 @@ #include "base/compiler_specific.h" #include "base/memory/scoped_ptr.h" -#include "base/safe_numerics.h" +#include "base/numerics/safe_conversions.h" #include "base/sys_byteorder.h" #include "content/public/common/child_process_sandbox_support_linux.h" #include "content/renderer/pepper/pepper_truetype_font.h" #include "ppapi/c/dev/ppb_truetype_font_dev.h" #include "ppapi/c/pp_errors.h" +#include "ppapi/c/trusted/ppb_browser_font_trusted.h" namespace content { @@ -23,13 +24,14 @@ class PepperTrueTypeFontLinux : public PepperTrueTypeFont { // PepperTrueTypeFont overrides. virtual bool IsValid() OVERRIDE; - virtual int32_t Describe( - ppapi::proxy::SerializedTrueTypeFontDesc* desc) OVERRIDE; + virtual int32_t Describe(ppapi::proxy::SerializedTrueTypeFontDesc* desc) + OVERRIDE; virtual int32_t GetTableTags(std::vector<uint32_t>* tags) OVERRIDE; virtual int32_t GetTable(uint32_t table_tag, int32_t offset, int32_t max_data_length, std::string* data) OVERRIDE; + private: // Save creation parameters here and use these to implement Describe. // TODO(bbudge) Modify content API to return results of font matching and @@ -41,8 +43,8 @@ class PepperTrueTypeFontLinux : public PepperTrueTypeFont { }; PepperTrueTypeFontLinux::PepperTrueTypeFontLinux( - const ppapi::proxy::SerializedTrueTypeFontDesc& desc) : - desc_(desc) { + const ppapi::proxy::SerializedTrueTypeFontDesc& desc) + : desc_(desc) { // If no face is provided, convert family to the platform defaults. These // names should be mapped by FontConfig to an appropriate default font. if (desc_.family.empty()) { @@ -65,22 +67,19 @@ PepperTrueTypeFontLinux::PepperTrueTypeFontLinux( } } - fd_ = MatchFontWithFallback( - desc_.family.c_str(), - desc_.weight >= PP_TRUETYPEFONTWEIGHT_BOLD, - desc_.style & PP_TRUETYPEFONTSTYLE_ITALIC, - desc_.charset); + fd_ = MatchFontWithFallback(desc_.family.c_str(), + desc_.weight >= PP_TRUETYPEFONTWEIGHT_BOLD, + desc_.style & PP_TRUETYPEFONTSTYLE_ITALIC, + desc_.charset, + PP_BROWSERFONT_TRUSTED_FAMILY_DEFAULT); } -PepperTrueTypeFontLinux::~PepperTrueTypeFontLinux() { -} +PepperTrueTypeFontLinux::~PepperTrueTypeFontLinux() {} -bool PepperTrueTypeFontLinux::IsValid() { - return fd_ != -1; -} +bool PepperTrueTypeFontLinux::IsValid() { return fd_ != -1; } int32_t PepperTrueTypeFontLinux::Describe( - ppapi::proxy::SerializedTrueTypeFontDesc* desc) { + ppapi::proxy::SerializedTrueTypeFontDesc* desc) { *desc = desc_; return PP_OK; } @@ -118,7 +117,7 @@ int32_t PepperTrueTypeFontLinux::GetTableTags(std::vector<uint32_t>* tags) { uint8_t* entry = table_entries.get() + i * kTableEntrySize; uint32_t tag = static_cast<uint32_t>(entry[0]) << 24 | static_cast<uint32_t>(entry[1]) << 16 | - static_cast<uint32_t>(entry[2]) << 8 | + static_cast<uint32_t>(entry[2]) << 8 | static_cast<uint32_t>(entry[3]); (*tags)[i] = tag; } @@ -139,12 +138,14 @@ int32_t PepperTrueTypeFontLinux::GetTable(uint32_t table_tag, // Only retrieve as much as the caller requested. table_size = std::min(table_size, static_cast<size_t>(max_data_length)); data->resize(table_size); - if (!GetFontTable(fd_, table_tag, offset, + if (!GetFontTable(fd_, + table_tag, + offset, reinterpret_cast<uint8_t*>(&(*data)[0]), &table_size)) return PP_ERROR_FAILED; - return base::checked_numeric_cast<int32_t>(table_size); + return base::checked_cast<int32_t>(table_size); } } // namespace @@ -156,4 +157,3 @@ PepperTrueTypeFont* PepperTrueTypeFont::Create( } } // namespace content - diff --git a/chromium/content/renderer/pepper/pepper_truetype_font_mac.mm b/chromium/content/renderer/pepper/pepper_truetype_font_mac.mm index cb6339d41ef..19e74749506 100644 --- a/chromium/content/renderer/pepper/pepper_truetype_font_mac.mm +++ b/chromium/content/renderer/pepper/pepper_truetype_font_mac.mm @@ -12,7 +12,7 @@ #include "base/mac/foundation_util.h" #include "base/mac/scoped_cftyperef.h" #include "base/mac/scoped_nsautorelease_pool.h" -#include "base/safe_numerics.h" +#include "base/numerics/safe_conversions.h" #include "base/strings/sys_string_conversions.h" #include "base/sys_byteorder.h" #include "ppapi/c/dev/ppb_truetype_font_dev.h" @@ -293,10 +293,10 @@ int32_t PepperTrueTypeFontMac::GetTable(uint32_t table_tag, CFIndex table_size = CFDataGetLength(table_ref); CFIndex safe_offset = - std::min(base::checked_numeric_cast<CFIndex>(offset), table_size); + std::min(base::checked_cast<CFIndex>(offset), table_size); CFIndex safe_length = std::min(table_size - safe_offset, - base::checked_numeric_cast<CFIndex>(max_data_length)); + base::checked_cast<CFIndex>(max_data_length)); data->resize(safe_length); CFDataGetBytes(table_ref, CFRangeMake(safe_offset, safe_length), reinterpret_cast<UInt8*>(&(*data)[0])); @@ -341,7 +341,7 @@ int32_t PepperTrueTypeFontMac::GetEntireFont(int32_t offset, } // Calculate the rest of the header values. - uint16_t num_tables = base::checked_numeric_cast<uint16_t>(table_count); + uint16_t num_tables = base::checked_cast<uint16_t>(table_count); uint16_t entry_selector = 0; uint16_t search_range = 1; while (search_range < num_tables >> 1) { @@ -386,7 +386,7 @@ int32_t PepperTrueTypeFontMac::GetEntireFont(int32_t offset, } // Extract a substring if the caller specified an offset or max data length. - int32_t font_size = base::checked_numeric_cast<int32_t>(font.size()); + int32_t font_size = base::checked_cast<int32_t>(font.size()); int32_t safe_offset = std::min(offset, font_size); int32_t safe_length = std::min(font_size - safe_offset, max_data_length); if (safe_offset || safe_length != font_size) diff --git a/chromium/content/renderer/pepper/pepper_truetype_font_win.cc b/chromium/content/renderer/pepper/pepper_truetype_font_win.cc index 6d040445dd8..9b8cdb482b0 100644 --- a/chromium/content/renderer/pepper/pepper_truetype_font_win.cc +++ b/chromium/content/renderer/pepper/pepper_truetype_font_win.cc @@ -29,13 +29,14 @@ class PepperTrueTypeFontWin : public PepperTrueTypeFont { // PepperTrueTypeFont overrides. virtual bool IsValid() OVERRIDE; - virtual int32_t Describe( - ppapi::proxy::SerializedTrueTypeFontDesc* desc) OVERRIDE; + virtual int32_t Describe(ppapi::proxy::SerializedTrueTypeFontDesc* desc) + OVERRIDE; virtual int32_t GetTableTags(std::vector<uint32_t>* tags) OVERRIDE; virtual int32_t GetTable(uint32_t table_tag, int32_t offset, int32_t max_data_length, std::string* data) OVERRIDE; + private: DWORD GetFontData(HDC hdc, DWORD table, @@ -70,31 +71,28 @@ PepperTrueTypeFontWin::PepperTrueTypeFontWin( } // TODO(bbudge) support widths (extended, condensed). - font_ = CreateFont(0 /* height */, - 0 /* width */, - 0 /* escapement */, - 0 /* orientation */, + font_ = CreateFont(0 /* height */, + 0 /* width */, + 0 /* escapement */, + 0 /* orientation */, desc.weight, // our weight enum matches Windows. (desc.style & PP_TRUETYPEFONTSTYLE_ITALIC) ? 1 : 0, - 0 /* underline */, - 0 /* strikeout */, - desc.charset, // our charset enum matches Windows. + 0 /* underline */, + 0 /* strikeout */, + desc.charset, // our charset enum matches Windows. OUT_OUTLINE_PRECIS, // truetype and other outline fonts CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, pitch_and_family, - UTF8ToUTF16(desc.family).c_str()); + base::UTF8ToUTF16(desc.family).c_str()); } -PepperTrueTypeFontWin::~PepperTrueTypeFontWin() { -} +PepperTrueTypeFontWin::~PepperTrueTypeFontWin() {} -bool PepperTrueTypeFontWin::IsValid() { - return font_ != NULL; -} +bool PepperTrueTypeFontWin::IsValid() { return font_ != NULL; } int32_t PepperTrueTypeFontWin::Describe( - ppapi::proxy::SerializedTrueTypeFontDesc* desc) { + ppapi::proxy::SerializedTrueTypeFontDesc* desc) { LOGFONT font_desc; if (!::GetObject(font_, sizeof(LOGFONT), &font_desc)) return PP_ERROR_FAILED; @@ -117,12 +115,11 @@ int32_t PepperTrueTypeFontWin::Describe( break; } - desc->style = font_desc.lfItalic ? PP_TRUETYPEFONTSTYLE_ITALIC : - PP_TRUETYPEFONTSTYLE_NORMAL; + desc->style = font_desc.lfItalic ? PP_TRUETYPEFONTSTYLE_ITALIC + : PP_TRUETYPEFONTSTYLE_NORMAL; desc->weight = static_cast<PP_TrueTypeFontWeight_Dev>(font_desc.lfWeight); desc->width = PP_TRUETYPEFONTWIDTH_NORMAL; - desc->charset = - static_cast<PP_TrueTypeFontCharset_Dev>(font_desc.lfCharSet); + desc->charset = static_cast<PP_TrueTypeFontCharset_Dev>(font_desc.lfCharSet); // To get the face name, select the font and query for the name. GetObject // doesn't fill in the name field of the LOGFONT structure. @@ -131,7 +128,7 @@ int32_t PepperTrueTypeFontWin::Describe( base::win::ScopedSelectObject select_object(hdc, font_); WCHAR name[LF_FACESIZE]; GetTextFace(hdc, LF_FACESIZE, name); - desc->family = UTF16ToUTF8(name); + desc->family = base::UTF16ToUTF8(name); } return PP_OK; } @@ -184,9 +181,9 @@ int32_t PepperTrueTypeFontWin::GetTableTags(std::vector<uint32_t>* tags) { DWORD directory_size = num_tables * kDirectoryEntrySize; scoped_ptr<uint8_t[]> directory(new uint8_t[directory_size]); // Get the table directory entries after the font header. - if (GetFontData(hdc, 0 /* tag */, kFontHeaderSize, - directory.get(), - directory_size) == GDI_ERROR) + if (GetFontData( + hdc, 0 /* tag */, kFontHeaderSize, directory.get(), directory_size) == + GDI_ERROR) return PP_ERROR_FAILED; tags->resize(num_tables); @@ -194,7 +191,7 @@ int32_t PepperTrueTypeFontWin::GetTableTags(std::vector<uint32_t>* tags) { const uint8_t* entry = directory.get() + i * kDirectoryEntrySize; uint32_t tag = static_cast<uint32_t>(entry[0]) << 24 | static_cast<uint32_t>(entry[1]) << 16 | - static_cast<uint32_t>(entry[2]) << 8 | + static_cast<uint32_t>(entry[2]) << 8 | static_cast<uint32_t>(entry[3]); (*tags)[i] = tag; } @@ -220,13 +217,15 @@ int32_t PepperTrueTypeFontWin::GetTable(uint32_t table_tag, return PP_ERROR_FAILED; DWORD safe_offset = std::min(static_cast<DWORD>(offset), table_size); - DWORD safe_length = std::min(table_size - safe_offset, - static_cast<DWORD>(max_data_length)); + DWORD safe_length = + std::min(table_size - safe_offset, static_cast<DWORD>(max_data_length)); data->resize(safe_length); if (safe_length == 0) { table_size = 0; } else { - table_size = GetFontData(hdc, table_tag, safe_offset, + table_size = GetFontData(hdc, + table_tag, + safe_offset, reinterpret_cast<uint8_t*>(&(*data)[0]), safe_length); if (table_size == GDI_ERROR) diff --git a/chromium/content/renderer/pepper/pepper_url_loader_host.cc b/chromium/content/renderer/pepper/pepper_url_loader_host.cc index 178548ee718..7b01400c2e6 100644 --- a/chromium/content/renderer/pepper/pepper_url_loader_host.cc +++ b/chromium/content/renderer/pepper/pepper_url_loader_host.cc @@ -21,13 +21,13 @@ #include "third_party/WebKit/public/platform/WebURLResponse.h" #include "third_party/WebKit/public/web/WebDocument.h" #include "third_party/WebKit/public/web/WebElement.h" -#include "third_party/WebKit/public/web/WebFrame.h" #include "third_party/WebKit/public/web/WebKit.h" +#include "third_party/WebKit/public/web/WebLocalFrame.h" #include "third_party/WebKit/public/web/WebPluginContainer.h" #include "third_party/WebKit/public/web/WebSecurityOrigin.h" #include "third_party/WebKit/public/web/WebURLLoaderOptions.h" -using blink::WebFrame; +using blink::WebLocalFrame; using blink::WebString; using blink::WebURL; using blink::WebURLError; @@ -104,20 +104,17 @@ PepperURLLoaderHost::~PepperURLLoaderHost() { int32_t PepperURLLoaderHost::OnResourceMessageReceived( const IPC::Message& msg, ppapi::host::HostMessageContext* context) { - IPC_BEGIN_MESSAGE_MAP(PepperURLLoaderHost, msg) - PPAPI_DISPATCH_HOST_RESOURCE_CALL( - PpapiHostMsg_URLLoader_Open, - OnHostMsgOpen) - PPAPI_DISPATCH_HOST_RESOURCE_CALL( - PpapiHostMsg_URLLoader_SetDeferLoading, - OnHostMsgSetDeferLoading) - PPAPI_DISPATCH_HOST_RESOURCE_CALL_0( - PpapiHostMsg_URLLoader_Close, - OnHostMsgClose); + PPAPI_BEGIN_MESSAGE_MAP(PepperURLLoaderHost, msg) + PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_URLLoader_Open, + OnHostMsgOpen) + PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_URLLoader_SetDeferLoading, + OnHostMsgSetDeferLoading) + PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_URLLoader_Close, + OnHostMsgClose); PPAPI_DISPATCH_HOST_RESOURCE_CALL_0( PpapiHostMsg_URLLoader_GrantUniversalAccess, OnHostMsgGrantUniversalAccess) - IPC_END_MESSAGE_MAP() + PPAPI_END_MESSAGE_MAP() return PP_ERROR_FAILED; } @@ -173,13 +170,14 @@ void PepperURLLoaderHost::didReceiveData(WebURLLoader* loader, } void PepperURLLoaderHost::didFinishLoading(WebURLLoader* loader, - double finish_time) { + double finish_time, + int64_t total_encoded_data_length) { // Note that |loader| will be NULL for document loads. SendUpdateToPlugin(new PpapiPluginMsg_URLLoader_FinishedLoading(PP_OK)); } void PepperURLLoaderHost::didFail(WebURLLoader* loader, - const WebURLError& error) { + const WebURLError& error) { // Note that |loader| will be NULL for document loads. int32_t pp_error = PP_ERROR_FAILED; if (error.domain.equals(WebString::fromUTF8(net::kErrorDomain))) { @@ -236,7 +234,9 @@ int32_t PepperURLLoaderHost::InternalOnHostMsgOpen( if (URLRequestRequiresUniversalAccess(filled_in_request_data) && !has_universal_access_) { ppapi::PpapiGlobals::Get()->LogWithSource( - pp_instance(), PP_LOGLEVEL_ERROR, std::string(), + pp_instance(), + PP_LOGLEVEL_ERROR, + std::string(), "PPB_URLLoader.Open: The URL you're requesting is " " on a different security origin than your plugin. To request " " cross-origin resources, see " @@ -247,15 +247,13 @@ int32_t PepperURLLoaderHost::InternalOnHostMsgOpen( if (loader_.get()) return PP_ERROR_INPROGRESS; - WebFrame* frame = GetFrame(); + WebLocalFrame* frame = GetFrame(); if (!frame) return PP_ERROR_FAILED; WebURLRequest web_request; - if (!CreateWebURLRequest(pp_instance(), - &filled_in_request_data, - frame, - &web_request)) { + if (!CreateWebURLRequest( + pp_instance(), &filled_in_request_data, frame, &web_request)) { return PP_ERROR_FAILED; } @@ -361,13 +359,21 @@ void PepperURLLoaderHost::SendOrderedUpdateToPlugin(IPC::Message* message) { } void PepperURLLoaderHost::Close() { - if (loader_.get()) + if (loader_.get()) { loader_->cancel(); - else if (main_document_loader_) - GetFrame()->stopLoading(); + } else if (main_document_loader_) { + // TODO(raymes): Calling WebLocalFrame::stopLoading here is incorrect as it + // cancels all URL loaders associated with the frame. If a client has opened + // other URLLoaders and then closes the main one, the others should still + // remain connected. Work out how to only cancel the main request: + // crbug.com/384197. + blink::WebLocalFrame* frame = GetFrame(); + if (frame) + frame->stopLoading(); + } } -blink::WebFrame* PepperURLLoaderHost::GetFrame() { +blink::WebLocalFrame* PepperURLLoaderHost::GetFrame() { PepperPluginInstance* instance_object = renderer_ppapi_host_->GetPluginInstance(pp_instance()); if (!instance_object) @@ -401,7 +407,7 @@ void PepperURLLoaderHost::SaveResponse(const WebURLResponse& response) { pp_instance(), response, base::Bind(&PepperURLLoaderHost::DidDataFromWebURLResponse, - weak_factory_.GetWeakPtr())); + weak_factory_.GetWeakPtr())); } } @@ -421,10 +427,10 @@ void PepperURLLoaderHost::UpdateProgress() { // flag. ppapi::proxy::ResourceMessageReplyParams params; SendUpdateToPlugin(new PpapiPluginMsg_URLLoader_UpdateProgress( - record_upload ? bytes_sent_ : -1, - record_upload ? total_bytes_to_be_sent_ : -1, - record_download ? bytes_received_ : -1, - record_download ? total_bytes_to_be_received_ : -1)); + record_upload ? bytes_sent_ : -1, + record_upload ? total_bytes_to_be_sent_ : -1, + record_download ? bytes_received_ : -1, + record_download ? total_bytes_to_be_received_ : -1)); } } diff --git a/chromium/content/renderer/pepper/pepper_url_loader_host.h b/chromium/content/renderer/pepper/pepper_url_loader_host.h index 2790c785c74..e2986595069 100644 --- a/chromium/content/renderer/pepper/pepper_url_loader_host.h +++ b/chromium/content/renderer/pepper/pepper_url_loader_host.h @@ -17,7 +17,7 @@ #include "third_party/WebKit/public/platform/WebURLLoaderClient.h" namespace blink { -class WebFrame; +class WebLocalFrame; class WebURLLoader; } @@ -25,9 +25,8 @@ namespace content { class RendererPpapiHostImpl; -class PepperURLLoaderHost - : public ppapi::host::ResourceHost, - public blink::WebURLLoaderClient { +class PepperURLLoaderHost : public ppapi::host::ResourceHost, + public blink::WebURLLoaderClient { public: // If main_document_loader is true, PP_Resource must be 0 since it will be // pending until the plugin resource attaches to it. @@ -59,7 +58,8 @@ class PepperURLLoaderHost int data_length, int encoded_data_length); virtual void didFinishLoading(blink::WebURLLoader* loader, - double finish_time); + double finish_time, + int64_t total_encoded_data_length); virtual void didFail(blink::WebURLLoader* loader, const blink::WebURLError& error); @@ -96,7 +96,7 @@ class PepperURLLoaderHost void Close(); // Returns the frame for the current request. - blink::WebFrame* GetFrame(); + blink::WebLocalFrame* GetFrame(); // Calls SetDefersLoading on the current load. This encapsulates the logic // differences between document loads and regular ones. diff --git a/chromium/content/renderer/pepper/pepper_url_request_unittest.cc b/chromium/content/renderer/pepper/pepper_url_request_unittest.cc index 4f171ff0a7a..44936c287be 100644 --- a/chromium/content/renderer/pepper/pepper_url_request_unittest.cc +++ b/chromium/content/renderer/pepper/pepper_url_request_unittest.cc @@ -3,6 +3,7 @@ // found in the LICENSE file. #include "base/compiler_specific.h" +#include "content/public/common/user_agent.h" #include "content/public/test/render_view_test.h" #include "content/renderer/pepper/url_request_info_util.h" #include "ppapi/proxy/connection.h" @@ -13,11 +14,9 @@ #include "ppapi/thunk/thunk.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/WebKit/public/platform/WebURLRequest.h" -#include "third_party/WebKit/public/web/WebFrame.h" #include "third_party/WebKit/public/web/WebFrameClient.h" +#include "third_party/WebKit/public/web/WebLocalFrame.h" #include "third_party/WebKit/public/web/WebView.h" -#include "webkit/common/user_agent/user_agent.h" -#include "webkit/common/user_agent/user_agent_util.h" // This test is a end-to-end test from the resource to the WebKit request // object. The actual resource implementation is so simple, it makes sense to @@ -25,7 +24,6 @@ // time. using blink::WebCString; -using blink::WebFrame; using blink::WebFrameClient; using blink::WebString; using blink::WebView; @@ -44,8 +42,7 @@ bool IsExpected(const WebString& web_string, const char* expected) { } // The base class destructor is protected, so derive. -class TestWebFrameClient : public WebFrameClient { -}; +class TestWebFrameClient : public WebFrameClient {}; } // namespace @@ -56,8 +53,7 @@ namespace content { class URLRequestInfoTest : public RenderViewTest { public: - URLRequestInfoTest() : pp_instance_(1234) { - } + URLRequestInfoTest() : pp_instance_(1234) {} virtual void SetUp() OVERRIDE { RenderViewTest::SetUp(); @@ -66,9 +62,8 @@ class URLRequestInfoTest : public RenderViewTest { test_globals_.GetResourceTracker()->DidCreateInstance(pp_instance_); // This resource doesn't do IPC, so a null connection is fine. - info_ = new URLRequestInfoResource(ppapi::proxy::Connection(), - pp_instance_, - URLRequestInfoData()); + info_ = new URLRequestInfoResource( + ppapi::proxy::Connection(), pp_instance_, URLRequestInfoData()); } virtual void TearDown() OVERRIDE { @@ -143,79 +138,73 @@ TEST_F(URLRequestInfoTest, StreamToFile) { EXPECT_FALSE(GetDownloadToFile()); - EXPECT_TRUE(SetBooleanProperty( - PP_URLREQUESTPROPERTY_STREAMTOFILE, true)); + EXPECT_TRUE(SetBooleanProperty(PP_URLREQUESTPROPERTY_STREAMTOFILE, true)); EXPECT_TRUE(GetDownloadToFile()); - EXPECT_TRUE(SetBooleanProperty( - PP_URLREQUESTPROPERTY_STREAMTOFILE, false)); + EXPECT_TRUE(SetBooleanProperty(PP_URLREQUESTPROPERTY_STREAMTOFILE, false)); EXPECT_FALSE(GetDownloadToFile()); } TEST_F(URLRequestInfoTest, FollowRedirects) { EXPECT_TRUE(info_->GetData().follow_redirects); - EXPECT_TRUE(SetBooleanProperty( - PP_URLREQUESTPROPERTY_FOLLOWREDIRECTS, false)); + EXPECT_TRUE(SetBooleanProperty(PP_URLREQUESTPROPERTY_FOLLOWREDIRECTS, false)); EXPECT_FALSE(info_->GetData().follow_redirects); - EXPECT_TRUE(SetBooleanProperty( - PP_URLREQUESTPROPERTY_FOLLOWREDIRECTS, true)); + EXPECT_TRUE(SetBooleanProperty(PP_URLREQUESTPROPERTY_FOLLOWREDIRECTS, true)); EXPECT_TRUE(info_->GetData().follow_redirects); } TEST_F(URLRequestInfoTest, RecordDownloadProgress) { EXPECT_FALSE(info_->GetData().record_download_progress); - EXPECT_TRUE(SetBooleanProperty( - PP_URLREQUESTPROPERTY_RECORDDOWNLOADPROGRESS, true)); + EXPECT_TRUE( + SetBooleanProperty(PP_URLREQUESTPROPERTY_RECORDDOWNLOADPROGRESS, true)); EXPECT_TRUE(info_->GetData().record_download_progress); - EXPECT_TRUE(SetBooleanProperty( - PP_URLREQUESTPROPERTY_RECORDDOWNLOADPROGRESS, false)); + EXPECT_TRUE( + SetBooleanProperty(PP_URLREQUESTPROPERTY_RECORDDOWNLOADPROGRESS, false)); EXPECT_FALSE(info_->GetData().record_download_progress); } TEST_F(URLRequestInfoTest, RecordUploadProgress) { EXPECT_FALSE(info_->GetData().record_upload_progress); - EXPECT_TRUE(SetBooleanProperty( - PP_URLREQUESTPROPERTY_RECORDUPLOADPROGRESS, true)); + EXPECT_TRUE( + SetBooleanProperty(PP_URLREQUESTPROPERTY_RECORDUPLOADPROGRESS, true)); EXPECT_TRUE(info_->GetData().record_upload_progress); - EXPECT_TRUE(SetBooleanProperty( - PP_URLREQUESTPROPERTY_RECORDUPLOADPROGRESS, false)); + EXPECT_TRUE( + SetBooleanProperty(PP_URLREQUESTPROPERTY_RECORDUPLOADPROGRESS, false)); EXPECT_FALSE(info_->GetData().record_upload_progress); } TEST_F(URLRequestInfoTest, AllowCrossOriginRequests) { EXPECT_FALSE(info_->GetData().allow_cross_origin_requests); - EXPECT_TRUE(SetBooleanProperty( - PP_URLREQUESTPROPERTY_ALLOWCROSSORIGINREQUESTS, true)); + EXPECT_TRUE( + SetBooleanProperty(PP_URLREQUESTPROPERTY_ALLOWCROSSORIGINREQUESTS, true)); EXPECT_TRUE(info_->GetData().allow_cross_origin_requests); - EXPECT_TRUE(SetBooleanProperty( - PP_URLREQUESTPROPERTY_ALLOWCROSSORIGINREQUESTS, false)); + EXPECT_TRUE(SetBooleanProperty(PP_URLREQUESTPROPERTY_ALLOWCROSSORIGINREQUESTS, + false)); EXPECT_FALSE(info_->GetData().allow_cross_origin_requests); } TEST_F(URLRequestInfoTest, AllowCredentials) { EXPECT_FALSE(info_->GetData().allow_credentials); - EXPECT_TRUE(SetBooleanProperty( - PP_URLREQUESTPROPERTY_ALLOWCREDENTIALS, true)); + EXPECT_TRUE(SetBooleanProperty(PP_URLREQUESTPROPERTY_ALLOWCREDENTIALS, true)); EXPECT_TRUE(info_->GetData().allow_credentials); - EXPECT_TRUE(SetBooleanProperty( - PP_URLREQUESTPROPERTY_ALLOWCREDENTIALS, false)); + EXPECT_TRUE( + SetBooleanProperty(PP_URLREQUESTPROPERTY_ALLOWCREDENTIALS, false)); EXPECT_FALSE(info_->GetData().allow_credentials); } TEST_F(URLRequestInfoTest, SetURL) { const char* url = "http://www.google.com/"; - EXPECT_TRUE(SetStringProperty( - PP_URLREQUESTPROPERTY_URL, url)); + EXPECT_TRUE(SetStringProperty(PP_URLREQUESTPROPERTY_URL, url)); EXPECT_TRUE(IsExpected(GetURL(), url)); } @@ -229,27 +218,21 @@ TEST_F(URLRequestInfoTest, JavascriptURL) { TEST_F(URLRequestInfoTest, SetMethod) { // Test default method is "GET". EXPECT_TRUE(IsExpected(GetMethod(), "GET")); - EXPECT_TRUE(SetStringProperty( - PP_URLREQUESTPROPERTY_METHOD, "POST")); + EXPECT_TRUE(SetStringProperty(PP_URLREQUESTPROPERTY_METHOD, "POST")); EXPECT_TRUE(IsExpected(GetMethod(), "POST")); } TEST_F(URLRequestInfoTest, SetHeaders) { // Test default header field. - EXPECT_TRUE(IsExpected( - GetHeaderValue("foo"), "")); + EXPECT_TRUE(IsExpected(GetHeaderValue("foo"), "")); // Test that we can set a header field. - EXPECT_TRUE(SetStringProperty( - PP_URLREQUESTPROPERTY_HEADERS, "foo: bar")); - EXPECT_TRUE(IsExpected( - GetHeaderValue("foo"), "bar")); + EXPECT_TRUE(SetStringProperty(PP_URLREQUESTPROPERTY_HEADERS, "foo: bar")); + EXPECT_TRUE(IsExpected(GetHeaderValue("foo"), "bar")); // Test that we can set multiple header fields using \n delimiter. - EXPECT_TRUE(SetStringProperty( - PP_URLREQUESTPROPERTY_HEADERS, "foo: bar\nbar: baz")); - EXPECT_TRUE(IsExpected( - GetHeaderValue("foo"), "bar")); - EXPECT_TRUE(IsExpected( - GetHeaderValue("bar"), "baz")); + EXPECT_TRUE( + SetStringProperty(PP_URLREQUESTPROPERTY_HEADERS, "foo: bar\nbar: baz")); + EXPECT_TRUE(IsExpected(GetHeaderValue("foo"), "bar")); + EXPECT_TRUE(IsExpected(GetHeaderValue("bar"), "baz")); } // TODO(bbudge) Unit tests for AppendDataToBody, AppendFileToBody. diff --git a/chromium/content/renderer/pepper/pepper_video_capture_host.cc b/chromium/content/renderer/pepper/pepper_video_capture_host.cc index 732842402d6..71bebb30ebd 100644 --- a/chromium/content/renderer/pepper/pepper_video_capture_host.cc +++ b/chromium/content/renderer/pepper/pepper_video_capture_host.cc @@ -10,6 +10,8 @@ #include "content/renderer/pepper/pepper_plugin_instance_impl.h" #include "content/renderer/pepper/renderer_ppapi_host_impl.h" #include "content/renderer/render_view_impl.h" +#include "media/base/limits.h" +#include "media/base/video_frame.h" #include "ppapi/host/dispatch_host_message.h" #include "ppapi/host/ppapi_host.h" #include "ppapi/proxy/host_dispatcher.h" @@ -39,12 +41,11 @@ PepperVideoCaptureHost::PepperVideoCaptureHost(RendererPpapiHostImpl* host, renderer_ppapi_host_(host), buffer_count_hint_(0), status_(PP_VIDEO_CAPTURE_STATUS_STOPPED), - enumeration_helper_( - this, - PepperMediaDeviceManager::GetForRenderView( - host->GetRenderViewForInstance(pp_instance())), - PP_DEVICETYPE_DEV_VIDEOCAPTURE, - host->GetDocumentURL(instance)) { + enumeration_helper_(this, + PepperMediaDeviceManager::GetForRenderView( + host->GetRenderViewForInstance(pp_instance())), + PP_DEVICETYPE_DEV_VIDEOCAPTURE, + host->GetDocumentURL(instance)) { } PepperVideoCaptureHost::~PepperVideoCaptureHost() { @@ -62,30 +63,21 @@ int32_t PepperVideoCaptureHost::OnResourceMessageReceived( if (enumeration_helper_.HandleResourceMessage(msg, context, &result)) return result; - IPC_BEGIN_MESSAGE_MAP(PepperVideoCaptureHost, msg) - PPAPI_DISPATCH_HOST_RESOURCE_CALL( - PpapiHostMsg_VideoCapture_Open, - OnOpen) - PPAPI_DISPATCH_HOST_RESOURCE_CALL_0( - PpapiHostMsg_VideoCapture_StartCapture, - OnStartCapture) - PPAPI_DISPATCH_HOST_RESOURCE_CALL( - PpapiHostMsg_VideoCapture_ReuseBuffer, - OnReuseBuffer) - PPAPI_DISPATCH_HOST_RESOURCE_CALL_0( - PpapiHostMsg_VideoCapture_StopCapture, - OnStopCapture) - PPAPI_DISPATCH_HOST_RESOURCE_CALL_0( - PpapiHostMsg_VideoCapture_Close, - OnClose) - IPC_END_MESSAGE_MAP() + PPAPI_BEGIN_MESSAGE_MAP(PepperVideoCaptureHost, msg) + PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_VideoCapture_Open, OnOpen) + PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_VideoCapture_StartCapture, + OnStartCapture) + PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_VideoCapture_ReuseBuffer, + OnReuseBuffer) + PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_VideoCapture_StopCapture, + OnStopCapture) + PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_VideoCapture_Close, + OnClose) + PPAPI_END_MESSAGE_MAP() return PP_ERROR_FAILED; } -void PepperVideoCaptureHost::OnInitialized(media::VideoCapture* capture, - bool succeeded) { - DCHECK(capture == platform_video_capture_.get()); - +void PepperVideoCaptureHost::OnInitialized(bool succeeded) { if (succeeded) { open_reply_context_.params.set_result(PP_OK); } else { @@ -97,25 +89,22 @@ void PepperVideoCaptureHost::OnInitialized(media::VideoCapture* capture, PpapiPluginMsg_VideoCapture_OpenReply()); } -void PepperVideoCaptureHost::OnStarted(media::VideoCapture* capture) { +void PepperVideoCaptureHost::OnStarted() { if (SetStatus(PP_VIDEO_CAPTURE_STATUS_STARTED, false)) SendStatus(); } -void PepperVideoCaptureHost::OnStopped(media::VideoCapture* capture) { +void PepperVideoCaptureHost::OnStopped() { if (SetStatus(PP_VIDEO_CAPTURE_STATUS_STOPPED, false)) SendStatus(); } -void PepperVideoCaptureHost::OnPaused(media::VideoCapture* capture) { +void PepperVideoCaptureHost::OnPaused() { if (SetStatus(PP_VIDEO_CAPTURE_STATUS_PAUSED, false)) SendStatus(); } -void PepperVideoCaptureHost::OnError(media::VideoCapture* capture, - int error_code) { - // Today, the media layer only sends "1" as an error. - DCHECK(error_code == 1); +void PepperVideoCaptureHost::OnError() { PostErrorReply(); } @@ -124,20 +113,17 @@ void PepperVideoCaptureHost::PostErrorReply() { // conflicting "master" resolution), or because the browser failed to start // the capture. SetStatus(PP_VIDEO_CAPTURE_STATUS_STOPPED, true); - host()->SendUnsolicitedReply(pp_resource(), - PpapiPluginMsg_VideoCapture_OnError(PP_ERROR_FAILED)); -} - -void PepperVideoCaptureHost::OnRemoved(media::VideoCapture* capture) { + host()->SendUnsolicitedReply( + pp_resource(), PpapiPluginMsg_VideoCapture_OnError(PP_ERROR_FAILED)); } void PepperVideoCaptureHost::OnFrameReady( - media::VideoCapture* capture, - const scoped_refptr<media::VideoFrame>& frame) { + const scoped_refptr<media::VideoFrame>& frame, + media::VideoCaptureFormat format) { DCHECK(frame.get()); - if (alloc_size_ != frame->coded_size()) { - AllocBuffers(frame->coded_size(), capture->CaptureFrameRate()); + if (alloc_size_ != frame->coded_size() || buffers_.empty()) { + AllocBuffers(frame->coded_size(), format.frame_rate); alloc_size_ = frame->coded_size(); } @@ -166,21 +152,19 @@ void PepperVideoCaptureHost::OnFrameReady( } } buffers_[i].in_use = true; - host()->SendUnsolicitedReply(pp_resource(), - PpapiPluginMsg_VideoCapture_OnBufferReady(i)); + host()->SendUnsolicitedReply( + pp_resource(), PpapiPluginMsg_VideoCapture_OnBufferReady(i)); return; } } } -void PepperVideoCaptureHost::AllocBuffers( - const gfx::Size& resolution, - int frame_rate) { +void PepperVideoCaptureHost::AllocBuffers(const gfx::Size& resolution, + int frame_rate) { PP_VideoCaptureDeviceInfo_Dev info = { - static_cast<uint32_t>(resolution.width()), - static_cast<uint32_t>(resolution.height()), - static_cast<uint32_t>(frame_rate) - }; + static_cast<uint32_t>(resolution.width()), + static_cast<uint32_t>(resolution.height()), + static_cast<uint32_t>(frame_rate)}; ReleaseBuffers(); const size_t size = media::VideoFrame::AllocationSize( @@ -193,8 +177,7 @@ void PepperVideoCaptureHost::AllocBuffers( // for sending below. std::vector<HostResource> buffer_host_resources; buffers_.reserve(buffer_count_hint_); - ppapi::ResourceTracker* tracker = - HostGlobals::Get()->GetResourceTracker(); + ppapi::ResourceTracker* tracker = HostGlobals::Get()->GetResourceTracker(); ppapi::proxy::HostDispatcher* dispatcher = ppapi::proxy::HostDispatcher::GetForInstance(pp_instance()); for (size_t i = 0; i < buffer_count_hint_; ++i) { @@ -242,10 +225,8 @@ void PepperVideoCaptureHost::AllocBuffers( #else #error Not implemented. #endif - params.AppendHandle( - ppapi::proxy::SerializedHandle( - dispatcher->ShareHandleWithRemote(platform_file, false), - size)); + params.AppendHandle(ppapi::proxy::SerializedHandle( + dispatcher->ShareHandleWithRemote(platform_file, false), size)); } } @@ -253,14 +234,15 @@ void PepperVideoCaptureHost::AllocBuffers( // We couldn't allocate/map buffers at all. Send an error and stop the // capture. SetStatus(PP_VIDEO_CAPTURE_STATUS_STOPPING, true); - platform_video_capture_->StopCapture(this); + platform_video_capture_->StopCapture(); PostErrorReply(); return; } - host()->Send(new PpapiPluginMsg_ResourceReply( - params, PpapiPluginMsg_VideoCapture_OnDeviceInfo( - info, buffer_host_resources, size))); + host()->Send( + new PpapiPluginMsg_ResourceReply(params, + PpapiPluginMsg_VideoCapture_OnDeviceInfo( + info, buffer_host_resources, size))); } int32_t PepperVideoCaptureHost::OnOpen( @@ -280,9 +262,8 @@ int32_t PepperVideoCaptureHost::OnOpen( RenderViewImpl* render_view = static_cast<RenderViewImpl*>( renderer_ppapi_host_->GetRenderViewForInstance(pp_instance())); - platform_video_capture_ = new PepperPlatformVideoCapture( - render_view->AsWeakPtr(), device_id, - document_url, this); + platform_video_capture_.reset(new PepperPlatformVideoCapture( + render_view->AsWeakPtr(), device_id, document_url, this)); open_reply_context_ = context->MakeReplyMessageContext(); @@ -299,7 +280,7 @@ int32_t PepperVideoCaptureHost::OnStartCapture( // It's safe to call this regardless it's capturing or not, because // PepperPlatformVideoCapture maintains the state. - platform_video_capture_->StartCapture(this, video_capture_params_); + platform_video_capture_->StartCapture(video_capture_params_); return PP_OK; } @@ -331,7 +312,7 @@ int32_t PepperVideoCaptureHost::StopCapture() { ReleaseBuffers(); // It's safe to call this regardless it's capturing or not, because // PepperPlatformVideoCapture maintains the state. - platform_video_capture_->StopCapture(this); + platform_video_capture_->StopCapture(); return PP_OK; } @@ -356,7 +337,7 @@ void PepperVideoCaptureHost::ReleaseBuffers() { void PepperVideoCaptureHost::SendStatus() { host()->SendUnsolicitedReply(pp_resource(), - PpapiPluginMsg_VideoCapture_OnStatus(status_)); + PpapiPluginMsg_VideoCapture_OnStatus(status_)); } void PepperVideoCaptureHost::SetRequestedInfo( @@ -364,18 +345,22 @@ void PepperVideoCaptureHost::SetRequestedInfo( uint32_t buffer_count) { // Clamp the buffer count to between 1 and |kMaxBuffers|. buffer_count_hint_ = std::min(std::max(buffer_count, 1U), kMaxBuffers); + // Clamp the frame rate to between 1 and |kMaxFramesPerSecond - 1|. + int frames_per_second = + std::min(std::max(device_info.frames_per_second, 1U), + static_cast<uint32_t>(media::limits::kMaxFramesPerSecond - 1)); video_capture_params_.requested_format = media::VideoCaptureFormat( gfx::Size(device_info.width, device_info.height), - device_info.frames_per_second, + frames_per_second, media::PIXEL_FORMAT_I420); video_capture_params_.allow_resolution_change = false; } void PepperVideoCaptureHost::DetachPlatformVideoCapture() { - if (platform_video_capture_.get()) { + if (platform_video_capture_) { platform_video_capture_->DetachEventHandler(); - platform_video_capture_ = NULL; + platform_video_capture_.reset(); } } @@ -427,9 +412,7 @@ bool PepperVideoCaptureHost::SetStatus(PP_VideoCaptureStatus_Dev status, } PepperVideoCaptureHost::BufferInfo::BufferInfo() - : in_use(false), - data(NULL), - buffer() { + : in_use(false), data(NULL), buffer() { } PepperVideoCaptureHost::BufferInfo::~BufferInfo() { diff --git a/chromium/content/renderer/pepper/pepper_video_capture_host.h b/chromium/content/renderer/pepper/pepper_video_capture_host.h index a8312a2f5a8..8326c5ec1aa 100644 --- a/chromium/content/renderer/pepper/pepper_video_capture_host.h +++ b/chromium/content/renderer/pepper/pepper_video_capture_host.h @@ -7,22 +7,25 @@ #include "base/compiler_specific.h" #include "base/memory/ref_counted.h" +#include "base/memory/scoped_ptr.h" +#include "content/common/media/video_capture.h" #include "content/public/renderer/renderer_ppapi_host.h" #include "content/renderer/pepper/pepper_device_enumeration_host_helper.h" #include "content/renderer/pepper/ppb_buffer_impl.h" -#include "media/video/capture/video_capture.h" #include "media/video/capture/video_capture_types.h" #include "ppapi/c/dev/ppp_video_capture_dev.h" #include "ppapi/host/host_message_context.h" #include "ppapi/host/resource_host.h" +namespace media { +class VideoFrame; +} // namespace media + namespace content { class PepperPlatformVideoCapture; class RendererPpapiHostImpl; -class PepperVideoCaptureHost - : public ppapi::host::ResourceHost, - public media::VideoCapture::EventHandler { +class PepperVideoCaptureHost : public ppapi::host::ResourceHost { public: PepperVideoCaptureHost(RendererPpapiHostImpl* host, PP_Instance instance, @@ -36,17 +39,28 @@ class PepperVideoCaptureHost const IPC::Message& msg, ppapi::host::HostMessageContext* context) OVERRIDE; - void OnInitialized(media::VideoCapture* capture, bool succeeded); + // These methods are called by PepperPlatformVideoCapture only. + + // Called when video capture is initialized. We can start + // video capture if |succeeded| is true. + void OnInitialized(bool succeeded); + + // Called when video capture has started successfully. + void OnStarted(); + + // Called when video capture has stopped. There will be no more + // frames delivered. + void OnStopped(); + + // Called when video capture has paused. + void OnPaused(); + + // Called when video capture cannot be started because of an error. + void OnError(); - // media::VideoCapture::EventHandler - virtual void OnStarted(media::VideoCapture* capture) OVERRIDE; - virtual void OnStopped(media::VideoCapture* capture) OVERRIDE; - virtual void OnPaused(media::VideoCapture* capture) OVERRIDE; - virtual void OnError(media::VideoCapture* capture, int error_code) OVERRIDE; - virtual void OnRemoved(media::VideoCapture* capture) OVERRIDE; - virtual void OnFrameReady( - media::VideoCapture* capture, - const scoped_refptr<media::VideoFrame>& frame) OVERRIDE; + // Called when a video frame is ready. + void OnFrameReady(const scoped_refptr<media::VideoFrame>& frame, + media::VideoCaptureFormat format); private: int32_t OnOpen(ppapi::host::HostMessageContext* context, @@ -62,8 +76,7 @@ class PepperVideoCaptureHost int32_t StopCapture(); int32_t Close(); void PostErrorReply(); - void AllocBuffers(const gfx::Size& resolution, - int frame_rate); + void AllocBuffers(const gfx::Size& resolution, int frame_rate); void ReleaseBuffers(); void SendStatus(); @@ -74,7 +87,7 @@ class PepperVideoCaptureHost bool SetStatus(PP_VideoCaptureStatus_Dev status, bool forced); - scoped_refptr<PepperPlatformVideoCapture> platform_video_capture_; + scoped_ptr<PepperPlatformVideoCapture> platform_video_capture_; // Buffers of video frame. struct BufferInfo { diff --git a/chromium/content/renderer/pepper/pepper_video_decoder_host.cc b/chromium/content/renderer/pepper/pepper_video_decoder_host.cc new file mode 100644 index 00000000000..abcab8f1b89 --- /dev/null +++ b/chromium/content/renderer/pepper/pepper_video_decoder_host.cc @@ -0,0 +1,403 @@ +// Copyright (c) 2014 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 "content/renderer/pepper/pepper_video_decoder_host.h" + +#include "base/bind.h" +#include "base/memory/shared_memory.h" +#include "content/common/gpu/client/gpu_channel_host.h" +#include "content/public/renderer/render_thread.h" +#include "content/public/renderer/renderer_ppapi_host.h" +#include "content/renderer/pepper/ppb_graphics_3d_impl.h" +#include "content/renderer/pepper/video_decoder_shim.h" +#include "media/video/video_decode_accelerator.h" +#include "ppapi/c/pp_completion_callback.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/host/dispatch_host_message.h" +#include "ppapi/host/ppapi_host.h" +#include "ppapi/proxy/ppapi_messages.h" +#include "ppapi/proxy/video_decoder_constants.h" +#include "ppapi/thunk/enter.h" +#include "ppapi/thunk/ppb_graphics_3d_api.h" + +using ppapi::proxy::SerializedHandle; +using ppapi::thunk::EnterResourceNoLock; +using ppapi::thunk::PPB_Graphics3D_API; + +namespace content { + +namespace { + +media::VideoCodecProfile PepperToMediaVideoProfile(PP_VideoProfile profile) { + switch (profile) { + case PP_VIDEOPROFILE_H264BASELINE: + return media::H264PROFILE_BASELINE; + case PP_VIDEOPROFILE_H264MAIN: + return media::H264PROFILE_MAIN; + case PP_VIDEOPROFILE_H264EXTENDED: + return media::H264PROFILE_EXTENDED; + case PP_VIDEOPROFILE_H264HIGH: + return media::H264PROFILE_HIGH; + case PP_VIDEOPROFILE_H264HIGH10PROFILE: + return media::H264PROFILE_HIGH10PROFILE; + case PP_VIDEOPROFILE_H264HIGH422PROFILE: + return media::H264PROFILE_HIGH422PROFILE; + case PP_VIDEOPROFILE_H264HIGH444PREDICTIVEPROFILE: + return media::H264PROFILE_HIGH444PREDICTIVEPROFILE; + case PP_VIDEOPROFILE_H264SCALABLEBASELINE: + return media::H264PROFILE_SCALABLEBASELINE; + case PP_VIDEOPROFILE_H264SCALABLEHIGH: + return media::H264PROFILE_SCALABLEHIGH; + case PP_VIDEOPROFILE_H264STEREOHIGH: + return media::H264PROFILE_STEREOHIGH; + case PP_VIDEOPROFILE_H264MULTIVIEWHIGH: + return media::H264PROFILE_MULTIVIEWHIGH; + case PP_VIDEOPROFILE_VP8MAIN: + return media::VP8PROFILE_MAIN; + case PP_VIDEOPROFILE_VP9MAIN: + return media::VP9PROFILE_MAIN; + // No default case, to catch unhandled PP_VideoProfile values. + } + + return media::VIDEO_CODEC_PROFILE_UNKNOWN; +} + +} // namespace + +PepperVideoDecoderHost::PendingDecode::PendingDecode( + uint32_t shm_id, + const ppapi::host::ReplyMessageContext& reply_context) + : shm_id(shm_id), reply_context(reply_context) { +} + +PepperVideoDecoderHost::PendingDecode::~PendingDecode() { +} + +PepperVideoDecoderHost::PepperVideoDecoderHost(RendererPpapiHost* host, + PP_Instance instance, + PP_Resource resource) + : ResourceHost(host->GetPpapiHost(), instance, resource), + renderer_ppapi_host_(host), + initialized_(false) { +} + +PepperVideoDecoderHost::~PepperVideoDecoderHost() { +} + +int32_t PepperVideoDecoderHost::OnResourceMessageReceived( + const IPC::Message& msg, + ppapi::host::HostMessageContext* context) { + PPAPI_BEGIN_MESSAGE_MAP(PepperVideoDecoderHost, msg) + PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_VideoDecoder_Initialize, + OnHostMsgInitialize) + PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_VideoDecoder_GetShm, + OnHostMsgGetShm) + PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_VideoDecoder_Decode, + OnHostMsgDecode) + PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_VideoDecoder_AssignTextures, + OnHostMsgAssignTextures) + PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_VideoDecoder_RecyclePicture, + OnHostMsgRecyclePicture) + PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_VideoDecoder_Flush, + OnHostMsgFlush) + PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_VideoDecoder_Reset, + OnHostMsgReset) + PPAPI_END_MESSAGE_MAP() + return PP_ERROR_FAILED; +} + +int32_t PepperVideoDecoderHost::OnHostMsgInitialize( + ppapi::host::HostMessageContext* context, + const ppapi::HostResource& graphics_context, + PP_VideoProfile profile, + bool allow_software_fallback) { + if (initialized_) + return PP_ERROR_FAILED; + + EnterResourceNoLock<PPB_Graphics3D_API> enter_graphics( + graphics_context.host_resource(), true); + if (enter_graphics.failed()) + return PP_ERROR_FAILED; + PPB_Graphics3D_Impl* graphics3d = + static_cast<PPB_Graphics3D_Impl*>(enter_graphics.object()); + + int command_buffer_route_id = graphics3d->GetCommandBufferRouteId(); + if (!command_buffer_route_id) + return PP_ERROR_FAILED; + + media::VideoCodecProfile media_profile = PepperToMediaVideoProfile(profile); + + // This is not synchronous, but subsequent IPC messages will be buffered, so + // it is okay to immediately send IPC messages through the returned channel. + GpuChannelHost* channel = graphics3d->channel(); + DCHECK(channel); + decoder_ = channel->CreateVideoDecoder(command_buffer_route_id); + if (decoder_ && decoder_->Initialize(media_profile, this)) { + initialized_ = true; + return PP_OK; + } + decoder_.reset(); + + if (!allow_software_fallback) + return PP_ERROR_NOTSUPPORTED; + + decoder_.reset(new VideoDecoderShim(this)); + initialize_reply_context_ = context->MakeReplyMessageContext(); + decoder_->Initialize(media_profile, this); + + return PP_OK_COMPLETIONPENDING; +} + +int32_t PepperVideoDecoderHost::OnHostMsgGetShm( + ppapi::host::HostMessageContext* context, + uint32_t shm_id, + uint32_t shm_size) { + if (!initialized_) + return PP_ERROR_FAILED; + + // Make the buffers larger since we hope to reuse them. + shm_size = std::max( + shm_size, + static_cast<uint32_t>(ppapi::proxy::kMinimumBitstreamBufferSize)); + if (shm_size > ppapi::proxy::kMaximumBitstreamBufferSize) + return PP_ERROR_FAILED; + + if (shm_id >= ppapi::proxy::kMaximumPendingDecodes) + return PP_ERROR_FAILED; + // The shm_id must be inside or at the end of shm_buffers_. + if (shm_id > shm_buffers_.size()) + return PP_ERROR_FAILED; + // Reject an attempt to reallocate a busy shm buffer. + if (shm_id < shm_buffers_.size() && shm_buffer_busy_[shm_id]) + return PP_ERROR_FAILED; + + content::RenderThread* render_thread = content::RenderThread::Get(); + scoped_ptr<base::SharedMemory> shm( + render_thread->HostAllocateSharedMemoryBuffer(shm_size).Pass()); + if (!shm || !shm->Map(shm_size)) + return PP_ERROR_FAILED; + + base::SharedMemoryHandle shm_handle = shm->handle(); + if (shm_id == shm_buffers_.size()) { + shm_buffers_.push_back(shm.release()); + shm_buffer_busy_.push_back(false); + } else { + // Remove the old buffer. Delete manually since ScopedVector won't delete + // the existing element if we just assign over it. + delete shm_buffers_[shm_id]; + shm_buffers_[shm_id] = shm.release(); + } + +#if defined(OS_WIN) + base::PlatformFile platform_file = shm_handle; +#elif defined(OS_POSIX) + base::PlatformFile platform_file = shm_handle.fd; +#else +#error Not implemented. +#endif + SerializedHandle handle( + renderer_ppapi_host_->ShareHandleWithRemote(platform_file, false), + shm_size); + ppapi::host::ReplyMessageContext reply_context = + context->MakeReplyMessageContext(); + reply_context.params.AppendHandle(handle); + host()->SendReply(reply_context, + PpapiPluginMsg_VideoDecoder_GetShmReply(shm_size)); + + return PP_OK_COMPLETIONPENDING; +} + +int32_t PepperVideoDecoderHost::OnHostMsgDecode( + ppapi::host::HostMessageContext* context, + uint32_t shm_id, + uint32_t size, + int32_t decode_id) { + if (!initialized_) + return PP_ERROR_FAILED; + DCHECK(decoder_); + // |shm_id| is just an index into shm_buffers_. Make sure it's in range. + if (static_cast<size_t>(shm_id) >= shm_buffers_.size()) + return PP_ERROR_FAILED; + // Reject an attempt to pass a busy buffer to the decoder again. + if (shm_buffer_busy_[shm_id]) + return PP_ERROR_FAILED; + // Reject non-unique decode_id values. + if (pending_decodes_.find(decode_id) != pending_decodes_.end()) + return PP_ERROR_FAILED; + + if (flush_reply_context_.is_valid() || reset_reply_context_.is_valid()) + return PP_ERROR_FAILED; + + pending_decodes_.insert(std::make_pair( + decode_id, PendingDecode(shm_id, context->MakeReplyMessageContext()))); + + shm_buffer_busy_[shm_id] = true; + decoder_->Decode( + media::BitstreamBuffer(decode_id, shm_buffers_[shm_id]->handle(), size)); + + return PP_OK_COMPLETIONPENDING; +} + +int32_t PepperVideoDecoderHost::OnHostMsgAssignTextures( + ppapi::host::HostMessageContext* context, + const PP_Size& size, + const std::vector<uint32_t>& texture_ids) { + if (!initialized_) + return PP_ERROR_FAILED; + DCHECK(decoder_); + + std::vector<media::PictureBuffer> picture_buffers; + for (uint32 i = 0; i < texture_ids.size(); i++) { + media::PictureBuffer buffer( + texture_ids[i], // Use the texture_id to identify the buffer. + gfx::Size(size.width, size.height), + texture_ids[i]); + picture_buffers.push_back(buffer); + } + decoder_->AssignPictureBuffers(picture_buffers); + return PP_OK; +} + +int32_t PepperVideoDecoderHost::OnHostMsgRecyclePicture( + ppapi::host::HostMessageContext* context, + uint32_t texture_id) { + if (!initialized_) + return PP_ERROR_FAILED; + DCHECK(decoder_); + + decoder_->ReusePictureBuffer(texture_id); + return PP_OK; +} + +int32_t PepperVideoDecoderHost::OnHostMsgFlush( + ppapi::host::HostMessageContext* context) { + if (!initialized_) + return PP_ERROR_FAILED; + DCHECK(decoder_); + if (flush_reply_context_.is_valid() || reset_reply_context_.is_valid()) + return PP_ERROR_FAILED; + + flush_reply_context_ = context->MakeReplyMessageContext(); + decoder_->Flush(); + + return PP_OK_COMPLETIONPENDING; +} + +int32_t PepperVideoDecoderHost::OnHostMsgReset( + ppapi::host::HostMessageContext* context) { + if (!initialized_) + return PP_ERROR_FAILED; + DCHECK(decoder_); + if (flush_reply_context_.is_valid() || reset_reply_context_.is_valid()) + return PP_ERROR_FAILED; + + reset_reply_context_ = context->MakeReplyMessageContext(); + decoder_->Reset(); + + return PP_OK_COMPLETIONPENDING; +} + +void PepperVideoDecoderHost::ProvidePictureBuffers( + uint32 requested_num_of_buffers, + const gfx::Size& dimensions, + uint32 texture_target) { + RequestTextures(requested_num_of_buffers, + dimensions, + texture_target, + std::vector<gpu::Mailbox>()); +} + +void PepperVideoDecoderHost::PictureReady(const media::Picture& picture) { + host()->SendUnsolicitedReply( + pp_resource(), + PpapiPluginMsg_VideoDecoder_PictureReady(picture.bitstream_buffer_id(), + picture.picture_buffer_id())); +} + +void PepperVideoDecoderHost::DismissPictureBuffer(int32 picture_buffer_id) { + host()->SendUnsolicitedReply( + pp_resource(), + PpapiPluginMsg_VideoDecoder_DismissPicture(picture_buffer_id)); +} + +void PepperVideoDecoderHost::NotifyEndOfBitstreamBuffer( + int32 bitstream_buffer_id) { + PendingDecodeMap::iterator it = pending_decodes_.find(bitstream_buffer_id); + if (it == pending_decodes_.end()) { + NOTREACHED(); + return; + } + const PendingDecode& pending_decode = it->second; + host()->SendReply( + pending_decode.reply_context, + PpapiPluginMsg_VideoDecoder_DecodeReply(pending_decode.shm_id)); + shm_buffer_busy_[pending_decode.shm_id] = false; + pending_decodes_.erase(it); +} + +void PepperVideoDecoderHost::NotifyFlushDone() { + DCHECK(pending_decodes_.empty()); + host()->SendReply(flush_reply_context_, + PpapiPluginMsg_VideoDecoder_FlushReply()); + flush_reply_context_ = ppapi::host::ReplyMessageContext(); +} + +void PepperVideoDecoderHost::NotifyResetDone() { + DCHECK(pending_decodes_.empty()); + host()->SendReply(reset_reply_context_, + PpapiPluginMsg_VideoDecoder_ResetReply()); + reset_reply_context_ = ppapi::host::ReplyMessageContext(); +} + +void PepperVideoDecoderHost::NotifyError( + media::VideoDecodeAccelerator::Error error) { + int32_t pp_error = PP_ERROR_FAILED; + switch (error) { + case media::VideoDecodeAccelerator::UNREADABLE_INPUT: + pp_error = PP_ERROR_MALFORMED_INPUT; + break; + case media::VideoDecodeAccelerator::ILLEGAL_STATE: + case media::VideoDecodeAccelerator::INVALID_ARGUMENT: + case media::VideoDecodeAccelerator::PLATFORM_FAILURE: + case media::VideoDecodeAccelerator::LARGEST_ERROR_ENUM: + pp_error = PP_ERROR_RESOURCE_FAILED; + break; + // No default case, to catch unhandled enum values. + } + host()->SendUnsolicitedReply( + pp_resource(), PpapiPluginMsg_VideoDecoder_NotifyError(pp_error)); +} + +void PepperVideoDecoderHost::OnInitializeComplete(int32_t result) { + if (!initialized_) { + if (result == PP_OK) + initialized_ = true; + initialize_reply_context_.params.set_result(result); + host()->SendReply(initialize_reply_context_, + PpapiPluginMsg_VideoDecoder_InitializeReply()); + } +} + +const uint8_t* PepperVideoDecoderHost::DecodeIdToAddress(uint32_t decode_id) { + PendingDecodeMap::const_iterator it = pending_decodes_.find(decode_id); + DCHECK(it != pending_decodes_.end()); + uint32_t shm_id = it->second.shm_id; + return static_cast<uint8_t*>(shm_buffers_[shm_id]->memory()); +} + +void PepperVideoDecoderHost::RequestTextures( + uint32 requested_num_of_buffers, + const gfx::Size& dimensions, + uint32 texture_target, + const std::vector<gpu::Mailbox>& mailboxes) { + host()->SendUnsolicitedReply( + pp_resource(), + PpapiPluginMsg_VideoDecoder_RequestTextures( + requested_num_of_buffers, + PP_MakeSize(dimensions.width(), dimensions.height()), + texture_target, + mailboxes)); +} + +} // namespace content diff --git a/chromium/content/renderer/pepper/pepper_video_decoder_host.h b/chromium/content/renderer/pepper/pepper_video_decoder_host.h new file mode 100644 index 00000000000..e76f95c4bf6 --- /dev/null +++ b/chromium/content/renderer/pepper/pepper_video_decoder_host.h @@ -0,0 +1,128 @@ +// Copyright (c) 2014 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 CONTENT_RENDERER_PEPPER_PEPPER_VIDEO_DECODER_HOST_H_ +#define CONTENT_RENDERER_PEPPER_PEPPER_VIDEO_DECODER_HOST_H_ + +#include <map> +#include <vector> + +#include "base/basictypes.h" +#include "base/containers/hash_tables.h" +#include "base/memory/scoped_ptr.h" +#include "base/memory/scoped_vector.h" +#include "content/common/content_export.h" +#include "media/video/video_decode_accelerator.h" +#include "ppapi/c/pp_codecs.h" +#include "ppapi/host/host_message_context.h" +#include "ppapi/host/resource_host.h" +#include "ppapi/proxy/resource_message_params.h" + +namespace base { +class SharedMemory; +} + +namespace content { + +class PPB_Graphics3D_Impl; +class RendererPpapiHost; +class RenderViewImpl; +class VideoDecoderShim; + +class CONTENT_EXPORT PepperVideoDecoderHost + : public ppapi::host::ResourceHost, + public media::VideoDecodeAccelerator::Client { + public: + PepperVideoDecoderHost(RendererPpapiHost* host, + PP_Instance instance, + PP_Resource resource); + virtual ~PepperVideoDecoderHost(); + + private: + struct PendingDecode { + PendingDecode(uint32_t shm_id, + const ppapi::host::ReplyMessageContext& reply_context); + ~PendingDecode(); + + const uint32_t shm_id; + const ppapi::host::ReplyMessageContext reply_context; + }; + + friend class VideoDecoderShim; + + // ResourceHost implementation. + virtual int32_t OnResourceMessageReceived( + const IPC::Message& msg, + ppapi::host::HostMessageContext* context) OVERRIDE; + + // media::VideoDecodeAccelerator::Client implementation. + virtual void ProvidePictureBuffers(uint32 requested_num_of_buffers, + const gfx::Size& dimensions, + uint32 texture_target) OVERRIDE; + virtual void DismissPictureBuffer(int32 picture_buffer_id) OVERRIDE; + virtual void PictureReady(const media::Picture& picture) OVERRIDE; + virtual void NotifyEndOfBitstreamBuffer(int32 bitstream_buffer_id) OVERRIDE; + virtual void NotifyFlushDone() OVERRIDE; + virtual void NotifyResetDone() OVERRIDE; + virtual void NotifyError(media::VideoDecodeAccelerator::Error error) OVERRIDE; + + int32_t OnHostMsgInitialize(ppapi::host::HostMessageContext* context, + const ppapi::HostResource& graphics_context, + PP_VideoProfile profile, + bool allow_software_fallback); + int32_t OnHostMsgGetShm(ppapi::host::HostMessageContext* context, + uint32_t shm_id, + uint32_t shm_size); + int32_t OnHostMsgDecode(ppapi::host::HostMessageContext* context, + uint32_t shm_id, + uint32_t size, + int32_t decode_id); + int32_t OnHostMsgAssignTextures(ppapi::host::HostMessageContext* context, + const PP_Size& size, + const std::vector<uint32_t>& texture_ids); + int32_t OnHostMsgRecyclePicture(ppapi::host::HostMessageContext* context, + uint32_t picture_id); + int32_t OnHostMsgFlush(ppapi::host::HostMessageContext* context); + int32_t OnHostMsgReset(ppapi::host::HostMessageContext* context); + + // These methods are needed by VideoDecodeShim, to look like a + // VideoDecodeAccelerator. + void OnInitializeComplete(int32_t result); + const uint8_t* DecodeIdToAddress(uint32_t decode_id); + void RequestTextures(uint32 requested_num_of_buffers, + const gfx::Size& dimensions, + uint32 texture_target, + const std::vector<gpu::Mailbox>& mailboxes); + + // Non-owning pointer. + RendererPpapiHost* renderer_ppapi_host_; + + scoped_ptr<media::VideoDecodeAccelerator> decoder_; + + // A vector holding our shm buffers, in sync with a similar vector in the + // resource. We use a buffer's index in these vectors as its id on both sides + // of the proxy. Only add buffers or update them in place so as not to + // invalidate these ids. + ScopedVector<base::SharedMemory> shm_buffers_; + // A vector of true/false indicating if a shm buffer is in use by the decoder. + // This is parallel to |shm_buffers_|. + std::vector<uint8_t> shm_buffer_busy_; + + // Maps decode uid to PendingDecode info. + typedef base::hash_map<int32_t, PendingDecode> PendingDecodeMap; + PendingDecodeMap pending_decodes_; + + ppapi::host::ReplyMessageContext flush_reply_context_; + ppapi::host::ReplyMessageContext reset_reply_context_; + // Only used when in software fallback mode. + ppapi::host::ReplyMessageContext initialize_reply_context_; + + bool initialized_; + + DISALLOW_COPY_AND_ASSIGN(PepperVideoDecoderHost); +}; + +} // namespace content + +#endif // CONTENT_RENDERER_PEPPER_PEPPER_VIDEO_DECODER_HOST_H_ diff --git a/chromium/content/renderer/pepper/pepper_video_destination_host.cc b/chromium/content/renderer/pepper/pepper_video_destination_host.cc index 4c19b90d8ee..5254374b1b0 100644 --- a/chromium/content/renderer/pepper/pepper_video_destination_host.cc +++ b/chromium/content/renderer/pepper/pepper_video_destination_host.cc @@ -20,29 +20,26 @@ using ppapi::host::ReplyMessageContext; namespace content { -PepperVideoDestinationHost::PepperVideoDestinationHost( - RendererPpapiHost* host, - PP_Instance instance, - PP_Resource resource) +PepperVideoDestinationHost::PepperVideoDestinationHost(RendererPpapiHost* host, + PP_Instance instance, + PP_Resource resource) : ResourceHost(host->GetPpapiHost(), instance, resource), renderer_ppapi_host_(host), - weak_factory_(this) { -} + weak_factory_(this) {} -PepperVideoDestinationHost::~PepperVideoDestinationHost() { -} +PepperVideoDestinationHost::~PepperVideoDestinationHost() {} int32_t PepperVideoDestinationHost::OnResourceMessageReceived( const IPC::Message& msg, HostMessageContext* context) { - IPC_BEGIN_MESSAGE_MAP(PepperVideoDestinationHost, msg) + PPAPI_BEGIN_MESSAGE_MAP(PepperVideoDestinationHost, msg) PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_VideoDestination_Open, OnHostMsgOpen) PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_VideoDestination_PutFrame, OnHostMsgPutFrame) PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_VideoDestination_Close, OnHostMsgClose) - IPC_END_MESSAGE_MAP() + PPAPI_END_MESSAGE_MAP() return PP_ERROR_FAILED; } @@ -54,17 +51,14 @@ int32_t PepperVideoDestinationHost::OnHostMsgOpen( return PP_ERROR_BADARGUMENT; FrameWriterInterface* frame_writer = NULL; - if (!VideoDestinationHandler::Open(NULL /* factory */, - NULL /* registry */, - gurl.spec(), - &frame_writer)) + if (!VideoDestinationHandler::Open( + NULL /* registry */, gurl.spec(), &frame_writer)) return PP_ERROR_FAILED; frame_writer_.reset(frame_writer); ReplyMessageContext reply_context = context->MakeReplyMessageContext(); reply_context.params.set_result(PP_OK); - host()->SendReply(reply_context, - PpapiPluginMsg_VideoDestination_OpenReply()); + host()->SendReply(reply_context, PpapiPluginMsg_VideoDestination_OpenReply()); return PP_OK_COMPLETIONPENDING; } diff --git a/chromium/content/renderer/pepper/pepper_video_destination_host.h b/chromium/content/renderer/pepper/pepper_video_destination_host.h index 1f4819033ce..277b6681fc5 100644 --- a/chromium/content/renderer/pepper/pepper_video_destination_host.h +++ b/chromium/content/renderer/pepper/pepper_video_destination_host.h @@ -9,7 +9,7 @@ #include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" #include "content/common/content_export.h" -#include "content/renderer/media/video_destination_handler.h" +#include "content/renderer/media/webrtc/video_destination_handler.h" #include "ppapi/c/pp_time.h" #include "ppapi/host/resource_host.h" diff --git a/chromium/content/renderer/pepper/pepper_video_source_host.cc b/chromium/content/renderer/pepper/pepper_video_source_host.cc index 2a8bd935934..d90ed26e8e7 100644 --- a/chromium/content/renderer/pepper/pepper_video_source_host.cc +++ b/chromium/content/renderer/pepper/pepper_video_source_host.cc @@ -5,7 +5,7 @@ #include "content/renderer/pepper/pepper_video_source_host.h" #include "base/bind.h" -#include "base/safe_numerics.h" +#include "base/numerics/safe_conversions.h" #include "content/public/renderer/renderer_ppapi_host.h" #include "content/renderer/pepper/ppb_image_data_impl.h" #include "content/renderer/render_thread_impl.h" @@ -17,8 +17,7 @@ #include "ppapi/shared_impl/scoped_pp_resource.h" #include "ppapi/thunk/enter.h" #include "ppapi/thunk/ppb_image_data_api.h" -#include "third_party/libjingle/source/talk/media/base/videocommon.h" -#include "third_party/libjingle/source/talk/media/base/videoframe.h" +#include "third_party/libyuv/include/libyuv/convert.h" #include "third_party/skia/include/core/SkBitmap.h" using ppapi::host::HostMessageContext; @@ -29,40 +28,34 @@ namespace content { PepperVideoSourceHost::FrameReceiver::FrameReceiver( const base::WeakPtr<PepperVideoSourceHost>& host) : host_(host), - main_message_loop_proxy_(base::MessageLoopProxy::current()) { -} + main_message_loop_proxy_(base::MessageLoopProxy::current()) {} -PepperVideoSourceHost::FrameReceiver::~FrameReceiver() { -} +PepperVideoSourceHost::FrameReceiver::~FrameReceiver() {} bool PepperVideoSourceHost::FrameReceiver::GotFrame( - cricket::VideoFrame* frame) { + const scoped_refptr<media::VideoFrame>& frame) { // It's not safe to access the host from this thread, so post a task to our // main thread to transfer the new frame. main_message_loop_proxy_->PostTask( - FROM_HERE, - base::Bind(&FrameReceiver::OnGotFrame, - this, - base::Passed(scoped_ptr<cricket::VideoFrame>(frame)))); + FROM_HERE, base::Bind(&FrameReceiver::OnGotFrame, this, frame)); return true; } void PepperVideoSourceHost::FrameReceiver::OnGotFrame( - scoped_ptr<cricket::VideoFrame> frame) { + const scoped_refptr<media::VideoFrame>& frame) { if (host_.get()) { - // Take ownership of the new frame, and possibly delete any unsent one. - host_->last_frame_.swap(frame); + // Hold a reference to the new frame and release the previous. + host_->last_frame_ = frame; if (host_->get_frame_pending_) host_->SendGetFrameReply(); } } -PepperVideoSourceHost::PepperVideoSourceHost( - RendererPpapiHost* host, - PP_Instance instance, - PP_Resource resource) +PepperVideoSourceHost::PepperVideoSourceHost(RendererPpapiHost* host, + PP_Instance instance, + PP_Resource resource) : ResourceHost(host->GetPpapiHost(), instance, resource), renderer_ppapi_host_(host), source_handler_(new VideoSourceHandler(NULL)), @@ -71,21 +64,19 @@ PepperVideoSourceHost::PepperVideoSourceHost( frame_receiver_ = new FrameReceiver(weak_factory_.GetWeakPtr()); } -PepperVideoSourceHost::~PepperVideoSourceHost() { - Close(); -} +PepperVideoSourceHost::~PepperVideoSourceHost() { Close(); } int32_t PepperVideoSourceHost::OnResourceMessageReceived( const IPC::Message& msg, HostMessageContext* context) { - IPC_BEGIN_MESSAGE_MAP(PepperVideoSourceHost, msg) + PPAPI_BEGIN_MESSAGE_MAP(PepperVideoSourceHost, msg) PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_VideoSource_Open, OnHostMsgOpen) PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_VideoSource_GetFrame, OnHostMsgGetFrame) PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_VideoSource_Close, OnHostMsgClose) - IPC_END_MESSAGE_MAP() + PPAPI_END_MESSAGE_MAP() return PP_ERROR_FAILED; } @@ -132,10 +123,12 @@ void PepperVideoSourceHost::SendGetFrameReply() { get_frame_pending_ = false; DCHECK(last_frame_.get()); - scoped_ptr<cricket::VideoFrame> frame(last_frame_.release()); + scoped_refptr<media::VideoFrame> frame(last_frame_); + last_frame_ = NULL; + + const int dst_width = frame->visible_rect().width(); + const int dst_height = frame->visible_rect().height(); - int32_t width = base::checked_numeric_cast<int32_t>(frame->GetWidth()); - int32_t height = base::checked_numeric_cast<int32_t>(frame->GetHeight()); PP_ImageDataDesc image_desc; IPC::PlatformFileForTransit image_handle; uint32_t byte_count; @@ -145,9 +138,11 @@ void PepperVideoSourceHost::SendGetFrameReply() { pp_instance(), ppapi::PPB_ImageData_Shared::SIMPLE, PP_IMAGEDATAFORMAT_BGRA_PREMUL, - PP_MakeSize(width, height), + PP_MakeSize(dst_width, dst_height), false /* init_to_zero */, - &image_desc, &image_handle, &byte_count)); + &image_desc, + &image_handle, + &byte_count)); if (!resource.get()) { SendGetFrameErrorReply(PP_ERROR_FAILED); return; @@ -179,30 +174,48 @@ void PepperVideoSourceHost::SendGetFrameReply() { return; } - size_t bitmap_size = bitmap->getSize(); - frame->ConvertToRgbBuffer(cricket::FOURCC_BGRA, - bitmap_pixels, - bitmap_size, - bitmap->rowBytes()); + // Calculate that portion of the |frame| that should be copied into + // |bitmap|. If |frame| has been cropped, + // frame->coded_size() != frame->visible_rect(). + const int src_width = frame->coded_size().width(); + const int src_height = frame->coded_size().height(); + DCHECK(src_width >= dst_width && src_height >= dst_height); + + const int horiz_crop = frame->visible_rect().x(); + const int vert_crop = frame->visible_rect().y(); + + const uint8* src_y = frame->data(media::VideoFrame::kYPlane) + + (src_width * vert_crop + horiz_crop); + const int center = (src_width + 1) / 2; + const uint8* src_u = frame->data(media::VideoFrame::kUPlane) + + (center * vert_crop + horiz_crop) / 2; + const uint8* src_v = frame->data(media::VideoFrame::kVPlane) + + (center * vert_crop + horiz_crop) / 2; + + libyuv::I420ToBGRA(src_y, + frame->stride(media::VideoFrame::kYPlane), + src_u, + frame->stride(media::VideoFrame::kUPlane), + src_v, + frame->stride(media::VideoFrame::kVPlane), + bitmap_pixels, + bitmap->rowBytes(), + dst_width, + dst_height); ppapi::HostResource host_resource; host_resource.SetHostResource(pp_instance(), resource.get()); - // Convert a video timestamp (int64, in nanoseconds) to a time delta (int64, - // microseconds) and then to a PP_TimeTicks (a double, in seconds). All times - // are relative to the Unix Epoch. - base::TimeDelta time_delta = base::TimeDelta::FromMicroseconds( - frame->GetTimeStamp() / base::Time::kNanosecondsPerMicrosecond); - PP_TimeTicks timestamp = time_delta.InSecondsF(); + // Convert a video timestamp to a PP_TimeTicks (a double, in seconds). + PP_TimeTicks timestamp = frame->timestamp().InSecondsF(); ppapi::proxy::SerializedHandle serialized_handle; serialized_handle.set_shmem(image_handle, byte_count); reply_context_.params.AppendHandle(serialized_handle); host()->SendReply(reply_context_, - PpapiPluginMsg_VideoSource_GetFrameReply(host_resource, - image_desc, - timestamp)); + PpapiPluginMsg_VideoSource_GetFrameReply( + host_resource, image_desc, timestamp)); reply_context_ = ppapi::host::ReplyMessageContext(); @@ -214,15 +227,14 @@ void PepperVideoSourceHost::SendGetFrameErrorReply(int32_t error) { reply_context_.params.set_result(error); host()->SendReply( reply_context_, - PpapiPluginMsg_VideoSource_GetFrameReply(ppapi::HostResource(), - PP_ImageDataDesc(), - 0.0 /* timestamp */)); + PpapiPluginMsg_VideoSource_GetFrameReply( + ppapi::HostResource(), PP_ImageDataDesc(), 0.0 /* timestamp */)); reply_context_ = ppapi::host::ReplyMessageContext(); } void PepperVideoSourceHost::Close() { if (source_handler_.get() && !stream_url_.empty()) - source_handler_->Close(stream_url_, frame_receiver_.get()); + source_handler_->Close(frame_receiver_.get()); source_handler_.reset(NULL); stream_url_.clear(); diff --git a/chromium/content/renderer/pepper/pepper_video_source_host.h b/chromium/content/renderer/pepper/pepper_video_source_host.h index f2ddfa41e7b..a1414ceadeb 100644 --- a/chromium/content/renderer/pepper/pepper_video_source_host.h +++ b/chromium/content/renderer/pepper/pepper_video_source_host.h @@ -42,9 +42,10 @@ class CONTENT_EXPORT PepperVideoSourceHost : public ppapi::host::ResourceHost { explicit FrameReceiver(const base::WeakPtr<PepperVideoSourceHost>& host); // FrameReaderInterface implementation. - virtual bool GotFrame(cricket::VideoFrame* frame) OVERRIDE; + virtual bool GotFrame(const scoped_refptr<media::VideoFrame>& frame) + OVERRIDE; - void OnGotFrame(scoped_ptr<cricket::VideoFrame> frame); + void OnGotFrame(const scoped_refptr<media::VideoFrame>& frame); private: friend class base::RefCountedThreadSafe<FrameReceiver>; @@ -76,7 +77,7 @@ class CONTENT_EXPORT PepperVideoSourceHost : public ppapi::host::ResourceHost { scoped_ptr<VideoSourceHandler> source_handler_; scoped_refptr<FrameReceiver> frame_receiver_; std::string stream_url_; - scoped_ptr<cricket::VideoFrame> last_frame_; + scoped_refptr<media::VideoFrame> last_frame_; bool get_frame_pending_; base::WeakPtrFactory<PepperVideoSourceHost> weak_factory_; diff --git a/chromium/content/renderer/pepper/pepper_webplugin_impl.cc b/chromium/content/renderer/pepper/pepper_webplugin_impl.cc index 129ee455222..828da7a3d87 100644 --- a/chromium/content/renderer/pepper/pepper_webplugin_impl.cc +++ b/chromium/content/renderer/pepper/pepper_webplugin_impl.cc @@ -14,7 +14,7 @@ #include "content/renderer/pepper/npobject_var.h" #include "content/renderer/pepper/pepper_plugin_instance_impl.h" #include "content/renderer/pepper/plugin_module.h" -#include "content/renderer/render_view_impl.h" +#include "content/renderer/render_frame_impl.h" #include "ppapi/shared_impl/ppapi_globals.h" #include "ppapi/shared_impl/var_tracker.h" #include "third_party/WebKit/public/platform/WebPoint.h" @@ -48,25 +48,21 @@ namespace content { struct PepperWebPluginImpl::InitData { scoped_refptr<PluginModule> module; - base::WeakPtr<RenderViewImpl> render_view; - RenderFrame* render_frame; + RenderFrameImpl* render_frame; std::vector<std::string> arg_names; std::vector<std::string> arg_values; GURL url; }; -PepperWebPluginImpl::PepperWebPluginImpl( - PluginModule* plugin_module, - const WebPluginParams& params, - const base::WeakPtr<RenderViewImpl>& render_view, - RenderFrame* render_frame) +PepperWebPluginImpl::PepperWebPluginImpl(PluginModule* plugin_module, + const WebPluginParams& params, + RenderFrameImpl* render_frame) : init_data_(new InitData()), full_frame_(params.loadManually), instance_object_(PP_MakeUndefined()), container_(NULL) { DCHECK(plugin_module); init_data_->module = plugin_module; - init_data_->render_view = render_view; init_data_->render_frame = render_frame; for (size_t i = 0; i < params.attributeNames.size(); ++i) { init_data_->arg_names.push_back(params.attributeNames[i].utf8()); @@ -78,8 +74,7 @@ PepperWebPluginImpl::PepperWebPluginImpl( base::debug::SetCrashKeyValue("subresource_url", init_data_->url.spec()); } -PepperWebPluginImpl::~PepperWebPluginImpl() { -} +PepperWebPluginImpl::~PepperWebPluginImpl() {} blink::WebPluginContainer* PepperWebPluginImpl::container() const { return container_; @@ -88,16 +83,15 @@ blink::WebPluginContainer* PepperWebPluginImpl::container() const { bool PepperWebPluginImpl::initialize(WebPluginContainer* container) { // The plugin delegate may have gone away. instance_ = init_data_->module->CreateInstance( - init_data_->render_view->main_render_frame(), container, init_data_->url); + init_data_->render_frame, container, init_data_->url); if (!instance_.get()) return false; // Enable script objects for this plugin. container->allowScriptObjects(); - bool success = instance_->Initialize(init_data_->arg_names, - init_data_->arg_values, - full_frame_); + bool success = instance_->Initialize( + init_data_->arg_names, init_data_->arg_values, full_frame_); if (!success) { instance_->Delete(); instance_ = NULL; @@ -154,13 +148,9 @@ NPObject* PepperWebPluginImpl::scriptableObject() { return message_channel_np_object; } -NPP PepperWebPluginImpl::pluginNPP() { - return instance_->instanceNPP(); -} +NPP PepperWebPluginImpl::pluginNPP() { return instance_->instanceNPP(); } -bool PepperWebPluginImpl::getFormValue(WebString& value) { - return false; -} +bool PepperWebPluginImpl::getFormValue(WebString& value) { return false; } void PepperWebPluginImpl::paint(WebCanvas* canvas, const WebRect& rect) { if (!instance_->FlashIsFullscreenOrPending()) @@ -185,12 +175,9 @@ void PepperWebPluginImpl::updateFocus(bool focused) { instance_->SetWebKitFocus(focused); } -void PepperWebPluginImpl::updateVisibility(bool visible) { -} +void PepperWebPluginImpl::updateVisibility(bool visible) {} -bool PepperWebPluginImpl::acceptsInputEvents() { - return true; -} +bool PepperWebPluginImpl::acceptsInputEvents() { return true; } bool PepperWebPluginImpl::handleInputEvent(const blink::WebInputEvent& event, blink::WebCursorInfo& cursor_info) { @@ -214,7 +201,8 @@ void PepperWebPluginImpl::didReceiveData(const char* data, int data_length) { void PepperWebPluginImpl::didFinishLoading() { blink::WebURLLoaderClient* document_loader = instance_->document_loader(); if (document_loader) - document_loader->didFinishLoading(NULL, 0.0); + document_loader->didFinishLoading( + NULL, 0.0, blink::WebURLLoaderClient::kUnknownEncodedDataLength); } void PepperWebPluginImpl::didFailLoading(const blink::WebURLError& error) { @@ -223,16 +211,13 @@ void PepperWebPluginImpl::didFailLoading(const blink::WebURLError& error) { document_loader->didFail(NULL, error); } -void PepperWebPluginImpl::didFinishLoadingFrameRequest( - const blink::WebURL& url, - void* notify_data) { -} +void PepperWebPluginImpl::didFinishLoadingFrameRequest(const blink::WebURL& url, + void* notify_data) {} void PepperWebPluginImpl::didFailLoadingFrameRequest( const blink::WebURL& url, void* notify_data, - const blink::WebURLError& error) { -} + const blink::WebURLError& error) {} bool PepperWebPluginImpl::hasSelection() const { return !selectionAsText().isEmpty(); @@ -264,9 +249,7 @@ void PepperWebPluginImpl::selectFindResult(bool forward) { instance_->SelectFindResult(forward); } -void PepperWebPluginImpl::stopFind() { - instance_->StopFind(); -} +void PepperWebPluginImpl::stopFind() { instance_->StopFind(); } bool PepperWebPluginImpl::supportsPaginatedPrint() { return instance_->SupportsPrintInterface(); @@ -280,25 +263,18 @@ int PepperWebPluginImpl::printBegin(const WebPrintParams& print_params) { return instance_->PrintBegin(print_params); } -bool PepperWebPluginImpl::printPage(int page_number, - blink::WebCanvas* canvas) { +bool PepperWebPluginImpl::printPage(int page_number, blink::WebCanvas* canvas) { return instance_->PrintPage(page_number, canvas); } -void PepperWebPluginImpl::printEnd() { - return instance_->PrintEnd(); -} +void PepperWebPluginImpl::printEnd() { return instance_->PrintEnd(); } -bool PepperWebPluginImpl::canRotateView() { - return instance_->CanRotateView(); -} +bool PepperWebPluginImpl::canRotateView() { return instance_->CanRotateView(); } void PepperWebPluginImpl::rotateView(RotationType type) { instance_->RotateView(type); } -bool PepperWebPluginImpl::isPlaceholder() { - return false; -} +bool PepperWebPluginImpl::isPlaceholder() { return false; } } // namespace content diff --git a/chromium/content/renderer/pepper/pepper_webplugin_impl.h b/chromium/content/renderer/pepper/pepper_webplugin_impl.h index 600dd578d5b..cee66902371 100644 --- a/chromium/content/renderer/pepper/pepper_webplugin_impl.h +++ b/chromium/content/renderer/pepper/pepper_webplugin_impl.h @@ -27,15 +27,13 @@ namespace content { class PepperPluginInstanceImpl; class PluginModule; class PPB_URLLoader_Impl; -class RenderFrame; -class RenderViewImpl; +class RenderFrameImpl; class PepperWebPluginImpl : public blink::WebPlugin { public: PepperWebPluginImpl(PluginModule* module, const blink::WebPluginParams& params, - const base::WeakPtr<RenderViewImpl>& render_view, - RenderFrame* render_frame); + RenderFrameImpl* render_frame); PepperPluginInstanceImpl* instance() { return instance_.get(); } diff --git a/chromium/content/renderer/pepper/pepper_websocket_host.cc b/chromium/content/renderer/pepper/pepper_websocket_host.cc index a88fdb54e47..9b74ccc2dc5 100644 --- a/chromium/content/renderer/pepper/pepper_websocket_host.cc +++ b/chromium/content/renderer/pepper/pepper_websocket_host.cc @@ -30,17 +30,49 @@ using blink::WebURL; namespace content { -PepperWebSocketHost::PepperWebSocketHost( - RendererPpapiHost* host, - PP_Instance instance, - PP_Resource resource) +#define COMPILE_ASSERT_MATCHING_ENUM(webkit_name, np_name) \ + COMPILE_ASSERT( \ + static_cast<int>(WebSocket::webkit_name) == static_cast<int>(np_name), \ + mismatching_enums) + +COMPILE_ASSERT_MATCHING_ENUM(CloseEventCodeNormalClosure, + PP_WEBSOCKETSTATUSCODE_NORMAL_CLOSURE); +COMPILE_ASSERT_MATCHING_ENUM(CloseEventCodeGoingAway, + PP_WEBSOCKETSTATUSCODE_GOING_AWAY); +COMPILE_ASSERT_MATCHING_ENUM(CloseEventCodeProtocolError, + PP_WEBSOCKETSTATUSCODE_PROTOCOL_ERROR); +COMPILE_ASSERT_MATCHING_ENUM(CloseEventCodeUnsupportedData, + PP_WEBSOCKETSTATUSCODE_UNSUPPORTED_DATA); +COMPILE_ASSERT_MATCHING_ENUM(CloseEventCodeNoStatusRcvd, + PP_WEBSOCKETSTATUSCODE_NO_STATUS_RECEIVED); +COMPILE_ASSERT_MATCHING_ENUM(CloseEventCodeAbnormalClosure, + PP_WEBSOCKETSTATUSCODE_ABNORMAL_CLOSURE); +COMPILE_ASSERT_MATCHING_ENUM(CloseEventCodeInvalidFramePayloadData, + PP_WEBSOCKETSTATUSCODE_INVALID_FRAME_PAYLOAD_DATA); +COMPILE_ASSERT_MATCHING_ENUM(CloseEventCodePolicyViolation, + PP_WEBSOCKETSTATUSCODE_POLICY_VIOLATION); +COMPILE_ASSERT_MATCHING_ENUM(CloseEventCodeMessageTooBig, + PP_WEBSOCKETSTATUSCODE_MESSAGE_TOO_BIG); +COMPILE_ASSERT_MATCHING_ENUM(CloseEventCodeMandatoryExt, + PP_WEBSOCKETSTATUSCODE_MANDATORY_EXTENSION); +COMPILE_ASSERT_MATCHING_ENUM(CloseEventCodeInternalError, + PP_WEBSOCKETSTATUSCODE_INTERNAL_SERVER_ERROR); +COMPILE_ASSERT_MATCHING_ENUM(CloseEventCodeTLSHandshake, + PP_WEBSOCKETSTATUSCODE_TLS_HANDSHAKE); +COMPILE_ASSERT_MATCHING_ENUM(CloseEventCodeMinimumUserDefined, + PP_WEBSOCKETSTATUSCODE_USER_REGISTERED_MIN); +COMPILE_ASSERT_MATCHING_ENUM(CloseEventCodeMaximumUserDefined, + PP_WEBSOCKETSTATUSCODE_USER_PRIVATE_MAX); + +PepperWebSocketHost::PepperWebSocketHost(RendererPpapiHost* host, + PP_Instance instance, + PP_Resource resource) : ResourceHost(host->GetPpapiHost(), instance, resource), renderer_ppapi_host_(host), connecting_(false), initiating_close_(false), accepting_close_(false), - error_was_received_(false) { -} + error_was_received_(false) {} PepperWebSocketHost::~PepperWebSocketHost() { if (websocket_) @@ -50,7 +82,7 @@ PepperWebSocketHost::~PepperWebSocketHost() { int32_t PepperWebSocketHost::OnResourceMessageReceived( const IPC::Message& msg, ppapi::host::HostMessageContext* context) { - IPC_BEGIN_MESSAGE_MAP(PepperWebSocketHost, msg) + PPAPI_BEGIN_MESSAGE_MAP(PepperWebSocketHost, msg) PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_WebSocket_Connect, OnHostMsgConnect) PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_WebSocket_Close, @@ -61,7 +93,7 @@ int32_t PepperWebSocketHost::OnResourceMessageReceived( OnHostMsgSendBinary) PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_WebSocket_Fail, OnHostMsgFail) - IPC_END_MESSAGE_MAP() + PPAPI_END_MESSAGE_MAP() return PP_ERROR_FAILED; } @@ -72,9 +104,7 @@ void PepperWebSocketHost::didConnect() { connecting_ = false; connect_reply_.params.set_result(PP_OK); host()->SendReply(connect_reply_, - PpapiPluginMsg_WebSocket_ConnectReply( - url_, - protocol)); + PpapiPluginMsg_WebSocket_ConnectReply(url_, protocol)); } void PepperWebSocketHost::didReceiveMessage(const blink::WebString& message) { @@ -84,9 +114,8 @@ void PepperWebSocketHost::didReceiveMessage(const blink::WebString& message) { // Send an IPC to transport received data. std::string string_message = message.utf8(); - host()->SendUnsolicitedReply(pp_resource(), - PpapiPluginMsg_WebSocket_ReceiveTextReply( - string_message)); + host()->SendUnsolicitedReply( + pp_resource(), PpapiPluginMsg_WebSocket_ReceiveTextReply(string_message)); } void PepperWebSocketHost::didReceiveArrayBuffer( @@ -98,9 +127,9 @@ void PepperWebSocketHost::didReceiveArrayBuffer( // Send an IPC to transport received data. uint8_t* data = static_cast<uint8_t*>(binaryData.data()); std::vector<uint8_t> array_message(data, data + binaryData.byteLength()); - host()->SendUnsolicitedReply(pp_resource(), - PpapiPluginMsg_WebSocket_ReceiveBinaryReply( - array_message)); + host()->SendUnsolicitedReply( + pp_resource(), + PpapiPluginMsg_WebSocket_ReceiveBinaryReply(array_message)); } void PepperWebSocketHost::didReceiveMessageError() { @@ -118,18 +147,18 @@ void PepperWebSocketHost::didReceiveMessageError() { void PepperWebSocketHost::didUpdateBufferedAmount( unsigned long buffered_amount) { // Send an IPC to update buffered amount. - host()->SendUnsolicitedReply(pp_resource(), - PpapiPluginMsg_WebSocket_BufferedAmountReply( - buffered_amount)); + host()->SendUnsolicitedReply( + pp_resource(), + PpapiPluginMsg_WebSocket_BufferedAmountReply(buffered_amount)); } void PepperWebSocketHost::didStartClosingHandshake() { accepting_close_ = true; // Send an IPC to notice that server starts closing handshake. - host()->SendUnsolicitedReply(pp_resource(), - PpapiPluginMsg_WebSocket_StateReply( - PP_WEBSOCKETREADYSTATE_CLOSING)); + host()->SendUnsolicitedReply( + pp_resource(), + PpapiPluginMsg_WebSocket_StateReply(PP_WEBSOCKETREADYSTATE_CLOSING)); } void PepperWebSocketHost::didClose(unsigned long unhandled_buffered_amount, @@ -145,27 +174,23 @@ void PepperWebSocketHost::didClose(unsigned long unhandled_buffered_amount, } // Set close_was_clean_. - bool was_clean = - (initiating_close_ || accepting_close_) && - !unhandled_buffered_amount && - status == WebSocketClient::ClosingHandshakeComplete; + bool was_clean = (initiating_close_ || accepting_close_) && + !unhandled_buffered_amount && + status == WebSocketClient::ClosingHandshakeComplete; if (initiating_close_) { initiating_close_ = false; close_reply_.params.set_result(PP_OK); - host()->SendReply(close_reply_, PpapiPluginMsg_WebSocket_CloseReply( - unhandled_buffered_amount, - was_clean, - code, - reason.utf8())); + host()->SendReply( + close_reply_, + PpapiPluginMsg_WebSocket_CloseReply( + unhandled_buffered_amount, was_clean, code, reason.utf8())); } else { accepting_close_ = false; - host()->SendUnsolicitedReply(pp_resource(), - PpapiPluginMsg_WebSocket_ClosedReply( - unhandled_buffered_amount, - was_clean, - code, - reason.utf8())); + host()->SendUnsolicitedReply( + pp_resource(), + PpapiPluginMsg_WebSocket_ClosedReply( + unhandled_buffered_amount, was_clean, code, reason.utf8())); } // Disconnect. @@ -198,8 +223,8 @@ int32_t PepperWebSocketHost::OnHostMsgConnect( // Check containing characters. for (std::string::const_iterator string_it = vector_it->begin(); - string_it != vector_it->end(); - ++string_it) { + string_it != vector_it->end(); + ++string_it) { uint8_t character = *string_it; // WebSocket specification says "(Subprotocol string must consist of) // characters in the range U+0021 to U+007E not including separator @@ -207,12 +232,13 @@ int32_t PepperWebSocketHost::OnHostMsgConnect( const uint8_t minimumProtocolCharacter = '!'; // U+0021. const uint8_t maximumProtocolCharacter = '~'; // U+007E. if (character < minimumProtocolCharacter || - character > maximumProtocolCharacter || - character == '"' || character == '(' || character == ')' || - character == ',' || character == '/' || + character > maximumProtocolCharacter || character == '"' || + character == '(' || character == ')' || character == ',' || + character == '/' || (character >= ':' && character <= '@') || // U+003A - U+0040 (character >= '[' && character <= ']') || // U+005B - u+005D - character == '{' || character == '}') + character == '{' || + character == '}') return PP_ERROR_BADARGUMENT; } // Join protocols with the comma separator. @@ -253,8 +279,18 @@ int32_t PepperWebSocketHost::OnHostMsgClose( return PP_ERROR_FAILED; close_reply_ = context->MakeReplyMessageContext(); initiating_close_ = true; + + blink::WebSocket::CloseEventCode event_code = + static_cast<blink::WebSocket::CloseEventCode>(code); + if (code == PP_WEBSOCKETSTATUSCODE_NOT_SPECIFIED) { + // PP_WEBSOCKETSTATUSCODE_NOT_SPECIFIED and CloseEventCodeNotSpecified are + // assigned to different values. A conversion is needed if + // PP_WEBSOCKETSTATUSCODE_NOT_SPECIFIED is specified. + event_code = blink::WebSocket::CloseEventCodeNotSpecified; + } + WebString web_reason = WebString::fromUTF8(reason); - websocket_->close(code, web_reason); + websocket_->close(event_code, web_reason); return PP_OK_COMPLETIONPENDING; } diff --git a/chromium/content/renderer/pepper/pepper_websocket_host.h b/chromium/content/renderer/pepper/pepper_websocket_host.h index 3447fcf91a7..091b3e12791 100644 --- a/chromium/content/renderer/pepper/pepper_websocket_host.h +++ b/chromium/content/renderer/pepper/pepper_websocket_host.h @@ -49,6 +49,7 @@ class CONTENT_EXPORT PepperWebSocketHost ClosingHandshakeCompletionStatus status, unsigned short code, const blink::WebString& reason); + private: // IPC message handlers. int32_t OnHostMsgConnect(ppapi::host::HostMessageContext* context, diff --git a/chromium/content/renderer/pepper/plugin_module.cc b/chromium/content/renderer/pepper/plugin_module.cc index 8ffc89e7adc..48add88a06a 100644 --- a/chromium/content/renderer/pepper/plugin_module.cc +++ b/chromium/content/renderer/pepper/plugin_module.cc @@ -25,12 +25,10 @@ #include "content/renderer/pepper/ppb_image_data_impl.h" #include "content/renderer/pepper/ppb_proxy_impl.h" #include "content/renderer/pepper/ppb_scrollbar_impl.h" -#include "content/renderer/pepper/ppb_uma_private_impl.h" #include "content/renderer/pepper/ppb_var_deprecated_impl.h" #include "content/renderer/pepper/ppb_video_decoder_impl.h" #include "content/renderer/pepper/renderer_ppapi_host_impl.h" #include "content/renderer/render_view_impl.h" -#include "ppapi/c/dev/ppb_alarms_dev.h" #include "ppapi/c/dev/ppb_audio_input_dev.h" #include "ppapi/c/dev/ppb_buffer_dev.h" #include "ppapi/c/dev/ppb_char_set_dev.h" @@ -38,35 +36,34 @@ #include "ppapi/c/dev/ppb_cursor_control_dev.h" #include "ppapi/c/dev/ppb_device_ref_dev.h" #include "ppapi/c/dev/ppb_file_chooser_dev.h" -#include "ppapi/c/dev/ppb_find_dev.h" #include "ppapi/c/dev/ppb_font_dev.h" #include "ppapi/c/dev/ppb_gles_chromium_texture_mapping_dev.h" -#include "ppapi/c/dev/ppb_graphics_2d_dev.h" #include "ppapi/c/dev/ppb_memory_dev.h" #include "ppapi/c/dev/ppb_opengles2ext_dev.h" #include "ppapi/c/dev/ppb_printing_dev.h" -#include "ppapi/c/dev/ppb_resource_array_dev.h" #include "ppapi/c/dev/ppb_scrollbar_dev.h" #include "ppapi/c/dev/ppb_text_input_dev.h" #include "ppapi/c/dev/ppb_trace_event_dev.h" #include "ppapi/c/dev/ppb_truetype_font_dev.h" #include "ppapi/c/dev/ppb_url_util_dev.h" #include "ppapi/c/dev/ppb_var_deprecated.h" -#include "ppapi/c/dev/ppb_var_resource_dev.h" #include "ppapi/c/dev/ppb_video_capture_dev.h" #include "ppapi/c/dev/ppb_video_decoder_dev.h" #include "ppapi/c/dev/ppb_view_dev.h" #include "ppapi/c/dev/ppb_widget_dev.h" #include "ppapi/c/dev/ppb_zoom_dev.h" -#include "ppapi/c/extensions/dev/ppb_ext_socket_dev.h" #include "ppapi/c/pp_module.h" #include "ppapi/c/pp_resource.h" #include "ppapi/c/pp_var.h" #include "ppapi/c/ppb_audio.h" +#include "ppapi/c/ppb_audio_buffer.h" #include "ppapi/c/ppb_audio_config.h" +#include "ppapi/c/ppb_compositor.h" +#include "ppapi/c/ppb_compositor_layer.h" #include "ppapi/c/ppb_console.h" #include "ppapi/c/ppb_core.h" #include "ppapi/c/ppb_file_io.h" +#include "ppapi/c/ppb_file_mapping.h" #include "ppapi/c/ppb_file_ref.h" #include "ppapi/c/ppb_file_system.h" #include "ppapi/c/ppb_fullscreen.h" @@ -75,6 +72,8 @@ #include "ppapi/c/ppb_host_resolver.h" #include "ppapi/c/ppb_image_data.h" #include "ppapi/c/ppb_instance.h" +#include "ppapi/c/ppb_media_stream_audio_track.h" +#include "ppapi/c/ppb_media_stream_video_track.h" #include "ppapi/c/ppb_messaging.h" #include "ppapi/c/ppb_mouse_cursor.h" #include "ppapi/c/ppb_mouse_lock.h" @@ -93,12 +92,15 @@ #include "ppapi/c/ppb_var_array.h" #include "ppapi/c/ppb_var_array_buffer.h" #include "ppapi/c/ppb_var_dictionary.h" +#include "ppapi/c/ppb_video_decoder.h" +#include "ppapi/c/ppb_video_frame.h" #include "ppapi/c/ppb_view.h" #include "ppapi/c/ppp.h" #include "ppapi/c/ppp_instance.h" #include "ppapi/c/private/ppb_ext_crx_file_system_private.h" #include "ppapi/c/private/ppb_file_io_private.h" #include "ppapi/c/private/ppb_file_ref_private.h" +#include "ppapi/c/private/ppb_find_private.h" #include "ppapi/c/private/ppb_flash.h" #include "ppapi/c/private/ppb_flash_clipboard.h" #include "ppapi/c/private/ppb_flash_device_id.h" @@ -110,6 +112,7 @@ #include "ppapi/c/private/ppb_flash_message_loop.h" #include "ppapi/c/private/ppb_flash_print.h" #include "ppapi/c/private/ppb_host_resolver_private.h" +#include "ppapi/c/private/ppb_input_event_private.h" #include "ppapi/c/private/ppb_instance_private.h" #include "ppapi/c/private/ppb_isolated_file_system_private.h" #include "ppapi/c/private/ppb_output_protection_private.h" @@ -186,9 +189,7 @@ void ReleaseResource(PP_Resource resource) { PpapiGlobals::Get()->GetResourceTracker()->ReleaseResource(resource); } -PP_Time GetTime() { - return TimeToPPTime(base::Time::Now()); -} +PP_Time GetTime() { return TimeToPPTime(base::Time::Now()); } PP_TimeTicks GetTickTime() { return TimeTicksToPPTimeTicks(base::TimeTicks::Now()); @@ -206,18 +207,14 @@ void CallOnMainThread(int delay_in_msec, } PP_Bool IsMainThread() { - return BoolToPPBool(PpapiGlobals::Get()-> - GetMainThreadMessageLoop()->BelongsToCurrentThread()); + return BoolToPPBool(PpapiGlobals::Get() + ->GetMainThreadMessageLoop() + ->BelongsToCurrentThread()); } -const PPB_Core core_interface = { - &AddRefResource, - &ReleaseResource, - &GetTime, - &GetTickTime, - &CallOnMainThread, - &IsMainThread -}; +const PPB_Core core_interface = {&AddRefResource, &ReleaseResource, + &GetTime, &GetTickTime, + &CallOnMainThread, &IsMainThread}; // PPB_Testing ----------------------------------------------------------------- @@ -245,9 +242,7 @@ uint32_t GetLiveObjectsForInstance(PP_Instance instance_id) { instance_id); } -PP_Bool IsOutOfProcess() { - return PP_FALSE; -} +PP_Bool IsOutOfProcess() { return PP_FALSE; } void SimulateInputEvent(PP_Instance instance, PP_Resource input_event) { PepperPluginInstanceImpl* plugin_instance = @@ -287,16 +282,11 @@ void SetMinimumArrayBufferSizeForShmem(PP_Instance /*instance*/, } const PPB_Testing_Private testing_interface = { - &ReadImageData, - &RunMessageLoop, - &QuitMessageLoop, - &GetLiveObjectsForInstance, - &IsOutOfProcess, - &SimulateInputEvent, - &GetDocumentURL, - &GetLiveVars, - &SetMinimumArrayBufferSizeForShmem -}; + &ReadImageData, &RunMessageLoop, + &QuitMessageLoop, &GetLiveObjectsForInstance, + &IsOutOfProcess, &SimulateInputEvent, + &GetDocumentURL, &GetLiveVars, + &SetMinimumArrayBufferSizeForShmem}; // GetInterface ---------------------------------------------------------------- @@ -307,29 +297,27 @@ const void* InternalGetInterface(const char* name) { if (custom_interface) return custom_interface; - // TODO(brettw) put these in a hash map for better performance. - #define UNPROXIED_IFACE(api_name, iface_str, iface_struct) \ - if (strcmp(name, iface_str) == 0) \ - return ppapi::thunk::Get##iface_struct##_Thunk(); - #define PROXIED_IFACE(api_name, iface_str, iface_struct) \ - UNPROXIED_IFACE(api_name, iface_str, iface_struct) +// TODO(brettw) put these in a hash map for better performance. +#define PROXIED_IFACE(iface_str, iface_struct) \ + if (strcmp(name, iface_str) == 0) \ + return ppapi::thunk::Get##iface_struct##_Thunk(); - #include "ppapi/thunk/interfaces_ppb_public_stable.h" - #include "ppapi/thunk/interfaces_ppb_public_dev.h" - #include "ppapi/thunk/interfaces_ppb_private.h" - #include "ppapi/thunk/interfaces_ppb_private_no_permissions.h" - #include "ppapi/thunk/interfaces_ppb_private_flash.h" +#include "ppapi/thunk/interfaces_ppb_private.h" +#include "ppapi/thunk/interfaces_ppb_private_flash.h" +#include "ppapi/thunk/interfaces_ppb_private_no_permissions.h" +#include "ppapi/thunk/interfaces_ppb_public_dev.h" +#include "ppapi/thunk/interfaces_ppb_public_dev_channel.h" +#include "ppapi/thunk/interfaces_ppb_public_stable.h" - #undef UNPROXIED_API - #undef PROXIED_IFACE +#undef PROXIED_IFACE - #define LEGACY_IFACE(iface_str, function_name) \ - if (strcmp(name, iface_str) == 0) \ - return function_name; +#define LEGACY_IFACE(iface_str, function_name) \ + if (strcmp(name, iface_str) == 0) \ + return function_name; - #include "ppapi/thunk/interfaces_legacy.h" +#include "ppapi/thunk/interfaces_legacy.h" - #undef LEGACY_IFACE +#undef LEGACY_IFACE // Only support the testing interface when the command line switch is // specified. This allows us to prevent people from (ab)using this interface @@ -351,9 +339,8 @@ const void* GetInterface(const char* name) { // Gets the PPAPI entry points from the given library and places them into the // given structure. Returns true on success. -bool LoadEntryPointsFromLibrary( - const base::NativeLibrary& library, - PepperPluginInfo::EntryPoints* entry_points) { +bool LoadEntryPointsFromLibrary(const base::NativeLibrary& library, + PepperPluginInfo::EntryPoints* entry_points) { entry_points->get_interface = reinterpret_cast<PepperPluginInfo::GetInterfaceFunc>( base::GetFunctionPointerFromNativeLibrary(library, @@ -390,9 +377,9 @@ void CreateHostForInProcessModule(RenderFrameImpl* render_frame, PepperPluginRegistry::GetInstance()->GetInfoForPlugin(webplugin_info); DCHECK(!info->is_out_of_process); - ppapi::PpapiPermissions perms( - PepperPluginRegistry::GetInstance()->GetInfoForPlugin( - webplugin_info)->permissions); + ppapi::PpapiPermissions perms(PepperPluginRegistry::GetInstance() + ->GetInfoForPlugin(webplugin_info) + ->permissions); RendererPpapiHostImpl* host_impl = RendererPpapiHostImpl::CreateOnModuleForInProcess(module, perms); render_frame->PepperPluginCreated(host_impl); @@ -412,7 +399,7 @@ PluginModule::PluginModule(const std::string& name, library_(NULL), name_(name), path_(path), - permissions_(perms), + permissions_(ppapi::PpapiPermissions::GetForCommandLine(perms.GetBits())), reserve_instance_id_(NULL) { // Ensure the globals object is created. if (!host_globals) @@ -499,13 +486,11 @@ void PluginModule::InitAsProxied( } scoped_refptr<PluginModule> - PluginModule::CreateModuleForExternalPluginInstance() { +PluginModule::CreateModuleForExternalPluginInstance() { // Create a new module, but don't set the lifetime delegate. This isn't a // plugin in the usual sense, so it isn't tracked by the browser. scoped_refptr<PluginModule> external_plugin_module( - new PluginModule(name_, - path_, - permissions_)); + new PluginModule(name_, path_, permissions_)); return external_plugin_module; } @@ -523,9 +508,7 @@ PP_ExternalPluginResult PluginModule::InitAsProxiedExternalPlugin( return instance->ResetAsProxied(this); } -bool PluginModule::IsProxied() const { - return !!host_dispatcher_wrapper_; -} +bool PluginModule::IsProxied() const { return !!host_dispatcher_wrapper_; } base::ProcessId PluginModule::GetPeerProcessId() { if (host_dispatcher_wrapper_) @@ -540,9 +523,7 @@ int PluginModule::GetPluginChildId() { } // static -const PPB_Core* PluginModule::GetCore() { - return &core_interface; -} +const PPB_Core* PluginModule::GetCore() { return &core_interface; } // static bool PluginModule::SupportsInterface(const char* name) { @@ -601,7 +582,8 @@ void PluginModule::PluginCrashed() { // Notify all instances that they crashed. for (PluginInstanceSet::iterator i = instances_.begin(); - i != instances_.end(); ++i) + i != instances_.end(); + ++i) (*i)->InstanceCrashed(); PepperPluginRegistry::GetInstance()->PluginModuleDead(this); @@ -624,9 +606,7 @@ void PluginModule::SetBroker(PepperBroker* broker) { broker_ = broker; } -PepperBroker* PluginModule::GetBroker() { - return broker_; -} +PepperBroker* PluginModule::GetBroker() { return broker_; } RendererPpapiHostImpl* PluginModule::CreateOutOfProcessModule( RenderFrameImpl* render_frame, @@ -638,12 +618,8 @@ RendererPpapiHostImpl* PluginModule::CreateOutOfProcessModule( bool is_external) { scoped_refptr<PepperHungPluginFilter> hung_filter(new PepperHungPluginFilter( path, render_frame->GetRoutingID(), plugin_child_id)); - scoped_ptr<HostDispatcherWrapper> dispatcher( - new HostDispatcherWrapper(this, - peer_pid, - plugin_child_id, - permissions, - is_external)); + scoped_ptr<HostDispatcherWrapper> dispatcher(new HostDispatcherWrapper( + this, peer_pid, plugin_child_id, permissions, is_external)); if (!dispatcher->Init( channel_handle, &GetInterface, @@ -672,7 +648,9 @@ bool PluginModule::InitializeModule( DCHECK(entry_points.initialize_module != NULL); int retval = entry_points.initialize_module(pp_module(), &GetInterface); if (retval != 0) { +#if !defined(DISABLE_NACL) LOG(WARNING) << "PPP_InitializeModule returned failure " << retval; +#endif // !defined(DISABLE_NACL) return false; } return true; @@ -711,9 +689,6 @@ scoped_refptr<PluginModule> PluginModule::Create( return scoped_refptr<PluginModule>(); } - ppapi::PpapiPermissions permissions = - ppapi::PpapiPermissions::GetForCommandLine(info->permissions); - // Out of process: have the browser start the plugin process for us. IPC::ChannelHandle channel_handle; base::ProcessId peer_pid; @@ -725,6 +700,8 @@ scoped_refptr<PluginModule> PluginModule::Create( return scoped_refptr<PluginModule>(); } + ppapi::PpapiPermissions permissions(info->permissions); + // AddLiveModule must be called before any early returns since the // module's destructor will remove itself. module = new PluginModule(info->name, path, permissions); diff --git a/chromium/content/renderer/pepper/plugin_module.h b/chromium/content/renderer/pepper/plugin_module.h index ad9463c45ad..dd25ecf8cb7 100644 --- a/chromium/content/renderer/pepper/plugin_module.h +++ b/chromium/content/renderer/pepper/plugin_module.h @@ -58,9 +58,8 @@ struct WebPluginInfo; // // Note: to get from a PP_Instance to a PepperPluginInstance*, use the // ResourceTracker. -class CONTENT_EXPORT PluginModule : - public base::RefCounted<PluginModule>, - public base::SupportsWeakPtr<PluginModule> { +class CONTENT_EXPORT PluginModule : public base::RefCounted<PluginModule>, + public base::SupportsWeakPtr<PluginModule> { public: typedef std::set<PepperPluginInstanceImpl*> PluginInstanceSet; @@ -138,10 +137,9 @@ class CONTENT_EXPORT PluginModule : const base::FilePath& path() const { return path_; } const ppapi::PpapiPermissions& permissions() const { return permissions_; } - PepperPluginInstanceImpl* CreateInstance( - RenderFrameImpl* render_frame, - blink::WebPluginContainer* container, - const GURL& plugin_url); + PepperPluginInstanceImpl* CreateInstance(RenderFrameImpl* render_frame, + blink::WebPluginContainer* container, + const GURL& plugin_url); // Returns "some" plugin instance associated with this module. This is not // guaranteed to be any one in particular. This is normally used to execute @@ -178,8 +176,7 @@ class CONTENT_EXPORT PluginModule : // it exists to validate the ID. If the callback has not been set (such as // for in-process plugins), the Reserve function will assume that the ID is // usable and will return true. - void SetReserveInstanceIDCallback( - PP_Bool (*reserve)(PP_Module, PP_Instance)); + void SetReserveInstanceIDCallback(PP_Bool (*reserve)(PP_Module, PP_Instance)); bool ReserveInstanceID(PP_Instance instance); // These should only be called from the main thread. diff --git a/chromium/content/renderer/pepper/plugin_object.cc b/chromium/content/renderer/pepper/plugin_object.cc index 55e4c6c08ec..6de7ce19efb 100644 --- a/chromium/content/renderer/pepper/plugin_object.cc +++ b/chromium/content/renderer/pepper/plugin_object.cc @@ -43,14 +43,14 @@ NPObject* WrapperClass_Allocate(NPP npp, NPClass* unused) { void WrapperClass_Deallocate(NPObject* np_object) { PluginObject* plugin_object = PluginObject::FromNPObject(np_object); - if (!plugin_object) - return; - plugin_object->ppp_class()->Deallocate(plugin_object->ppp_class_data()); - delete plugin_object; + if (plugin_object) { + plugin_object->ppp_class()->Deallocate(plugin_object->ppp_class_data()); + delete plugin_object; + } + delete np_object; } -void WrapperClass_Invalidate(NPObject* object) { -} +void WrapperClass_Invalidate(NPObject* object) {} bool WrapperClass_HasMethod(NPObject* object, NPIdentifier method_name) { NPObjectAccessorWithIdentifier accessor(object, method_name, false); @@ -60,14 +60,17 @@ bool WrapperClass_HasMethod(NPObject* object, NPIdentifier method_name) { PPResultAndExceptionToNPResult result_converter( accessor.object()->GetNPObject(), NULL); bool rv = accessor.object()->ppp_class()->HasMethod( - accessor.object()->ppp_class_data(), accessor.identifier(), + accessor.object()->ppp_class_data(), + accessor.identifier(), result_converter.exception()); result_converter.CheckExceptionForNoResult(); return rv; } -bool WrapperClass_Invoke(NPObject* object, NPIdentifier method_name, - const NPVariant* argv, uint32_t argc, +bool WrapperClass_Invoke(NPObject* object, + NPIdentifier method_name, + const NPVariant* argv, + uint32_t argc, NPVariant* result) { NPObjectAccessorWithIdentifier accessor(object, method_name, false); if (!accessor.is_valid()) @@ -75,8 +78,7 @@ bool WrapperClass_Invoke(NPObject* object, NPIdentifier method_name, PPResultAndExceptionToNPResult result_converter( accessor.object()->GetNPObject(), result); - PPVarArrayFromNPVariantArray args(accessor.object()->instance(), - argc, argv); + PPVarArrayFromNPVariantArray args(accessor.object()->instance(), argc, argv); // For the OOP plugin case we need to grab a reference on the plugin module // object to ensure that it is not destroyed courtsey an incoming @@ -84,13 +86,18 @@ bool WrapperClass_Invoke(NPObject* object, NPIdentifier method_name, // dispatcher. scoped_refptr<PluginModule> ref(accessor.object()->instance()->module()); - return result_converter.SetResult(accessor.object()->ppp_class()->Call( - accessor.object()->ppp_class_data(), accessor.identifier(), - argc, args.array(), result_converter.exception())); + return result_converter.SetResult( + accessor.object()->ppp_class()->Call(accessor.object()->ppp_class_data(), + accessor.identifier(), + argc, + args.array(), + result_converter.exception())); } -bool WrapperClass_InvokeDefault(NPObject* np_object, const NPVariant* argv, - uint32_t argc, NPVariant* result) { +bool WrapperClass_InvokeDefault(NPObject* np_object, + const NPVariant* argv, + uint32_t argc, + NPVariant* result) { PluginObject* obj = PluginObject::FromNPObject(np_object); if (!obj) return false; @@ -104,9 +111,12 @@ bool WrapperClass_InvokeDefault(NPObject* np_object, const NPVariant* argv, // dispatcher. scoped_refptr<PluginModule> ref(obj->instance()->module()); - result_converter.SetResult(obj->ppp_class()->Call( - obj->ppp_class_data(), PP_MakeUndefined(), argc, args.array(), - result_converter.exception())); + result_converter.SetResult( + obj->ppp_class()->Call(obj->ppp_class_data(), + PP_MakeUndefined(), + argc, + args.array(), + result_converter.exception())); return result_converter.success(); } @@ -118,13 +128,15 @@ bool WrapperClass_HasProperty(NPObject* object, NPIdentifier property_name) { PPResultAndExceptionToNPResult result_converter( accessor.object()->GetNPObject(), NULL); bool rv = accessor.object()->ppp_class()->HasProperty( - accessor.object()->ppp_class_data(), accessor.identifier(), + accessor.object()->ppp_class_data(), + accessor.identifier(), result_converter.exception()); result_converter.CheckExceptionForNoResult(); return rv; } -bool WrapperClass_GetProperty(NPObject* object, NPIdentifier property_name, +bool WrapperClass_GetProperty(NPObject* object, + NPIdentifier property_name, NPVariant* result) { NPObjectAccessorWithIdentifier accessor(object, property_name, true); if (!accessor.is_valid()) @@ -133,11 +145,13 @@ bool WrapperClass_GetProperty(NPObject* object, NPIdentifier property_name, PPResultAndExceptionToNPResult result_converter( accessor.object()->GetNPObject(), result); return result_converter.SetResult(accessor.object()->ppp_class()->GetProperty( - accessor.object()->ppp_class_data(), accessor.identifier(), + accessor.object()->ppp_class_data(), + accessor.identifier(), result_converter.exception())); } -bool WrapperClass_SetProperty(NPObject* object, NPIdentifier property_name, +bool WrapperClass_SetProperty(NPObject* object, + NPIdentifier property_name, const NPVariant* value) { NPObjectAccessorWithIdentifier accessor(object, property_name, true); if (!accessor.is_valid()) @@ -147,7 +161,9 @@ bool WrapperClass_SetProperty(NPObject* object, NPIdentifier property_name, accessor.object()->GetNPObject(), NULL); PP_Var value_var = NPVariantToPPVar(accessor.object()->instance(), value); accessor.object()->ppp_class()->SetProperty( - accessor.object()->ppp_class_data(), accessor.identifier(), value_var, + accessor.object()->ppp_class_data(), + accessor.identifier(), + value_var, result_converter.exception()); PpapiGlobals::Get()->GetVarTracker()->ReleaseVar(value_var); return result_converter.CheckExceptionForNoResult(); @@ -161,12 +177,14 @@ bool WrapperClass_RemoveProperty(NPObject* object, NPIdentifier property_name) { PPResultAndExceptionToNPResult result_converter( accessor.object()->GetNPObject(), NULL); accessor.object()->ppp_class()->RemoveProperty( - accessor.object()->ppp_class_data(), accessor.identifier(), + accessor.object()->ppp_class_data(), + accessor.identifier(), result_converter.exception()); return result_converter.CheckExceptionForNoResult(); } -bool WrapperClass_Enumerate(NPObject* object, NPIdentifier** values, +bool WrapperClass_Enumerate(NPObject* object, + NPIdentifier** values, uint32_t* count) { *values = NULL; *count = 0; @@ -178,7 +196,8 @@ bool WrapperClass_Enumerate(NPObject* object, NPIdentifier** values, PP_Var* properties = NULL; // Must be freed! PPResultAndExceptionToNPResult result_converter(obj->GetNPObject(), NULL); obj->ppp_class()->GetAllPropertyNames(obj->ppp_class_data(), - &property_count, &properties, + &property_count, + &properties, result_converter.exception()); // Convert the array of PP_Var to an array of NPIdentifiers. If any @@ -186,7 +205,7 @@ bool WrapperClass_Enumerate(NPObject* object, NPIdentifier** values, if (!result_converter.has_exception()) { if (property_count > 0) { *values = static_cast<NPIdentifier*>( - malloc(sizeof(NPIdentifier) * property_count)); + calloc(property_count, sizeof(NPIdentifier))); *count = 0; // Will be the number of items successfully converted. for (uint32_t i = 0; i < property_count; ++i) { if (!((*values)[i] = PPVarToNPIdentifier(properties[i]))) { @@ -221,8 +240,10 @@ bool WrapperClass_Enumerate(NPObject* object, NPIdentifier** values, return result_converter.success(); } -bool WrapperClass_Construct(NPObject* object, const NPVariant* argv, - uint32_t argc, NPVariant* result) { +bool WrapperClass_Construct(NPObject* object, + const NPVariant* argv, + uint32_t argc, + NPVariant* result) { PluginObject* obj = PluginObject::FromNPObject(object); if (!obj) return false; @@ -230,25 +251,17 @@ bool WrapperClass_Construct(NPObject* object, const NPVariant* argv, PPVarArrayFromNPVariantArray args(obj->instance(), argc, argv); PPResultAndExceptionToNPResult result_converter(obj->GetNPObject(), result); return result_converter.SetResult(obj->ppp_class()->Construct( - obj->ppp_class_data(), argc, args.array(), - result_converter.exception())); + obj->ppp_class_data(), argc, args.array(), result_converter.exception())); } const NPClass wrapper_class = { - NP_CLASS_STRUCT_VERSION, - WrapperClass_Allocate, - WrapperClass_Deallocate, - WrapperClass_Invalidate, - WrapperClass_HasMethod, - WrapperClass_Invoke, - WrapperClass_InvokeDefault, - WrapperClass_HasProperty, - WrapperClass_GetProperty, - WrapperClass_SetProperty, - WrapperClass_RemoveProperty, - WrapperClass_Enumerate, - WrapperClass_Construct -}; + NP_CLASS_STRUCT_VERSION, WrapperClass_Allocate, + WrapperClass_Deallocate, WrapperClass_Invalidate, + WrapperClass_HasMethod, WrapperClass_Invoke, + WrapperClass_InvokeDefault, WrapperClass_HasProperty, + WrapperClass_GetProperty, WrapperClass_SetProperty, + WrapperClass_RemoveProperty, WrapperClass_Enumerate, + WrapperClass_Construct}; } // namespace @@ -293,9 +306,9 @@ PP_Var PluginObject::Create(PepperPluginInstanceImpl* instance, // This will internally end up calling our AllocateObjectWrapper via the // WrapperClass_Allocated function which will have created an object wrapper // appropriate for this class (derived from NPObject). - NPObjectWrapper* wrapper = static_cast<NPObjectWrapper*>( - WebBindings::createObject(instance->instanceNPP(), - const_cast<NPClass*>(&wrapper_class))); + NPObjectWrapper* wrapper = + static_cast<NPObjectWrapper*>(WebBindings::createObject( + instance->instanceNPP(), const_cast<NPClass*>(&wrapper_class))); // This object will register itself both with the NPObject and with the // PluginModule. The NPObject will normally handle its lifetime, and it @@ -316,9 +329,7 @@ PP_Var PluginObject::Create(PepperPluginInstanceImpl* instance, return obj_var; } -NPObject* PluginObject::GetNPObject() const { - return object_wrapper_; -} +NPObject* PluginObject::GetNPObject() const { return object_wrapper_; } // static bool PluginObject::IsInstanceOf(NPObject* np_object, @@ -353,4 +364,3 @@ NPObject* PluginObject::AllocateObjectWrapper() { } } // namespace content - diff --git a/chromium/content/renderer/pepper/plugin_object.h b/chromium/content/renderer/pepper/plugin_object.h index 362979a8b1c..62ffd2ebfbd 100644 --- a/chromium/content/renderer/pepper/plugin_object.h +++ b/chromium/content/renderer/pepper/plugin_object.h @@ -35,7 +35,9 @@ class PluginObject { PepperPluginInstanceImpl* instance() const { return instance_; } const PPP_Class_Deprecated* ppp_class() { return ppp_class_; } - void* ppp_class_data() { return ppp_class_data_; }; + void* ppp_class_data() { + return ppp_class_data_; + }; NPObject* GetNPObject() const; diff --git a/chromium/content/renderer/pepper/ppb_audio_impl.cc b/chromium/content/renderer/pepper/ppb_audio_impl.cc index 40b1bd96b14..652c697c27a 100644 --- a/chromium/content/renderer/pepper/ppb_audio_impl.cc +++ b/chromium/content/renderer/pepper/ppb_audio_impl.cc @@ -8,6 +8,7 @@ #include "content/renderer/pepper/common.h" #include "content/renderer/pepper/pepper_platform_audio_output.h" #include "content/renderer/pepper/pepper_plugin_instance_impl.h" +#include "content/renderer/render_frame_impl.h" #include "content/renderer/render_view_impl.h" #include "media/audio/audio_output_controller.h" #include "ppapi/c/pp_completion_callback.h" @@ -29,9 +30,7 @@ namespace content { // PPB_Audio_Impl -------------------------------------------------------------- PPB_Audio_Impl::PPB_Audio_Impl(PP_Instance instance) - : Resource(ppapi::OBJECT_IS_IMPL, instance), - audio_(NULL) { -} + : Resource(ppapi::OBJECT_IS_IMPL, instance), audio_(NULL) {} PPB_Audio_Impl::~PPB_Audio_Impl() { // Calling ShutDown() makes sure StreamCreated cannot be called anymore and @@ -45,48 +44,7 @@ PPB_Audio_Impl::~PPB_Audio_Impl() { } } -// static -PP_Resource PPB_Audio_Impl::Create( - PP_Instance instance, - PP_Resource config, - const ppapi::AudioCallbackCombined& audio_callback, - void* user_data) { - scoped_refptr<PPB_Audio_Impl> audio(new PPB_Audio_Impl(instance)); - if (!audio->Init(config, audio_callback, user_data)) - return 0; - return audio->GetReference(); -} - -PPB_Audio_API* PPB_Audio_Impl::AsPPB_Audio_API() { - return this; -} - -bool PPB_Audio_Impl::Init(PP_Resource config, - const ppapi::AudioCallbackCombined& callback, - void* user_data) { - // Validate the config and keep a reference to it. - EnterResourceNoLock<PPB_AudioConfig_API> enter(config, true); - if (enter.failed()) - return false; - config_ = config; - - if (!callback.IsValid()) - return false; - SetCallback(callback, user_data); - - PepperPluginInstance* instance = PepperPluginInstance::Get(pp_instance()); - if (!instance) - return false; - - // When the stream is created, we'll get called back on StreamCreated(). - CHECK(!audio_); - audio_ = PepperPlatformAudioOutput::Create( - static_cast<int>(enter.object()->GetSampleRate()), - static_cast<int>(enter.object()->GetSampleFrameCount()), - instance->GetRenderView()->GetRoutingID(), - this); - return audio_ != NULL; -} +PPB_Audio_API* PPB_Audio_Impl::AsPPB_Audio_API() { return this; } PP_Resource PPB_Audio_Impl::GetCurrentConfig() { // AddRef on behalf of caller, while keeping a ref for ourselves. @@ -114,16 +72,16 @@ PP_Bool PPB_Audio_Impl::StopPlayback() { return PP_TRUE; } -int32_t PPB_Audio_Impl::Open( - PP_Resource config, - scoped_refptr<TrackedCallback> create_callback) { +int32_t PPB_Audio_Impl::Open(PP_Resource config, + scoped_refptr<TrackedCallback> create_callback) { // Validate the config and keep a reference to it. EnterResourceNoLock<PPB_AudioConfig_API> enter(config, true); if (enter.failed()) return PP_ERROR_FAILED; config_ = config; - PepperPluginInstance* instance = PepperPluginInstance::Get(pp_instance()); + PepperPluginInstanceImpl* instance = static_cast<PepperPluginInstanceImpl*>( + PepperPluginInstance::Get(pp_instance())); if (!instance) return PP_ERROR_FAILED; @@ -133,6 +91,7 @@ int32_t PPB_Audio_Impl::Open( static_cast<int>(enter.object()->GetSampleRate()), static_cast<int>(enter.object()->GetSampleFrameCount()), instance->GetRenderView()->GetRoutingID(), + instance->render_frame()->GetRoutingID(), this); if (!audio_) return PP_ERROR_FAILED; @@ -149,8 +108,7 @@ int32_t PPB_Audio_Impl::GetSyncSocket(int* sync_socket) { return GetSyncSocketImpl(sync_socket); } -int32_t PPB_Audio_Impl::GetSharedMemory(int* shm_handle, - uint32_t* shm_size) { +int32_t PPB_Audio_Impl::GetSharedMemory(int* shm_handle, uint32_t* shm_size) { return GetSharedMemoryImpl(shm_handle, shm_size); } @@ -159,8 +117,11 @@ void PPB_Audio_Impl::OnSetStreamInfo( size_t shared_memory_size, base::SyncSocket::Handle socket_handle) { EnterResourceNoLock<PPB_AudioConfig_API> enter(config_, true); - SetStreamInfo(pp_instance(), shared_memory_handle, shared_memory_size, - socket_handle, enter.object()->GetSampleRate(), + SetStreamInfo(pp_instance(), + shared_memory_handle, + shared_memory_size, + socket_handle, + enter.object()->GetSampleRate(), enter.object()->GetSampleFrameCount()); } diff --git a/chromium/content/renderer/pepper/ppb_audio_impl.h b/chromium/content/renderer/pepper/ppb_audio_impl.h index 16837c845cd..ecd49eb8438 100644 --- a/chromium/content/renderer/pepper/ppb_audio_impl.h +++ b/chromium/content/renderer/pepper/ppb_audio_impl.h @@ -23,28 +23,15 @@ class PepperPlatformAudioOutput; // Some of the backend functionality of this class is implemented by the // PPB_Audio_Shared so it can be shared with the proxy. +// +// TODO(teravest): PPB_Audio is no longer supported in-process. Clean this up +// to look more like typical HostResource implementations. class PPB_Audio_Impl : public ppapi::Resource, public ppapi::PPB_Audio_Shared, public AudioHelper { public: - // Trusted initialization. You must call Init after this. - // - // Untrusted initialization should just call the static Create() function - // to properly create & initialize this class. explicit PPB_Audio_Impl(PP_Instance instance); - // Creation function for untrusted plugins. This handles all initialization - // and will return 0 on failure. - static PP_Resource Create(PP_Instance instance, - PP_Resource config_id, - const ppapi::AudioCallbackCombined& audio_callback, - void* user_data); - - // Initialization function for trusted init. - bool Init(PP_Resource config_id, - const ppapi::AudioCallbackCombined& user_callback, - void* user_data); - // Resource overrides. virtual ppapi::thunk::PPB_Audio_API* AsPPB_Audio_API() OVERRIDE; @@ -52,9 +39,9 @@ class PPB_Audio_Impl : public ppapi::Resource, virtual PP_Resource GetCurrentConfig() OVERRIDE; virtual PP_Bool StartPlayback() OVERRIDE; virtual PP_Bool StopPlayback() OVERRIDE; - virtual int32_t Open( - PP_Resource config_id, - scoped_refptr<ppapi::TrackedCallback> create_callback) OVERRIDE; + virtual int32_t Open(PP_Resource config_id, + scoped_refptr<ppapi::TrackedCallback> create_callback) + OVERRIDE; virtual int32_t GetSyncSocket(int* sync_socket) OVERRIDE; virtual int32_t GetSharedMemory(int* shm_handle, uint32_t* shm_size) OVERRIDE; diff --git a/chromium/content/renderer/pepper/ppb_broker_impl.cc b/chromium/content/renderer/pepper/ppb_broker_impl.cc index 882c5db74aa..f75d56c53d4 100644 --- a/chromium/content/renderer/pepper/ppb_broker_impl.cc +++ b/chromium/content/renderer/pepper/ppb_broker_impl.cc @@ -31,9 +31,9 @@ PPB_Broker_Impl::PPB_Broker_Impl(PP_Instance instance) : Resource(ppapi::OBJECT_IS_IMPL, instance), broker_(NULL), connect_callback_(), - pipe_handle_(PlatformFileToInt(base::kInvalidPlatformFileValue)), + pipe_handle_(PlatformFileToInt(base::SyncSocket::kInvalidHandle)), routing_id_(RenderThreadImpl::current()->GenerateRoutingID()) { - ChildThread::current()->AddRoute(routing_id_, this); + ChildThread::current()->GetRouter()->AddRoute(routing_id_, this); } PPB_Broker_Impl::~PPB_Broker_Impl() { @@ -43,13 +43,11 @@ PPB_Broker_Impl::~PPB_Broker_Impl() { } // The plugin owns the handle. - pipe_handle_ = PlatformFileToInt(base::kInvalidPlatformFileValue); - ChildThread::current()->RemoveRoute(routing_id_); + pipe_handle_ = PlatformFileToInt(base::SyncSocket::kInvalidHandle); + ChildThread::current()->GetRouter()->RemoveRoute(routing_id_); } -PPB_Broker_API* PPB_Broker_Impl::AsPPB_Broker_API() { - return this; -} +PPB_Broker_API* PPB_Broker_Impl::AsPPB_Broker_API() { return this; } int32_t PPB_Broker_Impl::Connect( scoped_refptr<TrackedCallback> connect_callback) { @@ -78,8 +76,8 @@ int32_t PPB_Broker_Impl::Connect( broker_ = new PepperBroker(module); // Have the browser start the broker process for us. - RenderThreadImpl::current()->Send(new ViewHostMsg_OpenChannelToPpapiBroker( - routing_id_, broker_path)); + RenderThreadImpl::current()->Send( + new ViewHostMsg_OpenChannelToPpapiBroker(routing_id_, broker_path)); } RenderThreadImpl::current()->Send( @@ -97,7 +95,7 @@ int32_t PPB_Broker_Impl::Connect( } int32_t PPB_Broker_Impl::GetHandle(int32_t* handle) { - if (pipe_handle_ == PlatformFileToInt(base::kInvalidPlatformFileValue)) + if (pipe_handle_ == PlatformFileToInt(base::SyncSocket::kInvalidHandle)) return PP_ERROR_FAILED; // Handle not set yet. *handle = pipe_handle_; return PP_OK; @@ -111,10 +109,9 @@ GURL PPB_Broker_Impl::GetDocumentUrl() { // Transfers ownership of the handle to the plugin. void PPB_Broker_Impl::BrokerConnected(int32_t handle, int32_t result) { - DCHECK(pipe_handle_ == - PlatformFileToInt(base::kInvalidPlatformFileValue)); + DCHECK(pipe_handle_ == PlatformFileToInt(base::SyncSocket::kInvalidHandle)); DCHECK(result == PP_OK || - handle == PlatformFileToInt(base::kInvalidPlatformFileValue)); + handle == PlatformFileToInt(base::SyncSocket::kInvalidHandle)); pipe_handle_ = handle; diff --git a/chromium/content/renderer/pepper/ppb_buffer_impl.cc b/chromium/content/renderer/pepper/ppb_buffer_impl.cc index 4b806b94421..453e7168719 100644 --- a/chromium/content/renderer/pepper/ppb_buffer_impl.cc +++ b/chromium/content/renderer/pepper/ppb_buffer_impl.cc @@ -20,13 +20,9 @@ using ppapi::thunk::PPB_Buffer_API; namespace content { PPB_Buffer_Impl::PPB_Buffer_Impl(PP_Instance instance) - : Resource(ppapi::OBJECT_IS_IMPL, instance), - size_(0), - map_count_(0) { -} + : Resource(ppapi::OBJECT_IS_IMPL, instance), size_(0), map_count_(0) {} -PPB_Buffer_Impl::~PPB_Buffer_Impl() { -} +PPB_Buffer_Impl::~PPB_Buffer_Impl() {} // static PP_Resource PPB_Buffer_Impl::Create(PP_Instance instance, uint32_t size) { @@ -46,13 +42,9 @@ scoped_refptr<PPB_Buffer_Impl> PPB_Buffer_Impl::CreateResource( return buffer; } -PPB_Buffer_Impl* PPB_Buffer_Impl::AsPPB_Buffer_Impl() { - return this; -} +PPB_Buffer_Impl* PPB_Buffer_Impl::AsPPB_Buffer_Impl() { return this; } -PPB_Buffer_API* PPB_Buffer_Impl::AsPPB_Buffer_API() { - return this; -} +PPB_Buffer_API* PPB_Buffer_Impl::AsPPB_Buffer_API() { return this; } bool PPB_Buffer_Impl::Init(uint32_t size) { if (size == 0) @@ -89,8 +81,7 @@ int32_t PPB_Buffer_Impl::GetSharedMemory(int* shm_handle) { #if defined(OS_POSIX) *shm_handle = shared_memory_->handle().fd; #elif defined(OS_WIN) - *shm_handle = reinterpret_cast<int>( - shared_memory_->handle()); + *shm_handle = reinterpret_cast<int>(shared_memory_->handle()); #else #error "Platform not supported." #endif diff --git a/chromium/content/renderer/pepper/ppb_flash_message_loop_impl.cc b/chromium/content/renderer/pepper/ppb_flash_message_loop_impl.cc index ff2abc47078..b64abe66109 100644 --- a/chromium/content/renderer/pepper/ppb_flash_message_loop_impl.cc +++ b/chromium/content/renderer/pepper/ppb_flash_message_loop_impl.cc @@ -15,8 +15,7 @@ namespace content { class PPB_Flash_MessageLoop_Impl::State : public base::RefCounted<PPB_Flash_MessageLoop_Impl::State> { public: - State() : result_(PP_OK), run_called_(false), quit_called_(false) { - } + State() : result_(PP_OK), run_called_(false), quit_called_(false) {} int32_t result() const { return result_; } void set_result(int32_t result) { result_ = result; } @@ -43,9 +42,7 @@ class PPB_Flash_MessageLoop_Impl::State }; PPB_Flash_MessageLoop_Impl::PPB_Flash_MessageLoop_Impl(PP_Instance instance) - : Resource(ppapi::OBJECT_IS_IMPL, instance), - state_(new State()) { -} + : Resource(ppapi::OBJECT_IS_IMPL, instance), state_(new State()) {} PPB_Flash_MessageLoop_Impl::~PPB_Flash_MessageLoop_Impl() { // It is a no-op if either Run() hasn't been called or Quit() has been called @@ -59,7 +56,7 @@ PP_Resource PPB_Flash_MessageLoop_Impl::Create(PP_Instance instance) { } PPB_Flash_MessageLoop_API* - PPB_Flash_MessageLoop_Impl::AsPPB_Flash_MessageLoop_API() { +PPB_Flash_MessageLoop_Impl::AsPPB_Flash_MessageLoop_API() { return this; } @@ -72,9 +69,7 @@ void PPB_Flash_MessageLoop_Impl::RunFromHostProxy( InternalRun(callback); } -void PPB_Flash_MessageLoop_Impl::Quit() { - InternalQuit(PP_OK); -} +void PPB_Flash_MessageLoop_Impl::Quit() { InternalQuit(PP_OK); } int32_t PPB_Flash_MessageLoop_Impl::InternalRun( const RunFromHostProxyCallback& callback) { diff --git a/chromium/content/renderer/pepper/ppb_flash_message_loop_impl.h b/chromium/content/renderer/pepper/ppb_flash_message_loop_impl.h index 981a7da33b3..b26d4ce23f6 100644 --- a/chromium/content/renderer/pepper/ppb_flash_message_loop_impl.h +++ b/chromium/content/renderer/pepper/ppb_flash_message_loop_impl.h @@ -20,14 +20,14 @@ class PPB_Flash_MessageLoop_Impl static PP_Resource Create(PP_Instance instance); // Resource. - virtual ppapi::thunk::PPB_Flash_MessageLoop_API* - AsPPB_Flash_MessageLoop_API() OVERRIDE; + virtual ppapi::thunk::PPB_Flash_MessageLoop_API* AsPPB_Flash_MessageLoop_API() + OVERRIDE; // PPB_Flash_MessageLoop_API implementation. virtual int32_t Run() OVERRIDE; virtual void Quit() OVERRIDE; - virtual void RunFromHostProxy( - const RunFromHostProxyCallback& callback) OVERRIDE; + virtual void RunFromHostProxy(const RunFromHostProxyCallback& callback) + OVERRIDE; private: class State; diff --git a/chromium/content/renderer/pepper/ppb_graphics_3d_impl.cc b/chromium/content/renderer/pepper/ppb_graphics_3d_impl.cc index 989b9994395..d40f2202ebb 100644 --- a/chromium/content/renderer/pepper/ppb_graphics_3d_impl.cc +++ b/chromium/content/renderer/pepper/ppb_graphics_3d_impl.cc @@ -8,11 +8,13 @@ #include "base/command_line.h" #include "base/message_loop/message_loop.h" #include "base/strings/utf_string_conversions.h" +#include "content/common/gpu/client/command_buffer_proxy_impl.h" +#include "content/common/gpu/client/gpu_channel_host.h" #include "content/public/common/content_switches.h" #include "content/renderer/pepper/host_globals.h" -#include "content/renderer/pepper/pepper_platform_context_3d.h" #include "content/renderer/pepper/pepper_plugin_instance_impl.h" #include "content/renderer/pepper/plugin_module.h" +#include "content/renderer/render_thread_impl.h" #include "content/renderer/render_view_impl.h" #include "gpu/command_buffer/client/gles2_implementation.h" #include "ppapi/c/ppp_graphics_3d.h" @@ -21,14 +23,14 @@ #include "third_party/WebKit/public/web/WebConsoleMessage.h" #include "third_party/WebKit/public/web/WebDocument.h" #include "third_party/WebKit/public/web/WebElement.h" -#include "third_party/WebKit/public/web/WebFrame.h" +#include "third_party/WebKit/public/web/WebLocalFrame.h" #include "third_party/WebKit/public/web/WebPluginContainer.h" #include "webkit/common/webpreferences.h" using ppapi::thunk::EnterResourceNoLock; using ppapi::thunk::PPB_Graphics3D_API; using blink::WebConsoleMessage; -using blink::WebFrame; +using blink::WebLocalFrame; using blink::WebPluginContainer; using blink::WebString; @@ -38,42 +40,26 @@ namespace { const int32 kCommandBufferSize = 1024 * 1024; const int32 kTransferBufferSize = 1024 * 1024; -PP_Bool ShmToHandle(base::SharedMemory* shm, - size_t size, - int* shm_handle, - uint32_t* shm_size) { - if (!shm || !shm_handle || !shm_size) - return PP_FALSE; -#if defined(OS_POSIX) - *shm_handle = shm->handle().fd; -#elif defined(OS_WIN) - *shm_handle = reinterpret_cast<int>(shm->handle()); -#else - #error "Platform not supported." -#endif - *shm_size = size; - return PP_TRUE; -} - } // namespace. PPB_Graphics3D_Impl::PPB_Graphics3D_Impl(PP_Instance instance) : PPB_Graphics3D_Shared(instance), bound_to_instance_(false), commit_pending_(false), - weak_ptr_factory_(this) { -} + sync_point_(0), + has_alpha_(false), + command_buffer_(NULL), + weak_ptr_factory_(this) {} PPB_Graphics3D_Impl::~PPB_Graphics3D_Impl() { DestroyGLES2Impl(); -} + if (command_buffer_) { + DCHECK(channel_.get()); + channel_->DestroyCommandBuffer(command_buffer_); + command_buffer_ = NULL; + } -// static -PP_Bool PPB_Graphics3D_Impl::IsGpuBlacklisted() { - CommandLine* command_line = CommandLine::ForCurrentProcess(); - if (command_line) - return PP_FromBool(command_line->HasSwitch(switches::kDisablePepper3d)); - return PP_TRUE; + channel_ = NULL; } // static @@ -81,8 +67,6 @@ PP_Resource PPB_Graphics3D_Impl::Create(PP_Instance instance, PP_Resource share_context, const int32_t* attrib_list) { PPB_Graphics3D_API* share_api = NULL; - if (IsGpuBlacklisted()) - return 0; if (share_context) { EnterResourceNoLock<PPB_Graphics3D_API> enter(share_context, true); if (enter.failed()) @@ -101,8 +85,6 @@ PP_Resource PPB_Graphics3D_Impl::CreateRaw(PP_Instance instance, PP_Resource share_context, const int32_t* attrib_list) { PPB_Graphics3D_API* share_api = NULL; - if (IsGpuBlacklisted()) - return 0; if (share_context) { EnterResourceNoLock<PPB_Graphics3D_API> enter(share_context, true); if (enter.failed()) @@ -121,14 +103,10 @@ PP_Bool PPB_Graphics3D_Impl::SetGetBuffer(int32_t transfer_buffer_id) { return PP_TRUE; } -gpu::CommandBuffer::State PPB_Graphics3D_Impl::GetState() { - return GetCommandBuffer()->GetState(); -} - -int32_t PPB_Graphics3D_Impl::CreateTransferBuffer(uint32_t size) { - int32_t id = -1; - GetCommandBuffer()->CreateTransferBuffer(size, &id); - return id; +scoped_refptr<gpu::Buffer> PPB_Graphics3D_Impl::CreateTransferBuffer( + uint32_t size, + int32_t* id) { + return GetCommandBuffer()->CreateTransferBuffer(size, id); } PP_Bool PPB_Graphics3D_Impl::DestroyTransferBuffer(int32_t id) { @@ -136,31 +114,27 @@ PP_Bool PPB_Graphics3D_Impl::DestroyTransferBuffer(int32_t id) { return PP_TRUE; } -PP_Bool PPB_Graphics3D_Impl::GetTransferBuffer(int32_t id, - int* shm_handle, - uint32_t* shm_size) { - gpu::Buffer buffer = GetCommandBuffer()->GetTransferBuffer(id); - return ShmToHandle(buffer.shared_memory, buffer.size, shm_handle, shm_size); -} - PP_Bool PPB_Graphics3D_Impl::Flush(int32_t put_offset) { GetCommandBuffer()->Flush(put_offset); return PP_TRUE; } -gpu::CommandBuffer::State PPB_Graphics3D_Impl::FlushSync(int32_t put_offset) { - gpu::CommandBuffer::State state = GetCommandBuffer()->GetState(); - return GetCommandBuffer()->FlushSync(put_offset, state.get_offset); +gpu::CommandBuffer::State PPB_Graphics3D_Impl::WaitForTokenInRange( + int32_t start, + int32_t end) { + GetCommandBuffer()->WaitForTokenInRange(start, end); + return GetCommandBuffer()->GetLastState(); } -gpu::CommandBuffer::State PPB_Graphics3D_Impl::FlushSyncFast( - int32_t put_offset, - int32_t last_known_get) { - return GetCommandBuffer()->FlushSync(put_offset, last_known_get); +gpu::CommandBuffer::State PPB_Graphics3D_Impl::WaitForGetOffsetInRange( + int32_t start, + int32_t end) { + GetCommandBuffer()->WaitForGetOffsetInRange(start, end); + return GetCommandBuffer()->GetLastState(); } uint32_t PPB_Graphics3D_Impl::InsertSyncPoint() { - return platform_context_->GetGpuControl()->InsertSyncPoint(); + return command_buffer_->InsertSyncPoint(); } bool PPB_Graphics3D_Impl::BindToInstance(bool bind) { @@ -168,9 +142,7 @@ bool PPB_Graphics3D_Impl::BindToInstance(bool bind) { return true; } -bool PPB_Graphics3D_Impl::IsOpaque() { - return platform_context_->IsOpaque(); -} +bool PPB_Graphics3D_Impl::IsOpaque() { return !has_alpha_; } void PPB_Graphics3D_Impl::ViewInitiatedPaint() { commit_pending_ = false; @@ -179,18 +151,23 @@ void PPB_Graphics3D_Impl::ViewInitiatedPaint() { SwapBuffersACK(PP_OK); } -void PPB_Graphics3D_Impl::ViewFlushedPaint() { +void PPB_Graphics3D_Impl::ViewFlushedPaint() {} + +int PPB_Graphics3D_Impl::GetCommandBufferRouteId() { + DCHECK(command_buffer_); + return command_buffer_->GetRouteID(); } gpu::CommandBuffer* PPB_Graphics3D_Impl::GetCommandBuffer() { - return platform_context_->GetCommandBuffer(); + return command_buffer_; } gpu::GpuControl* PPB_Graphics3D_Impl::GetGpuControl() { - return platform_context_->GetGpuControl(); + return command_buffer_; } int32 PPB_Graphics3D_Impl::DoSwapBuffers() { + DCHECK(command_buffer_); // We do not have a GLES2 implementation when using an OOP proxy. // The plugin-side proxy is responsible for adding the SwapBuffers command // to the command buffer in that case. @@ -199,7 +176,7 @@ int32 PPB_Graphics3D_Impl::DoSwapBuffers() { // Since the backing texture has been updated, a new sync point should be // inserted. - platform_context_->InsertSyncPointForBackingMailbox(); + sync_point_ = command_buffer_->InsertSyncPoint(); if (bound_to_instance_) { // If we are bound to the instance, we need to ask the compositor @@ -213,11 +190,10 @@ int32 PPB_Graphics3D_Impl::DoSwapBuffers() { commit_pending_ = true; } else { // Wait for the command to complete on the GPU to allow for throttling. - platform_context_->Echo(base::Bind(&PPB_Graphics3D_Impl::OnSwapBuffers, - weak_ptr_factory_.GetWeakPtr())); + command_buffer_->Echo(base::Bind(&PPB_Graphics3D_Impl::OnSwapBuffers, + weak_ptr_factory_.GetWeakPtr())); } - return PP_OK_COMPLETIONPENDING; } @@ -226,18 +202,13 @@ bool PPB_Graphics3D_Impl::Init(PPB_Graphics3D_API* share_context, if (!InitRaw(share_context, attrib_list)) return false; - gpu::CommandBuffer* command_buffer = GetCommandBuffer(); - if (!command_buffer->Initialize()) - return false; - gpu::gles2::GLES2Implementation* share_gles2 = NULL; if (share_context) { share_gles2 = static_cast<PPB_Graphics3D_Shared*>(share_context)->gles2_impl(); } - return CreateGLES2Impl(kCommandBufferSize, kTransferBufferSize, - share_gles2); + return CreateGLES2Impl(kCommandBufferSize, kTransferBufferSize, share_gles2); } bool PPB_Graphics3D_Impl::InitRaw(PPB_Graphics3D_API* share_context, @@ -247,51 +218,94 @@ bool PPB_Graphics3D_Impl::InitRaw(PPB_Graphics3D_API* share_context, if (!plugin_instance) return false; - PlatformContext3D* share_platform_context = NULL; + const WebPreferences& prefs = + static_cast<RenderViewImpl*>(plugin_instance->GetRenderView()) + ->webkit_preferences(); + // 3D access might be disabled or blacklisted. + if (!prefs.pepper_3d_enabled) + return false; + + RenderThreadImpl* render_thread = RenderThreadImpl::current(); + if (!render_thread) + return false; + + channel_ = render_thread->EstablishGpuChannelSync( + CAUSE_FOR_GPU_LAUNCH_PEPPERPLATFORMCONTEXT3DIMPL_INITIALIZE); + if (!channel_.get()) + return false; + + gfx::Size surface_size; + std::vector<int32> attribs; + gfx::GpuPreference gpu_preference = gfx::PreferDiscreteGpu; + // TODO(alokp): Change GpuChannelHost::CreateOffscreenCommandBuffer() + // interface to accept width and height in the attrib_list so that + // we do not need to filter for width and height here. + if (attrib_list) { + for (const int32_t* attr = attrib_list; attr[0] != PP_GRAPHICS3DATTRIB_NONE; + attr += 2) { + switch (attr[0]) { + case PP_GRAPHICS3DATTRIB_WIDTH: + surface_size.set_width(attr[1]); + break; + case PP_GRAPHICS3DATTRIB_HEIGHT: + surface_size.set_height(attr[1]); + break; + case PP_GRAPHICS3DATTRIB_GPU_PREFERENCE: + gpu_preference = + (attr[1] == PP_GRAPHICS3DATTRIB_GPU_PREFERENCE_LOW_POWER) + ? gfx::PreferIntegratedGpu + : gfx::PreferDiscreteGpu; + break; + case PP_GRAPHICS3DATTRIB_ALPHA_SIZE: + has_alpha_ = attr[1] > 0; + // fall-through + default: + attribs.push_back(attr[0]); + attribs.push_back(attr[1]); + break; + } + } + attribs.push_back(PP_GRAPHICS3DATTRIB_NONE); + } + + CommandBufferProxyImpl* share_buffer = NULL; if (share_context) { PPB_Graphics3D_Impl* share_graphics = static_cast<PPB_Graphics3D_Impl*>(share_context); - share_platform_context = share_graphics->platform_context(); + share_buffer = share_graphics->command_buffer_; } - // If accelerated compositing of plugins is disabled, fail to create a 3D - // context, because it won't be visible. This allows graceful fallback in the - // modules. - const WebPreferences& prefs = static_cast<RenderViewImpl*>(plugin_instance-> - GetRenderView())->webkit_preferences(); - if (!prefs.accelerated_compositing_for_plugins_enabled) + command_buffer_ = channel_->CreateOffscreenCommandBuffer( + surface_size, share_buffer, attribs, GURL::EmptyGURL(), gpu_preference); + if (!command_buffer_) return false; - - platform_context_.reset(new PlatformContext3D); - if (!platform_context_) + if (!command_buffer_->Initialize()) return false; - - if (!platform_context_->Init(attrib_list, share_platform_context)) + mailbox_ = gpu::Mailbox::Generate(); + if (!command_buffer_->ProduceFrontBuffer(mailbox_)) return false; + sync_point_ = command_buffer_->InsertSyncPoint(); - platform_context_->SetContextLostCallback( - base::Bind(&PPB_Graphics3D_Impl::OnContextLost, - weak_ptr_factory_.GetWeakPtr())); + command_buffer_->SetChannelErrorCallback(base::Bind( + &PPB_Graphics3D_Impl::OnContextLost, weak_ptr_factory_.GetWeakPtr())); - platform_context_->SetOnConsoleMessageCallback( - base::Bind(&PPB_Graphics3D_Impl::OnConsoleMessage, - weak_ptr_factory_.GetWeakPtr())); + command_buffer_->SetOnConsoleMessageCallback(base::Bind( + &PPB_Graphics3D_Impl::OnConsoleMessage, weak_ptr_factory_.GetWeakPtr())); return true; } -void PPB_Graphics3D_Impl::OnConsoleMessage(const std::string& message, - int id) { +void PPB_Graphics3D_Impl::OnConsoleMessage(const std::string& message, int id) { if (!bound_to_instance_) return; WebPluginContainer* container = HostGlobals::Get()->GetInstance(pp_instance())->container(); if (!container) return; - WebFrame* frame = container->element().document().frame(); + WebLocalFrame* frame = container->element().document().frame(); if (!frame) return; WebConsoleMessage console_message = WebConsoleMessage( - WebConsoleMessage::LevelError, WebString(UTF8ToUTF16(message))); + WebConsoleMessage::LevelError, WebString(base::UTF8ToUTF16(message))); frame->addMessageToConsole(console_message); } @@ -308,8 +322,8 @@ void PPB_Graphics3D_Impl::OnContextLost() { // Don't need to check for NULL from GetPluginInstance since when we're // bound, we know our instance is valid. if (bound_to_instance_) { - HostGlobals::Get()->GetInstance(pp_instance())->BindGraphics( - pp_instance(), 0); + HostGlobals::Get()->GetInstance(pp_instance())->BindGraphics(pp_instance(), + 0); } // Send context lost to plugin. This may have been caused by a PPAPI call, so @@ -334,10 +348,8 @@ void PPB_Graphics3D_Impl::SendContextLost() { // send the Graphics3DContextLost to the plugin; the instance may care about // that event even though this context has been destroyed. PP_Instance this_pp_instance = pp_instance(); - const PPP_Graphics3D* ppp_graphics_3d = - static_cast<const PPP_Graphics3D*>( - instance->module()->GetPluginInterface( - PPP_GRAPHICS_3D_INTERFACE)); + const PPP_Graphics3D* ppp_graphics_3d = static_cast<const PPP_Graphics3D*>( + instance->module()->GetPluginInterface(PPP_GRAPHICS_3D_INTERFACE)); // We have to check *again* that the instance exists, because it could have // been deleted during GetPluginInterface(). Even the PluginModule could be // deleted, but in that case, the instance should also be gone, so the diff --git a/chromium/content/renderer/pepper/ppb_graphics_3d_impl.h b/chromium/content/renderer/pepper/ppb_graphics_3d_impl.h index d4d4c2bad28..c3520c05a03 100644 --- a/chromium/content/renderer/pepper/ppb_graphics_3d_impl.h +++ b/chromium/content/renderer/pepper/ppb_graphics_3d_impl.h @@ -6,11 +6,13 @@ #define CONTENT_RENDERER_PEPPER_PPB_GRAPHICS_3D_IMPL_H_ #include "base/memory/weak_ptr.h" +#include "gpu/command_buffer/common/mailbox.h" #include "ppapi/shared_impl/ppb_graphics_3d_shared.h" #include "ppapi/shared_impl/resource.h" namespace content { -class PlatformContext3D; +class CommandBufferProxyImpl; +class GpuChannelHost; class PPB_Graphics3D_Impl : public ppapi::PPB_Graphics3D_Shared { public: @@ -23,17 +25,15 @@ class PPB_Graphics3D_Impl : public ppapi::PPB_Graphics3D_Shared { // PPB_Graphics3D_API trusted implementation. virtual PP_Bool SetGetBuffer(int32_t transfer_buffer_id) OVERRIDE; - virtual gpu::CommandBuffer::State GetState() OVERRIDE; - virtual int32_t CreateTransferBuffer(uint32_t size) OVERRIDE; + virtual scoped_refptr<gpu::Buffer> CreateTransferBuffer(uint32_t size, + int32* id) OVERRIDE; virtual PP_Bool DestroyTransferBuffer(int32_t id) OVERRIDE; - virtual PP_Bool GetTransferBuffer(int32_t id, - int* shm_handle, - uint32_t* shm_size) OVERRIDE; virtual PP_Bool Flush(int32_t put_offset) OVERRIDE; - virtual gpu::CommandBuffer::State FlushSync(int32_t put_offset) OVERRIDE; - virtual gpu::CommandBuffer::State FlushSyncFast( - int32_t put_offset, - int32_t last_known_get) OVERRIDE; + virtual gpu::CommandBuffer::State WaitForTokenInRange(int32_t start, + int32_t end) OVERRIDE; + virtual gpu::CommandBuffer::State WaitForGetOffsetInRange(int32_t start, + int32_t end) + OVERRIDE; virtual uint32_t InsertSyncPoint() OVERRIDE; // Binds/unbinds the graphics of this context with the associated instance. @@ -48,7 +48,14 @@ class PPB_Graphics3D_Impl : public ppapi::PPB_Graphics3D_Shared { void ViewInitiatedPaint(); void ViewFlushedPaint(); - PlatformContext3D* platform_context() { return platform_context_.get(); } + void GetBackingMailbox(gpu::Mailbox* mailbox, uint32* sync_point) { + *mailbox = mailbox_; + *sync_point = sync_point_; + } + + int GetCommandBufferRouteId(); + + GpuChannelHost* channel() { return channel_; } protected: virtual ~PPB_Graphics3D_Impl(); @@ -60,12 +67,8 @@ class PPB_Graphics3D_Impl : public ppapi::PPB_Graphics3D_Shared { private: explicit PPB_Graphics3D_Impl(PP_Instance instance); - static PP_Bool IsGpuBlacklisted(); - - bool Init(PPB_Graphics3D_API* share_context, - const int32_t* attrib_list); - bool InitRaw(PPB_Graphics3D_API* share_context, - const int32_t* attrib_list); + bool Init(PPB_Graphics3D_API* share_context, const int32_t* attrib_list); + bool InitRaw(PPB_Graphics3D_API* share_context, const int32_t* attrib_list); // Notifications received from the GPU process. void OnSwapBuffers(); @@ -78,8 +81,13 @@ class PPB_Graphics3D_Impl : public ppapi::PPB_Graphics3D_Shared { bool bound_to_instance_; // True when waiting for compositor to commit our backing texture. bool commit_pending_; - // The 3D Context. Responsible for providing the command buffer. - scoped_ptr<PlatformContext3D> platform_context_; + + gpu::Mailbox mailbox_; + uint32 sync_point_; + bool has_alpha_; + scoped_refptr<GpuChannelHost> channel_; + CommandBufferProxyImpl* command_buffer_; + base::WeakPtrFactory<PPB_Graphics3D_Impl> weak_ptr_factory_; DISALLOW_COPY_AND_ASSIGN(PPB_Graphics3D_Impl); diff --git a/chromium/content/renderer/pepper/ppb_image_data_impl.cc b/chromium/content/renderer/pepper/ppb_image_data_impl.cc index 80cc38dcd3d..086eee299a9 100644 --- a/chromium/content/renderer/pepper/ppb_image_data_impl.cc +++ b/chromium/content/renderer/pepper/ppb_image_data_impl.cc @@ -29,7 +29,7 @@ namespace { // Returns true if the ImageData shared memory should be allocated in the // browser process for the current platform. bool IsBrowserAllocated() { -#if defined(OS_POSIX) && !defined(TOOLKIT_GTK) && !defined(OS_ANDROID) +#if defined(OS_POSIX) && !defined(OS_ANDROID) // On the Mac, shared memory has to be created in the browser in order to // work in the sandbox. return true; @@ -51,25 +51,24 @@ PPB_ImageData_Impl::PPB_ImageData_Impl(PP_Instance instance, case PPB_ImageData_Shared::SIMPLE: backend_.reset(new ImageDataSimpleBackend); return; - // No default: so that we get a compiler warning if any types are added. + // No default: so that we get a compiler warning if any types are added. } NOTREACHED(); } -PPB_ImageData_Impl::PPB_ImageData_Impl(PP_Instance instance, - ForTest) +PPB_ImageData_Impl::PPB_ImageData_Impl(PP_Instance instance, ForTest) : Resource(ppapi::OBJECT_IS_IMPL, instance), format_(PP_IMAGEDATAFORMAT_BGRA_PREMUL), width_(0), height_(0) { - backend_.reset(new ImageDataPlatformBackend(false)); + backend_.reset(new ImageDataPlatformBackend(false)); } -PPB_ImageData_Impl::~PPB_ImageData_Impl() { -} +PPB_ImageData_Impl::~PPB_ImageData_Impl() {} bool PPB_ImageData_Impl::Init(PP_ImageDataFormat format, - int width, int height, + int width, + int height, bool init_to_zero) { // TODO(brettw) this should be called only on the main thread! if (!IsImageDataFormatSupported(format)) @@ -92,20 +91,16 @@ PP_Resource PPB_ImageData_Impl::Create(PP_Instance instance, PP_ImageDataFormat format, const PP_Size& size, PP_Bool init_to_zero) { - scoped_refptr<PPB_ImageData_Impl> - data(new PPB_ImageData_Impl(instance, type)); + scoped_refptr<PPB_ImageData_Impl> data( + new PPB_ImageData_Impl(instance, type)); if (!data->Init(format, size.width, size.height, !!init_to_zero)) return 0; return data->GetReference(); } -PPB_ImageData_API* PPB_ImageData_Impl::AsPPB_ImageData_API() { - return this; -} +PPB_ImageData_API* PPB_ImageData_Impl::AsPPB_ImageData_API() { return this; } -bool PPB_ImageData_Impl::IsMapped() const { - return backend_->IsMapped(); -} +bool PPB_ImageData_Impl::IsMapped() const { return backend_->IsMapped(); } TransportDIB* PPB_ImageData_Impl::GetTransportDIB() const { return backend_->GetTransportDIB(); @@ -119,13 +114,9 @@ PP_Bool PPB_ImageData_Impl::Describe(PP_ImageDataDesc* desc) { return PP_TRUE; } -void* PPB_ImageData_Impl::Map() { - return backend_->Map(); -} +void* PPB_ImageData_Impl::Map() { return backend_->Map(); } -void PPB_ImageData_Impl::Unmap() { - backend_->Unmap(); -} +void PPB_ImageData_Impl::Unmap() { backend_->Unmap(); } int32_t PPB_ImageData_Impl::GetSharedMemory(int* handle, uint32_t* byte_count) { return backend_->GetSharedMemory(handle, byte_count); @@ -135,9 +126,7 @@ skia::PlatformCanvas* PPB_ImageData_Impl::GetPlatformCanvas() { return backend_->GetPlatformCanvas(); } -SkCanvas* PPB_ImageData_Impl::GetCanvas() { - return backend_->GetCanvas(); -} +SkCanvas* PPB_ImageData_Impl::GetCanvas() { return backend_->GetCanvas(); } void PPB_ImageData_Impl::SetIsCandidateForReuse() { // Nothing to do since we don't support image data re-use in-process. @@ -150,10 +139,7 @@ const SkBitmap* PPB_ImageData_Impl::GetMappedBitmap() const { // ImageDataPlatformBackend ---------------------------------------------------- ImageDataPlatformBackend::ImageDataPlatformBackend(bool is_browser_allocated) - : width_(0), - height_(0), - is_browser_allocated_(is_browser_allocated) { -} + : width_(0), height_(0), is_browser_allocated_(is_browser_allocated) {} // On POSIX, we have to tell the browser to free the transport DIB. ImageDataPlatformBackend::~ImageDataPlatformBackend() { @@ -169,7 +155,8 @@ ImageDataPlatformBackend::~ImageDataPlatformBackend() { bool ImageDataPlatformBackend::Init(PPB_ImageData_Impl* impl, PP_ImageDataFormat format, - int width, int height, + int width, + int height, bool init_to_zero) { // TODO(brettw) use init_to_zero when we implement caching. width_ = width; @@ -186,9 +173,8 @@ bool ImageDataPlatformBackend::Init(PPB_ImageData_Impl* impl, // TransportDIB is cached in the browser, and is freed (in typical cases) by // the TransportDIB's destructor. TransportDIB::Handle dib_handle; - IPC::Message* msg = new ViewHostMsg_AllocTransportDIB(buffer_size, - true, - &dib_handle); + IPC::Message* msg = + new ViewHostMsg_AllocTransportDIB(buffer_size, true, &dib_handle); if (!RenderThreadImpl::current()->Send(msg)) return false; if (!TransportDIB::is_valid_handle(dib_handle)) @@ -243,8 +229,6 @@ int32_t ImageDataPlatformBackend::GetSharedMemory(int* handle, *byte_count = dib_->size(); #if defined(OS_WIN) *handle = reinterpret_cast<intptr_t>(dib_->handle()); -#elif defined(TOOLKIT_GTK) - *handle = static_cast<intptr_t>(dib_->handle()); #else *handle = static_cast<intptr_t>(dib_->handle().fd); #endif @@ -256,9 +240,7 @@ skia::PlatformCanvas* ImageDataPlatformBackend::GetPlatformCanvas() { return mapped_canvas_.get(); } -SkCanvas* ImageDataPlatformBackend::GetCanvas() { - return mapped_canvas_.get(); -} +SkCanvas* ImageDataPlatformBackend::GetCanvas() { return mapped_canvas_.get(); } const SkBitmap* ImageDataPlatformBackend::GetMappedBitmap() const { if (!mapped_canvas_) @@ -268,31 +250,27 @@ const SkBitmap* ImageDataPlatformBackend::GetMappedBitmap() const { // ImageDataSimpleBackend ------------------------------------------------------ -ImageDataSimpleBackend::ImageDataSimpleBackend() - : map_count_(0) { -} +ImageDataSimpleBackend::ImageDataSimpleBackend() : map_count_(0) {} -ImageDataSimpleBackend::~ImageDataSimpleBackend() { -} +ImageDataSimpleBackend::~ImageDataSimpleBackend() {} bool ImageDataSimpleBackend::Init(PPB_ImageData_Impl* impl, PP_ImageDataFormat format, - int width, int height, + int width, + int height, bool init_to_zero) { - skia_bitmap_.setConfig(SkBitmap::kARGB_8888_Config, - impl->width(), impl->height()); - shared_memory_.reset(RenderThread::Get()->HostAllocateSharedMemoryBuffer( - skia_bitmap_.getSize()).release()); + skia_bitmap_.setConfig( + SkBitmap::kARGB_8888_Config, impl->width(), impl->height()); + shared_memory_.reset( + RenderThread::Get() + ->HostAllocateSharedMemoryBuffer(skia_bitmap_.getSize()) + .release()); return !!shared_memory_.get(); } -bool ImageDataSimpleBackend::IsMapped() const { - return map_count_ > 0; -} +bool ImageDataSimpleBackend::IsMapped() const { return map_count_ > 0; } -TransportDIB* ImageDataSimpleBackend::GetTransportDIB() const { - return NULL; -} +TransportDIB* ImageDataSimpleBackend::GetTransportDIB() const { return NULL; } void* ImageDataSimpleBackend::Map() { DCHECK(shared_memory_.get()); diff --git a/chromium/content/renderer/pepper/ppb_image_data_impl.h b/chromium/content/renderer/pepper/ppb_image_data_impl.h index 49c399b1d39..3ec7986ceb5 100644 --- a/chromium/content/renderer/pepper/ppb_image_data_impl.h +++ b/chromium/content/renderer/pepper/ppb_image_data_impl.h @@ -36,8 +36,11 @@ class CONTENT_EXPORT PPB_ImageData_Impl class Backend { public: virtual ~Backend() {}; - virtual bool Init(PPB_ImageData_Impl* impl, PP_ImageDataFormat format, - int width, int height, bool init_to_zero) = 0; + virtual bool Init(PPB_ImageData_Impl* impl, + PP_ImageDataFormat format, + int width, + int height, + bool init_to_zero) = 0; virtual bool IsMapped() const = 0; virtual TransportDIB* GetTransportDIB() const = 0; virtual void* Map() = 0; @@ -56,11 +59,11 @@ class CONTENT_EXPORT PPB_ImageData_Impl // Constructor used for unittests. The ImageData is always allocated locally. struct ForTest {}; - PPB_ImageData_Impl(PP_Instance instance, - ForTest); + PPB_ImageData_Impl(PP_Instance instance, ForTest); bool Init(PP_ImageDataFormat format, - int width, int height, + int width, + int height, bool init_to_zero); static PP_Resource Create(PP_Instance pp_instance, @@ -113,8 +116,11 @@ class ImageDataPlatformBackend : public PPB_ImageData_Impl::Backend { virtual ~ImageDataPlatformBackend(); // PPB_ImageData_Impl::Backend implementation. - virtual bool Init(PPB_ImageData_Impl* impl, PP_ImageDataFormat format, - int width, int height, bool init_to_zero) OVERRIDE; + virtual bool Init(PPB_ImageData_Impl* impl, + PP_ImageDataFormat format, + int width, + int height, + bool init_to_zero) OVERRIDE; virtual bool IsMapped() const OVERRIDE; virtual TransportDIB* GetTransportDIB() const OVERRIDE; virtual void* Map() OVERRIDE; @@ -145,8 +151,11 @@ class ImageDataSimpleBackend : public PPB_ImageData_Impl::Backend { virtual ~ImageDataSimpleBackend(); // PPB_ImageData_Impl::Backend implementation. - virtual bool Init(PPB_ImageData_Impl* impl, PP_ImageDataFormat format, - int width, int height, bool init_to_zero) OVERRIDE; + virtual bool Init(PPB_ImageData_Impl* impl, + PP_ImageDataFormat format, + int width, + int height, + bool init_to_zero) OVERRIDE; virtual bool IsMapped() const OVERRIDE; virtual TransportDIB* GetTransportDIB() const OVERRIDE; virtual void* Map() OVERRIDE; @@ -179,7 +188,7 @@ class ImageDataSimpleBackend : public PPB_ImageData_Impl::Backend { class ImageDataAutoMapper { public: explicit ImageDataAutoMapper(PPB_ImageData_Impl* image_data) - : image_data_(image_data) { + : image_data_(image_data) { if (image_data_->IsMapped()) { is_valid_ = true; needs_unmap_ = false; diff --git a/chromium/content/renderer/pepper/ppb_proxy_impl.cc b/chromium/content/renderer/pepper/ppb_proxy_impl.cc index cdae3ac65ed..aeae7f300f1 100644 --- a/chromium/content/renderer/pepper/ppb_proxy_impl.cc +++ b/chromium/content/renderer/pepper/ppb_proxy_impl.cc @@ -59,19 +59,12 @@ PP_Bool IsInModuleDestructor(PP_Module module) { } const PPB_Proxy_Private ppb_proxy = { - &PluginCrashed, - &GetInstanceForResource, - &SetReserveInstanceIDCallback, - &AddRefModule, - &ReleaseModule, - &IsInModuleDestructor -}; + &PluginCrashed, &GetInstanceForResource, &SetReserveInstanceIDCallback, + &AddRefModule, &ReleaseModule, &IsInModuleDestructor}; } // namespace // static -const PPB_Proxy_Private* PPB_Proxy_Impl::GetInterface() { - return &ppb_proxy; -} +const PPB_Proxy_Private* PPB_Proxy_Impl::GetInterface() { return &ppb_proxy; } } // namespace content diff --git a/chromium/content/renderer/pepper/ppb_proxy_impl.h b/chromium/content/renderer/pepper/ppb_proxy_impl.h index f7341c0ec17..e8a6a318526 100644 --- a/chromium/content/renderer/pepper/ppb_proxy_impl.h +++ b/chromium/content/renderer/pepper/ppb_proxy_impl.h @@ -17,4 +17,3 @@ class PPB_Proxy_Impl { } // namespace content #endif // CONTENT_RENDERER_PEPPER_PPB_PROXY_IMPL_H_ - diff --git a/chromium/content/renderer/pepper/ppb_scrollbar_impl.cc b/chromium/content/renderer/pepper/ppb_scrollbar_impl.cc index 326c7003183..e276e52e942 100644 --- a/chromium/content/renderer/pepper/ppb_scrollbar_impl.cc +++ b/chromium/content/renderer/pepper/ppb_scrollbar_impl.cc @@ -35,21 +35,16 @@ using blink::WebPluginScrollbar; namespace content { // static -PP_Resource PPB_Scrollbar_Impl::Create(PP_Instance instance, - bool vertical) { - scoped_refptr<PPB_Scrollbar_Impl> scrollbar( - new PPB_Scrollbar_Impl(instance)); +PP_Resource PPB_Scrollbar_Impl::Create(PP_Instance instance, bool vertical) { + scoped_refptr<PPB_Scrollbar_Impl> scrollbar(new PPB_Scrollbar_Impl(instance)); scrollbar->Init(vertical); return scrollbar->GetReference(); } PPB_Scrollbar_Impl::PPB_Scrollbar_Impl(PP_Instance instance) - : PPB_Widget_Impl(instance), - weak_ptr_factory_(this) { -} + : PPB_Widget_Impl(instance), weak_ptr_factory_(this) {} -PPB_Scrollbar_Impl::~PPB_Scrollbar_Impl() { -} +PPB_Scrollbar_Impl::~PPB_Scrollbar_Impl() {} void PPB_Scrollbar_Impl::Init(bool vertical) { PepperPluginInstanceImpl* plugin_instance = @@ -62,25 +57,17 @@ void PPB_Scrollbar_Impl::Init(bool vertical) { static_cast<blink::WebPluginScrollbarClient*>(this))); } -PPB_Scrollbar_API* PPB_Scrollbar_Impl::AsPPB_Scrollbar_API() { - return this; -} +PPB_Scrollbar_API* PPB_Scrollbar_Impl::AsPPB_Scrollbar_API() { return this; } -void PPB_Scrollbar_Impl::InstanceWasDeleted() { - scrollbar_.reset(); -} +void PPB_Scrollbar_Impl::InstanceWasDeleted() { scrollbar_.reset(); } uint32_t PPB_Scrollbar_Impl::GetThickness() { return WebPluginScrollbar::defaultThickness(); } -bool PPB_Scrollbar_Impl::IsOverlay() { - return scrollbar_->isOverlay(); -} +bool PPB_Scrollbar_Impl::IsOverlay() { return scrollbar_->isOverlay(); } -uint32_t PPB_Scrollbar_Impl::GetValue() { - return scrollbar_->value(); -} +uint32_t PPB_Scrollbar_Impl::GetValue() { return scrollbar_->value(); } void PPB_Scrollbar_Impl::SetValue(uint32_t value) { if (scrollbar_) @@ -101,7 +88,8 @@ void PPB_Scrollbar_Impl::SetTickMarks(const PP_Rect* tick_marks, tickmarks_[i] = WebRect(tick_marks[i].point.x, tick_marks[i].point.y, tick_marks[i].size.width, - tick_marks[i].size.height);; + tick_marks[i].size.height); + ; } PP_Rect rect = location(); Invalidate(&rect); @@ -111,8 +99,9 @@ void PPB_Scrollbar_Impl::ScrollBy(PP_ScrollBy_Dev unit, int32_t multiplier) { if (!scrollbar_) return; - WebScrollbar::ScrollDirection direction = multiplier >= 0 ? - WebScrollbar::ScrollForward : WebScrollbar::ScrollBackward; + WebScrollbar::ScrollDirection direction = multiplier >= 0 + ? WebScrollbar::ScrollForward + : WebScrollbar::ScrollBackward; float fmultiplier = 1.0; WebScrollbar::ScrollGranularity granularity; @@ -175,19 +164,18 @@ void PPB_Scrollbar_Impl::valueChanged(blink::WebPluginScrollbar* scrollbar) { return; const PPP_Scrollbar_Dev* ppp_scrollbar = - static_cast<const PPP_Scrollbar_Dev*>(plugin_module->GetPluginInterface( - PPP_SCROLLBAR_DEV_INTERFACE)); + static_cast<const PPP_Scrollbar_Dev*>( + plugin_module->GetPluginInterface(PPP_SCROLLBAR_DEV_INTERFACE)); if (!ppp_scrollbar) { // Try the old version. This is ok because the old interface is a subset of // the new one, and ValueChanged didn't change. - ppp_scrollbar = - static_cast<const PPP_Scrollbar_Dev*>(plugin_module->GetPluginInterface( - PPP_SCROLLBAR_DEV_INTERFACE_0_2)); + ppp_scrollbar = static_cast<const PPP_Scrollbar_Dev*>( + plugin_module->GetPluginInterface(PPP_SCROLLBAR_DEV_INTERFACE_0_2)); if (!ppp_scrollbar) return; } - ppp_scrollbar->ValueChanged(pp_instance(), pp_resource(), - scrollbar_->value()); + ppp_scrollbar->ValueChanged( + pp_instance(), pp_resource(), scrollbar_->value()); } void PPB_Scrollbar_Impl::overlayChanged(WebPluginScrollbar* scrollbar) { @@ -197,21 +185,18 @@ void PPB_Scrollbar_Impl::overlayChanged(WebPluginScrollbar* scrollbar) { return; const PPP_Scrollbar_Dev* ppp_scrollbar = - static_cast<const PPP_Scrollbar_Dev*>(plugin_module->GetPluginInterface( - PPP_SCROLLBAR_DEV_INTERFACE)); + static_cast<const PPP_Scrollbar_Dev*>( + plugin_module->GetPluginInterface(PPP_SCROLLBAR_DEV_INTERFACE)); if (!ppp_scrollbar) return; - ppp_scrollbar->OverlayChanged(pp_instance(), pp_resource(), - PP_FromBool(IsOverlay())); + ppp_scrollbar->OverlayChanged( + pp_instance(), pp_resource(), PP_FromBool(IsOverlay())); } void PPB_Scrollbar_Impl::invalidateScrollbarRect( blink::WebPluginScrollbar* scrollbar, const blink::WebRect& rect) { - gfx::Rect gfx_rect(rect.x, - rect.y, - rect.width, - rect.height); + gfx::Rect gfx_rect(rect.x, rect.y, rect.width, rect.height); dirty_.Union(gfx_rect); // Can't call into the client to tell them about the invalidate right away, // since the PPB_Scrollbar_Impl code is still in the middle of updating its diff --git a/chromium/content/renderer/pepper/ppb_scrollbar_impl.h b/chromium/content/renderer/pepper/ppb_scrollbar_impl.h index f649c816d8c..6eeee80ea34 100644 --- a/chromium/content/renderer/pepper/ppb_scrollbar_impl.h +++ b/chromium/content/renderer/pepper/ppb_scrollbar_impl.h @@ -46,8 +46,8 @@ class PPB_Scrollbar_Impl : public PPB_Widget_Impl, // PPB_Widget private implementation. virtual PP_Bool PaintInternal(const gfx::Rect& rect, PPB_ImageData_Impl* image) OVERRIDE; - virtual PP_Bool HandleEventInternal( - const ppapi::InputEventData& data) OVERRIDE; + virtual PP_Bool HandleEventInternal(const ppapi::InputEventData& data) + OVERRIDE; virtual void SetLocationInternal(const PP_Rect* location) OVERRIDE; // blink::WebPluginScrollbarClient implementation. @@ -55,9 +55,9 @@ class PPB_Scrollbar_Impl : public PPB_Widget_Impl, virtual void overlayChanged(blink::WebPluginScrollbar* scrollbar) OVERRIDE; virtual void invalidateScrollbarRect(blink::WebPluginScrollbar* scrollbar, const blink::WebRect& rect) OVERRIDE; - virtual void getTickmarks( - blink::WebPluginScrollbar* scrollbar, - blink::WebVector<blink::WebRect>* tick_marks) const OVERRIDE; + virtual void getTickmarks(blink::WebPluginScrollbar* scrollbar, + blink::WebVector<blink::WebRect>* tick_marks) const + OVERRIDE; void NotifyInvalidate(); diff --git a/chromium/content/renderer/pepper/ppb_uma_private_impl.cc b/chromium/content/renderer/pepper/ppb_uma_private_impl.cc deleted file mode 100644 index ae9fe10f9a6..00000000000 --- a/chromium/content/renderer/pepper/ppb_uma_private_impl.cc +++ /dev/null @@ -1,97 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "content/renderer/pepper/ppb_uma_private_impl.h" - -#include "base/metrics/histogram.h" -#include "ppapi/c/pp_var.h" -#include "ppapi/c/private/ppb_uma_private.h" -#include "ppapi/shared_impl/var.h" - -using ppapi::StringVar; - -namespace content { - -namespace { - -#define RETURN_IF_BAD_ARGS(_name, _sample, _min, _max, _bucket_count) \ - do { \ - if (_name.type != PP_VARTYPE_STRING || _name.value.as_id == 0) \ - return; \ - if (_min >= _max) \ - return; \ - if (_bucket_count <= 1) \ - return; \ - } while (0) - -void HistogramCustomTimes(PP_Var name, - int64_t sample, - int64_t min, int64_t max, - uint32_t bucket_count) { - RETURN_IF_BAD_ARGS(name, sample, min, max, bucket_count); - - StringVar* name_string = StringVar::FromPPVar(name); - if (name_string == NULL) - return; - base::HistogramBase* counter = - base::Histogram::FactoryTimeGet( - name_string->value(), - base::TimeDelta::FromMilliseconds(min), - base::TimeDelta::FromMilliseconds(max), - bucket_count, - base::HistogramBase::kUmaTargetedHistogramFlag); - counter->AddTime(base::TimeDelta::FromMilliseconds(sample)); -} - -void HistogramCustomCounts(PP_Var name, - int32_t sample, - int32_t min, int32_t max, - uint32_t bucket_count) { - RETURN_IF_BAD_ARGS(name, sample, min, max, bucket_count); - - StringVar* name_string = StringVar::FromPPVar(name); - if (name_string == NULL) - return; - base::HistogramBase* counter = - base::Histogram::FactoryGet( - name_string->value(), - min, - max, - bucket_count, - base::HistogramBase::kUmaTargetedHistogramFlag); - counter->Add(sample); -} - -void HistogramEnumeration(PP_Var name, - int32_t sample, - int32_t boundary_value) { - RETURN_IF_BAD_ARGS(name, sample, 1, boundary_value, boundary_value + 1); - - StringVar* name_string = StringVar::FromPPVar(name); - if (name_string == NULL) - return; - base::HistogramBase* counter = - base::LinearHistogram::FactoryGet( - name_string->value(), - 1, - boundary_value, - boundary_value + 1, - base::HistogramBase::kUmaTargetedHistogramFlag); - counter->Add(sample); -} - -} // namespace - -const PPB_UMA_Private ppb_uma = { - &HistogramCustomTimes, - &HistogramCustomCounts, - &HistogramEnumeration, -}; - -// static -const PPB_UMA_Private* PPB_UMA_Private_Impl::GetInterface() { - return &ppb_uma; -} - -} // namespace content diff --git a/chromium/content/renderer/pepper/ppb_uma_private_impl.h b/chromium/content/renderer/pepper/ppb_uma_private_impl.h deleted file mode 100644 index 91eae471043..00000000000 --- a/chromium/content/renderer/pepper/ppb_uma_private_impl.h +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CONTENT_RENDERER_PEPPER_PPB_UMA_PRIVATE_IMPL_H_ -#define CONTENT_RENDERER_PEPPER_PPB_UMA_PRIVATE_IMPL_H_ - -#include "ppapi/c/private/ppb_uma_private.h" - -namespace content { - -class PPB_UMA_Private_Impl { - public: - static const PPB_UMA_Private* GetInterface(); -}; - -} // namespace content - -#endif // CONTENT_RENDERER_PEPPER_PPB_UMA_PRIVATE_IMPL_H_ diff --git a/chromium/content/renderer/pepper/ppb_var_deprecated_impl.cc b/chromium/content/renderer/pepper/ppb_var_deprecated_impl.cc index 6f12733c1a4..f8fdd1431bf 100644 --- a/chromium/content/renderer/pepper/ppb_var_deprecated_impl.cc +++ b/chromium/content/renderer/pepper/ppb_var_deprecated_impl.cc @@ -109,8 +109,7 @@ bool PPVarToNPVariantNoCopy(PP_Var var, NPVariant* result) { class ObjectAccessorTryCatch : public TryCatch { public: ObjectAccessorTryCatch(PP_Var object, PP_Var* exception) - : TryCatch(exception), - object_(NPObjectVar::FromPPVar(object)) { + : TryCatch(exception), object_(NPObjectVar::FromPPVar(object)) { if (!object_.get()) { SetException(kInvalidObjectException); } @@ -145,8 +144,7 @@ class ObjectAccessorWithIdentifierTryCatch : public ObjectAccessorTryCatch { ObjectAccessorWithIdentifierTryCatch(PP_Var object, PP_Var identifier, PP_Var* exception) - : ObjectAccessorTryCatch(object, exception), - identifier_(0) { + : ObjectAccessorTryCatch(object, exception), identifier_(0) { if (!has_exception()) { identifier_ = PPVarToNPIdentifier(identifier); if (!identifier_) @@ -162,43 +160,36 @@ class ObjectAccessorWithIdentifierTryCatch : public ObjectAccessorTryCatch { DISALLOW_COPY_AND_ASSIGN(ObjectAccessorWithIdentifierTryCatch); }; -PP_Bool HasProperty(PP_Var var, - PP_Var name, - 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 PP_FALSE; - return BoolToPPBool(WebBindings::hasProperty(NULL, - accessor.object()->np_object(), - accessor.identifier())); + return BoolToPPBool(WebBindings::hasProperty( + NULL, accessor.object()->np_object(), accessor.identifier())); } -bool HasPropertyDeprecated(PP_Var var, - PP_Var name, - PP_Var* exception) { +bool HasPropertyDeprecated(PP_Var var, PP_Var name, PP_Var* exception) { return PPBoolToBool(HasProperty(var, name, exception)); } -bool HasMethodDeprecated(PP_Var var, - PP_Var name, - PP_Var* exception) { +bool HasMethodDeprecated(PP_Var var, PP_Var name, PP_Var* exception) { ObjectAccessorWithIdentifierTryCatch accessor(var, name, exception); if (accessor.has_exception()) return false; - return WebBindings::hasMethod(NULL, accessor.object()->np_object(), - accessor.identifier()); + return WebBindings::hasMethod( + NULL, accessor.object()->np_object(), accessor.identifier()); } -PP_Var GetProperty(PP_Var var, - PP_Var name, - PP_Var* exception) { +PP_Var GetProperty(PP_Var var, PP_Var name, PP_Var* exception) { ObjectAccessorWithIdentifierTryCatch accessor(var, name, exception); if (accessor.has_exception()) return PP_MakeUndefined(); NPVariant result; - if (!WebBindings::getProperty(NULL, accessor.object()->np_object(), - accessor.identifier(), &result)) { + if (!WebBindings::getProperty(NULL, + accessor.object()->np_object(), + accessor.identifier(), + &result)) { // An exception may have been raised. accessor.SetException(kUnableToGetPropertyException); return PP_MakeUndefined(); @@ -222,8 +213,8 @@ void EnumerateProperties(PP_Var var, NPIdentifier* identifiers = NULL; uint32_t count = 0; - if (!WebBindings::enumerate(NULL, accessor.object()->np_object(), - &identifiers, &count)) { + if (!WebBindings::enumerate( + NULL, accessor.object()->np_object(), &identifiers, &count)) { accessor.SetException(kUnableToGetAllPropertiesException); return; } @@ -252,20 +243,20 @@ void SetPropertyDeprecated(PP_Var var, accessor.SetException(kInvalidValueException); return; } - if (!WebBindings::setProperty(NULL, accessor.object()->np_object(), - accessor.identifier(), &variant)) + if (!WebBindings::setProperty(NULL, + accessor.object()->np_object(), + accessor.identifier(), + &variant)) accessor.SetException(kUnableToSetPropertyException); } -void DeletePropertyDeprecated(PP_Var var, - PP_Var name, - PP_Var* exception) { +void DeletePropertyDeprecated(PP_Var var, PP_Var name, PP_Var* exception) { ObjectAccessorWithIdentifierTryCatch accessor(var, name, exception); if (accessor.has_exception()) return; - if (!WebBindings::removeProperty(NULL, accessor.object()->np_object(), - accessor.identifier())) + if (!WebBindings::removeProperty( + NULL, accessor.object()->np_object(), accessor.identifier())) accessor.SetException(kUnableToRemovePropertyException); } @@ -305,11 +296,15 @@ PP_Var InternalCallDeprecated(ObjectAccessorTryCatch* accessor, NPVariant result; if (identifier) { - ok = WebBindings::invoke(NULL, accessor->object()->np_object(), - identifier, args.get(), argc, &result); + ok = WebBindings::invoke(NULL, + accessor->object()->np_object(), + identifier, + args.get(), + argc, + &result); } else { - ok = WebBindings::invokeDefault(NULL, accessor->object()->np_object(), - args.get(), argc, &result); + ok = WebBindings::invokeDefault( + NULL, accessor->object()->np_object(), args.get(), argc, &result); } if (!ok) { @@ -333,18 +328,14 @@ PP_Var CallDeprecated(PP_Var var, return PP_MakeUndefined(); PepperPluginInstanceImpl* plugin = accessor.GetPluginInstance(); if (plugin && plugin->IsProcessingUserGesture()) { - blink::WebScopedUserGesture user_gesture( - plugin->CurrentUserGestureToken()); - return InternalCallDeprecated(&accessor, method_name, argc, argv, - exception); + blink::WebScopedUserGesture user_gesture(plugin->CurrentUserGestureToken()); + return InternalCallDeprecated( + &accessor, method_name, argc, argv, exception); } return InternalCallDeprecated(&accessor, method_name, argc, argv, exception); } -PP_Var Construct(PP_Var var, - uint32_t argc, - PP_Var* argv, - PP_Var* exception) { +PP_Var Construct(PP_Var var, uint32_t argc, PP_Var* argv, PP_Var* exception) { ObjectAccessorTryCatch accessor(var, exception); if (accessor.has_exception()) return PP_MakeUndefined(); @@ -362,8 +353,8 @@ PP_Var Construct(PP_Var var, } NPVariant result; - if (!WebBindings::construct(NULL, accessor.object()->np_object(), - args.get(), argc, &result)) { + if (!WebBindings::construct( + NULL, accessor.object()->np_object(), args.get(), argc, &result)) { // An exception may have been raised. accessor.SetException(kUnableToConstructException); return PP_MakeUndefined(); @@ -381,8 +372,8 @@ bool IsInstanceOfDeprecated(PP_Var var, if (!object.get()) return false; // Not an object at all. - return PluginObject::IsInstanceOf(object->np_object(), - ppp_class, ppp_class_data); + return PluginObject::IsInstanceOf( + object->np_object(), ppp_class, ppp_class_data); } PP_Var CreateObjectDeprecated(PP_Instance pp_instance, @@ -403,8 +394,8 @@ PP_Var CreateObjectWithModuleDeprecated(PP_Module pp_module, PluginModule* module = HostGlobals::Get()->GetModule(pp_module); if (!module) return PP_MakeNull(); - return PluginObject::Create(module->GetSomeInstance(), - ppp_class, ppp_class_data); + return PluginObject::Create( + module->GetSomeInstance(), ppp_class, ppp_class_data); } } // namespace @@ -412,25 +403,23 @@ PP_Var CreateObjectWithModuleDeprecated(PP_Module pp_module, // static const PPB_Var_Deprecated* PPB_Var_Deprecated_Impl::GetVarDeprecatedInterface() { static const PPB_Var_Deprecated var_deprecated_interface = { - ppapi::PPB_Var_Shared::GetVarInterface1_0()->AddRef, - ppapi::PPB_Var_Shared::GetVarInterface1_0()->Release, - ppapi::PPB_Var_Shared::GetVarInterface1_0()->VarFromUtf8, - ppapi::PPB_Var_Shared::GetVarInterface1_0()->VarToUtf8, - &HasPropertyDeprecated, - &HasMethodDeprecated, - &GetProperty, - &EnumerateProperties, - &SetPropertyDeprecated, - &DeletePropertyDeprecated, - &CallDeprecated, - &Construct, - &IsInstanceOfDeprecated, - &CreateObjectDeprecated, - &CreateObjectWithModuleDeprecated, - }; + ppapi::PPB_Var_Shared::GetVarInterface1_0()->AddRef, + ppapi::PPB_Var_Shared::GetVarInterface1_0()->Release, + ppapi::PPB_Var_Shared::GetVarInterface1_0()->VarFromUtf8, + ppapi::PPB_Var_Shared::GetVarInterface1_0()->VarToUtf8, + &HasPropertyDeprecated, + &HasMethodDeprecated, + &GetProperty, + &EnumerateProperties, + &SetPropertyDeprecated, + &DeletePropertyDeprecated, + &CallDeprecated, + &Construct, + &IsInstanceOfDeprecated, + &CreateObjectDeprecated, + &CreateObjectWithModuleDeprecated, }; return &var_deprecated_interface; } } // namespace content - diff --git a/chromium/content/renderer/pepper/ppb_video_decoder_impl.cc b/chromium/content/renderer/pepper/ppb_video_decoder_impl.cc index 336892c2e64..4a3cde418a2 100644 --- a/chromium/content/renderer/pepper/ppb_video_decoder_impl.cc +++ b/chromium/content/renderer/pepper/ppb_video_decoder_impl.cc @@ -9,14 +9,14 @@ #include "base/logging.h" #include "base/message_loop/message_loop.h" #include "base/metrics/histogram.h" -#include "content/renderer/media/pepper_platform_video_decoder.h" +#include "content/common/gpu/client/gpu_channel_host.h" #include "content/renderer/pepper/common.h" #include "content/renderer/pepper/host_globals.h" -#include "content/renderer/pepper/pepper_platform_context_3d.h" #include "content/renderer/pepper/pepper_plugin_instance_impl.h" #include "content/renderer/pepper/plugin_module.h" #include "content/renderer/pepper/ppb_buffer_impl.h" #include "content/renderer/pepper/ppb_graphics_3d_impl.h" +#include "content/renderer/render_thread_impl.h" #include "gpu/command_buffer/client/gles2_implementation.h" #include "media/video/picture.h" #include "media/video/video_decode_accelerator.h" @@ -32,7 +32,6 @@ using ppapi::TrackedCallback; using ppapi::thunk::EnterResourceNoLock; using ppapi::thunk::PPB_Buffer_API; using ppapi::thunk::PPB_Graphics3D_API; -using ppapi::thunk::PPB_VideoDecoder_API; namespace { @@ -41,10 +40,10 @@ media::VideoCodecProfile PPToMediaProfile( const PP_VideoDecoder_Profile pp_profile) { switch (pp_profile) { case PP_VIDEODECODER_H264PROFILE_NONE: - // HACK: PPAPI contains a bogus "none" h264 profile that doesn't - // correspond to anything in h.264; but a number of released chromium - // versions silently promoted this to Baseline profile, so we retain that - // behavior here. Fall through. + // HACK: PPAPI contains a bogus "none" h264 profile that doesn't + // correspond to anything in h.264; but a number of released chromium + // versions silently promoted this to Baseline profile, so we retain that + // behavior here. Fall through. case PP_VIDEODECODER_H264PROFILE_BASELINE: return media::H264PROFILE_BASELINE; case PP_VIDEODECODER_H264PROFILE_MAIN: @@ -77,13 +76,13 @@ media::VideoCodecProfile PPToMediaProfile( PP_VideoDecodeError_Dev MediaToPPError( media::VideoDecodeAccelerator::Error error) { switch (error) { - case media::VideoDecodeAccelerator::ILLEGAL_STATE : + case media::VideoDecodeAccelerator::ILLEGAL_STATE: return PP_VIDEODECODERERROR_ILLEGAL_STATE; - case media::VideoDecodeAccelerator::INVALID_ARGUMENT : + case media::VideoDecodeAccelerator::INVALID_ARGUMENT: return PP_VIDEODECODERERROR_INVALID_ARGUMENT; - case media::VideoDecodeAccelerator::UNREADABLE_INPUT : + case media::VideoDecodeAccelerator::UNREADABLE_INPUT: return PP_VIDEODECODERERROR_UNREADABLE_INPUT; - case media::VideoDecodeAccelerator::PLATFORM_FAILURE : + case media::VideoDecodeAccelerator::PLATFORM_FAILURE: return PP_VIDEODECODERERROR_PLATFORM_FAILURE; default: NOTREACHED(); @@ -96,8 +95,7 @@ PP_VideoDecodeError_Dev MediaToPPError( namespace content { PPB_VideoDecoder_Impl::PPB_VideoDecoder_Impl(PP_Instance instance) - : PPB_VideoDecoder_Shared(instance), - ppp_videodecoder_(NULL) { + : PPB_VideoDecoder_Shared(instance), ppp_videodecoder_(NULL) { PluginModule* plugin_module = HostGlobals::Get()->GetInstance(pp_instance())->module(); if (plugin_module) { @@ -106,53 +104,47 @@ PPB_VideoDecoder_Impl::PPB_VideoDecoder_Impl(PP_Instance instance) } } -PPB_VideoDecoder_Impl::~PPB_VideoDecoder_Impl() { - Destroy(); -} +PPB_VideoDecoder_Impl::~PPB_VideoDecoder_Impl() { Destroy(); } // static -PP_Resource PPB_VideoDecoder_Impl::Create( - PP_Instance instance, - PP_Resource graphics_context, - PP_VideoDecoder_Profile profile) { - EnterResourceNoLock<PPB_Graphics3D_API> enter_context(graphics_context, true); - if (enter_context.failed()) - return 0; - PPB_Graphics3D_Impl* graphics3d_impl = - static_cast<PPB_Graphics3D_Impl*>(enter_context.object()); - +PP_Resource PPB_VideoDecoder_Impl::Create(PP_Instance instance, + PP_Resource graphics_context, + PP_VideoDecoder_Profile profile) { scoped_refptr<PPB_VideoDecoder_Impl> decoder( new PPB_VideoDecoder_Impl(instance)); - if (decoder->Init(graphics_context, graphics3d_impl->platform_context(), - graphics3d_impl->gles2_impl(), profile)) + if (decoder->Init(graphics_context, profile)) return decoder->GetReference(); return 0; } -bool PPB_VideoDecoder_Impl::Init( - PP_Resource graphics_context, - PlatformContext3D* context, - gpu::gles2::GLES2Implementation* gles2_impl, - PP_VideoDecoder_Profile profile) { - InitCommon(graphics_context, gles2_impl); - - int command_buffer_route_id = context->GetCommandBufferRouteId(); - if (command_buffer_route_id == 0) +bool PPB_VideoDecoder_Impl::Init(PP_Resource graphics_context, + PP_VideoDecoder_Profile profile) { + EnterResourceNoLock<PPB_Graphics3D_API> enter_context(graphics_context, true); + if (enter_context.failed()) return false; - platform_video_decoder_.reset(new PlatformVideoDecoder( - this, command_buffer_route_id)); - if (!platform_video_decoder_) + PPB_Graphics3D_Impl* graphics_3d = + static_cast<PPB_Graphics3D_Impl*>(enter_context.object()); + + int command_buffer_route_id = graphics_3d->GetCommandBufferRouteId(); + if (command_buffer_route_id == 0) return false; + InitCommon(graphics_context, graphics_3d->gles2_impl()); FlushCommandBuffer(); - return platform_video_decoder_->Initialize(PPToMediaProfile(profile)); + + // This is not synchronous, but subsequent IPC messages will be buffered, so + // it is okay to immediately send IPC messages through the returned channel. + GpuChannelHost* channel = graphics_3d->channel(); + DCHECK(channel); + decoder_ = channel->CreateVideoDecoder(command_buffer_route_id); + return (decoder_ && decoder_->Initialize(PPToMediaProfile(profile), this)); } int32_t PPB_VideoDecoder_Impl::Decode( const PP_VideoBitstreamBuffer_Dev* bitstream_buffer, scoped_refptr<TrackedCallback> callback) { - if (!platform_video_decoder_) + if (!decoder_) return PP_ERROR_BADRESOURCE; EnterResourceNoLock<PPB_Buffer_API> enter(bitstream_buffer->data, true); @@ -161,22 +153,21 @@ int32_t PPB_VideoDecoder_Impl::Decode( PPB_Buffer_Impl* buffer = static_cast<PPB_Buffer_Impl*>(enter.object()); DCHECK_GE(bitstream_buffer->id, 0); - media::BitstreamBuffer decode_buffer( - bitstream_buffer->id, - buffer->shared_memory()->handle(), - bitstream_buffer->size); + media::BitstreamBuffer decode_buffer(bitstream_buffer->id, + buffer->shared_memory()->handle(), + bitstream_buffer->size); if (!SetBitstreamBufferCallback(bitstream_buffer->id, callback)) return PP_ERROR_BADARGUMENT; FlushCommandBuffer(); - platform_video_decoder_->Decode(decode_buffer); + decoder_->Decode(decode_buffer); return PP_OK_COMPLETIONPENDING; } void PPB_VideoDecoder_Impl::AssignPictureBuffers( uint32_t no_of_buffers, const PP_PictureBuffer_Dev* buffers) { - if (!platform_video_decoder_) + if (!decoder_) return; UMA_HISTOGRAM_COUNTS_100("Media.PepperVideoDecoderPictureCount", no_of_buffers); @@ -195,46 +186,45 @@ void PPB_VideoDecoder_Impl::AssignPictureBuffers( } FlushCommandBuffer(); - platform_video_decoder_->AssignPictureBuffers(wrapped_buffers); + decoder_->AssignPictureBuffers(wrapped_buffers); } void PPB_VideoDecoder_Impl::ReusePictureBuffer(int32_t picture_buffer_id) { - if (!platform_video_decoder_) + if (!decoder_) return; FlushCommandBuffer(); - platform_video_decoder_->ReusePictureBuffer(picture_buffer_id); + decoder_->ReusePictureBuffer(picture_buffer_id); } int32_t PPB_VideoDecoder_Impl::Flush(scoped_refptr<TrackedCallback> callback) { - if (!platform_video_decoder_) + if (!decoder_) return PP_ERROR_BADRESOURCE; if (!SetFlushCallback(callback)) return PP_ERROR_INPROGRESS; FlushCommandBuffer(); - platform_video_decoder_->Flush(); + decoder_->Flush(); return PP_OK_COMPLETIONPENDING; } int32_t PPB_VideoDecoder_Impl::Reset(scoped_refptr<TrackedCallback> callback) { - if (!platform_video_decoder_) + if (!decoder_) return PP_ERROR_BADRESOURCE; if (!SetResetCallback(callback)) return PP_ERROR_INPROGRESS; FlushCommandBuffer(); - platform_video_decoder_->Reset(); + decoder_->Reset(); return PP_OK_COMPLETIONPENDING; } void PPB_VideoDecoder_Impl::Destroy() { FlushCommandBuffer(); - if (platform_video_decoder_) - platform_video_decoder_.release()->Destroy(); + decoder_.reset(); ppp_videodecoder_ = NULL; ::ppapi::PPB_VideoDecoder_Shared::Destroy(); @@ -244,15 +234,20 @@ void PPB_VideoDecoder_Impl::ProvidePictureBuffers( uint32 requested_num_of_buffers, const gfx::Size& dimensions, uint32 texture_target) { + DCHECK(RenderThreadImpl::current()); if (!ppp_videodecoder_) return; PP_Size out_dim = PP_MakeSize(dimensions.width(), dimensions.height()); - ppp_videodecoder_->ProvidePictureBuffers(pp_instance(), pp_resource(), - requested_num_of_buffers, &out_dim, texture_target); + ppp_videodecoder_->ProvidePictureBuffers(pp_instance(), + pp_resource(), + requested_num_of_buffers, + &out_dim, + texture_target); } void PPB_VideoDecoder_Impl::PictureReady(const media::Picture& picture) { + DCHECK(RenderThreadImpl::current()); if (!ppp_videodecoder_) return; @@ -263,39 +258,40 @@ void PPB_VideoDecoder_Impl::PictureReady(const media::Picture& picture) { } void PPB_VideoDecoder_Impl::DismissPictureBuffer(int32 picture_buffer_id) { + DCHECK(RenderThreadImpl::current()); if (!ppp_videodecoder_) return; - ppp_videodecoder_->DismissPictureBuffer(pp_instance(), pp_resource(), - picture_buffer_id); + ppp_videodecoder_->DismissPictureBuffer( + pp_instance(), pp_resource(), picture_buffer_id); } void PPB_VideoDecoder_Impl::NotifyError( media::VideoDecodeAccelerator::Error error) { + DCHECK(RenderThreadImpl::current()); if (!ppp_videodecoder_) return; PP_VideoDecodeError_Dev pp_error = MediaToPPError(error); ppp_videodecoder_->NotifyError(pp_instance(), pp_resource(), pp_error); - UMA_HISTOGRAM_ENUMERATION( - "Media.PepperVideoDecoderError", error, - media::VideoDecodeAccelerator::LARGEST_ERROR_ENUM); + UMA_HISTOGRAM_ENUMERATION("Media.PepperVideoDecoderError", + error, + media::VideoDecodeAccelerator::LARGEST_ERROR_ENUM); } void PPB_VideoDecoder_Impl::NotifyResetDone() { + DCHECK(RenderThreadImpl::current()); RunResetCallback(PP_OK); } void PPB_VideoDecoder_Impl::NotifyEndOfBitstreamBuffer( int32 bitstream_buffer_id) { + DCHECK(RenderThreadImpl::current()); RunBitstreamBufferCallback(bitstream_buffer_id, PP_OK); } void PPB_VideoDecoder_Impl::NotifyFlushDone() { + DCHECK(RenderThreadImpl::current()); RunFlushCallback(PP_OK); } -void PPB_VideoDecoder_Impl::NotifyInitializeDone() { - NOTREACHED() << "PlatformVideoDecoder::Initialize() is synchronous!"; -} - } // namespace content diff --git a/chromium/content/renderer/pepper/ppb_video_decoder_impl.h b/chromium/content/renderer/pepper/ppb_video_decoder_impl.h index d9b195bc5aa..c099950f97d 100644 --- a/chromium/content/renderer/pepper/ppb_video_decoder_impl.h +++ b/chromium/content/renderer/pepper/ppb_video_decoder_impl.h @@ -14,20 +14,13 @@ #include "ppapi/c/pp_var.h" #include "ppapi/shared_impl/ppb_video_decoder_shared.h" #include "ppapi/shared_impl/resource.h" -#include "ppapi/thunk/ppb_video_decoder_api.h" +#include "ppapi/thunk/ppb_video_decoder_dev_api.h" struct PP_PictureBuffer_Dev; struct PP_VideoBitstreamBuffer_Dev; -namespace gpu { -namespace gles2 { -class GLES2Implementation; -} // namespace gles2 -} // namespace gpu - namespace content { -class PlatformContext3D; -class PlatformVideoDecoder; +class PPB_Graphics3D_Impl; class PPB_VideoDecoder_Impl : public ppapi::PPB_VideoDecoder_Shared, public media::VideoDecodeAccelerator::Client { @@ -38,17 +31,18 @@ class PPB_VideoDecoder_Impl : public ppapi::PPB_VideoDecoder_Shared, PP_Resource graphics_context, PP_VideoDecoder_Profile profile); - // PPB_VideoDecoder_API implementation. - virtual int32_t Decode( - const PP_VideoBitstreamBuffer_Dev* bitstream_buffer, - scoped_refptr<ppapi::TrackedCallback> callback) OVERRIDE; - virtual void AssignPictureBuffers( - uint32_t no_of_buffers, const PP_PictureBuffer_Dev* buffers) OVERRIDE; + // PPB_VideoDecoder_Dev_API implementation. + virtual int32_t Decode(const PP_VideoBitstreamBuffer_Dev* bitstream_buffer, + scoped_refptr<ppapi::TrackedCallback> callback) + OVERRIDE; + virtual void AssignPictureBuffers(uint32_t no_of_buffers, + const PP_PictureBuffer_Dev* buffers) + OVERRIDE; virtual void ReusePictureBuffer(int32_t picture_buffer_id) OVERRIDE; - virtual int32_t Flush( - scoped_refptr<ppapi::TrackedCallback> callback) OVERRIDE; - virtual int32_t Reset( - scoped_refptr<ppapi::TrackedCallback> callback) OVERRIDE; + virtual int32_t Flush(scoped_refptr<ppapi::TrackedCallback> callback) + OVERRIDE; + virtual int32_t Reset(scoped_refptr<ppapi::TrackedCallback> callback) + OVERRIDE; virtual void Destroy() OVERRIDE; // media::VideoDecodeAccelerator::Client implementation. @@ -57,9 +51,7 @@ class PPB_VideoDecoder_Impl : public ppapi::PPB_VideoDecoder_Shared, uint32 texture_target) OVERRIDE; virtual void DismissPictureBuffer(int32 picture_buffer_id) OVERRIDE; virtual void PictureReady(const media::Picture& picture) OVERRIDE; - virtual void NotifyInitializeDone() OVERRIDE; - virtual void NotifyError( - media::VideoDecodeAccelerator::Error error) OVERRIDE; + virtual void NotifyError(media::VideoDecodeAccelerator::Error error) OVERRIDE; virtual void NotifyFlushDone() OVERRIDE; virtual void NotifyEndOfBitstreamBuffer(int32 buffer_id) OVERRIDE; virtual void NotifyResetDone() OVERRIDE; @@ -69,13 +61,11 @@ class PPB_VideoDecoder_Impl : public ppapi::PPB_VideoDecoder_Shared, explicit PPB_VideoDecoder_Impl(PP_Instance instance); bool Init(PP_Resource graphics_context, - PlatformContext3D* context, - gpu::gles2::GLES2Implementation* gles2_impl, PP_VideoDecoder_Profile profile); - // This is NULL before initialization, and if this PPB_VideoDecoder_Impl is - // swapped with another. - scoped_ptr<PlatformVideoDecoder> platform_video_decoder_; + // This is NULL before initialization, and after destruction. + // Holds a GpuVideoDecodeAcceleratorHost. + scoped_ptr<media::VideoDecodeAccelerator> decoder_; // Reference to the plugin requesting this interface. const PPP_VideoDecoder_Dev* ppp_videodecoder_; diff --git a/chromium/content/renderer/pepper/ppb_widget_impl.cc b/chromium/content/renderer/pepper/ppb_widget_impl.cc index 494eec707e7..c28d566d733 100644 --- a/chromium/content/renderer/pepper/ppb_widget_impl.cc +++ b/chromium/content/renderer/pepper/ppb_widget_impl.cc @@ -21,25 +21,22 @@ using ppapi::thunk::PPB_Widget_API; namespace content { PPB_Widget_Impl::PPB_Widget_Impl(PP_Instance instance) - : Resource(ppapi::OBJECT_IS_IMPL, instance), - scale_(1.0f) { + : Resource(ppapi::OBJECT_IS_IMPL, instance), scale_(1.0f) { memset(&location_, 0, sizeof(location_)); } -PPB_Widget_Impl::~PPB_Widget_Impl() { -} +PPB_Widget_Impl::~PPB_Widget_Impl() {} -PPB_Widget_API* PPB_Widget_Impl::AsPPB_Widget_API() { - return this; -} +PPB_Widget_API* PPB_Widget_Impl::AsPPB_Widget_API() { return this; } PP_Bool PPB_Widget_Impl::Paint(const PP_Rect* rect, PP_Resource image_id) { EnterResourceNoLock<PPB_ImageData_API> enter(image_id, true); if (enter.failed()) return PP_FALSE; - return PaintInternal(gfx::Rect(rect->point.x, rect->point.y, - rect->size.width, rect->size.height), - static_cast<PPB_ImageData_Impl*>(enter.object())); + return PaintInternal( + gfx::Rect( + rect->point.x, rect->point.y, rect->size.width, rect->size.height), + static_cast<PPB_ImageData_Impl*>(enter.object())); } PP_Bool PPB_Widget_Impl::HandleEvent(PP_Resource pp_input_event) { @@ -59,9 +56,7 @@ void PPB_Widget_Impl::SetLocation(const PP_Rect* location) { SetLocationInternal(location); } -void PPB_Widget_Impl::SetScale(float scale) { - scale_ = scale; -} +void PPB_Widget_Impl::SetScale(float scale) { scale_ = scale; } void PPB_Widget_Impl::Invalidate(const PP_Rect* dirty) { PepperPluginInstanceImpl* plugin_instance = @@ -76,4 +71,3 @@ void PPB_Widget_Impl::Invalidate(const PP_Rect* dirty) { } } // namespace content - diff --git a/chromium/content/renderer/pepper/ppb_widget_impl.h b/chromium/content/renderer/pepper/ppb_widget_impl.h index 66139ca7552..db6feb34e51 100644 --- a/chromium/content/renderer/pepper/ppb_widget_impl.h +++ b/chromium/content/renderer/pepper/ppb_widget_impl.h @@ -31,7 +31,7 @@ class PPB_Widget_Impl : public ppapi::Resource, virtual ppapi::thunk::PPB_Widget_API* AsPPB_Widget_API() OVERRIDE; // PPB_WidgetAPI implementation. - virtual PP_Bool Paint(const PP_Rect* rect, PP_Resource ) OVERRIDE; + virtual PP_Bool Paint(const PP_Rect* rect, PP_Resource) OVERRIDE; virtual PP_Bool HandleEvent(PP_Resource pp_input_event) OVERRIDE; virtual PP_Bool GetLocation(PP_Rect* location) OVERRIDE; virtual void SetLocation(const PP_Rect* location) OVERRIDE; diff --git a/chromium/content/renderer/pepper/ppp_pdf.h b/chromium/content/renderer/pepper/ppp_pdf.h deleted file mode 100644 index 6ad67bf3f44..00000000000 --- a/chromium/content/renderer/pepper/ppp_pdf.h +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (c) 2012 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 CONTENT_RENDERER_PEPPER_PPP_PDF_H_ -#define CONTENT_RENDERER_PEPPER_PPP_PDF_H_ - -#include "ppapi/c/pp_instance.h" -#include "ppapi/c/pp_point.h" -#include "ppapi/c/pp_var.h" - -#define PPP_PDF_INTERFACE_1 "PPP_Pdf;1" -#define PPP_PDF_INTERFACE PPP_PDF_INTERFACE_1 - -typedef enum { - // Rotates the page 90 degrees clockwise from its current orientation. - PP_PRIVATEPAGETRANSFORMTYPE_ROTATE_90_CW, - // Rotates the page 90 degrees counterclockwise from its current orientation. - PP_PRIVATEPAGETRANSFORMTYPE_ROTATE_90_CCW -} PP_PrivatePageTransformType; -PP_COMPILE_ASSERT_SIZE_IN_BYTES(PP_PrivatePageTransformType, 4); - -struct PPP_Pdf_1 { - // Returns an absolute URL if the position is over a link. - PP_Var (*GetLinkAtPosition)(PP_Instance instance, - PP_Point point); - - // Requests that the plugin apply the given transform to its view. - void (*Transform)(PP_Instance instance, PP_PrivatePageTransformType type); -}; - -typedef PPP_Pdf_1 PPP_Pdf; - -#endif // CONTENT_RENDERER_PEPPER_PPP_PDF_H_ diff --git a/chromium/content/renderer/pepper/renderer_ppapi_host_impl.cc b/chromium/content/renderer/pepper/renderer_ppapi_host_impl.cc index 5014c9898ef..b6e6e9e7e46 100644 --- a/chromium/content/renderer/pepper/renderer_ppapi_host_impl.cc +++ b/chromium/content/renderer/pepper/renderer_ppapi_host_impl.cc @@ -31,8 +31,8 @@ namespace content { // static -CONTENT_EXPORT RendererPpapiHost* -RendererPpapiHost::GetForPPInstance(PP_Instance instance) { +CONTENT_EXPORT RendererPpapiHost* RendererPpapiHost::GetForPPInstance( + PP_Instance instance) { return RendererPpapiHostImpl::GetForPPInstance(instance); } @@ -42,10 +42,10 @@ RendererPpapiHostImpl::RendererPpapiHostImpl( ppapi::proxy::HostDispatcher* dispatcher, const ppapi::PpapiPermissions& permissions) : module_(module), - dispatcher_(dispatcher) { + dispatcher_(dispatcher), + is_external_plugin_host_(false) { // Hook the PpapiHost up to the dispatcher for out-of-process communication. - ppapi_host_.reset( - new ppapi::host::PpapiHost(dispatcher, permissions)); + ppapi_host_.reset(new ppapi::host::PpapiHost(dispatcher, permissions)); ppapi_host_->AddHostFactoryFilter(scoped_ptr<ppapi::host::HostFactory>( new ContentRendererPepperHostFactory(this))); dispatcher->AddFilter(ppapi_host_.get()); @@ -56,8 +56,7 @@ RendererPpapiHostImpl::RendererPpapiHostImpl( RendererPpapiHostImpl::RendererPpapiHostImpl( PluginModule* module, const ppapi::PpapiPermissions& permissions) - : module_(module), - dispatcher_(NULL) { + : module_(module), dispatcher_(NULL), is_external_plugin_host_(false) { // Hook the host up to the in-process router. in_process_router_.reset(new PepperInProcessRouter(this)); ppapi_host_.reset(new ppapi::host::PpapiHost( @@ -80,8 +79,8 @@ RendererPpapiHostImpl* RendererPpapiHostImpl::CreateOnModuleForOutOfProcess( ppapi::proxy::HostDispatcher* dispatcher, const ppapi::PpapiPermissions& permissions) { DCHECK(!module->renderer_ppapi_host()); - RendererPpapiHostImpl* result = new RendererPpapiHostImpl( - module, dispatcher, permissions); + RendererPpapiHostImpl* result = + new RendererPpapiHostImpl(module, dispatcher, permissions); // Takes ownership of pointer. module->SetRendererPpapiHost(scoped_ptr<RendererPpapiHostImpl>(result)); @@ -94,8 +93,8 @@ RendererPpapiHostImpl* RendererPpapiHostImpl::CreateOnModuleForInProcess( PluginModule* module, const ppapi::PpapiPermissions& permissions) { DCHECK(!module->renderer_ppapi_host()); - RendererPpapiHostImpl* result = new RendererPpapiHostImpl( - module, permissions); + RendererPpapiHostImpl* result = + new RendererPpapiHostImpl(module, permissions); // Takes ownership of pointer. module->SetRendererPpapiHost(scoped_ptr<RendererPpapiHostImpl>(result)); @@ -128,12 +127,16 @@ PepperPluginInstanceImpl* RendererPpapiHostImpl::GetPluginInstanceImpl( return GetAndValidateInstance(instance); } +bool RendererPpapiHostImpl::IsExternalPluginHost() const { + return is_external_plugin_host_; +} + ppapi::host::PpapiHost* RendererPpapiHostImpl::GetPpapiHost() { return ppapi_host_.get(); } RenderFrame* RendererPpapiHostImpl::GetRenderFrameForInstance( - PP_Instance instance) const { + PP_Instance instance) const { PepperPluginInstanceImpl* instance_object = GetAndValidateInstance(instance); if (!instance_object) return NULL; @@ -164,7 +167,7 @@ PepperPluginInstance* RendererPpapiHostImpl::GetPluginInstance( } blink::WebPluginContainer* RendererPpapiHostImpl::GetContainerForInstance( - PP_Instance instance) const { + PP_Instance instance) const { PepperPluginInstanceImpl* instance_object = GetAndValidateInstance(instance); if (!instance_object) return NULL; @@ -173,7 +176,7 @@ blink::WebPluginContainer* RendererPpapiHostImpl::GetContainerForInstance( base::ProcessId RendererPpapiHostImpl::GetPluginPID() const { if (dispatcher_) - return dispatcher_->channel()->peer_pid(); + return dispatcher_->channel()->GetPeerPID(); return base::kNullProcessId; } @@ -203,18 +206,10 @@ gfx::Point RendererPpapiHostImpl::PluginPointToRenderFrame( PP_Instance instance, const gfx::Point& pt) const { PepperPluginInstanceImpl* plugin_instance = GetAndValidateInstance(instance); - if (!plugin_instance) + if (!plugin_instance || plugin_instance->flash_fullscreen()) { + // Flash fullscreen is special in that it renders into its own separate, + // dedicated window. So, do not offset the point. return pt; - - RenderFrameImpl* render_frame = static_cast<RenderFrameImpl*>( - GetRenderFrameForInstance(instance)); - if (plugin_instance->view_data().is_fullscreen || - plugin_instance->flash_fullscreen()) { - blink::WebRect window_rect = render_frame->GetRenderWidget()->windowRect(); - blink::WebRect screen_rect = - render_frame->GetRenderWidget()->screenInfo().rect; - return gfx::Point(pt.x() - window_rect.x + screen_rect.x, - pt.y() - window_rect.y + screen_rect.y); } return gfx::Point(pt.x() + plugin_instance->view_data().rect.point.x, pt.y() + plugin_instance->view_data().rect.point.y); @@ -228,9 +223,8 @@ IPC::PlatformFileForTransit RendererPpapiHostImpl::ShareHandleWithRemote( // Duplicate the file handle for in process mode so this function // has the same semantics for both in process mode and out of // process mode (i.e., the remote side must cloes the handle). - return BrokerGetFileHandleForProcess(handle, - base::GetCurrentProcId(), - should_close_source); + return BrokerGetFileHandleForProcess( + handle, base::GetCurrentProcId(), should_close_source); } return dispatcher_->ShareHandleWithRemote(handle, should_close_source); } @@ -239,6 +233,14 @@ bool RendererPpapiHostImpl::IsRunningInProcess() const { return is_running_in_process_; } +std::string RendererPpapiHostImpl::GetPluginName() const { + return module_->name(); +} + +void RendererPpapiHostImpl::SetToExternalPluginHost() { + is_external_plugin_host_ = true; +} + void RendererPpapiHostImpl::CreateBrowserResourceHosts( PP_Instance instance, const std::vector<IPC::Message>& nested_msgs, @@ -247,13 +249,12 @@ void RendererPpapiHostImpl::CreateBrowserResourceHosts( PepperBrowserConnection* browser_connection = PepperBrowserConnection::Get(render_frame); if (!browser_connection) { - base::MessageLoop::current()->PostTask(FROM_HERE, + base::MessageLoop::current()->PostTask( + FROM_HERE, base::Bind(callback, std::vector<int>(nested_msgs.size(), 0))); } else { - browser_connection->SendBrowserCreate(module_->GetPluginChildId(), - instance, - nested_msgs, - callback); + browser_connection->SendBrowserCreate( + module_->GetPluginChildId(), instance, nested_msgs, callback); } } diff --git a/chromium/content/renderer/pepper/renderer_ppapi_host_impl.h b/chromium/content/renderer/pepper/renderer_ppapi_host_impl.h index c2ad0d1cb0d..a30735dc3c4 100644 --- a/chromium/content/renderer/pepper/renderer_ppapi_host_impl.h +++ b/chromium/content/renderer/pepper/renderer_ppapi_host_impl.h @@ -73,32 +73,36 @@ class RendererPpapiHostImpl : public RendererPpapiHost { PepperPluginInstanceImpl* GetPluginInstanceImpl(PP_Instance instance) const; + bool IsExternalPluginHost() const; + // RendererPpapiHost implementation. virtual ppapi::host::PpapiHost* GetPpapiHost() OVERRIDE; virtual bool IsValidInstance(PP_Instance instance) const OVERRIDE; - virtual PepperPluginInstance* GetPluginInstance( - PP_Instance instance) const OVERRIDE; - virtual RenderFrame* GetRenderFrameForInstance( - PP_Instance instance) const OVERRIDE; - virtual RenderView* GetRenderViewForInstance( - PP_Instance instance) const OVERRIDE; + virtual PepperPluginInstance* GetPluginInstance(PP_Instance instance) const + OVERRIDE; + virtual RenderFrame* GetRenderFrameForInstance(PP_Instance instance) const + OVERRIDE; + virtual RenderView* GetRenderViewForInstance(PP_Instance instance) const + OVERRIDE; virtual blink::WebPluginContainer* GetContainerForInstance( PP_Instance instance) const OVERRIDE; virtual base::ProcessId GetPluginPID() const OVERRIDE; virtual bool HasUserGesture(PP_Instance instance) const OVERRIDE; virtual int GetRoutingIDForWidget(PP_Instance instance) const OVERRIDE; - virtual gfx::Point PluginPointToRenderFrame( - PP_Instance instance, - const gfx::Point& pt) const OVERRIDE; + virtual gfx::Point PluginPointToRenderFrame(PP_Instance instance, + const gfx::Point& pt) const + OVERRIDE; virtual IPC::PlatformFileForTransit ShareHandleWithRemote( base::PlatformFile handle, bool should_close_source) OVERRIDE; virtual bool IsRunningInProcess() const OVERRIDE; + virtual std::string GetPluginName() const OVERRIDE; + virtual void SetToExternalPluginHost() OVERRIDE; virtual void CreateBrowserResourceHosts( PP_Instance instance, const std::vector<IPC::Message>& nested_msgs, - const base::Callback<void( - const std::vector<int>&)>& callback) const OVERRIDE; + const base::Callback<void(const std::vector<int>&)>& callback) const + OVERRIDE; virtual GURL GetDocumentURL(PP_Instance instance) const OVERRIDE; private: @@ -130,6 +134,9 @@ class RendererPpapiHostImpl : public RendererPpapiHost { // Whether the plugin is running in process. bool is_running_in_process_; + // Whether this is a host for external plugins. + bool is_external_plugin_host_; + DISALLOW_COPY_AND_ASSIGN(RendererPpapiHostImpl); }; diff --git a/chromium/content/renderer/pepper/resource_converter.cc b/chromium/content/renderer/pepper/resource_converter.cc index 5054c2dc3a4..8192f0c7a41 100644 --- a/chromium/content/renderer/pepper/resource_converter.cc +++ b/chromium/content/renderer/pepper/resource_converter.cc @@ -8,6 +8,8 @@ #include "base/message_loop/message_loop.h" #include "content/public/renderer/renderer_ppapi_host.h" #include "content/renderer/pepper/pepper_file_system_host.h" +#include "content/renderer/pepper/pepper_media_stream_audio_track_host.h" +#include "content/renderer/pepper/pepper_media_stream_video_track_host.h" #include "ipc/ipc_message.h" #include "ppapi/host/ppapi_host.h" #include "ppapi/host/resource_host.h" @@ -15,8 +17,16 @@ #include "ppapi/shared_impl/resource_var.h" #include "ppapi/shared_impl/scoped_pp_var.h" #include "third_party/WebKit/public/platform/WebFileSystem.h" +#include "third_party/WebKit/public/platform/WebMediaStreamSource.h" +#include "third_party/WebKit/public/platform/WebMediaStreamTrack.h" #include "third_party/WebKit/public/web/WebDOMFileSystem.h" +#include "third_party/WebKit/public/web/WebDOMMediaStreamTrack.h" +#include "third_party/WebKit/public/web/WebLocalFrame.h" +#include "webkit/common/fileapi/file_system_util.h" +using ppapi::ResourceVar; + +namespace content { namespace { void FlushComplete( @@ -47,12 +57,36 @@ PP_FileSystemType WebFileSystemTypeToPPAPI(blink::WebFileSystem::Type type) { } } +// Converts a fileapi::FileSystemType to a blink::WebFileSystemType. +// Returns true on success, false if |type| does not correspond to a +// WebFileSystemType. +bool FileApiFileSystemTypeToWebFileSystemType( + fileapi::FileSystemType type, + blink::WebFileSystemType* result_type) { + switch (type) { + case fileapi::kFileSystemTypeTemporary: + *result_type = blink::WebFileSystemTypeTemporary; + return true; + case fileapi::kFileSystemTypePersistent: + *result_type = blink::WebFileSystemTypePersistent; + return true; + case fileapi::kFileSystemTypeIsolated: + *result_type = blink::WebFileSystemTypeIsolated; + return true; + case fileapi::kFileSystemTypeExternal: + *result_type = blink::WebFileSystemTypeExternal; + return true; + default: + return false; + } +} + // Given a V8 value containing a DOMFileSystem, creates a resource host and // returns the resource information for serialization. // On error, false. bool DOMFileSystemToResource( PP_Instance instance, - content::RendererPpapiHost* host, + RendererPpapiHost* host, const blink::WebDOMFileSystem& dom_file_system, int* pending_renderer_id, scoped_ptr<IPC::Message>* create_message, @@ -63,16 +97,17 @@ bool DOMFileSystemToResource( WebFileSystemTypeToPPAPI(dom_file_system.type()); GURL root_url = dom_file_system.rootURL(); - // External file systems are not currently supported. (Without this check, - // there would be a CHECK-fail in FileRefResource.) - // TODO(mgiuca): Support external file systems. - if (file_system_type == PP_FILESYSTEMTYPE_EXTERNAL) + // Raw external file system access is not allowed, but external file system + // access through fileapi is allowed. (Without this check, there would be a + // CHECK failure in FileRefResource.) + if ((file_system_type == PP_FILESYSTEMTYPE_EXTERNAL) && + (!root_url.is_valid())) { return false; + } *pending_renderer_id = host->GetPpapiHost()->AddPendingResourceHost( - scoped_ptr<ppapi::host::ResourceHost>( - new content::PepperFileSystemHost(host, instance, 0, root_url, - file_system_type))); + scoped_ptr<ppapi::host::ResourceHost>(new PepperFileSystemHost( + host, instance, 0, root_url, file_system_type))); if (*pending_renderer_id == 0) return false; @@ -85,22 +120,91 @@ bool DOMFileSystemToResource( return true; } -} // namespace +bool ResourceHostToDOMFileSystem( + content::PepperFileSystemHost* file_system_host, + v8::Handle<v8::Context> context, + v8::Handle<v8::Value>* dom_file_system) { + GURL root_url = file_system_host->GetRootUrl(); + GURL origin; + fileapi::FileSystemType type; + base::FilePath virtual_path; + fileapi::ParseFileSystemSchemeURL(root_url, &origin, &type, &virtual_path); -namespace content { + std::string name = fileapi::GetFileSystemName(origin, type); + blink::WebFileSystemType blink_type; + if (!FileApiFileSystemTypeToWebFileSystemType(type, &blink_type)) + return false; + blink::WebLocalFrame* frame = blink::WebLocalFrame::frameForContext(context); + blink::WebDOMFileSystem web_dom_file_system = blink::WebDOMFileSystem::create( + frame, + blink_type, + blink::WebString::fromUTF8(name), + root_url, + blink::WebDOMFileSystem::SerializableTypeSerializable); + *dom_file_system = + web_dom_file_system.toV8Value(context->Global(), context->GetIsolate()); + return true; +} + +bool ResourceHostToDOMMediaStreamVideoTrack( + content::PepperMediaStreamVideoTrackHost* host, + v8::Handle<v8::Context> context, + v8::Handle<v8::Value>* dom_video_track) { + // TODO(ronghuawu): Implement this once crbug/352219 is resolved. + // blink::WebMediaStreamTrack track = host->track(); + // *dom_video_track = track.toV8Value(); + return false; +} + +bool DOMMediaStreamTrackToResource( + PP_Instance instance, + RendererPpapiHost* host, + const blink::WebDOMMediaStreamTrack& dom_media_stream_track, + int* pending_renderer_id, + scoped_ptr<IPC::Message>* create_message) { + DCHECK(!dom_media_stream_track.isNull()); + *pending_renderer_id = 0; +#if defined(ENABLE_WEBRTC) + const blink::WebMediaStreamTrack track = dom_media_stream_track.component(); + const std::string id = track.source().id().utf8(); + + if (track.source().type() == blink::WebMediaStreamSource::TypeVideo) { + *pending_renderer_id = host->GetPpapiHost()->AddPendingResourceHost( + scoped_ptr<ppapi::host::ResourceHost>( + new PepperMediaStreamVideoTrackHost(host, instance, 0, track))); + if (*pending_renderer_id == 0) + return false; + + create_message->reset( + new PpapiPluginMsg_MediaStreamVideoTrack_CreateFromPendingHost(id)); + return true; + } else if (track.source().type() == blink::WebMediaStreamSource::TypeAudio) { + *pending_renderer_id = host->GetPpapiHost()->AddPendingResourceHost( + scoped_ptr<ppapi::host::ResourceHost>( + new PepperMediaStreamAudioTrackHost(host, instance, 0, track))); + if (*pending_renderer_id == 0) + return false; + + create_message->reset( + new PpapiPluginMsg_MediaStreamAudioTrack_CreateFromPendingHost(id)); + return true; + } +#endif + return false; +} + +} // namespace ResourceConverter::~ResourceConverter() {} ResourceConverterImpl::ResourceConverterImpl(PP_Instance instance, RendererPpapiHost* host) - : instance_(instance), - host_(host) { -} + : instance_(instance), host_(host) {} ResourceConverterImpl::~ResourceConverterImpl() { // Verify Flush() was called. DCHECK(browser_host_create_messages_.empty()); - DCHECK(browser_vars.empty()); + DCHECK(browser_vars_.empty()); } bool ResourceConverterImpl::FromV8Value(v8::Handle<v8::Object> val, @@ -118,8 +222,11 @@ bool ResourceConverterImpl::FromV8Value(v8::Handle<v8::Object> val, int pending_renderer_id; scoped_ptr<IPC::Message> create_message; scoped_ptr<IPC::Message> browser_host_create_message; - if (!DOMFileSystemToResource(instance_, host_, dom_file_system, - &pending_renderer_id, &create_message, + if (!DOMFileSystemToResource(instance_, + host_, + dom_file_system, + &pending_renderer_id, + &create_message, &browser_host_create_message)) { return false; } @@ -133,19 +240,96 @@ bool ResourceConverterImpl::FromV8Value(v8::Handle<v8::Object> val, return true; } + blink::WebDOMMediaStreamTrack dom_media_stream_track = + blink::WebDOMMediaStreamTrack::fromV8Value(val); + if (!dom_media_stream_track.isNull()) { + int pending_renderer_id; + scoped_ptr<IPC::Message> create_message; + if (!DOMMediaStreamTrackToResource(instance_, + host_, + dom_media_stream_track, + &pending_renderer_id, + &create_message)) { + return false; + } + DCHECK(create_message); + scoped_refptr<HostResourceVar> result_var = + CreateResourceVar(pending_renderer_id, *create_message); + *result = result_var->GetPPVar(); + *was_resource = true; + return true; + } + // The value was not convertible to a resource. Return true with // |was_resource| set to false. As per the interface of FromV8Value, |result| // may be left unmodified in this case. return true; } +void ResourceConverterImpl::Reset() { + browser_host_create_messages_.clear(); + browser_vars_.clear(); +} + +bool ResourceConverterImpl::NeedsFlush() { + return !browser_host_create_messages_.empty(); +} + void ResourceConverterImpl::Flush(const base::Callback<void(bool)>& callback) { host_->CreateBrowserResourceHosts( instance_, browser_host_create_messages_, - base::Bind(&FlushComplete, callback, browser_vars)); + base::Bind(&FlushComplete, callback, browser_vars_)); browser_host_create_messages_.clear(); - browser_vars.clear(); + browser_vars_.clear(); +} + +bool ResourceConverterImpl::ToV8Value(const PP_Var& var, + v8::Handle<v8::Context> context, + v8::Handle<v8::Value>* result) { + DCHECK(var.type == PP_VARTYPE_RESOURCE); + + ResourceVar* resource = ResourceVar::FromPPVar(var); + if (!resource) { + NOTREACHED(); + return false; + } + PP_Resource resource_id = resource->GetPPResource(); + + // Get the renderer-side resource host for this resource. + content::RendererPpapiHost* renderer_ppapi_host = + content::RendererPpapiHost::GetForPPInstance(instance_); + if (!renderer_ppapi_host) { + // This should never happen: the RendererPpapiHost is owned by the module + // and should outlive instances associated with it. However, if it doesn't + // for some reason, we do not want to crash. + NOTREACHED(); + return false; + } + ::ppapi::host::PpapiHost* ppapi_host = renderer_ppapi_host->GetPpapiHost(); + ::ppapi::host::ResourceHost* resource_host = + ppapi_host->GetResourceHost(resource_id); + if (resource_host == NULL) { + LOG(ERROR) << "No resource host for resource #" << resource_id; + return false; + } + + // Convert to the appropriate type of resource host. + if (resource_host->IsFileSystemHost()) { + return ResourceHostToDOMFileSystem( + static_cast<content::PepperFileSystemHost*>(resource_host), + context, + result); + } else if (resource_host->IsMediaStreamVideoTrackHost()) { + return ResourceHostToDOMMediaStreamVideoTrack( + static_cast<content::PepperMediaStreamVideoTrackHost*>(resource_host), + context, + result); + } else { + LOG(ERROR) << "The type of resource #" << resource_id + << " cannot be converted to a JavaScript object."; + return false; + } } scoped_refptr<HostResourceVar> ResourceConverterImpl::CreateResourceVar( @@ -162,7 +346,7 @@ ResourceConverterImpl::CreateResourceVarWithBrowserHost( scoped_refptr<HostResourceVar> result = CreateResourceVar(pending_renderer_id, create_message); browser_host_create_messages_.push_back(browser_host_create_message); - browser_vars.push_back(result); + browser_vars_.push_back(result); return result; } diff --git a/chromium/content/renderer/pepper/resource_converter.h b/chromium/content/renderer/pepper/resource_converter.h index a52f7ad83ce..842f7c72324 100644 --- a/chromium/content/renderer/pepper/resource_converter.h +++ b/chromium/content/renderer/pepper/resource_converter.h @@ -34,8 +34,16 @@ class CONTENT_EXPORT ResourceConverter { public: virtual ~ResourceConverter(); - // Flush() must be called before any vars created by the ResourceConverter - // are valid. It handles creating any resource hosts that need to be created. + // Reset the state of the resource converter. + virtual void Reset() = 0; + + // Returns true if Flush() needs to be called before using any vars created + // by the resource converter. + virtual bool NeedsFlush() = 0; + + // If NeedsFlush() is true then Flush() must be called before any vars created + // by the ResourceConverter are valid. It handles creating any resource hosts + // that need to be created. |callback| will always be called asynchronously. virtual void Flush(const base::Callback<void(bool)>& callback) = 0; // Attempts to convert a V8 object to a PP_Var with type PP_VARTYPE_RESOURCE. @@ -46,6 +54,13 @@ class CONTENT_EXPORT ResourceConverter { v8::Handle<v8::Context> context, PP_Var* result, bool* was_resource) = 0; + + // Attempts to convert a PP_Var to a V8 object. |var| must have type + // PP_VARTYPE_RESOURCE. On success, writes the resulting value to |result| and + // returns true. If an error occurs, returns false. + virtual bool ToV8Value(const PP_Var& var, + v8::Handle<v8::Context> context, + v8::Handle<v8::Value>* result) = 0; }; class ResourceConverterImpl : public ResourceConverter { @@ -54,11 +69,16 @@ class ResourceConverterImpl : public ResourceConverter { virtual ~ResourceConverterImpl(); // ResourceConverter overrides. + virtual void Reset() OVERRIDE; + virtual bool NeedsFlush() OVERRIDE; virtual void Flush(const base::Callback<void(bool)>& callback) OVERRIDE; virtual bool FromV8Value(v8::Handle<v8::Object> val, v8::Handle<v8::Context> context, PP_Var* result, bool* was_resource) OVERRIDE; + virtual bool ToV8Value(const PP_Var& var, + v8::Handle<v8::Context> context, + v8::Handle<v8::Value>* result) OVERRIDE; private: // Creates a resource var with the given |pending_renderer_id| and @@ -85,7 +105,7 @@ class ResourceConverterImpl : public ResourceConverter { // conveniently passed to |CreateBrowserResourceHosts|. std::vector<IPC::Message> browser_host_create_messages_; // A list of the resource vars associated with browser hosts. - std::vector<scoped_refptr<HostResourceVar> > browser_vars; + std::vector<scoped_refptr<HostResourceVar> > browser_vars_; DISALLOW_COPY_AND_ASSIGN(ResourceConverterImpl); }; diff --git a/chromium/content/renderer/pepper/resource_creation_impl.cc b/chromium/content/renderer/pepper/resource_creation_impl.cc index d9ed442aecd..a4fb6c26564 100644 --- a/chromium/content/renderer/pepper/resource_creation_impl.cc +++ b/chromium/content/renderer/pepper/resource_creation_impl.cc @@ -18,12 +18,10 @@ #include "ppapi/shared_impl/ppb_audio_shared.h" #include "ppapi/shared_impl/ppb_image_data_shared.h" #include "ppapi/shared_impl/ppb_input_event_shared.h" -#include "ppapi/shared_impl/ppb_resource_array_shared.h" #include "ppapi/shared_impl/var.h" using ppapi::InputEventData; using ppapi::PPB_InputEvent_Shared; -using ppapi::PPB_ResourceArray_Shared; using ppapi::StringVar; namespace content { @@ -31,27 +29,21 @@ namespace content { ResourceCreationImpl::ResourceCreationImpl(PepperPluginInstanceImpl* instance) { } -ResourceCreationImpl::~ResourceCreationImpl() { -} +ResourceCreationImpl::~ResourceCreationImpl() {} PP_Resource ResourceCreationImpl::CreateAudio1_0( PP_Instance instance, PP_Resource config_id, PPB_Audio_Callback_1_0 audio_callback, void* user_data) { - return PPB_Audio_Impl::Create( - instance, config_id, ppapi::AudioCallbackCombined(audio_callback), - user_data); + return 0; // Not supported in-process. } -PP_Resource ResourceCreationImpl::CreateAudio( - PP_Instance instance, - PP_Resource config_id, - PPB_Audio_Callback audio_callback, - void* user_data) { - return PPB_Audio_Impl::Create( - instance, config_id, ppapi::AudioCallbackCombined(audio_callback), - user_data); +PP_Resource ResourceCreationImpl::CreateAudio(PP_Instance instance, + PP_Resource config_id, + PPB_Audio_Callback audio_callback, + void* user_data) { + return 0; // Not supported in-process. } PP_Resource ResourceCreationImpl::CreateAudioConfig( @@ -62,8 +54,7 @@ PP_Resource ResourceCreationImpl::CreateAudioConfig( ppapi::OBJECT_IS_IMPL, instance, sample_rate, sample_frame_count); } -PP_Resource ResourceCreationImpl::CreateAudioTrusted( - PP_Instance instance) { +PP_Resource ResourceCreationImpl::CreateAudioTrusted(PP_Instance instance) { return (new PPB_Audio_Impl(instance))->GetReference(); } @@ -71,6 +62,10 @@ PP_Resource ResourceCreationImpl::CreateAudioInput(PP_Instance instance) { return 0; // Not supported in-process. } +PP_Resource ResourceCreationImpl::CreateCompositor(PP_Instance instance) { + return 0; // Not supported in-process. +} + PP_Resource ResourceCreationImpl::CreateBroker(PP_Instance instance) { return (new PPB_Broker_Impl(instance))->GetReference(); } @@ -101,10 +96,9 @@ PP_Resource ResourceCreationImpl::CreateFlashMessageLoop(PP_Instance instance) { return PPB_Flash_MessageLoop_Impl::Create(instance); } -PP_Resource ResourceCreationImpl::CreateGraphics3D( - PP_Instance instance, - PP_Resource share_context, - const int32_t* attrib_list) { +PP_Resource ResourceCreationImpl::CreateGraphics3D(PP_Instance instance, + PP_Resource share_context, + const int32_t* attrib_list) { return PPB_Graphics3D_Impl::Create(instance, share_context, attrib_list); } @@ -124,14 +118,15 @@ PP_Resource ResourceCreationImpl::CreateHostResolverPrivate( return 0; // Not supported in-process. } -PP_Resource ResourceCreationImpl::CreateImageData( - PP_Instance instance, - PP_ImageDataFormat format, - const PP_Size* size, - PP_Bool init_to_zero) { +PP_Resource ResourceCreationImpl::CreateImageData(PP_Instance instance, + PP_ImageDataFormat format, + const PP_Size* size, + PP_Bool init_to_zero) { return PPB_ImageData_Impl::Create(instance, ppapi::PPB_ImageData_Shared::PLATFORM, - format, *size, init_to_zero); + format, + *size, + init_to_zero); } PP_Resource ResourceCreationImpl::CreateImageDataSimple( @@ -141,7 +136,9 @@ PP_Resource ResourceCreationImpl::CreateImageDataSimple( PP_Bool init_to_zero) { return PPB_ImageData_Impl::Create(instance, ppapi::PPB_ImageData_Shared::SIMPLE, - format, *size, init_to_zero); + format, + *size, + init_to_zero); } PP_Resource ResourceCreationImpl::CreateIMEInputEvent( @@ -154,21 +151,57 @@ PP_Resource ResourceCreationImpl::CreateIMEInputEvent( int32_t target_segment, uint32_t selection_start, uint32_t selection_end) { - return PPB_InputEvent_Shared::CreateIMEInputEvent( - ppapi::OBJECT_IS_IMPL, instance, type, time_stamp, text, segment_number, - segment_offsets, target_segment, selection_start, selection_end); -} - -PP_Resource ResourceCreationImpl::CreateKeyboardInputEvent( + return PPB_InputEvent_Shared::CreateIMEInputEvent(ppapi::OBJECT_IS_IMPL, + instance, + type, + time_stamp, + text, + segment_number, + segment_offsets, + target_segment, + selection_start, + selection_end); +} + +PP_Resource ResourceCreationImpl::CreateKeyboardInputEvent_1_0( PP_Instance instance, PP_InputEvent_Type type, PP_TimeTicks time_stamp, uint32_t modifiers, uint32_t key_code, struct PP_Var character_text) { - return PPB_InputEvent_Shared::CreateKeyboardInputEvent( - ppapi::OBJECT_IS_IMPL, instance, type, time_stamp, modifiers, key_code, - character_text); + PP_Var code = StringVar::StringToPPVar(""); + return PPB_InputEvent_Shared::CreateKeyboardInputEvent(ppapi::OBJECT_IS_IMPL, + instance, + type, + time_stamp, + modifiers, + key_code, + character_text, + code); +} + +PP_Resource ResourceCreationImpl::CreateKeyboardInputEvent_1_2( + PP_Instance instance, + PP_InputEvent_Type type, + PP_TimeTicks time_stamp, + uint32_t modifiers, + uint32_t key_code, + struct PP_Var character_text, + struct PP_Var code) { + return PPB_InputEvent_Shared::CreateKeyboardInputEvent(ppapi::OBJECT_IS_IMPL, + instance, + type, + time_stamp, + modifiers, + key_code, + character_text, + code); +} + +PP_Resource ResourceCreationImpl::CreateMediaStreamVideoTrack( + PP_Instance instance) { + return 0; // Not supported in-process. } PP_Resource ResourceCreationImpl::CreateMouseInputEvent( @@ -180,9 +213,15 @@ PP_Resource ResourceCreationImpl::CreateMouseInputEvent( const PP_Point* mouse_position, int32_t click_count, const PP_Point* mouse_movement) { - return PPB_InputEvent_Shared::CreateMouseInputEvent( - ppapi::OBJECT_IS_IMPL, instance, type, time_stamp, modifiers, - mouse_button, mouse_position, click_count, mouse_movement); + return PPB_InputEvent_Shared::CreateMouseInputEvent(ppapi::OBJECT_IS_IMPL, + instance, + type, + time_stamp, + modifiers, + mouse_button, + mouse_position, + click_count, + mouse_movement); } PP_Resource ResourceCreationImpl::CreateNetAddressFromIPv4Address( @@ -203,15 +242,6 @@ PP_Resource ResourceCreationImpl::CreateNetAddressFromNetAddressPrivate( return 0; // Not supported in-process. } -PP_Resource ResourceCreationImpl::CreateTouchInputEvent( - PP_Instance instance, - PP_InputEvent_Type type, - PP_TimeTicks time_stamp, - uint32_t modifiers) { - return PPB_InputEvent_Shared::CreateTouchInputEvent( - ppapi::OBJECT_IS_IMPL, instance, type, time_stamp, modifiers); -} - PP_Resource ResourceCreationImpl::CreateNetworkMonitor(PP_Instance instance) { return 0; // Not supported in-process. } @@ -235,15 +265,6 @@ PP_Resource ResourceCreationImpl::CreateTalk(PP_Instance /* instance */) { return 0; // Not supported in-process. } -PP_Resource ResourceCreationImpl::CreateResourceArray( - PP_Instance instance, - const PP_Resource elements[], - uint32_t size) { - PPB_ResourceArray_Shared* object = new PPB_ResourceArray_Shared( - ppapi::OBJECT_IS_IMPL, instance, elements, size); - return object->GetReference(); -} - PP_Resource ResourceCreationImpl::CreateTCPServerSocketPrivate( PP_Instance instance) { return 0; // Not supported in-process. @@ -261,6 +282,14 @@ PP_Resource ResourceCreationImpl::CreateTCPSocketPrivate(PP_Instance instance) { return 0; // Not supported in-process. } +PP_Resource ResourceCreationImpl::CreateTouchInputEvent(PP_Instance instance, + PP_InputEvent_Type type, + PP_TimeTicks time_stamp, + uint32_t modifiers) { + return PPB_InputEvent_Shared::CreateTouchInputEvent( + ppapi::OBJECT_IS_IMPL, instance, type, time_stamp, modifiers); +} + PP_Resource ResourceCreationImpl::CreateUDPSocket(PP_Instance instance) { return 0; // Not supported in-process. } @@ -270,23 +299,25 @@ PP_Resource ResourceCreationImpl::CreateUDPSocketPrivate(PP_Instance instance) { } PP_Resource ResourceCreationImpl::CreateVideoCapture(PP_Instance instance) { - return 0; // VideoCapture is not supported in process now. + return 0; // Not supported in-process. } -PP_Resource ResourceCreationImpl::CreateVideoDecoder( +PP_Resource ResourceCreationImpl::CreateVideoDecoder(PP_Instance instance) { + return 0; // Not supported in-process. +} + +PP_Resource ResourceCreationImpl::CreateVideoDecoderDev( PP_Instance instance, PP_Resource graphics3d_id, PP_VideoDecoder_Profile profile) { return PPB_VideoDecoder_Impl::Create(instance, graphics3d_id, profile); } -PP_Resource ResourceCreationImpl::CreateVideoDestination( - PP_Instance instance) { +PP_Resource ResourceCreationImpl::CreateVideoDestination(PP_Instance instance) { return 0; // Not supported in-process. } -PP_Resource ResourceCreationImpl::CreateVideoSource( - PP_Instance instance) { +PP_Resource ResourceCreationImpl::CreateVideoSource(PP_Instance instance) { return 0; // Not supported in-process. } @@ -297,9 +328,13 @@ PP_Resource ResourceCreationImpl::CreateWheelInputEvent( const PP_FloatPoint* wheel_delta, const PP_FloatPoint* wheel_ticks, PP_Bool scroll_by_page) { - return PPB_InputEvent_Shared::CreateWheelInputEvent( - ppapi::OBJECT_IS_IMPL, instance, time_stamp, modifiers, - wheel_delta, wheel_ticks, scroll_by_page); + return PPB_InputEvent_Shared::CreateWheelInputEvent(ppapi::OBJECT_IS_IMPL, + instance, + time_stamp, + modifiers, + wheel_delta, + wheel_ticks, + scroll_by_page); } PP_Resource ResourceCreationImpl::CreateX509CertificatePrivate( diff --git a/chromium/content/renderer/pepper/resource_creation_impl.h b/chromium/content/renderer/pepper/resource_creation_impl.h index ac54b6b442a..d2b20dd2177 100644 --- a/chromium/content/renderer/pepper/resource_creation_impl.h +++ b/chromium/content/renderer/pepper/resource_creation_impl.h @@ -36,6 +36,7 @@ class ResourceCreationImpl : public ppapi::thunk::ResourceCreationAPI { PP_AudioSampleRate sample_rate, uint32_t sample_frame_count) OVERRIDE; virtual PP_Resource CreateAudioInput(PP_Instance instance) OVERRIDE; + virtual PP_Resource CreateCompositor(PP_Instance instance) OVERRIDE; virtual PP_Resource CreateBroker(PP_Instance instance) OVERRIDE; virtual PP_Resource CreateBuffer(PP_Instance instance, uint32_t size) OVERRIDE; @@ -72,13 +73,22 @@ class ResourceCreationImpl : public ppapi::thunk::ResourceCreationAPI { int32_t target_segment, uint32_t selection_start, uint32_t selection_end) OVERRIDE; - virtual PP_Resource CreateKeyboardInputEvent( - PP_Instance instance, - PP_InputEvent_Type type, - PP_TimeTicks time_stamp, - uint32_t modifiers, - uint32_t key_code, - PP_Var character_text) OVERRIDE; + virtual PP_Resource CreateKeyboardInputEvent_1_0(PP_Instance instance, + PP_InputEvent_Type type, + PP_TimeTicks time_stamp, + uint32_t modifiers, + uint32_t key_code, + PP_Var character_text) + OVERRIDE; + virtual PP_Resource CreateKeyboardInputEvent_1_2(PP_Instance instance, + PP_InputEvent_Type type, + PP_TimeTicks time_stamp, + uint32_t modifiers, + uint32_t key_code, + PP_Var character_text, + PP_Var code) OVERRIDE; + virtual PP_Resource CreateMediaStreamVideoTrack( + PP_Instance instance) OVERRIDE; virtual PP_Resource CreateMouseInputEvent( PP_Instance instance, PP_InputEvent_Type type, @@ -97,47 +107,41 @@ class ResourceCreationImpl : public ppapi::thunk::ResourceCreationAPI { virtual PP_Resource CreateNetAddressFromNetAddressPrivate( PP_Instance instance, const PP_NetAddress_Private& private_addr) OVERRIDE; - virtual PP_Resource CreateTouchInputEvent( - PP_Instance instance, - PP_InputEvent_Type type, - PP_TimeTicks time_stamp, - uint32_t modifiers) OVERRIDE; virtual PP_Resource CreateNetworkMonitor(PP_Instance instance) OVERRIDE; - virtual PP_Resource CreatePlatformVerificationPrivate( - PP_Instance instance) OVERRIDE; - virtual PP_Resource CreateResourceArray(PP_Instance instance, - const PP_Resource elements[], - uint32_t size) OVERRIDE; + virtual PP_Resource CreatePlatformVerificationPrivate(PP_Instance instance) + OVERRIDE; virtual PP_Resource CreateScrollbar(PP_Instance instance, PP_Bool vertical) OVERRIDE; - virtual PP_Resource CreateOutputProtectionPrivate( - PP_Instance instance) OVERRIDE; + virtual PP_Resource CreateOutputProtectionPrivate(PP_Instance instance) + OVERRIDE; virtual PP_Resource CreateTalk(PP_Instance instance) OVERRIDE; - virtual PP_Resource CreateTCPServerSocketPrivate( - PP_Instance instance) OVERRIDE; + virtual PP_Resource CreateTCPServerSocketPrivate(PP_Instance instance) + OVERRIDE; virtual PP_Resource CreateTCPSocket1_0(PP_Instance instance) OVERRIDE; virtual PP_Resource CreateTCPSocket(PP_Instance instance) OVERRIDE; virtual PP_Resource CreateTCPSocketPrivate(PP_Instance instance) OVERRIDE; + virtual PP_Resource CreateTouchInputEvent(PP_Instance instance, + PP_InputEvent_Type type, + PP_TimeTicks time_stamp, + uint32_t modifiers) OVERRIDE; virtual PP_Resource CreateUDPSocket(PP_Instance instance) OVERRIDE; virtual PP_Resource CreateUDPSocketPrivate(PP_Instance instance) OVERRIDE; virtual PP_Resource CreateVideoCapture(PP_Instance instance) OVERRIDE; - virtual PP_Resource CreateVideoDecoder( - PP_Instance instance, - PP_Resource graphics3d_id, - PP_VideoDecoder_Profile profile) OVERRIDE; - virtual PP_Resource CreateVideoDestination( - PP_Instance instance) OVERRIDE; - virtual PP_Resource CreateVideoSource( - PP_Instance instance) OVERRIDE; - virtual PP_Resource CreateWheelInputEvent( - PP_Instance instance, - PP_TimeTicks time_stamp, - uint32_t modifiers, - const PP_FloatPoint* wheel_delta, - const PP_FloatPoint* wheel_ticks, - PP_Bool scroll_by_page) OVERRIDE; - virtual PP_Resource CreateX509CertificatePrivate( - PP_Instance instance) OVERRIDE; + virtual PP_Resource CreateVideoDecoder(PP_Instance instance) OVERRIDE; + virtual PP_Resource CreateVideoDecoderDev(PP_Instance instance, + PP_Resource graphics3d_id, + PP_VideoDecoder_Profile profile) + OVERRIDE; + virtual PP_Resource CreateVideoDestination(PP_Instance instance) OVERRIDE; + virtual PP_Resource CreateVideoSource(PP_Instance instance) OVERRIDE; + virtual PP_Resource CreateWheelInputEvent(PP_Instance instance, + PP_TimeTicks time_stamp, + uint32_t modifiers, + const PP_FloatPoint* wheel_delta, + const PP_FloatPoint* wheel_ticks, + PP_Bool scroll_by_page) OVERRIDE; + virtual PP_Resource CreateX509CertificatePrivate(PP_Instance instance) + OVERRIDE; private: DISALLOW_COPY_AND_ASSIGN(ResourceCreationImpl); diff --git a/chromium/content/renderer/pepper/url_request_info_util.cc b/chromium/content/renderer/pepper/url_request_info_util.cc index 500b7bd2e75..2596a09017c 100644 --- a/chromium/content/renderer/pepper/url_request_info_util.cc +++ b/chromium/content/renderer/pepper/url_request_info_util.cc @@ -6,6 +6,7 @@ #include "base/logging.h" #include "base/strings/string_util.h" +#include "content/child/request_extra_data.h" #include "content/common/fileapi/file_system_messages.h" #include "content/renderer/pepper/common.h" #include "content/renderer/pepper/host_globals.h" @@ -27,7 +28,6 @@ #include "third_party/WebKit/public/web/WebFrame.h" #include "url/gurl.h" #include "url/url_util.h" -#include "webkit/child/weburlrequest_extradata_impl.h" using ppapi::Resource; using ppapi::URLRequestInfoData; @@ -45,13 +45,12 @@ namespace { // Appends the file ref given the Resource pointer associated with it to the // given HTTP body, returning true on success. -bool AppendFileRefToBody( - PP_Instance instance, - PP_Resource resource, - int64_t start_offset, - int64_t number_of_bytes, - PP_Time expected_last_modified_time, - WebHTTPBody *http_body) { +bool AppendFileRefToBody(PP_Instance instance, + PP_Resource resource, + int64_t start_offset, + int64_t number_of_bytes, + PP_Time expected_last_modified_time, + WebHTTPBody* http_body) { base::FilePath platform_path; PepperPluginInstanceImpl* instance_impl = HostGlobals::Get()->GetInstance(instance); @@ -83,11 +82,10 @@ bool AppendFileRefToBody( default: NOTREACHED(); } - http_body->appendFileRange( - platform_path.AsUTF16Unsafe(), - start_offset, - number_of_bytes, - expected_last_modified_time); + http_body->appendFileRange(platform_path.AsUTF16Unsafe(), + start_offset, + number_of_bytes, + expected_last_modified_time); return true; } @@ -98,7 +96,7 @@ bool ValidateURLRequestData(const URLRequestInfoData& data) { if (data.prefetch_buffer_lower_threshold < 0 || data.prefetch_buffer_upper_threshold < 0 || data.prefetch_buffer_upper_threshold <= - data.prefetch_buffer_lower_threshold) { + data.prefetch_buffer_lower_threshold) { return false; } return true; @@ -117,8 +115,7 @@ bool CreateWebURLRequest(PP_Instance instance, return false; dest->initialize(); - dest->setURL(frame->document().completeURL(WebString::fromUTF8( - data->url))); + dest->setURL(frame->document().completeURL(WebString::fromUTF8(data->url))); dest->setDownloadToFile(data->stream_to_file); dest->setReportUploadProgress(data->record_upload_progress); @@ -131,9 +128,8 @@ bool CreateWebURLRequest(PP_Instance instance, if (!headers.empty()) { net::HttpUtil::HeadersIterator it(headers.begin(), headers.end(), "\n\r"); while (it.GetNext()) { - dest->addHTTPHeaderField( - WebString::fromUTF8(it.name()), - WebString::fromUTF8(it.values())); + dest->addHTTPHeaderField(WebString::fromUTF8(it.name()), + WebString::fromUTF8(it.values())); } } @@ -176,21 +172,21 @@ bool CreateWebURLRequest(PP_Instance instance, if (data->has_custom_user_agent) { bool was_after_preconnect_request = false; - dest->setExtraData(new webkit_glue::WebURLRequestExtraDataImpl( - blink::WebReferrerPolicyDefault, // Ignored. - WebString::fromUTF8(data->custom_user_agent), - was_after_preconnect_request)); + RequestExtraData* extra_data = new RequestExtraData(); + extra_data->set_custom_user_agent( + WebString::fromUTF8(data->custom_user_agent)); + extra_data->set_was_after_preconnect_request(was_after_preconnect_request); + dest->setExtraData(extra_data); } return true; } bool URLRequestRequiresUniversalAccess(const URLRequestInfoData& data) { - return - data.has_custom_referrer_url || - data.has_custom_content_transfer_encoding || - data.has_custom_user_agent || - url_util::FindAndCompareScheme(data.url, "javascript", NULL); + return data.has_custom_referrer_url || + data.has_custom_content_transfer_encoding || + data.has_custom_user_agent || + url::FindAndCompareScheme(data.url, "javascript", NULL); } } // namespace content diff --git a/chromium/content/renderer/pepper/url_response_info_util.cc b/chromium/content/renderer/pepper/url_response_info_util.cc index 6349226a1db..2636e19c7e8 100644 --- a/chromium/content/renderer/pepper/url_response_info_util.cc +++ b/chromium/content/renderer/pepper/url_response_info_util.cc @@ -43,16 +43,14 @@ class HeaderFlattener : public WebHTTPHeaderVisitor { std::string buffer_; }; -bool IsRedirect(int32_t status) { - return status >= 300 && status <= 399; -} +bool IsRedirect(int32_t status) { return status >= 300 && status <= 399; } void DidCreateResourceHosts(const ppapi::URLResponseInfoData& in_data, const base::FilePath& external_path, int renderer_pending_host_id, const DataFromWebURLResponseCallback& callback, const std::vector<int>& browser_pending_host_ids) { - DCHECK(browser_pending_host_ids.size() == 1); + DCHECK_EQ(1U, browser_pending_host_ids.size()); int browser_pending_host_id = 0; if (browser_pending_host_ids.size() == 1) @@ -60,11 +58,11 @@ void DidCreateResourceHosts(const ppapi::URLResponseInfoData& in_data, ppapi::URLResponseInfoData data = in_data; - data.body_as_file_ref = ppapi::MakeExternalFileRefCreateInfo( - external_path, - std::string(), - browser_pending_host_id, - renderer_pending_host_id); + data.body_as_file_ref = + ppapi::MakeExternalFileRefCreateInfo(external_path, + std::string(), + browser_pending_host_id, + renderer_pending_host_id); callback.Run(data); } @@ -79,8 +77,8 @@ void DataFromWebURLResponse(RendererPpapiHostImpl* host_impl, data.status_code = response.httpStatusCode(); data.status_text = response.httpStatusText().utf8(); if (IsRedirect(data.status_code)) { - data.redirect_url = response.httpHeaderField( - WebString::fromUTF8("Location")).utf8(); + data.redirect_url = + response.httpHeaderField(WebString::fromUTF8("Location")).utf8(); } HeaderFlattener flattener; @@ -99,19 +97,17 @@ void DataFromWebURLResponse(RendererPpapiHostImpl* host_impl, scoped_ptr<ppapi::host::ResourceHost>(renderer_host)); std::vector<IPC::Message> create_msgs; - create_msgs.push_back(PpapiHostMsg_FileRef_CreateExternal(external_path)); - host_impl->CreateBrowserResourceHosts( - pp_instance, - create_msgs, - base::Bind(&DidCreateResourceHosts, - data, - external_path, - renderer_pending_host_id, - callback)); + create_msgs.push_back(PpapiHostMsg_FileRef_CreateForRawFS(external_path)); + host_impl->CreateBrowserResourceHosts(pp_instance, + create_msgs, + base::Bind(&DidCreateResourceHosts, + data, + external_path, + renderer_pending_host_id, + callback)); } else { - base::MessageLoop::current()->PostTask( - FROM_HERE, - base::Bind(callback, data)); + base::MessageLoop::current()->PostTask(FROM_HERE, + base::Bind(callback, data)); } } diff --git a/chromium/content/renderer/pepper/v8_var_converter.cc b/chromium/content/renderer/pepper/v8_var_converter.cc index 3f8b37e2878..b09fccd63e4 100644 --- a/chromium/content/renderer/pepper/v8_var_converter.cc +++ b/chromium/content/renderer/pepper/v8_var_converter.cc @@ -21,6 +21,7 @@ #include "ppapi/shared_impl/var.h" #include "ppapi/shared_impl/var_tracker.h" #include "third_party/WebKit/public/platform/WebArrayBuffer.h" +#include "third_party/WebKit/public/web/WebArrayBufferConverter.h" using ppapi::ArrayBufferVar; using ppapi::ArrayVar; @@ -53,14 +54,10 @@ namespace BASE_HASH_NAMESPACE { #if defined(COMPILER_GCC) template <> struct hash<HashedHandle> { - size_t operator()(const HashedHandle& handle) const { - return handle.hash(); - } + size_t operator()(const HashedHandle& handle) const { return handle.hash(); } }; #elif defined(COMPILER_MSVC) -inline size_t hash_value(const HashedHandle& handle) { - return handle.hash(); -} +inline size_t hash_value(const HashedHandle& handle) { return handle.hash(); } #endif } // namespace BASE_HASH_NAMESPACE @@ -81,12 +78,14 @@ typedef base::hash_set<HashedHandle> ParentHandleSet; // associated with it in the map will be returned, otherwise a new V8 value will // be created and added to the map. |did_create| indicates whether a new v8 // value was created as a result of calling the function. -bool GetOrCreateV8Value(v8::Isolate* isolate, +bool GetOrCreateV8Value(v8::Handle<v8::Context> context, const PP_Var& var, v8::Handle<v8::Value>* result, bool* did_create, VarHandleMap* visited_ids, - ParentVarSet* parent_ids) { + ParentVarSet* parent_ids, + ResourceConverter* resource_converter) { + v8::Isolate* isolate = context->GetIsolate(); *did_create = false; if (ppapi::VarTracker::IsVarTypeRefcounted(var.type)) { @@ -107,15 +106,14 @@ bool GetOrCreateV8Value(v8::Isolate* isolate, *result = v8::Null(isolate); break; case PP_VARTYPE_BOOL: - *result = (var.value.as_bool == PP_TRUE) - ? v8::True(isolate) - : v8::False(isolate); + *result = (var.value.as_bool == PP_TRUE) ? v8::True(isolate) + : v8::False(isolate); break; case PP_VARTYPE_INT32: - *result = v8::Integer::New(var.value.as_int); + *result = v8::Integer::New(isolate, var.value.as_int); break; case PP_VARTYPE_DOUBLE: - *result = v8::Number::New(var.value.as_double); + *result = v8::Number::New(isolate, var.value.as_double); break; case PP_VARTYPE_STRING: { StringVar* string = StringVar::FromPPVar(var); @@ -125,13 +123,12 @@ bool GetOrCreateV8Value(v8::Isolate* isolate, return false; } const std::string& value = string->value(); - // Create a string object rather than a string primitive. This allows us - // to have multiple references to the same string in javascript, which - // matches the reference behavior of PP_Vars. - *result = v8::String::NewFromUtf8(isolate, - value.c_str(), - v8::String::kNormalString, - value.size())->ToObject(); + // Create a string primitive rather than a string object. This is lossy + // in the sense that string primitives in JavaScript can't be referenced + // in the same way that string vars can in pepper. But that information + // isn't very useful and primitive strings are a more expected form in JS. + *result = v8::String::NewFromUtf8( + isolate, value.c_str(), v8::String::kNormalString, value.size()); break; } case PP_VARTYPE_ARRAY_BUFFER: { @@ -143,21 +140,25 @@ bool GetOrCreateV8Value(v8::Isolate* isolate, } HostArrayBufferVar* host_buffer = static_cast<HostArrayBufferVar*>(buffer); - *result = host_buffer->webkit_buffer().toV8Value(); + *result = blink::WebArrayBufferConverter::toV8Value( + &host_buffer->webkit_buffer(), context->Global(), isolate); break; } case PP_VARTYPE_ARRAY: *result = v8::Array::New(isolate); break; case PP_VARTYPE_DICTIONARY: - *result = v8::Object::New(); + *result = v8::Object::New(isolate); break; case PP_VARTYPE_OBJECT: - case PP_VARTYPE_RESOURCE: - // TODO(mgiuca): Convert PP_VARTYPE_RESOURCE vars into the correct V8 - // type. (http://crbug.com/177017) result->Clear(); return false; + case PP_VARTYPE_RESOURCE: + if (!resource_converter->ToV8Value(var, context, result)) { + result->Clear(); + return false; + } + break; } *did_create = true; @@ -188,8 +189,8 @@ bool GetOrCreateVar(v8::Handle<v8::Value> val, if (parent_handles->count(HashedHandle(val->ToObject())) != 0) return false; - HandleVarMap::const_iterator it = visited_handles->find( - HashedHandle(val->ToObject())); + HandleVarMap::const_iterator it = + visited_handles->find(HashedHandle(val->ToObject())); if (it != visited_handles->end()) { *result = it->second.get(); return true; @@ -213,15 +214,16 @@ bool GetOrCreateVar(v8::Handle<v8::Value> val, *result = (new ArrayVar())->GetPPVar(); } else if (val->IsObject()) { scoped_ptr<blink::WebArrayBuffer> web_array_buffer( - blink::WebArrayBuffer::createFromV8Value(val)); + blink::WebArrayBufferConverter::createFromV8Value( + val, context->GetIsolate())); if (web_array_buffer.get()) { - scoped_refptr<HostArrayBufferVar> buffer_var(new HostArrayBufferVar( - *web_array_buffer)); + scoped_refptr<HostArrayBufferVar> buffer_var( + new HostArrayBufferVar(*web_array_buffer)); *result = buffer_var->GetPPVar(); } else { bool was_resource; - if (!resource_converter->FromV8Value(val->ToObject(), context, result, - &was_resource)) + if (!resource_converter->FromV8Value( + val->ToObject(), context, result, &was_resource)) return false; if (!was_resource) { *result = (new DictionaryVar())->GetPPVar(); @@ -236,9 +238,9 @@ bool GetOrCreateVar(v8::Handle<v8::Value> val, *did_create = true; if (val->IsObject() || val->IsString()) { - visited_handles->insert(make_pair( - HashedHandle(val->ToObject()), - ScopedPPVar(ScopedPPVar::PassRef(), *result))); + visited_handles->insert( + make_pair(HashedHandle(val->ToObject()), + ScopedPPVar(ScopedPPVar::PassRef(), *result))); } return true; } @@ -255,15 +257,12 @@ V8VarConverter::V8VarConverter(PP_Instance instance) instance, RendererPpapiHost::GetForPPInstance(instance))); } -V8VarConverter::V8VarConverter( - PP_Instance instance, - scoped_ptr<ResourceConverter> resource_converter) +V8VarConverter::V8VarConverter(PP_Instance instance, + scoped_ptr<ResourceConverter> resource_converter) : message_loop_proxy_(base::MessageLoopProxy::current()), - resource_converter_(resource_converter.release()) { -} + resource_converter_(resource_converter.release()) {} -V8VarConverter::~V8VarConverter() { -} +V8VarConverter::~V8VarConverter() {} // To/FromV8Value use a stack-based DFS search to traverse V8/Var graph. Each // iteration, the top node on the stack examined. If the node has not been @@ -304,8 +303,13 @@ bool V8VarConverter::ToV8Value(const PP_Var& var, } bool did_create = false; - if (!GetOrCreateV8Value(isolate, current_var, ¤t_v8, &did_create, - &visited_ids, &parent_ids)) { + if (!GetOrCreateV8Value(context, + current_var, + ¤t_v8, + &did_create, + &visited_ids, + &parent_ids, + resource_converter_.get())) { return false; } @@ -328,8 +332,13 @@ bool V8VarConverter::ToV8Value(const PP_Var& var, for (size_t i = 0; i < array_var->elements().size(); ++i) { const PP_Var& child_var = array_var->elements()[i].get(); v8::Handle<v8::Value> child_v8; - if (!GetOrCreateV8Value(isolate, child_var, &child_v8, &did_create, - &visited_ids, &parent_ids)) { + if (!GetOrCreateV8Value(context, + child_var, + &child_v8, + &did_create, + &visited_ids, + &parent_ids, + resource_converter_.get())) { return false; } if (did_create && CanHaveChildren(child_var)) @@ -358,21 +367,25 @@ bool V8VarConverter::ToV8Value(const PP_Var& var, const std::string& key = iter->first; const PP_Var& child_var = iter->second.get(); v8::Handle<v8::Value> child_v8; - if (!GetOrCreateV8Value(isolate, child_var, &child_v8, &did_create, - &visited_ids, &parent_ids)) { + if (!GetOrCreateV8Value(context, + child_var, + &child_v8, + &did_create, + &visited_ids, + &parent_ids, + resource_converter_.get())) { return false; } if (did_create && CanHaveChildren(child_var)) stack.push(child_var); v8::TryCatch try_catch; - v8_object->Set(v8::String::NewFromUtf8(isolate, - key.c_str(), - v8::String::kNormalString, - key.length()), - child_v8); + v8_object->Set( + v8::String::NewFromUtf8( + isolate, key.c_str(), v8::String::kNormalString, key.length()), + child_v8); if (try_catch.HasCaught()) { LOG(ERROR) << "Setter for property " << key.c_str() << " threw an " - << "exception."; + << "exception."; return false; } } @@ -383,10 +396,37 @@ bool V8VarConverter::ToV8Value(const PP_Var& var, return true; } -void V8VarConverter::FromV8Value( +V8VarConverter::VarResult V8VarConverter::FromV8Value( v8::Handle<v8::Value> val, v8::Handle<v8::Context> context, const base::Callback<void(const ScopedPPVar&, bool)>& callback) { + VarResult result; + result.success = FromV8ValueInternal(val, context, &result.var); + if (!result.success) + resource_converter_->Reset(); + result.completed_synchronously = !resource_converter_->NeedsFlush(); + if (!result.completed_synchronously) + resource_converter_->Flush(base::Bind(callback, result.var)); + + return result; +} + +bool V8VarConverter::FromV8ValueSync( + v8::Handle<v8::Value> val, + v8::Handle<v8::Context> context, + ppapi::ScopedPPVar* result_var) { + bool success = FromV8ValueInternal(val, context, result_var); + if (!success || resource_converter_->NeedsFlush()) { + resource_converter_->Reset(); + return false; + } + return true; +} + +bool V8VarConverter::FromV8ValueInternal( + v8::Handle<v8::Value> val, + v8::Handle<v8::Context> context, + ppapi::ScopedPPVar* result_var) { v8::Context::Scope context_scope(context); v8::HandleScope handle_scope(context->GetIsolate()); @@ -396,6 +436,7 @@ void V8VarConverter::FromV8Value( std::stack<StackEntry<v8::Handle<v8::Value> > > stack; stack.push(StackEntry<v8::Handle<v8::Value> >(val)); ScopedPPVar root; + *result_var = PP_MakeUndefined(); bool is_root = true; while (!stack.empty()) { @@ -412,12 +453,14 @@ void V8VarConverter::FromV8Value( } bool did_create = false; - if (!GetOrCreateVar(current_v8, context, ¤t_var, &did_create, - &visited_handles, &parent_handles, + if (!GetOrCreateVar(current_v8, + context, + ¤t_var, + &did_create, + &visited_handles, + &parent_handles, resource_converter_.get())) { - message_loop_proxy_->PostTask(FROM_HERE, - base::Bind(callback, ScopedPPVar(PP_MakeUndefined()), false)); - return; + return false; } if (is_root) { @@ -434,30 +477,27 @@ void V8VarConverter::FromV8Value( ArrayVar* array_var = ArrayVar::FromPPVar(current_var); if (!array_var) { NOTREACHED(); - message_loop_proxy_->PostTask(FROM_HERE, - base::Bind(callback, ScopedPPVar(PP_MakeUndefined()), false)); - return; + return false; } for (uint32 i = 0; i < v8_array->Length(); ++i) { v8::TryCatch try_catch; v8::Handle<v8::Value> child_v8 = v8_array->Get(i); - if (try_catch.HasCaught()) { - message_loop_proxy_->PostTask(FROM_HERE, - base::Bind(callback, ScopedPPVar(PP_MakeUndefined()), false)); - return; - } + if (try_catch.HasCaught()) + return false; if (!v8_array->HasRealIndexedProperty(i)) continue; PP_Var child_var; - if (!GetOrCreateVar(child_v8, context, &child_var, &did_create, - &visited_handles, &parent_handles, + if (!GetOrCreateVar(child_v8, + context, + &child_var, + &did_create, + &visited_handles, + &parent_handles, resource_converter_.get())) { - message_loop_proxy_->PostTask(FROM_HERE, - base::Bind(callback, ScopedPPVar(PP_MakeUndefined()), false)); - return; + return false; } if (did_create && child_v8->IsObject()) stack.push(child_v8); @@ -472,9 +512,7 @@ void V8VarConverter::FromV8Value( DictionaryVar* dict_var = DictionaryVar::FromPPVar(current_var); if (!dict_var) { NOTREACHED(); - message_loop_proxy_->PostTask(FROM_HERE, - base::Bind(callback, ScopedPPVar(PP_MakeUndefined()), false)); - return; + return false; } v8::Handle<v8::Array> property_names(v8_object->GetOwnPropertyNames()); @@ -483,11 +521,10 @@ void V8VarConverter::FromV8Value( // Extend this test to cover more types as necessary and if sensible. if (!key->IsString() && !key->IsNumber()) { - NOTREACHED() << "Key \"" << *v8::String::Utf8Value(key) << "\" " + NOTREACHED() << "Key \"" << *v8::String::Utf8Value(key) + << "\" " "is neither a string nor a number"; - message_loop_proxy_->PostTask(FROM_HERE, - base::Bind(callback, ScopedPPVar(PP_MakeUndefined()), false)); - return; + return false; } // Skip all callbacks: crbug.com/139933 @@ -498,19 +535,18 @@ void V8VarConverter::FromV8Value( v8::TryCatch try_catch; v8::Handle<v8::Value> child_v8 = v8_object->Get(key); - if (try_catch.HasCaught()) { - message_loop_proxy_->PostTask(FROM_HERE, - base::Bind(callback, ScopedPPVar(PP_MakeUndefined()), false)); - return; - } + if (try_catch.HasCaught()) + return false; PP_Var child_var; - if (!GetOrCreateVar(child_v8, context, &child_var, &did_create, - &visited_handles, &parent_handles, + if (!GetOrCreateVar(child_v8, + context, + &child_var, + &did_create, + &visited_handles, + &parent_handles, resource_converter_.get())) { - message_loop_proxy_->PostTask(FROM_HERE, - base::Bind(callback, ScopedPPVar(PP_MakeUndefined()), false)); - return; + return false; } if (did_create && child_v8->IsObject()) stack.push(child_v8); @@ -521,7 +557,8 @@ void V8VarConverter::FromV8Value( } } } - resource_converter_->Flush(base::Bind(callback, root)); + *result_var = root; + return true; } } // namespace content diff --git a/chromium/content/renderer/pepper/v8_var_converter.h b/chromium/content/renderer/pepper/v8_var_converter.h index 37ce20824d0..42ef7a647f5 100644 --- a/chromium/content/renderer/pepper/v8_var_converter.h +++ b/chromium/content/renderer/pepper/v8_var_converter.h @@ -5,20 +5,16 @@ #ifndef CONTENT_RENDERER_PEPPER_V8_VAR_CONVERTER_H #define CONTENT_RENDERER_PEPPER_V8_VAR_CONVERTER_H - #include "base/basictypes.h" #include "base/callback.h" #include "base/compiler_specific.h" #include "base/message_loop/message_loop_proxy.h" #include "ppapi/c/pp_instance.h" #include "ppapi/c/pp_var.h" +#include "ppapi/shared_impl/scoped_pp_var.h" #include "v8/include/v8.h" #include "content/common/content_export.h" -namespace ppapi { -class ScopedPPVar; -} - namespace content { class ResourceConverter; @@ -27,9 +23,8 @@ class CONTENT_EXPORT V8VarConverter { public: explicit V8VarConverter(PP_Instance instance); // Constructor for testing. - V8VarConverter( - PP_Instance instance, - scoped_ptr<ResourceConverter> resource_converter); + V8VarConverter(PP_Instance instance, + scoped_ptr<ResourceConverter> resource_converter); ~V8VarConverter(); // Converts the given PP_Var to a v8::Value. True is returned upon success. @@ -37,19 +32,45 @@ class CONTENT_EXPORT V8VarConverter { v8::Handle<v8::Context> context, v8::Handle<v8::Value>* result); + struct VarResult { + public: + VarResult() : completed_synchronously(false), success(false) {} + + // True if the conversion completed synchronously and the callback will not + // be called. + bool completed_synchronously; + + // True if the conversion was successful. Only valid if + // |completed_synchronously| is true. + bool success; + + // The result if the conversion was successful. Only valid if + // |completed_synchronously| and |success| are true. + ppapi::ScopedPPVar var; + }; + // Converts the given v8::Value to a PP_Var. Every PP_Var in the reference // graph in the result will have a refcount equal to the number of references // to it in the graph. The root of the result will have one additional // reference. The callback is run when conversion is complete with the - // resulting var and a bool indicating success or failure. Conversion is + // resulting var and a bool indicating success or failure. Conversion may be // asynchronous because converting some resources may result in communication - // across IPC. |context| is guaranteed to only be used synchronously. - void FromV8Value( + // across IPC. |context| is guaranteed to only be used synchronously. If + // the conversion can occur synchronously, |callback| will not be run, + // otherwise it will be run. + VarResult FromV8Value( v8::Handle<v8::Value> val, v8::Handle<v8::Context> context, const base::Callback<void(const ppapi::ScopedPPVar&, bool)>& callback); - + bool FromV8ValueSync(v8::Handle<v8::Value> val, + v8::Handle<v8::Context> context, + ppapi::ScopedPPVar* result_var); private: + // Returns true on success, false on failure. + bool FromV8ValueInternal(v8::Handle<v8::Value> val, + v8::Handle<v8::Context> context, + ppapi::ScopedPPVar* result_var); + // The message loop to run the callback to |FromV8Value| from. scoped_refptr<base::MessageLoopProxy> message_loop_proxy_; diff --git a/chromium/content/renderer/pepper/v8_var_converter_unittest.cc b/chromium/content/renderer/pepper/v8_var_converter_unittest.cc index afe85fddf3c..9492a431a4d 100644 --- a/chromium/content/renderer/pepper/v8_var_converter_unittest.cc +++ b/chromium/content/renderer/pepper/v8_var_converter_unittest.cc @@ -43,11 +43,18 @@ namespace content { namespace { +void FromV8ValueComplete(const ScopedPPVar& scoped_var, + bool success) { + NOTREACHED(); +} + class MockResourceConverter : public content::ResourceConverter { public: virtual ~MockResourceConverter() {} + virtual void Reset() OVERRIDE {} + virtual bool NeedsFlush() OVERRIDE { return false; } virtual void Flush(const base::Callback<void(bool)>& callback) OVERRIDE { - callback.Run(true); + NOTREACHED(); } virtual bool FromV8Value(v8::Handle<v8::Object> val, v8::Handle<v8::Context> context, @@ -56,6 +63,11 @@ class MockResourceConverter : public content::ResourceConverter { *was_resource = false; return true; } + virtual bool ToV8Value(const PP_Var& var, + v8::Handle<v8::Context> context, + v8::Handle<v8::Value>* result) OVERRIDE { + return false; + } }; // Maps PP_Var IDs to the V8 value handle they correspond to. @@ -77,13 +89,13 @@ bool Equals(const PP_Var& var, return var.type == PP_VARTYPE_NULL; } else if (val->IsBoolean() || val->IsBooleanObject()) { return var.type == PP_VARTYPE_BOOL && - PP_FromBool(val->ToBoolean()->Value()) == var.value.as_bool; + PP_FromBool(val->ToBoolean()->Value()) == var.value.as_bool; } else if (val->IsInt32()) { return var.type == PP_VARTYPE_INT32 && - val->ToInt32()->Value() == var.value.as_int; + val->ToInt32()->Value() == var.value.as_int; } else if (val->IsNumber() || val->IsNumberObject()) { return var.type == PP_VARTYPE_DOUBLE && - fabs(val->ToNumber()->Value() - var.value.as_double) <= 1.0e-4; + fabs(val->ToNumber()->Value() - var.value.as_double) <= 1.0e-4; } else if (val->IsString() || val->IsStringObject()) { if (var.type != PP_VARTYPE_STRING) return false; @@ -128,8 +140,8 @@ bool Equals(const PP_Var& var, v8::String::Utf8Value name_utf8(key->ToString()); ScopedPPVar release_key(ScopedPPVar::PassRef(), - StringVar::StringToPPVar( - std::string(*name_utf8, name_utf8.length()))); + StringVar::StringToPPVar(std::string( + *name_utf8, name_utf8.length()))); if (!dict_var->HasKey(release_key.get())) return false; ScopedPPVar release_value(ScopedPPVar::PassRef(), @@ -143,8 +155,7 @@ bool Equals(const PP_Var& var, return false; } -bool Equals(const PP_Var& var, - v8::Handle<v8::Value> val) { +bool Equals(const PP_Var& var, v8::Handle<v8::Value> val) { VarHandleMap var_handle_map; return Equals(var, val, &var_handle_map); } @@ -152,8 +163,7 @@ bool Equals(const PP_Var& var, class V8VarConverterTest : public testing::Test { public: V8VarConverterTest() - : isolate_(v8::Isolate::GetCurrent()), - conversion_success_(false) { + : isolate_(v8::Isolate::GetCurrent()) { PP_Instance dummy = 1234; converter_.reset(new V8VarConverter( dummy, @@ -165,7 +175,7 @@ class V8VarConverterTest : public testing::Test { virtual void SetUp() { ProxyLock::Acquire(); v8::HandleScope handle_scope(isolate_); - v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New(); + v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New(isolate_); context_.Reset(isolate_, v8::Context::New(isolate_, NULL, global)); } virtual void TearDown() { @@ -178,25 +188,15 @@ class V8VarConverterTest : public testing::Test { bool FromV8ValueSync(v8::Handle<v8::Value> val, v8::Handle<v8::Context> context, PP_Var* result) { - base::RunLoop loop; - converter_->FromV8Value(val, context, base::Bind( - &V8VarConverterTest::FromV8ValueComplete, base::Unretained(this), - loop.QuitClosure())); - loop.Run(); - if (conversion_success_) - *result = conversion_result_; - return conversion_success_; - } - - void FromV8ValueComplete(base::Closure quit_closure, - const ScopedPPVar& scoped_var, - bool success) { - conversion_success_ = success; - if (success) { - ScopedPPVar var = scoped_var; - conversion_result_ = var.Release(); - } - quit_closure.Run(); + V8VarConverter::VarResult conversion_result = + converter_->FromV8Value(val, + context, + base::Bind(&FromV8ValueComplete)); + DCHECK(conversion_result.completed_synchronously); + if (conversion_result.success) + *result = conversion_result.var.Release(); + + return conversion_result.success; } bool RoundTrip(const PP_Var& var, PP_Var* result) { @@ -221,7 +221,7 @@ class V8VarConverterTest : public testing::Test { if (!RoundTrip(expected.get(), &actual_var)) return false; ScopedPPVar actual(ScopedPPVar::PassRef(), actual_var); - return TestEqual(expected.get(), actual.get()); + return TestEqual(expected.get(), actual.get(), false); } v8::Isolate* isolate_; @@ -234,8 +234,6 @@ class V8VarConverterTest : public testing::Test { private: TestGlobals globals_; - PP_Var conversion_result_; - bool conversion_success_; base::MessageLoop message_loop_; }; @@ -276,8 +274,8 @@ TEST_F(V8VarConverterTest, DictionaryArrayRoundTripTest) { EXPECT_TRUE(RoundTripAndCompare(array->GetPPVar())); // Array with 2 references to the same string. - ScopedPPVar release_string( - ScopedPPVar::PassRef(), StringVar::StringToPPVar("abc")); + ScopedPPVar release_string(ScopedPPVar::PassRef(), + StringVar::StringToPPVar("abc")); array->Set(index++, release_string.get()); array->Set(index++, release_string.get()); EXPECT_TRUE(RoundTripAndCompare(array->GetPPVar())); @@ -348,8 +346,8 @@ TEST_F(V8VarConverterTest, Cycles) { // Array <-> dictionary cycle. dictionary->SetWithStringKey("1", release_array.get()); - ASSERT_FALSE(converter_->ToV8Value(release_dictionary.get(), - context, &v8_result)); + ASSERT_FALSE( + converter_->ToV8Value(release_dictionary.get(), context, &v8_result)); // Break the cycle. // TODO(raymes): We need some better machinery for releasing vars with // cycles. Remove the code below once we have that. @@ -357,8 +355,8 @@ TEST_F(V8VarConverterTest, Cycles) { // Array with self reference. array->Set(0, release_array.get()); - ASSERT_FALSE(converter_->ToV8Value(release_array.get(), - context, &v8_result)); + ASSERT_FALSE( + converter_->ToV8Value(release_array.get(), context, &v8_result)); // Break the self reference. array->Set(0, PP_MakeUndefined()); } @@ -402,25 +400,26 @@ TEST_F(V8VarConverterTest, StrangeDictionaryKeyTest) { v8::Local<v8::Context>::New(isolate_, context_); v8::Context::Scope context_scope(context); - const char* source = "(function() {" + const char* source = + "(function() {" "return {" - "1: 'foo'," - "'2': 'bar'," - "true: 'baz'," - "false: 'qux'," - "null: 'quux'," - "undefined: 'oops'" + "1: 'foo'," + "'2': 'bar'," + "true: 'baz'," + "false: 'qux'," + "null: 'quux'," + "undefined: 'oops'" "};" "})();"; v8::Handle<v8::Script> script( - v8::Script::New(v8::String::NewFromUtf8(isolate_, source))); + v8::Script::Compile(v8::String::NewFromUtf8(isolate_, source))); v8::Handle<v8::Object> object = script->Run().As<v8::Object>(); ASSERT_FALSE(object.IsEmpty()); PP_Var actual; - ASSERT_TRUE(FromV8ValueSync(object, - v8::Local<v8::Context>::New(isolate_, context_), &actual)); + ASSERT_TRUE(FromV8ValueSync( + object, v8::Local<v8::Context>::New(isolate_, context_), &actual)); ScopedPPVar release_actual(ScopedPPVar::PassRef(), actual); scoped_refptr<DictionaryVar> expected(new DictionaryVar); @@ -436,10 +435,9 @@ TEST_F(V8VarConverterTest, StrangeDictionaryKeyTest) { expected->SetWithStringKey("null", quux.get()); ScopedPPVar oops(ScopedPPVar::PassRef(), StringVar::StringToPPVar("oops")); expected->SetWithStringKey("undefined", oops.get()); - ScopedPPVar release_expected( - ScopedPPVar::PassRef(), expected->GetPPVar()); + ScopedPPVar release_expected(ScopedPPVar::PassRef(), expected->GetPPVar()); - ASSERT_TRUE(TestEqual(release_expected.get(), release_actual.get())); + ASSERT_TRUE(TestEqual(release_expected.get(), release_actual.get(), true)); } } diff --git a/chromium/content/renderer/pepper/video_decoder_shim.cc b/chromium/content/renderer/pepper/video_decoder_shim.cc new file mode 100644 index 00000000000..50a63989278 --- /dev/null +++ b/chromium/content/renderer/pepper/video_decoder_shim.cc @@ -0,0 +1,589 @@ +// Copyright 2014 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 "content/renderer/pepper/video_decoder_shim.h" + +#include <GLES2/gl2.h> +#include <GLES2/gl2ext.h> +#include <GLES2/gl2extchromium.h> + +#include "base/bind.h" +#include "base/numerics/safe_conversions.h" +#include "content/public/renderer/render_thread.h" +#include "content/renderer/pepper/pepper_video_decoder_host.h" +#include "content/renderer/render_thread_impl.h" +#include "gpu/command_buffer/client/gles2_implementation.h" +#include "media/base/decoder_buffer.h" +#include "media/base/limits.h" +#include "media/base/video_decoder.h" +#include "media/filters/ffmpeg_video_decoder.h" +#include "media/filters/vpx_video_decoder.h" +#include "media/video/picture.h" +#include "media/video/video_decode_accelerator.h" +#include "ppapi/c/pp_errors.h" +#include "third_party/libyuv/include/libyuv.h" +#include "webkit/common/gpu/context_provider_web_context.h" + +namespace content { + +struct VideoDecoderShim::PendingDecode { + PendingDecode(uint32_t decode_id, + const scoped_refptr<media::DecoderBuffer>& buffer); + ~PendingDecode(); + + const uint32_t decode_id; + const scoped_refptr<media::DecoderBuffer> buffer; +}; + +VideoDecoderShim::PendingDecode::PendingDecode( + uint32_t decode_id, + const scoped_refptr<media::DecoderBuffer>& buffer) + : decode_id(decode_id), buffer(buffer) { +} + +VideoDecoderShim::PendingDecode::~PendingDecode() { +} + +struct VideoDecoderShim::PendingFrame { + explicit PendingFrame(uint32_t decode_id); + PendingFrame(uint32_t decode_id, const gfx::Size& size); + ~PendingFrame(); + + const uint32_t decode_id; + const gfx::Size size; + std::vector<uint8_t> argb_pixels; + + private: + // This could be expensive to copy, so guard against that. + DISALLOW_COPY_AND_ASSIGN(PendingFrame); +}; + +VideoDecoderShim::PendingFrame::PendingFrame(uint32_t decode_id) + : decode_id(decode_id) { +} + +VideoDecoderShim::PendingFrame::PendingFrame(uint32_t decode_id, + const gfx::Size& size) + : decode_id(decode_id), + size(size), + argb_pixels(size.width() * size.height() * 4) { +} + +VideoDecoderShim::PendingFrame::~PendingFrame() { +} + +// DecoderImpl runs the underlying VideoDecoder on the media thread, receiving +// calls from the VideoDecodeShim on the main thread and sending results back. +// This class is constructed on the main thread, but used and destructed on the +// media thread. +class VideoDecoderShim::DecoderImpl { + public: + explicit DecoderImpl(const base::WeakPtr<VideoDecoderShim>& proxy); + ~DecoderImpl(); + + void Initialize(media::VideoDecoderConfig config); + void Decode(uint32_t decode_id, scoped_refptr<media::DecoderBuffer> buffer); + void Reset(); + void Stop(); + + private: + void OnPipelineStatus(media::PipelineStatus status); + void DoDecode(); + void OnDecodeComplete(uint32_t decode_id, media::VideoDecoder::Status status); + void OnOutputComplete(const scoped_refptr<media::VideoFrame>& frame); + void OnResetComplete(); + + // WeakPtr is bound to main_message_loop_. Use only in shim callbacks. + base::WeakPtr<VideoDecoderShim> shim_; + scoped_ptr<media::VideoDecoder> decoder_; + scoped_refptr<base::MessageLoopProxy> main_message_loop_; + // Queue of decodes waiting for the decoder. + typedef std::queue<PendingDecode> PendingDecodeQueue; + PendingDecodeQueue pending_decodes_; + int max_decodes_at_decoder_; + int num_decodes_at_decoder_; + // VideoDecoder returns pictures without information about the decode buffer + // that generated it. Save the decode_id from the last decode that completed, + // which is close for most decoders, which only decode one buffer at a time. + uint32_t decode_id_; +}; + +VideoDecoderShim::DecoderImpl::DecoderImpl( + const base::WeakPtr<VideoDecoderShim>& proxy) + : shim_(proxy), + main_message_loop_(base::MessageLoopProxy::current()), + max_decodes_at_decoder_(0), + num_decodes_at_decoder_(0), + decode_id_(0) { +} + +VideoDecoderShim::DecoderImpl::~DecoderImpl() { + DCHECK(pending_decodes_.empty()); +} + +void VideoDecoderShim::DecoderImpl::Initialize( + media::VideoDecoderConfig config) { + DCHECK(!decoder_); + if (config.codec() == media::kCodecVP9) { + decoder_.reset( + new media::VpxVideoDecoder(base::MessageLoopProxy::current())); + } else { + scoped_ptr<media::FFmpegVideoDecoder> ffmpeg_video_decoder( + new media::FFmpegVideoDecoder(base::MessageLoopProxy::current())); + ffmpeg_video_decoder->set_decode_nalus(true); + decoder_ = ffmpeg_video_decoder.Pass(); + } + max_decodes_at_decoder_ = decoder_->GetMaxDecodeRequests(); + // We can use base::Unretained() safely in decoder callbacks because we call + // VideoDecoder::Stop() before deletion. Stop() guarantees there will be no + // outstanding callbacks after it returns. + decoder_->Initialize( + config, + true /* low_delay */, + base::Bind(&VideoDecoderShim::DecoderImpl::OnPipelineStatus, + base::Unretained(this)), + base::Bind(&VideoDecoderShim::DecoderImpl::OnOutputComplete, + base::Unretained(this))); +} + +void VideoDecoderShim::DecoderImpl::Decode( + uint32_t decode_id, + scoped_refptr<media::DecoderBuffer> buffer) { + DCHECK(decoder_); + pending_decodes_.push(PendingDecode(decode_id, buffer)); + DoDecode(); +} + +void VideoDecoderShim::DecoderImpl::Reset() { + DCHECK(decoder_); + // Abort all pending decodes. + while (!pending_decodes_.empty()) { + const PendingDecode& decode = pending_decodes_.front(); + scoped_ptr<PendingFrame> pending_frame(new PendingFrame(decode.decode_id)); + main_message_loop_->PostTask(FROM_HERE, + base::Bind(&VideoDecoderShim::OnDecodeComplete, + shim_, + media::VideoDecoder::kAborted, + decode.decode_id)); + pending_decodes_.pop(); + } + decoder_->Reset(base::Bind(&VideoDecoderShim::DecoderImpl::OnResetComplete, + base::Unretained(this))); +} + +void VideoDecoderShim::DecoderImpl::Stop() { + DCHECK(decoder_); + // Clear pending decodes now. We don't want OnDecodeComplete to call DoDecode + // again. + while (!pending_decodes_.empty()) + pending_decodes_.pop(); + decoder_->Stop(); + // This instance is deleted once we exit this scope. +} + +void VideoDecoderShim::DecoderImpl::OnPipelineStatus( + media::PipelineStatus status) { + int32_t result; + switch (status) { + case media::PIPELINE_OK: + result = PP_OK; + break; + case media::DECODER_ERROR_NOT_SUPPORTED: + result = PP_ERROR_NOTSUPPORTED; + break; + default: + result = PP_ERROR_FAILED; + break; + } + + // Calculate how many textures the shim should create. + uint32_t shim_texture_pool_size = + max_decodes_at_decoder_ + media::limits::kMaxVideoFrames; + main_message_loop_->PostTask( + FROM_HERE, + base::Bind(&VideoDecoderShim::OnInitializeComplete, + shim_, + result, + shim_texture_pool_size)); +} + +void VideoDecoderShim::DecoderImpl::DoDecode() { + while (!pending_decodes_.empty() && + num_decodes_at_decoder_ < max_decodes_at_decoder_) { + num_decodes_at_decoder_++; + const PendingDecode& decode = pending_decodes_.front(); + decoder_->Decode( + decode.buffer, + base::Bind(&VideoDecoderShim::DecoderImpl::OnDecodeComplete, + base::Unretained(this), + decode.decode_id)); + pending_decodes_.pop(); + } +} + +void VideoDecoderShim::DecoderImpl::OnDecodeComplete( + uint32_t decode_id, + media::VideoDecoder::Status status) { + num_decodes_at_decoder_--; + decode_id_ = decode_id; + + int32_t result; + switch (status) { + case media::VideoDecoder::kOk: + case media::VideoDecoder::kAborted: + result = PP_OK; + break; + case media::VideoDecoder::kDecodeError: + result = PP_ERROR_RESOURCE_FAILED; + break; + default: + NOTREACHED(); + result = PP_ERROR_FAILED; + break; + } + + main_message_loop_->PostTask( + FROM_HERE, + base::Bind( + &VideoDecoderShim::OnDecodeComplete, shim_, result, decode_id)); + + DoDecode(); +} + +void VideoDecoderShim::DecoderImpl::OnOutputComplete( + const scoped_refptr<media::VideoFrame>& frame) { + scoped_ptr<PendingFrame> pending_frame; + if (!frame->end_of_stream()) { + pending_frame.reset(new PendingFrame(decode_id_, frame->coded_size())); + // Convert the VideoFrame pixels to ABGR to match VideoDecodeAccelerator. + libyuv::I420ToABGR(frame->data(media::VideoFrame::kYPlane), + frame->stride(media::VideoFrame::kYPlane), + frame->data(media::VideoFrame::kUPlane), + frame->stride(media::VideoFrame::kUPlane), + frame->data(media::VideoFrame::kVPlane), + frame->stride(media::VideoFrame::kVPlane), + &pending_frame->argb_pixels.front(), + frame->coded_size().width() * 4, + frame->coded_size().width(), + frame->coded_size().height()); + } else { + pending_frame.reset(new PendingFrame(decode_id_)); + } + + main_message_loop_->PostTask(FROM_HERE, + base::Bind(&VideoDecoderShim::OnOutputComplete, + shim_, + base::Passed(&pending_frame))); +} + +void VideoDecoderShim::DecoderImpl::OnResetComplete() { + main_message_loop_->PostTask( + FROM_HERE, base::Bind(&VideoDecoderShim::OnResetComplete, shim_)); +} + +VideoDecoderShim::VideoDecoderShim(PepperVideoDecoderHost* host) + : state_(UNINITIALIZED), + host_(host), + media_message_loop_( + RenderThreadImpl::current()->GetMediaThreadMessageLoopProxy()), + context_provider_( + RenderThreadImpl::current()->SharedMainThreadContextProvider()), + texture_pool_size_(0), + num_pending_decodes_(0), + weak_ptr_factory_(this) { + DCHECK(host_); + DCHECK(media_message_loop_); + DCHECK(context_provider_); + decoder_impl_.reset(new DecoderImpl(weak_ptr_factory_.GetWeakPtr())); +} + +VideoDecoderShim::~VideoDecoderShim() { + DCHECK(RenderThreadImpl::current()); + // Delete any remaining textures. + TextureIdMap::iterator it = texture_id_map_.begin(); + for (; it != texture_id_map_.end(); ++it) + DeleteTexture(it->second); + texture_id_map_.clear(); + + FlushCommandBuffer(); + + weak_ptr_factory_.InvalidateWeakPtrs(); + // No more callbacks from the delegate will be received now. + + // The callback now holds the only reference to the DecoderImpl, which will be + // deleted when Stop completes. + media_message_loop_->PostTask( + FROM_HERE, + base::Bind(&VideoDecoderShim::DecoderImpl::Stop, + base::Owned(decoder_impl_.release()))); +} + +bool VideoDecoderShim::Initialize( + media::VideoCodecProfile profile, + media::VideoDecodeAccelerator::Client* client) { + DCHECK_EQ(client, host_); + DCHECK(RenderThreadImpl::current()); + DCHECK_EQ(state_, UNINITIALIZED); + media::VideoCodec codec = media::kUnknownVideoCodec; + if (profile <= media::H264PROFILE_MAX) + codec = media::kCodecH264; + else if (profile <= media::VP8PROFILE_MAX) + codec = media::kCodecVP8; + else if (profile <= media::VP9PROFILE_MAX) + codec = media::kCodecVP9; + DCHECK_NE(codec, media::kUnknownVideoCodec); + + media::VideoDecoderConfig config( + codec, + profile, + media::VideoFrame::YV12, + gfx::Size(32, 24), // Small sizes that won't fail. + gfx::Rect(32, 24), + gfx::Size(32, 24), + NULL /* extra_data */, // TODO(bbudge) Verify this isn't needed. + 0 /* extra_data_size */, + false /* decryption */); + + media_message_loop_->PostTask( + FROM_HERE, + base::Bind(&VideoDecoderShim::DecoderImpl::Initialize, + base::Unretained(decoder_impl_.get()), + config)); + // Return success, even though we are asynchronous, to mimic + // media::VideoDecodeAccelerator. + return true; +} + +void VideoDecoderShim::Decode(const media::BitstreamBuffer& bitstream_buffer) { + DCHECK(RenderThreadImpl::current()); + DCHECK_EQ(state_, DECODING); + + // We need the address of the shared memory, so we can copy the buffer. + const uint8_t* buffer = host_->DecodeIdToAddress(bitstream_buffer.id()); + DCHECK(buffer); + + media_message_loop_->PostTask( + FROM_HERE, + base::Bind( + &VideoDecoderShim::DecoderImpl::Decode, + base::Unretained(decoder_impl_.get()), + bitstream_buffer.id(), + media::DecoderBuffer::CopyFrom(buffer, bitstream_buffer.size()))); + num_pending_decodes_++; +} + +void VideoDecoderShim::AssignPictureBuffers( + const std::vector<media::PictureBuffer>& buffers) { + DCHECK(RenderThreadImpl::current()); + DCHECK_EQ(state_, DECODING); + if (buffers.empty()) { + NOTREACHED(); + return; + } + DCHECK_EQ(buffers.size(), pending_texture_mailboxes_.size()); + GLuint num_textures = base::checked_cast<GLuint>(buffers.size()); + std::vector<uint32_t> local_texture_ids(num_textures); + gpu::gles2::GLES2Interface* gles2 = context_provider_->ContextGL(); + gles2->GenTextures(num_textures, &local_texture_ids.front()); + for (uint32_t i = 0; i < num_textures; i++) { + gles2->ActiveTexture(GL_TEXTURE0); + gles2->BindTexture(GL_TEXTURE_2D, local_texture_ids[i]); + gles2->ConsumeTextureCHROMIUM(GL_TEXTURE_2D, + pending_texture_mailboxes_[i].name); + // Map the plugin texture id to the local texture id. + uint32_t plugin_texture_id = buffers[i].texture_id(); + texture_id_map_[plugin_texture_id] = local_texture_ids[i]; + available_textures_.insert(plugin_texture_id); + } + pending_texture_mailboxes_.clear(); + SendPictures(); +} + +void VideoDecoderShim::ReusePictureBuffer(int32 picture_buffer_id) { + DCHECK(RenderThreadImpl::current()); + uint32_t texture_id = static_cast<uint32_t>(picture_buffer_id); + if (textures_to_dismiss_.find(texture_id) != textures_to_dismiss_.end()) { + DismissTexture(texture_id); + } else if (texture_id_map_.find(texture_id) != texture_id_map_.end()) { + available_textures_.insert(texture_id); + SendPictures(); + } else { + NOTREACHED(); + } +} + +void VideoDecoderShim::Flush() { + DCHECK(RenderThreadImpl::current()); + DCHECK_EQ(state_, DECODING); + state_ = FLUSHING; +} + +void VideoDecoderShim::Reset() { + DCHECK(RenderThreadImpl::current()); + DCHECK_EQ(state_, DECODING); + state_ = RESETTING; + media_message_loop_->PostTask( + FROM_HERE, + base::Bind(&VideoDecoderShim::DecoderImpl::Reset, + base::Unretained(decoder_impl_.get()))); +} + +void VideoDecoderShim::Destroy() { + // This will be called, but our destructor does the actual work. +} + +void VideoDecoderShim::OnInitializeComplete(int32_t result, + uint32_t texture_pool_size) { + DCHECK(RenderThreadImpl::current()); + DCHECK(host_); + + if (result == PP_OK) { + state_ = DECODING; + texture_pool_size_ = texture_pool_size; + } + + host_->OnInitializeComplete(result); +} + +void VideoDecoderShim::OnDecodeComplete(int32_t result, uint32_t decode_id) { + DCHECK(RenderThreadImpl::current()); + DCHECK(host_); + + if (result == PP_ERROR_RESOURCE_FAILED) { + host_->NotifyError(media::VideoDecodeAccelerator::PLATFORM_FAILURE); + return; + } + + num_pending_decodes_--; + completed_decodes_.push(decode_id); + + // If frames are being queued because we're out of textures, don't notify + // the host that decode has completed. This exerts "back pressure" to keep + // the host from sending buffers that will cause pending_frames_ to grow. + if (pending_frames_.empty()) + NotifyCompletedDecodes(); +} + +void VideoDecoderShim::OnOutputComplete(scoped_ptr<PendingFrame> frame) { + DCHECK(RenderThreadImpl::current()); + DCHECK(host_); + + if (!frame->argb_pixels.empty()) { + if (texture_size_ != frame->size) { + // If the size has changed, all current textures must be dismissed. Add + // all textures to |textures_to_dismiss_| and dismiss any that aren't in + // use by the plugin. We will dismiss the rest as they are recycled. + for (TextureIdMap::const_iterator it = texture_id_map_.begin(); + it != texture_id_map_.end(); + ++it) { + textures_to_dismiss_.insert(it->second); + } + for (TextureIdSet::const_iterator it = available_textures_.begin(); + it != available_textures_.end(); + ++it) { + DismissTexture(*it); + } + available_textures_.clear(); + FlushCommandBuffer(); + + DCHECK(pending_texture_mailboxes_.empty()); + for (uint32_t i = 0; i < texture_pool_size_; i++) + pending_texture_mailboxes_.push_back(gpu::Mailbox::Generate()); + + host_->RequestTextures(texture_pool_size_, + frame->size, + GL_TEXTURE_2D, + pending_texture_mailboxes_); + texture_size_ = frame->size; + } + + pending_frames_.push(linked_ptr<PendingFrame>(frame.release())); + SendPictures(); + } +} + +void VideoDecoderShim::SendPictures() { + DCHECK(RenderThreadImpl::current()); + DCHECK(host_); + while (!pending_frames_.empty() && !available_textures_.empty()) { + const linked_ptr<PendingFrame>& frame = pending_frames_.front(); + + TextureIdSet::iterator it = available_textures_.begin(); + uint32_t texture_id = *it; + available_textures_.erase(it); + + uint32_t local_texture_id = texture_id_map_[texture_id]; + gpu::gles2::GLES2Interface* gles2 = context_provider_->ContextGL(); + gles2->ActiveTexture(GL_TEXTURE0); + gles2->BindTexture(GL_TEXTURE_2D, local_texture_id); + gles2->TexImage2D(GL_TEXTURE_2D, + 0, + GL_RGBA, + texture_size_.width(), + texture_size_.height(), + 0, + GL_RGBA, + GL_UNSIGNED_BYTE, + &frame->argb_pixels.front()); + + host_->PictureReady(media::Picture(texture_id, frame->decode_id)); + pending_frames_.pop(); + } + + FlushCommandBuffer(); + + if (pending_frames_.empty()) { + // If frames aren't backing up, notify the host of any completed decodes so + // it can send more buffers. + NotifyCompletedDecodes(); + + if (state_ == FLUSHING && !num_pending_decodes_) { + state_ = DECODING; + host_->NotifyFlushDone(); + } + } +} + +void VideoDecoderShim::OnResetComplete() { + DCHECK(RenderThreadImpl::current()); + DCHECK(host_); + + while (!pending_frames_.empty()) + pending_frames_.pop(); + NotifyCompletedDecodes(); + + // Dismiss any old textures now. + while (!textures_to_dismiss_.empty()) + DismissTexture(*textures_to_dismiss_.begin()); + + state_ = DECODING; + host_->NotifyResetDone(); +} + +void VideoDecoderShim::NotifyCompletedDecodes() { + while (!completed_decodes_.empty()) { + host_->NotifyEndOfBitstreamBuffer(completed_decodes_.front()); + completed_decodes_.pop(); + } +} + +void VideoDecoderShim::DismissTexture(uint32_t texture_id) { + DCHECK(host_); + textures_to_dismiss_.erase(texture_id); + DCHECK(texture_id_map_.find(texture_id) != texture_id_map_.end()); + DeleteTexture(texture_id_map_[texture_id]); + texture_id_map_.erase(texture_id); + host_->DismissPictureBuffer(texture_id); +} + +void VideoDecoderShim::DeleteTexture(uint32_t texture_id) { + gpu::gles2::GLES2Interface* gles2 = context_provider_->ContextGL(); + gles2->DeleteTextures(1, &texture_id); +} + +void VideoDecoderShim::FlushCommandBuffer() { + context_provider_->ContextGL()->Flush(); +} + +} // namespace content diff --git a/chromium/content/renderer/pepper/video_decoder_shim.h b/chromium/content/renderer/pepper/video_decoder_shim.h new file mode 100644 index 00000000000..aa33a7485f5 --- /dev/null +++ b/chromium/content/renderer/pepper/video_decoder_shim.h @@ -0,0 +1,129 @@ +// Copyright 2014 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 CONTENT_RENDERER_PEPPER_VIDEO_DECODER_SHIM_H_ +#define CONTENT_RENDERER_PEPPER_VIDEO_DECODER_SHIM_H_ + +#include <queue> +#include <vector> + +#include "base/basictypes.h" +#include "base/containers/hash_tables.h" +#include "base/memory/linked_ptr.h" +#include "base/memory/scoped_ptr.h" +#include "base/memory/weak_ptr.h" +#include "base/message_loop/message_loop_proxy.h" +#include "gpu/command_buffer/common/mailbox.h" +#include "media/base/video_decoder_config.h" +#include "media/video/video_decode_accelerator.h" + +#include "ppapi/c/pp_codecs.h" + +namespace gpu { +namespace gles2 { +class GLES2Interface; +} +} + +namespace media { +class DecoderBuffer; +} + +namespace webkit { +namespace gpu { +class ContextProviderWebContext; +} +} + +namespace content { + +class PepperVideoDecoderHost; + +// This class is a shim to wrap a media::VideoDecoder so that it can be used +// by PepperVideoDecoderHost in place of a media::VideoDecodeAccelerator. +// This class should be constructed, used, and destructed on the main (render) +// thread. +class VideoDecoderShim : public media::VideoDecodeAccelerator { + public: + explicit VideoDecoderShim(PepperVideoDecoderHost* host); + virtual ~VideoDecoderShim(); + + // media::VideoDecodeAccelerator implementation. + virtual bool Initialize( + media::VideoCodecProfile profile, + media::VideoDecodeAccelerator::Client* client) OVERRIDE; + virtual void Decode(const media::BitstreamBuffer& bitstream_buffer) OVERRIDE; + virtual void AssignPictureBuffers( + const std::vector<media::PictureBuffer>& buffers) OVERRIDE; + virtual void ReusePictureBuffer(int32 picture_buffer_id) OVERRIDE; + virtual void Flush() OVERRIDE; + virtual void Reset() OVERRIDE; + virtual void Destroy() OVERRIDE; + + private: + enum State { + UNINITIALIZED, + DECODING, + FLUSHING, + RESETTING, + }; + + struct PendingDecode; + struct PendingFrame; + class DecoderImpl; + + void OnInitializeComplete(int32_t result, uint32_t texture_pool_size); + void OnDecodeComplete(int32_t result, uint32_t decode_id); + void OnOutputComplete(scoped_ptr<PendingFrame> frame); + void SendPictures(); + void OnResetComplete(); + void NotifyCompletedDecodes(); + void DismissTexture(uint32_t texture_id); + void DeleteTexture(uint32_t texture_id); + // Call this whenever we change GL state that the plugin relies on, such as + // creating picture textures. + void FlushCommandBuffer(); + + scoped_ptr<DecoderImpl> decoder_impl_; + State state_; + + PepperVideoDecoderHost* host_; + scoped_refptr<base::MessageLoopProxy> media_message_loop_; + scoped_refptr<webkit::gpu::ContextProviderWebContext> context_provider_; + + // The current decoded frame size. + gfx::Size texture_size_; + // Map that takes the plugin's GL texture id to the renderer's GL texture id. + typedef base::hash_map<uint32_t, uint32_t> TextureIdMap; + TextureIdMap texture_id_map_; + // Available textures (these are plugin ids.) + typedef base::hash_set<uint32_t> TextureIdSet; + TextureIdSet available_textures_; + // Track textures that are no longer needed (these are plugin ids.) + TextureIdSet textures_to_dismiss_; + // Mailboxes for pending texture requests, to write to plugin's textures. + std::vector<gpu::Mailbox> pending_texture_mailboxes_; + + // Queue of completed decode ids, for notifying the host. + typedef std::queue<uint32_t> CompletedDecodeQueue; + CompletedDecodeQueue completed_decodes_; + + // Queue of decoded frames that have been converted to RGB and await upload to + // a GL texture. + typedef std::queue<linked_ptr<PendingFrame> > PendingFrameQueue; + PendingFrameQueue pending_frames_; + + // The optimal number of textures to allocate for decoder_impl_. + uint32_t texture_pool_size_; + + uint32_t num_pending_decodes_; + + base::WeakPtrFactory<VideoDecoderShim> weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(VideoDecoderShim); +}; + +} // namespace content + +#endif // CONTENT_RENDERER_PEPPER_VIDEO_DECODER_SHIM_H_ |