OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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_master.h" | 5 #include "chrome/browser/extensions/user_script_master.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/bind_helpers.h" | 10 #include "base/bind_helpers.h" |
11 #include "base/file_util.h" | 11 #include "base/file_util.h" |
12 #include "base/files/file_path.h" | 12 #include "base/files/file_path.h" |
13 #include "base/memory/shared_memory.h" | 13 #include "base/memory/shared_memory.h" |
14 #include "base/version.h" | 14 #include "base/version.h" |
15 #include "chrome/browser/chrome_notification_types.h" | 15 #include "chrome/browser/chrome_notification_types.h" |
16 #include "chrome/browser/extensions/extension_util.h" | 16 #include "chrome/browser/extensions/extension_util.h" |
17 #include "chrome/browser/profiles/profile.h" | 17 #include "chrome/browser/profiles/profile.h" |
18 #include "chrome/common/extensions/api/i18n/default_locale_handler.h" | |
19 #include "chrome/common/extensions/manifest_handlers/content_scripts_handler.h" | 18 #include "chrome/common/extensions/manifest_handlers/content_scripts_handler.h" |
20 #include "content/public/browser/notification_service.h" | 19 #include "content/public/browser/notification_service.h" |
21 #include "content/public/browser/render_process_host.h" | 20 #include "content/public/browser/render_process_host.h" |
22 #include "extensions/browser/component_extension_resource_manager.h" | 21 #include "extensions/browser/component_extension_resource_manager.h" |
23 #include "extensions/browser/content_verifier.h" | 22 #include "extensions/browser/content_verifier.h" |
24 #include "extensions/browser/extension_registry.h" | 23 #include "extensions/browser/extension_registry.h" |
25 #include "extensions/browser/extension_system.h" | 24 #include "extensions/browser/extension_system.h" |
26 #include "extensions/browser/extensions_browser_client.h" | 25 #include "extensions/browser/extensions_browser_client.h" |
27 #include "extensions/common/file_util.h" | 26 #include "extensions/common/file_util.h" |
28 #include "extensions/common/message_bundle.h" | 27 #include "extensions/common/message_bundle.h" |
29 #include "ui/base/resource/resource_bundle.h" | 28 #include "ui/base/resource/resource_bundle.h" |
30 | 29 |
31 using content::BrowserThread; | 30 using content::BrowserThread; |
32 using extensions::ExtensionsBrowserClient; | 31 using extensions::ExtensionsBrowserClient; |
33 | 32 |
34 namespace extensions { | 33 namespace extensions { |
35 | 34 |
36 namespace { | 35 namespace { |
37 | 36 |
38 typedef base::Callback<void(scoped_ptr<UserScriptList>, | 37 typedef base::Callback<void(scoped_ptr<UserScriptList>, |
39 scoped_ptr<base::SharedMemory>)> | 38 scoped_ptr<base::SharedMemory>)> |
40 LoadScriptsCallback; | 39 LoadScriptsCallback; |
41 | 40 |
42 void VerifyContent(scoped_refptr<ContentVerifier> verifier, | 41 void VerifyContent(scoped_refptr<ContentVerifier> verifier, |
43 const std::string& extension_id, | 42 const ExtensionId& extension_id, |
44 const base::FilePath& extension_root, | 43 const base::FilePath& extension_root, |
45 const base::FilePath& relative_path, | 44 const base::FilePath& relative_path, |
46 const std::string& content) { | 45 const std::string& content) { |
47 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); | 46 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
48 scoped_refptr<ContentVerifyJob> job( | 47 scoped_refptr<ContentVerifyJob> job( |
49 verifier->CreateJobFor(extension_id, extension_root, relative_path)); | 48 verifier->CreateJobFor(extension_id, extension_root, relative_path)); |
50 if (job.get()) { | 49 if (job.get()) { |
51 job->Start(); | 50 job->Start(); |
52 job->BytesRead(content.size(), content.data()); | 51 job->BytesRead(content.size(), content.data()); |
53 job->DoneReading(); | 52 job->DoneReading(); |
54 } | 53 } |
55 } | 54 } |
56 | 55 |
57 bool LoadScriptContent(const std::string& extension_id, | 56 bool LoadScriptContent(const ExtensionId& extension_id, |
58 UserScript::File* script_file, | 57 UserScript::File* script_file, |
59 const SubstitutionMap* localization_messages, | 58 const SubstitutionMap* localization_messages, |
60 scoped_refptr<ContentVerifier> verifier) { | 59 scoped_refptr<ContentVerifier> verifier) { |
61 std::string content; | 60 std::string content; |
62 const base::FilePath& path = ExtensionResource::GetFilePath( | 61 const base::FilePath& path = ExtensionResource::GetFilePath( |
63 script_file->extension_root(), script_file->relative_path(), | 62 script_file->extension_root(), script_file->relative_path(), |
64 ExtensionResource::SYMLINKS_MUST_RESOLVE_WITHIN_ROOT); | 63 ExtensionResource::SYMLINKS_MUST_RESOLVE_WITHIN_ROOT); |
65 if (path.empty()) { | 64 if (path.empty()) { |
66 int resource_id; | 65 int resource_id; |
67 if (ExtensionsBrowserClient::Get()->GetComponentExtensionResourceManager()-> | 66 if (ExtensionsBrowserClient::Get()->GetComponentExtensionResourceManager()-> |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
108 if (index == 0) { | 107 if (index == 0) { |
109 script_file->set_content(content.substr(strlen(base::kUtf8ByteOrderMark))); | 108 script_file->set_content(content.substr(strlen(base::kUtf8ByteOrderMark))); |
110 } else { | 109 } else { |
111 script_file->set_content(content); | 110 script_file->set_content(content); |
112 } | 111 } |
113 | 112 |
114 return true; | 113 return true; |
115 } | 114 } |
116 | 115 |
117 SubstitutionMap* GetLocalizationMessages(const ExtensionsInfo& extensions_info, | 116 SubstitutionMap* GetLocalizationMessages(const ExtensionsInfo& extensions_info, |
118 const std::string& extension_id) { | 117 const ExtensionId& extension_id) { |
119 ExtensionsInfo::const_iterator iter = extensions_info.find(extension_id); | 118 ExtensionsInfo::const_iterator iter = extensions_info.find(extension_id); |
120 if (iter == extensions_info.end()) | 119 if (iter == extensions_info.end()) |
121 return NULL; | 120 return NULL; |
122 return file_util::LoadMessageBundleSubstitutionMap(iter->second.first, | 121 return file_util::LoadMessageBundleSubstitutionMap(iter->second.first, |
123 extension_id, | 122 extension_id, |
124 iter->second.second); | 123 iter->second.second); |
125 } | 124 } |
126 | 125 |
127 void LoadUserScripts(UserScriptList* user_scripts, | 126 void LoadUserScripts(UserScriptList* user_scripts, |
128 const ExtensionsInfo& extensions_info, | 127 const ExtensionsInfo& extensions_info, |
129 const std::set<std::string>& new_extensions, | 128 const std::set<ExtensionId>& new_extensions, |
130 ContentVerifier* verifier) { | 129 ContentVerifier* verifier) { |
131 for (size_t i = 0; i < user_scripts->size(); ++i) { | 130 for (size_t i = 0; i < user_scripts->size(); ++i) { |
132 UserScript& script = user_scripts->at(i); | 131 UserScript& script = user_scripts->at(i); |
133 if (new_extensions.count(script.extension_id()) == 0) | 132 if (new_extensions.count(script.extension_id()) == 0) |
134 continue; | 133 continue; |
135 scoped_ptr<SubstitutionMap> localization_messages( | 134 scoped_ptr<SubstitutionMap> localization_messages( |
136 GetLocalizationMessages(extensions_info, script.extension_id())); | 135 GetLocalizationMessages(extensions_info, script.extension_id())); |
137 for (size_t k = 0; k < script.js_scripts().size(); ++k) { | 136 for (size_t k = 0; k < script.js_scripts().size(); ++k) { |
138 UserScript::File& script_file = script.js_scripts()[k]; | 137 UserScript::File& script_file = script.js_scripts()[k]; |
139 if (script_file.GetContent().empty()) | 138 if (script_file.GetContent().empty()) |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
192 if (!shared_memory.ShareReadOnlyToProcess(base::GetCurrentProcessHandle(), | 191 if (!shared_memory.ShareReadOnlyToProcess(base::GetCurrentProcessHandle(), |
193 &readonly_handle)) | 192 &readonly_handle)) |
194 return scoped_ptr<base::SharedMemory>(); | 193 return scoped_ptr<base::SharedMemory>(); |
195 | 194 |
196 return make_scoped_ptr(new base::SharedMemory(readonly_handle, | 195 return make_scoped_ptr(new base::SharedMemory(readonly_handle, |
197 /*read_only=*/true)); | 196 /*read_only=*/true)); |
198 } | 197 } |
199 | 198 |
200 void LoadScriptsOnFileThread(scoped_ptr<UserScriptList> user_scripts, | 199 void LoadScriptsOnFileThread(scoped_ptr<UserScriptList> user_scripts, |
201 const ExtensionsInfo& extensions_info, | 200 const ExtensionsInfo& extensions_info, |
202 const std::set<std::string>& new_extensions, | 201 const std::set<ExtensionId>& new_extensions, |
203 scoped_refptr<ContentVerifier> verifier, | 202 scoped_refptr<ContentVerifier> verifier, |
204 LoadScriptsCallback callback) { | 203 LoadScriptsCallback callback) { |
205 DCHECK(user_scripts.get()); | 204 DCHECK(user_scripts.get()); |
206 LoadUserScripts( | 205 LoadUserScripts( |
207 user_scripts.get(), extensions_info, new_extensions, verifier); | 206 user_scripts.get(), extensions_info, new_extensions, verifier); |
208 scoped_ptr<base::SharedMemory> memory = Serialize(*user_scripts); | 207 scoped_ptr<base::SharedMemory> memory = Serialize(*user_scripts); |
209 BrowserThread::PostTask( | 208 BrowserThread::PostTask( |
210 BrowserThread::UI, | 209 BrowserThread::UI, |
211 FROM_HERE, | 210 FROM_HERE, |
212 base::Bind(callback, | 211 base::Bind(callback, |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
325 // Greasemonkey does. | 324 // Greasemonkey does. |
326 if (script->globs().empty() && script->url_patterns().is_empty()) | 325 if (script->globs().empty() && script->url_patterns().is_empty()) |
327 script->add_glob("*"); | 326 script->add_glob("*"); |
328 | 327 |
329 return true; | 328 return true; |
330 } | 329 } |
331 | 330 |
332 // static | 331 // static |
333 void UserScriptMaster::LoadScriptsForTest(UserScriptList* user_scripts) { | 332 void UserScriptMaster::LoadScriptsForTest(UserScriptList* user_scripts) { |
334 ExtensionsInfo info; | 333 ExtensionsInfo info; |
335 std::set<std::string> new_extensions; | 334 std::set<ExtensionId> new_extensions; |
336 for (UserScriptList::const_iterator iter = user_scripts->begin(); | 335 for (UserScriptList::const_iterator iter = user_scripts->begin(); |
337 iter != user_scripts->end(); | 336 iter != user_scripts->end(); |
338 ++iter) { | 337 ++iter) { |
339 new_extensions.insert(iter->extension_id()); | 338 new_extensions.insert(iter->extension_id()); |
340 } | 339 } |
341 LoadUserScripts( | 340 LoadUserScripts( |
342 user_scripts, info, new_extensions, NULL /* no verifier for testing */); | 341 user_scripts, info, new_extensions, NULL /* no verifier for testing */); |
343 } | 342 } |
344 | 343 |
345 UserScriptMaster::UserScriptMaster(Profile* profile) | 344 UserScriptMaster::UserScriptMaster(Profile* profile, |
346 : user_scripts_(new UserScriptList()), | 345 ExtensionId owner_extension_id) |
347 extensions_service_ready_(false), | 346 : pending_load_(false), |
348 pending_load_(false), | |
349 profile_(profile), | 347 profile_(profile), |
350 extension_registry_observer_(this), | 348 weak_factory_(this), |
351 weak_factory_(this) { | 349 owner_extension_id_(owner_extension_id) { |
352 extension_registry_observer_.Add(ExtensionRegistry::Get(profile_)); | 350 registrar_.Add(this, |
353 registrar_.Add(this, chrome::NOTIFICATION_EXTENSIONS_READY, | 351 content::NOTIFICATION_RENDERER_PROCESS_CREATED, |
354 content::Source<Profile>(profile_)); | |
355 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CREATED, | |
356 content::NotificationService::AllBrowserContextsAndSources()); | 352 content::NotificationService::AllBrowserContextsAndSources()); |
357 } | 353 } |
358 | 354 |
359 UserScriptMaster::~UserScriptMaster() { | 355 UserScriptMaster::~UserScriptMaster() { |
360 } | 356 } |
361 | 357 |
358 void UserScriptMaster::Observe(int type, | |
359 const content::NotificationSource& source, | |
360 const content::NotificationDetails& details) { | |
361 DCHECK_EQ(content::NOTIFICATION_RENDERER_PROCESS_CREATED, type); | |
362 content::RenderProcessHost* process = | |
363 content::Source<content::RenderProcessHost>(source).ptr(); | |
364 Profile* profile = Profile::FromBrowserContext(process->GetBrowserContext()); | |
365 if (!profile_->IsSameProfile(profile)) | |
366 return; | |
367 if (ScriptsReady()) | |
368 SendUpdate(process, GetSharedMemory(), GetAllManagedExtensions()); | |
369 } | |
370 | |
362 void UserScriptMaster::OnScriptsLoaded( | 371 void UserScriptMaster::OnScriptsLoaded( |
363 scoped_ptr<UserScriptList> user_scripts, | 372 scoped_ptr<UserScriptList> user_scripts, |
364 scoped_ptr<base::SharedMemory> shared_memory) { | 373 scoped_ptr<base::SharedMemory> shared_memory) { |
365 user_scripts_.reset(user_scripts.release()); | 374 AcquireUserScripts(make_scoped_ptr(user_scripts.release())); |
366 if (pending_load_) { | 375 if (pending_load_) { |
367 // While we were loading, there were further changes. Don't bother | 376 // While we were loading, there were further changes. Don't bother |
368 // notifying about these scripts and instead just immediately reload. | 377 // notifying about these scripts and instead just immediately reload. |
369 pending_load_ = false; | 378 pending_load_ = false; |
370 StartLoad(); | 379 StartLoad(); |
371 return; | 380 return; |
372 } | 381 } |
373 | 382 |
374 if (shared_memory.get() == NULL) { | 383 if (shared_memory.get() == NULL) { |
375 // This can happen if we run out of file descriptors. In that case, we | 384 // This can happen if we run out of file descriptors. In that case, we |
376 // have a choice between silently omitting all user scripts for new tabs, | 385 // have a choice between silently omitting all user scripts for new tabs, |
377 // by nulling out shared_memory_, or only silently omitting new ones by | 386 // by nulling out shared_memory_, or only silently omitting new ones by |
378 // leaving the existing object in place. The second seems less bad, even | 387 // leaving the existing object in place. The second seems less bad, even |
379 // though it removes the possibility that freeing the shared memory block | 388 // though it removes the possibility that freeing the shared memory block |
380 // would open up enough FDs for long enough for a retry to succeed. | 389 // would open up enough FDs for long enough for a retry to succeed. |
381 | 390 |
382 // Pretend the extension change didn't happen. | 391 // Pretend the extension change didn't happen. |
383 return; | 392 return; |
384 } | 393 } |
385 | 394 |
386 // We've got scripts ready to go. | 395 // We've got scripts ready to go. |
387 shared_memory_.reset(shared_memory.release()); | 396 shared_memory_.reset(shared_memory.release()); |
388 | 397 |
389 for (content::RenderProcessHost::iterator i( | 398 for (content::RenderProcessHost::iterator i( |
390 content::RenderProcessHost::AllHostsIterator()); | 399 content::RenderProcessHost::AllHostsIterator()); |
391 !i.IsAtEnd(); i.Advance()) { | 400 !i.IsAtEnd(); i.Advance()) { |
392 SendUpdate(i.GetCurrentValue(), | 401 SendUpdate( |
393 shared_memory_.get(), | 402 i.GetCurrentValue(), shared_memory_.get(), GetChangedExtensions()); |
394 changed_extensions_); | |
395 } | 403 } |
396 changed_extensions_.clear(); | 404 ResetChangedExtensions(); |
397 | 405 |
398 content::NotificationService::current()->Notify( | 406 content::NotificationService::current()->Notify( |
399 chrome::NOTIFICATION_USER_SCRIPTS_UPDATED, | 407 chrome::NOTIFICATION_USER_SCRIPTS_UPDATED, |
400 content::Source<Profile>(profile_), | 408 content::Source<Profile>(profile_), |
401 content::Details<base::SharedMemory>(shared_memory_.get())); | 409 content::Details<base::SharedMemory>(shared_memory_.get())); |
402 } | 410 } |
403 | 411 |
404 void UserScriptMaster::OnExtensionLoaded( | 412 void UserScriptMaster::LoadScripts(scoped_ptr<UserScriptList> scripts, |
405 content::BrowserContext* browser_context, | 413 const ExtensionsInfo& extensions_info) { |
406 const Extension* extension) { | 414 content::BrowserThread::PostTask( |
407 added_extensions_.insert(extension->id()); | 415 content::BrowserThread::FILE, |
408 removed_extensions_.erase(extension->id()); | |
409 extensions_info_[extension->id()] = | |
410 ExtensionSet::ExtensionPathAndDefaultLocale( | |
411 extension->path(), LocaleInfo::GetDefaultLocale(extension)); | |
412 if (extensions_service_ready_) { | |
413 changed_extensions_.insert(extension->id()); | |
414 if (is_loading()) | |
415 pending_load_ = true; | |
416 else | |
417 StartLoad(); | |
418 } | |
419 } | |
420 | |
421 void UserScriptMaster::OnExtensionUnloaded( | |
422 content::BrowserContext* browser_context, | |
423 const Extension* extension, | |
424 UnloadedExtensionInfo::Reason reason) { | |
425 removed_extensions_.insert(extension->id()); | |
426 added_extensions_.erase(extension->id()); | |
427 // Remove any content scripts. | |
428 extensions_info_.erase(extension->id()); | |
429 changed_extensions_.insert(extension->id()); | |
430 if (is_loading()) | |
431 pending_load_ = true; | |
432 else | |
433 StartLoad(); | |
434 } | |
435 | |
436 void UserScriptMaster::Observe(int type, | |
437 const content::NotificationSource& source, | |
438 const content::NotificationDetails& details) { | |
439 bool should_start_load = false; | |
440 switch (type) { | |
441 case chrome::NOTIFICATION_EXTENSIONS_READY: | |
442 extensions_service_ready_ = true; | |
443 should_start_load = true; | |
444 break; | |
445 case content::NOTIFICATION_RENDERER_PROCESS_CREATED: { | |
446 content::RenderProcessHost* process = | |
447 content::Source<content::RenderProcessHost>(source).ptr(); | |
448 Profile* profile = Profile::FromBrowserContext( | |
449 process->GetBrowserContext()); | |
450 if (!profile_->IsSameProfile(profile)) | |
451 return; | |
452 if (ScriptsReady()) { | |
453 SendUpdate(process, | |
454 GetSharedMemory(), | |
455 std::set<std::string>()); // Include all extensions. | |
456 } | |
457 break; | |
458 } | |
459 default: | |
460 DCHECK(false); | |
461 } | |
462 | |
463 if (should_start_load) { | |
464 if (is_loading()) | |
465 pending_load_ = true; | |
466 else | |
467 StartLoad(); | |
468 } | |
469 } | |
470 | |
471 void UserScriptMaster::StartLoad() { | |
472 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
473 DCHECK(!is_loading()); | |
474 | |
475 // Remove any user scripts belonging to any extension that was updated or | |
476 // removed. | |
477 for (UserScriptList::iterator iter = user_scripts_->begin(); | |
478 iter != user_scripts_->end();) { | |
479 if (removed_extensions_.count(iter->extension_id()) > 0 || | |
480 added_extensions_.count(iter->extension_id()) > 0) { | |
481 iter = user_scripts_->erase(iter); | |
482 } else { | |
483 ++iter; | |
484 } | |
485 } | |
486 | |
487 // Add any content scripts for extensions that were recently loaded. | |
488 const ExtensionSet& enabled_extensions = | |
489 ExtensionRegistry::Get(profile_)->enabled_extensions(); | |
490 for (std::set<std::string>::const_iterator iter = added_extensions_.begin(); | |
491 iter != added_extensions_.end(); ++iter) { | |
492 const Extension* extension = enabled_extensions.GetByID(*iter); | |
493 if (!extension) | |
494 continue; | |
495 bool incognito_enabled = | |
496 util::IsIncognitoEnabled(extension->id(), profile_); | |
497 const UserScriptList& scripts = | |
498 ContentScriptsInfo::GetContentScripts(extension); | |
499 for (UserScriptList::const_iterator script = scripts.begin(); | |
500 script != scripts.end(); | |
501 ++script) { | |
502 user_scripts_->push_back(*script); | |
503 user_scripts_->back().set_incognito_enabled(incognito_enabled); | |
504 } | |
505 } | |
506 | |
507 BrowserThread::PostTask( | |
508 BrowserThread::FILE, | |
509 FROM_HERE, | 416 FROM_HERE, |
510 base::Bind(&LoadScriptsOnFileThread, | 417 base::Bind(&LoadScriptsOnFileThread, |
511 base::Passed(&user_scripts_), | 418 base::Passed(&scripts), |
512 extensions_info_, | 419 GetExtensionsInfo(), |
Devlin
2014/07/31 20:32:24
Wasn't this passed into the function?
| |
513 added_extensions_, | 420 GetAddedExtensions(), |
514 make_scoped_refptr( | 421 make_scoped_refptr( |
515 ExtensionSystem::Get(profile_)->content_verifier()), | 422 ExtensionSystem::Get(profile_)->content_verifier()), |
516 base::Bind(&UserScriptMaster::OnScriptsLoaded, | 423 base::Bind(&UserScriptMaster::OnScriptsLoaded, |
517 weak_factory_.GetWeakPtr()))); | 424 weak_factory_.GetWeakPtr()))); |
518 added_extensions_.clear(); | |
519 removed_extensions_.clear(); | |
520 user_scripts_.reset(NULL); | |
521 } | 425 } |
522 | 426 |
523 void UserScriptMaster::SendUpdate( | 427 void UserScriptMaster::SendUpdate( |
524 content::RenderProcessHost* process, | 428 content::RenderProcessHost* process, |
525 base::SharedMemory* shared_memory, | 429 base::SharedMemory* shared_memory, |
526 const std::set<std::string>& changed_extensions) { | 430 const std::set<ExtensionId>& changed_extensions) { |
527 // Don't allow injection of content scripts into <webview>. | 431 // Don't allow injection of content scripts into <webview>. |
528 if (process->IsIsolatedGuest()) | 432 if (process->IsIsolatedGuest()) |
529 return; | 433 return; |
530 | 434 |
531 Profile* profile = Profile::FromBrowserContext(process->GetBrowserContext()); | 435 Profile* profile = Profile::FromBrowserContext(process->GetBrowserContext()); |
532 // Make sure we only send user scripts to processes in our profile. | 436 // Make sure we only send user scripts to processes in our profile. |
533 if (!profile_->IsSameProfile(profile)) | 437 if (!profile_->IsSameProfile(profile)) |
534 return; | 438 return; |
535 | 439 |
536 // If the process is being started asynchronously, early return. We'll end up | 440 // If the process is being started asynchronously, early return. We'll end up |
537 // calling InitUserScripts when it's created which will call this again. | 441 // calling InitUserScripts when it's created which will call this again. |
538 base::ProcessHandle handle = process->GetHandle(); | 442 base::ProcessHandle handle = process->GetHandle(); |
539 if (!handle) | 443 if (!handle) |
540 return; | 444 return; |
541 | 445 |
542 base::SharedMemoryHandle handle_for_process; | 446 base::SharedMemoryHandle handle_for_process; |
543 if (!shared_memory->ShareToProcess(handle, &handle_for_process)) | 447 if (!shared_memory->ShareToProcess(handle, &handle_for_process)) |
544 return; // This can legitimately fail if the renderer asserts at startup. | 448 return; // This can legitimately fail if the renderer asserts at startup. |
545 | 449 |
546 if (base::SharedMemory::IsHandleValid(handle_for_process)) { | 450 if (base::SharedMemory::IsHandleValid(handle_for_process)) { |
547 process->Send(new ExtensionMsg_UpdateUserScripts(handle_for_process, | 451 process->Send(new ExtensionMsg_UpdateUserScripts( |
548 changed_extensions)); | 452 handle_for_process, owner_extension_id_, changed_extensions)); |
549 } | 453 } |
550 } | 454 } |
551 | 455 |
552 } // namespace extensions | 456 } // namespace extensions |
OLD | NEW |