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.
5 #include "extensions/renderer/user_script_set_manager.h"
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"
16 namespace extensions
{
18 UserScriptSetManager::UserScriptSetManager() {
19 content::RenderThread::Get()->AddObserver(this);
22 UserScriptSetManager::~UserScriptSetManager() {
25 void UserScriptSetManager::AddObserver(Observer
* observer
) {
26 observers_
.AddObserver(observer
);
29 void UserScriptSetManager::RemoveObserver(Observer
* observer
) {
30 observers_
.RemoveObserver(observer
);
33 scoped_ptr
<ScriptInjection
>
34 UserScriptSetManager::GetInjectionForDeclarativeScript(
36 content::RenderFrame
* render_frame
,
39 const std::string
& extension_id
) {
40 UserScriptSet
* user_script_set
=
41 GetProgrammaticScriptsByHostID(HostID(HostID::EXTENSIONS
, extension_id
));
43 return scoped_ptr
<ScriptInjection
>();
45 return user_script_set
->GetDeclarativeScriptInjection(
49 UserScript::BROWSER_DRIVEN
,
53 bool UserScriptSetManager::OnControlMessageReceived(
54 const IPC::Message
& message
) {
56 IPC_BEGIN_MESSAGE_MAP(UserScriptSetManager
, message
)
57 IPC_MESSAGE_HANDLER(ExtensionMsg_UpdateUserScripts
, OnUpdateUserScripts
)
58 IPC_MESSAGE_UNHANDLED(handled
= false)
63 void UserScriptSetManager::GetAllInjections(
64 ScopedVector
<ScriptInjection
>* injections
,
65 content::RenderFrame
* render_frame
,
67 UserScript::RunLocation run_location
) {
68 static_scripts_
.GetInjections(injections
, render_frame
, tab_id
, run_location
);
69 for (UserScriptSetMap::iterator it
= programmatic_scripts_
.begin();
70 it
!= programmatic_scripts_
.end();
72 it
->second
->GetInjections(injections
, render_frame
, tab_id
, run_location
);
76 void UserScriptSetManager::GetAllActiveExtensionIds(
77 std::set
<std::string
>* ids
) const {
79 static_scripts_
.GetActiveExtensionIds(ids
);
80 for (UserScriptSetMap::const_iterator it
= programmatic_scripts_
.begin();
81 it
!= programmatic_scripts_
.end();
83 it
->second
->GetActiveExtensionIds(ids
);
87 UserScriptSet
* UserScriptSetManager::GetProgrammaticScriptsByHostID(
88 const HostID
& host_id
) {
89 UserScriptSetMap::const_iterator it
= programmatic_scripts_
.find(host_id
);
90 return it
!= programmatic_scripts_
.end() ? it
->second
.get() : NULL
;
93 void UserScriptSetManager::OnUpdateUserScripts(
94 base::SharedMemoryHandle shared_memory
,
95 const HostID
& host_id
,
96 const std::set
<HostID
>& changed_hosts
,
97 bool whitelisted_only
) {
98 if (!base::SharedMemory::IsHandleValid(shared_memory
)) {
99 NOTREACHED() << "Bad scripts handle";
103 for (const HostID
& host_id
: changed_hosts
) {
104 if (host_id
.type() == HostID::EXTENSIONS
&&
105 !crx_file::id_util::IdIsValid(host_id
.id())) {
106 NOTREACHED() << "Invalid extension id: " << host_id
.id();
111 UserScriptSet
* scripts
= NULL
;
112 if (!host_id
.id().empty()) {
113 // The expectation when there is a host that "owns" this shared
114 // memory region is that the |changed_hosts| is either the empty list
115 // or just the owner.
116 CHECK(changed_hosts
.size() <= 1);
117 if (programmatic_scripts_
.find(host_id
) == programmatic_scripts_
.end()) {
118 scripts
= new UserScriptSet();
119 programmatic_scripts_
[host_id
] = make_linked_ptr(scripts
);
121 scripts
= programmatic_scripts_
[host_id
].get();
124 scripts
= &static_scripts_
;
128 // If no hosts are included in the set, that indicates that all
129 // hosts were updated. Add them all to the set so that observers and
130 // individual UserScriptSets don't need to know this detail.
131 const std::set
<HostID
>* effective_hosts
= &changed_hosts
;
132 std::set
<HostID
> all_hosts
;
133 if (changed_hosts
.empty()) {
134 // The meaning of "all hosts(extensions)" varies, depending on whether some
135 // host "owns" this shared memory region.
136 // No owner => all known hosts.
137 // Owner => just the owner host.
138 if (host_id
.id().empty()) {
139 std::set
<std::string
> extension_ids
=
140 RendererExtensionRegistry::Get()->GetIDs();
141 for (const std::string
& extension_id
: extension_ids
)
142 all_hosts
.insert(HostID(HostID::EXTENSIONS
, extension_id
));
144 all_hosts
.insert(host_id
);
146 effective_hosts
= &all_hosts
;
149 if (scripts
->UpdateUserScripts(shared_memory
,
155 OnUserScriptsUpdated(*effective_hosts
, scripts
->scripts()));
159 } // namespace extensions