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 |