1 // Copyright (c) 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.Manifest.permission;
8 import android.content.Context;
9 import android.content.pm.PackageManager;
10 import android.media.AudioManager;
11 import android.media.MediaPlayer;
13 import org.chromium.base.CalledByNative;
14 import org.chromium.base.JNINamespace;
16 // This class implements all the listener interface for android mediaplayer.
17 // Callbacks will be sent to the native class for processing.
18 @JNINamespace("media")
19 class MediaPlayerListener implements MediaPlayer.OnPreparedListener,
20 MediaPlayer.OnCompletionListener,
21 MediaPlayer.OnBufferingUpdateListener,
22 MediaPlayer.OnSeekCompleteListener,
23 MediaPlayer.OnVideoSizeChangedListener,
24 MediaPlayer.OnErrorListener,
25 AudioManager.OnAudioFocusChangeListener {
26 // These values are mirrored as enums in media/base/android/media_player_bridge.h.
27 // Please ensure they stay in sync.
28 private static final int MEDIA_ERROR_FORMAT = 0;
29 private static final int MEDIA_ERROR_DECODE = 1;
30 private static final int MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK = 2;
31 private static final int MEDIA_ERROR_INVALID_CODE = 3;
33 // These values are copied from android media player.
34 public static final int MEDIA_ERROR_MALFORMED = -1007;
35 public static final int MEDIA_ERROR_TIMED_OUT = -110;
37 // Used to determine the class instance to dispatch the native call to.
38 private int mNativeMediaPlayerListener = 0;
39 private final Context mContext;
41 private MediaPlayerListener(int nativeMediaPlayerListener, Context context) {
42 mNativeMediaPlayerListener = nativeMediaPlayerListener;
47 public boolean onError(MediaPlayer mp, int what, int extra) {
50 case MediaPlayer.MEDIA_ERROR_UNKNOWN:
52 case MEDIA_ERROR_MALFORMED:
53 errorType = MEDIA_ERROR_DECODE;
55 case MEDIA_ERROR_TIMED_OUT:
56 errorType = MEDIA_ERROR_INVALID_CODE;
59 errorType = MEDIA_ERROR_FORMAT;
63 case MediaPlayer.MEDIA_ERROR_SERVER_DIED:
64 errorType = MEDIA_ERROR_DECODE;
66 case MediaPlayer.MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK:
67 errorType = MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK;
70 // There are some undocumented error codes for android media player.
71 // For example, when surfaceTexture got deleted before we setVideoSuface
72 // to NULL, mediaplayer will report error -38. These errors should be ignored
73 // and not be treated as an error to webkit.
74 errorType = MEDIA_ERROR_INVALID_CODE;
77 nativeOnMediaError(mNativeMediaPlayerListener, errorType);
82 public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
83 nativeOnVideoSizeChanged(mNativeMediaPlayerListener, width, height);
87 public void onSeekComplete(MediaPlayer mp) {
88 nativeOnSeekComplete(mNativeMediaPlayerListener);
92 public void onBufferingUpdate(MediaPlayer mp, int percent) {
93 nativeOnBufferingUpdate(mNativeMediaPlayerListener, percent);
97 public void onCompletion(MediaPlayer mp) {
98 nativeOnPlaybackComplete(mNativeMediaPlayerListener);
102 public void onPrepared(MediaPlayer mp) {
103 nativeOnMediaPrepared(mNativeMediaPlayerListener);
107 public void onAudioFocusChange(int focusChange) {
108 if (focusChange == AudioManager.AUDIOFOCUS_LOSS ||
109 focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT) {
110 nativeOnMediaInterrupted(mNativeMediaPlayerListener);
115 public void releaseResources() {
116 if (mContext != null) {
117 // Unregister the wish for audio focus.
118 AudioManager am = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
120 am.abandonAudioFocus(this);
126 private static MediaPlayerListener create(int nativeMediaPlayerListener,
127 Context context, MediaPlayerBridge mediaPlayerBridge) {
128 final MediaPlayerListener listener =
129 new MediaPlayerListener(nativeMediaPlayerListener, context);
130 mediaPlayerBridge.setOnBufferingUpdateListener(listener);
131 mediaPlayerBridge.setOnCompletionListener(listener);
132 mediaPlayerBridge.setOnErrorListener(listener);
133 mediaPlayerBridge.setOnPreparedListener(listener);
134 mediaPlayerBridge.setOnSeekCompleteListener(listener);
135 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 int nativeMediaPlayerListener,
154 private native void nativeOnVideoSizeChanged(
155 int nativeMediaPlayerListener,
156 int width, int height);
158 private native void nativeOnBufferingUpdate(
159 int nativeMediaPlayerListener,
162 private native void nativeOnMediaPrepared(int nativeMediaPlayerListener);
164 private native void nativeOnPlaybackComplete(int nativeMediaPlayerListener);
166 private native void nativeOnSeekComplete(int nativeMediaPlayerListener);
168 private native void nativeOnMediaInterrupted(int nativeMediaPlayerListener);