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

Side by Side Diff: chrome/browser/background/background_application_list_model.cc

Issue 10298002: No longer start BG mode until a BackgroundContents is loaded (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Prospective fix for cros test failures. Created 8 years, 7 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 (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/background/background_application_list_model.h" 5 #include "chrome/browser/background/background_application_list_model.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <set> 8 #include <set>
9 9
10 #include "base/stl_util.h" 10 #include "base/stl_util.h"
11 #include "base/utf_string_conversions.h" 11 #include "base/utf_string_conversions.h"
12 #include "chrome/app/chrome_command_ids.h" 12 #include "chrome/app/chrome_command_ids.h"
13 #include "chrome/browser/background/background_mode_manager.h" 13 #include "chrome/browser/background/background_mode_manager.h"
14 #include "chrome/browser/background/background_contents_service.h"
15 #include "chrome/browser/background/background_contents_service_factory.h"
14 #include "chrome/browser/browser_process.h" 16 #include "chrome/browser/browser_process.h"
15 #include "chrome/browser/extensions/extension_prefs.h" 17 #include "chrome/browser/extensions/extension_prefs.h"
16 #include "chrome/browser/extensions/extension_service.h" 18 #include "chrome/browser/extensions/extension_service.h"
17 #include "chrome/browser/extensions/image_loading_tracker.h" 19 #include "chrome/browser/extensions/image_loading_tracker.h"
18 #include "chrome/browser/profiles/profile.h" 20 #include "chrome/browser/profiles/profile.h"
19 #include "chrome/common/chrome_notification_types.h" 21 #include "chrome/common/chrome_notification_types.h"
20 #include "chrome/common/extensions/extension.h" 22 #include "chrome/common/extensions/extension.h"
21 #include "chrome/common/extensions/extension_icon_set.h" 23 #include "chrome/common/extensions/extension_icon_set.h"
22 #include "chrome/common/extensions/extension_resource.h" 24 #include "chrome/common/extensions/extension_resource.h"
23 #include "content/public/browser/notification_details.h" 25 #include "content/public/browser/notification_details.h"
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
72 74
73 namespace { 75 namespace {
74 void GetServiceApplications(ExtensionService* service, 76 void GetServiceApplications(ExtensionService* service,
75 ExtensionList* applications_result) { 77 ExtensionList* applications_result) {
76 const ExtensionSet* extensions = service->extensions(); 78 const ExtensionSet* extensions = service->extensions();
77 79
78 for (ExtensionSet::const_iterator cursor = extensions->begin(); 80 for (ExtensionSet::const_iterator cursor = extensions->begin();
79 cursor != extensions->end(); 81 cursor != extensions->end();
80 ++cursor) { 82 ++cursor) {
81 const Extension* extension = *cursor; 83 const Extension* extension = *cursor;
82 if (BackgroundApplicationListModel::IsBackgroundApp(*extension)) 84 if (BackgroundApplicationListModel::IsBackgroundApp(*extension,
85 service->profile())) {
83 applications_result->push_back(extension); 86 applications_result->push_back(extension);
87 }
84 } 88 }
85 89
86 // Walk the list of terminated extensions also (just because an extension 90 // Walk the list of terminated extensions also (just because an extension
87 // crashed doesn't mean we should ignore it). 91 // crashed doesn't mean we should ignore it).
88 extensions = service->terminated_extensions(); 92 extensions = service->terminated_extensions();
89 for (ExtensionSet::const_iterator cursor = extensions->begin(); 93 for (ExtensionSet::const_iterator cursor = extensions->begin();
90 cursor != extensions->end(); 94 cursor != extensions->end();
91 ++cursor) { 95 ++cursor) {
92 const Extension* extension = *cursor; 96 const Extension* extension = *cursor;
93 if (BackgroundApplicationListModel::IsBackgroundApp(*extension)) 97 if (BackgroundApplicationListModel::IsBackgroundApp(*extension,
98 service->profile())) {
94 applications_result->push_back(extension); 99 applications_result->push_back(extension);
100 }
95 } 101 }
96 102
97 std::string locale = g_browser_process->GetApplicationLocale(); 103 std::string locale = g_browser_process->GetApplicationLocale();
98 icu::Locale loc(locale.c_str()); 104 icu::Locale loc(locale.c_str());
99 UErrorCode error = U_ZERO_ERROR; 105 UErrorCode error = U_ZERO_ERROR;
100 scoped_ptr<icu::Collator> collator(icu::Collator::createInstance(loc, error)); 106 scoped_ptr<icu::Collator> collator(icu::Collator::createInstance(loc, error));
101 std::sort(applications_result->begin(), applications_result->end(), 107 std::sort(applications_result->begin(), applications_result->end(),
102 ExtensionNameComparator(collator.get())); 108 ExtensionNameComparator(collator.get()));
103 } 109 }
104 110
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
160 content::Source<Profile>(profile)); 166 content::Source<Profile>(profile));
161 registrar_.Add(this, 167 registrar_.Add(this,
162 chrome::NOTIFICATION_EXTENSION_UNLOADED, 168 chrome::NOTIFICATION_EXTENSION_UNLOADED,
163 content::Source<Profile>(profile)); 169 content::Source<Profile>(profile));
164 registrar_.Add(this, 170 registrar_.Add(this,
165 chrome::NOTIFICATION_EXTENSIONS_READY, 171 chrome::NOTIFICATION_EXTENSIONS_READY,
166 content::Source<Profile>(profile)); 172 content::Source<Profile>(profile));
167 registrar_.Add(this, 173 registrar_.Add(this,
168 chrome::NOTIFICATION_EXTENSION_PERMISSIONS_UPDATED, 174 chrome::NOTIFICATION_EXTENSION_PERMISSIONS_UPDATED,
169 content::Source<Profile>(profile)); 175 content::Source<Profile>(profile));
176 registrar_.Add(this,
177 chrome::NOTIFICATION_BACKGROUND_CONTENTS_SERVICE_CHANGED,
178 content::Source<Profile>(profile));
170 ExtensionService* service = profile->GetExtensionService(); 179 ExtensionService* service = profile->GetExtensionService();
171 if (service && service->is_ready()) 180 if (service && service->is_ready())
172 Update(); 181 Update();
173 } 182 }
174 183
175 void BackgroundApplicationListModel::AddObserver(Observer* observer) { 184 void BackgroundApplicationListModel::AddObserver(Observer* observer) {
176 observers_.AddObserver(observer); 185 observers_.AddObserver(observer);
177 } 186 }
178 187
179 void BackgroundApplicationListModel::AssociateApplicationData( 188 void BackgroundApplicationListModel::AssociateApplicationData(
180 const Extension* extension) { 189 const Extension* extension) {
181 DCHECK(IsBackgroundApp(*extension)); 190 DCHECK(IsBackgroundApp(*extension, profile_));
182 Application* application = FindApplication(extension); 191 Application* application = FindApplication(extension);
183 if (!application) { 192 if (!application) {
184 // App position is used as a dynamic command and so must be less than any 193 // App position is used as a dynamic command and so must be less than any
185 // predefined command id. 194 // predefined command id.
186 if (applications_.size() >= IDC_MinimumLabelValue) { 195 if (applications_.size() >= IDC_MinimumLabelValue) {
187 LOG(ERROR) << "Background application limit of " << IDC_MinimumLabelValue 196 LOG(ERROR) << "Background application limit of " << IDC_MinimumLabelValue
188 << " exceeded. Ignoring."; 197 << " exceeded. Ignoring.";
189 return; 198 return;
190 } 199 }
191 application = new Application(this, extension); 200 application = new Application(this, extension);
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
243 ++cursor, ++position) { 252 ++cursor, ++position) {
244 if (id == cursor->get()->id()) 253 if (id == cursor->get()->id())
245 return position; 254 return position;
246 } 255 }
247 NOTREACHED(); 256 NOTREACHED();
248 return -1; 257 return -1;
249 } 258 }
250 259
251 // static 260 // static
252 bool BackgroundApplicationListModel::IsBackgroundApp( 261 bool BackgroundApplicationListModel::IsBackgroundApp(
253 const Extension& extension) { 262 const Extension& extension, Profile* profile) {
254 return extension.HasAPIPermission(ExtensionAPIPermission::kBackground); 263 // An extension is a "background app" if it has the "background API"
264 // permission, and meets one of the following criteria:
265 // 1) It is an extension (not a hosted app).
266 // 2) It is a hosted app, and has a background contents registered or in the
267 // manifest.
268
269 // Not a background app if we don't have the background permission.
270 if (!extension.HasAPIPermission(ExtensionAPIPermission::kBackground))
271 return false;
272
273 // Extensions and packaged apps with background permission are always treated
274 // as background apps.
275 if (!extension.is_hosted_app())
276 return true;
277
278 // Hosted apps with manifest-provided background pages are background apps.
279 if (extension.has_background_page())
280 return true;
281
282 BackgroundContentsService* service =
283 BackgroundContentsServiceFactory::GetForProfile(profile);
284 string16 app_id = ASCIIToUTF16(extension.id());
285 // If we have an active or registered background contents for this app, then
286 // it's a background app. This covers the cases where the app has created its
287 // background contents, but it hasn't navigated yet, or the background
288 // contents crashed and hasn't yet been restarted - in both cases we still
289 // want to treat the app as a background app.
290 if (service->GetAppBackgroundContents(app_id) ||
291 service->HasRegisteredBackgroundContents(app_id)) {
292 return true;
293 }
294
295 // Doesn't meet our criteria, so it's not a background app.
296 return false;
255 } 297 }
256 298
257 void BackgroundApplicationListModel::Observe( 299 void BackgroundApplicationListModel::Observe(
258 int type, 300 int type,
259 const content::NotificationSource& source, 301 const content::NotificationSource& source,
260 const content::NotificationDetails& details) { 302 const content::NotificationDetails& details) {
261 if (type == chrome::NOTIFICATION_EXTENSIONS_READY) { 303 if (type == chrome::NOTIFICATION_EXTENSIONS_READY) {
262 Update(); 304 Update();
263 return; 305 return;
264 } 306 }
265 ExtensionService* service = profile_->GetExtensionService(); 307 ExtensionService* service = profile_->GetExtensionService();
266 if (!service || !service->is_ready()) 308 if (!service || !service->is_ready())
267 return; 309 return;
268 310
269 switch (type) { 311 switch (type) {
270 case chrome::NOTIFICATION_EXTENSION_LOADED: 312 case chrome::NOTIFICATION_EXTENSION_LOADED:
271 OnExtensionLoaded(content::Details<Extension>(details).ptr()); 313 OnExtensionLoaded(content::Details<Extension>(details).ptr());
272 break; 314 break;
273 case chrome::NOTIFICATION_EXTENSION_UNLOADED: 315 case chrome::NOTIFICATION_EXTENSION_UNLOADED:
274 OnExtensionUnloaded( 316 OnExtensionUnloaded(
275 content::Details<UnloadedExtensionInfo>(details)->extension); 317 content::Details<UnloadedExtensionInfo>(details)->extension);
276 break; 318 break;
277 case chrome::NOTIFICATION_EXTENSION_PERMISSIONS_UPDATED: 319 case chrome::NOTIFICATION_EXTENSION_PERMISSIONS_UPDATED:
278 OnExtensionPermissionsUpdated( 320 OnExtensionPermissionsUpdated(
279 content::Details<UpdatedExtensionPermissionsInfo>(details)->extension, 321 content::Details<UpdatedExtensionPermissionsInfo>(details)->extension,
280 content::Details<UpdatedExtensionPermissionsInfo>(details)->reason, 322 content::Details<UpdatedExtensionPermissionsInfo>(details)->reason,
281 content::Details<UpdatedExtensionPermissionsInfo>(details)-> 323 content::Details<UpdatedExtensionPermissionsInfo>(details)->
282 permissions); 324 permissions);
283 break; 325 break;
326 case chrome::NOTIFICATION_BACKGROUND_CONTENTS_SERVICE_CHANGED:
327 Update();
328 break;
284 default: 329 default:
285 NOTREACHED() << "Received unexpected notification"; 330 NOTREACHED() << "Received unexpected notification";
286 } 331 }
287 } 332 }
288 333
289 void BackgroundApplicationListModel::SendApplicationDataChangedNotifications( 334 void BackgroundApplicationListModel::SendApplicationDataChangedNotifications(
290 const Extension* extension) { 335 const Extension* extension) {
291 FOR_EACH_OBSERVER(Observer, observers_, OnApplicationDataChanged(extension, 336 FOR_EACH_OBSERVER(Observer, observers_, OnApplicationDataChanged(extension,
292 profile_)); 337 profile_));
293 } 338 }
294 339
295 void BackgroundApplicationListModel::OnExtensionLoaded( 340 void BackgroundApplicationListModel::OnExtensionLoaded(
296 const Extension* extension) { 341 const Extension* extension) {
297 // We only care about extensions that are background applications 342 // We only care about extensions that are background applications
298 if (!IsBackgroundApp(*extension)) 343 if (!IsBackgroundApp(*extension, profile_))
299 return; 344 return;
300 AssociateApplicationData(extension); 345 AssociateApplicationData(extension);
301 } 346 }
302 347
303 void BackgroundApplicationListModel::OnExtensionUnloaded( 348 void BackgroundApplicationListModel::OnExtensionUnloaded(
304 const Extension* extension) { 349 const Extension* extension) {
305 if (!IsBackgroundApp(*extension)) 350 if (!IsBackgroundApp(*extension, profile_))
306 return; 351 return;
307 Update(); 352 Update();
308 DissociateApplicationData(extension); 353 DissociateApplicationData(extension);
309 } 354 }
310 355
311 void BackgroundApplicationListModel::OnExtensionPermissionsUpdated( 356 void BackgroundApplicationListModel::OnExtensionPermissionsUpdated(
312 const Extension* extension, 357 const Extension* extension,
313 UpdatedExtensionPermissionsInfo::Reason reason, 358 UpdatedExtensionPermissionsInfo::Reason reason,
314 const ExtensionPermissionSet* permissions) { 359 const ExtensionPermissionSet* permissions) {
315 if (permissions->HasAPIPermission(ExtensionAPIPermission::kBackground)) { 360 if (permissions->HasAPIPermission(ExtensionAPIPermission::kBackground)) {
316 switch (reason) { 361 switch (reason) {
317 case UpdatedExtensionPermissionsInfo::ADDED: 362 case UpdatedExtensionPermissionsInfo::ADDED:
318 DCHECK(IsBackgroundApp(*extension)); 363 DCHECK(IsBackgroundApp(*extension, profile_));
319 OnExtensionLoaded(extension); 364 OnExtensionLoaded(extension);
320 break; 365 break;
321 case UpdatedExtensionPermissionsInfo::REMOVED: 366 case UpdatedExtensionPermissionsInfo::REMOVED:
322 DCHECK(!IsBackgroundApp(*extension)); 367 DCHECK(!IsBackgroundApp(*extension, profile_));
323 Update(); 368 Update();
324 DissociateApplicationData(extension); 369 DissociateApplicationData(extension);
325 break; 370 break;
326 default: 371 default:
327 NOTREACHED(); 372 NOTREACHED();
328 } 373 }
329 } 374 }
330 } 375 }
331 376
332 void BackgroundApplicationListModel::RemoveObserver(Observer* observer) { 377 void BackgroundApplicationListModel::RemoveObserver(Observer* observer) {
(...skipping 18 matching lines...) Expand all
351 (*old_cursor)->name() == (*new_cursor)->name() && 396 (*old_cursor)->name() == (*new_cursor)->name() &&
352 (*old_cursor)->id() == (*new_cursor)->id()) { 397 (*old_cursor)->id() == (*new_cursor)->id()) {
353 ++old_cursor; 398 ++old_cursor;
354 ++new_cursor; 399 ++new_cursor;
355 } 400 }
356 if (old_cursor != extensions_.end() || new_cursor != extensions.end()) { 401 if (old_cursor != extensions_.end() || new_cursor != extensions.end()) {
357 extensions_ = extensions; 402 extensions_ = extensions;
358 FOR_EACH_OBSERVER(Observer, observers_, OnApplicationListChanged(profile_)); 403 FOR_EACH_OBSERVER(Observer, observers_, OnApplicationListChanged(profile_));
359 } 404 }
360 } 405 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698