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

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

Powered by Google App Engine
This is Rietveld 408576698