Home | History | Annotate | Download | only in extensions
      1 // Copyright (c) 2011 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 #pragma once
      8 
      9 #include <list>
     10 
     11 #include "base/memory/ref_counted.h"
     12 #include "content/browser/renderer_host/resource_queue.h"
     13 #include "content/common/notification_observer.h"
     14 #include "content/common/notification_registrar.h"
     15 
     16 namespace net {
     17 class URLRequest;
     18 }  // namespace net
     19 
     20 class Extension;
     21 class URLPattern;
     22 struct GlobalRequestID;
     23 
     24 // This class handles delaying of resource loads that depend on unloaded user
     25 // scripts. For each request that comes in, we check if it depends on a user
     26 // script, and if so, whether that user script is ready; if not, we delay the
     27 // request.
     28 //
     29 // This class lives mostly on the IO thread. It listens on the UI thread for
     30 // updates to loaded extensions.  It will delete itself on the UI thread after
     31 // WillShutdownResourceQueue is called (on the IO thread).
     32 class UserScriptListener
     33     : public base::RefCountedThreadSafe<UserScriptListener>,
     34       public ResourceQueueDelegate,
     35       public NotificationObserver {
     36  public:
     37   UserScriptListener();
     38 
     39   // ResourceQueueDelegate:
     40   virtual void Initialize(ResourceQueue* resource_queue);
     41   virtual bool ShouldDelayRequest(
     42       net::URLRequest* request,
     43       const ResourceDispatcherHostRequestInfo& request_info,
     44       const GlobalRequestID& request_id);
     45   virtual void WillShutdownResourceQueue();
     46 
     47  private:
     48   friend class base::RefCountedThreadSafe<UserScriptListener>;
     49 
     50   typedef std::list<URLPattern> URLPatterns;
     51 
     52   ~UserScriptListener();
     53 
     54   // Resume any requests that we delayed in order to wait for user scripts.
     55   void StartDelayedRequests();
     56 
     57   // Appends new url patterns to our list, also setting user_scripts_ready_
     58   // to false.
     59   void AppendNewURLPatterns(const URLPatterns& new_patterns);
     60 
     61   // Replaces our url pattern list. This is only used when patterns have been
     62   // deleted, so user_scripts_ready_ remains unchanged.
     63   void ReplaceURLPatterns(const URLPatterns& patterns);
     64 
     65   // Cleanup on UI thread.
     66   void Cleanup();
     67 
     68   ResourceQueue* resource_queue_;
     69 
     70   // A list of every request that we delayed. Will be flushed when user scripts
     71   // are ready.
     72   typedef std::list<GlobalRequestID> DelayedRequests;
     73   DelayedRequests delayed_request_ids_;
     74 
     75   // TODO(mpcomplete): the rest of this stuff should really be per-profile, but
     76   // the complexity doesn't seem worth it at this point.
     77 
     78   // True if the user scripts contained in |url_patterns_| are ready for
     79   // injection.
     80   bool user_scripts_ready_;
     81 
     82   // A list of URL patterns that have will have user scripts applied to them.
     83   URLPatterns url_patterns_;
     84 
     85   // --- UI thread:
     86 
     87   // Helper to collect the extension's user script URL patterns in a list and
     88   // return it.
     89   void CollectURLPatterns(const Extension* extension, URLPatterns* patterns);
     90 
     91   // NotificationObserver
     92   virtual void Observe(NotificationType type,
     93                        const NotificationSource& source,
     94                        const NotificationDetails& details);
     95 
     96   NotificationRegistrar registrar_;
     97 
     98   DISALLOW_COPY_AND_ASSIGN(UserScriptListener);
     99 };
    100 
    101 #endif  // CHROME_BROWSER_EXTENSIONS_USER_SCRIPT_LISTENER_H_
    102