Home | History | Annotate | Download | only in extensions
      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
      3 // found in the LICENSE file.
      4 
      5 #ifndef CHROME_BROWSER_EXTENSIONS_USER_SCRIPT_LISTENER_H_
      6 #define CHROME_BROWSER_EXTENSIONS_USER_SCRIPT_LISTENER_H_
      7 
      8 #include <deque>
      9 #include <list>
     10 #include <map>
     11 
     12 #include "base/compiler_specific.h"
     13 #include "base/memory/ref_counted.h"
     14 #include "base/memory/weak_ptr.h"
     15 #include "content/public/browser/browser_thread.h"
     16 #include "content/public/browser/notification_observer.h"
     17 #include "content/public/browser/notification_registrar.h"
     18 #include "webkit/common/resource_type.h"
     19 
     20 class GURL;
     21 class URLPattern;
     22 
     23 namespace content {
     24 class ResourceThrottle;
     25 }
     26 
     27 namespace extensions {
     28 class Extension;
     29 
     30 // This class handles delaying of resource loads that depend on unloaded user
     31 // scripts. For each request that comes in, we check if it depends on a user
     32 // script, and if so, whether that user script is ready; if not, we delay the
     33 // request.
     34 //
     35 // This class lives mostly on the IO thread. It listens on the UI thread for
     36 // updates to loaded extensions.
     37 class UserScriptListener
     38     : public base::RefCountedThreadSafe<
     39           UserScriptListener,
     40           content::BrowserThread::DeleteOnUIThread>,
     41       public content::NotificationObserver {
     42  public:
     43   UserScriptListener();
     44 
     45   // Constructs a ResourceThrottle if the UserScriptListener needs to delay the
     46   // given URL.  Otherwise, this method returns NULL.
     47   content::ResourceThrottle* CreateResourceThrottle(
     48       const GURL& url,
     49       ResourceType::Type resource_type);
     50 
     51  private:
     52   friend struct content::BrowserThread::DeleteOnThread<
     53       content::BrowserThread::UI>;
     54   friend class base::DeleteHelper<UserScriptListener>;
     55 
     56   typedef std::list<URLPattern> URLPatterns;
     57 
     58   virtual ~UserScriptListener();
     59 
     60   bool ShouldDelayRequest(const GURL& url, ResourceType::Type resource_type);
     61   void StartDelayedRequests();
     62 
     63   // Update user_scripts_ready_ based on the status of all profiles. On a
     64   // transition from false to true, we resume all delayed requests.
     65   void CheckIfAllUserScriptsReady();
     66 
     67   // Resume any requests that we delayed in order to wait for user scripts.
     68   void UserScriptsReady(void* profile_id);
     69 
     70   // Clean up per-profile information related to the given profile.
     71   void ProfileDestroyed(void* profile_id);
     72 
     73   // Appends new url patterns to our list, also setting user_scripts_ready_
     74   // to false.
     75   void AppendNewURLPatterns(void* profile_id, const URLPatterns& new_patterns);
     76 
     77   // Replaces our url pattern list. This is only used when patterns have been
     78   // deleted, so user_scripts_ready_ remains unchanged.
     79   void ReplaceURLPatterns(void* profile_id, const URLPatterns& patterns);
     80 
     81   // True if all user scripts from all profiles are ready.
     82   bool user_scripts_ready_;
     83 
     84   // Stores a throttle per URL request that we have delayed.
     85   class Throttle;
     86   typedef base::WeakPtr<Throttle> WeakThrottle;
     87   typedef std::deque<WeakThrottle> WeakThrottleList;
     88   WeakThrottleList throttles_;
     89 
     90   // Per-profile bookkeeping so we know when all user scripts are ready.
     91   struct ProfileData;
     92   typedef std::map<void*, ProfileData> ProfileDataMap;
     93   ProfileDataMap profile_data_;
     94 
     95   // --- UI thread:
     96 
     97   // Helper to collect the extension's user script URL patterns in a list and
     98   // return it.
     99   void CollectURLPatterns(const Extension* extension,
    100                           URLPatterns* patterns);
    101 
    102   // content::NotificationObserver
    103   virtual void Observe(int type,
    104                        const content::NotificationSource& source,
    105                        const content::NotificationDetails& details) OVERRIDE;
    106 
    107   content::NotificationRegistrar registrar_;
    108 
    109   DISALLOW_COPY_AND_ASSIGN(UserScriptListener);
    110 };
    111 
    112 }  // namespace extensions
    113 
    114 #endif  // CHROME_BROWSER_EXTENSIONS_USER_SCRIPT_LISTENER_H_
    115