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

Commit e3dfa282 authored by Jean-Michel Trivi's avatar Jean-Michel Trivi Committed by Android (Google) Code Review
Browse files

Merge "Define audio policy, mixes, and mixing rules"

parents 4267dbea a8b6bd88
Loading
Loading
Loading
Loading
+46 −10
Original line number Diff line number Diff line
@@ -412,16 +412,6 @@ public final class AudioAttributes implements Parcelable {
        }
    };

    /** @hide */
    @Override
    public String toString () {
        return new String("AudioAttributes:"
                + " usage=" + mUsage
                + " content=" + mContentType
                + " flags=0x" + Integer.toHexString(mFlags)
                + " tags=" + mTags);
    }

    @Override
    public int describeContents() {
        return 0;
@@ -486,6 +476,52 @@ public final class AudioAttributes implements Parcelable {
        }
    };

    /** @hide */
    @Override
    public String toString () {
        return new String("AudioAttributes:"
                + " usage=" + mUsage
                + " content=" + mContentType
                + " flags=0x" + Integer.toHexString(mFlags).toUpperCase()
                + " tags=" + mTags);
    }

    public String usageToString() {
        switch(mUsage) {
            case USAGE_UNKNOWN:
                return new String("USAGE_UNKNOWN");
            case USAGE_MEDIA:
                return new String("USAGE_MEDIA");
            case USAGE_VOICE_COMMUNICATION:
                return new String("USAGE_VOICE_COMMUNICATION");
            case USAGE_VOICE_COMMUNICATION_SIGNALLING:
                return new String("USAGE_VOICE_COMMUNICATION");
            case USAGE_ALARM:
                return new String("USAGE_ALARM");
            case USAGE_NOTIFICATION:
                return new String("USAGE_NOTIFICATION");
            case USAGE_NOTIFICATION_TELEPHONY_RINGTONE:
                return new String("USAGE_NOTIFICATION");
            case USAGE_NOTIFICATION_COMMUNICATION_REQUEST:
                return new String("USAGE_NOTIFICATION");
            case USAGE_NOTIFICATION_COMMUNICATION_INSTANT:
                return new String("USAGE_NOTIFICATION_COMMUNICATION_INSTANT");
            case USAGE_NOTIFICATION_COMMUNICATION_DELAYED:
                return new String("USAGE_NOTIFICATION_COMMUNICATION_DELAYED");
            case USAGE_NOTIFICATION_EVENT:
                return new String("USAGE_NOTIFICATION_EVENT");
            case USAGE_ASSISTANCE_ACCESSIBILITY:
                return new String("USAGE_ASSISTANCE_ACCESSIBILITY");
            case USAGE_ASSISTANCE_NAVIGATION_GUIDANCE:
                return new String("USAGE_ASSISTANCE_NAVIGATION_GUIDANCE");
            case USAGE_ASSISTANCE_SONIFICATION:
                return new String("USAGE_ASSISTANCE_SONIFICATION");
            case USAGE_GAME:
                return new String("USAGE_GAME");
            default:
                return new String("unknown usage " + mUsage);
        }
    }

    /** @hide */
    @IntDef({
+9 −5
Original line number Diff line number Diff line
@@ -227,19 +227,23 @@ public class AudioFormat {
    private int mChannelMask;
    private int mPropertySetMask;

    int getEncoding() {
    /** @hide */
    public int getEncoding() {
        return mEncoding;
    }

    int getSampleRate() {
    /** @hide */
    public int getSampleRate() {
        return mSampleRate;
    }

    int getChannelMask() {
    /** @hide */
    public int getChannelMask() {
        return mChannelMask;
    }

    int getPropertySetMask() {
    /** @hide */
    public int getPropertySetMask() {
        return mPropertySetMask;
    }

@@ -248,7 +252,7 @@ public class AudioFormat {
     * Builder class for {@link AudioFormat} objects.
     */
    public static class Builder {
        private int mEncoding = ENCODING_DEFAULT;
        private int mEncoding = ENCODING_PCM_16BIT;
        private int mSampleRate = 0;
        private int mChannelMask = CHANNEL_INVALID;
        private int mPropertySetMask = AUDIO_FORMAT_HAS_PROPERTY_NONE;
+50 −0
Original line number Diff line number Diff line
@@ -25,6 +25,8 @@ import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.media.RemoteController.OnClientUpdateListener;
import android.media.audiopolicy.AudioPolicy;
import android.media.audiopolicy.AudioPolicyConfig;
import android.media.session.MediaSessionLegacyHelper;
import android.os.Binder;
import android.os.Handler;
@@ -2448,6 +2450,52 @@ public class AudioManager {
        }
    }

    /**
     * @hide
     * CANDIDATE FOR PUBLIC API
     * Register the given {@link AudioPolicy}.
     * This call is synchronous and blocks until the registration process successfully completed
     * or failed to complete.
     * @param policy the {@link AudioPolicy} to register.
     * @return {@link #ERROR} if there was an error communicating with the registration service
     *    or if the user doesn't have the required
     *    {@link android.Manifest.permission#MODIFY_AUDIO_ROUTING} permission,
     *    {@link #SUCCESS} otherwise.
     */
    public int registerAudioPolicy(AudioPolicy policy) {
        if (policy == null) {
            throw new IllegalArgumentException("Illegal null AudioPolicy argument");
        }
        IAudioService service = getService();
        try {
            if (!service.registerAudioPolicy(policy.getConfig(), policy.token())) {
                return ERROR;
            }
        } catch (RemoteException e) {
            Log.e(TAG, "Dead object in registerAudioPolicyAsync()", e);
            return ERROR;
        }
        return SUCCESS;
    }

    /**
     * @hide
     * CANDIDATE FOR PUBLIC API
     * @param policy the {@link AudioPolicy} to unregister.
     */
    public void unregisterAudioPolicyAsync(AudioPolicy policy) {
        if (policy == null) {
            throw new IllegalArgumentException("Illegal null AudioPolicy argument");
        }
        IAudioService service = getService();
        try {
            service.unregisterAudioPolicyAsync(policy.token());
        } catch (RemoteException e) {
            Log.e(TAG, "Dead object in unregisterAudioPolicyAsync()", e);
        }
    }


    /**
     *  @hide
     *  Reload audio settings. This method is called by Settings backup
@@ -2912,6 +2960,7 @@ public class AudioManager {
     */

    /** @hide
     * CANDIDATE FOR PUBLIC API
     */
    public static final int SUCCESS = AudioSystem.SUCCESS;
    /**
@@ -2919,6 +2968,7 @@ public class AudioManager {
     */
    public static final int ERROR = AudioSystem.ERROR;
    /** @hide
     * CANDIDATE FOR PUBLIC API
     */
    public static final int ERROR_BAD_VALUE = AudioSystem.BAD_VALUE;
    /** @hide
+63 −0
Original line number Diff line number Diff line
@@ -48,6 +48,7 @@ import android.hardware.hdmi.HdmiTvClient;
import android.hardware.usb.UsbManager;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnErrorListener;
import android.media.audiopolicy.AudioPolicyConfig;
import android.media.session.MediaSessionLegacyHelper;
import android.os.Binder;
import android.os.Build;
@@ -68,6 +69,7 @@ import android.provider.Settings.System;
import android.telecomm.TelecommManager;
import android.text.TextUtils;
import android.util.Log;
import android.util.Slog;
import android.view.KeyEvent;
import android.view.Surface;
import android.view.WindowManager;
@@ -5041,4 +5043,65 @@ public class AudioService extends IAudioService.Stub {
            }
        }
    }

    //==========================================================================================
    // Audio policy management
    //==========================================================================================
    public boolean registerAudioPolicy(AudioPolicyConfig policyConfig, IBinder cb) {
        //Log.v(TAG, "registerAudioPolicy for " + cb + " got policy:" + policyConfig);
        boolean hasPermissionForPolicy =
                (PackageManager.PERMISSION_GRANTED == mContext.checkCallingOrSelfPermission(
                        android.Manifest.permission.MODIFY_AUDIO_ROUTING));
        if (!hasPermissionForPolicy) {
            Slog.w(TAG, "Can't register audio policy for pid " + Binder.getCallingPid() + " / uid "
                    + Binder.getCallingUid() + ", need MODIFY_AUDIO_ROUTING");
            return false;
        }
        synchronized (mAudioPolicies) {
            AudioPolicyProxy app = new AudioPolicyProxy(policyConfig, cb);
            try {
                cb.linkToDeath(app, 0/*flags*/);
                mAudioPolicies.put(cb, app);
            } catch (RemoteException e) {
                // audio policy owner has already died!
                Slog.w(TAG, "Audio policy registration failed, could not link to " + cb +
                        " binder death", e);
                return false;
            }
        }
        // TODO implement registration with native audio policy (including permission check)
        return true;
    }
    public void unregisterAudioPolicyAsync(IBinder cb) {
        synchronized (mAudioPolicies) {
            AudioPolicyProxy app = mAudioPolicies.remove(cb);
            if (app == null) {
                Slog.w(TAG, "Trying to unregister unknown audio policy for pid "
                        + Binder.getCallingPid() + " / uid " + Binder.getCallingUid());
            } else {
                cb.unlinkToDeath(app, 0/*flags*/);
            }
        }
        // TODO implement registration with native audio policy
    }

    public class AudioPolicyProxy implements IBinder.DeathRecipient {
        private static final String TAG = "AudioPolicyProxy";
        AudioPolicyConfig mConfig;
        IBinder mToken;
        AudioPolicyProxy(AudioPolicyConfig config, IBinder token) {
            mConfig = config;
            mToken = token;
        }

        public void binderDied() {
            synchronized (mAudioPolicies) {
                Log.v(TAG, "audio policy " + mToken + " died");
                mAudioPolicies.remove(mToken);
            }
        }
    };

    private HashMap<IBinder, AudioPolicyProxy> mAudioPolicies =
            new HashMap<IBinder, AudioPolicyProxy>();
}
+4 −0
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import android.media.IRemoteVolumeObserver;
import android.media.IRingtonePlayer;
import android.media.IVolumeController;
import android.media.Rating;
import android.media.audiopolicy.AudioPolicyConfig;
import android.net.Uri;
import android.view.KeyEvent;

@@ -199,4 +200,7 @@ interface IAudioService {
    void disableSafeMediaVolume();

    int setHdmiSystemAudioSupported(boolean on, int device, String name);

           boolean registerAudioPolicy(in AudioPolicyConfig policyConfig, IBinder cb);
    oneway void unregisterAudioPolicyAsync(in IBinder cb);
}
Loading