Saturday, September 7, 2019

Over the years, a number of things have attracted me to Android.

Around the time Android first showed up on the T-Mobile G1, it represented what I really wanted at that time. Which was something more like a computer and less like a PDA that could send e-mail or word files. Something that I could scratch my itches by writing software. Likewise at that time, I may as well have wanted a Porsche, lol.

What really made me enjoy the experience however was the moderness of the platform and the compatibility it offers.

Permissions


It has long bothered me how PC software works. You run as a user, let's call you Bob. You go download some program written by someone else, and probably won't be compiling it from code. That program can do anything you can, Bob. Whether that's as simple as uploading your address book (if you actually, still have a local one), encrypting your files for ransom, infecting your files, or just being useful, like you know: doing that task you had downloaded it for. A frequent solution in PCs has been to require running software with elevated permissions. But usually in a nuclear form: where the program goes from being able to doing anything you can, to literally being able to do anything your operating system can.

Newer models like the one Android follows, I believe are the natural evolution. Rather than "Ahh, shucks, I'll just run it as root!", the solution is a service interface. Android applications don't shout "Hey Bob, I need you to hit the grant godlike powers button right now". Instead they shout, "Hey Bob, I'm gonna need permission to use location services before I can tell you the nearest shawarma place". That's how things should work.

Once upon a time, computers didn't really have permissions. Time sharing used to have more to do with computers being expensive rather than a commodity. Today, I wouldn't expect a non-nerd to know what I just said. To be fair when the IBM PC came into being, it didn't have a lot of horsepower and having fifty people using it at the same time was the least personal worry.

UNIX and Vista probably had the longest reaching impacts prior to Android. I say that for two real reasons. Firstly, Unix's concept of users and file permissions are not only pervasive but the baseline of what you can call a multi-user system today. Secondly, thanks to the CP/M heritage, it wasn't really until Vista that a lot of PC using mooks got smacked over the head with the permissions stick; despite how long NT supported ACLs. Yeah, I'm a asshole.

I really like the brokered model that systems like Android follows. You don't solve a problem by running as god almighty with power to touch all the pointy things. You solve the problem by a service that brokers access to that specific thing. Because why should a program have as much power as you do? Do you trust strangers on the side walk with your debt card's PIN? I hope not.

User Services


Over the years a lot of things have become broadly universal. Today, you would be hard pressed to find a network aware program that does not utilize network sockets. Likewise as GUIs rose, so did frameworks to ease the task of writing such software. No one makes a GUI program by drawing raw pixels into a byte buffer anymore, they use things like GTK and MFC. Often these interfaces become common (e.g. BSD sockets and winsock are very similar) or they become portable (e.g. Qt runs on just about anything).

But there are also a great many things that are not broadly universal, aside from the concept that we want those things to work.

There are no universal APIs to solve problems like syncing and managing your contacts, calendars, locations, and so on. We have tools not interfaces.

In Android, we have concepts like a Calendar. It doesn't matter if I'm using Samsung's calendar app or Google's calendar app, or someone else's. There's a concept called a damned calendar. Wanna create an event? Fill out a common intent and expect good things to follow. If you write a calendar app then you're expected to do some things deemed the right thing, to make this work for the user, and that is the right thing if you're writing a calendar app that supports events.

On my laptop, I have to run a program like Mozilla Thunderbird or KOrganizer if I want an event calendar. Can I write a program that opens a new event in them and pre-populates it with some user provided data? Probably. Is there a common interface for my program to say, "Hey, operating system: Bob would love me to add this appointment to his calendar called 'Medical'. Here's the info!". Nope, nope, and nope a doodle! That's just not how PCs have evolved.

On the flipside, I will confess that Windows 10 does one thing I actually like. My contacts, messages, calendars, etc are all synchronized in much the same way my Android device does; I do not have the gag reflex necessary to see if MS also added any decent interfaces for applications to trigger these data exchanges the way Android does. But using Microsoft's built in apps for that suck less than interfacing my Debian machine.

Openness


As a curious and opinionated nerd, I prefer easy access to knowledge and limited restrictions. I first used computers running MS-DOS but most of my time has been around Unix systems.

To me the best way to know how something works is to take it apart and study the pieces. Want to know how programs are loaded into memory? Read the kernel's code for loading and linking executable files. Want to know how files are stored? Read a file system driver; coincidentally one for FAT is usually pretty simple compared to modern, more robust ones.

While I am a fan of tight permissioning and siloing of software, I am not a fan of restricting the owner. You paid good money for the device and it shouldn't try to stop you from using it. Whether your taste is cat videos or bouncing boobies.

A lot of people have been uppity over the nature of app stores, and they probably should be. But I also see it as natural. Modern unix systems typically get their software from a repository, and any package manager worth its salt is going to do things like verify signatures on those packages.

Where we diverge with younger systems is control. Android has done pretty well at that--in that you should be warned about importing some random file that you might not even know is a program, but you're still free to do so. Most people should obtain their software from a repo that they trust. Whether that's something like Google Play and iTunes, or something like your local mirror of Red Hat and Debian packages. But you should always be allowed to decide what that repo is.

Android has managed to hang onto a lot of that openness, where Apple has preferred to maintain control. I mean, razor wire, triple layered concrete thick barn doors. Whatever.

Stable Runtimes


There is a pretty long history of being able to run a pre-compiled program and share it with others. We've been doing it longer than most people have owned a computer. I view a major key to the success of PCs, the ease at which you could write a program, compile it, and expect it to run on someone else's machine without having to ship a code monkey with each floppy diskette. And not have to have a warehouse full of every microcomputer known to man, usually. Since then, computer software and hardware have become more isolated from the other for a great many tasks.

Today software is very long lived. Further time goes on, the more likely the code you write is to outlive you and the machine it first ran on. How well that binary runs on future systems is a more variable story.

Android has generally maintained a pretty strong ABI for keeping developer's stuff running. Think of Dalvik and the Android APIs what you will, and please do feel compelled to make rude hand gestures, but an Android application tends to execute without shouting "Holy link error, batman!" and aborting back to the launcher. Unless you do something that you shouldn't, or someone upstream does something that should be considered violation between vendor and stability worth smacking with a Googlely test suite sized beating stick.

But nothing is perfect or forever. To evolve, platforms must both create and destroy.

When I install a program from eons ago and it just runs on my PC, this tends to be a testament to how stable Microsoft's ABI is, and how (insanely) much work they have put into backwards compatibility. I find it kind of amazing how often old ass programs just run.

When it doesn't run, this tends to be a testament to how well the program was written or how well its assumptions have aged. It could be anything from assuming every file on disk is writable, or that all of nVidia's graphics accelerators work the same as back in 1999.

Considering how many programmers that I've met had a source-only mindset, I find it amazing how stable Android's runtime is at running APKs. As a user, you probably need worry more about issues like the evolution of GPU or service brokering breaking the apps assumptions at runtime than the app will fail to run at all.

You see there's a really big distinction between API and ABI. In really simplistic terms, an API means the programmer's shit will probably compile and an ABI means the programmer's shit will probably execute.

The more complicated operating systems and frameworks become: the less likely this is to be the case. But it's kind of nice when you can install an old game or utility and enjoy it without having to fire up a virtual machine with an antique operating system.

No comments:

Post a Comment