The Bifurcation Of Android
How the emergence of a dual-class app permission structure is handicapping developers in Africa 🌍
As they race to squeeze more and more battery out of their devices, Android handset manufactures are creating unlikely casualties: app developers.
To increase battery life, many manufacturers (OEMs) re-implement the inbuilt power management features of the Android Open Source Project (AOSP) in ways that aggressively restrict background processing for all but a handful of “special” apps.
Android developers across the continent are discovering the hard way that certain Android API components such as Wakelocks, Alarms, Broadcast Receivers, Jobs, Push Notifications, etc. do not work as expected on many devices made by Huawei, Tecno, Xiaomi and others.
It is no surprise, of course, that such restrictions disproportionately affect developers in Africa. Android is the dominant smartphone OS on the continent and entry-level devices, which make up the bulk of the market, are more likely to enact aggressive battery optimization.
Whitelisting is the new Pre-installing 🏷️
Chances are if you bought a brand new Tecno (the most popular phone brand in Africa) today, it would come pre-installed with WhatsApp, Facebook and a handful of other apps.
For years, Android OEMs have shipped devices with a bunch of pre-installed apps that cannot be removed. The process through which a third-party app gets pre-installed is largely opaque and has been a privilege enjoyed by only a handful of “special” apps.
The approach OEMs have taken to maximize battery life is giving rise to a new even more perturbing kind of privilege: whitelisting.
Many OEMs maintain a small list of apps that are allowed to run unrestricted by default. All other apps are restricted unless the user explicitly adds them to this list.
The above tweet from VLC illustrates the frustration this is causing developers. Whereas pre-installing mostly gave apps a distributional advantage, whitelisting gives them a functional one. The functionality of an app is its very essence. Thus, restricting the capabilities available to non-whitelisted apps effectively handicaps them.
Here’s one developer’s comment on an issue reporting this problem on the Android Issue Tracker:
I have an app with over 500K+ downloads on play store. I use a notification listener service, which is available in the android framework, and tested on almost all major manufacturer devices.
The users drop a poor rating because these stupid OEMs aggressively kills the services in background (even though the service is extremely lightweight). I frequently receive so many feedbacks mentioning that the app is not working on their phone, and when I ask them about the manufacturer, it is always the ones mentioned below.
Unassuming users often blame developers for the degraded performance of their apps and leave negative reviews on Google Play. You can’t blame them though: OEMs go to great lengths to hide the settings to whitelist new apps and only tech-savvy users can find them. What’s more, many users are not even aware that apps are competing on non-level playing field.
If this reminds you of the famous commandment from George Orwell’s Animal Farm, it should. Who knew that even things as intangible as binaries of compiled code could be more equal than others!
The Power of Defaults 🔦
It’s a bit of a truism in tech that users are “dumb.” As a result, many products prescribe “sensible” defaults for their users, so as not to burden them with too many steps.
The problem with defaults, of course, is that they end becoming something of a self-fulfilling prophecy. Making an option the default among a set of choices increases the likelihood that it is chosen.
Instead of making real hardware improvements, OEMs are exploiting this flaw in human psychology to squeeze out more battery life at the expense of their customers and third-party developers.
Some may argue that restricting newly installed apps is a sensible default since it protects users from malicious and poorly optimized apps that might hog their battery.
What this misses, however, is that such restrictions ultimately violate the principle of least astonishment. A user who downloads an alarm app and sets up an alarm expects it to go off at the set time. Similarly, one who installs a messaging app expects to be notified when there’s a new message.
Such a user has already shown sufficient intent that they are interested in using the functionality of the app they just installed and shouldn’t have to go through additional hoops to get the app to work as intended.
What’s more, some of the modifications OEMs make in their android forks go against the Android Compatibility Definition Document (CDD) requirements and break core APIs.
At NALA, we’ve had first-hand experience of the frustrations caused by such OEM modifications. The number 1 complaint we hear from some of our users is that the app keeps asking them to grant it the accessibility permission.
NALA is a mobile money application that brings together your financial accounts and helps you make transactions through your existing mobile money services all from one application. We enable people to make payments ‘offline’ and this is done through us automating USSD in the background of the users phones without needing a data connection.
In order to interact with USSD on behalf of the user, NALA requires permission to run an accessibility service and this is typically requested the first time a user installs the app.
However, on some devices (some models of Tecno, Itel, Infinix, Huawei, and Xiaomi), this permission is revoked whenever a user closes the app.
When we dug deeper to understand this behaviour, we were stunned to find out why: on some devices, when a user swipes an app away from the recent apps list, the app is force-stopped instead of just killing the app process.
Whereas there’s no difference, in the eyes of the user, between the two states, the OS handles them very differently. “Force stop” does not only kill the processes of the app but also moves it into the stopped state, where nothing in the app will run again until a user manually starts the app again.
In practice, this means that such an app won’t be able to run any background processing or receive push notifications. Moreover, for security reasons, Android disables all accessibility services for an app that is force-stopped.
This effectively means that NALA users on such devices are asked to grant the app the accessibility permission every time they open the app. As you might imagine, this drives many of our users nuts and some never use the app again.
Few things are as annoying as a bug that you did not cause and more importantly, that you just cannot fix. The only “fix” we’ve found is asking users to lock the app in the recent list so it doesn’t get cleared but even that doesn’t work on all devices and is less than ideal user experience.
An API is a contract and it should be treated as such. It falls on Google to ensure that all APIs documented in the Android Developer docs work as expected on all supported devices. Constantly having to patch code to work on specific devices not only kills productivity but it is also unsustainable.
Questionable Neutrality 🔍
One of the idiosyncrasies of the smartphone industry is that building a great phone is not necessarily the best way to maximize profit. It is getting increasingly harder for OEMs to convince people to upgrade to the latest device yet the ones they already have are “good enough” for their needs.
Because of this reality, many OEMs are starting to offer additional services to complement their devices in order to counter-balance the inevitable slow down in revenues.
Take Transsion, the company behind smartphone brands like Tecno and Infinix for example. It launched Boomplay, a Spotify-style streaming service for African music in 2015, and recently led a $40M investment in PalmPay, an Africa-focused payments startup.
This, of course, raises questions about the neutrality of OEMs as the arbiter of who gets to be whitelisted and who does not. In Thomas Sowell’s words, “the most basic question is not what’s best but who shall decide what’s best”.
Android OEMs are free to build new apps and services to diversify their revenues but they cannot be referee and player at the same time.
Google Turns a Blind Eye 💤
If OEMs are breaking core Android APIs and modifying the OS in ways that go against Android CDD requirements, how come Google allows them to ship such devices?
Well, your guess is as good as mine. Whatever the reason, it is not for a lack of power. In the past, Google has not hesitated to assert its power over OEMs when it suited its interests; even with things as trivial as forcing them to display the “Powered by Android” logo on the startup screen.
Then again, it is reasonable to question Google’s moral authority in this matter since it is also guilty of denying third-party developers access to APIs that some of its own apps use.
For a project whose stated goal is “to avoid any central point of failure in which one industry player can restrict or control the innovations of any other player”, Android has clearly lost its original ethos.
When asked about the OEM modifications on Reddit 10 months ago, here’s what the Android engineering team had to say:
We acknowledge the issue and take it very seriously. We have been actively working with device manufacturers to fix their implementations and seen some positive outcomes.
To help with the situation, we’ve added a CTS test in Android Q to ensure that an app is not killed upon being swiped from Recents. However, as you noted, device manufacturers have various implementations and it is extremely difficult to create an automated test to capture all wrong implementations that are against CDD requirements.
Though this is a step in the right direction, it doesn’t feel like Google is treating this matter with the urgency it deserves. For now, we can only hope and pray that Google will eventually assert its power to put an end to this bifurcation.