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