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