Home | History | Annotate | Download | only in android
      1 // Copyright 2013 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 
      5 #ifndef CONTENT_RENDERER_MEDIA_ANDROID_WEBMEDIAPLAYER_ANDROID_H_
      6 #define CONTENT_RENDERER_MEDIA_ANDROID_WEBMEDIAPLAYER_ANDROID_H_
      7 
      8 #include <jni.h>
      9 #include <string>
     10 #include <vector>
     11 
     12 #include "base/basictypes.h"
     13 #include "base/memory/ref_counted.h"
     14 #include "base/memory/scoped_ptr.h"
     15 #include "base/memory/weak_ptr.h"
     16 #include "base/time/time.h"
     17 #include "cc/layers/video_frame_provider.h"
     18 #include "content/common/media/media_player_messages_enums_android.h"
     19 #include "content/public/renderer/render_frame_observer.h"
     20 #include "content/renderer/media/android/media_info_loader.h"
     21 #include "content/renderer/media/android/media_source_delegate.h"
     22 #include "content/renderer/media/android/stream_texture_factory.h"
     23 #include "content/renderer/media/crypto/proxy_decryptor.h"
     24 #include "gpu/command_buffer/common/mailbox.h"
     25 #include "media/base/android/media_player_android.h"
     26 #include "media/base/demuxer_stream.h"
     27 #include "media/base/media_keys.h"
     28 #include "third_party/WebKit/public/platform/WebGraphicsContext3D.h"
     29 #include "third_party/WebKit/public/platform/WebMediaPlayer.h"
     30 #include "third_party/WebKit/public/platform/WebSize.h"
     31 #include "third_party/WebKit/public/platform/WebURL.h"
     32 #include "ui/gfx/rect_f.h"
     33 
     34 namespace base {
     35 class MessageLoopProxy;
     36 }
     37 
     38 namespace blink {
     39 class WebContentDecryptionModule;
     40 class WebFrame;
     41 class WebURL;
     42 }
     43 
     44 namespace gpu {
     45 struct MailboxHolder;
     46 }
     47 
     48 namespace media {
     49 class MediaLog;
     50 }
     51 
     52 namespace content {
     53 class RendererCdmManager;
     54 class RendererMediaPlayerManager;
     55 class WebContentDecryptionModuleImpl;
     56 class WebLayerImpl;
     57 class WebMediaPlayerDelegate;
     58 
     59 // This class implements blink::WebMediaPlayer by keeping the android
     60 // media player in the browser process. It listens to all the status changes
     61 // sent from the browser process and sends playback controls to the media
     62 // player.
     63 class WebMediaPlayerAndroid : public blink::WebMediaPlayer,
     64                               public cc::VideoFrameProvider,
     65                               public RenderFrameObserver,
     66                               public StreamTextureFactoryContextObserver {
     67  public:
     68   // Construct a WebMediaPlayerAndroid object. This class communicates with the
     69   // MediaPlayerAndroid object in the browser process through |proxy|.
     70   // TODO(qinmin): |frame| argument is used to determine whether the current
     71   // player can enter fullscreen. This logic should probably be moved into
     72   // blink, so that enterFullscreen() will not be called if another video is
     73   // already in fullscreen.
     74   WebMediaPlayerAndroid(blink::WebFrame* frame,
     75                         blink::WebMediaPlayerClient* client,
     76                         base::WeakPtr<WebMediaPlayerDelegate> delegate,
     77                         RendererMediaPlayerManager* player_manager,
     78                         RendererCdmManager* cdm_manager,
     79                         scoped_refptr<StreamTextureFactory> factory,
     80                         const scoped_refptr<base::MessageLoopProxy>& media_loop,
     81                         media::MediaLog* media_log);
     82   virtual ~WebMediaPlayerAndroid();
     83 
     84   // blink::WebMediaPlayer implementation.
     85   virtual void enterFullscreen();
     86   virtual void exitFullscreen();
     87   virtual bool canEnterFullscreen() const;
     88 
     89   // Resource loading.
     90   virtual void load(LoadType load_type,
     91                     const blink::WebURL& url,
     92                     CORSMode cors_mode);
     93 
     94   // Playback controls.
     95   virtual void play();
     96   virtual void pause();
     97   virtual void seek(double seconds);
     98   virtual bool supportsSave() const;
     99   virtual void setRate(double rate);
    100   virtual void setVolume(double volume);
    101   virtual blink::WebTimeRanges buffered() const;
    102   virtual double maxTimeSeekable() const;
    103 
    104   // Poster image, as defined in the <video> element.
    105   virtual void setPoster(const blink::WebURL& poster) OVERRIDE;
    106 
    107   // Methods for painting.
    108   virtual void paint(blink::WebCanvas* canvas,
    109                      const blink::WebRect& rect,
    110                      unsigned char alpha);
    111 
    112   virtual bool copyVideoTextureToPlatformTexture(
    113       blink::WebGraphicsContext3D* web_graphics_context,
    114       unsigned int texture,
    115       unsigned int level,
    116       unsigned int internal_format,
    117       unsigned int type,
    118       bool premultiply_alpha,
    119       bool flip_y);
    120 
    121   // True if the loaded media has a playable video/audio track.
    122   virtual bool hasVideo() const;
    123   virtual bool hasAudio() const;
    124 
    125   // Dimensions of the video.
    126   virtual blink::WebSize naturalSize() const;
    127 
    128   // Getters of playback state.
    129   virtual bool paused() const;
    130   virtual bool seeking() const;
    131   virtual double duration() const;
    132   virtual double timelineOffset() const;
    133   virtual double currentTime() const;
    134 
    135   virtual bool didLoadingProgress();
    136 
    137   // Internal states of loading and network.
    138   virtual blink::WebMediaPlayer::NetworkState networkState() const;
    139   virtual blink::WebMediaPlayer::ReadyState readyState() const;
    140 
    141   virtual bool hasSingleSecurityOrigin() const;
    142   virtual bool didPassCORSAccessCheck() const;
    143 
    144   virtual double mediaTimeForTimeValue(double timeValue) const;
    145 
    146   // Provide statistics.
    147   virtual unsigned decodedFrameCount() const;
    148   virtual unsigned droppedFrameCount() const;
    149   virtual unsigned audioDecodedByteCount() const;
    150   virtual unsigned videoDecodedByteCount() const;
    151 
    152   // cc::VideoFrameProvider implementation. These methods are running on the
    153   // compositor thread.
    154   virtual void SetVideoFrameProviderClient(
    155       cc::VideoFrameProvider::Client* client) OVERRIDE;
    156   virtual scoped_refptr<media::VideoFrame> GetCurrentFrame() OVERRIDE;
    157   virtual void PutCurrentFrame(const scoped_refptr<media::VideoFrame>& frame)
    158       OVERRIDE;
    159 
    160   // Media player callback handlers.
    161   void OnMediaMetadataChanged(const base::TimeDelta& duration, int width,
    162                               int height, bool success);
    163   void OnPlaybackComplete();
    164   void OnBufferingUpdate(int percentage);
    165   void OnSeekRequest(const base::TimeDelta& time_to_seek);
    166   void OnSeekComplete(const base::TimeDelta& current_time);
    167   void OnMediaError(int error_type);
    168   void OnVideoSizeChanged(int width, int height);
    169   void OnDurationChanged(const base::TimeDelta& duration);
    170 
    171   // Called to update the current time.
    172   void OnTimeUpdate(const base::TimeDelta& current_time);
    173 
    174   // Functions called when media player status changes.
    175   void OnConnectedToRemoteDevice(const std::string& remote_playback_message);
    176   void OnDisconnectedFromRemoteDevice();
    177   void OnDidEnterFullscreen();
    178   void OnDidExitFullscreen();
    179   void OnMediaPlayerPlay();
    180   void OnMediaPlayerPause();
    181   void OnRequestFullscreen();
    182 
    183   // StreamTextureFactoryContextObserver implementation.
    184   virtual void ResetStreamTextureProxy() OVERRIDE;
    185 
    186   // Called when the player is released.
    187   virtual void OnPlayerReleased();
    188 
    189   // This function is called by the RendererMediaPlayerManager to pause the
    190   // video and release the media player and surface texture when we switch tabs.
    191   // However, the actual GlTexture is not released to keep the video screenshot.
    192   virtual void ReleaseMediaResources();
    193 
    194   // RenderFrameObserver implementation.
    195   virtual void OnDestruct() OVERRIDE;
    196 
    197 #if defined(VIDEO_HOLE)
    198   // Calculate the boundary rectangle of the media player (i.e. location and
    199   // size of the video frame).
    200   // Returns true if the geometry has been changed since the last call.
    201   bool UpdateBoundaryRectangle();
    202 
    203   const gfx::RectF GetBoundaryRectangle();
    204 #endif  // defined(VIDEO_HOLE)
    205 
    206   virtual MediaKeyException generateKeyRequest(
    207       const blink::WebString& key_system,
    208       const unsigned char* init_data,
    209       unsigned init_data_length);
    210   virtual MediaKeyException addKey(
    211       const blink::WebString& key_system,
    212       const unsigned char* key,
    213       unsigned key_length,
    214       const unsigned char* init_data,
    215       unsigned init_data_length,
    216       const blink::WebString& session_id);
    217   virtual MediaKeyException cancelKeyRequest(
    218       const blink::WebString& key_system,
    219       const blink::WebString& session_id);
    220   virtual void setContentDecryptionModule(
    221       blink::WebContentDecryptionModule* cdm);
    222 
    223   void OnKeyAdded(const std::string& session_id);
    224   void OnKeyError(const std::string& session_id,
    225                   media::MediaKeys::KeyError error_code,
    226                   uint32 system_code);
    227   void OnKeyMessage(const std::string& session_id,
    228                     const std::vector<uint8>& message,
    229                     const GURL& destination_url);
    230 
    231   void OnMediaSourceOpened(blink::WebMediaSource* web_media_source);
    232 
    233   void OnNeedKey(const std::string& type,
    234                  const std::vector<uint8>& init_data);
    235 
    236   // TODO(xhwang): Implement WebMediaPlayer::setContentDecryptionModule().
    237   // See: http://crbug.com/224786
    238 
    239  protected:
    240   // Helper method to update the playing state.
    241   void UpdatePlayingState(bool is_playing_);
    242 
    243   // Helper methods for posting task for setting states and update WebKit.
    244   void UpdateNetworkState(blink::WebMediaPlayer::NetworkState state);
    245   void UpdateReadyState(blink::WebMediaPlayer::ReadyState state);
    246   void TryCreateStreamTextureProxyIfNeeded();
    247   void DoCreateStreamTexture();
    248 
    249   // Helper method to reestablish the surface texture peer for android
    250   // media player.
    251   void EstablishSurfaceTexturePeer();
    252 
    253   // Requesting whether the surface texture peer needs to be reestablished.
    254   void SetNeedsEstablishPeer(bool needs_establish_peer);
    255 
    256  private:
    257   void InitializePlayer(const GURL& url,
    258                         const GURL& first_party_for_cookies,
    259                         bool allowed_stored_credentials,
    260                         int demuxer_client_id);
    261   void Pause(bool is_media_related_action);
    262   void DrawRemotePlaybackText(const std::string& remote_playback_message);
    263   void ReallocateVideoFrame();
    264   void SetCurrentFrameInternal(scoped_refptr<media::VideoFrame>& frame);
    265   void DidLoadMediaInfo(MediaInfoLoader::Status status,
    266                         const GURL& redirected_url,
    267                         const GURL& first_party_for_cookies,
    268                         bool allow_stored_credentials);
    269   bool IsKeySystemSupported(const std::string& key_system);
    270 
    271   // Actually do the work for generateKeyRequest/addKey so they can easily
    272   // report results to UMA.
    273   MediaKeyException GenerateKeyRequestInternal(const std::string& key_system,
    274                                                const unsigned char* init_data,
    275                                                unsigned init_data_length);
    276   MediaKeyException AddKeyInternal(const std::string& key_system,
    277                                    const unsigned char* key,
    278                                    unsigned key_length,
    279                                    const unsigned char* init_data,
    280                                    unsigned init_data_length,
    281                                    const std::string& session_id);
    282   MediaKeyException CancelKeyRequestInternal(const std::string& key_system,
    283                                              const std::string& session_id);
    284 
    285   // Requests that this object notifies when a decryptor is ready through the
    286   // |decryptor_ready_cb| provided.
    287   // If |decryptor_ready_cb| is null, the existing callback will be fired with
    288   // NULL immediately and reset.
    289   void SetDecryptorReadyCB(const media::DecryptorReadyCB& decryptor_ready_cb);
    290 
    291   blink::WebFrame* const frame_;
    292 
    293   blink::WebMediaPlayerClient* const client_;
    294 
    295   // |delegate_| is used to notify the browser process of the player status, so
    296   // that the browser process can control screen locks.
    297   // TODO(qinmin): Currently android mediaplayer takes care of the screen
    298   // lock. So this is only used for media source. Will apply this to regular
    299   // media tag once http://crbug.com/247892 is fixed.
    300   base::WeakPtr<WebMediaPlayerDelegate> delegate_;
    301 
    302   // Save the list of buffered time ranges.
    303   blink::WebTimeRanges buffered_;
    304 
    305   // Size of the video.
    306   blink::WebSize natural_size_;
    307 
    308   // Size that has been sent to StreamTexture.
    309   blink::WebSize cached_stream_texture_size_;
    310 
    311   // The video frame object used for rendering by the compositor.
    312   scoped_refptr<media::VideoFrame> current_frame_;
    313   base::Lock current_frame_lock_;
    314 
    315   base::ThreadChecker main_thread_checker_;
    316 
    317   // Message loop for media thread.
    318   const scoped_refptr<base::MessageLoopProxy> media_loop_;
    319 
    320   // URL of the media file to be fetched.
    321   GURL url_;
    322 
    323   // Media duration.
    324   base::TimeDelta duration_;
    325 
    326   // Flag to remember if we have a trusted duration_ value provided by
    327   // MediaSourceDelegate notifying OnDurationChanged(). In this case, ignore
    328   // any subsequent duration value passed to OnMediaMetadataChange().
    329   bool ignore_metadata_duration_change_;
    330 
    331   // Seek gets pending if another seek is in progress. Only last pending seek
    332   // will have effect.
    333   bool pending_seek_;
    334   base::TimeDelta pending_seek_time_;
    335 
    336   // Internal seek state.
    337   bool seeking_;
    338   base::TimeDelta seek_time_;
    339 
    340   // Whether loading has progressed since the last call to didLoadingProgress.
    341   bool did_loading_progress_;
    342 
    343   // Manages this object and delegates player calls to the browser process.
    344   // Owned by RenderFrameImpl.
    345   RendererMediaPlayerManager* player_manager_;
    346 
    347   // Delegates EME calls to the browser process. Owned by RenderFrameImpl.
    348   // TODO(xhwang): Remove |cdm_manager_| when prefixed EME is deprecated. See
    349   // http://crbug.com/249976
    350   RendererCdmManager* cdm_manager_;
    351 
    352   // Player ID assigned by the |player_manager_|.
    353   int player_id_;
    354 
    355   // Current player states.
    356   blink::WebMediaPlayer::NetworkState network_state_;
    357   blink::WebMediaPlayer::ReadyState ready_state_;
    358 
    359   // GL texture ID allocated to the video.
    360   unsigned int texture_id_;
    361 
    362   // GL texture mailbox for texture_id_ to provide in the VideoFrame, and sync
    363   // point for when the mailbox was produced.
    364   gpu::Mailbox texture_mailbox_;
    365 
    366   // Stream texture ID allocated to the video.
    367   unsigned int stream_id_;
    368 
    369   // Whether the mediaplayer is playing.
    370   bool is_playing_;
    371 
    372   // Whether media player needs to re-establish the surface texture peer.
    373   bool needs_establish_peer_;
    374 
    375   // Whether the video size info is available.
    376   bool has_size_info_;
    377 
    378   const scoped_refptr<base::MessageLoopProxy> compositor_loop_;
    379 
    380   // Object for allocating stream textures.
    381   scoped_refptr<StreamTextureFactory> stream_texture_factory_;
    382 
    383   // Object for calling back the compositor thread to repaint the video when a
    384   // frame available. It should be initialized on the compositor thread.
    385   // Accessed on main thread and on compositor thread when main thread is
    386   // blocked.
    387   ScopedStreamTextureProxy stream_texture_proxy_;
    388 
    389   // Whether media player needs external surface.
    390   // Only used for the VIDEO_HOLE logic.
    391   bool needs_external_surface_;
    392 
    393   // A pointer back to the compositor to inform it about state changes. This is
    394   // not NULL while the compositor is actively using this webmediaplayer.
    395   // Accessed on main thread and on compositor thread when main thread is
    396   // blocked.
    397   cc::VideoFrameProvider::Client* video_frame_provider_client_;
    398 
    399   scoped_ptr<WebLayerImpl> video_weblayer_;
    400 
    401 #if defined(VIDEO_HOLE)
    402   // A rectangle represents the geometry of video frame, when computed last
    403   // time.
    404   gfx::RectF last_computed_rect_;
    405 
    406   // Whether to use the video overlay for all embedded video.
    407   // True only for testing.
    408   bool force_use_overlay_embedded_video_;
    409 #endif  // defined(VIDEO_HOLE)
    410 
    411   scoped_ptr<MediaSourceDelegate,
    412              MediaSourceDelegate::Destroyer> media_source_delegate_;
    413 
    414   // Internal pending playback state.
    415   // Store a playback request that cannot be started immediately.
    416   bool pending_playback_;
    417 
    418   MediaPlayerHostMsg_Initialize_Type player_type_;
    419 
    420   // The current playing time. Because the media player is in the browser
    421   // process, it will regularly update the |current_time_| by calling
    422   // OnTimeUpdate().
    423   double current_time_;
    424 
    425   // Whether the browser is currently connected to a remote media player.
    426   bool is_remote_;
    427 
    428   media::MediaLog* media_log_;
    429 
    430   scoped_ptr<MediaInfoLoader> info_loader_;
    431 
    432   // The currently selected key system. Empty string means that no key system
    433   // has been selected.
    434   std::string current_key_system_;
    435 
    436   // Temporary for EME v0.1. In the future the init data type should be passed
    437   // through GenerateKeyRequest() directly from WebKit.
    438   std::string init_data_type_;
    439 
    440   // Manages decryption keys and decrypts encrypted frames.
    441   scoped_ptr<ProxyDecryptor> proxy_decryptor_;
    442 
    443   // Non-owned pointer to the CDM. Updated via calls to
    444   // setContentDecryptionModule().
    445   WebContentDecryptionModuleImpl* web_cdm_;
    446 
    447   // This is only Used by Clear Key key system implementation, where a renderer
    448   // side CDM will be used. This is similar to WebMediaPlayerImpl. For other key
    449   // systems, a browser side CDM will be used and we set CDM by calling
    450   // player_manager_->SetCdm() directly.
    451   media::DecryptorReadyCB decryptor_ready_cb_;
    452 
    453   // Whether stored credentials are allowed to be passed to the server.
    454   bool allow_stored_credentials_;
    455 
    456   // NOTE: Weak pointers must be invalidated before all other member variables.
    457   base::WeakPtrFactory<WebMediaPlayerAndroid> weak_factory_;
    458 
    459   DISALLOW_COPY_AND_ASSIGN(WebMediaPlayerAndroid);
    460 };
    461 
    462 }  // namespace content
    463 
    464 #endif  // CONTENT_RENDERER_MEDIA_ANDROID_WEBMEDIAPLAYER_ANDROID_H_
    465