Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 "extensions/renderer/dispatcher.h" | 5 #include "extensions/renderer/dispatcher.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/callback.h" | 8 #include "base/callback.h" |
| 9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
| 10 #include "base/debug/alias.h" | 10 #include "base/debug/alias.h" |
| (...skipping 666 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 677 new GuestViewInternalCustomBindings(context))); | 677 new GuestViewInternalCustomBindings(context))); |
| 678 module_system->RegisterNativeHandler( | 678 module_system->RegisterNativeHandler( |
| 679 "i18n", scoped_ptr<NativeHandler>(new I18NCustomBindings(context))); | 679 "i18n", scoped_ptr<NativeHandler>(new I18NCustomBindings(context))); |
| 680 module_system->RegisterNativeHandler( | 680 module_system->RegisterNativeHandler( |
| 681 "id_generator", | 681 "id_generator", |
| 682 scoped_ptr<NativeHandler>(new IdGeneratorCustomBindings(context))); | 682 scoped_ptr<NativeHandler>(new IdGeneratorCustomBindings(context))); |
| 683 module_system->RegisterNativeHandler( | 683 module_system->RegisterNativeHandler( |
| 684 "runtime", scoped_ptr<NativeHandler>(new RuntimeCustomBindings(context))); | 684 "runtime", scoped_ptr<NativeHandler>(new RuntimeCustomBindings(context))); |
| 685 } | 685 } |
| 686 | 686 |
| 687 void Dispatcher::LoadExtensionForTest(const Extension* extension) { | |
| 688 CHECK(extensions_.Insert(extension)); | |
| 689 } | |
| 690 | |
| 687 bool Dispatcher::OnControlMessageReceived(const IPC::Message& message) { | 691 bool Dispatcher::OnControlMessageReceived(const IPC::Message& message) { |
| 688 bool handled = true; | 692 bool handled = true; |
| 689 IPC_BEGIN_MESSAGE_MAP(Dispatcher, message) | 693 IPC_BEGIN_MESSAGE_MAP(Dispatcher, message) |
| 690 IPC_MESSAGE_HANDLER(ExtensionMsg_ActivateExtension, OnActivateExtension) | 694 IPC_MESSAGE_HANDLER(ExtensionMsg_ActivateExtension, OnActivateExtension) |
| 691 IPC_MESSAGE_HANDLER(ExtensionMsg_CancelSuspend, OnCancelSuspend) | 695 IPC_MESSAGE_HANDLER(ExtensionMsg_CancelSuspend, OnCancelSuspend) |
| 692 IPC_MESSAGE_HANDLER(ExtensionMsg_DeliverMessage, OnDeliverMessage) | 696 IPC_MESSAGE_HANDLER(ExtensionMsg_DeliverMessage, OnDeliverMessage) |
| 693 IPC_MESSAGE_HANDLER(ExtensionMsg_DispatchOnConnect, OnDispatchOnConnect) | 697 IPC_MESSAGE_HANDLER(ExtensionMsg_DispatchOnConnect, OnDispatchOnConnect) |
| 694 IPC_MESSAGE_HANDLER(ExtensionMsg_DispatchOnDisconnect, OnDispatchOnDisconnect) | 698 IPC_MESSAGE_HANDLER(ExtensionMsg_DispatchOnDisconnect, OnDispatchOnDisconnect) |
| 695 IPC_MESSAGE_HANDLER(ExtensionMsg_Loaded, OnLoaded) | 699 IPC_MESSAGE_HANDLER(ExtensionMsg_Loaded, OnLoaded) |
| 696 IPC_MESSAGE_HANDLER(ExtensionMsg_MessageInvoke, OnMessageInvoke) | 700 IPC_MESSAGE_HANDLER(ExtensionMsg_MessageInvoke, OnMessageInvoke) |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 725 forced_idle_timer_.reset(new base::RepeatingTimer<content::RenderThread>); | 729 forced_idle_timer_.reset(new base::RepeatingTimer<content::RenderThread>); |
| 726 forced_idle_timer_->Start( | 730 forced_idle_timer_->Start( |
| 727 FROM_HERE, | 731 FROM_HERE, |
| 728 base::TimeDelta::FromMilliseconds(kMaxExtensionIdleHandlerDelayMs), | 732 base::TimeDelta::FromMilliseconds(kMaxExtensionIdleHandlerDelayMs), |
| 729 RenderThread::Get(), | 733 RenderThread::Get(), |
| 730 &RenderThread::IdleHandler); | 734 &RenderThread::IdleHandler); |
| 731 } | 735 } |
| 732 | 736 |
| 733 // Initialize host permissions for any extensions that were activated before | 737 // Initialize host permissions for any extensions that were activated before |
| 734 // WebKit was initialized. | 738 // WebKit was initialized. |
| 735 for (std::set<std::string>::iterator iter = active_extension_ids_.begin(); | 739 for (const std::string& extension_id : active_extension_ids_) { |
| 736 iter != active_extension_ids_.end(); | 740 const Extension* extension = extensions_.GetByID(extension_id); |
| 737 ++iter) { | |
| 738 const Extension* extension = extensions_.GetByID(*iter); | |
| 739 CHECK(extension); | 741 CHECK(extension); |
| 740 | |
| 741 InitOriginPermissions(extension); | 742 InitOriginPermissions(extension); |
| 742 } | 743 } |
| 743 | 744 |
| 744 EnableCustomElementWhiteList(); | 745 EnableCustomElementWhiteList(); |
| 745 | 746 |
| 746 is_webkit_initialized_ = true; | 747 is_webkit_initialized_ = true; |
| 747 } | 748 } |
| 748 | 749 |
| 749 void Dispatcher::IdleNotification() { | 750 void Dispatcher::IdleNotification() { |
| 750 if (set_idle_notifications_ && forced_idle_timer_) { | 751 if (set_idle_notifications_ && forced_idle_timer_) { |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 777 // executes on all renderers) be conservative and only crash in the renderer | 778 // executes on all renderers) be conservative and only crash in the renderer |
| 778 // of the extension which failed to load; this one. | 779 // of the extension which failed to load; this one. |
| 779 std::string& error = extension_load_errors_[extension_id]; | 780 std::string& error = extension_load_errors_[extension_id]; |
| 780 char minidump[256]; | 781 char minidump[256]; |
| 781 base::debug::Alias(&minidump); | 782 base::debug::Alias(&minidump); |
| 782 base::snprintf(minidump, | 783 base::snprintf(minidump, |
| 783 arraysize(minidump), | 784 arraysize(minidump), |
| 784 "e::dispatcher:%s:%s", | 785 "e::dispatcher:%s:%s", |
| 785 extension_id.c_str(), | 786 extension_id.c_str(), |
| 786 error.c_str()); | 787 error.c_str()); |
| 787 CHECK(extension) << extension_id << " was never loaded: " << error; | 788 LOG(FATAL) << extension_id << " was never loaded: " << error; |
| 788 } | 789 } |
| 789 | 790 |
| 790 active_extension_ids_.insert(extension_id); | 791 active_extension_ids_.insert(extension_id); |
| 791 | 792 |
| 792 // This is called when starting a new extension page, so start the idle | 793 // This is called when starting a new extension page, so start the idle |
| 793 // handler ticking. | 794 // handler ticking. |
| 794 RenderThread::Get()->ScheduleIdleHandler(kInitialExtensionIdleHandlerDelayMs); | 795 RenderThread::Get()->ScheduleIdleHandler(kInitialExtensionIdleHandlerDelayMs); |
| 795 | 796 |
| 796 if (is_webkit_initialized_) { | 797 if (is_webkit_initialized_) { |
| 797 DOMActivityLogger::AttachToWorld( | 798 DOMActivityLogger::AttachToWorld( |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 841 | 842 |
| 842 void Dispatcher::OnDispatchOnDisconnect(int port_id, | 843 void Dispatcher::OnDispatchOnDisconnect(int port_id, |
| 843 const std::string& error_message) { | 844 const std::string& error_message) { |
| 844 MessagingBindings::DispatchOnDisconnect(*script_context_set_, port_id, | 845 MessagingBindings::DispatchOnDisconnect(*script_context_set_, port_id, |
| 845 error_message, | 846 error_message, |
| 846 NULL); // All render frames. | 847 NULL); // All render frames. |
| 847 } | 848 } |
| 848 | 849 |
| 849 void Dispatcher::OnLoaded( | 850 void Dispatcher::OnLoaded( |
| 850 const std::vector<ExtensionMsg_Loaded_Params>& loaded_extensions) { | 851 const std::vector<ExtensionMsg_Loaded_Params>& loaded_extensions) { |
| 851 std::vector<ExtensionMsg_Loaded_Params>::const_iterator i; | 852 for (const auto& param : loaded_extensions) { |
| 852 for (i = loaded_extensions.begin(); i != loaded_extensions.end(); ++i) { | |
| 853 std::string error; | 853 std::string error; |
| 854 scoped_refptr<const Extension> extension = i->ConvertToExtension(&error); | 854 scoped_refptr<const Extension> extension = param.ConvertToExtension(&error); |
| 855 if (!extension.get()) { | 855 if (!extension.get()) { |
| 856 extension_load_errors_[i->id] = error; | 856 NOTREACHED() << error; |
| 857 // Note: in tests |param.id| has been observed to be empty (see comment | |
| 858 // just below) so this isn't all that reliable. | |
| 859 extension_load_errors_[param.id] = error; | |
| 857 continue; | 860 continue; |
| 858 } | 861 } |
| 859 OnLoadedInternal(extension); | 862 |
| 863 // This test is deliberately not a CHECK (though I wish it could be) and | |
|
Devlin
2015/06/03 20:53:37
This kind of sounds like a TODO. Wanna own it? :)
not at google - send to devlin
2015/06/03 21:53:03
well I don't plan on doing it, but sure :-)
| |
| 864 // uses extension->id() not params.id: | |
| 865 // 1. For some reason params.id can be empty. I've only seen it with | |
| 866 // the webstore extension, in tests, and I've spent some time trying to | |
| 867 // figure out why - but cost/benefit won. | |
| 868 // 2. The browser only sends this IPC to RenderProcessHosts once, but the | |
| 869 // Dispatcher is attached to a RenderThread. Presumably there is a | |
| 870 // mismatch there. In theory one would think it's possible for the | |
| 871 // browser to figure this out itself - but again, cost/benefit. | |
| 872 if (!extensions_.Contains(extension->id())) | |
| 873 extensions_.Insert(extension); | |
| 860 } | 874 } |
| 875 | |
| 861 // Update the available bindings for all contexts. These may have changed if | 876 // Update the available bindings for all contexts. These may have changed if |
| 862 // an externally_connectable extension was loaded that can connect to an | 877 // an externally_connectable extension was loaded that can connect to an |
| 863 // open webpage. | 878 // open webpage. |
| 864 UpdateBindings(""); | 879 UpdateBindings(""); |
| 865 } | 880 } |
| 866 | 881 |
| 867 void Dispatcher::OnLoadedInternal(scoped_refptr<const Extension> extension) { | |
| 868 extensions_.Insert(extension); | |
| 869 } | |
| 870 | |
| 871 void Dispatcher::OnMessageInvoke(const std::string& extension_id, | 882 void Dispatcher::OnMessageInvoke(const std::string& extension_id, |
| 872 const std::string& module_name, | 883 const std::string& module_name, |
| 873 const std::string& function_name, | 884 const std::string& function_name, |
| 874 const base::ListValue& args, | 885 const base::ListValue& args, |
| 875 bool user_gesture) { | 886 bool user_gesture) { |
| 876 InvokeModuleSystemMethod( | 887 InvokeModuleSystemMethod( |
| 877 NULL, extension_id, module_name, function_name, args, user_gesture); | 888 NULL, extension_id, module_name, function_name, args, user_gesture); |
| 878 } | 889 } |
| 879 | 890 |
| 880 void Dispatcher::OnSetChannel(int channel) { | 891 void Dispatcher::OnSetChannel(int channel) { |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 912 // event creates. | 923 // event creates. |
| 913 DispatchEvent(extension_id, kOnSuspendEvent); | 924 DispatchEvent(extension_id, kOnSuspendEvent); |
| 914 RenderThread::Get()->Send(new ExtensionHostMsg_SuspendAck(extension_id)); | 925 RenderThread::Get()->Send(new ExtensionHostMsg_SuspendAck(extension_id)); |
| 915 } | 926 } |
| 916 | 927 |
| 917 void Dispatcher::OnTransferBlobs(const std::vector<std::string>& blob_uuids) { | 928 void Dispatcher::OnTransferBlobs(const std::vector<std::string>& blob_uuids) { |
| 918 RenderThread::Get()->Send(new ExtensionHostMsg_TransferBlobsAck(blob_uuids)); | 929 RenderThread::Get()->Send(new ExtensionHostMsg_TransferBlobsAck(blob_uuids)); |
| 919 } | 930 } |
| 920 | 931 |
| 921 void Dispatcher::OnUnloaded(const std::string& id) { | 932 void Dispatcher::OnUnloaded(const std::string& id) { |
| 922 extensions_.Remove(id); | 933 // See comment in OnLoaded for why it would be nice, but perhaps incorrect, |
| 934 // to CHECK here rather than guarding. | |
| 935 if (!extensions_.Remove(id)) | |
| 936 return; | |
| 937 | |
| 923 active_extension_ids_.erase(id); | 938 active_extension_ids_.erase(id); |
| 924 | 939 |
| 925 script_injection_manager_->OnExtensionUnloaded(id); | 940 script_injection_manager_->OnExtensionUnloaded(id); |
| 926 | 941 |
| 927 // If the extension is later reloaded with a different set of permissions, | 942 // If the extension is later reloaded with a different set of permissions, |
| 928 // we'd like it to get a new isolated world ID, so that it can pick up the | 943 // we'd like it to get a new isolated world ID, so that it can pick up the |
| 929 // changed origin whitelist. | 944 // changed origin whitelist. |
| 930 ScriptInjection::RemoveIsolatedWorld(id); | 945 ScriptInjection::RemoveIsolatedWorld(id); |
| 931 | 946 |
| 932 // Invalidate all of the contexts that were removed. | 947 // Invalidate all of the contexts that were removed. |
| (...skipping 477 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1410 // The "guestViewDeny" module must always be loaded last. It registers | 1425 // The "guestViewDeny" module must always be loaded last. It registers |
| 1411 // error-providing custom elements for the GuestView types that are not | 1426 // error-providing custom elements for the GuestView types that are not |
| 1412 // available, and thus all of those types must have been checked and loaded | 1427 // available, and thus all of those types must have been checked and loaded |
| 1413 // (or not loaded) beforehand. | 1428 // (or not loaded) beforehand. |
| 1414 if (context_type == Feature::BLESSED_EXTENSION_CONTEXT) { | 1429 if (context_type == Feature::BLESSED_EXTENSION_CONTEXT) { |
| 1415 module_system->Require("guestViewDeny"); | 1430 module_system->Require("guestViewDeny"); |
| 1416 } | 1431 } |
| 1417 } | 1432 } |
| 1418 | 1433 |
| 1419 } // namespace extensions | 1434 } // namespace extensions |
| OLD | NEW |