Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / extensions / renderer / user_script_set_manager.cc
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 #include "extensions/renderer/user_script_set_manager.h"
6
7 #include "components/crx_file/id_util.h"
8 #include "content/public/renderer/render_thread.h"
9 #include "extensions/common/extension_messages.h"
10 #include "extensions/renderer/dispatcher.h"
11 #include "extensions/renderer/script_injection.h"
12 #include "extensions/renderer/user_script_set.h"
13 #include "ipc/ipc_message.h"
14 #include "ipc/ipc_message_macros.h"
15 #include "third_party/WebKit/public/web/WebFrame.h"
16
17 namespace extensions {
18
19 UserScriptSetManager::UserScriptSetManager(const ExtensionSet* extensions)
20     : static_scripts_(extensions), extensions_(extensions) {
21   content::RenderThread::Get()->AddObserver(this);
22 }
23
24 UserScriptSetManager::~UserScriptSetManager() {
25 }
26
27 void UserScriptSetManager::AddObserver(Observer* observer) {
28   observers_.AddObserver(observer);
29 }
30
31 void UserScriptSetManager::RemoveObserver(Observer* observer) {
32   observers_.RemoveObserver(observer);
33 }
34
35 scoped_ptr<ScriptInjection>
36 UserScriptSetManager::GetInjectionForDeclarativeScript(
37     int script_id,
38     blink::WebFrame* web_frame,
39     int tab_id,
40     const GURL& url,
41     const Extension* extension) {
42   UserScriptSet* user_script_set =
43       GetProgrammaticScriptsByExtension(extension->id());
44   if (!user_script_set)
45     return scoped_ptr<ScriptInjection>();
46
47   return user_script_set->GetDeclarativeScriptInjection(
48       script_id,
49       web_frame,
50       tab_id,
51       UserScript::BROWSER_DRIVEN,
52       url,
53       extension);
54 }
55
56 bool UserScriptSetManager::OnControlMessageReceived(
57     const IPC::Message& message) {
58   bool handled = true;
59   IPC_BEGIN_MESSAGE_MAP(UserScriptSetManager, message)
60     IPC_MESSAGE_HANDLER(ExtensionMsg_UpdateUserScripts, OnUpdateUserScripts)
61     IPC_MESSAGE_UNHANDLED(handled = false)
62   IPC_END_MESSAGE_MAP()
63   return handled;
64 }
65
66 void UserScriptSetManager::GetAllInjections(
67     ScopedVector<ScriptInjection>* injections,
68     blink::WebFrame* web_frame,
69     int tab_id,
70     UserScript::RunLocation run_location) {
71   static_scripts_.GetInjections(injections, web_frame, tab_id, run_location);
72   for (UserScriptSetMap::iterator it = programmatic_scripts_.begin();
73        it != programmatic_scripts_.end();
74        ++it) {
75     it->second->GetInjections(injections, web_frame, tab_id, run_location);
76   }
77 }
78
79 void UserScriptSetManager::GetAllActiveExtensionIds(
80     std::set<std::string>* ids) const {
81   DCHECK(ids);
82   static_scripts_.GetActiveExtensionIds(ids);
83   for (UserScriptSetMap::const_iterator it = programmatic_scripts_.begin();
84        it != programmatic_scripts_.end();
85        ++it) {
86     it->second->GetActiveExtensionIds(ids);
87   }
88 }
89
90 UserScriptSet* UserScriptSetManager::GetProgrammaticScriptsByExtension(
91     const ExtensionId& extension_id) {
92   UserScriptSetMap::const_iterator it =
93       programmatic_scripts_.find(extension_id);
94   return it != programmatic_scripts_.end() ? it->second.get() : NULL;
95 }
96
97 void UserScriptSetManager::OnUpdateUserScripts(
98     base::SharedMemoryHandle shared_memory,
99     const ExtensionId& extension_id,
100     const std::set<std::string>& changed_extensions) {
101   if (!base::SharedMemory::IsHandleValid(shared_memory)) {
102     NOTREACHED() << "Bad scripts handle";
103     return;
104   }
105
106   for (std::set<std::string>::const_iterator iter = changed_extensions.begin();
107        iter != changed_extensions.end();
108        ++iter) {
109     if (!crx_file::id_util::IdIsValid(*iter)) {
110       NOTREACHED() << "Invalid extension id: " << *iter;
111       return;
112     }
113   }
114
115   UserScriptSet* scripts = NULL;
116   if (!extension_id.empty()) {
117     // The expectation when there is an extension that "owns" this shared
118     // memory region is that the |changed_extensions| is either the empty list
119     // or just the owner.
120     CHECK(changed_extensions.size() <= 1);
121     if (programmatic_scripts_.find(extension_id) ==
122         programmatic_scripts_.end()) {
123       scripts = new UserScriptSet(extensions_);
124       programmatic_scripts_[extension_id] = make_linked_ptr(scripts);
125     } else {
126       scripts = programmatic_scripts_[extension_id].get();
127     }
128   } else {
129     scripts = &static_scripts_;
130   }
131   DCHECK(scripts);
132
133   // If no extensions are included in the set, that indicates that all
134   // extensions were updated. Add them all to the set so that observers and
135   // individual UserScriptSets don't need to know this detail.
136   const std::set<std::string>* effective_extensions = &changed_extensions;
137   std::set<std::string> all_extensions;
138   if (changed_extensions.empty()) {
139     // The meaning of "all extensions" varies, depending on whether some
140     // extension "owns" this shared memory region.
141     // No owner => all known extensions.
142     // Owner    => just the owner extension.
143     if (extension_id.empty())
144       all_extensions = extensions_->GetIDs();
145     else
146       all_extensions.insert(extension_id);
147     effective_extensions = &all_extensions;
148   }
149
150   if (scripts->UpdateUserScripts(shared_memory, *effective_extensions)) {
151     FOR_EACH_OBSERVER(
152         Observer,
153         observers_,
154         OnUserScriptsUpdated(*effective_extensions, scripts->scripts()));
155   }
156 }
157
158 }  // namespace extensions