Home | History | Annotate | Download | only in file_system_provider
      1 // Copyright 2014 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/chromeos/file_system_provider/notification_manager.h"
      6 
      7 #include "base/strings/utf_string_conversions.h"
      8 #include "chrome/browser/browser_process.h"
      9 #include "chrome/browser/extensions/app_icon_loader_impl.h"
     10 #include "chrome/grit/generated_resources.h"
     11 #include "ui/base/l10n/l10n_util.h"
     12 #include "ui/message_center/message_center.h"
     13 #include "ui/message_center/notification.h"
     14 #include "ui/message_center/notification_delegate.h"
     15 #include "ui/message_center/notification_types.h"
     16 #include "ui/message_center/notifier_settings.h"
     17 
     18 namespace chromeos {
     19 namespace file_system_provider {
     20 namespace {
     21 
     22 // Extension icon size for the notification.
     23 const int kIconSize = 48;
     24 
     25 // Forwards notification events to the notification manager.
     26 class ProviderNotificationDelegate
     27     : public message_center::NotificationDelegate {
     28  public:
     29   // Passing a raw pointer is safe here, since the life of each notification is
     30   // shorter than life of the |notification_manager|.
     31   explicit ProviderNotificationDelegate(
     32       NotificationManager* notification_manager)
     33       : notification_manager_(notification_manager) {}
     34 
     35   virtual void ButtonClick(int button_index) OVERRIDE {
     36     notification_manager_->OnButtonClick(button_index);
     37   }
     38 
     39   virtual void Display() OVERRIDE {}
     40 
     41   virtual void Error() OVERRIDE { notification_manager_->OnError(); }
     42 
     43   virtual void Close(bool by_user) OVERRIDE {
     44     notification_manager_->OnClose();
     45   }
     46 
     47   virtual void Click() OVERRIDE {}
     48 
     49  private:
     50   virtual ~ProviderNotificationDelegate() {}
     51   NotificationManager* notification_manager_;  // Not owned.
     52 
     53   DISALLOW_COPY_AND_ASSIGN(ProviderNotificationDelegate);
     54 };
     55 
     56 }  // namespace
     57 
     58 NotificationManager::NotificationManager(
     59     Profile* profile,
     60     const ProvidedFileSystemInfo& file_system_info)
     61     : profile_(profile),
     62       file_system_info_(file_system_info),
     63       icon_loader_(
     64           new extensions::AppIconLoaderImpl(profile, kIconSize, this)) {
     65 }
     66 
     67 NotificationManager::~NotificationManager() {
     68   if (callbacks_.size()) {
     69     g_browser_process->message_center()->RemoveNotification(
     70         file_system_info_.mount_path().value(), false /* by_user */);
     71   }
     72 }
     73 
     74 void NotificationManager::ShowUnresponsiveNotification(
     75     int id,
     76     const NotificationCallback& callback) {
     77   callbacks_[id] = callback;
     78 
     79   if (callbacks_.size() == 1) {
     80     g_browser_process->message_center()->AddNotification(CreateNotification());
     81   } else {
     82     g_browser_process->message_center()->UpdateNotification(
     83         file_system_info_.mount_path().value(), CreateNotification());
     84   }
     85 }
     86 
     87 void NotificationManager::HideUnresponsiveNotification(int id) {
     88   callbacks_.erase(id);
     89 
     90   if (callbacks_.size()) {
     91     g_browser_process->message_center()->UpdateNotification(
     92         file_system_info_.mount_path().value(), CreateNotification());
     93     return;
     94   }
     95 
     96   g_browser_process->message_center()->RemoveNotification(
     97       file_system_info_.mount_path().value(), false /* by_user */);
     98 }
     99 
    100 void NotificationManager::OnButtonClick(int button_index) {
    101   OnNotificationResult(ABORT);
    102 }
    103 
    104 void NotificationManager::OnError() {
    105   OnNotificationResult(CONTINUE);
    106 }
    107 
    108 void NotificationManager::OnClose() {
    109   OnNotificationResult(CONTINUE);
    110 }
    111 
    112 void NotificationManager::SetAppImage(const std::string& id,
    113                                       const gfx::ImageSkia& image) {
    114   extension_icon_.reset(new gfx::Image(image));
    115   g_browser_process->message_center()->UpdateNotification(
    116       file_system_info_.mount_path().value(), CreateNotification());
    117 }
    118 
    119 scoped_ptr<message_center::Notification>
    120 NotificationManager::CreateNotification() {
    121   if (!extension_icon_.get())
    122     icon_loader_->FetchImage(file_system_info_.extension_id());
    123 
    124   message_center::RichNotificationData rich_notification_data;
    125   rich_notification_data.buttons.push_back(
    126       message_center::ButtonInfo(l10n_util::GetStringUTF16(
    127           IDS_FILE_SYSTEM_PROVIDER_UNRESPONSIVE_ABORT_BUTTON)));
    128 
    129   scoped_ptr<message_center::Notification> notification(
    130       new message_center::Notification(
    131           message_center::NOTIFICATION_TYPE_SIMPLE,
    132           file_system_info_.mount_path().value(),
    133           base::UTF8ToUTF16(file_system_info_.display_name()),
    134           l10n_util::GetStringUTF16(
    135               callbacks_.size() == 1
    136                   ? IDS_FILE_SYSTEM_PROVIDER_UNRESPONSIVE_WARNING
    137                   : IDS_FILE_SYSTEM_PROVIDER_MANY_UNRESPONSIVE_WARNING),
    138           extension_icon_.get() ? *extension_icon_.get() : gfx::Image(),
    139           base::string16(),  // display_source
    140           message_center::NotifierId(
    141               message_center::NotifierId::SYSTEM_COMPONENT,
    142               file_system_info_.mount_path().value()),
    143           rich_notification_data,
    144           new ProviderNotificationDelegate(this)));
    145 
    146   notification->SetSystemPriority();
    147   return notification.Pass();
    148 }
    149 
    150 void NotificationManager::OnNotificationResult(NotificationResult result) {
    151   CallbackMap::iterator it = callbacks_.begin();
    152   while (it != callbacks_.end()) {
    153     CallbackMap::iterator current_it = it++;
    154     NotificationCallback callback = current_it->second;
    155     callbacks_.erase(current_it);
    156     callback.Run(result);
    157   }
    158 }
    159 
    160 }  // namespace file_system_provider
    161 }  // namespace chromeos
    162