Home | History | Annotate | Download | only in browser
      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
      3 // found in the LICENSE file.
      4 
      5 #ifndef EXTENSIONS_BROWSER_LAZY_BACKGROUND_TASK_QUEUE_H_
      6 #define EXTENSIONS_BROWSER_LAZY_BACKGROUND_TASK_QUEUE_H_
      7 
      8 #include <map>
      9 #include <string>
     10 
     11 #include "base/callback_forward.h"
     12 #include "base/compiler_specific.h"
     13 #include "base/gtest_prod_util.h"
     14 #include "base/memory/linked_ptr.h"
     15 #include "content/public/browser/notification_observer.h"
     16 #include "content/public/browser/notification_registrar.h"
     17 
     18 namespace content {
     19 class BrowserContext;
     20 }
     21 
     22 namespace extensions {
     23 class Extension;
     24 class ExtensionHost;
     25 
     26 // This class maintains a queue of tasks that should execute when an
     27 // extension's lazy background page is loaded. It is also in charge of loading
     28 // the page when the first task is queued.
     29 //
     30 // It is the consumer's responsibility to use this class when appropriate, i.e.
     31 // only with extensions that have not-yet-loaded lazy background pages.
     32 class LazyBackgroundTaskQueue : public content::NotificationObserver {
     33  public:
     34   typedef base::Callback<void(ExtensionHost*)> PendingTask;
     35 
     36   explicit LazyBackgroundTaskQueue(content::BrowserContext* browser_context);
     37   virtual ~LazyBackgroundTaskQueue();
     38 
     39   // Returns the number of extensions having pending tasks.
     40   size_t extensions_with_pending_tasks() { return pending_tasks_.size(); }
     41 
     42   // Returns true if the task should be added to the queue (that is, if the
     43   // extension has a lazy background page that isn't ready yet). If the
     44   // extension has a lazy background page that is being suspended this method
     45   // cancels that suspension.
     46   bool ShouldEnqueueTask(content::BrowserContext* context,
     47                          const Extension* extension);
     48 
     49   // Adds a task to the queue for a given extension. If this is the first
     50   // task added for the extension, its lazy background page will be loaded.
     51   // The task will be called either when the page is loaded, or when the
     52   // page fails to load for some reason (e.g. a crash or browser
     53   // shutdown). In the latter case, the ExtensionHost parameter is NULL.
     54   void AddPendingTask(
     55       content::BrowserContext* context,
     56       const std::string& extension_id,
     57       const PendingTask& task);
     58 
     59  private:
     60   FRIEND_TEST_ALL_PREFIXES(LazyBackgroundTaskQueueTest, ProcessPendingTasks);
     61 
     62   // A map between a BrowserContext/extension_id pair and the queue of tasks
     63   // pending the load of its background page.
     64   typedef std::string ExtensionID;
     65   typedef std::pair<content::BrowserContext*, ExtensionID> PendingTasksKey;
     66   typedef std::vector<PendingTask> PendingTasksList;
     67   typedef std::map<PendingTasksKey,
     68                    linked_ptr<PendingTasksList> > PendingTasksMap;
     69 
     70   // content::NotificationObserver interface.
     71   virtual void Observe(int type,
     72                        const content::NotificationSource& source,
     73                        const content::NotificationDetails& details) OVERRIDE;
     74 
     75   // Called when a lazy background page has finished loading, or has failed to
     76   // load (host is NULL in that case). All enqueued tasks are run in order.
     77   void ProcessPendingTasks(
     78       ExtensionHost* host,
     79       content::BrowserContext* context,
     80       const Extension* extension);
     81 
     82   content::BrowserContext* browser_context_;
     83   content::NotificationRegistrar registrar_;
     84   PendingTasksMap pending_tasks_;
     85 };
     86 
     87 }  // namespace extensions
     88 
     89 #endif  // EXTENSIONS_BROWSER_LAZY_BACKGROUND_TASK_QUEUE_H_
     90