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 "chrome/browser/extensions/extension_warning_service.h" 6 7 #include "chrome/browser/browser_process.h" 8 #include "chrome/browser/extensions/extension_service.h" 9 #include "chrome/browser/profiles/profile.h" 10 #include "chrome/browser/profiles/profile_manager.h" 11 #include "content/public/browser/browser_thread.h" 12 #include "extensions/browser/extension_registry.h" 13 #include "extensions/browser/extension_system.h" 14 15 using content::BrowserThread; 16 17 namespace extensions { 18 19 ExtensionWarningService::ExtensionWarningService(Profile* profile) 20 : profile_(profile), extension_registry_observer_(this) { 21 DCHECK(CalledOnValidThread()); 22 if (profile_) { 23 extension_registry_observer_.Add( 24 ExtensionRegistry::Get(profile_->GetOriginalProfile())); 25 } 26 } 27 28 ExtensionWarningService::~ExtensionWarningService() {} 29 30 void ExtensionWarningService::ClearWarnings( 31 const std::set<ExtensionWarning::WarningType>& types) { 32 DCHECK(CalledOnValidThread()); 33 bool deleted_anything = false; 34 for (ExtensionWarningSet::iterator i = warnings_.begin(); 35 i != warnings_.end();) { 36 if (types.find(i->warning_type()) != types.end()) { 37 deleted_anything = true; 38 warnings_.erase(i++); 39 } else { 40 ++i; 41 } 42 } 43 44 if (deleted_anything) 45 NotifyWarningsChanged(); 46 } 47 48 std::set<ExtensionWarning::WarningType> 49 ExtensionWarningService::GetWarningTypesAffectingExtension( 50 const std::string& extension_id) const { 51 DCHECK(CalledOnValidThread()); 52 std::set<ExtensionWarning::WarningType> result; 53 for (ExtensionWarningSet::const_iterator i = warnings_.begin(); 54 i != warnings_.end(); ++i) { 55 if (i->extension_id() == extension_id) 56 result.insert(i->warning_type()); 57 } 58 return result; 59 } 60 61 std::vector<std::string> 62 ExtensionWarningService::GetWarningMessagesForExtension( 63 const std::string& extension_id) const { 64 DCHECK(CalledOnValidThread()); 65 std::vector<std::string> result; 66 67 const ExtensionService* extension_service = 68 ExtensionSystem::Get(profile_)->extension_service(); 69 70 for (ExtensionWarningSet::const_iterator i = warnings_.begin(); 71 i != warnings_.end(); ++i) { 72 if (i->extension_id() == extension_id) 73 result.push_back(i->GetLocalizedMessage(extension_service->extensions())); 74 } 75 return result; 76 } 77 78 void ExtensionWarningService::AddWarnings( 79 const ExtensionWarningSet& warnings) { 80 DCHECK(CalledOnValidThread()); 81 size_t old_size = warnings_.size(); 82 83 warnings_.insert(warnings.begin(), warnings.end()); 84 85 if (old_size != warnings_.size()) 86 NotifyWarningsChanged(); 87 } 88 89 // static 90 void ExtensionWarningService::NotifyWarningsOnUI( 91 void* profile_id, 92 const ExtensionWarningSet& warnings) { 93 DCHECK_CURRENTLY_ON(BrowserThread::UI); 94 Profile* profile = reinterpret_cast<Profile*>(profile_id); 95 if (!profile || 96 !g_browser_process->profile_manager() || 97 !g_browser_process->profile_manager()->IsValidProfile(profile)) { 98 return; 99 } 100 101 extensions::ExtensionWarningService* warning_service = 102 extensions::ExtensionSystem::Get(profile)->warning_service(); 103 104 warning_service->AddWarnings(warnings); 105 } 106 107 void ExtensionWarningService::AddObserver(Observer* observer) { 108 observer_list_.AddObserver(observer); 109 } 110 111 void ExtensionWarningService::RemoveObserver(Observer* observer) { 112 observer_list_.RemoveObserver(observer); 113 } 114 115 void ExtensionWarningService::NotifyWarningsChanged() { 116 FOR_EACH_OBSERVER(Observer, observer_list_, ExtensionWarningsChanged()); 117 } 118 119 void ExtensionWarningService::OnExtensionUnloaded( 120 content::BrowserContext* browser_context, 121 const Extension* extension, 122 UnloadedExtensionInfo::Reason reason) { 123 // Unloading one extension might have solved the problems of others. 124 // Therefore, we clear warnings of this type for all extensions. 125 std::set<ExtensionWarning::WarningType> warning_types = 126 GetWarningTypesAffectingExtension(extension->id()); 127 ClearWarnings(warning_types); 128 } 129 130 } // namespace extensions 131