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

Commit 838913c5 authored by Jean-Michel Trivi's avatar Jean-Michel Trivi
Browse files

AudioService: initialize Spatializer, track routing changes

Implement initialization of SpatializerHelper, the AudioService
 proxy for the native Spatializer effect.
Implement release of Spatializer effect when feature is disabled
Implement Spatializer available dispatch.
Track routing changes reported through AudioSystem to
 check if device for media routing is compatible with
 spatialization. Use result to update Spatializer
 availability

Bug: 188502620
Test: adb logcat | grep Spatializer, check for "init succeeded"
Change-Id: Ib06b1f54fee20a5057768a7a31a047bd1fba930d
parent e7b68347
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -2443,8 +2443,7 @@ public class AudioManager {

    /**
     * Return a handle to the optional platform's {@link Spatializer}
     * @return {@code null} if spatialization is not supported, the {@code Spatializer} instance
     *         otherwise.
     * @return the {@code Spatializer} instance.
     */
    public @Nullable Spatializer getSpatializer() {
        int level = Spatializer.SPATIALIZER_IMMERSIVE_LEVEL_NONE;
+29 −3
Original line number Diff line number Diff line
@@ -114,27 +114,53 @@ public class Spatializer {

    /** @hide */
    @IntDef(flag = false, value = {
            SPATIALIZER_IMMERSIVE_LEVEL_OTHER,
            SPATIALIZER_IMMERSIVE_LEVEL_NONE,
            SPATIALIZER_IMMERSIVE_LEVEL_MULTICHANNEL,
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface ImmersiveAudioLevel {};

    /**
     * @hide
     * Constant indicating the {@code Spatializer} on this device supports a spatialization
     * mode that differs from the ones available at this SDK level.
     * @see #getImmersiveAudioLevel()
     */
    public static final int SPATIALIZER_IMMERSIVE_LEVEL_OTHER = -1;

    /**
     * @hide
     * Constant indicating there are no spatialization capabilities supported on this device.
     * @see AudioManager#getImmersiveAudioLevel()
     * @see #getImmersiveAudioLevel()
     */
    public static final int SPATIALIZER_IMMERSIVE_LEVEL_NONE = 0;

    /**
     * @hide
     * Constant indicating the {@link Spatializer} on this device supports multichannel
     * Constant indicating the {@code Spatializer} on this device supports multichannel
     * spatialization.
     * @see AudioManager#getImmersiveAudioLevel()
     * @see #getImmersiveAudioLevel()
     */
    public static final int SPATIALIZER_IMMERSIVE_LEVEL_MULTICHANNEL = 1;

    /**
     * @hide
     * Return the level of support for the spatialization feature on this device.
     * This level of support is independent of whether the {@code Spatializer} is currently
     * enabled or available and will not change over time.
     * @return the level of spatialization support
     * @see #isEnabled()
     * @see #isAvailable()
     */
    public @ImmersiveAudioLevel int getImmersiveAudioLevel() {
        int level = Spatializer.SPATIALIZER_IMMERSIVE_LEVEL_NONE;
        try {
            level = mAm.getService().getSpatializerImmersiveAudioLevel();
        } catch (Exception e) { /* using NONE */ }
        return level;
    }

    /**
     * @hide
     * Enables / disables the spatializer effect.
+46 −5
Original line number Diff line number Diff line
@@ -200,7 +200,8 @@ import java.util.stream.Collectors;
 */
public class AudioService extends IAudioService.Stub
        implements AccessibilityManager.TouchExplorationStateChangeListener,
            AccessibilityManager.AccessibilityServicesStateChangeListener {
            AccessibilityManager.AccessibilityServicesStateChangeListener,
            AudioSystemAdapter.OnRoutingUpdatedListener {

    private static final String TAG = "AS.AudioService";

@@ -314,12 +315,14 @@ public class AudioService extends IAudioService.Stub
    private static final int MSG_SET_A2DP_DEV_CONNECTION_STATE = 38;
    private static final int MSG_A2DP_DEV_CONFIG_CHANGE = 39;
    private static final int MSG_DISPATCH_AUDIO_MODE = 40;
    private static final int MSG_ROUTING_UPDATED = 41;

    // start of messages handled under wakelock
    //   these messages can only be queued, i.e. sent with queueMsgUnderWakeLock(),
    //   and not with sendMsg(..., ..., SENDMSG_QUEUE, ...)
    private static final int MSG_DISABLE_AUDIO_FOR_UID = 100;
    private static final int MSG_INIT_STREAMS_VOLUMES = 101;
    private static final int MSG_INIT_SPATIALIZER = 102;
    // end of messages handled under wakelock

    // retry delay in case of failure to indicate system ready to AudioFlinger
@@ -869,6 +872,8 @@ public class AudioService extends IAudioService.Stub

        mSfxHelper = new SoundEffectsHelper(mContext);

        mSpatializerHelper = new SpatializerHelper(this, mAudioSystem);

        mVibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
        mHasVibrator = mVibrator == null ? false : mVibrator.hasVibrator();

@@ -1033,6 +1038,9 @@ public class AudioService extends IAudioService.Stub
        // done with service initialization, continue additional work in our Handler thread
        queueMsgUnderWakeLock(mAudioHandler, MSG_INIT_STREAMS_VOLUMES,
                0 /* arg1 */,  0 /* arg2 */, null /* obj */,  0 /* delay */);
        queueMsgUnderWakeLock(mAudioHandler, MSG_INIT_SPATIALIZER,
                0 /* arg1 */,  0 /* arg2 */, null /* obj */,  0 /* delay */);

    }

    /**
@@ -1222,6 +1230,22 @@ public class AudioService extends IAudioService.Stub
        updateVibratorInfos();
    }

    //-----------------------------------------------------------------
    // routing monitoring from AudioSystemAdapter
    @Override
    public void onRoutingUpdatedFromNative() {
        sendMsg(mAudioHandler,
                MSG_ROUTING_UPDATED,
                SENDMSG_REPLACE, 0, 0, null,
                /*delay*/ 0);
    }

    void monitorRoutingChanges(boolean enabled) {
        mAudioSystem.setRoutingListener(enabled ? this : null);
    }


    //-----------------------------------------------------------------
    RoleObserver mRoleObserver;

    class RoleObserver implements OnRoleHoldersChangedListener {
@@ -1406,6 +1430,9 @@ public class AudioService extends IAudioService.Stub
            }
        }

        // TODO check property if feature enabled
        mSpatializerHelper.reset(/* featureEnabled */ true);

        onIndicateSystemReady();
        // indicate the end of reconfiguration phase to audio HAL
        AudioSystem.setParameters("restarting=false");
@@ -7539,6 +7566,13 @@ public class AudioService extends IAudioService.Stub
                    mAudioEventWakeLock.release();
                    break;

                case MSG_INIT_SPATIALIZER:
                    mSpatializerHelper.init();
                    // TODO read property to see if enabled
                    mSpatializerHelper.setFeatureEnabled(true);
                    mAudioEventWakeLock.release();
                    break;

                case MSG_CHECK_MUSIC_ACTIVE:
                    onCheckMusicActive((String) msg.obj);
                    break;
@@ -7671,6 +7705,10 @@ public class AudioService extends IAudioService.Stub
                case MSG_DISPATCH_AUDIO_MODE:
                    dispatchMode(msg.arg1);
                    break;

                case MSG_ROUTING_UPDATED:
                    mSpatializerHelper.onRoutingUpdated();
                    break;
            }
        }
    }
@@ -8239,7 +8277,7 @@ public class AudioService extends IAudioService.Stub
    }

    //==========================================================================================
    private final SpatializerHelper mSpatializerHelper = new SpatializerHelper();
    private final @NonNull SpatializerHelper mSpatializerHelper;

    private void enforceModifyDefaultAudioEffectsPermission() {
        if (mContext.checkCallingOrSelfPermission(
@@ -8249,9 +8287,12 @@ public class AudioService extends IAudioService.Stub
        }
    }

    /** @see AudioManager#getSpatializerImmersiveAudioLevel() */
    /**
     * Returns the immersive audio level that the platform is capable of
     * @see Spatializer#getImmersiveAudioLevel()
     */
    public int getSpatializerImmersiveAudioLevel() {
        return mSpatializerHelper.getImmersiveAudioLevel();
        return mSpatializerHelper.getCapableImmersiveAudioLevel();
    }

    /** @see Spatializer#isEnabled() */
@@ -8267,7 +8308,7 @@ public class AudioService extends IAudioService.Stub
    /** @see Spatializer#setSpatializerEnabled(boolean) */
    public void setSpatializerEnabled(boolean enabled) {
        enforceModifyDefaultAudioEffectsPermission();
        mSpatializerHelper.setEnabled(enabled);
        mSpatializerHelper.setFeatureEnabled(enabled);
    }

    /** @see Spatializer#canBeSpatialized() */
+23 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.server.audio;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.media.AudioAttributes;
import android.media.AudioDeviceAttributes;
import android.media.AudioSystem;
@@ -24,6 +25,8 @@ import android.media.audiopolicy.AudioMix;
import android.os.SystemClock;
import android.util.Log;

import com.android.internal.annotations.GuardedBy;

import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
@@ -59,6 +62,9 @@ public class AudioSystemAdapter implements AudioSystem.RoutingUpdateCallback {
    private ConcurrentHashMap<AudioAttributes, ArrayList<AudioDeviceAttributes>>
            mDevicesForAttrCache;
    private int[] mMethodCacheHit;
    private static final Object sRoutingListenerLock = new Object();
    @GuardedBy("sRoutingListenerLock")
    private static @Nullable OnRoutingUpdatedListener sRoutingListener;

    /**
     * should be false except when trying to debug caching errors. When true, the value retrieved
@@ -76,6 +82,23 @@ public class AudioSystemAdapter implements AudioSystem.RoutingUpdateCallback {
            Log.d(TAG, "---- onRoutingUpdated (from native) ----------");
        }
        invalidateRoutingCache();
        final OnRoutingUpdatedListener listener;
        synchronized (sRoutingListenerLock) {
            listener = sRoutingListener;
        }
        if (listener != null) {
            listener.onRoutingUpdatedFromNative();
        }
    }

    interface OnRoutingUpdatedListener {
        void onRoutingUpdatedFromNative();
    }

    static void setRoutingListener(@Nullable OnRoutingUpdatedListener listener) {
        synchronized (sRoutingListenerLock) {
            sRoutingListener = listener;
        }
    }

    /**
+363 −24

File changed.

Preview size limit exceeded, changes collapsed.