Search in sources :

Example 6 with AbstractFlashcardViewer

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);
            }
        }
    }
}
Also used : AbstractFlashcardViewer(com.ichi2.anki.AbstractFlashcardViewer) AudioAttributes(android.media.AudioAttributes) AudioFocusRequest(android.media.AudioFocusRequest) Uri(android.net.Uri) MediaPlayer(android.media.MediaPlayer)

Example 7 with AbstractFlashcardViewer

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();
}
Also used : AbstractFlashcardViewer(com.ichi2.anki.AbstractFlashcardViewer) Test(org.junit.Test)

Example 8 with AbstractFlashcardViewer

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));
}
Also used : AbstractFlashcardViewer(com.ichi2.anki.AbstractFlashcardViewer) Test(org.junit.Test)

Example 9 with AbstractFlashcardViewer

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));
}
Also used : AbstractFlashcardViewer(com.ichi2.anki.AbstractFlashcardViewer) Test(org.junit.Test)

Example 10 with AbstractFlashcardViewer

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();
}
Also used : AbstractFlashcardViewer(com.ichi2.anki.AbstractFlashcardViewer) Test(org.junit.Test)

Aggregations

AbstractFlashcardViewer (com.ichi2.anki.AbstractFlashcardViewer)9 Test (org.junit.Test)6 Resources (android.content.res.Resources)4 WebView (android.webkit.WebView)4 Uri (android.net.Uri)3 View (android.view.View)3 Context (android.content.Context)2 MediaPlayer (android.media.MediaPlayer)2 ImageView (android.widget.ImageView)2 TextView (android.widget.TextView)2 AudioView (com.ichi2.anki.multimediacard.AudioView)2 TaskData (com.ichi2.async.TaskData)2 SharedPreferences (android.content.SharedPreferences)1 AudioAttributes (android.media.AudioAttributes)1 AudioFocusRequest (android.media.AudioFocusRequest)1 Handler (android.os.Handler)1 TextToSpeech (android.speech.tts.TextToSpeech)1 UtteranceProgressListener (android.speech.tts.UtteranceProgressListener)1 OnClickListener (android.view.View.OnClickListener)1 ViewGroup (android.view.ViewGroup)1