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

Commit 946f72e4 authored by JW Wang's avatar JW Wang
Browse files

Implement AppStateHelper

* Implement #isInCall
* Implement #isRecordingAudio
* Make SYSTEM_UID privileged which needs to retrieve the client
  package name of an AudioRecordingConfiguration

Bug: 235306967
Test: manual test
Change-Id: I330f4828d09dee5c3cd2c6cedbfdfa6ebc6a2c52
parent c894d0ad
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -11386,8 +11386,8 @@ public class AudioService extends IAudioService.Stub
    }
    public List<AudioRecordingConfiguration> getActiveRecordingConfigurations() {
        final boolean isPrivileged =
                (PackageManager.PERMISSION_GRANTED == mContext.checkCallingPermission(
        final boolean isPrivileged = Binder.getCallingUid() == Process.SYSTEM_UID
                || (PackageManager.PERMISSION_GRANTED == mContext.checkCallingPermission(
                        android.Manifest.permission.MODIFY_AUDIO_ROUTING));
        return mRecordMonitor.getActiveRecordingConfigurations(isPrivileged);
    }
+47 −4
Original line number Diff line number Diff line
@@ -16,11 +16,16 @@

package com.android.server.pm;

import static android.media.AudioAttributes.USAGE_VOICE_COMMUNICATION;
import static android.media.AudioAttributes.USAGE_VOICE_COMMUNICATION_SIGNALLING;

import android.app.ActivityManager;
import android.app.ActivityManager.RunningAppProcessInfo;
import android.content.Context;
import android.media.AudioManager;
import android.media.IAudioService;
import android.os.ServiceManager;
import android.telecom.TelecomManager;
import android.text.TextUtils;
import android.util.ArraySet;

@@ -71,6 +76,43 @@ public class AppStateHelper {
        return false;
    }

    /**
     * True if any app is using voice communication.
     */
    private boolean hasVoiceCall() {
        var am = mContext.getSystemService(AudioManager.class);
        try {
            for (var apc : am.getActivePlaybackConfigurations()) {
                if (!apc.isActive()) {
                    continue;
                }
                var usage = apc.getAudioAttributes().getUsage();
                if (usage == USAGE_VOICE_COMMUNICATION
                        || usage == USAGE_VOICE_COMMUNICATION_SIGNALLING) {
                    return true;
                }
            }
        } catch (Exception ignore) {
        }
        return false;
    }

    /**
     * True if the app is recording audio.
     */
    private boolean isRecordingAudio(String packageName) {
        var am = mContext.getSystemService(AudioManager.class);
        try {
            for (var arc : am.getActiveRecordingConfigurations()) {
                if (TextUtils.equals(arc.getClientPackageName(), packageName)) {
                    return true;
                }
            }
        } catch (Exception ignore) {
        }
        return false;
    }

    /**
     * True if the app is in the foreground.
     */
@@ -89,8 +131,7 @@ public class AppStateHelper {
     * True if the app is playing/recording audio.
     */
    private boolean hasActiveAudio(String packageName) {
        // TODO(b/235306967): also check recording
        return hasAudioFocus(packageName);
        return hasAudioFocus(packageName) || isRecordingAudio(packageName);
    }

    /**
@@ -143,8 +184,10 @@ public class AppStateHelper {
     * True if there is an ongoing phone call.
     */
    public boolean isInCall() {
        // To be implemented
        return false;
        // TelecomManager doesn't handle the case where some apps don't implement ConnectionService.
        // We check apps using voice communication to detect if the device is in call.
        var tm = mContext.getSystemService(TelecomManager.class);
        return tm.isInCall() || hasVoiceCall();
    }

    /**