31 July, 2013

chrome.power.requestKeepAwake(): Not just for extensions

Fellow Chrome OS/Chromebook users: Have you noticed that while most hosted Web apps can't run offline at all (or at the very least have to first be synced to the device to run offline in the future), there are countless Chrome extensions that can? And if you're a Dev Channel user, have you noticed that there is a whole new class of apps that open offline AND outside of the browser by default?

"Useless without Internet"? Seriously? Those two reasons above are alone enough to thwart that claim.

Anyway, it may not come as too much of a huge surprise, but packaged apps and extensions share much of the same APIs. That includes one of the most welcome APIs of them all: chrome.power. In fact, there happens to be an official Chrome extension that makes use of the chrome.power API to allow users to, with a browser window open, just click a browser action to toggle between requestKeepAwake("display") and releaseKeepAwake(), with no options in between. However, unlike extensions, packaged apps have kind of slacked when it comes to the true power of these APIs.

Until now.

Given how much I myself am learning both the APIs and HTML5/CSS3/Javascript as a whole, I figured I would get used to how packaged apps work. Thankfully, the Google Code Editor will (with the chrome.syncFileSystem.DirectoryEntry flag enabled) work on Chrome OS 29+ (beta channel or newer) just fine, and I decided to play around with it. The result? This packaged app.

Now, you may be thinking, "What's the difference"? Plenty. Packaged apps, unlike extensions, don't depend on the browser at all. They continue to run in the background when closed, and as such will continue to keep the device awake until the user actually logs out of the device completely. Meaning that simply launching the packaged app, without launching any browser windows, is all that's needed to access it, and so by simply launching the packaged app and clicking a button the user has already kept the device awake for an extended period of time.

And then there's the "more options" argument.

What if the user wants to keep the system awake without actually keeping the display awake, saving battery in the process? There's several use cases for that. Downloading multi-gigabyte files (even, God forbid, multi-gigabyte packaged apps) is one of them. Waiting for device updates to download is another. Still another is creating recovery devices just to be on the safe side in case something goes wrong. In all these use cases, extensive use of the network AND the display, in contrast to just the network, is a serious battery drainer, and so the user would likely prefer just keeping the system awake over keeping the entire device awake, such that the user doesn't have to keep the Chromebook plugged in while such a download is in progress. Good thing my packaged app includes three options instead of two: users can click "Keep system awake" instead of "Keep display awake" to allow the display to go dark without the entire system going to sleep.

As for notifying the user whether the device is actually being kept awake or not, there was a bit of a stumbling block there. There's no way to "alert()" the user because that functionality has been disabled in packaged apps. Using document.createTextNode to modify an in-app <p> element was also kind of on my agenda... but there's no way to delete that node once it has been created. Well, there is hope: Rich Notifications to the rescue.

Using "document.getElementById().addEventListener('click', ..." along with the Rich Notifications API, clicking the buttons will not only fire chrome.power.requestKeepAwake but also notify the user that the system is being kept awake, telling the user what to do to bring it back to its normal state. All without a single browser window being open.

And because the buttons in the app are large, Chromebook Pixel users should be ecstatic: They're much easier to use on touch screens than their browser action counterpart. Not to mention that the buttons' use of RGBA color space should look amazing on the Pixel's high-resolution display.

So, let me know what you think in the comments. I seriously hope more packaged apps can also take advantage of such APIs and really shine, and also hope to use this as my personal first step towards more awesome killer packaged apps that can really take the market by storm.