1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef REMOTING_CLIENT_PLUGIN_CHROMOTING_INSTANCE_H_ 6 #define REMOTING_CLIENT_PLUGIN_CHROMOTING_INSTANCE_H_ 7 8 #include <string> 9 10 #include "base/gtest_prod_util.h" 11 #include "base/memory/scoped_ptr.h" 12 #include "base/memory/weak_ptr.h" 13 #include "base/thread_task_runner_handle.h" 14 #include "ppapi/c/pp_instance.h" 15 #include "ppapi/c/pp_rect.h" 16 #include "ppapi/c/pp_resource.h" 17 #include "ppapi/cpp/instance.h" 18 #include "ppapi/cpp/var.h" 19 #include "remoting/client/client_context.h" 20 #include "remoting/client/client_user_interface.h" 21 #include "remoting/client/key_event_mapper.h" 22 #include "remoting/client/plugin/media_source_video_renderer.h" 23 #include "remoting/client/plugin/pepper_input_handler.h" 24 #include "remoting/client/plugin/pepper_plugin_thread_delegate.h" 25 #include "remoting/proto/event.pb.h" 26 #include "remoting/protocol/client_stub.h" 27 #include "remoting/protocol/clipboard_stub.h" 28 #include "remoting/protocol/connection_to_host.h" 29 #include "remoting/protocol/cursor_shape_stub.h" 30 #include "remoting/protocol/input_event_tracker.h" 31 #include "remoting/protocol/mouse_input_filter.h" 32 #include "remoting/protocol/negotiating_client_authenticator.h" 33 #include "remoting/protocol/third_party_client_authenticator.h" 34 35 namespace base { 36 class DictionaryValue; 37 } // namespace base 38 39 namespace pp { 40 class InputEvent; 41 class Module; 42 class VarDictionary; 43 } // namespace pp 44 45 namespace jingle_glue { 46 class JingleThreadWrapper; 47 } // namespace jingle_glue 48 49 namespace webrtc { 50 class DesktopRegion; 51 class DesktopSize; 52 class DesktopVector; 53 } // namespace webrtc 54 55 namespace remoting { 56 57 class ChromotingClient; 58 class ChromotingStats; 59 class ClientContext; 60 class DelegatingSignalStrategy; 61 class FrameConsumer; 62 class FrameConsumerProxy; 63 class PepperAudioPlayer; 64 class TokenFetcherProxy; 65 class PepperView; 66 class RectangleUpdateDecoder; 67 class SignalStrategy; 68 class VideoRenderer; 69 70 struct ClientConfig; 71 72 class ChromotingInstance : 73 public ClientUserInterface, 74 public MediaSourceVideoRenderer::Delegate, 75 public protocol::ClipboardStub, 76 public protocol::CursorShapeStub, 77 public pp::Instance { 78 public: 79 // Plugin API version. This should be incremented whenever the API 80 // interface changes. 81 static const int kApiVersion = 7; 82 83 // Plugin API features. This allows orthogonal features to be supported 84 // without bumping the API version. 85 static const char kApiFeatures[]; 86 87 // Capabilities supported by the plugin that should also be supported by the 88 // webapp to be enabled. 89 static const char kRequestedCapabilities[]; 90 91 // Capabilities supported by the plugin that do not need to be supported by 92 // the webapp to be enabled. 93 static const char kSupportedCapabilities[]; 94 95 // Backward-compatibility version used by for the messaging 96 // interface. Should be updated whenever we remove support for 97 // an older version of the API. 98 static const int kApiMinMessagingVersion = 5; 99 100 // Backward-compatibility version used by for the ScriptableObject 101 // interface. Should be updated whenever we remove support for 102 // an older version of the API. 103 static const int kApiMinScriptableVersion = 5; 104 105 // Helper method to parse authentication_methods parameter. 106 static bool ParseAuthMethods(const std::string& auth_methods, 107 ClientConfig* config); 108 109 explicit ChromotingInstance(PP_Instance instance); 110 virtual ~ChromotingInstance(); 111 112 // pp::Instance interface. 113 virtual void DidChangeFocus(bool has_focus) OVERRIDE; 114 virtual void DidChangeView(const pp::View& view) OVERRIDE; 115 virtual bool Init(uint32_t argc, const char* argn[], 116 const char* argv[]) OVERRIDE; 117 virtual void HandleMessage(const pp::Var& message) OVERRIDE; 118 virtual bool HandleInputEvent(const pp::InputEvent& event) OVERRIDE; 119 120 // ClientUserInterface interface. 121 virtual void OnConnectionState(protocol::ConnectionToHost::State state, 122 protocol::ErrorCode error) OVERRIDE; 123 virtual void OnConnectionReady(bool ready) OVERRIDE; 124 virtual void OnRouteChanged(const std::string& channel_name, 125 const protocol::TransportRoute& route) OVERRIDE; 126 virtual void SetCapabilities(const std::string& capabilities) OVERRIDE; 127 virtual void SetPairingResponse( 128 const protocol::PairingResponse& pairing_response) OVERRIDE; 129 virtual void DeliverHostMessage( 130 const protocol::ExtensionMessage& message) OVERRIDE; 131 virtual protocol::ClipboardStub* GetClipboardStub() OVERRIDE; 132 virtual protocol::CursorShapeStub* GetCursorShapeStub() OVERRIDE; 133 virtual scoped_ptr<protocol::ThirdPartyClientAuthenticator::TokenFetcher> 134 GetTokenFetcher(const std::string& host_public_key) OVERRIDE; 135 136 // protocol::ClipboardStub interface. 137 virtual void InjectClipboardEvent( 138 const protocol::ClipboardEvent& event) OVERRIDE; 139 140 // protocol::CursorShapeStub interface. 141 virtual void SetCursorShape( 142 const protocol::CursorShapeInfo& cursor_shape) OVERRIDE; 143 144 // Called by PepperView. 145 void SetDesktopSize(const webrtc::DesktopSize& size, 146 const webrtc::DesktopVector& dpi); 147 void SetDesktopShape(const webrtc::DesktopRegion& shape); 148 void OnFirstFrameReceived(); 149 150 // Return statistics record by ChromotingClient. 151 // If no connection is currently active then NULL will be returned. 152 ChromotingStats* GetStats(); 153 154 // Registers a global log message handler that redirects the log output to 155 // our plugin instance. 156 // This is called by the plugin's PPP_InitializeModule. 157 // Note that no logging will be processed unless a ChromotingInstance has been 158 // registered for logging (see RegisterLoggingInstance). 159 static void RegisterLogMessageHandler(); 160 161 // Registers this instance so it processes messages sent by the global log 162 // message handler. This overwrites any previously registered instance. 163 void RegisterLoggingInstance(); 164 165 // Unregisters this instance so that debug log messages will no longer be sent 166 // to it. If this instance is not the currently registered logging instance, 167 // then the currently registered instance will stay in effect. 168 void UnregisterLoggingInstance(); 169 170 // A Log Message Handler that is called after each LOG message has been 171 // processed. This must be of type LogMessageHandlerFunction defined in 172 // base/logging.h. 173 static bool LogToUI(int severity, const char* file, int line, 174 size_t message_start, const std::string& str); 175 176 // Requests the webapp to fetch a third-party token. 177 void FetchThirdPartyToken( 178 const GURL& token_url, 179 const std::string& host_public_key, 180 const std::string& scope, 181 const base::WeakPtr<TokenFetcherProxy> pepper_token_fetcher); 182 183 private: 184 FRIEND_TEST_ALL_PREFIXES(ChromotingInstanceTest, TestCaseSetup); 185 186 // Used as the |FetchSecretCallback| for IT2Me (or Me2Me from old webapps). 187 // Immediately calls |secret_fetched_callback| with |shared_secret|. 188 static void FetchSecretFromString( 189 const std::string& shared_secret, 190 bool pairing_supported, 191 const protocol::SecretFetchedCallback& secret_fetched_callback); 192 193 // Message handlers for messages that come from JavaScript. Called 194 // from HandleMessage(). 195 void HandleConnect(const base::DictionaryValue& data); 196 void HandleDisconnect(const base::DictionaryValue& data); 197 void HandleOnIncomingIq(const base::DictionaryValue& data); 198 void HandleReleaseAllKeys(const base::DictionaryValue& data); 199 void HandleInjectKeyEvent(const base::DictionaryValue& data); 200 void HandleRemapKey(const base::DictionaryValue& data); 201 void HandleTrapKey(const base::DictionaryValue& data); 202 void HandleSendClipboardItem(const base::DictionaryValue& data); 203 void HandleNotifyClientResolution(const base::DictionaryValue& data); 204 void HandlePauseVideo(const base::DictionaryValue& data); 205 void HandleVideoControl(const base::DictionaryValue& data); 206 void HandlePauseAudio(const base::DictionaryValue& data); 207 void HandleOnPinFetched(const base::DictionaryValue& data); 208 void HandleOnThirdPartyTokenFetched(const base::DictionaryValue& data); 209 void HandleRequestPairing(const base::DictionaryValue& data); 210 void HandleExtensionMessage(const base::DictionaryValue& data); 211 void HandleAllowMouseLockMessage(); 212 void HandleEnableMediaSourceRendering(); 213 void HandleSendMouseInputWhenUnfocused(); 214 void HandleDelegateLargeCursors(); 215 216 // Helper method called from Connect() to connect with parsed config. 217 void ConnectWithConfig(const ClientConfig& config, 218 const std::string& local_jid); 219 220 // Helper method to post messages to the webapp. 221 void PostChromotingMessage(const std::string& method, 222 const pp::VarDictionary& data); 223 224 // Same as above, but serializes messages to JSON before sending them. This 225 // method is used for backward compatibility with older version of the webapp 226 // that expect to received most messages formatted using JSON. 227 // 228 // TODO(sergeyu): When all current versions of the webapp support raw messages 229 // remove this method and use PostChromotingMessage() instead. 230 void PostLegacyJsonMessage(const std::string& method, 231 scoped_ptr<base::DictionaryValue> data); 232 233 // Posts trapped keys to the web-app to handle. 234 void SendTrappedKey(uint32 usb_keycode, bool pressed); 235 236 // Callback for DelegatingSignalStrategy. 237 void SendOutgoingIq(const std::string& iq); 238 239 void SendPerfStats(); 240 241 void ProcessLogToUI(const std::string& message); 242 243 // Returns true if the hosting content has the chrome-extension:// scheme. 244 bool IsCallerAppOrExtension(); 245 246 // Returns true if there is a ConnectionToHost and it is connected. 247 bool IsConnected(); 248 249 // Used as the |FetchSecretCallback| for Me2Me connections. 250 // Uses the PIN request dialog in the webapp to obtain the shared secret. 251 void FetchSecretFromDialog( 252 bool pairing_supported, 253 const protocol::SecretFetchedCallback& secret_fetched_callback); 254 255 // MediaSourceVideoRenderer::Delegate implementation. 256 virtual void OnMediaSourceSize(const webrtc::DesktopSize& size, 257 const webrtc::DesktopVector& dpi) OVERRIDE; 258 virtual void OnMediaSourceShape(const webrtc::DesktopRegion& shape) OVERRIDE; 259 virtual void OnMediaSourceReset(const std::string& format) OVERRIDE; 260 virtual void OnMediaSourceData(uint8_t* buffer, size_t buffer_size, 261 bool keyframe) OVERRIDE; 262 263 bool initialized_; 264 265 PepperPluginThreadDelegate plugin_thread_delegate_; 266 scoped_refptr<PluginThreadTaskRunner> plugin_task_runner_; 267 scoped_ptr<base::ThreadTaskRunnerHandle> thread_task_runner_handle_; 268 scoped_ptr<jingle_glue::JingleThreadWrapper> thread_wrapper_; 269 ClientContext context_; 270 scoped_ptr<VideoRenderer> video_renderer_; 271 scoped_ptr<PepperView> view_; 272 scoped_ptr<base::WeakPtrFactory<FrameConsumer> > view_weak_factory_; 273 pp::View plugin_view_; 274 275 // Contains the most-recently-reported desktop shape, if any. 276 scoped_ptr<webrtc::DesktopRegion> desktop_shape_; 277 278 scoped_ptr<DelegatingSignalStrategy> signal_strategy_; 279 280 scoped_ptr<protocol::ConnectionToHost> host_connection_; 281 scoped_ptr<ChromotingClient> client_; 282 283 // Input pipeline components, in reverse order of distance from input source. 284 protocol::MouseInputFilter mouse_input_filter_; 285 protocol::InputEventTracker input_tracker_; 286 KeyEventMapper key_mapper_; 287 scoped_ptr<protocol::InputFilter> normalizing_input_filter_; 288 PepperInputHandler input_handler_; 289 290 // PIN Fetcher. 291 bool use_async_pin_dialog_; 292 protocol::SecretFetchedCallback secret_fetched_callback_; 293 294 // Set to true if the webapp has requested to use MediaSource API for 295 // rendering. In that case all the encoded video will be passed to the 296 // webapp for decoding. 297 bool use_media_source_rendering_; 298 299 // Set to true if the web-app can handle large cursors. If false, then large 300 // cursors will be cropped to the maximum size supported by Pepper. 301 bool delegate_large_cursors_; 302 303 base::WeakPtr<TokenFetcherProxy> token_fetcher_proxy_; 304 305 // Weak reference to this instance, used for global logging and task posting. 306 base::WeakPtrFactory<ChromotingInstance> weak_factory_; 307 308 DISALLOW_COPY_AND_ASSIGN(ChromotingInstance); 309 }; 310 311 } // namespace remoting 312 313 #endif // REMOTING_CLIENT_PLUGIN_CHROMOTING_INSTANCE_H_ 314