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

Commit b3ec3af4 authored by Jorge Ruesga's avatar Jorge Ruesga Committed by Michael Bestas
Browse files

deskclock: remove unused multiplayer



The current Deskclock multiplayer implementation only used the random feature and
none of the real multiplayer feature, and it lacks of a proper DocumentProvider support.
This change just returns to the default mediaplayer and resolve the random feature
externally

Change-Id: I1d721d95e9528530c86f8edbc8188167348c38c4
Signed-off-by: default avatarJorge Ruesga <jorge@ruesga.com>
(cherry picked from commit 2a1ff3d2)
parent e7b6168b
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -712,7 +712,7 @@ public class AlarmClockFragment extends DeskClockFragment implements
                                launchSingleRingTonePicker(alarm);
                                break;
                            case 1:
                                alarm.alert = MultiPlayer.RANDOM_URI;
                                alarm.alert = AlarmMediaPlayer.RANDOM_URI;
                                asyncUpdateAlarm(alarm, false);
                                break;
                        }
@@ -1557,7 +1557,7 @@ public class AlarmClockFragment extends DeskClockFragment implements
            // Try the cache first
            String title = mRingtoneTitleCache.getString(uri.toString());
            if (title == null) {
                if (uri.equals(MultiPlayer.RANDOM_URI)) {
                if (uri.equals(AlarmMediaPlayer.RANDOM_URI)) {
                    title = mContext.getResources().getString(R.string.alarm_type_random);
                } else {
                    // This is slow because a media player is created during Ringtone object creation.
+70 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2014 The CyanogenMod Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.deskclock;

import android.content.ContentUris;
import android.content.Context;
import android.database.Cursor;
import android.media.MediaPlayer;
import android.net.Uri;
import android.provider.MediaStore;
import android.provider.MediaStore.Audio;

import java.io.IOException;
import java.util.Map;

public class AlarmMediaPlayer extends MediaPlayer {

    public static final Uri RANDOM_URI = Uri.parse("random");

    private final Context mContext;

    public AlarmMediaPlayer(Context context) {
        mContext = context;
    }

    @Override
    public void setDataSource(Context context, Uri uri) throws IOException,
            IllegalArgumentException, SecurityException, IllegalStateException {
        setDataSource(context, uri, null);
    }

    @Override
    public void setDataSource(Context context, Uri uri, Map<String, String> headers)
            throws IOException, IllegalArgumentException, SecurityException, IllegalStateException {
        if (uri.equals(RANDOM_URI)) {
            super.setDataSource(context, getNextRandomUri(), headers);
        } else {
            super.setDataSource(context, uri, headers);
        }
    }

    private Uri getNextRandomUri() {
        Cursor c = mContext.getContentResolver().query(
                MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
                null, null, null, "RANDOM() LIMIT 1");
        try {
            if (c.moveToFirst()) {
                long id = c.getLong(c.getColumnIndex(MediaStore.Audio.Media._ID));
                return ContentUris.withAppendedId(Audio.Media.EXTERNAL_CONTENT_URI, id);
            }
        } finally {
            c.close();
        }
        return null;
    }
}
+0 −324
Original line number Diff line number Diff line
package com.android.deskclock;

import java.io.FileDescriptor;
import java.io.IOException;

import android.content.ContentUris;
import android.content.Context;
import android.database.Cursor;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnErrorListener;
import android.net.Uri;
import android.provider.MediaStore;
import android.provider.MediaStore.Audio;

public class MultiPlayer implements MediaPlayer.OnCompletionListener {

    public static final Uri RANDOM_URI = Uri.parse("random");

    private MediaPlayer mCurrentMediaPlayer = new MediaPlayer();
    private MediaPlayer mNextMediaPlayer;

    private boolean mIsInitialized = false;

    private Context mContext;

    private boolean mSingle;

    private OnErrorListener mErrorListener;
    private int mAudioStreamType = AudioManager.STREAM_ALARM;
    private boolean mLooping;
    private boolean mIsExternal;
    private boolean mRandom;

    private Cursor mCursor;

    private int mColumnIndex;
    private float mLeftVolume = -1;
    private float mRightVolume = -1;

    /**
     * Constructor of <code>MultiPlayer</code>
     */
    public MultiPlayer(Context context) {
        mContext = context;
    }

    /**
     * @param uri The Uri you want to play
     */
    public void setDataSource(Context context, final Uri uri) {
        handleSetDataSourceUri(uri);
        mIsInitialized = setDataSourceImpl(mCurrentMediaPlayer, getNextUri());
        if (mIsInitialized) {
            if (mSingle) {
                setNextDataSource(null);
            } else {
                setNextDataSource(getNextUri());
            }
        }
    }

    /**
     * Sets the data source (FileDescriptor) to use. It is the caller's responsibility
     * to close the file descriptor. It is safe to do so as soon as this call returns.
     *
     * @param fd the FileDescriptor for the file you want to play
     * @throws IllegalStateException if it is called in an invalid state
     */
    public void setDataSource(FileDescriptor fd, long offset, long length) {
        mIsInitialized = setDataSourceImpl(mCurrentMediaPlayer, fd, offset, length);
        if (mIsInitialized) {
            mSingle = true;
            setNextDataSource(null);
        }
    }

    /**
     * @param player The {@link MediaPlayer} to use
     * @param uri The path of the file, or the http/rtsp URL of the stream
     *            you want to play
     * @return True if the <code>player</code> has been prepared and is
     *         ready to play, false otherwise
     */
    private boolean setDataSourceImpl(final MediaPlayer player, final Uri uri) {
        try {
            player.reset();
            player.setOnPreparedListener(null);
            player.setDataSource(mContext, uri);
            player.setAudioStreamType(mAudioStreamType);
            if (mLeftVolume != -1 && mRightVolume != -1) {
                player.setVolume(mLeftVolume, mRightVolume);
            }
            mCurrentMediaPlayer.setLooping(mLooping);
            player.prepare();
        } catch (final IOException todo) {
            return false;
        } catch (final IllegalArgumentException todo) {
            return false;
        }
        player.setOnCompletionListener(this);
        player.setOnErrorListener(mErrorListener);
        return true;
    }

    private boolean setDataSourceImpl(
            final MediaPlayer player, FileDescriptor fd, long offset, long length) {
        try {
            player.reset();
            player.setOnPreparedListener(null);
            player.setDataSource(fd, offset, length);
            player.setAudioStreamType(mAudioStreamType);
            if (mLeftVolume != -1 && mRightVolume != -1) {
                player.setVolume(mLeftVolume, mRightVolume);
            }
            player.setLooping(mLooping);
            player.prepare();
        } catch (final IOException todo) {
            return false;
        } catch (final IllegalArgumentException todo) {
            return false;
        }
        player.setOnCompletionListener(this);
        player.setOnErrorListener(mErrorListener);
        return true;
    }

    /**
     * Set the MediaPlayer to start when this MediaPlayer finishes playback.
     *
     * @param uri The path of the file, or the http/rtsp URL of the stream
     *            you want to play
     */
    public void setNextDataSource(final Uri uri) {
        mCurrentMediaPlayer.setNextMediaPlayer(null);
        if (mNextMediaPlayer != null) {
            mNextMediaPlayer.release();
            mNextMediaPlayer = null;
        }
        if (uri == null) {
            return;
        }
        mNextMediaPlayer = new MediaPlayer();
        mNextMediaPlayer.setAudioSessionId(getAudioSessionId());
        if (setDataSourceImpl(mNextMediaPlayer, uri)) {
            mCurrentMediaPlayer.setNextMediaPlayer(mNextMediaPlayer);
        } else {
            if (mNextMediaPlayer != null) {
                mNextMediaPlayer.release();
                mNextMediaPlayer = null;
            }
        }
    }

    /**
     * Starts or resumes playback.
     */
    public void start() {
        mCurrentMediaPlayer.start();
    }

    /**
     * Resets the MediaPlayer to its uninitialized state.
     */
    public void stop() {
        mCurrentMediaPlayer.reset();
        mIsInitialized = false;
    }

    /**
     * Releases resources associated with this MediaPlayer object.
     */
    public void release() {
        stop();
        mCurrentMediaPlayer.release();

        if (mCursor != null) {
            mCursor.close();
            mCursor = null;
        }
    }

    public void reset() {
    }

    /**
     * Sets the volume on this player.
     *
     * @param leftVol Left and right volume scalar
     */
    public void setVolume(final float leftVol, final float rightVol) {
        mLeftVolume = leftVol;
        mRightVolume = rightVol;
        mCurrentMediaPlayer.setVolume(mLeftVolume, mRightVolume);
        if (mNextMediaPlayer != null) {
            mNextMediaPlayer.setVolume(mLeftVolume, mRightVolume);
        }
    }

    /**
     * Returns the audio session ID.
     *
     * @return The current audio session ID.
     */
    public int getAudioSessionId() {
        return mCurrentMediaPlayer.getAudioSessionId();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void onCompletion(final MediaPlayer mp) {
        if (mLooping) {
            // do not control sequence if we are looping
            return;
        }
        if (mp == mCurrentMediaPlayer && mNextMediaPlayer != null) {
            mCurrentMediaPlayer.release();
            mCurrentMediaPlayer = mNextMediaPlayer;
            mNextMediaPlayer = null;
        }

        setNextDataSource(getNextUri());
    }

    private Uri getNextUri() {
        if (mRandom) {
            Cursor c = mContext.getContentResolver().query(
                    MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
                    null, null, null, "RANDOM() LIMIT 1");
            try {
                if (c.moveToFirst()) {
                    long id = c.getLong(c.getColumnIndex(MediaStore.Audio.Media._ID));
                    return ContentUris.withAppendedId(Audio.Media.EXTERNAL_CONTENT_URI, id);
                }
            } finally {
                c.close();
            }
            return null;
        }
        if (mCursor == null) {
            Log.e("MultiPlayer: mCursor = null");
            return null;
        }

        long id = mCursor.getLong(mColumnIndex);
        if (!mCursor.moveToNext()) {
            // Cycle through the playlist
            mCursor.moveToFirst();
        }
        if(mIsExternal) {
            return ContentUris.withAppendedId(Audio.Media.EXTERNAL_CONTENT_URI, id);
        } else {
            return ContentUris.withAppendedId(Audio.Media.INTERNAL_CONTENT_URI, id);
        }
    }

    private void handleSetDataSourceUri(Uri uri) {
        mSingle = false;
        if (uri.equals(RANDOM_URI)) {
            mRandom = true;
            return;
        }

        String columnName = null;
        final String rawUri = uri.toString();
        if (rawUri.startsWith(Audio.Media.EXTERNAL_CONTENT_URI.toString())
                || rawUri.startsWith(Audio.Media.INTERNAL_CONTENT_URI.toString())) {
            columnName = Audio.Media._ID;
        } else if (rawUri.startsWith(Audio.Playlists.EXTERNAL_CONTENT_URI.toString())
                || rawUri.startsWith(Audio.Playlists.INTERNAL_CONTENT_URI.toString())) {
            long playlist_id = Long.parseLong(uri.getLastPathSegment());
            uri = Audio.Playlists.Members.getContentUri("external", playlist_id);
            columnName = Audio.Playlists.Members.AUDIO_ID;
        } else {
            Log.e("MultiPlayer: unknown uri: "+uri.toString());
        }
        mIsExternal = rawUri.contains("external");
        mCursor = mContext.getContentResolver().query(uri, null, null, null, null);
        if (mCursor == null) {
            Log.e("MultiPlayr: Query failed, cursor = null");
            return;
        }
        mColumnIndex = mCursor.getColumnIndex(columnName);
        if (mCursor.getCount() == 0) {
            Log.e("MultiPlayr: Query failed, cursor.getCout() = 0");
            return;
        }
        mCursor.moveToFirst();

        if (mCursor.getCount() == 1) {
            mSingle = true;
        }
    }

    public boolean isPlaying() {
        return mCurrentMediaPlayer.isPlaying();
    }

    public void setOnErrorListener(MediaPlayer.OnErrorListener l) {
        mErrorListener = l;
    }

    public void setAudioStreamType(int type) {
        mAudioStreamType = type;
        mCurrentMediaPlayer.setAudioStreamType(mAudioStreamType);
        if(mNextMediaPlayer != null) {
            mNextMediaPlayer.setAudioStreamType(mAudioStreamType);
        }
    }

    public void setLooping(boolean looping) {
        if (mSingle) {
            mLooping = looping;
        } else {
            mLooping = false;
        }
        mCurrentMediaPlayer.setLooping(mLooping);
    }

    public void prepare() {
    }
}
+18 −13
Original line number Diff line number Diff line
@@ -28,7 +28,7 @@ import android.os.Message;
import android.os.Vibrator;

import com.android.deskclock.Log;
import com.android.deskclock.MultiPlayer;
import com.android.deskclock.AlarmMediaPlayer;
import com.android.deskclock.R;
import com.android.deskclock.provider.AlarmInstance;

@@ -50,7 +50,7 @@ public class AlarmKlaxon {

    private static boolean sStarted = false;
    private static AudioManager sAudioManager = null;
    private static MultiPlayer sMediaPlayer = null;
    private static AlarmMediaPlayer sMediaPlayer = null;

    private static int sCurrentVolume = INCREASING_VOLUME_START;
    private static int sAlarmVolumeSetting;
@@ -131,8 +131,12 @@ public class AlarmKlaxon {
                sAudioManager.setStreamVolume(AudioManager.STREAM_ALARM, sCurrentVolume, 0);
            }

            // TODO: Reuse mMediaPlayer instead of creating a new one and/or use RingtoneManager.
            sMediaPlayer = new MultiPlayer(context);
            if (sMediaPlayer != null) {
                if (sMediaPlayer.isPlaying()) {
                    sMediaPlayer.stop();
                }
            } else {
                sMediaPlayer = new AlarmMediaPlayer(context);
                sMediaPlayer.setOnErrorListener(new OnErrorListener() {
                    @Override
                    public boolean onError(MediaPlayer mp, int what, int extra) {
@@ -141,6 +145,7 @@ public class AlarmKlaxon {
                        return true;
                    }
                });
            }

            try {
                // Check if we are in a call. If we are, use the in-call alarm
@@ -178,7 +183,7 @@ public class AlarmKlaxon {
    }

    // Do the common stuff when starting the alarm.
    private static void startAlarm(Context context, MultiPlayer player,
    private static void startAlarm(Context context, AlarmMediaPlayer player,
            AlarmInstance instance) throws IOException {
        // do not play alarms if stream volume is 0 (typically because ringer mode is silent).
        if (sAudioManager.getStreamVolume(AudioManager.STREAM_ALARM) != 0) {
@@ -195,7 +200,7 @@ public class AlarmKlaxon {
        }
    }

    private static void setDataSourceFromResource(Context context, MultiPlayer player, int res)
    private static void setDataSourceFromResource(Context context, AlarmMediaPlayer player, int res)
            throws IOException {
        AssetFileDescriptor afd = context.getResources().openRawResourceFd(res);
        if (afd != null) {