172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/browser/ui/webui/mediaplayer_ui.h"
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
74a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#include "base/command_line.h"
8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/logging.h"
9ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/singleton.h"
10ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/weak_ptr.h"
11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/message_loop.h"
12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/path_service.h"
13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/string_piece.h"
14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/string_util.h"
153f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "base/threading/thread.h"
16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/time.h"
17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/values.h"
18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/bookmarks/bookmark_model.h"
19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/download/download_manager.h"
20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/download/download_util.h"
21ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/extensions/file_manager_util.h"
22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/history/history_types.h"
234a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#include "chrome/browser/metrics/user_metrics.h"
2421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/profiles/profile.h"
253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/browser/tabs/tab_strip_model.h"
264a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#include "chrome/browser/ui/browser.h"
274a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#include "chrome/browser/ui/browser_list.h"
284a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#include "chrome/browser/ui/browser_window.h"
29dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/browser/ui/webui/favicon_source.h"
30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/chrome_paths.h"
314a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#include "chrome/common/chrome_switches.h"
32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/jstemplate_builder.h"
33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/net/url_fetcher.h"
34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/time_format.h"
35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/url_constants.h"
36dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/browser_thread.h"
37dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/tab_contents/tab_contents.h"
383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "grit/browser_resources.h"
393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "grit/chromium_strings.h"
403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "grit/generated_resources.h"
413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "grit/locale_settings.h"
42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/escape.h"
43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/load_flags.h"
44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/url_request/url_request_job.h"
4572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/resource/resource_bundle.h"
46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_CHROMEOS)
48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/chromeos/frame/panel_browser_view.h"
49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickstatic const char kPropertyPath[] = "path";
523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickstatic const char kPropertyForce[] = "force";
533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickstatic const char kPropertyOffset[] = "currentOffset";
543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickstatic const char kPropertyError[] = "error";
55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickstatic const char* kMediaplayerURL = "chrome://mediaplayer";
573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickstatic const char* kMediaplayerPlaylistURL = "chrome://mediaplayer#playlist";
583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickstatic const int kPopupLeft = 0;
593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickstatic const int kPopupTop = 0;
603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickstatic const int kPopupWidth = 350;
613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickstatic const int kPopupHeight = 300;
62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass MediaplayerUIHTMLSource : public ChromeURLDataManager::DataSource {
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  explicit MediaplayerUIHTMLSource(bool is_playlist);
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Called when the network layer has requested a resource underneath
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // the path we registered.
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void StartDataRequest(const std::string& path,
70ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                bool is_incognito,
71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                int request_id);
72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual std::string GetMimeType(const std::string&) const {
73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return "text/html";
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ~MediaplayerUIHTMLSource() {}
78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool is_playlist_;
79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DISALLOW_COPY_AND_ASSIGN(MediaplayerUIHTMLSource);
81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// The handler for Javascript messages related to the "mediaplayer" view.
8472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenclass MediaplayerHandler : public WebUIMessageHandler,
85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                           public base::SupportsWeakPtr<MediaplayerHandler> {
86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  struct MediaUrl {
89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    MediaUrl() {}
90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    explicit MediaUrl(const GURL& newurl)
91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        : url(newurl),
92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          haderror(false) {}
93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    GURL url;
94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    bool haderror;
95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  };
96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  typedef std::vector<MediaUrl> UrlVector;
97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  explicit MediaplayerHandler(bool is_playlist);
99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual ~MediaplayerHandler();
101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Init work after Attach.
103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void Init(bool is_playlist, TabContents* contents);
104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
10572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // WebUIMessageHandler implementation.
10672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  virtual WebUIMessageHandler* Attach(WebUI* web_ui);
107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void RegisterMessages();
108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Callback for the "currentOffsetChanged" message.
1103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  void HandleCurrentOffsetChanged(const ListValue* args);
111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void FirePlaylistChanged(const std::string& path,
113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                           bool force,
114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                           int offset);
115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void PlaybackMediaFile(const GURL& url);
117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
118ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  void EnqueueMediaFileUrl(const GURL& url);
119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  void GetPlaylistValue(ListValue& args);
121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Callback for the "playbackError" message.
1233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  void HandlePlaybackError(const ListValue* args);
124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Callback for the "getCurrentPlaylist" message.
1263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  void HandleGetCurrentPlaylist(const ListValue* args);
127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  void HandleTogglePlaylist(const ListValue* args);
1293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  void HandleShowPlaylist(const ListValue* args);
1303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  void HandleSetCurrentPlaylistOffset(const ListValue* args);
1313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  void HandleToggleFullscreen(const ListValue* args);
132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const UrlVector& GetCurrentPlaylist();
134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int GetCurrentPlaylistOffset();
136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void SetCurrentPlaylistOffset(int offset);
137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Sets  the playlist for playlist views, since the playlist is
138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // maintained by the mediaplayer itself.  Offset is the item in the
139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // playlist which is either now playing, or should be played.
140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void SetCurrentPlaylist(const UrlVector& playlist, int offset);
141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The current playlist of urls.
144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UrlVector current_playlist_;
145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The offset into the current_playlist_ of the currently playing item.
146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int current_offset_;
147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Indicator of if this handler is a playlist or a mediaplayer.
148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool is_playlist_;
149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DISALLOW_COPY_AND_ASSIGN(MediaplayerHandler);
150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch////////////////////////////////////////////////////////////////////////////////
153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//
154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// MediaplayerHTMLSource
155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//
156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch////////////////////////////////////////////////////////////////////////////////
157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
158c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochMediaplayerUIHTMLSource::MediaplayerUIHTMLSource(bool is_playlist)
159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    : DataSource(chrome::kChromeUIMediaplayerHost, MessageLoop::current()) {
160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  is_playlist_ = is_playlist;
161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid MediaplayerUIHTMLSource::StartDataRequest(const std::string& path,
164ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                               bool is_incognito,
165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                               int request_id) {
166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DictionaryValue localized_strings;
167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // TODO(dhg): Fix the strings that are currently hardcoded so they
168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // use the localized versions.
1693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  localized_strings.SetString("errorstring", "Error Playing Back");
170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SetFontAndTextDirection(&localized_strings);
172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string full_html;
174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static const base::StringPiece mediaplayer_html(
176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ResourceBundle::GetSharedInstance().GetRawDataResource(
177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          IDR_MEDIAPLAYER_HTML));
178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static const base::StringPiece playlist_html(
180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ResourceBundle::GetSharedInstance().GetRawDataResource(
181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          IDR_MEDIAPLAYERPLAYLIST_HTML));
182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (is_playlist_) {
184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    full_html = jstemplate_builder::GetI18nTemplateHtml(
185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        playlist_html, &localized_strings);
186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    full_html = jstemplate_builder::GetI18nTemplateHtml(
188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        mediaplayer_html, &localized_strings);
189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_refptr<RefCountedBytes> html_bytes(new RefCountedBytes);
192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  html_bytes->data.resize(full_html.size());
193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::copy(full_html.begin(), full_html.end(), html_bytes->data.begin());
194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SendResponse(request_id, html_bytes);
196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch////////////////////////////////////////////////////////////////////////////////
199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//
200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// MediaplayerHandler
201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//
202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch////////////////////////////////////////////////////////////////////////////////
203c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochMediaplayerHandler::MediaplayerHandler(bool is_playlist)
204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    : current_offset_(0),
205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      is_playlist_(is_playlist) {
206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
208c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochMediaplayerHandler::~MediaplayerHandler() {
209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
21172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenWebUIMessageHandler* MediaplayerHandler::Attach(WebUI* web_ui) {
212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Create our favicon data source.
21372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  Profile* profile = web_ui->GetProfile();
21472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  profile->GetChromeURLDataManager()->AddDataSource(
215ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      new FaviconSource(profile));
216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
21772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  return WebUIMessageHandler::Attach(web_ui);
218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid MediaplayerHandler::Init(bool is_playlist, TabContents* contents) {
22121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  MediaPlayer* player = MediaPlayer::GetInstance();
222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!is_playlist) {
223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    player->SetNewHandler(this, contents);
224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    player->RegisterNewPlaylistHandler(this, contents);
226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid MediaplayerHandler::RegisterMessages() {
23072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  web_ui_->RegisterMessageCallback("currentOffsetChanged",
231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NewCallback(this, &MediaplayerHandler::HandleCurrentOffsetChanged));
23272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  web_ui_->RegisterMessageCallback("playbackError",
233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NewCallback(this, &MediaplayerHandler::HandlePlaybackError));
23472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  web_ui_->RegisterMessageCallback("getCurrentPlaylist",
235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NewCallback(this, &MediaplayerHandler::HandleGetCurrentPlaylist));
23672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  web_ui_->RegisterMessageCallback("togglePlaylist",
237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NewCallback(this, &MediaplayerHandler::HandleTogglePlaylist));
23872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  web_ui_->RegisterMessageCallback("setCurrentPlaylistOffset",
239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NewCallback(this, &MediaplayerHandler::HandleSetCurrentPlaylistOffset));
24072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  web_ui_->RegisterMessageCallback("toggleFullscreen",
241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NewCallback(this, &MediaplayerHandler::HandleToggleFullscreen));
24272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  web_ui_->RegisterMessageCallback("showPlaylist",
243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NewCallback(this, &MediaplayerHandler::HandleShowPlaylist));
244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid MediaplayerHandler::GetPlaylistValue(ListValue& urls) {
247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (size_t x = 0; x < current_playlist_.size(); x++) {
248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DictionaryValue* url_value = new DictionaryValue();
249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    url_value->SetString(kPropertyPath, current_playlist_[x].url.spec());
250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    url_value->SetBoolean(kPropertyError, current_playlist_[x].haderror);
2513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    urls.Append(url_value);
252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid MediaplayerHandler::PlaybackMediaFile(const GURL& url) {
256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  current_playlist_.push_back(MediaplayerHandler::MediaUrl(url));
257ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FirePlaylistChanged(url.spec(), true, current_playlist_.size() - 1);
25821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  MediaPlayer::GetInstance()->NotifyPlaylistChanged();
259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst MediaplayerHandler::UrlVector& MediaplayerHandler::GetCurrentPlaylist() {
262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return current_playlist_;
263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint MediaplayerHandler::GetCurrentPlaylistOffset() {
266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return current_offset_;
267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid MediaplayerHandler::HandleToggleFullscreen(const ListValue* args) {
27021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  MediaPlayer::GetInstance()->ToggleFullscreen();
271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid MediaplayerHandler::HandleSetCurrentPlaylistOffset(const ListValue* args) {
2743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  int id;
2753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  CHECK(ExtractIntegerValue(args, &id));
27621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  MediaPlayer::GetInstance()->SetPlaylistOffset(id);
277c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid MediaplayerHandler::FirePlaylistChanged(const std::string& path,
280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                             bool force,
281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                             int offset) {
282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DictionaryValue info_value;
283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ListValue urls;
284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GetPlaylistValue(urls);
285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  info_value.SetString(kPropertyPath, path);
286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  info_value.SetBoolean(kPropertyForce, force);
287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  info_value.SetInteger(kPropertyOffset, offset);
288ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  web_ui_->CallJavascriptFunction("playlistChanged", info_value, urls);
289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
291c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid MediaplayerHandler::SetCurrentPlaylistOffset(int offset) {
292c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  current_offset_ = offset;
293c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FirePlaylistChanged(std::string(), true, current_offset_);
294c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
295c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
296c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid MediaplayerHandler::SetCurrentPlaylist(
297c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const MediaplayerHandler::UrlVector& playlist, int offset) {
298c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  current_playlist_ = playlist;
299c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  current_offset_ = offset;
300c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FirePlaylistChanged(std::string(), false, current_offset_);
301c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
302c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
303ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid MediaplayerHandler::EnqueueMediaFileUrl(const GURL& url) {
304c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  current_playlist_.push_back(MediaplayerHandler::MediaUrl(url));
305c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FirePlaylistChanged(url.spec(), false, current_offset_);
30621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  MediaPlayer::GetInstance()->NotifyPlaylistChanged();
307c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
308c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid MediaplayerHandler::HandleCurrentOffsetChanged(const ListValue* args) {
3103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  CHECK(ExtractIntegerValue(args, &current_offset_));
31121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  MediaPlayer::GetInstance()->NotifyPlaylistChanged();
312c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid MediaplayerHandler::HandlePlaybackError(const ListValue* args) {
3153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  std::string error;
3163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  std::string url;
3173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Get path string.
3183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (args->GetString(0, &error))
3193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    LOG(ERROR) << "Playback error" << error;
3203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (args->GetString(1, &url)) {
3213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    for (size_t x = 0; x < current_playlist_.size(); x++) {
3223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      if (current_playlist_[x].url == GURL(url)) {
3233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        current_playlist_[x].haderror = true;
324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      }
325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
3263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    FirePlaylistChanged(std::string(), false, current_offset_);
327c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
328c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
329c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid MediaplayerHandler::HandleGetCurrentPlaylist(const ListValue* args) {
331c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FirePlaylistChanged(std::string(), false, current_offset_);
332c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
333c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid MediaplayerHandler::HandleTogglePlaylist(const ListValue* args) {
33521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  MediaPlayer::GetInstance()->TogglePlaylistWindowVisible();
336c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
337c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid MediaplayerHandler::HandleShowPlaylist(const ListValue* args) {
33921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  MediaPlayer::GetInstance()->ShowPlaylistWindow();
340c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
341c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch////////////////////////////////////////////////////////////////////////////////
343c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//
344c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Mediaplayer
345c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//
346c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch////////////////////////////////////////////////////////////////////////////////
347c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
348c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Allows InvokeLater without adding refcounting. This class is a Singleton and
349c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// won't be deleted until it's last InvokeLater is run.
350c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochDISABLE_RUNNABLE_METHOD_REFCOUNT(MediaPlayer);
351c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3523345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickMediaPlayer::~MediaPlayer() {
3533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
3543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
35521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// static
35621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenMediaPlayer* MediaPlayer::GetInstance() {
35721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  return Singleton<MediaPlayer>::get();
35821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
35921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
360ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid MediaPlayer::EnqueueMediaFile(Profile* profile, const FilePath& file_path,
361ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                   Browser* creator) {
362ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  static GURL origin_url(kMediaplayerURL);
363ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  GURL url;
364ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (!FileManagerUtil::ConvertFileToFileSystemUrl(profile, file_path,
365ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                                   origin_url, &url)) {
366c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
367ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EnqueueMediaFileUrl(url, creator);
368ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
369ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
370ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid MediaPlayer::EnqueueMediaFileUrl(const GURL& url, Browser* creator) {
371c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (handler_ == NULL) {
372c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    unhandled_urls_.push_back(url);
373c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    PopupMediaPlayer(creator);
374c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
375ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    handler_->EnqueueMediaFileUrl(url);
376c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
377c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
378c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
379ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid MediaPlayer::ForcePlayMediaFile(Profile* profile,
380ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                     const FilePath& file_path,
381ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                     Browser* creator) {
382ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  static GURL origin_url(kMediaplayerURL);
383ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  GURL url;
384ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (!FileManagerUtil::ConvertFileToFileSystemUrl(profile, file_path,
385ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                                   origin_url, &url)) {
386c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
387ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ForcePlayMediaURL(url, creator);
388ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
389ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
390ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid MediaPlayer::ForcePlayMediaURL(const GURL& url, Browser* creator) {
391c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (handler_ == NULL) {
392c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    unhandled_urls_.push_back(url);
393c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    PopupMediaPlayer(creator);
394c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
395c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    handler_->PlaybackMediaFile(url);
396c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
397c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
398c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
399c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid MediaPlayer::TogglePlaylistWindowVisible() {
400c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (playlist_browser_) {
401c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ClosePlaylistWindow();
402c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
403c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ShowPlaylistWindow();
404c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
405c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
406c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
407c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid MediaPlayer::ShowPlaylistWindow() {
408c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (playlist_browser_ == NULL) {
409c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    PopupPlaylist(NULL);
410c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
411c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
412c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
413c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid MediaPlayer::ClosePlaylistWindow() {
414c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (playlist_browser_ != NULL) {
415c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    playlist_browser_->window()->Close();
416c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
417c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
418c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
419c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid MediaPlayer::SetPlaylistOffset(int offset) {
420c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (handler_) {
421c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    handler_->SetCurrentPlaylistOffset(offset);
422c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
423c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (playlist_) {
424c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    playlist_->SetCurrentPlaylistOffset(offset);
425c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
426c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
427c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
428c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid MediaPlayer::SetNewHandler(MediaplayerHandler* handler,
429c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                TabContents* contents) {
430c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  handler_ = handler;
431c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  mediaplayer_tab_ = contents;
432c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  RegisterListeners();
433c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (size_t x = 0; x < unhandled_urls_.size(); x++) {
434ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    handler_->EnqueueMediaFileUrl(unhandled_urls_[x]);
435c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
436c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  unhandled_urls_.clear();
437c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
438c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
439c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid MediaPlayer::RegisterListeners() {
440c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.RemoveAll();
441c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (playlist_tab_) {
442c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    registrar_.Add(this,
443c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                   NotificationType::TAB_CONTENTS_DESTROYED,
444c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                   Source<TabContents>(playlist_tab_));
445c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
446c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (mediaplayer_tab_) {
447c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    registrar_.Add(this,
448c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                   NotificationType::TAB_CONTENTS_DESTROYED,
449c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                   Source<TabContents>(mediaplayer_tab_));
450c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
451c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
452c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
453c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid MediaPlayer::Observe(NotificationType type,
454c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                          const NotificationSource& source,
455c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                          const NotificationDetails& details) {
456c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(type == NotificationType::TAB_CONTENTS_DESTROYED);
457c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (Source<TabContents>(source).ptr() == mediaplayer_tab_) {
458c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    RemoveHandler(handler_);
459c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    RegisterListeners();
460c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ClosePlaylistWindow();
461c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else if (Source<TabContents>(source).ptr() == playlist_tab_) {
462c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    RemovePlaylistHandler(playlist_);
463c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    RegisterListeners();
464c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
465c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
466c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
467c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid MediaPlayer::RegisterNewPlaylistHandler(MediaplayerHandler* handler,
468c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                             TabContents* contents) {
469c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  playlist_ = handler;
470c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  playlist_tab_ = contents;
471c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  RegisterListeners();
472c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NotifyPlaylistChanged();
473c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
474c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
475c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid MediaPlayer::RemovePlaylistHandler(MediaplayerHandler* handler) {
476c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (handler == playlist_) {
477c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    playlist_ = NULL;
478c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    playlist_browser_ = NULL;
479c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    playlist_tab_ = NULL;
480c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
481c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
482c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
483c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid MediaPlayer::NotifyPlaylistChanged() {
484c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (handler_ && playlist_) {
485c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    playlist_->SetCurrentPlaylist(handler_->GetCurrentPlaylist(),
486c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                  handler_->GetCurrentPlaylistOffset());
487c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
488c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
489c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
490c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid MediaPlayer::ToggleFullscreen() {
491c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (handler_ && mediaplayer_browser_) {
492c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    mediaplayer_browser_->ToggleFullscreenMode();
493c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
494c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
495c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
496c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid MediaPlayer::RemoveHandler(MediaplayerHandler* handler) {
497c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (handler == handler_) {
498c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    handler_ = NULL;
499c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    mediaplayer_browser_ = NULL;
500c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    mediaplayer_tab_ = NULL;
501c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
502c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
503c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
504c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid MediaPlayer::PopupPlaylist(Browser* creator) {
505c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Profile* profile = BrowserList::GetLastActive()->profile();
5063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  playlist_browser_ = Browser::CreateForType(Browser::TYPE_APP_PANEL,
5073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                             profile);
508731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  playlist_browser_->AddSelectedTabWithURL(GURL(kMediaplayerPlaylistURL),
509731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                           PageTransition::LINK);
510c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  playlist_browser_->window()->SetBounds(gfx::Rect(kPopupLeft,
511c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                                   kPopupTop,
512c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                                   kPopupWidth,
513c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                                   kPopupHeight));
514c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  playlist_browser_->window()->Show();
515c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
516c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
517c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid MediaPlayer::PopupMediaPlayer(Browser* creator) {
518731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
519731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    BrowserThread::PostTask(
520731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        BrowserThread::UI, FROM_HERE,
521c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        NewRunnableMethod(this, &MediaPlayer::PopupMediaPlayer,
522c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                          static_cast<Browser*>(NULL)));
523c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
524c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
525c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Profile* profile = BrowserList::GetLastActive()->profile();
5263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  mediaplayer_browser_ = Browser::CreateForType(Browser::TYPE_APP_PANEL,
5273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                                profile);
528c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_CHROMEOS)
529c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Since we are on chromeos, popups should be a PanelBrowserView,
530c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // so we can just cast it.
531c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (creator) {
532c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    chromeos::PanelBrowserView* creatorview =
533c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        static_cast<chromeos::PanelBrowserView*>(creator->window());
534c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    chromeos::PanelBrowserView* view =
535c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        static_cast<chromeos::PanelBrowserView*>(
536c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            mediaplayer_browser_->window());
537c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    view->SetCreatorView(creatorview);
538c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
539c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
540731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  mediaplayer_browser_->AddSelectedTabWithURL(GURL(kMediaplayerURL),
541731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                              PageTransition::LINK);
542c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  mediaplayer_browser_->window()->SetBounds(gfx::Rect(kPopupLeft,
543c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                                      kPopupTop,
544c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                                      kPopupWidth,
545c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                                      kPopupHeight));
546c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  mediaplayer_browser_->window()->Show();
547c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
548c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
54921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsennet::URLRequestJob* MediaPlayer::MaybeIntercept(net::URLRequest* request) {
550c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Don't attempt to intercept here as we want to wait until the mime
551c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // type is fully determined.
552c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return NULL;
553c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
554c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
555c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// This is the list of mime types currently supported by the Google
556c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Document Viewer.
557c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const char* const supported_mime_type_list[] = {
558c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  "audio/mpeg",
559c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  "video/mp4",
560c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  "audio/mp3"
561c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
562c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
56321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsennet::URLRequestJob* MediaPlayer::MaybeInterceptResponse(
56421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    net::URLRequest* request) {
565c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Do not intercept this request if it is a download.
566c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (request->load_flags() & net::LOAD_IS_DOWNLOAD) {
567c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return NULL;
568c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
569c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
570c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string mime_type;
571c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  request->GetMimeType(&mime_type);
572c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // If it is in our list of known URLs, enqueue the url then
573c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Cancel the request so the mediaplayer can handle it when
574c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // it hits it in the playlist.
575c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (supported_mime_types_.find(mime_type) != supported_mime_types_.end()) {
576c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (request->referrer() != chrome::kChromeUIMediaplayerURL &&
577c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        !request->referrer().empty()) {
578ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      EnqueueMediaFileUrl(request->url(), NULL);
579c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      request->Cancel();
580c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
581c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
582c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return NULL;
583c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
584c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
585c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochMediaPlayer::MediaPlayer()
586c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    : handler_(NULL),
587c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      playlist_(NULL),
588c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      playlist_browser_(NULL),
589c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      mediaplayer_browser_(NULL),
590c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      mediaplayer_tab_(NULL),
591c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      playlist_tab_(NULL) {
592c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (size_t i = 0; i < arraysize(supported_mime_type_list); ++i) {
593c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    supported_mime_types_.insert(supported_mime_type_list[i]);
594c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
595c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
596c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
597c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch////////////////////////////////////////////////////////////////////////////////
598c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//
599c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// MediaplayerUIContents
600c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//
601c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch////////////////////////////////////////////////////////////////////////////////
602c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
60372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenMediaplayerUI::MediaplayerUI(TabContents* contents) : WebUI(contents) {
604c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const GURL& url = contents->GetURL();
605c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool is_playlist = (url.ref() == "playlist");
606c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MediaplayerHandler* handler = new MediaplayerHandler(is_playlist);
607c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AddMessageHandler(handler->Attach(this));
608c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (is_playlist) {
609c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    handler->Init(true, contents);
610c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
611c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    handler->Init(false, contents);
612c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
613c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
614c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MediaplayerUIHTMLSource* html_source =
615c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      new MediaplayerUIHTMLSource(is_playlist);
616c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
617c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Set up the chrome://mediaplayer/ source.
61872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  contents->profile()->GetChromeURLDataManager()->AddDataSource(html_source);
619c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
620