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