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