1a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
2a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// found in the LICENSE file.
4a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
5a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "chrome/browser/extensions/extension_notification_observer.h"
6a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
7a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include <vector>
8a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
9a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "base/logging.h"
10a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "base/strings/stringprintf.h"
11a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "chrome/common/extensions/extension.h"
12a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
13a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)namespace extensions {
14a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
15a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)namespace {
16a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
17a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)std::string Str(const std::vector<chrome::NotificationType>& types) {
18a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  std::string str = "[";
19a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  bool needs_comma = false;
20a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  for (std::vector<chrome::NotificationType>::const_iterator it =
21a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)       types.begin(); it != types.end(); ++it) {
22a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    if (needs_comma)
23a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      str += ",";
24a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    needs_comma = true;
25a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    str += base::StringPrintf("%d", *it);
26a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
27a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  str += "]";
28a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return str;
29a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
30a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
31a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}  // namespace
32a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
33a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)ExtensionNotificationObserver::ExtensionNotificationObserver(
34a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    content::NotificationSource source,
35a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    const std::set<std::string>& extension_ids)
36a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    : extension_ids_(extension_ids) {
37a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LOADED, source);
38a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_INSTALLED, source);
39a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED, source);
40a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
41a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
42a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)ExtensionNotificationObserver::~ExtensionNotificationObserver() {}
43a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
44a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)testing::AssertionResult ExtensionNotificationObserver::CheckNotifications() {
45a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return CheckNotifications(std::vector<chrome::NotificationType>());
46a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
47a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
48a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)testing::AssertionResult ExtensionNotificationObserver::CheckNotifications(
49a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    chrome::NotificationType type) {
50a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return CheckNotifications(std::vector<chrome::NotificationType>(1, type));
51a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
52a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
53a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)testing::AssertionResult ExtensionNotificationObserver::CheckNotifications(
54a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    chrome::NotificationType t1,
55a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    chrome::NotificationType t2) {
56a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  std::vector<chrome::NotificationType> types;
57a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  types.push_back(t1);
58a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  types.push_back(t2);
59a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return CheckNotifications(types);
60a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
61a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
62a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)testing::AssertionResult ExtensionNotificationObserver::CheckNotifications(
63a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    chrome::NotificationType t1,
64a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    chrome::NotificationType t2,
65a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    chrome::NotificationType t3) {
66a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  std::vector<chrome::NotificationType> types;
67a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  types.push_back(t1);
68a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  types.push_back(t2);
69a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  types.push_back(t3);
70a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return CheckNotifications(types);
71a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
72a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
73a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)testing::AssertionResult ExtensionNotificationObserver::CheckNotifications(
74a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    chrome::NotificationType t1,
75a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    chrome::NotificationType t2,
76a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    chrome::NotificationType t3,
77a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    chrome::NotificationType t4,
78a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    chrome::NotificationType t5,
79a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    chrome::NotificationType t6) {
80a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  std::vector<chrome::NotificationType> types;
81a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  types.push_back(t1);
82a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  types.push_back(t2);
83a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  types.push_back(t3);
84a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  types.push_back(t4);
85a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  types.push_back(t5);
86a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  types.push_back(t6);
87a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return CheckNotifications(types);
88a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
89a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
90a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// content::NotificationObserver implementation.
91a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void ExtensionNotificationObserver::Observe(
92a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    int type,
93a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    const content::NotificationSource& source,
94a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    const content::NotificationDetails& details) {
95a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  switch (type) {
96a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    case chrome::NOTIFICATION_EXTENSION_INSTALLED: {
97a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      const Extension* extension =
98a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)          content::Details<const InstalledExtensionInfo>(details)->extension;
99a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      if (extension_ids_.count(extension->id()))
100a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        notifications_.push_back(static_cast<chrome::NotificationType>(type));
101a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      break;
102a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    }
103a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
104a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    case chrome::NOTIFICATION_EXTENSION_LOADED: {
105a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      const Extension* extension =
106a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)          content::Details<const Extension>(details).ptr();
107a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      if (extension_ids_.count(extension->id()))
108a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        notifications_.push_back(static_cast<chrome::NotificationType>(type));
109a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      break;
110a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    }
111a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
112a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    case chrome::NOTIFICATION_EXTENSION_UNLOADED: {
113a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      UnloadedExtensionInfo* reason =
114a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)          content::Details<UnloadedExtensionInfo>(details).ptr();
115a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      if (extension_ids_.count(reason->extension->id())) {
116a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        notifications_.push_back(static_cast<chrome::NotificationType>(type));
117a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        // The only way that extensions are unloaded in these tests is
118a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        // by blacklisting.
119a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        EXPECT_EQ(extension_misc::UNLOAD_REASON_BLACKLIST,
120a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                  reason->reason);
121a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      }
122a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      break;
123a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    }
124a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
125a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    default:
126a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      NOTREACHED();
127a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      break;
128a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
129a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
130a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
131a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)testing::AssertionResult ExtensionNotificationObserver::CheckNotifications(
132a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    const std::vector<chrome::NotificationType>& types) {
133a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  testing::AssertionResult result = (notifications_ == types) ?
134a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      testing::AssertionSuccess() :
135a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      testing::AssertionFailure() << "Expected " << Str(types) << ", " <<
136a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                     "Got " << Str(notifications_);
137a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  notifications_.clear();
138a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return result;
139a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
140a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
141a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}  // namespace extensions
142