diff options
author | sergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-07-20 01:49:27 +0000 |
---|---|---|
committer | sergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-07-20 01:49:27 +0000 |
commit | 0397dea43ea8a08e496971c80795970db5ad0644 (patch) | |
tree | 1a9b7d2331e7b4e44330954c6b54c1fa4d5578a4 /remoting/client | |
parent | a971e180d64cf2575bfbc8f092c2674f735c3754 (diff) | |
download | chromium_src-0397dea43ea8a08e496971c80795970db5ad0644.zip chromium_src-0397dea43ea8a08e496971c80795970db5ad0644.tar.gz chromium_src-0397dea43ea8a08e496971c80795970db5ad0644.tar.bz2 |
Revert 147595 - Rename ChromotingView to ClientUserInterface. Clean it up.
ChromotingView wasn't really doing what it was initially meant to do,
now FrameProducer and FrameConsumer interfaces are used to process video
stream. Renamed and simplified that interface. Also moved implementation
from PepperView to ChromotingInstance.
Review URL: https://chromiumcodereview.appspot.com/10703144
TBR=sergeyu@chromium.org
Review URL: https://chromiumcodereview.appspot.com/10800048
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@147596 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'remoting/client')
-rw-r--r-- | remoting/client/chromoting_client.cc | 16 | ||||
-rw-r--r-- | remoting/client/chromoting_client.h | 6 | ||||
-rw-r--r-- | remoting/client/chromoting_view.h (renamed from remoting/client/client_user_interface.h) | 28 | ||||
-rw-r--r-- | remoting/client/plugin/chromoting_instance.cc | 190 | ||||
-rw-r--r-- | remoting/client/plugin/chromoting_instance.h | 45 | ||||
-rw-r--r-- | remoting/client/plugin/pepper_view.cc | 101 | ||||
-rw-r--r-- | remoting/client/plugin/pepper_view.h | 13 |
7 files changed, 251 insertions, 148 deletions
diff --git a/remoting/client/chromoting_client.cc b/remoting/client/chromoting_client.cc index e77c53a..9d9df67 100644 --- a/remoting/client/chromoting_client.cc +++ b/remoting/client/chromoting_client.cc @@ -6,8 +6,8 @@ #include "base/bind.h" #include "remoting/client/audio_player.h" +#include "remoting/client/chromoting_view.h" #include "remoting/client/client_context.h" -#include "remoting/client/client_user_interface.h" #include "remoting/client/rectangle_update_decoder.h" #include "remoting/proto/audio.pb.h" #include "remoting/proto/video.pb.h" @@ -33,13 +33,13 @@ ChromotingClient::ChromotingClient( const ClientConfig& config, scoped_refptr<base::SingleThreadTaskRunner> task_runner, protocol::ConnectionToHost* connection, - ClientUserInterface* user_interface, + ChromotingView* view, RectangleUpdateDecoder* rectangle_decoder, AudioPlayer* audio_player) : config_(config), task_runner_(task_runner), connection_(connection), - user_interface_(user_interface), + view_(view), rectangle_decoder_(rectangle_decoder), audio_player_(audio_player), packet_being_processed_(false), @@ -66,6 +66,8 @@ void ChromotingClient::Start( connection_->Connect(xmpp_proxy, config_.local_jid, config_.host_jid, config_.host_public_key, transport_factory.Pass(), authenticator.Pass(), this, this, this, this, this); + + view_->Initialize(); } void ChromotingClient::Stop(const base::Closure& shutdown_task) { @@ -83,6 +85,8 @@ void ChromotingClient::Stop(const base::Closure& shutdown_task) { } void ChromotingClient::OnDisconnected(const base::Closure& shutdown_task) { + view_->TearDown(); + shutdown_task.Run(); } @@ -94,12 +98,12 @@ ChromotingStats* ChromotingClient::GetStats() { void ChromotingClient::InjectClipboardEvent( const protocol::ClipboardEvent& event) { DCHECK(task_runner_->BelongsToCurrentThread()); - user_interface_->GetClipboardStub()->InjectClipboardEvent(event); + view_->GetClipboardStub()->InjectClipboardEvent(event); } void ChromotingClient::SetCursorShape( const protocol::CursorShapeInfo& cursor_shape) { - user_interface_->GetCursorShapeStub()->SetCursorShape(cursor_shape); + view_->GetCursorShapeStub()->SetCursorShape(cursor_shape); } void ChromotingClient::ProcessVideoPacket(scoped_ptr<VideoPacket> packet, @@ -181,7 +185,7 @@ void ChromotingClient::OnConnectionState( VLOG(1) << "ChromotingClient::OnConnectionState(" << state << ")"; if (state == protocol::ConnectionToHost::CONNECTED) Initialize(); - user_interface_->OnConnectionState(state, error); + view_->SetConnectionState(state, error); } void ChromotingClient::OnPacketDone(bool last_packet, diff --git a/remoting/client/chromoting_client.h b/remoting/client/chromoting_client.h index d68ae3b..d15073f 100644 --- a/remoting/client/chromoting_client.h +++ b/remoting/client/chromoting_client.h @@ -15,6 +15,7 @@ #include "base/time.h" #include "remoting/client/client_config.h" #include "remoting/client/chromoting_stats.h" +#include "remoting/client/chromoting_view.h" #include "remoting/protocol/audio_stub.h" #include "remoting/protocol/client_stub.h" #include "remoting/protocol/clipboard_stub.h" @@ -34,7 +35,6 @@ class TransportFactory; } // namespace protocol class AudioPlayer; -class ClientUserInterface; class RectangleUpdateDecoder; // TODO(sergeyu): Move VideoStub implementation to RectangleUpdateDecoder. @@ -47,7 +47,7 @@ class ChromotingClient : public protocol::ConnectionToHost::HostEventCallback, ChromotingClient(const ClientConfig& config, scoped_refptr<base::SingleThreadTaskRunner> task_runner, protocol::ConnectionToHost* connection, - ClientUserInterface* user_interface, + ChromotingView* view, RectangleUpdateDecoder* rectangle_decoder, AudioPlayer* audio_player); @@ -110,7 +110,7 @@ class ChromotingClient : public protocol::ConnectionToHost::HostEventCallback, ClientConfig config_; scoped_refptr<base::SingleThreadTaskRunner> task_runner_; protocol::ConnectionToHost* connection_; - ClientUserInterface* user_interface_; + ChromotingView* view_; RectangleUpdateDecoder* rectangle_decoder_; AudioPlayer* audio_player_; diff --git a/remoting/client/client_user_interface.h b/remoting/client/chromoting_view.h index e6498fb..1035d3c 100644 --- a/remoting/client/client_user_interface.h +++ b/remoting/client/chromoting_view.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef REMOTING_CLIENT_CLIENT_USER_INTERFACE_H_ -#define REMOTING_CLIENT_CLIENT_USER_INTERFACE_H_ +#ifndef REMOTING_CLIENT_CHROMOTING_VIEW_H_ +#define REMOTING_CLIENT_CHROMOTING_VIEW_H_ #include "base/basictypes.h" #include "remoting/protocol/connection_to_host.h" @@ -15,18 +15,22 @@ class ClipboardStub; class CursorShapeStub; } // namespace protocol -// ClientUserInterface is an interface that must be implemented by -// applications embedding the Chromoting client, to provide client's user -// interface. -// -// TODO(sergeyu): Cleanup this interface, see crbug.com/138108 . -class ClientUserInterface { +// ChromotingView defines the behavior of an object that draws a view of the +// remote desktop. Its main function is to render the update stream onto the +// screen. +class ChromotingView { public: - virtual ~ClientUserInterface() {} + virtual ~ChromotingView() {} + + // Initialize the common structures for the view. + virtual bool Initialize() = 0; + + // Free up resources allocated by this view. + virtual void TearDown() = 0; // Record the update the state of the connection, updating the UI as needed. - virtual void OnConnectionState(protocol::ConnectionToHost::State state, - protocol::ErrorCode error) = 0; + virtual void SetConnectionState(protocol::ConnectionToHost::State state, + protocol::ErrorCode error) = 0; // Get the view's ClipboardStub implementation. virtual protocol::ClipboardStub* GetClipboardStub() = 0; @@ -37,4 +41,4 @@ class ClientUserInterface { } // namespace remoting -#endif // REMOTING_CLIENT_CLIENT_USER_INTERFACE_H_ +#endif // REMOTING_CLIENT_CHROMOTING_VIEW_H_ diff --git a/remoting/client/plugin/chromoting_instance.cc b/remoting/client/plugin/chromoting_instance.cc index a067357..77cd55f 100644 --- a/remoting/client/plugin/chromoting_instance.cc +++ b/remoting/client/plugin/chromoting_instance.cc @@ -57,57 +57,40 @@ const int kBytesPerPixel = 4; const int kPerfStatsIntervalMs = 1000; -std::string ConnectionStateToString(protocol::ConnectionToHost::State state) { - // Values returned by this function must match the - // remoting.ClientSession.State enum in JS code. +std::string ConnectionStateToString(ChromotingInstance::ConnectionState state) { switch (state) { - case protocol::ConnectionToHost::INITIALIZING: - return "INITIALIZING"; - case protocol::ConnectionToHost::CONNECTING: + case ChromotingInstance::STATE_CONNECTING: return "CONNECTING"; - case protocol::ConnectionToHost::CONNECTED: + case ChromotingInstance::STATE_INITIALIZING: + return "INITIALIZING"; + case ChromotingInstance::STATE_CONNECTED: return "CONNECTED"; - case protocol::ConnectionToHost::CLOSED: + case ChromotingInstance::STATE_CLOSED: return "CLOSED"; - case protocol::ConnectionToHost::FAILED: + case ChromotingInstance::STATE_FAILED: return "FAILED"; } NOTREACHED(); return ""; } -// TODO(sergeyu): Ideally we should just pass ErrorCode to the webapp -// and let it handle it, but it would be hard to fix it now because -// client plugin and webapp versions may not be in sync. It should be -// easy to do after we are finished moving the client plugin to NaCl. -std::string ConnectionErrorToString(protocol::ErrorCode error) { - // Values returned by this function must match the - // remoting.ClientSession.Error enum in JS code. +std::string ConnectionErrorToString(ChromotingInstance::ConnectionError error) { switch (error) { - case protocol::OK: + case ChromotingInstance::ERROR_NONE: return "NONE"; - - case protocol::PEER_IS_OFFLINE: + case ChromotingInstance::ERROR_HOST_IS_OFFLINE: return "HOST_IS_OFFLINE"; - - case protocol::SESSION_REJECTED: - case protocol::AUTHENTICATION_FAILED: + case ChromotingInstance::ERROR_SESSION_REJECTED: return "SESSION_REJECTED"; - - case protocol::INCOMPATIBLE_PROTOCOL: + case ChromotingInstance::ERROR_INCOMPATIBLE_PROTOCOL: return "INCOMPATIBLE_PROTOCOL"; - - case protocol::HOST_OVERLOAD: - return "HOST_OVERLOAD"; - - case protocol::CHANNEL_CONNECTION_ERROR: - case protocol::SIGNALING_ERROR: - case protocol::SIGNALING_TIMEOUT: - case protocol::UNKNOWN_ERROR: + case ChromotingInstance::ERROR_NETWORK_FAILURE: return "NETWORK_FAILURE"; + case ChromotingInstance::ERROR_HOST_OVERLOAD: + return "HOST_OVERLOAD"; } - DLOG(FATAL) << "Unknown error code" << error; - return ""; + NOTREACHED(); + return ""; } // This flag blocks LOGs to the UI if we're already in the middle of logging @@ -177,9 +160,6 @@ ChromotingInstance::~ChromotingInstance() { // to it. This will stop all logging in all Chromoting instances. UnregisterLoggingInstance(); - // PepperView must be destroyed before the client. - view_.reset(); - if (client_.get()) { base::WaitableEvent done_event(true, false); client_->Stop(base::Bind(&base::WaitableEvent::Signal, @@ -379,81 +359,15 @@ void ChromotingInstance::SetDesktopSize(int width, int height) { PostChromotingMessage("onDesktopSize", data.Pass()); } -void ChromotingInstance::OnConnectionState( - protocol::ConnectionToHost::State state, - protocol::ErrorCode error) { +void ChromotingInstance::SetConnectionState( + ConnectionState state, + ConnectionError error) { scoped_ptr<base::DictionaryValue> data(new base::DictionaryValue()); data->SetString("state", ConnectionStateToString(state)); data->SetString("error", ConnectionErrorToString(error)); PostChromotingMessage("onConnectionStatus", data.Pass()); } -protocol::ClipboardStub* ChromotingInstance::GetClipboardStub() { - // TODO(sergeyu): Move clipboard handling to a separate class. - // crbug.com/138108 - return this; -} - -protocol::CursorShapeStub* ChromotingInstance::GetCursorShapeStub() { - // TODO(sergeyu): Move cursor shape code to a separate class. - // crbug.com/138108 - return this; -} - -void ChromotingInstance::InjectClipboardEvent( - const protocol::ClipboardEvent& event) { - scoped_ptr<base::DictionaryValue> data(new base::DictionaryValue()); - data->SetString("mimeType", event.mime_type()); - data->SetString("item", event.data()); - PostChromotingMessage("injectClipboardItem", data.Pass()); -} - -void ChromotingInstance::SetCursorShape( - const protocol::CursorShapeInfo& cursor_shape) { - if (!cursor_shape.has_data() || - !cursor_shape.has_width() || - !cursor_shape.has_height() || - !cursor_shape.has_hotspot_x() || - !cursor_shape.has_hotspot_y()) { - return; - } - - if (pp::ImageData::GetNativeImageDataFormat() != - PP_IMAGEDATAFORMAT_BGRA_PREMUL) { - VLOG(2) << "Unable to set cursor shape - non-native image format"; - return; - } - - int width = cursor_shape.width(); - int height = cursor_shape.height(); - - if (width > 32 || height > 32) { - VLOG(2) << "Cursor too large for SetCursor: " - << width << "x" << height << " > 32x32"; - return; - } - - int hotspot_x = cursor_shape.hotspot_x(); - int hotspot_y = cursor_shape.hotspot_y(); - - pp::ImageData cursor_image(this, PP_IMAGEDATAFORMAT_BGRA_PREMUL, - pp::Size(width, height), false); - - int bytes_per_row = width * kBytesPerPixel; - const uint8* src_row_data = reinterpret_cast<const uint8*>( - cursor_shape.data().data()); - uint8* dst_row_data = reinterpret_cast<uint8*>(cursor_image.data()); - for (int row = 0; row < height; row++) { - memcpy(dst_row_data, src_row_data, bytes_per_row); - src_row_data += bytes_per_row; - dst_row_data += cursor_image.stride(); - } - - pp::MouseCursor::SetCursor(this, PP_MOUSECURSOR_TYPE_CUSTOM, - cursor_image, - pp::Point(hotspot_x, hotspot_y)); -} - void ChromotingInstance::OnFirstFrameReceived() { scoped_ptr<base::DictionaryValue> data(new base::DictionaryValue()); PostChromotingMessage("onFirstFrameReceived", data.Pass()); @@ -466,7 +380,7 @@ void ChromotingInstance::Connect(const ClientConfig& config) { host_connection_.reset(new protocol::ConnectionToHost(true)); client_.reset(new ChromotingClient(config, context_.main_task_runner(), - host_connection_.get(), this, + host_connection_.get(), view_.get(), rectangle_decoder_.get(), audio_player_.get())); @@ -509,14 +423,14 @@ void ChromotingInstance::Connect(const ClientConfig& config) { plugin_message_loop_->PostDelayedTask( FROM_HERE, base::Bind(&ChromotingInstance::SendPerfStats, AsWeakPtr()), base::TimeDelta::FromMilliseconds(kPerfStatsIntervalMs)); + + VLOG(1) << "Connection status: Initializing"; + SetConnectionState(STATE_INITIALIZING, ERROR_NONE); } void ChromotingInstance::Disconnect() { DCHECK(plugin_message_loop_->BelongsToCurrentThread()); - // PepperView must be destroyed before the client. - view_.reset(); - LOG(INFO) << "Disconnecting from host."; if (client_.get()) { // TODO(sergeyu): Should we disconnect asynchronously? @@ -531,6 +445,8 @@ void ChromotingInstance::Disconnect() { input_tracker_.reset(); mouse_input_filter_.reset(); host_connection_.reset(); + + SetConnectionState(STATE_CLOSED, ERROR_NONE); } void ChromotingInstance::OnIncomingIq(const std::string& iq) { @@ -639,6 +555,60 @@ void ChromotingInstance::SendPerfStats() { PostChromotingMessage("onPerfStats", data.Pass()); } +void ChromotingInstance::InjectClipboardEvent( + const protocol::ClipboardEvent& event) { + scoped_ptr<base::DictionaryValue> data(new base::DictionaryValue()); + data->SetString("mimeType", event.mime_type()); + data->SetString("item", event.data()); + PostChromotingMessage("injectClipboardItem", data.Pass()); +} + +void ChromotingInstance::SetCursorShape( + const protocol::CursorShapeInfo& cursor_shape) { + if (!cursor_shape.has_data() || + !cursor_shape.has_width() || + !cursor_shape.has_height() || + !cursor_shape.has_hotspot_x() || + !cursor_shape.has_hotspot_y()) { + return; + } + + if (pp::ImageData::GetNativeImageDataFormat() != + PP_IMAGEDATAFORMAT_BGRA_PREMUL) { + VLOG(2) << "Unable to set cursor shape - non-native image format"; + return; + } + + int width = cursor_shape.width(); + int height = cursor_shape.height(); + + if (width > 32 || height > 32) { + VLOG(2) << "Cursor too large for SetCursor: " + << width << "x" << height << " > 32x32"; + return; + } + + int hotspot_x = cursor_shape.hotspot_x(); + int hotspot_y = cursor_shape.hotspot_y(); + + pp::ImageData cursor_image(this, PP_IMAGEDATAFORMAT_BGRA_PREMUL, + pp::Size(width, height), false); + + int bytes_per_row = width * kBytesPerPixel; + const uint8* src_row_data = reinterpret_cast<const uint8*>( + cursor_shape.data().data()); + uint8* dst_row_data = reinterpret_cast<uint8*>(cursor_image.data()); + for (int row = 0; row < height; row++) { + memcpy(dst_row_data, src_row_data, bytes_per_row); + src_row_data += bytes_per_row; + dst_row_data += cursor_image.stride(); + } + + pp::MouseCursor::SetCursor(this, PP_MOUSECURSOR_TYPE_CUSTOM, + cursor_image, + pp::Point(hotspot_x, hotspot_y)); +} + // static void ChromotingInstance::RegisterLogMessageHandler() { base::AutoLock lock(g_logging_lock.Get()); diff --git a/remoting/client/plugin/chromoting_instance.h b/remoting/client/plugin/chromoting_instance.h index ff267bf..dbc840d 100644 --- a/remoting/client/plugin/chromoting_instance.h +++ b/remoting/client/plugin/chromoting_instance.h @@ -26,14 +26,13 @@ #include "ppapi/cpp/instance.h" #include "remoting/client/client_context.h" -#include "remoting/client/client_user_interface.h" #include "remoting/client/key_event_mapper.h" #include "remoting/client/plugin/mac_key_event_processor.h" #include "remoting/client/plugin/pepper_plugin_thread_delegate.h" #include "remoting/proto/event.pb.h" #include "remoting/protocol/clipboard_stub.h" -#include "remoting/protocol/connection_to_host.h" #include "remoting/protocol/cursor_shape_stub.h" +#include "remoting/protocol/connection_to_host.h" namespace base { class DictionaryValue; @@ -47,6 +46,7 @@ class Module; namespace remoting { namespace protocol { +class ConnectionToHost; class InputEventTracker; class MouseInputFilter; } // namespace protocol @@ -64,12 +64,32 @@ class RectangleUpdateDecoder; struct ClientConfig; class ChromotingInstance : - public ClientUserInterface, public protocol::ClipboardStub, public protocol::CursorShapeStub, public pp::Instance, public base::SupportsWeakPtr<ChromotingInstance> { public: + // These state values are duplicated in the JS code. Remember to + // update both copies when making changes. + enum ConnectionState { + STATE_CONNECTING = 1, + STATE_INITIALIZING, + STATE_CONNECTED, + STATE_CLOSED, + STATE_FAILED, + }; + + // These values are duplicated in the JS code. Remember to update + // both copies when making changes. + enum ConnectionError { + ERROR_NONE = 0, + ERROR_HOST_IS_OFFLINE, + ERROR_SESSION_REJECTED, + ERROR_INCOMPATIBLE_PROTOCOL, + ERROR_NETWORK_FAILURE, + ERROR_HOST_OVERLOAD, + }; + // Plugin API version. This should be incremented whenever the API // interface changes. static const int kApiVersion = 7; @@ -103,22 +123,17 @@ class ChromotingInstance : virtual void HandleMessage(const pp::Var& message) OVERRIDE; virtual bool HandleInputEvent(const pp::InputEvent& event) OVERRIDE; - // ClientUserInterface interface. - virtual void OnConnectionState(protocol::ConnectionToHost::State state, - protocol::ErrorCode error) OVERRIDE; - virtual protocol::ClipboardStub* GetClipboardStub() OVERRIDE; - virtual protocol::CursorShapeStub* GetCursorShapeStub() OVERRIDE; - - // protocol::ClipboardStub interface. - virtual void InjectClipboardEvent( - const protocol::ClipboardEvent& event) OVERRIDE; + // ClipboardStub implementation. + virtual void InjectClipboardEvent(const protocol::ClipboardEvent& event) + OVERRIDE; - // protocol::CursorShapeStub interface. - virtual void SetCursorShape( - const protocol::CursorShapeInfo& cursor_shape) OVERRIDE; + // CursorShapeStub implementation. + virtual void SetCursorShape(const protocol::CursorShapeInfo& cursor_shape) + OVERRIDE; // Called by PepperView. void SetDesktopSize(int width, int height); + void SetConnectionState(ConnectionState state, ConnectionError error); void OnFirstFrameReceived(); // Message handlers for messages that come from JavaScript. Called diff --git a/remoting/client/plugin/pepper_view.cc b/remoting/client/plugin/pepper_view.cc index a7f00a3..35976e4 100644 --- a/remoting/client/plugin/pepper_view.cc +++ b/remoting/client/plugin/pepper_view.cc @@ -31,6 +31,39 @@ namespace { // The maximum number of image buffers to be allocated at any point of time. const size_t kMaxPendingBuffersCount = 2; +// TODO(sergeyu): Ideally we should just pass ErrorCode to the webapp +// and let it handle it, but it would be hard to fix it now because +// client plugin and webapp versions may not be in sync. It should be +// easy to do after we are finished moving the client plugin to NaCl. +ChromotingInstance::ConnectionError ConvertConnectionError( + protocol::ErrorCode error) { + switch (error) { + case protocol::OK: + return ChromotingInstance::ERROR_NONE; + + case protocol::PEER_IS_OFFLINE: + return ChromotingInstance::ERROR_HOST_IS_OFFLINE; + + case protocol::SESSION_REJECTED: + case protocol::AUTHENTICATION_FAILED: + return ChromotingInstance::ERROR_SESSION_REJECTED; + + case protocol::INCOMPATIBLE_PROTOCOL: + return ChromotingInstance::ERROR_INCOMPATIBLE_PROTOCOL; + + case protocol::HOST_OVERLOAD: + return ChromotingInstance::ERROR_HOST_OVERLOAD; + + case protocol::CHANNEL_CONNECTION_ERROR: + case protocol::SIGNALING_ERROR: + case protocol::SIGNALING_TIMEOUT: + case protocol::UNKNOWN_ERROR: + return ChromotingInstance::ERROR_NETWORK_FAILURE; + } + DLOG(FATAL) << "Unknown error code" << error; + return ChromotingInstance::ERROR_NONE; +} + } // namespace PepperView::PepperView(ChromotingInstance* instance, @@ -45,11 +78,29 @@ PepperView::PepperView(ChromotingInstance* instance, clip_area_(SkIRect::MakeEmpty()), source_size_(SkISize::Make(0, 0)), flush_pending_(false), + is_initialized_(false), frame_received_(false) { - InitiateDrawing(); } PepperView::~PepperView() { + DCHECK(merge_buffer_ == NULL); + DCHECK(buffers_.empty()); +} + +bool PepperView::Initialize() { + DCHECK(!is_initialized_); + + is_initialized_ = true; + InitiateDrawing(); + return true; +} + +void PepperView::TearDown() { + DCHECK(context_->main_task_runner()->BelongsToCurrentThread()); + DCHECK(is_initialized_); + + is_initialized_ = false; + // The producer should now return any pending buffers. At this point, however, // ReturnBuffer() tasks scheduled by the producer will not be delivered, // so we free all the buffers once the producer's queue is empty. @@ -64,6 +115,45 @@ PepperView::~PepperView() { } } +void PepperView::SetConnectionState(protocol::ConnectionToHost::State state, + protocol::ErrorCode error) { + DCHECK(context_->main_task_runner()->BelongsToCurrentThread()); + + switch (state) { + case protocol::ConnectionToHost::CONNECTING: + instance_->SetConnectionState( + ChromotingInstance::STATE_CONNECTING, + ConvertConnectionError(error)); + break; + + case protocol::ConnectionToHost::CONNECTED: + instance_->SetConnectionState( + ChromotingInstance::STATE_CONNECTED, + ConvertConnectionError(error)); + break; + + case protocol::ConnectionToHost::CLOSED: + instance_->SetConnectionState( + ChromotingInstance::STATE_CLOSED, + ConvertConnectionError(error)); + break; + + case protocol::ConnectionToHost::FAILED: + instance_->SetConnectionState( + ChromotingInstance::STATE_FAILED, + ConvertConnectionError(error)); + break; + } +} + +protocol::ClipboardStub* PepperView::GetClipboardStub() { + return instance_; +} + +protocol::CursorShapeStub* PepperView::GetCursorShapeStub() { + return instance_; +} + void PepperView::SetView(const SkISize& view_size, const SkIRect& clip_area) { bool view_changed = false; @@ -120,6 +210,12 @@ void PepperView::ApplyBuffer(const SkISize& view_size, void PepperView::ReturnBuffer(pp::ImageData* buffer) { DCHECK(context_->main_task_runner()->BelongsToCurrentThread()); + // Free the buffer if there is nothing to paint. + if (!is_initialized_) { + FreeBuffer(buffer); + return; + } + // Reuse the buffer if it is large enough, otherwise drop it on the floor // and allocate a new one. if (buffer->size().width() >= clip_area_.width() && @@ -172,6 +268,9 @@ void PepperView::FreeBuffer(pp::ImageData* buffer) { } void PepperView::InitiateDrawing() { + if (!is_initialized_) + return; + pp::ImageData* buffer = AllocateBuffer(); while (buffer) { producer_->DrawBuffer(buffer); diff --git a/remoting/client/plugin/pepper_view.h b/remoting/client/plugin/pepper_view.h index 58eccb3..949703a 100644 --- a/remoting/client/plugin/pepper_view.h +++ b/remoting/client/plugin/pepper_view.h @@ -13,6 +13,7 @@ #include "base/memory/weak_ptr.h" #include "ppapi/cpp/graphics_2d.h" #include "ppapi/cpp/point.h" +#include "remoting/client/chromoting_view.h" #include "remoting/client/frame_consumer.h" namespace remoting { @@ -21,7 +22,8 @@ class ChromotingInstance; class ClientContext; class FrameProducer; -class PepperView : public FrameConsumer, +class PepperView : public ChromotingView, + public FrameConsumer, public base::SupportsWeakPtr<PepperView> { public: // Constructs a PepperView for the |instance|. The |instance|, |context| @@ -31,6 +33,15 @@ class PepperView : public FrameConsumer, FrameProducer* producer); virtual ~PepperView(); + // ChromotingView implementation. + virtual bool Initialize() OVERRIDE; + virtual void TearDown() OVERRIDE; + virtual void SetConnectionState( + protocol::ConnectionToHost::State state, + protocol::ErrorCode error) OVERRIDE; + virtual protocol::ClipboardStub* GetClipboardStub() OVERRIDE; + virtual protocol::CursorShapeStub* GetCursorShapeStub() OVERRIDE; + // FrameConsumer implementation. virtual void ApplyBuffer(const SkISize& view_size, const SkIRect& clip_area, |