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