Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / extensions / user_script_loader.h
1 // Copyright 2014 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_LOADER_H_
6 #define CHROME_BROWSER_EXTENSIONS_USER_SCRIPT_LOADER_H_
7
8 #include <map>
9 #include <set>
10
11 #include "base/compiler_specific.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "base/memory/weak_ptr.h"
14 #include "base/scoped_observer.h"
15 #include "content/public/browser/notification_observer.h"
16 #include "content/public/browser/notification_registrar.h"
17 #include "extensions/browser/extension_registry_observer.h"
18 #include "extensions/common/extension.h"
19 #include "extensions/common/extension_set.h"
20 #include "extensions/common/user_script.h"
21
22 namespace base {
23 class SharedMemory;
24 }
25
26 namespace content {
27 class BrowserContext;
28 class RenderProcessHost;
29 }
30
31 class Profile;
32
33 namespace extensions {
34
35 class ContentVerifier;
36 class ExtensionRegistry;
37
38 typedef std::map<ExtensionId, ExtensionSet::ExtensionPathAndDefaultLocale>
39     ExtensionsInfo;
40
41 // Manages one "logical unit" of user scripts in shared memory by constructing a
42 // new shared memory region when the set of scripts changes. Also notifies
43 // renderers of new shared memory region when new renderers appear, or when
44 // script reloading completes. Script loading lives on the UI thread. Instances
45 // of this class are embedded within classes with names ending in
46 // UserScriptMaster. These "master" classes implement the strategy for which
47 // scripts to load/unload on this logical unit of scripts.
48 class UserScriptLoader : public content::NotificationObserver,
49                          public ExtensionRegistryObserver {
50  public:
51   // Parses the includes out of |script| and returns them in |includes|.
52   static bool ParseMetadataHeader(const base::StringPiece& script_text,
53                                   UserScript* script);
54
55   // A wrapper around the method to load user scripts, which is normally run on
56   // the file thread. Exposed only for tests.
57   static void LoadScriptsForTest(UserScriptList* user_scripts);
58
59   UserScriptLoader(Profile* profile,
60                    const ExtensionId& owner_extension_id,
61                    bool listen_for_extension_system_loaded);
62   ~UserScriptLoader() override;
63
64   // Add |scripts| to the set of scripts managed by this loader.
65   void AddScripts(const std::set<UserScript>& scripts);
66
67   // Remove |scripts| from the set of scripts managed by this loader.
68   void RemoveScripts(const std::set<UserScript>& scripts);
69
70   // Clears the set of scripts managed by this loader.
71   void ClearScripts();
72
73   // Initiates procedure to start loading scripts on the file thread.
74   void StartLoad();
75
76   // Return true if we have any scripts ready.
77   bool scripts_ready() const { return shared_memory_.get() != NULL; }
78
79  private:
80   // content::NotificationObserver implementation.
81   void Observe(int type,
82                const content::NotificationSource& source,
83                const content::NotificationDetails& details) override;
84
85   // ExtensionRegistryObserver implementation.
86   void OnExtensionUnloaded(content::BrowserContext* browser_context,
87                            const Extension* extension,
88                            UnloadedExtensionInfo::Reason reason) override;
89
90   // Initiates script load when we have been waiting for the extension system
91   // to be ready.
92   void OnExtensionSystemReady();
93
94   // Returns whether or not it is possible that calls to AddScripts(),
95   // RemoveScripts(), and/or ClearScripts() have caused any real change in the
96   // set of scripts to be loaded.
97   bool ScriptsMayHaveChanged() const;
98
99   // Attempt to initiate a load.
100   void AttemptLoad();
101
102   // Called once we have finished loading the scripts on the file thread.
103   void OnScriptsLoaded(scoped_ptr<UserScriptList> user_scripts,
104                        scoped_ptr<base::SharedMemory> shared_memory);
105
106   // Sends the renderer process a new set of user scripts. If
107   // |changed_extensions| is not empty, this signals that only the scripts from
108   // those extensions should be updated. Otherwise, all extensions will be
109   // updated.
110   void SendUpdate(content::RenderProcessHost* process,
111                   base::SharedMemory* shared_memory,
112                   const std::set<ExtensionId>& changed_extensions);
113
114   // Add to |changed_extensions_| those extensions referred to by |scripts|.
115   void ExpandChangedExtensions(const std::set<UserScript>& scripts);
116
117   // Update |extensions_info_| to contain info for each element of
118   // |changed_extensions_|.
119   void UpdateExtensionsInfo();
120
121   bool is_loading() const {
122     // Ownership of |user_scripts_| is passed to the file thread when loading.
123     return user_scripts_.get() == NULL;
124   }
125
126   // Manages our notification registrations.
127   content::NotificationRegistrar registrar_;
128
129   // Contains the scripts that were found the last time scripts were updated.
130   scoped_ptr<base::SharedMemory> shared_memory_;
131
132   // List of scripts from currently-installed extensions we should load.
133   scoped_ptr<UserScriptList> user_scripts_;
134
135   // Maps extension info needed for localization to an extension ID.
136   ExtensionsInfo extensions_info_;
137
138   // The mutually-exclusive sets of scripts that were added or removed since the
139   // last script load.
140   std::set<UserScript> added_scripts_;
141   std::set<UserScript> removed_scripts_;
142
143   // Indicates whether the the collection of scripts should be cleared before
144   // additions and removals on the next script load.
145   bool clear_scripts_;
146
147   // The IDs of the extensions which changed in the last update sent to the
148   // renderer.
149   ExtensionIdSet changed_extensions_;
150
151   // If the extensions service has finished loading its initial set of
152   // extensions.
153   bool extension_system_ready_;
154
155   // If list of user scripts is modified while we're loading it, we note
156   // that we're currently mid-load and then start over again once the load
157   // finishes.  This boolean tracks whether another load is pending.
158   bool pending_load_;
159
160   // Whether or not we are currently loading.
161   bool is_loading_;
162
163   // The profile for which the scripts managed here are installed.
164   Profile* profile_;
165
166   // ID of the extension that owns these scripts, if any. This is only set to a
167   // non-empty value for declarative user script shared memory regions.
168   ExtensionId owner_extension_id_;
169
170   ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver>
171       extension_registry_observer_;
172
173   base::WeakPtrFactory<UserScriptLoader> weak_factory_;
174
175   DISALLOW_COPY_AND_ASSIGN(UserScriptLoader);
176 };
177
178 }  // namespace extensions
179
180 #endif  // CHROME_BROWSER_EXTENSIONS_USER_SCRIPT_LOADER_H_