summaryrefslogtreecommitdiffstats
path: root/remoting/host/plugin/host_script_object.h
blob: 2d776ad57306f0b434cd652c4d88e82dc312faad (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
// 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 REMOTING_HOST_PLUGIN_HOST_SCRIPT_OBJECT_H_
#define REMOTING_HOST_PLUGIN_HOST_SCRIPT_OBJECT_H_

#include <string>
#include <vector>

#include "base/compiler_specific.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/ref_counted.h"
#include "base/synchronization/cancellation_flag.h"
#include "base/synchronization/waitable_event.h"
#include "base/threading/platform_thread.h"
#include "base/time.h"
#include "remoting/host/chromoting_host_context.h"
#include "remoting/host/host_status_observer.h"
#include "remoting/host/plugin/host_plugin_utils.h"
#include "third_party/npapi/bindings/npapi.h"
#include "third_party/npapi/bindings/npfunctions.h"
#include "third_party/npapi/bindings/npruntime.h"

namespace tracked_objects {
class Location;
}  // namespace tracked_objects

namespace remoting {

class ChromotingHost;
class DesktopEnvironment;
class MutableHostConfig;
class RegisterSupportHostRequest;
class SignalStrategy;
class SupportAccessVerifier;

namespace policy_hack {
class NatPolicy;
}  // namespace policy_hack

// NPAPI plugin implementation for remoting host script object.
// HostNPScriptObject creates threads that are required to run
// ChromotingHost and starts/stops the host on those threads. When
// destroyed it sychronously shuts down the host and all threads.
class HostNPScriptObject : public HostStatusObserver {
 public:
  HostNPScriptObject(NPP plugin, NPObject* parent);
  virtual ~HostNPScriptObject();

  bool Init();

  bool HasMethod(const std::string& method_name);
  bool InvokeDefault(const NPVariant* args,
                     uint32_t argCount,
                     NPVariant* result);
  bool Invoke(const std::string& method_name,
              const NPVariant* args,
              uint32_t argCount,
              NPVariant* result);
  bool HasProperty(const std::string& property_name);
  bool GetProperty(const std::string& property_name, NPVariant* result);
  bool SetProperty(const std::string& property_name, const NPVariant* value);
  bool RemoveProperty(const std::string& property_name);
  bool Enumerate(std::vector<std::string>* values);

  // remoting::HostStatusObserver implementation.
  virtual void OnSignallingConnected(remoting::SignalStrategy* signal_strategy,
                                     const std::string& full_jid) OVERRIDE;
  virtual void OnSignallingDisconnected() OVERRIDE;
  virtual void OnAccessDenied() OVERRIDE;
  virtual void OnClientAuthenticated(
      remoting::protocol::ConnectionToClient* client) OVERRIDE;
  virtual void OnClientDisconnected(
      remoting::protocol::ConnectionToClient* client) OVERRIDE;
  virtual void OnShutdown() OVERRIDE;

  // 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:
  enum State {
    kDisconnected,
    kRequestedAccessCode,
    kReceivedAccessCode,
    kConnected,
    kAffirmingConnection,
    kError
  };

  // Start connection. args are:
  //   string uid, string auth_token
  // No result.
  bool Connect(const NPVariant* args, uint32_t argCount, NPVariant* result);

  // Disconnect. No arguments or result.
  bool Disconnect(const NPVariant* args, uint32_t argCount, NPVariant* result);

  // Call OnStateChanged handler if there is one.
  void OnStateChanged(State state);

  // Call LogDebugInfo handler if there is one.
  void LogDebugInfo(const std::string& message);

  // Callbacks invoked during session setup.
  void OnReceivedSupportID(remoting::SupportAccessVerifier* access_verifier,
                           bool success,
                           const std::string& support_id,
                           const base::TimeDelta& lifetime);

  // Helper functions that run on main thread. Can be called on any
  // other thread.
  void ReadPolicyAndConnect(const std::string& uid,
                            const std::string& auth_token,
                            const std::string& auth_service);
  void FinishConnect(const std::string& uid,
                       const std::string& auth_token,
                       const std::string& auth_service);
  void DisconnectInternal();

  // Callback for ChromotingHost::Shutdown().
  void OnShutdownFinished();

  // Called when the nat traversal policy is updated.
  void OnNatPolicyUpdate(bool nat_traversal_enabled);

  void LocalizeStrings();

  // Helper function for executing InvokeDefault on an NPObject that performs
  // a string->string mapping with one optional substitution parameter. Stores
  // the translation in |result| and returns true on success, or leaves it
  // unchanged and returns false on failure.
  bool LocalizeString(const char* tag, const char* substitution,
                      std::string* result);

  // Helper function for executing InvokeDefault on an NPObject, and ignoring
  // the return value.
  bool InvokeAndIgnoreResult(NPObject* func,
                             const NPVariant* args,
                             uint32_t argCount);

  // Posts a task on the main NP thread.
  void PostTaskToNPThread(
      const tracked_objects::Location& from_here, const base::Closure& task);

  // Utility function for PostTaskToNPThread.
  static void NPTaskSpringboard(void* task);

  // Set an exception for the current call.
  void SetException(const std::string& exception_string);

  NPP plugin_;
  NPObject* parent_;
  int state_;
  std::string access_code_;
  std::string client_username_;
  base::TimeDelta access_code_lifetime_;
  ScopedRefNPObject localize_func_;
  ScopedRefNPObject log_debug_info_func_;
  ScopedRefNPObject on_state_changed_func_;
  base::PlatformThreadId np_thread_id_;

  scoped_ptr<RegisterSupportHostRequest> register_request_;
  scoped_refptr<MutableHostConfig> host_config_;
  ChromotingHostContext host_context_;
  scoped_ptr<DesktopEnvironment> desktop_environment_;

  scoped_refptr<ChromotingHost> host_;
  int failed_login_attempts_;

  base::WaitableEvent disconnected_event_;
  base::CancellationFlag destructing_;

  scoped_ptr<policy_hack::NatPolicy> nat_policy_;

  // Host the current nat traversal policy setting.
  bool nat_traversal_enabled_;

  // Indiciates whether or not a policy has ever been read. This is to ensure
  // that on startup, we do not accidentally start a connection before we have
  // queried our policy restrictions.
  bool policy_received_;

  // On startup, it is possible to have Connect() called before the policy read
  // is completed.  Rather than just failing, we thunk the connection call so
  // it can be executed after at least one successful policy read. This
  // variable contains the thunk if it is necessary.
  base::Closure pending_connect_;
};

}  // namespace remoting

DISABLE_RUNNABLE_METHOD_REFCOUNT(remoting::HostNPScriptObject);

#endif  // REMOTING_HOST_HOST_SCRIPT_OBJECT_H_