OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "remoting/host/plugin/host_script_object.h" | 5 #include "remoting/host/plugin/host_script_object.h" |
| 6 #include "remoting/host/plugin/daemon_controller.h" |
6 | 7 |
7 #include "base/bind.h" | 8 #include "base/bind.h" |
8 #include "base/message_loop.h" | 9 #include "base/message_loop.h" |
9 #include "base/message_loop_proxy.h" | 10 #include "base/message_loop_proxy.h" |
10 #include "base/sys_string_conversions.h" | 11 #include "base/sys_string_conversions.h" |
11 #include "base/threading/platform_thread.h" | 12 #include "base/threading/platform_thread.h" |
12 #include "base/utf_string_conversions.h" | 13 #include "base/utf_string_conversions.h" |
13 #include "remoting/jingle_glue/xmpp_signal_strategy.h" | 14 #include "remoting/jingle_glue/xmpp_signal_strategy.h" |
14 #include "remoting/base/auth_token_util.h" | 15 #include "remoting/base/auth_token_util.h" |
15 #include "remoting/host/chromoting_host.h" | 16 #include "remoting/host/chromoting_host.h" |
16 #include "remoting/host/chromoting_host_context.h" | 17 #include "remoting/host/chromoting_host_context.h" |
17 #include "remoting/host/desktop_environment.h" | 18 #include "remoting/host/desktop_environment.h" |
18 #include "remoting/host/host_key_pair.h" | 19 #include "remoting/host/host_key_pair.h" |
19 #include "remoting/host/host_secret.h" | 20 #include "remoting/host/host_secret.h" |
20 #include "remoting/host/it2me_host_user_interface.h" | 21 #include "remoting/host/it2me_host_user_interface.h" |
21 #include "remoting/host/plugin/host_log_handler.h" | 22 #include "remoting/host/plugin/host_log_handler.h" |
22 #include "remoting/host/plugin/policy_hack/nat_policy.h" | 23 #include "remoting/host/plugin/policy_hack/nat_policy.h" |
23 #include "remoting/host/register_support_host_request.h" | 24 #include "remoting/host/register_support_host_request.h" |
24 #include "remoting/protocol/it2me_host_authenticator_factory.h" | 25 #include "remoting/protocol/it2me_host_authenticator_factory.h" |
25 | 26 |
26 namespace remoting { | 27 namespace remoting { |
27 | 28 |
28 // Supported Javascript interface: | |
29 // readonly attribute string accessCode; | |
30 // readonly attribute int accessCodeLifetime; | |
31 // readonly attribute string client; | |
32 // readonly attribute int state; | |
33 // | |
34 // state: { | |
35 // DISCONNECTED, | |
36 // STARTING, | |
37 // REQUESTED_ACCESS_CODE, | |
38 // RECEIVED_ACCESS_CODE, | |
39 // CONNECTED, | |
40 // DISCONNECTING, | |
41 // ERROR, | |
42 // } | |
43 // | |
44 // attribute Function void logDebugInfo(string); | |
45 // attribute Function void onNatTraversalPolicyChanged(boolean); | |
46 // attribute Function void onStateChanged(state); | |
47 // | |
48 // // The |auth_service_with_token| parameter should be in the format | |
49 // // "auth_service:auth_token". An example would be "oauth2:1/2a3912vd". | |
50 // void connect(string uid, string auth_service_with_token); | |
51 // void disconnect(); | |
52 // void localize(string (*localize_func)(string,...)); | |
53 | |
54 namespace { | 29 namespace { |
55 | 30 |
56 const char* kAttrNameAccessCode = "accessCode"; | 31 const char* kAttrNameAccessCode = "accessCode"; |
57 const char* kAttrNameAccessCodeLifetime = "accessCodeLifetime"; | 32 const char* kAttrNameAccessCodeLifetime = "accessCodeLifetime"; |
58 const char* kAttrNameClient = "client"; | 33 const char* kAttrNameClient = "client"; |
| 34 const char* kAttrNameDaemonState = "daemonState"; |
59 const char* kAttrNameState = "state"; | 35 const char* kAttrNameState = "state"; |
60 const char* kAttrNameLogDebugInfo = "logDebugInfo"; | 36 const char* kAttrNameLogDebugInfo = "logDebugInfo"; |
61 const char* kAttrNameOnNatTraversalPolicyChanged = | 37 const char* kAttrNameOnNatTraversalPolicyChanged = |
62 "onNatTraversalPolicyChanged"; | 38 "onNatTraversalPolicyChanged"; |
63 const char* kAttrNameOnStateChanged = "onStateChanged"; | 39 const char* kAttrNameOnStateChanged = "onStateChanged"; |
64 const char* kFuncNameConnect = "connect"; | 40 const char* kFuncNameConnect = "connect"; |
65 const char* kFuncNameDisconnect = "disconnect"; | 41 const char* kFuncNameDisconnect = "disconnect"; |
66 const char* kFuncNameLocalize = "localize"; | 42 const char* kFuncNameLocalize = "localize"; |
| 43 const char* kFuncNameSetDaemonPin = "setDaemonPin"; |
| 44 const char* kFuncNameStartDaemon = "startDaemon"; |
| 45 const char* kFuncNameStopDaemon = "stopDaemon"; |
67 | 46 |
68 // States. | 47 // States. |
69 const char* kAttrNameDisconnected = "DISCONNECTED"; | 48 const char* kAttrNameDisconnected = "DISCONNECTED"; |
70 const char* kAttrNameStarting = "STARTING"; | 49 const char* kAttrNameStarting = "STARTING"; |
71 const char* kAttrNameRequestedAccessCode = "REQUESTED_ACCESS_CODE"; | 50 const char* kAttrNameRequestedAccessCode = "REQUESTED_ACCESS_CODE"; |
72 const char* kAttrNameReceivedAccessCode = "RECEIVED_ACCESS_CODE"; | 51 const char* kAttrNameReceivedAccessCode = "RECEIVED_ACCESS_CODE"; |
73 const char* kAttrNameConnected = "CONNECTED"; | 52 const char* kAttrNameConnected = "CONNECTED"; |
74 const char* kAttrNameDisconnecting = "DISCONNECTING"; | 53 const char* kAttrNameDisconnecting = "DISCONNECTING"; |
75 const char* kAttrNameError = "ERROR"; | 54 const char* kAttrNameError = "ERROR"; |
76 | 55 |
77 const int kMaxLoginAttempts = 5; | 56 const int kMaxLoginAttempts = 5; |
78 | 57 |
79 } // namespace | 58 } // namespace |
80 | 59 |
81 HostNPScriptObject::HostNPScriptObject( | 60 HostNPScriptObject::HostNPScriptObject( |
82 NPP plugin, | 61 NPP plugin, |
83 NPObject* parent, | 62 NPObject* parent, |
84 PluginMessageLoopProxy::Delegate* plugin_thread_delegate) | 63 PluginMessageLoopProxy::Delegate* plugin_thread_delegate) |
85 : plugin_(plugin), | 64 : plugin_(plugin), |
86 parent_(parent), | 65 parent_(parent), |
87 state_(kDisconnected), | 66 state_(kDisconnected), |
88 np_thread_id_(base::PlatformThread::CurrentId()), | 67 np_thread_id_(base::PlatformThread::CurrentId()), |
89 plugin_message_loop_proxy_( | 68 plugin_message_loop_proxy_( |
90 new PluginMessageLoopProxy(plugin_thread_delegate)), | 69 new PluginMessageLoopProxy(plugin_thread_delegate)), |
91 host_context_(plugin_message_loop_proxy_), | 70 host_context_(plugin_message_loop_proxy_), |
92 failed_login_attempts_(0), | 71 failed_login_attempts_(0), |
| 72 daemon_controller_(DaemonController::Create()), |
93 disconnected_event_(true, false), | 73 disconnected_event_(true, false), |
94 am_currently_logging_(false), | 74 am_currently_logging_(false), |
95 nat_traversal_enabled_(false), | 75 nat_traversal_enabled_(false), |
96 policy_received_(false) { | 76 policy_received_(false) { |
97 } | 77 } |
98 | 78 |
99 HostNPScriptObject::~HostNPScriptObject() { | 79 HostNPScriptObject::~HostNPScriptObject() { |
100 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); | 80 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); |
101 | 81 |
102 // Shutdown It2MeHostUserInterface first so that it doesn't try to post | 82 // Shutdown It2MeHostUserInterface first so that it doesn't try to post |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
140 base::Bind(&HostNPScriptObject::OnNatPolicyUpdate, | 120 base::Bind(&HostNPScriptObject::OnNatPolicyUpdate, |
141 base::Unretained(this))); | 121 base::Unretained(this))); |
142 return true; | 122 return true; |
143 } | 123 } |
144 | 124 |
145 bool HostNPScriptObject::HasMethod(const std::string& method_name) { | 125 bool HostNPScriptObject::HasMethod(const std::string& method_name) { |
146 VLOG(2) << "HasMethod " << method_name; | 126 VLOG(2) << "HasMethod " << method_name; |
147 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); | 127 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); |
148 return (method_name == kFuncNameConnect || | 128 return (method_name == kFuncNameConnect || |
149 method_name == kFuncNameDisconnect || | 129 method_name == kFuncNameDisconnect || |
150 method_name == kFuncNameLocalize); | 130 method_name == kFuncNameLocalize || |
| 131 method_name == kFuncNameSetDaemonPin || |
| 132 method_name == kFuncNameStartDaemon || |
| 133 method_name == kFuncNameStopDaemon); |
151 } | 134 } |
152 | 135 |
153 bool HostNPScriptObject::InvokeDefault(const NPVariant* args, | 136 bool HostNPScriptObject::InvokeDefault(const NPVariant* args, |
154 uint32_t argCount, | 137 uint32_t argCount, |
155 NPVariant* result) { | 138 NPVariant* result) { |
156 VLOG(2) << "InvokeDefault"; | 139 VLOG(2) << "InvokeDefault"; |
157 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); | 140 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); |
158 SetException("exception during default invocation"); | 141 SetException("exception during default invocation"); |
159 return false; | 142 return false; |
160 } | 143 } |
161 | 144 |
162 bool HostNPScriptObject::Invoke(const std::string& method_name, | 145 bool HostNPScriptObject::Invoke(const std::string& method_name, |
163 const NPVariant* args, | 146 const NPVariant* args, |
164 uint32_t argCount, | 147 uint32_t argCount, |
165 NPVariant* result) { | 148 NPVariant* result) { |
166 VLOG(2) << "Invoke " << method_name; | 149 VLOG(2) << "Invoke " << method_name; |
167 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); | 150 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); |
168 if (method_name == kFuncNameConnect) { | 151 if (method_name == kFuncNameConnect) { |
169 return Connect(args, argCount, result); | 152 return Connect(args, argCount, result); |
170 } else if (method_name == kFuncNameDisconnect) { | 153 } else if (method_name == kFuncNameDisconnect) { |
171 return Disconnect(args, argCount, result); | 154 return Disconnect(args, argCount, result); |
172 } else if (method_name == kFuncNameLocalize) { | 155 } else if (method_name == kFuncNameLocalize) { |
173 return Localize(args, argCount, result); | 156 return Localize(args, argCount, result); |
| 157 } else if (method_name == kFuncNameSetDaemonPin) { |
| 158 return SetDaemonPin(args, argCount, result); |
| 159 } else if (method_name == kFuncNameStartDaemon) { |
| 160 return StartDaemon(args, argCount, result); |
| 161 } else if (method_name == kFuncNameStopDaemon) { |
| 162 return StopDaemon(args, argCount, result); |
174 } else { | 163 } else { |
175 SetException("Invoke: unknown method " + method_name); | 164 SetException("Invoke: unknown method " + method_name); |
176 return false; | 165 return false; |
177 } | 166 } |
178 } | 167 } |
179 | 168 |
180 bool HostNPScriptObject::HasProperty(const std::string& property_name) { | 169 bool HostNPScriptObject::HasProperty(const std::string& property_name) { |
181 VLOG(2) << "HasProperty " << property_name; | 170 VLOG(2) << "HasProperty " << property_name; |
182 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); | 171 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); |
183 return (property_name == kAttrNameAccessCode || | 172 return (property_name == kAttrNameAccessCode || |
184 property_name == kAttrNameAccessCodeLifetime || | 173 property_name == kAttrNameAccessCodeLifetime || |
185 property_name == kAttrNameClient || | 174 property_name == kAttrNameClient || |
| 175 property_name == kAttrNameDaemonState || |
186 property_name == kAttrNameState || | 176 property_name == kAttrNameState || |
187 property_name == kAttrNameLogDebugInfo || | 177 property_name == kAttrNameLogDebugInfo || |
188 property_name == kAttrNameOnNatTraversalPolicyChanged || | 178 property_name == kAttrNameOnNatTraversalPolicyChanged || |
189 property_name == kAttrNameOnStateChanged || | 179 property_name == kAttrNameOnStateChanged || |
190 property_name == kAttrNameDisconnected || | 180 property_name == kAttrNameDisconnected || |
191 property_name == kAttrNameStarting || | 181 property_name == kAttrNameStarting || |
192 property_name == kAttrNameRequestedAccessCode || | 182 property_name == kAttrNameRequestedAccessCode || |
193 property_name == kAttrNameReceivedAccessCode || | 183 property_name == kAttrNameReceivedAccessCode || |
194 property_name == kAttrNameConnected || | 184 property_name == kAttrNameConnected || |
195 property_name == kAttrNameDisconnecting || | 185 property_name == kAttrNameDisconnecting || |
(...skipping 25 matching lines...) Expand all Loading... |
221 base::AutoLock auto_lock(access_code_lock_); | 211 base::AutoLock auto_lock(access_code_lock_); |
222 *result = NPVariantFromString(access_code_); | 212 *result = NPVariantFromString(access_code_); |
223 return true; | 213 return true; |
224 } else if (property_name == kAttrNameAccessCodeLifetime) { | 214 } else if (property_name == kAttrNameAccessCodeLifetime) { |
225 base::AutoLock auto_lock(access_code_lock_); | 215 base::AutoLock auto_lock(access_code_lock_); |
226 INT32_TO_NPVARIANT(access_code_lifetime_.InSeconds(), *result); | 216 INT32_TO_NPVARIANT(access_code_lifetime_.InSeconds(), *result); |
227 return true; | 217 return true; |
228 } else if (property_name == kAttrNameClient) { | 218 } else if (property_name == kAttrNameClient) { |
229 *result = NPVariantFromString(client_username_); | 219 *result = NPVariantFromString(client_username_); |
230 return true; | 220 return true; |
| 221 } else if (property_name == kAttrNameDaemonState) { |
| 222 INT32_TO_NPVARIANT(daemon_controller_->GetState(), *result); |
| 223 return true; |
231 } else if (property_name == kAttrNameDisconnected) { | 224 } else if (property_name == kAttrNameDisconnected) { |
232 INT32_TO_NPVARIANT(kDisconnected, *result); | 225 INT32_TO_NPVARIANT(kDisconnected, *result); |
233 return true; | 226 return true; |
234 } else if (property_name == kAttrNameStarting) { | 227 } else if (property_name == kAttrNameStarting) { |
235 INT32_TO_NPVARIANT(kStarting, *result); | 228 INT32_TO_NPVARIANT(kStarting, *result); |
236 return true; | 229 return true; |
237 } else if (property_name == kAttrNameRequestedAccessCode) { | 230 } else if (property_name == kAttrNameRequestedAccessCode) { |
238 INT32_TO_NPVARIANT(kRequestedAccessCode, *result); | 231 INT32_TO_NPVARIANT(kRequestedAccessCode, *result); |
239 return true; | 232 return true; |
240 } else if (property_name == kAttrNameReceivedAccessCode) { | 233 } else if (property_name == kAttrNameReceivedAccessCode) { |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
313 } | 306 } |
314 | 307 |
315 bool HostNPScriptObject::Enumerate(std::vector<std::string>* values) { | 308 bool HostNPScriptObject::Enumerate(std::vector<std::string>* values) { |
316 VLOG(2) << "Enumerate"; | 309 VLOG(2) << "Enumerate"; |
317 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); | 310 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); |
318 const char* entries[] = { | 311 const char* entries[] = { |
319 kAttrNameAccessCode, | 312 kAttrNameAccessCode, |
320 kAttrNameState, | 313 kAttrNameState, |
321 kAttrNameLogDebugInfo, | 314 kAttrNameLogDebugInfo, |
322 kAttrNameOnStateChanged, | 315 kAttrNameOnStateChanged, |
323 kFuncNameConnect, | |
324 kFuncNameDisconnect, | |
325 kFuncNameLocalize, | |
326 kAttrNameDisconnected, | 316 kAttrNameDisconnected, |
327 kAttrNameStarting, | 317 kAttrNameStarting, |
328 kAttrNameRequestedAccessCode, | 318 kAttrNameRequestedAccessCode, |
329 kAttrNameReceivedAccessCode, | 319 kAttrNameReceivedAccessCode, |
330 kAttrNameConnected, | 320 kAttrNameConnected, |
331 kAttrNameDisconnecting, | 321 kAttrNameDisconnecting, |
332 kAttrNameError | 322 kAttrNameError, |
| 323 kFuncNameConnect, |
| 324 kFuncNameDisconnect, |
| 325 kFuncNameLocalize, |
| 326 kFuncNameSetDaemonPin, |
| 327 kFuncNameStartDaemon, |
| 328 kFuncNameStopDaemon |
333 }; | 329 }; |
334 for (size_t i = 0; i < arraysize(entries); ++i) { | 330 for (size_t i = 0; i < arraysize(entries); ++i) { |
335 values->push_back(entries[i]); | 331 values->push_back(entries[i]); |
336 } | 332 } |
337 return true; | 333 return true; |
338 } | 334 } |
339 | 335 |
340 void HostNPScriptObject::OnAccessDenied(const std::string& jid) { | 336 void HostNPScriptObject::OnAccessDenied(const std::string& jid) { |
341 DCHECK(host_context_.network_message_loop()->BelongsToCurrentThread()); | 337 DCHECK(host_context_.network_message_loop()->BelongsToCurrentThread()); |
342 | 338 |
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
559 if (NPVARIANT_IS_OBJECT(args[0])) { | 555 if (NPVARIANT_IS_OBJECT(args[0])) { |
560 ScopedRefNPObject localize_func(NPVARIANT_TO_OBJECT(args[0])); | 556 ScopedRefNPObject localize_func(NPVARIANT_TO_OBJECT(args[0])); |
561 LocalizeStrings(localize_func.get()); | 557 LocalizeStrings(localize_func.get()); |
562 return true; | 558 return true; |
563 } else { | 559 } else { |
564 SetException("localize: unexpected type for argument 1"); | 560 SetException("localize: unexpected type for argument 1"); |
565 return false; | 561 return false; |
566 } | 562 } |
567 } | 563 } |
568 | 564 |
| 565 bool HostNPScriptObject::SetDaemonPin(const NPVariant* args, |
| 566 uint32_t arg_count, |
| 567 NPVariant* result) { |
| 568 if (arg_count != 1) { |
| 569 SetException("startDaemon: bad number of arguments"); |
| 570 return false; |
| 571 } |
| 572 if (NPVARIANT_IS_STRING(args[0])) { |
| 573 bool set_pin_result = |
| 574 daemon_controller_->SetPin(StringFromNPVariant(args[0])); |
| 575 BOOLEAN_TO_NPVARIANT(set_pin_result, *result); |
| 576 return true; |
| 577 } else { |
| 578 SetException("startDaemon: unexpected type for argument 1"); |
| 579 return false; |
| 580 } |
| 581 } |
| 582 |
| 583 bool HostNPScriptObject::StartDaemon(const NPVariant* args, |
| 584 uint32_t arg_count, |
| 585 NPVariant* result) { |
| 586 if (arg_count != 0) { |
| 587 SetException("startDaemon: bad number of arguments"); |
| 588 return false; |
| 589 } |
| 590 bool start_result = daemon_controller_->Start(); |
| 591 BOOLEAN_TO_NPVARIANT(start_result, *result); |
| 592 return true; |
| 593 } |
| 594 |
| 595 bool HostNPScriptObject::StopDaemon(const NPVariant* args, |
| 596 uint32_t arg_count, |
| 597 NPVariant* result) { |
| 598 if (arg_count != 0) { |
| 599 SetException("startDaemon: bad number of arguments"); |
| 600 return false; |
| 601 } |
| 602 bool stop_result = daemon_controller_->Stop(); |
| 603 BOOLEAN_TO_NPVARIANT(stop_result, *result); |
| 604 return true; |
| 605 } |
| 606 |
569 void HostNPScriptObject::DisconnectInternal() { | 607 void HostNPScriptObject::DisconnectInternal() { |
570 if (!host_context_.network_message_loop()->BelongsToCurrentThread()) { | 608 if (!host_context_.network_message_loop()->BelongsToCurrentThread()) { |
571 host_context_.network_message_loop()->PostTask( | 609 host_context_.network_message_loop()->PostTask( |
572 FROM_HERE, base::Bind(&HostNPScriptObject::DisconnectInternal, | 610 FROM_HERE, base::Bind(&HostNPScriptObject::DisconnectInternal, |
573 base::Unretained(this))); | 611 base::Unretained(this))); |
574 return; | 612 return; |
575 } | 613 } |
576 | 614 |
577 switch (state_) { | 615 switch (state_) { |
578 case kDisconnected: | 616 case kDisconnected: |
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
836 uint32_t argCount) { | 874 uint32_t argCount) { |
837 NPVariant np_result; | 875 NPVariant np_result; |
838 bool is_good = g_npnetscape_funcs->invokeDefault(plugin_, func, args, | 876 bool is_good = g_npnetscape_funcs->invokeDefault(plugin_, func, args, |
839 argCount, &np_result); | 877 argCount, &np_result); |
840 if (is_good) | 878 if (is_good) |
841 g_npnetscape_funcs->releasevariantvalue(&np_result); | 879 g_npnetscape_funcs->releasevariantvalue(&np_result); |
842 return is_good; | 880 return is_good; |
843 } | 881 } |
844 | 882 |
845 } // namespace remoting | 883 } // namespace remoting |
OLD | NEW |