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 // TODO(kalman): This test is deliberately not a CHECK (though I wish it |
| 864 // could be) and 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 |