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 |