• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/notifications/notification_exceptions_table_model.h"
6 
7 #include "base/auto_reset.h"
8 #include "chrome/common/content_settings.h"
9 #include "chrome/common/content_settings_helper.h"
10 #include "chrome/common/content_settings_types.h"
11 #include "chrome/common/url_constants.h"
12 #include "content/common/notification_service.h"
13 #include "content/common/notification_type.h"
14 #include "grit/generated_resources.h"
15 #include "ui/base/l10n/l10n_util.h"
16 #include "ui/base/models/table_model_observer.h"
17 
18 struct NotificationExceptionsTableModel::Entry {
19   Entry(const GURL& origin, ContentSetting setting);
20   bool operator<(const Entry& b) const;
21 
22   GURL origin;
23   ContentSetting setting;
24 };
25 
NotificationExceptionsTableModel(DesktopNotificationService * service)26 NotificationExceptionsTableModel::NotificationExceptionsTableModel(
27     DesktopNotificationService* service)
28     : service_(service),
29       updates_disabled_(false),
30       observer_(NULL) {
31   registrar_.Add(this, NotificationType::DESKTOP_NOTIFICATION_SETTINGS_CHANGED,
32                  NotificationService::AllSources());
33   LoadEntries();
34 }
35 
~NotificationExceptionsTableModel()36 NotificationExceptionsTableModel::~NotificationExceptionsTableModel() {}
37 
CanRemoveRows(const Rows & rows) const38 bool NotificationExceptionsTableModel::CanRemoveRows(
39     const Rows& rows) const {
40   return !rows.empty();
41 }
42 
RemoveRows(const Rows & rows)43 void NotificationExceptionsTableModel::RemoveRows(const Rows& rows) {
44   AutoReset<bool> tmp(&updates_disabled_, true);
45   // This is O(n^2) in rows.size(). Since n is small, that's ok.
46   for (Rows::const_reverse_iterator i(rows.rbegin()); i != rows.rend(); ++i) {
47     size_t row = *i;
48     Entry* entry = &entries_[row];
49     if (entry->setting == CONTENT_SETTING_ALLOW) {
50       service_->ResetAllowedOrigin(entry->origin);
51     } else {
52       DCHECK_EQ(entry->setting, CONTENT_SETTING_BLOCK);
53       service_->ResetBlockedOrigin(entry->origin);
54     }
55     entries_.erase(entries_.begin() + row);  // Note: |entry| is now garbage.
56     if (observer_)
57       observer_->OnItemsRemoved(row, 1);
58   }
59 }
60 
RemoveAll()61 void NotificationExceptionsTableModel::RemoveAll() {
62   AutoReset<bool> tmp(&updates_disabled_, true);
63   entries_.clear();
64   service_->ResetAllOrigins();
65   if (observer_)
66     observer_->OnModelChanged();
67 }
68 
RowCount()69 int NotificationExceptionsTableModel::RowCount() {
70   return static_cast<int>(entries_.size());
71 }
72 
GetText(int row,int column_id)73 string16 NotificationExceptionsTableModel::GetText(int row,
74                                                    int column_id) {
75   const Entry& entry = entries_[row];
76   if (column_id == IDS_EXCEPTIONS_HOSTNAME_HEADER) {
77     return content_settings_helper::OriginToString16(entry.origin);
78   }
79 
80   if (column_id == IDS_EXCEPTIONS_ACTION_HEADER) {
81     switch (entry.setting) {
82       case CONTENT_SETTING_ALLOW:
83         return l10n_util::GetStringUTF16(IDS_EXCEPTIONS_ALLOW_BUTTON);
84       case CONTENT_SETTING_BLOCK:
85         return l10n_util::GetStringUTF16(IDS_EXCEPTIONS_BLOCK_BUTTON);
86       default:
87         break;
88     }
89   }
90 
91   NOTREACHED();
92   return string16();
93 }
94 
SetObserver(ui::TableModelObserver * observer)95 void NotificationExceptionsTableModel::SetObserver(
96     ui::TableModelObserver* observer) {
97   observer_ = observer;
98 }
99 
Observe(NotificationType type,const NotificationSource & source,const NotificationDetails & details)100 void NotificationExceptionsTableModel::Observe(
101     NotificationType type,
102     const NotificationSource& source,
103     const NotificationDetails& details) {
104   if (!updates_disabled_) {
105     DCHECK(type == NotificationType::DESKTOP_NOTIFICATION_SETTINGS_CHANGED);
106     entries_.clear();
107     LoadEntries();
108 
109     if (observer_)
110       observer_->OnModelChanged();
111   }
112 }
113 
LoadEntries()114 void NotificationExceptionsTableModel::LoadEntries() {
115   std::vector<GURL> allowed(service_->GetAllowedOrigins());
116   std::vector<GURL> blocked(service_->GetBlockedOrigins());
117   entries_.reserve(allowed.size() + blocked.size());
118   for (size_t i = 0; i < allowed.size(); ++i)
119     entries_.push_back(Entry(allowed[i], CONTENT_SETTING_ALLOW));
120   for (size_t i = 0; i < blocked.size(); ++i)
121     entries_.push_back(Entry(blocked[i], CONTENT_SETTING_BLOCK));
122   std::sort(entries_.begin(), entries_.end());
123 }
124 
Entry(const GURL & in_origin,ContentSetting in_setting)125 NotificationExceptionsTableModel::Entry::Entry(
126     const GURL& in_origin,
127     ContentSetting in_setting)
128     : origin(in_origin),
129       setting(in_setting) {
130 }
131 
operator <(const NotificationExceptionsTableModel::Entry & b) const132 bool NotificationExceptionsTableModel::Entry::operator<(
133     const NotificationExceptionsTableModel::Entry& b) const {
134   DCHECK_NE(origin, b.origin);
135   return origin < b.origin;
136 }
137