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/user_script_set.h"
12 #include "ipc/ipc_message.h"
13 #include "ipc/ipc_message_macros.h"
14 #include "third_party/WebKit/public/web/WebFrame.h"
16 namespace extensions
{
18 UserScriptSetManager::UserScriptSetManager(const ExtensionSet
* extensions
)
19 : static_scripts_(extensions
), extensions_(extensions
) {
20 content::RenderThread::Get()->AddObserver(this);
23 UserScriptSetManager::~UserScriptSetManager() {
26 void UserScriptSetManager::AddObserver(Observer
* observer
) {
27 observers_
.AddObserver(observer
);
30 void UserScriptSetManager::RemoveObserver(Observer
* observer
) {
31 observers_
.RemoveObserver(observer
);
34 bool UserScriptSetManager::OnControlMessageReceived(
35 const IPC::Message
& message
) {
37 IPC_BEGIN_MESSAGE_MAP(UserScriptSetManager
, message
)
38 IPC_MESSAGE_HANDLER(ExtensionMsg_UpdateUserScripts
, OnUpdateUserScripts
)
39 IPC_MESSAGE_UNHANDLED(handled
= false)
44 const UserScriptSet
* UserScriptSetManager::GetProgrammaticScriptsByExtension(
45 const ExtensionId
& extension_id
) {
46 UserScriptSetMap::const_iterator it
=
47 programmatic_scripts_
.find(extension_id
);
48 return it
!= programmatic_scripts_
.end() ? it
->second
.get() : NULL
;
51 void UserScriptSetManager::GetAllInjections(
52 ScopedVector
<ScriptInjection
>* injections
,
53 blink::WebFrame
* web_frame
,
55 UserScript::RunLocation run_location
) {
56 static_scripts_
.GetInjections(injections
, web_frame
, tab_id
, run_location
);
57 for (UserScriptSetMap::iterator it
= programmatic_scripts_
.begin();
58 it
!= programmatic_scripts_
.end();
60 it
->second
->GetInjections(injections
, web_frame
, tab_id
, run_location
);
64 void UserScriptSetManager::GetAllActiveExtensionIds(
65 std::set
<std::string
>* ids
) const {
67 static_scripts_
.GetActiveExtensionIds(ids
);
68 for (UserScriptSetMap::const_iterator it
= programmatic_scripts_
.begin();
69 it
!= programmatic_scripts_
.end();
71 it
->second
->GetActiveExtensionIds(ids
);
75 void UserScriptSetManager::OnUpdateUserScripts(
76 base::SharedMemoryHandle shared_memory
,
77 const ExtensionId
& extension_id
,
78 const std::set
<std::string
>& changed_extensions
) {
79 if (!base::SharedMemory::IsHandleValid(shared_memory
)) {
80 NOTREACHED() << "Bad scripts handle";
84 for (std::set
<std::string
>::const_iterator iter
= changed_extensions
.begin();
85 iter
!= changed_extensions
.end();
87 if (!crx_file::id_util::IdIsValid(*iter
)) {
88 NOTREACHED() << "Invalid extension id: " << *iter
;
93 UserScriptSet
* scripts
= NULL
;
94 if (!extension_id
.empty()) {
95 // The expectation when there is an extensions that "owns" this shared
96 // memory region is that it will list itself as the only changed extension.
97 CHECK(changed_extensions
.size() == 1 &&
98 changed_extensions
.find(extension_id
) != changed_extensions
.end());
99 if (programmatic_scripts_
.find(extension_id
) ==
100 programmatic_scripts_
.end()) {
101 scripts
= new UserScriptSet(extensions_
);
102 programmatic_scripts_
[extension_id
] = make_linked_ptr(scripts
);
104 scripts
= programmatic_scripts_
[extension_id
].get();
107 scripts
= &static_scripts_
;
111 // If no extensions are included in the set, that indicates that all
112 // extensions were updated. Add them all to the set so that observers and
113 // individual UserScriptSets don't need to know this detail.
114 const std::set
<std::string
>* effective_extensions
= &changed_extensions
;
115 std::set
<std::string
> all_extensions
;
116 if (changed_extensions
.empty()) {
117 all_extensions
= extensions_
->GetIDs();
118 effective_extensions
= &all_extensions
;
121 if (scripts
->UpdateUserScripts(shared_memory
, *effective_extensions
)) {
125 OnUserScriptsUpdated(*effective_extensions
, scripts
->scripts()));
129 } // namespace extensions