1 // Copyright 2012 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.
5 package org.chromium.media;
7 import android.content.Context;
8 import android.media.AudioManager;
9 import android.media.MediaPlayer;
11 import org.chromium.base.CalledByNative;
12 import org.chromium.base.JNINamespace;
14 // This class implements all the listener interface for android mediaplayer.
15 // Callbacks will be sent to the native class for processing.
16 @JNINamespace("media")
17 class MediaPlayerListener implements MediaPlayer.OnPreparedListener,
18 MediaPlayer.OnCompletionListener,
19 MediaPlayer.OnBufferingUpdateListener,
20 MediaPlayer.OnSeekCompleteListener,
21 MediaPlayer.OnVideoSizeChangedListener,
22 MediaPlayer.OnErrorListener,
23 AudioManager.OnAudioFocusChangeListener {
24 // These values are mirrored as enums in media/base/android/media_player_bridge.h.
25 // Please ensure they stay in sync.
26 private static final int MEDIA_ERROR_FORMAT = 0;
27 private static final int MEDIA_ERROR_DECODE = 1;
28 private static final int MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK = 2;
29 private static final int MEDIA_ERROR_INVALID_CODE = 3;
31 // These values are copied from android media player.
32 public static final int MEDIA_ERROR_MALFORMED = -1007;
33 public static final int MEDIA_ERROR_TIMED_OUT = -110;
35 // Used to determine the class instance to dispatch the native call to.
36 private long mNativeMediaPlayerListener = 0;
37 private final Context mContext;
39 private MediaPlayerListener(long nativeMediaPlayerListener, Context context) {
40 mNativeMediaPlayerListener = nativeMediaPlayerListener;
45 public boolean onError(MediaPlayer mp, int what, int extra) {
48 case MediaPlayer.MEDIA_ERROR_UNKNOWN:
50 case MEDIA_ERROR_MALFORMED:
51 errorType = MEDIA_ERROR_DECODE;
53 case MEDIA_ERROR_TIMED_OUT:
54 errorType = MEDIA_ERROR_INVALID_CODE;
57 errorType = MEDIA_ERROR_FORMAT;
61 case MediaPlayer.MEDIA_ERROR_SERVER_DIED:
62 errorType = MEDIA_ERROR_DECODE;
64 case MediaPlayer.MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK:
65 errorType = MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK;
68 // There are some undocumented error codes for android media player.
69 // For example, when surfaceTexture got deleted before we setVideoSuface
70 // to NULL, mediaplayer will report error -38. These errors should be ignored
71 // and not be treated as an error to webkit.
72 errorType = MEDIA_ERROR_INVALID_CODE;
75 nativeOnMediaError(mNativeMediaPlayerListener, errorType);
80 public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
81 nativeOnVideoSizeChanged(mNativeMediaPlayerListener, width, height);
85 public void onSeekComplete(MediaPlayer mp) {
86 nativeOnSeekComplete(mNativeMediaPlayerListener);
90 public void onBufferingUpdate(MediaPlayer mp, int percent) {
91 nativeOnBufferingUpdate(mNativeMediaPlayerListener, percent);
95 public void onCompletion(MediaPlayer mp) {
96 nativeOnPlaybackComplete(mNativeMediaPlayerListener);
100 public void onPrepared(MediaPlayer mp) {
101 nativeOnMediaPrepared(mNativeMediaPlayerListener);
105 public void onAudioFocusChange(int focusChange) {
106 if (focusChange == AudioManager.AUDIOFOCUS_LOSS ||
107 focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT) {
108 nativeOnMediaInterrupted(mNativeMediaPlayerListener);
113 public void releaseResources() {
114 if (mContext != null) {
115 // Unregister the wish for audio focus.
116 AudioManager am = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
118 am.abandonAudioFocus(this);
124 private static MediaPlayerListener create(long nativeMediaPlayerListener,
125 Context context, MediaPlayerBridge mediaPlayerBridge) {
126 final MediaPlayerListener listener =
127 new MediaPlayerListener(nativeMediaPlayerListener, context);
128 if (mediaPlayerBridge != null) {
129 mediaPlayerBridge.setOnBufferingUpdateListener(listener);
130 mediaPlayerBridge.setOnCompletionListener(listener);
131 mediaPlayerBridge.setOnErrorListener(listener);
132 mediaPlayerBridge.setOnPreparedListener(listener);
133 mediaPlayerBridge.setOnSeekCompleteListener(listener);
134 mediaPlayerBridge.setOnVideoSizeChangedListener(listener);
137 AudioManager am = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
138 am.requestAudioFocus(
140 AudioManager.STREAM_MUSIC,
142 // Request permanent focus.
143 AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK);
148 * See media/base/android/media_player_listener.cc for all the following functions.
150 private native void nativeOnMediaError(
151 long nativeMediaPlayerListener,
154 private native void nativeOnVideoSizeChanged(
155 long nativeMediaPlayerListener,
156 int width, int height);
158 private native void nativeOnBufferingUpdate(
159 long nativeMediaPlayerListener,
162 private native void nativeOnMediaPrepared(long nativeMediaPlayerListener);
164 private native void nativeOnPlaybackComplete(long nativeMediaPlayerListener);
166 private native void nativeOnSeekComplete(long nativeMediaPlayerListener);
168 private native void nativeOnMediaInterrupted(long nativeMediaPlayerListener);