diff options
Diffstat (limited to 'chromium/extensions/renderer')
18 files changed, 121 insertions, 70 deletions
diff --git a/chromium/extensions/renderer/api/automation/automation_ax_tree_wrapper.cc b/chromium/extensions/renderer/api/automation/automation_ax_tree_wrapper.cc index 893e6eceb8a..15b2b113b97 100644 --- a/chromium/extensions/renderer/api/automation/automation_ax_tree_wrapper.cc +++ b/chromium/extensions/renderer/api/automation/automation_ax_tree_wrapper.cc @@ -83,8 +83,6 @@ api::automation::EventType ToAutomationEvent(ax::mojom::Event event_type) { return api::automation::EVENT_TYPE_MENULISTVALUECHANGED; case ax::mojom::Event::kMenuPopupEnd: return api::automation::EVENT_TYPE_MENUPOPUPEND; - case ax::mojom::Event::kMenuPopupHide: - return api::automation::EVENT_TYPE_MENUPOPUPHIDE; case ax::mojom::Event::kMenuPopupStart: return api::automation::EVENT_TYPE_MENUPOPUPSTART; case ax::mojom::Event::kMenuStart: @@ -188,6 +186,7 @@ api::automation::EventType ToAutomationEvent( // but mapping for backward compat). case ui::AXEventGenerator::Event::AUTO_COMPLETE_CHANGED: case ui::AXEventGenerator::Event::COLLAPSED: + case ui::AXEventGenerator::Event::DESCRIPTION_CHANGED: case ui::AXEventGenerator::Event::EXPANDED: case ui::AXEventGenerator::Event::IMAGE_ANNOTATION_CHANGED: case ui::AXEventGenerator::Event::LIVE_REGION_NODE_CHANGED: @@ -203,7 +202,6 @@ api::automation::EventType ToAutomationEvent( case ui::AXEventGenerator::Event::CONTROLS_CHANGED: case ui::AXEventGenerator::Event::CLASS_NAME_CHANGED: case ui::AXEventGenerator::Event::DESCRIBED_BY_CHANGED: - case ui::AXEventGenerator::Event::DESCRIPTION_CHANGED: case ui::AXEventGenerator::Event::DROPEFFECT_CHANGED: case ui::AXEventGenerator::Event::ENABLED_CHANGED: case ui::AXEventGenerator::Event::FOCUS_CHANGED: @@ -248,6 +246,7 @@ AutomationAXTreeWrapper::AutomationAXTreeWrapper( : tree_id_(tree_id), owner_(owner), event_generator_(&tree_) { tree_.AddObserver(this); ui::AXTreeManagerMap::GetInstance().AddTreeManager(tree_id, this); + event_generator_.set_always_fire_load_complete(true); } AutomationAXTreeWrapper::~AutomationAXTreeWrapper() { @@ -304,12 +303,9 @@ bool AutomationAXTreeWrapper::OnAccessibilityEvents( owner_->SendNodesRemovedEvent(&tree_, deleted_node_ids_); if (update.nodes.size() && did_send_tree_change_during_unserialization_) { - ui::AXNode* target = tree_.GetFromId(update.nodes[0].id); - if (target) { - owner_->SendTreeChangeEvent( - api::automation::TREE_CHANGE_TYPE_SUBTREEUPDATEEND, &tree_, - target); - } + owner_->SendTreeChangeEvent( + api::automation::TREE_CHANGE_TYPE_SUBTREEUPDATEEND, &tree_, + tree_.root()); } } } @@ -363,6 +359,7 @@ bool AutomationAXTreeWrapper::OnAccessibilityEvents( ui::AXEvent generated_event; generated_event.id = targeted_event.node->id(); generated_event.event_from = targeted_event.event_params.event_from; + generated_event.event_intents = targeted_event.event_params.event_intents; owner_->SendAutomationEvent(event_bundle.tree_id, event_bundle.mouse_location, generated_event, event_type); @@ -571,7 +568,6 @@ bool AutomationAXTreeWrapper::IsEventTypeHandledByAXEventGenerator( case api::automation::EVENT_TYPE_LAYOUTCOMPLETE: case api::automation::EVENT_TYPE_MENULISTVALUECHANGED: case api::automation::EVENT_TYPE_MENUPOPUPEND: - case api::automation::EVENT_TYPE_MENUPOPUPHIDE: case api::automation::EVENT_TYPE_MENUPOPUPSTART: case api::automation::EVENT_TYPE_SELECTIONADD: case api::automation::EVENT_TYPE_SELECTIONREMOVE: diff --git a/chromium/extensions/renderer/api/automation/automation_internal_custom_bindings.cc b/chromium/extensions/renderer/api/automation/automation_internal_custom_bindings.cc index 81c64bd2248..0fbbff6ce82 100644 --- a/chromium/extensions/renderer/api/automation/automation_internal_custom_bindings.cc +++ b/chromium/extensions/renderer/api/automation/automation_internal_custom_bindings.cc @@ -1512,8 +1512,7 @@ void AutomationInternalCustomBindings::AddRoutes() { "GetTableCellColumnHeaders", [](v8::Isolate* isolate, v8::ReturnValue<v8::Value> result, AutomationAXTreeWrapper* tree_wrapper, ui::AXNode* node) { - std::vector<int32_t> col_headers; - node->GetTableCellColHeaderNodeIds(&col_headers); + std::vector<int32_t> col_headers = node->GetTableCellColHeaderNodeIds(); v8::Local<v8::Context> context = isolate->GetCurrentContext(); v8::Local<v8::Array> array_result( v8::Array::New(isolate, col_headers.size())); @@ -1528,8 +1527,7 @@ void AutomationInternalCustomBindings::AddRoutes() { "GetTableCellRowHeaders", [](v8::Isolate* isolate, v8::ReturnValue<v8::Value> result, AutomationAXTreeWrapper* tree_wrapper, ui::AXNode* node) { - std::vector<int32_t> row_headers; - node->GetTableCellRowHeaderNodeIds(&row_headers); + std::vector<int32_t> row_headers = node->GetTableCellRowHeaderNodeIds(); v8::Local<v8::Context> context = isolate->GetCurrentContext(); v8::Local<v8::Array> array_result( v8::Array::New(isolate, row_headers.size())); diff --git a/chromium/extensions/renderer/bindings/api_binding.cc b/chromium/extensions/renderer/bindings/api_binding.cc index 16c3ef8b279..322d32c7b88 100644 --- a/chromium/extensions/renderer/bindings/api_binding.cc +++ b/chromium/extensions/renderer/bindings/api_binding.cc @@ -65,24 +65,32 @@ struct SignaturePair { std::unique_ptr<APISignature> callback_signature; }; -SignaturePair GetAPISignatureFromDictionary(const base::DictionaryValue* dict) { - const base::ListValue* params = nullptr; - CHECK(dict->GetList("parameters", ¶ms)); +SignaturePair GetAPISignatureFromDictionary(const base::Value* dict) { + const base::Value* params = + dict->FindKeyOfType("parameters", base::Value::Type::LIST); + CHECK(params); - bool supports_promises = false; - dict->GetBoolean("supportsPromises", &supports_promises); + // The inclusion of the "returns_async" property indicates that an API + // supports promises. + const base::Value* returns_async = + dict->FindKeyOfType("returns_async", base::Value::Type::DICTIONARY); SignaturePair result; - result.method_signature = std::make_unique<APISignature>(*params); + result.method_signature = + std::make_unique<APISignature>(*params, returns_async); result.method_signature->set_promise_support( - supports_promises ? binding::PromiseSupport::kAllowed - : binding::PromiseSupport::kDisallowed); + returns_async && APIBinding::enable_promise_support_for_testing + ? binding::PromiseSupport::kAllowed + : binding::PromiseSupport::kDisallowed); // If response validation is enabled, parse the callback signature. Otherwise, // there's no reason to, so don't bother. if (result.method_signature->has_callback() && binding::IsResponseValidationEnabled()) { - const base::Value* callback_params = params->GetList().back().FindKeyOfType( - "parameters", base::Value::Type::LIST); + const base::Value* callback_params = + returns_async ? returns_async->FindKeyOfType("parameters", + base::Value::Type::LIST) + : params->GetList().back().FindKeyOfType( + "parameters", base::Value::Type::LIST); if (callback_params) { const base::ListValue* params_as_list = nullptr; callback_params->GetAsList(¶ms_as_list); @@ -532,6 +540,9 @@ void APIBinding::DecorateTemplateWithProperties( } // static +bool APIBinding::enable_promise_support_for_testing = false; + +// static void APIBinding::GetEventObject( v8::Local<v8::Name> property, const v8::PropertyCallbackInfo<v8::Value>& info) { diff --git a/chromium/extensions/renderer/bindings/api_binding.h b/chromium/extensions/renderer/bindings/api_binding.h index e62af331e4d..63b27c47f3f 100644 --- a/chromium/extensions/renderer/bindings/api_binding.h +++ b/chromium/extensions/renderer/bindings/api_binding.h @@ -83,6 +83,11 @@ class APIBinding { APIBindingHooks* hooks() { return binding_hooks_.get(); } + // Global bool to allow for testing of promise support. + // TODO(tjudkins): Replace this with a runtime determined condition gated on + // MV3. + static bool enable_promise_support_for_testing; + private: // Initializes the object_template_ for this API. Called lazily when the // first instance is created. diff --git a/chromium/extensions/renderer/bindings/api_binding_unittest.cc b/chromium/extensions/renderer/bindings/api_binding_unittest.cc index b2a29346cff..b56bb87e81b 100644 --- a/chromium/extensions/renderer/bindings/api_binding_unittest.cc +++ b/chromium/extensions/renderer/bindings/api_binding_unittest.cc @@ -4,6 +4,7 @@ #include "extensions/renderer/bindings/api_binding.h" +#include "base/auto_reset.h" #include "base/bind.h" #include "base/bind_helpers.h" #include "base/macros.h" @@ -1672,21 +1673,22 @@ TEST_F(APIBindingUnittest, // Tests promise-based APIs exposed on bindings. TEST_F(APIBindingUnittest, PromiseBasedAPIs) { + // TODO(tjudkins): Remove this once promise support is fully integrated into + // the API calling flow. + base::AutoReset<bool> auto_reset( + &APIBinding::enable_promise_support_for_testing, true); + constexpr char kFunctions[] = R"([{ 'name': 'supportsPromises', - 'supportsPromises': true, 'parameters': [{ 'name': 'int', 'type': 'integer' - }, { - 'name': 'callback', - 'type': 'function', - 'parameters': [{ - 'name': 'strResult', - 'type': 'string' - }] - }] + }], + "returns_async": { + 'name': 'strResult', + 'type': 'string' + } }])"; SetFunctions(kFunctions); @@ -1701,7 +1703,7 @@ TEST_F(APIBindingUnittest, PromiseBasedAPIs) { R"((function(api) { this.apiResult = api.supportsPromises(3); this.apiResult.then((strResult) => { - this.strResult = strResult; + this.promiseResult = strResult; }); }))"; v8::Local<v8::Function> promise_api_call = @@ -1723,8 +1725,29 @@ TEST_F(APIBindingUnittest, PromiseBasedAPIs) { EXPECT_EQ(v8::Promise::kFulfilled, promise->State()); EXPECT_EQ(R"("foo")", V8ToString(promise->Result(), context)); - EXPECT_EQ(R"("foo")", GetStringPropertyFromObject(context->Global(), - context, "strResult")); + EXPECT_EQ(R"("foo")", GetStringPropertyFromObject( + context->Global(), context, "promiseResult")); + } + // Also test that promise-based APIs still support passing a callback. + { + constexpr char kFunctionCall[] = + R"((function(api) { + api.supportsPromises(3, (strResult) => { + this.callbackResult = strResult + }); + }))"; + v8::Local<v8::Function> promise_api_call = + FunctionFromString(context, kFunctionCall); + v8::Local<v8::Value> args[] = {binding_object}; + RunFunctionOnGlobal(promise_api_call, context, base::size(args), args); + + ASSERT_TRUE(last_request()); + request_handler()->CompleteRequest(last_request()->request_id, + *ListValueFromString(R"(["bar"])"), + std::string()); + + EXPECT_EQ(R"("bar")", GetStringPropertyFromObject( + context->Global(), context, "callbackResult")); } } diff --git a/chromium/extensions/renderer/bindings/api_signature.cc b/chromium/extensions/renderer/bindings/api_signature.cc index 03b34af7ad7..e617533e508 100644 --- a/chromium/extensions/renderer/bindings/api_signature.cc +++ b/chromium/extensions/renderer/bindings/api_signature.cc @@ -19,10 +19,9 @@ namespace extensions { namespace { bool HasCallback(const std::vector<std::unique_ptr<ArgumentSpec>>& signature) { - // TODO(devlin): This is how extension APIs have always determined if a - // function has a callback, but it seems a little silly. In the long run (once - // signatures are generated), it probably makes sense to indicate this - // differently. + // TODO(tjudkins): Once we change the APISignature to represent the whole + // signature including any asynchronous return, we should replace this with a + // method on the APISignature object itself. return !signature.empty() && signature.back()->type() == ArgumentType::FUNCTION; } @@ -409,6 +408,27 @@ APISignature::APISignature(const base::ListValue& specification) { has_callback_ = HasCallback(signature_); } +APISignature::APISignature(const base::Value& specification_list, + bool supports_promises) { + auto size = specification_list.GetList().size() + (supports_promises ? 1 : 0); + signature_.reserve(size); + for (const auto& value : specification_list.GetList()) { + CHECK(value.is_dict()); + signature_.push_back(std::make_unique<ArgumentSpec>(value)); + } + // To allow promise supporting APIs to instead take a callback, we add an + // allowed function to the end of the signature. + if (supports_promises) { + auto callback = std::make_unique<ArgumentSpec>(ArgumentType::FUNCTION); + callback->set_name("callback"); + signature_.push_back(std::move(callback)); + } + + has_callback_ = HasCallback(signature_); + DCHECK(!supports_promises || has_callback_) + << "If an API supports promises, it must also support callbacks"; +} + APISignature::APISignature(std::vector<std::unique_ptr<ArgumentSpec>> signature) : signature_(std::move(signature)), has_callback_(HasCallback(signature_)) {} diff --git a/chromium/extensions/renderer/bindings/api_signature.h b/chromium/extensions/renderer/bindings/api_signature.h index 6cca11efd3e..814bb273976 100644 --- a/chromium/extensions/renderer/bindings/api_signature.h +++ b/chromium/extensions/renderer/bindings/api_signature.h @@ -28,6 +28,7 @@ class ArgumentSpec; class APISignature { public: explicit APISignature(const base::ListValue& specification); + APISignature(const base::Value& specification_list, bool supports_promises); explicit APISignature(std::vector<std::unique_ptr<ArgumentSpec>> signature); ~APISignature(); diff --git a/chromium/extensions/renderer/bindings/test_interaction_provider.cc b/chromium/extensions/renderer/bindings/test_interaction_provider.cc index f2d09c6bd9e..b4aa7415fe5 100644 --- a/chromium/extensions/renderer/bindings/test_interaction_provider.cc +++ b/chromium/extensions/renderer/bindings/test_interaction_provider.cc @@ -4,6 +4,8 @@ #include "extensions/renderer/bindings/test_interaction_provider.h" +#include "base/check.h" + namespace extensions { namespace { diff --git a/chromium/extensions/renderer/bindings/test_interaction_provider.h b/chromium/extensions/renderer/bindings/test_interaction_provider.h index 9fc794efabe..f3c28ea764c 100644 --- a/chromium/extensions/renderer/bindings/test_interaction_provider.h +++ b/chromium/extensions/renderer/bindings/test_interaction_provider.h @@ -7,7 +7,6 @@ #include "extensions/renderer/bindings/interaction_provider.h" -#include "base/logging.h" #include "base/macros.h" #include "v8/include/v8.h" diff --git a/chromium/extensions/renderer/extension_frame_helper.cc b/chromium/extensions/renderer/extension_frame_helper.cc index 5a6273b4ba4..d40ccf3d8dd 100644 --- a/chromium/extensions/renderer/extension_frame_helper.cc +++ b/chromium/extensions/renderer/extension_frame_helper.cc @@ -330,7 +330,6 @@ void ExtensionFrameHelper::ReadyToCommitNavigation( } void ExtensionFrameHelper::DidCommitProvisionalLoad( - bool is_same_document_navigation, ui::PageTransition transition) { // Grant cross browsing instance frame lookup if we are an extension. This // should match the conditions in FindFrame. diff --git a/chromium/extensions/renderer/extension_frame_helper.h b/chromium/extensions/renderer/extension_frame_helper.h index 9142935dd5c..bf3b66f417a 100644 --- a/chromium/extensions/renderer/extension_frame_helper.h +++ b/chromium/extensions/renderer/extension_frame_helper.h @@ -125,8 +125,7 @@ class ExtensionFrameHelper void DidCreateNewDocument() override; void ReadyToCommitNavigation( blink::WebDocumentLoader* document_loader) override; - void DidCommitProvisionalLoad(bool is_same_document_navigation, - ui::PageTransition transition) override; + void DidCommitProvisionalLoad(ui::PageTransition transition) override; void DidCreateScriptContext(v8::Local<v8::Context>, int32_t world_id) override; void WillReleaseScriptContext(v8::Local<v8::Context>, diff --git a/chromium/extensions/renderer/extension_throttle_simulation_unittest.cc b/chromium/extensions/renderer/extension_throttle_simulation_unittest.cc index ea2c489f7fd..5f9f7837234 100644 --- a/chromium/extensions/renderer/extension_throttle_simulation_unittest.cc +++ b/chromium/extensions/renderer/extension_throttle_simulation_unittest.cc @@ -458,7 +458,7 @@ class Requester : public DiscreteTimeSimulation::Actor { bool last_attempt_was_failure_; TimeDelta last_downtime_duration_; Server* const server_; - RequesterResults* const results_; // May be NULL. + RequesterResults* const results_; // May be nullptr. DISALLOW_COPY_AND_ASSIGN(Requester); }; @@ -571,7 +571,7 @@ double SimulateDowntime(const TimeDelta& duration, throttler_entry->DisableBackoffThrottling(); Requester requester(std::move(throttler_entry), average_client_interval, - &server, NULL); + &server, nullptr); requester.SetStartupJitter(duration / 3); requester.SetRequestJitter(average_client_interval); diff --git a/chromium/extensions/renderer/extensions_render_frame_observer.cc b/chromium/extensions/renderer/extensions_render_frame_observer.cc index 5802bde0d4d..77b64dded66 100644 --- a/chromium/extensions/renderer/extensions_render_frame_observer.cc +++ b/chromium/extensions/renderer/extensions_render_frame_observer.cc @@ -14,8 +14,8 @@ #include "extensions/common/constants.h" #include "extensions/common/extension_messages.h" #include "extensions/common/stack_frame.h" +#include "third_party/blink/public/web/web_frame_widget.h" #include "third_party/blink/public/web/web_local_frame.h" -#include "third_party/blink/public/web/web_view.h" namespace extensions { @@ -108,7 +108,7 @@ void ExtensionsRenderFrameObserver::SetVisuallyDeemphasized(bool deemphasized) { SkColor color = deemphasized ? SkColorSetARGB(178, 0, 0, 0) : SK_ColorTRANSPARENT; - render_frame()->GetWebFrame()->SetMainFrameOverlayColor(color); + render_frame()->GetWebFrame()->FrameWidget()->SetMainFrameOverlayColor(color); } void ExtensionsRenderFrameObserver::DetailedConsoleMessageAdded( diff --git a/chromium/extensions/renderer/guest_view/mime_handler_view/mime_handler_view_container_manager.cc b/chromium/extensions/renderer/guest_view/mime_handler_view/mime_handler_view_container_manager.cc index c1be9c9a9af..bbdb7a0db2b 100644 --- a/chromium/extensions/renderer/guest_view/mime_handler_view/mime_handler_view_container_manager.cc +++ b/chromium/extensions/renderer/guest_view/mime_handler_view/mime_handler_view_container_manager.cc @@ -270,6 +270,8 @@ void MimeHandlerViewContainerManager::RemoveFrameContainerForReason( bool retain_manager) { if (!RemoveFrameContainer(frame_container, retain_manager)) return; + // At this point |this| may be invalid, but it's still OK to call + // RecordInteraction() as it's declared static. RecordInteraction(event); } @@ -298,6 +300,7 @@ void MimeHandlerViewContainerManager::SetShowBeforeUnloadDialog( std::move(callback).Run(); } +// static void MimeHandlerViewContainerManager::RecordInteraction(UMAType type) { base::UmaHistogramEnumeration(MimeHandlerViewUMATypes::kUMAName, type); } diff --git a/chromium/extensions/renderer/guest_view/mime_handler_view/mime_handler_view_container_manager.h b/chromium/extensions/renderer/guest_view/mime_handler_view/mime_handler_view_container_manager.h index f513e21c394..8b5b1014f69 100644 --- a/chromium/extensions/renderer/guest_view/mime_handler_view/mime_handler_view_container_manager.h +++ b/chromium/extensions/renderer/guest_view/mime_handler_view/mime_handler_view_container_manager.h @@ -111,6 +111,9 @@ class MimeHandlerViewContainerManager const GURL& resource_url) override; private: + // Static so it can be called after self-deletion. + static void RecordInteraction(MimeHandlerViewUMATypes::Type type); + // PostMessageSupport::Delegate overrides. blink::WebLocalFrame* GetSourceFrame() override; blink::WebFrame* GetTargetFrame() override; @@ -126,8 +129,6 @@ class MimeHandlerViewContainerManager bool show_dialog, SetShowBeforeUnloadDialogCallback callback) override; - void RecordInteraction(MimeHandlerViewUMATypes::Type type); - // Returns true if the |element| is managed by // MimeHandlerViewContainerManager; this would be the element that is added by // the HTML string injected at MimeHandlerViewAttachHelper. diff --git a/chromium/extensions/renderer/messaging_util_unittest.cc b/chromium/extensions/renderer/messaging_util_unittest.cc index 3ed46522454..5935ad2b901 100644 --- a/chromium/extensions/renderer/messaging_util_unittest.cc +++ b/chromium/extensions/renderer/messaging_util_unittest.cc @@ -28,26 +28,13 @@ TEST_F(MessagingUtilTest, TestMaximumMessageSize) { constexpr char kMessageTooLongError[] = "Message length exceeded maximum allowed length."; - { - v8::Local<v8::Value> long_message = - V8ValueFromScriptSource(context, "'a'.repeat(1024 *1024 * 65)"); - std::string error; - std::unique_ptr<Message> message = - messaging_util::MessageFromV8(context, long_message, &error); - EXPECT_FALSE(message); - EXPECT_EQ(kMessageTooLongError, error); - } - - { - v8::Local<v8::Value> long_json_message = V8ValueFromScriptSource( - context, "(JSON.stringify('a'.repeat(1024 *1024 * 65)))"); - ASSERT_TRUE(long_json_message->IsString()); - std::string error; - std::unique_ptr<Message> message = messaging_util::MessageFromV8( - context, long_json_message.As<v8::String>(), &error); - EXPECT_FALSE(message); - EXPECT_EQ(kMessageTooLongError, error); - } + v8::Local<v8::Value> long_message = + V8ValueFromScriptSource(context, "'a'.repeat(1024 *1024 * 65)"); + std::string error; + std::unique_ptr<Message> message = + messaging_util::MessageFromV8(context, long_message, &error); + EXPECT_FALSE(message); + EXPECT_EQ(kMessageTooLongError, error); } TEST_F(MessagingUtilTest, TestParseMessageOptionsFrameId) { diff --git a/chromium/extensions/renderer/resources/test_custom_bindings.js b/chromium/extensions/renderer/resources/test_custom_bindings.js index 307f19320a7..4bad888c35f 100644 --- a/chromium/extensions/renderer/resources/test_custom_bindings.js +++ b/chromium/extensions/renderer/resources/test_custom_bindings.js @@ -164,7 +164,13 @@ apiBridge.registerCustomHook(function(api) { if (typeof(expected) !== typeof(actual)) return false; + if (Array.isArray(expected) !== Array.isArray(actual)) + return false; + // Handle the ArrayBuffer cases. Bail out in case of type mismatch, to + // prevent the ArrayBuffer from being treated as an empty enumerable below. + if ((actual instanceof ArrayBuffer) !== (expected instanceof ArrayBuffer)) + return false; if ((actual instanceof ArrayBuffer) && (expected instanceof ArrayBuffer)) { if (actual.byteLength != expected.byteLength) return false; diff --git a/chromium/extensions/renderer/script_injection.cc b/chromium/extensions/renderer/script_injection.cc index 9178bfb0c0c..62451422277 100644 --- a/chromium/extensions/renderer/script_injection.cc +++ b/chromium/extensions/renderer/script_injection.cc @@ -74,6 +74,7 @@ int GetIsolatedWorldIdForInstance(const InjectionHost* injection_host, info.security_origin = blink::WebSecurityOrigin::Create(injection_host->url()); info.human_readable_name = blink::WebString::FromUTF8(injection_host->name()); + info.stable_id = blink::WebString::FromUTF8(key); const std::string* csp = injection_host->GetContentSecurityPolicy(); if (csp) |