summaryrefslogtreecommitdiffstats
path: root/remoting/client/plugin/chromoting_instance.h
blob: c00f57b44b14a79dd4af14009455f8aa71a73a98 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
// 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.

// TODO(ajwong): We need to come up with a better description of the
// responsibilities for each thread.

#ifndef REMOTING_CLIENT_PLUGIN_CHROMOTING_INSTANCE_H_
#define REMOTING_CLIENT_PLUGIN_CHROMOTING_INSTANCE_H_

#include <string>

#include "base/gtest_prod_util.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "ppapi/c/pp_instance.h"
#include "ppapi/c/pp_rect.h"
#include "ppapi/c/pp_resource.h"
#include "ppapi/cpp/var.h"
#include "third_party/skia/include/core/SkPoint.h"
#include "third_party/skia/include/core/SkSize.h"

// Windows defines 'PostMessage', so we have to undef it before we
// include instance_private.h
#if defined(PostMessage)
#undef PostMessage
#endif

#include "ppapi/cpp/instance.h"
#include "remoting/client/client_context.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/cursor_shape_stub.h"
#include "remoting/protocol/connection_to_host.h"

namespace base {
class DictionaryValue;
}  // namespace base

namespace pp {
class InputEvent;
class Module;
}  // namespace pp

namespace remoting {

namespace protocol {
class ConnectionToHost;
class InputEventTracker;
class MouseInputFilter;
}  // namespace protocol

class ChromotingClient;
class ChromotingStats;
class ClientContext;
class FrameConsumerProxy;
class PepperAudioPlayer;
class PepperInputHandler;
class PepperView;
class PepperXmppProxy;
class RectangleUpdateDecoder;

struct ClientConfig;

class ChromotingInstance :
      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;

  // Plugin API features. This allows orthogonal features to be supported
  // without bumping the API version.
  static const char kApiFeatures[];

  // Backward-compatibility version used by for the messaging
  // interface. Should be updated whenever we remove support for
  // an older version of the API.
  static const int kApiMinMessagingVersion = 5;

  // Backward-compatibility version used by for the ScriptableObject
  // interface. Should be updated whenever we remove support for
  // an older version of the API.
  static const int kApiMinScriptableVersion = 5;

  // Helper method to parse authentication_methods parameter.
  static bool ParseAuthMethods(const std::string& auth_methods,
                               ClientConfig* config);

  explicit ChromotingInstance(PP_Instance instance);
  virtual ~ChromotingInstance();

  // pp::Instance interface.
  virtual void DidChangeView(const pp::Rect& position,
                             const pp::Rect& clip) OVERRIDE;
  virtual bool Init(uint32_t argc, const char* argn[],
                    const char* argv[]) OVERRIDE;
  virtual void HandleMessage(const pp::Var& message) OVERRIDE;
  virtual bool HandleInputEvent(const pp::InputEvent& event) OVERRIDE;

  // ClipboardStub implementation.
  virtual void InjectClipboardEvent(const protocol::ClipboardEvent& event)
      OVERRIDE;

  // CursorShapeStub implementation.
  virtual void SetCursorShape(const protocol::CursorShapeInfo& cursor_shape)
      OVERRIDE;

  // Called by PepperView.
  void SetDesktopSize(const SkISize& size, const SkIPoint& dpi);
  void SetConnectionState(ConnectionState state, ConnectionError error);
  void OnFirstFrameReceived();

  // Message handlers for messages that come from JavaScript. Called
  // from HandleMessage().
  void Connect(const ClientConfig& config);
  void Disconnect();
  void OnIncomingIq(const std::string& iq);
  void ReleaseAllKeys();
  void InjectKeyEvent(const protocol::KeyEvent& event);
  void RemapKey(uint32 in_usb_keycode, uint32 out_usb_keycode);
  void TrapKey(uint32 usb_keycode, bool trap);
  void SendClipboardItem(const std::string& mime_type, const std::string& item);
  void NotifyClientDimensions(int width, int height);
  void PauseVideo(bool pause);

  // Return statistics record by ChromotingClient.
  // If no connection is currently active then NULL will be returned.
  ChromotingStats* GetStats();

  // Registers a global log message handler that redirects the log output to
  // our plugin instance.
  // This is called by the plugin's PPP_InitializeModule.
  // Note that no logging will be processed unless a ChromotingInstance has been
  // registered for logging (see RegisterLoggingInstance).
  static void RegisterLogMessageHandler();

  // Registers this instance so it processes messages sent by the global log
  // message handler. This overwrites any previously registered instance.
  void RegisterLoggingInstance();

  // Unregisters this instance so that debug log messages will no longer be sent
  // to it. If this instance is not the currently registered logging instance,
  // then the currently registered instance will stay in effect.
  void UnregisterLoggingInstance();

  // A Log Message Handler that is called after each LOG message has been
  // processed. This must be of type LogMessageHandlerFunction defined in
  // base/logging.h.
  static bool LogToUI(int severity, const char* file, int line,
                      size_t message_start, const std::string& str);

 private:
  FRIEND_TEST_ALL_PREFIXES(ChromotingInstanceTest, TestCaseSetup);

  // Helper method to post messages to the webapp.
  void PostChromotingMessage(const std::string& method,
                             scoped_ptr<base::DictionaryValue> data);

  // Posts trapped keys to the web-app to handle.
  void SendTrappedKey(uint32 usb_keycode, bool pressed);

  // Callback for PepperXmppProxy.
  void SendOutgoingIq(const std::string& iq);

  void SendPerfStats();

  void ProcessLogToUI(const std::string& message);

  // Returns true if there is a ConnectionToHost and it is connected.
  bool IsConnected();

  bool initialized_;

  PepperPluginThreadDelegate plugin_thread_delegate_;
  scoped_refptr<PluginMessageLoopProxy> plugin_message_loop_;
  ClientContext context_;
  scoped_ptr<protocol::ConnectionToHost> host_connection_;
  scoped_ptr<PepperView> view_;

  scoped_refptr<RectangleUpdateDecoder> rectangle_decoder_;

  scoped_ptr<protocol::MouseInputFilter> mouse_input_filter_;
  scoped_ptr<protocol::InputEventTracker> input_tracker_;
#if defined(OS_MACOSX)
  scoped_ptr<MacKeyEventProcessor> mac_key_event_processor_;
#endif
  KeyEventMapper key_mapper_;
  scoped_ptr<PepperInputHandler> input_handler_;
  scoped_ptr<PepperAudioPlayer> audio_player_;
  scoped_ptr<ChromotingClient> client_;

  // XmppProxy is a refcounted interface used to perform thread-switching and
  // detaching between objects whose lifetimes are controlled by pepper, and
  // jingle_glue objects. This is used when if we start a sandboxed jingle
  // connection.
  scoped_refptr<PepperXmppProxy> xmpp_proxy_;

  base::WeakPtrFactory<ChromotingInstance> weak_factory_;

  DISALLOW_COPY_AND_ASSIGN(ChromotingInstance);
};

}  // namespace remoting

#endif  // REMOTING_CLIENT_PLUGIN_CHROMOTING_INSTANCE_H_