Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2837)

Unified Diff: chrome/browser/media/android/remote/remote_media_player_manager.cc

Issue 928643003: Upstream Chrome for Android Cast. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/media/android/remote/remote_media_player_manager.cc
diff --git a/chrome/browser/media/android/remote/remote_media_player_manager.cc b/chrome/browser/media/android/remote/remote_media_player_manager.cc
new file mode 100644
index 0000000000000000000000000000000000000000..9b9c9d2ac3c54c8532de25fefc2655e0bf4101da
--- /dev/null
+++ b/chrome/browser/media/android/remote/remote_media_player_manager.cc
@@ -0,0 +1,304 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
whywhat 2015/02/25 16:31:32 Do we want to update the year in the added files,
aberent 2015/03/10 18:46:47 I don't think so. Copyright normally is about the
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/media/android/remote/remote_media_player_manager.h"
whywhat 2015/02/25 16:31:32 insert a blank line after the class header file
aberent 2015/03/11 18:29:58 Done.
+#include "chrome/browser/android/tab_android.h"
+#include "chrome/common/chrome_content_client.h"
+#include "content/common/media/media_player_messages_android.h"
+#include "third_party/skia/include/core/SkBitmap.h"
+#include "ui/gfx/android/java_bitmap.h"
+
+using media::MediaPlayerAndroid;
+
+namespace remote_media {
+
+RemoteMediaPlayerManager::RemoteMediaPlayerManager(
+ content::RenderFrameHost* render_frame_host)
+ : BrowserMediaPlayerManager(render_frame_host),
+ weak_ptr_factory_(this) {
+}
+
+RemoteMediaPlayerManager::~RemoteMediaPlayerManager() {}
+
+void RemoteMediaPlayerManager::OnStart(int player_id) {
+ if (MaybeStartPlayingRemotely(player_id))
+ return;
+
+ ReplaceRemotePlayerWithLocal();
+ BrowserMediaPlayerManager::OnStart(player_id);
+}
+
+void RemoteMediaPlayerManager::OnInitialize(
+ const MediaPlayerHostMsg_Initialize_Params& media_params) {
+ BrowserMediaPlayerManager::OnInitialize(media_params);
+
+ MediaPlayerAndroid* player = GetPlayer(media_params.player_id);
+ if (player) {
+ CreateRemoteMediaPlayer(player);
+ RemoteMediaPlayerBridge* remote_player = GetRemotePlayer(
+ media_params.player_id);
+ if (remote_player)
+ remote_player->OnPlayerCreated();
+ }
+}
+
+void RemoteMediaPlayerManager::OnDestroyPlayer(int player_id) {
+ RemoteMediaPlayerBridge* player = GetRemotePlayer(player_id);
+ if (player)
+ player->OnPlayerDestroyed();
+ BrowserMediaPlayerManager::OnDestroyPlayer(player_id);
+}
+
+void RemoteMediaPlayerManager::OnReleaseResources(int player_id) {
+ // We only want to release resources of local players.
+ if (player_id != RemotePlayerId())
+ BrowserMediaPlayerManager::OnReleaseResources(player_id);
+}
+
+void RemoteMediaPlayerManager::OnRequestRemotePlayback(int player_id) {
+ RemoteMediaPlayerBridge* player = GetRemotePlayer(player_id);
+ if (player)
+ player->RequestRemotePlayback();
+}
+
+void RemoteMediaPlayerManager::OnRequestRemotePlaybackControl(int player_id) {
+ RemoteMediaPlayerBridge* player = GetRemotePlayer(player_id);
+ if (player)
+ player->RequestRemotePlaybackControl();
+}
+
+int RemoteMediaPlayerManager::GetTabId() {
+ if (!web_contents())
+ return -1;
+
+ TabAndroid* tab = TabAndroid::FromWebContents(web_contents());
+ if (!tab)
+ return -1;
+
+ return tab->GetAndroidId();
+}
+
+void RemoteMediaPlayerManager::OnSetPoster(int player_id, const GURL& url) {
+ RemoteMediaPlayerBridge* player = GetRemotePlayer(player_id);
+
+ if (player && url.is_empty()) {
+ player->SetPosterBitmap(std::vector<SkBitmap>());
+ } else {
+ // TODO(aberent) OnSetPoster is called when the attributes of the video
+ // element are parsed, which may be before OnInitialize is called. We are
+ // here relying on the image fetch taking longer than the delay until
+ // OnInitialize is called, and hence the player is created. This is not
+ // guaranteed.
+ content::WebContents::ImageDownloadCallback callback = base::Bind(
+ &RemoteMediaPlayerManager::DidDownloadPoster,
+ weak_ptr_factory_.GetWeakPtr(), player_id);
+ web_contents()->DownloadImage(
+ url,
+ false, // is_favicon, false so that cookies will be used.
+ 0, // max_bitmap_size, 0 means no limit.
+ callback);
+ }
+}
+
+void RemoteMediaPlayerManager::DidDownloadPoster(
+ int player_id,
+ int id,
+ int http_status_code,
+ const GURL& image_url,
+ const std::vector<SkBitmap>& bitmaps,
+ const std::vector<gfx::Size>& original_bitmap_sizes) {
+ RemoteMediaPlayerBridge* player = GetRemotePlayer(player_id);
+ if (player)
+ player->SetPosterBitmap(bitmaps);
+}
+
+RemoteMediaPlayerBridge* RemoteMediaPlayerManager::CreateRemoteMediaPlayer(
+ MediaPlayerAndroid* local_player) {
+ RemoteMediaPlayerBridge* player = new RemoteMediaPlayerBridge(
+ local_player,
+ GetUserAgent(),
+ false,
+ this);
+ remote_players_.push_back(player);
+ player->Initialize();
+ return player;
+}
+
+int RemoteMediaPlayerManager::RemotePlayerId() {
+ // The remote player is created with the same id as the corresponding local
+ // player.
+ if (replaced_local_player_.get()) {
+ return replaced_local_player_->player_id();
+ } else {
+ return -1;
+ }
+}
+
+void RemoteMediaPlayerManager::ReplaceLocalPlayerWithRemote(
+ MediaPlayerAndroid* player) {
+ if (!player)
+ return;
+
+ int player_id = player->player_id();
+ if (player_id == RemotePlayerId()) {
+ // The player is already remote.
+ return;
+ }
+
+ // Before we replace the new remote player, put the old local player back
+ // in its place.
+ ReplaceRemotePlayerWithLocal();
+
+ // Pause the local player first before replacing it. This will allow the local
+ // player to reset its state, such as the PowerSaveBlocker.
+ // We have to pause locally as well as telling the renderer to pause, because
+ // by the time the renderer comes back to us telling us to pause we will have
+ // switched players.
+ player->Pause(true);
+ Send(new MediaPlayerMsg_DidMediaPlayerPause(RoutingID(), player_id));
+
+ // Find the remote player
+ for (auto it = remote_players_.begin(); it != remote_players_.end(); ++it) {
+ if ((*it)->player_id() == player_id) {
+ replaced_local_player_ = SwapPlayer(player_id, *it);
+
+ // Seek to the previous player's position.
+ (*it)->SeekTo(player->GetCurrentTime());
+
+ // SwapPlayers takes ownership, so we have to remove the remote player
+ // from the vector.
+ remote_players_.weak_erase(it);
+ break;
+ }
+ }
+}
+
+void RemoteMediaPlayerManager::ReplaceRemotePlayerWithLocal() {
+ int player_id = RemotePlayerId();
+ if (player_id == -1)
+ return;
+
+ Send(new MediaPlayerMsg_DidMediaPlayerPause(RoutingID(), player_id));
+ Send(new MediaPlayerMsg_DisconnectedFromRemoteDevice(RoutingID(), player_id));
+
+ scoped_ptr<MediaPlayerAndroid> remote_player =
+ SwapPlayer(player_id, replaced_local_player_.release());
+ if (remote_player) {
+ // Seek to the previous player's position.
+ GetPlayer(player_id)->SeekTo(remote_player->GetCurrentTime());
+
+ remote_player->Release();
+ // Add the remote player back into the list
+ remote_players_.push_back(
+ static_cast<RemoteMediaPlayerBridge *>(remote_player.release()));
+ }
+}
+
+bool RemoteMediaPlayerManager::MaybeStartPlayingRemotely(int player_id) {
+ MediaPlayerAndroid* player = GetPlayer(player_id);
+ if (!player)
+ return false;
+
+ RemoteMediaPlayerBridge* remote_player = GetRemotePlayer(player_id);
+
+ if (!remote_player)
+ return false;
+
+ if (remote_player->IsMediaPlayableRemotely() &&
+ remote_player->IsRemotePlaybackAvailable() &&
+ remote_player->IsRemotePlaybackPreferredForFrame()) {
+ ReplaceLocalPlayerWithRemote(player);
+
+ remote_player->SetNativePlayer();
+ remote_player->Start();
+
+ Send(new MediaPlayerMsg_DidMediaPlayerPlay(RoutingID(), player_id));
+
+ Send(new MediaPlayerMsg_ConnectedToRemoteDevice(
+ RoutingID(),
+ player_id,
+ remote_player->GetCastingMessage()));
+
+ return true;
+ }
+
+ return false;
+}
+
+void RemoteMediaPlayerManager::OnRemoteDeviceSelected(int player_id) {
+
+ MediaPlayerAndroid* player = GetPlayer(player_id);
+ if (!player)
+ return;
+
+ if (MaybeStartPlayingRemotely(player_id))
+ return;
+ OnStart(player_id);
+}
+
+void RemoteMediaPlayerManager::OnRemoteDeviceUnselected(int player_id) {
+ if (player_id == RemotePlayerId())
+ ReplaceRemotePlayerWithLocal();
+}
+
+void RemoteMediaPlayerManager::OnRemotePlaybackFinished(int player_id) {
+ if (player_id == RemotePlayerId())
+ ReplaceRemotePlayerWithLocal();
+}
+
+void RemoteMediaPlayerManager::OnRouteAvailabilityChanged(
+ int player_id, bool routes_available) {
+ Send(
+ new MediaPlayerMsg_RemoteRouteAvailabilityChanged(RoutingID(), player_id,
+ routes_available));
+}
+
+void RemoteMediaPlayerManager::ReleaseFullscreenPlayer(
+ MediaPlayerAndroid* player) {
+ // Release the original player's resources, not the current fullscreen player
+ // (which is the remote player).
+ if (replaced_local_player_.get())
+ replaced_local_player_->Release();
+ else
+ BrowserMediaPlayerManager::ReleaseFullscreenPlayer(player);
+}
+
+void RemoteMediaPlayerManager::OnPlaying(int player_id) {
+ Send(new MediaPlayerMsg_DidMediaPlayerPlay(RoutingID(),player_id));
+}
+
+void RemoteMediaPlayerManager::OnPaused(int player_id) {
+ Send(new MediaPlayerMsg_DidMediaPlayerPause(RoutingID(),player_id));
+}
+
+RemoteMediaPlayerBridge* RemoteMediaPlayerManager::GetRemotePlayer(
+ int player_id) {
+ if (player_id == RemotePlayerId()) {
+ return static_cast<RemoteMediaPlayerBridge*>(GetPlayer(player_id));
+ } else {
+ for (RemoteMediaPlayerBridge* player : remote_players_) {
+ if (player->player_id() == player_id) {
+ return player;
+ }
+ }
+ return nullptr;
+ }
+}
+
+void RemoteMediaPlayerManager::OnMediaMetadataChanged(int player_id,
+ base::TimeDelta duration,
+ int width, int height,
+ bool success) {
+ if (player_id == RemotePlayerId() && replaced_local_player_.get()) {
+ Send(
+ new MediaPlayerMsg_MediaMetadataChanged(
+ RoutingID(), player_id, duration,
+ replaced_local_player_->GetVideoWidth(),
+ replaced_local_player_->GetVideoHeight(), success));
+ } else {
+ BrowserMediaPlayerManager::OnMediaMetadataChanged(player_id, duration,
+ width, height, success);
+ }
+}
+} // namespace remote_media
whywhat 2015/02/25 16:31:32 blank line before the namespace closing?
aberent 2015/03/11 18:29:58 Done.

Powered by Google App Engine
This is Rietveld 408576698