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 "content/public/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 content::ResourceType 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, 61 content::ResourceType resource_type); 62 void StartDelayedRequests(); 63 64 // Update user_scripts_ready_ based on the status of all profiles. On a 65 // transition from false to true, we resume all delayed requests. 66 void CheckIfAllUserScriptsReady(); 67 68 // Resume any requests that we delayed in order to wait for user scripts. 69 void UserScriptsReady(void* profile_id); 70 71 // Clean up per-profile information related to the given profile. 72 void ProfileDestroyed(void* profile_id); 73 74 // Appends new url patterns to our list, also setting user_scripts_ready_ 75 // to false. 76 void AppendNewURLPatterns(void* profile_id, const URLPatterns& new_patterns); 77 78 // Replaces our url pattern list. This is only used when patterns have been 79 // deleted, so user_scripts_ready_ remains unchanged. 80 void ReplaceURLPatterns(void* profile_id, const URLPatterns& patterns); 81 82 // True if all user scripts from all profiles are ready. 83 bool user_scripts_ready_; 84 85 // Stores a throttle per URL request that we have delayed. 86 class Throttle; 87 typedef base::WeakPtr<Throttle> WeakThrottle; 88 typedef std::deque<WeakThrottle> WeakThrottleList; 89 WeakThrottleList throttles_; 90 91 // Per-profile bookkeeping so we know when all user scripts are ready. 92 struct ProfileData; 93 typedef std::map<void*, ProfileData> ProfileDataMap; 94 ProfileDataMap profile_data_; 95 96 // --- UI thread: 97 98 // Helper to collect the extension's user script URL patterns in a list and 99 // return it. 100 void CollectURLPatterns(const Extension* extension, 101 URLPatterns* patterns); 102 103 // content::NotificationObserver 104 virtual void Observe(int type, 105 const content::NotificationSource& source, 106 const content::NotificationDetails& details) OVERRIDE; 107 108 content::NotificationRegistrar registrar_; 109 110 DISALLOW_COPY_AND_ASSIGN(UserScriptListener); 111 }; 112 113 } // namespace extensions 114 115 #endif // CHROME_BROWSER_EXTENSIONS_USER_SCRIPT_LISTENER_H_ 116