diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2019-07-31 15:50:41 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2019-08-30 12:35:23 +0000 |
commit | 7b2ffa587235a47d4094787d72f38102089f402a (patch) | |
tree | 30e82af9cbab08a7fa028bb18f4f2987a3f74dfa /chromium/chrome/browser/extensions | |
parent | d94af01c90575348c4e81a418257f254b6f8d225 (diff) | |
download | qtwebengine-chromium-7b2ffa587235a47d4094787d72f38102089f402a.tar.gz |
BASELINE: Update Chromium to 76.0.3809.94
Change-Id: I321c3f5f929c105aec0f98c5091ef6108822e647
Reviewed-by: Michael BrĂ¼ning <michael.bruning@qt.io>
Diffstat (limited to 'chromium/chrome/browser/extensions')
125 files changed, 1906 insertions, 2353 deletions
diff --git a/chromium/chrome/browser/extensions/BUILD.gn b/chromium/chrome/browser/extensions/BUILD.gn index 5aea5589b99..343d9631726 100644 --- a/chromium/chrome/browser/extensions/BUILD.gn +++ b/chromium/chrome/browser/extensions/BUILD.gn @@ -12,6 +12,10 @@ import("//mojo/public/tools/bindings/mojom.gni") import("//pdf/features.gni") import("//rlz/buildflags/buildflags.gni") +if (is_chromeos) { + import("//chrome/browser/chromeos/kiosk_next_home/kiosk_next.gni") +} + assert(enable_extensions) jumbo_static_library("extensions") { @@ -58,10 +62,8 @@ jumbo_static_library("extensions") { "api/autofill_private/autofill_private_event_router_factory.h", "api/autofill_private/autofill_util.cc", "api/autofill_private/autofill_util.h", - "api/automation_internal/automation_event_router.cc", - "api/automation_internal/automation_event_router.h", - "api/automation_internal/automation_internal_api.cc", - "api/automation_internal/automation_internal_api.h", + "api/automation_internal/chrome_automation_internal_api_delegate.cc", + "api/automation_internal/chrome_automation_internal_api_delegate.h", "api/bookmark_manager_private/bookmark_manager_private_api.cc", "api/bookmark_manager_private/bookmark_manager_private_api.h", "api/bookmarks/bookmark_api_constants.cc", @@ -362,6 +364,7 @@ jumbo_static_library("extensions") { "api/storage/syncable_settings_storage.h", "api/streams_private/streams_private_api.cc", "api/streams_private/streams_private_api.h", + "api/system_indicator/system_indicator_api.cc", "api/system_indicator/system_indicator_api.h", "api/system_indicator/system_indicator_manager.cc", "api/system_indicator/system_indicator_manager.h", @@ -568,10 +571,6 @@ jumbo_static_library("extensions") { "extension_service.h", "extension_special_storage_policy.cc", "extension_special_storage_policy.h", - "extension_storage_monitor.cc", - "extension_storage_monitor.h", - "extension_storage_monitor_factory.cc", - "extension_storage_monitor_factory.h", "extension_sync_data.cc", "extension_sync_data.h", "extension_sync_service.cc", @@ -682,10 +681,6 @@ jumbo_static_library("extensions") { "settings_api_helpers.h", "shared_module_service.cc", "shared_module_service.h", - "signin/gaia_auth_extension_loader.cc", - "signin/gaia_auth_extension_loader.h", - "signin/scoped_gaia_auth_extension.cc", - "signin/scoped_gaia_auth_extension.h", "standard_management_policy_provider.cc", "standard_management_policy_provider.h", "startup_helper.cc", @@ -974,8 +969,9 @@ jumbo_static_library("extensions") { configs += [ "//build/config/linux/dbus" ] } deps += [ + "//ash", + "//ash/keyboard/ui:resources_grit_grit", "//ash/public/cpp", - "//chrome/browser/chromeos/kiosk_next_home/mojom", "//chrome/browser/resources/chromeos/camera:chrome_camera_app", "//chromeos", "//chromeos/attestation", @@ -1009,11 +1005,16 @@ jumbo_static_library("extensions") { "//ui/chromeos", "//ui/chromeos/events", "//ui/file_manager", - "//ui/keyboard", - "//ui/keyboard:resources", "//ui/ozone", "//ui/views", ] + if (enable_kiosk_next) { + defines += [ "KIOSK_NEXT" ] + deps += [ "//chrome/browser/chromeos/kiosk_next_home/mojom" ] + if (is_chrome_branded) { + deps += [ "//chrome/browser/resources:kiosk_next_internal_resources" ] + } + } if (enable_nacl) { deps += [ "//chrome/browser/resources/chromeos/zip_archiver" ] } @@ -1107,6 +1108,7 @@ jumbo_static_library("extensions") { "//third_party/iaccessible2", "//third_party/isimpledom", ] + libs = [ "setupapi.lib" ] } else if (use_aura && !is_chromeos) { sources += [ "system_display/display_info_provider_aura.cc", diff --git a/chromium/chrome/browser/extensions/api/autofill_private/autofill_private_api.cc b/chromium/chrome/browser/extensions/api/autofill_private/autofill_private_api.cc index 1d0e5f584bb..2b44f3e0e6f 100644 --- a/chromium/chrome/browser/extensions/api/autofill_private/autofill_private_api.cc +++ b/chromium/chrome/browser/extensions/api/autofill_private/autofill_private_api.cc @@ -17,8 +17,9 @@ #include "chrome/common/extensions/api/autofill_private.h" #include "components/autofill/content/browser/content_autofill_driver.h" #include "components/autofill/content/browser/content_autofill_driver_factory.h" +#include "components/autofill/core/browser/autofill_address_util.h" #include "components/autofill/core/browser/autofill_manager.h" -#include "components/autofill/core/browser/autofill_profile.h" +#include "components/autofill/core/browser/data_model/autofill_profile.h" #include "components/autofill/core/browser/form_data_importer.h" #include "components/autofill/core/browser/payments/local_card_migration_manager.h" #include "components/autofill/core/browser/personal_data_manager.h" @@ -39,110 +40,6 @@ namespace { static const char kSettingsOrigin[] = "Chrome settings"; static const char kErrorDataUnavailable[] = "Autofill data unavailable."; -// TODO(crbug.com/903594): This does basically the same thing as -// components/autofill/core/browser/autofill_address_util.cc, we -// should refactor to use a single code path for this. -// Fills |components| with the address UI components that should be used to -// input an address for |country_code| when UI BCP 47 language code is -// |ui_language_code|. -void PopulateAddressComponents( - const std::string& country_code, - const std::string& ui_language_code, - autofill_private::AddressComponents* address_components) { - DCHECK(address_components); - - i18n::addressinput::Localization localization; - localization.SetGetter(l10n_util::GetStringUTF8); - std::string best_address_language_code; - std::vector<addressinput::AddressUiComponent> components = - i18n::addressinput::BuildComponents( - country_code, - localization, - ui_language_code, - &best_address_language_code); - if (components.empty()) { - static const char kDefaultCountryCode[] = "US"; - components = i18n::addressinput::BuildComponents( - kDefaultCountryCode, - localization, - ui_language_code, - &best_address_language_code); - } - address_components->language_code = best_address_language_code; - DCHECK(!components.empty()); - - autofill_private::AddressComponentRow* row = nullptr; - for (size_t i = 0; i < components.size(); ++i) { - if (components[i].field == ::i18n::addressinput::ORGANIZATION && - !base::FeatureList::IsEnabled( - autofill::features::kAutofillEnableCompanyName)) { - continue; - } - if (!row || - components[i - 1].length_hint == - addressinput::AddressUiComponent::HINT_LONG || - components[i].length_hint == - addressinput::AddressUiComponent::HINT_LONG) { - address_components->components.push_back( - autofill_private::AddressComponentRow()); - row = &address_components->components.back(); - } - - autofill_private::AddressComponent component; - component.field_name = components[i].name; - - switch (components[i].field) { - case i18n::addressinput::COUNTRY: - component.field = - autofill_private::AddressField::ADDRESS_FIELD_COUNTRY_CODE; - break; - case i18n::addressinput::ADMIN_AREA: - component.field = - autofill_private::AddressField::ADDRESS_FIELD_ADDRESS_LEVEL_1; - break; - case i18n::addressinput::LOCALITY: - component.field = - autofill_private::AddressField::ADDRESS_FIELD_ADDRESS_LEVEL_2; - break; - case i18n::addressinput::DEPENDENT_LOCALITY: - component.field = - autofill_private::AddressField::ADDRESS_FIELD_ADDRESS_LEVEL_3; - break; - case i18n::addressinput::SORTING_CODE: - component.field = - autofill_private::AddressField::ADDRESS_FIELD_SORTING_CODE; - break; - case i18n::addressinput::POSTAL_CODE: - component.field = - autofill_private::AddressField::ADDRESS_FIELD_POSTAL_CODE; - break; - case i18n::addressinput::STREET_ADDRESS: - component.field = - autofill_private::AddressField::ADDRESS_FIELD_ADDRESS_LINES; - break; - case i18n::addressinput::ORGANIZATION: - component.field = - autofill_private::AddressField::ADDRESS_FIELD_COMPANY_NAME; - break; - case i18n::addressinput::RECIPIENT: - component.field = - autofill_private::AddressField::ADDRESS_FIELD_FULL_NAME; - break; - } - - switch (components[i].length_hint) { - case addressinput::AddressUiComponent::HINT_LONG: - component.is_long_field = true; - break; - case addressinput::AddressUiComponent::HINT_SHORT: - component.is_long_field = false; - break; - } - - row->row.push_back(std::move(component)); - } -} - // Searches the |list| for the value at |index|. If this value is present in // any of the rest of the list, then the item (at |index|) is removed. The // comparison of phone number values is done on normalized versions of the phone @@ -294,6 +191,7 @@ ExtensionFunction::ResponseAction AutofillPrivateSaveAddressFunction::Run() { profile.set_language_code(*address->language_code); if (use_existing_profile) { + profile.set_origin(kSettingsOrigin); personal_data->UpdateProfile(profile); } else { personal_data->AddProfile(profile); @@ -343,13 +241,28 @@ ExtensionFunction::ResponseAction api::autofill_private::GetAddressComponents::Params::Create(*args_); EXTENSION_FUNCTION_VALIDATE(parameters.get()); - autofill_private::AddressComponents components; - PopulateAddressComponents( - parameters->country_code, - g_browser_process->GetApplicationLocale(), - &components); + auto components = std::make_unique<base::ListValue>(); + std::string language_code_; + + autofill::GetAddressComponents(parameters->country_code, + g_browser_process->GetApplicationLocale(), + components.get(), &language_code_); + + // Convert ListValue to AddressComponents + base::Value address_components(base::Value::Type::DICTIONARY); + base::Value rows(base::Value::Type::LIST); + + for (auto& component : components->GetList()) { + base::Value row(base::Value::Type::DICTIONARY); + row.SetKey("row", std::move(component)); + rows.GetList().emplace_back(std::move(row)); + } + + address_components.SetKey("components", std::move(rows)); + address_components.SetKey("languageCode", base::Value(language_code_)); - return RespondNow(OneArgument(components.ToValue())); + return RespondNow(OneArgument( + base::Value::ToUniquePtrValue(std::move(address_components)))); } //////////////////////////////////////////////////////////////////////////////// diff --git a/chromium/chrome/browser/extensions/api/autofill_private/autofill_private_event_router_factory.h b/chromium/chrome/browser/extensions/api/autofill_private/autofill_private_event_router_factory.h index 7870d8dd158..861c769550a 100644 --- a/chromium/chrome/browser/extensions/api/autofill_private/autofill_private_event_router_factory.h +++ b/chromium/chrome/browser/extensions/api/autofill_private/autofill_private_event_router_factory.h @@ -28,7 +28,7 @@ class AutofillPrivateEventRouterFactory static AutofillPrivateEventRouterFactory* GetInstance(); protected: - // BrowserContextKeyedBaseFactory overrides: + // BrowserContextKeyedServiceFactory overrides: content::BrowserContext* GetBrowserContextToUse( content::BrowserContext* context) const override; bool ServiceIsCreatedWithBrowserContext() const override; diff --git a/chromium/chrome/browser/extensions/api/autofill_private/autofill_util.cc b/chromium/chrome/browser/extensions/api/autofill_private/autofill_util.cc index 157f6c089b9..cbe58c41776 100644 --- a/chromium/chrome/browser/extensions/api/autofill_private/autofill_util.cc +++ b/chromium/chrome/browser/extensions/api/autofill_private/autofill_util.cc @@ -16,12 +16,12 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/common/extensions/api/autofill_private.h" #include "chrome/common/pref_names.h" -#include "components/autofill/core/browser/autofill_country.h" -#include "components/autofill/core/browser/autofill_profile.h" #include "components/autofill/core/browser/autofill_type.h" -#include "components/autofill/core/browser/country_combobox_model.h" -#include "components/autofill/core/browser/credit_card.h" +#include "components/autofill/core/browser/data_model/autofill_profile.h" +#include "components/autofill/core/browser/data_model/credit_card.h" #include "components/autofill/core/browser/field_types.h" +#include "components/autofill/core/browser/geo/autofill_country.h" +#include "components/autofill/core/browser/ui/country_combobox_model.h" #include "components/prefs/pref_service.h" #include "components/strings/grit/components_strings.h" #include "ui/base/l10n/l10n_util.h" diff --git a/chromium/chrome/browser/extensions/api/automation/DEPS b/chromium/chrome/browser/extensions/api/automation/DEPS deleted file mode 100644 index d9e08971f94..00000000000 --- a/chromium/chrome/browser/extensions/api/automation/DEPS +++ /dev/null @@ -1,6 +0,0 @@ -specific_include_rules = { - "automation_apitest\.cc": [ - "+ash/accelerators/accelerator_controller.h", - "+ash/shell.h", - ] -} diff --git a/chromium/chrome/browser/extensions/api/automation/automation_apitest.cc b/chromium/chrome/browser/extensions/api/automation/automation_apitest.cc index 8728681ad5e..bb1a099e82a 100644 --- a/chromium/chrome/browser/extensions/api/automation/automation_apitest.cc +++ b/chromium/chrome/browser/extensions/api/automation/automation_apitest.cc @@ -11,13 +11,11 @@ #include "base/test/scoped_feature_list.h" #include "base/threading/thread_task_runner_handle.h" #include "build/build_config.h" -#include "chrome/browser/extensions/api/automation_internal/automation_event_router.h" #include "chrome/browser/extensions/chrome_extension_function.h" #include "chrome/browser/extensions/extension_apitest.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/chrome_switches.h" -#include "chrome/common/extensions/api/automation_internal.h" #include "chrome/common/extensions/chrome_extension_messages.h" #include "chrome/common/pref_names.h" #include "chrome/test/base/ui_test_utils.h" @@ -27,6 +25,8 @@ #include "content/public/browser/render_widget_host_view.h" #include "content/public/browser/web_contents.h" #include "content/public/common/content_features.h" +#include "extensions/browser/api/automation_internal/automation_event_router.h" +#include "extensions/common/api/automation_internal.h" #include "extensions/test/extension_test_message_listener.h" #include "net/dns/mock_host_resolver.h" #include "net/test/embedded_test_server/embedded_test_server.h" @@ -37,11 +37,11 @@ #include "ui/accessibility/ax_tree.h" #include "ui/accessibility/ax_tree_serializer.h" #include "ui/accessibility/tree_generator.h" +#include "ui/base/accelerators/accelerator.h" #include "ui/display/display_switches.h" #if defined(OS_CHROMEOS) -#include "ash/accelerators/accelerator_controller.h" -#include "ash/shell.h" +#include "ash/public/cpp/accelerators.h" #include "chrome/browser/ui/aura/accessibility/automation_manager_aura.h" #endif @@ -264,8 +264,8 @@ IN_PROC_BROWSER_TEST_F(AutomationApiTest, DISABLED_DesktopHitTestIframe) { IN_PROC_BROWSER_TEST_F(AutomationApiTest, DISABLED_DesktopFocusViews) { AutomationManagerAura::GetInstance()->Enable(); // Trigger the shelf subtree to be computed. - ash::Shell::Get()->accelerator_controller()->PerformActionIfEnabled( - ash::FOCUS_SHELF); + ash::AcceleratorController::Get()->PerformActionIfEnabled(ash::FOCUS_SHELF, + {}); ASSERT_TRUE( RunExtensionSubtest("automation/tests/desktop", "focus_views.html")) @@ -295,8 +295,8 @@ IN_PROC_BROWSER_TEST_F(AutomationApiTest, DesktopNotRequested) { IN_PROC_BROWSER_TEST_F(AutomationApiTest, DISABLED_DesktopActions) { AutomationManagerAura::GetInstance()->Enable(); // Trigger the shelf subtree to be computed. - ash::Shell::Get()->accelerator_controller()->PerformActionIfEnabled( - ash::FOCUS_SHELF); + ash::AcceleratorController::Get()->PerformActionIfEnabled(ash::FOCUS_SHELF, + {}); ASSERT_TRUE(RunExtensionSubtest("automation/tests/desktop", "actions.html")) << message_; diff --git a/chromium/chrome/browser/extensions/api/automation_internal/automation_event_router.cc b/chromium/chrome/browser/extensions/api/automation_internal/automation_event_router.cc deleted file mode 100644 index 892cd3c87c9..00000000000 --- a/chromium/chrome/browser/extensions/api/automation_internal/automation_event_router.cc +++ /dev/null @@ -1,280 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/extensions/api/automation_internal/automation_event_router.h" - -#include <algorithm> -#include <memory> -#include <string> -#include <utility> - -#include "base/stl_util.h" -#include "base/values.h" -#include "build/build_config.h" -#include "chrome/browser/profiles/profile_manager.h" -#include "chrome/common/extensions/api/automation_internal.h" -#include "chrome/common/extensions/chrome_extension_messages.h" -#include "content/public/browser/notification_service.h" -#include "content/public/browser/notification_source.h" -#include "content/public/browser/notification_types.h" -#include "content/public/browser/render_process_host.h" -#include "extensions/browser/event_router.h" -#include "extensions/common/extension.h" -#include "extensions/common/extension_messages.h" -#include "ui/accessibility/ax_action_data.h" -#include "ui/accessibility/ax_enums.mojom.h" -#include "ui/accessibility/ax_node_data.h" - -#if defined(USE_AURA) -#include "chrome/browser/ui/aura/accessibility/automation_manager_aura.h" -#endif - -namespace extensions { - -// static -AutomationEventRouter* AutomationEventRouter::GetInstance() { - return base::Singleton< - AutomationEventRouter, - base::LeakySingletonTraits<AutomationEventRouter>>::get(); -} - -AutomationEventRouter::AutomationEventRouter() - : active_profile_(ProfileManager::GetActiveUserProfile()) { - registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_TERMINATED, - content::NotificationService::AllBrowserContextsAndSources()); - registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED, - content::NotificationService::AllBrowserContextsAndSources()); -#if defined(USE_AURA) - // Not reset because |this| is leaked. - AutomationManagerAura::GetInstance()->set_event_bundle_sink(this); -#endif -} - -AutomationEventRouter::~AutomationEventRouter() { -} - -void AutomationEventRouter::RegisterListenerForOneTree( - const ExtensionId& extension_id, - int listener_process_id, - ui::AXTreeID source_ax_tree_id) { - Register(extension_id, - listener_process_id, - source_ax_tree_id, - false); -} - -void AutomationEventRouter::RegisterListenerWithDesktopPermission( - const ExtensionId& extension_id, - int listener_process_id) { - Register(extension_id, listener_process_id, ui::AXTreeIDUnknown(), true); -} - -void AutomationEventRouter::DispatchAccessibilityEvents( - const ExtensionMsg_AccessibilityEventBundleParams& event_bundle) { - if (active_profile_ != ProfileManager::GetActiveUserProfile()) { - active_profile_ = ProfileManager::GetActiveUserProfile(); - UpdateActiveProfile(); - } - - for (const auto& listener : listeners_) { - // Skip listeners that don't want to listen to this tree. - if (!listener.desktop && listener.tree_ids.find(event_bundle.tree_id) == - listener.tree_ids.end()) { - continue; - } - - content::RenderProcessHost* rph = - content::RenderProcessHost::FromID(listener.process_id); - rph->Send(new ExtensionMsg_AccessibilityEventBundle( - event_bundle, listener.is_active_profile)); - } -} - -void AutomationEventRouter::DispatchAccessibilityLocationChange( - const ExtensionMsg_AccessibilityLocationChangeParams& params) { - for (const auto& listener : listeners_) { - // Skip listeners that don't want to listen to this tree. - if (!listener.desktop && - listener.tree_ids.find(params.tree_id) == listener.tree_ids.end()) { - continue; - } - - content::RenderProcessHost* rph = - content::RenderProcessHost::FromID(listener.process_id); - rph->Send(new ExtensionMsg_AccessibilityLocationChange(params)); - } -} - -void AutomationEventRouter::DispatchTreeDestroyedEvent( - ui::AXTreeID tree_id, - content::BrowserContext* browser_context) { - if (listeners_.empty()) - return; - - browser_context = browser_context ? browser_context : active_profile_; - std::unique_ptr<base::ListValue> args( - api::automation_internal::OnAccessibilityTreeDestroyed::Create( - tree_id.ToString())); - auto event = std::make_unique<Event>( - events::AUTOMATION_INTERNAL_ON_ACCESSIBILITY_TREE_DESTROYED, - api::automation_internal::OnAccessibilityTreeDestroyed::kEventName, - std::move(args), browser_context); - EventRouter::Get(browser_context)->BroadcastEvent(std::move(event)); - - if (tree_destroyed_callback_for_test_) - tree_destroyed_callback_for_test_.Run(tree_id); -} - -void AutomationEventRouter::DispatchActionResult(const ui::AXActionData& data, - bool result) { - CHECK(!data.source_extension_id.empty()); - - if (listeners_.empty()) - return; - - std::unique_ptr<base::ListValue> args( - api::automation_internal::OnActionResult::Create( - data.target_tree_id.ToString(), data.request_id, result)); - auto event = std::make_unique<Event>( - events::AUTOMATION_INTERNAL_ON_ACTION_RESULT, - api::automation_internal::OnActionResult::kEventName, std::move(args), - active_profile_); - EventRouter::Get(active_profile_) - ->DispatchEventToExtension(data.source_extension_id, std::move(event)); -} - -void AutomationEventRouter::SetTreeDestroyedCallbackForTest( - base::RepeatingCallback<void(ui::AXTreeID)> cb) { - tree_destroyed_callback_for_test_ = cb; -} - -void AutomationEventRouter::DispatchGetTextLocationDataResult( - const ui::AXActionData& data, - const base::Optional<gfx::Rect>& rect) { - CHECK(!data.source_extension_id.empty()); - - if (listeners_.empty()) - return; - extensions::api::automation_internal::AXTextLocationParams params; - params.tree_id = data.target_tree_id.ToString(); - params.node_id = data.target_node_id; - params.result = false; - if (rect) { - params.left = rect.value().x(); - params.top = rect.value().y(); - params.width = rect.value().width(); - params.height = rect.value().height(); - params.result = true; - } - params.request_id = data.request_id; - - std::unique_ptr<base::ListValue> args( - api::automation_internal::OnGetTextLocationResult::Create(params)); - auto event = std::make_unique<Event>( - events::AUTOMATION_INTERNAL_ON_GET_TEXT_LOCATION_RESULT, - api::automation_internal::OnGetTextLocationResult::kEventName, - std::move(args), active_profile_); - EventRouter::Get(active_profile_) - ->DispatchEventToExtension(data.source_extension_id, std::move(event)); -} - -AutomationEventRouter::AutomationListener::AutomationListener() { -} - -AutomationEventRouter::AutomationListener::AutomationListener( - const AutomationListener& other) = default; - -AutomationEventRouter::AutomationListener::~AutomationListener() { -} - -void AutomationEventRouter::Register(const ExtensionId& extension_id, - int listener_process_id, - ui::AXTreeID ax_tree_id, - bool desktop) { - DCHECK(desktop || ax_tree_id != ui::AXTreeIDUnknown()); - auto iter = - std::find_if(listeners_.begin(), listeners_.end(), - [listener_process_id](const AutomationListener& item) { - return item.process_id == listener_process_id; - }); - - // Add a new entry if we don't have one with that process. - if (iter == listeners_.end()) { - AutomationListener listener; - listener.extension_id = extension_id; - listener.process_id = listener_process_id; - listener.desktop = desktop; - if (!desktop) - listener.tree_ids.insert(ax_tree_id); - listeners_.push_back(listener); - UpdateActiveProfile(); - return; - } - - // We have an entry with that process so update the set of tree ids it wants - // to listen to, and update its desktop permission. - if (desktop) - iter->desktop = true; - else - iter->tree_ids.insert(ax_tree_id); -} - -void AutomationEventRouter::DispatchAccessibilityEvents( - const ui::AXTreeID& tree_id, - std::vector<ui::AXTreeUpdate> updates, - const gfx::Point& mouse_location, - std::vector<ui::AXEvent> events) { - ExtensionMsg_AccessibilityEventBundleParams event_bundle; - event_bundle.tree_id = tree_id; - event_bundle.updates = std::move(updates); - event_bundle.mouse_location = mouse_location; - event_bundle.events = std::move(events); - - DispatchAccessibilityEvents(event_bundle); -} - -void AutomationEventRouter::Observe( - int type, - const content::NotificationSource& source, - const content::NotificationDetails& details) { - if (type != content::NOTIFICATION_RENDERER_PROCESS_TERMINATED && - type != content::NOTIFICATION_RENDERER_PROCESS_CLOSED) { - NOTREACHED(); - return; - } - - content::RenderProcessHost* rph = - content::Source<content::RenderProcessHost>(source).ptr(); - int process_id = rph->GetID(); - base::EraseIf(listeners_, [process_id](const AutomationListener& item) { - return item.process_id == process_id; - }); - UpdateActiveProfile(); -} - -void AutomationEventRouter::UpdateActiveProfile() { - for (auto& listener : listeners_) { -#if defined(OS_CHROMEOS) - int extension_id_count = 0; - for (const auto& listener2 : listeners_) { - if (listener2.extension_id == listener.extension_id) - extension_id_count++; - } - content::RenderProcessHost* rph = - content::RenderProcessHost::FromID(listener.process_id); - - // The purpose of is_active_profile is to ensure different instances of - // the same extension running in different profiles don't interfere with - // one another. If an automation extension is only running in one profile, - // always mark it as active. If it's running in two or more profiles, - // only mark one as active. - listener.is_active_profile = (extension_id_count == 1 || - rph->GetBrowserContext() == active_profile_); -#else - listener.is_active_profile = true; -#endif - } -} - -} // namespace extensions diff --git a/chromium/chrome/browser/extensions/api/automation_internal/automation_event_router.h b/chromium/chrome/browser/extensions/api/automation_internal/automation_event_router.h deleted file mode 100644 index cda183d432d..00000000000 --- a/chromium/chrome/browser/extensions/api/automation_internal/automation_event_router.h +++ /dev/null @@ -1,137 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_EXTENSIONS_API_AUTOMATION_INTERNAL_AUTOMATION_EVENT_ROUTER_H_ -#define CHROME_BROWSER_EXTENSIONS_API_AUTOMATION_INTERNAL_AUTOMATION_EVENT_ROUTER_H_ - -#include <set> -#include <vector> - -#include "base/callback_forward.h" -#include "base/macros.h" -#include "base/memory/singleton.h" -#include "chrome/common/extensions/api/automation_internal.h" -#include "content/public/browser/ax_event_notification_details.h" -#include "content/public/browser/notification_observer.h" -#include "content/public/browser/notification_registrar.h" -#include "extensions/common/extension_id.h" -#include "extensions/common/extension_messages.h" -#include "ui/accessibility/ax_event_bundle_sink.h" -#include "ui/accessibility/ax_tree_id.h" - -class Profile; - -namespace content { -class BrowserContext; -} // namespace content - -namespace ui { -struct AXActionData; -} // namespace ui - -struct ExtensionMsg_AccessibilityEventBundleParams; -struct ExtensionMsg_AccessibilityLocationChangeParams; - -namespace extensions { -struct AutomationListener; - -class AutomationEventRouter : public ui::AXEventBundleSink, - public content::NotificationObserver { - public: - static AutomationEventRouter* GetInstance(); - - // Indicates that the listener at |listener_process_id| wants to receive - // automation events from the accessibility tree indicated by - // |source_ax_tree_id|. Automation events are forwarded from now on until the - // listener process dies. - void RegisterListenerForOneTree(const ExtensionId& extension_id, - int listener_process_id, - ui::AXTreeID source_ax_tree_id); - - // Indicates that the listener at |listener_process_id| wants to receive - // automation events from all accessibility trees because it has Desktop - // permission. - void RegisterListenerWithDesktopPermission(const ExtensionId& extension_id, - int listener_process_id); - - void DispatchAccessibilityEvents( - const ExtensionMsg_AccessibilityEventBundleParams& events); - - void DispatchAccessibilityLocationChange( - const ExtensionMsg_AccessibilityLocationChangeParams& params); - - // Notify all automation extensions that an accessibility tree was - // destroyed. If |browser_context| is null, - void DispatchTreeDestroyedEvent(ui::AXTreeID tree_id, - content::BrowserContext* browser_context); - - // Notify the source extension of the action of an action result. - void DispatchActionResult(const ui::AXActionData& data, bool result); - - void SetTreeDestroyedCallbackForTest( - base::RepeatingCallback<void(ui::AXTreeID)> cb); - - // Notify the source extension of the result to getTextLocation. - void DispatchGetTextLocationDataResult(const ui::AXActionData& data, - const base::Optional<gfx::Rect>& rect); - - private: - struct AutomationListener { - AutomationListener(); - AutomationListener(const AutomationListener& other); - ~AutomationListener(); - - ExtensionId extension_id; - int process_id; - bool desktop; - std::set<ui::AXTreeID> tree_ids; - bool is_active_profile; - }; - - AutomationEventRouter(); - ~AutomationEventRouter() override; - - void Register(const ExtensionId& extension_id, - int listener_process_id, - ui::AXTreeID source_ax_tree_id, - bool desktop); - - // ui::AXEventBundleSink: - void DispatchAccessibilityEvents(const ui::AXTreeID& tree_id, - std::vector<ui::AXTreeUpdate> updates, - const gfx::Point& mouse_location, - std::vector<ui::AXEvent> events) override; - - // content::NotificationObserver interface. - void Observe(int type, - const content::NotificationSource& source, - const content::NotificationDetails& details) override; - - // Called when the user switches profiles or when a listener is added - // or removed. The purpose is to ensure that multiple instances of the - // same extension running in different profiles don't interfere with one - // another, so in that case only the one associated with the active profile - // is marked as active. - // - // This is needed on Chrome OS because ChromeVox loads into the login profile - // in addition to the active profile. If a similar fix is needed on other - // platforms, we'd need an equivalent of SessionStateObserver that works - // everywhere. - void UpdateActiveProfile(); - - content::NotificationRegistrar registrar_; - std::vector<AutomationListener> listeners_; - - Profile* active_profile_; - - base::RepeatingCallback<void(ui::AXTreeID)> tree_destroyed_callback_for_test_; - - friend struct base::DefaultSingletonTraits<AutomationEventRouter>; - - DISALLOW_COPY_AND_ASSIGN(AutomationEventRouter); -}; - -} // namespace extensions - -#endif // CHROME_BROWSER_EXTENSIONS_API_AUTOMATION_INTERNAL_AUTOMATION_EVENT_ROUTER_H_ diff --git a/chromium/chrome/browser/extensions/api/automation_internal/automation_internal_api.cc b/chromium/chrome/browser/extensions/api/automation_internal/automation_internal_api.cc deleted file mode 100644 index e7970e28a32..00000000000 --- a/chromium/chrome/browser/extensions/api/automation_internal/automation_internal_api.cc +++ /dev/null @@ -1,652 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/extensions/api/automation_internal/automation_internal_api.h" - -#include <stdint.h> - -#include <memory> -#include <vector> - -#include "base/bind.h" -#include "base/macros.h" -#include "base/strings/string16.h" -#include "base/strings/string_number_conversions.h" -#include "base/strings/utf_string_conversions.h" -#include "chrome/browser/extensions/api/automation_internal/automation_event_router.h" -#include "chrome/browser/extensions/api/tabs/tabs_constants.h" -#include "chrome/browser/extensions/chrome_extension_function_details.h" -#include "chrome/browser/extensions/extension_tab_util.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/ui/browser.h" -#include "chrome/browser/ui/tabs/tab_strip_model.h" -#include "chrome/common/extensions/api/automation.h" -#include "chrome/common/extensions/api/automation_internal.h" -#include "chrome/common/extensions/chrome_extension_messages.h" -#include "content/public/browser/ax_event_notification_details.h" -#include "content/public/browser/browser_accessibility_state.h" -#include "content/public/browser/browser_context.h" -#include "content/public/browser/browser_plugin_guest_manager.h" -#include "content/public/browser/media_player_id.h" -#include "content/public/browser/media_session.h" -#include "content/public/browser/render_frame_host.h" -#include "content/public/browser/render_process_host.h" -#include "content/public/browser/render_widget_host.h" -#include "content/public/browser/render_widget_host_view.h" -#include "content/public/browser/web_contents.h" -#include "content/public/browser/web_contents_observer.h" -#include "content/public/browser/web_contents_user_data.h" -#include "extensions/common/extension_messages.h" -#include "extensions/common/manifest_handlers/automation.h" -#include "extensions/common/permissions/permissions_data.h" -#include "ui/accessibility/ax_action_data.h" -#include "ui/accessibility/ax_action_handler.h" -#include "ui/accessibility/ax_enum_util.h" -#include "ui/accessibility/ax_tree_id_registry.h" - -#if defined(USE_AURA) -#include "chrome/browser/ui/aura/accessibility/automation_manager_aura.h" -#include "ui/aura/env.h" -#endif - -namespace extensions { -class AutomationWebContentsObserver; -} // namespace extensions - -namespace extensions { - -namespace { - -const char kCannotRequestAutomationOnPage[] = - "Failed request of automation on a page"; -const char kRendererDestroyed[] = "The tab was closed."; -const char kNoDocument[] = "No document."; -const char kNodeDestroyed[] = - "domQuerySelector sent on node which is no longer in the tree."; - -// Handles sending and receiving IPCs for a single querySelector request. On -// creation, sends the request IPC, and is destroyed either when the response is -// received or the renderer is destroyed. -class QuerySelectorHandler : public content::WebContentsObserver { - public: - QuerySelectorHandler( - content::WebContents* web_contents, - int request_id, - int acc_obj_id, - const base::string16& query, - const extensions::AutomationInternalQuerySelectorFunction::Callback& - callback) - : content::WebContentsObserver(web_contents), - request_id_(request_id), - callback_(callback) { - content::RenderFrameHost* rfh = web_contents->GetMainFrame(); - - rfh->Send(new ExtensionMsg_AutomationQuerySelector( - rfh->GetRoutingID(), request_id, acc_obj_id, query)); - } - - ~QuerySelectorHandler() override {} - - bool OnMessageReceived(const IPC::Message& message, - content::RenderFrameHost* render_frame_host) override { - if (message.type() != ExtensionHostMsg_AutomationQuerySelector_Result::ID) - return false; - - // There may be several requests in flight; check this response matches. - int message_request_id = 0; - base::PickleIterator iter(message); - if (!iter.ReadInt(&message_request_id)) - return false; - - if (message_request_id != request_id_) - return false; - - IPC_BEGIN_MESSAGE_MAP(QuerySelectorHandler, message) - IPC_MESSAGE_HANDLER(ExtensionHostMsg_AutomationQuerySelector_Result, - OnQueryResponse) - IPC_END_MESSAGE_MAP() - return true; - } - - void WebContentsDestroyed() override { - callback_.Run(kRendererDestroyed, 0); - delete this; - } - - private: - void OnQueryResponse(int request_id, - ExtensionHostMsg_AutomationQuerySelector_Error error, - int result_acc_obj_id) { - std::string error_string; - switch (error.value) { - case ExtensionHostMsg_AutomationQuerySelector_Error::kNone: - break; - case ExtensionHostMsg_AutomationQuerySelector_Error::kNoDocument: - error_string = kNoDocument; - break; - case ExtensionHostMsg_AutomationQuerySelector_Error::kNodeDestroyed: - error_string = kNodeDestroyed; - break; - } - callback_.Run(error_string, result_acc_obj_id); - delete this; - } - - int request_id_; - const extensions::AutomationInternalQuerySelectorFunction::Callback callback_; -}; - -bool CanRequestAutomation(const Extension* extension, - const AutomationInfo* automation_info, - content::WebContents* contents) { - if (automation_info->desktop) - return true; - - const GURL& url = contents->GetURL(); - // TODO(aboxhall): check for webstore URL - if (automation_info->matches.MatchesURL(url)) - return true; - - int tab_id = ExtensionTabUtil::GetTabId(contents); - std::string unused_error; - return extension->permissions_data()->CanAccessPage(url, tab_id, - &unused_error); -} - -} // namespace - -// Helper class that receives accessibility data from |WebContents|. -class AutomationWebContentsObserver - : public content::WebContentsObserver, - public content::WebContentsUserData<AutomationWebContentsObserver> { - public: - ~AutomationWebContentsObserver() override {} - - // content::WebContentsObserver overrides. - void AccessibilityEventReceived(const content::AXEventNotificationDetails& - content_event_bundle) override { - ExtensionMsg_AccessibilityEventBundleParams extension_event_bundle; - extension_event_bundle.updates = content_event_bundle.updates; - extension_event_bundle.events = content_event_bundle.events; - extension_event_bundle.tree_id = content_event_bundle.ax_tree_id; -#if defined(USE_AURA) - extension_event_bundle.mouse_location = - aura::Env::GetInstance()->last_mouse_location(); -#endif - AutomationEventRouter* router = AutomationEventRouter::GetInstance(); - router->DispatchAccessibilityEvents(extension_event_bundle); - } - - void AccessibilityLocationChangesReceived( - const std::vector<content::AXLocationChangeNotificationDetails>& details) - override { - for (const auto& src : details) { - ExtensionMsg_AccessibilityLocationChangeParams dst; - dst.id = src.id; - dst.tree_id = src.ax_tree_id; - dst.new_location = src.new_location; - AutomationEventRouter* router = AutomationEventRouter::GetInstance(); - router->DispatchAccessibilityLocationChange(dst); - } - } - - void RenderFrameDeleted( - content::RenderFrameHost* render_frame_host) override { - ui::AXTreeID tree_id = render_frame_host->GetAXTreeID(); - if (tree_id == ui::AXTreeIDUnknown()) - return; - - AutomationEventRouter::GetInstance()->DispatchTreeDestroyedEvent( - tree_id, - browser_context_); - } - - void RenderFrameHostChanged(content::RenderFrameHost* old_host, - content::RenderFrameHost* new_host) override { - if (!old_host) - return; - - ui::AXTreeID tree_id = old_host->GetAXTreeID(); - if (tree_id == ui::AXTreeIDUnknown()) - return; - - AutomationEventRouter::GetInstance()->DispatchTreeDestroyedEvent( - tree_id, browser_context_); - } - - void MediaStartedPlaying(const MediaPlayerInfo& video_type, - const content::MediaPlayerId& id) override { - content::AXEventNotificationDetails content_event_bundle; - content_event_bundle.ax_tree_id = id.render_frame_host->GetAXTreeID(); - content_event_bundle.events.resize(1); - content_event_bundle.events[0].event_type = - ax::mojom::Event::kMediaStartedPlaying; - AccessibilityEventReceived(content_event_bundle); - } - - void MediaStoppedPlaying( - const MediaPlayerInfo& video_type, - const content::MediaPlayerId& id, - WebContentsObserver::MediaStoppedReason reason) override { - content::AXEventNotificationDetails content_event_bundle; - content_event_bundle.ax_tree_id = id.render_frame_host->GetAXTreeID(); - content_event_bundle.events.resize(1); - content_event_bundle.events[0].event_type = - ax::mojom::Event::kMediaStoppedPlaying; - AccessibilityEventReceived(content_event_bundle); - } - - private: - friend class content::WebContentsUserData<AutomationWebContentsObserver>; - - explicit AutomationWebContentsObserver(content::WebContents* web_contents) - : content::WebContentsObserver(web_contents), - browser_context_(web_contents->GetBrowserContext()) { - if (web_contents->IsCurrentlyAudible()) { - content::RenderFrameHost* rfh = web_contents->GetMainFrame(); - if (!rfh) - return; - - content::AXEventNotificationDetails content_event_bundle; - content_event_bundle.ax_tree_id = rfh->GetAXTreeID(); - content_event_bundle.events.resize(1); - content_event_bundle.events[0].event_type = - ax::mojom::Event::kMediaStartedPlaying; - AccessibilityEventReceived(content_event_bundle); - } - } - - content::BrowserContext* browser_context_; - - WEB_CONTENTS_USER_DATA_KEY_DECL(); - - DISALLOW_COPY_AND_ASSIGN(AutomationWebContentsObserver); -}; - -WEB_CONTENTS_USER_DATA_KEY_IMPL(AutomationWebContentsObserver) - -ExtensionFunction::ResponseAction -AutomationInternalEnableTabFunction::Run() { - const AutomationInfo* automation_info = AutomationInfo::Get(extension()); - EXTENSION_FUNCTION_VALIDATE(automation_info); - - using api::automation_internal::EnableTab::Params; - std::unique_ptr<Params> params(Params::Create(*args_)); - EXTENSION_FUNCTION_VALIDATE(params.get()); - content::WebContents* contents = NULL; - int tab_id = -1; - if (params->args.tab_id.get()) { - tab_id = *params->args.tab_id; - if (!ExtensionTabUtil::GetTabById( - tab_id, browser_context(), include_incognito_information(), - NULL, /* browser out param*/ - NULL, /* tab_strip out param */ - &contents, NULL /* tab_index out param */)) { - return RespondNow(Error(tabs_constants::kTabNotFoundError, - base::NumberToString(tab_id))); - } - } else { - contents = ChromeExtensionFunctionDetails(this) - .GetCurrentBrowser() - ->tab_strip_model() - ->GetActiveWebContents(); - if (!contents) - return RespondNow(Error("No active tab")); - - tab_id = ExtensionTabUtil::GetTabId(contents); - } - - content::RenderFrameHost* rfh = contents->GetMainFrame(); - if (!rfh) - return RespondNow(Error("Could not enable accessibility for active tab")); - - if (!CanRequestAutomation(extension(), automation_info, contents)) { - return RespondNow(Error(kCannotRequestAutomationOnPage)); - } - - AutomationWebContentsObserver::CreateForWebContents(contents); - contents->EnableWebContentsOnlyAccessibilityMode(); - - ui::AXTreeID ax_tree_id = rfh->GetAXTreeID(); - - // This gets removed when the extension process dies. - AutomationEventRouter::GetInstance()->RegisterListenerForOneTree( - extension_id(), - source_process_id(), - ax_tree_id); - - return RespondNow( - ArgumentList(api::automation_internal::EnableTab::Results::Create( - ax_tree_id.ToString(), tab_id))); -} - -ExtensionFunction::ResponseAction AutomationInternalEnableFrameFunction::Run() { - // TODO(dtseng): Limited to desktop tree for now pending out of proc iframes. - using api::automation_internal::EnableFrame::Params; - - std::unique_ptr<Params> params(Params::Create(*args_)); - EXTENSION_FUNCTION_VALIDATE(params.get()); - - ui::AXTreeID ax_tree_id = ui::AXTreeID::FromString(params->tree_id); - ui::AXTreeIDRegistry* registry = ui::AXTreeIDRegistry::GetInstance(); - ui::AXActionHandler* action_handler = registry->GetActionHandler(ax_tree_id); - if (action_handler) { - // Explicitly invalidate the pre-existing source tree first. This ensures - // the source tree sends a complete tree when the next event occurs. This - // is required whenever the client extension is reloaded. - ui::AXActionData action; - action.target_tree_id = ax_tree_id; - action.source_extension_id = extension_id(); - action.action = ax::mojom::Action::kInternalInvalidateTree; - action_handler->PerformAction(action); - } - - content::RenderFrameHost* rfh = - content::RenderFrameHost::FromAXTreeID(ax_tree_id); - if (!rfh) - return RespondNow(Error("unable to load tab")); - - content::WebContents* contents = - content::WebContents::FromRenderFrameHost(rfh); - AutomationWebContentsObserver::CreateForWebContents(contents); - - // Only call this if this is the root of a frame tree, to avoid resetting - // the accessibility state multiple times. - if (!rfh->GetParent()) - contents->EnableWebContentsOnlyAccessibilityMode(); - - return RespondNow(NoArguments()); -} - -ExtensionFunction::ResponseAction -AutomationInternalPerformActionFunction::ConvertToAXActionData( - api::automation_internal::PerformAction::Params* params, - ui::AXActionData* action) { - action->target_tree_id = ui::AXTreeID::FromString(params->args.tree_id); - action->source_extension_id = extension_id(); - action->target_node_id = params->args.automation_node_id; - int* request_id = params->args.request_id.get(); - action->request_id = request_id ? *request_id : -1; - api::automation::ActionType action_type = - api::automation::ParseActionType(params->args.action_type); - switch (action_type) { - case api::automation::ACTION_TYPE_BLUR: - action->action = ax::mojom::Action::kBlur; - break; - case api::automation::ACTION_TYPE_CLEARACCESSIBILITYFOCUS: - action->action = ax::mojom::Action::kClearAccessibilityFocus; - break; - case api::automation::ACTION_TYPE_DECREMENT: - action->action = ax::mojom::Action::kDecrement; - break; - case api::automation::ACTION_TYPE_DODEFAULT: - action->action = ax::mojom::Action::kDoDefault; - break; - case api::automation::ACTION_TYPE_INCREMENT: - action->action = ax::mojom::Action::kIncrement; - break; - case api::automation::ACTION_TYPE_FOCUS: - action->action = ax::mojom::Action::kFocus; - break; - case api::automation::ACTION_TYPE_GETIMAGEDATA: { - api::automation_internal::GetImageDataParams get_image_data_params; - EXTENSION_FUNCTION_VALIDATE( - api::automation_internal::GetImageDataParams::Populate( - params->opt_args.additional_properties, &get_image_data_params)); - action->action = ax::mojom::Action::kGetImageData; - action->target_rect = gfx::Rect(0, 0, get_image_data_params.max_width, - get_image_data_params.max_height); - break; - } - case api::automation::ACTION_TYPE_HITTEST: { - api::automation_internal::HitTestParams hit_test_params; - EXTENSION_FUNCTION_VALIDATE( - api::automation_internal::HitTestParams::Populate( - params->opt_args.additional_properties, &hit_test_params)); - action->action = ax::mojom::Action::kHitTest; - action->target_point = gfx::Point(hit_test_params.x, hit_test_params.y); - action->hit_test_event_to_fire = - ui::ParseEvent(hit_test_params.event_to_fire.c_str()); - if (action->hit_test_event_to_fire == ax::mojom::Event::kNone) - return RespondNow(NoArguments()); - break; - } - case api::automation::ACTION_TYPE_LOADINLINETEXTBOXES: - action->action = ax::mojom::Action::kLoadInlineTextBoxes; - break; - case api::automation::ACTION_TYPE_SETACCESSIBILITYFOCUS: - action->action = ax::mojom::Action::kSetAccessibilityFocus; - break; - case api::automation::ACTION_TYPE_SCROLLTOMAKEVISIBLE: - action->action = ax::mojom::Action::kScrollToMakeVisible; - break; - case api::automation::ACTION_TYPE_SCROLLBACKWARD: - action->action = ax::mojom::Action::kScrollBackward; - break; - case api::automation::ACTION_TYPE_SCROLLFORWARD: - action->action = ax::mojom::Action::kScrollForward; - break; - case api::automation::ACTION_TYPE_SCROLLUP: - action->action = ax::mojom::Action::kScrollUp; - break; - case api::automation::ACTION_TYPE_SCROLLDOWN: - action->action = ax::mojom::Action::kScrollDown; - break; - case api::automation::ACTION_TYPE_SCROLLLEFT: - action->action = ax::mojom::Action::kScrollLeft; - break; - case api::automation::ACTION_TYPE_SCROLLRIGHT: - action->action = ax::mojom::Action::kScrollRight; - break; - case api::automation::ACTION_TYPE_SETSELECTION: { - api::automation_internal::SetSelectionParams selection_params; - EXTENSION_FUNCTION_VALIDATE( - api::automation_internal::SetSelectionParams::Populate( - params->opt_args.additional_properties, &selection_params)); - action->anchor_node_id = params->args.automation_node_id; - action->anchor_offset = selection_params.anchor_offset; - action->focus_node_id = selection_params.focus_node_id; - action->focus_offset = selection_params.focus_offset; - action->action = ax::mojom::Action::kSetSelection; - break; - } - case api::automation::ACTION_TYPE_SHOWCONTEXTMENU: { - action->action = ax::mojom::Action::kShowContextMenu; - break; - } - case api::automation:: - ACTION_TYPE_SETSEQUENTIALFOCUSNAVIGATIONSTARTINGPOINT: { - action->action = - ax::mojom::Action::kSetSequentialFocusNavigationStartingPoint; - break; - } - case api::automation::ACTION_TYPE_CUSTOMACTION: { - api::automation_internal::PerformCustomActionParams - perform_custom_action_params; - EXTENSION_FUNCTION_VALIDATE( - api::automation_internal::PerformCustomActionParams::Populate( - params->opt_args.additional_properties, - &perform_custom_action_params)); - action->action = ax::mojom::Action::kCustomAction; - action->custom_action_id = perform_custom_action_params.custom_action_id; - break; - } - case api::automation::ACTION_TYPE_REPLACESELECTEDTEXT: { - api::automation_internal::ReplaceSelectedTextParams - replace_selected_text_params; - EXTENSION_FUNCTION_VALIDATE( - api::automation_internal::ReplaceSelectedTextParams::Populate( - params->opt_args.additional_properties, - &replace_selected_text_params)); - action->action = ax::mojom::Action::kReplaceSelectedText; - action->value = replace_selected_text_params.value; - break; - } - case api::automation::ACTION_TYPE_SETVALUE: { - api::automation_internal::SetValueParams set_value_params; - EXTENSION_FUNCTION_VALIDATE( - api::automation_internal::SetValueParams::Populate( - params->opt_args.additional_properties, &set_value_params)); - action->action = ax::mojom::Action::kSetValue; - action->value = set_value_params.value; - break; - } - // These actions are currently unused by any existing clients of - // automation. They also require additional arguments to be plumbed - // through (e.g. setValue takes a string value to be set). Future clients - // may wish to extend the api to support these actions. - case api::automation::ACTION_TYPE_SCROLLTOPOINT: - case api::automation::ACTION_TYPE_SETSCROLLOFFSET: - return RespondNow( - Error("Unsupported action: " + params->args.action_type)); - case api::automation::ACTION_TYPE_GETTEXTLOCATION: { - api::automation_internal::GetTextLocationDataParams - get_text_location_params; - EXTENSION_FUNCTION_VALIDATE( - api::automation_internal::GetTextLocationDataParams::Populate( - params->opt_args.additional_properties, - &get_text_location_params)); - action->action = ax::mojom::Action::kGetTextLocation; - action->start_index = get_text_location_params.start_index; - action->end_index = get_text_location_params.end_index; - break; - } - case api::automation::ACTION_TYPE_SHOWTOOLTIP: - action->action = ax::mojom::Action::kShowTooltip; - break; - case api::automation::ACTION_TYPE_HIDETOOLTIP: - action->action = ax::mojom::Action::kHideTooltip; - break; - case api::automation::ACTION_TYPE_ANNOTATEPAGEIMAGES: - case api::automation::ACTION_TYPE_SIGNALENDOFTEST: - case api::automation::ACTION_TYPE_INTERNALINVALIDATETREE: - case api::automation::ACTION_TYPE_NONE: - break; - } - return RespondNow(NoArguments()); -} - -ExtensionFunction::ResponseAction -AutomationInternalPerformActionFunction::Run() { - const AutomationInfo* automation_info = AutomationInfo::Get(extension()); - EXTENSION_FUNCTION_VALIDATE(automation_info && automation_info->interact); - - using api::automation_internal::PerformAction::Params; - std::unique_ptr<Params> params(Params::Create(*args_)); - EXTENSION_FUNCTION_VALIDATE(params.get()); - ui::AXTreeIDRegistry* registry = ui::AXTreeIDRegistry::GetInstance(); - ui::AXActionHandler* action_handler = registry->GetActionHandler( - ui::AXTreeID::FromString(params->args.tree_id)); - if (action_handler) { - // Handle an AXActionHandler with a rfh first. Some actions require a rfh -> - // web contents and this api requires web contents to perform a permissions - // check. - content::RenderFrameHost* rfh = content::RenderFrameHost::FromAXTreeID( - ui::AXTreeID::FromString(params->args.tree_id)); - if (rfh) { - content::WebContents* contents = - content::WebContents::FromRenderFrameHost(rfh); - if (!CanRequestAutomation(extension(), automation_info, contents)) { - return RespondNow(Error(kCannotRequestAutomationOnPage)); - } - - // Handle internal actions. - api::automation_internal::ActionTypePrivate internal_action_type = - api::automation_internal::ParseActionTypePrivate( - params->args.action_type); - content::MediaSession* session = content::MediaSession::Get(contents); - switch (internal_action_type) { - case api::automation_internal::ACTION_TYPE_PRIVATE_STARTDUCKINGMEDIA: - session->StartDucking(); - return RespondNow(NoArguments()); - case api::automation_internal::ACTION_TYPE_PRIVATE_STOPDUCKINGMEDIA: - session->StopDucking(); - return RespondNow(NoArguments()); - case api::automation_internal::ACTION_TYPE_PRIVATE_RESUMEMEDIA: - session->Resume(content::MediaSession::SuspendType::kSystem); - return RespondNow(NoArguments()); - case api::automation_internal::ACTION_TYPE_PRIVATE_SUSPENDMEDIA: - session->Suspend(content::MediaSession::SuspendType::kSystem); - return RespondNow(NoArguments()); - case api::automation_internal::ACTION_TYPE_PRIVATE_NONE: - // Not a private action. - break; - } - } - - ui::AXActionData data; - ExtensionFunction::ResponseAction result = - ConvertToAXActionData(params.get(), &data); - action_handler->PerformAction(data); - return result; - } - return RespondNow(Error("Unable to perform action on unknown tree.")); -} - -ExtensionFunction::ResponseAction -AutomationInternalEnableDesktopFunction::Run() { -#if defined(USE_AURA) - const AutomationInfo* automation_info = AutomationInfo::Get(extension()); - if (!automation_info || !automation_info->desktop) - return RespondNow(Error("desktop permission must be requested")); - - // This gets removed when the extension process dies. - AutomationEventRouter::GetInstance()->RegisterListenerWithDesktopPermission( - extension_id(), source_process_id()); - - AutomationManagerAura::GetInstance()->Enable(); - ui::AXTreeID ax_tree_id = AutomationManagerAura::GetInstance()->ax_tree_id(); - return RespondNow( - ArgumentList(api::automation_internal::EnableDesktop::Results::Create( - ax_tree_id.ToString()))); -#else - return RespondNow(Error("getDesktop is unsupported by this platform")); -#endif // defined(USE_AURA) -} - -// static -int AutomationInternalQuerySelectorFunction::query_request_id_counter_ = 0; - -ExtensionFunction::ResponseAction -AutomationInternalQuerySelectorFunction::Run() { - const AutomationInfo* automation_info = AutomationInfo::Get(extension()); - EXTENSION_FUNCTION_VALIDATE(automation_info); - - using api::automation_internal::QuerySelector::Params; - std::unique_ptr<Params> params(Params::Create(*args_)); - EXTENSION_FUNCTION_VALIDATE(params.get()); - - content::RenderFrameHost* rfh = content::RenderFrameHost::FromAXTreeID( - ui::AXTreeID::FromString(params->args.tree_id)); - if (!rfh) { - return RespondNow( - Error("domQuerySelector query sent on non-web or destroyed tree.")); - } - - content::WebContents* contents = - content::WebContents::FromRenderFrameHost(rfh); - - int request_id = query_request_id_counter_++; - base::string16 selector = base::UTF8ToUTF16(params->args.selector); - - // QuerySelectorHandler handles IPCs and deletes itself on completion. - new QuerySelectorHandler( - contents, request_id, params->args.automation_node_id, selector, - base::Bind(&AutomationInternalQuerySelectorFunction::OnResponse, this)); - - return RespondLater(); -} - -void AutomationInternalQuerySelectorFunction::OnResponse( - const std::string& error, - int result_acc_obj_id) { - if (!error.empty()) { - Respond(Error(error)); - return; - } - - Respond(OneArgument(std::make_unique<base::Value>(result_acc_obj_id))); -} - -} // namespace extensions diff --git a/chromium/chrome/browser/extensions/api/automation_internal/automation_internal_api.h b/chromium/chrome/browser/extensions/api/automation_internal/automation_internal_api.h deleted file mode 100644 index 8450b3164c3..00000000000 --- a/chromium/chrome/browser/extensions/api/automation_internal/automation_internal_api.h +++ /dev/null @@ -1,101 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_EXTENSIONS_API_AUTOMATION_INTERNAL_AUTOMATION_INTERNAL_API_H_ -#define CHROME_BROWSER_EXTENSIONS_API_AUTOMATION_INTERNAL_AUTOMATION_INTERNAL_API_H_ - -#include <string> - -#include "content/public/browser/web_contents_observer.h" -#include "content/public/browser/web_contents_user_data.h" -#include "extensions/browser/extension_function.h" - -namespace extensions { - -namespace api { -namespace automation_internal { -namespace PerformAction { -struct Params; -} // namespace PerformAction -} // namespace automation_internal -} // namespace api -} // namespace extensions - -namespace ui { -struct AXActionData; -} // namespace ui - -namespace extensions { - -// Implementation of the chrome.automation API. -class AutomationInternalEnableTabFunction : public UIThreadExtensionFunction { - DECLARE_EXTENSION_FUNCTION("automationInternal.enableTab", - AUTOMATIONINTERNAL_ENABLETAB) - protected: - ~AutomationInternalEnableTabFunction() override {} - - ExtensionFunction::ResponseAction Run() override; -}; - -class AutomationInternalPerformActionFunction - : public UIThreadExtensionFunction { - DECLARE_EXTENSION_FUNCTION("automationInternal.performAction", - AUTOMATIONINTERNAL_PERFORMACTION) - protected: - ~AutomationInternalPerformActionFunction() override {} - - ExtensionFunction::ResponseAction Run() override; - - private: - // Helper function to convert extension action to ax action. - ExtensionFunction::ResponseAction ConvertToAXActionData( - api::automation_internal::PerformAction::Params* params, - ui::AXActionData* data); -}; - -class AutomationInternalEnableFrameFunction : public UIThreadExtensionFunction { - DECLARE_EXTENSION_FUNCTION("automationInternal.enableFrame", - AUTOMATIONINTERNAL_ENABLEFRAME) - - protected: - ~AutomationInternalEnableFrameFunction() override {} - - ExtensionFunction::ResponseAction Run() override; -}; - -class AutomationInternalEnableDesktopFunction - : public UIThreadExtensionFunction { - DECLARE_EXTENSION_FUNCTION("automationInternal.enableDesktop", - AUTOMATIONINTERNAL_ENABLEDESKTOP) - protected: - ~AutomationInternalEnableDesktopFunction() override {} - - ResponseAction Run() override; -}; - -class AutomationInternalQuerySelectorFunction - : public UIThreadExtensionFunction { - DECLARE_EXTENSION_FUNCTION("automationInternal.querySelector", - AUTOMATIONINTERNAL_QUERYSELECTOR) - - public: - typedef base::Callback<void(const std::string& error, - int result_acc_obj_id)> Callback; - - protected: - ~AutomationInternalQuerySelectorFunction() override {} - - ResponseAction Run() override; - - private: - void OnResponse(const std::string& error, int result_acc_obj_id); - - // Used for assigning a unique ID to each request so that the response can be - // routed appropriately. - static int query_request_id_counter_; -}; - -} // namespace extensions - -#endif // CHROME_BROWSER_EXTENSIONS_API_AUTOMATION_INTERNAL_AUTOMATION_INTERNAL_API_H_ diff --git a/chromium/chrome/browser/extensions/api/automation_internal/chrome_automation_internal_api_delegate.cc b/chromium/chrome/browser/extensions/api/automation_internal/chrome_automation_internal_api_delegate.cc new file mode 100644 index 00000000000..b33da9fe462 --- /dev/null +++ b/chromium/chrome/browser/extensions/api/automation_internal/chrome_automation_internal_api_delegate.cc @@ -0,0 +1,110 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/extensions/api/automation_internal/chrome_automation_internal_api_delegate.h" + +#include <memory> + +#include "chrome/browser/extensions/api/tabs/tabs_constants.h" +#include "chrome/browser/extensions/chrome_extension_function_details.h" +#include "chrome/browser/extensions/extension_tab_util.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/profiles/profile_manager.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/tabs/tab_strip_model.h" +#include "chrome/common/extensions/chrome_extension_messages.h" +#include "content/public/browser/web_contents.h" +#include "extensions/common/api/automation.h" +#include "extensions/common/api/automation_internal.h" +#include "extensions/common/extension.h" +#include "extensions/common/manifest_handlers/automation.h" +#include "extensions/common/permissions/permissions_data.h" + +#if defined(USE_AURA) +#include "chrome/browser/ui/aura/accessibility/automation_manager_aura.h" +#endif + +namespace extensions { + +ChromeAutomationInternalApiDelegate::ChromeAutomationInternalApiDelegate() {} + +ChromeAutomationInternalApiDelegate::~ChromeAutomationInternalApiDelegate() {} + +bool ChromeAutomationInternalApiDelegate::CanRequestAutomation( + const Extension* extension, + const AutomationInfo* automation_info, + content::WebContents* contents) { + if (automation_info->desktop) + return true; + + const GURL& url = contents->GetURL(); + // TODO(aboxhall): check for webstore URL + if (automation_info->matches.MatchesURL(url)) + return true; + + int tab_id = ExtensionTabUtil::GetTabId(contents); + std::string unused_error; + return extension->permissions_data()->CanAccessPage(url, tab_id, + &unused_error); +} + +bool ChromeAutomationInternalApiDelegate::GetTabById( + int tab_id, + content::BrowserContext* browser_context, + bool include_incognito, + content::WebContents** contents, + std::string* error_msg) { + *error_msg = tabs_constants::kTabNotFoundError; + return ExtensionTabUtil::GetTabById( + tab_id, browser_context, include_incognito, + nullptr, /* browser out param */ + nullptr, /* tab strip out param */ + contents, nullptr /* tab_index out param */); +} + +int ChromeAutomationInternalApiDelegate::GetTabId( + content::WebContents* contents) { + return ExtensionTabUtil::GetTabId(contents); +} + +content::WebContents* ChromeAutomationInternalApiDelegate::GetActiveWebContents( + UIThreadExtensionFunction* function) { + return ChromeExtensionFunctionDetails(function) + .GetCurrentBrowser() + ->tab_strip_model() + ->GetActiveWebContents(); +} + +void ChromeAutomationInternalApiDelegate::EnableDesktop() { +#if defined(USE_AURA) + AutomationManagerAura::GetInstance()->Enable(); +#else + NOTIMPLEMENTED(); +#endif +} + +ui::AXTreeID ChromeAutomationInternalApiDelegate::GetAXTreeID() { +#if defined(USE_AURA) + return AutomationManagerAura::GetInstance()->ax_tree_id(); +#else + NOTIMPLEMENTED(); + return ui::AXTreeIDUnknown(); +#endif +} + +void ChromeAutomationInternalApiDelegate::SetEventBundleSink( + ui::AXEventBundleSink* sink) { +#if defined(USE_AURA) + AutomationManagerAura::GetInstance()->set_event_bundle_sink(sink); +#else + NOTIMPLEMENTED(); +#endif +} + +content::BrowserContext* +ChromeAutomationInternalApiDelegate::GetActiveUserContext() { + return ProfileManager::GetActiveUserProfile(); +} + +} // namespace extensions diff --git a/chromium/chrome/browser/extensions/api/automation_internal/chrome_automation_internal_api_delegate.h b/chromium/chrome/browser/extensions/api/automation_internal/chrome_automation_internal_api_delegate.h new file mode 100644 index 00000000000..474b575dc6e --- /dev/null +++ b/chromium/chrome/browser/extensions/api/automation_internal/chrome_automation_internal_api_delegate.h @@ -0,0 +1,40 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_EXTENSIONS_API_AUTOMATION_INTERNAL_CHROME_AUTOMATION_INTERNAL_API_DELEGATE_H_ +#define CHROME_BROWSER_EXTENSIONS_API_AUTOMATION_INTERNAL_CHROME_AUTOMATION_INTERNAL_API_DELEGATE_H_ + +#include "extensions/browser/api/automation_internal/automation_internal_api_delegate.h" + +namespace extensions { + +// A delegate for chrome specific automation api logic. +class ChromeAutomationInternalApiDelegate + : public AutomationInternalApiDelegate { + public: + ChromeAutomationInternalApiDelegate(); + ~ChromeAutomationInternalApiDelegate() override; + + bool CanRequestAutomation(const Extension* extension, + const AutomationInfo* automation_info, + content::WebContents* contents) override; + bool GetTabById(int tab_id, + content::BrowserContext* browser_context, + bool include_incognito, + content::WebContents** contents, + std::string* error_msg) override; + int GetTabId(content::WebContents* contents) override; + content::WebContents* GetActiveWebContents( + UIThreadExtensionFunction* function) override; + void EnableDesktop() override; + ui::AXTreeID GetAXTreeID() override; + void SetEventBundleSink(ui::AXEventBundleSink* sink) override; + content::BrowserContext* GetActiveUserContext() override; + + DISALLOW_COPY_AND_ASSIGN(ChromeAutomationInternalApiDelegate); +}; + +} // namespace extensions + +#endif // CHROME_BROWSER_EXTENSIONS_API_AUTOMATION_INTERNAL_CHROME_AUTOMATION_INTERNAL_API_DELEGATE_H_ diff --git a/chromium/chrome/browser/extensions/api/bluetooth_low_energy/OWNERS b/chromium/chrome/browser/extensions/api/bluetooth_low_energy/OWNERS index 6a2cb03fd3e..9591b06b237 100644 --- a/chromium/chrome/browser/extensions/api/bluetooth_low_energy/OWNERS +++ b/chromium/chrome/browser/extensions/api/bluetooth_low_energy/OWNERS @@ -1 +1 @@ -rkc@chromium.org +ortuno@chromium.org diff --git a/chromium/chrome/browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_apitest.cc b/chromium/chrome/browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_apitest.cc index a2259e79700..95240d00bc2 100644 --- a/chromium/chrome/browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_apitest.cc +++ b/chromium/chrome/browser/extensions/api/bluetooth_low_energy/bluetooth_low_energy_apitest.cc @@ -225,19 +225,19 @@ class BluetoothLowEnergyApiTest : public extensions::ExtensionApiTest { ACTION_TEMPLATE(InvokeCallbackArgument, HAS_1_TEMPLATE_PARAMS(int, k), AND_0_VALUE_PARAMS()) { - std::get<k>(args).Run(); + std::move(std::get<k>(args)).Run(); } ACTION_TEMPLATE(InvokeCallbackArgument, HAS_1_TEMPLATE_PARAMS(int, k), AND_1_VALUE_PARAMS(p0)) { - std::get<k>(args).Run(p0); + std::move(std::get<k>(args)).Run(p0); } ACTION_TEMPLATE(InvokeCallbackWithScopedPtrArg, HAS_2_TEMPLATE_PARAMS(int, k, typename, T), AND_1_VALUE_PARAMS(p0)) { - std::get<k>(args).Run(std::unique_ptr<T>(p0)); + std::move(std::get<k>(args)).Run(std::unique_ptr<T>(p0)); } BluetoothGattConnection* CreateGattConnection( @@ -658,16 +658,14 @@ IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, CharacteristicValueChanged) { new testing::NiceMock<MockBluetoothGattNotifySession>( chrc2_->GetWeakPtr()); - EXPECT_CALL(*chrc0_, StartNotifySession(_, _)) + EXPECT_CALL(*chrc0_, StartNotifySession_(_, _)) .Times(1) - .WillOnce( - InvokeCallbackWithScopedPtrArg<0, BluetoothGattNotifySession>( - session0)); - EXPECT_CALL(*chrc2_, StartNotifySession(_, _)) + .WillOnce(InvokeCallbackWithScopedPtrArg<0, BluetoothGattNotifySession>( + session0)); + EXPECT_CALL(*chrc2_, StartNotifySession_(_, _)) .Times(1) - .WillOnce( - InvokeCallbackWithScopedPtrArg<0, BluetoothGattNotifySession>( - session1)); + .WillOnce(InvokeCallbackWithScopedPtrArg<0, BluetoothGattNotifySession>( + session1)); ExtensionTestMessageListener listener("ready", true); ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII( @@ -713,7 +711,7 @@ IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, ReadCharacteristicValue) { .WillRepeatedly(Return(chrc0_.get())); std::vector<uint8_t> value; - EXPECT_CALL(*chrc0_, ReadRemoteCharacteristic(_, _)) + EXPECT_CALL(*chrc0_, ReadRemoteCharacteristic_(_, _)) .Times(2) .WillOnce(InvokeCallbackArgument<1>( BluetoothRemoteGattService::GATT_ERROR_FAILED)) @@ -755,7 +753,7 @@ IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, WriteCharacteristicValue) { .WillRepeatedly(Return(chrc0_.get())); std::vector<uint8_t> write_value; - EXPECT_CALL(*chrc0_, WriteRemoteCharacteristic(_, _, _)) + EXPECT_CALL(*chrc0_, WriteRemoteCharacteristic_(_, _, _)) .Times(2) .WillOnce(InvokeCallbackArgument<2>( BluetoothRemoteGattService::GATT_ERROR_FAILED)) @@ -978,7 +976,7 @@ IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, ReadDescriptorValue) { .WillRepeatedly(Return(desc0_.get())); std::vector<uint8_t> value; - EXPECT_CALL(*desc0_, ReadRemoteDescriptor(_, _)) + EXPECT_CALL(*desc0_, ReadRemoteDescriptor_(_, _)) .Times(8) .WillOnce(InvokeCallbackArgument<1>( BluetoothRemoteGattService::GATT_ERROR_FAILED)) @@ -1038,7 +1036,7 @@ IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, WriteDescriptorValue) { .WillRepeatedly(Return(desc0_.get())); std::vector<uint8_t> write_value; - EXPECT_CALL(*desc0_, WriteRemoteDescriptor(_, _, _)) + EXPECT_CALL(*desc0_, WriteRemoteDescriptor_(_, _, _)) .Times(2) .WillOnce(InvokeCallbackArgument<2>( BluetoothRemoteGattService::GATT_ERROR_FAILED)) @@ -1275,21 +1273,20 @@ IN_PROC_BROWSER_TEST_F(BluetoothLowEnergyApiTest, StartStopNotifications) { new testing::NiceMock<MockBluetoothGattNotifySession>( chrc1_->GetWeakPtr()); - EXPECT_CALL(*session1, Stop(_)) + EXPECT_CALL(*session1, Stop_(_)) .Times(1) .WillOnce(InvokeCallbackArgument<0>()); - EXPECT_CALL(*chrc0_, StartNotifySession(_, _)) + EXPECT_CALL(*chrc0_, StartNotifySession_(_, _)) .Times(2) .WillOnce(InvokeCallbackArgument<1>( BluetoothRemoteGattService::GATT_ERROR_FAILED)) .WillOnce(InvokeCallbackWithScopedPtrArg<0, BluetoothGattNotifySession>( session0)); - EXPECT_CALL(*chrc1_, StartNotifySession(_, _)) + EXPECT_CALL(*chrc1_, StartNotifySession_(_, _)) .Times(1) - .WillOnce( - InvokeCallbackWithScopedPtrArg<0, BluetoothGattNotifySession>( - session1)); + .WillOnce(InvokeCallbackWithScopedPtrArg<0, BluetoothGattNotifySession>( + session1)); ExtensionTestMessageListener listener("ready", true); listener.set_failure_message("fail"); diff --git a/chromium/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api.cc b/chromium/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api.cc index 2611f3fb73e..54c5f9eeacc 100644 --- a/chromium/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api.cc +++ b/chromium/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api.cc @@ -16,7 +16,6 @@ #include "base/strings/utf_string_conversions.h" #include "base/values.h" #include "chrome/browser/bookmarks/bookmark_model_factory.h" -#include "chrome/browser/bookmarks/bookmark_stats.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/extensions/api/bookmarks/bookmark_api_constants.h" #include "chrome/browser/extensions/api/bookmarks/bookmark_api_helpers.h" diff --git a/chromium/chrome/browser/extensions/api/bookmarks/bookmark_api_helpers.cc b/chromium/chrome/browser/extensions/api/bookmarks/bookmark_api_helpers.cc index 8b04de249db..4a0be820b9b 100644 --- a/chromium/chrome/browser/extensions/api/bookmarks/bookmark_api_helpers.cc +++ b/chromium/chrome/browser/extensions/api/bookmarks/bookmark_api_helpers.cc @@ -137,7 +137,7 @@ bool RemoveNode(BookmarkModel* model, *error = bookmark_api_constants::kModifyManagedError; return false; } - if (node->is_folder() && !node->empty() && !recursive) { + if (node->is_folder() && !node->children().empty() && !recursive) { *error = bookmark_api_constants::kFolderNotEmptyError; return false; } diff --git a/chromium/chrome/browser/extensions/api/browsing_data/browsing_data_api.cc b/chromium/chrome/browser/extensions/api/browsing_data/browsing_data_api.cc index 3d7ca79431b..e8fe2049f54 100644 --- a/chromium/chrome/browser/extensions/api/browsing_data/browsing_data_api.cc +++ b/chromium/chrome/browser/extensions/api/browsing_data/browsing_data_api.cc @@ -49,7 +49,6 @@ const char kOptionsKey[] = "options"; // Type keys. const char kAppCacheKey[] = "appcache"; const char kCacheKey[] = "cache"; -const char kChannelIDsKey[] = "serverBoundCertificates"; const char kCookiesKey[] = "cookies"; const char kDownloadsKey[] = "downloads"; const char kFileSystemsKey[] = "fileSystems"; @@ -117,9 +116,6 @@ int MaskForKey(const char* key) { return content::BrowsingDataRemover::DATA_TYPE_INDEXED_DB; if (strcmp(key, extension_browsing_data_api_constants::kLocalStorageKey) == 0) return content::BrowsingDataRemover::DATA_TYPE_LOCAL_STORAGE; - if (strcmp(key, - extension_browsing_data_api_constants::kChannelIDsKey) == 0) - return content::BrowsingDataRemover::DATA_TYPE_CHANNEL_IDS; if (strcmp(key, extension_browsing_data_api_constants::kPasswordsKey) == 0) return ChromeBrowsingDataRemoverDelegate::DATA_TYPE_PASSWORDS; if (strcmp(key, extension_browsing_data_api_constants::kPluginDataKey) == 0) @@ -227,9 +223,6 @@ ExtensionFunction::ResponseAction BrowsingDataSettingsFunction::Run() { extension_browsing_data_api_constants::kWebSQLKey, delete_site_data); SetDetails(selected.get(), permitted.get(), - extension_browsing_data_api_constants::kChannelIDsKey, - delete_site_data); - SetDetails(selected.get(), permitted.get(), extension_browsing_data_api_constants::kServiceWorkersKey, delete_site_data); SetDetails(selected.get(), permitted.get(), @@ -557,8 +550,7 @@ bool BrowsingDataRemoveCacheFunction::GetRemovalMask(int* removal_mask) { } bool BrowsingDataRemoveCookiesFunction::GetRemovalMask(int* removal_mask) { - *removal_mask = content::BrowsingDataRemover::DATA_TYPE_COOKIES | - content::BrowsingDataRemover::DATA_TYPE_CHANNEL_IDS; + *removal_mask = content::BrowsingDataRemover::DATA_TYPE_COOKIES; return true; } diff --git a/chromium/chrome/browser/extensions/api/browsing_data/browsing_data_unittest.cc b/chromium/chrome/browser/extensions/api/browsing_data/browsing_data_unittest.cc index df6fd26f0eb..19e460c0dbc 100644 --- a/chromium/chrome/browser/extensions/api/browsing_data/browsing_data_unittest.cc +++ b/chromium/chrome/browser/extensions/api/browsing_data/browsing_data_unittest.cc @@ -270,9 +270,7 @@ class BrowsingDataApiTest : public ExtensionServiceTestBase { GetAsMask(data_to_remove, "serviceWorkers", content::BrowsingDataRemover::DATA_TYPE_SERVICE_WORKERS) | GetAsMask(data_to_remove, "webSQL", - content::BrowsingDataRemover::DATA_TYPE_WEB_SQL) | - GetAsMask(data_to_remove, "serverBoundCertificates", - content::BrowsingDataRemover::DATA_TYPE_CHANNEL_IDS); + content::BrowsingDataRemover::DATA_TYPE_WEB_SQL); EXPECT_EQ(expected_removal_mask, removal_mask); } @@ -302,9 +300,8 @@ class BrowsingDataApiTest : public ExtensionServiceTestBase { << " for " << args; } - void VerifyFilterBuilder( - const std::string& options, - const content::BrowsingDataFilterBuilder& filter_builder) { + void VerifyFilterBuilder(const std::string& options, + content::BrowsingDataFilterBuilder* filter_builder) { delegate()->ExpectCall( base::Time::UnixEpoch(), base::Time::Max(), content::BrowsingDataRemover::DATA_TYPE_LOCAL_STORAGE, UNPROTECTED_WEB, @@ -375,7 +372,6 @@ TEST_F(BrowsingDataApiTest, RemoveBrowsingDataAll) { // TODO(ramyasharma): implement clearing of external protocol data // via the browsing data API. https://crbug.com/692850. content::BrowsingDataRemover::DATA_TYPE_COOKIES | - content::BrowsingDataRemover::DATA_TYPE_CHANNEL_IDS | (content::BrowsingDataRemover::DATA_TYPE_DOM_STORAGE & ~content::BrowsingDataRemover::DATA_TYPE_BACKGROUND_FETCH & ~content::BrowsingDataRemover::DATA_TYPE_EMBEDDER_DOM_STORAGE) | @@ -435,9 +431,6 @@ TEST_F(BrowsingDataApiTest, BrowsingDataRemovalMask) { RunBrowsingDataRemoveWithKeyAndCompareRemovalMask( "localStorage", content::BrowsingDataRemover::DATA_TYPE_LOCAL_STORAGE); RunBrowsingDataRemoveWithKeyAndCompareRemovalMask( - "serverBoundCertificates", - content::BrowsingDataRemover::DATA_TYPE_CHANNEL_IDS); - RunBrowsingDataRemoveWithKeyAndCompareRemovalMask( "passwords", ChromeBrowsingDataRemoverDelegate::DATA_TYPE_PASSWORDS); // We can't remove plugin data inside a test profile. RunBrowsingDataRemoveWithKeyAndCompareRemovalMask( @@ -510,8 +503,7 @@ TEST_F(BrowsingDataApiTest, ShortcutFunctionRemovalMask) { RunAndCompareRemovalMask<BrowsingDataRemoveCacheStorageFunction>( content::BrowsingDataRemover::DATA_TYPE_CACHE_STORAGE); RunAndCompareRemovalMask<BrowsingDataRemoveCookiesFunction>( - content::BrowsingDataRemover::DATA_TYPE_COOKIES | - content::BrowsingDataRemover::DATA_TYPE_CHANNEL_IDS); + content::BrowsingDataRemover::DATA_TYPE_COOKIES); RunAndCompareRemovalMask<BrowsingDataRemoveDownloadsFunction>( content::BrowsingDataRemover::DATA_TYPE_DOWNLOADS); RunAndCompareRemovalMask<BrowsingDataRemoveFileSystemsFunction>( @@ -574,7 +566,6 @@ TEST_F(BrowsingDataApiTest, SettingsFunctionSimple) { TEST_F(BrowsingDataApiTest, SettingsFunctionSiteData) { int supported_site_data_except_plugins = (content::BrowsingDataRemover::DATA_TYPE_COOKIES | - content::BrowsingDataRemover::DATA_TYPE_CHANNEL_IDS | content::BrowsingDataRemover::DATA_TYPE_DOM_STORAGE) & ~content::BrowsingDataRemover::DATA_TYPE_BACKGROUND_FETCH & ~content::BrowsingDataRemover::DATA_TYPE_EMBEDDER_DOM_STORAGE; @@ -606,7 +597,6 @@ TEST_F(BrowsingDataApiTest, SettingsFunctionSiteData) { TEST_F(BrowsingDataApiTest, SettingsFunctionAssorted) { int supported_site_data = (content::BrowsingDataRemover::DATA_TYPE_COOKIES | - content::BrowsingDataRemover::DATA_TYPE_CHANNEL_IDS | content::BrowsingDataRemover::DATA_TYPE_DOM_STORAGE) & ~content::BrowsingDataRemover::DATA_TYPE_BACKGROUND_FETCH & ~content::BrowsingDataRemover::DATA_TYPE_EMBEDDER_DOM_STORAGE; @@ -626,7 +616,7 @@ TEST_F(BrowsingDataApiTest, RemoveWithoutFilter) { content::BrowsingDataFilterBuilder::BLACKLIST); ASSERT_TRUE(filter_builder->IsEmptyBlacklist()); - VerifyFilterBuilder("{}", *filter_builder); + VerifyFilterBuilder("{}", filter_builder.get()); } TEST_F(BrowsingDataApiTest, RemoveWithWhitelistFilter) { @@ -635,7 +625,7 @@ TEST_F(BrowsingDataApiTest, RemoveWithWhitelistFilter) { filter_builder->AddOrigin(url::Origin::Create(GURL("http://example.com"))); VerifyFilterBuilder(R"({"origins": ["http://example.com"]})", - *filter_builder); + filter_builder.get()); } TEST_F(BrowsingDataApiTest, RemoveWithBlacklistFilter) { @@ -644,7 +634,7 @@ TEST_F(BrowsingDataApiTest, RemoveWithBlacklistFilter) { filter_builder->AddOrigin(url::Origin::Create(GURL("http://example.com"))); VerifyFilterBuilder(R"({"excludeOrigins": ["http://example.com"]})", - *filter_builder); + filter_builder.get()); } TEST_F(BrowsingDataApiTest, RemoveWithSpecialUrlFilter) { @@ -656,7 +646,7 @@ TEST_F(BrowsingDataApiTest, RemoveWithSpecialUrlFilter) { VerifyFilterBuilder( R"({"excludeOrigins": ["file:///tmp/foo.html/", "filesystem:http://example.com/foo.txt"]})", - *filter_builder); + filter_builder.get()); } TEST_F(BrowsingDataApiTest, RemoveCookiesWithFilter) { @@ -665,7 +655,7 @@ TEST_F(BrowsingDataApiTest, RemoveCookiesWithFilter) { filter_builder->AddRegisterableDomain("example.com"); delegate()->ExpectCall(base::Time::UnixEpoch(), base::Time::Max(), content::BrowsingDataRemover::DATA_TYPE_COOKIES, - UNPROTECTED_WEB, *filter_builder); + UNPROTECTED_WEB, filter_builder.get()); auto function = base::MakeRefCounted<BrowsingDataRemoveFunction>(); EXPECT_EQ(RunFunctionAndReturnSingleResult( @@ -685,7 +675,7 @@ TEST_F(BrowsingDataApiTest, RemoveCookiesAndStorageWithFilter) { filter_builder1->AddRegisterableDomain("example.com"); delegate()->ExpectCall(base::Time::UnixEpoch(), base::Time::Max(), content::BrowsingDataRemover::DATA_TYPE_COOKIES, - UNPROTECTED_WEB, *filter_builder1); + UNPROTECTED_WEB, filter_builder1.get()); auto filter_builder2 = content::BrowsingDataFilterBuilder::Create( content::BrowsingDataFilterBuilder::WHITELIST); @@ -693,7 +683,7 @@ TEST_F(BrowsingDataApiTest, RemoveCookiesAndStorageWithFilter) { url::Origin::Create(GURL("http://www.example.com"))); delegate()->ExpectCall(base::Time::UnixEpoch(), base::Time::Max(), content::BrowsingDataRemover::DATA_TYPE_LOCAL_STORAGE, - UNPROTECTED_WEB, *filter_builder2); + UNPROTECTED_WEB, filter_builder2.get()); auto function = base::MakeRefCounted<BrowsingDataRemoveFunction>(); EXPECT_EQ(RunFunctionAndReturnSingleResult( diff --git a/chromium/chrome/browser/extensions/api/cast_streaming/cast_streaming_apitest.cc b/chromium/chrome/browser/extensions/api/cast_streaming/cast_streaming_apitest.cc index e3c8e69b549..9148d2dc8cd 100644 --- a/chromium/chrome/browser/extensions/api/cast_streaming/cast_streaming_apitest.cc +++ b/chromium/chrome/browser/extensions/api/cast_streaming/cast_streaming_apitest.cc @@ -8,10 +8,10 @@ #include <algorithm> #include <cmath> #include <memory> +#include <utility> #include <vector> #include "base/bind.h" -#include "base/callback_helpers.h" #include "base/command_line.h" #include "base/macros.h" #include "base/run_loop.h" @@ -152,7 +152,7 @@ class TestPatternReceiver : public media::cast::InProcessReceiver { if (done_callback_.is_null()) return; if (expected_tones_.empty() && expected_yuv_colors_.empty()) { - base::ResetAndReturn(&done_callback_).Run(); + std::move(done_callback_).Run(); } else { LOG(INFO) << "Waiting to encounter " << expected_tones_.size() << " more tone(s) and " << expected_yuv_colors_.size() @@ -162,7 +162,7 @@ class TestPatternReceiver : public media::cast::InProcessReceiver { // Invoked by InProcessReceiver for each received audio frame. void OnAudioFrame(std::unique_ptr<media::AudioBus> audio_frame, - const base::TimeTicks& playout_time, + base::TimeTicks playout_time, bool is_continuous) override { DCHECK(cast_env()->CurrentlyOn(media::cast::CastEnvironment::MAIN)); @@ -199,8 +199,8 @@ class TestPatternReceiver : public media::cast::InProcessReceiver { } } - void OnVideoFrame(const scoped_refptr<media::VideoFrame>& video_frame, - const base::TimeTicks& playout_time, + void OnVideoFrame(scoped_refptr<media::VideoFrame> video_frame, + base::TimeTicks playout_time, bool is_continuous) override { DCHECK(cast_env()->CurrentlyOn(media::cast::CastEnvironment::MAIN)); @@ -215,7 +215,7 @@ class TestPatternReceiver : public media::cast::InProcessReceiver { // letterboxed content region of mostly a solid color plus a small piece of // "something" that's animating to keep the tab capture pipeline generating // new frames. - const gfx::Rect region = FindLetterboxedContentRegion(video_frame.get()); + const gfx::Rect region = FindLetterboxedContentRegion(*video_frame); YUVColor current_color; current_color.y = ComputeMedianIntensityInRegionInPlane( region, @@ -256,11 +256,11 @@ class TestPatternReceiver : public media::cast::InProcessReceiver { // Return the region that excludes the black letterboxing borders surrounding // the content within |frame|, if any. static gfx::Rect FindLetterboxedContentRegion( - const media::VideoFrame* frame) { + const media::VideoFrame& frame) { const int kNonBlackIntensityThreshold = 20; // 16 plus some fuzz. - const int width = frame->row_bytes(media::VideoFrame::kYPlane); - const int height = frame->rows(media::VideoFrame::kYPlane); - const int stride = frame->stride(media::VideoFrame::kYPlane); + const int width = frame.row_bytes(media::VideoFrame::kYPlane); + const int height = frame.rows(media::VideoFrame::kYPlane); + const int stride = frame.stride(media::VideoFrame::kYPlane); gfx::Rect result; @@ -268,7 +268,7 @@ class TestPatternReceiver : public media::cast::InProcessReceiver { // encountered. for (int y = height - 1; y >= 0; --y) { const uint8_t* const start = - frame->data(media::VideoFrame::kYPlane) + y * stride; + frame.data(media::VideoFrame::kYPlane) + y * stride; const uint8_t* const end = start + width; for (const uint8_t* p = end - 1; p >= start; --p) { if (*p > kNonBlackIntensityThreshold) { @@ -283,7 +283,7 @@ class TestPatternReceiver : public media::cast::InProcessReceiver { // Scan from the upper-left until the first non-black pixel is encountered. for (int y = 0; y < result.height(); ++y) { const uint8_t* const start = - frame->data(media::VideoFrame::kYPlane) + y * stride; + frame.data(media::VideoFrame::kYPlane) + y * stride; const uint8_t* const end = start + result.width(); for (const uint8_t* p = start; p < end; ++p) { if (*p > kNonBlackIntensityThreshold) { diff --git a/chromium/chrome/browser/extensions/api/cast_streaming/performance_test.cc b/chromium/chrome/browser/extensions/api/cast_streaming/performance_test.cc index bda71aad0c7..d06ede354bc 100644 --- a/chromium/chrome/browser/extensions/api/cast_streaming/performance_test.cc +++ b/chromium/chrome/browser/extensions/api/cast_streaming/performance_test.cc @@ -10,6 +10,7 @@ #include <cstring> #include <iterator> #include <map> +#include <memory> #include <vector> #include "base/base64.h" @@ -326,7 +327,7 @@ class TestPatternReceiver : public media::cast::InProcessReceiver { private: // Invoked by InProcessReceiver for each received audio frame. void OnAudioFrame(std::unique_ptr<media::AudioBus> audio_frame, - const base::TimeTicks& playout_time, + base::TimeTicks playout_time, bool is_continuous) override { CHECK(cast_env()->CurrentlyOn(media::cast::CastEnvironment::MAIN)); @@ -350,8 +351,8 @@ class TestPatternReceiver : public media::cast::InProcessReceiver { } } - void OnVideoFrame(const scoped_refptr<media::VideoFrame>& video_frame, - const base::TimeTicks& playout_time, + void OnVideoFrame(scoped_refptr<media::VideoFrame> video_frame, + base::TimeTicks playout_time, bool is_continuous) override { CHECK(cast_env()->CurrentlyOn(media::cast::CastEnvironment::MAIN)); @@ -360,7 +361,7 @@ class TestPatternReceiver : public media::cast::InProcessReceiver { (playout_time - base::TimeTicks()).InMicroseconds()); uint16_t frame_no; - if (media::cast::test::DecodeBarcode(video_frame, &frame_no)) { + if (media::cast::test::DecodeBarcode(*video_frame, &frame_no)) { video_events_.push_back(TimeData(frame_no, playout_time)); } else { DVLOG(2) << "Failed to decode barcode!"; @@ -674,7 +675,7 @@ IN_PROC_BROWSER_TEST_P(CastV2PerformanceTest, Performance) { } scoped_refptr<media::cast::StandaloneCastEnvironment> cast_environment( new SkewedCastEnvironment(delta)); - TestPatternReceiver* const receiver = new TestPatternReceiver( + auto receiver = std::make_unique<TestPatternReceiver>( cast_environment, receiver_end_point, is_full_performance_run()); receiver->Start(); diff --git a/chromium/chrome/browser/extensions/api/certificate_provider/certificate_provider_apitest.cc b/chromium/chrome/browser/extensions/api/certificate_provider/certificate_provider_apitest.cc index f8fba437e17..b88a6a08cd4 100644 --- a/chromium/chrome/browser/extensions/api/certificate_provider/certificate_provider_apitest.cc +++ b/chromium/chrome/browser/extensions/api/certificate_provider/certificate_provider_apitest.cc @@ -388,7 +388,7 @@ IN_PROC_BROWSER_TEST_F(CertificateProviderRequestPinTest, service->pin_dialog_manager()->active_view_for_testing(); // The textfield has to be disabled, as extension does not allow input now. - EXPECT_EQ(view->textfield_for_testing()->enabled(), false); + EXPECT_EQ(view->textfield_for_testing()->GetEnabled(), false); // Close the dialog. ExtensionTestMessageListener listener("No attempt left", false); diff --git a/chromium/chrome/browser/extensions/api/chrome_extensions_api_client.cc b/chromium/chrome/browser/extensions/api/chrome_extensions_api_client.cc index 4e43c5bfd8a..4b71741d26c 100644 --- a/chromium/chrome/browser/extensions/api/chrome_extensions_api_client.cc +++ b/chromium/chrome/browser/extensions/api/chrome_extensions_api_client.cc @@ -13,6 +13,7 @@ #include "base/task/post_task.h" #include "build/build_config.h" #include "chrome/browser/data_use_measurement/data_use_web_contents_observer.h" +#include "chrome/browser/extensions/api/automation_internal/chrome_automation_internal_api_delegate.h" #include "chrome/browser/extensions/api/chrome_device_permissions_prompt.h" #include "chrome/browser/extensions/api/declarative_content/chrome_content_rules_registry.h" #include "chrome/browser/extensions/api/declarative_content/default_content_predicate_evaluators.h" @@ -355,4 +356,13 @@ void ChromeExtensionsAPIClient::SaveImageDataToClipboard( } #endif +AutomationInternalApiDelegate* +ChromeExtensionsAPIClient::GetAutomationInternalApiDelegate() { + if (!extensions_automation_api_delegate_) { + extensions_automation_api_delegate_ = + std::make_unique<ChromeAutomationInternalApiDelegate>(); + } + return extensions_automation_api_delegate_.get(); +} + } // namespace extensions diff --git a/chromium/chrome/browser/extensions/api/chrome_extensions_api_client.h b/chromium/chrome/browser/extensions/api/chrome_extensions_api_client.h index 61936f76a8d..15b684a4a6d 100644 --- a/chromium/chrome/browser/extensions/api/chrome_extensions_api_client.h +++ b/chromium/chrome/browser/extensions/api/chrome_extensions_api_client.h @@ -11,6 +11,7 @@ namespace extensions { +class ChromeAutomationInternalApiDelegate; class ChromeMetricsPrivateDelegate; class ClipboardExtensionHelper; @@ -76,6 +77,8 @@ class ChromeExtensionsAPIClient : public ExtensionsAPIClient { const base::Callback<void(const std::string&)>& error_callback) override; #endif + AutomationInternalApiDelegate* GetAutomationInternalApiDelegate() override; + private: std::unique_ptr<ChromeMetricsPrivateDelegate> metrics_private_delegate_; std::unique_ptr<NetworkingCastPrivateDelegate> @@ -89,6 +92,8 @@ class ChromeExtensionsAPIClient : public ExtensionsAPIClient { std::unique_ptr<NonNativeFileSystemDelegate> non_native_file_system_delegate_; std::unique_ptr<ClipboardExtensionHelper> clipboard_extension_helper_; #endif + std::unique_ptr<extensions::ChromeAutomationInternalApiDelegate> + extensions_automation_api_delegate_; DISALLOW_COPY_AND_ASSIGN(ChromeExtensionsAPIClient); }; diff --git a/chromium/chrome/browser/extensions/api/chrome_extensions_api_client_unittest.cc b/chromium/chrome/browser/extensions/api/chrome_extensions_api_client_unittest.cc index 2146dfc5fd7..c5290bab04e 100644 --- a/chromium/chrome/browser/extensions/api/chrome_extensions_api_client_unittest.cc +++ b/chromium/chrome/browser/extensions/api/chrome_extensions_api_client_unittest.cc @@ -38,23 +38,31 @@ TEST_F(ChromeExtensionsAPIClientTest, ShouldHideResponseHeader) { TEST_F(ChromeExtensionsAPIClientTest, ShouldHideBrowserNetworkRequest) { ChromeExtensionsAPIClient client; + auto create_params = [](content::ResourceType type) { + WebRequestInfoInitParams request_params; + request_params.url = GURL("https://example.com/script.js"); + request_params.initiator = + url::Origin::Create(GURL(chrome::kChromeUINewTabURL)); + request_params.render_process_id = -1; + request_params.type = type; + return request_params; + }; + // Requests made by the browser with chrome://newtab as its initiator should // not be visible to extensions. - WebRequestInfo request; - request.url = GURL("https://example.com/script.js"); - request.initiator = url::Origin::Create(GURL(chrome::kChromeUINewTabURL)); - request.render_process_id = -1; - request.type = content::ResourceType::kScript; - EXPECT_TRUE(client.ShouldHideBrowserNetworkRequest(request)); + EXPECT_TRUE(client.ShouldHideBrowserNetworkRequest( + WebRequestInfo(create_params(content::ResourceType::kScript)))); // Main frame requests should always be visible to extensions. - request.type = content::ResourceType::kMainFrame; - EXPECT_FALSE(client.ShouldHideBrowserNetworkRequest(request)); + EXPECT_FALSE(client.ShouldHideBrowserNetworkRequest( + WebRequestInfo(create_params(content::ResourceType::kMainFrame)))); // Similar requests made by the renderer should be visible to extensions. - request.type = content::ResourceType::kScript; - request.render_process_id = 2; - EXPECT_FALSE(client.ShouldHideBrowserNetworkRequest(request)); + WebRequestInfoInitParams params = + create_params(content::ResourceType::kScript); + params.render_process_id = 2; + EXPECT_FALSE(client.ShouldHideBrowserNetworkRequest( + WebRequestInfo(std::move(params)))); } } // namespace extensions diff --git a/chromium/chrome/browser/extensions/api/content_settings/content_settings_apitest.cc b/chromium/chrome/browser/extensions/api/content_settings/content_settings_apitest.cc index 0240666142e..ede8794e010 100644 --- a/chromium/chrome/browser/extensions/api/content_settings/content_settings_apitest.cc +++ b/chromium/chrome/browser/extensions/api/content_settings/content_settings_apitest.cc @@ -191,9 +191,9 @@ class ExtensionContentSettingsApiTest : public ExtensionApiTest { EXPECT_EQ(CONTENT_SETTING_ALLOW, map->GetContentSetting( url, url, CONTENT_SETTINGS_TYPE_JAVASCRIPT, std::string())); - EXPECT_EQ(CONTENT_SETTING_DETECT_IMPORTANT_CONTENT, - map->GetContentSetting( - url, url, CONTENT_SETTINGS_TYPE_PLUGINS, std::string())); + EXPECT_EQ(CONTENT_SETTING_BLOCK, + map->GetContentSetting(url, url, CONTENT_SETTINGS_TYPE_PLUGINS, + std::string())); EXPECT_EQ(CONTENT_SETTING_BLOCK, map->GetContentSetting( url, url, CONTENT_SETTINGS_TYPE_POPUPS, std::string())); diff --git a/chromium/chrome/browser/extensions/api/content_settings/content_settings_custom_extension_provider.cc b/chromium/chrome/browser/extensions/api/content_settings/content_settings_custom_extension_provider.cc index 013ef4f1a63..3e2ffead87c 100644 --- a/chromium/chrome/browser/extensions/api/content_settings/content_settings_custom_extension_provider.cc +++ b/chromium/chrome/browser/extensions/api/content_settings/content_settings_custom_extension_provider.cc @@ -37,7 +37,7 @@ bool CustomExtensionProvider::SetWebsiteSetting( const ContentSettingsPattern& secondary_pattern, ContentSettingsType content_type, const ResourceIdentifier& resource_identifier, - base::Value* value) { + std::unique_ptr<base::Value>&& value) { return false; } diff --git a/chromium/chrome/browser/extensions/api/content_settings/content_settings_custom_extension_provider.h b/chromium/chrome/browser/extensions/api/content_settings/content_settings_custom_extension_provider.h index 0f84a6a9a43..fb461b9e978 100644 --- a/chromium/chrome/browser/extensions/api/content_settings/content_settings_custom_extension_provider.h +++ b/chromium/chrome/browser/extensions/api/content_settings/content_settings_custom_extension_provider.h @@ -34,7 +34,7 @@ class CustomExtensionProvider : public ObservableProvider, const ContentSettingsPattern& secondary_pattern, ContentSettingsType content_type, const ResourceIdentifier& resource_identifier, - base::Value* value) override; + std::unique_ptr<base::Value>&& value) override; void ClearAllContentSettingsRules(ContentSettingsType content_type) override { } diff --git a/chromium/chrome/browser/extensions/api/content_settings/content_settings_service.cc b/chromium/chrome/browser/extensions/api/content_settings/content_settings_service.cc index 272f5ee9eb2..66c59d56e6e 100644 --- a/chromium/chrome/browser/extensions/api/content_settings/content_settings_service.cc +++ b/chromium/chrome/browser/extensions/api/content_settings/content_settings_service.cc @@ -12,7 +12,8 @@ namespace extensions { ContentSettingsService::ContentSettingsService(content::BrowserContext* context) - : content_settings_store_(new ContentSettingsStore()) {} + : content_settings_store_(new ContentSettingsStore()), + scoped_observer_(this) {} ContentSettingsService::~ContentSettingsService() {} @@ -69,4 +70,13 @@ void ContentSettingsService::OnExtensionStateChanged( content_settings_store_->SetExtensionState(extension_id, state); } +void ContentSettingsService::OnExtensionPrefsWillBeDestroyed( + ExtensionPrefs* prefs) { + scoped_observer_.Remove(prefs); +} + +void ContentSettingsService::OnExtensionPrefsAvailable(ExtensionPrefs* prefs) { + scoped_observer_.Add(prefs); +} + } // namespace extensions diff --git a/chromium/chrome/browser/extensions/api/content_settings/content_settings_service.h b/chromium/chrome/browser/extensions/api/content_settings/content_settings_service.h index 0b4d70ca25f..4887f5ee2cd 100644 --- a/chromium/chrome/browser/extensions/api/content_settings/content_settings_service.h +++ b/chromium/chrome/browser/extensions/api/content_settings/content_settings_service.h @@ -7,6 +7,7 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" +#include "base/scoped_observer.h" #include "chrome/browser/extensions/api/content_settings/content_settings_store.h" #include "extensions/browser/browser_context_keyed_api_factory.h" #include "extensions/browser/extension_prefs_observer.h" @@ -19,7 +20,8 @@ class ExtensionPrefs; // This service hosts a single ContentSettingsStore for the // chrome.contentSettings API. class ContentSettingsService : public BrowserContextKeyedAPI, - public ExtensionPrefsObserver { + public ExtensionPrefsObserver, + public EarlyExtensionPrefsObserver { public: explicit ContentSettingsService(content::BrowserContext* context); ~ContentSettingsService() override; @@ -44,6 +46,10 @@ class ContentSettingsService : public BrowserContextKeyedAPI, void OnExtensionPrefsDeleted(const std::string& extension_id) override; void OnExtensionStateChanged(const std::string& extension_id, bool state) override; + void OnExtensionPrefsWillBeDestroyed(ExtensionPrefs* prefs) override; + + // EarlyExtensionPrefsObserver implementation. + void OnExtensionPrefsAvailable(ExtensionPrefs* prefs) override; private: friend class BrowserContextKeyedAPIFactory<ContentSettingsService>; @@ -53,6 +59,7 @@ class ContentSettingsService : public BrowserContextKeyedAPI, static const char* service_name() { return "ContentSettingsService"; } scoped_refptr<ContentSettingsStore> content_settings_store_; + ScopedObserver<ExtensionPrefs, ExtensionPrefsObserver> scoped_observer_; DISALLOW_COPY_AND_ASSIGN(ContentSettingsService); }; diff --git a/chromium/chrome/browser/extensions/api/cookies/cookies_api.cc b/chromium/chrome/browser/extensions/api/cookies/cookies_api.cc index 663e72c0e6a..279f9164e0d 100644 --- a/chromium/chrome/browser/extensions/api/cookies/cookies_api.cc +++ b/chromium/chrome/browser/extensions/api/cookies/cookies_api.cc @@ -323,9 +323,8 @@ ExtensionFunction::ResponseAction CookiesSetFunction::Run() { base::Time::FromDoubleT(*parsed_args_->details.expiration_date); } - net::CookieSameSite same_site = net::CookieSameSite::NO_RESTRICTION; + net::CookieSameSite same_site = net::CookieSameSite::UNSPECIFIED; switch (parsed_args_->details.same_site) { - case api::cookies::SAME_SITE_STATUS_NONE: case api::cookies::SAME_SITE_STATUS_NO_RESTRICTION: same_site = net::CookieSameSite::NO_RESTRICTION; break; @@ -335,6 +334,13 @@ ExtensionFunction::ResponseAction CookiesSetFunction::Run() { case api::cookies::SAME_SITE_STATUS_STRICT: same_site = net::CookieSameSite::STRICT_MODE; break; + // This is the case if the optional sameSite property is given as + // "unspecified": + case api::cookies::SAME_SITE_STATUS_UNSPECIFIED: + // This is the case if the optional sameSite property is left out: + case api::cookies::SAME_SITE_STATUS_NONE: + same_site = net::CookieSameSite::UNSPECIFIED; + break; } // clang-format off diff --git a/chromium/chrome/browser/extensions/api/cookies/cookies_helpers.cc b/chromium/chrome/browser/extensions/api/cookies/cookies_helpers.cc index c0261872774..2c663be2948 100644 --- a/chromium/chrome/browser/extensions/api/cookies/cookies_helpers.cc +++ b/chromium/chrome/browser/extensions/api/cookies/cookies_helpers.cc @@ -82,10 +82,7 @@ Cookie CreateCookie(const net::CanonicalCookie& canonical_cookie, cookie.http_only = canonical_cookie.IsHttpOnly(); switch (canonical_cookie.SameSite()) { - // TODO(chlily): UNSPECIFIED should map to SAME_SITE_STATUS_NONE and vice - // versa. case net::CookieSameSite::NO_RESTRICTION: - case net::CookieSameSite::UNSPECIFIED: cookie.same_site = api::cookies::SAME_SITE_STATUS_NO_RESTRICTION; break; case net::CookieSameSite::LAX_MODE: @@ -95,6 +92,9 @@ Cookie CreateCookie(const net::CanonicalCookie& canonical_cookie, case net::CookieSameSite::STRICT_MODE: cookie.same_site = api::cookies::SAME_SITE_STATUS_STRICT; break; + case net::CookieSameSite::UNSPECIFIED: + cookie.same_site = api::cookies::SAME_SITE_STATUS_UNSPECIFIED; + break; } cookie.session = !canonical_cookie.IsPersistent(); diff --git a/chromium/chrome/browser/extensions/api/cryptotoken_private/cryptotoken_private_api.cc b/chromium/chrome/browser/extensions/api/cryptotoken_private/cryptotoken_private_api.cc index 73eceeb4bbb..40acfb6057a 100644 --- a/chromium/chrome/browser/extensions/api/cryptotoken_private/cryptotoken_private_api.cc +++ b/chromium/chrome/browser/extensions/api/cryptotoken_private/cryptotoken_private_api.cc @@ -243,14 +243,5 @@ void CryptotokenPrivateCanAppIdGetAttestationFunction::Complete(bool result) { Respond(OneArgument(std::make_unique<base::Value>(result))); } -CryptotokenPrivateCanProxyToWebAuthnFunction:: - CryptotokenPrivateCanProxyToWebAuthnFunction() {} - -ExtensionFunction::ResponseAction -CryptotokenPrivateCanProxyToWebAuthnFunction::Run() { - return RespondNow(OneArgument(std::make_unique<base::Value>( - base::FeatureList::IsEnabled(device::kWebAuthProxyCryptotoken)))); -} - } // namespace api } // namespace extensions diff --git a/chromium/chrome/browser/extensions/api/cryptotoken_private/cryptotoken_private_api.h b/chromium/chrome/browser/extensions/api/cryptotoken_private/cryptotoken_private_api.h index 3c3950878f1..7c92493260b 100644 --- a/chromium/chrome/browser/extensions/api/cryptotoken_private/cryptotoken_private_api.h +++ b/chromium/chrome/browser/extensions/api/cryptotoken_private/cryptotoken_private_api.h @@ -63,17 +63,6 @@ class CryptotokenPrivateCanAppIdGetAttestationFunction void Complete(bool result); }; -class CryptotokenPrivateCanProxyToWebAuthnFunction - : public UIThreadExtensionFunction { - public: - CryptotokenPrivateCanProxyToWebAuthnFunction(); - DECLARE_EXTENSION_FUNCTION("cryptotokenPrivate.canProxyToWebAuthn", - CRYPTOTOKENPRIVATE_CANPROXYTOWEBAUTHN) - protected: - ~CryptotokenPrivateCanProxyToWebAuthnFunction() override {} - ResponseAction Run() override; -}; - } // namespace api } // namespace extensions diff --git a/chromium/chrome/browser/extensions/api/debugger/extension_dev_tools_infobar.cc b/chromium/chrome/browser/extensions/api/debugger/extension_dev_tools_infobar.cc index e01e92e821a..b976be9f10a 100644 --- a/chromium/chrome/browser/extensions/api/debugger/extension_dev_tools_infobar.cc +++ b/chromium/chrome/browser/extensions/api/debugger/extension_dev_tools_infobar.cc @@ -5,9 +5,9 @@ #include "chrome/browser/extensions/api/debugger/extension_dev_tools_infobar.h" #include <memory> +#include <utility> #include "base/bind.h" -#include "base/callback_helpers.h" #include "base/lazy_instance.h" #include "base/strings/utf_string_conversions.h" #include "chrome/browser/devtools/global_confirm_info_bar.h" @@ -64,8 +64,7 @@ bool ExtensionDevToolsInfoBarDelegate::ShouldExpire( void ExtensionDevToolsInfoBarDelegate::InfoBarDismissed() { DCHECK(!dismissed_callback_.is_null()); - // Use ResetAndReturn() since running the callback may delete |this|. - base::ResetAndReturn(&dismissed_callback_).Run(); + std::move(dismissed_callback_).Run(); } base::string16 ExtensionDevToolsInfoBarDelegate::GetMessageText() const { diff --git a/chromium/chrome/browser/extensions/api/declarative_content/content_action_unittest.cc b/chromium/chrome/browser/extensions/api/declarative_content/content_action_unittest.cc index 42e49361350..02062bbef9f 100644 --- a/chromium/chrome/browser/extensions/api/declarative_content/content_action_unittest.cc +++ b/chromium/chrome/browser/extensions/api/declarative_content/content_action_unittest.cc @@ -155,18 +155,15 @@ TEST_P(ParameterizedDeclarativeContentActionTest, ShowAction) { EXPECT_TRUE(error.empty()) << error; ASSERT_TRUE(result.get()); - ExtensionAction* action = nullptr; auto* action_manager = ExtensionActionManager::Get(env.profile()); - const bool is_browser_action = - GetParam() == ExtensionBuilder::ActionType::BROWSER_ACTION; - if (is_browser_action) { - action = action_manager->GetBrowserAction(*extension); - ASSERT_TRUE(action); + ExtensionAction* action = action_manager->GetExtensionAction(*extension); + ASSERT_TRUE(action); + if (GetParam() == ExtensionBuilder::ActionType::BROWSER_ACTION) { + EXPECT_EQ(ActionInfo::TYPE_BROWSER, action->action_type()); // Switch the default so we properly see the action toggling. action->SetIsVisible(ExtensionAction::kDefaultTabId, false); } else { - action = action_manager->GetPageAction(*extension); - ASSERT_TRUE(action); + EXPECT_EQ(ActionInfo::TYPE_PAGE, action->action_type()); } std::unique_ptr<content::WebContents> contents = env.MakeTab(); @@ -242,21 +239,21 @@ TEST(DeclarativeContentActionTest, SetIcon) { "Extensions.DeclarativeSetIconWasVisibleRendered"), testing::ElementsAre(base::Bucket(1, 1))); - ExtensionAction* page_action = - ExtensionActionManager::Get(env.profile())->GetPageAction(*extension); + ExtensionAction* action = ExtensionActionManager::Get(env.profile()) + ->GetExtensionAction(*extension); std::unique_ptr<content::WebContents> contents = env.MakeTab(); const int tab_id = ExtensionTabUtil::GetTabId(contents.get()); - EXPECT_FALSE(page_action->GetIsVisible(tab_id)); + EXPECT_FALSE(action->GetIsVisible(tab_id)); ContentAction::ApplyInfo apply_info = { extension, env.profile(), contents.get(), 100 }; // The declarative icon shouldn't exist unless the content action is applied. - EXPECT_TRUE(page_action->GetDeclarativeIcon(tab_id).IsEmpty()); + EXPECT_TRUE(action->GetDeclarativeIcon(tab_id).IsEmpty()); result->Apply(apply_info); - EXPECT_FALSE(page_action->GetDeclarativeIcon(tab_id).IsEmpty()); + EXPECT_FALSE(action->GetDeclarativeIcon(tab_id).IsEmpty()); result->Revert(apply_info); - EXPECT_TRUE(page_action->GetDeclarativeIcon(tab_id).IsEmpty()); + EXPECT_TRUE(action->GetDeclarativeIcon(tab_id).IsEmpty()); } TEST(DeclarativeContentActionTest, SetInvisibleIcon) { diff --git a/chromium/chrome/browser/extensions/api/declarative_content/declarative_content_apitest.cc b/chromium/chrome/browser/extensions/api/declarative_content/declarative_content_apitest.cc index a1578d2a69b..c75ebb8b91f 100644 --- a/chromium/chrome/browser/extensions/api/declarative_content/declarative_content_apitest.cc +++ b/chromium/chrome/browser/extensions/api/declarative_content/declarative_content_apitest.cc @@ -154,10 +154,10 @@ void DeclarativeContentApiTest::CheckIncognito(IncognitoMode mode, ASSERT_TRUE(extension); Browser* incognito_browser = CreateIncognitoBrowser(); - const ExtensionAction* incognito_page_action = - ExtensionActionManager::Get(incognito_browser->profile())-> - GetPageAction(*extension); - ASSERT_TRUE(incognito_page_action); + const ExtensionAction* incognito_action = + ExtensionActionManager::Get(incognito_browser->profile()) + ->GetExtensionAction(*extension); + ASSERT_TRUE(incognito_action); ASSERT_TRUE(ready.WaitUntilSatisfied()); if (is_enabled_in_incognito && mode == SPLIT) @@ -167,39 +167,39 @@ void DeclarativeContentApiTest::CheckIncognito(IncognitoMode mode, incognito_browser->tab_strip_model()->GetWebContentsAt(0); const int incognito_tab_id = ExtensionTabUtil::GetTabId(incognito_tab); - EXPECT_FALSE(incognito_page_action->GetIsVisible(incognito_tab_id)); + EXPECT_FALSE(incognito_action->GetIsVisible(incognito_tab_id)); NavigateInRenderer(incognito_tab, GURL("http://test_split/")); if (mode == SPLIT) { EXPECT_EQ(is_enabled_in_incognito, - incognito_page_action->GetIsVisible(incognito_tab_id)); + incognito_action->GetIsVisible(incognito_tab_id)); } else { - EXPECT_FALSE(incognito_page_action->GetIsVisible(incognito_tab_id)); + EXPECT_FALSE(incognito_action->GetIsVisible(incognito_tab_id)); } NavigateInRenderer(incognito_tab, GURL("http://test_normal/")); if (mode != SPLIT) { EXPECT_EQ(is_enabled_in_incognito, - incognito_page_action->GetIsVisible(incognito_tab_id)); + incognito_action->GetIsVisible(incognito_tab_id)); } else { - EXPECT_FALSE(incognito_page_action->GetIsVisible(incognito_tab_id)); + EXPECT_FALSE(incognito_action->GetIsVisible(incognito_tab_id)); } // Verify that everything works as expected in the non-incognito browser. - const ExtensionAction* page_action = - ExtensionActionManager::Get(browser()->profile())-> - GetPageAction(*extension); + const ExtensionAction* action = + ExtensionActionManager::Get(browser()->profile()) + ->GetExtensionAction(*extension); content::WebContents* const tab = browser()->tab_strip_model()->GetWebContentsAt(0); const int tab_id = ExtensionTabUtil::GetTabId(tab); - EXPECT_FALSE(page_action->GetIsVisible(tab_id)); + EXPECT_FALSE(action->GetIsVisible(tab_id)); NavigateInRenderer(tab, GURL("http://test_normal/")); - EXPECT_TRUE(page_action->GetIsVisible(tab_id)); + EXPECT_TRUE(action->GetIsVisible(tab_id)); NavigateInRenderer(tab, GURL("http://test_split/")); - EXPECT_FALSE(page_action->GetIsVisible(tab_id)); + EXPECT_FALSE(action->GetIsVisible(tab_id)); } void DeclarativeContentApiTest::CheckBookmarkEvents(bool match_is_bookmarked) { @@ -212,12 +212,13 @@ void DeclarativeContentApiTest::CheckBookmarkEvents(bool match_is_bookmarked) { const Extension* extension = LoadExtension(ext_dir_.UnpackedPath()); ASSERT_TRUE(extension); - const ExtensionAction* page_action = ExtensionActionManager::Get( - browser()->profile())->GetPageAction(*extension); - ASSERT_TRUE(page_action); + const ExtensionAction* action = + ExtensionActionManager::Get(browser()->profile()) + ->GetExtensionAction(*extension); + ASSERT_TRUE(action); NavigateInRenderer(tab, GURL("http://test1/")); - EXPECT_FALSE(page_action->GetIsVisible(tab_id)); + EXPECT_FALSE(action->GetIsVisible(tab_id)); static const char kSetIsBookmarkedRule[] = "setRules([{\n" @@ -229,7 +230,7 @@ void DeclarativeContentApiTest::CheckBookmarkEvents(bool match_is_bookmarked) { extension->id(), base::StringPrintf(kSetIsBookmarkedRule, match_is_bookmarked ? "true" : "false"))); - EXPECT_EQ(!match_is_bookmarked, page_action->GetIsVisible(tab_id)); + EXPECT_EQ(!match_is_bookmarked, action->GetIsVisible(tab_id)); // Check rule evaluation on add/remove bookmark. bookmarks::BookmarkModel* bookmark_model = @@ -238,10 +239,10 @@ void DeclarativeContentApiTest::CheckBookmarkEvents(bool match_is_bookmarked) { bookmark_model->AddURL(bookmark_model->other_node(), 0, base::ASCIIToUTF16("title"), GURL("http://test1/")); - EXPECT_EQ(match_is_bookmarked, page_action->GetIsVisible(tab_id)); + EXPECT_EQ(match_is_bookmarked, action->GetIsVisible(tab_id)); bookmark_model->Remove(node); - EXPECT_EQ(!match_is_bookmarked, page_action->GetIsVisible(tab_id)); + EXPECT_EQ(!match_is_bookmarked, action->GetIsVisible(tab_id)); // Check rule evaluation on navigate to bookmarked and non-bookmarked URL. bookmark_model->AddURL(bookmark_model->other_node(), 0, @@ -249,10 +250,10 @@ void DeclarativeContentApiTest::CheckBookmarkEvents(bool match_is_bookmarked) { GURL("http://test2/")); NavigateInRenderer(tab, GURL("http://test2/")); - EXPECT_EQ(match_is_bookmarked, page_action->GetIsVisible(tab_id)); + EXPECT_EQ(match_is_bookmarked, action->GetIsVisible(tab_id)); NavigateInRenderer(tab, GURL("http://test3/")); - EXPECT_EQ(!match_is_bookmarked, page_action->GetIsVisible(tab_id)); + EXPECT_EQ(!match_is_bookmarked, action->GetIsVisible(tab_id)); } // Disabled due to flake. https://crbug.com/606574. @@ -283,10 +284,10 @@ IN_PROC_BROWSER_TEST_F(DeclarativeContentApiTest, DISABLED_Overview) { ExtensionTestMessageListener ready("ready", false); const Extension* extension = LoadExtension(ext_dir_.UnpackedPath()); ASSERT_TRUE(extension); - const ExtensionAction* page_action = - ExtensionActionManager::Get(browser()->profile())-> - GetPageAction(*extension); - ASSERT_TRUE(page_action); + const ExtensionAction* action = + ExtensionActionManager::Get(browser()->profile()) + ->GetExtensionAction(*extension); + ASSERT_TRUE(action); ASSERT_TRUE(ready.WaitUntilSatisfied()); content::WebContents* const tab = @@ -297,11 +298,11 @@ IN_PROC_BROWSER_TEST_F(DeclarativeContentApiTest, DISABLED_Overview) { // The declarative API should show the page action instantly, rather // than waiting for the extension to run. - EXPECT_TRUE(page_action->GetIsVisible(tab_id)); + EXPECT_TRUE(action->GetIsVisible(tab_id)); // Make sure leaving a matching page unshows the page action. NavigateInRenderer(tab, GURL("http://not_checked/")); - EXPECT_FALSE(page_action->GetIsVisible(tab_id)); + EXPECT_FALSE(action->GetIsVisible(tab_id)); // Insert a password field to make sure that's noticed. // Notice that we touch offsetTop to force a synchronous layout. @@ -313,7 +314,7 @@ IN_PROC_BROWSER_TEST_F(DeclarativeContentApiTest, DISABLED_Overview) { // update. ASSERT_TRUE(content::ExecuteScript(tab, std::string())); - EXPECT_TRUE(page_action->GetIsVisible(tab_id)) + EXPECT_TRUE(action->GetIsVisible(tab_id)) << "Adding a matching element should show the page action."; // Remove it again to make sure that reverts the action. @@ -326,7 +327,7 @@ IN_PROC_BROWSER_TEST_F(DeclarativeContentApiTest, DISABLED_Overview) { // update. ASSERT_TRUE(content::ExecuteScript(tab, std::string())); - EXPECT_FALSE(page_action->GetIsVisible(tab_id)) + EXPECT_FALSE(action->GetIsVisible(tab_id)) << "Removing the matching element should hide the page action again."; } @@ -366,10 +367,10 @@ IN_PROC_BROWSER_TEST_F(DeclarativeContentApiTest, ReusedActionInstance) { // Wait for declarative rules to be set up. content::BrowserContext::GetDefaultStoragePartition(profile()) ->FlushNetworkInterfaceForTesting(); - const ExtensionAction* page_action = + const ExtensionAction* action = ExtensionActionManager::Get(browser()->profile()) - ->GetPageAction(*extension); - ASSERT_TRUE(page_action); + ->GetExtensionAction(*extension); + ASSERT_TRUE(action); ASSERT_TRUE(ready.WaitUntilSatisfied()); content::WebContents* const tab = @@ -379,7 +380,7 @@ IN_PROC_BROWSER_TEST_F(DeclarativeContentApiTest, ReusedActionInstance) { // This navigation matches both rules. NavigateInRenderer(tab, GURL("http://test1/")); - EXPECT_TRUE(page_action->GetIsVisible(tab_id)); + EXPECT_TRUE(action->GetIsVisible(tab_id)); } // Tests that the rules are evaluated at the time they are added or removed. @@ -388,10 +389,10 @@ IN_PROC_BROWSER_TEST_F(DeclarativeContentApiTest, RulesEvaluatedOnAddRemove) { ext_dir_.WriteFile(FILE_PATH_LITERAL("background.js"), kBackgroundHelpers); const Extension* extension = LoadExtension(ext_dir_.UnpackedPath()); ASSERT_TRUE(extension); - const ExtensionAction* page_action = - ExtensionActionManager::Get(browser()->profile())-> - GetPageAction(*extension); - ASSERT_TRUE(page_action); + const ExtensionAction* action = + ExtensionActionManager::Get(browser()->profile()) + ->GetExtensionAction(*extension); + ASSERT_TRUE(action); content::WebContents* const tab = browser()->tab_strip_model()->GetWebContentsAt(0); @@ -414,23 +415,23 @@ IN_PROC_BROWSER_TEST_F(DeclarativeContentApiTest, RulesEvaluatedOnAddRemove) { EXPECT_EQ("add_rules", ExecuteScriptInBackgroundPage(extension->id(), kAddTestRules)); - EXPECT_TRUE(page_action->GetIsVisible(tab_id)); + EXPECT_TRUE(action->GetIsVisible(tab_id)); const std::string kRemoveTestRule1 = "removeRule('1', 'remove_rule1');\n"; EXPECT_EQ("remove_rule1", ExecuteScriptInBackgroundPage(extension->id(), kRemoveTestRule1)); - EXPECT_FALSE(page_action->GetIsVisible(tab_id)); + EXPECT_FALSE(action->GetIsVisible(tab_id)); NavigateInRenderer(tab, GURL("http://test2/")); - EXPECT_TRUE(page_action->GetIsVisible(tab_id)); + EXPECT_TRUE(action->GetIsVisible(tab_id)); const std::string kRemoveTestRule2 = "removeRule('2', 'remove_rule2');\n"; EXPECT_EQ("remove_rule2", ExecuteScriptInBackgroundPage(extension->id(), kRemoveTestRule2)); - EXPECT_FALSE(page_action->GetIsVisible(tab_id)); + EXPECT_FALSE(action->GetIsVisible(tab_id)); } class ParameterizedShowActionDeclarativeContentApiTest @@ -458,8 +459,9 @@ void ParameterizedShowActionDeclarativeContentApiTest::TestShowAction( case ActionInfo::TYPE_PAGE: action_key = R"("page_action": {},)"; break; - case ActionInfo::TYPE_SYSTEM_INDICATOR: - NOTREACHED(); + case ActionInfo::TYPE_ACTION: + action_key = R"("action": {},)"; + break; } } @@ -482,11 +484,8 @@ void ParameterizedShowActionDeclarativeContentApiTest::TestShowAction( // (for visibility reasons). ASSERT_TRUE(action); - // Ensure browser actions are hidden (so that the ShowAction() rule has an - // effect). - bool has_browser_action = - action_type && *action_type == ActionInfo::TYPE_BROWSER; - if (has_browser_action) + // Ensure actions are hidden (so that the ShowAction() rule has an effect). + if (action->default_state() == ActionInfo::STATE_DISABLED) action->SetIsVisible(ExtensionAction::kDefaultTabId, false); const char kScript[] = @@ -512,15 +511,11 @@ void ParameterizedShowActionDeclarativeContentApiTest::TestShowAction( const int tab_id = SessionTabHelper::IdForTab(tab).id(); EXPECT_TRUE(action->GetIsVisible(tab_id)); - // Even an extension with no specified action with have a (synthesized) page - // action. Only browser action extensions are expected to not have a page - // action. - bool expect_page_action = !has_browser_action; - ExtensionAction* page_action = - ExtensionActionManager::Get(browser()->profile()) - ->GetPageAction(*extension); - EXPECT_EQ(expect_page_action, page_action != nullptr); - EXPECT_EQ(expect_page_action ? 1u : 0u, + // If an extension had no action specified in the manifest, it will get a + // synthesized page action. + ActionInfo::Type expected_type = action_type.value_or(ActionInfo::TYPE_PAGE); + EXPECT_EQ(expected_type, action->action_type()); + EXPECT_EQ(expected_type == ActionInfo::TYPE_PAGE ? 1u : 0u, extension_action_test_util::GetVisiblePageActionCount(tab)); } @@ -539,6 +534,11 @@ IN_PROC_BROWSER_TEST_P(ParameterizedShowActionDeclarativeContentApiTest, TestShowAction(ActionInfo::TYPE_BROWSER); } +IN_PROC_BROWSER_TEST_P(ParameterizedShowActionDeclarativeContentApiTest, + ActionInManifest) { + TestShowAction(ActionInfo::TYPE_ACTION); +} + // Tests that rules from manifest are added and evaluated properly. IN_PROC_BROWSER_TEST_P(ParameterizedShowActionDeclarativeContentApiTest, RulesAddedFromManifest) { @@ -565,21 +565,21 @@ IN_PROC_BROWSER_TEST_P(ParameterizedShowActionDeclarativeContentApiTest, ext_dir_.WriteManifest(base::StringPrintf(manifest, GetParam())); const Extension* extension = LoadExtension(ext_dir_.UnpackedPath()); ASSERT_TRUE(extension); - const ExtensionAction* page_action = + const ExtensionAction* action = ExtensionActionManager::Get(browser()->profile()) - ->GetPageAction(*extension); - ASSERT_TRUE(page_action); + ->GetExtensionAction(*extension); + ASSERT_TRUE(action); content::WebContents* const tab = browser()->tab_strip_model()->GetWebContentsAt(0); const int tab_id = ExtensionTabUtil::GetTabId(tab); NavigateInRenderer(tab, GURL("http://blank/")); - EXPECT_FALSE(page_action->GetIsVisible(tab_id)); + EXPECT_FALSE(action->GetIsVisible(tab_id)); NavigateInRenderer(tab, GURL("http://test1/")); - EXPECT_TRUE(page_action->GetIsVisible(tab_id)); + EXPECT_TRUE(action->GetIsVisible(tab_id)); NavigateInRenderer(tab, GURL("http://test2/")); - EXPECT_FALSE(page_action->GetIsVisible(tab_id)); + EXPECT_FALSE(action->GetIsVisible(tab_id)); } INSTANTIATE_TEST_SUITE_P(LegacyShowActionKey, @@ -633,13 +633,13 @@ IN_PROC_BROWSER_TEST_F(DeclarativeContentApiTest, ASSERT_TRUE(extension); ASSERT_TRUE(ready.WaitUntilSatisfied()); - const ExtensionAction* incognito_page_action = - ExtensionActionManager::Get(incognito_browser->profile())-> - GetPageAction(*extension); - ASSERT_TRUE(incognito_page_action); + const ExtensionAction* incognito_action = + ExtensionActionManager::Get(incognito_browser->profile()) + ->GetExtensionAction(*extension); + ASSERT_TRUE(incognito_action); // The page action should be shown. - EXPECT_TRUE(incognito_page_action->GetIsVisible(incognito_tab_id)); + EXPECT_TRUE(incognito_action->GetIsVisible(incognito_tab_id)); } // Sets up rules matching http://test1/ in a normal and incognito browser. @@ -679,17 +679,17 @@ IN_PROC_BROWSER_TEST_F(DeclarativeContentApiTest, DISABLED_RulesPersistence) { browser()->tab_strip_model()->GetWebContentsAt(0); const int tab_id = ExtensionTabUtil::GetTabId(tab); - const ExtensionAction* page_action = - ExtensionActionManager::Get(browser()->profile())-> - GetPageAction(*extension); - ASSERT_TRUE(page_action); - EXPECT_FALSE(page_action->GetIsVisible(tab_id)); + const ExtensionAction* action = + ExtensionActionManager::Get(browser()->profile()) + ->GetExtensionAction(*extension); + ASSERT_TRUE(action); + EXPECT_FALSE(action->GetIsVisible(tab_id)); NavigateInRenderer(tab, GURL("http://test_normal/")); - EXPECT_TRUE(page_action->GetIsVisible(tab_id)); + EXPECT_TRUE(action->GetIsVisible(tab_id)); NavigateInRenderer(tab, GURL("http://test_split/")); - EXPECT_FALSE(page_action->GetIsVisible(tab_id)); + EXPECT_FALSE(action->GetIsVisible(tab_id)); // Check incognito browser. Browser* incognito_browser = CreateIncognitoBrowser(); @@ -698,16 +698,16 @@ IN_PROC_BROWSER_TEST_F(DeclarativeContentApiTest, DISABLED_RulesPersistence) { incognito_browser->tab_strip_model()->GetWebContentsAt(0); const int incognito_tab_id = ExtensionTabUtil::GetTabId(incognito_tab); - const ExtensionAction* incognito_page_action = - ExtensionActionManager::Get(incognito_browser->profile())-> - GetPageAction(*extension); - ASSERT_TRUE(incognito_page_action); + const ExtensionAction* incognito_action = + ExtensionActionManager::Get(incognito_browser->profile()) + ->GetExtensionAction(*extension); + ASSERT_TRUE(incognito_action); NavigateInRenderer(incognito_tab, GURL("http://test_split/")); - EXPECT_TRUE(incognito_page_action->GetIsVisible(incognito_tab_id)); + EXPECT_TRUE(incognito_action->GetIsVisible(incognito_tab_id)); NavigateInRenderer(incognito_tab, GURL("http://test_normal/")); - EXPECT_FALSE(incognito_page_action->GetIsVisible(incognito_tab_id)); + EXPECT_FALSE(incognito_action->GetIsVisible(incognito_tab_id)); } // http://crbug.com/304373 @@ -728,9 +728,10 @@ IN_PROC_BROWSER_TEST_F(DeclarativeContentApiTest, content::BrowserContext::GetDefaultStoragePartition(profile()) ->FlushNetworkInterfaceForTesting(); const std::string extension_id = extension->id(); - const ExtensionAction* page_action = ExtensionActionManager::Get( - browser()->profile())->GetPageAction(*extension); - ASSERT_TRUE(page_action); + const ExtensionAction* action = + ExtensionActionManager::Get(browser()->profile()) + ->GetExtensionAction(*extension); + ASSERT_TRUE(action); const std::string kTestRule = "setRules([{\n" @@ -747,12 +748,12 @@ IN_PROC_BROWSER_TEST_F(DeclarativeContentApiTest, NavigateInRenderer(tab, GURL("http://test/")); - EXPECT_TRUE(page_action->GetIsVisible(tab_id)); + EXPECT_TRUE(action->GetIsVisible(tab_id)); EXPECT_TRUE(WaitForPageActionVisibilityChangeTo(1)); EXPECT_EQ(1u, extension_action_test_util::GetVisiblePageActionCount(tab)); EXPECT_EQ(1u, extension_action_test_util::GetTotalPageActionCount(tab)); - ReloadExtension(extension_id); // Invalidates page_action and extension. + ReloadExtension(extension_id); // Invalidates action and extension. // Wait for declarative rules to be removed. content::BrowserContext::GetDefaultStoragePartition(profile()) ->FlushNetworkInterfaceForTesting(); @@ -792,10 +793,11 @@ IN_PROC_BROWSER_TEST_F(DeclarativeContentApiTest, const Extension* extension = LoadExtension(ext_dir_.UnpackedPath()); ASSERT_TRUE(extension); - const ExtensionAction* page_action = ExtensionActionManager::Get( - browser()->profile())->GetPageAction(*extension); - ASSERT_TRUE(page_action); - EXPECT_FALSE(page_action->GetIsVisible(tab_id)); + const ExtensionAction* action = + ExtensionActionManager::Get(browser()->profile()) + ->GetExtensionAction(*extension); + ASSERT_TRUE(action); + EXPECT_FALSE(action->GetIsVisible(tab_id)); EXPECT_EQ("rule0", ExecuteScriptInBackgroundPage( extension->id(), @@ -812,7 +814,7 @@ IN_PROC_BROWSER_TEST_F(DeclarativeContentApiTest, ASSERT_TRUE(content::ExecuteScript(tab, std::string())); EXPECT_FALSE(tab->IsCrashed()); - EXPECT_TRUE(page_action->GetIsVisible(tab_id)) + EXPECT_TRUE(action->GetIsVisible(tab_id)) << "Loading an extension when an open page matches its rules " << "should show the page action."; @@ -822,7 +824,7 @@ IN_PROC_BROWSER_TEST_F(DeclarativeContentApiTest, "onPageChanged.removeRules(undefined, function() {\n" " window.domAutomationController.send('removed');\n" "});\n")); - EXPECT_FALSE(page_action->GetIsVisible(tab_id)); + EXPECT_FALSE(action->GetIsVisible(tab_id)); } IN_PROC_BROWSER_TEST_F(DeclarativeContentApiTest, @@ -921,9 +923,10 @@ IN_PROC_BROWSER_TEST_F(DeclarativeContentApiTest, ext_dir_.WriteFile(FILE_PATH_LITERAL("background.js"), kBackgroundHelpers); const Extension* extension = LoadExtension(ext_dir_.UnpackedPath()); ASSERT_TRUE(extension); - const ExtensionAction* page_action = ExtensionActionManager::Get( - browser()->profile())->GetPageAction(*extension); - ASSERT_TRUE(page_action); + const ExtensionAction* action = + ExtensionActionManager::Get(browser()->profile()) + ->GetExtensionAction(*extension); + ASSERT_TRUE(action); // Create two tabs. content::WebContents* const tab1 = @@ -948,7 +951,7 @@ IN_PROC_BROWSER_TEST_F(DeclarativeContentApiTest, "}], 'add_rules');\n"; EXPECT_EQ("add_rules", ExecuteScriptInBackgroundPage(extension->id(), kAddTestRules)); - EXPECT_TRUE(page_action->GetIsVisible(ExtensionTabUtil::GetTabId(tab2))); + EXPECT_TRUE(action->GetIsVisible(ExtensionTabUtil::GetTabId(tab2))); // Remove the rule. const std::string kRemoveTestRule1 = "removeRule('2', 'remove_rule1');\n"; @@ -960,7 +963,7 @@ IN_PROC_BROWSER_TEST_F(DeclarativeContentApiTest, browser()->tab_strip_model()->DetachWebContentsAt( browser()->tab_strip_model()->GetIndexOfWebContents(tab2)); NavigateInRenderer(tab1, GURL("http://test1/")); - EXPECT_TRUE(page_action->GetIsVisible(ExtensionTabUtil::GetTabId(tab1))); + EXPECT_TRUE(action->GetIsVisible(ExtensionTabUtil::GetTabId(tab1))); } // https://crbug.com/517492 diff --git a/chromium/chrome/browser/extensions/api/declarative_content/set_icon_apitest.cc b/chromium/chrome/browser/extensions/api/declarative_content/set_icon_apitest.cc index b06f9309bf5..d017f72f716 100644 --- a/chromium/chrome/browser/extensions/api/declarative_content/set_icon_apitest.cc +++ b/chromium/chrome/browser/extensions/api/declarative_content/set_icon_apitest.cc @@ -78,10 +78,10 @@ IN_PROC_BROWSER_TEST_F(SetIconAPITest, Overview) { // Wait for declarative rules to be set up. content::BrowserContext::GetDefaultStoragePartition(profile()) ->FlushNetworkInterfaceForTesting(); - const ExtensionAction* page_action = - ExtensionActionManager::Get(browser()->profile())-> - GetPageAction(*extension); - ASSERT_TRUE(page_action); + const ExtensionAction* action = + ExtensionActionManager::Get(browser()->profile()) + ->GetExtensionAction(*extension); + ASSERT_TRUE(action); ASSERT_TRUE(ready.WaitUntilSatisfied()); content::WebContents* const tab = @@ -89,13 +89,13 @@ IN_PROC_BROWSER_TEST_F(SetIconAPITest, Overview) { const int tab_id = ExtensionTabUtil::GetTabId(tab); // There should be no declarative icon until we navigate to a matched page. - EXPECT_TRUE(page_action->GetDeclarativeIcon(tab_id).IsEmpty()); + EXPECT_TRUE(action->GetDeclarativeIcon(tab_id).IsEmpty()); NavigateInRenderer(tab, GURL("http://test1/")); - EXPECT_FALSE(page_action->GetDeclarativeIcon(tab_id).IsEmpty()); + EXPECT_FALSE(action->GetDeclarativeIcon(tab_id).IsEmpty()); // Navigating to an unmatched page should reset the icon. NavigateInRenderer(tab, GURL("http://test2/")); - EXPECT_TRUE(page_action->GetDeclarativeIcon(tab_id).IsEmpty()); + EXPECT_TRUE(action->GetDeclarativeIcon(tab_id).IsEmpty()); } } // namespace } // namespace extensions diff --git a/chromium/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_browsertest.cc b/chromium/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_browsertest.cc index 84a039dcf4f..38ba6dbacab 100644 --- a/chromium/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_browsertest.cc +++ b/chromium/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_browsertest.cc @@ -52,6 +52,7 @@ #include "content/public/browser/notification_service.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/storage_partition.h" +#include "content/public/common/url_constants.h" #include "content/public/test/browser_test_utils.h" #include "content/public/test/simple_url_loader_test_helper.h" #include "content/public/test/test_navigation_observer.h" @@ -870,8 +871,8 @@ IN_PROC_BROWSER_TEST_P(DeclarativeNetRequestBrowserTest, } } -// Tests allowing rules. -IN_PROC_BROWSER_TEST_P(DeclarativeNetRequestBrowserTest, Allow) { +// Tests allowing rules for blocks. +IN_PROC_BROWSER_TEST_P(DeclarativeNetRequestBrowserTest, AllowBlock) { const int kNumRequests = 6; TestRule rule = CreateGenericRule(); @@ -915,6 +916,103 @@ IN_PROC_BROWSER_TEST_P(DeclarativeNetRequestBrowserTest, Allow) { } } +// Tests allowing rules for redirects. +IN_PROC_BROWSER_TEST_P(DeclarativeNetRequestBrowserTest, AllowRedirect) { + set_has_background_script(true); + + const GURL static_redirect_url = embedded_test_server()->GetURL( + "example.com", base::StringPrintf("/pages_with_script/page2.html")); + + const GURL dynamic_redirect_url = embedded_test_server()->GetURL( + "abc.com", base::StringPrintf("/pages_with_script/page.html")); + + // Create 2 static and 2 dynamic rules. + struct { + std::string url_filter; + int id; + std::string action_type; + base::Optional<std::string> redirect_url; + } rules_data[] = { + {"google.com", 1, "redirect", static_redirect_url.spec()}, + {"num=1|", 2, "allow", base::nullopt}, + {"1|", 3, "redirect", dynamic_redirect_url.spec()}, + {"num=21|", 4, "allow", base::nullopt}, + }; + + std::vector<TestRule> rules; + for (const auto& rule_data : rules_data) { + TestRule rule = CreateGenericRule(); + rule.id = rule_data.id; + rule.priority = kMinValidPriority; + rule.condition->url_filter = rule_data.url_filter; + rule.condition->resource_types = std::vector<std::string>({"main_frame"}); + rule.action->type = rule_data.action_type; + rule.action->redirect_url = rule_data.redirect_url; + rules.push_back(rule); + } + + std::vector<TestRule> static_rules; + static_rules.push_back(rules[0]); + static_rules.push_back(rules[1]); + + std::vector<TestRule> dynamic_rules; + dynamic_rules.push_back(rules[2]); + dynamic_rules.push_back(rules[3]); + + ASSERT_NO_FATAL_FAILURE(LoadExtensionWithRules( + static_rules, "test_extension", {URLPattern::kAllUrlsPattern})); + + auto get_url = [this](int i) { + return embedded_test_server()->GetURL( + "google.com", + base::StringPrintf("/pages_with_script/page.html?num=%d", i)); + }; + + struct { + GURL initial_url; + GURL expected_final_url; + } static_test_cases[] = { + {get_url(0), static_redirect_url}, + {get_url(1), get_url(1)}, + }; + + for (const auto& test_case : static_test_cases) { + GURL url = test_case.initial_url; + SCOPED_TRACE(base::StringPrintf("Testing %s", url.spec().c_str())); + + ui_test_utils::NavigateToURL(browser(), url); + EXPECT_TRUE(WasFrameWithScriptLoaded(GetMainFrame())); + + GURL final_url = web_contents()->GetLastCommittedURL(); + EXPECT_EQ(test_case.expected_final_url, final_url); + } + + // Now add dynamic rules. These should override static rules in priority. + const ExtensionId& extension_id = last_loaded_extension_id(); + ASSERT_NO_FATAL_FAILURE(AddDynamicRules(extension_id, dynamic_rules)); + + // Test that rules follow the priority of: dynamic allow > dynamic redirect > + // static allow > static redirect. + struct { + GURL initial_url; + GURL expected_final_url; + } dynamic_test_cases[] = { + {get_url(1), dynamic_redirect_url}, + {get_url(21), get_url(21)}, + }; + + for (const auto& test_case : dynamic_test_cases) { + GURL url = test_case.initial_url; + SCOPED_TRACE(base::StringPrintf("Testing %s", url.spec().c_str())); + + ui_test_utils::NavigateToURL(browser(), url); + EXPECT_TRUE(WasFrameWithScriptLoaded(GetMainFrame())); + + GURL final_url = web_contents()->GetLastCommittedURL(); + EXPECT_EQ(test_case.expected_final_url, final_url); + } +} + // Tests that the extension ruleset is active only when the extension is // enabled. IN_PROC_BROWSER_TEST_P(DeclarativeNetRequestBrowserTest, @@ -1104,6 +1202,8 @@ IN_PROC_BROWSER_TEST_P(DeclarativeNetRequestBrowserTest, BlockAndRedirect) { {"abc.com", 3, "redirect", get_url_for_host("def.com")}, {"def.com", 4, "block", base::nullopt}, {"def.com", 5, "redirect", get_url_for_host("xyz.com")}, + {"ghi*", 6, "redirect", get_url_for_host("ghijk.com")}, + {"ijk*", 7, "redirect", "/manifest.json"}, }; // Load the extension. @@ -1124,37 +1224,46 @@ IN_PROC_BROWSER_TEST_P(DeclarativeNetRequestBrowserTest, BlockAndRedirect) { struct { std::string hostname; bool expected_main_frame_loaded; - base::Optional<std::string> expected_final_hostname; + base::Optional<GURL> expected_final_url; base::Optional<size_t> expected_redirect_chain_length; } test_cases[] = { // example.com -> yahoo.com -> google.com. - {"example.com", true, std::string("google.com"), 3}, + {"example.com", true, GURL(get_url_for_host("google.com")), 3}, // yahoo.com -> google.com. - {"yahoo.com", true, std::string("google.com"), 2}, + {"yahoo.com", true, GURL(get_url_for_host("google.com")), 2}, // abc.com -> def.com (blocked). // Note def.com won't be redirected since blocking rules are given // priority over redirect rules. {"abc.com", false, base::nullopt, base::nullopt}, // def.com (blocked). {"def.com", false, base::nullopt, base::nullopt}, - }; + // ghi.com -> ghijk.com. + // Though ghijk.com still matches the redirect rule for |ghi*|, it will + // not redirect to itself. + {"ghi.com", true, GURL(get_url_for_host("ghijk.com")), 2}, + // ijklm.com -> chrome-extension://<extension_id>/manifest.json. + // Since this redirects to a manifest.json, don't expect the frame with + // script to load. + {"ijklm.com", false, + GURL("chrome-extension://" + last_loaded_extension_id() + + "/manifest.json"), + 2}}; for (const auto& test_case : test_cases) { std::string url = get_url_for_host(test_case.hostname); SCOPED_TRACE(base::StringPrintf("Testing %s", url.c_str())); ui_test_utils::NavigateToURL(browser(), GURL(url)); + EXPECT_EQ(test_case.expected_main_frame_loaded, + WasFrameWithScriptLoaded(GetMainFrame())); - if (!test_case.expected_main_frame_loaded) { - EXPECT_FALSE(WasFrameWithScriptLoaded(GetMainFrame())); + if (!test_case.expected_final_url) { EXPECT_EQ(content::PAGE_TYPE_ERROR, GetPageType()); } else { - EXPECT_TRUE(WasFrameWithScriptLoaded(GetMainFrame())); EXPECT_EQ(content::PAGE_TYPE_NORMAL, GetPageType()); GURL final_url = web_contents()->GetLastCommittedURL(); - EXPECT_EQ(GURL(get_url_for_host(*test_case.expected_final_hostname)), - final_url); + EXPECT_EQ(*test_case.expected_final_url, final_url); EXPECT_EQ(*test_case.expected_redirect_chain_length, web_contents() @@ -1292,7 +1401,8 @@ IN_PROC_BROWSER_TEST_P(DeclarativeNetRequestBrowserTest, IN_PROC_BROWSER_TEST_P(DeclarativeNetRequestBrowserTest, ChromeURLS) { // Have the extension block all chrome:// urls. TestRule rule = CreateGenericRule(); - rule.condition->url_filter = std::string("chrome://"); + rule.condition->url_filter = + std::string(content::kChromeUIScheme) + url::kStandardSchemeSeparator; ASSERT_NO_FATAL_FAILURE(LoadExtensionWithRules({rule})); std::vector<const char*> test_urls = { diff --git a/chromium/chrome/browser/extensions/api/declarative_net_request/ruleset_manager_unittest.cc b/chromium/chrome/browser/extensions/api/declarative_net_request/ruleset_manager_unittest.cc index 77fc55a988e..3bd99e54abd 100644 --- a/chromium/chrome/browser/extensions/api/declarative_net_request/ruleset_manager_unittest.cc +++ b/chromium/chrome/browser/extensions/api/declarative_net_request/ruleset_manager_unittest.cc @@ -34,6 +34,28 @@ namespace extensions { namespace declarative_net_request { + +// Note: This is not declared in the anonymous namespace so that we can use it +// with gtest. +bool operator==(const RulesetManager::Action& lhs, + const RulesetManager::Action& rhs) { + static_assert(flat::ActionIndex_count == 6, + "Modify this method to ensure it stays updated as new actions " + "are added."); + + auto are_vectors_equal = [](std::vector<const char*> a, + std::vector<const char*> b) { + return std::set<base::StringPiece>(a.begin(), a.end()) == + std::set<base::StringPiece>(b.begin(), b.end()); + }; + + return lhs.type == rhs.type && lhs.redirect_url == rhs.redirect_url && + are_vectors_equal(lhs.request_headers_to_remove, + rhs.request_headers_to_remove) && + are_vectors_equal(lhs.response_headers_to_remove, + rhs.response_headers_to_remove); +} + namespace { constexpr char kJSONRulesFilename[] = "rules_file.json"; @@ -101,12 +123,15 @@ class RulesetManagerTest : public DNRTestBase { return last_loaded_extension_.get(); } - // Returns a renderer-initiated request to the given |url|. - WebRequestInfo GetRequestForURL(base::StringPiece url) { + // Returns renderer-initiated request params for the given |url|. + WebRequestInfoInitParams GetRequestParamsForURL( + base::StringPiece url, + base::Optional<url::Origin> initiator = base::nullopt) { const int kRendererId = 1; - WebRequestInfo info; + WebRequestInfoInitParams info; info.url = GURL(url); info.render_process_id = kRendererId; + info.initiator = std::move(initiator); return info; } @@ -138,10 +163,6 @@ TEST_P(RulesetManagerTest, MultipleRulesets) { RulesetManager* manager = info_map()->GetRulesetManager(); ASSERT_TRUE(manager); - WebRequestInfo request_one_info = GetRequestForURL("http://one.com"); - WebRequestInfo request_two_info = GetRequestForURL("http://two.com"); - WebRequestInfo request_three_info = GetRequestForURL("http://three.com"); - auto should_block_request = [manager](const WebRequestInfo& request) { return manager->EvaluateRequest(request, false /*is_incognito_context*/) == Action(ActionType::BLOCK); @@ -177,6 +198,11 @@ TEST_P(RulesetManagerTest, MultipleRulesets) { ASSERT_EQ(expected_matcher_count, manager->GetMatcherCountForTest()); + WebRequestInfo request_one_info(GetRequestParamsForURL("http://one.com")); + WebRequestInfo request_two_info(GetRequestParamsForURL("http://two.com")); + WebRequestInfo request_three_info( + GetRequestParamsForURL("http://three.com")); + EXPECT_EQ((mask & kEnableRulesetOne) != 0, should_block_request(request_one_info)); EXPECT_EQ((mask & kEnableRulesetTwo) != 0, @@ -206,7 +232,7 @@ TEST_P(RulesetManagerTest, IncognitoRequests) { manager->AddRuleset(last_loaded_extension()->id(), std::move(matcher), URLPatternSet()); - WebRequestInfo request_info = GetRequestForURL("http://example.com"); + WebRequestInfo request_info(GetRequestParamsForURL("http://example.com")); // By default, the extension is disabled in incognito mode. So requests from // incognito contexts should not be evaluated. @@ -215,9 +241,11 @@ TEST_P(RulesetManagerTest, IncognitoRequests) { EXPECT_EQ( Action(ActionType::NONE), manager->EvaluateRequest(request_info, true /*is_incognito_context*/)); + request_info.dnr_action.reset(); EXPECT_EQ( Action(ActionType::BLOCK), manager->EvaluateRequest(request_info, false /*is_incognito_context*/)); + request_info.dnr_action.reset(); // Enabling the extension in incognito mode, should cause requests from // incognito contexts to also be evaluated. @@ -227,9 +255,11 @@ TEST_P(RulesetManagerTest, IncognitoRequests) { EXPECT_EQ( Action(ActionType::BLOCK), manager->EvaluateRequest(request_info, true /*is_incognito_context*/)); + request_info.dnr_action.reset(); EXPECT_EQ( Action(ActionType::BLOCK), manager->EvaluateRequest(request_info, false /*is_incognito_context*/)); + request_info.dnr_action.reset(); } // Tests that @@ -239,8 +269,10 @@ TEST_P(RulesetManagerTest, TotalEvaluationTimeHistogram) { RulesetManager* manager = info_map()->GetRulesetManager(); ASSERT_TRUE(manager); - WebRequestInfo example_com_request = GetRequestForURL("http://example.com"); - WebRequestInfo google_com_request = GetRequestForURL("http://google.com"); + WebRequestInfo example_com_request( + GetRequestParamsForURL("http://example.com")); + WebRequestInfo google_com_request( + GetRequestParamsForURL("http://google.com")); bool is_incognito_context = false; const char* kHistogramName = "Extensions.DeclarativeNetRequest.EvaluateRequestTime.AllExtensions2"; @@ -253,6 +285,8 @@ TEST_P(RulesetManagerTest, TotalEvaluationTimeHistogram) { Action(ActionType::NONE), manager->EvaluateRequest(google_com_request, is_incognito_context)); tester.ExpectTotalCount(kHistogramName, 0); + example_com_request.dnr_action.reset(); + google_com_request.dnr_action.reset(); } // Add an extension ruleset which blocks requests to "example.com". @@ -274,6 +308,8 @@ TEST_P(RulesetManagerTest, TotalEvaluationTimeHistogram) { Action(ActionType::NONE), manager->EvaluateRequest(google_com_request, is_incognito_context)); tester.ExpectTotalCount(kHistogramName, 2); + example_com_request.dnr_action.reset(); + google_com_request.dnr_action.reset(); } } @@ -298,30 +334,32 @@ TEST_P(RulesetManagerTest, Redirect) { // Create a request to "example.com" with an empty initiator. It should be // redirected to "google.com". const bool is_incognito_context = false; - WebRequestInfo request = GetRequestForURL("http://example.com"); - request.initiator = base::nullopt; - Action action = manager->EvaluateRequest(request, is_incognito_context); - EXPECT_EQ(ActionType::REDIRECT, action.type); - EXPECT_EQ(GURL("http://google.com"), action.redirect_url); + const char* kExampleURL = "http://example.com"; + Action expected_redirect_action(ActionType::REDIRECT); + expected_redirect_action.redirect_url = GURL("http://google.com"); + WebRequestInfo request_1(GetRequestParamsForURL(kExampleURL, base::nullopt)); + EXPECT_EQ(expected_redirect_action, + manager->EvaluateRequest(request_1, is_incognito_context)); // Change the initiator to "xyz.com". It should not be redirected since we // don't have host permissions to the request initiator. - request.initiator = url::Origin::Create(GURL("http://xyz.com")); - action = manager->EvaluateRequest(request, is_incognito_context); - EXPECT_EQ(Action(ActionType::NONE), action); + WebRequestInfo request_2(GetRequestParamsForURL( + kExampleURL, url::Origin::Create(GURL("http://xyz.com")))); + EXPECT_EQ(Action(ActionType::NONE), + manager->EvaluateRequest(request_2, is_incognito_context)); // Change the initiator to "abc.com". It should be redirected since we have // the required host permissions. - request.initiator = url::Origin::Create(GURL("http://abc.com")); - action = manager->EvaluateRequest(request, is_incognito_context); - EXPECT_EQ(ActionType::REDIRECT, action.type); - EXPECT_EQ(GURL("http://google.com"), action.redirect_url); + WebRequestInfo request_3(GetRequestParamsForURL( + kExampleURL, url::Origin::Create(GURL("http://abc.com")))); + EXPECT_EQ(expected_redirect_action, + manager->EvaluateRequest(request_3, is_incognito_context)); // Ensure web-socket requests are not redirected. - request = GetRequestForURL("ws://example.com"); - request.initiator = base::nullopt; - action = manager->EvaluateRequest(request, is_incognito_context); - EXPECT_EQ(Action(ActionType::NONE), action); + WebRequestInfo request_4( + GetRequestParamsForURL("ws://example.com", base::nullopt)); + EXPECT_EQ(Action(ActionType::NONE), + manager->EvaluateRequest(request_4, is_incognito_context)); } // Tests that an extension can't block or redirect resources on the chrome- @@ -366,32 +404,38 @@ TEST_P(RulesetManagerTest, ExtensionScheme) { // Ensure that "http://example.com" will be blocked (with blocking taking // priority over redirection). - WebRequestInfo request = GetRequestForURL("http://example.com"); - EXPECT_EQ(Action(ActionType::BLOCK), - manager->EvaluateRequest(request, false /*is_incognito_context*/)); + WebRequestInfo request_1(GetRequestParamsForURL("http://example.com")); + EXPECT_EQ( + Action(ActionType::BLOCK), + manager->EvaluateRequest(request_1, false /*is_incognito_context*/)); // Ensure that the background page for |extension_1| won't be blocked or // redirected. GURL background_page_url_1 = BackgroundInfo::GetBackgroundURL(extension_1); EXPECT_TRUE(!background_page_url_1.is_empty()); - request = GetRequestForURL(background_page_url_1.spec()); - EXPECT_EQ(Action(ActionType::NONE), - manager->EvaluateRequest(request, false /*is_incognito_context*/)); + WebRequestInfo request_2( + GetRequestParamsForURL(background_page_url_1.spec())); + EXPECT_EQ( + Action(ActionType::NONE), + manager->EvaluateRequest(request_2, false /*is_incognito_context*/)); // Ensure that the background page for |extension_2| won't be blocked or // redirected. GURL background_page_url_2 = BackgroundInfo::GetBackgroundURL(extension_2); EXPECT_TRUE(!background_page_url_2.is_empty()); - request = GetRequestForURL(background_page_url_2.spec()); - EXPECT_EQ(Action(ActionType::NONE), - manager->EvaluateRequest(request, false /*is_incognito_context*/)); + WebRequestInfo request_3( + GetRequestParamsForURL(background_page_url_2.spec())); + EXPECT_EQ( + Action(ActionType::NONE), + manager->EvaluateRequest(request_3, false /*is_incognito_context*/)); // Also ensure that an arbitrary url on the chrome extension scheme is also // not blocked or redirected. - request = GetRequestForURL(base::StringPrintf("%s://%s/%s", kExtensionScheme, - "extension_id", "path")); - EXPECT_EQ(Action(ActionType::NONE), - manager->EvaluateRequest(request, false /*is_incognito_context*/)); + WebRequestInfo request_4(GetRequestParamsForURL(base::StringPrintf( + "%s://%s/%s", kExtensionScheme, "extension_id", "path"))); + EXPECT_EQ( + Action(ActionType::NONE), + manager->EvaluateRequest(request_4, false /*is_incognito_context*/)); } TEST_P(RulesetManagerTest, PageAllowingAPI) { @@ -527,30 +571,31 @@ TEST_P(RulesetManagerTest, PageAllowingAPI) { SCOPED_TRACE(base::StringPrintf("Testing case number %zu with url %s", i + 1, test_case.url.c_str())); - WebRequestInfo info = GetRequestForURL(test_case.url); - ASSERT_TRUE(info.url.is_valid()); - info.type = test_case.type; + WebRequestInfoInitParams params = GetRequestParamsForURL(test_case.url); + ASSERT_TRUE(params.url.is_valid()); + params.type = test_case.type; if (test_case.initiator) - info.initiator = url::Origin::Create(GURL(*test_case.initiator)); + params.initiator = url::Origin::Create(GURL(*test_case.initiator)); - info.frame_id = test_case.frame_routing_id; + params.frame_id = test_case.frame_routing_id; if (test_case.frame_data_params) { - const FrameDataParams& params = *test_case.frame_data_params; - info.frame_data = ExtensionApiFrameIdMap::FrameData( - params.frame_id, params.parent_frame_id, kDummyTabId, kDummyWindowId, - GURL(params.last_committed_main_frame_url)); - if (params.pending_main_frame_url) - info.frame_data->pending_main_frame_url = - GURL(*params.pending_main_frame_url); + const FrameDataParams& frame_params = *test_case.frame_data_params; + params.frame_data = ExtensionApiFrameIdMap::FrameData( + frame_params.frame_id, frame_params.parent_frame_id, kDummyTabId, + kDummyWindowId, GURL(frame_params.last_committed_main_frame_url)); + if (frame_params.pending_main_frame_url) + params.frame_data->pending_main_frame_url = + GURL(*frame_params.pending_main_frame_url); } Action expected_action = test_case.expect_blocked_with_allowed_pages ? Action(ActionType::BLOCK) : Action(ActionType::NONE); EXPECT_EQ(expected_action, - manager->EvaluateRequest(info, false /*is_incognito_context*/)); + manager->EvaluateRequest(WebRequestInfo(std::move(params)), + false /*is_incognito_context*/)); } } @@ -623,8 +668,7 @@ TEST_P(RulesetManagerTest, HostPermissionForInitiator) { "Url-%s initiator-%s", url.c_str(), initiator ? initiator->Serialize().c_str() : "empty")); - WebRequestInfo request = GetRequestForURL(url); - request.initiator = initiator; + WebRequestInfo request(GetRequestParamsForURL(url, initiator)); bool is_incognito_context = false; EXPECT_EQ(expected_action, diff --git a/chromium/chrome/browser/extensions/api/declarative_webrequest/webrequest_action_unittest.cc b/chromium/chrome/browser/extensions/api/declarative_webrequest/webrequest_action_unittest.cc index 6f56e081152..fcfdf5db350 100644 --- a/chromium/chrome/browser/extensions/api/declarative_webrequest/webrequest_action_unittest.cc +++ b/chromium/chrome/browser/extensions/api/declarative_webrequest/webrequest_action_unittest.cc @@ -155,8 +155,9 @@ bool WebRequestActionWithThreadsTest::ActionWorksOnRequest( EventResponseDeltas deltas; scoped_refptr<net::HttpResponseHeaders> headers( new net::HttpResponseHeaders("")); - WebRequestInfo request_info(regular_request.get()); - request_info.render_process_id = kRendererId; + WebRequestInfoInitParams request_params(regular_request.get()); + request_params.render_process_id = kRendererId; + WebRequestInfo request_info(std::move(request_params)); WebRequestData request_data(&request_info, stage, headers.get()); std::set<std::string> ignored_tags; WebRequestAction::ApplyInfo apply_info = { extension_info_map_.get(), diff --git a/chromium/chrome/browser/extensions/api/declarative_webrequest/webrequest_rules_registry_unittest.cc b/chromium/chrome/browser/extensions/api/declarative_webrequest/webrequest_rules_registry_unittest.cc index 7cf3c6be1f2..51d86cb4112 100644 --- a/chromium/chrome/browser/extensions/api/declarative_webrequest/webrequest_rules_registry_unittest.cc +++ b/chromium/chrome/browser/extensions/api/declarative_webrequest/webrequest_rules_registry_unittest.cc @@ -50,8 +50,8 @@ const char kRuleId3[] = "rule3"; const char kRuleId4[] = "rule4"; // Creates a main-frame navigation request to |url|. -WebRequestInfo CreateRequest(const GURL& url) { - WebRequestInfo info; +WebRequestInfoInitParams CreateRequestParams(const GURL& url) { + WebRequestInfoInitParams info; info.url = url; info.is_browser_side_navigation = true; info.type = content::ResourceType::kMainFrame; @@ -286,7 +286,7 @@ TEST_F(WebRequestRulesRegistryTest, AddRulesImpl) { std::set<const WebRequestRule*> matches; GURL http_url("http://www.example.com"); - WebRequestInfo http_request_info = CreateRequest(http_url); + WebRequestInfo http_request_info(CreateRequestParams(http_url)); WebRequestData request_data(&http_request_info, ON_BEFORE_REQUEST); matches = registry->GetMatches(request_data); EXPECT_EQ(2u, matches.size()); @@ -300,7 +300,7 @@ TEST_F(WebRequestRulesRegistryTest, AddRulesImpl) { base::ContainsKey(matches_ids, std::make_pair(kExtensionId, kRuleId2))); GURL foobar_url("http://www.foobar.com"); - WebRequestInfo foobar_request_info = CreateRequest(foobar_url); + WebRequestInfo foobar_request_info(CreateRequestParams(foobar_url)); request_data.request = &foobar_request_info; matches = registry->GetMatches(request_data); EXPECT_EQ(1u, matches.size()); @@ -436,7 +436,7 @@ TEST_F(WebRequestRulesRegistryTest, Precedences) { } GURL url("http://www.google.com"); - WebRequestInfo request_info = CreateRequest(url); + WebRequestInfo request_info(CreateRequestParams(url)); WebRequestData request_data(&request_info, ON_BEFORE_REQUEST); EventResponseDeltas deltas = registry->CreateDeltas(NULL, request_data, false); @@ -488,7 +488,7 @@ TEST_F(WebRequestRulesRegistryTest, Priorities) { } GURL url("http://www.google.com/index.html"); - WebRequestInfo request_info = CreateRequest(url); + WebRequestInfo request_info(CreateRequestParams(url)); WebRequestData request_data(&request_info, ON_BEFORE_REQUEST); EventResponseDeltas deltas = registry->CreateDeltas(nullptr, request_data, false); @@ -564,7 +564,7 @@ TEST_F(WebRequestRulesRegistryTest, IgnoreRulesByTag) { EXPECT_FALSE(registry->IsEmpty()); GURL url("http://www.foo.com/test"); - WebRequestInfo request_info = CreateRequest(url); + WebRequestInfo request_info(CreateRequestParams(url)); WebRequestData request_data(&request_info, ON_BEFORE_REQUEST); EventResponseDeltas deltas = registry->CreateDeltas(NULL, request_data, false); @@ -614,7 +614,7 @@ TEST_F(WebRequestRulesRegistryTest, GetMatchesCheckFulfilled) { std::set<const WebRequestRule*> matches; GURL http_url("http://www.example.com"); - WebRequestInfo http_request_info = CreateRequest(http_url); + WebRequestInfo http_request_info(CreateRequestParams(http_url)); WebRequestData request_data(&http_request_info, ON_BEFORE_REQUEST); matches = registry->GetMatches(request_data); EXPECT_EQ(1u, matches.size()); @@ -674,8 +674,9 @@ TEST_F(WebRequestRulesRegistryTest, GetMatchesDifferentUrls) { for (size_t i = 0; i < base::size(matchingRuleIds); ++i) { // Construct the inputs. - WebRequestInfo http_request_info = CreateRequest(urls[i]); - http_request_info.site_for_cookies = firstPartyUrls[i]; + WebRequestInfoInitParams params = CreateRequestParams(urls[i]); + params.site_for_cookies = firstPartyUrls[i]; + WebRequestInfo http_request_info(std::move(params)); WebRequestData request_data(&http_request_info, ON_BEFORE_REQUEST); // Now run both rules on the input. matches = registry->GetMatches(request_data); @@ -823,14 +824,14 @@ TEST_F(WebRequestRulesRegistryTest, CheckOriginAndPathRegEx) { // No match because match is in the query parameter. GURL url1("http://bar.com/index.html?foo.com"); - WebRequestInfo request1_info = CreateRequest(url1); + WebRequestInfo request1_info(CreateRequestParams(url1)); WebRequestData request_data1(&request1_info, ON_BEFORE_REQUEST); deltas = registry->CreateDeltas(NULL, request_data1, false); EXPECT_EQ(0u, deltas.size()); // This is a correct match. GURL url2("http://foo.com/index.html"); - WebRequestInfo request2_info = CreateRequest(url2); + WebRequestInfo request2_info(CreateRequestParams(url2)); WebRequestData request_data2(&request2_info, ON_BEFORE_REQUEST); deltas = registry->CreateDeltas(NULL, request_data2, false); EXPECT_EQ(1u, deltas.size()); diff --git a/chromium/chrome/browser/extensions/api/developer_private/extension_info_generator.cc b/chromium/chrome/browser/extensions/api/developer_private/extension_info_generator.cc index 2e5b7499404..c885dc1aa37 100644 --- a/chromium/chrome/browser/extensions/api/developer_private/extension_info_generator.cc +++ b/chromium/chrome/browser/extensions/api/developer_private/extension_info_generator.cc @@ -12,7 +12,6 @@ #include "base/base64.h" #include "base/bind.h" -#include "base/callback_helpers.h" #include "base/location.h" #include "base/single_thread_task_runner.h" #include "base/stl_util.h" @@ -781,7 +780,7 @@ void ExtensionInfoGenerator::OnImageLoaded( if (pending_image_loads_ == 0) { // All done! ExtensionInfoList list = std::move(list_); list_.clear(); - base::ResetAndReturn(&callback_).Run(std::move(list)); + std::move(callback_).Run(std::move(list)); // WARNING: |this| is possibly deleted after this line! } } diff --git a/chromium/chrome/browser/extensions/api/developer_private/extension_info_generator_unittest.cc b/chromium/chrome/browser/extensions/api/developer_private/extension_info_generator_unittest.cc index 0761394d958..cf68ed7c110 100644 --- a/chromium/chrome/browser/extensions/api/developer_private/extension_info_generator_unittest.cc +++ b/chromium/chrome/browser/extensions/api/developer_private/extension_info_generator_unittest.cc @@ -299,8 +299,6 @@ TEST_F(ExtensionInfoGeneratorUnitTest, BasicInfoTest) { EXPECT_FALSE(info->file_access.is_active); EXPECT_TRUE(info->incognito_access.is_enabled); EXPECT_FALSE(info->incognito_access.is_active); - PermissionMessages messages = - extension->permissions_data()->GetPermissionMessages(); // Strip out the kHostReadWrite permission created by the extension requesting // host permissions above; runtime host permissions mean these are always @@ -309,11 +307,12 @@ TEST_F(ExtensionInfoGeneratorUnitTest, BasicInfoTest) { // entry in |messages| has a matching entry in // |info->permissions.simple_permissions|, and kHostReadWrite is not a simple // permission. - for (auto it = messages.begin(); it != messages.end(); ++it) { - if (it->permissions().ContainsID( + PermissionMessages messages; + for (const PermissionMessage& message : + extension->permissions_data()->GetPermissionMessages()) { + if (!message.permissions().ContainsID( extensions::APIPermission::kHostReadWrite)) { - messages.erase(it); - break; + messages.push_back(message); } } diff --git a/chromium/chrome/browser/extensions/api/device_permissions_manager_unittest.cc b/chromium/chrome/browser/extensions/api/device_permissions_manager_unittest.cc index b8555d62fad..e025c5a9ee7 100644 --- a/chromium/chrome/browser/extensions/api/device_permissions_manager_unittest.cc +++ b/chromium/chrome/browser/extensions/api/device_permissions_manager_unittest.cc @@ -12,15 +12,15 @@ #include "base/test/values_test_util.h" #include "chrome/browser/extensions/test_extension_environment.h" #include "chrome/test/base/testing_profile.h" -#include "device/usb/public/cpp/fake_usb_device_manager.h" -#include "device/usb/public/mojom/device.mojom.h" #include "extensions/browser/api/device_permissions_manager.h" #include "extensions/browser/api/hid/hid_device_manager.h" #include "extensions/browser/api/usb/usb_device_manager.h" #include "extensions/browser/extension_prefs.h" #include "extensions/common/extension.h" #include "services/device/public/cpp/hid/fake_hid_manager.h" +#include "services/device/public/cpp/test/fake_usb_device_manager.h" #include "services/device/public/mojom/hid.mojom.h" +#include "services/device/public/mojom/usb_device.mojom.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" diff --git a/chromium/chrome/browser/extensions/api/downloads/downloads_api.cc b/chromium/chrome/browser/extensions/api/downloads/downloads_api.cc index 9b7a6503f7c..e9237e6585a 100644 --- a/chromium/chrome/browser/extensions/api/downloads/downloads_api.cc +++ b/chromium/chrome/browser/extensions/api/downloads/downloads_api.cc @@ -313,8 +313,9 @@ class DownloadFileIconExtractorImpl : public DownloadFileIconExtractor { IconURLCallback callback) override; private: - void OnIconLoadComplete( - float scale, const IconURLCallback& callback, gfx::Image* icon); + void OnIconLoadComplete(float scale, + const IconURLCallback& callback, + gfx::Image icon); base::CancelableTaskTracker cancelable_task_tracker_; }; @@ -337,12 +338,15 @@ bool DownloadFileIconExtractorImpl::ExtractIconURLForPath( } void DownloadFileIconExtractorImpl::OnIconLoadComplete( - float scale, const IconURLCallback& callback, gfx::Image* icon) { + float scale, + const IconURLCallback& callback, + gfx::Image icon) { DCHECK_CURRENTLY_ON(BrowserThread::UI); callback.Run( - !icon ? std::string() - : webui::GetBitmapDataUrl( - icon->ToImageSkia()->GetRepresentation(scale).GetBitmap())); + icon.IsEmpty() + ? std::string() + : webui::GetBitmapDataUrl( + icon.ToImageSkia()->GetRepresentation(scale).GetBitmap())); } IconLoader::IconSize IconLoaderSizeFromPixelSize(int pixel_size) { diff --git a/chromium/chrome/browser/extensions/api/downloads/downloads_api_browsertest.cc b/chromium/chrome/browser/extensions/api/downloads/downloads_api_browsertest.cc index 923a5565161..734a2c28b0c 100644 --- a/chromium/chrome/browser/extensions/api/downloads/downloads_api_browsertest.cc +++ b/chromium/chrome/browser/extensions/api/downloads/downloads_api_browsertest.cc @@ -14,13 +14,13 @@ #include "base/guid.h" #include "base/json/json_reader.h" #include "base/memory/ptr_util.h" -#include "base/message_loop/message_loop_current.h" #include "base/run_loop.h" #include "base/stl_util.h" #include "base/strings/stringprintf.h" #include "base/task/post_task.h" #include "base/test/bind_test_util.h" #include "base/threading/thread_restrictions.h" +#include "base/threading/thread_task_runner_handle.h" #include "build/build_config.h" #include "chrome/browser/download/download_core_service.h" #include "chrome/browser/download/download_core_service_factory.h" @@ -75,6 +75,7 @@ #include "storage/browser/fileapi/file_system_operation_runner.h" #include "storage/browser/fileapi/file_system_url.h" #include "ui/base/page_transition_types.h" +#include "url/origin.h" using content::BrowserContext; using content::BrowserThread; @@ -493,7 +494,7 @@ class DownloadExtensionTest : public ExtensionApiTest { base::GenerateGUID(), download::DownloadItem::kInvalidId + 1 + i, downloads_directory().Append(history_info[i].filename), downloads_directory().Append(history_info[i].filename), url_chain, - GURL(), GURL(), GURL(), GURL(), std::string(), + GURL(), GURL(), GURL(), GURL(), url::Origin(), std::string(), std::string(), // mime_type, original_mime_type current, current, // start_time, end_time @@ -1813,7 +1814,7 @@ class CustomResponse : public net::test_server::HttpResponse { if (first_request_) { *callback_ = std::move(done); - *task_runner_ = base::MessageLoopCurrent::Get()->task_runner().get(); + *task_runner_ = base::ThreadTaskRunnerHandle::Get().get(); send.Run(response, base::BindRepeating([]() {})); } else { send.Run(response, std::move(done)); diff --git a/chromium/chrome/browser/extensions/api/enterprise_device_attributes/enterprise_device_attributes_apitest.cc b/chromium/chrome/browser/extensions/api/enterprise_device_attributes/enterprise_device_attributes_apitest.cc index 75ff22fb010..9d3f31a0a72 100644 --- a/chromium/chrome/browser/extensions/api/enterprise_device_attributes/enterprise_device_attributes_apitest.cc +++ b/chromium/chrome/browser/extensions/api/enterprise_device_attributes/enterprise_device_attributes_apitest.cc @@ -147,6 +147,7 @@ class EnterpriseDeviceAttributesTest device_affiliation_ids.insert(kAffiliationID); ASSERT_NO_FATAL_FAILURE(affiliation_helper.SetDeviceAffiliationIDs( &test_helper_, device_affiliation_ids)); + test_helper_.InstallOwnerKey(); std::set<std::string> user_affiliation_ids; if (GetParam().affiliated) { diff --git a/chromium/chrome/browser/extensions/api/enterprise_reporting_private/enterprise_reporting_private_unittest.cc b/chromium/chrome/browser/extensions/api/enterprise_reporting_private/enterprise_reporting_private_unittest.cc index f850d1b2fe4..bca47a1b158 100644 --- a/chromium/chrome/browser/extensions/api/enterprise_reporting_private/enterprise_reporting_private_unittest.cc +++ b/chromium/chrome/browser/extensions/api/enterprise_reporting_private/enterprise_reporting_private_unittest.cc @@ -9,7 +9,7 @@ #include "base/strings/stringprintf.h" #include "chrome/browser/extensions/extension_api_unittest.h" #include "chrome/browser/extensions/extension_function_test_utils.h" -#include "chrome/browser/policy/browser_dm_token_storage.h" +#include "chrome/browser/policy/fake_browser_dm_token_storage.h" #include "components/policy/core/common/cloud/mock_cloud_policy_client.h" #include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h" #include "services/network/test/test_url_loader_factory.h" @@ -26,56 +26,6 @@ const char kFakeDMToken[] = "fake-dm-token"; const char kFakeClientId[] = "fake-client-id"; const char kFakeMachineNameReport[] = "{\"computername\":\"name\"}"; -class MockCloudPolicyClient : public policy::MockCloudPolicyClient { - public: - explicit MockCloudPolicyClient( - scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) - : policy::MockCloudPolicyClient(std::move(url_loader_factory)) {} - - void UploadChromeDesktopReport( - std::unique_ptr<enterprise_management::ChromeDesktopReportRequest> - request, - const StatusCallback& callback) override { - UploadChromeDesktopReportProxy(request.get(), callback); - } - MOCK_METHOD2(UploadChromeDesktopReportProxy, - void(enterprise_management::ChromeDesktopReportRequest*, - const StatusCallback&)); - - void OnReportUploadedFailed(const StatusCallback& callback) { - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::BindOnce(callback, false)); - } - - void OnReportUploadedSucceeded(const StatusCallback& callback) { - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::BindOnce(callback, true)); - } - - private: - DISALLOW_COPY_AND_ASSIGN(MockCloudPolicyClient); -}; - -class FakeBrowserDMTokenStorage : public policy::BrowserDMTokenStorage { - public: - FakeBrowserDMTokenStorage() = default; - ~FakeBrowserDMTokenStorage() override = default; - - void SetClientId(const std::string& client_id) { client_id_ = client_id; } - - // policy::BrowserDMTokenStorage: - std::string InitClientId() override { return client_id_; } - std::string InitEnrollmentToken() override { return std::string(); } - std::string InitDMToken() override { return std::string(); } - bool InitEnrollmentErrorOption() override { return true; } - void SaveDMToken(const std::string& token) override {} - - private: - std::string client_id_; - - DISALLOW_COPY_AND_ASSIGN(FakeBrowserDMTokenStorage); -}; - } // namespace // Test for API enterprise.reportingPrivate.uploadChromeDesktopReport @@ -89,7 +39,7 @@ class EnterpriseReportingPrivateUploadChromeDesktopReportTest EnterpriseReportingPrivateUploadChromeDesktopReportFunction* function = EnterpriseReportingPrivateUploadChromeDesktopReportFunction:: CreateForTesting(test_url_loader_factory_.GetSafeWeakWrapper()); - auto client = std::make_unique<MockCloudPolicyClient>( + auto client = std::make_unique<policy::MockCloudPolicyClient>( test_url_loader_factory_.GetSafeWeakWrapper()); client_ = client.get(); function->SetCloudPolicyClientForTesting(std::move(client)); @@ -109,7 +59,7 @@ class EnterpriseReportingPrivateUploadChromeDesktopReportTest "{\"chromeUserProfileReport\":[{\"chromeSignInUser\":\"Name\"}]}}]"); } - MockCloudPolicyClient* client_; + policy::MockCloudPolicyClient* client_; private: network::TestURLLoaderFactory test_url_loader_factory_; @@ -140,8 +90,7 @@ TEST_F(EnterpriseReportingPrivateUploadChromeDesktopReportTest, UploadFailed) { EXPECT_CALL(*client_, SetupRegistration(kFakeDMToken, kFakeClientId, _)) .Times(1); EXPECT_CALL(*client_, UploadChromeDesktopReportProxy(_, _)) - .WillOnce(WithArgs<1>( - Invoke(client_, &MockCloudPolicyClient::OnReportUploadedFailed))); + .WillOnce(WithArgs<1>(policy::ScheduleStatusCallback(false))); ASSERT_EQ(enterprise_reporting::kUploadFailed, RunFunctionAndReturnError(function, GenerateArgs(kFakeMachineNameReport))); @@ -155,8 +104,7 @@ TEST_F(EnterpriseReportingPrivateUploadChromeDesktopReportTest, EXPECT_CALL(*client_, SetupRegistration(kFakeDMToken, kFakeClientId, _)) .Times(1); EXPECT_CALL(*client_, UploadChromeDesktopReportProxy(_, _)) - .WillOnce(WithArgs<1>( - Invoke(client_, &MockCloudPolicyClient::OnReportUploadedSucceeded))); + .WillOnce(WithArgs<1>(policy::ScheduleStatusCallback(true))); ASSERT_EQ(nullptr, RunFunctionAndReturnValue( function, GenerateArgs(kFakeMachineNameReport))); ::testing::Mock::VerifyAndClearExpectations(client_); @@ -165,16 +113,14 @@ TEST_F(EnterpriseReportingPrivateUploadChromeDesktopReportTest, // Test for API enterprise.reportingPrivate.getDeviceId class EnterpriseReportingPrivateGetDeviceIdTest : public ExtensionApiUnittest { public: - EnterpriseReportingPrivateGetDeviceIdTest() { - policy::BrowserDMTokenStorage::SetForTesting(&storage_); - } + EnterpriseReportingPrivateGetDeviceIdTest() = default; void SetClientId(const std::string& client_id) { storage_.SetClientId(client_id); } private: - FakeBrowserDMTokenStorage storage_; + policy::FakeBrowserDMTokenStorage storage_; DISALLOW_COPY_AND_ASSIGN(EnterpriseReportingPrivateGetDeviceIdTest); }; diff --git a/chromium/chrome/browser/extensions/api/extension_action/browser_action_apitest.cc b/chromium/chrome/browser/extensions/api/extension_action/browser_action_apitest.cc index 482a95a6821..c9aa19e8eba 100644 --- a/chromium/chrome/browser/extensions/api/extension_action/browser_action_apitest.cc +++ b/chromium/chrome/browser/extensions/api/extension_action/browser_action_apitest.cc @@ -145,8 +145,12 @@ class BrowserActionApiTest : public ExtensionApiTest { } ExtensionAction* GetBrowserAction(const Extension& extension) { - return ExtensionActionManager::Get(browser()->profile())-> - GetBrowserAction(extension); + ExtensionAction* extension_action = + ExtensionActionManager::Get(browser()->profile()) + ->GetExtensionAction(extension); + return extension_action->action_type() == ActionInfo::TYPE_BROWSER + ? extension_action + : nullptr; } private: diff --git a/chromium/chrome/browser/extensions/api/extension_action/browser_action_browsertest.cc b/chromium/chrome/browser/extensions/api/extension_action/browser_action_browsertest.cc index be83e7d9243..2c4893d0dc1 100644 --- a/chromium/chrome/browser/extensions/api/extension_action/browser_action_browsertest.cc +++ b/chromium/chrome/browser/extensions/api/extension_action/browser_action_browsertest.cc @@ -64,7 +64,7 @@ IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, ASSERT_TRUE(listener.WaitUntilSatisfied()); ExtensionAction* extension_action = - ExtensionActionManager::Get(profile())->GetBrowserAction(*extension); + ExtensionActionManager::Get(profile())->GetExtensionAction(*extension); ASSERT_TRUE(extension_action); EXPECT_EQ(SK_ColorBLUE, extension_action->GetBadgeBackgroundColor(0)); } @@ -89,7 +89,7 @@ IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, BrowserActionDefaultPersistence) { ASSERT_TRUE(extension) << "Could not find extension in registry."; ExtensionAction* extension_action = - ExtensionActionManager::Get(profile())->GetBrowserAction(*extension); + ExtensionActionManager::Get(profile())->GetExtensionAction(*extension); ASSERT_TRUE(extension_action); // If the extension hasn't already set the badge text, then we should wait for diff --git a/chromium/chrome/browser/extensions/api/extension_action/browser_action_interactive_test.cc b/chromium/chrome/browser/extensions/api/extension_action/browser_action_interactive_test.cc index 760a4fafa83..7ad5b39767f 100644 --- a/chromium/chrome/browser/extensions/api/extension_action/browser_action_interactive_test.cc +++ b/chromium/chrome/browser/extensions/api/extension_action/browser_action_interactive_test.cc @@ -22,8 +22,12 @@ #include "chrome/browser/ui/toolbar/toolbar_actions_model.h" #include "chrome/test/base/interactive_test_utils.h" #include "chrome/test/base/ui_test_utils.h" +#include "components/zoom/test/zoom_test_utils.h" +#include "components/zoom/zoom_controller.h" +#include "content/public/browser/host_zoom_map.h" #include "content/public/browser/notification_service.h" #include "content/public/browser/notification_types.h" +#include "content/public/common/page_zoom.h" #include "extensions/browser/extension_registry.h" #include "extensions/browser/extension_system.h" #include "extensions/browser/notification_types.h" @@ -419,6 +423,77 @@ IN_PROC_BROWSER_TEST_F(BrowserActionInteractiveTest, EXPECT_FALSE(browser_action_test_util->HasPopup()); } +IN_PROC_BROWSER_TEST_F(BrowserActionInteractiveTest, PopupZoomsIndependently) { + if (!ShouldRunPopupTest()) + return; + + ASSERT_TRUE( + LoadExtension(test_data_dir_.AppendASCII("browser_action/open_popup"))); + const Extension* extension = GetSingleLoadedExtension(); + ASSERT_TRUE(extension) << message_; + + // Navigate to one of the extension's pages in a tab. + ui_test_utils::NavigateToURL(browser(), + extension->GetResourceURL("popup.html")); + content::WebContents* tab_contents = + browser()->tab_strip_model()->GetActiveWebContents(); + + // Zoom the extension page in the tab. + zoom::ZoomController* zoom_controller = + zoom::ZoomController::FromWebContents(tab_contents); + double tab_old_zoom_level = zoom_controller->GetZoomLevel(); + double tab_new_zoom_level = tab_old_zoom_level + 1.0; + zoom::ZoomController::ZoomChangedEventData zoom_change_data( + tab_contents, tab_old_zoom_level, tab_new_zoom_level, + zoom::ZoomController::ZOOM_MODE_DEFAULT, true); + zoom::ZoomChangedWatcher zoom_change_watcher(tab_contents, zoom_change_data); + zoom_controller->SetZoomLevel(tab_new_zoom_level); + zoom_change_watcher.Wait(); + + // Open the extension's popup. + content::WindowedNotificationObserver popup_observer( + NOTIFICATION_EXTENSION_HOST_CREATED, + content::NotificationService::AllSources()); + OpenPopupViaToolbar(); + popup_observer.Wait(); + ExtensionHost* extension_host = + content::Details<ExtensionHost>(popup_observer.details()).ptr(); + content::WebContents* popup_contents = extension_host->host_contents(); + + // The popup should not use the per-origin zoom level that was set by zooming + // the tab. + const double default_zoom_level = + content::HostZoomMap::GetForWebContents(popup_contents) + ->GetDefaultZoomLevel(); + double popup_zoom_level = content::HostZoomMap::GetZoomLevel(popup_contents); + EXPECT_TRUE(content::ZoomValuesEqual(popup_zoom_level, default_zoom_level)) + << popup_zoom_level << " vs " << default_zoom_level; + + // Preventing the use of the per-origin zoom level in the popup should not + // affect the zoom of the tab. + EXPECT_TRUE(content::ZoomValuesEqual(zoom_controller->GetZoomLevel(), + tab_new_zoom_level)) + << zoom_controller->GetZoomLevel() << " vs " << tab_new_zoom_level; + + // Subsequent zooming in the tab should also be done independently of the + // popup. + tab_old_zoom_level = zoom_controller->GetZoomLevel(); + tab_new_zoom_level = tab_old_zoom_level + 1.0; + zoom::ZoomController::ZoomChangedEventData zoom_change_data2( + tab_contents, tab_old_zoom_level, tab_new_zoom_level, + zoom::ZoomController::ZOOM_MODE_DEFAULT, true); + zoom::ZoomChangedWatcher zoom_change_watcher2(tab_contents, + zoom_change_data2); + zoom_controller->SetZoomLevel(tab_new_zoom_level); + zoom_change_watcher2.Wait(); + + popup_zoom_level = content::HostZoomMap::GetZoomLevel(popup_contents); + EXPECT_TRUE(content::ZoomValuesEqual(popup_zoom_level, default_zoom_level)) + << popup_zoom_level << " vs " << default_zoom_level; + + ClosePopup(); +} + class BrowserActionInteractiveViewsTest : public BrowserActionInteractiveTest { public: BrowserActionInteractiveViewsTest() = default; diff --git a/chromium/chrome/browser/extensions/api/extension_action/extension_action_api.cc b/chromium/chrome/browser/extensions/api/extension_action/extension_action_api.cc index 4c48e782bf5..1f2c8aa8225 100644 --- a/chromium/chrome/browser/extensions/api/extension_action/extension_action_api.cc +++ b/chromium/chrome/browser/extensions/api/extension_action/extension_action_api.cc @@ -76,15 +76,6 @@ void ExtensionActionAPI::Observer::OnExtensionActionUpdated( content::BrowserContext* browser_context) { } -void ExtensionActionAPI::Observer::OnExtensionActionVisibilityChanged( - const std::string& extension_id, - bool is_now_visible) { -} - -void ExtensionActionAPI::Observer::OnPageActionsUpdated( - content::WebContents* web_contents) { -} - void ExtensionActionAPI::Observer::OnExtensionActionAPIShuttingDown() { } @@ -171,8 +162,6 @@ void ExtensionActionAPI::SetBrowserActionVisibility( GetExtensionPrefs()->UpdateExtensionPref( extension_id, kBrowserActionVisible, std::make_unique<base::Value>(visible)); - for (auto& observer : observers_) - observer.OnExtensionActionVisibilityChanged(extension_id, visible); } bool ExtensionActionAPI::ShowExtensionActionPopup( @@ -203,9 +192,6 @@ void ExtensionActionAPI::NotifyChange(ExtensionAction* extension_action, content::BrowserContext* context) { for (auto& observer : observers_) observer.OnExtensionActionUpdated(extension_action, web_contents, context); - - if (extension_action->action_type() == ActionInfo::TYPE_PAGE) - NotifyPageActionsChanged(web_contents); } void ExtensionActionAPI::DispatchExtensionActionClicked( @@ -215,6 +201,12 @@ void ExtensionActionAPI::DispatchExtensionActionClicked( events::HistogramValue histogram_value = events::UNKNOWN; const char* event_name = NULL; switch (extension_action.action_type()) { + case ActionInfo::TYPE_ACTION: + // TODO(https://crbug.com/893373): Add testing for this API (currently + // restricted to trunk). + histogram_value = events::ACTION_ON_CLICKED; + event_name = "action.onClicked"; + break; case ActionInfo::TYPE_BROWSER: histogram_value = events::BROWSER_ACTION_ON_CLICKED; event_name = "browserAction.onClicked"; @@ -223,10 +215,6 @@ void ExtensionActionAPI::DispatchExtensionActionClicked( histogram_value = events::PAGE_ACTION_ON_CLICKED; event_name = "pageAction.onClicked"; break; - case ActionInfo::TYPE_SYSTEM_INDICATOR: - // The System Indicator handles its own clicks. - NOTREACHED(); - break; } if (event_name) { @@ -287,16 +275,6 @@ void ExtensionActionAPI::DispatchEventToExtension( ->DispatchEventToExtension(extension_id, std::move(event)); } -void ExtensionActionAPI::NotifyPageActionsChanged( - content::WebContents* web_contents) { - Browser* browser = chrome::FindBrowserWithWebContents(web_contents); - if (!browser) - return; - - for (auto& observer : observers_) - observer.OnPageActionsUpdated(web_contents); -} - void ExtensionActionAPI::Shutdown() { for (auto& observer : observers_) observer.OnExtensionActionAPIShuttingDown(); @@ -319,15 +297,7 @@ ExtensionActionFunction::~ExtensionActionFunction() { ExtensionFunction::ResponseAction ExtensionActionFunction::Run() { ExtensionActionManager* manager = ExtensionActionManager::Get(browser_context()); - if (base::StartsWith(name(), "systemIndicator.", - base::CompareCase::INSENSITIVE_ASCII)) { - extension_action_ = manager->GetSystemIndicator(*extension()); - } else { - extension_action_ = manager->GetBrowserAction(*extension()); - if (!extension_action_) { - extension_action_ = manager->GetPageAction(*extension()); - } - } + extension_action_ = manager->GetExtensionAction(*extension()); if (!extension_action_) { // TODO(kalman): ideally the browserAction/pageAction APIs wouldn't event // exist for extensions that don't have one declared. This should come as @@ -346,11 +316,9 @@ ExtensionFunction::ResponseAction ExtensionActionFunction::Run() { if (!contents_) return RespondNow(Error(kNoTabError, base::NumberToString(tab_id_))); } else { - // Only browser actions and system indicators have a default tabId. - ActionInfo::Type action_type = extension_action_->action_type(); - EXTENSION_FUNCTION_VALIDATE( - action_type == ActionInfo::TYPE_BROWSER || - action_type == ActionInfo::TYPE_SYSTEM_INDICATOR); + // Only browser actions have a default tabId. + EXTENSION_FUNCTION_VALIDATE(extension_action_->action_type() == + ActionInfo::TYPE_BROWSER); } return RunExtensionAction(); } diff --git a/chromium/chrome/browser/extensions/api/extension_action/extension_action_api.h b/chromium/chrome/browser/extensions/api/extension_action/extension_action_api.h index a9c08ccb71e..d75a9023c05 100644 --- a/chromium/chrome/browser/extensions/api/extension_action/extension_action_api.h +++ b/chromium/chrome/browser/extensions/api/extension_action/extension_action_api.h @@ -46,15 +46,6 @@ class ExtensionActionAPI : public BrowserContextKeyedAPI { content::WebContents* web_contents, content::BrowserContext* browser_context); - // Called when there is a change to the extension action's visibility. - virtual void OnExtensionActionVisibilityChanged( - const std::string& extension_id, - bool is_now_visible); - - // Called when the page actions have been refreshed do to a possible change - // in count or visibility. - virtual void OnPageActionsUpdated(content::WebContents* web_contents); - // Called when the ExtensionActionAPI is shutting down, giving observers a // chance to unregister themselves if there is not a definitive lifecycle. virtual void OnExtensionActionAPIShuttingDown(); @@ -102,10 +93,6 @@ class ExtensionActionAPI : public BrowserContextKeyedAPI { // given |web_contents| (and signals that page actions changed). void ClearAllValuesForTab(content::WebContents* web_contents); - // Notifies that the current set of page actions for |web_contents| has - // changed, and signals the browser to update. - void NotifyPageActionsChanged(content::WebContents* web_contents); - void set_prefs_for_testing(ExtensionPrefs* prefs) { extension_prefs_ = prefs; } diff --git a/chromium/chrome/browser/extensions/api/extension_action/extension_action_apitest.cc b/chromium/chrome/browser/extensions/api/extension_action/extension_action_apitest.cc index 09dc8754e2a..93b5c147acc 100644 --- a/chromium/chrome/browser/extensions/api/extension_action/extension_action_apitest.cc +++ b/chromium/chrome/browser/extensions/api/extension_action/extension_action_apitest.cc @@ -3,6 +3,7 @@ // found in the LICENSE file. #include <map> +#include <memory> #include <string> #include "base/macros.h" @@ -16,11 +17,14 @@ #include "chrome/browser/sessions/session_tab_helper.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" +#include "chrome/common/extensions/extension_test_util.h" #include "chrome/test/base/ui_test_utils.h" +#include "components/version_info/channel.h" #include "content/public/browser/web_contents.h" #include "content/public/test/test_utils.h" #include "extensions/browser/browsertest_util.h" #include "extensions/browser/state_store.h" +#include "extensions/common/features/feature_channel.h" #include "extensions/common/manifest_constants.h" #include "extensions/test/extension_test_message_listener.h" #include "extensions/test/test_extension_dir.h" @@ -59,11 +63,6 @@ class TestStateStoreObserver : public StateStore::TestObserver { DISALLOW_COPY_AND_ASSIGN(TestStateStoreObserver); }; -enum class TestActionType { - kBrowser, - kPage, -}; - } // namespace class ExtensionActionAPITest : public ExtensionApiTest { @@ -71,11 +70,13 @@ class ExtensionActionAPITest : public ExtensionApiTest { ExtensionActionAPITest() {} ~ExtensionActionAPITest() override {} - const char* GetManifestKey(TestActionType action_type) { + const char* GetManifestKey(ActionInfo::Type action_type) { switch (action_type) { - case TestActionType::kBrowser: + case ActionInfo::TYPE_ACTION: + return manifest_keys::kAction; + case ActionInfo::TYPE_BROWSER: return manifest_keys::kBrowserAction; - case TestActionType::kPage: + case ActionInfo::TYPE_PAGE: return manifest_keys::kPageAction; } NOTREACHED(); @@ -90,9 +91,19 @@ class ExtensionActionAPITest : public ExtensionApiTest { using BrowserActionAPITest = ExtensionActionAPITest; using PageActionAPITest = ExtensionActionAPITest; -// A class that runs tests exercising both page and browser action behavior. -class MultiActionAPITest : public ExtensionActionAPITest, - public testing::WithParamInterface<TestActionType> { +// A class that runs tests exercising each type of possible toolbar action. +class MultiActionAPITest + : public ExtensionActionAPITest, + public testing::WithParamInterface<ActionInfo::Type> { + public: + MultiActionAPITest() + : current_channel_( + extension_test_util::GetOverrideChannelForActionType(GetParam())) {} + + private: + std::unique_ptr<ScopedCurrentChannel> current_channel_; + + DISALLOW_COPY_AND_ASSIGN(MultiActionAPITest); }; // Check that updating the browser action badge for a specific tab id does not @@ -260,7 +271,8 @@ IN_PROC_BROWSER_TEST_P(MultiActionAPITest, TitleLocalization) { INSTANTIATE_TEST_SUITE_P(, MultiActionAPITest, - testing::Values(TestActionType::kBrowser, - TestActionType::kPage)); + testing::Values(ActionInfo::TYPE_ACTION, + ActionInfo::TYPE_PAGE, + ActionInfo::TYPE_BROWSER)); } // namespace extensions diff --git a/chromium/chrome/browser/extensions/api/extension_action/page_action_apitest.cc b/chromium/chrome/browser/extensions/api/extension_action/page_action_apitest.cc index 1ba7c0a978d..117882e39ed 100644 --- a/chromium/chrome/browser/extensions/api/extension_action/page_action_apitest.cc +++ b/chromium/chrome/browser/extensions/api/extension_action/page_action_apitest.cc @@ -33,8 +33,12 @@ namespace { class PageActionApiTest : public ExtensionApiTest { protected: ExtensionAction* GetPageAction(const Extension& extension) { - return ExtensionActionManager::Get(browser()->profile())-> - GetPageAction(extension); + ExtensionAction* extension_action = + ExtensionActionManager::Get(browser()->profile()) + ->GetExtensionAction(extension); + return extension_action->action_type() == ActionInfo::TYPE_PAGE + ? extension_action + : nullptr; } }; diff --git a/chromium/chrome/browser/extensions/api/feedback_private/OWNERS b/chromium/chrome/browser/extensions/api/feedback_private/OWNERS index c32d77036ab..bd30e9ff740 100644 --- a/chromium/chrome/browser/extensions/api/feedback_private/OWNERS +++ b/chromium/chrome/browser/extensions/api/feedback_private/OWNERS @@ -1,5 +1,4 @@ afakhry@chromium.org -rkc@chromium.org jkardatzke@chromium.org # COMPONENT: Platform>Apps>Feedback diff --git a/chromium/chrome/browser/extensions/api/feedback_private/chrome_feedback_private_delegate.cc b/chromium/chrome/browser/extensions/api/feedback_private/chrome_feedback_private_delegate.cc index b4891f15197..5c762878153 100644 --- a/chromium/chrome/browser/extensions/api/feedback_private/chrome_feedback_private_delegate.cc +++ b/chromium/chrome/browser/extensions/api/feedback_private/chrome_feedback_private_delegate.cc @@ -25,6 +25,8 @@ #include "ui/base/webui/web_ui_util.h" #if defined(OS_CHROMEOS) +#include "base/strings/string_split.h" +#include "base/system/sys_info.h" #include "chrome/browser/chromeos/arc/arc_util.h" #include "chrome/browser/chromeos/system_logs/iwlwifi_dump_log_source.h" #include "chrome/browser/chromeos/system_logs/single_debug_daemon_log_source.h" @@ -32,6 +34,8 @@ #include "chrome/browser/extensions/component_loader.h" #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ui/ash/kiosk_next_shell_client.h" +#include "components/feedback/feedback_util.h" #include "components/feedback/system_logs/system_logs_source.h" #include "extensions/browser/extension_system.h" #include "extensions/common/constants.h" @@ -196,14 +200,12 @@ void ChromeFeedbackPrivateDelegate::FetchExtraLogs( constexpr bool scrub = true; if (system_logs::ContainsIwlwifiLogs(feedback_data->sys_info())) { - VLOG(1) << "Fetching WiFi dump logs."; system_logs::SystemLogsFetcher* fetcher = new system_logs::SystemLogsFetcher(scrub); fetcher->AddSource(std::make_unique<system_logs::IwlwifiDumpLogSource>()); fetcher->Fetch(base::BindOnce(&OnFetchedExtraLogs, feedback_data, std::move(callback))); } else { - VLOG(1) << "WiFi dump logs are not present."; std::move(callback).Run(feedback_data); } } @@ -215,6 +217,25 @@ void ChromeFeedbackPrivateDelegate::UnloadFeedbackExtension( ->component_loader() ->Remove(extension_misc::kFeedbackExtensionId); } + +api::feedback_private::LandingPageType +ChromeFeedbackPrivateDelegate::GetLandingPageType( + const feedback::FeedbackData& feedback_data) const { + if (KioskNextShellClient::Get() && + KioskNextShellClient::Get()->has_launched()) { + return api::feedback_private::LANDING_PAGE_TYPE_NOLANDINGPAGE; + } + + // Googlers using eve get a custom landing page. + if (!feedback_util::IsGoogleEmail(feedback_data.user_email())) + return api::feedback_private::LANDING_PAGE_TYPE_NORMAL; + + const std::vector<std::string> board = + base::SplitString(base::SysInfo::GetLsbReleaseBoard(), "-", + base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY); + return board[0] == "eve" ? api::feedback_private::LANDING_PAGE_TYPE_TECHSTOP + : api::feedback_private::LANDING_PAGE_TYPE_NORMAL; +} #endif // defined(OS_CHROMEOS) std::string ChromeFeedbackPrivateDelegate::GetSignedInUserEmail( diff --git a/chromium/chrome/browser/extensions/api/feedback_private/chrome_feedback_private_delegate.h b/chromium/chrome/browser/extensions/api/feedback_private/chrome_feedback_private_delegate.h index 2469dad25e8..63b7db7556f 100644 --- a/chromium/chrome/browser/extensions/api/feedback_private/chrome_feedback_private_delegate.h +++ b/chromium/chrome/browser/extensions/api/feedback_private/chrome_feedback_private_delegate.h @@ -29,6 +29,8 @@ class ChromeFeedbackPrivateDelegate : public FeedbackPrivateDelegate { void FetchExtraLogs(scoped_refptr<feedback::FeedbackData> feedback_data, FetchExtraLogsCallback callback) const override; void UnloadFeedbackExtension(content::BrowserContext* context) const override; + api::feedback_private::LandingPageType GetLandingPageType( + const feedback::FeedbackData& feedback_data) const override; #endif // defined(OS_CHROMEOS) std::string GetSignedInUserEmail( content::BrowserContext* context) const override; diff --git a/chromium/chrome/browser/extensions/api/feedback_private/feedback_browsertest.cc b/chromium/chrome/browser/extensions/api/feedback_private/feedback_browsertest.cc index d3eb91ea973..5e1ea66b880 100644 --- a/chromium/chrome/browser/extensions/api/feedback_private/feedback_browsertest.cc +++ b/chromium/chrome/browser/extensions/api/feedback_private/feedback_browsertest.cc @@ -13,6 +13,7 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" #include "chrome/common/extensions/extension_constants.h" +#include "chrome/common/webui_url_constants.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h" #include "content/public/common/content_switches.h" @@ -58,10 +59,12 @@ class FeedbackTest : public ExtensionBrowserTest { void StartFeedbackUI(FeedbackFlow flow, const std::string& extra_diagnostics, - bool from_assistant = false) { + bool from_assistant = false, + bool include_bluetooth_logs = false) { base::Closure callback = base::Bind(&StopMessageLoopCallback); extensions::FeedbackPrivateGetStringsFunction::set_test_callback(&callback); - InvokeFeedbackUI(flow, extra_diagnostics, from_assistant); + InvokeFeedbackUI(flow, extra_diagnostics, from_assistant, + include_bluetooth_logs); content::RunMessageLoop(); extensions::FeedbackPrivateGetStringsFunction::set_test_callback(NULL); } @@ -79,13 +82,15 @@ class FeedbackTest : public ExtensionBrowserTest { private: void InvokeFeedbackUI(FeedbackFlow flow, const std::string& extra_diagnostics, - bool from_assistant) { + bool from_assistant, + bool include_bluetooth_logs) { extensions::FeedbackPrivateAPI* api = extensions::FeedbackPrivateAPI::GetFactoryInstance()->Get( browser()->profile()); - api->RequestFeedbackForFlow( - "Test description", "Test placeholder", "Test tag", extra_diagnostics, - GURL("http://www.test.com"), flow, from_assistant); + api->RequestFeedbackForFlow("Test description", "Test placeholder", + "Test tag", extra_diagnostics, + GURL("http://www.test.com"), flow, + from_assistant, include_bluetooth_logs); } }; @@ -248,11 +253,62 @@ IN_PROC_BROWSER_TEST_F(FeedbackTest, MAYBE_ShowFeedbackFromAssistant) { EXPECT_TRUE(bool_result); } +#if defined(OS_CHROMEOS) +// Ensures that when triggered from a Google account and a Bluetooth related +// string is entered into the description, that we provide the option for +// uploading Bluetooth logs as well. +IN_PROC_BROWSER_TEST_F(FeedbackTest, ProvideBluetoothLogs) { + WaitForExtensionViewsToLoad(); + + ASSERT_TRUE(IsFeedbackAppAvailable()); + StartFeedbackUI(FeedbackFlow::FEEDBACK_FLOW_GOOGLEINTERNAL, std::string(), + /*from_assistant*/ false, /*include_bluetooth_logs*/ true); + VerifyFeedbackAppLaunch(); + + AppWindow* const window = + PlatformAppBrowserTest::GetFirstAppWindowForBrowser(browser()); + ASSERT_TRUE(window); + content::WebContents* const content = window->web_contents(); + + // It shouldn't be visible until we put the Bluetooth text into the + // description. + bool bool_result = false; + ASSERT_TRUE(content::ExecuteScriptAndExtractBool( + content, + "domAutomationController.send(" + " ((function() {" + " if ($('bluetooth-checkbox-container') != null &&" + " $('bluetooth-checkbox-container').hidden == true) {" + " return true;" + " }" + " return false;" + " })()));", + &bool_result)); + EXPECT_TRUE(bool_result); + bool_result = false; + ASSERT_TRUE(content::ExecuteScriptAndExtractBool( + content, + "domAutomationController.send(" + " ((function() {" + " var elem = document.getElementById('description-text');" + " elem.value = 'bluetooth';" + " elem.dispatchEvent(new Event('input', {}));" + " if ($('bluetooth-checkbox-container') != null &&" + " $('bluetooth-checkbox-container').hidden == false) {" + " return true;" + " }" + " return false;" + " })()));", + &bool_result)); + EXPECT_TRUE(bool_result); +} +#endif // if defined(CHROME_OS) + IN_PROC_BROWSER_TEST_F(FeedbackTest, GetTargetTabUrl) { const std::pair<std::string, std::string> test_cases[] = { {"https://www.google.com/", "https://www.google.com/"}, - {"about://version/", "chrome://version/"}, - {"chrome://bookmarks/", "chrome://bookmarks/"}, + {"about://version/", chrome::kChromeUIVersionURL}, + {chrome::kChromeUIBookmarksURL, chrome::kChromeUIBookmarksURL}, }; for (const auto& test_case : test_cases) { diff --git a/chromium/chrome/browser/extensions/api/file_system/chrome_file_system_delegate.cc b/chromium/chrome/browser/extensions/api/file_system/chrome_file_system_delegate.cc index 0c631b3bc98..b440c80df8a 100644 --- a/chromium/chrome/browser/extensions/api/file_system/chrome_file_system_delegate.cc +++ b/chromium/chrome/browser/extensions/api/file_system/chrome_file_system_delegate.cc @@ -167,12 +167,12 @@ void OnConsentReceived( // Set a fixed register name, as the automatic one would leak the mount point // directory. std::string register_name = "fs"; - const std::string file_system_id = + const storage::IsolatedContext::ScopedFSHandle file_system = isolated_context->RegisterFileSystemForPath( storage::kFileSystemTypeNativeForPlatformApp, std::string() /* file_system_id */, original_url.path(), ®ister_name); - if (file_system_id.empty()) { + if (!file_system.is_valid()) { error_callback.Run(kSecurityError); return; } @@ -184,21 +184,21 @@ void OnConsentReceived( content::ChildProcessSecurityPolicy::GetInstance(); DCHECK(policy); - const auto process_id = requester->render_frame_host()->GetProcess()->GetID(); + const auto process_id = requester->source_process_id(); // Read-only permisisons. policy->GrantReadFile(process_id, volume->mount_path()); - policy->GrantReadFileSystem(process_id, file_system_id); + policy->GrantReadFileSystem(process_id, file_system.id()); // Additional write permissions. if (writable) { policy->GrantCreateReadWriteFile(process_id, volume->mount_path()); policy->GrantCopyInto(process_id, volume->mount_path()); - policy->GrantWriteFileSystem(process_id, file_system_id); - policy->GrantDeleteFromFileSystem(process_id, file_system_id); - policy->GrantCreateFileForFileSystem(process_id, file_system_id); + policy->GrantWriteFileSystem(process_id, file_system.id()); + policy->GrantDeleteFromFileSystem(process_id, file_system.id()); + policy->GrantCreateFileForFileSystem(process_id, file_system.id()); } - success_callback.Run(file_system_id, register_name); + success_callback.Run(file_system.id(), register_name); } } // namespace diff --git a/chromium/chrome/browser/extensions/api/file_system/request_file_system_notification.cc b/chromium/chrome/browser/extensions/api/file_system/request_file_system_notification.cc index f4672d8dbe0..287985a136b 100644 --- a/chromium/chrome/browser/extensions/api/file_system/request_file_system_notification.cc +++ b/chromium/chrome/browser/extensions/api/file_system/request_file_system_notification.cc @@ -56,9 +56,9 @@ class AppNotificationLauncher : public AppIconLoaderDelegate { // AppIconLoaderDelegate overrides: void OnAppImageUpdated(const std::string& id, const gfx::ImageSkia& image) override { - extension_icon_.reset(new gfx::Image(image)); + extension_icon_ = gfx::Image(image); - pending_notification_->set_icon(*extension_icon_); + pending_notification_->set_icon(extension_icon_); NotificationDisplayService::GetForProfile(profile_)->Display( NotificationHandler::Type::TRANSIENT, *pending_notification_, /*metadata=*/nullptr); @@ -70,7 +70,7 @@ class AppNotificationLauncher : public AppIconLoaderDelegate { Profile* profile_; std::unique_ptr<AppIconLoader> icon_loader_; - std::unique_ptr<gfx::Image> extension_icon_; + gfx::Image extension_icon_; std::unique_ptr<message_center::Notification> pending_notification_; DISALLOW_COPY_AND_ASSIGN(AppNotificationLauncher); diff --git a/chromium/chrome/browser/extensions/api/font_settings/font_settings_api.cc b/chromium/chrome/browser/extensions/api/font_settings/font_settings_api.cc index 45dc594178f..2f63eff6a5d 100644 --- a/chromium/chrome/browser/extensions/api/font_settings/font_settings_api.cc +++ b/chromium/chrome/browser/extensions/api/font_settings/font_settings_api.cc @@ -38,6 +38,10 @@ #include "extensions/browser/extension_system.h" #include "extensions/common/error_utils.h" +#if defined(OS_WIN) +#include "ui/gfx/win/direct_write.h" +#endif // defined(OS_WIN) + namespace extensions { namespace fonts = api::font_settings; @@ -78,6 +82,20 @@ std::string GetFontNamePrefPath(fonts::GenericFamily generic_family_enum, return result; } +void MaybeUnlocalizeFontName(std::string* font_name) { +#if defined(OS_WIN) + // Try to get the 'us-en' font name. If it is failing, use the first name + // available. + base::Optional<std::string> localized_font_name = + gfx::win::RetrieveLocalizedFontName(*font_name, "us-en"); + if (!localized_font_name) + localized_font_name = gfx::win::RetrieveLocalizedFontName(*font_name, ""); + + if (localized_font_name) + *font_name = std::move(localized_font_name.value()); +#endif // defined(OS_WIN) +} + } // namespace FontSettingsEventRouter::FontSettingsEventRouter(Profile* profile) @@ -144,7 +162,6 @@ void FontSettingsEventRouter::OnFontNamePrefChanged( NOTREACHED(); return; } - font_name = settings_utils::MaybeGetLocalizedFontName(font_name); base::ListValue args; std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); @@ -230,7 +247,11 @@ ExtensionFunction::ResponseAction FontSettingsGetFontFunction::Run() { std::string font_name; EXTENSION_FUNCTION_VALIDATE( pref && pref->GetValue()->GetAsString(&font_name)); - font_name = settings_utils::MaybeGetLocalizedFontName(font_name); + + // Legacy code was using the localized font name for fontId. These values may + // have been stored in prefs. For backward compatibility, we are converting + // the font name to the unlocalized name. + MaybeUnlocalizeFontName(&font_name); // We don't support incognito-specific font prefs, so don't consider them when // getting level of control. diff --git a/chromium/chrome/browser/extensions/api/gcm/gcm_api.cc b/chromium/chrome/browser/extensions/api/gcm/gcm_api.cc index fdcab227fb3..7e92c5b2fb0 100644 --- a/chromium/chrome/browser/extensions/api/gcm/gcm_api.cc +++ b/chromium/chrome/browser/extensions/api/gcm/gcm_api.cc @@ -19,7 +19,7 @@ #include "chrome/browser/gcm/gcm_profile_service_factory.h" #include "chrome/browser/profiles/profile.h" #include "chrome/common/extensions/api/gcm.h" -#include "components/gcm_driver/common/gcm_messages.h" +#include "components/gcm_driver/common/gcm_message.h" #include "components/gcm_driver/gcm_driver.h" #include "components/gcm_driver/gcm_profile_service.h" #include "extensions/browser/event_router.h" diff --git a/chromium/chrome/browser/extensions/api/history/history_api.cc b/chromium/chrome/browser/extensions/api/history/history_api.cc index 133a5caac83..010b8478e82 100644 --- a/chromium/chrome/browser/extensions/api/history/history_api.cc +++ b/chromium/chrome/browser/extensions/api/history/history_api.cc @@ -277,13 +277,10 @@ ExtensionFunction::ResponseAction HistoryGetVisitsFunction::Run() { return RespondLater(); // QueryComplete() will be called asynchronously. } -void HistoryGetVisitsFunction::QueryComplete( - bool success, - const history::URLRow& url_row, - const history::VisitVector& visits) { +void HistoryGetVisitsFunction::QueryComplete(history::QueryURLResult result) { VisitItemList visit_item_vec; - if (success && !visits.empty()) { - for (const history::VisitRow& visit : visits) + if (result.success && !result.visits.empty()) { + for (const history::VisitRow& visit : result.visits) visit_item_vec.push_back(GetVisitItem(visit)); } @@ -310,20 +307,19 @@ ExtensionFunction::ResponseAction HistorySearchFunction::Run() { history::HistoryService* hs = HistoryServiceFactory::GetForProfile( GetProfile(), ServiceAccessType::EXPLICIT_ACCESS); - hs->QueryHistory(search_text, - options, - base::Bind(&HistorySearchFunction::SearchComplete, - base::Unretained(this)), + hs->QueryHistory(search_text, options, + base::BindOnce(&HistorySearchFunction::SearchComplete, + base::Unretained(this)), &task_tracker_); AddRef(); // Balanced in SearchComplete(). return RespondLater(); // SearchComplete() will be called asynchronously. } -void HistorySearchFunction::SearchComplete(history::QueryResults* results) { +void HistorySearchFunction::SearchComplete(history::QueryResults results) { HistoryItemList history_item_vec; - if (results && !results->empty()) { - for (const auto& item : *results) + if (!results.empty()) { + for (const auto& item : results) history_item_vec.push_back(GetHistoryItem(item)); } Respond(ArgumentList(Search::Results::Create(history_item_vec))); diff --git a/chromium/chrome/browser/extensions/api/history/history_api.h b/chromium/chrome/browser/extensions/api/history/history_api.h index 36d12ac0841..9a0433dbf79 100644 --- a/chromium/chrome/browser/extensions/api/history/history_api.h +++ b/chromium/chrome/browser/extensions/api/history/history_api.h @@ -129,9 +129,7 @@ class HistoryGetVisitsFunction : public HistoryFunctionWithCallback { ResponseAction Run() override; // Callback for the history function to provide results. - void QueryComplete(bool success, - const history::URLRow& url_row, - const history::VisitVector& visits); + void QueryComplete(history::QueryURLResult result); }; class HistorySearchFunction : public HistoryFunctionWithCallback { @@ -145,7 +143,7 @@ class HistorySearchFunction : public HistoryFunctionWithCallback { ResponseAction Run() override; // Callback for the history function to provide results. - void SearchComplete(history::QueryResults* results); + void SearchComplete(history::QueryResults results); }; class HistoryAddUrlFunction : public HistoryFunction { diff --git a/chromium/chrome/browser/extensions/api/identity/identity_api.cc b/chromium/chrome/browser/extensions/api/identity/identity_api.cc index 49dbcecb513..ad6f8c0186f 100644 --- a/chromium/chrome/browser/extensions/api/identity/identity_api.cc +++ b/chromium/chrome/browser/extensions/api/identity/identity_api.cc @@ -43,7 +43,7 @@ namespace extensions { #if BUILDFLAG(ENABLE_DICE_SUPPORT) const base::Feature kExtensionsAllAccountsFeature{ - "ExtensionsAllAccounts", base::FEATURE_DISABLED_BY_DEFAULT}; + "ExtensionsAllAccounts", base::FEATURE_ENABLED_BY_DEFAULT}; #endif IdentityTokenCacheValue::IdentityTokenCacheValue() diff --git a/chromium/chrome/browser/extensions/api/identity/identity_api_unittest.cc b/chromium/chrome/browser/extensions/api/identity/identity_api_unittest.cc index 8432fb2993a..06ba8e19052 100644 --- a/chromium/chrome/browser/extensions/api/identity/identity_api_unittest.cc +++ b/chromium/chrome/browser/extensions/api/identity/identity_api_unittest.cc @@ -31,8 +31,11 @@ TEST(IdentityApiTest, DiceAllAccountsExtensions) { { ScopedAccountConsistencyDiceMigration scoped_dice_migration; - TestingProfile profile; - IdentityAPI api(&profile); + TestingProfile::Builder profile_builder; + // The profile is not a new profile to prevent automatic migration. + profile_builder.OverrideIsNewProfile(false); + std::unique_ptr<TestingProfile> profile = profile_builder.Build(); + IdentityAPI api(profile.get()); EXPECT_TRUE(api.AreExtensionsRestrictedToPrimaryAccount()); api.Shutdown(); } diff --git a/chromium/chrome/browser/extensions/api/identity/identity_apitest.cc b/chromium/chrome/browser/extensions/api/identity/identity_apitest.cc index 44129fe709e..bb187fb62b2 100644 --- a/chromium/chrome/browser/extensions/api/identity/identity_apitest.cc +++ b/chromium/chrome/browser/extensions/api/identity/identity_apitest.cc @@ -355,7 +355,7 @@ class FakeGetAuthTokenFunction : public IdentityGetAuthTokenFunction { void FixOrAddSecondaryAccount() { identity::IdentityManager* identity_manager = IdentityManagerFactory::GetForProfile(GetProfile()); - std::vector<AccountInfo> accounts = + std::vector<CoreAccountInfo> accounts = identity_manager->GetAccountsWithRefreshTokens(); std::string primary_id = identity_manager->GetPrimaryAccountId(); bool fixed_auth_error = false; @@ -777,7 +777,7 @@ class GetAuthTokenFunctionTest return ext; } - const std::string& GetPrimaryAccountId() { + std::string GetPrimaryAccountId() { return identity_test_env()->identity_manager()->GetPrimaryAccountId(); } diff --git a/chromium/chrome/browser/extensions/api/identity/identity_get_accounts_function.cc b/chromium/chrome/browser/extensions/api/identity/identity_get_accounts_function.cc index 297a7cf8730..e125be0e33c 100644 --- a/chromium/chrome/browser/extensions/api/identity/identity_get_accounts_function.cc +++ b/chromium/chrome/browser/extensions/api/identity/identity_get_accounts_function.cc @@ -30,7 +30,7 @@ ExtensionFunction::ResponseAction IdentityGetAccountsFunction::Run() { return RespondNow(Error(identity_constants::kOffTheRecord)); } - std::vector<AccountInfo> accounts = + std::vector<CoreAccountInfo> accounts = IdentityManagerFactory::GetForProfile( Profile::FromBrowserContext(browser_context())) ->GetAccountsWithRefreshTokens(); diff --git a/chromium/chrome/browser/extensions/api/image_writer_private/removable_storage_provider_mac.cc b/chromium/chrome/browser/extensions/api/image_writer_private/removable_storage_provider_mac.cc index d7b008a962a..4cc10223c1a 100644 --- a/chromium/chrome/browser/extensions/api/image_writer_private/removable_storage_provider_mac.cc +++ b/chromium/chrome/browser/extensions/api/image_writer_private/removable_storage_provider_mac.cc @@ -5,7 +5,6 @@ #include "chrome/browser/extensions/api/image_writer_private/removable_storage_provider.h" #include <CoreFoundation/CoreFoundation.h> -#include <IOKit/IOBSD.h> #include <IOKit/IOKitLib.h> #include <IOKit/storage/IOBlockStorageDevice.h> #include <IOKit/storage/IOMedia.h> @@ -27,48 +26,38 @@ RemovableStorageProvider::PopulateDeviceList() { base::ScopedBlockingCall scoped_blocking_call(FROM_HERE, base::BlockingType::MAY_BLOCK); // Match only writable whole-disks. - CFMutableDictionaryRef matching = IOServiceMatching(kIOMediaClass); + base::ScopedCFTypeRef<CFMutableDictionaryRef> matching( + IOServiceMatching(kIOMediaClass)); CFDictionaryAddValue(matching, CFSTR(kIOMediaWholeKey), kCFBooleanTrue); CFDictionaryAddValue(matching, CFSTR(kIOMediaWritableKey), kCFBooleanTrue); - io_service_t disk_iterator; - if (IOServiceGetMatchingServices( - kIOMasterPortDefault, matching, &disk_iterator) != KERN_SUCCESS) { + // IOServiceGetMatchingServices consumes a reference to the matching + // dictionary passed to it. + base::mac::ScopedIOObject<io_service_t> disk_iterator; + if (IOServiceGetMatchingServices(kIOMasterPortDefault, matching.release(), + disk_iterator.InitializeInto()) != + KERN_SUCCESS) { LOG(ERROR) << "Unable to get disk services."; return nullptr; } - base::mac::ScopedIOObject<io_service_t> iterator_ref(disk_iterator); - io_object_t disk_obj; + base::mac::ScopedIOObject<io_object_t> disk_obj; scoped_refptr<StorageDeviceList> device_list(new StorageDeviceList()); - while ((disk_obj = IOIteratorNext(disk_iterator))) { - base::mac::ScopedIOObject<io_object_t> disk_obj_ref(disk_obj); - - CFMutableDictionaryRef dict; - if (IORegistryEntryCreateCFProperties( - disk_obj, &dict, kCFAllocatorDefault, 0) != KERN_SUCCESS) { - LOG(ERROR) << "Unable to get properties of disk object."; + while (disk_obj.reset(IOIteratorNext(disk_iterator)), disk_obj) { + std::string bsd_name; + uint64_t size_in_bytes; + bool removable; + + bool is_suitable = IsSuitableRemovableStorageDevice( + disk_obj, &bsd_name, &size_in_bytes, &removable); + if (!is_suitable) continue; - } - base::ScopedCFTypeRef<CFMutableDictionaryRef> dict_ref(dict); - - CFStringRef cf_bsd_name = base::mac::GetValueFromDictionary<CFStringRef>( - dict, CFSTR(kIOBSDNameKey)); - std::string bsd_name = base::SysCFStringRefToUTF8(cf_bsd_name); - CFNumberRef size_number = base::mac::GetValueFromDictionary<CFNumberRef>( - dict, CFSTR(kIOMediaSizeKey)); - uint64_t size_in_bytes = 0; - if (size_number) - CFNumberGetValue(size_number, kCFNumberLongLongType, &size_in_bytes); - - CFBooleanRef cf_removable = base::mac::GetValueFromDictionary<CFBooleanRef>( - dict, CFSTR(kIOMediaRemovableKey)); - bool removable = CFBooleanGetValue(cf_removable); - - bool is_usb = IsUsbDevice(disk_obj); - - if (!removable && !is_usb) { + base::ScopedCFTypeRef<CFMutableDictionaryRef> dict; + if (IORegistryEntryCreateCFProperties(disk_obj, dict.InitializeInto(), + kCFAllocatorDefault, + 0) != KERN_SUCCESS) { + LOG(ERROR) << "Unable to get properties of disk object."; continue; } @@ -80,8 +69,8 @@ RemovableStorageProvider::PopulateDeviceList() { kCFAllocatorDefault, kIORegistryIterateParents | kIORegistryIterateRecursively))); - if (characteristics == NULL) { - LOG(ERROR) << "Unable to find device characteristics for " << cf_bsd_name; + if (!characteristics) { + LOG(ERROR) << "Unable to find device characteristics for " << bsd_name; continue; } diff --git a/chromium/chrome/browser/extensions/api/input_ime/input_ime_api_chromeos.cc b/chromium/chrome/browser/extensions/api/input_ime/input_ime_api_chromeos.cc index 1135dd14cae..d4dc455d531 100644 --- a/chromium/chrome/browser/extensions/api/input_ime/input_ime_api_chromeos.cc +++ b/chromium/chrome/browser/extensions/api/input_ime/input_ime_api_chromeos.cc @@ -9,6 +9,7 @@ #include <memory> #include <utility> +#include "ash/public/interfaces/keyboard_config.mojom.h" #include "base/feature_list.h" #include "base/macros.h" #include "chrome/browser/chromeos/input_method/input_method_engine.h" @@ -27,7 +28,6 @@ #include "ui/base/ime/chromeos/input_method_manager.h" #include "ui/base/ime/ime_engine_handler_interface.h" #include "ui/base/ui_base_features.h" -#include "ui/keyboard/public/keyboard_config.mojom.h" namespace input_ime = extensions::api::input_ime; namespace input_method_private = extensions::api::input_method_private; diff --git a/chromium/chrome/browser/extensions/api/input_ime/input_ime_api_nonchromeos.cc b/chromium/chrome/browser/extensions/api/input_ime/input_ime_api_nonchromeos.cc index 5aa32a682f0..112b9cc3f87 100644 --- a/chromium/chrome/browser/extensions/api/input_ime/input_ime_api_nonchromeos.cc +++ b/chromium/chrome/browser/extensions/api/input_ime/input_ime_api_nonchromeos.cc @@ -13,14 +13,12 @@ #include <memory> #include "base/bind.h" -#include "base/command_line.h" #include "base/macros.h" #include "base/values.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/input_method/input_method_engine.h" -#include "chrome/common/chrome_switches.h" #include "chrome/common/extensions/api/input_ime.h" #include "extensions/browser/extension_prefs.h" #include "ui/base/ime/ime_bridge.h" @@ -37,8 +35,6 @@ namespace input_ime = extensions::api::input_ime; namespace { -const char kErrorAPIDisabled[] = - "The chrome.input.ime API is not supported on the current platform"; const char kErrorNoActiveEngine[] = "The extension has not been activated."; const char kErrorPermissionDenied[] = "User denied permission."; const char kErrorCouldNotFindActiveBrowser[] = @@ -59,11 +55,6 @@ const char kPrefNeverActivatedSinceLoaded[] = "never_activated_since_loaded"; // A preference to see whether the extension is the last active extension. const char kPrefLastActiveEngine[] = "last_activated_ime_engine"; -bool IsInputImeEnabled() { - return !base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kDisableInputImeAPI); -} - class ImeBridgeObserver : public ui::IMEBridgeObserver { public: void OnRequestSwitchEngine() override { @@ -116,10 +107,6 @@ class ImeObserverNonChromeOS : public ui::ImeObserver { extensions::events::HistogramValue histogram_value, const std::string& event_name, std::unique_ptr<base::ListValue> args) override { - if (!IsInputImeEnabled()) { - return; - } - auto event = std::make_unique<extensions::Event>( histogram_value, event_name, std::move(args), profile_); extensions::EventRouter::Get(profile_) @@ -239,8 +226,6 @@ void InputImeEventRouter::DeleteInputMethodEngine( bool InputImeActivateFunction::disable_bubble_for_testing_ = false; ExtensionFunction::ResponseAction InputImeActivateFunction::Run() { - if (!IsInputImeEnabled()) - return RespondNow(Error(kErrorAPIDisabled)); Profile* profile = Profile::FromBrowserContext(browser_context()); InputImeEventRouter* event_router = GetInputImeEventRouter(profile); if (!event_router) @@ -338,9 +323,6 @@ void InputImeActivateFunction::OnPermissionBubbleFinished( } ExtensionFunction::ResponseAction InputImeDeactivateFunction::Run() { - if (!IsInputImeEnabled()) - return RespondNow(Error(kErrorAPIDisabled)); - InputMethodEngine* engine = GetActiveEngine(browser_context(), extension_id()); ui::IMEBridge::Get()->SetCurrentEngineHandler(nullptr); @@ -350,9 +332,6 @@ ExtensionFunction::ResponseAction InputImeDeactivateFunction::Run() { } ExtensionFunction::ResponseAction InputImeCreateWindowFunction::Run() { - if (!IsInputImeEnabled()) - return RespondNow(Error(kErrorAPIDisabled)); - // Using input_ime::CreateWindow::Params::Create() causes the link errors on // Windows, only if the method name is 'createWindow'. // So doing the by-hand parameter unpacking here. @@ -395,9 +374,6 @@ ExtensionFunction::ResponseAction InputImeCreateWindowFunction::Run() { } ExtensionFunction::ResponseAction InputImeShowWindowFunction::Run() { - if (!IsInputImeEnabled()) - return RespondNow(Error(kErrorAPIDisabled)); - InputMethodEngine* engine = GetActiveEngine(browser_context(), extension_id()); if (!engine) @@ -411,9 +387,6 @@ ExtensionFunction::ResponseAction InputImeShowWindowFunction::Run() { } ExtensionFunction::ResponseAction InputImeHideWindowFunction::Run() { - if (!IsInputImeEnabled()) - return RespondNow(Error(kErrorAPIDisabled)); - InputMethodEngine* engine = GetActiveEngine(browser_context(), extension_id()); if (!engine) diff --git a/chromium/chrome/browser/extensions/api/language_settings_private/language_settings_private_api.cc b/chromium/chrome/browser/extensions/api/language_settings_private/language_settings_private_api.cc index be7b9253e90..79319a90768 100644 --- a/chromium/chrome/browser/extensions/api/language_settings_private/language_settings_private_api.cc +++ b/chromium/chrome/browser/extensions/api/language_settings_private/language_settings_private_api.cc @@ -13,7 +13,6 @@ #include <vector> #include "base/containers/flat_set.h" -#include "base/feature_list.h" #include "base/stl_util.h" #include "base/strings/string16.h" #include "base/strings/string_split.h" @@ -233,12 +232,9 @@ LanguageSettingsPrivateGetLanguageListFunction::Run() { if (entry.supports_translate) { language.supports_translate.reset(new bool(true)); } - if (base::FeatureList::IsEnabled(translate::kRegionalLocalesAsDisplayUI)) { - std::string temp_locale = entry.code; - if (language::ConvertToActualUILocale(&temp_locale)) { - language.supports_ui.reset(new bool(true)); - } - } else if (base::ContainsKey(locale_set, entry.code)) { + + std::string temp_locale = entry.code; + if (language::ConvertToActualUILocale(&temp_locale)) { language.supports_ui.reset(new bool(true)); } #if defined(OS_CHROMEOS) diff --git a/chromium/chrome/browser/extensions/api/language_settings_private/language_settings_private_delegate_factory.h b/chromium/chrome/browser/extensions/api/language_settings_private/language_settings_private_delegate_factory.h index c88541a717a..5f3198c36c0 100644 --- a/chromium/chrome/browser/extensions/api/language_settings_private/language_settings_private_delegate_factory.h +++ b/chromium/chrome/browser/extensions/api/language_settings_private/language_settings_private_delegate_factory.h @@ -29,7 +29,7 @@ class LanguageSettingsPrivateDelegateFactory static LanguageSettingsPrivateDelegateFactory* GetInstance(); protected: - // BrowserContextKeyedBaseFactory overrides: + // BrowserContextKeyedServiceFactory overrides: content::BrowserContext* GetBrowserContextToUse( content::BrowserContext* context) const override; bool ServiceIsCreatedWithBrowserContext() const override; diff --git a/chromium/chrome/browser/extensions/api/management/chrome_management_api_delegate.cc b/chromium/chrome/browser/extensions/api/management/chrome_management_api_delegate.cc index c4d58486a4d..75d783e861b 100644 --- a/chromium/chrome/browser/extensions/api/management/chrome_management_api_delegate.cc +++ b/chromium/chrome/browser/extensions/api/management/chrome_management_api_delegate.cc @@ -5,9 +5,9 @@ #include "chrome/browser/extensions/api/management/chrome_management_api_delegate.h" #include <memory> +#include <utility> #include "base/bind.h" -#include "base/callback_helpers.h" #include "base/macros.h" #include "base/strings/utf_string_conversions.h" #include "base/task/post_task.h" @@ -29,11 +29,11 @@ #include "chrome/browser/ui/scoped_tabbed_browser_displayer.h" #include "chrome/browser/ui/web_applications/web_app_dialog_utils.h" #include "chrome/browser/ui/webui/extensions/extension_icon_source.h" +#include "chrome/browser/web_applications/components/app_registrar.h" #include "chrome/browser/web_applications/components/install_manager.h" #include "chrome/browser/web_applications/components/web_app_constants.h" #include "chrome/browser/web_applications/components/web_app_provider_base.h" #include "chrome/browser/web_applications/components/web_app_utils.h" -#include "chrome/browser/web_applications/extensions/bookmark_app_util.h" #include "chrome/common/extensions/extension_metrics.h" #include "chrome/common/extensions/manifest_handlers/app_launch_info.h" #include "chrome/common/web_application_info.h" @@ -87,8 +87,8 @@ class ManagementSetEnabledFunctionInstallPromptDelegate private: void OnInstallPromptDone(ExtensionInstallPrompt::Result result) { - base::ResetAndReturn(&callback_).Run( - result == ExtensionInstallPrompt::Result::ACCEPTED); + std::move(callback_).Run(result == + ExtensionInstallPrompt::Result::ACCEPTED); } // Used for prompting to re-enable items with permissions escalation updates. @@ -290,11 +290,11 @@ void ChromeManagementAPIDelegate:: data_decoder::SafeJsonParser::Parse( content::ServiceManagerConnection::GetForProcess()->GetConnector(), manifest_str, - base::Bind( + base::BindOnce( &extensions::ManagementGetPermissionWarningsByManifestFunction:: OnParseSuccess, function), - base::Bind( + base::BindOnce( &extensions::ManagementGetPermissionWarningsByManifestFunction:: OnParseFailure, function)); @@ -368,7 +368,10 @@ ChromeManagementAPIDelegate::GenerateAppForLinkFunctionDelegate( bool ChromeManagementAPIDelegate::IsWebAppInstalled( content::BrowserContext* context, const GURL& web_app_url) const { - return extensions::BookmarkOrHostedAppInstalled(context, web_app_url); + auto* provider = web_app::WebAppProviderBase::GetProviderBase( + Profile::FromBrowserContext(context)); + DCHECK(provider); + return provider->registrar().IsInstalled(web_app_url); } bool ChromeManagementAPIDelegate::CanContextInstallWebApps( diff --git a/chromium/chrome/browser/extensions/api/management/management_api_browsertest.cc b/chromium/chrome/browser/extensions/api/management/management_api_browsertest.cc index c06d4096937..16f29ac9da4 100644 --- a/chromium/chrome/browser/extensions/api/management/management_api_browsertest.cc +++ b/chromium/chrome/browser/extensions/api/management/management_api_browsertest.cc @@ -36,7 +36,7 @@ #endif namespace keys = extension_management_api_constants; -namespace util = extension_function_test_utils; +namespace test_utils = extension_function_test_utils; namespace extensions { @@ -179,19 +179,17 @@ IN_PROC_BROWSER_TEST_F(ExtensionManagementApiBrowserTest, new ManagementCreateAppShortcutFunction()); create_shortcut_function->set_user_gesture(true); ManagementCreateAppShortcutFunction::SetAutoConfirmForTest(true); - util::RunFunctionAndReturnSingleResult( + test_utils::RunFunctionAndReturnSingleResult( create_shortcut_function.get(), - base::StringPrintf("[\"%s\"]", app_id.c_str()), - browser()); + base::StringPrintf("[\"%s\"]", app_id.c_str()), browser()); create_shortcut_function = new ManagementCreateAppShortcutFunction(); create_shortcut_function->set_user_gesture(true); ManagementCreateAppShortcutFunction::SetAutoConfirmForTest(false); EXPECT_TRUE(base::MatchPattern( - util::RunFunctionAndReturnError( + test_utils::RunFunctionAndReturnError( create_shortcut_function.get(), - base::StringPrintf("[\"%s\"]", app_id.c_str()), - browser()), + base::StringPrintf("[\"%s\"]", app_id.c_str()), browser()), keys::kCreateShortcutCanceledError)); } @@ -209,7 +207,8 @@ IN_PROC_BROWSER_TEST_F(ExtensionManagementApiBrowserTest, scoped_refptr<ManagementGetAllFunction> function = new ManagementGetAllFunction(); std::unique_ptr<base::Value> result( - util::RunFunctionAndReturnSingleResult(function.get(), "[]", browser())); + test_utils::RunFunctionAndReturnSingleResult(function.get(), "[]", + browser())); base::ListValue* list; ASSERT_TRUE(result->GetAsList(&list)); EXPECT_EQ(1U, list->GetSize()); @@ -218,8 +217,8 @@ IN_PROC_BROWSER_TEST_F(ExtensionManagementApiBrowserTest, ASSERT_TRUE(CrashEnabledExtension(extension->id())); function = new ManagementGetAllFunction(); - result.reset(util::RunFunctionAndReturnSingleResult( - function.get(), "[]", browser())); + result.reset(test_utils::RunFunctionAndReturnSingleResult(function.get(), + "[]", browser())); ASSERT_TRUE(result->GetAsList(&list)); EXPECT_EQ(1U, list->GetSize()); } @@ -271,7 +270,7 @@ class ExtensionManagementApiEscalationTest : function->set_user_gesture(true); function->SetRenderFrameHost(browser()->tab_strip_model()-> GetActiveWebContents()->GetMainFrame()); - bool response = util::RunFunction( + bool response = test_utils::RunFunction( function.get(), base::StringPrintf("[\"%s\", %s]", kId, enabled_string), browser(), api_test_utils::NONE); if (expected_error.empty()) { @@ -294,8 +293,9 @@ IN_PROC_BROWSER_TEST_F(ExtensionManagementApiEscalationTest, DisabledReason) { scoped_refptr<ManagementGetFunction> function = new ManagementGetFunction(); - std::unique_ptr<base::Value> result(util::RunFunctionAndReturnSingleResult( - function.get(), base::StringPrintf("[\"%s\"]", kId), browser())); + std::unique_ptr<base::Value> result( + test_utils::RunFunctionAndReturnSingleResult( + function.get(), base::StringPrintf("[\"%s\"]", kId), browser())); ASSERT_TRUE(result.get() != NULL); ASSERT_TRUE(result->is_dict()); base::DictionaryValue* dict = diff --git a/chromium/chrome/browser/extensions/api/management/management_apitest.cc b/chromium/chrome/browser/extensions/api/management/management_apitest.cc index 8c68561345b..2a3b0f125f1 100644 --- a/chromium/chrome/browser/extensions/api/management/management_apitest.cc +++ b/chromium/chrome/browser/extensions/api/management/management_apitest.cc @@ -16,7 +16,8 @@ #include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/browser_list.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" -#include "chrome/browser/web_applications/extensions/bookmark_app_util.h" +#include "chrome/browser/web_applications/components/app_registrar.h" +#include "chrome/browser/web_applications/components/web_app_provider_base.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/extensions/extension_constants.h" #include "extensions/browser/api/management/management_api.h" @@ -314,13 +315,14 @@ IN_PROC_BROWSER_TEST_F(InstallReplacementWebAppApiTest, InstallableWebApp) { chrome::SetAutoAcceptPWAInstallConfirmationForTesting(true); const GURL good_web_app_url = https_test_server_.GetURL(kGoodWebAppURL); - EXPECT_FALSE(extensions::BookmarkOrHostedAppInstalled(browser()->profile(), - good_web_app_url)); + + auto* provider = + web_app::WebAppProviderBase::GetProviderBase(browser()->profile()); + EXPECT_FALSE(provider->registrar().IsInstalled(good_web_app_url)); RunTest(kGoodWebAppURL, kBackground, true /* from_webstore */, true /* whitelisted */); - EXPECT_TRUE(extensions::BookmarkOrHostedAppInstalled(browser()->profile(), - good_web_app_url)); + EXPECT_TRUE(provider->registrar().IsInstalled(good_web_app_url)); chrome::SetAutoAcceptPWAInstallConfirmationForTesting(false); } diff --git a/chromium/chrome/browser/extensions/api/media_perception_private/media_perception_api_delegate_chromeos.cc b/chromium/chrome/browser/extensions/api/media_perception_private/media_perception_api_delegate_chromeos.cc index 920bd4d8a56..9f241e74ad1 100644 --- a/chromium/chrome/browser/extensions/api/media_perception_private/media_perception_api_delegate_chromeos.cc +++ b/chromium/chrome/browser/extensions/api/media_perception_private/media_perception_api_delegate_chromeos.cc @@ -11,7 +11,7 @@ #include "chrome/browser/browser_process.h" #include "chrome/browser/component_updater/cros_component_installer_chromeos.h" #include "content/public/browser/browser_thread.h" -#include "content/public/browser/delegate_to_browser_gpu_service_accelerator_factory.h" +#include "content/public/browser/chromeos/delegate_to_browser_gpu_service_accelerator_factory.h" #include "content/public/browser/render_frame_host.h" #include "content/public/common/service_manager_connection.h" #include "mojo/public/cpp/bindings/strong_binding.h" diff --git a/chromium/chrome/browser/extensions/api/networking_private/networking_private_chromeos_apitest.cc b/chromium/chrome/browser/extensions/api/networking_private/networking_private_chromeos_apitest.cc index d21e9f5eb97..50dee6a1a61 100644 --- a/chromium/chrome/browser/extensions/api/networking_private/networking_private_chromeos_apitest.cc +++ b/chromium/chrome/browser/extensions/api/networking_private/networking_private_chromeos_apitest.cc @@ -243,8 +243,6 @@ class NetworkingPrivateChromeOSApiTest : public extensions::ExtensionApiTest { // Add a Cellular GSM Device. device_test_->AddDevice(kCellularDevicePath, shill::kTypeCellular, "stub_cellular_device1"); - SetDeviceProperty(kCellularDevicePath, shill::kCarrierProperty, - base::Value("Cellular1_Carrier")); base::DictionaryValue home_provider; home_provider.SetString("name", "Cellular1_Provider"); home_provider.SetString("code", "000000"); @@ -528,17 +526,6 @@ IN_PROC_BROWSER_TEST_F(NetworkingPrivateChromeOSApiTest, StartActivate) { EXPECT_EQ(1, UIDelegateStub::s_show_account_details_called_); } -IN_PROC_BROWSER_TEST_F(NetworkingPrivateChromeOSApiTest, StartActivateSprint) { - SetupCellular(); - // Set the carrier to Sprint. - DBusThreadManager::Get()->GetShillDeviceClient()->SetCarrier( - dbus::ObjectPath(kCellularDevicePath), shill::kCarrierSprint, - base::DoNothing(), - base::BindRepeating([](const std::string&, const std::string&) {})); - EXPECT_TRUE(RunNetworkingSubtest("startActivateSprint")) << message_; - EXPECT_EQ(0, UIDelegateStub::s_show_account_details_called_); -} - IN_PROC_BROWSER_TEST_F(NetworkingPrivateChromeOSApiTest, StartConnectNonexistent) { EXPECT_TRUE(RunNetworkingSubtest("startConnectNonexistent")) << message_; @@ -773,7 +760,7 @@ IN_PROC_BROWSER_TEST_F(NetworkingPrivateChromeOSApiTest, GetManagedProperties) { } IN_PROC_BROWSER_TEST_F(NetworkingPrivateChromeOSApiTest, GetErrorState) { - chromeos::NetworkHandler::Get()->network_state_handler()->SetLastErrorForTest( + chromeos::NetworkHandler::Get()->network_state_handler()->SetErrorForTest( kWifi1ServicePath, "TestErrorState"); EXPECT_TRUE(RunNetworkingSubtest("getErrorState")) << message_; } @@ -802,6 +789,12 @@ IN_PROC_BROWSER_TEST_F(NetworkingPrivateChromeOSApiTest, } IN_PROC_BROWSER_TEST_F(NetworkingPrivateChromeOSApiTest, + OnDeviceScanningChangedEvent) { + SetupCellular(); + EXPECT_TRUE(RunNetworkingSubtest("onDeviceScanningChangedEvent")) << message_; +} + +IN_PROC_BROWSER_TEST_F(NetworkingPrivateChromeOSApiTest, OnCertificateListsChangedEvent) { TestListener listener( "eventListenerReady", base::BindRepeating([]() { diff --git a/chromium/chrome/browser/extensions/api/notifications/notifications_api.cc b/chromium/chrome/browser/extensions/api/notifications/notifications_api.cc index 23e895169b2..45ea9511897 100644 --- a/chromium/chrome/browser/extensions/api/notifications/notifications_api.cc +++ b/chromium/chrome/browser/extensions/api/notifications/notifications_api.cc @@ -48,7 +48,6 @@ #include "ui/gfx/image/image_skia_operations.h" #include "ui/gfx/image/image_skia_rep.h" #include "ui/gfx/skia_util.h" -#include "ui/message_center/public/cpp/features.h" #include "ui/message_center/public/cpp/message_center_constants.h" #include "ui/message_center/public/cpp/notification.h" #include "ui/message_center/public/cpp/notification_delegate.h" @@ -362,9 +361,7 @@ bool NotificationsApiFunction::CreateNotification( } optional_fields.settings_button_handler = - base::FeatureList::IsEnabled(message_center::kNewStyleNotifications) - ? message_center::SettingsButtonHandler::INLINE - : message_center::SettingsButtonHandler::NONE; + message_center::SettingsButtonHandler::INLINE; // TODO(crbug.com/772004): Remove the manual limitation in favor of an IDL // annotation once supported. diff --git a/chromium/chrome/browser/extensions/api/passwords_private/passwords_private_delegate_factory.h b/chromium/chrome/browser/extensions/api/passwords_private/passwords_private_delegate_factory.h index a56f726c476..e28c3bf3d56 100644 --- a/chromium/chrome/browser/extensions/api/passwords_private/passwords_private_delegate_factory.h +++ b/chromium/chrome/browser/extensions/api/passwords_private/passwords_private_delegate_factory.h @@ -32,7 +32,7 @@ class PasswordsPrivateDelegateFactory PasswordsPrivateDelegateFactory(); ~PasswordsPrivateDelegateFactory() override; - // BrowserContextKeyedBaseFactory implementation. + // BrowserContextKeyedServiceFactory implementation. KeyedService* BuildServiceInstanceFor( content::BrowserContext* profile) const override; bool ServiceIsCreatedWithBrowserContext() const override; diff --git a/chromium/chrome/browser/extensions/api/passwords_private/passwords_private_event_router_factory.h b/chromium/chrome/browser/extensions/api/passwords_private/passwords_private_event_router_factory.h index 42ede59ec17..3e1c70a1a2c 100644 --- a/chromium/chrome/browser/extensions/api/passwords_private/passwords_private_event_router_factory.h +++ b/chromium/chrome/browser/extensions/api/passwords_private/passwords_private_event_router_factory.h @@ -28,7 +28,7 @@ class PasswordsPrivateEventRouterFactory static PasswordsPrivateEventRouterFactory* GetInstance(); protected: - // BrowserContextKeyedBaseFactory overrides: + // BrowserContextKeyedServiceFactory overrides: content::BrowserContext* GetBrowserContextToUse( content::BrowserContext* context) const override; bool ServiceIsCreatedWithBrowserContext() const override; diff --git a/chromium/chrome/browser/extensions/api/permissions/permissions_api_helpers.cc b/chromium/chrome/browser/extensions/api/permissions/permissions_api_helpers.cc index 34b0007c795..0b6e2cfcf0f 100644 --- a/chromium/chrome/browser/extensions/api/permissions/permissions_api_helpers.cc +++ b/chromium/chrome/browser/extensions/api/permissions/permissions_api_helpers.cc @@ -114,21 +114,21 @@ bool UnpackAPIPermissions(const std::vector<std::string>& permissions_input, // Validate and partition the parsed APIs. for (const auto* api_permission : apis) { if (required_permissions.apis().count(api_permission->id())) { - result->required_apis.insert(api_permission->id()); + result->required_apis.insert(api_permission->Clone()); continue; } if (!optional_permissions.apis().count(api_permission->id())) { - result->unlisted_apis.insert(api_permission->id()); + result->unlisted_apis.insert(api_permission->Clone()); continue; } if (!api_permission->info()->supports_optional()) { - result->unsupported_optional_apis.insert(api_permission->id()); + result->unsupported_optional_apis.insert(api_permission->Clone()); continue; } - result->optional_apis.insert(api_permission->id()); + result->optional_apis.insert(api_permission->Clone()); } return true; diff --git a/chromium/chrome/browser/extensions/api/permissions/permissions_api_helpers_unittest.cc b/chromium/chrome/browser/extensions/api/permissions/permissions_api_helpers_unittest.cc index 12c46b9cd29..9d9bbd62be2 100644 --- a/chromium/chrome/browser/extensions/api/permissions/permissions_api_helpers_unittest.cc +++ b/chromium/chrome/browser/extensions/api/permissions/permissions_api_helpers_unittest.cc @@ -9,12 +9,15 @@ #include <memory> #include <utility> +#include "base/json/json_reader.h" #include "base/macros.h" #include "base/values.h" #include "chrome/browser/extensions/permissions_test_util.h" #include "chrome/common/extensions/api/permissions.h" #include "extensions/common/extension.h" #include "extensions/common/permissions/permission_set.h" +#include "extensions/common/permissions/permissions_info.h" +#include "extensions/common/permissions/usb_device_permission.h" #include "extensions/common/url_pattern_set.h" #include "extensions/common/user_script.h" #include "testing/gmock/include/gmock/gmock.h" @@ -484,4 +487,46 @@ TEST(ExtensionPermissionsAPIHelpers, Unpack_FileSchemes_Specific) { } } +// Tests that unpacking a UsbDevicePermission with a list of USB device IDs +// preserves the device list in the result object. +TEST(ExtensionPermissionsAPIHelpers, Unpack_UsbDevicePermission) { + constexpr char kDeviceListJson[] = R"([{"productId":2,"vendorId":1}])"; + constexpr char kUsbDevicesPermissionJson[] = + R"(usbDevices|[{"productId":2,"vendorId":1}])"; + + auto device_list = base::JSONReader::Read(kDeviceListJson); + ASSERT_TRUE(device_list) << "Failed to parse device list JSON."; + + auto usb_device_permission = std::make_unique<UsbDevicePermission>( + PermissionsInfo::GetInstance()->GetByID(APIPermission::ID::kUsbDevice)); + std::string error; + std::vector<std::string> unhandled_permissions; + bool from_value_result = usb_device_permission->FromValue( + &device_list.value(), &error, &unhandled_permissions); + ASSERT_TRUE(from_value_result); + EXPECT_TRUE(unhandled_permissions.empty()); + + APIPermissionSet api_permission_set; + api_permission_set.insert(usb_device_permission->Clone()); + PermissionSet optional_permissions(std::move(api_permission_set), + ManifestPermissionSet(), URLPatternSet(), + URLPatternSet()); + + Permissions permissions_object; + permissions_object.permissions = std::make_unique<std::vector<std::string>>( + std::vector<std::string>({kUsbDevicesPermissionJson})); + constexpr bool kHasFileAccess = false; + std::unique_ptr<UnpackPermissionSetResult> unpack_result = + UnpackPermissionSet(permissions_object, PermissionSet(), + optional_permissions, kHasFileAccess, &error); + + ASSERT_TRUE(unpack_result) << error; + + ASSERT_EQ(1U, unpack_result->optional_apis.size()); + EXPECT_EQ(APIPermission::ID::kUsbDevice, + unpack_result->optional_apis.begin()->id()); + EXPECT_TRUE(unpack_result->optional_apis.begin()->Contains( + usb_device_permission.get())); +} + } // namespace extensions diff --git a/chromium/chrome/browser/extensions/api/platform_keys/platform_keys_apitest_nss.cc b/chromium/chrome/browser/extensions/api/platform_keys/platform_keys_apitest_nss.cc index 6c2854a494b..f6600316db6 100644 --- a/chromium/chrome/browser/extensions/api/platform_keys/platform_keys_apitest_nss.cc +++ b/chromium/chrome/browser/extensions/api/platform_keys/platform_keys_apitest_nss.cc @@ -19,7 +19,6 @@ #include "chrome/browser/extensions/api/platform_keys/platform_keys_test_base.h" #include "chrome/browser/net/nss_context.h" #include "chrome/browser/policy/profile_policy_connector.h" -#include "chrome/browser/policy/profile_policy_connector_factory.h" #include "chrome/browser/profiles/profile.h" #include "components/policy/policy_constants.h" #include "content/public/browser/browser_task_traits.h" @@ -135,7 +134,7 @@ class PlatformKeysTest : public PlatformKeysTestBase { LoadExtension(test_data_dir_.AppendASCII("platform_keys_genkey")); policy::ProfilePolicyConnector* const policy_connector = - policy::ProfilePolicyConnectorFactory::GetForBrowserContext(profile()); + profile()->GetProfilePolicyConnector(); extensions::StateStore* const state_store = extensions::ExtensionSystem::Get(profile())->state_store(); diff --git a/chromium/chrome/browser/extensions/api/platform_keys/platform_keys_test_base.cc b/chromium/chrome/browser/extensions/api/platform_keys/platform_keys_test_base.cc index e52211c6fd8..305c68f0abf 100644 --- a/chromium/chrome/browser/extensions/api/platform_keys/platform_keys_test_base.cc +++ b/chromium/chrome/browser/extensions/api/platform_keys/platform_keys_test_base.cc @@ -10,7 +10,6 @@ #include "base/task/post_task.h" #include "chrome/browser/chromeos/policy/affiliation_test_helper.h" #include "chrome/browser/policy/profile_policy_connector.h" -#include "chrome/browser/policy/profile_policy_connector_factory.h" #include "chrome/browser/ui/browser.h" #include "chrome/common/chrome_paths.h" #include "chrome/test/base/ui_test_utils.h" @@ -104,6 +103,7 @@ void PlatformKeysTestBase::SetUpInProcessBrowserTestFixture() { device_affiliation_ids.insert(kAffiliationID); ASSERT_NO_FATAL_FAILURE(affiliation_helper.SetDeviceAffiliationIDs( &device_policy_test_helper_, device_affiliation_ids)); + device_policy_test_helper_.InstallOwnerKey(); install_attributes_.Get()->SetCloudManaged( policy::PolicyBuilder::kFakeDomain, policy::PolicyBuilder::kFakeDeviceId); @@ -148,8 +148,7 @@ void PlatformKeysTestBase::SetUpOnMainThread() { if (user_status() != UserStatus::UNMANAGED) { policy::ProfilePolicyConnector* const connector = - policy::ProfilePolicyConnectorFactory::GetForBrowserContext( - profile()); + profile()->GetProfilePolicyConnector(); connector->OverrideIsManagedForTesting(true); } } diff --git a/chromium/chrome/browser/extensions/api/platform_keys/verify_trust_api.cc b/chromium/chrome/browser/extensions/api/platform_keys/verify_trust_api.cc index b8c1983c3f4..09b9b975cee 100644 --- a/chromium/chrome/browser/extensions/api/platform_keys/verify_trust_api.cc +++ b/chromium/chrome/browser/extensions/api/platform_keys/verify_trust_api.cc @@ -181,7 +181,8 @@ void VerifyTrustAPI::IOPart::Verify(std::unique_ptr<Params> params, } if (!base::ContainsKey(extension_to_verifier_, extension_id)) { - extension_to_verifier_[extension_id] = net::CertVerifier::CreateDefault(); + extension_to_verifier_[extension_id] = + net::CertVerifier::CreateDefault(/*cert_net_fetcher=*/nullptr); } net::CertVerifier* verifier = extension_to_verifier_[extension_id].get(); @@ -191,6 +192,7 @@ void VerifyTrustAPI::IOPart::Verify(std::unique_ptr<Params> params, const int flags = 0; std::string ocsp_response; + std::string sct_list; net::CertVerifyResult* const verify_result_ptr = verify_result.get(); RequestState* request_state = new RequestState(); @@ -200,7 +202,7 @@ void VerifyTrustAPI::IOPart::Verify(std::unique_ptr<Params> params, const int return_value = verifier->Verify( net::CertVerifier::RequestParams(std::move(cert_chain), details.hostname, - flags, ocsp_response), + flags, ocsp_response, sct_list), verify_result_ptr, bound_callback, &request_state->request, *net_log); if (return_value != net::ERR_IO_PENDING) { diff --git a/chromium/chrome/browser/extensions/api/preference/preference_api.cc b/chromium/chrome/browser/extensions/api/preference/preference_api.cc index a66fafe99fb..346eeb905d5 100644 --- a/chromium/chrome/browser/extensions/api/preference/preference_api.cc +++ b/chromium/chrome/browser/extensions/api/preference/preference_api.cc @@ -159,6 +159,9 @@ const PrefMappingEntry kPrefMapping[] = { {"screenMagnifier", ash::prefs::kAccessibilityScreenMagnifierEnabled, APIPermission::kAccessibilityFeaturesRead, APIPermission::kAccessibilityFeaturesModify}, + {"selectToSpeak", ash::prefs::kAccessibilitySelectToSpeakEnabled, + APIPermission::kAccessibilityFeaturesRead, + APIPermission::kAccessibilityFeaturesModify}, {"spokenFeedback", ash::prefs::kAccessibilitySpokenFeedbackEnabled, APIPermission::kAccessibilityFeaturesRead, APIPermission::kAccessibilityFeaturesModify}, diff --git a/chromium/chrome/browser/extensions/api/preference/preference_api_prefs_unittest.cc b/chromium/chrome/browser/extensions/api/preference/preference_api_prefs_unittest.cc index 54ad94c2a24..621171c300e 100644 --- a/chromium/chrome/browser/extensions/api/preference/preference_api_prefs_unittest.cc +++ b/chromium/chrome/browser/extensions/api/preference/preference_api_prefs_unittest.cc @@ -103,7 +103,7 @@ ExtensionControlledPrefsTest::ExtensionControlledPrefsTest() : PrefsPrepopulatedTestBase(), content_settings_(ContentSettingsService::Get(&profile_)), test_preference_api_(&prefs_, content_settings_) { - prefs_.prefs()->AddObserver(content_settings_); + content_settings_->OnExtensionPrefsAvailable(prefs_.prefs()); } ExtensionControlledPrefsTest::~ExtensionControlledPrefsTest() { diff --git a/chromium/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_api_unittest.cc b/chromium/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_api_unittest.cc index 3c29f4de2c2..9cff1e3b5a2 100644 --- a/chromium/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_api_unittest.cc +++ b/chromium/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_api_unittest.cc @@ -114,6 +114,12 @@ void SafeBrowsingPrivateApiUnitTest::TearDown() { browser()->tab_strip_model()->DetachWebContentsAt(0); browser_window_.reset(); content::BrowserSideNavigationTearDown(); + + // Make sure the NetworkContext owned by SafeBrowsingService is destructed + // before the NetworkService object.. + TestingBrowserProcess::GetGlobal()->safe_browsing_service()->ShutDown(); + TestingBrowserProcess::GetGlobal()->SetSafeBrowsingService(nullptr); + ExtensionServiceTestBase::TearDown(); } diff --git a/chromium/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_event_router_factory.h b/chromium/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_event_router_factory.h index 670735961dc..b5e98c491a1 100644 --- a/chromium/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_event_router_factory.h +++ b/chromium/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_event_router_factory.h @@ -28,7 +28,7 @@ class SafeBrowsingPrivateEventRouterFactory static SafeBrowsingPrivateEventRouterFactory* GetInstance(); protected: - // BrowserContextKeyedBaseFactory overrides: + // BrowserContextKeyedServiceFactory overrides: content::BrowserContext* GetBrowserContextToUse( content::BrowserContext* context) const override; bool ServiceIsCreatedWithBrowserContext() const override; diff --git a/chromium/chrome/browser/extensions/api/settings_overrides/settings_overrides_browsertest.cc b/chromium/chrome/browser/extensions/api/settings_overrides/settings_overrides_browsertest.cc index c69063e7a9b..3d9892b6d8b 100644 --- a/chromium/chrome/browser/extensions/api/settings_overrides/settings_overrides_browsertest.cc +++ b/chromium/chrome/browser/extensions/api/settings_overrides/settings_overrides_browsertest.cc @@ -36,7 +36,7 @@ namespace extensions { namespace { #if defined(OS_WIN) || defined(OS_MACOSX) // Prepopulated id hardcoded in test_extension. -const int kTestExtensionPrepopulatedId = 1; +const int kTestExtensionPrepopulatedId = 3; // TemplateURLData with search engines settings from test extension manifest. // chrome/test/data/extensions/settings_override/manifest.json std::unique_ptr<TemplateURLData> TestExtensionSearchEngine(PrefService* prefs) { diff --git a/chromium/chrome/browser/extensions/api/settings_private/generated_prefs_factory.h b/chromium/chrome/browser/extensions/api/settings_private/generated_prefs_factory.h index c435e5b2784..e755cf0f57b 100644 --- a/chromium/chrome/browser/extensions/api/settings_private/generated_prefs_factory.h +++ b/chromium/chrome/browser/extensions/api/settings_private/generated_prefs_factory.h @@ -28,7 +28,7 @@ class GeneratedPrefsFactory : public BrowserContextKeyedServiceFactory { GeneratedPrefsFactory(); ~GeneratedPrefsFactory() override; - // BrowserContextKeyedBaseFactory implementation. + // BrowserContextKeyedServiceFactory implementation. KeyedService* BuildServiceInstanceFor( content::BrowserContext* profile) const override; diff --git a/chromium/chrome/browser/extensions/api/settings_private/prefs_util.cc b/chromium/chrome/browser/extensions/api/settings_private/prefs_util.cc index a69f602826a..7155c905d10 100644 --- a/chromium/chrome/browser/extensions/api/settings_private/prefs_util.cc +++ b/chromium/chrome/browser/extensions/api/settings_private/prefs_util.cc @@ -320,7 +320,7 @@ const PrefsUtil::TypedPrefMap& PrefsUtil::GetWhitelistedKeys() { (*s_whitelist)[ash::prefs::kAccessibilityAutoclickEnabled] = settings_api::PrefType::PREF_TYPE_BOOLEAN; (*s_whitelist)[ash::prefs::kAccessibilityAutoclickDelayMs] = - settings_api::PrefType::PREF_TYPE_BOOLEAN; + settings_api::PrefType::PREF_TYPE_NUMBER; (*s_whitelist)[ash::prefs::kAccessibilityAutoclickEventType] = settings_api::PrefType::PREF_TYPE_NUMBER; (*s_whitelist)[ash::prefs::kAccessibilityAutoclickRevertToLeftClick] = @@ -521,6 +521,8 @@ const PrefsUtil::TypedPrefMap& PrefsUtil::GetWhitelistedKeys() { settings_api::PrefType::PREF_TYPE_DICTIONARY; (*s_whitelist)[chromeos::kDisplayRotationDefault] = settings_api::PrefType::PREF_TYPE_DICTIONARY; + (*s_whitelist)[arc::prefs::kArcHasAccessToRemovableMedia] = + settings_api::PrefType::PREF_TYPE_BOOLEAN; // Native Printing settings. (*s_whitelist)[::prefs::kUserNativePrintersAllowed] = diff --git a/chromium/chrome/browser/extensions/api/settings_private/settings_private_delegate_factory.h b/chromium/chrome/browser/extensions/api/settings_private/settings_private_delegate_factory.h index a69bf7f7c18..65a19ab7d18 100644 --- a/chromium/chrome/browser/extensions/api/settings_private/settings_private_delegate_factory.h +++ b/chromium/chrome/browser/extensions/api/settings_private/settings_private_delegate_factory.h @@ -31,7 +31,7 @@ class SettingsPrivateDelegateFactory SettingsPrivateDelegateFactory(); ~SettingsPrivateDelegateFactory() override; - // BrowserContextKeyedBaseFactory implementation. + // BrowserContextKeyedServiceFactory implementation. KeyedService* BuildServiceInstanceFor( content::BrowserContext* profile) const override; content::BrowserContext* GetBrowserContextToUse( diff --git a/chromium/chrome/browser/extensions/api/settings_private/settings_private_event_router_factory.h b/chromium/chrome/browser/extensions/api/settings_private/settings_private_event_router_factory.h index 8ef02d8e1da..fe475609fe7 100644 --- a/chromium/chrome/browser/extensions/api/settings_private/settings_private_event_router_factory.h +++ b/chromium/chrome/browser/extensions/api/settings_private/settings_private_event_router_factory.h @@ -28,7 +28,7 @@ class SettingsPrivateEventRouterFactory static SettingsPrivateEventRouterFactory* GetInstance(); protected: - // BrowserContextKeyedBaseFactory overrides: + // BrowserContextKeyedServiceFactory overrides: content::BrowserContext* GetBrowserContextToUse( content::BrowserContext* context) const override; bool ServiceIsCreatedWithBrowserContext() const override; diff --git a/chromium/chrome/browser/extensions/api/signed_in_devices/id_mapping_helper.cc b/chromium/chrome/browser/extensions/api/signed_in_devices/id_mapping_helper.cc index 4ad8cf093b7..792533e9de5 100644 --- a/chromium/chrome/browser/extensions/api/signed_in_devices/id_mapping_helper.cc +++ b/chromium/chrome/browser/extensions/api/signed_in_devices/id_mapping_helper.cc @@ -12,7 +12,7 @@ #include "chrome/browser/extensions/api/signed_in_devices/signed_in_devices_api.h" #include "chrome/browser/profiles/profile.h" #include "components/crx_file/id_util.h" -#include "components/sync/device_info/device_info.h" +#include "components/sync_device_info/device_info.h" using base::DictionaryValue; using base::Value; diff --git a/chromium/chrome/browser/extensions/api/signed_in_devices/id_mapping_helper_unittest.cc b/chromium/chrome/browser/extensions/api/signed_in_devices/id_mapping_helper_unittest.cc index 688b3d057ff..cdc749a01c9 100644 --- a/chromium/chrome/browser/extensions/api/signed_in_devices/id_mapping_helper_unittest.cc +++ b/chromium/chrome/browser/extensions/api/signed_in_devices/id_mapping_helper_unittest.cc @@ -8,8 +8,9 @@ #include <string> #include "base/guid.h" +#include "base/time/time.h" #include "base/values.h" -#include "components/sync/device_info/device_info.h" +#include "components/sync_device_info/device_info.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -32,12 +33,12 @@ TEST(IdMappingHelperTest, SetIdsForDevices) { devices.push_back(std::make_unique<DeviceInfo>( base::GenerateGUID(), "abc Device", "XYZ v1", "XYZ SyncAgent v1", - sync_pb::SyncEnums_DeviceType_TYPE_LINUX, "device_id1", + sync_pb::SyncEnums_DeviceType_TYPE_LINUX, "device_id1", base::Time(), /*send_tab_to_self_receiving_enabled=*/true)); devices.push_back(std::make_unique<DeviceInfo>( base::GenerateGUID(), "def Device", "XYZ v1", "XYZ SyncAgent v1", - sync_pb::SyncEnums_DeviceType_TYPE_LINUX, "device_id2", + sync_pb::SyncEnums_DeviceType_TYPE_LINUX, "device_id2", base::Time(), /*send_tab_to_self_receiving_enabled=*/true)); base::DictionaryValue dictionary; @@ -55,7 +56,7 @@ TEST(IdMappingHelperTest, SetIdsForDevices) { // Now add a third device. devices.push_back(std::make_unique<DeviceInfo>( base::GenerateGUID(), "ghi Device", "XYZ v1", "XYZ SyncAgent v1", - sync_pb::SyncEnums_DeviceType_TYPE_LINUX, "device_id3", + sync_pb::SyncEnums_DeviceType_TYPE_LINUX, "device_id3", base::Time(), /*send_tab_to_self_receiving_enabled=*/true)); CreateMappingForUnmappedDevices(devices, &dictionary); diff --git a/chromium/chrome/browser/extensions/api/signed_in_devices/signed_in_devices_api.cc b/chromium/chrome/browser/extensions/api/signed_in_devices/signed_in_devices_api.cc index dfba45bf6ab..222f50c0150 100644 --- a/chromium/chrome/browser/extensions/api/signed_in_devices/signed_in_devices_api.cc +++ b/chromium/chrome/browser/extensions/api/signed_in_devices/signed_in_devices_api.cc @@ -12,9 +12,9 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/sync/device_info_sync_service_factory.h" #include "chrome/common/extensions/api/signed_in_devices.h" -#include "components/sync/device_info/device_info_sync_service.h" -#include "components/sync/device_info/device_info_tracker.h" -#include "components/sync/device_info/local_device_info_provider.h" +#include "components/sync_device_info/device_info_sync_service.h" +#include "components/sync_device_info/device_info_tracker.h" +#include "components/sync_device_info/local_device_info_provider.h" #include "extensions/browser/extension_prefs.h" using base::DictionaryValue; diff --git a/chromium/chrome/browser/extensions/api/signed_in_devices/signed_in_devices_api_unittest.cc b/chromium/chrome/browser/extensions/api/signed_in_devices/signed_in_devices_api_unittest.cc index 6bd0b8b49ba..f4f9013ada4 100644 --- a/chromium/chrome/browser/extensions/api/signed_in_devices/signed_in_devices_api_unittest.cc +++ b/chromium/chrome/browser/extensions/api/signed_in_devices/signed_in_devices_api_unittest.cc @@ -11,14 +11,15 @@ #include "base/bind.h" #include "base/guid.h" #include "base/threading/thread_task_runner_handle.h" +#include "base/time/time.h" #include "base/values.h" #include "chrome/browser/extensions/extension_api_unittest.h" #include "chrome/browser/extensions/test_extension_prefs.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/sync/device_info_sync_service_factory.h" -#include "components/sync/device_info/device_info.h" -#include "components/sync/device_info/device_info_sync_service.h" -#include "components/sync/device_info/device_info_tracker.h" +#include "components/sync_device_info/device_info.h" +#include "components/sync_device_info/device_info_sync_service.h" +#include "components/sync_device_info/device_info_tracker.h" #include "content/public/test/test_browser_thread_bundle.h" #include "extensions/common/extension.h" #include "testing/gmock/include/gmock/gmock.h" @@ -48,6 +49,7 @@ class MockDeviceInfoTracker : public DeviceInfoTracker { device_info.guid(), device_info.client_name(), device_info.chrome_version(), device_info.sync_user_agent(), device_info.device_type(), device_info.signin_scoped_device_id(), + device_info.last_updated_timestamp(), device_info.send_tab_to_self_receiving_enabled()); } @@ -89,13 +91,15 @@ TEST(SignedInDevicesAPITest, GetSignedInDevices) { scoped_refptr<Extension> extension_test = extension_prefs.AddExtension(extension_name); - DeviceInfo device_info1( - base::GenerateGUID(), "abc Device", "XYZ v1", "XYZ SyncAgent v1", - sync_pb::SyncEnums_DeviceType_TYPE_LINUX, "device_id", true); + DeviceInfo device_info1(base::GenerateGUID(), "abc Device", "XYZ v1", + "XYZ SyncAgent v1", + sync_pb::SyncEnums_DeviceType_TYPE_LINUX, "device_id", + base::Time(), true); - DeviceInfo device_info2( - base::GenerateGUID(), "def Device", "XYZ v2", "XYZ SyncAgent v2", - sync_pb::SyncEnums_DeviceType_TYPE_LINUX, "device_id", true); + DeviceInfo device_info2(base::GenerateGUID(), "def Device", "XYZ v2", + "XYZ SyncAgent v2", + sync_pb::SyncEnums_DeviceType_TYPE_LINUX, "device_id", + base::Time(), true); device_tracker.Add(&device_info1); device_tracker.Add(&device_info2); @@ -112,9 +116,10 @@ TEST(SignedInDevicesAPITest, GetSignedInDevices) { // Add a third device and make sure the first 2 ids are retained and a new // id is generated for the third device. - DeviceInfo device_info3( - base::GenerateGUID(), "def Device", "jkl v2", "XYZ SyncAgent v2", - sync_pb::SyncEnums_DeviceType_TYPE_LINUX, "device_id", true); + DeviceInfo device_info3(base::GenerateGUID(), "def Device", "jkl v2", + "XYZ SyncAgent v2", + sync_pb::SyncEnums_DeviceType_TYPE_LINUX, "device_id", + base::Time(), true); device_tracker.Add(&device_info3); @@ -200,13 +205,15 @@ TEST_F(ExtensionSignedInDevicesTest, GetAll) { DeviceInfoSyncServiceFactory::GetForProfile(profile())) ->mock_tracker(); - DeviceInfo device_info1( - base::GenerateGUID(), "abc Device", "XYZ v1", "XYZ SyncAgent v1", - sync_pb::SyncEnums_DeviceType_TYPE_LINUX, "device_id", true); + DeviceInfo device_info1(base::GenerateGUID(), "abc Device", "XYZ v1", + "XYZ SyncAgent v1", + sync_pb::SyncEnums_DeviceType_TYPE_LINUX, "device_id", + base::Time(), true); - DeviceInfo device_info2( - base::GenerateGUID(), "def Device", "XYZ v2", "XYZ SyncAgent v2", - sync_pb::SyncEnums_DeviceType_TYPE_LINUX, "device_id", true); + DeviceInfo device_info2(base::GenerateGUID(), "def Device", "XYZ v2", + "XYZ SyncAgent v2", + sync_pb::SyncEnums_DeviceType_TYPE_LINUX, "device_id", + base::Time(), true); device_tracker->Add(&device_info1); device_tracker->Add(&device_info2); diff --git a/chromium/chrome/browser/extensions/api/signed_in_devices/signed_in_devices_manager.cc b/chromium/chrome/browser/extensions/api/signed_in_devices/signed_in_devices_manager.cc index 14a887de4fd..8b6576e9656 100644 --- a/chromium/chrome/browser/extensions/api/signed_in_devices/signed_in_devices_manager.cc +++ b/chromium/chrome/browser/extensions/api/signed_in_devices/signed_in_devices_manager.cc @@ -16,8 +16,8 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/sync/device_info_sync_service_factory.h" #include "chrome/common/extensions/api/signed_in_devices.h" -#include "components/sync/device_info/device_info.h" -#include "components/sync/device_info/device_info_sync_service.h" +#include "components/sync_device_info/device_info.h" +#include "components/sync_device_info/device_info_sync_service.h" #include "extensions/browser/event_router.h" #include "extensions/browser/extension_registry.h" #include "extensions/common/extension.h" diff --git a/chromium/chrome/browser/extensions/api/signed_in_devices/signed_in_devices_manager.h b/chromium/chrome/browser/extensions/api/signed_in_devices/signed_in_devices_manager.h index 9763eece2ad..bb7ab76b965 100644 --- a/chromium/chrome/browser/extensions/api/signed_in_devices/signed_in_devices_manager.h +++ b/chromium/chrome/browser/extensions/api/signed_in_devices/signed_in_devices_manager.h @@ -12,7 +12,7 @@ #include "base/gtest_prod_util.h" #include "base/macros.h" #include "base/scoped_observer.h" -#include "components/sync/device_info/device_info_tracker.h" +#include "components/sync_device_info/device_info_tracker.h" #include "content/public/browser/notification_registrar.h" #include "extensions/browser/browser_context_keyed_api_factory.h" #include "extensions/browser/event_router.h" diff --git a/chromium/chrome/browser/extensions/api/socket/tcp_socket_unittest.cc b/chromium/chrome/browser/extensions/api/socket/tcp_socket_unittest.cc index 539c1a8a395..116d11b88df 100644 --- a/chromium/chrome/browser/extensions/api/socket/tcp_socket_unittest.cc +++ b/chromium/chrome/browser/extensions/api/socket/tcp_socket_unittest.cc @@ -528,7 +528,6 @@ class TestSocketFactory : public net::ClientSocketFactory { bool using_spdy, net::NextProto negotiated_protocol, net::ProxyDelegate* proxy_delegate, - bool is_https_proxy, const net::NetworkTrafficAnnotationTag& traffic_annotation) override { NOTIMPLEMENTED(); return nullptr; diff --git a/chromium/chrome/browser/extensions/api/storage/managed_value_store_cache.cc b/chromium/chrome/browser/extensions/api/storage/managed_value_store_cache.cc index d553819af02..417d22e213e 100644 --- a/chromium/chrome/browser/extensions/api/storage/managed_value_store_cache.cc +++ b/chromium/chrome/browser/extensions/api/storage/managed_value_store_cache.cc @@ -18,7 +18,6 @@ #include "base/task/post_task.h" #include "chrome/browser/extensions/api/storage/policy_value_store.h" #include "chrome/browser/policy/profile_policy_connector.h" -#include "chrome/browser/policy/profile_policy_connector_factory.h" #include "chrome/browser/policy/schema_registry_service.h" #include "chrome/browser/profiles/profile.h" #include "chrome/common/extensions/api/storage/storage_schema_manifest_handler.h" @@ -236,9 +235,7 @@ ManagedValueStoreCache::ManagedValueStoreCache( scoped_refptr<SettingsObserverList> observers) : profile_(Profile::FromBrowserContext(context)), policy_domain_(GetPolicyDomain(profile_)), - policy_service_( - policy::ProfilePolicyConnectorFactory::GetForBrowserContext(context) - ->policy_service()), + policy_service_(profile_->GetProfilePolicyConnector()->policy_service()), storage_factory_(std::move(factory)), observers_(std::move(observers)) { DCHECK_CURRENTLY_ON(BrowserThread::UI); diff --git a/chromium/chrome/browser/extensions/api/storage/settings_sync_unittest.cc b/chromium/chrome/browser/extensions/api/storage/settings_sync_unittest.cc index d46189d0759..29cdc5a7efd 100644 --- a/chromium/chrome/browser/extensions/api/storage/settings_sync_unittest.cc +++ b/chromium/chrome/browser/extensions/api/storage/settings_sync_unittest.cc @@ -41,8 +41,6 @@ using base::ListValue; using base::Value; namespace extensions { -namespace util = settings_test_util; - namespace { // To save typing ValueStore::DEFAULTS everywhere. @@ -213,8 +211,8 @@ class ExtensionSettingsSyncTest : public testing::Test { ValueStore* AddExtensionAndGetStorage( const std::string& id, Manifest::Type type) { scoped_refptr<const Extension> extension = - util::AddExtensionWithId(profile_.get(), id, type); - return util::GetStorage(extension, frontend_.get()); + settings_test_util::AddExtensionWithId(profile_.get(), id, type); + return settings_test_util::GetStorage(extension, frontend_.get()); } // Gets the syncer::SyncableService for the given sync type. @@ -1425,7 +1423,7 @@ namespace { static void UnlimitedSyncStorageTestCallback(ValueStore* sync_storage) { // Sync storage should still run out after ~100K; the unlimitedStorage // permission can't apply to sync. - std::unique_ptr<base::Value> kilobyte = util::CreateKilobyte(); + std::unique_ptr<base::Value> kilobyte = settings_test_util::CreateKilobyte(); for (int i = 0; i < 100; ++i) { sync_storage->Set(ValueStore::DEFAULTS, base::NumberToString(i), *kilobyte); } @@ -1437,7 +1435,7 @@ static void UnlimitedSyncStorageTestCallback(ValueStore* sync_storage) { static void UnlimitedLocalStorageTestCallback(ValueStore* local_storage) { // Local storage should never run out. - std::unique_ptr<base::Value> megabyte = util::CreateMegabyte(); + std::unique_ptr<base::Value> megabyte = settings_test_util::CreateMegabyte(); for (int i = 0; i < 7; ++i) { local_storage->Set(ValueStore::DEFAULTS, base::NumberToString(i), *megabyte); @@ -1463,7 +1461,7 @@ TEST_F(ExtensionSettingsSyncTest, MAYBE_UnlimitedStorageForLocalButNotSync) { std::set<std::string> permissions; permissions.insert("unlimitedStorage"); scoped_refptr<const Extension> extension = - util::AddExtensionWithIdAndPermissions( + settings_test_util::AddExtensionWithIdAndPermissions( profile_.get(), id, Manifest::TYPE_EXTENSION, permissions); frontend_->RunWithStorage(extension, diff --git a/chromium/chrome/browser/extensions/api/system_indicator/system_indicator_api.cc b/chromium/chrome/browser/extensions/api/system_indicator/system_indicator_api.cc new file mode 100644 index 00000000000..14407bcd85c --- /dev/null +++ b/chromium/chrome/browser/extensions/api/system_indicator/system_indicator_api.cc @@ -0,0 +1,80 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/extensions/api/system_indicator/system_indicator_api.h" + +#include "base/no_destructor.h" +#include "chrome/browser/extensions/api/system_indicator/system_indicator_manager.h" +#include "chrome/browser/extensions/api/system_indicator/system_indicator_manager_factory.h" +#include "chrome/browser/extensions/extension_action.h" +#include "chrome/common/extensions/api/system_indicator/system_indicator_handler.h" +#include "ui/gfx/image/image.h" +#include "ui/gfx/image/image_skia.h" + +namespace extensions { + +namespace { + +// Returns true if the extension has a system indicator. +bool HasSystemIndicator(const Extension& extension) { + return SystemIndicatorHandler::GetSystemIndicatorIcon(extension) != nullptr; +} + +} // namespace + +ExtensionFunction::ResponseAction SystemIndicatorSetIconFunction::Run() { + EXTENSION_FUNCTION_VALIDATE(extension()); + EXTENSION_FUNCTION_VALIDATE(HasSystemIndicator(*extension())); + + EXTENSION_FUNCTION_VALIDATE(args_->GetList().size() == 1); + EXTENSION_FUNCTION_VALIDATE(args_->GetList()[0].is_dict()); + + const base::Value& set_icon_details = args_->GetList()[0]; + + // NOTE: For historical reasons, this code is primarily taken from + // ExtensionActionSetIconFunction. + // setIcon can take a variant argument: either a dictionary of canvas + // ImageData, or an icon index. + if (const base::Value* canvas_set = set_icon_details.FindKeyOfType( + "imageData", base::Value::Type::DICTIONARY)) { + gfx::ImageSkia icon; + EXTENSION_FUNCTION_VALIDATE(ExtensionAction::ParseIconFromCanvasDictionary( + static_cast<const base::DictionaryValue&>(*canvas_set), &icon)); + + if (icon.isNull()) + return RespondNow(Error("Icon invalid.")); + + SystemIndicatorManagerFactory::GetForContext(browser_context()) + ->SetSystemIndicatorDynamicIcon(*extension(), gfx::Image(icon)); + } else if (set_icon_details.FindKeyOfType("iconIndex", + base::Value::Type::INTEGER)) { + // Obsolete argument: ignore it. + // TODO(devlin): Do we need this here? Does any systemIndicator extension + // use it? + } else { + EXTENSION_FUNCTION_VALIDATE(false); + } + + return RespondNow(NoArguments()); +} + +ExtensionFunction::ResponseAction SystemIndicatorEnableFunction::Run() { + EXTENSION_FUNCTION_VALIDATE(extension()); + EXTENSION_FUNCTION_VALIDATE(HasSystemIndicator(*extension())); + + SystemIndicatorManagerFactory::GetForContext(browser_context()) + ->SetSystemIndicatorEnabled(*extension(), true); + return RespondNow(NoArguments()); +} + +ExtensionFunction::ResponseAction SystemIndicatorDisableFunction::Run() { + EXTENSION_FUNCTION_VALIDATE(extension()); + EXTENSION_FUNCTION_VALIDATE(HasSystemIndicator(*extension())); + + SystemIndicatorManagerFactory::GetForContext(browser_context()) + ->SetSystemIndicatorEnabled(*extension(), false); + return RespondNow(NoArguments()); +} + +} // namespace extensions diff --git a/chromium/chrome/browser/extensions/api/system_indicator/system_indicator_api.h b/chromium/chrome/browser/extensions/api/system_indicator/system_indicator_api.h index 318d8ebf5f7..b0bd25e0404 100644 --- a/chromium/chrome/browser/extensions/api/system_indicator/system_indicator_api.h +++ b/chromium/chrome/browser/extensions/api/system_indicator/system_indicator_api.h @@ -5,31 +5,36 @@ #ifndef CHROME_BROWSER_EXTENSIONS_API_SYSTEM_INDICATOR_SYSTEM_INDICATOR_API_H_ #define CHROME_BROWSER_EXTENSIONS_API_SYSTEM_INDICATOR_SYSTEM_INDICATOR_API_H_ -#include "chrome/browser/extensions/api/extension_action/extension_action_api.h" #include "extensions/browser/extension_function.h" namespace extensions { -class SystemIndicatorSetIconFunction : public ExtensionActionSetIconFunction { +class SystemIndicatorSetIconFunction : public UIThreadExtensionFunction { public: DECLARE_EXTENSION_FUNCTION("systemIndicator.setIcon", SYSTEMINDICATOR_SETICON) + ResponseAction Run() override; + protected: ~SystemIndicatorSetIconFunction() override {} }; -class SystemIndicatorEnableFunction : public ExtensionActionShowFunction { +class SystemIndicatorEnableFunction : public UIThreadExtensionFunction { public: DECLARE_EXTENSION_FUNCTION("systemIndicator.enable", SYSTEMINDICATOR_ENABLE) + ResponseAction Run() override; + protected: ~SystemIndicatorEnableFunction() override {} }; -class SystemIndicatorDisableFunction : public ExtensionActionHideFunction { +class SystemIndicatorDisableFunction : public UIThreadExtensionFunction { public: DECLARE_EXTENSION_FUNCTION("systemIndicator.disable", SYSTEMINDICATOR_DISABLE) + ResponseAction Run() override; + protected: ~SystemIndicatorDisableFunction() override {} }; diff --git a/chromium/chrome/browser/extensions/api/system_indicator/system_indicator_apitest.cc b/chromium/chrome/browser/extensions/api/system_indicator/system_indicator_apitest.cc index 2313974b371..ff92a14e3d8 100644 --- a/chromium/chrome/browser/extensions/api/system_indicator/system_indicator_apitest.cc +++ b/chromium/chrome/browser/extensions/api/system_indicator/system_indicator_apitest.cc @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "build/build_config.h" #include "chrome/browser/extensions/api/system_indicator/system_indicator_manager.h" #include "chrome/browser/extensions/api/system_indicator/system_indicator_manager_factory.h" #include "chrome/browser/extensions/extension_action.h" @@ -9,63 +10,70 @@ #include "chrome/browser/extensions/extension_apitest.h" #include "chrome/browser/extensions/lazy_background_page_test_util.h" #include "chrome/browser/ui/browser.h" +#include "components/version_info/channel.h" #include "extensions/browser/process_manager.h" #include "extensions/common/extension.h" +#include "extensions/common/features/feature_channel.h" +#include "extensions/common/manifest_test.h" #include "extensions/test/result_catcher.h" namespace extensions { class SystemIndicatorApiTest : public ExtensionApiTest { public: + SystemIndicatorApiTest() : scoped_channel_(version_info::Channel::DEV) {} + ~SystemIndicatorApiTest() override = default; + void SetUpOnMainThread() override { ExtensionApiTest::SetUpOnMainThread(); // Set shorter delays to prevent test timeouts in tests that need to wait // for the event page to unload. - extensions::ProcessManager::SetEventPageIdleTimeForTesting(1); - extensions::ProcessManager::SetEventPageSuspendingTimeForTesting(1); + ProcessManager::SetEventPageIdleTimeForTesting(1); + ProcessManager::SetEventPageSuspendingTimeForTesting(1); } - const extensions::Extension* LoadExtensionAndWait( - const std::string& test_name) { + const Extension* LoadExtensionAndWait(const std::string& test_name) { LazyBackgroundObserver page_complete; base::FilePath extdir = test_data_dir_.AppendASCII(test_name); - const extensions::Extension* extension = LoadExtension(extdir); + const Extension* extension = LoadExtension(extdir); if (extension) page_complete.Wait(); return extension; } + + private: + ScopedCurrentChannel scoped_channel_; + + DISALLOW_COPY_AND_ASSIGN(SystemIndicatorApiTest); }; -IN_PROC_BROWSER_TEST_F(ExtensionApiTest, SystemIndicator) { - // Only run this test on supported platforms. SystemIndicatorManagerFactory - // returns NULL on unsupported platforms. - extensions::SystemIndicatorManager* manager = - extensions::SystemIndicatorManagerFactory::GetForProfile(profile()); - if (manager) { - ASSERT_TRUE(RunExtensionTest("system_indicator/basics")) << message_; - } +// https://crbug.com/960363: Test crashes on ChromeOS. +#if defined(OS_CHROMEOS) +#define MAYBE_SystemIndicatorBasic DISABLED_SystemIndicatorBasic +#else +#define MAYBE_SystemIndicatorBasic SystemIndicatorBasic +#endif +IN_PROC_BROWSER_TEST_F(SystemIndicatorApiTest, MAYBE_SystemIndicatorBasic) { + ASSERT_TRUE(RunExtensionTest("system_indicator/basics")) << message_; } // Failing on 10.6, flaky elsewhere http://crbug.com/497643 -IN_PROC_BROWSER_TEST_F(SystemIndicatorApiTest, DISABLED_SystemIndicator) { - // Only run this test on supported platforms. SystemIndicatorManagerFactory - // returns NULL on unsupported platforms. - extensions::SystemIndicatorManager* manager = - extensions::SystemIndicatorManagerFactory::GetForProfile(profile()); - if (manager) { - extensions::ResultCatcher catcher; +IN_PROC_BROWSER_TEST_F(SystemIndicatorApiTest, + DISABLED_SystemIndicatorUnloaded) { + ResultCatcher catcher; - const extensions::Extension* extension = - LoadExtensionAndWait("system_indicator/unloaded"); - ASSERT_TRUE(extension) << message_; + const Extension* extension = + LoadExtensionAndWait("system_indicator/unloaded"); + ASSERT_TRUE(extension) << message_; - // Lazy Background Page has been shut down. - extensions::ProcessManager* pm = extensions::ProcessManager::Get(profile()); - EXPECT_FALSE(pm->GetBackgroundHostForExtension(last_loaded_extension_id())); + // Lazy Background Page has been shut down. + ProcessManager* pm = ProcessManager::Get(profile()); + EXPECT_FALSE(pm->GetBackgroundHostForExtension(last_loaded_extension_id())); - EXPECT_TRUE(manager->SendClickEventToExtensionForTest(extension->id())); - EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); - } + SystemIndicatorManager* manager = + SystemIndicatorManagerFactory::GetForContext(profile()); + EXPECT_TRUE(manager->SendClickEventToExtensionForTest(extension->id())); + EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); } } // namespace extensions diff --git a/chromium/chrome/browser/extensions/api/system_indicator/system_indicator_manager.cc b/chromium/chrome/browser/extensions/api/system_indicator/system_indicator_manager.cc index baa15574995..ee22cb179bf 100644 --- a/chromium/chrome/browser/extensions/api/system_indicator/system_indicator_manager.cc +++ b/chromium/chrome/browser/extensions/api/system_indicator/system_indicator_manager.cc @@ -6,6 +6,7 @@ #include <utility> +#include "base/stl_util.h" #include "base/strings/utf_string_conversions.h" #include "chrome/browser/extensions/extension_action.h" #include "chrome/browser/profiles/profile.h" @@ -13,11 +14,13 @@ #include "chrome/browser/status_icons/status_icon_observer.h" #include "chrome/browser/status_icons/status_tray.h" #include "chrome/common/extensions/api/system_indicator.h" +#include "chrome/common/extensions/api/system_indicator/system_indicator_handler.h" #include "content/public/browser/web_contents.h" #include "extensions/browser/event_router.h" +#include "extensions/browser/extension_icon_image.h" #include "extensions/browser/extension_registry.h" #include "extensions/common/extension.h" -#include "ui/gfx/image/image.h" +#include "extensions/common/extension_icon_set.h" namespace extensions { @@ -28,57 +31,69 @@ namespace system_indicator = api::system_indicator; // and removing the icon from the notification area during construction and // destruction. class ExtensionIndicatorIcon : public StatusIconObserver, - public ExtensionActionIconFactory::Observer { + public IconImage::Observer { public: static std::unique_ptr<ExtensionIndicatorIcon> Create( - const Extension* extension, - ExtensionAction* action, + const Extension& extension, + const ExtensionIconSet& icon_set, Profile* profile, StatusTray* status_tray); ~ExtensionIndicatorIcon() override; - // StatusIconObserver implementation. - void OnStatusIconClicked() override; + // Sets the dynamic icon for the indicator. + void SetDynamicIcon(gfx::Image dynamic_icon); - // ExtensionActionIconFactory::Observer implementation. - void OnIconUpdated() override; + // StatusIconObserver: + void OnStatusIconClicked() override; private: - ExtensionIndicatorIcon(const Extension* extension, - ExtensionAction* action, + ExtensionIndicatorIcon(const Extension& extension, + const ExtensionIconSet& manifest_icon_set, Profile* profile, StatusTray* status_tray); - const extensions::Extension* extension_; + // IconImage::Observer: + void OnExtensionIconImageChanged(IconImage* image) override; + + const Extension* extension_; StatusTray* status_tray_; - StatusIcon* icon_; + StatusIcon* status_icon_; Profile* profile_; - ExtensionActionIconFactory icon_factory_; + IconImage manifest_icon_; + gfx::Image dynamic_icon_; + + DISALLOW_COPY_AND_ASSIGN(ExtensionIndicatorIcon); }; std::unique_ptr<ExtensionIndicatorIcon> ExtensionIndicatorIcon::Create( - const Extension* extension, - ExtensionAction* action, + const Extension& extension, + const ExtensionIconSet& icon_set, Profile* profile, StatusTray* status_tray) { - std::unique_ptr<ExtensionIndicatorIcon> extension_icon( - new ExtensionIndicatorIcon(extension, action, profile, status_tray)); + // Private ctor, so have to use WrapUnique. + auto extension_icon = base::WrapUnique( + new ExtensionIndicatorIcon(extension, icon_set, profile, status_tray)); // Check if a status icon was successfully created. - if (extension_icon->icon_) + if (extension_icon->status_icon_) return extension_icon; // We could not create a status icon. - return std::unique_ptr<ExtensionIndicatorIcon>(); + return nullptr; } ExtensionIndicatorIcon::~ExtensionIndicatorIcon() { - if (icon_) { - icon_->RemoveObserver(this); - status_tray_->RemoveStatusIcon(icon_); + if (status_icon_) { + status_icon_->RemoveObserver(this); + status_tray_->RemoveStatusIcon(status_icon_); } } +void ExtensionIndicatorIcon::SetDynamicIcon(gfx::Image dynamic_icon) { + dynamic_icon_ = std::move(dynamic_icon); + status_icon_->SetImage(dynamic_icon_.AsImageSkia()); +} + void ExtensionIndicatorIcon::OnStatusIconClicked() { std::unique_ptr<base::ListValue> params( api::system_indicator::OnClicked::Create()); @@ -90,40 +105,46 @@ void ExtensionIndicatorIcon::OnStatusIconClicked() { event_router->DispatchEventToExtension(extension_->id(), std::move(event)); } -void ExtensionIndicatorIcon::OnIconUpdated() { - icon_->SetImage( - icon_factory_.GetIcon(ExtensionAction::kDefaultTabId).AsImageSkia()); +void ExtensionIndicatorIcon::OnExtensionIconImageChanged(IconImage* image) { + if (dynamic_icon_.IsEmpty()) // Don't override a dynamically-set icon. + status_icon_->SetImage(manifest_icon_.image().AsImageSkia()); } -ExtensionIndicatorIcon::ExtensionIndicatorIcon(const Extension* extension, - ExtensionAction* action, - Profile* profile, - StatusTray* status_tray) - : extension_(extension), +ExtensionIndicatorIcon::ExtensionIndicatorIcon( + const Extension& extension, + const ExtensionIconSet& manifest_icon_set, + Profile* profile, + StatusTray* status_tray) + : extension_(&extension), status_tray_(status_tray), - icon_(NULL), + status_icon_(nullptr), profile_(profile), - icon_factory_(profile, extension, action, this) { + manifest_icon_(profile, + &extension, + manifest_icon_set, + ExtensionAction::ActionIconSize(), + ExtensionAction::FallbackIcon().AsImageSkia(), + this) { // Get the icon image and tool tip for the status icon. The extension name is // used as the tool tip. - gfx::ImageSkia icon_image = - icon_factory_.GetIcon(ExtensionAction::kDefaultTabId).AsImageSkia(); + gfx::ImageSkia icon_skia = manifest_icon_.image().AsImageSkia(); base::string16 tool_tip = base::UTF8ToUTF16(extension_->name()); - icon_ = status_tray_->CreateStatusIcon( - StatusTray::OTHER_ICON, icon_image, tool_tip); - if (icon_) - icon_->AddObserver(this); + status_icon_ = status_tray_->CreateStatusIcon(StatusTray::OTHER_ICON, + icon_skia, tool_tip); + if (status_icon_) + status_icon_->AddObserver(this); } +SystemIndicatorManager::SystemIndicator::SystemIndicator() {} +SystemIndicatorManager::SystemIndicator::~SystemIndicator() = default; + SystemIndicatorManager::SystemIndicatorManager(Profile* profile, StatusTray* status_tray) : profile_(profile), status_tray_(status_tray), - extension_action_observer_(this), extension_registry_observer_(this) { extension_registry_observer_.Add(ExtensionRegistry::Get(profile_)); - extension_action_observer_.Add(ExtensionActionAPI::Get(profile_)); } SystemIndicatorManager::~SystemIndicatorManager() { @@ -134,64 +155,73 @@ void SystemIndicatorManager::Shutdown() { DCHECK(thread_checker_.CalledOnValidThread()); } -void SystemIndicatorManager::OnExtensionUnloaded( - content::BrowserContext* browser_context, - const Extension* extension, - UnloadedExtensionReason reason) { - RemoveIndicator(extension->id()); +void SystemIndicatorManager::SetSystemIndicatorDynamicIcon( + const Extension& extension, + gfx::Image icon) { + DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK(base::ContainsKey(system_indicators_, extension.id())); + auto& indicator = system_indicators_[extension.id()]; + indicator.dynamic_icon = icon; + if (indicator.system_tray_indicator) + indicator.system_tray_indicator->SetDynamicIcon(std::move(icon)); } -void SystemIndicatorManager::OnExtensionActionUpdated( - ExtensionAction* extension_action, - content::WebContents* web_contents, - content::BrowserContext* browser_context) { +void SystemIndicatorManager::SetSystemIndicatorEnabled( + const Extension& extension, + bool is_enabled) { DCHECK(thread_checker_.CalledOnValidThread()); - if (profile_->GetOriginalProfile() != browser_context || - extension_action->action_type() != ActionInfo::TYPE_SYSTEM_INDICATOR) + DCHECK(base::ContainsKey(system_indicators_, extension.id())); + auto& indicator = system_indicators_[extension.id()]; + bool is_already_enabled = !!indicator.system_tray_indicator; + if (is_already_enabled == is_enabled) return; - std::string extension_id = extension_action->extension_id(); - if (extension_action->GetIsVisible(ExtensionAction::kDefaultTabId)) { - CreateOrUpdateIndicator( - ExtensionRegistry::Get(profile_)->enabled_extensions().GetByID( - extension_id), - extension_action); + if (is_enabled) { + indicator.system_tray_indicator = ExtensionIndicatorIcon::Create( + extension, indicator.manifest_icon_set, profile_, status_tray_); + // Note: The system tray indicator creation can fail. + if (indicator.system_tray_indicator && !indicator.dynamic_icon.IsEmpty()) { + indicator.system_tray_indicator->SetDynamicIcon(indicator.dynamic_icon); + } } else { - RemoveIndicator(extension_id); + indicator.system_tray_indicator.reset(); } } -bool SystemIndicatorManager::SendClickEventToExtensionForTest( - const std::string& extension_id) { - auto it = system_indicators_.find(extension_id); - - if (it == system_indicators_.end()) - return false; +void SystemIndicatorManager::OnExtensionLoaded( + content::BrowserContext* browser_context, + const Extension* extension) { + DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK(!base::ContainsKey(system_indicators_, extension->id())); + const ExtensionIconSet* indicator_icon = + SystemIndicatorHandler::GetSystemIndicatorIcon(*extension); + if (!indicator_icon) + return; - it->second->OnStatusIconClicked(); - return true; + auto& indicator = system_indicators_[extension->id()]; + indicator.manifest_icon_set = *indicator_icon; } -void SystemIndicatorManager::CreateOrUpdateIndicator( +void SystemIndicatorManager::OnExtensionUnloaded( + content::BrowserContext* browser_context, const Extension* extension, - ExtensionAction* extension_action) { + UnloadedExtensionReason reason) { DCHECK(thread_checker_.CalledOnValidThread()); - auto it = system_indicators_.find(extension->id()); - if (it != system_indicators_.end()) { - it->second->OnIconUpdated(); - return; - } - - std::unique_ptr<ExtensionIndicatorIcon> extension_icon = - ExtensionIndicatorIcon::Create(extension, extension_action, profile_, - status_tray_); - if (extension_icon) - system_indicators_[extension->id()] = std::move(extension_icon); + system_indicators_.erase(extension->id()); } -void SystemIndicatorManager::RemoveIndicator(const std::string& extension_id) { +bool SystemIndicatorManager::SendClickEventToExtensionForTest( + const ExtensionId& extension_id) { DCHECK(thread_checker_.CalledOnValidThread()); - system_indicators_.erase(extension_id); + auto it = system_indicators_.find(extension_id); + + if (it == system_indicators_.end() || + it->second.system_tray_indicator == nullptr) { + return false; + } + + it->second.system_tray_indicator->OnStatusIconClicked(); + return true; } } // namespace extensions diff --git a/chromium/chrome/browser/extensions/api/system_indicator/system_indicator_manager.h b/chromium/chrome/browser/extensions/api/system_indicator/system_indicator_manager.h index a16d5f37f2d..378cc6a5796 100644 --- a/chromium/chrome/browser/extensions/api/system_indicator/system_indicator_manager.h +++ b/chromium/chrome/browser/extensions/api/system_indicator/system_indicator_manager.h @@ -12,17 +12,17 @@ #include "base/macros.h" #include "base/scoped_observer.h" #include "base/threading/thread_checker.h" -#include "chrome/browser/extensions/api/extension_action/extension_action_api.h" -#include "chrome/browser/extensions/extension_action_icon_factory.h" #include "components/keyed_service/core/keyed_service.h" #include "extensions/browser/extension_registry_observer.h" +#include "extensions/common/extension_icon_set.h" +#include "extensions/common/extension_id.h" +#include "ui/gfx/image/image.h" -class ExtensionAction; class Profile; class StatusTray; namespace extensions { -FORWARD_DECLARE_TEST(SystemIndicatorApiTest, SystemIndicator); +FORWARD_DECLARE_TEST(SystemIndicatorApiTest, SystemIndicatorUnloaded); class ExtensionIndicatorIcon; class ExtensionRegistry; @@ -31,54 +31,60 @@ class ExtensionRegistry; // that are currently visible in the UI. Use SystemIndicatorManagerFactory to // create a SystemIndicatorManager object. class SystemIndicatorManager : public ExtensionRegistryObserver, - public ExtensionActionAPI::Observer, public KeyedService { public: SystemIndicatorManager(Profile* profile, StatusTray* status_tray); ~SystemIndicatorManager() override; + // Sets the icon of the system indicator for the given |extension| to + // |icon|. + void SetSystemIndicatorDynamicIcon(const Extension& extension, + gfx::Image icon); + + // Sets whether the system indicator for the given |extension| is enabled. + void SetSystemIndicatorEnabled(const Extension& extension, bool is_enabled); + // KeyedService implementation. void Shutdown() override; private: - FRIEND_TEST_ALL_PREFIXES(SystemIndicatorApiTest, SystemIndicator); - - // ExtensionRegistryObserver implementation. + FRIEND_TEST_ALL_PREFIXES(SystemIndicatorApiTest, SystemIndicatorUnloaded); + + // A structure representing the system indicator for an extension. + struct SystemIndicator { + SystemIndicator(); + ~SystemIndicator(); + + // A dynamically-set icon (through systemIndicator.setIcon()). Takes + // precedence over the |default_icon|. + gfx::Image dynamic_icon; + // The default system indicator icon specified in the manifest. + ExtensionIconSet manifest_icon_set; + // The system tray indicator. This is only non-null if the system indicator + // is enabled. + std::unique_ptr<ExtensionIndicatorIcon> system_tray_indicator; + + DISALLOW_COPY_AND_ASSIGN(SystemIndicator); + }; + + // ExtensionRegistryObserver: + void OnExtensionLoaded(content::BrowserContext* browser_context, + const Extension* extension) override; void OnExtensionUnloaded(content::BrowserContext* browser_context, const Extension* extension, UnloadedExtensionReason reason) override; - // ExtensionActionAPI::Observer implementation. - void OnExtensionActionUpdated( - ExtensionAction* extension_action, - content::WebContents* web_contents, - content::BrowserContext* browser_context) override; - // Causes a call to OnStatusIconClicked for the specified extension_id. // Returns false if no ExtensionIndicatorIcon is found for the extension. bool SendClickEventToExtensionForTest(const std::string& extension_id); - // Causes an indicator to be shown for the given extension_action. Creates - // the indicator if necessary. - void CreateOrUpdateIndicator( - const Extension* extension, - ExtensionAction* extension_action); - - // Causes the indicator for the given extension to be hidden. - void RemoveIndicator(const std::string& extension_id); - - using SystemIndicatorMap = - std::map<const std::string, std::unique_ptr<ExtensionIndicatorIcon>>; + using SystemIndicatorMap = std::map<ExtensionId, SystemIndicator>; Profile* profile_; StatusTray* status_tray_; SystemIndicatorMap system_indicators_; base::ThreadChecker thread_checker_; - ScopedObserver<ExtensionActionAPI, ExtensionActionAPI::Observer> - extension_action_observer_; - - // Listen to extension unloaded notifications. ScopedObserver<ExtensionRegistry, ExtensionRegistryObserver> extension_registry_observer_; diff --git a/chromium/chrome/browser/extensions/api/system_indicator/system_indicator_manager_factory.cc b/chromium/chrome/browser/extensions/api/system_indicator/system_indicator_manager_factory.cc index 8aef0625f4d..f28a58d4b97 100644 --- a/chromium/chrome/browser/extensions/api/system_indicator/system_indicator_manager_factory.cc +++ b/chromium/chrome/browser/extensions/api/system_indicator/system_indicator_manager_factory.cc @@ -5,7 +5,6 @@ #include "chrome/browser/extensions/api/system_indicator/system_indicator_manager_factory.h" #include "chrome/browser/browser_process.h" -#include "chrome/browser/extensions/api/extension_action/extension_action_api.h" #include "chrome/browser/extensions/api/system_indicator/system_indicator_manager.h" #include "chrome/browser/profiles/profile.h" #include "components/keyed_service/content/browser_context_dependency_manager.h" @@ -15,10 +14,10 @@ namespace extensions { // static -SystemIndicatorManager* SystemIndicatorManagerFactory::GetForProfile( - Profile* profile) { +SystemIndicatorManager* SystemIndicatorManagerFactory::GetForContext( + content::BrowserContext* context) { return static_cast<SystemIndicatorManager*>( - GetInstance()->GetServiceForBrowserContext(profile, true)); + GetInstance()->GetServiceForBrowserContext(context, true)); } // static @@ -31,7 +30,6 @@ SystemIndicatorManagerFactory::SystemIndicatorManagerFactory() "SystemIndicatorManager", BrowserContextDependencyManager::GetInstance()) { DependsOn(ExtensionsBrowserClient::Get()->GetExtensionSystemFactory()); - DependsOn(ExtensionActionAPI::GetFactoryInstance()); } SystemIndicatorManagerFactory::~SystemIndicatorManagerFactory() {} @@ -46,4 +44,11 @@ KeyedService* SystemIndicatorManagerFactory::BuildServiceInstanceFor( status_tray); } +bool SystemIndicatorManagerFactory::ServiceIsCreatedWithBrowserContext() const { + // The SystemIndicatorManager monitors extensions being loaded and unloaded + // to check if they have system indicators specified. In order to observe + // these, it needs to be created at profile initialization. + return true; +} + } // namespace extensions diff --git a/chromium/chrome/browser/extensions/api/system_indicator/system_indicator_manager_factory.h b/chromium/chrome/browser/extensions/api/system_indicator/system_indicator_manager_factory.h index 3828a7da1a9..a20383186cb 100644 --- a/chromium/chrome/browser/extensions/api/system_indicator/system_indicator_manager_factory.h +++ b/chromium/chrome/browser/extensions/api/system_indicator/system_indicator_manager_factory.h @@ -8,7 +8,9 @@ #include "base/memory/singleton.h" #include "components/keyed_service/content/browser_context_keyed_service_factory.h" -class Profile; +namespace content { +class BrowserContext; +} namespace extensions { class SystemIndicatorManager; @@ -16,7 +18,8 @@ class SystemIndicatorManager; // BrowserContextKeyedServiceFactory for each SystemIndicatorManager. class SystemIndicatorManagerFactory : public BrowserContextKeyedServiceFactory { public: - static SystemIndicatorManager* GetForProfile(Profile* profile); + static SystemIndicatorManager* GetForContext( + content::BrowserContext* context); static SystemIndicatorManagerFactory* GetInstance(); @@ -26,9 +29,10 @@ class SystemIndicatorManagerFactory : public BrowserContextKeyedServiceFactory { SystemIndicatorManagerFactory(); ~SystemIndicatorManagerFactory() override; - // BrowserContextKeyedBaseFactory implementation. + // BrowserContextKeyedServiceFactory implementation. KeyedService* BuildServiceInstanceFor( - content::BrowserContext* profile) const override; + content::BrowserContext* context) const override; + bool ServiceIsCreatedWithBrowserContext() const override; }; } // namespace extensions diff --git a/chromium/chrome/browser/extensions/api/tabs/tabs_api.cc b/chromium/chrome/browser/extensions/api/tabs/tabs_api.cc index 22717b0f96c..bb3a4f05a79 100644 --- a/chromium/chrome/browser/extensions/api/tabs/tabs_api.cc +++ b/chromium/chrome/browser/extensions/api/tabs/tabs_api.cc @@ -1249,7 +1249,7 @@ ExtensionFunction::ResponseAction TabsUpdateFunction::Run() { // Navigate the tab to a new location if the url is different. if (params->update_properties.url.get()) { std::string updated_url = *params->update_properties.url; - if (browser->profile()->GetProfileType() == Profile::INCOGNITO_PROFILE && + if (browser->profile()->IsIncognitoProfile() && !IsURLAllowedInIncognito(GURL(updated_url), browser->profile())) { return RespondNow(Error(ErrorUtils::FormatErrorMessage( tabs_constants::kURLsNotAllowedInIncognitoError, updated_url))); @@ -1505,8 +1505,9 @@ bool TabsMoveFunction::MoveTab(int tab_id, *new_index = target_tab_strip->count(); content::WebContents* web_contents_raw = web_contents.get(); - target_tab_strip->InsertWebContentsAt(*new_index, std::move(web_contents), - TabStripModel::ADD_NONE); + + *new_index = target_tab_strip->InsertWebContentsAt( + *new_index, std::move(web_contents), TabStripModel::ADD_NONE); if (has_callback()) { tab_values->Append(ExtensionTabUtil::CreateTabObject( @@ -1527,7 +1528,8 @@ bool TabsMoveFunction::MoveTab(int tab_id, *new_index = source_tab_strip->count() - 1; if (*new_index != tab_index) - source_tab_strip->MoveWebContentsAt(tab_index, *new_index, false); + *new_index = + source_tab_strip->MoveWebContentsAt(tab_index, *new_index, false); if (has_callback()) { tab_values->Append(ExtensionTabUtil::CreateTabObject( diff --git a/chromium/chrome/browser/extensions/api/tabs/tabs_event_router.cc b/chromium/chrome/browser/extensions/api/tabs/tabs_event_router.cc index 88a4fc52aed..ead6f0a7144 100644 --- a/chromium/chrome/browser/extensions/api/tabs/tabs_event_router.cc +++ b/chromium/chrome/browser/extensions/api/tabs/tabs_event_router.cc @@ -187,36 +187,35 @@ void TabsEventRouter::OnTabStripModelChanged( const TabStripSelectionChange& selection) { switch (change.type()) { case TabStripModelChange::kInserted: { - for (const auto& delta : change.deltas()) { - DispatchTabInsertedAt(tab_strip_model, delta.insert.contents, - delta.insert.index, - selection.new_contents == delta.insert.contents); + for (const auto& contents : change.GetInsert()->contents) { + DispatchTabInsertedAt(tab_strip_model, contents.contents, + contents.index, + selection.new_contents == contents.contents); } break; } case TabStripModelChange::kRemoved: { - for (const auto& delta : change.deltas()) { - if (delta.remove.will_be_deleted) - DispatchTabClosingAt(tab_strip_model, delta.remove.contents, - delta.remove.index); - - DispatchTabDetachedAt(delta.remove.contents, delta.remove.index, - selection.old_contents == delta.remove.contents); + const bool will_be_deleted = change.GetRemove()->will_be_deleted; + for (const auto& contents : change.GetRemove()->contents) { + if (will_be_deleted) { + DispatchTabClosingAt(tab_strip_model, contents.contents, + contents.index); + } + + DispatchTabDetachedAt(contents.contents, contents.index, + selection.old_contents == contents.contents); } break; } case TabStripModelChange::kMoved: { - for (const auto& delta : change.deltas()) { - DispatchTabMoved(delta.move.contents, delta.move.from_index, - delta.move.to_index); - } + auto* move = change.GetMove(); + DispatchTabMoved(move->contents, move->from_index, move->to_index); break; } case TabStripModelChange::kReplaced: { - for (const auto& delta : change.deltas()) { - DispatchTabReplacedAt(delta.replace.old_contents, - delta.replace.new_contents, delta.replace.index); - } + auto* replace = change.GetReplace(); + DispatchTabReplacedAt(replace->old_contents, replace->new_contents, + replace->index); break; } case TabStripModelChange::kGroupChanged: diff --git a/chromium/chrome/browser/extensions/api/tabs/tabs_test.cc b/chromium/chrome/browser/extensions/api/tabs/tabs_test.cc index 5843368e01e..748dc56a796 100644 --- a/chromium/chrome/browser/extensions/api/tabs/tabs_test.cc +++ b/chromium/chrome/browser/extensions/api/tabs/tabs_test.cc @@ -40,12 +40,14 @@ #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/browser/ui/views/frame/browser_view.h" #include "chrome/browser/ui/zoom/chrome_zoom_level_prefs.h" +#include "chrome/common/webui_url_constants.h" #include "chrome/test/base/ui_test_utils.h" #include "components/prefs/pref_service.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/notification_service.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/storage_partition.h" +#include "content/public/common/mime_handler_view_mode.h" #include "content/public/common/page_zoom.h" #include "content/public/common/url_constants.h" #include "content/public/test/browser_test_utils.h" @@ -444,15 +446,16 @@ IN_PROC_BROWSER_TEST_F(ExtensionTabsTest, update_tab_function->set_extension(extension.get()); update_tab_function->set_include_incognito_information(true); - static const char kArgsWithNonIncognitoUrl[] = - "[null, {\"url\": \"chrome://extensions/configureCommands\"}]"; std::string error = extension_function_test_utils::RunFunctionAndReturnError( - update_tab_function.get(), kArgsWithNonIncognitoUrl, + update_tab_function.get(), + std::string("[null, {\"url\": \"") + chrome::kChromeUIExtensionsURL + + chrome::kExtensionConfigureCommandsSubPage + "\"}]", incognito, // incognito doesn't have any tabs. api_test_utils::NONE); EXPECT_EQ(ErrorUtils::FormatErrorMessage( tabs_constants::kURLsNotAllowedInIncognitoError, - "chrome://extensions/configureCommands"), + std::string(chrome::kChromeUIExtensionsURL) + + chrome::kExtensionConfigureCommandsSubPage), error); // Ensure the tab was not updated. It should stay as the new tab page. @@ -946,8 +949,9 @@ IN_PROC_BROWSER_TEST_F(ExtensionWindowLastFocusedTest, CloseAppWindow(app_window); } +// https://crbug.com/956870 IN_PROC_BROWSER_TEST_F(ExtensionWindowLastFocusedTest, - NoTabIdForDevToolsAndAppWindows) { + DISABLED_NoTabIdForDevToolsAndAppWindows) { Browser* normal_browser = CreateBrowserWithEmptyTab(false); { ActivateBrowserWindow(normal_browser); @@ -2084,10 +2088,18 @@ IN_PROC_BROWSER_TEST_F(ExtensionApiTest, MAYBE_TemporaryAddressSpoof) { pdf_extension_test_util::EnsurePDFHasLoaded(second_web_contents); EXPECT_TRUE(load_success); + auto* web_contents_for_click = second_web_contents; + if (content::MimeHandlerViewMode::UsesCrossProcessFrame()) { + auto inner_web_contents = web_contents_for_click->GetInnerWebContents(); + ASSERT_EQ(1U, inner_web_contents.size()); + // With MimeHandlerViewInCrossProcessFrame input should directly route to + // the guest WebContents as there is no longer a BrowserPlugin involved. + web_contents_for_click = inner_web_contents[0]; + } // The actual PDF page coordinates that this click goes to is (346, 333), // after several space transformations, not (400, 400). This clicks on a link // to "http://www.facebook.com:83". - content::SimulateMouseClickAt(second_web_contents, 0, + content::SimulateMouseClickAt(web_contents_for_click, 0, blink::WebMouseEvent::Button::kLeft, gfx::Point(400, 400)); diff --git a/chromium/chrome/browser/extensions/api/tabs/tabs_util_chromeos.cc b/chromium/chrome/browser/extensions/api/tabs/tabs_util_chromeos.cc index 0d37fecd99d..6539ae0132f 100644 --- a/chromium/chrome/browser/extensions/api/tabs/tabs_util_chromeos.cc +++ b/chromium/chrome/browser/extensions/api/tabs/tabs_util_chromeos.cc @@ -10,6 +10,8 @@ #include "chrome/browser/chromeos/accessibility/accessibility_manager.h" #include "chrome/browser/chromeos/arc/arc_session_manager.h" #include "chrome/browser/chromeos/arc/arc_util.h" +#include "chrome/browser/chromeos/arc/voice_interaction/voice_interaction_controller_client.h" +#include "chrome/browser/chromeos/assistant/assistant_util.h" #include "chrome/browser/ui/ash/chrome_screenshot_grabber.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_command_controller.h" @@ -69,6 +71,12 @@ void SetLockedFullscreenState(Browser* browser, bool locked) { arc_session_manager->RequestEnable(); } } + + if (assistant::IsAssistantAllowedForProfile(profile) == + ash::mojom::AssistantAllowedState::ALLOWED) { + arc::VoiceInteractionControllerClient::Get() + ->NotifyLockedFullScreenStateChanged(locked); + } } } // namespace tabs_util diff --git a/chromium/chrome/browser/extensions/api/virtual_keyboard_private/OWNERS b/chromium/chrome/browser/extensions/api/virtual_keyboard_private/OWNERS index 41986102de4..9834f7a713e 100644 --- a/chromium/chrome/browser/extensions/api/virtual_keyboard_private/OWNERS +++ b/chromium/chrome/browser/extensions/api/virtual_keyboard_private/OWNERS @@ -1,3 +1,3 @@ -file://ui/keyboard/OWNERS +file://ash/keyboard/ui/OWNERS # COMPONENT: UI>Input>VirtualKeyboard diff --git a/chromium/chrome/browser/extensions/api/virtual_keyboard_private/chrome_virtual_keyboard_delegate.cc b/chromium/chrome/browser/extensions/api/virtual_keyboard_private/chrome_virtual_keyboard_delegate.cc index 1aa88fcd3c2..812e63a5eb9 100644 --- a/chromium/chrome/browser/extensions/api/virtual_keyboard_private/chrome_virtual_keyboard_delegate.cc +++ b/chromium/chrome/browser/extensions/api/virtual_keyboard_private/chrome_virtual_keyboard_delegate.cc @@ -8,6 +8,8 @@ #include <string> #include <utility> +#include "ash/public/cpp/keyboard/keyboard_switches.h" +#include "ash/public/interfaces/keyboard_controller_types.mojom.h" #include "base/bind.h" #include "base/command_line.h" #include "base/feature_list.h" @@ -43,8 +45,6 @@ #include "ui/events/keycodes/dom/dom_key.h" #include "ui/events/keycodes/dom/keycode_converter.h" #include "ui/events/keycodes/keyboard_code_conversion.h" -#include "ui/keyboard/public/keyboard_controller_types.mojom.h" -#include "ui/keyboard/public/keyboard_switches.h" namespace keyboard_api = extensions::api::virtual_keyboard_private; @@ -64,8 +64,6 @@ keyboard::mojom::ContainerType ConvertKeyboardModeToContainerType(int mode) { return keyboard::mojom::ContainerType::kFullWidth; case keyboard_api::KEYBOARD_MODE_FLOATING: return keyboard::mojom::ContainerType::kFloating; - case keyboard_api::KEYBOARD_MODE_FULLSCREEN: - return keyboard::mojom::ContainerType::kFullscreen; } NOTREACHED(); @@ -141,7 +139,8 @@ bool SendKeyEventImpl(const std::string& type, // Indicate that the simulated key event is from the Virtual Keyboard. ui::Event::Properties properties; - properties[ui::kPropertyFromVK] = std::vector<uint8_t>(); + properties[ui::kPropertyFromVK] = + std::vector<uint8_t>(ui::kPropertyFromVKSize); event.SetProperties(properties); ui::EventDispatchDetails details = aura::EventInjector().Inject(host, &event); @@ -356,17 +355,15 @@ void ChromeVirtualKeyboardDelegate::OnHasInputDevices( results->SetBoolean("hotrodmode", g_hotrod_keyboard_enabled); std::unique_ptr<base::ListValue> features(new base::ListValue()); + // TODO(https://crbug.com/880659): Cleanup these flags after removing these + // flags from IME extension. features->AppendString(GenerateFeatureFlag("floatingkeyboard", true)); - features->AppendString(GenerateFeatureFlag( - "gesturetyping", !base::CommandLine::ForCurrentProcess()->HasSwitch( - keyboard::switches::kDisableGestureTyping))); + features->AppendString(GenerateFeatureFlag("gesturetyping", true)); // TODO(https://crbug.com/890134): Implement gesture editing. features->AppendString(GenerateFeatureFlag("gestureediting", false)); features->AppendString(GenerateFeatureFlag("fullscreenhandwriting", false)); features->AppendString(GenerateFeatureFlag("virtualkeyboardmdui", true)); - features->AppendString(GenerateFeatureFlag( - "imeservice", base::FeatureList::IsEnabled( - chromeos::features::kImeServiceConnectable))); + features->AppendString(GenerateFeatureFlag("imeservice", true)); keyboard::mojom::KeyboardConfig config = keyboard_client->GetKeyboardConfig(); // TODO(oka): Change this to use config.voice_input. diff --git a/chromium/chrome/browser/extensions/api/web_navigation/web_navigation_api.cc b/chromium/chrome/browser/extensions/api/web_navigation/web_navigation_api.cc index aa48f3d6298..7677465aa8f 100644 --- a/chromium/chrome/browser/extensions/api/web_navigation/web_navigation_api.cc +++ b/chromium/chrome/browser/extensions/api/web_navigation/web_navigation_api.cc @@ -98,25 +98,22 @@ void WebNavigationEventRouter::OnTabStripModelChanged( if (change.type() != TabStripModelChange::kReplaced) return; - for (const auto& delta : change.deltas()) { - content::WebContents* old_contents = delta.replace.old_contents; - content::WebContents* new_contents = delta.replace.new_contents; - - WebNavigationTabObserver* tab_observer = - WebNavigationTabObserver::Get(old_contents); - if (!tab_observer) { - // If you hit this DCHECK(), please add reproduction steps to - // http://crbug.com/109464. - DCHECK(GetViewType(old_contents) != VIEW_TYPE_TAB_CONTENTS); - continue; - } - if (!FrameNavigationState::IsValidUrl(old_contents->GetURL()) || - !FrameNavigationState::IsValidUrl(new_contents->GetURL())) - continue; + auto* replace = change.GetReplace(); + WebNavigationTabObserver* tab_observer = + WebNavigationTabObserver::Get(replace->old_contents); - web_navigation_api_helpers::DispatchOnTabReplaced(old_contents, profile_, - new_contents); + if (!tab_observer) { + // If you hit this DCHECK(), please add reproduction steps to + // http://crbug.com/109464. + DCHECK(GetViewType(replace->old_contents) != VIEW_TYPE_TAB_CONTENTS); + return; } + if (!FrameNavigationState::IsValidUrl(replace->old_contents->GetURL()) || + !FrameNavigationState::IsValidUrl(replace->new_contents->GetURL())) + return; + + web_navigation_api_helpers::DispatchOnTabReplaced( + replace->old_contents, profile_, replace->new_contents); } void WebNavigationEventRouter::Observe( diff --git a/chromium/chrome/browser/extensions/api/web_navigation/web_navigation_apitest.cc b/chromium/chrome/browser/extensions/api/web_navigation/web_navigation_apitest.cc index 6ab810e59fa..14e565b45b5 100644 --- a/chromium/chrome/browser/extensions/api/web_navigation/web_navigation_apitest.cc +++ b/chromium/chrome/browser/extensions/api/web_navigation/web_navigation_apitest.cc @@ -370,16 +370,7 @@ IN_PROC_BROWSER_TEST_F(WebNavigationApiTest, MAYBE_UserAction) { GURL url = extension->GetResourceURL( "a.html?" + base::NumberToString(embedded_test_server()->port())); - // Register an observer for the navigation in the subframe, so the test - // can wait until it is fully complete. Otherwise the context menu - // navigation is non-deterministic on which process it will get associated - // with, leading to test flakiness. - content::TestNavigationManager nav_manager( - tab, embedded_test_server()->GetURL( - "/extensions/api_test/webnavigation/userAction/subframe.html")); ui_test_utils::NavigateToURL(browser(), url); - nav_manager.WaitForNavigationFinished(); - EXPECT_TRUE(nav_manager.was_successful()); // This corresponds to "Open link in new tab". content::ContextMenuParams params; diff --git a/chromium/chrome/browser/extensions/api/web_request/OWNERS b/chromium/chrome/browser/extensions/api/web_request/OWNERS index d5f125f04e3..77b56cf082c 100644 --- a/chromium/chrome/browser/extensions/api/web_request/OWNERS +++ b/chromium/chrome/browser/extensions/api/web_request/OWNERS @@ -1 +1,3 @@ -battre@chromium.org +file://extensions/browser/api/web_request/OWNERS + +# COMPONENT: Platform>Extensions>API diff --git a/chromium/chrome/browser/extensions/api/web_request/web_request_api_unittest.cc b/chromium/chrome/browser/extensions/api/web_request/web_request_api_unittest.cc index bb40cff88ca..40ee4b1fb7a 100644 --- a/chromium/chrome/browser/extensions/api/web_request/web_request_api_unittest.cc +++ b/chromium/chrome/browser/extensions/api/web_request/web_request_api_unittest.cc @@ -47,6 +47,7 @@ #include "extensions/browser/api/web_request/web_request_api.h" #include "extensions/browser/api/web_request/web_request_api_constants.h" #include "extensions/browser/api/web_request/web_request_api_helpers.h" +#include "extensions/browser/api/web_request/web_request_info.h" #include "extensions/common/api/web_request.h" #include "extensions/common/constants.h" #include "extensions/common/extension_messages.h" @@ -99,6 +100,7 @@ using helpers::ResponseHeader; using helpers::ResponseHeaders; using helpers::StringToCharList; using testing::ElementsAre; +using Action = extensions::declarative_net_request::RulesetManager::Action; namespace extensions { @@ -225,7 +227,7 @@ class TestIPCSender : public IPC::Sender { SentMessages sent_messages_; }; -class TestLogger : public WebRequestInfo::Logger { +class TestLogger : public WebRequestInfoLogger { public: TestLogger() = default; ~TestLogger() override = default; @@ -1708,8 +1710,7 @@ TEST(ExtensionWebRequestHelpersTest, TestCalculateOnHeadersReceivedDelta) { "X-Chrome-ID-Consistency-Response: Value6\r\n" "\r\n"; auto base_headers = base::MakeRefCounted<net::HttpResponseHeaders>( - net::HttpUtil::AssembleRawHeaders(base_headers_string.c_str(), - base_headers_string.size())); + net::HttpUtil::AssembleRawHeaders(base_headers_string)); ResponseHeaders new_headers = { {"kEy1", "Value1"}, // Unchanged @@ -1758,8 +1759,7 @@ TEST(ExtensionWebRequestHelpersTest, "HTTP/1.0 200 OK\r\n" "Key1: Value1\r\n"; auto base_headers = base::MakeRefCounted<net::HttpResponseHeaders>( - net::HttpUtil::AssembleRawHeaders(base_headers_string.c_str(), - base_headers_string.size())); + net::HttpUtil::AssembleRawHeaders(base_headers_string)); ResponseHeaders new_headers = { {"Key1", "Value1"}, @@ -2063,7 +2063,6 @@ TEST(ExtensionWebRequestHelpersTest, TestMergeOnBeforeSendHeadersResponses) { net::HttpRequestHeaders base_headers; base_headers.SetHeader("key1", "value 1"); base_headers.SetHeader("key2", "value 2"); - TestLogger logger; helpers::IgnoredActions ignored_actions; std::string header_value; EventResponseDeltas deltas; @@ -2077,8 +2076,14 @@ TEST(ExtensionWebRequestHelpersTest, TestMergeOnBeforeSendHeadersResponses) { std::set<std::string> ignore1, ignore2; net::HttpRequestHeaders headers0; headers0.MergeFrom(base_headers); - MergeOnBeforeSendHeadersResponses(GURL(), deltas, &headers0, &ignored_actions, - &logger, &ignore1, &ignore2, + WebRequestInfoInitParams info_params; + info_params.logger = std::make_unique<TestLogger>(); + WebRequestInfo info(std::move(info_params)); + info.dnr_action.emplace(Action::Type::NONE); + // Take a reference to TestLogger to simplify accessing TestLogger methods. + TestLogger& logger = static_cast<TestLogger&>(*info.logger); + MergeOnBeforeSendHeadersResponses(info, deltas, &headers0, &ignored_actions, + &ignore1, &ignore2, &request_headers_modified0); ASSERT_TRUE(headers0.GetHeader("key1", &header_value)); EXPECT_EQ("value 1", header_value); @@ -2104,8 +2109,8 @@ TEST(ExtensionWebRequestHelpersTest, TestMergeOnBeforeSendHeadersResponses) { bool request_headers_modified1; net::HttpRequestHeaders headers1; headers1.MergeFrom(base_headers); - MergeOnBeforeSendHeadersResponses(GURL(), deltas, &headers1, &ignored_actions, - &logger, &ignore1, &ignore2, + MergeOnBeforeSendHeadersResponses(info, deltas, &headers1, &ignored_actions, + &ignore1, &ignore2, &request_headers_modified1); EXPECT_FALSE(headers1.HasHeader("key1")); ASSERT_TRUE(headers1.GetHeader("key2", &header_value)); @@ -2133,8 +2138,8 @@ TEST(ExtensionWebRequestHelpersTest, TestMergeOnBeforeSendHeadersResponses) { bool request_headers_modified2; net::HttpRequestHeaders headers2; headers2.MergeFrom(base_headers); - MergeOnBeforeSendHeadersResponses(GURL(), deltas, &headers2, &ignored_actions, - &logger, &ignore1, &ignore2, + MergeOnBeforeSendHeadersResponses(info, deltas, &headers2, &ignored_actions, + &ignore1, &ignore2, &request_headers_modified2); EXPECT_FALSE(headers2.HasHeader("key1")); ASSERT_TRUE(headers2.GetHeader("key2", &header_value)); @@ -2166,8 +2171,8 @@ TEST(ExtensionWebRequestHelpersTest, TestMergeOnBeforeSendHeadersResponses) { bool request_headers_modified3; net::HttpRequestHeaders headers3; headers3.MergeFrom(base_headers); - MergeOnBeforeSendHeadersResponses(GURL(), deltas, &headers3, &ignored_actions, - &logger, &ignore1, &ignore2, + MergeOnBeforeSendHeadersResponses(info, deltas, &headers3, &ignored_actions, + &ignore1, &ignore2, &request_headers_modified3); EXPECT_FALSE(headers3.HasHeader("key1")); ASSERT_TRUE(headers3.GetHeader("key2", &header_value)); @@ -2182,6 +2187,89 @@ TEST(ExtensionWebRequestHelpersTest, TestMergeOnBeforeSendHeadersResponses) { web_request::IGNORED_ACTION_TYPE_REQUEST_HEADERS)); EXPECT_EQ(3u, logger.log_size()); EXPECT_TRUE(request_headers_modified3); + + // Check that headers removed by Declarative Net Request API can't be modified + // and result in a conflict. + ignored_actions.clear(); + logger.clear(); + ignore1.clear(); + ignore2.clear(); + bool request_headers_modified4 = false; + net::HttpRequestHeaders headers4; + headers4.MergeFrom(base_headers); + info.dnr_action.emplace(Action::Type::REMOVE_HEADERS); + info.dnr_action->request_headers_to_remove = {"key5"}; + MergeOnBeforeSendHeadersResponses(info, deltas, &headers4, &ignored_actions, + &ignore1, &ignore2, + &request_headers_modified4); + // deleted by |d1|. + EXPECT_FALSE(headers4.HasHeader("key1")); + // Added by |d1|. + ASSERT_TRUE(headers4.GetHeader("key2", &header_value)); + EXPECT_EQ("value 3", header_value); + // Removed by Declarative Net Request API. + EXPECT_FALSE(headers4.HasHeader("key5")); + EXPECT_EQ(2u, ignored_actions.size()); + EXPECT_TRUE( + HasIgnoredAction(ignored_actions, "extid2", + web_request::IGNORED_ACTION_TYPE_REQUEST_HEADERS)); + EXPECT_TRUE( + HasIgnoredAction(ignored_actions, "extid2", + web_request::IGNORED_ACTION_TYPE_REQUEST_HEADERS)); + EXPECT_TRUE( + HasIgnoredAction(ignored_actions, "extid3", + web_request::IGNORED_ACTION_TYPE_REQUEST_HEADERS)); + EXPECT_EQ(3u, logger.log_size()); + EXPECT_TRUE(request_headers_modified4); +} + +// Ensure conflicts between different extensions are handled correctly with +// header names being interpreted in a case insensitive manner. Regression test +// for crbug.com/956795. +TEST(ExtensionWebRequestHelpersTest, + TestMergeOnBeforeSendHeadersResponses_Conflicts) { + // Have two extensions which both modify header "key1". + EventResponseDeltas deltas; + { + EventResponseDelta d1("extid1", base::Time::FromInternalValue(2000)); + d1.modified_request_headers.SetHeader("key1", "ext1"); + deltas.push_back(std::move(d1)); + } + + { + EventResponseDelta d2("extid2", base::Time::FromInternalValue(1000)); + d2.modified_request_headers.SetHeader("KEY1", "ext2"); + deltas.push_back(std::move(d2)); + } + + deltas.sort(&InDecreasingExtensionInstallationTimeOrder); + + WebRequestInfoInitParams info_params; + info_params.logger = std::make_unique<TestLogger>(); + WebRequestInfo info(std::move(info_params)); + info.dnr_action.emplace(Action::Type::NONE); + helpers::IgnoredActions ignored_actions; + std::set<std::string> removed_headers, set_headers; + bool request_headers_modified = false; + + net::HttpRequestHeaders headers; + headers.SetHeader("key1", "value 1"); + + // Take a reference to TestLogger to simplify accessing TestLogger methods. + TestLogger& logger = static_cast<TestLogger&>(*info.logger); + + MergeOnBeforeSendHeadersResponses(info, deltas, &headers, &ignored_actions, + &removed_headers, &set_headers, + &request_headers_modified); + + std::string header_value; + ASSERT_TRUE(headers.GetHeader("key1", &header_value)); + EXPECT_EQ("ext1", header_value); + EXPECT_EQ(1u, ignored_actions.size()); + EXPECT_EQ(2u, logger.log_size()); + EXPECT_TRUE(request_headers_modified); + EXPECT_THAT(removed_headers, ::testing::IsEmpty()); + EXPECT_THAT(set_headers, ElementsAre("key1")); } TEST(ExtensionWebRequestHelpersTest, @@ -2189,7 +2277,6 @@ TEST(ExtensionWebRequestHelpersTest, net::HttpRequestHeaders base_headers; base_headers.SetHeader("Cookie", "name=value; name2=value2; name3=\"value3\""); - TestLogger logger; helpers::IgnoredActions ignored_actions; std::string header_value; EventResponseDeltas deltas; @@ -2234,8 +2321,14 @@ TEST(ExtensionWebRequestHelpersTest, net::HttpRequestHeaders headers1; headers1.MergeFrom(base_headers); ignored_actions.clear(); - MergeOnBeforeSendHeadersResponses(GURL(), deltas, &headers1, &ignored_actions, - &logger, &ignore1, &ignore2, + + WebRequestInfoInitParams info_params; + info_params.logger = std::make_unique<TestLogger>(); + WebRequestInfo info(std::move(info_params)); + // Take a reference to TestLogger to simplify accessing TestLogger methods. + TestLogger& logger = static_cast<TestLogger&>(*info.logger); + MergeOnBeforeSendHeadersResponses(info, deltas, &headers1, &ignored_actions, + &ignore1, &ignore2, &request_headers_modified1); EXPECT_TRUE(headers1.HasHeader("Cookie")); ASSERT_TRUE(headers1.GetHeader("Cookie", &header_value)); @@ -2297,10 +2390,8 @@ TEST(ExtensionWebRequestHelpersTest, "Set-Cookie: sessionCookie=removed; Max-Age=INVALID\r\n" "Set-Cookie: sessionCookie2=removed\r\n" "\r\n"; - scoped_refptr<net::HttpResponseHeaders> base_headers( - new net::HttpResponseHeaders( - net::HttpUtil::AssembleRawHeaders( - base_headers_string.c_str(), base_headers_string.size()))); + auto base_headers = base::MakeRefCounted<net::HttpResponseHeaders>( + net::HttpUtil::AssembleRawHeaders(base_headers_string)); // Check that we can handle if not touching the response headers. { @@ -2455,10 +2546,8 @@ TEST(ExtensionWebRequestHelpersTest, deltas.push_back(std::move(delta)); } deltas.sort(&InDecreasingExtensionInstallationTimeOrder); - scoped_refptr<net::HttpResponseHeaders> headers1( - new net::HttpResponseHeaders( - net::HttpUtil::AssembleRawHeaders( - base_headers_string.c_str(), base_headers_string.size()))); + auto headers1 = base::MakeRefCounted<net::HttpResponseHeaders>( + net::HttpUtil::AssembleRawHeaders(base_headers_string)); scoped_refptr<net::HttpResponseHeaders> new_headers1; MergeCookiesInOnHeadersReceivedResponses(GURL(), deltas, headers1.get(), &new_headers1, &logger); @@ -2489,7 +2578,6 @@ TEST(ExtensionWebRequestHelpersTest, } TEST(ExtensionWebRequestHelpersTest, TestMergeOnHeadersReceivedResponses) { - TestLogger logger; helpers::IgnoredActions ignored_actions; std::string header_value; EventResponseDeltas deltas; @@ -2499,10 +2587,8 @@ TEST(ExtensionWebRequestHelpersTest, TestMergeOnHeadersReceivedResponses) { "Key1: Value1\r\n" "Key2: Value2, Foo\r\n" "\r\n"; - scoped_refptr<net::HttpResponseHeaders> base_headers( - new net::HttpResponseHeaders( - net::HttpUtil::AssembleRawHeaders( - base_headers_string, sizeof(base_headers_string)))); + auto base_headers = base::MakeRefCounted<net::HttpResponseHeaders>( + net::HttpUtil::AssembleRawHeaders(base_headers_string)); // Check that we can handle if not touching the response headers. { @@ -2512,9 +2598,17 @@ TEST(ExtensionWebRequestHelpersTest, TestMergeOnHeadersReceivedResponses) { bool response_headers_modified0; scoped_refptr<net::HttpResponseHeaders> new_headers0; GURL allowed_unsafe_redirect_url0; - MergeOnHeadersReceivedResponses(GURL(kExampleUrl), deltas, base_headers.get(), + WebRequestInfoInitParams info_params; + info_params.url = GURL(kExampleUrl); + info_params.logger = std::make_unique<TestLogger>(); + WebRequestInfo info(std::move(info_params)); + info.dnr_action.emplace(Action::Type::NONE); + // Take a reference to TestLogger to simplify accessing TestLogger methods. + TestLogger& logger = static_cast<TestLogger&>(*info.logger); + + MergeOnHeadersReceivedResponses(info, deltas, base_headers.get(), &new_headers0, &allowed_unsafe_redirect_url0, - &ignored_actions, &logger, + &ignored_actions, &response_headers_modified0); EXPECT_FALSE(new_headers0.get()); EXPECT_TRUE(allowed_unsafe_redirect_url0.is_empty()); @@ -2528,6 +2622,7 @@ TEST(ExtensionWebRequestHelpersTest, TestMergeOnHeadersReceivedResponses) { d1.deleted_response_headers.push_back( ResponseHeader("KEY2", "Value2, Foo")); d1.added_response_headers.push_back(ResponseHeader("Key2", "Value3")); + d1.added_response_headers.push_back(ResponseHeader("Key3", "Foo")); deltas.push_back(std::move(d1)); } deltas.sort(&InDecreasingExtensionInstallationTimeOrder); @@ -2536,14 +2631,15 @@ TEST(ExtensionWebRequestHelpersTest, TestMergeOnHeadersReceivedResponses) { bool response_headers_modified1; scoped_refptr<net::HttpResponseHeaders> new_headers1; GURL allowed_unsafe_redirect_url1; - MergeOnHeadersReceivedResponses(GURL(kExampleUrl), deltas, base_headers.get(), + MergeOnHeadersReceivedResponses(info, deltas, base_headers.get(), &new_headers1, &allowed_unsafe_redirect_url1, - &ignored_actions, &logger, + &ignored_actions, &response_headers_modified1); ASSERT_TRUE(new_headers1.get()); EXPECT_TRUE(allowed_unsafe_redirect_url1.is_empty()); std::multimap<std::string, std::string> expected1; expected1.insert(std::pair<std::string, std::string>("Key2", "Value3")); + expected1.insert(std::pair<std::string, std::string>("Key3", "Foo")); size_t iter = 0; std::string name; std::string value; @@ -2572,9 +2668,9 @@ TEST(ExtensionWebRequestHelpersTest, TestMergeOnHeadersReceivedResponses) { bool response_headers_modified2; scoped_refptr<net::HttpResponseHeaders> new_headers2; GURL allowed_unsafe_redirect_url2; - MergeOnHeadersReceivedResponses(GURL(kExampleUrl), deltas, base_headers.get(), + MergeOnHeadersReceivedResponses(info, deltas, base_headers.get(), &new_headers2, &allowed_unsafe_redirect_url2, - &ignored_actions, &logger, + &ignored_actions, &response_headers_modified2); ASSERT_TRUE(new_headers2.get()); EXPECT_TRUE(allowed_unsafe_redirect_url2.is_empty()); @@ -2590,12 +2686,41 @@ TEST(ExtensionWebRequestHelpersTest, TestMergeOnHeadersReceivedResponses) { web_request::IGNORED_ACTION_TYPE_RESPONSE_HEADERS)); EXPECT_EQ(2u, logger.log_size()); EXPECT_TRUE(response_headers_modified2); + + // Ensure headers removed by Declarative Net Request API can't be added by web + // request extensions and result in a conflict. + info.dnr_action.emplace(Action::Type::REMOVE_HEADERS); + info.dnr_action->response_headers_to_remove = {"key3"}; + ignored_actions.clear(); + logger.clear(); + bool response_headers_modified3 = false; + scoped_refptr<net::HttpResponseHeaders> new_headers3; + GURL allowed_unsafe_redirect_url3; + MergeOnHeadersReceivedResponses(info, deltas, base_headers.get(), + &new_headers3, &allowed_unsafe_redirect_url3, + &ignored_actions, + &response_headers_modified3); + ASSERT_TRUE(new_headers3.get()); + EXPECT_TRUE(allowed_unsafe_redirect_url3.is_empty()); + iter = 0; + std::multimap<std::string, std::string> actual3; + while (new_headers3->EnumerateHeaderLines(&iter, &name, &value)) + actual3.emplace(name, value); + std::multimap<std::string, std::string> expected3; + expected3.emplace("Key2", "Value4"); + expected3.emplace("Key1", "Value1"); + EXPECT_EQ(expected3, actual3); + EXPECT_EQ(1u, ignored_actions.size()); + EXPECT_TRUE( + HasIgnoredAction(ignored_actions, "extid1", + web_request::IGNORED_ACTION_TYPE_RESPONSE_HEADERS)); + EXPECT_EQ(2u, logger.log_size()); + EXPECT_TRUE(response_headers_modified3); } // Check that we do not delete too much TEST(ExtensionWebRequestHelpersTest, TestMergeOnHeadersReceivedResponsesDeletion) { - TestLogger logger; helpers::IgnoredActions ignored_actions; std::string header_value; EventResponseDeltas deltas; @@ -2607,10 +2732,8 @@ TEST(ExtensionWebRequestHelpersTest, "Key1: Value3\r\n" "Key2: Value4\r\n" "\r\n"; - scoped_refptr<net::HttpResponseHeaders> base_headers( - new net::HttpResponseHeaders( - net::HttpUtil::AssembleRawHeaders( - base_headers_string, sizeof(base_headers_string)))); + auto base_headers = base::MakeRefCounted<net::HttpResponseHeaders>( + net::HttpUtil::AssembleRawHeaders(base_headers_string)); { EventResponseDelta d1("extid1", base::Time::FromInternalValue(2000)); @@ -2620,9 +2743,18 @@ TEST(ExtensionWebRequestHelpersTest, bool response_headers_modified1; scoped_refptr<net::HttpResponseHeaders> new_headers1; GURL allowed_unsafe_redirect_url1; - MergeOnHeadersReceivedResponses(GURL(kExampleUrl), deltas, base_headers.get(), + + WebRequestInfoInitParams info_params; + info_params.url = GURL(kExampleUrl); + info_params.logger = std::make_unique<TestLogger>(); + WebRequestInfo info(std::move(info_params)); + info.dnr_action.emplace(Action::Type::NONE); + // Take a reference to TestLogger to simplify accessing TestLogger methods. + TestLogger& logger = static_cast<TestLogger&>(*info.logger); + + MergeOnHeadersReceivedResponses(info, deltas, base_headers.get(), &new_headers1, &allowed_unsafe_redirect_url1, - &ignored_actions, &logger, + &ignored_actions, &response_headers_modified1); ASSERT_TRUE(new_headers1.get()); EXPECT_TRUE(allowed_unsafe_redirect_url1.is_empty()); @@ -2649,15 +2781,13 @@ TEST(ExtensionWebRequestHelpersTest, TEST(ExtensionWebRequestHelpersTest, TestMergeOnHeadersReceivedResponsesRedirect) { EventResponseDeltas deltas; - TestLogger logger; helpers::IgnoredActions ignored_actions; char base_headers_string[] = "HTTP/1.0 200 OK\r\n" "\r\n"; - scoped_refptr<net::HttpResponseHeaders> base_headers( - new net::HttpResponseHeaders(net::HttpUtil::AssembleRawHeaders( - base_headers_string, sizeof(base_headers_string)))); + auto base_headers = base::MakeRefCounted<net::HttpResponseHeaders>( + net::HttpUtil::AssembleRawHeaders(base_headers_string)); // No redirect { @@ -2667,9 +2797,17 @@ TEST(ExtensionWebRequestHelpersTest, bool response_headers_modified0; scoped_refptr<net::HttpResponseHeaders> new_headers0; GURL allowed_unsafe_redirect_url0; - MergeOnHeadersReceivedResponses(GURL(kExampleUrl), deltas, base_headers.get(), + + WebRequestInfoInitParams info_params; + info_params.url = GURL(kExampleUrl); + info_params.logger = std::make_unique<TestLogger>(); + WebRequestInfo info(std::move(info_params)); + // Take a reference to TestLogger to simplify accessing TestLogger methods. + TestLogger& logger = static_cast<TestLogger&>(*info.logger); + + MergeOnHeadersReceivedResponses(info, deltas, base_headers.get(), &new_headers0, &allowed_unsafe_redirect_url0, - &ignored_actions, &logger, + &ignored_actions, &response_headers_modified0); EXPECT_FALSE(new_headers0.get()); EXPECT_TRUE(allowed_unsafe_redirect_url0.is_empty()); @@ -2690,9 +2828,9 @@ TEST(ExtensionWebRequestHelpersTest, scoped_refptr<net::HttpResponseHeaders> new_headers1; GURL allowed_unsafe_redirect_url1; - MergeOnHeadersReceivedResponses(GURL(kExampleUrl), deltas, base_headers.get(), + MergeOnHeadersReceivedResponses(info, deltas, base_headers.get(), &new_headers1, &allowed_unsafe_redirect_url1, - &ignored_actions, &logger, + &ignored_actions, &response_headers_modified1); EXPECT_TRUE(new_headers1.get()); diff --git a/chromium/chrome/browser/extensions/api/web_request/web_request_apitest.cc b/chromium/chrome/browser/extensions/api/web_request/web_request_apitest.cc index 4373dff71ae..4f7e40c972a 100644 --- a/chromium/chrome/browser/extensions/api/web_request/web_request_apitest.cc +++ b/chromium/chrome/browser/extensions/api/web_request/web_request_apitest.cc @@ -7,7 +7,6 @@ #include "base/bind.h" #include "base/command_line.h" -#include "base/feature_list.h" #include "base/macros.h" #include "base/memory/ptr_util.h" #include "base/optional.h" @@ -39,7 +38,6 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_destroyer.h" #include "chrome/browser/profiles/profile_manager.h" -#include "chrome/browser/search/ntp_features.h" #include "chrome/browser/search/one_google_bar/one_google_bar_loader.h" #include "chrome/browser/search/one_google_bar/one_google_bar_service.h" #include "chrome/browser/search/one_google_bar/one_google_bar_service_factory.h" @@ -115,9 +113,6 @@ using content::WebContents; namespace extensions { -using extension_web_request_api_helpers:: - WebRequestSpecialRequestHeaderModification; - namespace { class CancelLoginDialog : public content::NotificationObserver { @@ -1852,10 +1847,11 @@ IN_PROC_BROWSER_TEST_F(ExtensionWebRequestApiTest, chromeos::ProfileHelper::SetAlwaysReturnPrimaryUserForTesting(true); #endif // defined(OS_CHROMEOS) ProfileManager* profile_manager = g_browser_process->profile_manager(); - Profile* temp_profile = Profile::CreateProfile( - profile_manager->user_data_dir().AppendASCII("profile"), nullptr, - Profile::CreateMode::CREATE_MODE_SYNCHRONOUS); - + Profile* temp_profile = + Profile::CreateProfile( + profile_manager->user_data_dir().AppendASCII("profile"), nullptr, + Profile::CreateMode::CREATE_MODE_SYNCHRONOUS) + .release(); // Create a WebRequestAPI instance that we can control the lifetime of. auto api = std::make_unique<WebRequestAPI>(temp_profile); // Make sure we are proxying for |temp_profile|. @@ -1999,7 +1995,6 @@ class LocalNTPInterceptionWebRequestAPITest base::Unretained(this))); ASSERT_TRUE(https_test_server_.InitializeAndListen()); ExtensionApiTest::SetUp(); - feature_list_.InitWithFeatures({::features::kUseGoogleLocalNtp}, {}); } void SetUpCommandLine(base::CommandLine* command_line) override { ExtensionApiTest::SetUpCommandLine(command_line); @@ -2051,7 +2046,6 @@ class LocalNTPInterceptionWebRequestAPITest } net::EmbeddedTestServer https_test_server_; - base::test::ScopedFeatureList feature_list_; std::unique_ptr<base::RunLoop> runloop_; // Initialized on the UI thread in SetUpOnMainThread. Read on UI and Embedded @@ -2440,6 +2434,11 @@ IN_PROC_BROWSER_TEST_F(ExtensionWebRequestMockedClockTest, } IN_PROC_BROWSER_TEST_F(ExtensionWebRequestApiTest, ChangeHeaderUMAs) { + using RequestHeaderType = + extension_web_request_api_helpers::RequestHeaderType; + using ResponseHeaderType = + extension_web_request_api_helpers::ResponseHeaderType; + ASSERT_TRUE(embedded_test_server()->Start()); TestExtensionDir test_dir; @@ -2459,6 +2458,9 @@ IN_PROC_BROWSER_TEST_F(ExtensionWebRequestApiTest, ChangeHeaderUMAs) { break; } } + headers.push({name: 'Foo1', value: 'Bar1'}); + headers.push({name: 'Foo2', value: 'Bar2'}); + headers.push({name: 'DNT', value: '0'}); return {requestHeaders: headers}; }, {urls: ['*://*/set-cookie*']}, ['blocking', 'requestHeaders', 'extraHeaders']); @@ -2466,11 +2468,16 @@ IN_PROC_BROWSER_TEST_F(ExtensionWebRequestApiTest, ChangeHeaderUMAs) { chrome.webRequest.onHeadersReceived.addListener(function(details) { var headers = details.responseHeaders; for (var i = 0; i < headers.length; i++) { - if (headers[i].name.toLowerCase() == 'set-cookie') { - headers[i].value = 'Blah=Blah'; - break; + if (headers[i].name.toLowerCase() == 'set-cookie' && + headers[i].value == 'key1=val1') { + headers.splice(i, 1); + i--; + } else if (headers[i].name == 'Content-Length') { + headers[i].value = '0'; } } + headers.push({name: 'Foo3', value: 'Bar3'}); + headers.push({name: 'Foo4', value: 'Bar4'}); return {responseHeaders: headers}; }, {urls: ['*://*/set-cookie*']}, ['blocking', 'responseHeaders', 'extraHeaders']); @@ -2484,24 +2491,50 @@ IN_PROC_BROWSER_TEST_F(ExtensionWebRequestApiTest, ChangeHeaderUMAs) { base::HistogramTester tester; ui_test_utils::NavigateToURL( - browser(), embedded_test_server()->GetURL("/set-cookie?Foo=Bar")); - - // Changed histograms should record kUserAgent and true. - tester.ExpectUniqueSample( - "Extensions.WebRequest.SpecialRequestHeadersChanged", - WebRequestSpecialRequestHeaderModification::kUserAgent, 1); - tester.ExpectUniqueSample( - "Extensions.WebRequest.SetCookieResponseHeaderChanged", true, 1); - - // Removed histograms should record kNone and false. - tester.ExpectUniqueSample( - "Extensions.WebRequest.SpecialRequestHeadersRemoved", - WebRequestSpecialRequestHeaderModification::kNone, 1); - tester.ExpectUniqueSample( - "Extensions.WebRequest.SetCookieResponseHeaderRemoved", false, 1); + browser(), + embedded_test_server()->GetURL("/set-cookie?key1=val1&key2=val2")); + + // Changed histograms should record kUserAgent request header along with + // kSetCookie and kContentLength response headers. + tester.ExpectUniqueSample("Extensions.WebRequest.RequestHeaderChanged", + RequestHeaderType::kUserAgent, 1); + EXPECT_THAT( + tester.GetAllSamples("Extensions.WebRequest.ResponseHeaderChanged"), + ::testing::UnorderedElementsAre( + base::Bucket(static_cast<base::HistogramBase::Sample>( + ResponseHeaderType::kSetCookie), + 1), + base::Bucket(static_cast<base::HistogramBase::Sample>( + ResponseHeaderType::kContentLength), + 1))); + + // Added request header histogram should record kOther and kDNT. + EXPECT_THAT(tester.GetAllSamples("Extensions.WebRequest.RequestHeaderAdded"), + ::testing::UnorderedElementsAre( + base::Bucket(static_cast<base::HistogramBase::Sample>( + RequestHeaderType::kDnt), + 1), + base::Bucket(static_cast<base::HistogramBase::Sample>( + RequestHeaderType::kOther), + 2))); + + // Added response header histogram should record kOther. + tester.ExpectUniqueSample("Extensions.WebRequest.ResponseHeaderAdded", + ResponseHeaderType::kOther, 2); + + // Histograms for removed headers should record kNone. + tester.ExpectUniqueSample("Extensions.WebRequest.RequestHeaderRemoved", + RequestHeaderType::kNone, 1); + tester.ExpectUniqueSample("Extensions.WebRequest.ResponseHeaderRemoved", + ResponseHeaderType::kNone, 1); } IN_PROC_BROWSER_TEST_F(ExtensionWebRequestApiTest, RemoveHeaderUMAs) { + using RequestHeaderType = + extension_web_request_api_helpers::RequestHeaderType; + using ResponseHeaderType = + extension_web_request_api_helpers::ResponseHeaderType; + ASSERT_TRUE(embedded_test_server()->Start()); TestExtensionDir test_dir; @@ -2548,19 +2581,23 @@ IN_PROC_BROWSER_TEST_F(ExtensionWebRequestApiTest, RemoveHeaderUMAs) { ui_test_utils::NavigateToURL( browser(), embedded_test_server()->GetURL("/set-cookie?Foo=Bar")); - // Removed histograms should record kUserAgent and true. - tester.ExpectUniqueSample( - "Extensions.WebRequest.SpecialRequestHeadersRemoved", - WebRequestSpecialRequestHeaderModification::kUserAgent, 1); - tester.ExpectUniqueSample( - "Extensions.WebRequest.SetCookieResponseHeaderRemoved", true, 1); + // Histograms for removed headers should record kUserAgent and kSetCookie. + tester.ExpectUniqueSample("Extensions.WebRequest.RequestHeaderRemoved", + RequestHeaderType::kUserAgent, 1); + tester.ExpectUniqueSample("Extensions.WebRequest.ResponseHeaderRemoved", + ResponseHeaderType::kSetCookie, 1); + + // Histograms for changed headers should record kNone. + tester.ExpectUniqueSample("Extensions.WebRequest.RequestHeaderChanged", + RequestHeaderType::kNone, 1); + tester.ExpectUniqueSample("Extensions.WebRequest.ResponseHeaderChanged", + ResponseHeaderType::kNone, 1); - // Changed histograms should record kNone and false. - tester.ExpectUniqueSample( - "Extensions.WebRequest.SpecialRequestHeadersChanged", - WebRequestSpecialRequestHeaderModification::kNone, 1); - tester.ExpectUniqueSample( - "Extensions.WebRequest.SetCookieResponseHeaderChanged", false, 1); + // Histograms for added headers should record kNone. + tester.ExpectUniqueSample("Extensions.WebRequest.RequestHeaderAdded", + RequestHeaderType::kNone, 1); + tester.ExpectUniqueSample("Extensions.WebRequest.ResponseHeaderAdded", + ResponseHeaderType::kNone, 1); } IN_PROC_BROWSER_TEST_F(ExtensionWebRequestApiTest, ServiceWorkerFetch) { @@ -2710,4 +2747,65 @@ IN_PROC_BROWSER_TEST_F(ExtensionWebRequestApiTest, Initiator_SplitIncognito) { profile()->GetOffTheRecordProfile(), extension->id(), kScript)); } +// A request handler that sets the Access-Control-Allow-Origin header. +std::unique_ptr<net::test_server::HttpResponse> HandleXHRRequest( + const net::test_server::HttpRequest& request) { + auto http_response = std::make_unique<net::test_server::BasicHttpResponse>(); + http_response->set_code(net::HTTP_OK); + http_response->AddCustomHeader("Access-Control-Allow-Origin", "*"); + return http_response; +} + +// Regression test for http://crbug.com/971206. The responseHeaders should still +// be present in onBeforeRedirect even for HSTS upgrade. +IN_PROC_BROWSER_TEST_F(ExtensionWebRequestApiTest, + ExtraHeadersWithHSTSUpgrade) { + net::EmbeddedTestServer https_test_server( + net::EmbeddedTestServer::TYPE_HTTPS); + https_test_server.RegisterRequestHandler( + base::BindRepeating(&HandleXHRRequest)); + ASSERT_TRUE(https_test_server.Start()); + + TestExtensionDir test_dir; + test_dir.WriteManifest(R"({ + "name": "Web Request HSTS Test", + "manifest_version": 2, + "version": "0.1", + "background": { "scripts": ["background.js"] }, + "permissions": ["<all_urls>", "webRequest", "webRequestBlocking"] + })"); + test_dir.WriteFile(FILE_PATH_LITERAL("background.js"), R"( + chrome.webRequest.onBeforeRedirect.addListener(function(details) { + window.headerCount = details.responseHeaders.length; + }, {urls: ['<all_urls>']}, + ['responseHeaders', 'extraHeaders']); + + chrome.test.sendMessage('ready'); + )"); + + ExtensionTestMessageListener listener("ready", false); + const Extension* extension = LoadExtension(test_dir.UnpackedPath()); + ASSERT_TRUE(extension); + EXPECT_TRUE(listener.WaitUntilSatisfied()); + + ui_test_utils::NavigateToURL(browser(), https_test_server.GetURL("/echo")); + + content::StoragePartition* partition = + content::BrowserContext::GetDefaultStoragePartition(profile()); + base::RunLoop run_loop; + partition->GetNetworkContext()->AddHSTS( + https_test_server.host_port_pair().host(), + base::Time::Now() + base::TimeDelta::FromDays(100), true, + run_loop.QuitClosure()); + run_loop.Run(); + + PerformXhrInFrame( + browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(), + https_test_server.host_port_pair().host(), https_test_server.port(), + "echo"); + EXPECT_GT( + GetCountFromBackgroundPage(extension, profile(), "window.headerCount"), + 0); +} + } // namespace extensions diff --git a/chromium/chrome/browser/extensions/api/web_request/web_request_event_details_unittest.cc b/chromium/chrome/browser/extensions/api/web_request/web_request_event_details_unittest.cc index 293b67a076d..74cdf220816 100644 --- a/chromium/chrome/browser/extensions/api/web_request/web_request_event_details_unittest.cc +++ b/chromium/chrome/browser/extensions/api/web_request/web_request_event_details_unittest.cc @@ -9,6 +9,7 @@ #include "base/values.h" #include "extensions/browser/api/web_request/web_request_api_constants.h" #include "extensions/browser/api/web_request/web_request_api_helpers.h" +#include "extensions/browser/api/web_request/web_request_info.h" #include "google_apis/gaia/gaia_urls.h" #include "net/http/http_response_headers.h" #include "net/http/http_util.h" @@ -84,9 +85,8 @@ TEST(WebRequestEventDetailsTest, SetResponseHeaders) { "Key1: Value1\r\n" "X-Chrome-ID-Consistency-Response: Value2\r\n" "\r\n"; - scoped_refptr<net::HttpResponseHeaders> headers( - new net::HttpResponseHeaders(net::HttpUtil::AssembleRawHeaders( - headers_string, sizeof(headers_string)))); + auto headers = base::MakeRefCounted<net::HttpResponseHeaders>( + net::HttpUtil::AssembleRawHeaders(headers_string)); { // Non-Gaia URL. diff --git a/chromium/chrome/browser/extensions/api/web_request/web_request_permissions_unittest.cc b/chromium/chrome/browser/extensions/api/web_request/web_request_permissions_unittest.cc index cf759c37dad..d9e2bea4e94 100644 --- a/chromium/chrome/browser/extensions/api/web_request/web_request_permissions_unittest.cc +++ b/chromium/chrome/browser/extensions/api/web_request/web_request_permissions_unittest.cc @@ -27,11 +27,12 @@ #include "chromeos/login/login_state/login_state.h" #endif // defined(OS_CHROMEOS) +using extension_test_util::LoadManifestUnchecked; using extensions::Extension; using extensions::Manifest; using extensions::PermissionsData; using extensions::WebRequestInfo; -using extension_test_util::LoadManifestUnchecked; +using extensions::WebRequestInfoInitParams; class ExtensionWebRequestHelpersTestWithThreadsTest : public testing::Test { public: @@ -105,23 +106,23 @@ void ExtensionWebRequestHelpersTestWithThreadsTest::SetUp() { // extensions. TEST_F(ExtensionWebRequestHelpersTestWithThreadsTest, BlacklistUpdateUrlsHidden) { - auto create_request = [](const std::string& url) { + auto create_request_params = [](const std::string& url) { const int kRendererProcessId = 2; - WebRequestInfo request; + WebRequestInfoInitParams request; request.url = GURL(url); request.render_process_id = kRendererProcessId; return request; }; - WebRequestInfo request = - create_request("http://www.gstatic.com/chrome/extensions/blacklist"); + WebRequestInfo request_1(create_request_params( + "http://www.gstatic.com/chrome/extensions/blacklist")); EXPECT_TRUE( - WebRequestPermissions::HideRequest(extension_info_map_.get(), request)); + WebRequestPermissions::HideRequest(extension_info_map_.get(), request_1)); - request = - create_request("https://www.gstatic.com/chrome/extensions/blacklist"); + WebRequestInfo request_2(create_request_params( + "https://www.gstatic.com/chrome/extensions/blacklist")); EXPECT_TRUE( - WebRequestPermissions::HideRequest(extension_info_map_.get(), request)); + WebRequestPermissions::HideRequest(extension_info_map_.get(), request_2)); } // Ensure requests made by the local NTP are hidden from extensions. Regression @@ -129,30 +130,44 @@ TEST_F(ExtensionWebRequestHelpersTestWithThreadsTest, TEST_F(ExtensionWebRequestHelpersTestWithThreadsTest, LocalNTPRequests) { const GURL example_com("http://example.com"); - WebRequestInfo info; - info.url = example_com; - info.initiator = url::Origin::Create(GURL(chrome::kChromeSearchLocalNtpUrl)); - info.render_process_id = -1; + auto create_request_params = + [&example_com](const url::Origin& initiator, content::ResourceType type, + extensions::WebRequestResourceType web_request_type, + bool is_browser_side_navigation) { + WebRequestInfoInitParams info_params; + info_params.url = example_com; + info_params.initiator = initiator; + info_params.render_process_id = -1; + info_params.type = type; + info_params.web_request_type = web_request_type; + info_params.is_browser_side_navigation = is_browser_side_navigation; + return info_params; + }; + + url::Origin ntp_origin = + url::Origin::Create(GURL(chrome::kChromeSearchLocalNtpUrl)); // Sub-resource browser initiated requests are hidden from extensions. - info.type = content::ResourceType::kSubResource; - info.web_request_type = extensions::WebRequestResourceType::OTHER; - info.is_browser_side_navigation = false; - EXPECT_TRUE( - WebRequestPermissions::HideRequest(extension_info_map_.get(), info)); + WebRequestInfoInitParams info_params_1 = + create_request_params(ntp_origin, content::ResourceType::kSubResource, + extensions::WebRequestResourceType::OTHER, false); + EXPECT_TRUE(WebRequestPermissions::HideRequest( + extension_info_map_.get(), WebRequestInfo(std::move(info_params_1)))); // Sub-frame navigations initiated from the local ntp should be hidden. - info.type = content::ResourceType::kSubFrame; - info.web_request_type = extensions::WebRequestResourceType::SUB_FRAME; - info.is_browser_side_navigation = true; - EXPECT_TRUE( - WebRequestPermissions::HideRequest(extension_info_map_.get(), info)); + WebRequestInfoInitParams info_params_2 = create_request_params( + ntp_origin, content::ResourceType::kSubFrame, + extensions::WebRequestResourceType::SUB_FRAME, true); + EXPECT_TRUE(WebRequestPermissions::HideRequest( + extension_info_map_.get(), WebRequestInfo(std::move(info_params_2)))); // Sub-frame navigations initiated from a non-sensitive domain should not be // hidden. - info.initiator = url::Origin::Create(example_com); - EXPECT_FALSE( - WebRequestPermissions::HideRequest(extension_info_map_.get(), info)); + WebRequestInfoInitParams info_params_3 = create_request_params( + url::Origin::Create(example_com), content::ResourceType::kSubFrame, + extensions::WebRequestResourceType::SUB_FRAME, true); + EXPECT_FALSE(WebRequestPermissions::HideRequest( + extension_info_map_.get(), WebRequestInfo(std::move(info_params_3)))); } TEST_F(ExtensionWebRequestHelpersTestWithThreadsTest, |