blob: 48062a87d6e8ada0c5709944782f73c93021cf90 [file] [log] [blame]
/*
* Copyright (C) 2017 The Android Open Source 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.dialer.voicemail.listui;
import android.content.Context;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnErrorListener;
import android.media.MediaPlayer.OnPreparedListener;
import android.net.Uri;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import com.android.dialer.common.Assert;
import com.android.dialer.common.LogUtil;
import java.io.IOException;
/** A wrapper around {@link MediaPlayer} */
public class NewVoicemailMediaPlayer {
private final MediaPlayer mediaPlayer;
private Uri voicemailLastPlayedOrPlayingUri;
private Uri voicemailUriLastPreparedOrPreparingToPlay;
private OnErrorListener newVoicemailMediaPlayerOnErrorListener;
private OnPreparedListener newVoicemailMediaPlayerOnPreparedListener;
private OnCompletionListener newVoicemailMediaPlayerOnCompletionListener;
private Uri pausedUri;
@Nullable private Uri voicemailRequestedToDownload;
public NewVoicemailMediaPlayer(@NonNull MediaPlayer player) {
mediaPlayer = Assert.isNotNull(player);
}
public void prepareMediaPlayerAndPlayVoicemailWhenReady(Context context, Uri uri)
throws IOException {
Assert.checkArgument(uri != null, "Media player cannot play a null uri");
LogUtil.i(
"NewVoicemailMediaPlayer",
"trying to prepare playing voicemail uri: %s",
String.valueOf(uri));
try {
reset();
voicemailUriLastPreparedOrPreparingToPlay = uri;
verifyListenersNotNull();
LogUtil.i("NewVoicemailMediaPlayer", "setData source");
mediaPlayer.setDataSource(context, uri);
LogUtil.i("NewVoicemailMediaPlayer", "prepare async");
mediaPlayer.prepareAsync();
} catch (IllegalStateException e) {
LogUtil.i(
"NewVoicemailMediaPlayer", "caught an IllegalStateException state exception : \n" + e);
} catch (Exception e) {
LogUtil.i(
"NewVoicemailMediaPlayer",
"threw an Exception " + e + " for uri: " + uri + "for context : " + context);
}
}
private void verifyListenersNotNull() {
Assert.isNotNull(
newVoicemailMediaPlayerOnErrorListener,
"newVoicemailMediaPlayerOnErrorListener must be set before preparing to "
+ "play voicemails");
Assert.isNotNull(
newVoicemailMediaPlayerOnCompletionListener,
"newVoicemailMediaPlayerOnCompletionListener must be set before preparing"
+ " to play voicemails");
Assert.isNotNull(
newVoicemailMediaPlayerOnPreparedListener,
"newVoicemailMediaPlayerOnPreparedListener must be set before preparing to"
+ " play voicemails");
}
// Must be called from onPrepared
public void start(Uri startPlayingVoicemailUri) {
Assert.checkArgument(
startPlayingVoicemailUri.equals(voicemailUriLastPreparedOrPreparingToPlay),
"uri:%s was not prepared before calling start. Uri that is currently prepared: %s",
startPlayingVoicemailUri,
getLastPreparedOrPreparingToPlayVoicemailUri());
mediaPlayer.start();
voicemailLastPlayedOrPlayingUri = startPlayingVoicemailUri;
pausedUri = null;
voicemailRequestedToDownload = null;
}
public void reset() {
LogUtil.enterBlock("NewVoicemailMediaPlayer.reset");
mediaPlayer.reset();
voicemailLastPlayedOrPlayingUri = null;
voicemailUriLastPreparedOrPreparingToPlay = null;
pausedUri = null;
voicemailRequestedToDownload = null;
}
public void pauseMediaPlayer(Uri voicemailUri) {
pausedUri = voicemailUri;
Assert.checkArgument(
voicemailUriLastPreparedOrPreparingToPlay.equals(voicemailLastPlayedOrPlayingUri),
"last prepared and last playing should be the same");
Assert.checkArgument(
pausedUri.equals(voicemailLastPlayedOrPlayingUri),
"only the last played uri can be paused");
mediaPlayer.pause();
}
public void seekTo(int progress) {
mediaPlayer.seekTo(progress);
}
public void setOnErrorListener(OnErrorListener onErrorListener) {
mediaPlayer.setOnErrorListener(onErrorListener);
newVoicemailMediaPlayerOnErrorListener = onErrorListener;
}
public void setOnPreparedListener(OnPreparedListener onPreparedListener) {
mediaPlayer.setOnPreparedListener(onPreparedListener);
newVoicemailMediaPlayerOnPreparedListener = onPreparedListener;
}
public void setOnCompletionListener(OnCompletionListener onCompletionListener) {
mediaPlayer.setOnCompletionListener(onCompletionListener);
newVoicemailMediaPlayerOnCompletionListener = onCompletionListener;
}
public void setVoicemailRequestedToDownload(@NonNull Uri uri) {
Assert.isNotNull(uri, "cannot download a null voicemail");
voicemailRequestedToDownload = uri;
}
/**
* Note: In some cases it's possible mediaPlayer.isPlaying() can return true, but
* mediaPlayer.getCurrentPosition() can be greater than mediaPlayer.getDuration(), after which
* mediaPlayer.isPlaying() will be false. This is a weird corner case and adding the
* mediaPlayer.getCurrentPosition() < mediaPlayer.getDuration() check here messes with the
* mediaPlayer.start() (doesn't return mediaPlayer.isPlaying() to be true immediately).
*
* @return if the media plaer;
*/
public boolean isPlaying() {
return mediaPlayer.isPlaying();
}
public int getCurrentPosition() {
return mediaPlayer.getCurrentPosition();
}
public Uri getLastPlayedOrPlayingVoicemailUri() {
if (mediaPlayer.isPlaying()) {
Assert.isNotNull(voicemailLastPlayedOrPlayingUri);
}
return voicemailLastPlayedOrPlayingUri == null ? Uri.EMPTY : voicemailLastPlayedOrPlayingUri;
}
/**
* All the places that call this function, we expect the voicemail to have been prepared, but we
* could get rid of the assert check in the future if needed.
*/
public Uri getLastPreparedOrPreparingToPlayVoicemailUri() {
return Assert.isNotNull(
voicemailUriLastPreparedOrPreparingToPlay,
"we expect whoever called this to have prepared a voicemail before calling this function");
}
public Uri getLastPausedVoicemailUri() {
return pausedUri;
}
public MediaPlayer getMediaPlayer() {
return mediaPlayer;
}
public int getDuration() {
Assert.checkArgument(mediaPlayer != null);
return mediaPlayer.getDuration();
}
/**
* A null v/s non-value is important for the {@link NewVoicemailAdapter} to differentiate between
* a underlying table change due to a voicemail being downloaded or something else (e.g delete).
*
* @return if there was a Uri that was requested to be downloaded from the server, null otherwise.
*/
@Nullable
public Uri getVoicemailRequestedToDownload() {
return voicemailRequestedToDownload;
}
public boolean isPaused() {
return pausedUri != null;
}
}