Monday, May 13, 2013

Mobile phones suck!

Here we go again, another rant about mobile operating systems.

I'm fed up with Android. But there's no alternative for me right now. So I have to moan. To make this moaning more constuctive, let's go over what I hate about Android, what I like about other OSs, and what I want to see.

Android sucks

  • Multimedia [audio] is not realtime. Seriously, this is stupid. A dual-core 1.5GHz CPU, and I still hear clicks and pops every now and then when I launch the browser
  • Multimedia scanner notifications are broken. So, I download a piece of music, and what happens next? Right, the media scanner kicks in and kills the music player. Why? Oh, because the cool kids are going mad about OOP  and design patterns nowadays, but implementing a proper live configuration updating is beyond the scope of the abilities of those Senior Developers. Sure, burning everything to the ground and creating the new instance of the class is the only way to go   
  • No, I ain't going to replace my phone with an mp3 player because I'm lazy. I don't want to bother copying music over to it, I just want to download it over Wi-Fi from warez sites (d'oh)
  • UI lags. Even on a quad-core CPU with 2Gb ram
  • Apps crash every now and then. Oh well. I don't even know why. In java you have structured exception handling and stuff like that. Even on Windows Mobile where everything was written in plain C with manual memory management, there were not that many crashes. Does your destkop crash every 30 seconds? No? Ok, I'll blame Java. Android's Dalvik JVM, to be more precise. The application life cycle is implemented in Java, the launcher is implemented in Java, but for some multimedia apps the performance of Java is not enough, and IntBuffer's create a considerable overhead. Besides, parsing C structures without JNA is just painful. So, developers have to integrate their C and C++ code into the Java environment. Every Java-to-C call and C-to-Java involves lots of manual memory manipulations, and I suppose most developers don't do that correctly. Still,  it puzzles me why pure Java apps crash so often
  • No proper fsck and dead file removal. Seriously, if your data file system is corrupted, and the settings database for an app becomes unwritable, guess what happens? Right, the app launches, crashes with the IOException, and the cycle repeats indefinitely
  • Android's using a crippled custom libc and is binary incompatible with GNU/Linux. Okay, libhybris allows us to steal Android's OpenGL drivers, I'm not moaning anymore

Android unsucks

There are positive points, of course
  • The system is open-source, it can be easily adapted for any custom piece of hardware [I'm more interested in the HW engineer's point of view rather than the end user's one]
  • It is based on linux kernel, allowing to reuse many software via chroot or doable porting [like Qt4]
  • That's about all
  • Oh, no. There are a lot of commercial devices available, the user has a lot of choices

What next

I've used many mobile platforms and here's what I've liked and disliked about them

Windows Mobile

  • Damn slow UI. No compositing or 3D support whatsoever
  • Low memory footprint
  • Very stable
  • Lots of apps
  • Native C SDK
  • Ability to load kernel-mode drivers
  • Good driver model, with stable ABI and configuration via registry 


Windows Phone

  • Locked down tightly. No fun for hacking
  • Too expensive to build a custom device
  • But on the positive side, capability-based resource management and app isolation via containers (security!)

iOS

  • It just works
  • But no source code
  • And SDKs are tied to OSX


Maemo/Meego

  • Based on Qt and X11 (Wayland soon), lots of reusable code
  • Using traditional GNU/Linux stack and buildsystem
  • Open-source
  • Native code (except for some parts of UI written in QML).
  • Lower resource requirements than Android


I'm looking forward to Jolla's Sailfish OS and trying to port the Nemo Mobile (the unbranded open-source stack behind Sailfish) to my omap4 devices.

Some ideas

Here's what I think a new kind of mobile OS must be
  • Realtime scheduling [at least, proper priority handling for multimedia and UI, but policy is a complex question]
  • Using capability security model
  • Ability to proxify services and override methods
  • Built with power optimization in mind
  • Microkernel architecture with fixed IPC buffer size [to prevent buffer overflow exploits, to ease debugging]
  • Support para- and hw- virtualization
  • Dynamic resource paths. I want to query irqs like XPath. For example, |irq = Irq_session "/soc/gic/12"| or "/bus/i2c/omap4-1/0x30/irq_expander/10". Maybe a solution is some kind of a platform driver that will just map strings to irq at runtime.
  • Reuse existing linux API and code
So far some of these features are implemented by Fiasco.OC and Genode, but there are some areas in which I want a completely different approach
  • Replace XML and LUA configs with... an XML with schema or, better, a DSL with static checking
  • Avoid runtime memory allocation. I want that as much data structures as possible (at least in drivers) are allocated at compile-time. This will reduce memory trashing, bootup time and simplify the out-of-memory handling
Use a decent language. I mean, something like Scala or Haskell.
  • First one is no uninitialized data. During my C coding experience, 80% of "WTF" problems are uninitialized variables.
  • Next, immutability. Functions without side effects can be verified. Of course, verifying 100% code is very expensive (and well, absolute verification is impossible because we cannot verify the universe), but at least splitting the code to the "dangerous" and "debuggable" is a good start".
  • Strict type checking and lack of implicit type casts. Will save a lot of problems with the C "everything is an int" paradigm
  • Option types. Like haskell's Maybe/Just and OCaml's Some. They eliminate the "NULL" pointers, the source of all crashes and undefined behaviour in C++ and Java, by forcing the programmer to pattern-match the value
As for reusing linux code, I think a starting point could be microkernelizing linux. We could make every module a separate process and replace all global non-static variables and exported symbols with IPC calls for a start. 

Open questions

I am still unsure on some points, and would be happy to see comments on them
  • Whether implementing heterogenous CPU support is a feasible task
  • Can we make a better bytecode than JVM? why does JVM suck? why is it slow? or is it not?
  • What systems of such kind exists already? Phantom OS? Inferno OS?