Home | History | Annotate | Download | only in browser
      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
     23 ErrorMap::ExtensionEntry::ExtensionEntry() {
     24 }
     25 
     26 ErrorMap::ExtensionEntry::~ExtensionEntry() {
     27   DeleteAllErrors();
     28 }
     29 
     30 void ErrorMap::ExtensionEntry::DeleteAllErrors() {
     31   STLDeleteContainerPointers(list_.begin(), list_.end());
     32   list_.clear();
     33 }
     34 
     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 
     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 
     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
     87 ErrorMap::ErrorMap() {
     88 }
     89 
     90 ErrorMap::~ErrorMap() {
     91   RemoveAllErrors();
     92 }
     93 
     94 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 
    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 
    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 
    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 
    125 void ErrorMap::RemoveIncognitoErrors() {
    126   for (EntryMap::iterator iter = map_.begin(); iter != map_.end(); ++iter)
    127     iter->second->DeleteIncognitoErrors();
    128 }
    129 
    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