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 #include "content/browser/media/android/browser_media_player_manager.h"
      6 
      7 #include "base/command_line.h"
      8 #include "content/browser/android/content_view_core_impl.h"
      9 #include "content/browser/media/android/browser_demuxer_android.h"
     10 #include "content/browser/media/android/media_resource_getter_impl.h"
     11 #include "content/browser/renderer_host/render_view_host_impl.h"
     12 #include "content/browser/web_contents/web_contents_view_android.h"
     13 #include "content/common/media/media_player_messages_android.h"
     14 #include "content/public/browser/android/content_view_core.h"
     15 #include "content/public/browser/browser_context.h"
     16 #include "content/public/browser/render_process_host.h"
     17 #include "content/public/browser/render_view_host.h"
     18 #include "content/public/browser/storage_partition.h"
     19 #include "content/public/browser/web_contents.h"
     20 #include "content/public/browser/web_contents_delegate.h"
     21 #include "content/public/common/content_switches.h"
     22 #include "media/base/android/media_drm_bridge.h"
     23 #include "media/base/android/media_player_bridge.h"
     24 #include "media/base/android/media_source_player.h"
     25 #include "media/base/media_switches.h"
     26 
     27 using media::MediaDrmBridge;
     28 using media::MediaPlayerAndroid;
     29 using media::MediaPlayerBridge;
     30 using media::MediaPlayerManager;
     31 using media::MediaSourcePlayer;
     32 
     33 // Threshold on the number of media players per renderer before we start
     34 // attempting to release inactive media players.
     35 static const int kMediaPlayerThreshold = 1;
     36 
     37 // Maximum sizes for various EME message parameters. These are checks to
     38 // prevent unnecessarily large messages from being passed around, and the sizes
     39 // are somewhat arbitrary as the EME specification doesn't specify any limits.
     40 static const size_t kEmeUuidSize = 16;
     41 static const size_t kEmeTypeMaximum = 50;  // Type is a MIME type.
     42 static const size_t kEmeInitDataMaximum = 10240;  // 10 KB
     43 static const size_t kEmeResponseMaximum = 10240;  // 10 KB
     44 
     45 namespace content {
     46 
     47 static BrowserMediaPlayerManager::Factory g_factory = NULL;
     48 
     49 // static
     50 void BrowserMediaPlayerManager::RegisterFactory(Factory factory) {
     51   g_factory = factory;
     52 }
     53 
     54 // static
     55 BrowserMediaPlayerManager* BrowserMediaPlayerManager::Create(
     56     RenderViewHost* rvh) {
     57   if (g_factory)
     58     return g_factory(rvh);
     59   return new BrowserMediaPlayerManager(rvh);
     60 }
     61 
     62 #if !defined(GOOGLE_TV)
     63 // static
     64 MediaPlayerAndroid* BrowserMediaPlayerManager::CreateMediaPlayer(
     65     MediaPlayerHostMsg_Initialize_Type type,
     66     int player_id,
     67     const GURL& url,
     68     const GURL& first_party_for_cookies,
     69     int demuxer_client_id,
     70     bool hide_url_log,
     71     MediaPlayerManager* manager,
     72     BrowserDemuxerAndroid* demuxer) {
     73   switch (type) {
     74     case MEDIA_PLAYER_TYPE_URL: {
     75       MediaPlayerBridge* media_player_bridge = new MediaPlayerBridge(
     76           player_id, url, first_party_for_cookies, hide_url_log, manager);
     77       BrowserMediaPlayerManager* browser_media_player_manager =
     78           static_cast<BrowserMediaPlayerManager*>(manager);
     79       ContentViewCoreImpl* content_view_core_impl =
     80           static_cast<ContentViewCoreImpl*>(ContentViewCore::FromWebContents(
     81               browser_media_player_manager->web_contents_));
     82       if (!content_view_core_impl) {
     83         // May reach here due to prerendering. Don't extract the metadata
     84         // since it is expensive.
     85         // TODO(qinmin): extract the metadata once the user decided to load
     86         // the page.
     87         browser_media_player_manager->OnMediaMetadataChanged(
     88             player_id, base::TimeDelta(), 0, 0, false);
     89       } else if (!content_view_core_impl->ShouldBlockMediaRequest(url)) {
     90         media_player_bridge->Initialize();
     91       }
     92       return media_player_bridge;
     93     }
     94 
     95     case MEDIA_PLAYER_TYPE_MEDIA_SOURCE: {
     96       return new MediaSourcePlayer(
     97           player_id, manager, demuxer->CreateDemuxer(demuxer_client_id));
     98     }
     99   }
    100 
    101   NOTREACHED();
    102   return NULL;
    103 }
    104 #endif
    105 
    106 BrowserMediaPlayerManager::BrowserMediaPlayerManager(
    107     RenderViewHost* render_view_host)
    108     : WebContentsObserver(WebContents::FromRenderViewHost(render_view_host)),
    109       fullscreen_player_id_(-1),
    110       pending_fullscreen_player_id_(-1),
    111       fullscreen_player_is_released_(false),
    112       web_contents_(WebContents::FromRenderViewHost(render_view_host)),
    113       weak_ptr_factory_(this) {
    114 }
    115 
    116 BrowserMediaPlayerManager::~BrowserMediaPlayerManager() {}
    117 
    118 bool BrowserMediaPlayerManager::OnMessageReceived(const IPC::Message& msg) {
    119   bool handled = true;
    120   IPC_BEGIN_MESSAGE_MAP(BrowserMediaPlayerManager, msg)
    121     IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_EnterFullscreen, OnEnterFullscreen)
    122     IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_ExitFullscreen, OnExitFullscreen)
    123     IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_Initialize, OnInitialize)
    124     IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_Start, OnStart)
    125     IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_Seek, OnSeek)
    126     IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_Pause, OnPause)
    127     IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_SetVolume, OnSetVolume)
    128     IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_Release, OnReleaseResources)
    129     IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_DestroyMediaPlayer, OnDestroyPlayer)
    130     IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_DestroyAllMediaPlayers,
    131                         DestroyAllMediaPlayers)
    132     IPC_MESSAGE_HANDLER(MediaKeysHostMsg_InitializeCDM,
    133                         OnInitializeCDM)
    134     IPC_MESSAGE_HANDLER(MediaKeysHostMsg_CreateSession, OnCreateSession)
    135     IPC_MESSAGE_HANDLER(MediaKeysHostMsg_UpdateSession, OnUpdateSession)
    136     IPC_MESSAGE_HANDLER(MediaKeysHostMsg_ReleaseSession, OnReleaseSession)
    137 #if defined(VIDEO_HOLE)
    138     IPC_MESSAGE_HANDLER(MediaPlayerHostMsg_NotifyExternalSurface,
    139                         OnNotifyExternalSurface)
    140 #endif  // defined(VIDEO_HOLE)
    141     IPC_MESSAGE_UNHANDLED(handled = false)
    142   IPC_END_MESSAGE_MAP()
    143   return handled;
    144 }
    145 
    146 void BrowserMediaPlayerManager::FullscreenPlayerPlay() {
    147   MediaPlayerAndroid* player = GetFullscreenPlayer();
    148   if (player) {
    149     if (fullscreen_player_is_released_) {
    150       video_view_->OpenVideo();
    151       fullscreen_player_is_released_ = false;
    152     }
    153     player->Start();
    154     Send(new MediaPlayerMsg_DidMediaPlayerPlay(
    155         routing_id(), fullscreen_player_id_));
    156   }
    157 }
    158 
    159 void BrowserMediaPlayerManager::FullscreenPlayerPause() {
    160   MediaPlayerAndroid* player = GetFullscreenPlayer();
    161   if (player) {
    162     player->Pause(true);
    163     Send(new MediaPlayerMsg_DidMediaPlayerPause(
    164         routing_id(), fullscreen_player_id_));
    165   }
    166 }
    167 
    168 void BrowserMediaPlayerManager::FullscreenPlayerSeek(int msec) {
    169   MediaPlayerAndroid* player = GetFullscreenPlayer();
    170   if (player) {
    171     // TODO(kbalazs): if |fullscreen_player_is_released_| is true
    172     // at this point, player->GetCurrentTime() will be wrong until
    173     // FullscreenPlayerPlay (http://crbug.com/322798).
    174     OnSeekRequest(fullscreen_player_id_,
    175                   base::TimeDelta::FromMilliseconds(msec));
    176   }
    177 }
    178 
    179 void BrowserMediaPlayerManager::ExitFullscreen(bool release_media_player) {
    180   Send(new MediaPlayerMsg_DidExitFullscreen(
    181       routing_id(), fullscreen_player_id_));
    182   video_view_.reset();
    183   MediaPlayerAndroid* player = GetFullscreenPlayer();
    184   fullscreen_player_id_ = -1;
    185   if (!player)
    186     return;
    187   if (release_media_player)
    188     player->Release();
    189   else
    190     player->SetVideoSurface(gfx::ScopedJavaSurface());
    191 }
    192 
    193 void BrowserMediaPlayerManager::OnTimeUpdate(int player_id,
    194                                              base::TimeDelta current_time) {
    195   Send(new MediaPlayerMsg_MediaTimeUpdate(
    196       routing_id(), player_id, current_time));
    197 }
    198 
    199 void BrowserMediaPlayerManager::SetVideoSurface(
    200     gfx::ScopedJavaSurface surface) {
    201   MediaPlayerAndroid* player = GetFullscreenPlayer();
    202   if (!player)
    203     return;
    204   if (!surface.IsEmpty()) {
    205     Send(new MediaPlayerMsg_DidEnterFullscreen(routing_id(),
    206                                                player->player_id()));
    207   }
    208   player->SetVideoSurface(surface.Pass());
    209 }
    210 
    211 void BrowserMediaPlayerManager::OnMediaMetadataChanged(
    212     int player_id, base::TimeDelta duration, int width, int height,
    213     bool success) {
    214   Send(new MediaPlayerMsg_MediaMetadataChanged(
    215       routing_id(), player_id, duration, width, height, success));
    216   if (fullscreen_player_id_ == player_id)
    217     video_view_->UpdateMediaMetadata();
    218 }
    219 
    220 void BrowserMediaPlayerManager::OnPlaybackComplete(int player_id) {
    221   Send(new MediaPlayerMsg_MediaPlaybackCompleted(routing_id(), player_id));
    222   if (fullscreen_player_id_ == player_id)
    223     video_view_->OnPlaybackComplete();
    224 }
    225 
    226 void BrowserMediaPlayerManager::OnMediaInterrupted(int player_id) {
    227   // Tell WebKit that the audio should be paused, then release all resources
    228   Send(new MediaPlayerMsg_DidMediaPlayerPause(routing_id(), player_id));
    229   OnReleaseResources(player_id);
    230 }
    231 
    232 void BrowserMediaPlayerManager::OnBufferingUpdate(
    233     int player_id, int percentage) {
    234   Send(new MediaPlayerMsg_MediaBufferingUpdate(
    235       routing_id(), player_id, percentage));
    236   if (fullscreen_player_id_ == player_id)
    237     video_view_->OnBufferingUpdate(percentage);
    238 }
    239 
    240 void BrowserMediaPlayerManager::OnSeekRequest(
    241     int player_id,
    242     const base::TimeDelta& time_to_seek) {
    243   Send(new MediaPlayerMsg_SeekRequest(routing_id(), player_id, time_to_seek));
    244 }
    245 
    246 void BrowserMediaPlayerManager::OnSeekComplete(
    247     int player_id,
    248     const base::TimeDelta& current_time) {
    249   Send(new MediaPlayerMsg_SeekCompleted(routing_id(), player_id, current_time));
    250 }
    251 
    252 void BrowserMediaPlayerManager::OnError(int player_id, int error) {
    253   Send(new MediaPlayerMsg_MediaError(routing_id(), player_id, error));
    254   if (fullscreen_player_id_ == player_id)
    255     video_view_->OnMediaPlayerError(error);
    256 }
    257 
    258 void BrowserMediaPlayerManager::OnVideoSizeChanged(
    259     int player_id, int width, int height) {
    260   Send(new MediaPlayerMsg_MediaVideoSizeChanged(routing_id(), player_id,
    261       width, height));
    262   if (fullscreen_player_id_ == player_id)
    263     video_view_->OnVideoSizeChanged(width, height);
    264 }
    265 
    266 void BrowserMediaPlayerManager::RequestMediaResources(int player_id) {
    267   int num_active_player = 0;
    268   ScopedVector<MediaPlayerAndroid>::iterator it;
    269   for (it = players_.begin(); it != players_.end(); ++it) {
    270     if (!(*it)->IsPlayerReady())
    271       continue;
    272 
    273     // The player is already active, ignore it.
    274     if ((*it)->player_id() == player_id)
    275       return;
    276     else
    277       num_active_player++;
    278   }
    279 
    280   // Number of active players are less than the threshold, do nothing.
    281   if (num_active_player < kMediaPlayerThreshold)
    282     return;
    283 
    284   for (it = players_.begin(); it != players_.end(); ++it) {
    285     if ((*it)->IsPlayerReady() && !(*it)->IsPlaying() &&
    286         fullscreen_player_id_ != (*it)->player_id()) {
    287       (*it)->Release();
    288       Send(new MediaPlayerMsg_MediaPlayerReleased(
    289           routing_id(), (*it)->player_id()));
    290     }
    291   }
    292 }
    293 
    294 void BrowserMediaPlayerManager::ReleaseMediaResources(int player_id) {
    295   // Nothing needs to be done.
    296 }
    297 
    298 media::MediaResourceGetter*
    299 BrowserMediaPlayerManager::GetMediaResourceGetter() {
    300   if (!media_resource_getter_.get()) {
    301     RenderProcessHost* host = web_contents()->GetRenderProcessHost();
    302     BrowserContext* context = host->GetBrowserContext();
    303     StoragePartition* partition = host->GetStoragePartition();
    304     fileapi::FileSystemContext* file_system_context =
    305         partition ? partition->GetFileSystemContext() : NULL;
    306     media_resource_getter_.reset(new MediaResourceGetterImpl(
    307         context, file_system_context, host->GetID(), routing_id()));
    308   }
    309   return media_resource_getter_.get();
    310 }
    311 
    312 MediaPlayerAndroid* BrowserMediaPlayerManager::GetFullscreenPlayer() {
    313   return GetPlayer(fullscreen_player_id_);
    314 }
    315 
    316 MediaPlayerAndroid* BrowserMediaPlayerManager::GetPlayer(int player_id) {
    317   for (ScopedVector<MediaPlayerAndroid>::iterator it = players_.begin();
    318       it != players_.end(); ++it) {
    319     if ((*it)->player_id() == player_id)
    320       return *it;
    321   }
    322   return NULL;
    323 }
    324 
    325 MediaDrmBridge* BrowserMediaPlayerManager::GetDrmBridge(int media_keys_id) {
    326   for (ScopedVector<MediaDrmBridge>::iterator it = drm_bridges_.begin();
    327       it != drm_bridges_.end(); ++it) {
    328     if ((*it)->media_keys_id() == media_keys_id)
    329       return *it;
    330   }
    331   return NULL;
    332 }
    333 
    334 void BrowserMediaPlayerManager::DestroyAllMediaPlayers() {
    335   players_.clear();
    336   drm_bridges_.clear();
    337   if (fullscreen_player_id_ != -1) {
    338     video_view_.reset();
    339     fullscreen_player_id_ = -1;
    340   }
    341 }
    342 
    343 void BrowserMediaPlayerManager::OnProtectedSurfaceRequested(int player_id) {
    344   if (fullscreen_player_id_ == player_id)
    345     return;
    346 
    347   if (fullscreen_player_id_ != -1) {
    348     // TODO(qinmin): Determine the correct error code we should report to WMPA.
    349     OnError(player_id, MediaPlayerAndroid::MEDIA_ERROR_DECODE);
    350     return;
    351   }
    352 
    353   // If the player is pending approval, wait for the approval to happen.
    354   if (media_keys_ids_pending_approval_.end() !=
    355       media_keys_ids_pending_approval_.find(player_id)) {
    356     pending_fullscreen_player_id_ = player_id;
    357     return;
    358   }
    359 
    360   // Send an IPC to the render process to request the video element to enter
    361   // fullscreen. OnEnterFullscreen() will be called later on success.
    362   // This guarantees the fullscreen video will be rendered correctly.
    363   // During the process, DisableFullscreenEncryptedMediaPlayback() may get
    364   // called before or after OnEnterFullscreen(). If it is called before
    365   // OnEnterFullscreen(), the player will not enter fullscreen. And it will
    366   // retry the process once CreateSession() is allowed to proceed.
    367   // TODO(qinmin): make this flag default on android.
    368   if (CommandLine::ForCurrentProcess()->HasSwitch(
    369       switches::kDisableGestureRequirementForMediaFullscreen)) {
    370     Send(new MediaPlayerMsg_RequestFullscreen(routing_id(), player_id));
    371   }
    372 }
    373 
    374 // The following 5 functions are EME MediaKeySession events.
    375 
    376 void BrowserMediaPlayerManager::OnSessionCreated(
    377     int media_keys_id,
    378     uint32 session_id,
    379     const std::string& web_session_id) {
    380   Send(new MediaKeysMsg_SessionCreated(
    381       routing_id(), media_keys_id, session_id, web_session_id));
    382 }
    383 
    384 void BrowserMediaPlayerManager::OnSessionMessage(
    385     int media_keys_id,
    386     uint32 session_id,
    387     const std::vector<uint8>& message,
    388     const std::string& destination_url) {
    389   Send(new MediaKeysMsg_SessionMessage(
    390       routing_id(), media_keys_id, session_id, message, destination_url));
    391 }
    392 
    393 void BrowserMediaPlayerManager::OnSessionReady(int media_keys_id,
    394                                                uint32 session_id) {
    395   Send(new MediaKeysMsg_SessionReady(routing_id(), media_keys_id, session_id));
    396 }
    397 
    398 void BrowserMediaPlayerManager::OnSessionClosed(int media_keys_id,
    399                                                 uint32 session_id) {
    400   Send(new MediaKeysMsg_SessionClosed(routing_id(), media_keys_id, session_id));
    401 }
    402 
    403 void BrowserMediaPlayerManager::OnSessionError(
    404     int media_keys_id,
    405     uint32 session_id,
    406     media::MediaKeys::KeyError error_code,
    407     int system_code) {
    408   Send(new MediaKeysMsg_SessionError(
    409       routing_id(), media_keys_id, session_id, error_code, system_code));
    410 }
    411 
    412 #if defined(VIDEO_HOLE)
    413 void BrowserMediaPlayerManager::AttachExternalVideoSurface(int player_id,
    414                                                            jobject surface) {
    415   MediaPlayerAndroid* player = GetPlayer(player_id);
    416   if (player) {
    417     player->SetVideoSurface(
    418         gfx::ScopedJavaSurface::AcquireExternalSurface(surface));
    419   }
    420 }
    421 
    422 void BrowserMediaPlayerManager::DetachExternalVideoSurface(int player_id) {
    423   MediaPlayerAndroid* player = GetPlayer(player_id);
    424   if (player)
    425     player->SetVideoSurface(gfx::ScopedJavaSurface());
    426 }
    427 
    428 void BrowserMediaPlayerManager::OnNotifyExternalSurface(
    429     int player_id, bool is_request, const gfx::RectF& rect) {
    430   if (!web_contents_)
    431     return;
    432 
    433   WebContentsViewAndroid* view =
    434       static_cast<WebContentsViewAndroid*>(web_contents_->GetView());
    435   if (view)
    436     view->NotifyExternalSurface(player_id, is_request, rect);
    437 }
    438 #endif  // defined(VIDEO_HOLE)
    439 
    440 void BrowserMediaPlayerManager::DisableFullscreenEncryptedMediaPlayback() {
    441   if (fullscreen_player_id_ == -1)
    442     return;
    443 
    444   // If the fullscreen player is not playing back encrypted video, do nothing.
    445   MediaDrmBridge* drm_bridge = GetDrmBridge(fullscreen_player_id_);
    446   if (!drm_bridge)
    447     return;
    448 
    449   // Exit fullscreen.
    450   pending_fullscreen_player_id_ = fullscreen_player_id_;
    451   OnExitFullscreen(fullscreen_player_id_);
    452 }
    453 
    454 void BrowserMediaPlayerManager::OnEnterFullscreen(int player_id) {
    455   DCHECK_EQ(fullscreen_player_id_, -1);
    456   if (media_keys_ids_pending_approval_.find(player_id) !=
    457       media_keys_ids_pending_approval_.end()) {
    458     return;
    459   }
    460 
    461   if (video_view_.get()) {
    462     fullscreen_player_id_ = player_id;
    463     video_view_->OpenVideo();
    464   } else if (!ContentVideoView::HasContentVideoView()) {
    465     // In Android WebView, two ContentViewCores could both try to enter
    466     // fullscreen video, we just ignore the second one.
    467     fullscreen_player_id_ = player_id;
    468     ContentViewCoreImpl* content_view_core_impl =
    469         ContentViewCoreImpl::FromWebContents(web_contents());
    470     video_view_.reset(new ContentVideoView(content_view_core_impl->GetContext(),
    471         content_view_core_impl->GetContentVideoViewClient(), this));
    472   }
    473 }
    474 
    475 void BrowserMediaPlayerManager::OnExitFullscreen(int player_id) {
    476   if (fullscreen_player_id_ == player_id) {
    477     MediaPlayerAndroid* player = GetPlayer(player_id);
    478     if (player)
    479       player->SetVideoSurface(gfx::ScopedJavaSurface());
    480     video_view_->OnExitFullscreen();
    481   }
    482 }
    483 
    484 void BrowserMediaPlayerManager::OnInitialize(
    485     MediaPlayerHostMsg_Initialize_Type type,
    486     int player_id,
    487     const GURL& url,
    488     const GURL& first_party_for_cookies,
    489     int demuxer_client_id) {
    490   DCHECK(type != MEDIA_PLAYER_TYPE_MEDIA_SOURCE || demuxer_client_id > 0)
    491       << "Media source players must have positive demuxer client IDs: "
    492       << demuxer_client_id;
    493 
    494   RemovePlayer(player_id);
    495 
    496   RenderProcessHostImpl* host = static_cast<RenderProcessHostImpl*>(
    497       web_contents()->GetRenderProcessHost());
    498   AddPlayer(CreateMediaPlayer(
    499       type, player_id, url, first_party_for_cookies, demuxer_client_id,
    500       host->GetBrowserContext()->IsOffTheRecord(), this,
    501       host->browser_demuxer_android()));
    502 }
    503 
    504 void BrowserMediaPlayerManager::OnStart(int player_id) {
    505   MediaPlayerAndroid* player = GetPlayer(player_id);
    506   if (player)
    507     player->Start();
    508 }
    509 
    510 void BrowserMediaPlayerManager::OnSeek(
    511     int player_id,
    512     const base::TimeDelta& time) {
    513   MediaPlayerAndroid* player = GetPlayer(player_id);
    514   if (player)
    515     player->SeekTo(time);
    516 }
    517 
    518 void BrowserMediaPlayerManager::OnPause(
    519     int player_id,
    520     bool is_media_related_action) {
    521   MediaPlayerAndroid* player = GetPlayer(player_id);
    522   if (player)
    523     player->Pause(is_media_related_action);
    524 }
    525 
    526 void BrowserMediaPlayerManager::OnSetVolume(int player_id, double volume) {
    527   MediaPlayerAndroid* player = GetPlayer(player_id);
    528   if (player)
    529     player->SetVolume(volume);
    530 }
    531 
    532 void BrowserMediaPlayerManager::OnReleaseResources(int player_id) {
    533   MediaPlayerAndroid* player = GetPlayer(player_id);
    534   if (player)
    535     player->Release();
    536   if (player_id == fullscreen_player_id_)
    537     fullscreen_player_is_released_ = true;
    538 
    539 #if defined(VIDEO_HOLE)
    540   WebContentsViewAndroid* view =
    541       static_cast<WebContentsViewAndroid*>(web_contents_->GetView());
    542   if (view)
    543     view->NotifyExternalSurface(player_id, false, gfx::RectF());
    544 #endif  // defined(VIDEO_HOLE)
    545 }
    546 
    547 void BrowserMediaPlayerManager::OnDestroyPlayer(int player_id) {
    548   RemovePlayer(player_id);
    549   if (fullscreen_player_id_ == player_id)
    550     fullscreen_player_id_ = -1;
    551 }
    552 
    553 void BrowserMediaPlayerManager::OnInitializeCDM(
    554     int media_keys_id,
    555     const std::vector<uint8>& uuid,
    556     const GURL& frame_url) {
    557   if (uuid.size() != kEmeUuidSize) {
    558     // This failure will be discovered and reported by OnCreateSession()
    559     // as GetDrmBridge() will return null.
    560     NOTREACHED() << "Invalid UUID for ID: " << media_keys_id;
    561     return;
    562   }
    563 
    564   AddDrmBridge(media_keys_id, uuid, frame_url);
    565   // In EME v0.1b MediaKeys lives in the media element. So the |media_keys_id|
    566   // is the same as the |player_id|.
    567   OnSetMediaKeys(media_keys_id, media_keys_id);
    568 }
    569 
    570 void BrowserMediaPlayerManager::OnCreateSession(
    571     int media_keys_id,
    572     uint32 session_id,
    573     const std::string& type,
    574     const std::vector<uint8>& init_data) {
    575   if (type.length() > kEmeTypeMaximum) {
    576     OnSessionError(
    577         media_keys_id, session_id, media::MediaKeys::kUnknownError, 0);
    578     return;
    579   }
    580   if (init_data.size() > kEmeInitDataMaximum) {
    581     OnSessionError(
    582         media_keys_id, session_id, media::MediaKeys::kUnknownError, 0);
    583     return;
    584   }
    585 
    586   if (CommandLine::ForCurrentProcess()
    587       ->HasSwitch(switches::kDisableInfobarForProtectedMediaIdentifier)) {
    588     GenerateKeyIfAllowed(media_keys_id, session_id, type, init_data, true);
    589     return;
    590   }
    591 
    592   MediaDrmBridge* drm_bridge = GetDrmBridge(media_keys_id);
    593   if (!drm_bridge) {
    594     DLOG(WARNING) << "No MediaDrmBridge for ID: " << media_keys_id << " found";
    595     OnSessionError(
    596         media_keys_id, session_id, media::MediaKeys::kUnknownError, 0);
    597     return;
    598   }
    599 
    600   if (media_keys_ids_approved_.find(media_keys_id) ==
    601       media_keys_ids_approved_.end()) {
    602     media_keys_ids_pending_approval_.insert(media_keys_id);
    603   }
    604   web_contents()->GetDelegate()->RequestProtectedMediaIdentifierPermission(
    605       web_contents(),
    606       drm_bridge->frame_url(),
    607       base::Bind(&BrowserMediaPlayerManager::GenerateKeyIfAllowed,
    608                  weak_ptr_factory_.GetWeakPtr(),
    609                  media_keys_id,
    610                  session_id,
    611                  type,
    612                  init_data));
    613 }
    614 
    615 void BrowserMediaPlayerManager::OnUpdateSession(
    616     int media_keys_id,
    617     uint32 session_id,
    618     const std::vector<uint8>& response) {
    619   MediaDrmBridge* drm_bridge = GetDrmBridge(media_keys_id);
    620   if (!drm_bridge) {
    621     DLOG(WARNING) << "No MediaDrmBridge for ID: " << media_keys_id << " found";
    622     OnSessionError(
    623         media_keys_id, session_id, media::MediaKeys::kUnknownError, 0);
    624     return;
    625   }
    626 
    627   if (response.size() > kEmeResponseMaximum) {
    628     DLOG(WARNING) << "Response for ID: " << media_keys_id
    629                   << " too long: " << response.size();
    630     OnSessionError(
    631         media_keys_id, session_id, media::MediaKeys::kUnknownError, 0);
    632     return;
    633   }
    634 
    635   drm_bridge->UpdateSession(session_id, &response[0], response.size());
    636   // In EME v0.1b MediaKeys lives in the media element. So the |media_keys_id|
    637   // is the same as the |player_id|.
    638   // TODO(xhwang): Separate |media_keys_id| and |player_id|.
    639   MediaPlayerAndroid* player = GetPlayer(media_keys_id);
    640   if (player)
    641     player->OnKeyAdded();
    642 }
    643 
    644 void BrowserMediaPlayerManager::OnReleaseSession(int media_keys_id,
    645                                                  uint32 session_id) {
    646   MediaDrmBridge* drm_bridge = GetDrmBridge(media_keys_id);
    647   if (!drm_bridge) {
    648     DLOG(WARNING) << "No MediaDrmBridge for ID: " << media_keys_id << " found";
    649     OnSessionError(
    650         media_keys_id, session_id, media::MediaKeys::kUnknownError, 0);
    651     return;
    652   }
    653 
    654   drm_bridge->ReleaseSession(session_id);
    655 }
    656 
    657 void BrowserMediaPlayerManager::AddPlayer(MediaPlayerAndroid* player) {
    658   DCHECK(!GetPlayer(player->player_id()));
    659   players_.push_back(player);
    660   if (player->IsRemote()) {
    661     Send(new MediaPlayerMsg_ConnectedToRemoteDevice(routing_id(),
    662                                                     player->player_id()));
    663   }
    664 }
    665 
    666 void BrowserMediaPlayerManager::RemovePlayer(int player_id) {
    667   for (ScopedVector<MediaPlayerAndroid>::iterator it = players_.begin();
    668       it != players_.end(); ++it) {
    669     MediaPlayerAndroid* player = *it;
    670     if (player->player_id() == player_id) {
    671       if (player->IsRemote()) {
    672         Send(new MediaPlayerMsg_DisconnectedFromRemoteDevice(
    673             routing_id(), player->player_id()));
    674       }
    675       players_.erase(it);
    676       break;
    677     }
    678   }
    679 }
    680 
    681 scoped_ptr<media::MediaPlayerAndroid> BrowserMediaPlayerManager::SwapPlayer(
    682       int player_id, media::MediaPlayerAndroid* player) {
    683   media::MediaPlayerAndroid* previous_player = NULL;
    684   for (ScopedVector<MediaPlayerAndroid>::iterator it = players_.begin();
    685       it != players_.end(); ++it) {
    686     if ((*it)->player_id() == player_id) {
    687       previous_player = *it;
    688       players_.weak_erase(it);
    689       players_.push_back(player);
    690       if (!previous_player->IsRemote() && player->IsRemote()) {
    691         Send(new MediaPlayerMsg_ConnectedToRemoteDevice(
    692             routing_id(), player->player_id()));
    693       } else if (previous_player->IsRemote() && !player->IsRemote()) {
    694         Send(new MediaPlayerMsg_DisconnectedFromRemoteDevice(
    695             routing_id(), player->player_id()));
    696       }
    697       break;
    698     }
    699   }
    700   return scoped_ptr<media::MediaPlayerAndroid>(previous_player);
    701 }
    702 
    703 void BrowserMediaPlayerManager::AddDrmBridge(int media_keys_id,
    704                                              const std::vector<uint8>& uuid,
    705                                              const GURL& frame_url) {
    706   DCHECK(!GetDrmBridge(media_keys_id));
    707   // TODO(xhwang/ddorwin): Pass the security level from key system.
    708   std::string security_level = "L3";
    709   if (CommandLine::ForCurrentProcess()
    710           ->HasSwitch(switches::kMediaDrmEnableNonCompositing)) {
    711     security_level = "L1";
    712   }
    713 
    714   scoped_ptr<MediaDrmBridge> drm_bridge(MediaDrmBridge::Create(
    715       media_keys_id, uuid, frame_url, security_level, this));
    716   if (!drm_bridge) {
    717     // This failure will be discovered and reported by OnCreateSession()
    718     // as GetDrmBridge() will return null.
    719     DVLOG(1) << "failed to create drm bridge.";
    720     return;
    721   }
    722 
    723   drm_bridges_.push_back(drm_bridge.release());
    724 }
    725 
    726 void BrowserMediaPlayerManager::RemoveDrmBridge(int media_keys_id) {
    727   for (ScopedVector<MediaDrmBridge>::iterator it = drm_bridges_.begin();
    728       it != drm_bridges_.end(); ++it) {
    729     if ((*it)->media_keys_id() == media_keys_id) {
    730       drm_bridges_.erase(it);
    731       break;
    732     }
    733   }
    734 }
    735 
    736 void BrowserMediaPlayerManager::OnSetMediaKeys(int player_id,
    737                                                int media_keys_id) {
    738   MediaPlayerAndroid* player = GetPlayer(player_id);
    739   MediaDrmBridge* drm_bridge = GetDrmBridge(media_keys_id);
    740   if (!player || !drm_bridge) {
    741     DVLOG(1) << "OnSetMediaKeys(): Player and MediaKeys must be present.";
    742     return;
    743   }
    744   // TODO(qinmin): add the logic to decide whether we should create the
    745   // fullscreen surface for EME lv1.
    746   player->SetDrmBridge(drm_bridge);
    747 }
    748 
    749 void BrowserMediaPlayerManager::GenerateKeyIfAllowed(
    750     int media_keys_id,
    751     uint32 session_id,
    752     const std::string& type,
    753     const std::vector<uint8>& init_data,
    754     bool allowed) {
    755   if (!allowed)
    756     return;
    757 
    758   MediaDrmBridge* drm_bridge = GetDrmBridge(media_keys_id);
    759   if (!drm_bridge) {
    760     DLOG(WARNING) << "No MediaDrmBridge for ID: " << media_keys_id << " found";
    761     OnSessionError(
    762         media_keys_id, session_id, media::MediaKeys::kUnknownError, 0);
    763     return;
    764   }
    765   media_keys_ids_pending_approval_.erase(media_keys_id);
    766   media_keys_ids_approved_.insert(media_keys_id);
    767   drm_bridge->CreateSession(session_id, type, &init_data[0], init_data.size());
    768 
    769   // TODO(qinmin): currently |media_keys_id| and player ID are identical.
    770   // This might not be true in the future.
    771   if (pending_fullscreen_player_id_ != media_keys_id)
    772     return;
    773 
    774   pending_fullscreen_player_id_ = -1;
    775   MediaPlayerAndroid* player = GetPlayer(media_keys_id);
    776   if (player->IsPlaying())
    777     OnProtectedSurfaceRequested(media_keys_id);
    778 }
    779 
    780 }  // namespace content
    781