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