summaryrefslogtreecommitdiffstats
path: root/extensions
diff options
context:
space:
mode:
authorrdevlin.cronin <rdevlin.cronin@chromium.org>2015-03-20 17:56:30 -0700
committerCommit bot <commit-bot@chromium.org>2015-03-21 00:57:07 +0000
commitc799f9f7755bb466fdc4cbd980a3b64071bbcd03 (patch)
treea9ac2b20f825b7d58957fef8afdd82b5df8f9a16 /extensions
parente879c2bb12d35c171e6263aba21e85763e0799cc (diff)
downloadchromium_src-c799f9f7755bb466fdc4cbd980a3b64071bbcd03.zip
chromium_src-c799f9f7755bb466fdc4cbd980a3b64071bbcd03.tar.gz
chromium_src-c799f9f7755bb466fdc4cbd980a3b64071bbcd03.tar.bz2
[Extensions] Add a developerPrivate.deleteExtensionErrors function
Add a developerPrivate API function for removing extension errors. BUG=TBD Review URL: https://codereview.chromium.org/1014323003 Cr-Commit-Position: refs/heads/master@{#321673}
Diffstat (limited to 'extensions')
-rw-r--r--extensions/browser/error_map.cc148
-rw-r--r--extensions/browser/error_map.h67
-rw-r--r--extensions/browser/error_map_unittest.cc43
-rw-r--r--extensions/browser/extension_error.cc1
-rw-r--r--extensions/browser/extension_error.h8
-rw-r--r--extensions/browser/extension_error_test_util.h3
-rw-r--r--extensions/browser/extension_function_histogram_value.h1
7 files changed, 179 insertions, 92 deletions
diff --git a/extensions/browser/error_map.cc b/extensions/browser/error_map.cc
index dfcef9f..0495ae08 100644
--- a/extensions/browser/error_map.cc
+++ b/extensions/browser/error_map.cc
@@ -6,9 +6,9 @@
#include "base/lazy_instance.h"
#include "base/stl_util.h"
-#include "extensions/common/extension.h"
namespace extensions {
+
namespace {
// The maximum number of errors to be stored per extension.
@@ -16,10 +16,95 @@ const size_t kMaxErrorsPerExtension = 100;
base::LazyInstance<ErrorList> g_empty_error_list = LAZY_INSTANCE_INITIALIZER;
+// An incrementing counter for the next error id. Overflowing this is very
+// unlikely, since the number of errors per extension is capped at 100.
+int kNextErrorId = 1;
+
} // namespace
////////////////////////////////////////////////////////////////////////////////
+// ErrorMap::Filter
+ErrorMap::Filter::Filter(const std::string& restrict_to_extension_id,
+ int restrict_to_type,
+ const std::set<int>& restrict_to_ids,
+ bool restrict_to_incognito)
+ : restrict_to_extension_id(restrict_to_extension_id),
+ restrict_to_type(restrict_to_type),
+ restrict_to_ids(restrict_to_ids),
+ restrict_to_incognito(restrict_to_incognito) {
+}
+
+ErrorMap::Filter::~Filter() {
+}
+
+ErrorMap::Filter ErrorMap::Filter::ErrorsForExtension(
+ const std::string& extension_id) {
+ return Filter(extension_id, -1, std::set<int>(), false);
+}
+
+ErrorMap::Filter ErrorMap::Filter::ErrorsForExtensionWithType(
+ const std::string& extension_id,
+ ExtensionError::Type type) {
+ return Filter(extension_id, type, std::set<int>(), false);
+}
+
+ErrorMap::Filter ErrorMap::Filter::ErrorsForExtensionWithIds(
+ const std::string& extension_id,
+ const std::set<int>& ids) {
+ return Filter(extension_id, -1, ids, false);
+}
+
+ErrorMap::Filter ErrorMap::Filter::ErrorsForExtensionWithTypeAndIds(
+ const std::string& extension_id,
+ ExtensionError::Type type,
+ const std::set<int>& ids) {
+ return Filter(extension_id, type, ids, false);
+}
+
+ErrorMap::Filter ErrorMap::Filter::IncognitoErrors() {
+ return Filter(std::string(), -1, std::set<int>(), true);
+}
+
+bool ErrorMap::Filter::Matches(const ExtensionError* error) const {
+ if (restrict_to_type != -1 && restrict_to_type != error->type())
+ return false;
+ if (restrict_to_incognito && !error->from_incognito())
+ return false;
+ if (!restrict_to_extension_id.empty() &&
+ error->extension_id() != restrict_to_extension_id)
+ return false;
+ if (!restrict_to_ids.empty() && restrict_to_ids.count(error->id()) == 0)
+ return false;
+ return true;
+}
+
+////////////////////////////////////////////////////////////////////////////////
// ErrorMap::ExtensionEntry
+class ErrorMap::ExtensionEntry {
+ public:
+ ExtensionEntry();
+ ~ExtensionEntry();
+
+ // Delete any errors in the entry that match the given ids and type, if
+ // provided.
+ void DeleteErrors(const ErrorMap::Filter& filter);
+ // Delete all errors in the entry.
+ void DeleteAllErrors();
+
+ // Add the error to the list, and return a weak reference.
+ const ExtensionError* AddError(scoped_ptr<ExtensionError> error);
+
+ const ErrorList* list() const { return &list_; }
+
+ private:
+ // The list of all errors associated with the extension. The errors are
+ // owned by the Entry (in turn owned by the ErrorMap) and are deleted upon
+ // destruction.
+ ErrorList list_;
+
+ DISALLOW_COPY_AND_ASSIGN(ExtensionEntry);
+};
+
ErrorMap::ExtensionEntry::ExtensionEntry() {
}
@@ -27,15 +112,9 @@ ErrorMap::ExtensionEntry::~ExtensionEntry() {
DeleteAllErrors();
}
-void ErrorMap::ExtensionEntry::DeleteAllErrors() {
- STLDeleteContainerPointers(list_.begin(), list_.end());
- list_.clear();
-}
-
-void ErrorMap::ExtensionEntry::DeleteIncognitoErrors() {
- ErrorList::iterator iter = list_.begin();
- while (iter != list_.end()) {
- if ((*iter)->from_incognito()) {
+void ErrorMap::ExtensionEntry::DeleteErrors(const Filter& filter) {
+ for (ErrorList::iterator iter = list_.begin(); iter != list_.end();) {
+ if (filter.Matches(*iter)) {
delete *iter;
iter = list_.erase(iter);
} else {
@@ -44,16 +123,9 @@ void ErrorMap::ExtensionEntry::DeleteIncognitoErrors() {
}
}
-void ErrorMap::ExtensionEntry::DeleteErrorsOfType(ExtensionError::Type type) {
- ErrorList::iterator iter = list_.begin();
- while (iter != list_.end()) {
- if ((*iter)->type() == type) {
- delete *iter;
- iter = list_.erase(iter);
- } else {
- ++iter;
- }
- }
+void ErrorMap::ExtensionEntry::DeleteAllErrors() {
+ STLDeleteContainerPointers(list_.begin(), list_.end());
+ list_.clear();
}
const ExtensionError* ErrorMap::ExtensionEntry::AddError(
@@ -65,6 +137,7 @@ const ExtensionError* ErrorMap::ExtensionEntry::AddError(
// view, etc.
if (error->IsEqual(*iter)) {
error->set_occurrences((*iter)->occurrences() + 1);
+ error->set_id((*iter)->id());
delete *iter;
list_.erase(iter);
break;
@@ -78,6 +151,9 @@ const ExtensionError* ErrorMap::ExtensionEntry::AddError(
list_.pop_front();
}
+ if (error->id() == 0)
+ error->set_id(kNextErrorId++);
+
list_.push_back(error.release());
return list_.back();
}
@@ -106,32 +182,20 @@ const ExtensionError* ErrorMap::AddError(scoped_ptr<ExtensionError> error) {
return iter->second->AddError(error.Pass());
}
-void ErrorMap::Remove(const std::string& extension_id) {
- EntryMap::iterator iter = map_.find(extension_id);
- if (iter == map_.end())
- return;
-
- delete iter->second;
- map_.erase(iter);
-}
-
-void ErrorMap::RemoveErrorsForExtensionOfType(const std::string& extension_id,
- ExtensionError::Type type) {
- EntryMap::iterator iter = map_.find(extension_id);
- if (iter != map_.end())
- iter->second->DeleteErrorsOfType(type);
-}
-
-void ErrorMap::RemoveIncognitoErrors() {
- for (EntryMap::iterator iter = map_.begin(); iter != map_.end(); ++iter)
- iter->second->DeleteIncognitoErrors();
+void ErrorMap::RemoveErrors(const Filter& filter) {
+ if (!filter.restrict_to_extension_id.empty()) {
+ EntryMap::iterator iter = map_.find(filter.restrict_to_extension_id);
+ if (iter != map_.end())
+ iter->second->DeleteErrors(filter);
+ } else {
+ for (auto& key_val : map_)
+ key_val.second->DeleteErrors(filter);
+ }
}
void ErrorMap::RemoveAllErrors() {
- for (EntryMap::iterator iter = map_.begin(); iter != map_.end(); ++iter) {
- iter->second->DeleteAllErrors();
+ for (EntryMap::iterator iter = map_.begin(); iter != map_.end(); ++iter)
delete iter->second;
- }
map_.clear();
}
diff --git a/extensions/browser/error_map.h b/extensions/browser/error_map.h
index 216d136..f0e6b2c 100644
--- a/extensions/browser/error_map.h
+++ b/extensions/browser/error_map.h
@@ -7,6 +7,7 @@
#include <deque>
#include <map>
+#include <set>
#include <string>
#include "base/basictypes.h"
@@ -25,19 +26,43 @@ class ErrorMap {
ErrorMap();
~ErrorMap();
+ struct Filter {
+ Filter(const std::string& restrict_to_extension_id,
+ int restrict_to_type,
+ const std::set<int>& restrict_to_ids,
+ bool restrict_to_incognito);
+ ~Filter();
+
+ // Convenience methods to get a specific type of filter. Prefer these over
+ // the constructor when possible.
+ static Filter ErrorsForExtension(const std::string& extension_id);
+ static Filter ErrorsForExtensionWithType(const std::string& extension_id,
+ ExtensionError::Type type);
+ static Filter ErrorsForExtensionWithIds(const std::string& extension_id,
+ const std::set<int>& ids);
+ static Filter ErrorsForExtensionWithTypeAndIds(
+ const std::string& extension_id,
+ ExtensionError::Type type,
+ const std::set<int>& ids);
+ static Filter IncognitoErrors();
+
+ bool Matches(const ExtensionError* error) const;
+
+ const std::string restrict_to_extension_id;
+ const int restrict_to_type;
+ const std::set<int> restrict_to_ids;
+ const bool restrict_to_incognito;
+ };
+
// Return the list of all errors associated with the given extension.
const ErrorList& GetErrorsForExtension(const std::string& extension_id) const;
// Add the |error| to the ErrorMap.
const ExtensionError* AddError(scoped_ptr<ExtensionError> error);
- // Remove an extension from the ErrorMap, deleting all associated errors.
- void Remove(const std::string& extension_id);
- // Remove all errors of a given type for an extension.
- void RemoveErrorsForExtensionOfType(const std::string& extension_id,
- ExtensionError::Type type);
- // Remove all incognito errors for all extensions.
- void RemoveIncognitoErrors();
+ // Removes errors that match the given |filter| from the map.
+ void RemoveErrors(const Filter& filter);
+
// Remove all errors for all extensions, and clear the map.
void RemoveAllErrors();
@@ -46,32 +71,8 @@ class ErrorMap {
private:
// An Entry is created for each Extension ID, and stores the errors related to
// that Extension.
- class ExtensionEntry {
- public:
- ExtensionEntry();
- ~ExtensionEntry();
-
- // Delete all errors associated with this extension.
- void DeleteAllErrors();
- // Delete all incognito errors associated with this extension.
- void DeleteIncognitoErrors();
- // Delete all errors of the given |type| associated with this extension.
- void DeleteErrorsOfType(ExtensionError::Type type);
-
- // Add the error to the list, and return a weak reference.
- const ExtensionError* AddError(scoped_ptr<ExtensionError> error);
-
- const ErrorList* list() const { return &list_; }
-
- private:
- // The list of all errors associated with the extension. The errors are
- // owned by the Entry (in turn owned by the ErrorMap) and are deleted upon
- // destruction.
- ErrorList list_;
-
- DISALLOW_COPY_AND_ASSIGN(ExtensionEntry);
- };
- typedef std::map<std::string, ExtensionEntry*> EntryMap;
+ class ExtensionEntry;
+ using EntryMap = std::map<std::string, ExtensionEntry*>;
// The mapping between Extension IDs and their corresponding Entries.
EntryMap map_;
diff --git a/extensions/browser/error_map_unittest.cc b/extensions/browser/error_map_unittest.cc
index d393624..b8ae20d 100644
--- a/extensions/browser/error_map_unittest.cc
+++ b/extensions/browser/error_map_unittest.cc
@@ -16,6 +16,7 @@
namespace extensions {
using error_test_util::CreateNewRuntimeError;
+using error_test_util::CreateNewManifestError;
class ErrorMapUnitTest : public testing::Test {
public:
@@ -44,39 +45,53 @@ TEST_F(ErrorMapUnitTest, AddAndRemoveErrors) {
// There should only be one entry in the map, since errors are stored in lists
// keyed by extension id.
- ASSERT_EQ(1u, errors_.size());
+ EXPECT_EQ(1u, errors_.size());
- ASSERT_EQ(kNumTotalErrors, errors_.GetErrorsForExtension(kId).size());
+ EXPECT_EQ(kNumTotalErrors, errors_.GetErrorsForExtension(kId).size());
// Remove the incognito errors; three errors should remain, and all should
// be from non-incognito contexts.
- errors_.RemoveIncognitoErrors();
+ errors_.RemoveErrors(ErrorMap::Filter::IncognitoErrors());
const ErrorList& list = errors_.GetErrorsForExtension(kId);
- ASSERT_EQ(kNumNonIncognitoErrors, list.size());
+ EXPECT_EQ(kNumNonIncognitoErrors, list.size());
for (size_t i = 0; i < list.size(); ++i)
- ASSERT_FALSE(list[i]->from_incognito());
+ EXPECT_FALSE(list[i]->from_incognito());
// Add another error for a different extension id.
const std::string kSecondId = crx_file::id_util::GenerateId("id2");
- ASSERT_TRUE(errors_.AddError(CreateNewRuntimeError(kSecondId, "foo")));
+ EXPECT_TRUE(errors_.AddError(CreateNewRuntimeError(kSecondId, "foo")));
// There should be two entries now, one for each id, and there should be one
// error for the second extension.
- ASSERT_EQ(2u, errors_.size());
- ASSERT_EQ(1u, errors_.GetErrorsForExtension(kSecondId).size());
+ EXPECT_EQ(2u, errors_.size());
+ EXPECT_EQ(1u, errors_.GetErrorsForExtension(kSecondId).size());
// Remove all errors for the second id.
- errors_.Remove(kSecondId);
- ASSERT_EQ(1u, errors_.size());
- ASSERT_EQ(0u, errors_.GetErrorsForExtension(kSecondId).size());
+ errors_.RemoveErrors(ErrorMap::Filter::ErrorsForExtension(kSecondId));
+ EXPECT_EQ(0u, errors_.GetErrorsForExtension(kSecondId).size());
// First extension should be unaffected.
- ASSERT_EQ(kNumNonIncognitoErrors,
+ EXPECT_EQ(kNumNonIncognitoErrors, errors_.GetErrorsForExtension(kId).size());
+
+ errors_.AddError(CreateNewManifestError(kId, "manifest error"));
+ EXPECT_EQ(kNumNonIncognitoErrors + 1,
errors_.GetErrorsForExtension(kId).size());
+ errors_.RemoveErrors(ErrorMap::Filter::ErrorsForExtensionWithType(
+ kId, ExtensionError::MANIFEST_ERROR));
+ EXPECT_EQ(kNumNonIncognitoErrors, errors_.GetErrorsForExtension(kId).size());
+
+ const ExtensionError* added_error =
+ errors_.AddError(CreateNewManifestError(kId, "manifest error2"));
+ EXPECT_EQ(kNumNonIncognitoErrors + 1,
+ errors_.GetErrorsForExtension(kId).size());
+ std::set<int> ids;
+ ids.insert(added_error->id());
+ errors_.RemoveErrors(ErrorMap::Filter::ErrorsForExtensionWithIds(kId, ids));
+ EXPECT_EQ(kNumNonIncognitoErrors, errors_.GetErrorsForExtension(kId).size());
// Remove remaining errors.
errors_.RemoveAllErrors();
- ASSERT_EQ(0u, errors_.size());
- ASSERT_EQ(0u, errors_.GetErrorsForExtension(kId).size());
+ EXPECT_EQ(0u, errors_.size());
+ EXPECT_EQ(0u, errors_.GetErrorsForExtension(kId).size());
}
// Test that if we add enough errors, only the most recent
diff --git a/extensions/browser/extension_error.cc b/extensions/browser/extension_error.cc
index 19a31ea..605efbb 100644
--- a/extensions/browser/extension_error.cc
+++ b/extensions/browser/extension_error.cc
@@ -33,6 +33,7 @@ ExtensionError::ExtensionError(Type type,
const base::string16& message)
: type_(type),
extension_id_(extension_id),
+ id_(0),
from_incognito_(from_incognito),
level_(level),
source_(source),
diff --git a/extensions/browser/extension_error.h b/extensions/browser/extension_error.h
index ba44d55..7628f7e 100644
--- a/extensions/browser/extension_error.h
+++ b/extensions/browser/extension_error.h
@@ -24,9 +24,9 @@ namespace extensions {
class ExtensionError {
public:
enum Type {
- MANIFEST_ERROR,
+ MANIFEST_ERROR = 0,
RUNTIME_ERROR,
- NUM_ERROR_TYPES // Put new values above this.
+ NUM_ERROR_TYPES, // Put new values above this.
};
virtual ~ExtensionError();
@@ -42,6 +42,8 @@ class ExtensionError {
Type type() const { return type_; }
const std::string& extension_id() const { return extension_id_; }
+ int id() const { return id_; }
+ void set_id(int id) { id_ = id; }
bool from_incognito() const { return from_incognito_; }
logging::LogSeverity level() const { return level_; }
const base::string16& source() const { return source_; }
@@ -71,6 +73,8 @@ class ExtensionError {
Type type_;
// The ID of the extension which caused the error.
std::string extension_id_;
+ // The id of this particular error. This can be zero if the id is never set.
+ int id_;
// Whether or not the error was caused while incognito.
bool from_incognito_;
// The severity level of the error.
diff --git a/extensions/browser/extension_error_test_util.h b/extensions/browser/extension_error_test_util.h
index 4866cef..6ea2da6 100644
--- a/extensions/browser/extension_error_test_util.h
+++ b/extensions/browser/extension_error_test_util.h
@@ -27,7 +27,8 @@ scoped_ptr<ExtensionError> CreateNewRuntimeError(
// Create a new ManifestError.
scoped_ptr<ExtensionError> CreateNewManifestError(
- const std::string& extension_id, const std::string& mnessage);
+ const std::string& extension_id,
+ const std::string& message);
} // namespace error_test_util
} // namespace extensions
diff --git a/extensions/browser/extension_function_histogram_value.h b/extensions/browser/extension_function_histogram_value.h
index 3cbb60b..f3d0785 100644
--- a/extensions/browser/extension_function_histogram_value.h
+++ b/extensions/browser/extension_function_histogram_value.h
@@ -1040,6 +1040,7 @@ enum HistogramValue {
DEVELOPERPRIVATE_GETEXTENSIONINFO,
FILEMANAGERPRIVATE_ENABLEEXTERNALFILESCHEME,
DEVELOPERPRIVATE_UPDATEEXTENSIONCONFIGURATION,
+ DEVELOPERPRIVATE_DELETEEXTENSIONERRORS,
// Last entry: Add new entries above and ensure to update
// tools/metrics/histograms/histograms.xml.
ENUM_BOUNDARY