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

Commit 835a3326 authored by jiabin's avatar jiabin Committed by Jiabin Huang
Browse files

Add interface to enable HapticGenerator for Ringtone.

HapticGenerator is an audio effect to generate haptic data from audio
data. An important usecase for HapticGenerator is ringtone. However, it
is not easy to use audio effect for the Ringtone class as the
Ringtone's lifecycle is different from AudioTrack/MediaPlayer. In that
case, add an interface in Ringtone to enable HapticGenerator. The
HapticGenerator will only be added if the effect is available for the
device.

Bug: 179080948
Test: atest RingtoneTest
Change-Id: Ia0416f6b6c6f311627be88dd9a57a989379ac947
parent 77bb0b72
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -22978,10 +22978,12 @@ package android.media {
    method @Deprecated public int getStreamType();
    method public String getTitle(android.content.Context);
    method public float getVolume();
    method public boolean isHapticGeneratorEnabled();
    method public boolean isLooping();
    method public boolean isPlaying();
    method public void play();
    method public void setAudioAttributes(android.media.AudioAttributes) throws java.lang.IllegalArgumentException;
    method public boolean setHapticGeneratorEnabled(boolean);
    method public void setLooping(boolean);
    method @Deprecated public void setStreamType(int);
    method public void setVolume(float);
+2 −1
Original line number Diff line number Diff line
@@ -33,7 +33,8 @@ interface IRingtonePlayer {
        float volume, boolean looping, in @nullable VolumeShaper.Configuration volumeShaperConfig);
    oneway void stop(IBinder token);
    boolean isPlaying(IBinder token);
    oneway void setPlaybackProperties(IBinder token, float volume, boolean looping);
    oneway void setPlaybackProperties(IBinder token, float volume, boolean looping,
        boolean hapticGeneratorEnabled);

    /** Used for Notification sound playback. */
    oneway void playAsync(in Uri uri, in UserHandle user, boolean looping, in AudioAttributes aa);
+43 −1
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import android.content.Context;
import android.content.res.AssetFileDescriptor;
import android.content.res.Resources.NotFoundException;
import android.database.Cursor;
import android.media.audiofx.HapticGenerator;
import android.net.Uri;
import android.os.Binder;
import android.os.Build;
@@ -77,6 +78,7 @@ public class Ringtone {
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
    private MediaPlayer mLocalPlayer;
    private final MyOnCompletionListener mCompletionListener = new MyOnCompletionListener();
    private HapticGenerator mHapticGenerator;

    @UnsupportedAppUsage
    private Uri mUri;
@@ -89,6 +91,7 @@ public class Ringtone {
    // playback properties, use synchronized with mPlaybackSettingsLock
    private boolean mIsLooping = false;
    private float mVolume = 1.0f;
    private boolean mHapticGeneratorEnabled = false;
    private final Object mPlaybackSettingsLock = new Object();

    /** {@hide} */
@@ -196,6 +199,34 @@ public class Ringtone {
        }
    }

    /**
     * Enable or disable the {@link android.media.audiofx.HapticGenerator} effect. The effect can
     * only be enabled on devices that support the effect.
     *
     * @return true if the HapticGenerator effect is successfully enabled. Otherwise, return false.
     * @see android.media.audiofx.HapticGenerator#isAvailable()
     */
    public boolean setHapticGeneratorEnabled(boolean enabled) {
        if (!HapticGenerator.isAvailable()) {
            return false;
        }
        synchronized (mPlaybackSettingsLock) {
            mHapticGeneratorEnabled = enabled;
            applyPlaybackProperties_sync();
        }
        return true;
    }

    /**
     * Return whether the {@link android.media.audiofx.HapticGenerator} effect is enabled or not.
     * @return true if the HapticGenerator is enabled.
     */
    public boolean isHapticGeneratorEnabled() {
        synchronized (mPlaybackSettingsLock) {
            return mHapticGeneratorEnabled;
        }
    }

    /**
     * Must be called synchronized on mPlaybackSettingsLock
     */
@@ -203,9 +234,16 @@ public class Ringtone {
        if (mLocalPlayer != null) {
            mLocalPlayer.setVolume(mVolume);
            mLocalPlayer.setLooping(mIsLooping);
            if (mHapticGenerator == null && mHapticGeneratorEnabled) {
                mHapticGenerator = HapticGenerator.create(mLocalPlayer.getAudioSessionId());
            }
            if (mHapticGenerator != null) {
                mHapticGenerator.setEnabled(mHapticGeneratorEnabled);
            }
        } else if (mAllowRemote && (mRemotePlayer != null)) {
            try {
                mRemotePlayer.setPlaybackProperties(mRemoteToken, mVolume, mIsLooping);
                mRemotePlayer.setPlaybackProperties(
                        mRemoteToken, mVolume, mIsLooping, mHapticGeneratorEnabled);
            } catch (RemoteException e) {
                Log.w(TAG, "Problem setting playback properties: ", e);
            }
@@ -413,6 +451,10 @@ public class Ringtone {

    private void destroyLocalPlayer() {
        if (mLocalPlayer != null) {
            if (mHapticGenerator != null) {
                mHapticGenerator.release();
                mHapticGenerator = null;
            }
            mLocalPlayer.setOnCompletionListener(null);
            mLocalPlayer.reset();
            mLocalPlayer.release();
+3 −1
Original line number Diff line number Diff line
@@ -163,7 +163,8 @@ public class RingtonePlayer extends SystemUI {
        }

        @Override
        public void setPlaybackProperties(IBinder token, float volume, boolean looping) {
        public void setPlaybackProperties(IBinder token, float volume, boolean looping,
                boolean hapticGeneratorEnabled) {
            Client client;
            synchronized (mClients) {
                client = mClients.get(token);
@@ -171,6 +172,7 @@ public class RingtonePlayer extends SystemUI {
            if (client != null) {
                client.mRingtone.setVolume(volume);
                client.mRingtone.setLooping(looping);
                client.mRingtone.setHapticGeneratorEnabled(hapticGeneratorEnabled);
            }
            // else no client for token when setting playback properties but will be set at play()
        }