Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4195049f authored by Philip Cuadra's avatar Philip Cuadra
Browse files

Allow Bluetooth CAP_SYS_NICE, set RT priority for Bluetooth HAL

Bluetooth needs CAP_SYS_NICE in order to make important threads use RT
scheduling policy.

SchedulingPolicyService should set RT priority for the Bluetooth HAL.

Bug 37518404

Test: Play Bluetooth audio, confirm RT priority in systrace
Change-Id: I0ee55a2f2cfd80cbb066d9c034bb85d8d85ba470
parent 3d5f41bb
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -685,11 +685,14 @@ static jint com_android_internal_os_Zygote_nativeForkAndSpecialize(

    // Grant CAP_WAKE_ALARM to the Bluetooth process.
    // Additionally, allow bluetooth to open packet sockets so it can start the DHCP client.
    // Grant CAP_SYS_NICE to allow Bluetooth to set RT priority for
    // audio-related threads.
    // TODO: consider making such functionality an RPC to netd.
    if (multiuser_get_app_id(uid) == AID_BLUETOOTH) {
      capabilities |= (1LL << CAP_WAKE_ALARM);
      capabilities |= (1LL << CAP_NET_RAW);
      capabilities |= (1LL << CAP_NET_BIND_SERVICE);
      capabilities |= (1LL << CAP_SYS_NICE);
    }

    // Grant CAP_BLOCK_SUSPEND to processes that belong to GID "wakelock"
+15 −5
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import android.content.pm.PackageManager;
import android.os.Binder;
import android.os.ISchedulingPolicyService;
import android.os.Process;
import android.util.Log;

/**
 * The implementation of the scheduling policy service interface.
@@ -52,14 +53,22 @@ public class SchedulingPolicyService extends ISchedulingPolicyService.Stub {
                prio > PRIORITY_MAX || Process.getThreadGroupLeader(tid) != pid) {
           return PackageManager.PERMISSION_DENIED;
        }
        if (Binder.getCallingUid() != Process.BLUETOOTH_UID) {
            try {
                // make good use of our CAP_SYS_NICE capability
                Process.setThreadGroup(tid, !isForApp ?
                  Process.THREAD_GROUP_AUDIO_SYS : Process.THREAD_GROUP_AUDIO_APP);
            } catch (RuntimeException e) {
                Log.e(TAG, "Failed setThreadGroup: " + e);
                return PackageManager.PERMISSION_DENIED;
           }
        }
        try {
            // must be in this order or it fails the schedulability constraint
            Process.setThreadScheduler(tid, Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK,
                                       prio);
        } catch (RuntimeException e) {
            Log.e(TAG, "Failed setThreadScheduler: " + e);
            return PackageManager.PERMISSION_DENIED;
        }
        return PackageManager.PERMISSION_GRANTED;
@@ -74,6 +83,7 @@ public class SchedulingPolicyService extends ISchedulingPolicyService.Stub {
        switch (Binder.getCallingUid()) {
        case Process.AUDIOSERVER_UID: // fastcapture, fastmixer
        case Process.CAMERASERVER_UID: // camera high frame rate recording
        case Process.BLUETOOTH_UID: // Bluetooth audio playback
            return true;
        default:
            return false;