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