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#include "content/browser/android/browser_media_player_manager.h" 6 7#include "content/browser/android/content_view_core_impl.h" 8#include "content/browser/android/media_resource_getter_impl.h" 9#include "content/browser/web_contents/web_contents_view_android.h" 10#include "content/common/media/media_player_messages_android.h" 11#include "content/public/browser/browser_context.h" 12#include "content/public/browser/render_process_host.h" 13#include "content/public/browser/render_view_host.h" 14#include "content/public/browser/storage_partition.h" 15#include "content/public/browser/web_contents.h" 16#include "media/base/android/media_drm_bridge.h" 17 18using media::MediaDrmBridge; 19using media::MediaPlayerAndroid; 20 21// Threshold on the number of media players per renderer before we start 22// attempting to release inactive media players. 23static const int kMediaPlayerThreshold = 1; 24 25namespace media { 26 27static MediaPlayerManager::FactoryFunction g_factory_function = NULL; 28 29// static 30CONTENT_EXPORT void MediaPlayerManager::RegisterFactoryFunction( 31 FactoryFunction factory_function) { 32 g_factory_function = factory_function; 33} 34 35// static 36media::MediaPlayerManager* MediaPlayerManager::Create( 37 content::RenderViewHost* render_view_host) { 38 if (g_factory_function) 39 return g_factory_function(render_view_host); 40 return new content::BrowserMediaPlayerManager(render_view_host); 41} 42 43} // namespace media 44 45namespace content { 46 47BrowserMediaPlayerManager::BrowserMediaPlayerManager( 48 RenderViewHost* render_view_host) 49 : RenderViewHostObserver(render_view_host), 50 fullscreen_player_id_(-1), 51 web_contents_(WebContents::FromRenderViewHost(render_view_host)) { 52} 53 54BrowserMediaPlayerManager::~BrowserMediaPlayerManager() {} 55 56bool BrowserMediaPlayerManager::OnMessageReceived(const IPC::Message& msg) { 57 bool handled = true; 58 IPC_BEGIN_MESSAGE_MAP(BrowserMediaPlayerManager, msg) 59 IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_EnterFullscreen, OnEnterFullscreen) 60 IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_ExitFullscreen, OnExitFullscreen) 61 IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_Initialize, OnInitialize) 62 IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_Start, OnStart) 63 IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_Seek, OnSeek) 64 IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_Pause, OnPause) 65 IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_SetVolume, OnSetVolume) 66 IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_Release, OnReleaseResources) 67 IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_DestroyMediaPlayer, OnDestroyPlayer) 68 IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_DestroyAllMediaPlayers, 69 DestroyAllMediaPlayers) 70 IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_DemuxerReady, 71 OnDemuxerReady) 72 IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_ReadFromDemuxerAck, 73 OnReadFromDemuxerAck) 74 IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_DurationChanged, 75 OnDurationChanged) 76 IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_MediaSeekRequestAck, 77 OnMediaSeekRequestAck) 78 IPC_MESSAGE_HANDLER(MediaKeysHostMsg_InitializeCDM, 79 OnInitializeCDM) 80 IPC_MESSAGE_HANDLER(MediaKeysHostMsg_GenerateKeyRequest, 81 OnGenerateKeyRequest) 82 IPC_MESSAGE_HANDLER(MediaKeysHostMsg_AddKey, OnAddKey) 83 IPC_MESSAGE_HANDLER(MediaKeysHostMsg_CancelKeyRequest, 84 OnCancelKeyRequest) 85#if defined(GOOGLE_TV) 86 IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_NotifyExternalSurface, 87 OnNotifyExternalSurface) 88#endif 89 IPC_MESSAGE_UNHANDLED(handled = false) 90 IPC_END_MESSAGE_MAP() 91 return handled; 92} 93 94void BrowserMediaPlayerManager::FullscreenPlayerPlay() { 95 MediaPlayerAndroid* player = GetFullscreenPlayer(); 96 if (player) { 97 player->Start(); 98 Send(new MediaPlayerMsg_DidMediaPlayerPlay( 99 routing_id(), fullscreen_player_id_)); 100 } 101} 102 103void BrowserMediaPlayerManager::FullscreenPlayerPause() { 104 MediaPlayerAndroid* player = GetFullscreenPlayer(); 105 if (player) { 106 player->Pause(); 107 Send(new MediaPlayerMsg_DidMediaPlayerPause( 108 routing_id(), fullscreen_player_id_)); 109 } 110} 111 112void BrowserMediaPlayerManager::FullscreenPlayerSeek(int msec) { 113 MediaPlayerAndroid* player = GetFullscreenPlayer(); 114 if (player) 115 player->SeekTo(base::TimeDelta::FromMilliseconds(msec)); 116} 117 118void BrowserMediaPlayerManager::ExitFullscreen(bool release_media_player) { 119 Send(new MediaPlayerMsg_DidExitFullscreen( 120 routing_id(), fullscreen_player_id_)); 121 video_view_.reset(); 122 MediaPlayerAndroid* player = GetFullscreenPlayer(); 123 fullscreen_player_id_ = -1; 124 if (!player) 125 return; 126 if (release_media_player) 127 player->Release(); 128 else 129 player->SetVideoSurface(gfx::ScopedJavaSurface()); 130} 131 132void BrowserMediaPlayerManager::OnTimeUpdate(int player_id, 133 base::TimeDelta current_time) { 134 Send(new MediaPlayerMsg_MediaTimeUpdate( 135 routing_id(), player_id, current_time)); 136} 137 138void BrowserMediaPlayerManager::SetVideoSurface( 139 gfx::ScopedJavaSurface surface) { 140 MediaPlayerAndroid* player = GetFullscreenPlayer(); 141 if (player) { 142 player->SetVideoSurface(surface.Pass()); 143 Send(new MediaPlayerMsg_DidEnterFullscreen( 144 routing_id(), player->player_id())); 145 } 146} 147 148void BrowserMediaPlayerManager::OnMediaMetadataChanged( 149 int player_id, base::TimeDelta duration, int width, int height, 150 bool success) { 151 Send(new MediaPlayerMsg_MediaMetadataChanged( 152 routing_id(), player_id, duration, width, height, success)); 153 if (fullscreen_player_id_ != -1) 154 video_view_->UpdateMediaMetadata(); 155} 156 157void BrowserMediaPlayerManager::OnPlaybackComplete(int player_id) { 158 Send(new MediaPlayerMsg_MediaPlaybackCompleted(routing_id(), player_id)); 159 if (fullscreen_player_id_ != -1) 160 video_view_->OnPlaybackComplete(); 161} 162 163void BrowserMediaPlayerManager::OnMediaInterrupted(int player_id) { 164 // Tell WebKit that the audio should be paused, then release all resources 165 Send(new MediaPlayerMsg_DidMediaPlayerPause(routing_id(), player_id)); 166 OnReleaseResources(player_id); 167} 168 169void BrowserMediaPlayerManager::OnBufferingUpdate( 170 int player_id, int percentage) { 171 Send(new MediaPlayerMsg_MediaBufferingUpdate( 172 routing_id(), player_id, percentage)); 173 if (fullscreen_player_id_ != -1) 174 video_view_->OnBufferingUpdate(percentage); 175} 176 177void BrowserMediaPlayerManager::OnSeekComplete(int player_id, 178 base::TimeDelta current_time) { 179 Send(new MediaPlayerMsg_MediaSeekCompleted( 180 routing_id(), player_id, current_time)); 181} 182 183void BrowserMediaPlayerManager::OnError(int player_id, int error) { 184 Send(new MediaPlayerMsg_MediaError(routing_id(), player_id, error)); 185 if (fullscreen_player_id_ != -1) 186 video_view_->OnMediaPlayerError(error); 187} 188 189void BrowserMediaPlayerManager::OnVideoSizeChanged( 190 int player_id, int width, int height) { 191 Send(new MediaPlayerMsg_MediaVideoSizeChanged(routing_id(), player_id, 192 width, height)); 193 if (fullscreen_player_id_ != -1) 194 video_view_->OnVideoSizeChanged(width, height); 195} 196 197void BrowserMediaPlayerManager::OnReadFromDemuxer( 198 int player_id, media::DemuxerStream::Type type) { 199 Send(new MediaPlayerMsg_ReadFromDemuxer(routing_id(), player_id, type)); 200} 201 202void BrowserMediaPlayerManager::RequestMediaResources(int player_id) { 203 int num_active_player = 0; 204 ScopedVector<MediaPlayerAndroid>::iterator it; 205 for (it = players_.begin(); it != players_.end(); ++it) { 206 if (!(*it)->IsPlayerReady()) 207 continue; 208 209 // The player is already active, ignore it. 210 if ((*it)->player_id() == player_id) 211 return; 212 else 213 num_active_player++; 214 } 215 216 // Number of active players are less than the threshold, do nothing. 217 if (num_active_player < kMediaPlayerThreshold) 218 return; 219 220 for (it = players_.begin(); it != players_.end(); ++it) { 221 if ((*it)->IsPlayerReady() && !(*it)->IsPlaying() && 222 fullscreen_player_id_ != (*it)->player_id()) { 223 (*it)->Release(); 224 Send(new MediaPlayerMsg_MediaPlayerReleased( 225 routing_id(), (*it)->player_id())); 226 } 227 } 228} 229 230void BrowserMediaPlayerManager::ReleaseMediaResources(int player_id) { 231 // Nothing needs to be done. 232} 233 234media::MediaResourceGetter* 235BrowserMediaPlayerManager::GetMediaResourceGetter() { 236 if (!media_resource_getter_.get()) { 237 RenderProcessHost* host = render_view_host()->GetProcess(); 238 BrowserContext* context = host->GetBrowserContext(); 239 StoragePartition* partition = host->GetStoragePartition(); 240 fileapi::FileSystemContext* file_system_context = 241 partition ? partition->GetFileSystemContext() : NULL; 242 media_resource_getter_.reset(new MediaResourceGetterImpl( 243 context, file_system_context, host->GetID(), routing_id())); 244 } 245 return media_resource_getter_.get(); 246} 247 248MediaPlayerAndroid* BrowserMediaPlayerManager::GetFullscreenPlayer() { 249 return GetPlayer(fullscreen_player_id_); 250} 251 252MediaPlayerAndroid* BrowserMediaPlayerManager::GetPlayer(int player_id) { 253 for (ScopedVector<MediaPlayerAndroid>::iterator it = players_.begin(); 254 it != players_.end(); ++it) { 255 if ((*it)->player_id() == player_id) 256 return *it; 257 } 258 return NULL; 259} 260 261MediaDrmBridge* BrowserMediaPlayerManager::GetDrmBridge(int media_keys_id) { 262 for (ScopedVector<MediaDrmBridge>::iterator it = drm_bridges_.begin(); 263 it != drm_bridges_.end(); ++it) { 264 if ((*it)->media_keys_id() == media_keys_id) 265 return *it; 266 } 267 return NULL; 268} 269 270void BrowserMediaPlayerManager::DestroyAllMediaPlayers() { 271 players_.clear(); 272 if (fullscreen_player_id_ != -1) { 273 video_view_.reset(); 274 fullscreen_player_id_ = -1; 275 } 276} 277 278void BrowserMediaPlayerManager::OnMediaSeekRequest( 279 int player_id, base::TimeDelta time_to_seek, unsigned seek_request_id) { 280 Send(new MediaPlayerMsg_MediaSeekRequest( 281 routing_id(), player_id, time_to_seek, seek_request_id)); 282} 283 284void BrowserMediaPlayerManager::OnMediaConfigRequest(int player_id) { 285 Send(new MediaPlayerMsg_MediaConfigRequest(routing_id(), player_id)); 286} 287 288void BrowserMediaPlayerManager::OnProtectedSurfaceRequested(int player_id) { 289 if (fullscreen_player_id_ == player_id) 290 return; 291 if (fullscreen_player_id_ != -1) { 292 // TODO(qinmin): Determine the correct error code we should report to WMPA. 293 OnError(player_id, MediaPlayerAndroid::MEDIA_ERROR_DECODE); 294 return; 295 } 296 OnEnterFullscreen(player_id); 297} 298 299void BrowserMediaPlayerManager::OnKeyAdded(int media_keys_id, 300 const std::string& session_id) { 301 Send(new MediaKeysMsg_KeyAdded(routing_id(), media_keys_id, session_id)); 302} 303 304void BrowserMediaPlayerManager::OnKeyError( 305 int media_keys_id, 306 const std::string& session_id, 307 media::MediaKeys::KeyError error_code, 308 int system_code) { 309 Send(new MediaKeysMsg_KeyError(routing_id(), media_keys_id, 310 session_id, error_code, system_code)); 311} 312 313void BrowserMediaPlayerManager::OnKeyMessage( 314 int media_keys_id, 315 const std::string& session_id, 316 const std::vector<uint8>& message, 317 const std::string& destination_url) { 318 Send(new MediaKeysMsg_KeyMessage(routing_id(), media_keys_id, 319 session_id, message, destination_url)); 320} 321 322#if defined(GOOGLE_TV) 323void BrowserMediaPlayerManager::AttachExternalVideoSurface(int player_id, 324 jobject surface) { 325 MediaPlayerAndroid* player = GetPlayer(player_id); 326 if (player) { 327 player->SetVideoSurface( 328 gfx::ScopedJavaSurface::AcquireExternalSurface(surface)); 329 } 330} 331 332void BrowserMediaPlayerManager::DetachExternalVideoSurface(int player_id) { 333 MediaPlayerAndroid* player = GetPlayer(player_id); 334 if (player) 335 player->SetVideoSurface(gfx::ScopedJavaSurface()); 336} 337 338void BrowserMediaPlayerManager::OnNotifyExternalSurface( 339 int player_id, bool is_request, const gfx::RectF& rect) { 340 if (!web_contents_) 341 return; 342 343 WebContentsViewAndroid* view = 344 static_cast<WebContentsViewAndroid*>(web_contents_->GetView()); 345 if (view) 346 view->NotifyExternalSurface(player_id, is_request, rect); 347} 348#endif 349 350void BrowserMediaPlayerManager::OnEnterFullscreen(int player_id) { 351 DCHECK_EQ(fullscreen_player_id_, -1); 352 353 if (video_view_.get()) { 354 fullscreen_player_id_ = player_id; 355 video_view_->OpenVideo(); 356 } else if (!ContentVideoView::HasContentVideoView()) { 357 // In Android WebView, two ContentViewCores could both try to enter 358 // fullscreen video, we just ignore the second one. 359 fullscreen_player_id_ = player_id; 360 WebContents* web_contents = 361 WebContents::FromRenderViewHost(render_view_host()); 362 ContentViewCoreImpl* content_view_core_impl = 363 ContentViewCoreImpl::FromWebContents(web_contents); 364 video_view_.reset(new ContentVideoView(content_view_core_impl->GetContext(), 365 content_view_core_impl->GetContentVideoViewClient(), this)); 366 } 367} 368 369void BrowserMediaPlayerManager::OnExitFullscreen(int player_id) { 370 if (fullscreen_player_id_ == player_id) { 371 MediaPlayerAndroid* player = GetPlayer(player_id); 372 if (player) 373 player->SetVideoSurface(gfx::ScopedJavaSurface()); 374 video_view_->OnExitFullscreen(); 375 } 376} 377 378void BrowserMediaPlayerManager::OnInitialize( 379 int player_id, 380 const GURL& url, 381 media::MediaPlayerAndroid::SourceType source_type, 382 const GURL& first_party_for_cookies) { 383 RemovePlayer(player_id); 384 385 RenderProcessHost* host = render_view_host()->GetProcess(); 386 ContentViewCoreImpl* content_view_core_impl = 387 static_cast<ContentViewCoreImpl*>( 388 ContentViewCore::FromWebContents(web_contents_)); 389 AddPlayer(media::MediaPlayerAndroid::Create( 390 player_id, url, source_type, first_party_for_cookies, 391 host->GetBrowserContext()->IsOffTheRecord(), this, 392 !content_view_core_impl->ShouldBlockMediaRequest(url))); 393} 394 395void BrowserMediaPlayerManager::OnStart(int player_id) { 396 MediaPlayerAndroid* player = GetPlayer(player_id); 397 if (player) 398 player->Start(); 399} 400 401void BrowserMediaPlayerManager::OnSeek(int player_id, base::TimeDelta time) { 402 MediaPlayerAndroid* player = GetPlayer(player_id); 403 if (player) 404 player->SeekTo(time); 405} 406 407void BrowserMediaPlayerManager::OnPause(int player_id) { 408 MediaPlayerAndroid* player = GetPlayer(player_id); 409 if (player) 410 player->Pause(); 411} 412 413void BrowserMediaPlayerManager::OnSetVolume(int player_id, double volume) { 414 MediaPlayerAndroid* player = GetPlayer(player_id); 415 if (player) 416 player->SetVolume(volume); 417} 418 419void BrowserMediaPlayerManager::OnReleaseResources(int player_id) { 420 MediaPlayerAndroid* player = GetPlayer(player_id); 421 // Don't release the fullscreen player when tab visibility changes, 422 // it will be released when user hit the back/home button or when 423 // OnDestroyPlayer is called. 424 if (player && player_id != fullscreen_player_id_) 425 player->Release(); 426 427#if defined(GOOGLE_TV) 428 WebContentsViewAndroid* view = 429 static_cast<WebContentsViewAndroid*>(web_contents_->GetView()); 430 if (view) 431 view->NotifyExternalSurface(player_id, false, gfx::RectF()); 432#endif 433} 434 435void BrowserMediaPlayerManager::OnDestroyPlayer(int player_id) { 436 RemovePlayer(player_id); 437 if (fullscreen_player_id_ == player_id) 438 fullscreen_player_id_ = -1; 439} 440 441void BrowserMediaPlayerManager::OnDemuxerReady( 442 int player_id, 443 const media::MediaPlayerHostMsg_DemuxerReady_Params& params) { 444 MediaPlayerAndroid* player = GetPlayer(player_id); 445 if (player) 446 player->DemuxerReady(params); 447} 448 449void BrowserMediaPlayerManager::OnReadFromDemuxerAck( 450 int player_id, 451 const media::MediaPlayerHostMsg_ReadFromDemuxerAck_Params& params) { 452 MediaPlayerAndroid* player = GetPlayer(player_id); 453 if (player) 454 player->ReadFromDemuxerAck(params); 455} 456 457void BrowserMediaPlayerManager::OnMediaSeekRequestAck( 458 int player_id, unsigned seek_request_id) { 459 MediaPlayerAndroid* player = GetPlayer(player_id); 460 if (player) 461 player->OnSeekRequestAck(seek_request_id); 462} 463 464void BrowserMediaPlayerManager::OnInitializeCDM( 465 int media_keys_id, 466 const std::vector<uint8>& uuid) { 467 AddDrmBridge(media_keys_id, uuid); 468 // In EME v0.1b MediaKeys lives in the media element. So the |media_keys_id| 469 // is the same as the |player_id|. 470 OnSetMediaKeys(media_keys_id, media_keys_id); 471} 472 473void BrowserMediaPlayerManager::OnGenerateKeyRequest( 474 int media_keys_id, 475 const std::string& type, 476 const std::vector<uint8>& init_data) { 477 MediaDrmBridge* drm_bridge = GetDrmBridge(media_keys_id); 478 if (drm_bridge) 479 drm_bridge->GenerateKeyRequest(type, &init_data[0], init_data.size()); 480} 481 482void BrowserMediaPlayerManager::OnAddKey(int media_keys_id, 483 const std::vector<uint8>& key, 484 const std::vector<uint8>& init_data, 485 const std::string& session_id) { 486 MediaDrmBridge* drm_bridge = GetDrmBridge(media_keys_id); 487 if (drm_bridge) { 488 drm_bridge->AddKey(&key[0], key.size(), &init_data[0], init_data.size(), 489 session_id); 490 } 491} 492 493void BrowserMediaPlayerManager::OnCancelKeyRequest( 494 int media_keys_id, 495 const std::string& session_id) { 496 MediaDrmBridge* drm_bridge = GetDrmBridge(media_keys_id); 497 if (drm_bridge) 498 drm_bridge->CancelKeyRequest(session_id); 499} 500 501void BrowserMediaPlayerManager::OnDurationChanged( 502 int player_id, const base::TimeDelta& duration) { 503 MediaPlayerAndroid* player = GetPlayer(player_id); 504 if (player) 505 player->DurationChanged(duration); 506} 507 508void BrowserMediaPlayerManager::AddPlayer(MediaPlayerAndroid* player) { 509 DCHECK(!GetPlayer(player->player_id())); 510 players_.push_back(player); 511} 512 513void BrowserMediaPlayerManager::RemovePlayer(int player_id) { 514 for (ScopedVector<MediaPlayerAndroid>::iterator it = players_.begin(); 515 it != players_.end(); ++it) { 516 if ((*it)->player_id() == player_id) { 517 players_.erase(it); 518 break; 519 } 520 } 521} 522 523void BrowserMediaPlayerManager::AddDrmBridge(int media_keys_id, 524 const std::vector<uint8>& uuid) { 525 DCHECK(!GetDrmBridge(media_keys_id)); 526 scoped_ptr<MediaDrmBridge> drm_bridge( 527 MediaDrmBridge::Create(media_keys_id, uuid, this)); 528 DCHECK(drm_bridge) << "failed to create drm bridge. "; 529 drm_bridges_.push_back(drm_bridge.release()); 530} 531 532void BrowserMediaPlayerManager::RemoveDrmBridge(int media_keys_id) { 533 for (ScopedVector<MediaDrmBridge>::iterator it = drm_bridges_.begin(); 534 it != drm_bridges_.end(); ++it) { 535 if ((*it)->media_keys_id() == media_keys_id) { 536 drm_bridges_.erase(it); 537 break; 538 } 539 } 540} 541 542void BrowserMediaPlayerManager::OnSetMediaKeys(int player_id, 543 int media_keys_id) { 544 MediaPlayerAndroid* player = GetPlayer(player_id); 545 MediaDrmBridge* drm_bridge = GetDrmBridge(media_keys_id); 546 if (!player || !drm_bridge) { 547 NOTREACHED() << "OnSetMediaKeys(): Player and MediaKeys must be present."; 548 return; 549 } 550 // TODO(qinmin): add the logic to decide whether we should create the 551 // fullscreen surface for EME lv1. 552 player->SetDrmBridge(drm_bridge); 553} 554 555} // namespace content 556