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
PluginExceptionsTableModel(HostContentSettingsMap * content_settings_map,HostContentSettingsMap * otr_content_settings_map)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
~PluginExceptionsTableModel()26 PluginExceptionsTableModel::~PluginExceptionsTableModel() {
27 }
28
CanRemoveRows(const Rows & rows) const29 bool PluginExceptionsTableModel::CanRemoveRows(const Rows& rows) const {
30 return !rows.empty();
31 }
32
RemoveRows(const Rows & rows)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
RemoveAll()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
RowCount()77 int PluginExceptionsTableModel::RowCount() {
78 return settings_.size();
79 }
80
GetText(int row,int column_id)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
HasGroups()103 bool PluginExceptionsTableModel::HasGroups() {
104 return true;
105 }
106
SetObserver(ui::TableModelObserver * observer)107 void PluginExceptionsTableModel::SetObserver(ui::TableModelObserver* observer) {
108 observer_ = observer;
109 }
110
GetGroups()111 ui::TableModel::Groups PluginExceptionsTableModel::GetGroups() {
112 return groups_;
113 }
114
GetGroupID(int row)115 int PluginExceptionsTableModel::GetGroupID(int row) {
116 DCHECK_LT(row, static_cast<int>(settings_.size()));
117 return settings_[row].plugin_id;
118 }
119
Observe(NotificationType type,const NotificationSource & source,const NotificationDetails & details)120 void PluginExceptionsTableModel::Observe(NotificationType type,
121 const NotificationSource& source,
122 const NotificationDetails& details) {
123 if (!updates_disabled_)
124 ReloadSettings();
125 }
126
ClearSettings()127 void PluginExceptionsTableModel::ClearSettings() {
128 settings_.clear();
129 groups_.clear();
130 row_counts_.clear();
131 resources_.clear();
132 }
133
GetPlugins(std::vector<webkit::npapi::PluginGroup> * plugin_groups)134 void PluginExceptionsTableModel::GetPlugins(
135 std::vector<webkit::npapi::PluginGroup>* plugin_groups) {
136 webkit::npapi::PluginList::Singleton()->GetPluginGroups(false, plugin_groups);
137 }
138
LoadSettings()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
ReloadSettings()188 void PluginExceptionsTableModel::ReloadSettings() {
189 ClearSettings();
190 LoadSettings();
191
192 if (observer_)
193 observer_->OnModelChanged();
194 }
195