11e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 51e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#ifndef EXTENSIONS_BROWSER_LAZY_BACKGROUND_TASK_QUEUE_H_ 61e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#define EXTENSIONS_BROWSER_LAZY_BACKGROUND_TASK_QUEUE_H_ 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <map> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback_forward.h" 121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "base/compiler_specific.h" 131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "base/gtest_prod_util.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/linked_ptr.h" 15116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/scoped_observer.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_observer.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_registrar.h" 18116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "extensions/browser/extension_registry_observer.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)namespace content { 211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)class BrowserContext; 221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace extensions { 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Extension; 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ExtensionHost; 27116680a4aac90f2aa7413d9095a592090648e557Ben Murdochclass ExtensionRegistry; 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This class maintains a queue of tasks that should execute when an 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// extension's lazy background page is loaded. It is also in charge of loading 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the page when the first task is queued. 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// It is the consumer's responsibility to use this class when appropriate, i.e. 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// only with extensions that have not-yet-loaded lazy background pages. 35116680a4aac90f2aa7413d9095a592090648e557Ben Murdochclass LazyBackgroundTaskQueue : public content::NotificationObserver, 36116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch public ExtensionRegistryObserver { 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef base::Callback<void(ExtensionHost*)> PendingTask; 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) explicit LazyBackgroundTaskQueue(content::BrowserContext* browser_context); 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~LazyBackgroundTaskQueue(); 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Returns the number of extensions having pending tasks. 441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) size_t extensions_with_pending_tasks() { return pending_tasks_.size(); } 451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns true if the task should be added to the queue (that is, if the 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // extension has a lazy background page that isn't ready yet). If the 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // extension has a lazy background page that is being suspended this method 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // cancels that suspension. 501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) bool ShouldEnqueueTask(content::BrowserContext* context, 511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const Extension* extension); 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Adds a task to the queue for a given extension. If this is the first 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // task added for the extension, its lazy background page will be loaded. 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The task will be called either when the page is loaded, or when the 5658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // page fails to load for some reason (e.g. a crash or browser 5758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // shutdown). In the latter case, the ExtensionHost parameter is NULL. 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void AddPendingTask( 591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) content::BrowserContext* context, 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& extension_id, 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const PendingTask& task); 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(LazyBackgroundTaskQueueTest, ProcessPendingTasks); 651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // A map between a BrowserContext/extension_id pair and the queue of tasks 671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // pending the load of its background page. 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef std::string ExtensionID; 691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) typedef std::pair<content::BrowserContext*, ExtensionID> PendingTasksKey; 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef std::vector<PendingTask> PendingTasksList; 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef std::map<PendingTasksKey, 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) linked_ptr<PendingTasksList> > PendingTasksMap; 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // content::NotificationObserver interface. 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void Observe(int type, 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const content::NotificationSource& source, 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const content::NotificationDetails& details) OVERRIDE; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 79116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // ExtensionRegistryObserver interface. 80116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch virtual void OnExtensionUnloaded( 81116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch content::BrowserContext* browser_context, 82116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const Extension* extension, 83116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch UnloadedExtensionInfo::Reason reason) OVERRIDE; 84116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Called when a lazy background page has finished loading, or has failed to 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // load (host is NULL in that case). All enqueued tasks are run in order. 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ProcessPendingTasks( 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionHost* host, 891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) content::BrowserContext* context, 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Extension* extension); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 921e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) content::BrowserContext* browser_context_; 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::NotificationRegistrar registrar_; 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PendingTasksMap pending_tasks_; 95116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 96116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver> 97116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch extension_registry_observer_; 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace extensions 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1021e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#endif // EXTENSIONS_BROWSER_LAZY_BACKGROUND_TASK_QUEUE_H_ 103