OLD | NEW |
---|---|
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 /** @suppress {duplicate} */ | 5 /** @suppress {duplicate} */ |
6 var remoting = remoting || {}; | 6 var remoting = remoting || {}; |
7 | 7 |
8 (function() { | 8 (function() { |
9 'use strict'; | 9 'use strict'; |
10 | 10 |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
150 } | 150 } |
151 | 151 |
152 remoting.init = function() { | 152 remoting.init = function() { |
153 l10n.localize(); | 153 l10n.localize(); |
154 var button = document.getElementById('toggle-scaling'); | 154 var button = document.getElementById('toggle-scaling'); |
155 button.title = chrome.i18n.getMessage(/*i18n-content*/'TOOLTIP_SCALING'); | 155 button.title = chrome.i18n.getMessage(/*i18n-content*/'TOOLTIP_SCALING'); |
156 // Create global objects. | 156 // Create global objects. |
157 remoting.oauth2 = new remoting.OAuth2(); | 157 remoting.oauth2 = new remoting.OAuth2(); |
158 remoting.debug = | 158 remoting.debug = |
159 new remoting.DebugLog(document.getElementById('debug-messages')); | 159 new remoting.DebugLog(document.getElementById('debug-messages')); |
160 remoting.sessionId = 1; | |
160 | 161 |
161 refreshEmail_(); | 162 refreshEmail_(); |
162 var email = getEmail(); | 163 var email = getEmail(); |
163 if (email) { | 164 if (email) { |
164 document.getElementById('current-email').innerText = email; | 165 document.getElementById('current-email').innerText = email; |
165 } | 166 } |
166 | 167 |
167 remoting.setMode(getAppStartupMode()); | 168 remoting.setMode(getAppStartupMode()); |
168 if (isHostModeSupported()) { | 169 if (isHostModeSupported()) { |
169 var unsupported = document.getElementById('client-footer-text-cros'); | 170 var unsupported = document.getElementById('client-footer-text-cros'); |
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
371 plugin.parentNode.removeChild(plugin); | 372 plugin.parentNode.removeChild(plugin); |
372 } else if (state == plugin.ERROR) { | 373 } else if (state == plugin.ERROR) { |
373 remoting.debug.log('Host plugin state: ERROR'); | 374 remoting.debug.log('Host plugin state: ERROR'); |
374 showShareError_(/*i18n-content*/'ERROR_GENERIC'); | 375 showShareError_(/*i18n-content*/'ERROR_GENERIC'); |
375 } else { | 376 } else { |
376 remoting.debug.log('Unknown state -> ' + state); | 377 remoting.debug.log('Unknown state -> ' + state); |
377 } | 378 } |
378 } | 379 } |
379 | 380 |
380 /** | 381 /** |
381 * This is the callback that the host plugin invokes to indicate that there | 382 * This is the callback that the host plugin invokes to indicate that there |
382 * is additional debug log info to display. | 383 * is additional debug log info to display. |
383 * @param {string} msg The message (which will not be localized) to be logged. | 384 * @param {string} msg The message (which will not be localized) to be logged. |
384 */ | 385 */ |
385 function debugInfoCallback_(msg) { | 386 function debugInfoCallback_(msg) { |
386 remoting.debug.log('plugin: ' + msg); | 387 remoting.debug.log('plugin: ' + msg); |
387 } | 388 } |
388 | 389 |
389 /** | 390 /** |
390 * Show a host-side error message. | 391 * Show a host-side error message. |
391 * | 392 * |
392 * @param {string} errorTag The error message to be localized and displayed. | 393 * @param {string} errorTag The error message to be localized and displayed. |
393 * @return {void} Nothing. | 394 * @return {void} Nothing. |
394 */ | 395 */ |
395 function showShareError_(errorTag) { | 396 function showShareError_(errorTag) { |
396 var errorDiv = document.getElementById('host-plugin-error'); | 397 var errorDiv = document.getElementById('host-plugin-error'); |
397 l10n.localizeElementFromTag(errorDiv, errorTag); | 398 l10n.localizeElementFromTag(errorDiv, errorTag); |
398 remoting.debug.log('Sharing error: ' + errorTag); | 399 remoting.debug.log('Sharing error: ' + errorTag); |
399 remoting.setMode(remoting.AppMode.HOST_SHARE_FAILED); | 400 remoting.setMode(remoting.AppMode.HOST_SHARE_FAILED); |
400 } | 401 } |
401 | 402 |
403 /** | |
404 * Cancel an active or pending share operation. | |
405 * | |
406 * @return {void} Nothing. | |
407 */ | |
402 remoting.cancelShare = function() { | 408 remoting.cancelShare = function() { |
403 remoting.debug.log('Canceling share...'); | 409 remoting.debug.log('Canceling share...'); |
404 remoting.lastShareWasCancelled = true; | 410 remoting.lastShareWasCancelled = true; |
405 var plugin = /** @type {remoting.HostPlugin} */ | 411 var plugin = /** @type {remoting.HostPlugin} */ |
406 document.getElementById(remoting.HOST_PLUGIN_ID); | 412 document.getElementById(remoting.HOST_PLUGIN_ID); |
407 try { | 413 try { |
408 plugin.disconnect(); | 414 plugin.disconnect(); |
409 } catch (error) { | 415 } catch (error) { |
410 remoting.debug.log('Error disconnecting: ' + error.description + | 416 remoting.debug.log('Error disconnecting: ' + error.description + |
411 '. The host plugin probably crashed.'); | 417 '. The host plugin probably crashed.'); |
412 // TODO(jamiewalch): Clean this up. We should have a class representing | 418 // TODO(jamiewalch): Clean this up. We should have a class representing |
413 // the host plugin, like we do for the client, which should handle crash | 419 // the host plugin, like we do for the client, which should handle crash |
414 // reporting and it should use a more detailed error message than the | 420 // reporting and it should use a more detailed error message than the |
415 // default 'generic' one. See crbug.com/94624 | 421 // default 'generic' one. See crbug.com/94624 |
416 showShareError_(/*i18n-content*/'ERROR_GENERIC'); | 422 showShareError_(/*i18n-content*/'ERROR_GENERIC'); |
417 } | 423 } |
418 disableTimeoutCountdown_(); | 424 disableTimeoutCountdown_(); |
419 } | 425 } |
420 | 426 |
427 /** | |
428 * Cancel an incomplete connect operation. | |
429 * | |
430 * @return {void} Nothing. | |
431 */ | |
432 remoting.cancelConnect = function() { | |
433 ++remoting.sessionId; | |
434 if (remoting.session) { | |
435 remoting.session.removePlugin(); | |
436 remoting.session = null; | |
437 } | |
438 remoting.setMode(remoting.AppMode.HOME); | |
439 } | |
440 | |
421 function updateStatistics() { | 441 function updateStatistics() { |
422 if (!remoting.session) | 442 if (!remoting.session) |
423 return; | 443 return; |
424 if (remoting.session.state != remoting.ClientSession.State.CONNECTED) | 444 if (remoting.session.state != remoting.ClientSession.State.CONNECTED) |
425 return; | 445 return; |
426 var stats = remoting.session.stats(); | 446 var stats = remoting.session.stats(); |
427 | 447 |
428 var units = ''; | 448 var units = ''; |
429 var videoBandwidth = stats['video_bandwidth']; | 449 var videoBandwidth = stats['video_bandwidth']; |
430 if (videoBandwidth < 1024) { | 450 if (videoBandwidth < 1024) { |
(...skipping 22 matching lines...) Expand all Loading... | |
453 window.setTimeout(updateStatistics, 1000); | 473 window.setTimeout(updateStatistics, 1000); |
454 } | 474 } |
455 | 475 |
456 function showToolbarPreview_() { | 476 function showToolbarPreview_() { |
457 var toolbar = document.getElementById('session-toolbar'); | 477 var toolbar = document.getElementById('session-toolbar'); |
458 addClass(toolbar, 'toolbar-preview'); | 478 addClass(toolbar, 'toolbar-preview'); |
459 window.setTimeout(removeClass, 3000, toolbar, 'toolbar-preview'); | 479 window.setTimeout(removeClass, 3000, toolbar, 'toolbar-preview'); |
460 } | 480 } |
461 | 481 |
462 function onClientStateChange_(oldState) { | 482 function onClientStateChange_(oldState) { |
483 if (!remoting.session) { | |
484 // If the connection has been cancelled, then we no longer have a reference | |
485 // to the session object and should ignore any state changes. | |
486 return; | |
487 } | |
463 var state = remoting.session.state; | 488 var state = remoting.session.state; |
464 if (state == remoting.ClientSession.State.CREATED) { | 489 if (state == remoting.ClientSession.State.CREATED) { |
465 remoting.debug.log('Created plugin'); | 490 remoting.debug.log('Created plugin'); |
466 } else if (state == remoting.ClientSession.State.BAD_PLUGIN_VERSION) { | 491 } else if (state == remoting.ClientSession.State.BAD_PLUGIN_VERSION) { |
467 showConnectError_(remoting.ClientError.MISSING_PLUGIN); | 492 showConnectError_(remoting.ClientError.MISSING_PLUGIN); |
468 } else if (state == remoting.ClientSession.State.CONNECTING) { | 493 } else if (state == remoting.ClientSession.State.CONNECTING) { |
469 remoting.debug.log('Connecting as ' + remoting.username); | 494 remoting.debug.log('Connecting as ' + remoting.username); |
470 } else if (state == remoting.ClientSession.State.INITIALIZING) { | 495 } else if (state == remoting.ClientSession.State.INITIALIZING) { |
471 remoting.debug.log('Initializing connection'); | 496 remoting.debug.log('Initializing connection'); |
472 } else if (state == remoting.ClientSession.State.CONNECTED) { | 497 } else if (state == remoting.ClientSession.State.CONNECTED) { |
473 remoting.setMode(remoting.AppMode.IN_SESSION); | 498 if (remoting.session) { |
474 recenterToolbar_(); | 499 remoting.setMode(remoting.AppMode.IN_SESSION); |
475 showToolbarPreview_(); | 500 recenterToolbar_(); |
476 updateStatistics(); | 501 showToolbarPreview_(); |
477 var accessCode = document.getElementById('access-code-entry'); | 502 updateStatistics(); |
478 accessCode.value = ''; | 503 } |
479 } else if (state == remoting.ClientSession.State.CLOSED) { | 504 } else if (state == remoting.ClientSession.State.CLOSED) { |
480 if (oldState == remoting.ClientSession.State.CONNECTED) { | 505 if (oldState == remoting.ClientSession.State.CONNECTED) { |
481 remoting.session.removePlugin(); | 506 remoting.session.removePlugin(); |
482 remoting.session = null; | 507 remoting.session = null; |
483 remoting.debug.log('Connection closed by host'); | 508 remoting.debug.log('Connection closed by host'); |
484 remoting.setMode(remoting.AppMode.CLIENT_SESSION_FINISHED); | 509 remoting.setMode(remoting.AppMode.CLIENT_SESSION_FINISHED); |
485 } else { | 510 } else { |
486 // The transition from CONNECTING to CLOSED state may happen | 511 // The transition from CONNECTING to CLOSED state may happen |
487 // only with older client plugins. Current version should go the | 512 // only with older client plugins. Current version should go the |
488 // FAILED state when connection fails. | 513 // FAILED state when connection fails. |
(...skipping 19 matching lines...) Expand all Loading... | |
508 } else { | 533 } else { |
509 remoting.debug.log('Unexpected client plugin state: ' + state); | 534 remoting.debug.log('Unexpected client plugin state: ' + state); |
510 // This should only happen if the web-app and client plugin get out of | 535 // This should only happen if the web-app and client plugin get out of |
511 // sync, and even then the version check should allow compatibility. | 536 // sync, and even then the version check should allow compatibility. |
512 showConnectError_(remoting.ClientError.MISSING_PLUGIN); | 537 showConnectError_(remoting.ClientError.MISSING_PLUGIN); |
513 } | 538 } |
514 } | 539 } |
515 | 540 |
516 function startSession_() { | 541 function startSession_() { |
517 remoting.debug.log('Starting session...'); | 542 remoting.debug.log('Starting session...'); |
543 var accessCode = document.getElementById('access-code-entry'); | |
544 accessCode.value = ''; // The code has been validated and won't work again. | |
518 remoting.username = | 545 remoting.username = |
519 /** @type {string} email must be non-NULL to get here */ getEmail(); | 546 /** @type {string} email must be non-NULL to get here */ getEmail(); |
520 remoting.session = | 547 remoting.session = |
521 new remoting.ClientSession(remoting.hostJid, remoting.hostPublicKey, | 548 new remoting.ClientSession(remoting.hostJid, remoting.hostPublicKey, |
522 remoting.accessCode, remoting.username, | 549 remoting.accessCode, remoting.username, |
523 onClientStateChange_); | 550 onClientStateChange_); |
524 remoting.oauth2.callWithToken(function(token) { | 551 remoting.oauth2.callWithToken(function(token) { |
525 remoting.session.createPluginAndConnect( | 552 remoting.session.createPluginAndConnect( |
526 document.getElementById('session-mode'), | 553 document.getElementById('session-mode'), |
527 token); | 554 token); |
(...skipping 12 matching lines...) Expand all Loading... | |
540 var errorDiv = document.getElementById('connect-error-message'); | 567 var errorDiv = document.getElementById('connect-error-message'); |
541 l10n.localizeElementFromTag(errorDiv, /** @type {string} */ (errorTag)); | 568 l10n.localizeElementFromTag(errorDiv, /** @type {string} */ (errorTag)); |
542 remoting.accessCode = ''; | 569 remoting.accessCode = ''; |
543 if (remoting.session) { | 570 if (remoting.session) { |
544 remoting.session.disconnect(); | 571 remoting.session.disconnect(); |
545 remoting.session = null; | 572 remoting.session = null; |
546 } | 573 } |
547 remoting.setMode(remoting.AppMode.CLIENT_CONNECT_FAILED); | 574 remoting.setMode(remoting.AppMode.CLIENT_CONNECT_FAILED); |
548 } | 575 } |
549 | 576 |
550 function parseServerResponse_(xhr) { | 577 function parseServerResponse_(xhr, sessionId) { |
578 if (sessionId != remoting.sessionId) { | |
579 remoting.debug.log('ignoring request id ' + sessionId); | |
580 return; | |
581 } | |
582 ++remoting.sessionId; | |
Wez
2011/10/14 01:21:26
Consider tweaking the xhr.get() call to return the
Jamie
2011/10/14 18:17:07
Done.
| |
551 remoting.debug.log('parseServerResponse: status = ' + xhr.status); | 583 remoting.debug.log('parseServerResponse: status = ' + xhr.status); |
552 if (xhr.status == 200) { | 584 if (xhr.status == 200) { |
553 var host = JSON.parse(xhr.responseText); | 585 var host = JSON.parse(xhr.responseText); |
554 if (host.data && host.data.jabberId) { | 586 if (host.data && host.data.jabberId) { |
555 remoting.hostJid = host.data.jabberId; | 587 remoting.hostJid = host.data.jabberId; |
556 remoting.hostPublicKey = host.data.publicKey; | 588 remoting.hostPublicKey = host.data.publicKey; |
557 var split = remoting.hostJid.split('/'); | 589 var split = remoting.hostJid.split('/'); |
558 document.getElementById('connected-to').innerText = split[0]; | 590 document.getElementById('connected-to').innerText = split[0]; |
559 startSession_(); | 591 startSession_(); |
560 return; | 592 return; |
(...skipping 14 matching lines...) Expand all Loading... | |
575 // Trim whitespace. | 607 // Trim whitespace. |
576 // TODO(sergeyu): Do we need to do any other normalization here? | 608 // TODO(sergeyu): Do we need to do any other normalization here? |
577 return accessCode.replace(/\s/g, ''); | 609 return accessCode.replace(/\s/g, ''); |
578 } | 610 } |
579 | 611 |
580 function resolveSupportId(supportId) { | 612 function resolveSupportId(supportId) { |
581 var headers = { | 613 var headers = { |
582 'Authorization': 'OAuth ' + remoting.oauth2.getAccessToken() | 614 'Authorization': 'OAuth ' + remoting.oauth2.getAccessToken() |
583 }; | 615 }; |
584 | 616 |
617 var sessionId = remoting.sessionId; | |
585 remoting.xhr.get( | 618 remoting.xhr.get( |
586 'https://www.googleapis.com/chromoting/v1/support-hosts/' + | 619 'https://www.googleapis.com/chromoting/v1/support-hosts/' + |
587 encodeURIComponent(supportId), | 620 encodeURIComponent(supportId), |
588 parseServerResponse_, | 621 function(xhr) { parseServerResponse_(xhr, sessionId); }, |
589 '', | 622 '', |
590 headers); | 623 headers); |
591 } | 624 } |
592 | 625 |
593 remoting.tryConnect = function() { | 626 remoting.tryConnect = function() { |
627 document.getElementById('cancel-button').disabled = false; | |
594 if (remoting.oauth2.needsNewAccessToken()) { | 628 if (remoting.oauth2.needsNewAccessToken()) { |
595 remoting.oauth2.refreshAccessToken(function(xhr) { | 629 remoting.oauth2.refreshAccessToken(function(xhr) { |
596 if (remoting.oauth2.needsNewAccessToken()) { | 630 if (remoting.oauth2.needsNewAccessToken()) { |
597 // Failed to get access token | 631 // Failed to get access token |
598 remoting.debug.log('tryConnect: OAuth2 token fetch failed'); | 632 remoting.debug.log('tryConnect: OAuth2 token fetch failed'); |
599 showConnectError_(remoting.ClientError.OAUTH_FETCH_FAILED); | 633 showConnectError_(remoting.ClientError.OAUTH_FETCH_FAILED); |
600 return; | 634 return; |
601 } | 635 } |
602 remoting.tryConnectWithAccessToken(); | 636 remoting.tryConnectWithAccessToken(); |
603 }); | 637 }); |
(...skipping 23 matching lines...) Expand all Loading... | |
627 remoting.debug.log('Bad access code length'); | 661 remoting.debug.log('Bad access code length'); |
628 showConnectError_(remoting.ClientError.INVALID_ACCESS_CODE); | 662 showConnectError_(remoting.ClientError.INVALID_ACCESS_CODE); |
629 } else { | 663 } else { |
630 var supportId = remoting.accessCode.substring(0, kSupportIdLen); | 664 var supportId = remoting.accessCode.substring(0, kSupportIdLen); |
631 remoting.setMode(remoting.AppMode.CLIENT_CONNECTING); | 665 remoting.setMode(remoting.AppMode.CLIENT_CONNECTING); |
632 resolveSupportId(supportId); | 666 resolveSupportId(supportId); |
633 } | 667 } |
634 } | 668 } |
635 | 669 |
636 remoting.cancelPendingOperation = function() { | 670 remoting.cancelPendingOperation = function() { |
637 document.getElementById('cancel-button').disabled = true; | 671 document.getElementById('cancel-button').disabled = true; |
Wez
2011/10/14 01:21:26
nit: Indentation.
Jamie
2011/10/14 18:17:07
Done.
| |
638 if (remoting.getMajorMode() == remoting.AppMode.HOST) { | 672 switch (remoting.getMajorMode()) { |
673 case remoting.AppMode.HOST: | |
Wez
2011/10/14 01:21:26
nit: Is this the right indentation for case?
Jamie
2011/10/14 18:17:07
Apparently not. Fixed.
| |
639 remoting.cancelShare(); | 674 remoting.cancelShare(); |
675 break; | |
676 case remoting.AppMode.CLIENT: | |
677 remoting.cancelConnect(); | |
678 break; | |
640 } | 679 } |
641 } | 680 } |
642 | 681 |
643 /** | 682 /** |
644 * Gets the major-mode that this application should start up in. | 683 * Gets the major-mode that this application should start up in. |
645 * | 684 * |
646 * @return {remoting.AppMode} The mode to start in. | 685 * @return {remoting.AppMode} The mode to start in. |
647 */ | 686 */ |
648 function getAppStartupMode() { | 687 function getAppStartupMode() { |
649 if (!remoting.oauth2.isAuthenticated()) { | 688 if (!remoting.oauth2.isAuthenticated()) { |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
733 } | 772 } |
734 } | 773 } |
735 | 774 |
736 function recenterToolbar_() { | 775 function recenterToolbar_() { |
737 var toolbar = document.getElementById('session-toolbar'); | 776 var toolbar = document.getElementById('session-toolbar'); |
738 var toolbarX = (window.innerWidth - toolbar.clientWidth) / 2; | 777 var toolbarX = (window.innerWidth - toolbar.clientWidth) / 2; |
739 toolbar.style['left'] = toolbarX + 'px'; | 778 toolbar.style['left'] = toolbarX + 'px'; |
740 } | 779 } |
741 | 780 |
742 }()); | 781 }()); |
OLD | NEW |