Skip to content

Tec Design Background: Optimization of Power Consumption

pelzvieh edited this page Oct 4, 2015 · 5 revisions

Analyzing the situation

IPv6Droid was suspect to cause higher power consumption on devices, but it was hard to track down: Android versions prior to 5.1 usually judged innocent on IPv6Droid and listed extraordinary power consumption by system processes. With Android 5.1, this changed, but remained obscure: it doesn't sound logical if your app is made responsible for 80% of power consumption in the past 24 hours, but the only information you get on it are 1 minute of CPU usage and 2 minutes keeping the device awake! Actually it turned out that the communication behavior was causing problems - as described below.

Nevertheless I started with an attempt to optimize CPU usage. Especially I found out to much of my surprise, that, by default, the FileDescriptor you get from the Android VPN API is in non-blocking mode. This seems to be a bit suboptimal, as there's no way to get into the non-blocking world Java NIO "selectable" channels from a FileDescriptor. In result, you have to use Threads for communication, and you have to poll on the InputStream reading from the FileDescriptor.

Only with Android 5, the VpnService API was extended by a method to switch the FileDescriptor to blocking mode - and polling becomes (non-busy) waiting on input to become available. IPv6Droid running on earlier versions of Android now gradually increases the polling interval from 100ms to 10s.

The result is significant in terms of CPU usage reduction - but unfortunately, this never was a significant source of power drain!

Only after intensifying search for any useful hints, I disovered a a very useful article on Android developers. It is put - sort of hidden, if you ask me - to the cloud and connectivity chapter of training articles, and gives an excellent explanation of what happens by data transfers initiated from an app.

AYIYA, Heartbeat, and Mobile Networks

Part of the AYIYA protocol is a heartbeat functionality in order to maintain information for the tunnel provider, that the tunnel client is still up, and to promote changes to the IPv4 address of the client. SiXXs documentation suggests that the heartbeat interval was typically 5 minutes which would be absolutely uncritical. However, the heartbeat interval is a parameter that comes with the tunnel description over the TIC protocol, and IPv6Droid simply used to obey to whatever value was given there.

Closer inspection - motivated by the article mentioned above - explained a lot about IPv6Droids influence on power consumption:

  • TIC demanded a heartbeat interval of only 60 seconds instead of 300 seconds - at least for all my tunnels
  • Being relaxed about heartbeat, I made IPv6Droid send a heartbeat packet twice as fast as requested (i.e. in practices every 30 secs)
  • I didn't care determining if a heartbeat was actually required (because of packets with payload being sent already)

Back to the Android Developers article, we learn that IPv6Droid would keep the device's radio in high power mode for 40 seconds each minute and reduced power for 20 seconds, never letting it go to standby mode! Also it becomes quite plausible, why the problem became much more prominent: with LTE coming up and coverage growing, a type of mobile network is effective with a much higher power consumption - just to transfer a single small network packet once every minute.

Changed Priorities in IPv6Droid's Implementation

Seeing that the heartbeat mechanism is in inherent conflict with power optimization in mobile networks, I decided to be less eager towards (over-)fulfilling heartbeat specification:

  • the app generates heartbeat packages only every heartbeat interval, instead of twice as fast
  • heartbeat packages are only sent if no payload activity happened for one heartbeat interval
  • on mobile networks only, the app imposes a minimum of 300 secs to the heartbeat interval.

The latter may lead to a situation that the provider side assumes the tunnel to be down, and packages coming from outside to the device after a long phase of network inactivity would get lost. Given the fact that most communication of mobile devices in practice is initiated by the device, and remote side sending responses within few seconds, this appears an acceptable tradeoff.

External Causes of Inefficient Network Usage

Being a VPN app, IPv6Droid's communication behavior is much influenced by the communication behavior of apps using IPv6. Currently, no bundling of inefficient sparse packets transferred from other apps is implemented, nor is there a way to track down the issue to the 3rd party app causing the issue: if a user is running an ill-behaving, IPv6-aware app, resulting power drain will be accounted to IPv6Droid (on Android 5.1 and later) or to the system (on earlier Android releases). We'll have to see if this is going to be a problem. Even if so, I'm not too much a fan of implementing counter-measures in IPv6Droid. Hopefully the doze and app standby mechanisms introduced in Android 6 will cure the problem.