fognl

Get off my lawn.

Friday, November 28, 2008

To/From Ibex

Whenever a new version of Ubuntu comes out, I usually write some kind of post about it after I upgrade, talking about it. In every case so far, the upgrade brings new functionality, better ease-of-use, a cooler-looking user interface, and other minutiae that no one really cares about, but still represents progress.

So, a couple of weeks ago, I installed the latest Ubuntu, Ibex (8.10), on my big supercollider machine in my house. I use that machine mostly for audio recording. It has an M-Audio sound card with variable sample rate, 12 in/outs, gold-plated connectors, 2ms latency, etc. In the world of "Machines in my Basement", this one is fairly important, and one of the cooler ones.

Before doing the upgrade, I took the opportunity to move my home directory to a separate physical partition on the drive. Having done this, I highly recommend it, since now I can upgrade the OS without touching the data in my home directory (read as "pretty much everything but the OS and applications").

Having done that, on to the upgrade. I did a clean installation on the non-home partition, formatting the partition first.

The installation started out smoothly enough, then stopped with a message:

Unable to copy files. It may be that your CD-ROM is defective, or your CD burner is defective, or your machine has overheated, or is running in a hot environment. Also, you could have burned the CD you're installing from at too high a rate. That can cause problems. You might want to burn another one at a lower rate.

Unable to copy files. You may be installing this OS in a jungle, or on a machine that should probably be thrown away. That's probably it. Either way, it sucks to be you. If the problems I've mentioned aren't the cause of this problem, well..... Go away and burn a CD, and take your time doing it. That may take your mind off the fact that your new OS installation isn't going so well. Sorry about that. Please don't be mad at us.

It sounded like a tech-support guy with no answers, trying to get someone off the phone. (Like those nice people who work for Embarq in residential DSL support.)

No other options were available to me, so I did as the message suggested and burned a CD on another machine at the slowest possible rate, to really bake those files into the plastic. (Rule #1 with Linux machines: NEVER EVER have just one machine. You'll need a second machine for emergency support at some point.)

With my new fully-cooked/half-melted CD in the drive, I attempted the installation again. This time it worked without any complaints. It was able to copy all of the files, and the installation completed successfully. I guess that error message was helpful after all.

Having completed the installation, I booted into the new OS. Here's what I found:

. The new "Ibex" wallpaper looks bad. It's as if someone got a monkey to stand next to a concrete wall, and then smashed into the wall with tractor, crushing the monkey against it. Then they came back a few weeks later after things had dried, hosed the broken bones, hair and teeth off the wall, and took a sepia-toned photograph of the crime scene.

. There's a new "Guest" account, which is great if you have a coffee shop or something where people want to come in and surf the web in style while enjoying a $4 latte. Except the window manager was using some crappy-looking theme from 1998, so it wasn't that stylish.

. Audio is completely broken. I couldn't get anything related to audio to work at all, ever, under any circumstances, unless I used mplayer from the command line to play movies, or jackd to play "pro" audio stuff.

. Shortcut keys still don't work. Starting with 8.04, all of the shortcut keys I defined in System/Preferences/Shortcut Keysstopped working. I had to manually define them in the GConf editor, or use UbuntuTweak to do it. This was broken in Ibex too.

. I found out that there's no SMP real-time kernel support, so even if the audio worked, it wouldn't work as well in Ibex as it did in Hardy.

Last night, I downgraded. It took about 45 minutes to put the old version back on, get it configured the way I want it, and get the machine back into a useable state. Audio is working fine again, all my stuff is there, and I'm happy with it. Thank God for separate home partitions.

I guess this Ubuntu release is intended more for mobile users, and there are some improvements in the UI, but it didn't constitute an improvement for me. I guess this is still a sign of progress... When the OS gets to the point where it works great and an upgrade offers little to no benefit, you could say it's getting pretty good and hard to improve on.

Thursday, November 27, 2008

Android: net-handler-android

I built a library that I've been using in Android applications for dealing with long-running background operations where you need to retrieve data from an external source, and getting the data might take a while.

I thought about writing a bunch of stuff about it here, but decided against it. It's a library, pretty simple, and is thus boring. If you disagree, you can check it out on Google Code at http://code.google.com/p/net-handler-android/.

Tuesday, November 25, 2008

Picture post

Android: Ring Control

I've been playing around with a little Android application for a few weeks now, while taking occasional breaks from working on other, more "real" Android projects.

It's called Ring Control, and it puts your phone on vibrate (or silent, depending on your preferences) mode if you put it upside-down in your pocket, or lay it face-down on a table (again, depending on your preferences).

The idea is pretty simple, and the implementation was too, at least initially. It's easy: Get a reference to the SensorManager, tell it you want to know about orientation changes, calculate the degrees of pitch in the orientation, and set the ringer mode depending on the pitch value. I gave it about 50 degrees of latitude (or is that longitude) in either direction to keep it from being too touchy about device orientation.

The app consists mainly of two parts: The UI screen (for starting and stopping Ring Control and setting preferences), and the background service that actually controls the ringer. Probably the smallest Android app I've written since that "Hello World" app back in '08.

As I said, the idea is simple, but it turns out to be kind of a tricky problem. The "hard" part (well, not hard, now that I know what to do) is making it work like you would expect it to work.

As it happens, Android is pretty conservative about things like memory and battery power, and isn't keen on letting background services just sit there and nibble on the CPU while doing nothing else. ("nothing else" in this case defined as "not having any clients asking them for things"). So after about 1/2 hour, my background service would just stop, with no notifications or anything else. Since the whole point of Ring Control is to turn your ringer to vibrate and keep the phone quiet, it doesn't seem too useful to have it just stop suddenly, letting your phone spew out a loud "riiiiinnng..." (or other obnoxious ringtone) while you're in a funeral or something and need for it to be quiet.

I started reading about the various ways to tackle the problem, and read about "wake locks" and other things that you can use to poke at the phone's CPU to keep it alive so your service will work. That seemed like a good way to eat up batteries, and there was still nothing in the idea that would seem to actually ensure that the service kept working.

So, no.

As it turns out, there is an accepted way to keep a background service running, and that is to use the AlarmManager system service. Essentially, you schedule a repeating alarm, say, every 5-10 minutes, and the "alarm" is an "Intent" (Android-speak for "thing that runs something") telling the AlarmManager to start your service (or activity or broadcast message). It seems like kind of a goofy way to do it, really. I read about it, and thought "Seriously? I have the AlarmManager start me at regular intervals?" Whatever works, I guess. In any case, I set it up so the "start" signal just keeps the service running if it's already running, instead of starting another copy.

Having done that, the service now runs as long as it's supposed to, and doesn't poop out spontaneously.

Ring Control turned out to be pretty popular on the Android Market, with a lot of people downloading it and e-mailing me about it and commenting on it in the Android Market. (Best comment so far: "I give it 3 stars. I wish it would show movie times." Huh?) One feature people asked for was the ability to run it automatically when the phone boots.

Like a lot of things with Android, I seem to look in the wrong place initially for information about how to do something. I started thinking about some kind of "startup folder" metaphor somewhere, found nothing.

The way to get a service or application to run at startup is to create a "BroadcastReceiver", a class that receives a broadcast notification from the OS when something happens, and assign to it a key. There are keys for all kinds of events (e.g. incoming call, SMS message, blah blah blah). The one I was interested in was "android.intent.action.BOOT_COMPLETED." This notification gets sent to applications that want to know about it, even if they're not running. Android pulls a BroadcastReceiver out of bed and calls its onReceive() method, passing it some info about what's starting it. In my case, I just start the Ring Control service in my BroadcastReceiver, and that's it.

Now that that's done, I've got some other ideas on how to use the orientation sensor for something interesting.

Overall, I kind of enjoy walking around with a device with all this stuff on it. It has a compass, orientation sensors, GPS, internet access, audio and video playback (makes a good iPod), functions as a mirror when the screen's turned off, makes a good hand warmer if you surf the web a lot, is heavy and chunky enough to ward off an attacker, and has changed my life in general: I no longer have time to sit in meetings getting annoyed at people playing with their fancy phones. I'm too busy playing with my phone.