Jimadine
Jimadine

Reputation: 1064

Chrome idle extension for kiosk environment with notification and browsing data reset

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

Upvotes: 0

Views: 2757

Answers (1)

Xan
Xan

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 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.

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

Related Questions