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

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

Spatializer: more SysApi for availability, head tracker

  Add @SystemApi to check if the Spatializer will be available for
a given device, if it has a head tracker, if enabled, and
change its tracker enabled state.
  Implement checking device compatibility with transaural and
binaural modes. Create list of compatible devices, list of
devices that have been enabled, and list of disabled. This is
to support the V3 UI where add/removeCompatibleDevice is used
to control Spatial Audio state for a subset of output devices.

Bug: 210803914
Test: atest SpatializerTest
Change-Id: I0acf0c0310dbd503de2ea87328fca7e5597ae32d
parent db48e2b6
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -6266,6 +6266,9 @@ package android.media {
    method @RequiresPermission("android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS") public int getHeadTrackingMode();
    method @IntRange(from=0) @RequiresPermission("android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS") public int getOutput();
    method @NonNull @RequiresPermission("android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS") public java.util.List<java.lang.Integer> getSupportedHeadTrackingModes();
    method @RequiresPermission("android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS") public boolean hasHeadTracker(@NonNull android.media.AudioDeviceAttributes);
    method @RequiresPermission("android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS") public boolean isAvailableForDevice(@NonNull android.media.AudioDeviceAttributes);
    method @RequiresPermission("android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS") public boolean isHeadTrackerEnabled(@NonNull android.media.AudioDeviceAttributes);
    method @RequiresPermission("android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS") public void recenterHeadTracker();
    method @RequiresPermission("android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS") public void removeCompatibleAudioDevice(@NonNull android.media.AudioDeviceAttributes);
    method @RequiresPermission("android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS") public void removeOnHeadTrackingModeChangedListener(@NonNull android.media.Spatializer.OnHeadTrackingModeChangedListener);
@@ -6273,6 +6276,7 @@ package android.media {
    method @RequiresPermission("android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS") public void setEffectParameter(int, @NonNull byte[]);
    method @RequiresPermission("android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS") public void setEnabled(boolean);
    method @RequiresPermission("android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS") public void setGlobalTransform(@NonNull float[]);
    method @RequiresPermission("android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS") public void setHeadTrackerEnabled(boolean, @NonNull android.media.AudioDeviceAttributes);
    method @RequiresPermission("android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS") public void setOnHeadToSoundstagePoseUpdatedListener(@NonNull java.util.concurrent.Executor, @NonNull android.media.Spatializer.OnHeadToSoundstagePoseUpdatedListener);
    method @RequiresPermission("android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS") public void setOnSpatializerOutputChangedListener(@NonNull java.util.concurrent.Executor, @NonNull android.media.Spatializer.OnSpatializerOutputChangedListener);
    field @RequiresPermission("android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS") public static final int HEAD_TRACKING_MODE_DISABLED = -1; // 0xffffffff
+8 −0
Original line number Diff line number Diff line
@@ -402,6 +402,14 @@ interface IAudioService {

    boolean isSpatializerAvailable();

    boolean isSpatializerAvailableForDevice(in AudioDeviceAttributes device);

    boolean hasHeadTracker(in AudioDeviceAttributes device);

    void setHeadTrackerEnabled(boolean enabled, in AudioDeviceAttributes device);

    boolean isHeadTrackerEnabled(in AudioDeviceAttributes device);

    void setSpatializerEnabled(boolean enabled);

    boolean canBeSpatialized(in AudioAttributes aa, in AudioFormat af);
+77 −0
Original line number Diff line number Diff line
@@ -108,6 +108,83 @@ public class Spatializer {
        }
    }

    /**
     * @hide
     * Returns whether spatialization is available for a given audio device
     * Reasons for spatialization being unavailable include situations where audio output is
     * incompatible with sound spatialization, such as the device being a monophonic speaker, or
     * the spatializer effect not supporting transaural processing when querying for speaker.
     * @param device the audio device for which spatializer availability is queried
     * @return {@code true} if the spatializer effect is available and capable
     *         of processing the audio over the given audio device,
     *         {@code false} otherwise.
     * @see #isEnabled()
     */
    @SystemApi(client = SystemApi.Client.PRIVILEGED_APPS)
    @RequiresPermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
    public boolean isAvailableForDevice(@NonNull AudioDeviceAttributes device)  {
        Objects.requireNonNull(device);
        try {
            return mAm.getService().isSpatializerAvailableForDevice(device);
        } catch (RemoteException e) {
            e.rethrowFromSystemServer();
        }
        return false;
    }

    /**
     * @hide
     * Returns whether the given device has an associated headtracker
     * @param device the audio device to query
     * @return true if the device has a head tracker, false otherwise
     */
    @SystemApi(client = SystemApi.Client.PRIVILEGED_APPS)
    @RequiresPermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
    public boolean hasHeadTracker(@NonNull AudioDeviceAttributes device) {
        Objects.requireNonNull(device);
        try {
            return mAm.getService().hasHeadTracker(device);
        } catch (RemoteException e) {
            e.rethrowFromSystemServer();
        }
        return false;
    }

    /**
     * @hide
     * Enables or disables the head tracker of the given device
     * @param enabled true to enable, false to disable
     * @param device the device whose head tracker state is changed
     */
    @SystemApi(client = SystemApi.Client.PRIVILEGED_APPS)
    @RequiresPermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
    public void setHeadTrackerEnabled(boolean enabled, @NonNull AudioDeviceAttributes device) {
        Objects.requireNonNull(device);
        try {
            mAm.getService().setHeadTrackerEnabled(enabled, device);
        } catch (RemoteException e) {
            e.rethrowFromSystemServer();
        }
    }

    /**
     * @hide
     * Returns whether the head tracker of the device is enabled
     * @param device the device to query
     * @return true if the head tracker is enabled, false if disabled or if there isn't one
     */
    @SystemApi(client = SystemApi.Client.PRIVILEGED_APPS)
    @RequiresPermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
    public boolean isHeadTrackerEnabled(@NonNull AudioDeviceAttributes device) {
        Objects.requireNonNull(device);
        try {
            return mAm.getService().isHeadTrackerEnabled(device);
        } catch (RemoteException e) {
            e.rethrowFromSystemServer();
        }
        return false;
    }

    /** @hide */
    @IntDef(flag = false, value = {
            SPATIALIZER_IMMERSIVE_LEVEL_OTHER,
+24 −0
Original line number Diff line number Diff line
@@ -8570,6 +8570,30 @@ public class AudioService extends IAudioService.Stub
        return mSpatializerHelper.isAvailable();
    }

    /** @see Spatializer#isAvailableForDevice(AudioDeviceAttributes) */
    public boolean isSpatializerAvailableForDevice(@NonNull AudioDeviceAttributes device)  {
        enforceModifyDefaultAudioEffectsPermission();
        return mSpatializerHelper.isAvailableForDevice(Objects.requireNonNull(device));
    }

    /** @see Spatializer#hasHeadTracker(AudioDeviceAttributes) */
    public boolean hasHeadTracker(@NonNull AudioDeviceAttributes device) {
        enforceModifyDefaultAudioEffectsPermission();
        return mSpatializerHelper.hasHeadTracker(Objects.requireNonNull(device));
    }

    /** @see Spatializer#setHeadTrackerEnabled(boolean, AudioDeviceAttributes) */
    public void setHeadTrackerEnabled(boolean enabled, @NonNull AudioDeviceAttributes device) {
        enforceModifyDefaultAudioEffectsPermission();
        mSpatializerHelper.setHeadTrackerEnabled(enabled, Objects.requireNonNull(device));
    }

    /** @see Spatializer#isHeadTrackerEnabled(AudioDeviceAttributes) */
    public boolean isHeadTrackerEnabled(@NonNull AudioDeviceAttributes device) {
        enforceModifyDefaultAudioEffectsPermission();
        return mSpatializerHelper.isHeadTrackerEnabled(Objects.requireNonNull(device));
    }

    /** @see Spatializer#setSpatializerEnabled(boolean) */
    public void setSpatializerEnabled(boolean enabled) {
        enforceModifyDefaultAudioEffectsPermission();
+453 −18

File changed.

Preview size limit exceeded, changes collapsed.