| OLD | NEW |
| (Empty) |
| 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 * Class for detecting when the application is idle. Note that chrome.idle is | |
| 8 * not suitable for this purpose because it detects when the computer is idle, | |
| 9 * and we'd like to close the application and free up VM resources even if the | |
| 10 * user has been using another application for a long time. | |
| 11 * | |
| 12 * There are two idle timeouts. The first controls the visibility of the idle | |
| 13 * timeout warning dialog and is reset on mouse input; when it expires, the | |
| 14 * idle warning dialog is displayed. The second controls the length of time | |
| 15 * for which the idle warning dialog is displayed; when it expires, the ctor | |
| 16 * callback is invoked, which it is assumed will exit the application--no | |
| 17 * further idle detection is done. | |
| 18 */ | |
| 19 | |
| 20 'use strict'; | |
| 21 | |
| 22 /** @suppress {duplicate} */ | |
| 23 var remoting = remoting || {}; | |
| 24 | |
| 25 /** | |
| 26 * @param {HTMLElement} rootElement The idle warning dialog. | |
| 27 * @param {remoting.WindowShape} windowShape | |
| 28 * @param {string} applicationName | |
| 29 * @param {function():void} callback Called when the idle warning dialog has | |
| 30 * timed out or the user has explicitly indicated that they are no longer | |
| 31 * using the session. | |
| 32 * @constructor | |
| 33 * @implements {base.Disposable} | |
| 34 */ | |
| 35 remoting.IdleDetector = function(rootElement, windowShape, applicationName, | |
| 36 callback) { | |
| 37 /** @private */ | |
| 38 this.callback_ = callback; | |
| 39 | |
| 40 /** | |
| 41 * @private {base.OneShotTimer} | |
| 42 */ | |
| 43 this.timer_ = null; | |
| 44 | |
| 45 /** @private {?function():void} */ | |
| 46 this.resetTimeoutRef_ = null; | |
| 47 | |
| 48 var message = rootElement.querySelector('.idle-warning-message'); | |
| 49 l10n.localizeElement(message, applicationName); | |
| 50 | |
| 51 /** @private */ | |
| 52 this.dialog_ = new remoting.Html5ModalDialog({ | |
| 53 dialog: /** @type {HTMLDialogElement} */ (rootElement), | |
| 54 primaryButton: rootElement.querySelector('.idle-dialog-continue'), | |
| 55 secondaryButton: rootElement.querySelector('.idle-dialog-disconnect'), | |
| 56 closeOnEscape: false, | |
| 57 windowShape: windowShape | |
| 58 }); | |
| 59 | |
| 60 this.resetTimeout_(); | |
| 61 }; | |
| 62 | |
| 63 remoting.IdleDetector.prototype.dispose = function() { | |
| 64 base.dispose(this.timer_); | |
| 65 this.timer_ = null; | |
| 66 | |
| 67 if (this.resetTimeoutRef_) { | |
| 68 this.registerInputDetectionCallbacks_(false); | |
| 69 } | |
| 70 base.dispose(this.dialog_); | |
| 71 this.dialog_ = null; | |
| 72 }; | |
| 73 | |
| 74 /** | |
| 75 * @param {boolean} register True to register the callbacks; false to remove | |
| 76 * them. | |
| 77 * @private | |
| 78 */ | |
| 79 remoting.IdleDetector.prototype.registerInputDetectionCallbacks_ = | |
| 80 function(register) { | |
| 81 var events = [ 'mousemove', 'mousedown', 'mouseup', 'click', | |
| 82 'keyup', 'keydown', 'keypress' ]; | |
| 83 if (register) { | |
| 84 console.assert(this.resetTimeoutRef_ == null, | |
| 85 '|resetTimeoutRef_| already exists.'); | |
| 86 this.resetTimeoutRef_ = this.resetTimeout_.bind(this); | |
| 87 for (var i = 0; i < events.length; ++i) { | |
| 88 document.body.addEventListener(events[i], this.resetTimeoutRef_, true); | |
| 89 } | |
| 90 } else { | |
| 91 console.assert(this.resetTimeoutRef_ != null, | |
| 92 '|resetTimeoutRef_| does not exist.'); | |
| 93 for (var i = 0; i < events.length; ++i) { | |
| 94 document.body.removeEventListener(events[i], this.resetTimeoutRef_, true); | |
| 95 } | |
| 96 this.resetTimeoutRef_ = null; | |
| 97 } | |
| 98 }; | |
| 99 | |
| 100 /** | |
| 101 * @private | |
| 102 */ | |
| 103 remoting.IdleDetector.prototype.resetTimeout_ = function() { | |
| 104 if (this.resetTimeoutRef_ == null) { | |
| 105 this.registerInputDetectionCallbacks_(true); | |
| 106 } | |
| 107 base.dispose(this.timer_); | |
| 108 this.timer_ = new base.OneShotTimer(this.onIdleTimeout_.bind(this), | |
| 109 remoting.IdleDetector.kIdleTimeoutMs); | |
| 110 }; | |
| 111 | |
| 112 /** | |
| 113 * @private | |
| 114 */ | |
| 115 remoting.IdleDetector.prototype.onIdleTimeout_ = function() { | |
| 116 this.registerInputDetectionCallbacks_(false); | |
| 117 this.timer_ = new base.OneShotTimer(this.onDialogTimeout_.bind(this), | |
| 118 remoting.IdleDetector.kDialogTimeoutMs); | |
| 119 this.showIdleWarning_(); | |
| 120 }; | |
| 121 | |
| 122 /** | |
| 123 * @private | |
| 124 */ | |
| 125 remoting.IdleDetector.prototype.onDialogTimeout_ = function() { | |
| 126 base.dispose(this.timer_); | |
| 127 this.timer_ = null; | |
| 128 this.dialog_.close(remoting.MessageDialog.Result.SECONDARY); | |
| 129 }; | |
| 130 | |
| 131 /** | |
| 132 * @private | |
| 133 */ | |
| 134 remoting.IdleDetector.prototype.showIdleWarning_ = function() { | |
| 135 var that = this; | |
| 136 this.dialog_.show().then(function( | |
| 137 /** remoting.MessageDialog.Result */ result) { | |
| 138 if (result === remoting.MessageDialog.Result.PRIMARY) { | |
| 139 // Continue. | |
| 140 that.resetTimeout_(); | |
| 141 } else if (result === remoting.MessageDialog.Result.SECONDARY) { | |
| 142 // Disconnect. | |
| 143 base.dispose(that.timer_); | |
| 144 that.timer_ = null; | |
| 145 that.callback_(); | |
| 146 } | |
| 147 }); | |
| 148 }; | |
| 149 | |
| 150 // Time-out after 1hr of no activity. | |
| 151 remoting.IdleDetector.kIdleTimeoutMs = 60 * 60 * 1000; | |
| 152 | |
| 153 // Show the idle warning dialog for 2 minutes. | |
| 154 remoting.IdleDetector.kDialogTimeoutMs = 2 * 60 * 1000; | |
| OLD | NEW |