alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Android example source code file (MediaPlayerStateUnitTestTemplate.java)

This example Android source code file (MediaPlayerStateUnitTestTemplate.java) is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Android by Example" TM.

Java - Android tags/keywords

android, exception, handler, idle, initialized, media, mediaplayer, mediaplayerstateerrors, milliseconds, object, os, override, photo, playback_completed, prepared_after_stop, sound, started, stopped, string, test

The MediaPlayerStateUnitTestTemplate.java Android example source code

/*
 * Copyright (C) 2008 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.mediaframeworktest.unit;

import android.util.Log;
import android.os.Looper;
import android.os.Handler;
import android.os.Message;
import android.media.MediaPlayer;
import android.test.AndroidTestCase;
import com.android.mediaframeworktest.MediaNames;

/**
 * A template class for running a method under test in all possible
 * states of a MediaPlayer object.
 * 
 * @see com.android.mediaframeworktest.unit.MediaPlayerSeekToStateUnitTest
 * for an example of using this class.
 * 
 * A typical concrete unit test class would implement the 
 * MediaPlayerMethodUnderTest interface and have a reference to an object of
 * this class. Then it calls runTestOnMethod() to actually perform the unit
 * tests.
 * 
 */
class MediaPlayerStateUnitTestTemplate extends AndroidTestCase {
    private static final String TEST_PATH = MediaNames.TEST_PATH_1;
    private static final String TAG = "MediaPlayerSeekToStateUnitTest";
    private static final int SEEK_TO_END  = 135110;  // Milliseconds.
    private static int WAIT_FOR_COMMAND_TO_COMPLETE = 1000;  // Milliseconds.
    
    private MediaPlayerStateErrors mStateErrors = new MediaPlayerStateErrors();
    private MediaPlayer mMediaPlayer = null;
    private boolean mInitialized = false;
    private boolean mOnCompletionHasBeenCalled = false;
    private MediaPlayerStateErrors.MediaPlayerState mMediaPlayerState = null;
    private Looper mLooper = null;
    private final Object lock = new Object();
    private MediaPlayerMethodUnderTest mMethodUnderTest = null;
    
    // An Handler object is absolutely necessary for receiving callback 
    // messages from MediaPlayer objects.
    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            /*
            switch(msg.what) {
                case MediaPlayerStateErrors.MEDIA_PLAYER_ERROR:
                    Log.v(TAG, "handleMessage: received MEDIA_PLAYER_ERROR message");
                    break;
                default:
                    Log.v(TAG, "handleMessage: received unknown message");
                break;
            }
            */
        }
    };
    
    /**
     * Runs the given method under test in all possible states of a MediaPlayer
     * object.
     * 
     * @param testMethod the method under test.
     */
    public void runTestOnMethod(MediaPlayerMethodUnderTest testMethod) {
        mMethodUnderTest = testMethod;
        if (mMethodUnderTest != null) {  // Method under test has been set?
            initializeMessageLooper();
            synchronized(lock) {
                try {
                    lock.wait(WAIT_FOR_COMMAND_TO_COMPLETE);
                } catch(Exception e) {
                    Log.v(TAG, "runTestOnMethod: wait was interrupted.");
                }
            }
            assertTrue(mInitialized);  // mMediaPlayer has been initialized?
            checkMethodUnderTestInAllPossibleStates();
            terminateMessageLooper();   // Release message looper thread.
            assertTrue(mOnCompletionHasBeenCalled);
            mMethodUnderTest.checkStateErrors(mStateErrors);
            cleanUp();
        }
    }
    
    /*
     * Initializes the message looper so that the MediaPlayer object can 
     * receive the callback messages.
     */
    private void initializeMessageLooper() {
        new Thread() {
            @Override
            public void run() {
                // Set up a looper to be used by mMediaPlayer.
                Looper.prepare();

                // Save the looper so that we can terminate this thread 
                // after we are done with it.
                mLooper = Looper.myLooper();
                
                mMediaPlayer = new MediaPlayer();                
                mMediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
                    public boolean onError(MediaPlayer player, int what, int extra) {
                        Log.v(TAG, "onError has been called.");
                        synchronized(lock) {
                            Log.v(TAG, "notify lock.");
                            setStateError(mMediaPlayerState, true);
                            if (mMediaPlayerState != MediaPlayerStateErrors.MediaPlayerState.ERROR) {
                                notifyStateError();
                            }
                            lock.notify();
                        }
                        return true;
                    }
                });
                mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                    public void onCompletion(MediaPlayer player) {
                        Log.v(TAG, "onCompletion has been called.");
                        synchronized(lock) {
                            if (mMediaPlayerState == MediaPlayerStateErrors.MediaPlayerState.PLAYBACK_COMPLETED) {
                                mOnCompletionHasBeenCalled = true;
                            }
                            lock.notify();
                        }
                    }
                });
                synchronized(lock) {
                    mInitialized = true;
                    lock.notify();
                }
                Looper.loop();  // Blocks forever until Looper.quit() is called.
                Log.v(TAG, "initializeMessageLooper: quit.");
            }
        }.start();
    }
    
    /*
     * Calls method under test in the given state of the MediaPlayer object.
     * 
     * @param state the MediaPlayer state in which the method under test is called.
     */
    private void callMediaPlayerMethodUnderTestInState(MediaPlayerStateErrors.MediaPlayerState state) {
        Log.v(TAG, "call " + mMethodUnderTest + ": started in state " + state);
        setMediaPlayerToState(state);
        mMethodUnderTest.invokeMethodUnderTest(mMediaPlayer);
        synchronized(lock) {
            try {
                lock.wait(WAIT_FOR_COMMAND_TO_COMPLETE);
           } catch(Exception e) {
               Log.v(TAG, "callMediaPlayerMethodUnderTestInState: wait is interrupted in state " + state);
           }
        }
        Log.v(TAG, "call " + mMethodUnderTest + ": ended in state " + state);
    }

    /*
     * The following setMediaPlayerToXXXStateXXX methods sets the MediaPlayer
     * object to the corresponding state, given the assumption that reset()
     * always resets the MediaPlayer object to Idle (after reset) state. 
     */
    private void setMediaPlayerToIdleStateAfterReset() {
        try {
            mMediaPlayer.reset();
            mMediaPlayer.setDataSource(TEST_PATH);
            mMediaPlayer.prepare();
            mMediaPlayer.reset();
        } catch(Exception e) {
            Log.v(TAG, "setMediaPlayerToIdleStateAfterReset: Exception " + e.getClass().getName() + " was thrown.");
            assertTrue(false);
        }
    }
    
    private void setMediaPlayerToInitializedState() {
        try {
            mMediaPlayer.reset();
            mMediaPlayer.setDataSource(TEST_PATH);
        } catch(Exception e) {
            Log.v(TAG, "setMediaPlayerToInitializedState: Exception " + e.getClass().getName() + " was thrown.");
            assertTrue(false);
        }
    }
    
    private void setMediaPlayerToPreparedState() {
        try {
            mMediaPlayer.reset();
            mMediaPlayer.setDataSource(TEST_PATH);
            mMediaPlayer.prepare();
        } catch(Exception e) {
            Log.v(TAG, "setMediaPlayerToPreparedState: Exception " + e.getClass().getName() + " was thrown.");
            assertTrue(false);
        }
    }
    
    private void setMediaPlayerToPreparedStateAfterStop() {
        try {
            mMediaPlayer.reset();
            mMediaPlayer.setDataSource(TEST_PATH);
            mMediaPlayer.prepare();
            mMediaPlayer.start();
            mMediaPlayer.stop();
            mMediaPlayer.prepare();
        } catch(Exception e) {
            Log.v(TAG, "setMediaPlayerToPreparedStateAfterStop: Exception " + e.getClass().getName() + " was thrown.");
            assertTrue(false);
        }
    }
    
    private void setMediaPlayerToStartedState() {
        try {
            mMediaPlayer.reset();
            mMediaPlayer.setDataSource(TEST_PATH);
            mMediaPlayer.prepare();
            mMediaPlayer.start();
        } catch(Exception e) {
            Log.v(TAG, "setMediaPlayerToStartedState: Exception " + e.getClass().getName() + " was thrown.");
            assertTrue(false);
        }
    }
    
    private void setMediaPlayerToStartedStateAfterPause() {
        try {
            mMediaPlayer.reset();
            mMediaPlayer.setDataSource(TEST_PATH);
            mMediaPlayer.prepare();
            mMediaPlayer.start();
            mMediaPlayer.pause();

            // pause() is an asynchronous call and returns immediately, but 
            // PV player engine may take quite a while to actually set the 
            // player state to Paused; if we call start() right after pause() 
            // without waiting, start() may fail.
            try {
                Thread.sleep(MediaNames.PAUSE_WAIT_TIME);
            } catch(Exception ie) {
                Log.v(TAG, "sleep was interrupted and terminated prematurely");
            }

            mMediaPlayer.start();
        } catch(Exception e) {
            Log.v(TAG, "setMediaPlayerToStartedStateAfterPause: Exception " + e.getClass().getName() + " was thrown.");
            assertTrue(false);
        }
    }
    
    private void setMediaPlayerToPausedState() {
        try {
            mMediaPlayer.reset();
            mMediaPlayer.setDataSource(TEST_PATH);
            mMediaPlayer.prepare();
            mMediaPlayer.start();
            mMediaPlayer.pause();
        } catch(Exception e) {
            Log.v(TAG, "setMediaPlayerToPausedState: Exception " + e.getClass().getName() + " was thrown.");
            assertTrue(false);
        }
    }
    
    private void setMediaPlayerToStoppedState() {
        try {
            mMediaPlayer.reset();
            mMediaPlayer.setDataSource(TEST_PATH);
            mMediaPlayer.prepare();
            mMediaPlayer.start();
            mMediaPlayer.stop();
        } catch(Exception e) {
            Log.v(TAG, "setMediaPlayerToStoppedState: Exception " + e.getClass().getName() + " was thrown.");
            assertTrue(false);
        }
    }
    
    private void setMediaPlayerToPlaybackCompletedState() {
        try {
            mMediaPlayer.reset();
            mMediaPlayer.setDataSource(TEST_PATH);
            mMediaPlayer.prepare();
            mMediaPlayer.seekTo(SEEK_TO_END);
            mMediaPlayer.start();
            synchronized(lock) {
                try {
                    lock.wait(WAIT_FOR_COMMAND_TO_COMPLETE);
                } catch(Exception e) {
                    Log.v(TAG, "setMediaPlayerToPlaybackCompletedState: wait was interrupted.");
                }
            }
        } catch(Exception e) {
            Log.v(TAG, "setMediaPlayerToPlaybackCompletedState: Exception " + e.getClass().getName() + " was thrown.");
            assertTrue(false);
        }
        Log.v(TAG, "setMediaPlayerToPlaybackCompletedState: done.");
    }
    
    /*
     * There are a lot of ways to force the MediaPlayer object to enter
     * the Error state. The impact (such as onError is called or not) highly 
     * depends on how the Error state is entered.
     */
    private void setMediaPlayerToErrorState() {
        try {
            mMediaPlayer.reset();
            mMediaPlayer.setDataSource(TEST_PATH);
            mMediaPlayer.start();
            synchronized(lock) {
                try {
                    lock.wait(WAIT_FOR_COMMAND_TO_COMPLETE);
                } catch(Exception e) {
                    Log.v(TAG, "setMediaPlayerToErrorState: wait was interrupted.");
                }
            }
        } catch(Exception e) {
            Log.v(TAG, "setMediaPlayerToErrorState: Exception " + e.getClass().getName() + " was thrown.");
            assertTrue(e instanceof IllegalStateException);
        }
        Log.v(TAG, "setMediaPlayerToErrorState: done.");
    }
    
    /*
     * Sets the state of the MediaPlayer object to the specified one.
     * 
     * @param state the state of the MediaPlayer object.
     */
    private void setMediaPlayerToState(MediaPlayerStateErrors.MediaPlayerState state) {
        mMediaPlayerState = state;
        switch(state) {
            case IDLE:
                // Does nothing.
                break;
            case IDLE_AFTER_RESET:
                setMediaPlayerToIdleStateAfterReset();
                break;
            case INITIALIZED:
                setMediaPlayerToInitializedState();
                break;
            case PREPARED:
                setMediaPlayerToPreparedState();
                break;
            case PREPARED_AFTER_STOP:
                setMediaPlayerToPreparedStateAfterStop();
                break;
            case STARTED:
                setMediaPlayerToStartedState();
                break;
            case STARTED_AFTER_PAUSE:
                setMediaPlayerToStartedStateAfterPause();
                break;
            case PAUSED:
                setMediaPlayerToPausedState();
                break;
            case STOPPED:
                setMediaPlayerToStoppedState();
                break;
            case PLAYBACK_COMPLETED:
                setMediaPlayerToPlaybackCompletedState();
                break;
            case ERROR:
                setMediaPlayerToErrorState();
                break;
        }
    }
    
    /*
     * Sets the error value of the corresponding state to the given error.
     * 
     * @param state the state of the MediaPlayer object.
     * @param error the value of the state error to be set.
     */
    private void setStateError(MediaPlayerStateErrors.MediaPlayerState state, boolean error) {
        switch(state) {
            case IDLE:
                mStateErrors.errorInIdleState = error;
                break;
            case IDLE_AFTER_RESET:
                mStateErrors.errorInIdleStateAfterReset = error;
                break;
            case INITIALIZED:
                mStateErrors.errorInInitializedState = error;
                break;
            case PREPARED:
                mStateErrors.errorInPreparedState = error;
                break;
            case PREPARED_AFTER_STOP:
                mStateErrors.errorInPreparedStateAfterStop = error;
                break;
            case STARTED:
                mStateErrors.errorInStartedState = error;
                break;
            case STARTED_AFTER_PAUSE:
                mStateErrors.errorInStartedStateAfterPause = error;
                break;
            case PAUSED:
                mStateErrors.errorInPausedState = error;
                break;
            case STOPPED:
                mStateErrors.errorInStoppedState = error;
                break;
            case PLAYBACK_COMPLETED:
                mStateErrors.errorInPlaybackCompletedState = error;
                break;
            case ERROR:
                mStateErrors.errorInErrorState = error;
                break;
        }
    }
    
    private void notifyStateError() {
        mHandler.sendMessage(mHandler.obtainMessage(MediaPlayerStateErrors.MEDIA_PLAYER_ERROR));
    }

    private void checkIdleState() {
        callMediaPlayerMethodUnderTestInState(MediaPlayerStateErrors.MediaPlayerState.IDLE);
    }
    
    private void checkIdleStateAfterReset() {
        callMediaPlayerMethodUnderTestInState(MediaPlayerStateErrors.MediaPlayerState.IDLE_AFTER_RESET);
    }
    
    private void checkInitializedState() {
        callMediaPlayerMethodUnderTestInState(MediaPlayerStateErrors.MediaPlayerState.INITIALIZED);
    }
    
    private void checkPreparedState() {
        callMediaPlayerMethodUnderTestInState(MediaPlayerStateErrors.MediaPlayerState.PREPARED);
    }
    
    private void checkPreparedStateAfterStop() {
        callMediaPlayerMethodUnderTestInState(MediaPlayerStateErrors.MediaPlayerState.PREPARED_AFTER_STOP);
    }
    
    private void checkStartedState() {
        callMediaPlayerMethodUnderTestInState(MediaPlayerStateErrors.MediaPlayerState.STARTED);
    }
    
    private void checkPausedState() {
        callMediaPlayerMethodUnderTestInState(MediaPlayerStateErrors.MediaPlayerState.PAUSED);
    }
    
    private void checkStartedStateAfterPause() {
        callMediaPlayerMethodUnderTestInState(MediaPlayerStateErrors.MediaPlayerState.STARTED_AFTER_PAUSE);
    }
    
    private void checkStoppedState() {
        callMediaPlayerMethodUnderTestInState(MediaPlayerStateErrors.MediaPlayerState.STOPPED);
    }
    
    private void checkPlaybackCompletedState() {
        callMediaPlayerMethodUnderTestInState(MediaPlayerStateErrors.MediaPlayerState.PLAYBACK_COMPLETED);
    }
    
    private void checkErrorState() {
        callMediaPlayerMethodUnderTestInState(MediaPlayerStateErrors.MediaPlayerState.ERROR);
    }

    /*
     * Checks the given method under test in all possible states of the MediaPlayer object.
     */
    private void checkMethodUnderTestInAllPossibleStates() {
        // Must be called first.
        checkIdleState(); 
        
        // The sequence of the following method calls should not 
        // affect the test results.
        checkErrorState();
        checkIdleStateAfterReset();
        checkInitializedState();
        checkStartedState();
        checkStartedStateAfterPause();
        checkPausedState();
        checkPreparedState();
        
        checkPreparedStateAfterStop();
        
        checkPlaybackCompletedState();
        checkStoppedState();
    }
    
    /*
     * Terminates the message looper thread.
     */
    private void terminateMessageLooper() {
        mLooper.quit();
        mMediaPlayer.release();
    }
    
    /*
     * Cleans up all the internal object references.
     */
    private void cleanUp() {
        mMediaPlayer = null;
        mMediaPlayerState = null;
        mLooper = null;
        mStateErrors = null;
        mMethodUnderTest = null;
    }
}

Other Android examples (source code examples)

Here is a short list of links related to this Android MediaPlayerStateUnitTestTemplate.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.