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