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 18 using media::MediaDrmBridge; 19 using media::MediaPlayerAndroid; 20 21 // Threshold on the number of media players per renderer before we start 22 // attempting to release inactive media players. 23 static const int kMediaPlayerThreshold = 1; 24 25 namespace media { 26 27 static MediaPlayerManager::FactoryFunction g_factory_function = NULL; 28 29 // static 30 CONTENT_EXPORT void MediaPlayerManager::RegisterFactoryFunction( 31 FactoryFunction factory_function) { 32 g_factory_function = factory_function; 33 } 34 35 // static 36 media::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 45 namespace content { 46 47 BrowserMediaPlayerManager::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 54 BrowserMediaPlayerManager::~BrowserMediaPlayerManager() {} 55 56 bool 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 94 void 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 103 void 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 112 void BrowserMediaPlayerManager::FullscreenPlayerSeek(int msec) { 113 MediaPlayerAndroid* player = GetFullscreenPlayer(); 114 if (player) 115 player->SeekTo(base::TimeDelta::FromMilliseconds(msec)); 116 } 117 118 void 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 132 void BrowserMediaPlayerManager::OnTimeUpdate(int player_id, 133 base::TimeDelta current_time) { 134 Send(new MediaPlayerMsg_MediaTimeUpdate( 135 routing_id(), player_id, current_time)); 136 } 137 138 void 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 148 void 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 157 void 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 163 void 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 169 void 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 177 void BrowserMediaPlayerManager::OnSeekComplete(int player_id, 178 base::TimeDelta current_time) { 179 Send(new MediaPlayerMsg_MediaSeekCompleted( 180 routing_id(), player_id, current_time)); 181 } 182 183 void 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 189 void 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 197 void BrowserMediaPlayerManager::OnReadFromDemuxer( 198 int player_id, media::DemuxerStream::Type type) { 199 Send(new MediaPlayerMsg_ReadFromDemuxer(routing_id(), player_id, type)); 200 } 201 202 void 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 230 void BrowserMediaPlayerManager::ReleaseMediaResources(int player_id) { 231 // Nothing needs to be done. 232 } 233 234 media::MediaResourceGetter* 235 BrowserMediaPlayerManager::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 248 MediaPlayerAndroid* BrowserMediaPlayerManager::GetFullscreenPlayer() { 249 return GetPlayer(fullscreen_player_id_); 250 } 251 252 MediaPlayerAndroid* 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 261 MediaDrmBridge* 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 270 void BrowserMediaPlayerManager::DestroyAllMediaPlayers() { 271 players_.clear(); 272 if (fullscreen_player_id_ != -1) { 273 video_view_.reset(); 274 fullscreen_player_id_ = -1; 275 } 276 } 277 278 void 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 284 void BrowserMediaPlayerManager::OnMediaConfigRequest(int player_id) { 285 Send(new MediaPlayerMsg_MediaConfigRequest(routing_id(), player_id)); 286 } 287 288 void 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 299 void 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 304 void 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 313 void 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) 323 void 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 332 void BrowserMediaPlayerManager::DetachExternalVideoSurface(int player_id) { 333 MediaPlayerAndroid* player = GetPlayer(player_id); 334 if (player) 335 player->SetVideoSurface(gfx::ScopedJavaSurface()); 336 } 337 338 void 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 350 void 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 369 void 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 378 void 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 AddPlayer(media::MediaPlayerAndroid::Create( 387 player_id, url, source_type, first_party_for_cookies, 388 host->GetBrowserContext()->IsOffTheRecord(), this)); 389 } 390 391 void BrowserMediaPlayerManager::OnStart(int player_id) { 392 MediaPlayerAndroid* player = GetPlayer(player_id); 393 if (player) 394 player->Start(); 395 } 396 397 void BrowserMediaPlayerManager::OnSeek(int player_id, base::TimeDelta time) { 398 MediaPlayerAndroid* player = GetPlayer(player_id); 399 if (player) 400 player->SeekTo(time); 401 } 402 403 void BrowserMediaPlayerManager::OnPause(int player_id) { 404 MediaPlayerAndroid* player = GetPlayer(player_id); 405 if (player) 406 player->Pause(); 407 } 408 409 void BrowserMediaPlayerManager::OnSetVolume(int player_id, double volume) { 410 MediaPlayerAndroid* player = GetPlayer(player_id); 411 if (player) 412 player->SetVolume(volume); 413 } 414 415 void BrowserMediaPlayerManager::OnReleaseResources(int player_id) { 416 MediaPlayerAndroid* player = GetPlayer(player_id); 417 // Don't release the fullscreen player when tab visibility changes, 418 // it will be released when user hit the back/home button or when 419 // OnDestroyPlayer is called. 420 if (player && player_id != fullscreen_player_id_) 421 player->Release(); 422 423 #if defined(GOOGLE_TV) 424 WebContentsViewAndroid* view = 425 static_cast<WebContentsViewAndroid*>(web_contents_->GetView()); 426 if (view) 427 view->NotifyExternalSurface(player_id, false, gfx::RectF()); 428 #endif 429 } 430 431 void BrowserMediaPlayerManager::OnDestroyPlayer(int player_id) { 432 RemovePlayer(player_id); 433 if (fullscreen_player_id_ == player_id) 434 fullscreen_player_id_ = -1; 435 } 436 437 void BrowserMediaPlayerManager::OnDemuxerReady( 438 int player_id, 439 const media::MediaPlayerHostMsg_DemuxerReady_Params& params) { 440 MediaPlayerAndroid* player = GetPlayer(player_id); 441 if (player) 442 player->DemuxerReady(params); 443 } 444 445 void BrowserMediaPlayerManager::OnReadFromDemuxerAck( 446 int player_id, 447 const media::MediaPlayerHostMsg_ReadFromDemuxerAck_Params& params) { 448 MediaPlayerAndroid* player = GetPlayer(player_id); 449 if (player) 450 player->ReadFromDemuxerAck(params); 451 } 452 453 void BrowserMediaPlayerManager::OnMediaSeekRequestAck( 454 int player_id, unsigned seek_request_id) { 455 MediaPlayerAndroid* player = GetPlayer(player_id); 456 if (player) 457 player->OnSeekRequestAck(seek_request_id); 458 } 459 460 void BrowserMediaPlayerManager::OnInitializeCDM( 461 int media_keys_id, 462 const std::vector<uint8>& uuid) { 463 AddDrmBridge(media_keys_id, uuid); 464 // In EME v0.1b MediaKeys lives in the media element. So the |media_keys_id| 465 // is the same as the |player_id|. 466 OnSetMediaKeys(media_keys_id, media_keys_id); 467 } 468 469 void BrowserMediaPlayerManager::OnGenerateKeyRequest( 470 int media_keys_id, 471 const std::string& type, 472 const std::vector<uint8>& init_data) { 473 MediaDrmBridge* drm_bridge = GetDrmBridge(media_keys_id); 474 if (drm_bridge) 475 drm_bridge->GenerateKeyRequest(type, &init_data[0], init_data.size()); 476 } 477 478 void BrowserMediaPlayerManager::OnAddKey(int media_keys_id, 479 const std::vector<uint8>& key, 480 const std::vector<uint8>& init_data, 481 const std::string& session_id) { 482 MediaDrmBridge* drm_bridge = GetDrmBridge(media_keys_id); 483 if (drm_bridge) { 484 drm_bridge->AddKey(&key[0], key.size(), &init_data[0], init_data.size(), 485 session_id); 486 } 487 } 488 489 void BrowserMediaPlayerManager::OnCancelKeyRequest( 490 int media_keys_id, 491 const std::string& session_id) { 492 MediaDrmBridge* drm_bridge = GetDrmBridge(media_keys_id); 493 if (drm_bridge) 494 drm_bridge->CancelKeyRequest(session_id); 495 } 496 497 void BrowserMediaPlayerManager::OnDurationChanged( 498 int player_id, const base::TimeDelta& duration) { 499 MediaPlayerAndroid* player = GetPlayer(player_id); 500 if (player) 501 player->DurationChanged(duration); 502 } 503 504 void BrowserMediaPlayerManager::AddPlayer(MediaPlayerAndroid* player) { 505 DCHECK(!GetPlayer(player->player_id())); 506 players_.push_back(player); 507 } 508 509 void BrowserMediaPlayerManager::RemovePlayer(int player_id) { 510 for (ScopedVector<MediaPlayerAndroid>::iterator it = players_.begin(); 511 it != players_.end(); ++it) { 512 if ((*it)->player_id() == player_id) { 513 players_.erase(it); 514 break; 515 } 516 } 517 } 518 519 void BrowserMediaPlayerManager::AddDrmBridge(int media_keys_id, 520 const std::vector<uint8>& uuid) { 521 DCHECK(!GetDrmBridge(media_keys_id)); 522 scoped_ptr<MediaDrmBridge> drm_bridge( 523 MediaDrmBridge::Create(media_keys_id, uuid, this)); 524 DCHECK(drm_bridge) << "failed to create drm bridge. "; 525 drm_bridges_.push_back(drm_bridge.release()); 526 } 527 528 void BrowserMediaPlayerManager::RemoveDrmBridge(int media_keys_id) { 529 for (ScopedVector<MediaDrmBridge>::iterator it = drm_bridges_.begin(); 530 it != drm_bridges_.end(); ++it) { 531 if ((*it)->media_keys_id() == media_keys_id) { 532 drm_bridges_.erase(it); 533 break; 534 } 535 } 536 } 537 538 void BrowserMediaPlayerManager::OnSetMediaKeys(int player_id, 539 int media_keys_id) { 540 MediaPlayerAndroid* player = GetPlayer(player_id); 541 MediaDrmBridge* drm_bridge = GetDrmBridge(media_keys_id); 542 if (!player || !drm_bridge) { 543 NOTREACHED() << "OnSetMediaKeys(): Player and MediaKeys must be present."; 544 return; 545 } 546 // TODO(qinmin): add the logic to decide whether we should create the 547 // fullscreen surface for EME lv1. 548 player->SetDrmBridge(drm_bridge); 549 } 550 551 } // namespace content 552