remoting.js revision 58537e28ecd584eab876aee8be7156509866d23a
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)'use strict'; 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** @suppress {duplicate} */ 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)var remoting = remoting || {}; 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** @type {remoting.HostSession} */ remoting.hostSession = null; 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 1358e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch * @type {boolean} True if this is a v2 app; false if it is a legacy app. 1458e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch */ 1558e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdochremoting.isAppsV2 = false; 1658e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch 1758e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch/** 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Show the authorization consent UI and register a one-shot event handler to 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * continue the authorization process. 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param {function():void} authContinue Callback to invoke when the user 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * clicks "Continue". 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)function consentRequired_(authContinue) { 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /** @type {HTMLElement} */ 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) var dialog = document.getElementById('auth-dialog'); 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /** @type {HTMLElement} */ 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) var button = document.getElementById('auth-button'); 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) var consentGranted = function(event) { 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dialog.hidden = true; 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) button.removeEventListener('click', consentGranted, false); 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) authContinue(); 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dialog.hidden = false; 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) button.addEventListener('click', consentGranted, false); 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Entry point for app initialization. 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)remoting.init = function() { 4258e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch // Determine whether or not this is a V2 web-app. In order to keep the apps 4358e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch // v2 patch as small as possible, all JS changes needed for apps v2 are done 4458e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch // at run-time. Only the manifest is patched. 4558e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch var manifest = chrome.runtime.getManifest(); 4658e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch if (manifest && manifest.app && manifest.app.background) { 4758e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch remoting.isAppsV2 = true; 482385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch var htmlNode = /** @type {HTMLElement} */ (document.body.parentNode); 492385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch htmlNode.classList.add('apps-v2'); 5058e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch } 5158e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch 5258e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch if (!remoting.isAppsV2) { 5358e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch migrateLocalToChromeStorage_(); 5458e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch } 5558e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) remoting.logExtensionInfo_(); 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) l10n.localize(); 5858e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create global objects. 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) remoting.settings = new remoting.Settings(); 6158e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch if (remoting.isAppsV2) { 6258e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch remoting.identity = new remoting.Identity(consentRequired_); 6358e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch } else { 6458e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch remoting.oauth2 = new remoting.OAuth2(); 6558e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch if (!remoting.oauth2.isAuthenticated()) { 6658e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch document.getElementById('auth-dialog').hidden = false; 6758e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch } 6858e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch remoting.identity = remoting.oauth2; 6958e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch } 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) remoting.stats = new remoting.ConnectionStats( 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) document.getElementById('statistics')); 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) remoting.formatIq = new remoting.FormatIq(); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) remoting.hostList = new remoting.HostList( 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) document.getElementById('host-list'), 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) document.getElementById('host-list-empty'), 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) document.getElementById('host-list-error-message'), 7758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) document.getElementById('host-list-refresh-failed-button'), 7858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) document.getElementById('host-list-loading-indicator')); 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) remoting.toolbar = new remoting.Toolbar( 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) document.getElementById('session-toolbar')); 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) remoting.clipboard = new remoting.Clipboard(); 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) var sandbox = /** @type {HTMLIFrameElement} */ 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) document.getElementById('wcs-sandbox'); 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) remoting.wcsSandbox = new remoting.WcsSandboxContainer(sandbox.contentWindow); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 86b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) /** @param {remoting.Error} error */ 87b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) var onGetEmailError = function(error) { 88b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // No need to show the error message for NOT_AUTHENTICATED 89b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // because we will show "auth-dialog". 90b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (error != remoting.Error.NOT_AUTHENTICATED) { 91b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) remoting.showErrorMessage(error); 92b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) } 93b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) } 94b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) remoting.identity.getEmail(remoting.onEmail, onGetEmailError); 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) remoting.showOrHideIT2MeUi(); 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) remoting.showOrHideMe2MeUi(); 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The plugin's onFocus handler sends a paste command to |window|, because 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // it can't send one to the plugin element itself. 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window.addEventListener('paste', pluginGotPaste_, false); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window.addEventListener('copy', pluginGotCopy_, false); 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) remoting.initModalDialogs(); 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (isHostModeSupported_()) { 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var noShare = document.getElementById('chrome-os-no-share'); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) noShare.parentNode.removeChild(noShare); 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var button = document.getElementById('share-button'); 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) button.disabled = true; 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) var onLoad = function() { 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Parse URL parameters. 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) var urlParams = getUrlParameters_(); 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if ('mode' in urlParams) { 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (urlParams['mode'] == 'me2me') { 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) var hostId = urlParams['hostId']; 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) remoting.connectMe2Me(hostId); 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // No valid URL parameters, start up normally. 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) remoting.initHomeScreenUi(); 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) remoting.hostList.load(onLoad); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // For Apps v1, check the tab type to warn the user if they are not getting 1303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // the best keyboard experience. 1313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!remoting.isAppsV2 && navigator.platform.indexOf('Mac') == -1) { 1323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) /** @param {boolean} isWindowed */ 1333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) var onIsWindowed = function(isWindowed) { 1343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!isWindowed) { 1353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) document.getElementById('startup-mode-box-me2me').hidden = false; 1363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) document.getElementById('startup-mode-box-it2me').hidden = false; 1373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 1383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) }; 1393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) isWindowed_(onIsWindowed); 1403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Display the user's email address and allow access to the rest of the app, 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * including parsing URL parameters. 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {string} email The user's email address. 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @return {void} Nothing. 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)remoting.onEmail = function(email) { 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) document.getElementById('current-email').innerText = email; 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) document.getElementById('get-started-it2me').disabled = false; 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) document.getElementById('get-started-me2me').disabled = false; 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/** 157b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) * Returns whether or not IT2Me is supported via the host NPAPI plugin. 158b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) * 159b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) * @return {boolean} 160b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) */ 161b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)function isIT2MeSupported_() { 162b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) var container = document.getElementById('host-plugin-container'); 163b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) /** @type {remoting.HostPlugin} */ 164b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) var plugin = remoting.HostSession.createPlugin(); 165b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) container.appendChild(plugin); 166b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) var result = plugin.hasOwnProperty('REQUESTED_ACCESS_CODE'); 167b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) container.removeChild(plugin); 168b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return result; 169b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} 170b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 171b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)/** 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * initHomeScreenUi is called if the app is not starting up in session mode, 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * and also if the user cancels pin entry or the connection in session mode. 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */ 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)remoting.initHomeScreenUi = function() { 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) remoting.hostController = new remoting.HostController(); 177b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) document.getElementById('share-button').disabled = !isIT2MeSupported_(); 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) remoting.setMode(remoting.AppMode.HOME); 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) remoting.hostSetupDialog = 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new remoting.HostSetupDialog(remoting.hostController); 181a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch var dialog = document.getElementById('paired-clients-list'); 182a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch var message = document.getElementById('paired-client-manager-message'); 183a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch var deleteAll = document.getElementById('delete-all-paired-clients'); 184a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch var close = document.getElementById('close-paired-client-manager-dialog'); 185a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch var working = document.getElementById('paired-client-manager-dialog-working'); 186a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch var error = document.getElementById('paired-client-manager-dialog-error'); 187a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch var noPairedClients = document.getElementById('no-paired-clients'); 188a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch remoting.pairedClientManager = 189a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch new remoting.PairedClientManager(remoting.hostController, dialog, message, 190a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch deleteAll, close, noPairedClients, 191a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch working, error); 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Display the cached host list, then asynchronously update and re-display it. 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) remoting.updateLocalHostState(); 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) remoting.hostList.refresh(remoting.updateLocalHostState); 195868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) remoting.butterBar = new remoting.ButterBar(); 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 199a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch * Fetches local host state and updates the DOM accordingly. 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)remoting.updateLocalHostState = function() { 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /** 203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * @param {string?} hostId Host id. 204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) */ 205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) var onHostId = function(hostId) { 206c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) remoting.hostController.getLocalHostState(onHostState.bind(null, hostId)); 207c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) }; 208c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 209c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /** 210c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * @param {string?} hostId Host id. 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param {remoting.HostController.State} state Host state. 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */ 213c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) var onHostState = function(hostId, state) { 214c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) remoting.hostList.setLocalHostStateAndId(state, hostId); 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) remoting.hostList.display(); 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 217c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 218a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch /** 219a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) * @param {boolean} response True if the feature is present. 220a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch */ 221a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) var onHasFeatureResponse = function(response) { 222a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) /** 223a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) * @param {remoting.Error} error 224a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) */ 225a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) var onError = function(error) { 226a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) console.error('Failed to get pairing status: ' + error); 227a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) remoting.pairedClientManager.setPairedClients([]); 228a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) }; 229a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 230a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (response) { 231a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) remoting.hostController.getPairedClients( 232a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) remoting.pairedClientManager.setPairedClients.bind( 233a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) remoting.pairedClientManager), 234a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) onError); 235a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } else { 236a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) console.log('Pairing registry not supported by host.'); 237a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) remoting.pairedClientManager.setPairedClients([]); 238a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 239a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) }; 240a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 241a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) remoting.hostController.hasFeature( 242a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) remoting.HostController.Feature.PAIRING_REGISTRY, onHasFeatureResponse); 243c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) remoting.hostController.getLocalHostId(onHostId); 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Log information about the current extension. 2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * The extension manifest is parsed to extract this info. 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)remoting.logExtensionInfo_ = function() { 25158e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch var v2OrLegacy = remoting.isAppsV2 ? " (v2)" : " (legacy)"; 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) var manifest = chrome.runtime.getManifest(); 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (manifest && manifest.version) { 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) var name = chrome.i18n.getMessage('PRODUCT_NAME'); 25558e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch console.log(name + ' version: ' + manifest.version + v2OrLegacy); 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) console.error('Failed to get product version. Corrupt manifest?'); 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * If an IT2Me client or host is active then prompt the user before closing. 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * If a Me2Me client is active then don't bother, since closing the window is 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the more intuitive way to end a Me2Me session, and re-connecting is easy. 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)remoting.promptClose = function() { 2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!remoting.clientSession || 2683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) remoting.clientSession.getMode() == remoting.ClientSession.Mode.ME2ME) { 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return null; 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (remoting.currentMode) { 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case remoting.AppMode.CLIENT_CONNECTING: 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case remoting.AppMode.HOST_WAITING_FOR_CODE: 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case remoting.AppMode.HOST_WAITING_FOR_CONNECTION: 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case remoting.AppMode.HOST_SHARED: 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case remoting.AppMode.IN_SESSION: 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return chrome.i18n.getMessage(/*i18n-content*/'CLOSE_PROMPT'); 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return null; 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Sign the user out of Chromoting by clearing (and revoking, if possible) the 2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * OAuth refresh token. 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Also clear all local storage, to avoid leaking information. 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)remoting.signOut = function() { 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) remoting.oauth2.clear(); 2917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) chrome.storage.local.clear(); 2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) remoting.setMode(remoting.AppMode.HOME); 2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) document.getElementById('auth-dialog').hidden = false; 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns whether the app is running on ChromeOS. 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @return {boolean} True if the app is running on ChromeOS. 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)remoting.runningOnChromeOS = function() { 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return !!navigator.userAgent.match(/\bCrOS\b/); 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Callback function called when the browser window gets a paste operation. 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {Event} eventUncast 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @return {void} Nothing. 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)function pluginGotPaste_(eventUncast) { 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var event = /** @type {remoting.ClipboardEvent} */ eventUncast; 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (event && event.clipboardData) { 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) remoting.clipboard.toHost(event.clipboardData); 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Callback function called when the browser window gets a copy operation. 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {Event} eventUncast 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @return {void} Nothing. 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)function pluginGotCopy_(eventUncast) { 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var event = /** @type {remoting.ClipboardEvent} */ eventUncast; 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (event && event.clipboardData) { 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (remoting.clipboard.toOs(event.clipboardData)) { 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The default action may overwrite items that we added to clipboardData. 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event.preventDefault(); 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns whether Host mode is supported on this platform. 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @return {boolean} True if Host mode is supported. 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)function isHostModeSupported_() { 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Currently, sharing on Chromebooks is not supported. 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return !remoting.runningOnChromeOS(); 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @return {Object.<string, string>} The URL parameters. 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)function getUrlParameters_() { 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var result = {}; 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var parts = window.location.search.substring(1).split('&'); 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (var i = 0; i < parts.length; i++) { 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var pair = parts[i].split('='); 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result[pair[0]] = decodeURIComponent(pair[1]); 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {string} jsonString A JSON-encoded string. 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @return {*} The decoded object, or undefined if the string cannot be parsed. 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)function jsonParseSafe(jsonString) { 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) try { 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return JSON.parse(jsonString); 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } catch (err) { 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return undefined; 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Return the current time as a formatted string suitable for logging. 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @return {string} The current time, formatted as [mmdd/hhmmss.xyz] 3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */ 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)remoting.timestamp = function() { 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /** 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {number} num A number. 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {number} len The required length of the answer. 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @return {string} The number, formatted as a string of the specified length 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * by prepending zeroes as necessary. 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var pad = function(num, len) { 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var result = num.toString(); 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result.length < len) { 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = new Array(len - result.length + 1).join('0') + result; 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var now = new Date(); 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var timestamp = pad(now.getMonth() + 1, 2) + pad(now.getDate(), 2) + '/' + 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pad(now.getHours(), 2) + pad(now.getMinutes(), 2) + 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pad(now.getSeconds(), 2) + '.' + pad(now.getMilliseconds(), 3); 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return '[' + timestamp + ']'; 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Show an error message, optionally including a short-cut for signing in to 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Chromoting again. 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {remoting.Error} error 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @return {void} Nothing. 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)remoting.showErrorMessage = function(error) { 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) l10n.localizeElementFromTag( 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) document.getElementById('token-refresh-error-message'), 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error); 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var auth_failed = (error == remoting.Error.AUTHENTICATION_FAILED); 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) document.getElementById('token-refresh-auth-failed').hidden = !auth_failed; 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) document.getElementById('token-refresh-other-error').hidden = auth_failed; 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) remoting.setMode(remoting.AppMode.TOKEN_REFRESH_FAILED); 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/** 4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Determine whether or not the app is running in a window. 4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @param {function(boolean):void} callback Callback to receive whether or not 4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * the current tab is running in windowed mode. 4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */ 4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)function isWindowed_(callback) { 4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /** @param {chrome.Window} win The current window. */ 4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) var windowCallback = function(win) { 4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback(win.type == 'popup'); 4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /** @param {chrome.Tab} tab The current tab. */ 4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) var tabCallback = function(tab) { 4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (tab.pinned) { 4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback(false); 4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) chrome.windows.get(tab.windowId, null, windowCallback); 4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (chrome.tabs) { 4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) chrome.tabs.getCurrent(tabCallback); 4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) console.error('chome.tabs is not available.'); 4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 436c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 437c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)/** 438c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * Migrate settings in window.localStorage to chrome.storage.local so that 439c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * users of older web-apps that used the former do not lose their settings. 440c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) */ 441c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)function migrateLocalToChromeStorage_() { 442c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The OAuth2 class still uses window.localStorage, so don't migrate any of 443c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // those settings. 444c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) var oauthSettings = [ 445c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 'oauth2-refresh-token', 446c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 'oauth2-refresh-token-revokable', 447c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 'oauth2-access-token', 448c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 'oauth2-xsrf-token', 449c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 'remoting-email' 450c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ]; 451c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (var setting in window.localStorage) { 452c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (oauthSettings.indexOf(setting) == -1) { 453c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) var copy = {} 454c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) copy[setting] = window.localStorage.getItem(setting); 455c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) chrome.storage.local.set(copy); 456c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) window.localStorage.removeItem(setting); 457c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 458c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 459c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 460c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 461c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)/** 462c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * Generate a nonce, to be used as an xsrf protection token. 463c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * 464c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * @return {string} A URL-Safe Base64-encoded 128-bit random value. */ 465c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)remoting.generateXsrfToken = function() { 466c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) var random = new Uint8Array(16); 467c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) window.crypto.getRandomValues(random); 468c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) var base64Token = window.btoa(String.fromCharCode.apply(null, random)); 469c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return base64Token.replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, ''); 470c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 471