1 // Copyright (c) 2011 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/ui/webui/mediaplayer_ui.h"
6
7 #include "base/command_line.h"
8 #include "base/logging.h"
9 #include "base/memory/singleton.h"
10 #include "base/memory/weak_ptr.h"
11 #include "base/message_loop.h"
12 #include "base/path_service.h"
13 #include "base/string_piece.h"
14 #include "base/string_util.h"
15 #include "base/threading/thread.h"
16 #include "base/time.h"
17 #include "base/values.h"
18 #include "chrome/browser/bookmarks/bookmark_model.h"
19 #include "chrome/browser/download/download_manager.h"
20 #include "chrome/browser/download/download_util.h"
21 #include "chrome/browser/extensions/file_manager_util.h"
22 #include "chrome/browser/history/history_types.h"
23 #include "chrome/browser/metrics/user_metrics.h"
24 #include "chrome/browser/profiles/profile.h"
25 #include "chrome/browser/tabs/tab_strip_model.h"
26 #include "chrome/browser/ui/browser.h"
27 #include "chrome/browser/ui/browser_list.h"
28 #include "chrome/browser/ui/browser_window.h"
29 #include "chrome/browser/ui/webui/favicon_source.h"
30 #include "chrome/common/chrome_paths.h"
31 #include "chrome/common/chrome_switches.h"
32 #include "chrome/common/jstemplate_builder.h"
33 #include "chrome/common/net/url_fetcher.h"
34 #include "chrome/common/time_format.h"
35 #include "chrome/common/url_constants.h"
36 #include "content/browser/browser_thread.h"
37 #include "content/browser/tab_contents/tab_contents.h"
38 #include "grit/browser_resources.h"
39 #include "grit/chromium_strings.h"
40 #include "grit/generated_resources.h"
41 #include "grit/locale_settings.h"
42 #include "net/base/escape.h"
43 #include "net/base/load_flags.h"
44 #include "net/url_request/url_request_job.h"
45 #include "ui/base/resource/resource_bundle.h"
46
47 #if defined(OS_CHROMEOS)
48 #include "chrome/browser/chromeos/frame/panel_browser_view.h"
49 #endif
50
51 static const char kPropertyPath[] = "path";
52 static const char kPropertyForce[] = "force";
53 static const char kPropertyOffset[] = "currentOffset";
54 static const char kPropertyError[] = "error";
55
56 static const char* kMediaplayerURL = "chrome://mediaplayer";
57 static const char* kMediaplayerPlaylistURL = "chrome://mediaplayer#playlist";
58 static const int kPopupLeft = 0;
59 static const int kPopupTop = 0;
60 static const int kPopupWidth = 350;
61 static const int kPopupHeight = 300;
62
63 class MediaplayerUIHTMLSource : public ChromeURLDataManager::DataSource {
64 public:
65 explicit MediaplayerUIHTMLSource(bool is_playlist);
66
67 // Called when the network layer has requested a resource underneath
68 // the path we registered.
69 virtual void StartDataRequest(const std::string& path,
70 bool is_incognito,
71 int request_id);
GetMimeType(const std::string &) const72 virtual std::string GetMimeType(const std::string&) const {
73 return "text/html";
74 }
75
76 private:
~MediaplayerUIHTMLSource()77 ~MediaplayerUIHTMLSource() {}
78 bool is_playlist_;
79
80 DISALLOW_COPY_AND_ASSIGN(MediaplayerUIHTMLSource);
81 };
82
83 // The handler for Javascript messages related to the "mediaplayer" view.
84 class MediaplayerHandler : public WebUIMessageHandler,
85 public base::SupportsWeakPtr<MediaplayerHandler> {
86 public:
87
88 struct MediaUrl {
MediaUrlMediaplayerHandler::MediaUrl89 MediaUrl() {}
MediaUrlMediaplayerHandler::MediaUrl90 explicit MediaUrl(const GURL& newurl)
91 : url(newurl),
92 haderror(false) {}
93 GURL url;
94 bool haderror;
95 };
96 typedef std::vector<MediaUrl> UrlVector;
97
98 explicit MediaplayerHandler(bool is_playlist);
99
100 virtual ~MediaplayerHandler();
101
102 // Init work after Attach.
103 void Init(bool is_playlist, TabContents* contents);
104
105 // WebUIMessageHandler implementation.
106 virtual WebUIMessageHandler* Attach(WebUI* web_ui);
107 virtual void RegisterMessages();
108
109 // Callback for the "currentOffsetChanged" message.
110 void HandleCurrentOffsetChanged(const ListValue* args);
111
112 void FirePlaylistChanged(const std::string& path,
113 bool force,
114 int offset);
115
116 void PlaybackMediaFile(const GURL& url);
117
118 void EnqueueMediaFileUrl(const GURL& url);
119
120 void GetPlaylistValue(ListValue& args);
121
122 // Callback for the "playbackError" message.
123 void HandlePlaybackError(const ListValue* args);
124
125 // Callback for the "getCurrentPlaylist" message.
126 void HandleGetCurrentPlaylist(const ListValue* args);
127
128 void HandleTogglePlaylist(const ListValue* args);
129 void HandleShowPlaylist(const ListValue* args);
130 void HandleSetCurrentPlaylistOffset(const ListValue* args);
131 void HandleToggleFullscreen(const ListValue* args);
132
133 const UrlVector& GetCurrentPlaylist();
134
135 int GetCurrentPlaylistOffset();
136 void SetCurrentPlaylistOffset(int offset);
137 // Sets the playlist for playlist views, since the playlist is
138 // maintained by the mediaplayer itself. Offset is the item in the
139 // playlist which is either now playing, or should be played.
140 void SetCurrentPlaylist(const UrlVector& playlist, int offset);
141
142 private:
143 // The current playlist of urls.
144 UrlVector current_playlist_;
145 // The offset into the current_playlist_ of the currently playing item.
146 int current_offset_;
147 // Indicator of if this handler is a playlist or a mediaplayer.
148 bool is_playlist_;
149 DISALLOW_COPY_AND_ASSIGN(MediaplayerHandler);
150 };
151
152 ////////////////////////////////////////////////////////////////////////////////
153 //
154 // MediaplayerHTMLSource
155 //
156 ////////////////////////////////////////////////////////////////////////////////
157
MediaplayerUIHTMLSource(bool is_playlist)158 MediaplayerUIHTMLSource::MediaplayerUIHTMLSource(bool is_playlist)
159 : DataSource(chrome::kChromeUIMediaplayerHost, MessageLoop::current()) {
160 is_playlist_ = is_playlist;
161 }
162
StartDataRequest(const std::string & path,bool is_incognito,int request_id)163 void MediaplayerUIHTMLSource::StartDataRequest(const std::string& path,
164 bool is_incognito,
165 int request_id) {
166 DictionaryValue localized_strings;
167 // TODO(dhg): Fix the strings that are currently hardcoded so they
168 // use the localized versions.
169 localized_strings.SetString("errorstring", "Error Playing Back");
170
171 SetFontAndTextDirection(&localized_strings);
172
173 std::string full_html;
174
175 static const base::StringPiece mediaplayer_html(
176 ResourceBundle::GetSharedInstance().GetRawDataResource(
177 IDR_MEDIAPLAYER_HTML));
178
179 static const base::StringPiece playlist_html(
180 ResourceBundle::GetSharedInstance().GetRawDataResource(
181 IDR_MEDIAPLAYERPLAYLIST_HTML));
182
183 if (is_playlist_) {
184 full_html = jstemplate_builder::GetI18nTemplateHtml(
185 playlist_html, &localized_strings);
186 } else {
187 full_html = jstemplate_builder::GetI18nTemplateHtml(
188 mediaplayer_html, &localized_strings);
189 }
190
191 scoped_refptr<RefCountedBytes> html_bytes(new RefCountedBytes);
192 html_bytes->data.resize(full_html.size());
193 std::copy(full_html.begin(), full_html.end(), html_bytes->data.begin());
194
195 SendResponse(request_id, html_bytes);
196 }
197
198 ////////////////////////////////////////////////////////////////////////////////
199 //
200 // MediaplayerHandler
201 //
202 ////////////////////////////////////////////////////////////////////////////////
MediaplayerHandler(bool is_playlist)203 MediaplayerHandler::MediaplayerHandler(bool is_playlist)
204 : current_offset_(0),
205 is_playlist_(is_playlist) {
206 }
207
~MediaplayerHandler()208 MediaplayerHandler::~MediaplayerHandler() {
209 }
210
Attach(WebUI * web_ui)211 WebUIMessageHandler* MediaplayerHandler::Attach(WebUI* web_ui) {
212 // Create our favicon data source.
213 Profile* profile = web_ui->GetProfile();
214 profile->GetChromeURLDataManager()->AddDataSource(
215 new FaviconSource(profile));
216
217 return WebUIMessageHandler::Attach(web_ui);
218 }
219
Init(bool is_playlist,TabContents * contents)220 void MediaplayerHandler::Init(bool is_playlist, TabContents* contents) {
221 MediaPlayer* player = MediaPlayer::GetInstance();
222 if (!is_playlist) {
223 player->SetNewHandler(this, contents);
224 } else {
225 player->RegisterNewPlaylistHandler(this, contents);
226 }
227 }
228
RegisterMessages()229 void MediaplayerHandler::RegisterMessages() {
230 web_ui_->RegisterMessageCallback("currentOffsetChanged",
231 NewCallback(this, &MediaplayerHandler::HandleCurrentOffsetChanged));
232 web_ui_->RegisterMessageCallback("playbackError",
233 NewCallback(this, &MediaplayerHandler::HandlePlaybackError));
234 web_ui_->RegisterMessageCallback("getCurrentPlaylist",
235 NewCallback(this, &MediaplayerHandler::HandleGetCurrentPlaylist));
236 web_ui_->RegisterMessageCallback("togglePlaylist",
237 NewCallback(this, &MediaplayerHandler::HandleTogglePlaylist));
238 web_ui_->RegisterMessageCallback("setCurrentPlaylistOffset",
239 NewCallback(this, &MediaplayerHandler::HandleSetCurrentPlaylistOffset));
240 web_ui_->RegisterMessageCallback("toggleFullscreen",
241 NewCallback(this, &MediaplayerHandler::HandleToggleFullscreen));
242 web_ui_->RegisterMessageCallback("showPlaylist",
243 NewCallback(this, &MediaplayerHandler::HandleShowPlaylist));
244 }
245
GetPlaylistValue(ListValue & urls)246 void MediaplayerHandler::GetPlaylistValue(ListValue& urls) {
247 for (size_t x = 0; x < current_playlist_.size(); x++) {
248 DictionaryValue* url_value = new DictionaryValue();
249 url_value->SetString(kPropertyPath, current_playlist_[x].url.spec());
250 url_value->SetBoolean(kPropertyError, current_playlist_[x].haderror);
251 urls.Append(url_value);
252 }
253 }
254
PlaybackMediaFile(const GURL & url)255 void MediaplayerHandler::PlaybackMediaFile(const GURL& url) {
256 current_playlist_.push_back(MediaplayerHandler::MediaUrl(url));
257 FirePlaylistChanged(url.spec(), true, current_playlist_.size() - 1);
258 MediaPlayer::GetInstance()->NotifyPlaylistChanged();
259 }
260
GetCurrentPlaylist()261 const MediaplayerHandler::UrlVector& MediaplayerHandler::GetCurrentPlaylist() {
262 return current_playlist_;
263 }
264
GetCurrentPlaylistOffset()265 int MediaplayerHandler::GetCurrentPlaylistOffset() {
266 return current_offset_;
267 }
268
HandleToggleFullscreen(const ListValue * args)269 void MediaplayerHandler::HandleToggleFullscreen(const ListValue* args) {
270 MediaPlayer::GetInstance()->ToggleFullscreen();
271 }
272
HandleSetCurrentPlaylistOffset(const ListValue * args)273 void MediaplayerHandler::HandleSetCurrentPlaylistOffset(const ListValue* args) {
274 int id;
275 CHECK(ExtractIntegerValue(args, &id));
276 MediaPlayer::GetInstance()->SetPlaylistOffset(id);
277 }
278
FirePlaylistChanged(const std::string & path,bool force,int offset)279 void MediaplayerHandler::FirePlaylistChanged(const std::string& path,
280 bool force,
281 int offset) {
282 DictionaryValue info_value;
283 ListValue urls;
284 GetPlaylistValue(urls);
285 info_value.SetString(kPropertyPath, path);
286 info_value.SetBoolean(kPropertyForce, force);
287 info_value.SetInteger(kPropertyOffset, offset);
288 web_ui_->CallJavascriptFunction("playlistChanged", info_value, urls);
289 }
290
SetCurrentPlaylistOffset(int offset)291 void MediaplayerHandler::SetCurrentPlaylistOffset(int offset) {
292 current_offset_ = offset;
293 FirePlaylistChanged(std::string(), true, current_offset_);
294 }
295
SetCurrentPlaylist(const MediaplayerHandler::UrlVector & playlist,int offset)296 void MediaplayerHandler::SetCurrentPlaylist(
297 const MediaplayerHandler::UrlVector& playlist, int offset) {
298 current_playlist_ = playlist;
299 current_offset_ = offset;
300 FirePlaylistChanged(std::string(), false, current_offset_);
301 }
302
EnqueueMediaFileUrl(const GURL & url)303 void MediaplayerHandler::EnqueueMediaFileUrl(const GURL& url) {
304 current_playlist_.push_back(MediaplayerHandler::MediaUrl(url));
305 FirePlaylistChanged(url.spec(), false, current_offset_);
306 MediaPlayer::GetInstance()->NotifyPlaylistChanged();
307 }
308
HandleCurrentOffsetChanged(const ListValue * args)309 void MediaplayerHandler::HandleCurrentOffsetChanged(const ListValue* args) {
310 CHECK(ExtractIntegerValue(args, ¤t_offset_));
311 MediaPlayer::GetInstance()->NotifyPlaylistChanged();
312 }
313
HandlePlaybackError(const ListValue * args)314 void MediaplayerHandler::HandlePlaybackError(const ListValue* args) {
315 std::string error;
316 std::string url;
317 // Get path string.
318 if (args->GetString(0, &error))
319 LOG(ERROR) << "Playback error" << error;
320 if (args->GetString(1, &url)) {
321 for (size_t x = 0; x < current_playlist_.size(); x++) {
322 if (current_playlist_[x].url == GURL(url)) {
323 current_playlist_[x].haderror = true;
324 }
325 }
326 FirePlaylistChanged(std::string(), false, current_offset_);
327 }
328 }
329
HandleGetCurrentPlaylist(const ListValue * args)330 void MediaplayerHandler::HandleGetCurrentPlaylist(const ListValue* args) {
331 FirePlaylistChanged(std::string(), false, current_offset_);
332 }
333
HandleTogglePlaylist(const ListValue * args)334 void MediaplayerHandler::HandleTogglePlaylist(const ListValue* args) {
335 MediaPlayer::GetInstance()->TogglePlaylistWindowVisible();
336 }
337
HandleShowPlaylist(const ListValue * args)338 void MediaplayerHandler::HandleShowPlaylist(const ListValue* args) {
339 MediaPlayer::GetInstance()->ShowPlaylistWindow();
340 }
341
342 ////////////////////////////////////////////////////////////////////////////////
343 //
344 // Mediaplayer
345 //
346 ////////////////////////////////////////////////////////////////////////////////
347
348 // Allows InvokeLater without adding refcounting. This class is a Singleton and
349 // won't be deleted until it's last InvokeLater is run.
350 DISABLE_RUNNABLE_METHOD_REFCOUNT(MediaPlayer);
351
~MediaPlayer()352 MediaPlayer::~MediaPlayer() {
353 }
354
355 // static
GetInstance()356 MediaPlayer* MediaPlayer::GetInstance() {
357 return Singleton<MediaPlayer>::get();
358 }
359
EnqueueMediaFile(Profile * profile,const FilePath & file_path,Browser * creator)360 void MediaPlayer::EnqueueMediaFile(Profile* profile, const FilePath& file_path,
361 Browser* creator) {
362 static GURL origin_url(kMediaplayerURL);
363 GURL url;
364 if (!FileManagerUtil::ConvertFileToFileSystemUrl(profile, file_path,
365 origin_url, &url)) {
366 }
367 EnqueueMediaFileUrl(url, creator);
368 }
369
EnqueueMediaFileUrl(const GURL & url,Browser * creator)370 void MediaPlayer::EnqueueMediaFileUrl(const GURL& url, Browser* creator) {
371 if (handler_ == NULL) {
372 unhandled_urls_.push_back(url);
373 PopupMediaPlayer(creator);
374 } else {
375 handler_->EnqueueMediaFileUrl(url);
376 }
377 }
378
ForcePlayMediaFile(Profile * profile,const FilePath & file_path,Browser * creator)379 void MediaPlayer::ForcePlayMediaFile(Profile* profile,
380 const FilePath& file_path,
381 Browser* creator) {
382 static GURL origin_url(kMediaplayerURL);
383 GURL url;
384 if (!FileManagerUtil::ConvertFileToFileSystemUrl(profile, file_path,
385 origin_url, &url)) {
386 }
387 ForcePlayMediaURL(url, creator);
388 }
389
ForcePlayMediaURL(const GURL & url,Browser * creator)390 void MediaPlayer::ForcePlayMediaURL(const GURL& url, Browser* creator) {
391 if (handler_ == NULL) {
392 unhandled_urls_.push_back(url);
393 PopupMediaPlayer(creator);
394 } else {
395 handler_->PlaybackMediaFile(url);
396 }
397 }
398
TogglePlaylistWindowVisible()399 void MediaPlayer::TogglePlaylistWindowVisible() {
400 if (playlist_browser_) {
401 ClosePlaylistWindow();
402 } else {
403 ShowPlaylistWindow();
404 }
405 }
406
ShowPlaylistWindow()407 void MediaPlayer::ShowPlaylistWindow() {
408 if (playlist_browser_ == NULL) {
409 PopupPlaylist(NULL);
410 }
411 }
412
ClosePlaylistWindow()413 void MediaPlayer::ClosePlaylistWindow() {
414 if (playlist_browser_ != NULL) {
415 playlist_browser_->window()->Close();
416 }
417 }
418
SetPlaylistOffset(int offset)419 void MediaPlayer::SetPlaylistOffset(int offset) {
420 if (handler_) {
421 handler_->SetCurrentPlaylistOffset(offset);
422 }
423 if (playlist_) {
424 playlist_->SetCurrentPlaylistOffset(offset);
425 }
426 }
427
SetNewHandler(MediaplayerHandler * handler,TabContents * contents)428 void MediaPlayer::SetNewHandler(MediaplayerHandler* handler,
429 TabContents* contents) {
430 handler_ = handler;
431 mediaplayer_tab_ = contents;
432 RegisterListeners();
433 for (size_t x = 0; x < unhandled_urls_.size(); x++) {
434 handler_->EnqueueMediaFileUrl(unhandled_urls_[x]);
435 }
436 unhandled_urls_.clear();
437 }
438
RegisterListeners()439 void MediaPlayer::RegisterListeners() {
440 registrar_.RemoveAll();
441 if (playlist_tab_) {
442 registrar_.Add(this,
443 NotificationType::TAB_CONTENTS_DESTROYED,
444 Source<TabContents>(playlist_tab_));
445 }
446 if (mediaplayer_tab_) {
447 registrar_.Add(this,
448 NotificationType::TAB_CONTENTS_DESTROYED,
449 Source<TabContents>(mediaplayer_tab_));
450 }
451 };
452
Observe(NotificationType type,const NotificationSource & source,const NotificationDetails & details)453 void MediaPlayer::Observe(NotificationType type,
454 const NotificationSource& source,
455 const NotificationDetails& details) {
456 DCHECK(type == NotificationType::TAB_CONTENTS_DESTROYED);
457 if (Source<TabContents>(source).ptr() == mediaplayer_tab_) {
458 RemoveHandler(handler_);
459 RegisterListeners();
460 ClosePlaylistWindow();
461 } else if (Source<TabContents>(source).ptr() == playlist_tab_) {
462 RemovePlaylistHandler(playlist_);
463 RegisterListeners();
464 }
465 }
466
RegisterNewPlaylistHandler(MediaplayerHandler * handler,TabContents * contents)467 void MediaPlayer::RegisterNewPlaylistHandler(MediaplayerHandler* handler,
468 TabContents* contents) {
469 playlist_ = handler;
470 playlist_tab_ = contents;
471 RegisterListeners();
472 NotifyPlaylistChanged();
473 }
474
RemovePlaylistHandler(MediaplayerHandler * handler)475 void MediaPlayer::RemovePlaylistHandler(MediaplayerHandler* handler) {
476 if (handler == playlist_) {
477 playlist_ = NULL;
478 playlist_browser_ = NULL;
479 playlist_tab_ = NULL;
480 }
481 }
482
NotifyPlaylistChanged()483 void MediaPlayer::NotifyPlaylistChanged() {
484 if (handler_ && playlist_) {
485 playlist_->SetCurrentPlaylist(handler_->GetCurrentPlaylist(),
486 handler_->GetCurrentPlaylistOffset());
487 }
488 }
489
ToggleFullscreen()490 void MediaPlayer::ToggleFullscreen() {
491 if (handler_ && mediaplayer_browser_) {
492 mediaplayer_browser_->ToggleFullscreenMode();
493 }
494 }
495
RemoveHandler(MediaplayerHandler * handler)496 void MediaPlayer::RemoveHandler(MediaplayerHandler* handler) {
497 if (handler == handler_) {
498 handler_ = NULL;
499 mediaplayer_browser_ = NULL;
500 mediaplayer_tab_ = NULL;
501 }
502 }
503
PopupPlaylist(Browser * creator)504 void MediaPlayer::PopupPlaylist(Browser* creator) {
505 Profile* profile = BrowserList::GetLastActive()->profile();
506 playlist_browser_ = Browser::CreateForType(Browser::TYPE_APP_PANEL,
507 profile);
508 playlist_browser_->AddSelectedTabWithURL(GURL(kMediaplayerPlaylistURL),
509 PageTransition::LINK);
510 playlist_browser_->window()->SetBounds(gfx::Rect(kPopupLeft,
511 kPopupTop,
512 kPopupWidth,
513 kPopupHeight));
514 playlist_browser_->window()->Show();
515 }
516
PopupMediaPlayer(Browser * creator)517 void MediaPlayer::PopupMediaPlayer(Browser* creator) {
518 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
519 BrowserThread::PostTask(
520 BrowserThread::UI, FROM_HERE,
521 NewRunnableMethod(this, &MediaPlayer::PopupMediaPlayer,
522 static_cast<Browser*>(NULL)));
523 return;
524 }
525 Profile* profile = BrowserList::GetLastActive()->profile();
526 mediaplayer_browser_ = Browser::CreateForType(Browser::TYPE_APP_PANEL,
527 profile);
528 #if defined(OS_CHROMEOS)
529 // Since we are on chromeos, popups should be a PanelBrowserView,
530 // so we can just cast it.
531 if (creator) {
532 chromeos::PanelBrowserView* creatorview =
533 static_cast<chromeos::PanelBrowserView*>(creator->window());
534 chromeos::PanelBrowserView* view =
535 static_cast<chromeos::PanelBrowserView*>(
536 mediaplayer_browser_->window());
537 view->SetCreatorView(creatorview);
538 }
539 #endif
540 mediaplayer_browser_->AddSelectedTabWithURL(GURL(kMediaplayerURL),
541 PageTransition::LINK);
542 mediaplayer_browser_->window()->SetBounds(gfx::Rect(kPopupLeft,
543 kPopupTop,
544 kPopupWidth,
545 kPopupHeight));
546 mediaplayer_browser_->window()->Show();
547 }
548
MaybeIntercept(net::URLRequest * request)549 net::URLRequestJob* MediaPlayer::MaybeIntercept(net::URLRequest* request) {
550 // Don't attempt to intercept here as we want to wait until the mime
551 // type is fully determined.
552 return NULL;
553 }
554
555 // This is the list of mime types currently supported by the Google
556 // Document Viewer.
557 static const char* const supported_mime_type_list[] = {
558 "audio/mpeg",
559 "video/mp4",
560 "audio/mp3"
561 };
562
MaybeInterceptResponse(net::URLRequest * request)563 net::URLRequestJob* MediaPlayer::MaybeInterceptResponse(
564 net::URLRequest* request) {
565 // Do not intercept this request if it is a download.
566 if (request->load_flags() & net::LOAD_IS_DOWNLOAD) {
567 return NULL;
568 }
569
570 std::string mime_type;
571 request->GetMimeType(&mime_type);
572 // If it is in our list of known URLs, enqueue the url then
573 // Cancel the request so the mediaplayer can handle it when
574 // it hits it in the playlist.
575 if (supported_mime_types_.find(mime_type) != supported_mime_types_.end()) {
576 if (request->referrer() != chrome::kChromeUIMediaplayerURL &&
577 !request->referrer().empty()) {
578 EnqueueMediaFileUrl(request->url(), NULL);
579 request->Cancel();
580 }
581 }
582 return NULL;
583 }
584
MediaPlayer()585 MediaPlayer::MediaPlayer()
586 : handler_(NULL),
587 playlist_(NULL),
588 playlist_browser_(NULL),
589 mediaplayer_browser_(NULL),
590 mediaplayer_tab_(NULL),
591 playlist_tab_(NULL) {
592 for (size_t i = 0; i < arraysize(supported_mime_type_list); ++i) {
593 supported_mime_types_.insert(supported_mime_type_list[i]);
594 }
595 };
596
597 ////////////////////////////////////////////////////////////////////////////////
598 //
599 // MediaplayerUIContents
600 //
601 ////////////////////////////////////////////////////////////////////////////////
602
MediaplayerUI(TabContents * contents)603 MediaplayerUI::MediaplayerUI(TabContents* contents) : WebUI(contents) {
604 const GURL& url = contents->GetURL();
605 bool is_playlist = (url.ref() == "playlist");
606 MediaplayerHandler* handler = new MediaplayerHandler(is_playlist);
607 AddMessageHandler(handler->Attach(this));
608 if (is_playlist) {
609 handler->Init(true, contents);
610 } else {
611 handler->Init(false, contents);
612 }
613
614 MediaplayerUIHTMLSource* html_source =
615 new MediaplayerUIHTMLSource(is_playlist);
616
617 // Set up the chrome://mediaplayer/ source.
618 contents->profile()->GetChromeURLDataManager()->AddDataSource(html_source);
619 }
620