message_center_notification_manager.cc revision 58537e28ecd584eab876aee8be7156509866d23a
12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/notifications/message_center_notification_manager.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/logging.h"
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/scoped_ptr.h"
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_service.h"
102385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "chrome/browser/chrome_notification_types.h"
11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/extensions/extension_info_map.h"
12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/extensions/extension_system.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/notifications/desktop_notification_service.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/notifications/desktop_notification_service_factory.h"
1558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "chrome/browser/notifications/fullscreen_notification_blocker.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/notifications/message_center_settings_controller.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/notifications/notification.h"
1858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "chrome/browser/notifications/screen_lock_notification_blocker.h"
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/profiles/profile.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/browser_finder.h"
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/chrome_pages.h"
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/host_desktop.h"
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/extensions/extension_set.h"
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/pref_names.h"
252385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "content/public/browser/notification_service.h"
262385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "content/public/browser/user_metrics.h"
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/web_contents.h"
28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/public/common/url_constants.h"
29424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "ui/gfx/image/image_skia.h"
3090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "ui/message_center/message_center_style.h"
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/message_center/message_center_tray.h"
3258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "ui/message_center/message_center_types.h"
33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/message_center/notifier_settings.h"
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#if defined(OS_CHROMEOS)
3658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "chrome/browser/notifications/login_state_notification_blocker_chromeos.h"
3758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#endif
3858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
39eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochnamespace {
40eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// The first-run balloon will be shown |kFirstRunIdleDelaySeconds| after all
41eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// popups go away and the user has notifications in the message center.
42eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochconst int kFirstRunIdleDelaySeconds = 1;
43eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}  // namespace
44eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)MessageCenterNotificationManager::MessageCenterNotificationManager(
46eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    message_center::MessageCenter* message_center,
47bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    PrefService* local_state,
48bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    scoped_ptr<message_center::NotifierSettingsProvider> settings_provider)
49868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    : message_center_(message_center),
50eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#if defined(OS_WIN)
51eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      first_run_idle_timeout_(
52eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          base::TimeDelta::FromSeconds(kFirstRunIdleDelaySeconds)),
53eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      weak_factory_(this),
54eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif
5558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      settings_provider_(settings_provider.Pass()),
5658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      system_observer_(this) {
57eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#if defined(OS_WIN)
58eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  first_run_pref_.Init(prefs::kMessageCenterShowedFirstRunBalloon, local_state);
59eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif
60eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  message_center_->AddObserver(this);
62bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  message_center_->SetNotifierSettingsProvider(settings_provider_.get());
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#if defined(OS_CHROMEOS)
6558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  blockers_.push_back(
6658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      new LoginStateNotificationBlockerChromeOS(message_center));
6758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#else
6858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  blockers_.push_back(new ScreenLockNotificationBlocker(message_center));
6958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#endif
7058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  blockers_.push_back(new FullscreenNotificationBlocker(message_center));
7158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
72868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#if defined(OS_WIN) || defined(OS_MACOSX) \
73868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  || (defined(USE_AURA) && !defined(USE_ASH))
74868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // On Windows, Linux and Mac, the notification manager owns the tray icon and
75868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // views.Other platforms have global ownership and Create will return NULL.
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  tray_.reset(message_center::CreateMessageCenterTray());
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
782385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  registrar_.Add(this,
792385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                 chrome::NOTIFICATION_FULLSCREEN_CHANGED,
802385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                 content::NotificationService::AllSources());
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)MessageCenterNotificationManager::~MessageCenterNotificationManager() {
84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  message_center_->RemoveObserver(this);
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// NotificationUIManager
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void MessageCenterNotificationManager::Add(const Notification& notification,
9158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                           Profile* profile) {
9258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (Update(notification, profile))
9358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return;
94868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AddProfileNotification(
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new ProfileNotification(profile, notification, message_center_));
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)bool MessageCenterNotificationManager::Update(const Notification& notification,
10058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                              Profile* profile) {
101a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Only progress notification update can be reflected immediately in the
102a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // message center.
103a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  bool update_progress_notification =
104a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      notification.type() == message_center::NOTIFICATION_TYPE_PROGRESS;
105a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  bool is_message_center_visible = message_center_->IsMessageCenterVisible();
106a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (!update_progress_notification && is_message_center_visible)
107868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return false;
108868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const string16& replace_id = notification.replace_id();
110868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (replace_id.empty())
111868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return false;
112868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const GURL origin_url = notification.origin_url();
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(origin_url.is_valid());
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Since replace_id is provided by arbitrary JS, we need to use origin_url
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // (which is an app url in case of app/extension) to scope the replace ids
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // in the given profile.
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (NotificationMap::iterator iter = profile_notifications_.begin();
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       iter != profile_notifications_.end(); ++iter) {
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ProfileNotification* old_notification = (*iter).second;
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (old_notification->notification().replace_id() == replace_id &&
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        old_notification->notification().origin_url() == origin_url &&
124eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        old_notification->profile() == profile) {
125a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      // Changing the type from non-progress to progress does not count towards
126a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      // the immediate update allowed in the message center.
127a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      if (update_progress_notification && is_message_center_visible &&
128a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)          old_notification->notification().type() !=
129a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)              message_center::NOTIFICATION_TYPE_PROGRESS) {
130a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        return false;
131a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      }
132a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      std::string old_id =
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          old_notification->notification().notification_id();
135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      DCHECK(message_center_->HasNotification(old_id));
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // Add/remove notification in the local list but just update the same
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // one in MessageCenter.
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      delete old_notification;
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      profile_notifications_.erase(old_id);
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProfileNotification* new_notification =
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          new ProfileNotification(profile, notification, message_center_);
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      profile_notifications_[notification.notification_id()] = new_notification;
144868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
145868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      // Now pass a copy to message center.
146868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      scoped_ptr<message_center::Notification> message_center_notification(
147868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          make_scoped_ptr(new message_center::Notification(notification)));
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      message_center_->UpdateNotification(old_id,
149868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                          message_center_notification.Pass());
150868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new_notification->StartDownloads();
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return true;
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return false;
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)const Notification* MessageCenterNotificationManager::FindById(
15958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const std::string& id) const {
16058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  NotificationMap::const_iterator iter = profile_notifications_.find(id);
16158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (iter == profile_notifications_.end())
16258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return NULL;
16358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return &(iter->second->notification());
16458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)bool MessageCenterNotificationManager::CancelById(const std::string& id) {
16758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // See if this ID hasn't been shown yet.
16858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // If it has been shown, remove it.
16958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  NotificationMap::iterator iter = profile_notifications_.find(id);
17058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (iter == profile_notifications_.end())
17158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return false;
17258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
17358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  message_center_->RemoveNotification(id, /* by_user */ false);
17458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return true;
17558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
17658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
17758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)std::set<std::string>
17858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)MessageCenterNotificationManager::GetAllIdsByProfileAndSourceOrigin(
17958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    Profile* profile,
18058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const GURL& source) {
18158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
18258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  std::set<std::string> notification_ids;
18358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  for (NotificationMap::iterator iter = profile_notifications_.begin();
18458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)       iter != profile_notifications_.end(); iter++) {
18558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    if ((*iter).second->notification().origin_url() == source &&
18658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        profile == (*iter).second->profile()) {
18758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      notification_ids.insert(iter->first);
18858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    }
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
19058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return notification_ids;
19158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
19358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)bool MessageCenterNotificationManager::CancelAllBySourceOrigin(
19458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const GURL& source) {
19558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Same pattern as CancelById, but more complicated than the above
19658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // because there may be multiple notifications from the same source.
19758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  bool removed = false;
198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
19958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  for (NotificationMap::iterator loopiter = profile_notifications_.begin();
20058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)       loopiter != profile_notifications_.end(); ) {
20158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    NotificationMap::iterator curiter = loopiter++;
20258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    if ((*curiter).second->notification().origin_url() == source) {
20358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      message_center_->RemoveNotification(curiter->first, /* by_user */ false);
20458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      removed = true;
20558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    }
20658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
20758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return removed;
20858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
20958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
21058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)bool MessageCenterNotificationManager::CancelAllByProfile(Profile* profile) {
21158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Same pattern as CancelAllBySourceOrigin.
21258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  bool removed = false;
21358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
21458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  for (NotificationMap::iterator loopiter = profile_notifications_.begin();
21558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)       loopiter != profile_notifications_.end(); ) {
21658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    NotificationMap::iterator curiter = loopiter++;
21758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    if (profile == (*curiter).second->profile()) {
21858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      message_center_->RemoveNotification(curiter->first, /* by_user */ false);
21958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      removed = true;
22058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    }
22158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
22258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return removed;
22358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
22458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
22558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void MessageCenterNotificationManager::CancelAll() {
22658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  message_center_->RemoveAllNotifications(/* by_user */ false);
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
229c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// MessageCenter::Observer
231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void MessageCenterNotificationManager::OnNotificationRemoved(
232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const std::string& notification_id,
233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    bool by_user) {
234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Do not call FindProfileNotification(). Some tests create notifications
235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // directly to MessageCenter, but this method will be called for the removals
236c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // of such notifications.
237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  NotificationMap::const_iterator iter =
238c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      profile_notifications_.find(notification_id);
239c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (iter != profile_notifications_.end())
240ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    RemoveProfileNotification(iter->second);
241eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
242eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#if defined(OS_WIN)
243eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  CheckFirstRunTimer();
244eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif
245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
24758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void MessageCenterNotificationManager::OnCenterVisibilityChanged(
24858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    message_center::Visibility visibility) {
24958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  switch (visibility) {
25058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    case message_center::VISIBILITY_TRANSIENT:
251eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#if defined(OS_WIN)
25258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      CheckFirstRunTimer();
253eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif
25458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      break;
25558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    case message_center::VISIBILITY_MESSAGE_CENTER:
25658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      content::RecordAction(
25758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          content::UserMetricsAction("Notifications.ShowMessageCenter"));
25858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      break;
25958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    case message_center::VISIBILITY_SETTINGS:
26058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      content::RecordAction(
26158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          content::UserMetricsAction("Notifications.ShowSettings"));
26258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      break;
26358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
264eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
265eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
266eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid MessageCenterNotificationManager::OnNotificationUpdated(
267eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const std::string& notification_id) {
268eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#if defined(OS_WIN)
269eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  CheckFirstRunTimer();
270eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif
271eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
272eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
273eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid MessageCenterNotificationManager::SetMessageCenterTrayDelegateForTest(
274eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    message_center::MessageCenterTrayDelegate* delegate) {
275eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  tray_.reset(delegate);
276868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
277868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2782385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochvoid MessageCenterNotificationManager::Observe(
2792385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    int type,
2802385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    const content::NotificationSource& source,
2812385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    const content::NotificationDetails& details) {
2822385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  if (type == chrome::NOTIFICATION_FULLSCREEN_CHANGED) {
2832385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    const bool is_fullscreen = *content::Details<bool>(details).ptr();
2842385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
2852385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    if (is_fullscreen && tray_.get() && tray_->GetMessageCenterTray())
2862385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      tray_->GetMessageCenterTray()->HidePopupBubble();
2872385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  }
2882385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}
2892385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// ImageDownloads
2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)MessageCenterNotificationManager::ImageDownloads::ImageDownloads(
294c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    message_center::MessageCenter* message_center,
295c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ImageDownloadsObserver* observer)
296c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : message_center_(message_center),
297c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      pending_downloads_(0),
298c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      observer_(observer) {
2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)MessageCenterNotificationManager::ImageDownloads::~ImageDownloads() { }
3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MessageCenterNotificationManager::ImageDownloads::StartDownloads(
3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const Notification& notification) {
305c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // In case all downloads are synchronous, assume a pending download.
306c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  AddPendingDownload();
307c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Notification primary icon.
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  StartDownloadWithImage(
3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      notification,
3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      &notification.icon(),
3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      notification.icon_url(),
3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      message_center::kNotificationIconSize,
3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&message_center::MessageCenter::SetNotificationIcon,
3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 base::Unretained(message_center_),
3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 notification.notification_id()));
3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Notification image.
319868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  StartDownloadWithImage(
3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      notification,
321868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      NULL,
322868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      notification.image_url(),
3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      message_center::kNotificationPreferredImageSize,
3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&message_center::MessageCenter::SetNotificationImage,
3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 base::Unretained(message_center_),
3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 notification.notification_id()));
3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Notification button icons.
329868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  StartDownloadWithImage(
3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      notification,
331868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      NULL,
332868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      notification.button_one_icon_url(),
3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      message_center::kNotificationButtonIconSize,
3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&message_center::MessageCenter::SetNotificationButtonIcon,
3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 base::Unretained(message_center_),
336868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                 notification.notification_id(),
337868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                 0));
338868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  StartDownloadWithImage(
339868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      notification,
340868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      NULL,
341868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      notification.button_two_icon_url(),
3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      message_center::kNotificationButtonIconSize,
3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&message_center::MessageCenter::SetNotificationButtonIcon,
3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 base::Unretained(message_center_),
345868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                 notification.notification_id(),
346868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                 1));
347c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
348c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // This should tell the observer we're done if everything was synchronous.
349c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  PendingDownloadCompleted();
3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MessageCenterNotificationManager::ImageDownloads::StartDownloadWithImage(
3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const Notification& notification,
3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const gfx::Image* image,
3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GURL& url,
3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int size,
3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const SetImageCallback& callback) {
3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Set the image directly if we have it.
3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (image && !image->IsEmpty()) {
3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    callback.Run(*image);
3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Leave the image null if there's no URL.
3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (url.is_empty())
3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  content::RenderViewHost* host = notification.GetRenderViewHost();
3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!host) {
3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LOG(WARNING) << "Notification needs an image but has no RenderViewHost";
3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  content::WebContents* contents =
3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      content::WebContents::FromRenderViewHost(host);
3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!contents) {
3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LOG(WARNING) << "Notification needs an image but has no WebContents";
3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
381c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  AddPendingDownload();
382c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
383c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  contents->DownloadImage(
3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      url,
385eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      false,  // Not a favicon
386eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      size,  // Preferred size
387eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      0,  // No maximum size
3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(
3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          &MessageCenterNotificationManager::ImageDownloads::DownloadComplete,
3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          AsWeakPtr(),
3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          callback));
3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MessageCenterNotificationManager::ImageDownloads::DownloadComplete(
3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const SetImageCallback& callback,
3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int download_id,
39790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    int http_status_code,
3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GURL& image_url,
3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int requested_size,
4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::vector<SkBitmap>& bitmaps) {
401c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  PendingDownloadCompleted();
402c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (bitmaps.empty())
4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Image image = gfx::Image::CreateFrom1xBitmap(bitmaps[0]);
4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  callback.Run(image);
4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
409c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Private methods.
410c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
411c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void MessageCenterNotificationManager::ImageDownloads::AddPendingDownload() {
412c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ++pending_downloads_;
413c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
414c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
415c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void
416c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)MessageCenterNotificationManager::ImageDownloads::PendingDownloadCompleted() {
417c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(pending_downloads_ > 0);
418c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (--pending_downloads_ == 0 && observer_)
419c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    observer_->OnDownloadsCompleted();
420c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
421c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// ProfileNotification
4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)MessageCenterNotificationManager::ProfileNotification::ProfileNotification(
4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Profile* profile,
4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const Notification& notification,
4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    message_center::MessageCenter* message_center)
4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : profile_(profile),
4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      notification_(notification),
431c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      downloads_(new ImageDownloads(message_center, this)) {
4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(profile);
4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)MessageCenterNotificationManager::ProfileNotification::~ProfileNotification() {
4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MessageCenterNotificationManager::ProfileNotification::StartDownloads() {
4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  downloads_->StartDownloads(notification_);
4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
442c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void
443c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)MessageCenterNotificationManager::ProfileNotification::OnDownloadsCompleted() {
444c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  notification_.DoneRendering();
445c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
446c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::string
4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MessageCenterNotificationManager::ProfileNotification::GetExtensionId() {
449c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ExtensionInfoMap* extension_info_map =
450c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      extensions::ExtensionSystem::Get(profile())->info_map();
451c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ExtensionSet extensions;
452c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  extension_info_map->GetExtensionsWithAPIPermissionForSecurityOrigin(
453c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      notification().origin_url(), notification().process_id(),
454c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      extensions::APIPermission::kNotification, &extensions);
455c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
456c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DesktopNotificationService* desktop_service =
457c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      DesktopNotificationServiceFactory::GetForProfile(profile());
458c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  for (ExtensionSet::const_iterator iter = extensions.begin();
459c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)       iter != extensions.end(); ++iter) {
460eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    if (desktop_service->IsNotifierEnabled(message_center::NotifierId(
461eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch            message_center::NotifierId::APPLICATION, (*iter)->id()))) {
462c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return (*iter)->id();
463eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    }
464c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
465c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return std::string();
4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// private
4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MessageCenterNotificationManager::AddProfileNotification(
4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ProfileNotification* profile_notification) {
4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const Notification& notification = profile_notification->notification();
4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string id = notification.notification_id();
4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Notification ids should be unique.
4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(profile_notifications_.find(id) == profile_notifications_.end());
4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  profile_notifications_[id] = profile_notification;
4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
479868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Create the copy for message center, and ensure the extension ID is correct.
480868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  scoped_ptr<message_center::Notification> message_center_notification(
481868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new message_center::Notification(notification));
482868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  message_center_->AddNotification(message_center_notification.Pass());
483868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  profile_notification->StartDownloads();
4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MessageCenterNotificationManager::RemoveProfileNotification(
488ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    ProfileNotification* profile_notification) {
4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string id = profile_notification->notification().notification_id();
4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  profile_notifications_.erase(id);
4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  delete profile_notification;
4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)MessageCenterNotificationManager::ProfileNotification*
4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MessageCenterNotificationManager::FindProfileNotification(
4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        const std::string& id) const {
4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NotificationMap::const_iterator iter = profile_notifications_.find(id);
498c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (iter == profile_notifications_.end())
499c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return NULL;
500c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return (*iter).second;
5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
503