diff options
author | dhg@chromium.org <dhg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-10 19:48:23 +0000 |
---|---|---|
committer | dhg@chromium.org <dhg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-10 19:48:23 +0000 |
commit | 17496bbed312152a6a0c2251c88ccefd70849540 (patch) | |
tree | 03edf49985ed65b6e42d2385566d600fd88f2535 /chrome | |
parent | a0607da9446e3ec76a7ced32502f8c7e71654d53 (diff) | |
download | chromium_src-17496bbed312152a6a0c2251c88ccefd70849540.zip chromium_src-17496bbed312152a6a0c2251c88ccefd70849540.tar.gz chromium_src-17496bbed312152a6a0c2251c88ccefd70849540.tar.bz2 |
Adding initial version of the mediaplayer. This only hooks into the system if the user selects a file via the filebrowser.
BUG=none
TEST=none
Review URL: http://codereview.chromium.org/749001
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@41191 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
19 files changed, 1399 insertions, 2 deletions
diff --git a/chrome/app/theme/mediaplayer_menu.png b/chrome/app/theme/mediaplayer_menu.png Binary files differnew file mode 100644 index 0000000..a8e3b90 --- /dev/null +++ b/chrome/app/theme/mediaplayer_menu.png diff --git a/chrome/app/theme/mediaplayer_next.png b/chrome/app/theme/mediaplayer_next.png Binary files differnew file mode 100644 index 0000000..f8af798 --- /dev/null +++ b/chrome/app/theme/mediaplayer_next.png diff --git a/chrome/app/theme/mediaplayer_pause.png b/chrome/app/theme/mediaplayer_pause.png Binary files differnew file mode 100644 index 0000000..c874205 --- /dev/null +++ b/chrome/app/theme/mediaplayer_pause.png diff --git a/chrome/app/theme/mediaplayer_play.png b/chrome/app/theme/mediaplayer_play.png Binary files differnew file mode 100644 index 0000000..a1aaf8e --- /dev/null +++ b/chrome/app/theme/mediaplayer_play.png diff --git a/chrome/app/theme/mediaplayer_prev.png b/chrome/app/theme/mediaplayer_prev.png Binary files differnew file mode 100644 index 0000000..ff38633 --- /dev/null +++ b/chrome/app/theme/mediaplayer_prev.png diff --git a/chrome/app/theme/mediaplayer_vol_high.png b/chrome/app/theme/mediaplayer_vol_high.png Binary files differnew file mode 100644 index 0000000..067a56c --- /dev/null +++ b/chrome/app/theme/mediaplayer_vol_high.png diff --git a/chrome/app/theme/theme_resources.grd b/chrome/app/theme/theme_resources.grd index 1206f72..e3d59ee 100644 --- a/chrome/app/theme/theme_resources.grd +++ b/chrome/app/theme/theme_resources.grd @@ -440,6 +440,12 @@ <include name="IDR_FILEBROWSER_UPLOAD" file="filebrowse_upload.png" type="BINDATA" /> <include name="IDR_FILEBROWSER_FULLSCREEN" file="filebrowse_fullscreen.png" type="BINDATA" /> <include name="IDR_FILEBROWSER_MENU" file="filebrowse_menu.png" type="BINDATA" /> + <include name="IDR_MEDIAPLAYER_PLAY" file="mediaplayer_play.png" type="BINDATA" /> + <include name="IDR_MEDIAPLAYER_PAUSE" file="mediaplayer_pause.png" type="BINDATA" /> + <include name="IDR_MEDIAPLAYER_NEXT" file="mediaplayer_next.png" type="BINDATA" /> + <include name="IDR_MEDIAPLAYER_PREV" file="mediaplayer_prev.png" type="BINDATA" /> + <include name="IDR_MEDIAPLAYER_MENU" file="mediaplayer_menu.png" type="BINDATA" /> + <include name="IDR_MEDIAPLAYER_VOL_HIGH" file="mediaplayer_vol_high.png" type="BINDATA" /> </if> <if expr="(pp_ifdef('chromeos') or pp_ifdef('toolkit_views')) and pp_ifdef('_google_chrome')"> diff --git a/chrome/browser/browser_init.cc b/chrome/browser/browser_init.cc index 9f92ad8..8481acf 100644 --- a/chrome/browser/browser_init.cc +++ b/chrome/browser/browser_init.cc @@ -61,6 +61,7 @@ #if defined(OS_CHROMEOS) #include "chrome/browser/chromeos/browser_notification_observers.h" +#include "chrome/browser/dom_ui/mediaplayer_ui.h" #include "chrome/browser/chromeos/cros/mount_library.h" #include "chrome/browser/chromeos/gview_request_interceptor.h" #include "chrome/browser/chromeos/usb_mount_observer.h" @@ -386,6 +387,8 @@ bool BrowserInit::LaunchBrowser( // and have the constructor take care of everything else. chromeos::MountLibrary* lib = chromeos::MountLibrary::Get(); chromeos::USBMountObserver* observe = chromeos::USBMountObserver::Get(); + MediaPlayer* player = MediaPlayer::Get(); + player->set_profile(profile); observe->set_profile(profile); lib->AddObserver(observe); } diff --git a/chrome/browser/browser_resources.grd b/chrome/browser/browser_resources.grd index 9ce3355..22d06ba 100644 --- a/chrome/browser/browser_resources.grd +++ b/chrome/browser/browser_resources.grd @@ -41,6 +41,8 @@ without changes to the corresponding grd file. tea --> <if expr="pp_ifdef('chromeos') or pp_ifdef('toolkit_views')"> <include name="IDR_FILEBROWSE_HTML" file="resources\filebrowse.html" flattenhtml="true" type="BINDATA" /> <include name="IDR_OS_CREDITS_HTML" file="resources\about_os_credits.html" flattenhtml="true" type="BINDATA" /> + <include name="IDR_MEDIAPLAYER_HTML" file="resources\mediaplayer.html" flattenhtml="true" type="BINDATA" /> + <include name="IDR_MEDIAPLAYERPLAYLIST_HTML" file="resources\playlist.html" flattenhtml="true" type="BINDATA" /> </if> <include name="IDR_BOOKMARKS_MANIFEST" file="resources\bookmark_manager\manifest.json" type="BINDATA" /> <include name="IDR_DOWNLOADS_HTML" file="resources\downloads.html" flattenhtml="true" type="BINDATA" /> diff --git a/chrome/browser/dom_ui/dom_ui_factory.cc b/chrome/browser/dom_ui/dom_ui_factory.cc index 3e584e3..86f78c5 100644 --- a/chrome/browser/dom_ui/dom_ui_factory.cc +++ b/chrome/browser/dom_ui/dom_ui_factory.cc @@ -10,6 +10,7 @@ #include "chrome/browser/dom_ui/history_ui.h" #include "chrome/browser/dom_ui/filebrowse_ui.h" #include "chrome/browser/dom_ui/html_dialog_ui.h" +#include "chrome/browser/dom_ui/mediaplayer_ui.h" #include "chrome/browser/dom_ui/new_tab_ui.h" #include "chrome/browser/dom_ui/print_ui.h" #include "chrome/browser/extensions/extension_dom_ui.h" @@ -98,6 +99,9 @@ static DOMUIFactoryFunction GetDOMUIFactoryFunction(const GURL& url) { #if defined(OS_CHROMEOS) if (url.host() == chrome::kChromeUIFileBrowseHost) return &NewDOMUI<FileBrowseUI>; + + if (url.host() == chrome::kChromeUIMediaplayerHost) + return &NewDOMUI<MediaplayerUI>; #endif return NULL; diff --git a/chrome/browser/dom_ui/filebrowse_ui.cc b/chrome/browser/dom_ui/filebrowse_ui.cc index a1b56d9..100124e 100644 --- a/chrome/browser/dom_ui/filebrowse_ui.cc +++ b/chrome/browser/dom_ui/filebrowse_ui.cc @@ -34,6 +34,7 @@ #include "chrome/common/jstemplate_builder.h" #include "chrome/common/time_format.h" #include "chrome/common/url_constants.h" +#include "chrome/browser/dom_ui/mediaplayer_ui.h" #include "net/base/escape.h" #include "grit/browser_resources.h" @@ -156,6 +157,8 @@ class FilebrowseHandler : public net::DirectoryLister::DirectoryListerDelegate, void HandleCreateNewFolder(const Value* value); + void PlayMediaFile(const Value* value); + void HandleDeleteFile(const Value* value); void DeleteFile(const FilePath& path); void FireDeleteComplete(const FilePath& path); @@ -358,6 +361,8 @@ void FilebrowseHandler::RegisterMessages() { NewCallback(this, &FilebrowseHandler::HandleGetDownloads)); dom_ui_->RegisterMessageCallback("createNewFolder", NewCallback(this, &FilebrowseHandler::HandleCreateNewFolder)); + dom_ui_->RegisterMessageCallback("playMediaFile", + NewCallback(this, &FilebrowseHandler::PlayMediaFile)); dom_ui_->RegisterMessageCallback("pauseToggleDownload", NewCallback(this, &FilebrowseHandler::HandlePauseToggleDownload)); dom_ui_->RegisterMessageCallback("deleteFile", @@ -498,6 +503,31 @@ void FilebrowseHandler::HandleCreateNewFolder(const Value* value) { #endif } +void FilebrowseHandler::PlayMediaFile(const Value* value) { +#if defined(OS_CHROMEOS) + if (value && value->GetType() == Value::TYPE_LIST) { + const ListValue* list_value = static_cast<const ListValue*>(value); + std::string path; + + // Get path string. + if (list_value->GetString(0, &path)) { + FilePath currentpath; + currentpath = FilePath(path); + + MediaPlayer* mediaplayer = MediaPlayer::Get(); + std::string url = currentpath.value(); + + GURL gurl(url); + + mediaplayer->EnqueueMediaURL(gurl); + } else { + LOG(ERROR) << "Unable to get string"; + return; + } + } +#endif +} + void FilebrowseHandler::HandleRefreshDirectory(const Value* value) { if (value && value->GetType() == Value::TYPE_LIST) { const ListValue* list_value = static_cast<const ListValue*>(value); diff --git a/chrome/browser/dom_ui/mediaplayer_ui.cc b/chrome/browser/dom_ui/mediaplayer_ui.cc new file mode 100644 index 0000000..1feeef6 --- /dev/null +++ b/chrome/browser/dom_ui/mediaplayer_ui.cc @@ -0,0 +1,528 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/dom_ui/mediaplayer_ui.h" + +#include "app/l10n_util.h" +#include "app/resource_bundle.h" +#include "base/logging.h" +#include "base/message_loop.h" +#include "base/path_service.h" +#include "base/singleton.h" +#include "base/string_piece.h" +#include "base/string_util.h" +#include "base/thread.h" +#include "base/time.h" +#include "base/values.h" +#include "base/weak_ptr.h" +#include "chrome/browser/bookmarks/bookmark_model.h" +#include "chrome/browser/browser.h" +#include "chrome/browser/browser_window.h" +#include "chrome/browser/chrome_thread.h" +#include "chrome/browser/dom_ui/dom_ui_favicon_source.h" +#include "chrome/browser/download/download_manager.h" +#include "chrome/browser/download/download_util.h" +#include "chrome/browser/metrics/user_metrics.h" +#include "chrome/browser/net/url_fetcher.h" +#include "chrome/browser/history/history_types.h" +#include "chrome/browser/profile.h" +#include "chrome/browser/tab_contents/tab_contents.h" +#include "chrome/common/chrome_paths.h" +#include "chrome/common/jstemplate_builder.h" +#include "chrome/common/time_format.h" +#include "chrome/common/url_constants.h" +#include "net/base/escape.h" + +#include "grit/browser_resources.h" +#include "grit/chromium_strings.h" +#include "grit/generated_resources.h" +#include "grit/locale_settings.h" + +static const std::wstring kPropertyPath = L"path"; +static const std::wstring kPropertyForce = L"force"; +static const std::wstring kPropertyTitle = L"title"; +static const std::wstring kPropertyOffset = L"currentOffset"; + +const char* kMediaplayerURL = "chrome://mediaplayer"; +const char* kMediaplayerPlaylistURL = "chrome://mediaplayer#playlist"; +const int kPopupLeft = 0; +const int kPopupTop = 0; +const int kPopupWidth = 350; +const int kPopupHeight = 300; + +class MediaplayerUIHTMLSource : public ChromeURLDataManager::DataSource { + public: + explicit MediaplayerUIHTMLSource(bool is_playlist); + + // Called when the network layer has requested a resource underneath + // the path we registered. + virtual void StartDataRequest(const std::string& path, + bool is_off_the_record, + int request_id); + virtual std::string GetMimeType(const std::string&) const { + return "text/html"; + } + + private: + ~MediaplayerUIHTMLSource() {} + bool is_playlist_; + + DISALLOW_COPY_AND_ASSIGN(MediaplayerUIHTMLSource); +}; + +// The handler for Javascript messages related to the "mediaplayer" view. +class MediaplayerHandler : public DOMMessageHandler, + public base::SupportsWeakPtr<MediaplayerHandler> { + public: + explicit MediaplayerHandler(bool is_playlist); + virtual ~MediaplayerHandler(); + + // Init work after Attach. + void Init(bool is_playlist, TabContents* contents); + + // DOMMessageHandler implementation. + virtual DOMMessageHandler* Attach(DOMUI* dom_ui); + virtual void RegisterMessages(); + + // Callback for the "currentOffsetChanged" message. + void HandleCurrentOffsetChanged(const Value* value); + + void PlaybackMediaFile(const GURL& url); + + void EnqueueMediaFile(const GURL& url); + + void GetPlaylistValue(ListValue& value); + + // Callback for the "playbackError" message. + void HandlePlaybackError(const Value* value); + + // Callback for the "getCurrentPlaylist" message. + void HandleGetCurrentPlaylist(const Value* value); + + void HandleTogglePlaylist(const Value* value); + void HandleSetCurrentPlaylistOffset(const Value* value); + + const std::vector<GURL>& GetCurrentPlaylist(); + + int GetCurrentPlaylistOffset(); + void SetCurrentPlaylistOffset(int offset); + // Used to set the playlist for playlist views, since the playlist is + // maintained by the mediaplayer itself. + void SetCurrentPlaylist(const std::vector<GURL>& playlist, int offset); + + private: + + Profile* profile_; + std::vector<GURL> currentPlaylist_; + int currentOffset_; + bool is_playlist_; + DISALLOW_COPY_AND_ASSIGN(MediaplayerHandler); +}; + +//////////////////////////////////////////////////////////////////////////////// +// +// MediaplayerHTMLSource +// +//////////////////////////////////////////////////////////////////////////////// + +MediaplayerUIHTMLSource::MediaplayerUIHTMLSource(bool is_playlist) + : DataSource(chrome::kChromeUIMediaplayerHost, MessageLoop::current()) { + is_playlist_ = is_playlist; +} + +void MediaplayerUIHTMLSource::StartDataRequest(const std::string& path, + bool is_off_the_record, int request_id) { + DictionaryValue localized_strings; + // TODO(dhg): Add stirings to localized strings, also add more strings + // that are currently hardcoded. + localized_strings.SetString(L"devices", "devices"); + + SetFontAndTextDirection(&localized_strings); + + std::string full_html; + + static const base::StringPiece mediaplayer_html( + ResourceBundle::GetSharedInstance().GetRawDataResource( + IDR_MEDIAPLAYER_HTML)); + + static const base::StringPiece playlist_html( + ResourceBundle::GetSharedInstance().GetRawDataResource( + IDR_MEDIAPLAYERPLAYLIST_HTML)); + + if (is_playlist_) { + full_html = jstemplate_builder::GetI18nTemplateHtml( + playlist_html, &localized_strings); + } else { + full_html = jstemplate_builder::GetI18nTemplateHtml( + mediaplayer_html, &localized_strings); + } + + scoped_refptr<RefCountedBytes> html_bytes(new RefCountedBytes); + html_bytes->data.resize(full_html.size()); + std::copy(full_html.begin(), full_html.end(), html_bytes->data.begin()); + + SendResponse(request_id, html_bytes); +} + +//////////////////////////////////////////////////////////////////////////////// +// +// MediaplayerHandler +// +//////////////////////////////////////////////////////////////////////////////// +MediaplayerHandler::MediaplayerHandler(bool is_playlist) + : profile_(NULL), + currentOffset_(0), + is_playlist_(is_playlist) { +} + +MediaplayerHandler::~MediaplayerHandler() { +} + +DOMMessageHandler* MediaplayerHandler::Attach(DOMUI* dom_ui) { + // Create our favicon data source. + ChromeThread::PostTask( + ChromeThread::IO, FROM_HERE, + NewRunnableMethod( + Singleton<ChromeURLDataManager>::get(), + &ChromeURLDataManager::AddDataSource, + make_scoped_refptr(new DOMUIFavIconSource(dom_ui->GetProfile())))); + profile_ = dom_ui->GetProfile(); + + return DOMMessageHandler::Attach(dom_ui); +} + +void MediaplayerHandler::Init(bool is_playlist, TabContents* contents) { + MediaPlayer* player = MediaPlayer::Get(); + if (!is_playlist) { + player->RegisterNewHandler(this, contents); + } else { + player->RegisterNewPlaylistHandler(this, contents); + } +} + +void MediaplayerHandler::RegisterMessages() { + dom_ui_->RegisterMessageCallback("currentOffsetChanged", + NewCallback(this, &MediaplayerHandler::HandleCurrentOffsetChanged)); + dom_ui_->RegisterMessageCallback("playbackError", + NewCallback(this, &MediaplayerHandler::HandlePlaybackError)); + dom_ui_->RegisterMessageCallback("getCurrentPlaylist", + NewCallback(this, &MediaplayerHandler::HandleGetCurrentPlaylist)); + dom_ui_->RegisterMessageCallback("togglePlaylist", + NewCallback(this, &MediaplayerHandler::HandleTogglePlaylist)); + dom_ui_->RegisterMessageCallback("setCurrentPlaylistOffset", + NewCallback(this, &MediaplayerHandler::HandleSetCurrentPlaylistOffset)); +} + +void MediaplayerHandler::GetPlaylistValue(ListValue& value) { + for (unsigned int x = 0; x < currentPlaylist_.size(); x++) { + DictionaryValue* url_value = new DictionaryValue(); + url_value->SetString(kPropertyPath, currentPlaylist_[x].spec()); + value.Append(url_value); + } +} + +void MediaplayerHandler::PlaybackMediaFile(const GURL& url) { + GURL newurl(url); + currentPlaylist_.clear(); + currentPlaylist_.push_back(newurl); + + DictionaryValue info_value; + ListValue urls; + GetPlaylistValue(urls); + info_value.SetBoolean(kPropertyForce, true); + info_value.SetString(kPropertyPath, newurl.spec()); + dom_ui_->CallJavascriptFunction(L"playlistChanged", info_value, urls); + MediaPlayer::Get()->NotifyPlaylistChanged(); +} + +const std::vector<GURL>& MediaplayerHandler::GetCurrentPlaylist() { + return currentPlaylist_; +} + +int MediaplayerHandler::GetCurrentPlaylistOffset() { + return currentOffset_; +} + +void MediaplayerHandler::HandleSetCurrentPlaylistOffset(const Value* value) { + ListValue results_value; + DictionaryValue info_value; + if (value && value->GetType() == Value::TYPE_LIST) { + const ListValue* list_value = static_cast<const ListValue*>(value); + std::string val; + + // Get the new playlist offset; + if (list_value->GetString(0, &val)) { + int id = atoi(val.c_str()); + MediaPlayer::Get()->SetPlaylistOffset(id); + } + } +} + +void MediaplayerHandler::SetCurrentPlaylistOffset(int offset) { + currentOffset_ = offset; + DictionaryValue info_value; + ListValue urls; + GetPlaylistValue(urls); + info_value.SetString(kPropertyPath, ""); + info_value.SetBoolean(kPropertyForce, true); + info_value.SetInteger(kPropertyOffset, currentOffset_); + dom_ui_->CallJavascriptFunction(L"playlistChanged", info_value, urls); +} + +void MediaplayerHandler::SetCurrentPlaylist(const std::vector<GURL>& playlist, + int offset) { + currentPlaylist_ = playlist; + currentOffset_ = offset; + DictionaryValue info_value; + ListValue urls; + GetPlaylistValue(urls); + info_value.SetString(kPropertyPath, ""); + info_value.SetBoolean(kPropertyForce, false); + info_value.SetInteger(kPropertyOffset, currentOffset_); + dom_ui_->CallJavascriptFunction(L"playlistChanged", info_value, urls); +} + +void MediaplayerHandler::EnqueueMediaFile(const GURL& url) { + GURL newurl(url); + currentPlaylist_.push_back(newurl); + DictionaryValue info_value; + ListValue urls; + GetPlaylistValue(urls); + info_value.SetString(kPropertyPath, newurl.spec()); + info_value.SetBoolean(kPropertyForce, false); + info_value.SetInteger(kPropertyOffset, currentOffset_); + dom_ui_->CallJavascriptFunction(L"playlistChanged", info_value, urls); + MediaPlayer::Get()->NotifyPlaylistChanged(); +} + +void MediaplayerHandler::HandleCurrentOffsetChanged(const Value* value) { + ListValue results_value; + DictionaryValue info_value; + if (value && value->GetType() == Value::TYPE_LIST) { + const ListValue* list_value = static_cast<const ListValue*>(value); + std::string val; + + // Get the new playlist offset; + if (list_value->GetString(0, &val)) { + int id = atoi(val.c_str()); + currentOffset_ = id; + MediaPlayer::Get()->NotifyPlaylistChanged(); + } + } +} + +void MediaplayerHandler::HandlePlaybackError(const Value* value) { + if (value && value->GetType() == Value::TYPE_LIST) { + const ListValue* list_value = static_cast<const ListValue*>(value); + std::string error; + + // Get path string. + if (list_value->GetString(0, &error)) { + LOG(ERROR) << "Playback error" << error; + } + } +} + +void MediaplayerHandler::HandleGetCurrentPlaylist(const Value* value) { + DictionaryValue info_value; + ListValue urls; + GetPlaylistValue(urls); + info_value.SetInteger(kPropertyOffset, currentOffset_); + dom_ui_->CallJavascriptFunction(L"playlistChanged", info_value, urls); +} + +void MediaplayerHandler::HandleTogglePlaylist(const Value* value) { + MediaPlayer::Get()->TogglePlaylistWindowVisible(); +} + +//////////////////////////////////////////////////////////////////////////////// +// +// Mediaplayer +// +//////////////////////////////////////////////////////////////////////////////// + +void MediaPlayer::EnqueueMediaURL(const GURL& url) { + if (handler_ == NULL) { + GURL newurl(url); + unhandled_urls_.push_back(url); + PopupMediaPlayer(); + } else { + handler_->EnqueueMediaFile(url); + } +} + +void MediaPlayer::ForcePlayMediaURL(const GURL& url) { + if (handler_ == NULL) { + GURL newurl(url); + unhandled_urls_.push_back(url); + PopupMediaPlayer(); + } else { + handler_->PlaybackMediaFile(url); + } +} + +void MediaPlayer::TogglePlaylistWindowVisible() { + if (playlist_browser_) { + ClosePlaylistWindow(); + } else { + ShowPlaylistWindow(); + } +} + +void MediaPlayer::ShowPlaylistWindow() { + if (playlist_browser_ == NULL) { + PopupPlaylist(); + } +} + +void MediaPlayer::ClosePlaylistWindow() { + if (playlist_browser_ != NULL) { + playlist_browser_->window()->Close(); + } +} + +void MediaPlayer::SetPlaylistOffset(int offset) { + if (handler_) { + handler_->SetCurrentPlaylistOffset(offset); + } + if (playlist_) { + playlist_->SetCurrentPlaylistOffset(offset); + } +} + +void MediaPlayer::RegisterNewHandler(MediaplayerHandler* handler, + TabContents* contents) { + handler_ = handler; + mediaplayer_tab_ = contents; + RegisterListeners(); + if (unhandled_urls_.size() != 0) { + for (unsigned int x = 0; x < unhandled_urls_.size(); x++) { + handler_->EnqueueMediaFile(unhandled_urls_[x]); + } + unhandled_urls_.clear(); + } +} + +void MediaPlayer::RegisterListeners() { + registrar_.RemoveAll(); + if (playlist_tab_) { + registrar_.Add(this, + NotificationType::TAB_CONTENTS_DESTROYED, + Source<TabContents>(playlist_tab_)); + } + if (mediaplayer_tab_) { + registrar_.Add(this, + NotificationType::TAB_CONTENTS_DESTROYED, + Source<TabContents>(mediaplayer_tab_)); + } +}; + +void MediaPlayer::Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details) { + DCHECK(type == NotificationType::TAB_CONTENTS_DESTROYED); + if (Source<TabContents>(source).ptr() == mediaplayer_tab_) { + RemoveHandler(handler_); + RegisterListeners(); + ClosePlaylistWindow(); + } else if (Source<TabContents>(source).ptr() == playlist_tab_) { + RemovePlaylistHandler(playlist_); + RegisterListeners(); + } +} + +void MediaPlayer::RegisterNewPlaylistHandler( + MediaplayerHandler* handler, TabContents* contents) { + playlist_ = handler; + playlist_tab_ = contents; + RegisterListeners(); + NotifyPlaylistChanged(); +} + +void MediaPlayer::RemovePlaylistHandler(MediaplayerHandler* handler) { + if (handler == playlist_) { + playlist_ = NULL; + playlist_browser_ = NULL; + playlist_tab_ = NULL; + } +} + +void MediaPlayer::NotifyPlaylistChanged() { + if (handler_ && playlist_) { + playlist_->SetCurrentPlaylist(handler_->GetCurrentPlaylist(), + handler_->GetCurrentPlaylistOffset()); + } +} + +void MediaPlayer::RemoveHandler(MediaplayerHandler* handler) { + if (handler == handler_) { + handler_ = NULL; + mediaplayer_browser_ = NULL; + mediaplayer_tab_ = NULL; + } +} + +void MediaPlayer::PopupPlaylist() { + playlist_browser_ = Browser::CreateForPopup(profile_); + playlist_browser_->AddTabWithURL( + GURL(kMediaplayerPlaylistURL), GURL(), PageTransition::LINK, + true, -1, false, NULL); + playlist_browser_->window()->SetBounds(gfx::Rect(kPopupLeft, + kPopupTop, + kPopupWidth, + kPopupHeight), + BrowserWindow::WINDOW_BOUNDS); + playlist_browser_->window()->Show(); +}; + +void MediaPlayer::PopupMediaPlayer() { + mediaplayer_browser_ = Browser::CreateForPopup(profile_); + mediaplayer_browser_->AddTabWithURL( + GURL(kMediaplayerURL), GURL(), PageTransition::LINK, + true, -1, false, NULL); + mediaplayer_browser_->window()->SetBounds(gfx::Rect(kPopupLeft, + kPopupTop, + kPopupWidth, + kPopupHeight), + BrowserWindow::WINDOW_BOUNDS); + mediaplayer_browser_->window()->Show(); +}; + +MediaPlayer::MediaPlayer() + : handler_(NULL), + playlist_(NULL), + playlist_browser_(NULL), + mediaplayer_browser_(NULL), + mediaplayer_tab_(NULL), + playlist_tab_(NULL) { +}; + +//////////////////////////////////////////////////////////////////////////////// +// +// MediaplayerUIContents +// +//////////////////////////////////////////////////////////////////////////////// + +MediaplayerUI::MediaplayerUI(TabContents* contents) : DOMUI(contents) { + const GURL& url = contents->GetURL(); + bool is_playlist = (url.ref() == "playlist"); + MediaplayerHandler* handler = new MediaplayerHandler(is_playlist); + AddMessageHandler((handler)->Attach(this)); + if (is_playlist) { + handler->Init(true, contents); + } else { + handler->Init(false, contents); + } + + MediaplayerUIHTMLSource* html_source = + new MediaplayerUIHTMLSource(is_playlist); + + // Set up the chrome://mediaplayer/ source. + ChromeThread::PostTask( + ChromeThread::IO, FROM_HERE, + NewRunnableMethod( + Singleton<ChromeURLDataManager>::get(), + &ChromeURLDataManager::AddDataSource, + make_scoped_refptr(html_source))); +} diff --git a/chrome/browser/dom_ui/mediaplayer_ui.h b/chrome/browser/dom_ui/mediaplayer_ui.h new file mode 100644 index 0000000..9a1ce87 --- /dev/null +++ b/chrome/browser/dom_ui/mediaplayer_ui.h @@ -0,0 +1,80 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_DOM_UI_MEDIAPLAYER_UI_H_ +#define CHROME_BROWSER_DOM_UI_MEDIAPLAYER_UI_H_ + +#include <vector> + +#include "base/file_path.h" +#include "base/scoped_ptr.h" +#include "base/singleton.h" +#include "base/values.h" +#include "chrome/browser/dom_ui/chrome_url_data_manager.h" +#include "chrome/browser/dom_ui/dom_ui.h" +#include "chrome/common/notification_observer.h" +#include "chrome/common/notification_source.h" +#include "chrome/common/notification_type.h" +#include "chrome/common/notification_registrar.h" +#include "net/base/directory_lister.h" + +class GURL; +class MediaplayerHandler; +class Browser; + +class MediaPlayer : public NotificationObserver { + public: + ~MediaPlayer() {} + void EnqueueMediaURL(const GURL& url); + void ForcePlayMediaURL(const GURL& url); + void TogglePlaylistWindowVisible(); + void ShowPlaylistWindow(); + void ClosePlaylistWindow(); + void SetPlaylistOffset(int offset); + void RegisterNewHandler(MediaplayerHandler* handler, + TabContents* contents); + void RemoveHandler(MediaplayerHandler* handler); + void RegisterNewPlaylistHandler(MediaplayerHandler* handler, + TabContents* contents); + void RemovePlaylistHandler(MediaplayerHandler* handler); + void NotifyPlaylistChanged(); + + // Used to detect when the mediaplayer is closed + void Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details); + + static MediaPlayer* Get() { + return Singleton<MediaPlayer>::get(); + } + void set_profile(Profile* profile) { profile_ = profile; } + + private: + MediaPlayer(); + void PopupMediaPlayer(); + void PopupPlaylist(); + void RegisterListeners(); + + Profile* profile_; + MediaplayerHandler* handler_; + MediaplayerHandler* playlist_; + Browser* playlist_browser_; + Browser* mediaplayer_browser_; + std::vector<GURL> unhandled_urls_; + NotificationRegistrar registrar_; + TabContents* mediaplayer_tab_; + TabContents* playlist_tab_; + friend struct DefaultSingletonTraits<MediaPlayer>; + DISALLOW_COPY_AND_ASSIGN(MediaPlayer); +}; + +class MediaplayerUI : public DOMUI { + public: + explicit MediaplayerUI(TabContents* contents); + + private: + DISALLOW_COPY_AND_ASSIGN(MediaplayerUI); +}; + +#endif // CHROME_BROWSER_DOM_UI_MEDIAPLAYER_UI_H_ diff --git a/chrome/browser/resources/filebrowse.html b/chrome/browser/resources/filebrowse.html index 4ebbe325..095bb2d 100644 --- a/chrome/browser/resources/filebrowse.html +++ b/chrome/browser/resources/filebrowse.html @@ -1190,8 +1190,8 @@ function playMediaFile(path) { videoPlaybackElement.src = 'file://' + path; } } else { - var newPath = 'chrome://filebrowse#' + path; - chrome.send('openNewPopupWindow', [newPath]); + var newPath = 'file://' + path; + chrome.send('playMediaFile', [newPath]); } }; diff --git a/chrome/browser/resources/mediaplayer.html b/chrome/browser/resources/mediaplayer.html new file mode 100644 index 0000000..d03c138 --- /dev/null +++ b/chrome/browser/resources/mediaplayer.html @@ -0,0 +1,618 @@ +<!DOCTYPE HTML> +<html i18n-values="dir:textdirection;"> +<head> +<meta charset="utf-8"> +<title>Media Player</title> +<style type="text/css"> +.audio.progress { + -webkit-appearance: slider-horizontal; + position: absolute; + left: 93px; + right:90px; + bottom:-2px; + height: 30px; +} + +body { + overflow:hidden; + background:black; +} + +.video.progress { + -webkit-appearance: slider-horizontal; + position: absolute; + left: 93px; + right:90px; + bottom:-2px; + height: 30px; +} + +.videocontrols { + bottom: 0; + left: 0; + z-index:999; + height: 30px; + right: 0; + position:absolute; + background: -webkit-gradient(linear, + left top, + left bottom, + from(#323232), + to(#070707)); +} + +.audiocontrols { + bottom: 0; + left: 0; + z-index:999; + height: 30px; + right: 0; + position:absolute; + background: -webkit-gradient(linear, + left top, + left bottom, + from(#323232), + to(#070707)); +} + +.audio.playbutton { + position: absolute; + left: 0; + bottom: 0; + cursor: pointer; + z-index: 9999; + width: 30px; + background: url('../../app/theme/mediaplayer_play.png'); + background-repeat: no-repeat; + background-position: 8px 8px; + height: 30px; +} + +.audio.soundbutton { + position:absolute; + cursor: pointer; + right: 30px; + bottom:0; + z-index: 9999; + width: 30px; + background: url('../../app/theme/mediaplayer_vol_high.png'); + background-repeat: no-repeat; + background-position: 8px 8px; + height: 30px; +} + +.video.soundbutton { + position:absolute; + right: 30px; + cursor: pointer; + bottom:0; + z-index: 9999; + width: 30px; + background: url('../../app/theme/mediaplayer_vol_high.png'); + background-repeat: no-repeat; + background-position: 8px 8px; + height: 30px; +} + +.audio.volume { + position: absolute; + bottom: 30px; + height: 80px; + width: 30px; + right: 30px; + background: black; + background: -webkit-gradient(linear, + left top, + left bottom, + from(#323232), + to(#070707)); +} + +.video.volume { + position: absolute; + bottom: 30px; + height: 80px; + width: 30px; + right: 30px; + background: black; + background: -webkit-gradient(linear, + left top, + left bottom, + from(#323232), + to(#070707)); +} + +.volumeslider { + -webkit-appearance: slider-vertical; + position: absolute; + left: 0; + right:0; + bottom:0; + top: 0; +} + +.video.playbutton { + position: absolute; + left: 0; + bottom: 0; + cursor: pointer; + z-index: 9999; + width: 30px; + background: url('../../app/theme/mediaplayer_play.png'); + background-repeat: no-repeat; + background-position: 8px 8px; + height: 30px; +} + +.audio.pausebutton { + position: absolute; + left: 0; + bottom: 0; + cursor: pointer; + z-index: 9999; + width: 30px; + height: 30px; + background: url('../../app/theme/mediaplayer_pause.png'); + background-repeat: no-repeat; + background-position: 8px 8px; +} + +.video.pausebutton { + position: absolute; + left: 0; + bottom: 0; + cursor: pointer; + z-index: 9999; + width: 30px; + height: 30px; + background: url('../../app/theme/mediaplayer_pause.png'); + background-repeat: no-repeat; + background-position: 8px 8px; +} + +.video.prevbutton { + position: absolute; + left:30px; + cursor:pointer; + bottom:0; + width:30px; + height:30px; + background: url('../../app/theme/mediaplayer_prev.png'); + background-repeat: no-repeat; + background-position: 8px 8px; +} + +.playbackvideoelement { + width:100%; + height:100%; + position: absolute; + left:0; + top:0; +} + +.duration { + right: 58px; + color: white; + position: absolute; + top: 7px; + font-size: .6em; +} + +.playbackaudioelement { + width:100%; + height:100%; + position: absolute; + left:0; + top:0; +} + +.audio.prevbutton { + position: absolute; + left:30px; + cursor:pointer; + bottom:0; + width:30px; + height:30px; + background: url('../../app/theme/mediaplayer_prev.png'); + background-repeat: no-repeat; + background-position: 8px 8px; +} + +.video.nextbutton { + position: absolute; + left:60px; + cursor:pointer; + bottom:0; + z-index: 9999; + width:30px; + height:30px; + background: url('../../app/theme/mediaplayer_next.png'); + background-repeat: no-repeat; + background-position: 8px 8px; +} + +.playlistbutton { + position: absolute; + right: 0; + cursor:pointer; + z-index: 9999; + bottom: 0; + width: 30px; + height: 30px; + background: url('../../app/theme/mediaplayer_menu.png'); + background-repeat: no-repeat; + background-position: 8px 8px; +} + +.audio.nextbutton { + position: absolute; + left:60px; + cursor:pointer; + bottom:0; + z-index: 9999; + width:30px; + height:30px; + background: url('../../app/theme/mediaplayer_next.png'); + background-repeat: no-repeat; + background-position: 8px 8px; +} + +</style> +<script src='local_strings.js'></script> +<script> + +function $(o) { + return document.getElementById(o); +} + +function pathIsVideoFile(path) { + return /\.(mp4|ogg|mpg|avi)$/i.test(path); +}; + +function pathIsAudioFile(path) { + return /\.(mp3|m4a)$/i.test(path); +}; + +/////////////////////////////////////////////////////////////////////////////// +// Document Functions: +/** + * Window onload handler, sets up the page. + */ +function load() { + chrome.send('getCurrentPlaylist', []); +}; + +var videoPlaybackElement = null; +var audioPlaybackElement = null; +var currentPlaylist = null; +var currentItem = -1; + +function onMediaProgress() { + var element = getMediaElement(); + var current = element.currentTime; + var duration = element.duration; + var progress = $('progress'); + progress.value = (current*100)/duration; + if (progress.value == 100) { + onMediaComplete(); + } +}; + +function onMediaError(e) { + chrome.send('playbackError', ['Error playing back']); + onMediaComplete(); +}; + +function onMediaComplete() { + var mediaElement = getMediaElement(); + mediaElement.removeEventListener("timeupdate", onMediaProgress, true); + mediaElement.removeEventListener("durationchange", onMetadataAvail, true); + // MediaElement.removeEventListener("ended", onMediaComplete, true); + mediaElement.removeEventListener("play", onMediaPlay, true); + mediaElement.removeEventListener("pause", onMediaPause, true); + currentItem ++; + + if (currentItem >= currentPlaylist.length) { + currentItem = -1; + return; + } + chrome.send('currentOffsetChanged', ['' + currentItem]); + playMediaFile(currentPlaylist[currentItem].path); +}; + +function onMediaPlay() { + var pausebutton = $('pausebutton'); + var playbutton = $('playbutton'); + pausebutton.style.display = 'block'; + playbutton.style.display = 'none'; +}; + +function onMediaPause() { + var pausebutton = $('pausebutton'); + var playbutton = $('playbutton'); + playbutton.style.display = 'block'; + pausebutton.style.display = 'none'; +}; + +function setupMediaEvents(element) { + element.addEventListener("timeupdate", onMediaProgress, true); + element.addEventListener("durationchange", onMetadataAvail, true); + // element.addEventListener("ended", onMediaComplete, true); + element.onerror = onMediaError; + element.addEventListener("play", onMediaPlay, true); + element.addEventListener("pause", onMediaPause, true); +}; + +function getMediaElement() { + var mediaElement; + if (videoPlaybackElement) { + mediaElement = videoPlaybackElement; + } else { + mediaElement = audioPlaybackElement; + } + return mediaElement; +}; + +function playPauseButtonClick() { + var mediaElement = getMediaElement(); + if (mediaElement.paused || mediaElement.ended) { + mediaElement.play(); + } else { + mediaElement.pause(); + } +}; + +function prevButtonClick() { + var element = getMediaElement(); + if (element.currentTime > 6) { + element.currentTime = 0; + return; + } + currentItem --; + if (currentItem < 0) { + currentItem = -1; + return; + } + chrome.send('currentOffsetChanged', ['' + currentItem]); + playMediaFile(currentPlaylist[currentItem].path); +}; + +function nextButtonClick() { + currentItem ++; + if (currentItem >= currentPlaylist.length) { + currentItem = -1; + return; + } + chrome.send('currentOffsetChanged', ['' + currentItem]); + playMediaFile(currentPlaylist[currentItem].path); +}; + +function userChangedProgress() { + var val = $('progress').value; + var element = getMediaElement(); + if (element.seekable && element.duration) { + var current = (progress.value * element.duration)/100; + element.currentTime = current; + } +}; + +function toggleVolumeVisible() { + var volume_div = $('volume'); + if (volume_div.style.display == 'none') { + volume_div.style.display = 'block'; + } else { + volume_div.style.display = 'none'; + } +}; + +function volumeChange() { + var volumeslider = $('volumeslider'); + var element = getMediaElement(); + element.volume = (volumeslider.value/100); +}; + +function setupPlaybackControls() { + var element = $('playercontrols'); + playercontrols.innerHTML = ''; // clear out other + var controlsclass = ''; + if (videoPlaybackElement != null) { + controlsclass = 'video'; + element.className = 'videocontrols'; + } else if (audioPlaybackElement != null) { + controlsclass = 'audio'; + element.className = 'audiocontrols'; + } + + var playbutton = document.createElement('div'); + playbutton.id = 'playbutton'; + playbutton.className = controlsclass + ' playbutton'; + playbutton.onclick = playPauseButtonClick; + element.appendChild(playbutton); + + + var pausebutton = document.createElement('div'); + pausebutton.id = 'pausebutton'; + pausebutton.className = controlsclass + ' pausebutton'; + pausebutton.onclick = playPauseButtonClick; + element.appendChild(pausebutton); + + var nextbutton = document.createElement('div'); + nextbutton.id = 'nextbutton'; + nextbutton.className = controlsclass + ' nextbutton'; + nextbutton.onclick = nextButtonClick; + element.appendChild(nextbutton); + + var prevbutton = document.createElement('div'); + prevbutton.id = 'prevbutton'; + prevbutton.className = controlsclass + ' prevbutton'; + prevbutton.onclick = prevButtonClick; + element.appendChild(prevbutton); + + var playlistbutton = document.createElement('div'); + playlistbutton.id = 'playlistbutton'; + playlistbutton.className = 'playlistbutton'; + playlistbutton.onclick = togglePlaylist; + element.appendChild(playlistbutton); + + var slider = document.createElement('input'); + slider.type = 'range'; + slider.id = 'progress'; + slider.className = controlsclass + ' progress'; + slider.onchange = userChangedProgress; + element.appendChild(slider); + + var soundbutton = document.createElement('div'); + soundbutton.id = 'soundbutton'; + soundbutton.className = controlsclass + ' soundbutton'; + soundbutton.onclick = toggleVolumeVisible; + element.appendChild(soundbutton); + + var volume = document.createElement('div'); + volume.id = 'volume'; + volume.className = controlsclass + ' volume'; + volume.style.display = 'none'; + var volumeslider = document.createElement('input'); + volumeslider.type = 'range'; + volumeslider.id = 'volumeslider'; + volumeslider.className = 'volumeslider'; + volumeslider.onchange = volumeChange; + volume.appendChild(volumeslider); + document.body.appendChild(volume); + + var duration = document.createElement('div'); + duration.id = 'duration'; + duration.className = 'duration'; + element.appendChild(duration); +}; + +function playAudioFile(uri) { + if (videoPlaybackElement != null) { + document.body.removeChild(videoPlaybackElement); + videoPlaybackElement = null; + } + if (audioPlaybackElement == null) { + audioPlaybackElement = document.createElement('audio'); + audioPlaybackElement.className = 'playbackaudioelement'; + audioPlaybackElement.autoplay = true; + audioPlaybackElement.controls = false; + setupMediaEvents(audioPlaybackElement); + audioPlaybackElement.src = uri; + setupPlaybackControls(); + document.body.appendChild(audioPlaybackElement); + } else { + setupMediaEvents(audioPlaybackElement); + audioPlaybackElement.src = uri; + audioPlaybackElement.currentTime = 0; + audioPlaybackElement.load(); + audioPlaybackElement.play(); + } +}; + +function toggleFullscreen() { + +}; + +function onMetadataAvail() { + var element = getMediaElement(); + var duration = element.duration; + if (duration) { + var durString = '' + Math.floor((duration / 60)) + ':' + (Math.floor(duration) % 60); + var durDiv = $('duration'); + durDiv.textContent = durString; + } +}; + +function playVideoFile(uri) { + if (audioPlaybackElement != null) { + document.body.removeChild(audioPlaybackElement); + audioPlaybackElement = null; + } + if (videoPlaybackElement == null) { + videoPlaybackElement = document.createElement('video'); + videoPlaybackElement.className = 'playbackvideoelement'; + videoPlaybackElement.autoplay = true; + videoPlaybackElement.controls = false; + setupMediaEvents(videoPlaybackElement); + videoPlaybackElement.src = uri; + videoPlaybackElement.load(); + var toggleButton = document.createElement('div'); + toggleButton.className = 'fullscreentoggle'; + toggleButton.id = 'fullscreentoggle'; + toggleButton.onclick = toggleFullscreen; + document.body.appendChild(toggleButton); + setupPlaybackControls(); + document.body.appendChild(videoPlaybackElement); + } else { + setupMediaEvents(videoPlaybackElement); + videoPlaybackElement.src = uri; + videoPlaybackElement.currentTime = 0; + videoPlaybackElement.load(); + videoPlaybackElement.play(); + } +}; + +function stopAllPlayback() { + var element = getMediaElement(); + if (element != null) { + element.pause(); + } +}; + +function playlistChanged(info, playlist) { + if (info.force) { + currentPlaylist = playlist; + stopAllPlayback(); + if (playlist.length >= 1) { + if (info.currentOffset) { + currentItem = info.currentOffset; + } else { + currentItem = 0; + } + var item = playlist[currentItem]; + playMediaFile(item.path); + } + } else { + var media = getMediaElement(); + currentPlaylist = playlist; + // Only need to handle the case where we are not playing + // since if it is currently playing, it will just move + // to the next file when the current is complete. + if (media == null || media.ended == true) { + for (var x = 0; x < playlist.length; x++) { + if (playlist[x].path == info.path) { + // found the newly added item. + currentItem = x; + chrome.send('currentOffsetChanged', ['' + currentItem]); + playMediaFile(playlist[x].path); + return; + } + } + if (playlist.length > 0) { + currentItem = 0; + chrome.send('currentOffsetChanged', ['' + currentItem]); + playMediaFile(playlist[0].path); + } + } + } +}; + +function togglePlaylist() { + chrome.send("togglePlaylist", []); +}; + +function playMediaFile(url) { + if (pathIsVideoFile(url) ) { + playVideoFile(url); + } else if(pathIsAudioFile(url)) { + playAudioFile(url); + } else { + alert('file unknown'); + } +}; + +</script> +<body onload='load();' onselectstart='return false'> +<div id='playercontrols' class='playercontrols'> +</div> +</body> +</html> diff --git a/chrome/browser/resources/playlist.html b/chrome/browser/resources/playlist.html new file mode 100644 index 0000000..80415f6 --- /dev/null +++ b/chrome/browser/resources/playlist.html @@ -0,0 +1,120 @@ +<!DOCTYPE HTML> +<html i18n-values="dir:textdirection;"> +<head> +<meta charset="utf-8"> +<title>Media Playlist</title> +<style type="text/css"> + +.playlist { + width: 100%; + height: 100%; + background: #080809; + color: #8AACE7; + font-size: .7em; + position: absolute; + top: 0; + left: 0; +} + +.playlistitem { + width: 100%; + padding: 6px; + cursor: pointer; +} + +.playing { + background: #393b41; + color: #dddde7; + font-weight: bold; +} + +.tracknum { + width: 20px; + position: relative; + float: left; +} + +.title { + +} + +</style> +<script src='local_strings.js'></script> +<script> + +function $(o) { + return document.getElementById(o); +} + +function pathIsVideoFile(path) { + return /\.(mp4|ogg|mpg|avi)$/i.test(path); +}; + +function pathIsAudioFile(path) { + return /\.(mp3|m4a)$/i.test(path); +}; + +/////////////////////////////////////////////////////////////////////////////// +// Document Functions: +/** + * Window onload handler, sets up the page. + */ + +var currentPlaylist = null; +var currentOffset = -1; +function load() { + chrome.send("getCurrentPlaylist", []); +}; + +function getDisplayNameFromPath(path) { + slash = path.lastIndexOf("/") + if (slash != -1) { + fileName = path.substring(slash+1,path.length) + return fileName; + } else { + return path; + } +}; + +function setPlaylistOffset(offset) { + chrome.send("setCurrentPlaylistOffset", ['' + offset]); +}; + +function updateUI() { + var main = $('main'); + if (currentPlaylist) { + main.innerHTML = ''; + var main = $('main'); + for (var x = 0; x < currentPlaylist.length; x++) { + var rowdiv = document.createElement('div'); + rowdiv.className = 'playlistitem'; + + var numberdiv = document.createElement('div'); + numberdiv.className = 'tracknum'; + numberdiv.textContent = '' + (x + 1); + rowdiv.appendChild(numberdiv); + + var titlediv = document.createElement('div'); + titlediv.classname = 'title'; + titlediv.textContent = getDisplayNameFromPath(currentPlaylist[x].path); + rowdiv.appendChild(titlediv); + rowdiv.onclick = new Function('setPlaylistOffset(' + x + ')'); + if (currentOffset == x) { + rowdiv.className = 'playlistitem playing'; + } + main.appendChild(rowdiv); + } + } +}; + +function playlistChanged(info, playlist) { + currentPlaylist = playlist; + currentOffset = info.currentOffset; + updateUI(); +}; +</script> +<body onload='load();' onselectstart='return false'> +<div id='main' class='playlist'> +</div> +</body> +</html> diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index fb75ba1..026eebb 100755 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -818,6 +818,8 @@ 'browser/dom_ui/html_dialog_tab_contents_delegate.h', 'browser/dom_ui/html_dialog_ui.cc', 'browser/dom_ui/html_dialog_ui.h', + 'browser/dom_ui/mediaplayer_ui.cc', + 'browser/dom_ui/mediaplayer_ui.h', 'browser/dom_ui/most_visited_handler.cc', 'browser/dom_ui/most_visited_handler.h', 'browser/dom_ui/new_tab_page_sync_handler.cc', diff --git a/chrome/common/url_constants.cc b/chrome/common/url_constants.cc index f2e3ff7..156ca96 100644 --- a/chrome/common/url_constants.cc +++ b/chrome/common/url_constants.cc @@ -56,6 +56,7 @@ const char kChromeUIDownloadsURL[] = "chrome://downloads/"; const char kChromeUIExtensionsURL[] = "chrome://extensions/"; const char kChromeUIHistoryURL[] = "chrome://history/"; const char kChromeUIFileBrowseURL[] = "chrome://filebrowse/"; +const char kChromeUIMediaplayerURL[] = "chrome://mediaplayer/"; const char kChromeUIIPCURL[] = "chrome://about/ipc"; const char kChromeUINetworkURL[] = "chrome://about/network"; const char kChromeUINewTabURL[] = "chrome://newtab"; @@ -68,6 +69,7 @@ const char kChromeUIExtensionsHost[] = "extensions"; const char kChromeUIFavIconPath[] = "favicon"; const char kChromeUIHistoryHost[] = "history"; const char kChromeUIFileBrowseHost[] = "filebrowse"; +const char kChromeUIMediaplayerHost[] = "mediaplayer"; const char kChromeUIInspectorHost[] = "inspector"; const char kChromeUINewTabHost[] = "newtab"; const char kChromeUIThumbnailPath[] = "thumb"; diff --git a/chrome/common/url_constants.h b/chrome/common/url_constants.h index a44992f..ac03c81 100644 --- a/chrome/common/url_constants.h +++ b/chrome/common/url_constants.h @@ -52,6 +52,7 @@ extern const char kChromeUIDownloadsURL[]; extern const char kChromeUIExtensionsURL[]; extern const char kChromeUIHistoryURL[]; extern const char kChromeUIFileBrowseURL[]; +extern const char kChromeUIMediaplayerURL[]; extern const char kChromeUIIPCURL[]; extern const char kChromeUINetworkURL[]; extern const char kChromeUINewTabURL[]; @@ -66,6 +67,7 @@ extern const char kChromeUIExtensionsHost[]; extern const char kChromeUIFavIconPath[]; extern const char kChromeUIHistoryHost[]; extern const char kChromeUIFileBrowseHost[]; +extern const char kChromeUIMediaplayerHost[]; extern const char kChromeUIInspectorHost[]; extern const char kChromeUINewTabHost[]; extern const char kChromeUIThumbnailPath[]; |