back to index

Method: Removing volume warning from Android

The Bureaucratic Background

In 2009, the European Commission in its infinite wisdom decided to clamp down on enjoyably loud music. It decided to implement limits on the output volume. The limits were enacted in 2013 (see here).

To quote the press release, "Consumers will benefit from new default settings on personal music players set at safe exposure levels, as well clear warnings on the adverse effects of excessive exposure to high sound levels, following a decision by the European Commission today."

Exactly in line with the Brussels thinking, safety has to be forced down the end users' throats, regardless if they want it, regardless of unintended consequences - and there are plenty.

The warnings are typically implemented to appear at 75% of the maximum output volume. Then the user has to either click through, or in the better but still annoying case press the volume-up key again. In either case the pop-up warning is annoying.

The warnings are shown when anything that could be a pair of headphones is attached, whether by the audio jack or via Bluetooth. Usual cases are external speakers, a car stereo, or an amplifier. The Brussels Bureaucrat of course did not realize this and the warning pops up in these cases neverthless.

As it is implemented on a fixed point of the volume setting, it also does not take in account the distinct possibility that the audio file being played could be quieter, not normalized to the usual flat high volume (classical music tends to fit the bill, some badly recorded non-remastered files as well, also some audiobooks and podcasts may require higher volume to be understandable). The warning popup does not care. The Bureaucrat is happy.

There are other unintended consequences there. As of 2014, the Windows Phone had tendency to randomly show the nannywarning and lower the volume to half. As this happens when the user is busy with something else, e.g. driving a vehicle, this can be highly distracting and one day it will kill someone.

Another unintended consequence is that the smartphone-connected radiation detector may not work on European variants of iPhones, as the clamped volume means the device does not get enough power (the device is apparently powered with rectified audio signal, a clever hack):

EU volume-limit problem

Type 4 may NOT support iOS devices sold in Europe area (except Italy, Finland or Spain), because headphone output may not exceed 100dB to prevent hearing damages, under the EU You can check if your iOS device is volume-limited or not at http://triggertrap.com/ios-eu-volume-limit/ [dead link] If you use latest iOS devices with iOS 7.x, you may able to turn off the volume-limit as below.

And, last but by far not the least, there is the irritation factor when one finds that the Brussels is worming its way into one's own pocket computer, which is supposed to be one's sovereign domain, ruled with one's own iron fist. Where one is supposed to have the highest authority, uninterfered with by any lesser beings, any untermensch like eurocommissioners, lawyers or bureaucrats.

Bug removal

A bug is a bug, even if it is there because of a law. As such, it shall be removed. Especially because there are already too many bureaucrappy annoyances. Let's get rid of at least those that can be easily addressed.

Hardware used

The hardware the method was tested on is Asus Zenfone 2. The phone has unlocked bootloader and runs Cyanogenmod 13, based on Android 6.0. The type was chosen and bought specifically for its full compatibility with Cyanogenmod, so no functionality would have to be sacrificed.

The method should however work on any sufficiently recent Android where the variable described below is in the location described below. Try and look; if the framework-res.apk file is not in its supposed location, or the bools.xml variables file is not in the apk file, or the variable declaration is not in the bools.xml file, the method won't work for you as-is and may have to be modified.

Workarounds

Some users avoid this nonsense by importing gear from the USA or other such less overbureaucratized markets. This however poses logistical problems and may introduce other limitations, which usually are not disclosed in advance. (Is there any collection of information, a wiki or database or other, which market has which annoyances enforced, so globalization can be used to work around them?)

Some versions of Cyanogenmod had a possibility to disable this in the settings. It is not there anymore in the version 13.0. (Why, oh why? Does anybody know?)

There is a plugin for the Xposed framework for Android that exposes many various settings. The Xposed framework has to be flashed using e.g. the TWRP recovery image. This can be risky and introduce e.g. a boot loop that may be difficult to get out of. A less harsh way had to be taken.

The Autostarts app, available via the F-Droid store, a third-party APK store of free/opensource software for Android (https://f-droid.org/), as of http://forum.xda-developers.com/showthread.php?t=2699719, may be also used.

Permanent unilateral opt-out

The Internet was consulted. There seem to be no simple easy non-risky workarounds so far, mostly just a choir of voices crying in anguish into the big void of the Net after being burned by Brussels. Some posts have quite useful information, though.

The nannying is enabled by one configuration variable in the Android framework. The variable is located in the res/values/bools.xml file, as config_safe_media_volume_enabled, set by default to "true"; the file is packaged in the /system/framework/framework-res.apk file, and not available directly as the APK file is compiled.

Requirements

A rooted phone is required, with the TWRP recovery image installed. (Other recoveries should work but aren't described here.)

A Java 7 is needed on a computer, to run the APKTOOL decompiler/rebuilder. (This may also work on the Android itself - untested hypothesis.)

The unzipping/zipping instructions are for a linux console. Other packers can be used instead, but the disabling of compression (store-only) setting may be more difficult to access.

Retrieving the framework config

The TWRP recovery can be leveraged to access the APK file, to exfiltrate it out of the device and then to write back the modified version. This can be done from the file manager by the "copy" function, using the removable SD card or a USB-OTG connected thumbdrive, or via adb console or, if SSH server is installed, via scp. The exfiltration is easy as the file is only read, so no read-write remounting of the partition is needed.

Decompiling

This requires the APKTOOL tool. It can be installed according to the instructions here. It is essentially a JAR file, with associated .bat and shell-script wrappers. The wrappers aren't necessary, they just allow the users to not have to run it through the "java -jar apktool.jar" command.

Place the framework-res.apk file to a directory on a computer.

Run the apktool:

 apktool d framework-res.apk
And wait, and wait. A framework-res directory gets created in the current directory.

Stay in the current directory. The following instructions assume this location.

Editing

Now edit the file framework-res/res/values/bools.xml.

Replace

 <bool name="config_safe_media_volume_enabled">true</bool>
with
 <bool name="config_safe_media_volume_enabled">false</bool>

And save the modified file

The relevant values in the framework are here, found with grep:

 res/values-mcc311/bools.xml:    <bool name="config_safe_media_volume_enabled">false</bool>
 res/values-mcc315/bools.xml:    <bool name="config_safe_media_volume_enabled">false</bool>
 res/values/integers.xml:    <integer name="config_safe_media_volume_index">10</integer>
 res/values/public.xml:    <public type="integer" name="config_safe_media_volume_index" id="0x010e0091" />
 res/values/public.xml:    <public type="bool" name="config_safe_media_volume_enabled" id="0x01120086" />
 res/values/bools.xml:    <bool name="config_safe_media_volume_enabled">true</bool>
 res/values-mcc316/bools.xml:    <bool name="config_safe_media_volume_enabled">false</bool>
 res/values-mcc312/bools.xml:    <bool name="config_safe_media_volume_enabled">false</bool>
 res/values-mcc310/bools.xml:    <bool name="config_safe_media_volume_enabled">false</bool>
 res/values-mcc314/bools.xml:    <bool name="config_safe_media_volume_enabled">false</bool>
 res/values-mcc313/bools.xml:    <bool name="config_safe_media_volume_enabled">false</bool>
Only the one in values/bools.xml needs to be edited. The other ones are shown for the sake of awareness.

Rebuilding

Run the apktool again:

 apktool b framework-res

And now wait. And wait, and wait, and, for change, wait a bit more. It takes time.

Now there is the modified file compiled in the framework-res/dist/framework-res.apk location.

Beware: as of here the compiled resources.arsc file with the resources apparently should not be compressed, or it can cause a boot loop.

So it has to be written into the original file.

To be sure, create a backup file:

 cp framework-res.apk framework-res.apk.orig
Delete the original resources.arsc file from the original APK:
 zip -d framework-res.apk resources.arsc
Extract the modified resources.arsc file from the rebuilt file:
 unzip framework-res/dist/framework-res.apk resources.arsc
Add the modded ones back, without compressing them as it is said to do problems:
 zip -0 framework-res.apk resources.arsc

Writing back

Copy framework-res.apk and framework-res.apk.orig to the removable SD card (or the USB OTG thumbdrive, or anywhere comfortable in the filesystem).

The file can be directly copied; mount the system partition remount as read-write, and copy the framework-res.apk file to the /system/framework/ directory. This may be a little risky. A TWRP way was chosen instead.

The phone is rebooted into the TWRP recovery.

The system partition is mounted (this has to be done explicitly as it is not done by default).

The modified framework-res.apk file on the SD card (or wherever it was placed to) is accessed via the TWRP file manager. It is copied to /system/framework/framework-res.apk destination.

Now the phone is rebooted again. After a few dozen seconds of nervous waiting, it should boot up correctly and then not show the nannying eurowarning anymore. Suck it up, Brussels!

(If this does not work, the original framework-res.apk.orig can be restored the same way, by copying it to /system/framework/framework-res.apk - that's why it was kept around. Another option to backup it is to rename it in its original directory from the TWRP file manager.)

If only all the other euroidiocies, eurolimitations and euroannoyances could be hacked off this easily...

See also:

Is it possible to use AudioService.disableSafeMediaVolume() from an app or scheduler?


If you have any comments or questions about the topic, please let me know here:
Your name:
Your email:
Spambait
Leave this empty!
Only spambots enter stuff here.
Feedback: