Home | History | Annotate | Download | only in webui
      1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "chrome/browser/ui/webui/slideshow_ui.h"
      6 
      7 #include "base/callback.h"
      8 #include "base/memory/singleton.h"
      9 #include "base/memory/weak_ptr.h"
     10 #include "base/message_loop.h"
     11 #include "base/path_service.h"
     12 #include "base/string_piece.h"
     13 #include "base/string_util.h"
     14 #include "base/threading/thread.h"
     15 #include "base/time.h"
     16 #include "base/utf_string_conversions.h"
     17 #include "base/values.h"
     18 #include "chrome/browser/history/history_types.h"
     19 #include "chrome/browser/metrics/user_metrics.h"
     20 #include "chrome/browser/profiles/profile.h"
     21 #include "chrome/browser/ui/webui/favicon_source.h"
     22 #include "chrome/common/chrome_paths.h"
     23 #include "chrome/common/jstemplate_builder.h"
     24 #include "chrome/common/url_constants.h"
     25 #include "content/browser/browser_thread.h"
     26 #include "content/browser/tab_contents/tab_contents.h"
     27 #include "grit/browser_resources.h"
     28 #include "grit/chromium_strings.h"
     29 #include "grit/generated_resources.h"
     30 #include "grit/locale_settings.h"
     31 #include "net/base/directory_lister.h"
     32 #include "net/base/escape.h"
     33 #include "ui/base/resource/resource_bundle.h"
     34 
     35 static const char kPropertyPath[] = "path";
     36 static const char kPropertyTitle[] = "title";
     37 static const char kPropertyOffset[] = "currentOffset";
     38 static const char kPropertyDirectory[] = "isDirectory";
     39 
     40 class SlideshowUIHTMLSource : public ChromeURLDataManager::DataSource {
     41  public:
     42   SlideshowUIHTMLSource();
     43 
     44   // Called when the network layer has requested a resource underneath
     45   // the path we registered.
     46   virtual void StartDataRequest(const std::string& path,
     47                                 bool is_incognito,
     48                                 int request_id);
     49   virtual std::string GetMimeType(const std::string&) const {
     50     return "text/html";
     51   }
     52 
     53  private:
     54   ~SlideshowUIHTMLSource() {}
     55 
     56   DISALLOW_COPY_AND_ASSIGN(SlideshowUIHTMLSource);
     57 };
     58 
     59 // The handler for Javascript messages related to the "slideshow" view.
     60 class SlideshowHandler : public net::DirectoryLister::DirectoryListerDelegate,
     61                          public WebUIMessageHandler,
     62                          public base::SupportsWeakPtr<SlideshowHandler> {
     63  public:
     64   SlideshowHandler();
     65   virtual ~SlideshowHandler();
     66 
     67   // Init work after Attach.
     68   void Init();
     69 
     70   // DirectoryLister::DirectoryListerDelegate methods:
     71   virtual void OnListFile(
     72       const net::DirectoryLister::DirectoryListerData& data);
     73   virtual void OnListDone(int error);
     74 
     75   // WebUIMessageHandler implementation.
     76   virtual WebUIMessageHandler* Attach(WebUI* web_ui);
     77   virtual void RegisterMessages();
     78 
     79   void GetChildrenForPath(const FilePath& path, bool is_refresh);
     80 
     81   // Callback for the "getChildren" message.
     82   void HandleGetChildren(const ListValue* args);
     83 
     84   void HandleRefreshDirectory(const ListValue* args);
     85 
     86  private:
     87   bool PathIsImageFile(const char* filename);
     88 
     89   scoped_ptr<ListValue> filelist_value_;
     90   FilePath currentpath_;
     91   FilePath originalpath_;
     92   Profile* profile_;
     93   int counter_;
     94   int currentOffset_;
     95   scoped_refptr<net::DirectoryLister> lister_;
     96   bool is_refresh_;
     97 
     98   DISALLOW_COPY_AND_ASSIGN(SlideshowHandler);
     99 };
    100 
    101 ////////////////////////////////////////////////////////////////////////////////
    102 //
    103 // SlideshowHTMLSource
    104 //
    105 ////////////////////////////////////////////////////////////////////////////////
    106 
    107 SlideshowUIHTMLSource::SlideshowUIHTMLSource()
    108     : DataSource(chrome::kChromeUISlideshowHost, MessageLoop::current()) {
    109 }
    110 
    111 void SlideshowUIHTMLSource::StartDataRequest(const std::string& path,
    112                                               bool is_incognito,
    113                                               int request_id) {
    114   DictionaryValue localized_strings;
    115   // TODO(dhg): Add stirings to localized strings, also add more strings
    116   // that are currently hardcoded.
    117   SetFontAndTextDirection(&localized_strings);
    118 
    119   static const base::StringPiece slideshow_html(
    120       ResourceBundle::GetSharedInstance().GetRawDataResource(
    121           IDR_SLIDESHOW_HTML));
    122   const std::string full_html = jstemplate_builder::GetI18nTemplateHtml(
    123       slideshow_html, &localized_strings);
    124 
    125   scoped_refptr<RefCountedBytes> html_bytes(new RefCountedBytes);
    126   html_bytes->data.resize(full_html.size());
    127   std::copy(full_html.begin(), full_html.end(), html_bytes->data.begin());
    128 
    129   SendResponse(request_id, html_bytes);
    130 }
    131 
    132 ////////////////////////////////////////////////////////////////////////////////
    133 //
    134 // SlideshowHandler
    135 //
    136 ////////////////////////////////////////////////////////////////////////////////
    137 SlideshowHandler::SlideshowHandler()
    138     : profile_(NULL),
    139       is_refresh_(false) {
    140   lister_ = NULL;
    141 }
    142 
    143 SlideshowHandler::~SlideshowHandler() {
    144   if (lister_.get()) {
    145     lister_->Cancel();
    146     lister_->set_delegate(NULL);
    147   }
    148 }
    149 
    150 WebUIMessageHandler* SlideshowHandler::Attach(WebUI* web_ui) {
    151   profile_ = web_ui->GetProfile();
    152   // Create our favicon data source.
    153   profile_->GetChromeURLDataManager()->AddDataSource(
    154       new FaviconSource(profile_));
    155   return WebUIMessageHandler::Attach(web_ui);
    156 }
    157 
    158 void SlideshowHandler::Init() {
    159 }
    160 
    161 void SlideshowHandler::RegisterMessages() {
    162   web_ui_->RegisterMessageCallback("getChildren",
    163       NewCallback(this, &SlideshowHandler::HandleGetChildren));
    164   web_ui_->RegisterMessageCallback("refreshDirectory",
    165       NewCallback(this, &SlideshowHandler::HandleRefreshDirectory));
    166 }
    167 
    168 void SlideshowHandler::HandleRefreshDirectory(const ListValue* args) {
    169 #if defined(OS_CHROMEOS)
    170   std::string path = UTF16ToUTF8(ExtractStringValue(args));
    171   GetChildrenForPath(FilePath(path), true);
    172 #endif
    173 }
    174 
    175 void SlideshowHandler::GetChildrenForPath(const FilePath& path,
    176                                           bool is_refresh) {
    177   filelist_value_.reset(new ListValue());
    178   currentpath_ = path;
    179 
    180   if (lister_.get()) {
    181     lister_->Cancel();
    182     lister_->set_delegate(NULL);
    183     lister_ = NULL;
    184   }
    185 
    186   is_refresh_ = is_refresh;
    187   if (file_util::EnsureEndsWithSeparator(&currentpath_) &&
    188       currentpath_.IsAbsolute()) {
    189     lister_ = new net::DirectoryLister(currentpath_, this);
    190   } else {
    191     originalpath_ = currentpath_;
    192     currentpath_ = currentpath_.DirName();
    193     lister_ = new net::DirectoryLister(currentpath_, this);
    194   }
    195   counter_ = 0;
    196   currentOffset_ = -1;
    197   lister_->Start();
    198 }
    199 
    200 void SlideshowHandler::HandleGetChildren(const ListValue* args) {
    201 #if defined(OS_CHROMEOS)
    202   filelist_value_.reset(new ListValue());
    203   std::string path = UTF16ToUTF8(ExtractStringValue(args));
    204   GetChildrenForPath(FilePath(path), false);
    205 #endif
    206 }
    207 
    208 bool SlideshowHandler::PathIsImageFile(const char* filename) {
    209 #if defined(OS_CHROMEOS)
    210   FilePath file = FilePath(filename);
    211   std::string ext = file.Extension();
    212   ext = StringToLowerASCII(ext);
    213   if (ext == ".jpg" ||
    214       ext == ".jpeg" ||
    215       ext == ".png" ||
    216       ext == ".gif") {
    217     return true;
    218   } else {
    219     return false;
    220   }
    221 #else
    222   return false;
    223 #endif
    224 }
    225 
    226 void SlideshowHandler::OnListFile(
    227     const net::DirectoryLister::DirectoryListerData& data) {
    228 #if defined(OS_CHROMEOS)
    229   if (data.info.filename[0] == '.') {
    230     return;
    231   }
    232   if (!PathIsImageFile(data.info.filename.c_str())) {
    233     return;
    234   }
    235 
    236   DictionaryValue* file_value = new DictionaryValue();
    237 
    238   file_value->SetString(kPropertyTitle, data.info.filename);
    239   file_value->SetString(kPropertyPath,
    240                         currentpath_.Append(data.info.filename).value());
    241   file_value->SetBoolean(kPropertyDirectory, S_ISDIR(data.info.stat.st_mode));
    242   filelist_value_->Append(file_value);
    243   std::string val;
    244   file_value->GetString(kPropertyTitle, &val);
    245   if (val == originalpath_.BaseName().value()) {
    246     currentOffset_ = counter_;
    247   }
    248   counter_++;
    249 #endif
    250 }
    251 
    252 void SlideshowHandler::OnListDone(int error) {
    253   DictionaryValue info_value;
    254   counter_ = 0;
    255   if (!(file_util::EnsureEndsWithSeparator(&originalpath_) &&
    256         originalpath_.IsAbsolute()) &&
    257       currentOffset_ != -1) {
    258     info_value.SetInteger(kPropertyOffset, currentOffset_);
    259   }
    260   if (is_refresh_) {
    261     info_value.SetString("functionCall", "refresh");
    262   } else {
    263     info_value.SetString("functionCall", "getChildren");
    264   }
    265   info_value.SetString(kPropertyPath, currentpath_.value());
    266   web_ui_->CallJavascriptFunction("browseFileResult",
    267                                   info_value, *(filelist_value_.get()));
    268 }
    269 
    270 ////////////////////////////////////////////////////////////////////////////////
    271 //
    272 // SlideshowUI
    273 //
    274 ////////////////////////////////////////////////////////////////////////////////
    275 
    276 SlideshowUI::SlideshowUI(TabContents* contents) : WebUI(contents) {
    277   SlideshowHandler* handler = new SlideshowHandler();
    278   AddMessageHandler((handler)->Attach(this));
    279   handler->Init();
    280   SlideshowUIHTMLSource* html_source = new SlideshowUIHTMLSource();
    281 
    282   // Set up the chrome://slideshow/ source.
    283   contents->profile()->GetChromeURLDataManager()->AddDataSource(html_source);
    284 }
    285