1

Non rooted Moto G6 Play running Android 9.

I'm using Termux and would like to use Sox's rec command to record audio from the terminal. Unfortunately, since Termux doesn't request the mic permission, it just records silence. I can't grant Termux the permission in Settings because...well, it doesn't request it. It's not in the app manifest, therefore Android (understandably) assumes it wouldn't know what to do with the permission if it had it and doesn't list "record audio" as an option.

Is there a way I can force Android to grant an app a permission it never asked for?

  • Just in case this is an XY problem (X: how to record audio using sox from terminal, Y: how to grant a new permission on Termux), you might be interested in ZShaolin that claims having in-built sox (there's also the free ZShaolin Light XDA-Dev, though I'm not sure if it includes sox) – Andrew T. Oct 10 at 7:20
1

Not possible without root but even with root SoX recording might not work.


Android Manifest Permissions

Android permission system has different Protection Levels (1, 2); Normal permissions are granted to any app without user interaction while Signature|Privileged (SignatureOrSystem) permissions (whitelisted in /etc/permissions/privapp-permissions-*.xml) are granted only to system apps. Both are granted when app is installed or on first startup (if system app) and configuration is saved in /data/system/packages.xml file. Some signature permissions can be granted to non-system apps after user's approval using appops.

Dangerous permissions are those which require user's approval to be granted or denied. User's choice is saved in /data/system/users/<User_ID>/runtime-permissions.xml where device owner's User_ID is 0 (don't confuse it with UNIX DAC's UID).

Most of the manifest permissions are enforced by Android framework (system_server) but some are mapped to GIDs; hence enforced by kernel. Permission to GID mapping is stored in /data/system/packages.list.

How to Grant an App Unrequested Permission

You can modify above mentioned files to grant a permission which isn't requested by an app in its Manifest. I haven't tested with all permissions but this trick works (at least up to Pie) because Android framework doesn't verify the saved permission configuration vs. apps manifest files on every reboot (may be the changes are reverted back to actual during a scheduled maintenance task or when some app is installed or updated; I'm not sure).

In our case we want to grant android.permission.RECORD_AUDIO to Termux which is a dangerous permission, so this is how you should edit your runtime-permissions.xml followed by an immediate reboot:

<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
<runtime-permissions fingerprint="...">
  ...
  <shared-user name="com.termux">
    <item name="android.permission.READ_EXTERNAL_STORAGE" granted="true" flags="0" />
    <item name="android.permission.WRITE_EXTERNAL_STORAGE" granted="true" flags="0" />
    <item name="android.permission.RECORD_AUDIO" granted="true" flags="0" />
  </shared-user>
  ...
</runtime-permissions>

To confirm:

~$ pm dump com.termux | grep -A3 'runtime permissions:'
      runtime permissions:
        android.permission.READ_EXTERNAL_STORAGE: granted=true
        android.permission.WRITE_EXTERNAL_STORAGE: granted=true
        android.permission.RECORD_AUDIO: granted=true

Why SoX won't work?

That said, still SoX won't be able to record audio because (AFAIK) it's not using Android's Java APIs (android.media) or native APIs (aaudio/opensles). It uses ALSA/OSS driver directly or through PulseAudio which needs direct access to device interfaces in /dev/snd/ or /dev/{audio,dsp*} and proc tree in /proc/asound/. For details see Android Audio Architecture.

However direct kernel level access isn't a norm on Android, so you need root access. Apps with android.permission.MANAGE_VOICE_KEYPHRASES are allowed to read /dev/snd/* devices. It's a privileged signature level permission which is mapped to GID audio (1005). You can edit packages.xml to get this permission granted:

    <package name="com.termux" ... >
        <perms>
            <item name="android.permission.MANAGE_VOICE_KEYPHRASES" granted="true" flags="0" />
        </perms>
    </package>

    <shared-user name="com.termux" ...>
        <perms>
            <item name="android.permission.MANAGE_VOICE_KEYPHRASES" granted="true" flags="0" />
        </perms>
    </shared-user>

And packages.list:

com.termux ... 0 /data/user/0/com.termux default:targetSdkVersion=28... 1005,3003

But SELinux allows only privileged apps (having context priv_app) to traverse /dev while /proc/asound/ isn't readable by apps at all, so you need to patch sepolicy as well.

And even after that, configuring SoX to use ALSA/OSS/PA is up to you.


Non-Root Solutions

Instead of using ALSA directly, PulseAudio can also be configured to stream audio over TCP or UDP or UNIX sockets. That's how media playback works on Termux. See this issue. However capturing audio only work through Android APIs. You can install termux-api package to use termux-microphone-record command for audio recording. It uses MediaRecorder class of Java API, or you may consider modifying SoX source to use Android's native APIs.


RELATED

0

There are two ways:

  1. Termux is an open-source app on Github. Therefore you just need the Android development tools and git for cloning and building a custom version (may be with a different package name so you can have both your version and the official installed).

  2. As your device is rooted you can try to add the permission to the list of registered permissions of an installed Termux. As far as I know the relevant data should /data/system/packages.list or /data/system/packages.xml. After modifying those files you should reboot the device to activate the changes. For more details see also this answer. Note: I am not sure what happens to these modifications in case an update of Termux is installed. I assume that the update will revert your changes.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.