• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "extensions/browser/error_map.h"
6 
7 #include "base/lazy_instance.h"
8 #include "base/stl_util.h"
9 #include "extensions/common/extension.h"
10 
11 namespace extensions {
12 namespace {
13 
14 // The maximum number of errors to be stored per extension.
15 const size_t kMaxErrorsPerExtension = 100;
16 
17 base::LazyInstance<ErrorList> g_empty_error_list = LAZY_INSTANCE_INITIALIZER;
18 
19 }  // namespace
20 
21 ////////////////////////////////////////////////////////////////////////////////
22 // ErrorMap::ExtensionEntry
ExtensionEntry()23 ErrorMap::ExtensionEntry::ExtensionEntry() {
24 }
25 
~ExtensionEntry()26 ErrorMap::ExtensionEntry::~ExtensionEntry() {
27   DeleteAllErrors();
28 }
29 
DeleteAllErrors()30 void ErrorMap::ExtensionEntry::DeleteAllErrors() {
31   STLDeleteContainerPointers(list_.begin(), list_.end());
32   list_.clear();
33 }
34 
DeleteIncognitoErrors()35 void ErrorMap::ExtensionEntry::DeleteIncognitoErrors() {
36   ErrorList::iterator iter = list_.begin();
37   while (iter != list_.end()) {
38     if ((*iter)->from_incognito()) {
39       delete *iter;
40       iter = list_.erase(iter);
41     } else {
42       ++iter;
43     }
44   }
45 }
46 
DeleteErrorsOfType(ExtensionError::Type type)47 void ErrorMap::ExtensionEntry::DeleteErrorsOfType(ExtensionError::Type type) {
48   ErrorList::iterator iter = list_.begin();
49   while (iter != list_.end()) {
50     if ((*iter)->type() == type) {
51       delete *iter;
52       iter = list_.erase(iter);
53     } else {
54       ++iter;
55     }
56   }
57 }
58 
AddError(scoped_ptr<ExtensionError> error)59 const ExtensionError* ErrorMap::ExtensionEntry::AddError(
60     scoped_ptr<ExtensionError> error) {
61   for (ErrorList::iterator iter = list_.begin(); iter != list_.end(); ++iter) {
62     // If we find a duplicate error, remove the old error and add the new one,
63     // incrementing the occurrence count of the error. We use the new error
64     // for runtime errors, so we can link to the latest context, inspectable
65     // view, etc.
66     if (error->IsEqual(*iter)) {
67       error->set_occurrences((*iter)->occurrences() + 1);
68       delete *iter;
69       list_.erase(iter);
70       break;
71     }
72   }
73 
74   // If there are too many errors for an extension already, limit ourselves to
75   // the most recent ones.
76   if (list_.size() >= kMaxErrorsPerExtension) {
77     delete list_.front();
78     list_.pop_front();
79   }
80 
81   list_.push_back(error.release());
82   return list_.back();
83 }
84 
85 ////////////////////////////////////////////////////////////////////////////////
86 // ErrorMap
ErrorMap()87 ErrorMap::ErrorMap() {
88 }
89 
~ErrorMap()90 ErrorMap::~ErrorMap() {
91   RemoveAllErrors();
92 }
93 
GetErrorsForExtension(const std::string & extension_id) const94 const ErrorList& ErrorMap::GetErrorsForExtension(
95     const std::string& extension_id) const {
96   EntryMap::const_iterator iter = map_.find(extension_id);
97   return iter != map_.end() ? *iter->second->list() : g_empty_error_list.Get();
98 }
99 
AddError(scoped_ptr<ExtensionError> error)100 const ExtensionError* ErrorMap::AddError(scoped_ptr<ExtensionError> error) {
101   EntryMap::iterator iter = map_.find(error->extension_id());
102   if (iter == map_.end()) {
103     iter = map_.insert(std::pair<std::string, ExtensionEntry*>(
104         error->extension_id(), new ExtensionEntry)).first;
105   }
106   return iter->second->AddError(error.Pass());
107 }
108 
Remove(const std::string & extension_id)109 void ErrorMap::Remove(const std::string& extension_id) {
110   EntryMap::iterator iter = map_.find(extension_id);
111   if (iter == map_.end())
112     return;
113 
114   delete iter->second;
115   map_.erase(iter);
116 }
117 
RemoveErrorsForExtensionOfType(const std::string & extension_id,ExtensionError::Type type)118 void ErrorMap::RemoveErrorsForExtensionOfType(const std::string& extension_id,
119                                               ExtensionError::Type type) {
120   EntryMap::iterator iter = map_.find(extension_id);
121   if (iter != map_.end())
122     iter->second->DeleteErrorsOfType(type);
123 }
124 
RemoveIncognitoErrors()125 void ErrorMap::RemoveIncognitoErrors() {
126   for (EntryMap::iterator iter = map_.begin(); iter != map_.end(); ++iter)
127     iter->second->DeleteIncognitoErrors();
128 }
129 
RemoveAllErrors()130 void ErrorMap::RemoveAllErrors() {
131   for (EntryMap::iterator iter = map_.begin(); iter != map_.end(); ++iter) {
132     iter->second->DeleteAllErrors();
133     delete iter->second;
134   }
135   map_.clear();
136 }
137 
138 }  // namespace extensions
139