1// Copyright 2014 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5/** 6 * @fileoverview 7 * 8 * HostInstaller allows the caller to download the host binary and monitor the 9 * install progress of the host by pinging the host periodically via native 10 * messaging. 11 * 12 * To download the host and wait for install: 13 * var hostInstaller = new remoting.HostInstaller(); 14 * hostInstaller.downloadAndWaitForInstall().then(function() { 15 * // Install has completed. 16 * }, function(){ 17 * // Download has failed. 18 * }) 19 * 20 * To stop listening to the install progress: 21 * hostInstaller.cancel(); 22 */ 23 24'use strict'; 25 26/** @suppress {duplicate} */ 27var remoting = remoting || {}; 28 29/** 30 * @constructor 31 */ 32remoting.HostInstaller = function() { 33 /** 34 * @type {Promise} 35 * @private 36 */ 37 this.downloadAndWaitForInstallPromise_ = null; 38 39 /** 40 * @type {?number} 41 * @private 42 */ 43 this.checkInstallIntervalId_ = null; 44}; 45 46/** 47 * @return {Promise} The promise will resolve to a boolean value indicating 48 * whether the host is installed or not. 49 */ 50remoting.HostInstaller.prototype.isInstalled = function() { 51 // Always do a fresh check as we don't get notified when the host is 52 // uninstalled. 53 54 /** @param {function(*=):void} resolve */ 55 return new Promise(function(resolve) { 56 // TODO(kelvinp): Use different native messaging ports for the Me2me host 57 // vs It2MeHost. 58 /** @type {chrome.runtime.Port} */ 59 var port = 60 chrome.runtime.connectNative('com.google.chrome.remote_assistance'); 61 62 function onMessage() { 63 port.onDisconnect.removeListener(onDisconnected); 64 port.onMessage.removeListener(onMessage); 65 port.disconnect(); 66 resolve(true); 67 } 68 69 function onDisconnected() { 70 port.onDisconnect.removeListener(onDisconnected); 71 port.onMessage.removeListener(onMessage); 72 resolve(false); 73 } 74 75 port.onDisconnect.addListener(onDisconnected); 76 port.onMessage.addListener(onMessage); 77 port.postMessage({type: 'hello'}); 78 }); 79}; 80 81/** 82 * @throws {Error} Throws if there is no matching host binary for the current 83 * platform. 84 */ 85remoting.HostInstaller.prototype.download = function() { 86 /** @type {Object.<string,string>} */ 87 var hostDownloadUrls = { 88 'Win32' : 'http://dl.google.com/dl/edgedl/chrome-remote-desktop/' + 89 'chromeremotedesktophost.msi', 90 'Win64' : 'http://dl.google.com/dl/edgedl/chrome-remote-desktop/' + 91 'chromeremotedesktophost.msi', 92 'MacIntel' : 'https://dl.google.com/chrome-remote-desktop/' + 93 'chromeremotedesktop.dmg', 94 'Linux x86_64' : 'https://dl.google.com/linux/direct/' + 95 'chrome-remote-desktop_current_amd64.deb', 96 'Linux i386' : 'https://dl.google.com/linux/direct/' + 97 'chrome-remote-desktop_current_i386.deb' 98 }; 99 100 var hostPackageUrl = hostDownloadUrls[navigator.platform]; 101 if (hostPackageUrl === undefined) { 102 throw new Error(remoting.Error.CANCELLED); 103 } 104 105 // Start downloading the package. 106 if (base.isAppsV2()) { 107 // TODO(jamiewalch): Use chrome.downloads when it is available to 108 // apps v2 (http://crbug.com/174046) 109 window.open(hostPackageUrl); 110 } else { 111 window.location = hostPackageUrl; 112 } 113}; 114 115/** @return {Promise} */ 116remoting.HostInstaller.prototype.downloadAndWaitForInstall = function() { 117 /** @type {remoting.HostInstaller} */ 118 var that = this; 119 /** 120 * @type {number} 121 * @const 122 */ 123 var CHECK_INSTALL_INTERVAL_IN_MILLISECONDS = 1000; 124 125 /** @param {boolean} installed */ 126 return this.isInstalled().then(function(installed){ 127 if (installed) { 128 return Promise.resolve(true); 129 } 130 131 if (that.downloadAndWaitForInstallPromise_ === null) { 132 that.downloadAndWaitForInstallPromise_ = new Promise( 133 /** @param {Function} resolve */ 134 function(resolve){ 135 that.download(); 136 that.checkInstallIntervalId_ = window.setInterval(function() { 137 /** @param {boolean} installed */ 138 that.isInstalled().then(function(installed) { 139 if (installed) { 140 that.cancel(); 141 resolve(); 142 } 143 }); 144 }, CHECK_INSTALL_INTERVAL_IN_MILLISECONDS); 145 }); 146 } 147 return that.downloadAndWaitForInstallPromise_; 148 }); 149}; 150 151/** 152 * Stops waiting for the host to be installed. 153 * For example 154 * var promise = hostInstaller.downloadAndWaitForInstall(); 155 * hostInstaller.cancel(); // This will prevent |promise| from fulfilling. 156 */ 157remoting.HostInstaller.prototype.cancel = function() { 158 if (this.checkInstallIntervalId_ !== null) { 159 window.clearInterval(this.checkInstallIntervalId_); 160 this.checkInstallIntervalId_ = null; 161 } 162 this.downloadAndWaitForInstallPromise_ = null; 163}; 164