Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // 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
| |
| 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 "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.
| |
| 6 #include "chrome/browser/android/tab_android.h" | |
| 7 #include "chrome/common/chrome_content_client.h" | |
| 8 #include "content/common/media/media_player_messages_android.h" | |
| 9 #include "third_party/skia/include/core/SkBitmap.h" | |
| 10 #include "ui/gfx/android/java_bitmap.h" | |
| 11 | |
| 12 using media::MediaPlayerAndroid; | |
| 13 | |
| 14 namespace remote_media { | |
| 15 | |
| 16 RemoteMediaPlayerManager::RemoteMediaPlayerManager( | |
| 17 content::RenderFrameHost* render_frame_host) | |
| 18 : BrowserMediaPlayerManager(render_frame_host), | |
| 19 weak_ptr_factory_(this) { | |
| 20 } | |
| 21 | |
| 22 RemoteMediaPlayerManager::~RemoteMediaPlayerManager() {} | |
| 23 | |
| 24 void RemoteMediaPlayerManager::OnStart(int player_id) { | |
| 25 if (MaybeStartPlayingRemotely(player_id)) | |
| 26 return; | |
| 27 | |
| 28 ReplaceRemotePlayerWithLocal(); | |
| 29 BrowserMediaPlayerManager::OnStart(player_id); | |
| 30 } | |
| 31 | |
| 32 void RemoteMediaPlayerManager::OnInitialize( | |
| 33 const MediaPlayerHostMsg_Initialize_Params& media_params) { | |
| 34 BrowserMediaPlayerManager::OnInitialize(media_params); | |
| 35 | |
| 36 MediaPlayerAndroid* player = GetPlayer(media_params.player_id); | |
| 37 if (player) { | |
| 38 CreateRemoteMediaPlayer(player); | |
| 39 RemoteMediaPlayerBridge* remote_player = GetRemotePlayer( | |
| 40 media_params.player_id); | |
| 41 if (remote_player) | |
| 42 remote_player->OnPlayerCreated(); | |
| 43 } | |
| 44 } | |
| 45 | |
| 46 void RemoteMediaPlayerManager::OnDestroyPlayer(int player_id) { | |
| 47 RemoteMediaPlayerBridge* player = GetRemotePlayer(player_id); | |
| 48 if (player) | |
| 49 player->OnPlayerDestroyed(); | |
| 50 BrowserMediaPlayerManager::OnDestroyPlayer(player_id); | |
| 51 } | |
| 52 | |
| 53 void RemoteMediaPlayerManager::OnReleaseResources(int player_id) { | |
| 54 // We only want to release resources of local players. | |
| 55 if (player_id != RemotePlayerId()) | |
| 56 BrowserMediaPlayerManager::OnReleaseResources(player_id); | |
| 57 } | |
| 58 | |
| 59 void RemoteMediaPlayerManager::OnRequestRemotePlayback(int player_id) { | |
| 60 RemoteMediaPlayerBridge* player = GetRemotePlayer(player_id); | |
| 61 if (player) | |
| 62 player->RequestRemotePlayback(); | |
| 63 } | |
| 64 | |
| 65 void RemoteMediaPlayerManager::OnRequestRemotePlaybackControl(int player_id) { | |
| 66 RemoteMediaPlayerBridge* player = GetRemotePlayer(player_id); | |
| 67 if (player) | |
| 68 player->RequestRemotePlaybackControl(); | |
| 69 } | |
| 70 | |
| 71 int RemoteMediaPlayerManager::GetTabId() { | |
| 72 if (!web_contents()) | |
| 73 return -1; | |
| 74 | |
| 75 TabAndroid* tab = TabAndroid::FromWebContents(web_contents()); | |
| 76 if (!tab) | |
| 77 return -1; | |
| 78 | |
| 79 return tab->GetAndroidId(); | |
| 80 } | |
| 81 | |
| 82 void RemoteMediaPlayerManager::OnSetPoster(int player_id, const GURL& url) { | |
| 83 RemoteMediaPlayerBridge* player = GetRemotePlayer(player_id); | |
| 84 | |
| 85 if (player && url.is_empty()) { | |
| 86 player->SetPosterBitmap(std::vector<SkBitmap>()); | |
| 87 } else { | |
| 88 // TODO(aberent) OnSetPoster is called when the attributes of the video | |
| 89 // element are parsed, which may be before OnInitialize is called. We are | |
| 90 // here relying on the image fetch taking longer than the delay until | |
| 91 // OnInitialize is called, and hence the player is created. This is not | |
| 92 // guaranteed. | |
| 93 content::WebContents::ImageDownloadCallback callback = base::Bind( | |
| 94 &RemoteMediaPlayerManager::DidDownloadPoster, | |
| 95 weak_ptr_factory_.GetWeakPtr(), player_id); | |
| 96 web_contents()->DownloadImage( | |
| 97 url, | |
| 98 false, // is_favicon, false so that cookies will be used. | |
| 99 0, // max_bitmap_size, 0 means no limit. | |
| 100 callback); | |
| 101 } | |
| 102 } | |
| 103 | |
| 104 void RemoteMediaPlayerManager::DidDownloadPoster( | |
| 105 int player_id, | |
| 106 int id, | |
| 107 int http_status_code, | |
| 108 const GURL& image_url, | |
| 109 const std::vector<SkBitmap>& bitmaps, | |
| 110 const std::vector<gfx::Size>& original_bitmap_sizes) { | |
| 111 RemoteMediaPlayerBridge* player = GetRemotePlayer(player_id); | |
| 112 if (player) | |
| 113 player->SetPosterBitmap(bitmaps); | |
| 114 } | |
| 115 | |
| 116 RemoteMediaPlayerBridge* RemoteMediaPlayerManager::CreateRemoteMediaPlayer( | |
| 117 MediaPlayerAndroid* local_player) { | |
| 118 RemoteMediaPlayerBridge* player = new RemoteMediaPlayerBridge( | |
| 119 local_player, | |
| 120 GetUserAgent(), | |
| 121 false, | |
| 122 this); | |
| 123 remote_players_.push_back(player); | |
| 124 player->Initialize(); | |
| 125 return player; | |
| 126 } | |
| 127 | |
| 128 int RemoteMediaPlayerManager::RemotePlayerId() { | |
| 129 // The remote player is created with the same id as the corresponding local | |
| 130 // player. | |
| 131 if (replaced_local_player_.get()) { | |
| 132 return replaced_local_player_->player_id(); | |
| 133 } else { | |
| 134 return -1; | |
| 135 } | |
| 136 } | |
| 137 | |
| 138 void RemoteMediaPlayerManager::ReplaceLocalPlayerWithRemote( | |
| 139 MediaPlayerAndroid* player) { | |
| 140 if (!player) | |
| 141 return; | |
| 142 | |
| 143 int player_id = player->player_id(); | |
| 144 if (player_id == RemotePlayerId()) { | |
| 145 // The player is already remote. | |
| 146 return; | |
| 147 } | |
| 148 | |
| 149 // Before we replace the new remote player, put the old local player back | |
| 150 // in its place. | |
| 151 ReplaceRemotePlayerWithLocal(); | |
| 152 | |
| 153 // Pause the local player first before replacing it. This will allow the local | |
| 154 // player to reset its state, such as the PowerSaveBlocker. | |
| 155 // We have to pause locally as well as telling the renderer to pause, because | |
| 156 // by the time the renderer comes back to us telling us to pause we will have | |
| 157 // switched players. | |
| 158 player->Pause(true); | |
| 159 Send(new MediaPlayerMsg_DidMediaPlayerPause(RoutingID(), player_id)); | |
| 160 | |
| 161 // Find the remote player | |
| 162 for (auto it = remote_players_.begin(); it != remote_players_.end(); ++it) { | |
| 163 if ((*it)->player_id() == player_id) { | |
| 164 replaced_local_player_ = SwapPlayer(player_id, *it); | |
| 165 | |
| 166 // Seek to the previous player's position. | |
| 167 (*it)->SeekTo(player->GetCurrentTime()); | |
| 168 | |
| 169 // SwapPlayers takes ownership, so we have to remove the remote player | |
| 170 // from the vector. | |
| 171 remote_players_.weak_erase(it); | |
| 172 break; | |
| 173 } | |
| 174 } | |
| 175 } | |
| 176 | |
| 177 void RemoteMediaPlayerManager::ReplaceRemotePlayerWithLocal() { | |
| 178 int player_id = RemotePlayerId(); | |
| 179 if (player_id == -1) | |
| 180 return; | |
| 181 | |
| 182 Send(new MediaPlayerMsg_DidMediaPlayerPause(RoutingID(), player_id)); | |
| 183 Send(new MediaPlayerMsg_DisconnectedFromRemoteDevice(RoutingID(), player_id)); | |
| 184 | |
| 185 scoped_ptr<MediaPlayerAndroid> remote_player = | |
| 186 SwapPlayer(player_id, replaced_local_player_.release()); | |
| 187 if (remote_player) { | |
| 188 // Seek to the previous player's position. | |
| 189 GetPlayer(player_id)->SeekTo(remote_player->GetCurrentTime()); | |
| 190 | |
| 191 remote_player->Release(); | |
| 192 // Add the remote player back into the list | |
| 193 remote_players_.push_back( | |
| 194 static_cast<RemoteMediaPlayerBridge *>(remote_player.release())); | |
| 195 } | |
| 196 } | |
| 197 | |
| 198 bool RemoteMediaPlayerManager::MaybeStartPlayingRemotely(int player_id) { | |
| 199 MediaPlayerAndroid* player = GetPlayer(player_id); | |
| 200 if (!player) | |
| 201 return false; | |
| 202 | |
| 203 RemoteMediaPlayerBridge* remote_player = GetRemotePlayer(player_id); | |
| 204 | |
| 205 if (!remote_player) | |
| 206 return false; | |
| 207 | |
| 208 if (remote_player->IsMediaPlayableRemotely() && | |
| 209 remote_player->IsRemotePlaybackAvailable() && | |
| 210 remote_player->IsRemotePlaybackPreferredForFrame()) { | |
| 211 ReplaceLocalPlayerWithRemote(player); | |
| 212 | |
| 213 remote_player->SetNativePlayer(); | |
| 214 remote_player->Start(); | |
| 215 | |
| 216 Send(new MediaPlayerMsg_DidMediaPlayerPlay(RoutingID(), player_id)); | |
| 217 | |
| 218 Send(new MediaPlayerMsg_ConnectedToRemoteDevice( | |
| 219 RoutingID(), | |
| 220 player_id, | |
| 221 remote_player->GetCastingMessage())); | |
| 222 | |
| 223 return true; | |
| 224 } | |
| 225 | |
| 226 return false; | |
| 227 } | |
| 228 | |
| 229 void RemoteMediaPlayerManager::OnRemoteDeviceSelected(int player_id) { | |
| 230 | |
| 231 MediaPlayerAndroid* player = GetPlayer(player_id); | |
| 232 if (!player) | |
| 233 return; | |
| 234 | |
| 235 if (MaybeStartPlayingRemotely(player_id)) | |
| 236 return; | |
| 237 OnStart(player_id); | |
| 238 } | |
| 239 | |
| 240 void RemoteMediaPlayerManager::OnRemoteDeviceUnselected(int player_id) { | |
| 241 if (player_id == RemotePlayerId()) | |
| 242 ReplaceRemotePlayerWithLocal(); | |
| 243 } | |
| 244 | |
| 245 void RemoteMediaPlayerManager::OnRemotePlaybackFinished(int player_id) { | |
| 246 if (player_id == RemotePlayerId()) | |
| 247 ReplaceRemotePlayerWithLocal(); | |
| 248 } | |
| 249 | |
| 250 void RemoteMediaPlayerManager::OnRouteAvailabilityChanged( | |
| 251 int player_id, bool routes_available) { | |
| 252 Send( | |
| 253 new MediaPlayerMsg_RemoteRouteAvailabilityChanged(RoutingID(), player_id, | |
| 254 routes_available)); | |
| 255 } | |
| 256 | |
| 257 void RemoteMediaPlayerManager::ReleaseFullscreenPlayer( | |
| 258 MediaPlayerAndroid* player) { | |
| 259 // Release the original player's resources, not the current fullscreen player | |
| 260 // (which is the remote player). | |
| 261 if (replaced_local_player_.get()) | |
| 262 replaced_local_player_->Release(); | |
| 263 else | |
| 264 BrowserMediaPlayerManager::ReleaseFullscreenPlayer(player); | |
| 265 } | |
| 266 | |
| 267 void RemoteMediaPlayerManager::OnPlaying(int player_id) { | |
| 268 Send(new MediaPlayerMsg_DidMediaPlayerPlay(RoutingID(),player_id)); | |
| 269 } | |
| 270 | |
| 271 void RemoteMediaPlayerManager::OnPaused(int player_id) { | |
| 272 Send(new MediaPlayerMsg_DidMediaPlayerPause(RoutingID(),player_id)); | |
| 273 } | |
| 274 | |
| 275 RemoteMediaPlayerBridge* RemoteMediaPlayerManager::GetRemotePlayer( | |
| 276 int player_id) { | |
| 277 if (player_id == RemotePlayerId()) { | |
| 278 return static_cast<RemoteMediaPlayerBridge*>(GetPlayer(player_id)); | |
| 279 } else { | |
| 280 for (RemoteMediaPlayerBridge* player : remote_players_) { | |
| 281 if (player->player_id() == player_id) { | |
| 282 return player; | |
| 283 } | |
| 284 } | |
| 285 return nullptr; | |
| 286 } | |
| 287 } | |
| 288 | |
| 289 void RemoteMediaPlayerManager::OnMediaMetadataChanged(int player_id, | |
| 290 base::TimeDelta duration, | |
| 291 int width, int height, | |
| 292 bool success) { | |
| 293 if (player_id == RemotePlayerId() && replaced_local_player_.get()) { | |
| 294 Send( | |
| 295 new MediaPlayerMsg_MediaMetadataChanged( | |
| 296 RoutingID(), player_id, duration, | |
| 297 replaced_local_player_->GetVideoWidth(), | |
| 298 replaced_local_player_->GetVideoHeight(), success)); | |
| 299 } else { | |
| 300 BrowserMediaPlayerManager::OnMediaMetadataChanged(player_id, duration, | |
| 301 width, height, success); | |
| 302 } | |
| 303 } | |
| 304 } // namespace remote_media | |
|
whywhat
2015/02/25 16:31:32
blank line before the namespace closing?
aberent
2015/03/11 18:29:58
Done.
| |
| OLD | NEW |