media_player_bridge.h revision 23730a6e56a168d1879203e4b3819bb36e3d8f1f
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef MEDIA_BASE_ANDROID_MEDIA_PLAYER_BRIDGE_H_ 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MEDIA_BASE_ANDROID_MEDIA_PLAYER_BRIDGE_H_ 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <jni.h> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <map> 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/android/scoped_java_ref.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/weak_ptr.h" 16eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h" 17eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/timer/timer.h" 18b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "media/base/android/media_player_android.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/base/android/media_player_listener.h" 207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "url/gurl.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace media { 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class MediaPlayerManager; 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// This class serves as a bridge between the native code and Android MediaPlayer 277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// Java class. For more information on Android MediaPlayer, check 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// http://developer.android.com/reference/android/media/MediaPlayer.html 297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// The actual Android MediaPlayer instance is created lazily when Start(), 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Pause(), SeekTo() gets called. As a result, media information may not 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// be available until one of those operations is performed. After that, we 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// will cache those information in case the mediaplayer gets released. 337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// The class uses the corresponding MediaPlayerBridge Java class to talk to 347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// the Android MediaPlayer instance. 35b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)class MEDIA_EXPORT MediaPlayerBridge : public MediaPlayerAndroid { 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static bool RegisterMediaPlayerBridge(JNIEnv* env); 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Construct a MediaPlayerBridge object. This object needs to call |manager|'s 407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // RequestMediaResources() before decoding the media stream. This allows 417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // |manager| to track unused resources and free them when needed. On the other 427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // hand, it needs to call ReleaseMediaResources() when it is done with 437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // decoding. MediaPlayerBridge also forwards Android MediaPlayer callbacks to 447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // the |manager| when needed. 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MediaPlayerBridge(int player_id, 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GURL& url, 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GURL& first_party_for_cookies, 485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& user_agent, 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool hide_url_log, 50a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) MediaPlayerManager* manager, 51a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const RequestMediaResourcesCB& request_media_resources_cb, 52a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const ReleaseMediaResourcesCB& release_media_resources_cb); 53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual ~MediaPlayerBridge(); 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Initialize this object and extract the metadata from the media. 5690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) virtual void Initialize(); 5790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 58b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // MediaPlayerAndroid implementation. 59868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) virtual void SetVideoSurface(gfx::ScopedJavaSurface surface) OVERRIDE; 60b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) virtual void Start() OVERRIDE; 61d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) virtual void Pause(bool is_media_related_action ALLOW_UNUSED) OVERRIDE; 6223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) virtual void SeekTo(base::TimeDelta timestamp) OVERRIDE; 63b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) virtual void Release() OVERRIDE; 64a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) virtual void SetVolume(double volume) OVERRIDE; 65b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) virtual int GetVideoWidth() OVERRIDE; 66b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) virtual int GetVideoHeight() OVERRIDE; 67b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) virtual base::TimeDelta GetCurrentTime() OVERRIDE; 68b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) virtual base::TimeDelta GetDuration() OVERRIDE; 69b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) virtual bool IsPlaying() OVERRIDE; 70b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) virtual bool CanPause() OVERRIDE; 71b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) virtual bool CanSeekForward() OVERRIDE; 72b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) virtual bool CanSeekBackward() OVERRIDE; 73b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) virtual bool IsPlayerReady() OVERRIDE; 74868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) virtual GURL GetUrl() OVERRIDE; 75868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) virtual GURL GetFirstPartyForCookies() OVERRIDE; 76a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) virtual bool IsSurfaceInUse() const OVERRIDE; 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // MediaPlayerListener callbacks. 7968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) void OnVideoSizeChanged(int width, int height); 8068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) void OnMediaError(int error_type); 8168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) void OnBufferingUpdate(int percent); 8268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) void OnPlaybackComplete(); 8368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) void OnMediaInterrupted(); 8468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) void OnSeekComplete(); 85a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) void OnDidSetDataUriDataSource(JNIEnv* env, jobject obj, jboolean success); 8668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 87b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) protected: 887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch void SetJavaMediaPlayerBridge(jobject j_media_player_bridge); 890f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) base::android::ScopedJavaLocalRef<jobject> GetJavaMediaPlayerBridge(); 90b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) void SetMediaPlayerListener(); 91868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) void SetDuration(base::TimeDelta time); 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) virtual void PendingSeekInternal(const base::TimeDelta& time); 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Prepare the player for playback, asynchronously. When succeeds, 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // OnMediaPrepared() will be called. Otherwise, OnMediaError() will 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // be called with an error type. 98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void Prepare(); 99b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) void OnMediaPrepared(); 100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Create the corresponding Java class instance. 1027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch virtual void CreateJavaMediaPlayerBridge(); 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1040f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // Get allowed operations from the player. 1050f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) virtual base::android::ScopedJavaLocalRef<jobject> GetAllowedOperations(); 1060f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 107868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) private: 10823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) friend class MediaPlayerListener; 10923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Set the data source for the media player. 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void SetDataSource(const std::string& url); 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Functions that implements media player control. 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void StartInternal(); 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void PauseInternal(); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SeekInternal(base::TimeDelta time); 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Called when |time_update_timer_| fires. 11968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) void OnTimeUpdateTimerFired(); 12068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 1210f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // Update allowed operations from the player. 1220f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) void UpdateAllowedOperations(); 123b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 124b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // Callback function passed to |resource_getter_|. Called when the cookies 125b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // are retrieved. 126b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) void OnCookiesRetrieved(const std::string& cookies); 127b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Extract the media metadata from a url, asynchronously. 129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // OnMediaMetadataExtracted() will be called when this call finishes. 130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void ExtractMediaMetadata(const std::string& url); 131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void OnMediaMetadataExtracted(base::TimeDelta duration, int width, int height, 132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool success); 133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Whether the player is prepared for playback. 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool prepared_; 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Pending play event while player is preparing. 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool pending_play_; 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Pending seek time while player is preparing. 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta pending_seek_; 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Url for playback. 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GURL url_; 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // First party url for cookies. 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GURL first_party_for_cookies_; 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // User agent string to be used for media player. 1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string user_agent_; 1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Hide url log from media player. 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool hide_url_log_; 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Stats about the media. 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta duration_; 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int width_; 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int height_; 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Meta data about actions can be taken. 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool can_pause_; 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool can_seek_forward_; 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool can_seek_backward_; 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Cookies for |url_|. 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string cookies_; 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Java MediaPlayerBridge instance. 1697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch base::android::ScopedJavaGlobalRef<jobject> j_media_player_bridge_; 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::RepeatingTimer<MediaPlayerBridge> time_update_timer_; 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Listener object that listens to all the media player events. 17423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) scoped_ptr<MediaPlayerListener> listener_; 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 176a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Whether player is currently using a surface. 177a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool is_surface_in_use_; 178a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 17923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // Weak pointer passed to |listener_| for callbacks. 18023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // NOTE: Weak pointers must be invalidated before all other member variables. 18123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) base::WeakPtrFactory<MediaPlayerBridge> weak_factory_; 18223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(MediaPlayerBridge); 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace media 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // MEDIA_BASE_ANDROID_MEDIA_PLAYER_BRIDGE_H_ 189