Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(338)

Side by Side Diff: chrome/browser/extensions/error_console/error_console.cc

Issue 238073002: Provide UI for per-extension enabling/disabling of error collection. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/extensions/error_console/error_console.h" 5 #include "chrome/browser/extensions/error_console/error_console.h"
6 6
7 #include <list> 7 #include <list>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 19 matching lines...) Expand all
30 #include "extensions/common/feature_switch.h" 30 #include "extensions/common/feature_switch.h"
31 31
32 namespace extensions { 32 namespace extensions {
33 33
34 namespace { 34 namespace {
35 35
36 // The key into the Extension prefs for an Extension's specific reporting 36 // The key into the Extension prefs for an Extension's specific reporting
37 // settings. 37 // settings.
38 const char kStoreExtensionErrorsPref[] = "store_extension_errors"; 38 const char kStoreExtensionErrorsPref[] = "store_extension_errors";
39 39
40 // The default mask (for the time being) is to report everything. 40 // This is the default mask for which errors to report. That is, if an extension
41 const int32 kDefaultMask = (1 << ExtensionError::MANIFEST_ERROR) | 41 // does not have specific preference set, this will be used instead.
42 (1 << ExtensionError::RUNTIME_ERROR); 42 const int kDefaultMask = 0;
43 43
44 const char kAppsDeveloperToolsExtensionId[] = 44 const char kAppsDeveloperToolsExtensionId[] =
45 "ohmmkhmmmpcnpikjeljgnaoabkaalbgc"; 45 "ohmmkhmmmpcnpikjeljgnaoabkaalbgc";
46 46
47 } // namespace 47 } // namespace
48 48
49 void ErrorConsole::Observer::OnErrorConsoleDestroyed() { 49 void ErrorConsole::Observer::OnErrorConsoleDestroyed() {
50 } 50 }
51 51
52 ErrorConsole::ErrorConsole(Profile* profile) 52 ErrorConsole::ErrorConsole(Profile* profile)
53 : enabled_(false), 53 : enabled_(false),
54 default_mask_(kDefaultMask), 54 default_mask_(kDefaultMask),
55 profile_(profile), 55 profile_(profile),
56 prefs_(NULL),
56 registry_observer_(this) { 57 registry_observer_(this) {
57 // TODO(rdevlin.cronin): Remove once crbug.com/159265 is fixed. 58 // TODO(rdevlin.cronin): Remove once crbug.com/159265 is fixed.
58 #if !defined(ENABLE_EXTENSIONS) 59 #if !defined(ENABLE_EXTENSIONS)
59 return; 60 return;
60 #endif 61 #endif
61 62
62 pref_registrar_.Init(profile_->GetPrefs()); 63 pref_registrar_.Init(profile_->GetPrefs());
63 pref_registrar_.Add(prefs::kExtensionsUIDeveloperMode, 64 pref_registrar_.Add(prefs::kExtensionsUIDeveloperMode,
64 base::Bind(&ErrorConsole::OnPrefChanged, 65 base::Bind(&ErrorConsole::OnPrefChanged,
65 base::Unretained(this))); 66 base::Unretained(this)));
(...skipping 12 matching lines...) Expand all
78 return ExtensionSystem::Get(profile)->error_console(); 79 return ExtensionSystem::Get(profile)->error_console();
79 } 80 }
80 81
81 void ErrorConsole::SetReportingForExtension(const std::string& extension_id, 82 void ErrorConsole::SetReportingForExtension(const std::string& extension_id,
82 ExtensionError::Type type, 83 ExtensionError::Type type,
83 bool enabled) { 84 bool enabled) {
84 DCHECK(thread_checker_.CalledOnValidThread()); 85 DCHECK(thread_checker_.CalledOnValidThread());
85 if (!enabled_ || !Extension::IdIsValid(extension_id)) 86 if (!enabled_ || !Extension::IdIsValid(extension_id))
86 return; 87 return;
87 88
88 ErrorPreferenceMap::iterator pref = pref_map_.find(extension_id); 89 int mask = default_mask_;
90 // This call can fail if the preference isn't set, but we don't really care
91 // if it does, because we just use the default mask instead.
92 prefs_->ReadPrefAsInteger(extension_id, kStoreExtensionErrorsPref, &mask);
89 93
90 if (pref == pref_map_.end()) { 94 if (enabled)
91 pref = pref_map_.insert( 95 mask |= 1 << type;
92 std::pair<std::string, int32>(extension_id, default_mask_)).first; 96 else
93 } 97 mask &= ~(1 << type);
94 98
95 pref->second = 99 prefs_->UpdateExtensionPref(extension_id,
96 enabled ? pref->second | (1 << type) : pref->second &~(1 << type); 100 kStoreExtensionErrorsPref,
101 base::Value::CreateIntegerValue(mask));
102 }
97 103
98 ExtensionPrefs::Get(profile_)->UpdateExtensionPref( 104 void ErrorConsole::SetReportingAllForExtension(
99 extension_id, 105 const std::string& extension_id, bool enabled) {
100 kStoreExtensionErrorsPref, 106 DCHECK(thread_checker_.CalledOnValidThread());
101 base::Value::CreateIntegerValue(pref->second)); 107 if (!enabled_ || !Extension::IdIsValid(extension_id))
108 return;
109
110 int mask = 0;
111 if (enabled)
112 mask = (1 << ExtensionError::NUM_ERROR_TYPES) - 1;
113
114 prefs_->UpdateExtensionPref(extension_id,
115 kStoreExtensionErrorsPref,
116 base::Value::CreateIntegerValue(mask));
117 }
118
119 bool ErrorConsole::IsReportingEnabledForExtension(
120 const std::string& extension_id) const {
121 DCHECK(thread_checker_.CalledOnValidThread());
122 if (!enabled_ || !Extension::IdIsValid(extension_id))
123 return false;
124
125 int mask = default_mask_;
126 // This call can fail if the preference isn't set, but we don't really care
127 // if it does, because we just use the default mask instead.
128 prefs_->ReadPrefAsInteger(extension_id, kStoreExtensionErrorsPref, &mask);
129 return mask != 0;
102 } 130 }
103 131
104 void ErrorConsole::UseDefaultReportingForExtension( 132 void ErrorConsole::UseDefaultReportingForExtension(
105 const std::string& extension_id) { 133 const std::string& extension_id) {
106 DCHECK(thread_checker_.CalledOnValidThread()); 134 DCHECK(thread_checker_.CalledOnValidThread());
107 if (!enabled_ || !Extension::IdIsValid(extension_id)) 135 if (!enabled_ || !Extension::IdIsValid(extension_id))
108 return; 136 return;
109 137
110 pref_map_.erase(extension_id); 138 prefs_->UpdateExtensionPref(extension_id, kStoreExtensionErrorsPref, NULL);
111 ExtensionPrefs::Get(profile_)->UpdateExtensionPref(
112 extension_id,
113 kStoreExtensionErrorsPref,
114 NULL);
115 } 139 }
116 140
117 void ErrorConsole::ReportError(scoped_ptr<ExtensionError> error) { 141 void ErrorConsole::ReportError(scoped_ptr<ExtensionError> error) {
118 DCHECK(thread_checker_.CalledOnValidThread()); 142 DCHECK(thread_checker_.CalledOnValidThread());
119 if (!enabled_ || !Extension::IdIsValid(error->extension_id())) 143 if (!enabled_ ||
120 return; 144 !Extension::IdIsValid(error->extension_id()) ||
121 145 !ShouldReportErrorForExtension(error->extension_id(), error->type())) {
122 ErrorPreferenceMap::const_iterator pref =
123 pref_map_.find(error->extension_id());
124 // Check the mask to see if we report the error. If we don't have a specific
125 // entry, use the default mask.
126 if ((pref == pref_map_.end() &&
127 ((default_mask_ & (1 << error->type())) == 0)) ||
128 (pref != pref_map_.end() && (pref->second & (1 << error->type())) == 0)) {
129 return; 146 return;
130 } 147 }
131 148
132 const ExtensionError* weak_error = errors_.AddError(error.Pass()); 149 const ExtensionError* weak_error = errors_.AddError(error.Pass());
133 FOR_EACH_OBSERVER(Observer, observers_, OnErrorAdded(weak_error)); 150 FOR_EACH_OBSERVER(Observer, observers_, OnErrorAdded(weak_error));
134 } 151 }
135 152
136 const ErrorList& ErrorConsole::GetErrorsForExtension( 153 const ErrorList& ErrorConsole::GetErrorsForExtension(
137 const std::string& extension_id) const { 154 const std::string& extension_id) const {
138 return errors_.GetErrorsForExtension(extension_id); 155 return errors_.GetErrorsForExtension(extension_id);
(...skipping 25 matching lines...) Expand all
164 IsEnabledForAppsDeveloperTools(); 181 IsEnabledForAppsDeveloperTools();
165 if (should_be_enabled && !enabled_) 182 if (should_be_enabled && !enabled_)
166 Enable(); 183 Enable();
167 if (!should_be_enabled && enabled_) 184 if (!should_be_enabled && enabled_)
168 Disable(); 185 Disable();
169 } 186 }
170 187
171 void ErrorConsole::Enable() { 188 void ErrorConsole::Enable() {
172 enabled_ = true; 189 enabled_ = true;
173 190
191 // We postpone the initialization of |prefs_| until now because they can be
192 // NULL in unit_tests. Any unit tests that enable the error console should
193 // also create an ExtensionPrefs object.
194 prefs_ = ExtensionPrefs::Get(profile_);
195
174 notification_registrar_.Add( 196 notification_registrar_.Add(
175 this, 197 this,
176 chrome::NOTIFICATION_PROFILE_DESTROYED, 198 chrome::NOTIFICATION_PROFILE_DESTROYED,
177 content::NotificationService::AllBrowserContextsAndSources()); 199 content::NotificationService::AllBrowserContextsAndSources());
178 notification_registrar_.Add( 200 notification_registrar_.Add(
179 this, 201 this,
180 chrome::NOTIFICATION_EXTENSION_UNINSTALLED, 202 chrome::NOTIFICATION_EXTENSION_UNINSTALLED,
181 content::Source<Profile>(profile_)); 203 content::Source<Profile>(profile_));
182 notification_registrar_.Add( 204 notification_registrar_.Add(
183 this, 205 this,
184 chrome::NOTIFICATION_EXTENSION_INSTALLED, 206 chrome::NOTIFICATION_EXTENSION_INSTALLED,
185 content::Source<Profile>(profile_)); 207 content::Source<Profile>(profile_));
186 208
187 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile_);
188 const ExtensionSet& extensions = 209 const ExtensionSet& extensions =
189 ExtensionRegistry::Get(profile_)->enabled_extensions(); 210 ExtensionRegistry::Get(profile_)->enabled_extensions();
190 for (ExtensionSet::const_iterator iter = extensions.begin(); 211 for (ExtensionSet::const_iterator iter = extensions.begin();
191 iter != extensions.end(); 212 iter != extensions.end();
192 ++iter) { 213 ++iter) {
193 int mask = 0;
194 if (prefs->ReadPrefAsInteger(iter->get()->id(),
195 kStoreExtensionErrorsPref,
196 &mask)) {
197 pref_map_[iter->get()->id()] = mask;
198 }
199 AddManifestErrorsForExtension(iter->get()); 214 AddManifestErrorsForExtension(iter->get());
200 } 215 }
201 } 216 }
202 217
203 void ErrorConsole::Disable() { 218 void ErrorConsole::Disable() {
204 notification_registrar_.RemoveAll(); 219 notification_registrar_.RemoveAll();
205 errors_.RemoveAllErrors(); 220 errors_.RemoveAllErrors();
206 enabled_ = false; 221 enabled_ = false;
207 } 222 }
208 223
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
262 ExtensionError::MANIFEST_ERROR); 277 ExtensionError::MANIFEST_ERROR);
263 278
264 AddManifestErrorsForExtension(info->extension); 279 AddManifestErrorsForExtension(info->extension);
265 break; 280 break;
266 } 281 }
267 default: 282 default:
268 NOTREACHED(); 283 NOTREACHED();
269 } 284 }
270 } 285 }
271 286
287 bool ErrorConsole::ShouldReportErrorForExtension(
288 const std::string& extension_id, ExtensionError::Type type) const {
289 // Registered preferences take priority over everything else.
290 int pref = 0;
291 if (prefs_->ReadPrefAsInteger(
292 extension_id, kStoreExtensionErrorsPref, &pref)) {
293 return (pref & (1 << type)) != 0;
294 }
295
296 // If the default mask says to report the error, do so.
297 if ((default_mask_ & (1 << type)) != 0)
298 return true;
299
300 // One last check: If the extension is unpacked, we report all errors by
301 // default.
302 const Extension* extension =
303 ExtensionRegistry::Get(profile_)->GetExtensionById(
304 extension_id, ExtensionRegistry::EVERYTHING);
305 if (extension && extension->location() == Manifest::UNPACKED)
306 return true;
307
308 return false;
309 }
310
272 } // namespace extensions 311 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698