• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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