• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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, &current_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