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_npapi.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* kFuncNameStartDaemon = "startDaemon"; | |
44 const char* kFuncNameStopDaemon = "stopDaemon"; | |
67 | 45 |
68 // States. | 46 // States. |
69 const char* kAttrNameDisconnected = "DISCONNECTED"; | 47 const char* kAttrNameDisconnected = "DISCONNECTED"; |
70 const char* kAttrNameStarting = "STARTING"; | 48 const char* kAttrNameStarting = "STARTING"; |
71 const char* kAttrNameRequestedAccessCode = "REQUESTED_ACCESS_CODE"; | 49 const char* kAttrNameRequestedAccessCode = "REQUESTED_ACCESS_CODE"; |
72 const char* kAttrNameReceivedAccessCode = "RECEIVED_ACCESS_CODE"; | 50 const char* kAttrNameReceivedAccessCode = "RECEIVED_ACCESS_CODE"; |
73 const char* kAttrNameConnected = "CONNECTED"; | 51 const char* kAttrNameConnected = "CONNECTED"; |
74 const char* kAttrNameDisconnecting = "DISCONNECTING"; | 52 const char* kAttrNameDisconnecting = "DISCONNECTING"; |
75 const char* kAttrNameError = "ERROR"; | 53 const char* kAttrNameError = "ERROR"; |
76 | 54 |
77 const int kMaxLoginAttempts = 5; | 55 const int kMaxLoginAttempts = 5; |
78 | 56 |
79 } // namespace | 57 } // namespace |
80 | 58 |
81 HostNPScriptObject::HostNPScriptObject( | 59 HostNPScriptObject::HostNPScriptObject( |
82 NPP plugin, | 60 NPP plugin, |
83 NPObject* parent, | 61 NPObject* parent, |
84 PluginMessageLoopProxy::Delegate* plugin_thread_delegate) | 62 PluginMessageLoopProxy::Delegate* plugin_thread_delegate) |
85 : plugin_(plugin), | 63 : plugin_(plugin), |
86 parent_(parent), | 64 parent_(parent), |
87 state_(kDisconnected), | 65 state_(kDisconnected), |
88 np_thread_id_(base::PlatformThread::CurrentId()), | 66 np_thread_id_(base::PlatformThread::CurrentId()), |
89 plugin_message_loop_proxy_( | 67 plugin_message_loop_proxy_( |
90 new PluginMessageLoopProxy(plugin_thread_delegate)), | 68 new PluginMessageLoopProxy(plugin_thread_delegate)), |
91 host_context_(plugin_message_loop_proxy_), | 69 host_context_(plugin_message_loop_proxy_), |
92 failed_login_attempts_(0), | 70 failed_login_attempts_(0), |
71 daemon_npapi_(DaemonNpapi::Create()), | |
93 disconnected_event_(true, false), | 72 disconnected_event_(true, false), |
94 am_currently_logging_(false), | 73 am_currently_logging_(false), |
95 nat_traversal_enabled_(false), | 74 nat_traversal_enabled_(false), |
96 policy_received_(false) { | 75 policy_received_(false) { |
97 } | 76 } |
98 | 77 |
99 HostNPScriptObject::~HostNPScriptObject() { | 78 HostNPScriptObject::~HostNPScriptObject() { |
100 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); | 79 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); |
101 | 80 |
102 // Shutdown It2MeHostUserInterface first so that it doesn't try to post | 81 // 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, | 119 base::Bind(&HostNPScriptObject::OnNatPolicyUpdate, |
141 base::Unretained(this))); | 120 base::Unretained(this))); |
142 return true; | 121 return true; |
143 } | 122 } |
144 | 123 |
145 bool HostNPScriptObject::HasMethod(const std::string& method_name) { | 124 bool HostNPScriptObject::HasMethod(const std::string& method_name) { |
146 VLOG(2) << "HasMethod " << method_name; | 125 VLOG(2) << "HasMethod " << method_name; |
147 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); | 126 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); |
148 return (method_name == kFuncNameConnect || | 127 return (method_name == kFuncNameConnect || |
149 method_name == kFuncNameDisconnect || | 128 method_name == kFuncNameDisconnect || |
150 method_name == kFuncNameLocalize); | 129 method_name == kFuncNameLocalize || |
130 method_name == kFuncNameStartDaemon || | |
131 method_name == kFuncNameStopDaemon); | |
151 } | 132 } |
152 | 133 |
153 bool HostNPScriptObject::InvokeDefault(const NPVariant* args, | 134 bool HostNPScriptObject::InvokeDefault(const NPVariant* args, |
154 uint32_t argCount, | 135 uint32_t argCount, |
155 NPVariant* result) { | 136 NPVariant* result) { |
156 VLOG(2) << "InvokeDefault"; | 137 VLOG(2) << "InvokeDefault"; |
157 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); | 138 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); |
158 SetException("exception during default invocation"); | 139 SetException("exception during default invocation"); |
159 return false; | 140 return false; |
160 } | 141 } |
161 | 142 |
162 bool HostNPScriptObject::Invoke(const std::string& method_name, | 143 bool HostNPScriptObject::Invoke(const std::string& method_name, |
163 const NPVariant* args, | 144 const NPVariant* args, |
164 uint32_t argCount, | 145 uint32_t argCount, |
165 NPVariant* result) { | 146 NPVariant* result) { |
166 VLOG(2) << "Invoke " << method_name; | 147 VLOG(2) << "Invoke " << method_name; |
167 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); | 148 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); |
168 if (method_name == kFuncNameConnect) { | 149 if (method_name == kFuncNameConnect) { |
169 return Connect(args, argCount, result); | 150 return Connect(args, argCount, result); |
170 } else if (method_name == kFuncNameDisconnect) { | 151 } else if (method_name == kFuncNameDisconnect) { |
171 return Disconnect(args, argCount, result); | 152 return Disconnect(args, argCount, result); |
172 } else if (method_name == kFuncNameLocalize) { | 153 } else if (method_name == kFuncNameLocalize) { |
173 return Localize(args, argCount, result); | 154 return Localize(args, argCount, result); |
155 } else if (method_name == kFuncNameStartDaemon) { | |
156 return StartDaemon(args, argCount, result); | |
157 } else if (method_name == kFuncNameStopDaemon) { | |
158 return StopDaemon(args, argCount, result); | |
174 } else { | 159 } else { |
175 SetException("Invoke: unknown method " + method_name); | 160 SetException("Invoke: unknown method " + method_name); |
176 return false; | 161 return false; |
177 } | 162 } |
178 } | 163 } |
179 | 164 |
180 bool HostNPScriptObject::HasProperty(const std::string& property_name) { | 165 bool HostNPScriptObject::HasProperty(const std::string& property_name) { |
181 VLOG(2) << "HasProperty " << property_name; | 166 VLOG(2) << "HasProperty " << property_name; |
182 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); | 167 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); |
183 return (property_name == kAttrNameAccessCode || | 168 return (property_name == kAttrNameAccessCode || |
184 property_name == kAttrNameAccessCodeLifetime || | 169 property_name == kAttrNameAccessCodeLifetime || |
185 property_name == kAttrNameClient || | 170 property_name == kAttrNameClient || |
171 property_name == kAttrNameDaemonState || | |
186 property_name == kAttrNameState || | 172 property_name == kAttrNameState || |
187 property_name == kAttrNameLogDebugInfo || | 173 property_name == kAttrNameLogDebugInfo || |
188 property_name == kAttrNameOnNatTraversalPolicyChanged || | 174 property_name == kAttrNameOnNatTraversalPolicyChanged || |
189 property_name == kAttrNameOnStateChanged || | 175 property_name == kAttrNameOnStateChanged || |
190 property_name == kAttrNameDisconnected || | 176 property_name == kAttrNameDisconnected || |
191 property_name == kAttrNameStarting || | 177 property_name == kAttrNameStarting || |
192 property_name == kAttrNameRequestedAccessCode || | 178 property_name == kAttrNameRequestedAccessCode || |
193 property_name == kAttrNameReceivedAccessCode || | 179 property_name == kAttrNameReceivedAccessCode || |
194 property_name == kAttrNameConnected || | 180 property_name == kAttrNameConnected || |
195 property_name == kAttrNameDisconnecting || | 181 property_name == kAttrNameDisconnecting || |
(...skipping 25 matching lines...) Expand all Loading... | |
221 base::AutoLock auto_lock(access_code_lock_); | 207 base::AutoLock auto_lock(access_code_lock_); |
222 *result = NPVariantFromString(access_code_); | 208 *result = NPVariantFromString(access_code_); |
223 return true; | 209 return true; |
224 } else if (property_name == kAttrNameAccessCodeLifetime) { | 210 } else if (property_name == kAttrNameAccessCodeLifetime) { |
225 base::AutoLock auto_lock(access_code_lock_); | 211 base::AutoLock auto_lock(access_code_lock_); |
226 INT32_TO_NPVARIANT(access_code_lifetime_.InSeconds(), *result); | 212 INT32_TO_NPVARIANT(access_code_lifetime_.InSeconds(), *result); |
227 return true; | 213 return true; |
228 } else if (property_name == kAttrNameClient) { | 214 } else if (property_name == kAttrNameClient) { |
229 *result = NPVariantFromString(client_username_); | 215 *result = NPVariantFromString(client_username_); |
230 return true; | 216 return true; |
217 } else if (property_name == kAttrNameDaemonState) { | |
218 INT32_TO_NPVARIANT(daemon_npapi_->GetState(), *result); | |
219 return true; | |
231 } else if (property_name == kAttrNameDisconnected) { | 220 } else if (property_name == kAttrNameDisconnected) { |
232 INT32_TO_NPVARIANT(kDisconnected, *result); | 221 INT32_TO_NPVARIANT(kDisconnected, *result); |
233 return true; | 222 return true; |
234 } else if (property_name == kAttrNameStarting) { | 223 } else if (property_name == kAttrNameStarting) { |
235 INT32_TO_NPVARIANT(kStarting, *result); | 224 INT32_TO_NPVARIANT(kStarting, *result); |
236 return true; | 225 return true; |
237 } else if (property_name == kAttrNameRequestedAccessCode) { | 226 } else if (property_name == kAttrNameRequestedAccessCode) { |
238 INT32_TO_NPVARIANT(kRequestedAccessCode, *result); | 227 INT32_TO_NPVARIANT(kRequestedAccessCode, *result); |
239 return true; | 228 return true; |
240 } else if (property_name == kAttrNameReceivedAccessCode) { | 229 } else if (property_name == kAttrNameReceivedAccessCode) { |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
313 } | 302 } |
314 | 303 |
315 bool HostNPScriptObject::Enumerate(std::vector<std::string>* values) { | 304 bool HostNPScriptObject::Enumerate(std::vector<std::string>* values) { |
316 VLOG(2) << "Enumerate"; | 305 VLOG(2) << "Enumerate"; |
317 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); | 306 CHECK_EQ(base::PlatformThread::CurrentId(), np_thread_id_); |
318 const char* entries[] = { | 307 const char* entries[] = { |
319 kAttrNameAccessCode, | 308 kAttrNameAccessCode, |
320 kAttrNameState, | 309 kAttrNameState, |
321 kAttrNameLogDebugInfo, | 310 kAttrNameLogDebugInfo, |
322 kAttrNameOnStateChanged, | 311 kAttrNameOnStateChanged, |
323 kFuncNameConnect, | |
324 kFuncNameDisconnect, | |
325 kFuncNameLocalize, | |
326 kAttrNameDisconnected, | 312 kAttrNameDisconnected, |
327 kAttrNameStarting, | 313 kAttrNameStarting, |
328 kAttrNameRequestedAccessCode, | 314 kAttrNameRequestedAccessCode, |
329 kAttrNameReceivedAccessCode, | 315 kAttrNameReceivedAccessCode, |
330 kAttrNameConnected, | 316 kAttrNameConnected, |
331 kAttrNameDisconnecting, | 317 kAttrNameDisconnecting, |
332 kAttrNameError | 318 kAttrNameError, |
319 kFuncNameConnect, | |
320 kFuncNameDisconnect, | |
321 kFuncNameLocalize, | |
322 kFuncNameStartDaemon, | |
323 kFuncNameStopDaemon | |
333 }; | 324 }; |
334 for (size_t i = 0; i < arraysize(entries); ++i) { | 325 for (size_t i = 0; i < arraysize(entries); ++i) { |
335 values->push_back(entries[i]); | 326 values->push_back(entries[i]); |
336 } | 327 } |
337 return true; | 328 return true; |
338 } | 329 } |
339 | 330 |
340 void HostNPScriptObject::OnAccessDenied(const std::string& jid) { | 331 void HostNPScriptObject::OnAccessDenied(const std::string& jid) { |
341 DCHECK(host_context_.network_message_loop()->BelongsToCurrentThread()); | 332 DCHECK(host_context_.network_message_loop()->BelongsToCurrentThread()); |
342 | 333 |
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
559 if (NPVARIANT_IS_OBJECT(args[0])) { | 550 if (NPVARIANT_IS_OBJECT(args[0])) { |
560 ScopedRefNPObject localize_func(NPVARIANT_TO_OBJECT(args[0])); | 551 ScopedRefNPObject localize_func(NPVARIANT_TO_OBJECT(args[0])); |
561 LocalizeStrings(localize_func.get()); | 552 LocalizeStrings(localize_func.get()); |
562 return true; | 553 return true; |
563 } else { | 554 } else { |
564 SetException("localize: unexpected type for argument 1"); | 555 SetException("localize: unexpected type for argument 1"); |
565 return false; | 556 return false; |
566 } | 557 } |
567 } | 558 } |
568 | 559 |
560 bool HostNPScriptObject::StartDaemon(const NPVariant* args, | |
561 uint32_t arg_count, | |
562 NPVariant* result) { | |
563 if (arg_count != 1) { | |
564 SetException("startDaemon: bad number of arguments"); | |
565 return false; | |
566 } | |
567 if (NPVARIANT_IS_STRING(args[0])) { | |
568 NPString pin = NPVARIANT_TO_STRING(args[0]); | |
569 daemon_npapi_->Start( | |
570 std::string(pin.UTF8Characters, pin.UTF8Length).c_str()); | |
Wez
2012/02/03 01:25:36
Definitely cleaner for Start() to accept a std::st
Jamie
2012/02/03 01:40:15
Done.
| |
571 return true; | |
572 } else { | |
573 SetException("startDaemon: unexpected type for argument 1"); | |
574 return false; | |
575 } | |
576 } | |
577 | |
578 bool HostNPScriptObject::StopDaemon(const NPVariant* args, | |
579 uint32_t arg_count, | |
580 NPVariant* result) { | |
581 if (arg_count != 0) { | |
582 SetException("startDaemon: bad number of arguments"); | |
583 return false; | |
584 } | |
585 daemon_npapi_->Stop(); | |
586 return true; | |
587 } | |
588 | |
569 void HostNPScriptObject::DisconnectInternal() { | 589 void HostNPScriptObject::DisconnectInternal() { |
570 if (!host_context_.network_message_loop()->BelongsToCurrentThread()) { | 590 if (!host_context_.network_message_loop()->BelongsToCurrentThread()) { |
571 host_context_.network_message_loop()->PostTask( | 591 host_context_.network_message_loop()->PostTask( |
572 FROM_HERE, base::Bind(&HostNPScriptObject::DisconnectInternal, | 592 FROM_HERE, base::Bind(&HostNPScriptObject::DisconnectInternal, |
573 base::Unretained(this))); | 593 base::Unretained(this))); |
574 return; | 594 return; |
575 } | 595 } |
576 | 596 |
577 switch (state_) { | 597 switch (state_) { |
578 case kDisconnected: | 598 case kDisconnected: |
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
836 uint32_t argCount) { | 856 uint32_t argCount) { |
837 NPVariant np_result; | 857 NPVariant np_result; |
838 bool is_good = g_npnetscape_funcs->invokeDefault(plugin_, func, args, | 858 bool is_good = g_npnetscape_funcs->invokeDefault(plugin_, func, args, |
839 argCount, &np_result); | 859 argCount, &np_result); |
840 if (is_good) | 860 if (is_good) |
841 g_npnetscape_funcs->releasevariantvalue(&np_result); | 861 g_npnetscape_funcs->releasevariantvalue(&np_result); |
842 return is_good; | 862 return is_good; |
843 } | 863 } |
844 | 864 |
845 } // namespace remoting | 865 } // namespace remoting |
OLD | NEW |