Gitorious ain’t glorious today

Gitorious’s ssh-authenticated access has been down all day, preventing us from pushing our commits on StatusNet and the StatusNet client.

Until it’s fixed, I’ve put up my StatusNet & StatusNet Desktop/Mobile client dev branches up on github, to be merged back onto the Gitorious mainline later:

* StatusNet – http://github.com/brion/statusnet
* client – http://github.com/brion/statusnet-client

Hopefully this inconvenience won’t last too long; I can add folks as collaborators on those repositories to make direct commits in the meantime.

Yet another iOS mulititasking explanation post

There’s been a lot of confusion about just how multitasking works in the iPhone’s latest iOS 4.0, and just what the limitations on background processes are. Most of the articles I’ve seen attempting to clarify it have concentrated on the addition of the new suspend state and how apps being background vs suspended vs terminated relates to the task list interface. That helps with the end-user confusion, but to me has just made it even more confusing from the developer’s perspective — I want to know what my app will be able to do in this brave new multitasking world, and what its limitations are going to be.

I’ve gone ahead and actually looked at the documentation (RTFM); here’s some notes… (Impatient readers may wish to skip to the summary at the end!)

Application state lifecycle

First, let’s go ahead and put those “background” and “suspend” states into perspective…

Not running

On screen? no
Running? no
In memory? no
Resources none

In the beginning, there was nothing… Before your application is started, it just doesn’t exist in the system yet.

An app that’s not running has no way to execute code, but popup notifications may be shown on its behalf by a registered server application or from earlier scheduling.

When your app gets launched, your code gets loaded into memory and you transition into:
Active state

On screen? yes
Running? yes
In memory? yes
Resources as you like

Your app is large and in charge! Your code and data are in memory, code is being executed, and you’ve got free control over the user interface, audio, network, etc.

There’s also an inactive state when the system takes over the UI and event loops for stuff like showing the incoming phone call dialog; your app is temporarily paused from the UI, but all your resources stay intact and you’ll get them back soon.

When it comes time to switch apps (through the home menu, task list, or programatically), your app loses control of the screen and enters the…
Background state

On screen? no
Running? yes
In memory? yes
Resources restricted*

Your code is still running, but you’ve got no access to the screen, and various resources start getting cut off. Usually this is a temporary state giving an application a chance to save data, close out unneeded resources, and generally tidy up before being suspended completely.

There are some special exceptions which can allow an app to run in background state for prolonged time, which is where the really interesting stuff comes in. We’ll get to that soon!

When we’re done with background state, the OS can put your app to bed; now it’s in…
Suspend state

On screen? no
Running? no
In memory? yes
Resources mostly freed

This is the biggest change in iOS 4: after your post-switchaway cleanup, the app remains in memory so it can be continued at a moment’s notice.

Previously, after your app did a little cleanup on the way out it would be terminated and all its memory and network resources freed. Instead, the app is now simply stopped at this point, but with the explicit warning that it may or may not ever be continued.

If the app is reactivated from suspend mode, anything you kept in memory is still there — you have a lot less work to do to reestablish your application’s running state than when relaunching the process.

But you may die before you wake, in which case you’re back to…

Not running state.

If the system needs more memory to assign to another application, or gets shut down, your suspended app will be terminated without being woken to inform it.

You need to be prepared for termination before entering suspend state… but really, you’re already writing code that assumes it could crash at any time and saves state at intervals and key points so it won’t lose user data, right? Um, right?

Background mode limitations

So just what are the limits of what you can do while running in background state? The docs mix together a lot of strict limits along with recommendations for being a good citizen; I’ve tried to split them out here:

YOU CANNOT (technical restrictions on what you can do):

  • Can’t make OpenGL calls; they will terminate your app.
  • Can’t accept new connections on a listening socket.
  • Can’t use shared system resources like the Address Book (it sounds like they might sorta work if still open, but you could get terminated if there’s a conflict.)
  • Can’t use external accessories — you must register for and handle disconnection events.

YOU SHOULD (recommendations for behaving well):

  • Should be prepared for loss of connectivity — open network connections could be torn down at any time.
  • Should save your state, since your app could be terminated due to memory pressure.
    (You should be saving state during regular operation anyway to protect against application or system crashes, power failures, etc. Programs that assume orderly shutdown are asking for trouble!)
  • Should avoid updating your windows and views; it’ll work but since your UI is hidden it’s a waste of time & battery.
  • Should normalize your UI state — cancel modal alerts, hide temporarily shown passwords, etc.
  • Should “do minimal work” while in background.

Reaching the user when not on screen

iPhone OS 2 introduced networked push notifications, where — through the magic of the internet — your app’s web services can trigger a notification dialog on the phone, even if your application is no longer running. iOS 4 extends this to local background tasks; if your app is in the background state, it can pop up a notification immediately without needing to go out to the network.

You can also schedule a future notification at any time (up to 128 scheduled per app), which will trigger even if your app has been terminated — obviously handy for alarms, calendars, and timer apps.

Notifications are limited in that they alert the user, not the app. If you were suspended or not running when the notification came, you won’t be woken unless the user pushes the button that opens your app.

When in background…

Any app can start up background task threads, which will block the background->suspended state transition.

This is primarily intended for orderly shutdown tasks, like completing that photo uploading to Twitbook or syncing mailbox state to a server after reading a bunch of messages. The system actually gives you a time limit, and will terminate your app if you don’t declare your tasks complete when the time limit’s up! Once you’re done, you’re forced to suspend… absent other triggers, your app is going to stay that way until the user switches back to it or it’s terminated.

You can also register to receive an event for “significant location updates“, which will wake or even relaunch your application when the cell network has noticed that you’ve moved a non-trivial distance. This avoids running down the battery with the GPS if you want updates but don’t really need to be watching it continuously.

Special backgrounding modes

An app can declare itself to have certain types of backgrounding characteristics, which can allow some additional behaviors in background state. Since these are pre-declared in the code-signed app bundle, you need to be aware of what affect they’ll have on your app’s runtime behavior, and will have to run the App Store approval gauntlet with an extra bulls-eye on your forehead. ;)

Background audio mode

Normally, the system audio frameworks cut you off when transitioning from active to background state. If your app is marked as a background audio app, you get two perks:

  • Audio in/out continues to work in background state.
  • Suspend is blocked while playing audio, so you can keep running in the background arbitrarily long.

If audio is not active, your app will still be able to suspend — so a music player that’s paused, or reaches the end of its playlist in the background, can free its resources.

Articles I’ve seen have had a lot of vague language seeming to indicate that apps in this mode can “only” play audio and do nothing else, which might imply that there’s some kind of wacky alternate API for bg audio — this is not true. The docs recommend avoiding unnecessary work while playing background audio to keep resource usage down, but there’s no artificial restriction beyond the general limitations on backgrounded apps.

You’ll still use the same old network interfaces, the same old audio APIs, etc; reportedly it only took an hour to port Pandora’s iPhone player to use background audio.

Background VOIP mode

The VOIP mode is really about management of long-running network clients — an actual VOIP app will probably need to also mark itself as needing background audio. Your app will still get suspended if the user switches away with no active call, but gets a few special abilities:

  • Sockets you register as VOIP control channels will stay live when your app is suspended. If data comes in, you’ll be woken up — this lets you handle an incoming call.
  • You can register a timeout to be woken at intervals, so you to send keepalive pings if needed.
  • The app is automatically launched in the background on boot, so you can connect to the server.
  • The app is automatically relaunched on non-zero exit code, so a one-off app crash won’t break the VOIP service.

Note that while this mode sounds ideal for IM/chat apps, connections to real-time update streams for social networking clients, etc, I suspect that Apple would not actually approve such apps.

Continuous location mode

Navigation apps, GPS tracers, etc may need a more direct way to monitor the GPS for location changes while backgrounded. This is similar to the background audio mode:

  • Continue to use the regular location services APIs…
  • …while you’ve got it active, suspend will be blocked and you can remain in background mode arbitrarily long.

GPS has a particularly bad reputation for running down the battery, so if you’re just looking to ping 4square or something you should probably use the “significant location updates” event registration instead.

Summary

Now that we’ve seen something about how it all works, let’s take some sample cases and ask whether they’ll actually do what we need… So what do we need?

I’m a media player (Pandora, Airfoil Speakers, etc)

  • Can I continue playing audio after switching away?
    • Yes — mark your app as requiring background audio, and it’ll stay backgrounded on switch.
  • Can I keep communicating with the network while playing audio?
    • Yes! But if you’re doing other stuff not needed for your audio and Apple notices, they may not approve your app.
  • Can I start playing audio later on after having been backgrounded, like an alarm clock?
    • No — if you’re not playing audio at switch time, you’ll still get suspended. You could schedule a local notification to alert the user and they could push a button to launch your app and then you could play the music. Ewww!
  • Can I keep a socket open to listen for other computers to connect and send me audio to play?
    • No — your listening sockets will be closed, and you’ll have been suspended anyway as above.

I’m a VOIP client (SIP clients, Skype etc)

  • Can I keep an active call going after switching away from the app?
    • Yes — mark your app as requiring background audio, and a running call will be able to keep on going.
  • Can I maintain a connection to my server to listen for incoming calls?
    • Yes — mark your app as needing VOIP mode, and set the special flag on your control channel after setting up the connection.
  • Can I be automatically launched on boot, so I can open that connection?
    • Yes — mark your app as needing VOIP mode, you’ll be automatically launched if you
  • Can I maintain a listening socket to receive direct SIP calls?
    • No — all listening sockets will be closed in the background. You need an existing connection to a server which’ll send a packet down when there’s an event.
  • Can I auto-answer calls?
    • I’m not 100% sure on this one; if the system fully foregrounds you to handle incoming events so you can show an “incoming” screen then yes, otherwise I don’t think so.

I’m an IM or social networking client (AIM, Meebo etc; StatusNet, Twitter, Facebook, etc)

  • Can I finish uploading a post in the background if the user switches apps before it’s done?
    • Yes — do it from a background task thread, and notify the system when you’re done and ready to be suspended.
  • Can I poll my server in the background to check for updates?
    • No — you’ll need to pair with a server component and use networked notifications to alert the user.
  • Can I keep a socket open to listen for real-time updates from my server?
    • No — in theory the VOIP mode would allow this, but Apple would have to approve your app’s using it for non-VOIP use.
  • Can I be woken to check status when the physical location has changed?
    • Yes — you can register for significant location updates and be woken or launched to check if you need to perform any actions.

I’m any kind of server:

  • Can I listen for clients while in the background?
    • No. Your listening sockets will be closed, and any Bonjour service stuff will be torn down.
  • Can I finish up an existing client connection after switching away?
    • In theory this ought to work, if the operation can complete in a background task thread before you’re forced to suspend.

I’m any other bit of software:

  • Can my app be woken at a specified time?
    • No. You can set a notification to display at a given time, but user interaction will be needed to wake or launch your app.

Whee!

Firefox font rendering differences between Ubuntu, Mozilla packages?

Has anybody else encountered this? Subpixel antialiasing on text seems to be a lot more aggressive when running Mozilla’s packages of Firefox and Thunderbird than when running the Ubuntu packages:

I originally noticed it when running Mozilla’s Thunderbird 3 packages on Ubuntu 9.10, but originally chalked it up to “weird stuff from 32-bit apps sometimes acting weird”, but both the 32-bit and 64-bit Firefox 4.0b1 packages are doing it to me on Ubuntu 10.04.

Is there some difference with the bundled libraries, or some custom Ubuntu or Debian patch that changes the behavior? And can I change it??? I’m liking Firefox 4 so far but this text is just awful on my eyes.

Updated 2010-07-13: Commenter noted this bug, which looks like it may be it: https://bugs.launchpad.net/firefox/+bug/379761

Freedom, compromise, and geek fights

I’ve seen a rash of complaints lately about some absolutist flame wars and trollfests in various parts of the free & open source software community, and it leaves me kind of sad when I see people whose work I respect jumping around and saying hurtful things to each other.

I understand, of course… us geeks tend to like absolutes. Absolutes are often very handy in an engineering context — this algorithm is more efficient with our data sets under these constraints; that algorithm is less efficient. This hard drive performs better for this server load; that one is worse. We unfortunately have a tendency to apply the same sort of arguments when we don’t have a clear-cut context… and there may be legitimately different answers for different people. Which programming language is best? (The one I’m most productive in!) Which mobile gadget is best? (The one that I would buy for my needs!) Which operating system is best? (The one I like to run my applications or tune to my preferences!) Which voting system is best? Which political system is best? Which religion is best?

We quickly fall into unwinnable circular arguments where the participants talk past each other. Not only are these unproductive; they can create very angry, adversarial communities that tend to drive away new members. Especially where participation is self-selected and involves both technical and ideological goals — like free software and Wikipedia communities — there’s a constant danger of ugly geekfights.

I’ll admit I’ve flamed my share of people who disagreed with me on the Internet — more so at 21 than at 31! — but I’ve always tried to keep myself in check by reminding myself of an incident in my youth…

When I was a young lad, I was raised in what is sometimes called a Post-Christian environment. As middle-class white Americans, we inherited some of the outside trappings of the old Christian civilization of medieval Europe, but we were never really religious. We celebrated Christmas and Easter,  assumed “Yahweh” when someone said “God” instead of asking “which god?”, and understood that the “Bible” is the default holy book, with one section where GOD HATES SHRIMP and another where JESUS LOVES YOU. But we only had a token prayer at dinner, and only went to churches as tourists or funeralgoers; the one time I got dragged to my grandparents’ regular Sunday services at a Lutheran church I found the whole thing incomprehensible. Bible stories sometimes got presented to me as cultural background, but no more so than other religious tales like the similarly-ancient Greco-Roman myths which nobody believes are literal truth.

As a 14-year-old or so, I assumed that this was the normal, natural way that everyone in our post-Englightenment science-based Western culture was raised. Someone who believed in any particular religion — so concluded my adolescent brain — must then be either ignorant or stupid. If they were ignorant, then surely explaining the true facts to them would make them give a quick facepalm and finally join the 18th century. If they didn’t get the explanation, then either my explanation wasn’t good enough (let’s try it again!) or they’re just stupid and it’s time to write them off entirely.

Eventually I started realizing that my assumptions didn’t actually hold. One day, a schoolyard discussion about science and philosophy (as only 9th-graders can philosophize… poorly!) resulted in a classmate declaring that “Darwin was a jerk!” for putting forth his theories on biological evolution. Yes, one of my honors-level classmates wasn’t just religious, he was a creationist. I knew he wasn’t an idiot — he was a bright kid who did great in math, science, literature, and history. I knew his parents weren’t idiots — they were smart, successful people. But this smart, successful family believed things I found to range from the odd to the silly to the downright insane.

I’ve never been convinced about religion — and definitely not creationism! — but that day I started to learn that believing things I find to be obviously wrong doesn’t make someone an unintelligent or malicious person, even if I can point to a heap of evidence that totally convinces me how wrong they are.

At best I could accuse him of being wrong and not having the same set of assumptions and values in his decision-making process that made the opposite conclusion so obvious to me. Given time, education, and a changing environment, he might change his mind, or he might not. But my arguments weren’t doing it, and weren’t going to do it, yet I couldn’t dismiss him entirely as an idiot.

I was instead going to have to just deal with someone being wrong.

This was probably the most important lesson I’ve ever learned. It’s hard, and I mean hard, to practice it, especially as a techie geek.

But it’s one of the foundations of our modern pluralistic democracies, and basically comes down to the social contract of “don’t oppress me, and I won’t oppress you”. My freedom to be an agnostic/atheist comes with the responsibility to tolerate Christians, Jews, Muslims, Buddhists, Hindus, etc… and even Creationists, to an extent. I’m willing to accept that compromise because they’re bound to it, too — it keeps “them” from ostracizing me as a heretic, burning me at the stake, stoning me to death, or just refusing to let me vote, own property, or run for public office just for being an agnostic/atheist, Christian, Jew, Muslim, Buddhist, Hindu, etc. We just have to work out a reasonable compromise — we teach the actual state of science in public-school science class, and it’s up to each religious group to explain to their children the specific ways, if any, that their religious worldview differs from centuries of evidence-based scientific research so that even the creationist kids still learn the cultural context of how our post-Enlightenment society works, even if they disagree with it.

So please… before you go flaming people for being traitors to the cause, or not getting it, or whatever… consider whether what you’re saying is actually going to add anything useful to the conversation, or if you’re just piling more noise on a never-ending geekfight. If we can avoid killing our neighbors over fundamental religious differences, we really ought to be able to live with someone else occasionally saying something nice about a product line you dislike.

Nexus 1 + Froyo notes & iPhone 4

The Android 2.2 “Froyo” update finally came through over the last few days for Nexus 1 owners. After a few days of on-and-off usage, some notes to add to my initial review of the N1 running 2.1:

What’s new:

  • Speed: Things definitely feel snappier than they used to, but not really in a firmly quantifiable way. I’ll try another head-to-head scrolling test after a bit, but I can still expect to see the N1 way behind on that — scrolling still feels jerkier, and usually slower, than on an iPhone.
  • Tethering: For me, this was one of the main the killer features that pushed me to actually buy the N1, and I’m very happy to see it working! AT&T might finally have gotten around to enabling tethering for the iPhone, but they’ve shot themselves in the foot by making it cheaper to buy a new Android phone instead of the $20/month to not get a bandwidth limit increase on your iPhone. Over your 2-year contract, that comes to $480 wasted on AT&T… and it still wouldn’t power your Wifi iPad while the Android will! Sorry, guys. I know which features I want.
  • Screen: my background image is still pretty badly banded, but gradients in the web browser look smoother. There may be piecemeal improvements in how images get rendered and dithered for fullcolor output, but it’s still a bit inconsistent.

Otherwise, the OS isn’t mind-blowingly different, but definitely has a lot of nice little bumps. Ars Technica has a general review of Froyo on the N1 if you want to peek at a few other under-the-hood changes.

Update: There’s also a notification system that looks like a very flexible superset of what the iPhone platform has, which might be very nice for things like sending realtime updates to our upcoming mobile client without it having to poll in the background. That ain’t much useful to users yet, but we’re sure gonna use it in future!

Compared to the iPhone 4

Of course, Apple’s been moving as well. iOS 4 is out for the existing iPhone 3G and 3Gs, and the new iPhone 4 is available and busy fighting a reception issue scandal.

iOS 4 on my iPhone 3G feels like a very nice incremental improvement. Things aren’t radically different, but it’s definitely a bit nicer: folders have helped organize home screens by moving out rarely-used apps, background processing is a big help for a few apps (like Pandora!) and there are other niceties like threading in the mail reader.

I haven’t picked up an iPhone 4 for personal use yet, but I did swing through an Apple store the other day (when the crowds had died down a bit!) to check it out. There are only a couple of interesting user-visible hardware changes beyond the case change:

My favorite is the awesome, awesome high-resolution display. I am really looking forward to this pixel density being available on desktop-size screens… some day we can stop worrying about pixels and just have text and graphics that look good.

There’s some talk that HDTV has actually set display technology back for large formats; I’ve seen only a handful of commercially-available monitors that venture much beyond 1920×1080, and those are all to gain extra desktop space not to improve density/sharpness.

The screen on the Nexus 1 is visibly sharper than the iPhone 3Gs, but even with my slightly blurry vision is visible pixelated at smartphone-usage distances from my eye. The iPhone 4 really, literally, truly moves it into the realm where pixels no longer matter; as this level of display technology makes it out into the broader market, I think it’s going to make a big difference in what we’re comfortable reading on a small screen.

The front-facing camera & video calling support is the primary selling point in Apple’s current ad campaign; the nice saleslady demoed it for me, and the quality’s pretty good for what it is. But honestly I don’t see myself ever using it as more than a gimmick; I’ve had a webcam on my laptop for 5 years and have never been on a video chat that’s not about trying out the video chat feature. Perhaps Apple will prove me wrong — and like with video chats on computers, some people get a lot more mileage out of it than others. I can certainly see if I had a small child we’d probably be on with my parents a lot more often — my mom doesn’t need too many real-time updates on the cats. ;)

There’s also an improved main camera, which may be a nice extra but isn’t a killer feature for me — the current phone cameras are adequate (though not great) and aren’t main selling points for me.

The Awful Tooth: missing Wikimania

Let that be a lesson to all the aspiring young computer programmers out there: stay in school, and brush your teeth!

I’ll unfortunately be missing this year’s Wikimania and WikiSym conferences in Gdansk, Poland as I’m recovering from a tooth extraction. It seems to be going ok, but it’s got me totally wiped out — I can barely make it across San Francisco by bus, this ain’t time for me to hit the planes. :(

Those of you who’re also coming to OSCON in Portland later this month, I’ll see you there. The rest of you, I’ll catch ya on the internets!

The sad, sad tale

So when you’re a young man or lady, at some point you have to make a lot of Important Life Choices, such as what to do about your wisdom teeth. These molars are pretty far back in the mouth, and not hugely useful in actual chewing. Moreover, they’re more likely than other teeth to suffer from either bad impaction when they’re new (coming in at funny angles, or butting up against other teeth and screwing things up — they’re entering an already-full mouth) or bad decay later on (since they’re hard to reach they can be hard to clean, greatly increasing the chances of decay).

My teeth were coming in reasonably straight, so as a lad I made the decision to leave them. For many years this served me just fine, but SECRET TOOTH DECAY was my enemy, stealing into my jaw in the night to chip away at one of the ol’ wizzy teeth. A few weeks ago the decay crossed some limit and basically the side of the tooth fell out to reveal a gigantic cave system rivaling Carlsbad Caverns.

Other minor cavities were easily patched up by my local dentist, but this one was gonna need a removal. I was hoping I could push it back until after my packed June-July travel schedule, but it started acting up again last week when I was in Montreal for RecentChangesCamp and to coordinate the StatusNet 0.9.3 release.

Rather than wait and hope it didn’t crack, collapse, or get infected while zipping about Central Europe, I thought I’d better go ahead and get it taken care of while I was on the ground in SF for a few days. If I was lucky, I’d be recovered enough to pack myself up with some painkillers and still make it, and if not I’d have time for a fuller recovery before OSCON.

The actual procedure was quick and easy — local anesthetic does wonders, and I got over my fear of dental procedures as a kid (I find it quite interesting to sort of follow along, actually). Recovery though… well, let’s be honest. Recovering from a wisdom tooth removal is gonna lay you out a bit. This is pretty much a best case — upper jaw, not impacted, reasonably exposed, other teeth not affected. But between the pain, the mental fuzziness from the vicodin treating the pain, and the general tiredness from the body redirecting some of its efforts to healing a wound, I’m still pretty out of it a few days later. It’s particularly aggravating for a knowledge worker liker myself — the wound itself doesn’t prevent me from doing what I do, but the medicine means I just can’t concentrate enough to get much done either for work or fun! Grr!

So… BRUSH AND FLOSS YOUR WISDOM TEETH REGULARLY if you got em!