Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(317)

Side by Side Diff: chrome/browser/extensions/user_script_loader.cc

Issue 899983002: Revert of Introduce HostID and de-couple Extensions from "script injection System" [browser side] (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/extensions/user_script_loader.h" 5 #include "chrome/browser/extensions/user_script_loader.h"
6 6
7 #include <set> 7 #include <set>
8 #include <string> 8 #include <string>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
11 #include "base/bind_helpers.h" 11 #include "base/bind_helpers.h"
12 #include "base/files/file_path.h" 12 #include "base/files/file_path.h"
13 #include "base/files/file_util.h" 13 #include "base/files/file_util.h"
14 #include "base/memory/shared_memory.h"
14 #include "base/version.h" 15 #include "base/version.h"
15 #include "chrome/browser/chrome_notification_types.h" 16 #include "chrome/browser/chrome_notification_types.h"
16 #include "chrome/browser/profiles/profile.h" 17 #include "chrome/browser/profiles/profile.h"
17 #include "content/public/browser/browser_thread.h" 18 #include "content/public/browser/browser_thread.h"
18 #include "content/public/browser/notification_service.h" 19 #include "content/public/browser/notification_service.h"
19 #include "content/public/browser/render_process_host.h" 20 #include "content/public/browser/render_process_host.h"
21 #include "extensions/browser/component_extension_resource_manager.h"
20 #include "extensions/browser/content_verifier.h" 22 #include "extensions/browser/content_verifier.h"
23 #include "extensions/browser/extension_registry.h"
24 #include "extensions/browser/extension_system.h"
25 #include "extensions/browser/extensions_browser_client.h"
21 #include "extensions/common/extension_messages.h" 26 #include "extensions/common/extension_messages.h"
22 #include "extensions/common/file_util.h" 27 #include "extensions/common/file_util.h"
28 #include "extensions/common/manifest_handlers/default_locale_handler.h"
29 #include "extensions/common/message_bundle.h"
30 #include "extensions/common/one_shot_event.h"
31 #include "ui/base/resource/resource_bundle.h"
23 32
24 using content::BrowserThread; 33 using content::BrowserThread;
34 using extensions::ExtensionsBrowserClient;
25 35
26 namespace extensions { 36 namespace extensions {
27 37
28 namespace { 38 namespace {
29 39
30 using LoadScriptsCallback = 40 typedef base::Callback<
31 base::Callback<void(scoped_ptr<UserScriptList>, 41 void(scoped_ptr<UserScriptList>, scoped_ptr<base::SharedMemory>)>
32 scoped_ptr<base::SharedMemory>)>; 42 LoadScriptsCallback;
33 43
34 UserScriptLoader::SubstitutionMap* GetLocalizationMessages( 44 void VerifyContent(scoped_refptr<ContentVerifier> verifier,
35 const UserScriptLoader::HostsInfo& hosts_info, 45 const ExtensionId& extension_id,
36 const HostID& host_id) { 46 const base::FilePath& extension_root,
37 UserScriptLoader::HostsInfo::const_iterator iter = hosts_info.find(host_id); 47 const base::FilePath& relative_path,
38 if (iter == hosts_info.end()) 48 const std::string& content) {
39 return nullptr; 49 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
40 return file_util::LoadMessageBundleSubstitutionMap( 50 scoped_refptr<ContentVerifyJob> job(
41 iter->second.first, host_id.id(), iter->second.second); 51 verifier->CreateJobFor(extension_id, extension_root, relative_path));
52 if (job.get()) {
53 job->Start();
54 job->BytesRead(content.size(), content.data());
55 job->DoneReading();
56 }
42 } 57 }
43 58
44 void LoadUserScripts( 59 bool LoadScriptContent(const ExtensionId& extension_id,
45 UserScriptList* user_scripts, 60 UserScript::File* script_file,
46 const UserScriptLoader::HostsInfo& hosts_info, 61 const SubstitutionMap* localization_messages,
47 const std::set<int>& added_script_ids, 62 scoped_refptr<ContentVerifier> verifier) {
48 const scoped_refptr<ContentVerifier>& verifier, 63 std::string content;
49 UserScriptLoader::LoadUserScriptsContentFunction callback) { 64 const base::FilePath& path = ExtensionResource::GetFilePath(
65 script_file->extension_root(),
66 script_file->relative_path(),
67 ExtensionResource::SYMLINKS_MUST_RESOLVE_WITHIN_ROOT);
68 if (path.empty()) {
69 int resource_id;
70 if (ExtensionsBrowserClient::Get()->GetComponentExtensionResourceManager()->
71 IsComponentExtensionResource(script_file->extension_root(),
72 script_file->relative_path(),
73 &resource_id)) {
74 const ResourceBundle& rb = ResourceBundle::GetSharedInstance();
75 content = rb.GetRawDataResource(resource_id).as_string();
76 } else {
77 LOG(WARNING) << "Failed to get file path to "
78 << script_file->relative_path().value() << " from "
79 << script_file->extension_root().value();
80 return false;
81 }
82 } else {
83 if (!base::ReadFileToString(path, &content)) {
84 LOG(WARNING) << "Failed to load user script file: " << path.value();
85 return false;
86 }
87 if (verifier.get()) {
88 content::BrowserThread::PostTask(content::BrowserThread::IO,
89 FROM_HERE,
90 base::Bind(&VerifyContent,
91 verifier,
92 extension_id,
93 script_file->extension_root(),
94 script_file->relative_path(),
95 content));
96 }
97 }
98
99 // Localize the content.
100 if (localization_messages) {
101 std::string error;
102 MessageBundle::ReplaceMessagesWithExternalDictionary(
103 *localization_messages, &content, &error);
104 if (!error.empty()) {
105 LOG(WARNING) << "Failed to replace messages in script: " << error;
106 }
107 }
108
109 // Remove BOM from the content.
110 std::string::size_type index = content.find(base::kUtf8ByteOrderMark);
111 if (index == 0) {
112 script_file->set_content(content.substr(strlen(base::kUtf8ByteOrderMark)));
113 } else {
114 script_file->set_content(content);
115 }
116
117 return true;
118 }
119
120 SubstitutionMap* GetLocalizationMessages(const ExtensionsInfo& extensions_info,
121 const ExtensionId& extension_id) {
122 ExtensionsInfo::const_iterator iter = extensions_info.find(extension_id);
123 if (iter == extensions_info.end())
124 return NULL;
125 return file_util::LoadMessageBundleSubstitutionMap(
126 iter->second.first, extension_id, iter->second.second);
127 }
128
129 void LoadUserScripts(UserScriptList* user_scripts,
130 const ExtensionsInfo& extensions_info,
131 const std::set<int>& added_script_ids,
132 ContentVerifier* verifier) {
50 for (UserScriptList::iterator script = user_scripts->begin(); 133 for (UserScriptList::iterator script = user_scripts->begin();
51 script != user_scripts->end(); 134 script != user_scripts->end();
52 ++script) { 135 ++script) {
53 if (added_script_ids.count(script->id()) == 0) 136 if (added_script_ids.count(script->id()) == 0)
54 continue; 137 continue;
55 scoped_ptr<UserScriptLoader::SubstitutionMap> localization_messages( 138 scoped_ptr<SubstitutionMap> localization_messages(
56 GetLocalizationMessages(hosts_info, script->host_id())); 139 GetLocalizationMessages(extensions_info, script->extension_id()));
57 for (size_t k = 0; k < script->js_scripts().size(); ++k) { 140 for (size_t k = 0; k < script->js_scripts().size(); ++k) {
58 UserScript::File& script_file = script->js_scripts()[k]; 141 UserScript::File& script_file = script->js_scripts()[k];
59 if (script_file.GetContent().empty()) 142 if (script_file.GetContent().empty())
60 callback.Run(script->host_id(), &script_file, NULL, verifier); 143 LoadScriptContent(script->extension_id(), &script_file, NULL, verifier);
61 } 144 }
62 for (size_t k = 0; k < script->css_scripts().size(); ++k) { 145 for (size_t k = 0; k < script->css_scripts().size(); ++k) {
63 UserScript::File& script_file = script->css_scripts()[k]; 146 UserScript::File& script_file = script->css_scripts()[k];
64 if (script_file.GetContent().empty()) 147 if (script_file.GetContent().empty())
65 callback.Run(script->host_id(), &script_file, 148 LoadScriptContent(script->extension_id(),
66 localization_messages.get(), verifier); 149 &script_file,
150 localization_messages.get(),
151 verifier);
67 } 152 }
68 } 153 }
69 } 154 }
70 155
71 // Pickle user scripts and return pointer to the shared memory. 156 // Pickle user scripts and return pointer to the shared memory.
72 scoped_ptr<base::SharedMemory> Serialize(const UserScriptList& scripts) { 157 scoped_ptr<base::SharedMemory> Serialize(const UserScriptList& scripts) {
73 Pickle pickle; 158 Pickle pickle;
74 pickle.WriteSizeT(scripts.size()); 159 pickle.WriteSizeT(scripts.size());
75 for (UserScriptList::const_iterator script = scripts.begin(); 160 for (UserScriptList::const_iterator script = scripts.begin();
76 script != scripts.end(); 161 script != scripts.end();
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
108 193
109 base::SharedMemoryHandle readonly_handle; 194 base::SharedMemoryHandle readonly_handle;
110 if (!shared_memory.ShareReadOnlyToProcess(base::GetCurrentProcessHandle(), 195 if (!shared_memory.ShareReadOnlyToProcess(base::GetCurrentProcessHandle(),
111 &readonly_handle)) 196 &readonly_handle))
112 return scoped_ptr<base::SharedMemory>(); 197 return scoped_ptr<base::SharedMemory>();
113 198
114 return make_scoped_ptr(new base::SharedMemory(readonly_handle, 199 return make_scoped_ptr(new base::SharedMemory(readonly_handle,
115 /*read_only=*/true)); 200 /*read_only=*/true));
116 } 201 }
117 202
118 void LoadScriptsOnFileThread( 203 void LoadScriptsOnFileThread(scoped_ptr<UserScriptList> user_scripts,
119 scoped_ptr<UserScriptList> user_scripts, 204 const ExtensionsInfo& extensions_info,
120 const UserScriptLoader::HostsInfo& hosts_info, 205 const std::set<int>& added_script_ids,
121 const std::set<int>& added_script_ids, 206 scoped_refptr<ContentVerifier> verifier,
122 const scoped_refptr<ContentVerifier>& verifier, 207 LoadScriptsCallback callback) {
123 UserScriptLoader::LoadUserScriptsContentFunction function,
124 LoadScriptsCallback callback) {
125 DCHECK(user_scripts.get()); 208 DCHECK(user_scripts.get());
126 LoadUserScripts(user_scripts.get(), hosts_info, added_script_ids, 209 LoadUserScripts(
127 verifier, function); 210 user_scripts.get(), extensions_info, added_script_ids, verifier.get());
128 scoped_ptr<base::SharedMemory> memory = Serialize(*user_scripts); 211 scoped_ptr<base::SharedMemory> memory = Serialize(*user_scripts);
129 BrowserThread::PostTask( 212 BrowserThread::PostTask(
130 BrowserThread::UI, 213 BrowserThread::UI,
131 FROM_HERE, 214 FROM_HERE,
132 base::Bind(callback, base::Passed(&user_scripts), base::Passed(&memory))); 215 base::Bind(callback, base::Passed(&user_scripts), base::Passed(&memory)));
133 } 216 }
134 217
135 // Helper function to parse greasesmonkey headers 218 // Helper function to parse greasesmonkey headers
136 bool GetDeclarationValue(const base::StringPiece& line, 219 bool GetDeclarationValue(const base::StringPiece& line,
137 const base::StringPiece& prefix, 220 const base::StringPiece& prefix,
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
240 } 323 }
241 324
242 // If no patterns were specified, default to @include *. This is what 325 // If no patterns were specified, default to @include *. This is what
243 // Greasemonkey does. 326 // Greasemonkey does.
244 if (script->globs().empty() && script->url_patterns().is_empty()) 327 if (script->globs().empty() && script->url_patterns().is_empty())
245 script->add_glob("*"); 328 script->add_glob("*");
246 329
247 return true; 330 return true;
248 } 331 }
249 332
333 // static
250 void UserScriptLoader::LoadScriptsForTest(UserScriptList* user_scripts) { 334 void UserScriptLoader::LoadScriptsForTest(UserScriptList* user_scripts) {
251 HostsInfo info; 335 ExtensionsInfo info;
252 std::set<int> added_script_ids; 336 std::set<int> added_script_ids;
253 for (UserScriptList::iterator it = user_scripts->begin(); 337 for (UserScriptList::iterator it = user_scripts->begin();
254 it != user_scripts->end(); 338 it != user_scripts->end();
255 ++it) { 339 ++it) {
256 added_script_ids.insert(it->id()); 340 added_script_ids.insert(it->id());
257 } 341 }
258 LoadUserScripts(user_scripts, info, added_script_ids, 342 LoadUserScripts(
259 NULL /* no verifier for testing */, 343 user_scripts, info, added_script_ids, NULL /* no verifier for testing */);
260 GetLoadUserScriptsFunction());
261 } 344 }
262 345
263 UserScriptLoader::UserScriptLoader( 346 UserScriptLoader::UserScriptLoader(Profile* profile,
264 Profile* profile, 347 const ExtensionId& owner_extension_id,
265 const HostID& host_id, 348 bool listen_for_extension_system_loaded)
266 const scoped_refptr<ContentVerifier>& content_verifier)
267 : user_scripts_(new UserScriptList()), 349 : user_scripts_(new UserScriptList()),
268 clear_scripts_(false), 350 clear_scripts_(false),
269 ready_(false), 351 extension_system_ready_(false),
270 pending_load_(false), 352 pending_load_(false),
271 profile_(profile), 353 profile_(profile),
272 host_id_(host_id), 354 owner_extension_id_(owner_extension_id),
273 content_verifier_(content_verifier), 355 extension_registry_observer_(this),
274 weak_factory_(this) { 356 weak_factory_(this) {
357 extension_registry_observer_.Add(ExtensionRegistry::Get(profile));
358 if (listen_for_extension_system_loaded) {
359 ExtensionSystem::Get(profile_)->ready().Post(
360 FROM_HERE,
361 base::Bind(&UserScriptLoader::OnExtensionSystemReady,
362 weak_factory_.GetWeakPtr()));
363 } else {
364 extension_system_ready_ = true;
365 }
275 registrar_.Add(this, 366 registrar_.Add(this,
276 content::NOTIFICATION_RENDERER_PROCESS_CREATED, 367 content::NOTIFICATION_RENDERER_PROCESS_CREATED,
277 content::NotificationService::AllBrowserContextsAndSources()); 368 content::NotificationService::AllBrowserContextsAndSources());
278 } 369 }
279 370
280 UserScriptLoader::~UserScriptLoader() { 371 UserScriptLoader::~UserScriptLoader() {
281 } 372 }
282 373
283 void UserScriptLoader::AddScripts(const std::set<UserScript>& scripts) { 374 void UserScriptLoader::AddScripts(const std::set<UserScript>& scripts) {
284 for (std::set<UserScript>::const_iterator it = scripts.begin(); 375 for (std::set<UserScript>::const_iterator it = scripts.begin();
(...skipping 25 matching lines...) Expand all
310 void UserScriptLoader::Observe(int type, 401 void UserScriptLoader::Observe(int type,
311 const content::NotificationSource& source, 402 const content::NotificationSource& source,
312 const content::NotificationDetails& details) { 403 const content::NotificationDetails& details) {
313 DCHECK_EQ(type, content::NOTIFICATION_RENDERER_PROCESS_CREATED); 404 DCHECK_EQ(type, content::NOTIFICATION_RENDERER_PROCESS_CREATED);
314 content::RenderProcessHost* process = 405 content::RenderProcessHost* process =
315 content::Source<content::RenderProcessHost>(source).ptr(); 406 content::Source<content::RenderProcessHost>(source).ptr();
316 Profile* profile = Profile::FromBrowserContext(process->GetBrowserContext()); 407 Profile* profile = Profile::FromBrowserContext(process->GetBrowserContext());
317 if (!profile_->IsSameProfile(profile)) 408 if (!profile_->IsSameProfile(profile))
318 return; 409 return;
319 if (scripts_ready()) { 410 if (scripts_ready()) {
320 SendUpdate(process, shared_memory_.get(), 411 SendUpdate(process,
321 std::set<HostID>()); // Include all hosts. 412 shared_memory_.get(),
413 std::set<ExtensionId>()); // Include all extensions.
322 } 414 }
323 } 415 }
324 416
417 void UserScriptLoader::OnExtensionUnloaded(
418 content::BrowserContext* browser_context,
419 const Extension* extension,
420 UnloadedExtensionInfo::Reason reason) {
421 extensions_info_.erase(extension->id());
422 }
423
424 void UserScriptLoader::OnExtensionSystemReady() {
425 extension_system_ready_ = true;
426 AttemptLoad();
427 }
428
325 bool UserScriptLoader::ScriptsMayHaveChanged() const { 429 bool UserScriptLoader::ScriptsMayHaveChanged() const {
326 // Scripts may have changed if there are scripts added, scripts removed, or 430 // Scripts may have changed if there are scripts added, scripts removed, or
327 // if scripts were cleared and either: 431 // if scripts were cleared and either:
328 // (1) A load is in progress (which may result in a non-zero number of 432 // (1) A load is in progress (which may result in a non-zero number of
329 // scripts that need to be cleared), or 433 // scripts that need to be cleared), or
330 // (2) The current set of scripts is non-empty (so they need to be cleared). 434 // (2) The current set of scripts is non-empty (so they need to be cleared).
331 return (added_scripts_.size() || 435 return (added_scripts_.size() ||
332 removed_scripts_.size() || 436 removed_scripts_.size() ||
333 (clear_scripts_ && 437 (clear_scripts_ &&
334 (is_loading() || user_scripts_->size()))); 438 (is_loading() || user_scripts_->size())));
335 } 439 }
336 440
337 void UserScriptLoader::AttemptLoad() { 441 void UserScriptLoader::AttemptLoad() {
338 if (ready_ && ScriptsMayHaveChanged()) { 442 if (extension_system_ready_ && ScriptsMayHaveChanged()) {
339 if (is_loading()) 443 if (is_loading())
340 pending_load_ = true; 444 pending_load_ = true;
341 else 445 else
342 StartLoad(); 446 StartLoad();
343 } 447 }
344 } 448 }
345 449
346 void UserScriptLoader::StartLoad() { 450 void UserScriptLoader::StartLoad() {
347 DCHECK_CURRENTLY_ON(BrowserThread::UI); 451 DCHECK_CURRENTLY_ON(BrowserThread::UI);
348 DCHECK(!is_loading()); 452 DCHECK(!is_loading());
(...skipping 15 matching lines...) Expand all
364 user_scripts_->insert( 468 user_scripts_->insert(
365 user_scripts_->end(), added_scripts_.begin(), added_scripts_.end()); 469 user_scripts_->end(), added_scripts_.begin(), added_scripts_.end());
366 470
367 std::set<int> added_script_ids; 471 std::set<int> added_script_ids;
368 for (std::set<UserScript>::const_iterator it = added_scripts_.begin(); 472 for (std::set<UserScript>::const_iterator it = added_scripts_.begin();
369 it != added_scripts_.end(); 473 it != added_scripts_.end();
370 ++it) { 474 ++it) {
371 added_script_ids.insert(it->id()); 475 added_script_ids.insert(it->id());
372 } 476 }
373 477
374 // Expand |changed_hosts_| for OnScriptsLoaded, which will use it in 478 // Expand |changed_extensions_| for OnScriptsLoaded, which will use it in
375 // its IPC message. This must be done before we clear |added_scripts_| and 479 // its IPC message. This must be done before we clear |added_scripts_| and
376 // |removed_scripts_| below. 480 // |removed_scripts_| below.
377 std::set<UserScript> changed_scripts(added_scripts_); 481 std::set<UserScript> changed_scripts(added_scripts_);
378 changed_scripts.insert(removed_scripts_.begin(), removed_scripts_.end()); 482 changed_scripts.insert(removed_scripts_.begin(), removed_scripts_.end());
379 for (const UserScript& script : changed_scripts) 483 ExpandChangedExtensions(changed_scripts);
380 changed_hosts_.insert(script.host_id());
381 484
382 // |changed_hosts_| before passing it to LoadScriptsOnFileThread. 485 // Update |extensions_info_| to contain info from every extension in
383 UpdateHostsInfo(changed_hosts_); 486 // |changed_extensions_| before passing it to LoadScriptsOnFileThread.
487 UpdateExtensionsInfo();
384 488
385 BrowserThread::PostTask( 489 BrowserThread::PostTask(
386 BrowserThread::FILE, FROM_HERE, 490 BrowserThread::FILE,
387 base::Bind(&LoadScriptsOnFileThread, base::Passed(&user_scripts_), 491 FROM_HERE,
388 hosts_info_, added_script_ids, content_verifier_, 492 base::Bind(&LoadScriptsOnFileThread,
389 GetLoadUserScriptsFunction(), 493 base::Passed(&user_scripts_),
494 extensions_info_,
495 added_script_ids,
496 make_scoped_refptr(
497 ExtensionSystem::Get(profile_)->content_verifier()),
390 base::Bind(&UserScriptLoader::OnScriptsLoaded, 498 base::Bind(&UserScriptLoader::OnScriptsLoaded,
391 weak_factory_.GetWeakPtr()))); 499 weak_factory_.GetWeakPtr())));
392 500
393 clear_scripts_ = false; 501 clear_scripts_ = false;
394 added_scripts_.clear(); 502 added_scripts_.clear();
395 removed_scripts_.clear(); 503 removed_scripts_.clear();
396 user_scripts_.reset(NULL); 504 user_scripts_.reset(NULL);
397 } 505 }
398 506
399 void UserScriptLoader::AddHostInfo(const HostID& host_id,
400 const PathAndDefaultLocale& location) {
401 if (hosts_info_.find(host_id) != hosts_info_.end())
402 return;
403 hosts_info_[host_id] = location;
404 }
405
406 void UserScriptLoader::RemoveHostInfo(const HostID& host_id) {
407 hosts_info_.erase(host_id);
408 }
409
410 void UserScriptLoader::SetReady(bool ready) {
411 bool was_ready = ready_;
412 ready_ = ready;
413 if (ready_ && !was_ready)
414 AttemptLoad();
415 }
416
417 void UserScriptLoader::OnScriptsLoaded( 507 void UserScriptLoader::OnScriptsLoaded(
418 scoped_ptr<UserScriptList> user_scripts, 508 scoped_ptr<UserScriptList> user_scripts,
419 scoped_ptr<base::SharedMemory> shared_memory) { 509 scoped_ptr<base::SharedMemory> shared_memory) {
420 user_scripts_.reset(user_scripts.release()); 510 user_scripts_.reset(user_scripts.release());
421 if (pending_load_) { 511 if (pending_load_) {
422 // While we were loading, there were further changes. Don't bother 512 // While we were loading, there were further changes. Don't bother
423 // notifying about these scripts and instead just immediately reload. 513 // notifying about these scripts and instead just immediately reload.
424 pending_load_ = false; 514 pending_load_ = false;
425 StartLoad(); 515 StartLoad();
426 return; 516 return;
(...skipping 11 matching lines...) Expand all
438 return; 528 return;
439 } 529 }
440 530
441 // We've got scripts ready to go. 531 // We've got scripts ready to go.
442 shared_memory_.reset(shared_memory.release()); 532 shared_memory_.reset(shared_memory.release());
443 533
444 for (content::RenderProcessHost::iterator i( 534 for (content::RenderProcessHost::iterator i(
445 content::RenderProcessHost::AllHostsIterator()); 535 content::RenderProcessHost::AllHostsIterator());
446 !i.IsAtEnd(); 536 !i.IsAtEnd();
447 i.Advance()) { 537 i.Advance()) {
448 SendUpdate(i.GetCurrentValue(), shared_memory_.get(), changed_hosts_); 538 SendUpdate(i.GetCurrentValue(), shared_memory_.get(), changed_extensions_);
449 } 539 }
450 changed_hosts_.clear(); 540 changed_extensions_.clear();
451 541
452 content::NotificationService::current()->Notify( 542 content::NotificationService::current()->Notify(
453 extensions::NOTIFICATION_USER_SCRIPTS_UPDATED, 543 extensions::NOTIFICATION_USER_SCRIPTS_UPDATED,
454 content::Source<Profile>(profile_), 544 content::Source<Profile>(profile_),
455 content::Details<base::SharedMemory>(shared_memory_.get())); 545 content::Details<base::SharedMemory>(shared_memory_.get()));
456 } 546 }
457 547
458 void UserScriptLoader::SendUpdate(content::RenderProcessHost* process, 548 void UserScriptLoader::SendUpdate(
459 base::SharedMemory* shared_memory, 549 content::RenderProcessHost* process,
460 const std::set<HostID>& changed_hosts) { 550 base::SharedMemory* shared_memory,
551 const std::set<ExtensionId>& changed_extensions) {
461 // Don't allow injection of content scripts into <webview>. 552 // Don't allow injection of content scripts into <webview>.
462 if (process->IsIsolatedGuest()) 553 if (process->IsIsolatedGuest())
463 return; 554 return;
464 555
465 Profile* profile = Profile::FromBrowserContext(process->GetBrowserContext()); 556 Profile* profile = Profile::FromBrowserContext(process->GetBrowserContext());
466 // Make sure we only send user scripts to processes in our profile. 557 // Make sure we only send user scripts to processes in our profile.
467 if (!profile_->IsSameProfile(profile)) 558 if (!profile_->IsSameProfile(profile))
468 return; 559 return;
469 560
470 // If the process is being started asynchronously, early return. We'll end up 561 // If the process is being started asynchronously, early return. We'll end up
471 // calling InitUserScripts when it's created which will call this again. 562 // calling InitUserScripts when it's created which will call this again.
472 base::ProcessHandle handle = process->GetHandle(); 563 base::ProcessHandle handle = process->GetHandle();
473 if (!handle) 564 if (!handle)
474 return; 565 return;
475 566
476 base::SharedMemoryHandle handle_for_process; 567 base::SharedMemoryHandle handle_for_process;
477 if (!shared_memory->ShareToProcess(handle, &handle_for_process)) 568 if (!shared_memory->ShareToProcess(handle, &handle_for_process))
478 return; // This can legitimately fail if the renderer asserts at startup. 569 return; // This can legitimately fail if the renderer asserts at startup.
479 570
480 // TODO(hanxi): update the IPC message to send a set of HostIDs to render.
481 // Also, remove this function when the refactor is done on render side.
482 std::set<std::string> changed_ids_set;
483 for (const HostID& id : changed_hosts)
484 changed_ids_set.insert(id.id());
485
486 if (base::SharedMemory::IsHandleValid(handle_for_process)) { 571 if (base::SharedMemory::IsHandleValid(handle_for_process)) {
487 process->Send(new ExtensionMsg_UpdateUserScripts( 572 process->Send(new ExtensionMsg_UpdateUserScripts(
488 handle_for_process, host_id().id(), changed_ids_set)); 573 handle_for_process, owner_extension_id_, changed_extensions));
489 } 574 }
490 } 575 }
491 576
577 void UserScriptLoader::ExpandChangedExtensions(
578 const std::set<UserScript>& scripts) {
579 for (std::set<UserScript>::const_iterator it = scripts.begin();
580 it != scripts.end();
581 ++it) {
582 changed_extensions_.insert(it->extension_id());
583 }
584 }
585
586 void UserScriptLoader::UpdateExtensionsInfo() {
587 ExtensionRegistry* registry = ExtensionRegistry::Get(profile_);
588 for (std::set<ExtensionId>::const_iterator it = changed_extensions_.begin();
589 it != changed_extensions_.end();
590 ++it) {
591 if (extensions_info_.find(*it) == extensions_info_.end()) {
592 const Extension* extension =
593 registry->GetExtensionById(*it, ExtensionRegistry::EVERYTHING);
594 // |changed_extensions_| may include extensions that have been removed,
595 // which leads to the above lookup failing. In this case, just continue.
596 if (!extension)
597 continue;
598 extensions_info_[*it] = ExtensionSet::ExtensionPathAndDefaultLocale(
599 extension->path(), LocaleInfo::GetDefaultLocale(extension));
600 }
601 }
602 }
603
492 } // namespace extensions 604 } // namespace extensions
OLDNEW
« no previous file with comments | « chrome/browser/extensions/user_script_loader.h ('k') | chrome/browser/extensions/user_script_loader_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698