Home | History | Annotate | Download | only in browser
      1 // Copyright (c) 2011 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/plugin_exceptions_table_model.h"
      6 
      7 #include "base/auto_reset.h"
      8 #include "base/sys_string_conversions.h"
      9 #include "base/utf_string_conversions.h"
     10 #include "content/common/notification_service.h"
     11 #include "grit/generated_resources.h"
     12 #include "ui/base/l10n/l10n_util.h"
     13 #include "ui/base/models/table_model_observer.h"
     14 
     15 PluginExceptionsTableModel::PluginExceptionsTableModel(
     16     HostContentSettingsMap* content_settings_map,
     17     HostContentSettingsMap* otr_content_settings_map)
     18     : map_(content_settings_map),
     19       otr_map_(otr_content_settings_map),
     20       updates_disabled_(false),
     21       observer_(NULL) {
     22   registrar_.Add(this, NotificationType::CONTENT_SETTINGS_CHANGED,
     23                  NotificationService::AllSources());
     24 }
     25 
     26 PluginExceptionsTableModel::~PluginExceptionsTableModel() {
     27 }
     28 
     29 bool PluginExceptionsTableModel::CanRemoveRows(const Rows& rows) const {
     30   return !rows.empty();
     31 }
     32 
     33 void PluginExceptionsTableModel::RemoveRows(const Rows& rows) {
     34   AutoReset<bool> tmp(&updates_disabled_, true);
     35   bool reload_all = false;
     36   // Iterate over the rows starting with the highest ones so we can delete
     37   // entries from |settings_| without the other indices shifting.
     38   for (Rows::const_reverse_iterator it = rows.rbegin();
     39        it != rows.rend(); ++it) {
     40     DCHECK_LT(*it, settings_.size());
     41     SettingsEntry entry = settings_[*it];
     42     HostContentSettingsMap* map = entry.is_otr ? otr_map_ : map_;
     43     map->SetContentSetting(entry.pattern,
     44                            CONTENT_SETTINGS_TYPE_PLUGINS,
     45                            resources_[entry.plugin_id],
     46                            CONTENT_SETTING_DEFAULT);
     47     settings_.erase(settings_.begin() + *it);
     48     row_counts_[entry.plugin_id]--;
     49     if (!reload_all) {
     50       // If we remove the last exception for a plugin, recreate all groups
     51       // to get correct IDs.
     52       if (row_counts_[entry.plugin_id] == 0)  {
     53         reload_all = true;
     54       } else {
     55         if (observer_)
     56           observer_->OnItemsRemoved(*it, 1);
     57       }
     58     }
     59   }
     60   if (reload_all) {
     61     // This also notifies the observer.
     62     ReloadSettings();
     63   }
     64 }
     65 
     66 void PluginExceptionsTableModel::RemoveAll() {
     67   AutoReset<bool> tmp(&updates_disabled_, true);
     68   map_->ClearSettingsForOneType(CONTENT_SETTINGS_TYPE_PLUGINS);
     69   if (otr_map_)
     70     otr_map_->ClearSettingsForOneType(CONTENT_SETTINGS_TYPE_PLUGINS);
     71 
     72   ClearSettings();
     73   if (observer_)
     74     observer_->OnModelChanged();
     75 }
     76 
     77 int PluginExceptionsTableModel::RowCount() {
     78   return settings_.size();
     79 }
     80 
     81 string16 PluginExceptionsTableModel::GetText(int row, int column_id) {
     82   DCHECK_GE(row, 0);
     83   DCHECK_LT(row, static_cast<int>(settings_.size()));
     84   SettingsEntry& entry = settings_[row];
     85   if (column_id == IDS_EXCEPTIONS_PATTERN_HEADER ||
     86       column_id == IDS_EXCEPTIONS_HOSTNAME_HEADER) {
     87     return UTF8ToUTF16(entry.pattern.AsString());
     88   } else if (column_id == IDS_EXCEPTIONS_ACTION_HEADER) {
     89     switch (entry.setting) {
     90       case CONTENT_SETTING_ALLOW:
     91         return l10n_util::GetStringUTF16(IDS_EXCEPTIONS_ALLOW_BUTTON);
     92       case CONTENT_SETTING_BLOCK:
     93         return l10n_util::GetStringUTF16(IDS_EXCEPTIONS_BLOCK_BUTTON);
     94       default:
     95         NOTREACHED();
     96     }
     97   } else {
     98     NOTREACHED();
     99   }
    100   return string16();
    101 }
    102 
    103 bool PluginExceptionsTableModel::HasGroups() {
    104   return true;
    105 }
    106 
    107 void PluginExceptionsTableModel::SetObserver(ui::TableModelObserver* observer) {
    108   observer_ = observer;
    109 }
    110 
    111 ui::TableModel::Groups PluginExceptionsTableModel::GetGroups() {
    112   return groups_;
    113 }
    114 
    115 int PluginExceptionsTableModel::GetGroupID(int row) {
    116   DCHECK_LT(row, static_cast<int>(settings_.size()));
    117   return settings_[row].plugin_id;
    118 }
    119 
    120 void PluginExceptionsTableModel::Observe(NotificationType type,
    121                                          const NotificationSource& source,
    122                                          const NotificationDetails& details) {
    123   if (!updates_disabled_)
    124     ReloadSettings();
    125 }
    126 
    127 void PluginExceptionsTableModel::ClearSettings() {
    128   settings_.clear();
    129   groups_.clear();
    130   row_counts_.clear();
    131   resources_.clear();
    132 }
    133 
    134 void PluginExceptionsTableModel::GetPlugins(
    135     std::vector<webkit::npapi::PluginGroup>* plugin_groups) {
    136   webkit::npapi::PluginList::Singleton()->GetPluginGroups(false, plugin_groups);
    137 }
    138 
    139 void PluginExceptionsTableModel::LoadSettings() {
    140   int group_id = 0;
    141   std::vector<webkit::npapi::PluginGroup> plugins;
    142   GetPlugins(&plugins);
    143   for (size_t i = 0; i < plugins.size(); ++i) {
    144     std::string plugin = plugins[i].identifier();
    145     HostContentSettingsMap::SettingsForOneType settings;
    146     map_->GetSettingsForOneType(CONTENT_SETTINGS_TYPE_PLUGINS,
    147                                 plugin,
    148                                 &settings);
    149     HostContentSettingsMap::SettingsForOneType otr_settings;
    150     if (otr_map_) {
    151       otr_map_->GetSettingsForOneType(CONTENT_SETTINGS_TYPE_PLUGINS,
    152                                       plugin,
    153                                       &otr_settings);
    154     }
    155     string16 title = plugins[i].GetGroupName();
    156     for (HostContentSettingsMap::SettingsForOneType::iterator setting_it =
    157              settings.begin();
    158          setting_it != settings.end(); ++setting_it) {
    159       SettingsEntry entry = {
    160         setting_it->first,
    161         group_id,
    162         setting_it->second,
    163         false
    164       };
    165       settings_.push_back(entry);
    166     }
    167     for (HostContentSettingsMap::SettingsForOneType::iterator setting_it =
    168              otr_settings.begin();
    169          setting_it != otr_settings.end(); ++setting_it) {
    170       SettingsEntry entry = {
    171         setting_it->first,
    172         group_id,
    173         setting_it->second,
    174         true
    175       };
    176       settings_.push_back(entry);
    177     }
    178     int num_plugins = settings.size() + otr_settings.size();
    179     if (num_plugins > 0) {
    180       Group group = { title, group_id++ };
    181       groups_.push_back(group);
    182       resources_.push_back(plugin);
    183       row_counts_.push_back(num_plugins);
    184     }
    185   }
    186 }
    187 
    188 void PluginExceptionsTableModel::ReloadSettings() {
    189   ClearSettings();
    190   LoadSettings();
    191 
    192   if (observer_)
    193     observer_->OnModelChanged();
    194 }
    195