| // Copyright 2015 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| /** |
| * @fileoverview |
| * Class handling saving and restoring of per-host options. |
| */ |
| |
| /** @suppress {duplicate} */ |
| var remoting = remoting || {}; |
| |
| (function(){ |
| |
| 'use strict'; |
| |
| /** |
| * @param {string} hostId |
| * @constructor |
| */ |
| remoting.HostOptions = function (hostId) { |
| /** @private @const */ |
| this.hostId_ = hostId; |
| |
| // This class violates the convention that private variables end with an |
| // underscore because it simplifies the load/save code. |
| |
| /** @private {?boolean} */ |
| this.shrinkToFit = null; |
| /** @private {?boolean} */ |
| this.resizeToClient = null; |
| /** @private {?number} */ |
| this.desktopScale = null; |
| /** @private {?remoting.PairingInfo} */ |
| this.pairingInfo = null; |
| /** @private {Object} */ |
| this.remapKeys = null; |
| }; |
| |
| /** |
| * Create a typed HostOptions instance from an untyped Object. |
| * |
| * @param {Object} object |
| * @param {string} hostId |
| * @return {remoting.HostOptions} |
| */ |
| remoting.HostOptions.fromObject = function(object, hostId) { |
| var result = new remoting.HostOptions(hostId); |
| try { |
| result.shrinkToFit = base.assertBoolean(object.shrinkToFit); |
| } catch (e) {} |
| try { |
| result.resizeToClient = base.assertBoolean(object.resizeToClient); |
| } catch (e) {} |
| try { |
| result.desktopScale = base.assertNumber(object.desktopScale); |
| } catch (e) {} |
| try { |
| pairingInfo = base.assertObject(object.pairingInfo); |
| } catch (e) {} |
| try { |
| remapKeys = base.assertObject(object.remapKeys); |
| } catch (e) {} |
| return result; |
| }; |
| |
| /** @return {boolean} True if the remote desktop should be reduced in size to |
| * fit a smaller client window; false if scroll-bars or bump-scrolling |
| * should be used instead. |
| */ |
| remoting.HostOptions.prototype.getShrinkToFit = function() { |
| return (this.shrinkToFit == null) ? true : this.shrinkToFit; |
| }; |
| |
| /** @param {boolean} shrinkToFit */ |
| remoting.HostOptions.prototype.setShrinkToFit = function(shrinkToFit) { |
| this.shrinkToFit = shrinkToFit; |
| }; |
| |
| /** @return {boolean} True if the remote desktop should be resized to fit the |
| * client window size. |
| */ |
| remoting.HostOptions.prototype.getResizeToClient = function() { |
| return (this.resizeToClient == null) ? true : this.resizeToClient; |
| }; |
| |
| /** @param {boolean} resizeToClient */ |
| remoting.HostOptions.prototype.setResizeToClient = function(resizeToClient) { |
| this.resizeToClient = resizeToClient; |
| }; |
| |
| /** @return {number} The scaling factor applied when rendering or resizing the |
| * remote desktop. |
| */ |
| remoting.HostOptions.prototype.getDesktopScale = function() { |
| return (this.desktopScale == null) ? 1 : this.desktopScale; |
| }; |
| |
| /** @param {number} desktopScale */ |
| remoting.HostOptions.prototype.setDesktopScale = function(desktopScale) { |
| this.desktopScale = desktopScale; |
| }; |
| |
| /** |
| * @return {!remoting.PairingInfo} The pairing info for this client/host pair. |
| */ |
| remoting.HostOptions.prototype.getPairingInfo = function() { |
| return (this.pairingInfo == null) |
| ? {clientId: '', sharedSecret: ''} |
| : /** @type {remoting.PairingInfo} */ (base.deepCopy(this.pairingInfo)); |
| }; |
| |
| /** |
| * @param {!remoting.PairingInfo} pairingInfo |
| */ |
| remoting.HostOptions.prototype.setPairingInfo = function(pairingInfo) { |
| this.pairingInfo = |
| /** @type {remoting.PairingInfo} */ (base.deepCopy(pairingInfo)); |
| }; |
| |
| /** |
| * @return {!Object} The key remapping to apply to connections to this host. |
| */ |
| remoting.HostOptions.prototype.getRemapKeys = function() { |
| if (this.remapKeys == null) { |
| return (remoting.platformIsChromeOS()) ? {0x0700e4: 0x0700e7} : {}; |
| } else { |
| return /** @type {!Object} */ (base.deepCopy(this.remapKeys)); |
| } |
| }; |
| |
| /** |
| * @param {string|!Object} remapKeys The new key remapping, either in the new- |
| * style dictionary format, or the old-style "from>to,..." string encoding. |
| */ |
| remoting.HostOptions.prototype.setRemapKeys = function(remapKeys) { |
| this.remapKeys = (typeof remapKeys == 'string') |
| ? remapKeysFromString_(/** @type {string} */(remapKeys)) |
| : /** @type {!Object} */ (base.deepCopy(remapKeys)) |
| }; |
| |
| /** |
| * Save the settings for this host. Only settings that have been set using one |
| * of the setter methods are saved. |
| * |
| * @return {Promise} Promise resolved when the save is complete. |
| */ |
| remoting.HostOptions.prototype.save = function() { |
| var settings = base.copyWithoutNullFields(this); |
| delete settings['hostId_']; // No need to save the hostId |
| |
| var hostId = this.hostId_; |
| return remoting.HostOptions.loadInternal_().then( |
| function(/** Object */ allHosts) { |
| allHosts[hostId] = settings; |
| var newSettings = {}; |
| newSettings[remoting.HostOptions.KEY_] = JSON.stringify(allHosts); |
| var deferred = new base.Deferred(); |
| chrome.storage.local.set(newSettings, |
| function() { deferred.resolve(); }); |
| return deferred.promise(); |
| }); |
| }; |
| |
| /** |
| * Load the settings for this host. |
| * |
| * @return {Promise} Promise resolved when the load is complete. |
| */ |
| remoting.HostOptions.prototype.load = function() { |
| var that = this; |
| return remoting.HostOptions.loadInternal_().then( |
| function(/** Object */ allHosts) { |
| if (allHosts.hasOwnProperty(that.hostId_) && |
| typeof(allHosts[that.hostId_]) == 'object') { |
| /** @type {!Object} */ |
| var host = allHosts[that.hostId_]; |
| base.mergeWithoutNullFields(that, host); |
| // Older clients stored remapKeys as a string, which will be decoded |
| // in setRemapKeys(). |
| if (typeof that.remapKeys == 'string') { |
| that.setRemapKeys(/** @type {string} */ (host['remapKeys'])); |
| } |
| } |
| }); |
| }; |
| |
| /** |
| * Helper function for both load and save. |
| * |
| * @return {Promise<Object>} Promise resolved with the current settings for |
| * all hosts. |
| * @private |
| */ |
| remoting.HostOptions.loadInternal_ = function() { |
| var deferred = new base.Deferred(); |
| /** |
| * @param {Object} storageResult The current options for all hosts. |
| */ |
| var onDone = function(storageResult) { |
| var result = {}; |
| try { |
| /** @type {string} */ |
| var allHosts = storageResult[remoting.HostOptions.KEY_]; |
| if (allHosts && typeof allHosts == 'string') { |
| result = base.jsonParseSafe(allHosts); |
| if (typeof(result) != 'object') { |
| console.error('Error loading host settings: Not an object'); |
| result = {}; |
| } |
| } |
| } catch (/** @type {*} */ err) { |
| console.error('Error loading host settings:', err); |
| } |
| deferred.resolve(result); |
| }; |
| chrome.storage.local.get(remoting.HostOptions.KEY_, onDone); |
| return deferred.promise(); |
| }; |
| |
| /** |
| * Convert an old-style string key remapping into a new-style dictionary one. |
| * |
| * @param {string} remappings |
| * @return {!Object} The same remapping expressed as a dictionary. |
| */ |
| function remapKeysFromString_(remappings) { |
| var remappingsArr = remappings.split(','); |
| var result = {}; |
| for (var i = 0; i < remappingsArr.length; ++i) { |
| var keyCodes = remappingsArr[i].split('>'); |
| if (keyCodes.length != 2) { |
| console.log('bad remapKey: ' + remappingsArr[i]); |
| continue; |
| } |
| var fromKey = parseInt(keyCodes[0], 0); |
| var toKey = parseInt(keyCodes[1], 0); |
| if (!fromKey || !toKey) { |
| console.log('bad remapKey code: ' + remappingsArr[i]); |
| continue; |
| } |
| result[fromKey] = toKey; |
| } |
| return result; |
| }; |
| |
| /** @type {string} @private */ |
| remoting.HostOptions.KEY_ = 'remoting-host-options'; |
| |
| })(); |