Reputation: 1064
I've written a skeleton Chrome extension for a Library kiosk environment. The purpose of the extension is to clear all browsing data and restart Chrome after X seconds of inactivity. I was inspired by the Idle Reset extension on the Chrome web store, but this doesn't provide all features I'd like. Ideally I would like to mimic Presto-based Opera's inactivity reset, present in kiosk mode, where a dialogue window with a countdown is displayed, i.e.:
Inactivity reset
The browser will be reset and all browsing data removed in 60...1 seconds
But I think that's maybe a bit too complicated and I'm not sure whether the chrome.notification
API supports dynamic content such as countdown timers.
So far I have come up with some code that displays a chrome notification after 1 minute of inactivity. The notification informs the user the browser will be reset in 30 seconds unless activity is resumed. The notification then closes itself. After a further 30 seconds of inactivity, the browsing data is cleared, any existing tabs removed and a new tab opened. I am using the chrome.alarms
API and lowering the chrome.idle.setDetectionInterval
after the first idle event. If the user resumes activity the alarms and notifications are cleared, and chrome.idle.setDetectionInterval
is restored to the default value of 60 seconds.
Here is my event.js
code:
chrome.idle.onStateChanged.addListener(function (newState) {
if (newState == "idle") {
var opt = {
type: "basic",
title: "Web Browser about to be reset",
message: "Web browser has been inactive for 1 minute. Move the mouse or type something within 30 seconds to prevent the reset.",
iconUrl: "refresh-icon.png"
};
chrome.notifications.create("browserResetNotification", opt, function() {
chrome.idle.setDetectionInterval(15);
chrome.alarms.create("inactivityAlarm", {'when': Date.now() + 30000})
});
}
else {
chrome.alarms.clear("inactivityAlarm", function() {});
chrome.notifications.clear("browserResetNotification", function() {});
chrome.idle.setDetectionInterval(60);
}
});
chrome.alarms.onAlarm.addListener(function (alarm) {
if (alarm.name == 'inactivityAlarm') {
chrome.browsingData.remove({
}, {
"appcache": true,
"cache": true,
"cookies": true,
"downloads": true,
"fileSystems": true,
"formData": true,
"history": true,
"indexedDB": true,
"localStorage": true,
"pluginData": true,
"passwords": true,
"webSQL": true
});
chrome.tabs.create({
url: "http://myurl.com",
active: true
}, function (newtab) {
chrome.tabs.query({}, function (results) {
for (var i = 0; i < results.length; i++) {
var tab = results[i];
if (tab.id != newtab.id) {
chrome.tabs.remove(tab.id);
}
}
});
});
}
})
My questions
chrome.idle
API, in particular when to use chrome.idle.queryState
method versus when to use chrome.idle.onStateChanged
event. In particular it would be nice to be able to query the state at that very moment without having to provide a detectionIntervalInSeconds
, required by the method.chrome.notifications.clear
method actually do? Signal to Chrome that any record of a notification should be removed? Or force a notification to be removed from the user's display? I'm unclear on when it'd be appropriate to use it.Upvotes: 0
Views: 2757
Reputation: 77571
It's not good to lump questions together on SO, but I'll try to reply.
First off, some background info on notifications.
A notification can be shown on screen (which normally happens when it's created), or hidden in the notification center of Chrome (the bell icon in the system tray). In either case it's still "open". Chrome automatically moves notifications there after a bit of time (that depends on the priority
property).
Now, to your questions.
I've been testing my code and have found it's not altogether reliable (i.e. the notification/reset doesn't always occur), and TBH I'm not surprised.
The notification does not re-appear if you try to reuse the notification ID without closing the notification first. It is then updated in-place in the notification center and not re-shown. So if you are reusing the ID and want it to appear again, clear
before create
.
The alarm might not go off because the minimum granularity for chrome.alarms
API is 1 minute. If you need lower granularity, you'll need to use DOM setTimeout
(which is not compatible with event pages if you use one).
Is it possible to display a chrome notification for a fixed duration rather than have it open and close of its own accord? I'd like to have it show for the full 30 seconds up to the point the alarm fires and the browser resets.
Not easily, no. Like I said, the time it's shown on-screen depends on the priority, but even high-priority notifications don't last forever and the exact timing is not documented. However, this leads to the existence of the priority update trick.
In your case, you may have better luck with Web Notifications API. They look simpler, but will do the job in your particular use case. The upside is that they never disappear on their own.
I am confused about the
chrome.idle
API, in particular when to usechrome.idle.queryState
method versus when to usechrome.idle.onStateChanged
event. In particular it would be nice to be able to query the state at that very moment without having to provide adetectionIntervalInSeconds
, required by the method.
The difference is between the question "As of this moment, have the user been idle in the last N seconds?" and asking Chrome "Tell me as soon as user has been idle for N seconds". They both have their use, but in your case you probably want to react to events.
By the way, in your code calling chrome.idle.setDetectionInterval(15)
makes no sense. As soon as input happens when your current state is idle
the event will fire - it does not matter how long it was idle for before.
It can actually break your logic completely (maybe that's the reason your code is unreliable) if that makes Chrome reconsider the idle
state.
What does
chrome.notifications.clear
method actually do? Signal to Chrome that any record of a notification should be removed? Or force a notification to be removed from the user's display? I'm unclear on when it'd be appropriate to use it.
chrome.notifications.clear
does the same as clicking the X
on the notification itself - closes it, as opposed to hiding. This makes the ID no longer refer to a notification - so a new one will be created if you reuse the ID. It also triggers the onClosed
event. If the notification is displayed on screen at this point, it will be immediately removed.
If you're looking at the message center when clear
is called, the weirdest thing happens - the notification ceases to exist from your code's perspective, but is still visible until the message center is closed.
And finally..
Is there a better approach?
I honestly don't know. Your approach seems okay, if one forgets the minimum alarms
granularity.
Upvotes: 2