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 13 using content::BrowserThread; 14 15 namespace extensions { 16 17 WarningService::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 26 WarningService::~WarningService() {} 27 28 void 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 46 std::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 58 std::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 74 void 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 85 void 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 104 void WarningService::AddObserver(Observer* observer) { 105 observer_list_.AddObserver(observer); 106 } 107 108 void WarningService::RemoveObserver(Observer* observer) { 109 observer_list_.RemoveObserver(observer); 110 } 111 112 void WarningService::NotifyWarningsChanged() { 113 FOR_EACH_OBSERVER(Observer, observer_list_, ExtensionWarningsChanged()); 114 } 115 116 void 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