/chrome/test/android/cast_emulator/src/org/chromium/chrome/browser/media/remote/DummyPlayer.java

https://gitlab.com/0072016/Facebook-SDK- · Java · 236 lines · 193 code · 25 blank · 18 comment · 47 complexity · 9b25715932aead7e50e562bd3ac0fc54 MD5 · raw file

  1. // Copyright 2014 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. package org.chromium.chrome.browser.media.remote;
  5. import android.content.Context;
  6. import android.media.MediaPlayer;
  7. import android.os.Handler;
  8. import android.os.SystemClock;
  9. import android.support.v7.media.MediaItemStatus;
  10. import android.support.v7.media.MediaRouter.RouteInfo;
  11. import org.chromium.base.Log;
  12. import java.io.IOException;
  13. /**
  14. * Handles playback of a single media item using MediaPlayer.
  15. */
  16. public class DummyPlayer implements MediaPlayer.OnPreparedListener,
  17. MediaPlayer.OnCompletionListener, MediaPlayer.OnErrorListener,
  18. MediaPlayer.OnSeekCompleteListener {
  19. private static final String TAG = "CastEmulator";
  20. private static final int STATE_IDLE = 0;
  21. private static final int STATE_PLAY_PENDING = 1;
  22. private static final int STATE_READY = 2;
  23. private static final int STATE_PLAYING = 3;
  24. private static final int STATE_PAUSED = 4;
  25. private final Context mContext;
  26. private final Handler mHandler = new Handler();
  27. private MediaPlayer mMediaPlayer;
  28. private int mState = STATE_IDLE;
  29. private int mSeekToPos;
  30. private Callback mCallback;
  31. /**
  32. * Callback interface for the session manager
  33. */
  34. public static interface Callback {
  35. void onError();
  36. void onCompletion();
  37. void onSeekComplete();
  38. void onPrepared();
  39. }
  40. public DummyPlayer(Context context) {
  41. // reset media player
  42. reset();
  43. mContext = context;
  44. }
  45. public void connect(RouteInfo route) {
  46. Log.v(TAG, "connecting to: %s", route);
  47. }
  48. public void release() {
  49. Log.v(TAG, "releasing");
  50. // release media player
  51. if (mMediaPlayer != null) {
  52. mMediaPlayer.stop();
  53. mMediaPlayer.release();
  54. mMediaPlayer = null;
  55. }
  56. }
  57. // Player
  58. public void play(final MediaItem item) {
  59. Log.v(TAG, "play: item=%s", item);
  60. reset();
  61. mSeekToPos = (int) item.getPosition();
  62. try {
  63. mMediaPlayer.setDataSource(mContext, item.getUri());
  64. mMediaPlayer.prepare();
  65. } catch (IllegalStateException e) {
  66. Log.e(TAG, "MediaPlayer throws IllegalStateException, uri=%s", item.getUri());
  67. } catch (IOException e) {
  68. Log.e(TAG, "MediaPlayer throws IOException, uri=%s", item.getUri());
  69. } catch (IllegalArgumentException e) {
  70. Log.e(TAG, "MediaPlayer throws IllegalArgumentException, uri=%s", item.getUri());
  71. } catch (SecurityException e) {
  72. Log.e(TAG, "MediaPlayer throws SecurityException, uri=%s", item.getUri());
  73. }
  74. if (item.getState() == MediaItemStatus.PLAYBACK_STATE_PLAYING) {
  75. resume();
  76. } else {
  77. pause();
  78. }
  79. }
  80. public void seek(final MediaItem item) {
  81. Log.v(TAG, "seek: item=%s", item);
  82. int pos = (int) item.getPosition();
  83. if (mState == STATE_PLAYING || mState == STATE_PAUSED) {
  84. mMediaPlayer.seekTo(pos);
  85. mSeekToPos = pos;
  86. } else if (mState == STATE_IDLE || mState == STATE_PLAY_PENDING) {
  87. // Seek before onPrepared() arrives,
  88. // need to performed delayed seek in onPrepared()
  89. mSeekToPos = pos;
  90. }
  91. }
  92. public void getStatus(final MediaItem item, final boolean update) {
  93. if (mState == STATE_PLAYING || mState == STATE_PAUSED) {
  94. // use mSeekToPos if we're currently seeking (mSeekToPos is reset
  95. // when seeking is completed)
  96. item.setDuration(mMediaPlayer.getDuration());
  97. item.setPosition(mSeekToPos > 0 ? mSeekToPos : mMediaPlayer.getCurrentPosition());
  98. item.setTimestamp(SystemClock.uptimeMillis());
  99. }
  100. }
  101. public void pause() {
  102. Log.v(TAG, "pause");
  103. if (mState == STATE_PLAYING) {
  104. mMediaPlayer.pause();
  105. mState = STATE_PAUSED;
  106. }
  107. }
  108. public void resume() {
  109. Log.v(TAG, "resume");
  110. if (mState == STATE_READY || mState == STATE_PAUSED) {
  111. mMediaPlayer.start();
  112. mState = STATE_PLAYING;
  113. } else if (mState == STATE_IDLE) {
  114. mState = STATE_PLAY_PENDING;
  115. }
  116. }
  117. public void stop() {
  118. Log.v(TAG, "stop");
  119. if (mState == STATE_PLAYING || mState == STATE_PAUSED) {
  120. mMediaPlayer.stop();
  121. mState = STATE_IDLE;
  122. }
  123. }
  124. // MediaPlayer Listeners
  125. @Override
  126. public void onPrepared(MediaPlayer mp) {
  127. Log.v(TAG, "onPrepared");
  128. mHandler.post(new Runnable() {
  129. @Override
  130. public void run() {
  131. if (mState == STATE_IDLE) {
  132. mState = STATE_READY;
  133. } else if (mState == STATE_PLAY_PENDING) {
  134. mState = STATE_PLAYING;
  135. if (mSeekToPos > 0) {
  136. Log.v(TAG, "seek to initial pos: %d", mSeekToPos);
  137. mMediaPlayer.seekTo(mSeekToPos);
  138. }
  139. mMediaPlayer.start();
  140. }
  141. if (mCallback != null) {
  142. mCallback.onPrepared();
  143. }
  144. }
  145. });
  146. }
  147. @Override
  148. public void onCompletion(MediaPlayer mp) {
  149. Log.v(TAG, "onCompletion");
  150. mHandler.post(new Runnable() {
  151. @Override
  152. public void run() {
  153. if (mCallback != null) {
  154. mCallback.onCompletion();
  155. }
  156. }
  157. });
  158. }
  159. @Override
  160. public boolean onError(MediaPlayer mp, int what, int extra) {
  161. Log.v(TAG, "onError");
  162. mHandler.post(new Runnable() {
  163. @Override
  164. public void run() {
  165. if (mCallback != null) {
  166. mCallback.onError();
  167. }
  168. }
  169. });
  170. // return true so that onCompletion is not called
  171. return true;
  172. }
  173. @Override
  174. public void onSeekComplete(MediaPlayer mp) {
  175. Log.v(TAG, "onSeekComplete");
  176. mHandler.post(new Runnable() {
  177. @Override
  178. public void run() {
  179. mSeekToPos = 0;
  180. if (mCallback != null) {
  181. mCallback.onSeekComplete();
  182. }
  183. }
  184. });
  185. }
  186. protected Context getContext() {
  187. return mContext;
  188. }
  189. private void reset() {
  190. if (mMediaPlayer != null) {
  191. mMediaPlayer.stop();
  192. mMediaPlayer.release();
  193. mMediaPlayer = null;
  194. }
  195. mMediaPlayer = new MediaPlayer();
  196. mMediaPlayer.setOnPreparedListener(this);
  197. mMediaPlayer.setOnCompletionListener(this);
  198. mMediaPlayer.setOnErrorListener(this);
  199. mMediaPlayer.setOnSeekCompleteListener(this);
  200. mState = STATE_IDLE;
  201. mSeekToPos = 0;
  202. }
  203. public void setCallback(Callback callback) {
  204. mCallback = callback;
  205. }
  206. public static DummyPlayer create(Context context, RouteInfo route) {
  207. DummyPlayer player = new DummyPlayer(context);
  208. player.connect(route);
  209. return player;
  210. }
  211. }