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"
9a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "base/prefs/pref_registry_simple.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_service.h"
11116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/stl_util.h"
126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "chrome/browser/extensions/api/notification_provider/notification_provider_api.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/notifications/desktop_notification_service.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/notifications/desktop_notification_service_factory.h"
151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chrome/browser/notifications/extension_welcome_notification.h"
161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chrome/browser/notifications/extension_welcome_notification_factory.h"
1758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "chrome/browser/notifications/fullscreen_notification_blocker.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/notifications/message_center_settings_controller.h"
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/notifications/notification.h"
206e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "chrome/browser/notifications/notification_conversion_helper.h"
2158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "chrome/browser/notifications/screen_lock_notification_blocker.h"
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/profiles/profile.h"
236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "chrome/common/extensions/api/notification_provider.h"
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/pref_names.h"
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/web_contents.h"
26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/public/common/url_constants.h"
276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "extensions/browser/extension_registry.h"
285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/common/extension_set.h"
296e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "extensions/common/permissions/permissions_data.h"
30424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "ui/gfx/image/image_skia.h"
3190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "ui/message_center/message_center_style.h"
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/message_center/message_center_tray.h"
3358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "ui/message_center/message_center_types.h"
34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/message_center/notifier_settings.h"
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#if defined(OS_CHROMEOS)
3758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "chrome/browser/notifications/login_state_notification_blocker_chromeos.h"
38a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/browser/ui/ash/multi_user/multi_user_util.h"
3958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#endif
4058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(USE_ASH)
425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ash/shell.h"
435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ash/system/web_notification/web_notification_tray.h"
445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#if defined(OS_WIN)
47eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// The first-run balloon will be shown |kFirstRunIdleDelaySeconds| after all
48eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// popups go away and the user has notifications in the message center.
49eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochconst int kFirstRunIdleDelaySeconds = 1;
5068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#endif
51eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)MessageCenterNotificationManager::MessageCenterNotificationManager(
53eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    message_center::MessageCenter* message_center,
54bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    PrefService* local_state,
55bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    scoped_ptr<message_center::NotifierSettingsProvider> settings_provider)
56868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    : message_center_(message_center),
57eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#if defined(OS_WIN)
58eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      first_run_idle_timeout_(
59eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          base::TimeDelta::FromSeconds(kFirstRunIdleDelaySeconds)),
60eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      weak_factory_(this),
61eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif
6258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      settings_provider_(settings_provider.Pass()),
6368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      system_observer_(this),
64010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      stats_collector_(message_center),
65010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      google_now_stats_collector_(message_center) {
66eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#if defined(OS_WIN)
67eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  first_run_pref_.Init(prefs::kMessageCenterShowedFirstRunBalloon, local_state);
68eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif
69eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  message_center_->AddObserver(this);
71bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  message_center_->SetNotifierSettingsProvider(settings_provider_.get());
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#if defined(OS_CHROMEOS)
741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#if !defined(USE_ATHENA)
751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // TODO(oshima|hashimoto): Support notification on athena. crbug.com/408755.
7658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  blockers_.push_back(
7758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      new LoginStateNotificationBlockerChromeOS(message_center));
781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#endif
7958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#else
8058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  blockers_.push_back(new ScreenLockNotificationBlocker(message_center));
8158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#endif
8258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  blockers_.push_back(new FullscreenNotificationBlocker(message_center));
8358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
84868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#if defined(OS_WIN) || defined(OS_MACOSX) \
85cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  || (defined(OS_LINUX) && !defined(OS_CHROMEOS))
86868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // On Windows, Linux and Mac, the notification manager owns the tray icon and
87868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // views.Other platforms have global ownership and Create will return NULL.
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  tray_.reset(message_center::CreateMessageCenterTray());
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)MessageCenterNotificationManager::~MessageCenterNotificationManager() {
93cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  message_center_->SetNotifierSettingsProvider(NULL);
94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  message_center_->RemoveObserver(this);
95116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
96116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  STLDeleteContainerPairSecondPointers(profile_notifications_.begin(),
97116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                       profile_notifications_.end());
98116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  profile_notifications_.clear();
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
101a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid MessageCenterNotificationManager::RegisterPrefs(
102a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    PrefRegistrySimple* registry) {
103a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  registry->RegisterBooleanPref(prefs::kMessageCenterShowedFirstRunBalloon,
104a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                                false);
1055c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  registry->RegisterBooleanPref(prefs::kMessageCenterShowIcon, true);
1065c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  registry->RegisterBooleanPref(prefs::kMessageCenterForcedOnTaskbar, false);
107a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch}
108a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// NotificationUIManager
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void MessageCenterNotificationManager::Add(const Notification& notification,
11358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                           Profile* profile) {
11458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (Update(notification, profile))
11558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return;
116868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ExtensionWelcomeNotificationFactory::GetForBrowserContext(profile)->
1188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      ShowWelcomeNotificationIfNecessary(notification);
1198bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1206e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // WARNING: You MUST update the message center via the notification within a
1216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // ProfileNotification object or the profile ID will not be correctly set for
1226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // ChromeOS.
1236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  ProfileNotification* profile_notification(
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new ProfileNotification(profile, notification, message_center_));
1256e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  AddProfileNotification(profile_notification);
1266e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // TODO(liyanhou): Change the logic to only send notifications to one party.
1286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Currently, if there is an app with notificationProvider permission,
1296e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // notifications will go to both message center and the app.
1306e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Change it to send notifications to message center only when the user chose
1316e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // default message center (extension_id.empty()).
1326e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // If there exist apps/extensions that have notificationProvider permission,
1346e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // route notifications to one of the apps/extensions.
1356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  std::string extension_id = GetExtensionTakingOverNotifications(profile);
1366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (!extension_id.empty())
1376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    profile_notification->AddToAlternateProvider(extension_id);
1386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  message_center_->AddNotification(make_scoped_ptr(
1406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      new message_center::Notification(profile_notification->notification())));
1416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  profile_notification->StartDownloads();
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)bool MessageCenterNotificationManager::Update(const Notification& notification,
14558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                              Profile* profile) {
146a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const base::string16& replace_id = notification.replace_id();
147868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (replace_id.empty())
148868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return false;
149868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const GURL origin_url = notification.origin_url();
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(origin_url.is_valid());
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Since replace_id is provided by arbitrary JS, we need to use origin_url
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // (which is an app url in case of app/extension) to scope the replace ids
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // in the given profile.
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (NotificationMap::iterator iter = profile_notifications_.begin();
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       iter != profile_notifications_.end(); ++iter) {
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ProfileNotification* old_notification = (*iter).second;
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (old_notification->notification().replace_id() == replace_id &&
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        old_notification->notification().origin_url() == origin_url &&
161eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        old_notification->profile() == profile) {
162a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      // Changing the type from non-progress to progress does not count towards
163a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      // the immediate update allowed in the message center.
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      std::string old_id =
1656d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)          old_notification->notification().delegate_id();
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // Add/remove notification in the local list but just update the same
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // one in MessageCenter.
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      delete old_notification;
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      profile_notifications_.erase(old_id);
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProfileNotification* new_notification =
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          new ProfileNotification(profile, notification, message_center_);
1736d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      profile_notifications_[notification.delegate_id()] = new_notification;
174868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1756e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      // TODO(liyanhou): Add routing updated notifications to alternative
1766e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      // providers.
1776e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
178116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      // WARNING: You MUST use AddProfileNotification or update the message
179116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      // center via the notification within a ProfileNotification object or the
180116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      // profile ID will not be correctly set for ChromeOS.
181116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      message_center_->UpdateNotification(
182116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          old_id,
183116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          make_scoped_ptr(new message_center::Notification(
184116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch              new_notification->notification())));
185868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new_notification->StartDownloads();
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return true;
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return false;
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
19358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)const Notification* MessageCenterNotificationManager::FindById(
19458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const std::string& id) const {
19558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  NotificationMap::const_iterator iter = profile_notifications_.find(id);
19658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (iter == profile_notifications_.end())
19758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return NULL;
19858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return &(iter->second->notification());
19958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
20158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)bool MessageCenterNotificationManager::CancelById(const std::string& id) {
20258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // See if this ID hasn't been shown yet.
20358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // If it has been shown, remove it.
20458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  NotificationMap::iterator iter = profile_notifications_.find(id);
20558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (iter == profile_notifications_.end())
20658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return false;
20758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
20868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  RemoveProfileNotification(iter->second);
20958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  message_center_->RemoveNotification(id, /* by_user */ false);
21058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return true;
21158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
21258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
21358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)std::set<std::string>
21458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)MessageCenterNotificationManager::GetAllIdsByProfileAndSourceOrigin(
21558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    Profile* profile,
21658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const GURL& source) {
21758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
21858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  std::set<std::string> notification_ids;
21958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  for (NotificationMap::iterator iter = profile_notifications_.begin();
22058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)       iter != profile_notifications_.end(); iter++) {
22158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    if ((*iter).second->notification().origin_url() == source &&
22258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        profile == (*iter).second->profile()) {
22358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      notification_ids.insert(iter->first);
22458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    }
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
22658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return notification_ids;
22758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
22958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)bool MessageCenterNotificationManager::CancelAllBySourceOrigin(
23058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const GURL& source) {
23158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Same pattern as CancelById, but more complicated than the above
23258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // because there may be multiple notifications from the same source.
23358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  bool removed = false;
234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
23558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  for (NotificationMap::iterator loopiter = profile_notifications_.begin();
23658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)       loopiter != profile_notifications_.end(); ) {
23758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    NotificationMap::iterator curiter = loopiter++;
23858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    if ((*curiter).second->notification().origin_url() == source) {
23968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      const std::string id = curiter->first;
24068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      RemoveProfileNotification(curiter->second);
24168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      message_center_->RemoveNotification(id, /* by_user */ false);
24258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      removed = true;
24358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    }
24458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
24558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return removed;
24658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
24758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
24858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)bool MessageCenterNotificationManager::CancelAllByProfile(Profile* profile) {
24958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Same pattern as CancelAllBySourceOrigin.
25058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  bool removed = false;
25158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
25258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  for (NotificationMap::iterator loopiter = profile_notifications_.begin();
25358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)       loopiter != profile_notifications_.end(); ) {
25458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    NotificationMap::iterator curiter = loopiter++;
25558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    if (profile == (*curiter).second->profile()) {
25668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      const std::string id = curiter->first;
25768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      RemoveProfileNotification(curiter->second);
25868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      message_center_->RemoveNotification(id, /* by_user */ false);
25958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      removed = true;
26058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    }
26158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
26258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return removed;
26358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
26458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
26558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void MessageCenterNotificationManager::CancelAll() {
26658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  message_center_->RemoveAllNotifications(/* by_user */ false);
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
269c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
270c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// MessageCenter::Observer
271c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void MessageCenterNotificationManager::OnNotificationRemoved(
272c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const std::string& notification_id,
273c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    bool by_user) {
274c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  NotificationMap::const_iterator iter =
275c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      profile_notifications_.find(notification_id);
276c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (iter != profile_notifications_.end())
277ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    RemoveProfileNotification(iter->second);
278eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
279eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#if defined(OS_WIN)
280eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  CheckFirstRunTimer();
281eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif
282c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
283c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
28458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void MessageCenterNotificationManager::OnCenterVisibilityChanged(
28558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    message_center::Visibility visibility) {
286eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#if defined(OS_WIN)
28768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (visibility == message_center::VISIBILITY_TRANSIENT)
28868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    CheckFirstRunTimer();
289eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif
290eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
291eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
292eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid MessageCenterNotificationManager::OnNotificationUpdated(
293eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const std::string& notification_id) {
294eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#if defined(OS_WIN)
295eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  CheckFirstRunTimer();
296eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif
297eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
298eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
2995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void MessageCenterNotificationManager::EnsureMessageCenterClosed() {
3005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (tray_.get())
3015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    tray_->GetMessageCenterTray()->HideMessageCenterBubble();
3025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(USE_ASH)
3045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (ash::Shell::HasInstance()) {
3055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ash::WebNotificationTray* tray =
3065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        ash::Shell::GetInstance()->GetWebNotificationTray();
3075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (tray)
3085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      tray->GetMessageCenterTray()->HideMessageCenterBubble();
3095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
3105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif
3115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
313eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid MessageCenterNotificationManager::SetMessageCenterTrayDelegateForTest(
314eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    message_center::MessageCenterTrayDelegate* delegate) {
315eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  tray_.reset(delegate);
316868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
317868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// ImageDownloads
3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)MessageCenterNotificationManager::ImageDownloads::ImageDownloads(
322c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    message_center::MessageCenter* message_center,
323c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ImageDownloadsObserver* observer)
324c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : message_center_(message_center),
325c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      pending_downloads_(0),
326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      observer_(observer) {
3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)MessageCenterNotificationManager::ImageDownloads::~ImageDownloads() { }
3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MessageCenterNotificationManager::ImageDownloads::StartDownloads(
3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const Notification& notification) {
333c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // In case all downloads are synchronous, assume a pending download.
334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  AddPendingDownload();
335c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Notification primary icon.
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  StartDownloadWithImage(
3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      notification,
3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      &notification.icon(),
3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      notification.icon_url(),
3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&message_center::MessageCenter::SetNotificationIcon,
3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 base::Unretained(message_center_),
3436d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                 notification.delegate_id()));
3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Notification image.
346868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  StartDownloadWithImage(
3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      notification,
348868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      NULL,
349868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      notification.image_url(),
3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&message_center::MessageCenter::SetNotificationImage,
3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 base::Unretained(message_center_),
3526d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                 notification.delegate_id()));
3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Notification button icons.
355868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  StartDownloadWithImage(
3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      notification,
357868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      NULL,
358868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      notification.button_one_icon_url(),
3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&message_center::MessageCenter::SetNotificationButtonIcon,
3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 base::Unretained(message_center_),
3616d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                 notification.delegate_id(),
362868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                 0));
363868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  StartDownloadWithImage(
364868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      notification,
365868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      NULL,
366868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      notification.button_two_icon_url(),
3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&message_center::MessageCenter::SetNotificationButtonIcon,
3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 base::Unretained(message_center_),
3696d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                 notification.delegate_id(),
370868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                 1));
371c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
372c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // This should tell the observer we're done if everything was synchronous.
373c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  PendingDownloadCompleted();
3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MessageCenterNotificationManager::ImageDownloads::StartDownloadWithImage(
3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const Notification& notification,
3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const gfx::Image* image,
3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GURL& url,
3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const SetImageCallback& callback) {
3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Set the image directly if we have it.
3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (image && !image->IsEmpty()) {
3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    callback.Run(*image);
3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Leave the image null if there's no URL.
3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (url.is_empty())
3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  content::WebContents* contents = notification.delegate()->GetWebContents();
3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!contents) {
3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LOG(WARNING) << "Notification needs an image but has no WebContents";
3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
397c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  AddPendingDownload();
398c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
399c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  contents->DownloadImage(
4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      url,
401eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      false,  // Not a favicon
402eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      0,  // No maximum size
4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(
4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          &MessageCenterNotificationManager::ImageDownloads::DownloadComplete,
4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          AsWeakPtr(),
4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          callback));
4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MessageCenterNotificationManager::ImageDownloads::DownloadComplete(
4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const SetImageCallback& callback,
4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int download_id,
41290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    int http_status_code,
4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GURL& image_url,
414d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    const std::vector<SkBitmap>& bitmaps,
415d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    const std::vector<gfx::Size>& original_bitmap_sizes) {
416c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  PendingDownloadCompleted();
417c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (bitmaps.empty())
4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Image image = gfx::Image::CreateFrom1xBitmap(bitmaps[0]);
4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  callback.Run(image);
4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
424c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Private methods.
425c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
426c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void MessageCenterNotificationManager::ImageDownloads::AddPendingDownload() {
427c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ++pending_downloads_;
428c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
429c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
430c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void
431c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)MessageCenterNotificationManager::ImageDownloads::PendingDownloadCompleted() {
432c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(pending_downloads_ > 0);
433c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (--pending_downloads_ == 0 && observer_)
434c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    observer_->OnDownloadsCompleted();
435c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
436c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// ProfileNotification
4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)MessageCenterNotificationManager::ProfileNotification::ProfileNotification(
4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Profile* profile,
4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const Notification& notification,
4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    message_center::MessageCenter* message_center)
4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : profile_(profile),
4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      notification_(notification),
446c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      downloads_(new ImageDownloads(message_center, this)) {
4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(profile);
448a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#if defined(OS_CHROMEOS)
449a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  notification_.set_profile_id(multi_user_util::GetUserIDFromProfile(profile));
450a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#endif
4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)MessageCenterNotificationManager::ProfileNotification::~ProfileNotification() {
4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MessageCenterNotificationManager::ProfileNotification::StartDownloads() {
4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  downloads_->StartDownloads(notification_);
4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
460c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void
461c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)MessageCenterNotificationManager::ProfileNotification::OnDownloadsCompleted() {
4621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  notification_.delegate()->ReleaseRenderViewHost();
4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4656e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void
4666e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)MessageCenterNotificationManager::ProfileNotification::AddToAlternateProvider(
4676e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    const std::string extension_id) {
4686e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Convert data from Notification type to NotificationOptions type.
4696e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  extensions::api::notifications::NotificationOptions options;
4706e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  NotificationConversionHelper::NotificationToNotificationOptions(notification_,
4716e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                                                  &options);
4726e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
4736e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Send the notification to the alternate provider extension/app.
4746e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  extensions::NotificationProviderEventRouter event_router(profile_);
4756e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  event_router.CreateNotification(extension_id,
4766e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                  notification_.notifier_id().id,
4776e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                  notification_.delegate_id(),
4786e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                  options);
4796e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
4806e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// private
4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MessageCenterNotificationManager::AddProfileNotification(
4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ProfileNotification* profile_notification) {
4866e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  std::string id = profile_notification->notification().delegate_id();
4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Notification ids should be unique.
4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(profile_notifications_.find(id) == profile_notifications_.end());
4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  profile_notifications_[id] = profile_notification;
4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MessageCenterNotificationManager::RemoveProfileNotification(
493ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    ProfileNotification* profile_notification) {
4946d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  std::string id = profile_notification->notification().delegate_id();
4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  profile_notifications_.erase(id);
4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  delete profile_notification;
4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)MessageCenterNotificationManager::ProfileNotification*
5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MessageCenterNotificationManager::FindProfileNotification(
5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        const std::string& id) const {
5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NotificationMap::const_iterator iter = profile_notifications_.find(id);
503c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (iter == profile_notifications_.end())
504c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return NULL;
505c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return (*iter).second;
5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5086e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
5096e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)std::string
5106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)MessageCenterNotificationManager::GetExtensionTakingOverNotifications(
5116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    Profile* profile) {
5126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // TODO(liyanhou): When additional settings in Chrome Settings is implemented,
5136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // change choosing the last app with permission to a user selected app.
5146e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  extensions::ExtensionRegistry* registry =
5156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      extensions::ExtensionRegistry::Get(profile);
5166e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  DCHECK(registry);
5176e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  std::string extension_id;
5186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  for (extensions::ExtensionSet::const_iterator it =
5196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)           registry->enabled_extensions().begin();
5206e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)       it != registry->enabled_extensions().end();
5216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)       ++it) {
5226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    if ((*it->get()).permissions_data()->HasAPIPermission(
5236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            extensions::APIPermission::ID::kNotificationProvider)) {
5246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      extension_id = (*it->get()).id();
5256e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      return extension_id;
5266e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    }
5276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  }
5286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  return extension_id;
5296e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
530