Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(399)

Side by Side Diff: remoting/host/plugin/host_script_object.cc

Issue 340993002: Revert of Remove NPAPI plugin from chromoting webapp. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « remoting/host/plugin/host_script_object.h ('k') | remoting/host/win/version.rc.jinja2 » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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 #include "remoting/host/plugin/host_script_object.h"
6
7 #include "base/bind.h"
8 #include "base/json/json_reader.h"
9 #include "base/json/json_writer.h"
10 #include "base/strings/string_util.h"
11 #include "base/strings/stringprintf.h"
12 #include "base/strings/sys_string_conversions.h"
13 #include "base/strings/utf_string_conversions.h"
14 #include "remoting/base/auth_token_util.h"
15 #include "remoting/base/auto_thread.h"
16 #include "remoting/base/logging.h"
17 #include "remoting/base/resources.h"
18 #include "remoting/base/rsa_key_pair.h"
19 #include "remoting/host/chromoting_host_context.h"
20 #include "remoting/host/host_config.h"
21 #include "remoting/host/pairing_registry_delegate.h"
22 #include "remoting/host/pin_hash.h"
23 #include "remoting/host/plugin/host_log_handler.h"
24 #include "remoting/host/policy_hack/policy_watcher.h"
25 #include "remoting/host/service_urls.h"
26 #include "third_party/npapi/bindings/npapi.h"
27 #include "third_party/npapi/bindings/npfunctions.h"
28 #include "third_party/npapi/bindings/npruntime.h"
29
30 namespace remoting {
31
32 namespace {
33
34 const char* kAttrNameAccessCode = "accessCode";
35 const char* kAttrNameAccessCodeLifetime = "accessCodeLifetime";
36 const char* kAttrNameClient = "client";
37 const char* kAttrNameDaemonState = "daemonState";
38 const char* kAttrNameState = "state";
39 const char* kAttrNameLogDebugInfo = "logDebugInfo";
40 const char* kAttrNameOnNatTraversalPolicyChanged =
41 "onNatTraversalPolicyChanged";
42 const char* kAttrNameOnStateChanged = "onStateChanged";
43 const char* kAttrNameXmppServerAddress = "xmppServerAddress";
44 const char* kAttrNameXmppServerUseTls = "xmppServerUseTls";
45 const char* kAttrNameDirectoryBotJid = "directoryBotJid";
46 const char* kAttrNameSupportedFeatures = "supportedFeatures";
47 const char* kFuncNameConnect = "connect";
48 const char* kFuncNameDisconnect = "disconnect";
49 const char* kFuncNameLocalize = "localize";
50 const char* kFuncNameClearPairedClients = "clearPairedClients";
51 const char* kFuncNameDeletePairedClient = "deletePairedClient";
52 const char* kFuncNameGetHostName = "getHostName";
53 const char* kFuncNameGetPinHash = "getPinHash";
54 const char* kFuncNameGenerateKeyPair = "generateKeyPair";
55 const char* kFuncNameUpdateDaemonConfig = "updateDaemonConfig";
56 const char* kFuncNameGetDaemonConfig = "getDaemonConfig";
57 const char* kFuncNameGetDaemonVersion = "getDaemonVersion";
58 const char* kFuncNameGetPairedClients = "getPairedClients";
59 const char* kFuncNameGetUsageStatsConsent = "getUsageStatsConsent";
60 const char* kFuncNameInstallHost = "installHost";
61 const char* kFuncNameStartDaemon = "startDaemon";
62 const char* kFuncNameStopDaemon = "stopDaemon";
63
64 // States.
65 const char* kAttrNameDisconnected = "DISCONNECTED";
66 const char* kAttrNameStarting = "STARTING";
67 const char* kAttrNameRequestedAccessCode = "REQUESTED_ACCESS_CODE";
68 const char* kAttrNameReceivedAccessCode = "RECEIVED_ACCESS_CODE";
69 const char* kAttrNameConnected = "CONNECTED";
70 const char* kAttrNameDisconnecting = "DISCONNECTING";
71 const char* kAttrNameError = "ERROR";
72 const char* kAttrNameInvalidDomainError = "INVALID_DOMAIN_ERROR";
73
74 // Space separated list of features supported in addition to the base protocol.
75 const char* kSupportedFeatures = "pairingRegistry";
76
77 } // namespace
78
79 HostNPScriptObject::HostNPScriptObject(
80 NPP plugin,
81 NPObject* parent,
82 scoped_refptr<AutoThreadTaskRunner> plugin_task_runner)
83 : plugin_(plugin),
84 parent_(parent),
85 plugin_task_runner_(plugin_task_runner),
86 am_currently_logging_(false),
87 state_(kDisconnected),
88 weak_factory_(this) {
89 DCHECK(plugin_task_runner_->BelongsToCurrentThread());
90
91 weak_ptr_ = weak_factory_.GetWeakPtr();
92
93 // Set the thread task runner for the plugin thread so that timers and other
94 // code using |base::ThreadTaskRunnerHandle| could be used on the plugin
95 // thread.
96 //
97 // If component build is used, Chrome and the plugin may end up sharing base
98 // binary. This means that the instance of |base::ThreadTaskRunnerHandle|
99 // created by Chrome for the current thread is shared as well. This routinely
100 // happens in the development setting so the below check for
101 // |!base::ThreadTaskRunnerHandle::IsSet()| is a hack/workaround allowing this
102 // configuration to work. It lets the plugin to access Chrome's message loop
103 // directly via |base::ThreadTaskRunnerHandle|. This is safe as long as both
104 // Chrome and the plugin are built from the same version of the sources.
105 if (!base::ThreadTaskRunnerHandle::IsSet()) {
106 plugin_task_runner_handle_.reset(
107 new base::ThreadTaskRunnerHandle(plugin_task_runner_));
108 }
109
110 daemon_controller_ = DaemonController::Create();
111
112 ServiceUrls* service_urls = ServiceUrls::GetInstance();
113 bool xmpp_server_valid = net::ParseHostAndPort(
114 service_urls->xmpp_server_address(),
115 &xmpp_server_config_.host, &xmpp_server_config_.port);
116 // For the plugin, this is always the default address, which must be valid.
117 DCHECK(xmpp_server_valid);
118 xmpp_server_config_.use_tls = service_urls->xmpp_server_use_tls();
119 directory_bot_jid_ = service_urls->directory_bot_jid();
120
121 // Create worker thread for encryption key generation and loading the paired
122 // clients.
123 worker_thread_ = AutoThread::Create("ChromotingWorkerThread",
124 plugin_task_runner_);
125
126 pairing_registry_ = CreatePairingRegistry(worker_thread_);
127 }
128
129 HostNPScriptObject::~HostNPScriptObject() {
130 DCHECK(plugin_task_runner_->BelongsToCurrentThread());
131
132 HostLogHandler::UnregisterLoggingScriptObject(this);
133
134 // Stop the It2Me host if the caller forgot to.
135 if (it2me_host_.get()) {
136 it2me_host_->Disconnect();
137 it2me_host_ = NULL;
138 }
139 }
140
141 bool HostNPScriptObject::HasMethod(const std::string& method_name) {
142 VLOG(2) << "HasMethod " << method_name;
143 DCHECK(plugin_task_runner_->BelongsToCurrentThread());
144 return (method_name == kFuncNameConnect ||
145 method_name == kFuncNameDisconnect ||
146 method_name == kFuncNameLocalize ||
147 method_name == kFuncNameClearPairedClients ||
148 method_name == kFuncNameDeletePairedClient ||
149 method_name == kFuncNameGetHostName ||
150 method_name == kFuncNameGetPinHash ||
151 method_name == kFuncNameGenerateKeyPair ||
152 method_name == kFuncNameUpdateDaemonConfig ||
153 method_name == kFuncNameGetDaemonConfig ||
154 method_name == kFuncNameGetDaemonVersion ||
155 method_name == kFuncNameGetPairedClients ||
156 method_name == kFuncNameGetUsageStatsConsent ||
157 method_name == kFuncNameInstallHost ||
158 method_name == kFuncNameStartDaemon ||
159 method_name == kFuncNameStopDaemon);
160 }
161
162 bool HostNPScriptObject::InvokeDefault(const NPVariant* args,
163 uint32_t arg_count,
164 NPVariant* result) {
165 VLOG(2) << "InvokeDefault";
166 DCHECK(plugin_task_runner_->BelongsToCurrentThread());
167 SetException("exception during default invocation");
168 return false;
169 }
170
171 bool HostNPScriptObject::Invoke(const std::string& method_name,
172 const NPVariant* args,
173 uint32_t arg_count,
174 NPVariant* result) {
175 VLOG(2) << "Invoke " << method_name;
176 DCHECK(plugin_task_runner_->BelongsToCurrentThread());
177 if (method_name == kFuncNameConnect) {
178 return Connect(args, arg_count, result);
179 } else if (method_name == kFuncNameDisconnect) {
180 return Disconnect(args, arg_count, result);
181 } else if (method_name == kFuncNameLocalize) {
182 return Localize(args, arg_count, result);
183 } else if (method_name == kFuncNameClearPairedClients) {
184 return ClearPairedClients(args, arg_count, result);
185 } else if (method_name == kFuncNameDeletePairedClient) {
186 return DeletePairedClient(args, arg_count, result);
187 } else if (method_name == kFuncNameGetHostName) {
188 return GetHostName(args, arg_count, result);
189 } else if (method_name == kFuncNameGetPinHash) {
190 return GetPinHash(args, arg_count, result);
191 } else if (method_name == kFuncNameGenerateKeyPair) {
192 return GenerateKeyPair(args, arg_count, result);
193 } else if (method_name == kFuncNameUpdateDaemonConfig) {
194 return UpdateDaemonConfig(args, arg_count, result);
195 } else if (method_name == kFuncNameGetDaemonConfig) {
196 return GetDaemonConfig(args, arg_count, result);
197 } else if (method_name == kFuncNameGetDaemonVersion) {
198 return GetDaemonVersion(args, arg_count, result);
199 } else if (method_name == kFuncNameGetPairedClients) {
200 return GetPairedClients(args, arg_count, result);
201 } else if (method_name == kFuncNameGetUsageStatsConsent) {
202 return GetUsageStatsConsent(args, arg_count, result);
203 } else if (method_name == kFuncNameInstallHost) {
204 return InstallHost(args, arg_count, result);
205 } else if (method_name == kFuncNameStartDaemon) {
206 return StartDaemon(args, arg_count, result);
207 } else if (method_name == kFuncNameStopDaemon) {
208 return StopDaemon(args, arg_count, result);
209 } else {
210 SetException("Invoke: unknown method " + method_name);
211 return false;
212 }
213 }
214
215 bool HostNPScriptObject::HasProperty(const std::string& property_name) {
216 VLOG(2) << "HasProperty " << property_name;
217 DCHECK(plugin_task_runner_->BelongsToCurrentThread());
218 return (property_name == kAttrNameAccessCode ||
219 property_name == kAttrNameAccessCodeLifetime ||
220 property_name == kAttrNameClient ||
221 property_name == kAttrNameDaemonState ||
222 property_name == kAttrNameState ||
223 property_name == kAttrNameLogDebugInfo ||
224 property_name == kAttrNameOnNatTraversalPolicyChanged ||
225 property_name == kAttrNameOnStateChanged ||
226 property_name == kAttrNameDisconnected ||
227 property_name == kAttrNameStarting ||
228 property_name == kAttrNameRequestedAccessCode ||
229 property_name == kAttrNameReceivedAccessCode ||
230 property_name == kAttrNameConnected ||
231 property_name == kAttrNameDisconnecting ||
232 property_name == kAttrNameError ||
233 property_name == kAttrNameXmppServerAddress ||
234 property_name == kAttrNameXmppServerUseTls ||
235 property_name == kAttrNameDirectoryBotJid ||
236 property_name == kAttrNameSupportedFeatures);
237 }
238
239 bool HostNPScriptObject::GetProperty(const std::string& property_name,
240 NPVariant* result) {
241 VLOG(2) << "GetProperty " << property_name;
242 DCHECK(plugin_task_runner_->BelongsToCurrentThread());
243 if (!result) {
244 SetException("GetProperty: NULL result");
245 return false;
246 }
247
248 if (property_name == kAttrNameOnNatTraversalPolicyChanged) {
249 OBJECT_TO_NPVARIANT(on_nat_traversal_policy_changed_func_.get(), *result);
250 return true;
251 } else if (property_name == kAttrNameOnStateChanged) {
252 OBJECT_TO_NPVARIANT(on_state_changed_func_.get(), *result);
253 return true;
254 } else if (property_name == kAttrNameLogDebugInfo) {
255 OBJECT_TO_NPVARIANT(log_debug_info_func_.get(), *result);
256 return true;
257 } else if (property_name == kAttrNameState) {
258 INT32_TO_NPVARIANT(state_, *result);
259 return true;
260 } else if (property_name == kAttrNameAccessCode) {
261 *result = NPVariantFromString(access_code_);
262 return true;
263 } else if (property_name == kAttrNameAccessCodeLifetime) {
264 INT32_TO_NPVARIANT(access_code_lifetime_.InSeconds(), *result);
265 return true;
266 } else if (property_name == kAttrNameClient) {
267 *result = NPVariantFromString(client_username_);
268 return true;
269 } else if (property_name == kAttrNameDaemonState) {
270 INT32_TO_NPVARIANT(daemon_controller_->GetState(), *result);
271 return true;
272 } else if (property_name == kAttrNameDisconnected) {
273 INT32_TO_NPVARIANT(kDisconnected, *result);
274 return true;
275 } else if (property_name == kAttrNameStarting) {
276 INT32_TO_NPVARIANT(kStarting, *result);
277 return true;
278 } else if (property_name == kAttrNameRequestedAccessCode) {
279 INT32_TO_NPVARIANT(kRequestedAccessCode, *result);
280 return true;
281 } else if (property_name == kAttrNameReceivedAccessCode) {
282 INT32_TO_NPVARIANT(kReceivedAccessCode, *result);
283 return true;
284 } else if (property_name == kAttrNameConnected) {
285 INT32_TO_NPVARIANT(kConnected, *result);
286 return true;
287 } else if (property_name == kAttrNameDisconnecting) {
288 INT32_TO_NPVARIANT(kDisconnecting, *result);
289 return true;
290 } else if (property_name == kAttrNameError) {
291 INT32_TO_NPVARIANT(kError, *result);
292 return true;
293 } else if (property_name == kAttrNameInvalidDomainError) {
294 INT32_TO_NPVARIANT(kInvalidDomainError, *result);
295 return true;
296 } else if (property_name == kAttrNameXmppServerAddress) {
297 *result = NPVariantFromString(base::StringPrintf(
298 "%s:%u", xmpp_server_config_.host.c_str(), xmpp_server_config_.port));
299 return true;
300 } else if (property_name == kAttrNameXmppServerUseTls) {
301 BOOLEAN_TO_NPVARIANT(xmpp_server_config_.use_tls, *result);
302 return true;
303 } else if (property_name == kAttrNameDirectoryBotJid) {
304 *result = NPVariantFromString(directory_bot_jid_);
305 return true;
306 } else if (property_name == kAttrNameSupportedFeatures) {
307 *result = NPVariantFromString(kSupportedFeatures);
308 return true;
309 } else {
310 SetException("GetProperty: unsupported property " + property_name);
311 return false;
312 }
313 }
314
315 bool HostNPScriptObject::SetProperty(const std::string& property_name,
316 const NPVariant* value) {
317 VLOG(2) << "SetProperty " << property_name;
318 DCHECK(plugin_task_runner_->BelongsToCurrentThread());
319
320 if (property_name == kAttrNameOnNatTraversalPolicyChanged) {
321 if (NPVARIANT_IS_OBJECT(*value)) {
322 on_nat_traversal_policy_changed_func_ = NPVARIANT_TO_OBJECT(*value);
323 if (it2me_host_.get()) {
324 // Ask the It2Me host to notify the web-app of the policy.
325 it2me_host_->RequestNatPolicy();
326 }
327 return true;
328 } else {
329 SetException("SetProperty: unexpected type for property " +
330 property_name);
331 }
332 return false;
333 }
334
335 if (property_name == kAttrNameOnStateChanged) {
336 if (NPVARIANT_IS_OBJECT(*value)) {
337 on_state_changed_func_ = NPVARIANT_TO_OBJECT(*value);
338 return true;
339 } else {
340 SetException("SetProperty: unexpected type for property " +
341 property_name);
342 }
343 return false;
344 }
345
346 if (property_name == kAttrNameLogDebugInfo) {
347 if (NPVARIANT_IS_OBJECT(*value)) {
348 log_debug_info_func_ = NPVARIANT_TO_OBJECT(*value);
349 HostLogHandler::RegisterLoggingScriptObject(this);
350 return true;
351 } else {
352 SetException("SetProperty: unexpected type for property " +
353 property_name);
354 }
355 return false;
356 }
357
358 #if !defined(NDEBUG)
359 if (property_name == kAttrNameXmppServerAddress) {
360 if (NPVARIANT_IS_STRING(*value)) {
361 std::string address = StringFromNPVariant(*value);
362 bool xmpp_server_valid = net::ParseHostAndPort(
363 address, &xmpp_server_config_.host, &xmpp_server_config_.port);
364 if (xmpp_server_valid) {
365 return true;
366 } else {
367 SetException("SetProperty: invalid value for property " +
368 property_name);
369 }
370 } else {
371 SetException("SetProperty: unexpected type for property " +
372 property_name);
373 }
374 return false;
375 }
376
377 if (property_name == kAttrNameXmppServerUseTls) {
378 if (NPVARIANT_IS_BOOLEAN(*value)) {
379 xmpp_server_config_.use_tls = NPVARIANT_TO_BOOLEAN(*value);
380 return true;
381 } else {
382 SetException("SetProperty: unexpected type for property " +
383 property_name);
384 }
385 return false;
386 }
387
388 if (property_name == kAttrNameDirectoryBotJid) {
389 if (NPVARIANT_IS_STRING(*value)) {
390 directory_bot_jid_ = StringFromNPVariant(*value);
391 return true;
392 } else {
393 SetException("SetProperty: unexpected type for property " +
394 property_name);
395 }
396 return false;
397 }
398 #endif // !defined(NDEBUG)
399
400 return false;
401 }
402
403 bool HostNPScriptObject::RemoveProperty(const std::string& property_name) {
404 VLOG(2) << "RemoveProperty " << property_name;
405 DCHECK(plugin_task_runner_->BelongsToCurrentThread());
406 return false;
407 }
408
409 bool HostNPScriptObject::Enumerate(std::vector<std::string>* values) {
410 VLOG(2) << "Enumerate";
411 DCHECK(plugin_task_runner_->BelongsToCurrentThread());
412 const char* entries[] = {
413 kAttrNameAccessCode,
414 kAttrNameState,
415 kAttrNameLogDebugInfo,
416 kAttrNameOnStateChanged,
417 kAttrNameDisconnected,
418 kAttrNameStarting,
419 kAttrNameRequestedAccessCode,
420 kAttrNameReceivedAccessCode,
421 kAttrNameConnected,
422 kAttrNameDisconnecting,
423 kAttrNameError,
424 kAttrNameXmppServerAddress,
425 kAttrNameXmppServerUseTls,
426 kAttrNameDirectoryBotJid,
427 kFuncNameConnect,
428 kFuncNameDisconnect,
429 kFuncNameLocalize,
430 kFuncNameClearPairedClients,
431 kFuncNameDeletePairedClient,
432 kFuncNameGetHostName,
433 kFuncNameGetPinHash,
434 kFuncNameGenerateKeyPair,
435 kFuncNameUpdateDaemonConfig,
436 kFuncNameGetDaemonConfig,
437 kFuncNameGetDaemonVersion,
438 kFuncNameGetPairedClients,
439 kFuncNameGetUsageStatsConsent,
440 kFuncNameInstallHost,
441 kFuncNameStartDaemon,
442 kFuncNameStopDaemon
443 };
444 for (size_t i = 0; i < arraysize(entries); ++i) {
445 values->push_back(entries[i]);
446 }
447 return true;
448 }
449
450 // string username, string auth_token
451 bool HostNPScriptObject::Connect(const NPVariant* args,
452 uint32_t arg_count,
453 NPVariant* result) {
454 DCHECK(plugin_task_runner_->BelongsToCurrentThread());
455
456 HOST_LOG << "Connecting...";
457
458 if (arg_count != 2) {
459 SetException("connect: bad number of arguments");
460 return false;
461 }
462
463 if (it2me_host_.get()) {
464 SetException("connect: can be called only when disconnected");
465 return false;
466 }
467
468 XmppSignalStrategy::XmppServerConfig xmpp_config = xmpp_server_config_;
469
470 xmpp_config.username = StringFromNPVariant(args[0]);
471 if (xmpp_config.username.empty()) {
472 SetException("connect: bad username argument");
473 return false;
474 }
475
476 std::string auth_service_with_token = StringFromNPVariant(args[1]);
477 ParseAuthTokenWithService(auth_service_with_token, &xmpp_config.auth_token,
478 &xmpp_config.auth_service);
479 if (xmpp_config.auth_token.empty()) {
480 SetException("connect: auth_service_with_token argument has empty token");
481 return false;
482 }
483
484 // Create a host context to manage the threads for the it2me host.
485 // The plugin, rather than the It2MeHost object, owns and maintains the
486 // lifetime of the host context.
487 host_context_.reset(
488 ChromotingHostContext::Create(plugin_task_runner_).release());
489 if (!host_context_) {
490 SetException("connect: failed to start threads");
491 return false;
492 }
493
494 // Create the It2Me host and start connecting.
495 scoped_ptr<It2MeHostFactory> factory(new It2MeHostFactory());
496 it2me_host_ = factory->CreateIt2MeHost(
497 host_context_.get(), plugin_task_runner_, weak_ptr_,
498 xmpp_config, directory_bot_jid_);
499 it2me_host_->Connect();
500
501 return true;
502 }
503
504 bool HostNPScriptObject::Disconnect(const NPVariant* args,
505 uint32_t arg_count,
506 NPVariant* result) {
507 DCHECK(plugin_task_runner_->BelongsToCurrentThread());
508 if (arg_count != 0) {
509 SetException("disconnect: bad number of arguments");
510 return false;
511 }
512
513 if (it2me_host_.get()) {
514 it2me_host_->Disconnect();
515 it2me_host_ = NULL;
516 }
517
518 return true;
519 }
520
521 bool HostNPScriptObject::Localize(const NPVariant* args,
522 uint32_t arg_count,
523 NPVariant* result) {
524 DCHECK(plugin_task_runner_->BelongsToCurrentThread());
525 if (arg_count != 1) {
526 SetException("localize: bad number of arguments");
527 return false;
528 }
529
530 if (NPVARIANT_IS_OBJECT(args[0])) {
531 ScopedRefNPObject localize_func(NPVARIANT_TO_OBJECT(args[0]));
532 LocalizeStrings(localize_func.get());
533 return true;
534 } else {
535 SetException("localize: unexpected type for argument 1");
536 return false;
537 }
538 }
539
540 bool HostNPScriptObject::ClearPairedClients(const NPVariant* args,
541 uint32_t arg_count,
542 NPVariant* result) {
543 if (arg_count != 1) {
544 SetException("clearPairedClients: bad number of arguments");
545 return false;
546 }
547
548 if (!NPVARIANT_IS_OBJECT(args[0])) {
549 SetException("clearPairedClients: invalid callback parameter");
550 return false;
551 }
552
553 scoped_ptr<ScopedRefNPObject> callback_obj(
554 new ScopedRefNPObject(ObjectFromNPVariant(args[0])));
555 if (pairing_registry_) {
556 pairing_registry_->ClearAllPairings(
557 base::Bind(&HostNPScriptObject::InvokeBooleanCallback, weak_ptr_,
558 base::Passed(&callback_obj)));
559 } else {
560 InvokeBooleanCallback(callback_obj.Pass(), false);
561 }
562
563 return true;
564 }
565
566 bool HostNPScriptObject::DeletePairedClient(const NPVariant* args,
567 uint32_t arg_count,
568 NPVariant* result) {
569 if (arg_count != 2) {
570 SetException("deletePairedClient: bad number of arguments");
571 return false;
572 }
573
574 if (!NPVARIANT_IS_STRING(args[0])) {
575 SetException("deletePairedClient: bad clientId parameter");
576 return false;
577 }
578
579 if (!NPVARIANT_IS_OBJECT(args[1])) {
580 SetException("deletePairedClient: invalid callback parameter");
581 return false;
582 }
583
584 std::string client_id = StringFromNPVariant(args[0]);
585 scoped_ptr<ScopedRefNPObject> callback_obj(
586 new ScopedRefNPObject(ObjectFromNPVariant(args[1])));
587 if (pairing_registry_) {
588 pairing_registry_->DeletePairing(
589 client_id,
590 base::Bind(&HostNPScriptObject::InvokeBooleanCallback,
591 weak_ptr_, base::Passed(&callback_obj)));
592 } else {
593 InvokeBooleanCallback(callback_obj.Pass(), false);
594 }
595
596 return true;
597 }
598
599 bool HostNPScriptObject::GetHostName(const NPVariant* args,
600 uint32_t arg_count,
601 NPVariant* result) {
602 if (arg_count != 1) {
603 SetException("getHostName: bad number of arguments");
604 return false;
605 }
606
607 ScopedRefNPObject callback_obj(ObjectFromNPVariant(args[0]));
608 if (!callback_obj.get()) {
609 SetException("getHostName: invalid callback parameter");
610 return false;
611 }
612
613 NPVariant host_name_val = NPVariantFromString(net::GetHostName());
614 InvokeAndIgnoreResult(callback_obj, &host_name_val, 1);
615 g_npnetscape_funcs->releasevariantvalue(&host_name_val);
616
617 return true;
618 }
619
620 bool HostNPScriptObject::GetPinHash(const NPVariant* args,
621 uint32_t arg_count,
622 NPVariant* result) {
623 if (arg_count != 3) {
624 SetException("getPinHash: bad number of arguments");
625 return false;
626 }
627
628 std::string host_id = StringFromNPVariant(args[0]);
629 if (host_id.empty()) {
630 SetException("getPinHash: bad hostId parameter");
631 return false;
632 }
633
634 if (!NPVARIANT_IS_STRING(args[1])) {
635 SetException("getPinHash: bad pin parameter");
636 return false;
637 }
638 std::string pin = StringFromNPVariant(args[1]);
639
640 ScopedRefNPObject callback_obj(ObjectFromNPVariant(args[2]));
641 if (!callback_obj.get()) {
642 SetException("getPinHash: invalid callback parameter");
643 return false;
644 }
645
646 NPVariant pin_hash_val = NPVariantFromString(
647 remoting::MakeHostPinHash(host_id, pin));
648 InvokeAndIgnoreResult(callback_obj, &pin_hash_val, 1);
649 g_npnetscape_funcs->releasevariantvalue(&pin_hash_val);
650
651 return true;
652 }
653
654 bool HostNPScriptObject::GenerateKeyPair(const NPVariant* args,
655 uint32_t arg_count,
656 NPVariant* result) {
657 if (arg_count != 1) {
658 SetException("generateKeyPair: bad number of arguments");
659 return false;
660 }
661
662 scoped_ptr<ScopedRefNPObject> callback_obj(
663 new ScopedRefNPObject(ObjectFromNPVariant(args[0])));
664 if (!callback_obj->get()) {
665 SetException("generateKeyPair: invalid callback parameter");
666 return false;
667 }
668
669 base::Callback<void (const std::string&,
670 const std::string&)> wrapped_callback =
671 base::Bind(&HostNPScriptObject::InvokeGenerateKeyPairCallback, weak_ptr_,
672 base::Passed(&callback_obj));
673 worker_thread_->PostTask(
674 FROM_HERE, base::Bind(&HostNPScriptObject::DoGenerateKeyPair,
675 plugin_task_runner_, wrapped_callback));
676 return true;
677 }
678
679 bool HostNPScriptObject::UpdateDaemonConfig(const NPVariant* args,
680 uint32_t arg_count,
681 NPVariant* result) {
682 if (arg_count != 2) {
683 SetException("updateDaemonConfig: bad number of arguments");
684 return false;
685 }
686
687 std::string config_str = StringFromNPVariant(args[0]);
688 scoped_ptr<base::Value> config(
689 base::JSONReader::Read(config_str, base::JSON_ALLOW_TRAILING_COMMAS));
690 if (config_str.empty() || !config.get() ||
691 !config->IsType(base::Value::TYPE_DICTIONARY)) {
692 SetException("updateDaemonConfig: bad config parameter");
693 return false;
694 }
695 scoped_ptr<base::DictionaryValue> config_dict(
696 reinterpret_cast<base::DictionaryValue*>(config.release()));
697
698 scoped_ptr<ScopedRefNPObject> callback_obj(
699 new ScopedRefNPObject(ObjectFromNPVariant(args[1])));
700 if (!callback_obj->get()) {
701 SetException("updateDaemonConfig: invalid callback parameter");
702 return false;
703 }
704
705 if (config_dict->HasKey(kHostIdConfigPath) ||
706 config_dict->HasKey(kXmppLoginConfigPath)) {
707 SetException("updateDaemonConfig: trying to update immutable config "
708 "parameters");
709 return false;
710 }
711
712 daemon_controller_->UpdateConfig(
713 config_dict.Pass(),
714 base::Bind(&HostNPScriptObject::InvokeAsyncResultCallback, weak_ptr_,
715 base::Passed(&callback_obj)));
716 return true;
717 }
718
719 bool HostNPScriptObject::GetDaemonConfig(const NPVariant* args,
720 uint32_t arg_count,
721 NPVariant* result) {
722 if (arg_count != 1) {
723 SetException("getDaemonConfig: bad number of arguments");
724 return false;
725 }
726
727 scoped_ptr<ScopedRefNPObject> callback_obj(
728 new ScopedRefNPObject(ObjectFromNPVariant(args[0])));
729 if (!callback_obj->get()) {
730 SetException("getDaemonConfig: invalid callback parameter");
731 return false;
732 }
733
734 daemon_controller_->GetConfig(
735 base::Bind(&HostNPScriptObject::InvokeGetDaemonConfigCallback, weak_ptr_,
736 base::Passed(&callback_obj)));
737 return true;
738 }
739
740 bool HostNPScriptObject::GetDaemonVersion(const NPVariant* args,
741 uint32_t arg_count,
742 NPVariant* result) {
743 if (arg_count != 1) {
744 SetException("getDaemonVersion: bad number of arguments");
745 return false;
746 }
747
748 scoped_ptr<ScopedRefNPObject> callback_obj(
749 new ScopedRefNPObject(ObjectFromNPVariant(args[0])));
750 if (!callback_obj->get()) {
751 SetException("getDaemonVersion: invalid callback parameter");
752 return false;
753 }
754
755 daemon_controller_->GetVersion(
756 base::Bind(&HostNPScriptObject::InvokeGetDaemonVersionCallback, weak_ptr_,
757 base::Passed(&callback_obj)));
758
759 return true;
760 }
761
762 bool HostNPScriptObject::GetPairedClients(const NPVariant* args,
763 uint32_t arg_count,
764 NPVariant* result) {
765 if (arg_count != 1) {
766 SetException("getPairedClients: bad number of arguments");
767 return false;
768 }
769
770 scoped_ptr<ScopedRefNPObject> callback_obj(
771 new ScopedRefNPObject(ObjectFromNPVariant(args[0])));
772 if (!callback_obj->get()) {
773 SetException("getPairedClients: invalid callback parameter");
774 return false;
775 }
776
777 if (pairing_registry_) {
778 pairing_registry_->GetAllPairings(
779 base::Bind(&HostNPScriptObject::InvokeGetPairedClientsCallback,
780 weak_ptr_, base::Passed(&callback_obj)));
781 } else {
782 scoped_ptr<base::ListValue> no_paired_clients(new base::ListValue);
783 InvokeGetPairedClientsCallback(callback_obj.Pass(),
784 no_paired_clients.Pass());
785 }
786 return true;
787 }
788
789 bool HostNPScriptObject::GetUsageStatsConsent(const NPVariant* args,
790 uint32_t arg_count,
791 NPVariant* result) {
792 if (arg_count != 1) {
793 SetException("getUsageStatsConsent: bad number of arguments");
794 return false;
795 }
796
797 scoped_ptr<ScopedRefNPObject> callback_obj(
798 new ScopedRefNPObject(ObjectFromNPVariant(args[0])));
799 if (!callback_obj->get()) {
800 SetException("getUsageStatsConsent: invalid callback parameter");
801 return false;
802 }
803
804 daemon_controller_->GetUsageStatsConsent(
805 base::Bind(&HostNPScriptObject::InvokeGetUsageStatsConsentCallback,
806 weak_ptr_, base::Passed(&callback_obj)));
807 return true;
808 }
809
810 bool HostNPScriptObject::InstallHost(const NPVariant* args,
811 uint32_t arg_count,
812 NPVariant* result) {
813 DCHECK(plugin_task_runner_->BelongsToCurrentThread());
814
815 if (arg_count != 1) {
816 SetException("installHost: bad number of arguments");
817 return false;
818 }
819
820 scoped_ptr<ScopedRefNPObject> callback_obj(
821 new ScopedRefNPObject(ObjectFromNPVariant(args[0])));
822 if (!callback_obj->get()) {
823 SetException("installHost: invalid callback parameter");
824 return false;
825 }
826
827 daemon_controller_->InstallHost(
828 base::Bind(&HostNPScriptObject::InvokeAsyncResultCallback, weak_ptr_,
829 base::Passed(&callback_obj)));
830 return true;
831 }
832
833 bool HostNPScriptObject::StartDaemon(const NPVariant* args,
834 uint32_t arg_count,
835 NPVariant* result) {
836 DCHECK(plugin_task_runner_->BelongsToCurrentThread());
837
838 if (arg_count != 3) {
839 SetException("startDaemon: bad number of arguments");
840 return false;
841 }
842
843 std::string config_str = StringFromNPVariant(args[0]);
844 scoped_ptr<base::Value> config(
845 base::JSONReader::Read(config_str, base::JSON_ALLOW_TRAILING_COMMAS));
846 if (config_str.empty() || !config.get() ||
847 !config->IsType(base::Value::TYPE_DICTIONARY)) {
848 SetException("startDaemon: bad config parameter");
849 return false;
850 }
851 scoped_ptr<base::DictionaryValue> config_dict(
852 reinterpret_cast<base::DictionaryValue*>(config.release()));
853
854 if (!NPVARIANT_IS_BOOLEAN(args[1])) {
855 SetException("startDaemon: invalid consent parameter");
856 return false;
857 }
858
859 scoped_ptr<ScopedRefNPObject> callback_obj(
860 new ScopedRefNPObject(ObjectFromNPVariant(args[2])));
861 if (!callback_obj->get()) {
862 SetException("startDaemon: invalid callback parameter");
863 return false;
864 }
865
866 daemon_controller_->SetConfigAndStart(
867 config_dict.Pass(),
868 NPVARIANT_TO_BOOLEAN(args[1]),
869 base::Bind(&HostNPScriptObject::InvokeAsyncResultCallback, weak_ptr_,
870 base::Passed(&callback_obj)));
871 return true;
872 }
873
874 bool HostNPScriptObject::StopDaemon(const NPVariant* args,
875 uint32_t arg_count,
876 NPVariant* result) {
877 DCHECK(plugin_task_runner_->BelongsToCurrentThread());
878
879 if (arg_count != 1) {
880 SetException("stopDaemon: bad number of arguments");
881 return false;
882 }
883
884 scoped_ptr<ScopedRefNPObject> callback_obj(
885 new ScopedRefNPObject(ObjectFromNPVariant(args[0])));
886 if (!callback_obj->get()) {
887 SetException("stopDaemon: invalid callback parameter");
888 return false;
889 }
890
891 daemon_controller_->Stop(
892 base::Bind(&HostNPScriptObject::InvokeAsyncResultCallback, weak_ptr_,
893 base::Passed(&callback_obj)));
894 return true;
895 }
896
897 void HostNPScriptObject::OnStateChanged(It2MeHostState state) {
898 DCHECK(plugin_task_runner_->BelongsToCurrentThread());
899
900 state_ = state;
901
902 if (state_ == kDisconnected)
903 client_username_.clear();
904
905 if (on_state_changed_func_.get()) {
906 NPVariant state_var;
907 INT32_TO_NPVARIANT(state, state_var);
908 InvokeAndIgnoreResult(on_state_changed_func_, &state_var, 1);
909 }
910 }
911
912 void HostNPScriptObject::OnNatPolicyChanged(bool nat_traversal_enabled) {
913 DCHECK(plugin_task_runner_->BelongsToCurrentThread());
914
915 if (on_nat_traversal_policy_changed_func_.get()) {
916 NPVariant policy;
917 BOOLEAN_TO_NPVARIANT(nat_traversal_enabled, policy);
918 InvokeAndIgnoreResult(on_nat_traversal_policy_changed_func_,
919 &policy, 1);
920 }
921 }
922
923 // Stores the Access Code for the web-app to query.
924 void HostNPScriptObject::OnStoreAccessCode(
925 const std::string& access_code, base::TimeDelta access_code_lifetime) {
926 DCHECK(plugin_task_runner_->BelongsToCurrentThread());
927
928 access_code_ = access_code;
929 access_code_lifetime_ = access_code_lifetime;
930 }
931
932 // Stores the client user's name for the web-app to query.
933 void HostNPScriptObject::OnClientAuthenticated(
934 const std::string& client_username) {
935 DCHECK(plugin_task_runner_->BelongsToCurrentThread());
936
937 client_username_ = client_username;
938 }
939
940 void HostNPScriptObject::PostLogDebugInfo(const std::string& message) {
941 if (plugin_task_runner_->BelongsToCurrentThread()) {
942 // Make sure we're not currently processing a log message.
943 // We only need to check this if we're on the plugin thread.
944 if (am_currently_logging_)
945 return;
946 }
947
948 // Always post (even if we're already on the correct thread) so that debug
949 // log messages are shown in the correct order.
950 plugin_task_runner_->PostTask(
951 FROM_HERE, base::Bind(&HostNPScriptObject::LogDebugInfo,
952 weak_ptr_, message));
953 }
954
955 void HostNPScriptObject::SetWindow(NPWindow* np_window) {
956 DCHECK(plugin_task_runner_->BelongsToCurrentThread());
957
958 daemon_controller_->SetWindow(np_window->window);
959 }
960
961 void HostNPScriptObject::LocalizeStrings(NPObject* localize_func) {
962 DCHECK(plugin_task_runner_->BelongsToCurrentThread());
963
964 // Reload resources for the current locale. The default UI locale is used on
965 // Windows.
966 #if !defined(OS_WIN)
967 base::string16 ui_locale;
968 LocalizeString(localize_func, "@@ui_locale", &ui_locale);
969 remoting::LoadResources(base::UTF16ToUTF8(ui_locale));
970 #endif // !defined(OS_WIN)
971 }
972
973 bool HostNPScriptObject::LocalizeString(NPObject* localize_func,
974 const char* tag,
975 base::string16* result) {
976 return LocalizeStringWithSubstitution(localize_func, tag, NULL, result);
977 }
978
979 bool HostNPScriptObject::LocalizeStringWithSubstitution(
980 NPObject* localize_func,
981 const char* tag,
982 const char* substitution,
983 base::string16* result) {
984 int argc = substitution ? 2 : 1;
985 scoped_ptr<NPVariant[]> args(new NPVariant[argc]);
986 STRINGZ_TO_NPVARIANT(tag, args[0]);
987 if (substitution) {
988 STRINGZ_TO_NPVARIANT(substitution, args[1]);
989 }
990 NPVariant np_result;
991 bool is_good = g_npnetscape_funcs->invokeDefault(
992 plugin_, localize_func, args.get(), argc, &np_result);
993 if (!is_good) {
994 LOG(ERROR) << "Localization failed for " << tag;
995 return false;
996 }
997 std::string translation = StringFromNPVariant(np_result);
998 g_npnetscape_funcs->releasevariantvalue(&np_result);
999 if (translation.empty()) {
1000 LOG(ERROR) << "Missing translation for " << tag;
1001 return false;
1002 }
1003 *result = base::UTF8ToUTF16(translation);
1004 return true;
1005 }
1006
1007 // static
1008 void HostNPScriptObject::DoGenerateKeyPair(
1009 const scoped_refptr<AutoThreadTaskRunner>& plugin_task_runner,
1010 const base::Callback<void (const std::string&,
1011 const std::string&)>& callback) {
1012 scoped_refptr<RsaKeyPair> key_pair = RsaKeyPair::Generate();
1013 plugin_task_runner->PostTask(FROM_HERE,
1014 base::Bind(callback, key_pair->ToString(),
1015 key_pair->GetPublicKey()));
1016 }
1017
1018 void HostNPScriptObject::InvokeGenerateKeyPairCallback(
1019 scoped_ptr<ScopedRefNPObject> callback,
1020 const std::string& private_key,
1021 const std::string& public_key) {
1022 DCHECK(plugin_task_runner_->BelongsToCurrentThread());
1023
1024 NPVariant params[2];
1025 params[0] = NPVariantFromString(private_key);
1026 params[1] = NPVariantFromString(public_key);
1027 InvokeAndIgnoreResult(*callback, params, arraysize(params));
1028 g_npnetscape_funcs->releasevariantvalue(&(params[0]));
1029 g_npnetscape_funcs->releasevariantvalue(&(params[1]));
1030 }
1031
1032 void HostNPScriptObject::InvokeAsyncResultCallback(
1033 scoped_ptr<ScopedRefNPObject> callback,
1034 DaemonController::AsyncResult result) {
1035 DCHECK(plugin_task_runner_->BelongsToCurrentThread());
1036
1037 NPVariant result_var;
1038 INT32_TO_NPVARIANT(static_cast<int32>(result), result_var);
1039 InvokeAndIgnoreResult(*callback, &result_var, 1);
1040 g_npnetscape_funcs->releasevariantvalue(&result_var);
1041 }
1042
1043 void HostNPScriptObject::InvokeBooleanCallback(
1044 scoped_ptr<ScopedRefNPObject> callback, bool result) {
1045 DCHECK(plugin_task_runner_->BelongsToCurrentThread());
1046
1047 NPVariant result_var;
1048 BOOLEAN_TO_NPVARIANT(result, result_var);
1049 InvokeAndIgnoreResult(*callback, &result_var, 1);
1050 g_npnetscape_funcs->releasevariantvalue(&result_var);
1051 }
1052
1053 void HostNPScriptObject::InvokeGetDaemonConfigCallback(
1054 scoped_ptr<ScopedRefNPObject> callback,
1055 scoped_ptr<base::DictionaryValue> config) {
1056 DCHECK(plugin_task_runner_->BelongsToCurrentThread());
1057
1058 // There is no easy way to create a dictionary from an NPAPI plugin
1059 // so we have to serialize the dictionary to pass it to JavaScript.
1060 std::string config_str;
1061 if (config.get())
1062 base::JSONWriter::Write(config.get(), &config_str);
1063
1064 NPVariant config_val = NPVariantFromString(config_str);
1065 InvokeAndIgnoreResult(*callback, &config_val, 1);
1066 g_npnetscape_funcs->releasevariantvalue(&config_val);
1067 }
1068
1069 void HostNPScriptObject::InvokeGetDaemonVersionCallback(
1070 scoped_ptr<ScopedRefNPObject> callback, const std::string& version) {
1071 DCHECK(plugin_task_runner_->BelongsToCurrentThread());
1072
1073 NPVariant version_val = NPVariantFromString(version);
1074 InvokeAndIgnoreResult(*callback, &version_val, 1);
1075 g_npnetscape_funcs->releasevariantvalue(&version_val);
1076 }
1077
1078 void HostNPScriptObject::InvokeGetPairedClientsCallback(
1079 scoped_ptr<ScopedRefNPObject> callback,
1080 scoped_ptr<base::ListValue> paired_clients) {
1081 DCHECK(plugin_task_runner_->BelongsToCurrentThread());
1082
1083 std::string paired_clients_json;
1084 base::JSONWriter::Write(paired_clients.get(), &paired_clients_json);
1085
1086 NPVariant paired_clients_val = NPVariantFromString(paired_clients_json);
1087 InvokeAndIgnoreResult(*callback, &paired_clients_val, 1);
1088 g_npnetscape_funcs->releasevariantvalue(&paired_clients_val);
1089 }
1090
1091 void HostNPScriptObject::InvokeGetUsageStatsConsentCallback(
1092 scoped_ptr<ScopedRefNPObject> callback,
1093 const DaemonController::UsageStatsConsent& consent) {
1094 DCHECK(plugin_task_runner_->BelongsToCurrentThread());
1095
1096 NPVariant params[3];
1097 BOOLEAN_TO_NPVARIANT(consent.supported, params[0]);
1098 BOOLEAN_TO_NPVARIANT(consent.allowed, params[1]);
1099 BOOLEAN_TO_NPVARIANT(consent.set_by_policy, params[2]);
1100 InvokeAndIgnoreResult(*callback, params, arraysize(params));
1101 g_npnetscape_funcs->releasevariantvalue(&(params[0]));
1102 g_npnetscape_funcs->releasevariantvalue(&(params[1]));
1103 g_npnetscape_funcs->releasevariantvalue(&(params[2]));
1104 }
1105
1106 void HostNPScriptObject::LogDebugInfo(const std::string& message) {
1107 DCHECK(plugin_task_runner_->BelongsToCurrentThread());
1108
1109 if (log_debug_info_func_.get()) {
1110 am_currently_logging_ = true;
1111 NPVariant log_message;
1112 STRINGZ_TO_NPVARIANT(message.c_str(), log_message);
1113 bool is_good = InvokeAndIgnoreResult(log_debug_info_func_,
1114 &log_message, 1);
1115 if (!is_good) {
1116 LOG(ERROR) << "ERROR - LogDebugInfo failed\n";
1117 }
1118 am_currently_logging_ = false;
1119 }
1120 }
1121
1122 bool HostNPScriptObject::InvokeAndIgnoreResult(const ScopedRefNPObject& func,
1123 const NPVariant* args,
1124 uint32_t arg_count) {
1125 DCHECK(plugin_task_runner_->BelongsToCurrentThread());
1126
1127 NPVariant np_result;
1128 bool is_good = g_npnetscape_funcs->invokeDefault(plugin_, func.get(), args,
1129 arg_count, &np_result);
1130 if (is_good)
1131 g_npnetscape_funcs->releasevariantvalue(&np_result);
1132
1133 return is_good;
1134 }
1135
1136 void HostNPScriptObject::SetException(const std::string& exception_string) {
1137 DCHECK(plugin_task_runner_->BelongsToCurrentThread());
1138
1139 g_npnetscape_funcs->setexception(parent_, exception_string.c_str());
1140 HOST_LOG << exception_string;
1141 }
1142
1143 } // namespace remoting
OLDNEW
« no previous file with comments | « remoting/host/plugin/host_script_object.h ('k') | remoting/host/win/version.rc.jinja2 » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698