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

Commit 203b411d authored by Eric Laurent's avatar Eric Laurent
Browse files

Ringtone: keep a reference until playback completion.

Keep a reference on active Ringtones to avoid garbage collection
before playback is complete.

Bug: 11366759.
Change-Id: Icb04da427c20e0b4657e9e8b13b3ecab98e5a333
parent b9f2b4ec
Loading
Loading
Loading
Loading
+38 −2
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import android.content.Context;
import android.content.res.AssetFileDescriptor;
import android.content.res.Resources.NotFoundException;
import android.database.Cursor;
import android.media.MediaPlayer.OnCompletionListener;
import android.net.Uri;
import android.os.Binder;
import android.os.RemoteException;
@@ -29,6 +30,7 @@ import android.provider.Settings;
import android.util.Log;

import java.io.IOException;
import java.util.ArrayList;

/**
 * Ringtone provides a quick method for playing a ringtone, notification, or
@@ -49,6 +51,9 @@ public class Ringtone {
        MediaStore.Audio.Media.TITLE
    };

    // keep references on active Ringtones until stopped or completion listener called.
    private static final ArrayList<Ringtone> sActiveRingtones = new ArrayList<Ringtone>();

    private final Context mContext;
    private final AudioManager mAudioManager;

@@ -62,6 +67,7 @@ public class Ringtone {
    private final Binder mRemoteToken;

    private MediaPlayer mLocalPlayer;
    private final MyOnCompletionListener mCompletionListener = new MyOnCompletionListener();

    private Uri mUri;
    private String mTitle;
@@ -247,7 +253,7 @@ public class Ringtone {
            // (typically because ringer mode is silent).
            if (mAudioManager.getStreamVolume(
                    AudioAttributes.toLegacyStreamType(mAudioAttributes)) != 0) {
                mLocalPlayer.start();
                startLocalPlayer();
            }
        } else if (mAllowRemote && (mRemotePlayer != null)) {
            final Uri canonicalUri = mUri.getCanonicalUri();
@@ -285,7 +291,21 @@ public class Ringtone {
            mLocalPlayer.reset();
            mLocalPlayer.release();
            mLocalPlayer = null;
            synchronized (sActiveRingtones) {
                sActiveRingtones.remove(this);
            }
        }
    }

    private void startLocalPlayer() {
        if (mLocalPlayer == null) {
            return;
        }
        synchronized (sActiveRingtones) {
            sActiveRingtones.add(this);
        }
        mLocalPlayer.setOnCompletionListener(mCompletionListener);
        mLocalPlayer.start();
    }

    /**
@@ -330,7 +350,7 @@ public class Ringtone {
                        }
                        mLocalPlayer.setAudioAttributes(mAudioAttributes);
                        mLocalPlayer.prepare();
                        mLocalPlayer.start();
                        startLocalPlayer();
                        afd.close();
                        return true;
                    } else {
@@ -352,4 +372,20 @@ public class Ringtone {
    void setTitle(String title) {
        mTitle = title;
    }

    @Override
    protected void finalize() {
        if (mLocalPlayer != null) {
            mLocalPlayer.release();
        }
    }

    class MyOnCompletionListener implements MediaPlayer.OnCompletionListener {
        public void onCompletion(MediaPlayer mp)
        {
            synchronized (sActiveRingtones) {
                sActiveRingtones.remove(Ringtone.this);
            }
        }
    }
}