Index: content/browser/media/android/media_web_contents_observer_android.cc |
diff --git a/content/browser/media/android/media_web_contents_observer_android.cc b/content/browser/media/android/media_web_contents_observer_android.cc |
index 80137aa31a5619882a5898f3db01d43a0d3d2e6a..f9415b1dfca49c8a946887915ac56b7585f740b1 100644 |
--- a/content/browser/media/android/media_web_contents_observer_android.cc |
+++ b/content/browser/media/android/media_web_contents_observer_android.cc |
@@ -4,12 +4,14 @@ |
#include "content/browser/media/android/media_web_contents_observer_android.h" |
+#include "base/callback.h" |
#include "content/browser/media/android/browser_media_player_manager.h" |
#include "content/browser/media/android/browser_media_session_manager.h" |
#include "content/browser/media/android/media_session.h" |
#include "content/browser/media/android/media_session_observer.h" |
#include "content/browser/media/cdm/browser_cdm_manager.h" |
#include "content/browser/web_contents/web_contents_impl.h" |
+#include "content/common/frame_messages.h" |
#include "content/common/media/media_player_messages_android.h" |
#include "content/common/media/media_session_messages_android.h" |
#include "content/public/browser/render_frame_host.h" |
@@ -48,12 +50,15 @@ class MediaSessionController : public MediaSessionObserver { |
return false; |
} |
+ initialized_ = true; |
return true; |
} |
~MediaSessionController() { |
- MediaSession::Get(media_web_contents_observer_->web_contents()) |
- ->RemovePlayer(this, player_id_); |
+ if (initialized_) { |
+ MediaSession::Get(media_web_contents_observer_->web_contents()) |
+ ->RemovePlayer(this, player_id_); |
+ } |
} |
void OnSuspend(int player_id) { |
@@ -81,7 +86,7 @@ class MediaSessionController : public MediaSessionObserver { |
const WebContentsObserver::MediaPlayerId id_; |
MediaWebContentsObserver* const media_web_contents_observer_; |
int player_id_ = 0; |
- bool initialize_failed_ = false; |
+ bool initialized_ = false; |
DISALLOW_COPY_AND_ASSIGN(MediaSessionController); |
}; |
@@ -90,10 +95,7 @@ MediaWebContentsObserverAndroid::MediaWebContentsObserverAndroid( |
WebContents* web_contents) |
: MediaWebContentsObserver(web_contents) {} |
-MediaWebContentsObserverAndroid::~MediaWebContentsObserverAndroid() { |
- // Clear active sessions before destructing the observer. |
- media_session_map_.clear(); |
-} |
+MediaWebContentsObserverAndroid::~MediaWebContentsObserverAndroid() {} |
// static |
MediaWebContentsObserverAndroid* |
@@ -129,6 +131,20 @@ MediaWebContentsObserverAndroid::GetMediaSessionManager( |
return manager; |
} |
+// static |
+void MediaWebContentsObserverAndroid::CheckFocus( |
+ int render_frame_id, |
+ const base::Closure& on_focus_cb) { |
+ for (const auto& kv : media_session_map_) { |
+ if (kv.first.first->GetRoutingID() == render_frame_id) { |
+ on_focus_cb.Run(); |
+ return; |
+ } |
+ } |
+ |
+ deferred_focus_cbs_[render_frame_id].push_back(on_focus_cb); |
+} |
+ |
#if defined(VIDEO_HOLE) |
void MediaWebContentsObserverAndroid::OnFrameInfoUpdated() { |
for (auto it = media_player_managers_.begin(); |
@@ -142,6 +158,13 @@ void MediaWebContentsObserverAndroid::RenderFrameDeleted( |
RenderFrameHost* render_frame_host) { |
MediaWebContentsObserver::RenderFrameDeleted(render_frame_host); |
+ for (auto it = media_session_map_.begin(); it != media_session_map_.end();) { |
+ if (it->first.first == render_frame_host) |
+ it = media_session_map_.erase(it); |
+ else |
+ ++it; |
+ } |
+ |
// Always destroy the media players before CDMs because we do not support |
// detaching CDMs from media players yet. See http://crbug.com/330324 |
media_player_managers_.erase(render_frame_host); |
@@ -149,7 +172,7 @@ void MediaWebContentsObserverAndroid::RenderFrameDeleted( |
// TODO(xhwang): Currently MediaWebContentsObserver, BrowserMediaPlayerManager |
// and BrowserCdmManager all run on browser UI thread. So this call is okay. |
- // In the future we need to support the case where MediaWebContentsObserver |
+ // In the future we need to support the ~case where MediaWebContentsObserver |
// get notified on browser UI thread, but BrowserMediaPlayerManager and |
// BrowserCdmManager run on a different thread. |
BrowserCdmManager* browser_cdm_manager = |
@@ -291,6 +314,7 @@ void MediaWebContentsObserverAndroid::OnMediaDestroyedNotification( |
RenderFrameHost* render_frame_host, |
int64_t player_cookie) { |
media_session_map_.erase(MediaPlayerId(render_frame_host, player_cookie)); |
+ deferred_focus_cbs_.erase(render_frame_host->GetRoutingID()); |
} |
void MediaWebContentsObserverAndroid::OnMediaPlayingNotification( |
@@ -314,6 +338,14 @@ void MediaWebContentsObserverAndroid::OnMediaPlayingNotification( |
return; |
media_session_map_[id] = std::move(controller); |
+ |
+ // Notify any deferred focus callbacks. |
+ auto it = deferred_focus_cbs_.find(render_frame_host->GetRoutingID()); |
+ if (it != deferred_focus_cbs_.end()) { |
+ for (const auto& cb : it->second) |
+ cb.Run(); |
+ deferred_focus_cbs_.erase(it); |
+ } |
} |
void MediaWebContentsObserverAndroid::OnMediaPausedNotification( |