1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "extensions/browser/warning_service.h"
6
7#include "content/public/browser/browser_thread.h"
8#include "extensions/browser/extension_registry.h"
9#include "extensions/browser/extension_system.h"
10#include "extensions/browser/extensions_browser_client.h"
11#include "extensions/common/extension_set.h"
12
13using content::BrowserThread;
14
15namespace extensions {
16
17WarningService::WarningService(content::BrowserContext* browser_context)
18    : browser_context_(browser_context), extension_registry_observer_(this) {
19  DCHECK(CalledOnValidThread());
20  if (browser_context_) {
21    extension_registry_observer_.Add(ExtensionRegistry::Get(
22        ExtensionsBrowserClient::Get()->GetOriginalContext(browser_context_)));
23  }
24}
25
26WarningService::~WarningService() {}
27
28void WarningService::ClearWarnings(
29    const std::set<Warning::WarningType>& types) {
30  DCHECK(CalledOnValidThread());
31  bool deleted_anything = false;
32  for (WarningSet::iterator i = warnings_.begin();
33       i != warnings_.end();) {
34    if (types.find(i->warning_type()) != types.end()) {
35      deleted_anything = true;
36      warnings_.erase(i++);
37    } else {
38      ++i;
39    }
40  }
41
42  if (deleted_anything)
43    NotifyWarningsChanged();
44}
45
46std::set<Warning::WarningType> WarningService::
47    GetWarningTypesAffectingExtension(const std::string& extension_id) const {
48  DCHECK(CalledOnValidThread());
49  std::set<Warning::WarningType> result;
50  for (WarningSet::const_iterator i = warnings_.begin();
51       i != warnings_.end(); ++i) {
52    if (i->extension_id() == extension_id)
53      result.insert(i->warning_type());
54  }
55  return result;
56}
57
58std::vector<std::string> WarningService::GetWarningMessagesForExtension(
59    const std::string& extension_id) const {
60  DCHECK(CalledOnValidThread());
61  std::vector<std::string> result;
62
63  const ExtensionSet& extension_set =
64      ExtensionRegistry::Get(browser_context_)->enabled_extensions();
65
66  for (WarningSet::const_iterator i = warnings_.begin();
67       i != warnings_.end(); ++i) {
68    if (i->extension_id() == extension_id)
69      result.push_back(i->GetLocalizedMessage(&extension_set));
70  }
71  return result;
72}
73
74void WarningService::AddWarnings(const WarningSet& warnings) {
75  DCHECK(CalledOnValidThread());
76  size_t old_size = warnings_.size();
77
78  warnings_.insert(warnings.begin(), warnings.end());
79
80  if (old_size != warnings_.size())
81    NotifyWarningsChanged();
82}
83
84// static
85void WarningService::NotifyWarningsOnUI(
86    void* profile_id,
87    const WarningSet& warnings) {
88  DCHECK_CURRENTLY_ON(BrowserThread::UI);
89  content::BrowserContext* browser_context =
90      reinterpret_cast<content::BrowserContext*>(profile_id);
91
92  if (!browser_context ||
93      !ExtensionsBrowserClient::Get() ||
94      !ExtensionsBrowserClient::Get()->IsValidContext(browser_context)) {
95    return;
96  }
97
98  WarningService* warning_service =
99      ExtensionSystem::Get(browser_context)->warning_service();
100
101  warning_service->AddWarnings(warnings);
102}
103
104void WarningService::AddObserver(Observer* observer) {
105  observer_list_.AddObserver(observer);
106}
107
108void WarningService::RemoveObserver(Observer* observer) {
109  observer_list_.RemoveObserver(observer);
110}
111
112void WarningService::NotifyWarningsChanged() {
113  FOR_EACH_OBSERVER(Observer, observer_list_, ExtensionWarningsChanged());
114}
115
116void WarningService::OnExtensionUnloaded(
117    content::BrowserContext* browser_context,
118    const Extension* extension,
119    UnloadedExtensionInfo::Reason reason) {
120  // Unloading one extension might have solved the problems of others.
121  // Therefore, we clear warnings of this type for all extensions.
122  std::set<Warning::WarningType> warning_types =
123      GetWarningTypesAffectingExtension(extension->id());
124  ClearWarnings(warning_types);
125}
126
127}  // namespace extensions
128