use of com.ichi2.anki.AbstractFlashcardViewer in project Anki-Android by ankidroid.
the class Sound method playSoundInternal.
/**
* Plays a sound without ensuring that the playAllListener will release the audio
*/
@SuppressWarnings({ "PMD.EmptyIfStmt", "PMD.CollapsibleIfStatements" })
private void playSoundInternal(String soundPath, @NonNull OnCompletionListener playAllListener, VideoView videoView, OnErrorListener errorListener) {
Timber.d("Playing %s has listener? %b", soundPath, playAllListener != null);
Uri soundUri = Uri.parse(soundPath);
mCurrentAudioUri = soundUri;
final OnErrorListener errorHandler = errorListener == null ? (mp, what, extra, path) -> {
Timber.w("Media Error: (%d, %d). Calling OnCompletionListener", what, extra);
return false;
} : errorListener;
if ("tts".equals(soundPath.substring(0, 3))) {
// TODO: give information about did
// ReadText.textToSpeech(soundPath.substring(4, soundPath.length()),
// Integer.parseInt(soundPath.substring(3, 4)));
} else {
// Check if the file extension is that of a known video format
final String extension = soundPath.substring(soundPath.lastIndexOf(".") + 1).toLowerCase(Locale.getDefault());
boolean isVideo = Arrays.asList(VIDEO_WHITELIST).contains(extension);
if (!isVideo) {
final String guessedType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
isVideo = (guessedType != null) && guessedType.startsWith("video/");
}
// Also check that there is a video thumbnail, as some formats like mp4 can be audio only
isVideo = isVideo && hasVideoThumbnail(soundUri);
// holder
if (isVideo && videoView == null && mCallingActivity != null && mCallingActivity.get() != null) {
Timber.d("Requesting AbstractFlashcardViewer play video - no SurfaceHolder");
mPlayAllListener = playAllListener;
((AbstractFlashcardViewer) mCallingActivity.get()).playVideo(soundPath);
return;
}
// Play media
try {
// Create media player
if (mMediaPlayer == null) {
Timber.d("Creating media player for playback");
mMediaPlayer = new MediaPlayer();
} else {
Timber.d("Resetting media for playback");
mMediaPlayer.reset();
}
if (mAudioManager == null) {
mAudioManager = (AudioManager) AnkiDroidApp.getInstance().getApplicationContext().getSystemService(Context.AUDIO_SERVICE);
}
// Provide a VideoView to the MediaPlayer if valid video file
if (isVideo && videoView != null) {
mMediaPlayer.setDisplay(videoView.getHolder());
mMediaPlayer.setOnVideoSizeChangedListener((mp, width, height) -> configureVideo(videoView, width, height));
}
mMediaPlayer.setOnErrorListener((mp, which, extra) -> errorHandler.onError(mp, which, extra, soundPath));
// Setup the MediaPlayer
mMediaPlayer.setDataSource(AnkiDroidApp.getInstance().getApplicationContext(), soundUri);
mMediaPlayer.setAudioAttributes(new AudioAttributes.Builder().setContentType(AudioAttributes.CONTENT_TYPE_MUSIC).build());
mMediaPlayer.setOnPreparedListener(mp -> {
Timber.d("Starting media player");
mMediaPlayer.start();
});
mMediaPlayer.setOnCompletionListener(playAllListener);
mMediaPlayer.prepareAsync();
Timber.d("Requesting audio focus");
// Set mAudioFocusRequest for API 26 and above.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
mAudioFocusRequest = new AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK).setOnAudioFocusChangeListener(afChangeListener).build();
}
CompatHelper.getCompat().requestAudioFocus(mAudioManager, afChangeListener, mAudioFocusRequest);
} catch (Exception e) {
Timber.e(e, "playSounds - Error reproducing sound %s", soundPath);
if (!errorHandler.onError(mMediaPlayer, MediaPlayer.MEDIA_ERROR_UNSUPPORTED, 0, soundPath)) {
Timber.d("Force playing next sound.");
playAllListener.onCompletion(mMediaPlayer);
}
}
}
}
use of com.ichi2.anki.AbstractFlashcardViewer in project Anki-Android by ankidroid.
the class OnRenderProcessGoneDelegateTest method secondCallCausesDialog.
@Test
public void secondCallCausesDialog() {
AbstractFlashcardViewer mock = getViewer();
OnRenderProcessGoneDelegateImpl delegate = getInstance(mock);
callOnRenderProcessGone(delegate);
verify(mock, times(1)).displayCardQuestion();
callOnRenderProcessGone(delegate);
verify(mock, times(1).description("displayCardQuestion should not be called again as the screen should close")).displayCardQuestion();
assertThat(delegate.mDisplayedDialog, is(true));
verify(mock, times(1).description("After the dialog, the screen should be closed")).finishWithoutAnimation();
}
use of com.ichi2.anki.AbstractFlashcardViewer in project Anki-Android by ankidroid.
the class OnRenderProcessGoneDelegateTest method singleCallCausesRefresh.
@Test
public void singleCallCausesRefresh() {
AbstractFlashcardViewer mock = getViewer();
OnRenderProcessGoneDelegateImpl delegate = getInstance(mock);
callOnRenderProcessGone(delegate);
verify(mock, times(1)).displayCardQuestion();
assertThat(delegate.mDisplayedToast, is(true));
}
use of com.ichi2.anki.AbstractFlashcardViewer in project Anki-Android by ankidroid.
the class OnRenderProcessGoneDelegateTest method secondCallDoesNothingIfMinimised.
@Test
public void secondCallDoesNothingIfMinimised() {
AbstractFlashcardViewer mock = getMinimisedViewer();
OnRenderProcessGoneDelegateImpl delegate = getInstance(mock);
callOnRenderProcessGone(delegate);
verify(mock, times(1)).displayCardQuestion();
callOnRenderProcessGone(delegate);
verify(mock, times(2).description("displayCardQuestion should be called again as the app was minimised")).displayCardQuestion();
assertThat(delegate.mDisplayedDialog, is(false));
}
use of com.ichi2.anki.AbstractFlashcardViewer in project Anki-Android by ankidroid.
the class OnRenderProcessGoneDelegateTest method unrecoverableCrashCloses.
@SuppressWarnings("ResultOfMethodCallIgnored")
@Test
public void unrecoverableCrashCloses() {
AbstractFlashcardViewer mock = getMinimisedViewer();
OnRenderProcessGoneDelegateImpl delegate = getInstance(mock);
doReturn(null).when(mock).getCurrentCard();
callOnRenderProcessGone(delegate);
verify(mock, times(1)).destroyWebViewFrame();
verify(mock, never()).recreateWebViewFrame();
assertThat("A toast should not be displayed as the screen is minimised", delegate.mDisplayedToast, is(false));
verify(mock, times(1).description("screen should be closed")).finishWithoutAnimation();
}
Aggregations