1package com.xtremelabs.robolectric.shadows;
2
3import android.content.Context;
4import android.media.MediaPlayer;
5import android.net.Uri;
6
7import com.xtremelabs.robolectric.internal.Implementation;
8import com.xtremelabs.robolectric.internal.Implements;
9import com.xtremelabs.robolectric.internal.RealObject;
10
11import static com.xtremelabs.robolectric.Robolectric.shadowOf;
12
13/**
14 * Shadows the Android {@code MediaPlayer} class.
15 */
16@Implements(MediaPlayer.class)
17public class ShadowMediaPlayer {
18
19	@RealObject private MediaPlayer player;
20
21	private boolean playing;
22	private boolean prepared;
23	private int currentPosition;
24	private Uri sourceUri;
25	private int sourceResId;
26	private MediaPlayer.OnCompletionListener completionListener;
27	private MediaPlayer.OnPreparedListener preparedListener;
28
29	@Implementation
30	public static MediaPlayer create(Context context, int resId) {
31		MediaPlayer mp = new MediaPlayer();
32		shadowOf(mp).sourceResId = resId;
33		try {
34			mp.prepare();
35		} catch (Exception e) { return null; }
36
37		return mp;
38	}
39
40	@Implementation
41	public static MediaPlayer create(Context context, Uri uri) {
42		MediaPlayer mp = new MediaPlayer();
43		try {
44			mp.setDataSource(context, uri);
45			mp.prepare();
46		} catch (Exception e) { return null; }
47
48		return mp;
49	}
50
51	public void __constructor__() {
52		playing = true;
53	}
54
55	@Implementation
56	public void	setDataSource(Context context, Uri uri) {
57		this.sourceUri = uri;
58	}
59
60	@Implementation
61	public void setOnCompletionListener(MediaPlayer.OnCompletionListener listener) {
62		completionListener = listener;
63	}
64
65	@Implementation
66	public void setOnPreparedListener(MediaPlayer.OnPreparedListener listener) {
67		preparedListener = listener;
68	}
69
70	@Implementation
71	public boolean isPlaying() {
72		return playing;
73	}
74
75	@Implementation
76	public void prepare() {
77		prepared = true;
78		invokePreparedListener();
79	}
80
81	/**
82	 * Test cases are expected to simulate completion of the 'prepare' phase
83	 * by manually invoking {@code #invokePreparedListener}.
84	 */
85	@Implementation
86	public void prepareAsync() {
87		prepared = true;
88	}
89
90	@Implementation
91	public void start() {
92		playing = true;
93	}
94
95	@Implementation
96	public void pause() {
97		playing = false;
98	}
99
100	@Implementation
101	public void release() {
102		playing = false;
103		prepared = false;
104	}
105
106	@Implementation
107	public void reset() {
108		playing = false;
109		prepared = false;
110	}
111
112	@Implementation
113	public void stop() {
114		playing = false;
115	}
116
117	@Implementation
118    public int getCurrentPosition() {
119        return currentPosition;
120    }
121
122    public void setCurrentPosition(int position) {
123        currentPosition = position;
124    }
125
126    /**
127     * Non-Android accessor.  Use for assertions.
128     * @return
129     */
130    public Uri getSourceUri() {
131    	return sourceUri;
132    }
133
134    /**
135     * Non-Android accessor.  Use for assertions.
136     * @return
137     */
138    public int getSourceResId() {
139    	return sourceResId;
140    }
141
142    /**
143     * Non-Android accessor.  Use for assertions.
144     * @return
145     */
146    public boolean isPrepared() {
147    	return prepared;
148    }
149
150    /**
151     * Non-Android accessor.  Use for assertions.
152     * @return
153     */
154    public MediaPlayer.OnCompletionListener getOnCompletionListener() {
155    	return completionListener;
156    }
157
158    /**
159     * Non-Android accessor.  Use for assertions.
160     * @return
161     */
162    public MediaPlayer.OnPreparedListener getOnPreparedListener() {
163    	return preparedListener;
164    }
165
166    /**
167     * Allows test cases to simulate 'prepared' state by invoking callback.
168     */
169    public void invokePreparedListener() {
170    	if (preparedListener == null) return;
171    	preparedListener.onPrepared( player );
172    }
173
174    /**
175     * Allows test cases to simulate 'completed' state by invoking callback.
176     */
177    public void invokeCompletionListener() {
178    	if (completionListener == null) return;
179    	completionListener.onCompletion( player );
180    }
181}
182