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.
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.
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.
22 /** @suppress {duplicate} */
23 var remoting = remoting || {};
26 * @param {HTMLElement} rootElement The idle warning dialog.
27 * @param {string} applicationName
28 * @param {function():void} callback Called when the idle warning dialog has
29 * timed out or the user has explicitly indicated that they are no longer
32 * @implements {base.Disposable}
34 remoting.IdleDetector = function(rootElement, applicationName, callback) {
36 this.callback_ = callback;
39 * @private {base.OneShotTimer}
43 /** @private {?function():void} */
44 this.resetTimeoutRef_ = null;
46 var message = rootElement.querySelector('.idle-warning-message');
47 l10n.localizeElement(message, applicationName);
50 this.dialog_ = new remoting.Html5ModalDialog({
51 dialog: /** @type {HTMLDialogElement} */ (rootElement),
52 primaryButton: rootElement.querySelector('.idle-dialog-continue'),
53 secondaryButton: rootElement.querySelector('.idle-dialog-disconnect'),
60 remoting.IdleDetector.prototype.dispose = function() {
61 base.dispose(this.timer_);
64 if (this.resetTimeoutRef_) {
65 this.registerInputDetectionCallbacks_(false);
67 base.dispose(this.dialog_);
72 * @param {boolean} register True to register the callbacks; false to remove
76 remoting.IdleDetector.prototype.registerInputDetectionCallbacks_ =
78 var events = [ 'mousemove', 'mousedown', 'mouseup', 'click',
79 'keyup', 'keydown', 'keypress' ];
81 base.debug.assert(this.resetTimeoutRef_ == null);
82 this.resetTimeoutRef_ = this.resetTimeout_.bind(this);
83 for (var i = 0; i < events.length; ++i) {
84 document.body.addEventListener(events[i], this.resetTimeoutRef_, true);
87 base.debug.assert(this.resetTimeoutRef_ != null);
88 for (var i = 0; i < events.length; ++i) {
89 document.body.removeEventListener(events[i], this.resetTimeoutRef_, true);
91 this.resetTimeoutRef_ = null;
98 remoting.IdleDetector.prototype.resetTimeout_ = function() {
99 if (this.resetTimeoutRef_ == null) {
100 this.registerInputDetectionCallbacks_(true);
102 base.dispose(this.timer_);
103 this.timer_ = new base.OneShotTimer(this.onIdleTimeout_.bind(this),
104 remoting.IdleDetector.kIdleTimeoutMs);
110 remoting.IdleDetector.prototype.onIdleTimeout_ = function() {
111 this.registerInputDetectionCallbacks_(false);
112 this.timer_ = new base.OneShotTimer(this.onDialogTimeout_.bind(this),
113 remoting.IdleDetector.kDialogTimeoutMs);
114 this.showIdleWarning_();
120 remoting.IdleDetector.prototype.onDialogTimeout_ = function() {
121 base.dispose(this.timer_);
123 this.dialog_.close(remoting.MessageDialog.Result.SECONDARY);
129 remoting.IdleDetector.prototype.showIdleWarning_ = function() {
131 this.dialog_.show().then(function(
132 /** remoting.MessageDialog.Result */ result) {
133 if (result === remoting.MessageDialog.Result.PRIMARY) {
135 that.resetTimeout_();
136 } else if (result === remoting.MessageDialog.Result.SECONDARY) {
138 base.dispose(that.timer_);
145 // Time-out after 1hr of no activity.
146 remoting.IdleDetector.kIdleTimeoutMs = 60 * 60 * 1000;
148 // Show the idle warning dialog for 2 minutes.
149 remoting.IdleDetector.kDialogTimeoutMs = 2 * 60 * 1000;