client_screen.js revision 90dce4d38c5ff5333bea97d859d4e484e27edf0c
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @fileoverview
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Functions related to the 'client screen' for Chromoting.
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)'use strict';
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** @suppress {duplicate} */
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)var remoting = remoting || {};
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @type {remoting.SessionConnector} The connector object, set when a connection
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *     is initiated.
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)remoting.connector = null;
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @type {remoting.ClientSession} The client session object, set once the
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *     connector has invoked its onOk callback.
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)remoting.clientSession = null;
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Initiate an IT2Me connection.
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)remoting.connectIT2Me = function() {
31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!remoting.connector) {
32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    remoting.connector = new remoting.SessionConnector(
33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        document.getElementById('session-mode'),
34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        remoting.onConnected,
35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        showConnectError_);
36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  var accessCode = document.getElementById('access-code-entry').value;
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  remoting.setMode(remoting.AppMode.CLIENT_CONNECTING);
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  remoting.connector.connectIT2Me(accessCode);
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Update the remoting client layout in response to a resize event.
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @return {void} Nothing.
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)remoting.onResize = function() {
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (remoting.clientSession) {
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    remoting.clientSession.onResize();
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Handle changes in the visibility of the window, for example by pausing video.
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @return {void} Nothing.
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)remoting.onVisibilityChanged = function() {
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (remoting.clientSession) {
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    remoting.clientSession.pauseVideo(document.webkitHidden);
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Disconnect the remoting client.
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @return {void} Nothing.
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)remoting.disconnect = function() {
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!remoting.clientSession) {
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (remoting.clientSession.mode == remoting.ClientSession.Mode.IT2ME) {
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    remoting.setMode(remoting.AppMode.CLIENT_SESSION_FINISHED_IT2ME);
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    remoting.setMode(remoting.AppMode.CLIENT_SESSION_FINISHED_ME2ME);
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  remoting.clientSession.disconnect(true);
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  remoting.clientSession = null;
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  console.log('Disconnected.');
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Sends a Ctrl-Alt-Del sequence to the remoting client.
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @return {void} Nothing.
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)remoting.sendCtrlAltDel = function() {
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (remoting.clientSession) {
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    console.log('Sending Ctrl-Alt-Del.');
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    remoting.clientSession.sendCtrlAltDel();
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Sends a Print Screen keypress to the remoting client.
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @return {void} Nothing.
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)remoting.sendPrintScreen = function() {
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (remoting.clientSession) {
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    console.log('Sending Print Screen.');
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    remoting.clientSession.sendPrintScreen();
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Callback function called when the state of the client plugin changes. The
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * current state is available via the |state| member variable.
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {number} oldState The previous state of the plugin.
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {number} newState The current state of the plugin.
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)function onClientStateChange_(oldState, newState) {
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  switch (newState) {
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case remoting.ClientSession.State.CLOSED:
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      console.log('Connection closed by host');
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (remoting.clientSession.mode == remoting.ClientSession.Mode.IT2ME) {
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        remoting.setMode(remoting.AppMode.CLIENT_SESSION_FINISHED_IT2ME);
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else {
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        remoting.setMode(remoting.AppMode.CLIENT_SESSION_FINISHED_ME2ME);
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case remoting.ClientSession.State.FAILED:
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      var error = remoting.clientSession.getError();
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      console.error('Client plugin reported connection failed: ' + error);
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (error == null) {
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        error = remoting.Error.UNEXPECTED;
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      showConnectError_(error);
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    default:
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      console.error('Unexpected client plugin state: ' + newState);
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // This should only happen if the web-app and client plugin get out of
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // sync, so MISSING_PLUGIN is a suitable error.
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      showConnectError_(remoting.Error.MISSING_PLUGIN);
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  remoting.clientSession.disconnect(false);
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  remoting.clientSession.removePlugin();
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  remoting.clientSession = null;
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Show a client-side error message.
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {remoting.Error} errorTag The error to be localized and
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *     displayed.
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @return {void} Nothing.
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)function showConnectError_(errorTag) {
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  console.error('Connection failed: ' + errorTag);
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  var errorDiv = document.getElementById('connect-error-message');
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  l10n.localizeElementFromTag(errorDiv, /** @type {string} */ (errorTag));
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  remoting.accessCode = '';
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  var mode = remoting.clientSession ? remoting.clientSession.mode
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                    : remoting.connector.getConnectionMode();
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (mode == remoting.ClientSession.Mode.IT2ME) {
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    remoting.setMode(remoting.AppMode.CLIENT_CONNECT_FAILED_IT2ME);
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    remoting.setMode(remoting.AppMode.CLIENT_CONNECT_FAILED_ME2ME);
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Set the text on the buttons shown under the error message so that they are
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * easy to understand in the case where a successful connection failed, as
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * opposed to the case where a connection never succeeded.
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)function setConnectionInterruptedButtonsText_() {
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  var button1 = document.getElementById('client-reconnect-button');
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  l10n.localizeElementFromTag(button1, /*i18n-content*/'RECONNECT');
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  button1.removeAttribute('autofocus');
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  var button2 = document.getElementById('client-finished-me2me-button');
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  l10n.localizeElementFromTag(button2, /*i18n-content*/'OK');
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  button2.setAttribute('autofocus', 'autofocus');
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Timer callback to update the statistics panel.
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)function updateStatistics_() {
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!remoting.clientSession ||
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      remoting.clientSession.state != remoting.ClientSession.State.CONNECTED) {
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  var perfstats = remoting.clientSession.getPerfStats();
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  remoting.stats.update(perfstats);
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  remoting.clientSession.logStatistics(perfstats);
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Update the stats once per second.
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window.setTimeout(updateStatistics_, 1000);
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Entry-point for Me2Me connections, handling showing of the host-upgrade nag
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * dialog if necessary.
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {string} hostId The unique id of the host.
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @return {void} Nothing.
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)remoting.connectMe2Me = function(hostId) {
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  var host = remoting.hostList.getHostForId(hostId);
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!host) {
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    showConnectError_(remoting.Error.HOST_IS_OFFLINE);
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  var webappVersion = chrome.runtime.getManifest().version;
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (remoting.Host.needsUpdate(host, webappVersion)) {
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    var needsUpdateMessage =
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        document.getElementById('host-needs-update-message');
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    l10n.localizeElementFromTag(needsUpdateMessage,
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                /*i18n-content*/'HOST_NEEDS_UPDATE_TITLE',
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                host.hostName);
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    /** @type {Element} */
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    var connect = document.getElementById('host-needs-update-connect-button');
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    /** @type {Element} */
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    var cancel = document.getElementById('host-needs-update-cancel-button');
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    /** @param {Event} event */
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    var onClick = function(event) {
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      connect.removeEventListener('click', onClick, false);
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      cancel.removeEventListener('click', onClick, false);
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (event.target == connect) {
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        remoting.connectMe2MeHostVersionAcknowledged_(host);
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      } else {
227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        remoting.setMode(remoting.AppMode.HOME);
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    connect.addEventListener('click', onClick, false);
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    cancel.addEventListener('click', onClick, false);
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    remoting.setMode(remoting.AppMode.CLIENT_HOST_NEEDS_UPGRADE);
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    remoting.connectMe2MeHostVersionAcknowledged_(host);
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Shows PIN entry screen localized to include the host name, and registers
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * a host-specific one-shot event handler for the form submission.
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param {remoting.Host} host The Me2Me host to which to connect.
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @return {void} Nothing.
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)remoting.connectMe2MeHostVersionAcknowledged_ = function(host) {
246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!remoting.connector) {
247c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    remoting.connector = new remoting.SessionConnector(
248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        document.getElementById('session-mode'),
249c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        remoting.onConnected,
250c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        showConnectError_);
251c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  remoting.setMode(remoting.AppMode.CLIENT_CONNECTING);
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
254c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  /**
255c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   * @param {string} tokenUrl Token-issue URL received from the host.
256c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   * @param {string} scope OAuth scope to request the token for.
257c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   * @param {string} hostPublicKey Host public key (DER and Base64 encoded).
258c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   * @param {function(string, string):void} onThirdPartyTokenFetched Callback.
259c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   */
260c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  var fetchThirdPartyToken = function(
261c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      tokenUrl, hostPublicKey, scope, onThirdPartyTokenFetched) {
262c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    var thirdPartyTokenFetcher = new remoting.ThirdPartyTokenFetcher(
263c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        tokenUrl, hostPublicKey, scope, host.tokenUrlPatterns,
264c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        onThirdPartyTokenFetched);
265c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    thirdPartyTokenFetcher.fetchToken();
266c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  };
267c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
26890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  /**
26990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)   * @param {boolean} supportsPairing
27090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)   * @param {function(string):void} onPinFetched
27190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)   */
27290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  var requestPin = function(supportsPairing, onPinFetched) {
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    /** @type {Element} */
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    var pinForm = document.getElementById('pin-form');
275c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    /** @type {Element} */
276c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    var pinCancel = document.getElementById('cancel-pin-entry-button');
277c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    /**
278c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)     * Event handler for both the 'submit' and 'cancel' actions. Using
279c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)     * a single handler for both greatly simplifies the task of making
280c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)     * them one-shot. If separate handlers were used, each would have
281c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)     * to unregister both itself and the other.
282c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)     *
283c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)     * @param {Event} event The click or submit event.
284c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)     */
285c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    var onSubmitOrCancel = function(event) {
286c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      pinForm.removeEventListener('submit', onSubmitOrCancel, false);
287c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      pinCancel.removeEventListener('click', onSubmitOrCancel, false);
288c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      var pinField = document.getElementById('pin-entry');
289c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      var pin = pinField.value;
290c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      pinField.value = '';
291c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      if (event.target == pinForm) {
292c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        event.preventDefault();
293c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        remoting.setMode(remoting.AppMode.CLIENT_CONNECTING);
294c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        onPinFetched(pin);
295c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      } else {
296c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        remoting.setMode(remoting.AppMode.HOME);
297c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      }
2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    };
299c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    pinForm.addEventListener('submit', onSubmitOrCancel, false);
300c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    pinCancel.addEventListener('click', onSubmitOrCancel, false);
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    var rememberPin = document.getElementById('remember-pin');
30390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    rememberPin.hidden = !supportsPairing;
30490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    var checkbox = /** @type {HTMLInputElement} */
30590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        document.getElementById('remember-pin-checkbox');
30690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    checkbox.checked = false;
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    var message = document.getElementById('pin-message');
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    l10n.localizeElement(message, host.hostName);
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    remoting.setMode(remoting.AppMode.CLIENT_PIN_PROMPT);
3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
311c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  remoting.connector.connectMe2Me(host, requestPin, fetchThirdPartyToken);
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/** @param {remoting.ClientSession} clientSession */
3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)remoting.onConnected = function(clientSession) {
3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  remoting.clientSession = clientSession;
3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  remoting.clientSession.setOnStateChange(onClientStateChange_);
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  setConnectionInterruptedButtonsText_();
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  var connectedTo = document.getElementById('connected-to');
3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  connectedTo.innerText = clientSession.hostDisplayName;
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  remoting.setMode(remoting.AppMode.IN_SESSION);
3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  remoting.toolbar.center();
3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  remoting.toolbar.preview();
3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  remoting.clipboard.startSession();
3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  updateStatistics_();
3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
327